diff --git a/.bazelrc b/.bazelrc index e7bddacdda211..61356f086fda5 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,4 +1,4 @@ -startup --host_jvm_args=-Xmx6g +startup --host_jvm_args=-Xmx8g startup --unlimit_coredumps run:ci --color=yes diff --git a/.bazelversion b/.bazelversion index c7cb1311a645f..84197c89467dd 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -5.3.1 +5.3.2 diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000..d114ba901dc2b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git/ +bazel-bin/ +bazel-out/ +bazel-tidb/ +bazel-testlogs/ +bin/ +tidb-server/tidb-server +*.test.bin +cmd/ +Dockerfile diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b1d1d17e8acd9..9fd79475351a3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,5 +1,6 @@ # Require review from domain experts when the PR modified significant config files. -/sessionctx/variable @pingcap/tidb-configuration-reviewer -/config/config.toml.example @pingcap/tidb-configuration-reviewer -/session/bootstrap.go @pingcap/tidb-configuration-reviewer -/telemetry/ @pingcap/telemetry-reviewer +# TODO: Enable these again before merging the feature branch to pingcap/master +#/sessionctx/variable @pingcap/tidb-configuration-reviewer +#/config/config.toml.example @pingcap/tidb-configuration-reviewer +#/session/bootstrap.go @pingcap/tidb-configuration-reviewer +#/telemetry/ @pingcap/telemetry-reviewer diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000000..bde24b721461e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + day: "friday" + time: "18:00" + timezone: "Asia/Shanghai" + allow: + - dependency-name: "golang.org/*" + - dependency-name: "github.com/golangci/golangci-lint" + open-pull-requests-limit: 2 + diff --git a/.github/licenserc.yml b/.github/licenserc.yml index 68e70685a12f8..e1add7017983b 100644 --- a/.github/licenserc.yml +++ b/.github/licenserc.yml @@ -6,6 +6,7 @@ header: - "docs/" - "br/" - ".gitignore" + - ".dockerignore" - ".gitattributes" - ".cilinter.yaml" - ".golangci.yml" diff --git a/.github/workflows/integration-test-br-compatibility.yml b/.github/workflows/integration-test-br-compatibility.yml deleted file mode 100644 index b455799b91afa..0000000000000 --- a/.github/workflows/integration-test-br-compatibility.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: BR / Compatibility Test - -on: - push: - # merged git action - branches: - - master - - "release-[0-9].[0-9]*" - paths: - - "br/**" - - "!**.html" - - "!**.md" - - "!CNAME" - - "!LICENSE" - - "!br/docs/**" - - "!br/tests/**" - - "!br/docker/**" - # disable pull request only keep the merge action since it is very costly to run those tests - # pull_request: - -concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - timeout-minutes: 25 - steps: - - uses: actions/checkout@v2 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: 'go.mod' - - - name: Generate compatibility test backup data - timeout-minutes: 15 - run: sh br/compatibility/prepare_backup.sh - - - name: Start server - run: | - TAG=nightly PORT_SUFFIX=1 docker-compose -f br/compatibility/backup_cluster.yaml rm -s -v - TAG=nightly PORT_SUFFIX=1 docker-compose -f br/compatibility/backup_cluster.yaml build - TAG=nightly PORT_SUFFIX=1 docker-compose -f br/compatibility/backup_cluster.yaml up --remove-orphans -d - TAG=nightly PORT_SUFFIX=1 docker-compose -f br/compatibility/backup_cluster.yaml exec -T control go mod tidy - TAG=nightly PORT_SUFFIX=1 docker-compose -f br/compatibility/backup_cluster.yaml exec -T control make build_br - TAG=nightly PORT_SUFFIX=1 docker-compose -f br/compatibility/backup_cluster.yaml exec -T control br/tests/run_compatible.sh run - - - name: Collect component log - if: ${{ failure() }} - run: | - tar czvf ${{ github.workspace }}/logs.tar.gz /tmp/br/docker/backup_logs/* - - - uses: actions/upload-artifact@v2 - if: ${{ failure() }} - with: - name: logs - path: ${{ github.workspace }}/logs.tar.gz diff --git a/.github/workflows/integration-test-compile-br.yml b/.github/workflows/integration-test-compile-br.yml index 17cbd48b25d7b..7b22aa4e24bbe 100644 --- a/.github/workflows/integration-test-compile-br.yml +++ b/.github/workflows/integration-test-compile-br.yml @@ -36,6 +36,9 @@ concurrency: group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: true +permissions: + contents: read # to fetch code (actions/checkout) + jobs: compile-windows: if: github.event_name == 'push' || github.event_name == 'pull_request' && github.event.label.name == 'action/run-br-cross-platform-build' diff --git a/.github/workflows/integration-test-dumpling.yml b/.github/workflows/integration-test-dumpling.yml index e1dd6a58d3e6d..14bae6e6b7115 100644 --- a/.github/workflows/integration-test-dumpling.yml +++ b/.github/workflows/integration-test-dumpling.yml @@ -40,6 +40,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read # to fetch code (actions/checkout) + jobs: integration-test: strategy: diff --git a/.github/workflows/misc.yml b/.github/workflows/misc.yml index 78e0f9a46d4a7..94b68e9c95510 100644 --- a/.github/workflows/misc.yml +++ b/.github/workflows/misc.yml @@ -12,8 +12,15 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read # to fetch code (actions/checkout) + jobs: check: + permissions: + contents: read # to fetch code (actions/checkout) + pull-requests: write # to comment on pull-requests + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.gitignore b/.gitignore index e2cdcd078a0f1..35af372bcccad 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ bazel-out bazel-testlogs bazel-tidb .ijwb/ +/oom_record/ diff --git a/DEPS.bzl b/DEPS.bzl index 2e78e45f88b6e..a1ff508ca83c7 100644 --- a/DEPS.bzl +++ b/DEPS.bzl @@ -5,8 +5,8 @@ def go_deps(): name = "cc_mvdan_gofumpt", build_file_proto_mode = "disable", importpath = "mvdan.cc/gofumpt", - sum = "h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8=", - version = "v0.3.1", + sum = "h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM=", + version = "v0.4.0", ) go_repository( name = "cc_mvdan_interfacer", @@ -44,6 +44,21 @@ def go_deps(): sum = "h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0=", version = "v0.1.0", ) + go_repository( + name = "com_github_abirdcfly_dupword", + build_file_proto_mode = "disable", + importpath = "github.com/Abirdcfly/dupword", + sum = "h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q=", + version = "v0.0.7", + ) + + go_repository( + name = "com_github_acarl005_stripansi", + build_file_proto_mode = "disable", + importpath = "github.com/acarl005/stripansi", + sum = "h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=", + version = "v0.0.0-20180116102854-5a71ef0e047d", + ) go_repository( name = "com_github_ajg_form", @@ -73,6 +88,14 @@ def go_deps(): sum = "h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=", version = "v0.0.0-20190924025748-f65c72e2690d", ) + go_repository( + name = "com_github_aleksi_gocov_xml", + build_file_proto_mode = "disable", + importpath = "github.com/AlekSi/gocov-xml", + sum = "h1:4QctJBgXEkbzeKz6PJy6bt3JSPNSN4I2mITYW+eKUoQ=", + version = "v1.0.0", + ) + go_repository( name = "com_github_alexkohler_prealloc", build_file_proto_mode = "disable", @@ -160,6 +183,14 @@ def go_deps(): sum = "h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to=", version = "v0.0.0-20180808171621-7fddfc383310", ) + go_repository( + name = "com_github_armon_go_socks5", + build_file_proto_mode = "disable", + importpath = "github.com/armon/go-socks5", + sum = "h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=", + version = "v0.0.0-20160902184237-e75332964ef5", + ) + go_repository( name = "com_github_ashanbrown_forbidigo", build_file_proto_mode = "disable", @@ -182,6 +213,14 @@ def go_deps(): sum = "h1:jLDC9RsNoYMLFlKpB8LdqUnoDdC2yvkS4QbuyPQJ8+M=", version = "v1.44.48", ) + go_repository( + name = "com_github_axw_gocov", + build_file_proto_mode = "disable", + importpath = "github.com/axw/gocov", + sum = "h1:YsqYR66hUmilVr23tu8USgnJIJvnwh3n7j5zRn7x4LU=", + version = "v1.0.0", + ) + go_repository( name = "com_github_aymerick_raymond", build_file_proto_mode = "disable_global", @@ -261,6 +300,13 @@ def go_deps(): sum = "h1:tYoz1OeRpx3dJZlh9T4dQt4kAndcmpl+VNdzbSgFC/0=", version = "v0.0.0-20160505134755-913427a1d5e8", ) + go_repository( + name = "com_github_bitly_go_simplejson", + build_file_proto_mode = "disable", + importpath = "github.com/bitly/go-simplejson", + sum = "h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=", + version = "v0.5.0", + ) go_repository( name = "com_github_bketelsen_crypt", @@ -298,6 +344,14 @@ def go_deps(): sum = "h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM=", version = "v3.3.0", ) + go_repository( + name = "com_github_breeswish_gin_jwt_v2", + build_file_proto_mode = "disable", + importpath = "github.com/breeswish/gin-jwt/v2", + sum = "h1:KLE/YeX+9FNaGVW5MtImRVPhjDpfpgJhvkuYWBmOYbo=", + version = "v2.6.4-jwt-patch", + ) + go_repository( name = "com_github_breml_bidichk", build_file_proto_mode = "disable", @@ -317,8 +371,8 @@ def go_deps(): name = "com_github_burntsushi_toml", build_file_proto_mode = "disable_global", importpath = "github.com/BurntSushi/toml", - sum = "h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=", - version = "v1.2.0", + sum = "h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=", + version = "v1.2.1", ) go_repository( name = "com_github_burntsushi_xgb", @@ -334,6 +388,13 @@ def go_deps(): sum = "h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY=", version = "v0.1.1", ) + go_repository( + name = "com_github_cakturk_go_netstat", + build_file_proto_mode = "disable", + importpath = "github.com/cakturk/go-netstat", + sum = "h1:BjkPE3785EwPhhyuFkbINB+2a1xATwk8SNDWnJiD41g=", + version = "v0.0.0-20200220111822-e5b49efee7a5", + ) go_repository( name = "com_github_carlmjohnson_flagext", @@ -349,13 +410,20 @@ def go_deps(): sum = "h1:7vXVw3g7XE+Vnj0A9TmFGtMeP4oZQ5ZzpPvKhLFa80E=", version = "v2.0.0+incompatible", ) + go_repository( + name = "com_github_cenkalti_backoff_v4", + build_file_proto_mode = "disable", + importpath = "github.com/cenkalti/backoff/v4", + sum = "h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs=", + version = "v4.0.2", + ) go_repository( name = "com_github_census_instrumentation_opencensus_proto", build_file_proto_mode = "disable_global", importpath = "github.com/census-instrumentation/opencensus-proto", - sum = "h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=", - version = "v0.2.1", + sum = "h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=", + version = "v0.3.0", ) go_repository( name = "com_github_certifi_gocertifi", @@ -375,8 +443,8 @@ def go_deps(): name = "com_github_cespare_xxhash_v2", build_file_proto_mode = "disable_global", importpath = "github.com/cespare/xxhash/v2", - sum = "h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=", - version = "v2.1.2", + sum = "h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=", + version = "v2.2.0", ) go_repository( name = "com_github_charithe_durationcheck", @@ -435,6 +503,14 @@ def go_deps(): sum = "h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=", version = "v0.3.4", ) + go_repository( + name = "com_github_cloudfoundry_gosigar", + build_file_proto_mode = "disable", + importpath = "github.com/cloudfoundry/gosigar", + sum = "h1:T3MoGdugg1vdHn8Az7wDn7cZ4+QCjZph+eXf2CjSjo4=", + version = "v1.3.4", + ) + go_repository( name = "com_github_cloudykit_fastprinter", build_file_proto_mode = "disable_global", @@ -608,8 +684,8 @@ def go_deps(): name = "com_github_coreos_go_systemd", build_file_proto_mode = "disable_global", importpath = "github.com/coreos/go-systemd", - sum = "h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=", - version = "v0.0.0-20190321100706-95778dfbb74e", + sum = "h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=", + version = "v0.0.0-20190719114852-fd7a80b32e1f", ) go_repository( name = "com_github_coreos_go_systemd_v22", @@ -650,8 +726,8 @@ def go_deps(): name = "com_github_curioswitch_go_reassign", build_file_proto_mode = "disable", importpath = "github.com/curioswitch/go-reassign", - sum = "h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc/tlYpkmI=", - version = "v0.1.2", + sum = "h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo=", + version = "v0.2.0", ) go_repository( @@ -679,8 +755,8 @@ def go_deps(): name = "com_github_daixiang0_gci", build_file_proto_mode = "disable", importpath = "github.com/daixiang0/gci", - sum = "h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E=", - version = "v0.6.3", + sum = "h1:yBdsd376w+RIBvFXjj0MAcGWS8cSCfAlRNPfn5xvjl0=", + version = "v0.8.5", ) go_repository( @@ -711,6 +787,21 @@ def go_deps(): sum = "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=", version = "v1.1.1", ) + go_repository( + name = "com_github_decred_dcrd_crypto_blake256", + build_file_proto_mode = "disable", + importpath = "github.com/decred/dcrd/crypto/blake256", + sum = "h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=", + version = "v1.0.0", + ) + go_repository( + name = "com_github_decred_dcrd_dcrec_secp256k1_v4", + build_file_proto_mode = "disable", + importpath = "github.com/decred/dcrd/dcrec/secp256k1/v4", + sum = "h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=", + version = "v4.1.0", + ) + go_repository( name = "com_github_denis_tingaikin_go_header", build_file_proto_mode = "disable", @@ -730,8 +821,8 @@ def go_deps(): name = "com_github_dgraph_io_ristretto", build_file_proto_mode = "disable_global", importpath = "github.com/dgraph-io/ristretto", - sum = "h1:Wrc3UKTS+cffkOx0xRGFC+ZesNuTfn0ThvEC72N0krk=", - version = "v0.1.1-0.20220403145359-8e850b710d6d", + sum = "h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=", + version = "v0.1.1", ) go_repository( name = "com_github_dgrijalva_jwt_go", @@ -770,6 +861,14 @@ def go_deps(): sum = "h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=", version = "v1.2.0", ) + go_repository( + name = "com_github_dnephin_pflag", + build_file_proto_mode = "disable", + importpath = "github.com/dnephin/pflag", + sum = "h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk=", + version = "v1.0.7", + ) + go_repository( name = "com_github_docker_go_units", build_file_proto_mode = "disable_global", @@ -826,6 +925,21 @@ def go_deps(): sum = "h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=", version = "v1.0.0", ) + go_repository( + name = "com_github_elazarl_goproxy", + build_file_proto_mode = "disable", + importpath = "github.com/elazarl/goproxy", + sum = "h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=", + version = "v0.0.0-20180725130230-947c36da3153", + ) + go_repository( + name = "com_github_elliotchance_pie_v2", + build_file_proto_mode = "disable", + importpath = "github.com/elliotchance/pie/v2", + sum = "h1:KEVAAzxYxTyFs4hvebFZVzBdEo3YeMzl2HYDWn+P3F4=", + version = "v2.1.0", + ) + go_repository( name = "com_github_emirpasic_gods", build_file_proto_mode = "disable", @@ -838,8 +952,8 @@ def go_deps(): name = "com_github_envoyproxy_go_control_plane", build_file_proto_mode = "disable_global", importpath = "github.com/envoyproxy/go-control-plane", - sum = "h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs=", - version = "v0.9.10-0.20210907150352-cf90f659a021", + sum = "h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0=", + version = "v0.10.2-0.20220325020618-49ff273808a1", ) go_repository( name = "com_github_envoyproxy_protoc_gen_validate", @@ -881,8 +995,8 @@ def go_deps(): name = "com_github_evanphx_json_patch", build_file_proto_mode = "disable", importpath = "github.com/evanphx/json-patch", - sum = "h1:K1MDoo4AZ4wU0GIU/fPmtZg7VpzLjCxu+UwBD1FvwOc=", - version = "v4.1.0+incompatible", + sum = "h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=", + version = "v4.12.0+incompatible", ) go_repository( name = "com_github_facebookgo_clock", @@ -955,8 +1069,8 @@ def go_deps(): name = "com_github_fogleman_gg", build_file_proto_mode = "disable_global", importpath = "github.com/fogleman/gg", - sum = "h1:WXb3TSNmHp2vHoCroCIB1foO/yQ36swABL8aOVeDpgg=", - version = "v1.2.1-0.20190220221249-0403632d5b90", + sum = "h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=", + version = "v1.3.0", ) go_repository( name = "com_github_form3tech_oss_jwt_go", @@ -1036,19 +1150,34 @@ def go_deps(): sum = "h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=", version = "v1.0.0", ) + go_repository( + name = "com_github_gin_contrib_cors", + build_file_proto_mode = "disable", + importpath = "github.com/gin-contrib/cors", + sum = "h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=", + version = "v1.4.0", + ) + go_repository( + name = "com_github_gin_contrib_gzip", + build_file_proto_mode = "disable", + importpath = "github.com/gin-contrib/gzip", + sum = "h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=", + version = "v0.0.1", + ) + go_repository( name = "com_github_gin_contrib_sse", build_file_proto_mode = "disable_global", importpath = "github.com/gin-contrib/sse", - sum = "h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=", - version = "v0.0.0-20190301062529-5545eab6dad3", + sum = "h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=", + version = "v0.1.0", ) go_repository( name = "com_github_gin_gonic_gin", build_file_proto_mode = "disable_global", importpath = "github.com/gin-gonic/gin", - sum = "h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=", - version = "v1.4.0", + sum = "h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=", + version = "v1.8.1", ) go_repository( name = "com_github_go_check_check", @@ -1061,8 +1190,15 @@ def go_deps(): name = "com_github_go_critic_go_critic", build_file_proto_mode = "disable", importpath = "github.com/go-critic/go-critic", - sum = "h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E=", - version = "v0.6.4", + sum = "h1:fDaR/5GWURljXwF8Eh31T2GZNz9X4jeboS912mWF8Uo=", + version = "v0.6.5", + ) + go_repository( + name = "com_github_go_echarts_go_echarts", + build_file_proto_mode = "disable", + importpath = "github.com/go-echarts/go-echarts", + sum = "h1:n181E4iXwj4zrU9VYmdM2m8dyhERt2w9k9YhHqdp6A8=", + version = "v1.0.0", ) go_repository( @@ -1105,8 +1241,8 @@ def go_deps(): name = "com_github_go_kit_log", build_file_proto_mode = "disable_global", importpath = "github.com/go-kit/log", - sum = "h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw=", - version = "v0.2.0", + sum = "h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=", + version = "v0.2.1", ) go_repository( name = "com_github_go_logfmt_logfmt", @@ -1115,6 +1251,14 @@ def go_deps(): sum = "h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=", version = "v0.5.1", ) + go_repository( + name = "com_github_go_logr_logr", + build_file_proto_mode = "disable", + importpath = "github.com/go-logr/logr", + sum = "h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=", + version = "v1.2.3", + ) + go_repository( name = "com_github_go_martini_martini", build_file_proto_mode = "disable_global", @@ -1129,12 +1273,69 @@ def go_deps(): sum = "h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=", version = "v1.2.6", ) + go_repository( + name = "com_github_go_openapi_jsonpointer", + build_file_proto_mode = "disable", + importpath = "github.com/go-openapi/jsonpointer", + sum = "h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=", + version = "v0.19.5", + ) + go_repository( + name = "com_github_go_openapi_jsonreference", + build_file_proto_mode = "disable", + importpath = "github.com/go-openapi/jsonreference", + sum = "h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=", + version = "v0.19.6", + ) + go_repository( + name = "com_github_go_openapi_spec", + build_file_proto_mode = "disable", + importpath = "github.com/go-openapi/spec", + sum = "h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=", + version = "v0.20.4", + ) + go_repository( + name = "com_github_go_openapi_swag", + build_file_proto_mode = "disable", + importpath = "github.com/go-openapi/swag", + sum = "h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=", + version = "v0.19.15", + ) + go_repository( + name = "com_github_go_playground_locales", + build_file_proto_mode = "disable", + importpath = "github.com/go-playground/locales", + sum = "h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=", + version = "v0.14.0", + ) + go_repository( + name = "com_github_go_playground_universal_translator", + build_file_proto_mode = "disable", + importpath = "github.com/go-playground/universal-translator", + sum = "h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=", + version = "v0.18.0", + ) + go_repository( + name = "com_github_go_playground_validator_v10", + build_file_proto_mode = "disable", + importpath = "github.com/go-playground/validator/v10", + sum = "h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=", + version = "v10.10.0", + ) + go_repository( + name = "com_github_go_resty_resty_v2", + build_file_proto_mode = "disable", + importpath = "github.com/go-resty/resty/v2", + sum = "h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=", + version = "v2.6.0", + ) + go_repository( name = "com_github_go_sql_driver_mysql", build_file_proto_mode = "disable_global", importpath = "github.com/go-sql-driver/mysql", - sum = "h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=", - version = "v1.6.0", + sum = "h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=", + version = "v1.7.0", ) go_repository( name = "com_github_go_stack_stack", @@ -1161,15 +1362,15 @@ def go_deps(): name = "com_github_go_toolsmith_astcopy", build_file_proto_mode = "disable", importpath = "github.com/go-toolsmith/astcopy", - sum = "h1:l09oBhAPyV74kLJ3ZO31iBU8htZGTwr9LTjuMCyL8go=", - version = "v1.0.1", + sum = "h1:YnWf5Rnh1hUudj11kei53kI57quN/VH6Hp1n+erozn0=", + version = "v1.0.2", ) go_repository( name = "com_github_go_toolsmith_astequal", build_file_proto_mode = "disable", importpath = "github.com/go-toolsmith/astequal", - sum = "h1:+XvaV8zNxua+9+Oa4AHmgmpo4RYAbwr/qjNppLfX2yM=", - version = "v1.0.2", + sum = "h1:+LVdyRatFS+XO78SGV4I3TCEA0AC7fKEGma+fH+674o=", + version = "v1.0.3", ) go_repository( name = "com_github_go_toolsmith_astfmt", @@ -1235,6 +1436,22 @@ def go_deps(): sum = "h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=", version = "v1.0.2", ) + go_repository( + name = "com_github_goccy_go_graphviz", + build_file_proto_mode = "disable", + importpath = "github.com/goccy/go-graphviz", + sum = "h1:s/FMMJ1Joj6La3S5ApO3Jk2cwM4LpXECC2muFx3IPQQ=", + version = "v0.0.9", + ) + + go_repository( + name = "com_github_goccy_go_json", + build_file_proto_mode = "disable", + importpath = "github.com/goccy/go-json", + sum = "h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=", + version = "v0.9.11", + ) + go_repository( name = "com_github_godbus_dbus_v5", build_file_proto_mode = "disable_global", @@ -1300,6 +1517,14 @@ def go_deps(): sum = "h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=", version = "v0.0.0-20210331224755-41bb18bfe9da", ) + go_repository( + name = "com_github_golang_jwt_jwt", + build_file_proto_mode = "disable", + importpath = "github.com/golang-jwt/jwt", + sum = "h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=", + version = "v3.2.1+incompatible", + ) + go_repository( name = "com_github_golang_mock", build_file_proto_mode = "disable_global", @@ -1351,15 +1576,15 @@ def go_deps(): name = "com_github_golangci_gofmt", build_file_proto_mode = "disable", importpath = "github.com/golangci/gofmt", - sum = "h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks=", - version = "v0.0.0-20190930125516-244bba706f1a", + sum = "h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY=", + version = "v0.0.0-20220901101216-f2edd75033f2", ) go_repository( name = "com_github_golangci_golangci_lint", build_file_proto_mode = "disable", importpath = "github.com/golangci/golangci-lint", - sum = "h1:I8WHOavragDttlLHtSraHn/h39C+R60bEQ5NoGcHQr8=", - version = "v1.49.0", + sum = "h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY=", + version = "v1.50.1", ) go_repository( name = "com_github_golangci_gosec", @@ -1427,12 +1652,20 @@ def go_deps(): sum = "h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=", version = "v1.1.2", ) + go_repository( + name = "com_github_google_gnostic", + build_file_proto_mode = "disable", + importpath = "github.com/google/gnostic", + sum = "h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=", + version = "v0.5.7-v3refs", + ) + go_repository( name = "com_github_google_go_cmp", build_file_proto_mode = "disable_global", importpath = "github.com/google/go-cmp", - sum = "h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=", - version = "v0.5.8", + sum = "h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=", + version = "v0.5.9", ) go_repository( name = "com_github_google_go_querystring", @@ -1445,8 +1678,8 @@ def go_deps(): name = "com_github_google_gofuzz", build_file_proto_mode = "disable_global", importpath = "github.com/google/gofuzz", - sum = "h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=", - version = "v1.0.0", + sum = "h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=", + version = "v1.1.0", ) go_repository( name = "com_github_google_martian", @@ -1476,6 +1709,14 @@ def go_deps(): sum = "h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=", version = "v0.1.0", ) + go_repository( + name = "com_github_google_shlex", + build_file_proto_mode = "disable", + importpath = "github.com/google/shlex", + sum = "h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=", + version = "v0.0.0-20191202100458-e7afc7fbc510", + ) + go_repository( name = "com_github_google_uuid", build_file_proto_mode = "disable_global", @@ -1483,12 +1724,20 @@ def go_deps(): sum = "h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=", version = "v1.3.0", ) + go_repository( + name = "com_github_googleapis_enterprise_certificate_proxy", + build_file_proto_mode = "disable", + importpath = "github.com/googleapis/enterprise-certificate-proxy", + sum = "h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs=", + version = "v0.2.0", + ) + go_repository( name = "com_github_googleapis_gax_go_v2", build_file_proto_mode = "disable_global", importpath = "github.com/googleapis/gax-go/v2", - sum = "h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE=", - version = "v2.2.0", + sum = "h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=", + version = "v2.7.0", ) go_repository( name = "com_github_googleapis_gnostic", @@ -1497,6 +1746,14 @@ def go_deps(): sum = "h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=", version = "v0.2.0", ) + go_repository( + name = "com_github_googleapis_go_type_adapters", + build_file_proto_mode = "disable", + importpath = "github.com/googleapis/go-type-adapters", + sum = "h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=", + version = "v1.0.0", + ) + go_repository( name = "com_github_gophercloud_gophercloud", build_file_proto_mode = "disable", @@ -1631,6 +1888,13 @@ def go_deps(): sum = "h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=", version = "v0.0.0-20180507213350-8e809c8a8645", ) + go_repository( + name = "com_github_gtank_cryptopasta", + build_file_proto_mode = "disable", + importpath = "github.com/gtank/cryptopasta", + sum = "h1:7xsUJsB2NrdcttQPa7JLEaGzvdbk7KvfrjgHZXOQRo0=", + version = "v0.0.0-20170601214702-1f550f6f2f69", + ) go_repository( name = "com_github_hashicorp_consul_api", @@ -1819,8 +2083,8 @@ def go_deps(): name = "com_github_inconshreveable_mousetrap", build_file_proto_mode = "disable_global", importpath = "github.com/inconshreveable/mousetrap", - sum = "h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=", - version = "v1.0.0", + sum = "h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=", + version = "v1.0.1", ) go_repository( name = "com_github_influxdata_influxdb", @@ -1950,6 +2214,21 @@ def go_deps(): sum = "h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=", version = "v1.1.1", ) + go_repository( + name = "com_github_jinzhu_inflection", + build_file_proto_mode = "disable", + importpath = "github.com/jinzhu/inflection", + sum = "h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=", + version = "v1.0.0", + ) + go_repository( + name = "com_github_jinzhu_now", + build_file_proto_mode = "disable", + importpath = "github.com/jinzhu/now", + sum = "h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=", + version = "v1.1.2", + ) + go_repository( name = "com_github_jirfag_go_printf_func_name", build_file_proto_mode = "disable", @@ -1972,6 +2251,14 @@ def go_deps(): sum = "h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=", version = "v1.5.1", ) + go_repository( + name = "com_github_joho_godotenv", + build_file_proto_mode = "disable", + importpath = "github.com/joho/godotenv", + sum = "h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=", + version = "v1.4.0", + ) + go_repository( name = "com_github_joho_sqltocsv", build_file_proto_mode = "disable_global", @@ -2000,6 +2287,21 @@ def go_deps(): sum = "h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=", version = "v0.2.2", ) + go_repository( + name = "com_github_joomcode_errorx", + build_file_proto_mode = "disable", + importpath = "github.com/joomcode/errorx", + sum = "h1:CalpDWz14ZHd68fIqluJasJosAewpz2TFaJALrUxjrk=", + version = "v1.0.1", + ) + go_repository( + name = "com_github_josharian_intern", + build_file_proto_mode = "disable", + importpath = "github.com/josharian/intern", + sum = "h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=", + version = "v1.0.0", + ) + go_repository( name = "com_github_jpillora_backoff", build_file_proto_mode = "disable_global", @@ -2124,12 +2426,20 @@ def go_deps(): sum = "h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=", version = "v1.0.0", ) + go_repository( + name = "com_github_kkhaike_contextcheck", + build_file_proto_mode = "disable", + importpath = "github.com/kkHAIKE/contextcheck", + sum = "h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw=", + version = "v1.1.3", + ) + go_repository( name = "com_github_klauspost_compress", build_file_proto_mode = "disable_global", importpath = "github.com/klauspost/compress", - sum = "h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=", - version = "v1.15.1", + sum = "h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0=", + version = "v1.15.13", ) go_repository( name = "com_github_klauspost_cpuid", @@ -2195,6 +2505,13 @@ def go_deps(): sum = "h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g=", version = "v1.0.6", ) + go_repository( + name = "com_github_kylebanks_depth", + build_file_proto_mode = "disable", + importpath = "github.com/KyleBanks/depth", + sum = "h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=", + version = "v1.2.1", + ) go_repository( name = "com_github_kyoh86_exportloopref", @@ -2232,6 +2549,14 @@ def go_deps(): sum = "h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM=", version = "v0.3.1", ) + go_repository( + name = "com_github_leodido_go_urn", + build_file_proto_mode = "disable", + importpath = "github.com/leodido/go-urn", + sum = "h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=", + version = "v1.2.1", + ) + go_repository( name = "com_github_leonklingele_grouper", build_file_proto_mode = "disable", @@ -2239,6 +2564,49 @@ def go_deps(): sum = "h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg=", version = "v1.1.0", ) + go_repository( + name = "com_github_lestrrat_go_blackmagic", + build_file_proto_mode = "disable", + importpath = "github.com/lestrrat-go/blackmagic", + sum = "h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=", + version = "v1.0.1", + ) + go_repository( + name = "com_github_lestrrat_go_httpcc", + build_file_proto_mode = "disable", + importpath = "github.com/lestrrat-go/httpcc", + sum = "h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=", + version = "v1.0.1", + ) + go_repository( + name = "com_github_lestrrat_go_httprc", + build_file_proto_mode = "disable", + importpath = "github.com/lestrrat-go/httprc", + sum = "h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8=", + version = "v1.0.4", + ) + go_repository( + name = "com_github_lestrrat_go_iter", + build_file_proto_mode = "disable", + importpath = "github.com/lestrrat-go/iter", + sum = "h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=", + version = "v1.0.2", + ) + go_repository( + name = "com_github_lestrrat_go_jwx_v2", + build_file_proto_mode = "disable", + importpath = "github.com/lestrrat-go/jwx/v2", + sum = "h1:RlyYNLV892Ed7+FTfj1ROoF6x7WxL965PGTHso/60G0=", + version = "v2.0.6", + ) + go_repository( + name = "com_github_lestrrat_go_option", + build_file_proto_mode = "disable", + importpath = "github.com/lestrrat-go/option", + sum = "h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=", + version = "v1.0.0", + ) + go_repository( name = "com_github_lib_pq", build_file_proto_mode = "disable", @@ -2276,6 +2644,22 @@ def go_deps(): sum = "h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=", version = "v1.8.6", ) + go_repository( + name = "com_github_mailru_easyjson", + build_file_proto_mode = "disable", + importpath = "github.com/mailru/easyjson", + sum = "h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=", + version = "v0.7.6", + ) + + go_repository( + name = "com_github_maratori_testableexamples", + build_file_proto_mode = "disable", + importpath = "github.com/maratori/testableexamples", + sum = "h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=", + version = "v1.0.0", + ) + go_repository( name = "com_github_maratori_testpackage", build_file_proto_mode = "disable", @@ -2319,6 +2703,21 @@ def go_deps(): sum = "h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=", version = "v0.0.14", ) + go_repository( + name = "com_github_mattn_go_shellwords", + build_file_proto_mode = "disable", + importpath = "github.com/mattn/go-shellwords", + sum = "h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=", + version = "v1.0.12", + ) + go_repository( + name = "com_github_mattn_go_sqlite3", + build_file_proto_mode = "disable", + importpath = "github.com/mattn/go-sqlite3", + sum = "h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=", + version = "v1.14.9", + ) + go_repository( name = "com_github_mattn_goveralls", build_file_proto_mode = "disable_global", @@ -2330,8 +2729,8 @@ def go_deps(): name = "com_github_matttproud_golang_protobuf_extensions", build_file_proto_mode = "disable_global", importpath = "github.com/matttproud/golang_protobuf_extensions", - sum = "h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=", - version = "v1.0.1", + sum = "h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=", + version = "v1.0.4", ) go_repository( name = "com_github_maxatome_go_testdeep", @@ -2393,6 +2792,14 @@ def go_deps(): sum = "h1:oN9gL93BkuPrer2rehDbDx86k4zbYJEnMP6Krh82nh0=", version = "v1.1.10", ) + go_repository( + name = "com_github_minio_sio", + build_file_proto_mode = "disable", + importpath = "github.com/minio/sio", + sum = "h1:syEFBewzOMOYVzSTFpp1MqpSZk8rUNbz8VIIc+PNzus=", + version = "v0.3.0", + ) + go_repository( name = "com_github_mitchellh_cli", build_file_proto_mode = "disable_global", @@ -2458,6 +2865,13 @@ def go_deps(): sum = "h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=", version = "v1.0.1", ) + go_repository( + name = "com_github_moby_spdystream", + build_file_proto_mode = "disable", + importpath = "github.com/moby/spdystream", + sum = "h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=", + version = "v0.2.0", + ) go_repository( name = "com_github_modern_go_concurrent", @@ -2510,6 +2924,14 @@ def go_deps(): sum = "h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=", version = "v0.0.0-20190716064945-2f068394615f", ) + go_repository( + name = "com_github_mxk_go_flowrate", + build_file_proto_mode = "disable", + importpath = "github.com/mxk/go-flowrate", + sum = "h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=", + version = "v0.0.0-20140419014527-cca7078d478f", + ) + go_repository( name = "com_github_nakabonne_nestif", build_file_proto_mode = "disable", @@ -2579,8 +3001,8 @@ def go_deps(): name = "com_github_nishanths_exhaustive", build_file_proto_mode = "disable", importpath = "github.com/nishanths/exhaustive", - sum = "h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo=", - version = "v0.8.1", + sum = "h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMowvhsrM=", + version = "v0.8.3", ) go_repository( @@ -2613,6 +3035,14 @@ def go_deps(): sum = "h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=", version = "v1.3.1", ) + go_repository( + name = "com_github_oleiade_reflections", + build_file_proto_mode = "disable", + importpath = "github.com/oleiade/reflections", + sum = "h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM=", + version = "v1.0.1", + ) + go_repository( name = "com_github_olekukonko_tablewriter", build_file_proto_mode = "disable_global", @@ -2638,22 +3068,22 @@ def go_deps(): name = "com_github_onsi_ginkgo_v2", build_file_proto_mode = "disable_global", importpath = "github.com/onsi/ginkgo/v2", - sum = "h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=", - version = "v2.0.0", + sum = "h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs=", + version = "v2.4.0", ) go_repository( name = "com_github_onsi_gomega", build_file_proto_mode = "disable_global", importpath = "github.com/onsi/gomega", - sum = "h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=", - version = "v1.18.1", + sum = "h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys=", + version = "v1.23.0", ) go_repository( name = "com_github_openpeedeep_depguard", build_file_proto_mode = "disable", importpath = "github.com/OpenPeeDeeP/depguard", - sum = "h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o=", - version = "v1.1.0", + sum = "h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA=", + version = "v1.1.1", ) go_repository( @@ -2732,8 +3162,8 @@ def go_deps(): name = "com_github_pelletier_go_toml_v2", build_file_proto_mode = "disable", importpath = "github.com/pelletier/go-toml/v2", - sum = "h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw=", - version = "v2.0.2", + sum = "h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=", + version = "v2.0.5", ) go_repository( name = "com_github_peterbourgon_g2s", @@ -2746,8 +3176,8 @@ def go_deps(): name = "com_github_petermattis_goid", build_file_proto_mode = "disable", importpath = "github.com/petermattis/goid", - sum = "h1:rUMC+oZ89Om6l9wvUNjzI0ZrKrSnXzV+opsgAohYUNc=", - version = "v0.0.0-20170504144140-0ded85884ba5", + sum = "h1:64bxqeTEN0/xoEqhKGowgihNuzISS9rEG6YUMU4bzJo=", + version = "v0.0.0-20211229010228-4d14c490ee36", ) go_repository( @@ -2765,6 +3195,14 @@ def go_deps(): sum = "h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=", version = "v0.0.0-20180830031419-95f893ade6f2", ) + go_repository( + name = "com_github_phf_go_queue", + build_file_proto_mode = "disable", + importpath = "github.com/phf/go-queue", + sum = "h1:U+PMnTlV2tu7RuMK5etusZG3Cf+rpow5hqQByeCzJ2g=", + version = "v0.0.0-20170504031614-9abe38d0371d", + ) + go_repository( name = "com_github_pierrec_lz4", build_file_proto_mode = "disable_global", @@ -2776,22 +3214,30 @@ def go_deps(): name = "com_github_pingcap_badger", build_file_proto_mode = "disable_global", importpath = "github.com/pingcap/badger", - sum = "h1:MKVFZuqFvAMiDtv3AbihOQ6rY5IE8LWflI1BuZ/hF0Y=", - version = "v1.5.1-0.20220314162537-ab58fbf40580", + sum = "h1:AEcvKyVM8CUII3bYzgz8haFXtGiqcrtXW1csu/5UELY=", + version = "v1.5.1-0.20230103063557-828f39b09b6d", ) go_repository( name = "com_github_pingcap_check", build_file_proto_mode = "disable_global", importpath = "github.com/pingcap/check", - sum = "h1:iRtOAQ6FXkY/BGvst3CDfTva4nTqh6CL8WXvanLdbu0=", - version = "v0.0.0-20191107115940-caf2b9e6ccf4", + sum = "h1:R8gStypOBmpnHEx1qi//SaqxJVI4inOqljg/Aj5/390=", + version = "v0.0.0-20200212061837-5e12011dc712", + ) + go_repository( + name = "com_github_pingcap_errcode", + build_file_proto_mode = "disable", + importpath = "github.com/pingcap/errcode", + sum = "h1:IF6LC/4+b1KNwrMlr2rBTUrojFPMexXBcDWZSpNwxjg=", + version = "v0.3.0", ) + go_repository( name = "com_github_pingcap_errors", build_file_proto_mode = "disable_global", importpath = "github.com/pingcap/errors", - sum = "h1:3Dm0DWeQlwV8LbpQxP2tojHhxd9aY59KI+QN0ns6bBo=", - version = "v0.11.5-0.20220729040631-518f63d66278", + sum = "h1:m5ZsBa5o/0CkzZXfXLaThzKuR85SnHHetqBCpzQ30h8=", + version = "v0.11.5-0.20221009092201-b66cddb77c32", ) go_repository( name = "com_github_pingcap_failpoint", @@ -2818,15 +3264,15 @@ def go_deps(): name = "com_github_pingcap_kvproto", build_file_proto_mode = "disable_global", importpath = "github.com/pingcap/kvproto", - sum = "h1:ceg4xjEEXNgPsScTQ5dtidiltLF4h17Y/jUqfyLAy9E=", - version = "v0.0.0-20220929075948-06e08d5ed64c", + sum = "h1:LB+BrfyO5fsz5pwN3V4HvTrpZTAmsjB4VkCEBLbjYUw=", + version = "v0.0.0-20230119031034-25f1909b7934", ) go_repository( name = "com_github_pingcap_log", build_file_proto_mode = "disable_global", importpath = "github.com/pingcap/log", - sum = "h1:ELiPxACz7vdo1qAvvaWJg1NrYFoY6gqAh/+Uo6aXdD8=", - version = "v1.1.0", + sum = "h1:crhkw6DD+07Bg1wYhW5Piw+kYNKZqFQqfC2puUf6gMI=", + version = "v1.1.1-0.20221116035753-734d527bc87c", ) go_repository( name = "com_github_pingcap_sysutil", @@ -2835,12 +3281,20 @@ def go_deps(): sum = "h1:HYbcxtnkN3s5tqrZ/z3eJS4j3Db8wMphEm1q10lY/TM=", version = "v0.0.0-20220114020952-ea68d2dbf5b4", ) + go_repository( + name = "com_github_pingcap_tidb_dashboard", + build_file_proto_mode = "disable", + importpath = "github.com/pingcap/tidb-dashboard", + sum = "h1:FUdoQ6zWktVjIWLokNeulEcqIzGn6TnoOjdS9bQcFUo=", + version = "v0.0.0-20221201151320-ea3ee6971f2e", + ) + go_repository( name = "com_github_pingcap_tipb", build_file_proto_mode = "disable_global", importpath = "github.com/pingcap/tipb", - sum = "h1:kWYridgsn8xSKYJ2EkXp7uj5HwJnG5snpY3XP8oYmPU=", - version = "v0.0.0-20220824081009-0714a57aff1d", + sum = "h1:j5sw2YZY7QfgIFZEoUcn1P5cYflms1PCVVS96i+IQiI=", + version = "v0.0.0-20230119054146-c6b7a5a1623b", ) go_repository( name = "com_github_pkg_browser", @@ -2874,8 +3328,8 @@ def go_deps(): name = "com_github_polyfloyd_go_errorlint", build_file_proto_mode = "disable", importpath = "github.com/polyfloyd/go-errorlint", - sum = "h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk=", - version = "v1.0.2", + sum = "h1:AHB5JRCjlmelh9RrLxT9sgzpalIwwq4hqE8EkwIwKdY=", + version = "v1.0.5", ) go_repository( @@ -2896,29 +3350,29 @@ def go_deps(): name = "com_github_prometheus_client_golang", build_file_proto_mode = "disable_global", importpath = "github.com/prometheus/client_golang", - sum = "h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=", - version = "v1.13.0", + sum = "h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=", + version = "v1.14.0", ) go_repository( name = "com_github_prometheus_client_model", build_file_proto_mode = "disable_global", importpath = "github.com/prometheus/client_model", - sum = "h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=", - version = "v0.2.0", + sum = "h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=", + version = "v0.3.0", ) go_repository( name = "com_github_prometheus_common", build_file_proto_mode = "disable_global", importpath = "github.com/prometheus/common", - sum = "h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=", - version = "v0.37.0", + sum = "h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI=", + version = "v0.39.0", ) go_repository( name = "com_github_prometheus_procfs", build_file_proto_mode = "disable_global", importpath = "github.com/prometheus/procfs", - sum = "h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=", - version = "v0.8.0", + sum = "h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=", + version = "v0.9.0", ) go_repository( name = "com_github_prometheus_prometheus", @@ -2935,12 +3389,27 @@ def go_deps(): sum = "h1:w1tAGxsBMLkuGrFMhqgcCeBkM5d1YI24udArs+aASuQ=", version = "v0.8.0", ) + go_repository( + name = "com_github_puerkitobio_purell", + build_file_proto_mode = "disable", + importpath = "github.com/PuerkitoBio/purell", + sum = "h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=", + version = "v1.1.1", + ) + go_repository( + name = "com_github_puerkitobio_urlesc", + build_file_proto_mode = "disable", + importpath = "github.com/PuerkitoBio/urlesc", + sum = "h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=", + version = "v0.0.0-20170810143723-de5bf2ad4578", + ) + go_repository( name = "com_github_quasilyte_go_ruleguard", build_file_proto_mode = "disable", importpath = "github.com/quasilyte/go-ruleguard", - sum = "h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI=", - version = "v0.3.17", + sum = "h1:sd+abO1PEI9fkYennwzHn9kl3nqP6M5vE7FiOzZ+5CE=", + version = "v0.3.18", ) go_repository( name = "com_github_quasilyte_go_ruleguard_dsl", @@ -2953,8 +3422,8 @@ def go_deps(): name = "com_github_quasilyte_gogrep", build_file_proto_mode = "disable", importpath = "github.com/quasilyte/gogrep", - sum = "h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8=", - version = "v0.0.0-20220120141003-628d8b3623b5", + sum = "h1:6Gtn2i04RD0gVyYf2/IUMTIs+qYleBt4zxDqkLTcu4U=", + version = "v0.0.0-20220828223005-86e4605de09f", ) go_repository( name = "com_github_quasilyte_regex_syntax", @@ -2985,6 +3454,14 @@ def go_deps(): sum = "h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=", version = "v0.0.0-20200410134404-eec4a21b6bb0", ) + go_repository( + name = "com_github_renekroon_ttlcache_v2", + build_file_proto_mode = "disable", + importpath = "github.com/ReneKroon/ttlcache/v2", + sum = "h1:qZnUjRKIrbKHH6vF5T7Y9Izn5ObfTZfyYpGhvz2BKPo=", + version = "v2.3.0", + ) + go_repository( name = "com_github_rivo_uniseg", build_file_proto_mode = "disable_global", @@ -3018,6 +3495,14 @@ def go_deps(): sum = "h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=", version = "v1.6.1", ) + go_repository( + name = "com_github_rs_cors", + build_file_proto_mode = "disable", + importpath = "github.com/rs/cors", + sum = "h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=", + version = "v1.7.0", + ) + go_repository( name = "com_github_rubyist_circuitbreaker", build_file_proto_mode = "disable", @@ -3081,8 +3566,8 @@ def go_deps(): name = "com_github_sasha_s_go_deadlock", build_file_proto_mode = "disable", importpath = "github.com/sasha-s/go-deadlock", - sum = "h1:yVBZEAirqhDYAc7xftf/swe8eHcg63jqfwdqN8KSoR8=", - version = "v0.0.0-20161201235124-341000892f3d", + sum = "h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y=", + version = "v0.2.0", ) go_repository( name = "com_github_sashamelentyev_interfacebloat", @@ -3095,8 +3580,8 @@ def go_deps(): name = "com_github_sashamelentyev_usestdlibvars", build_file_proto_mode = "disable", importpath = "github.com/sashamelentyev/usestdlibvars", - sum = "h1:uObNudVEEHf6JbOJy5bgKJloA1bWjxR9fwgNFpPzKnI=", - version = "v1.13.0", + sum = "h1:K6CXjqqtSYSsuyRDDC7Sjn6vTMLiSJa4ZmDkiokoqtw=", + version = "v1.20.0", ) go_repository( @@ -3143,13 +3628,20 @@ def go_deps(): sum = "h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=", version = "v0.0.0-20160112020656-b6b7b6733b8c", ) + go_repository( + name = "com_github_shirou_gopsutil", + build_file_proto_mode = "disable", + importpath = "github.com/shirou/gopsutil", + sum = "h1:uenXGGa8ESCQq+dbgtl916dmg6PSAz2cXov0uORQ9v8=", + version = "v3.21.3+incompatible", + ) go_repository( name = "com_github_shirou_gopsutil_v3", build_file_proto_mode = "disable_global", importpath = "github.com/shirou/gopsutil/v3", - sum = "h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4=", - version = "v3.22.7", + sum = "h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=", + version = "v3.22.9", ) go_repository( name = "com_github_shopify_goreferrer", @@ -3205,8 +3697,8 @@ def go_deps(): name = "com_github_shurcool_vfsgen", build_file_proto_mode = "disable_global", importpath = "github.com/shurcooL/vfsgen", - sum = "h1:y0cMJ0qjii33BnD6tMGcF/+gHYsoKQ6tbwQpy233OII=", - version = "v0.0.0-20180711163814-62bca832be04", + sum = "h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=", + version = "v0.0.0-20181202132449-6a9ea43bcacd", ) go_repository( name = "com_github_sirupsen_logrus", @@ -3237,6 +3729,13 @@ def go_deps(): sum = "h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE=", version = "v1.7.0", ) + go_repository( + name = "com_github_smallnest_chanx", + build_file_proto_mode = "disable", + importpath = "github.com/smallnest/chanx", + sum = "h1:Txo4SXVJq/OgEjwgkWoxkMoTjGlcrgsQE/XSghjmu0w=", + version = "v0.0.0-20221229104322-eb4c998d2072", + ) go_repository( name = "com_github_smartystreets_assertions", @@ -3278,8 +3777,8 @@ def go_deps(): name = "com_github_spaolacci_murmur3", build_file_proto_mode = "disable_global", importpath = "github.com/spaolacci/murmur3", - sum = "h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=", - version = "v0.0.0-20180118202830-f09979ecbc72", + sum = "h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=", + version = "v1.1.0", ) go_repository( name = "com_github_spf13_afero", @@ -3299,8 +3798,8 @@ def go_deps(): name = "com_github_spf13_cobra", build_file_proto_mode = "disable_global", importpath = "github.com/spf13/cobra", - sum = "h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=", - version = "v1.5.0", + sum = "h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=", + version = "v1.6.1", ) go_repository( name = "com_github_spf13_jwalterweatherman", @@ -3334,8 +3833,8 @@ def go_deps(): name = "com_github_stackexchange_wmi", build_file_proto_mode = "disable", importpath = "github.com/StackExchange/wmi", - sum = "h1:5ZfJxyXo8KyX8DgGXC5B7ILL8y51fci/qYz2B4j8iLY=", - version = "v0.0.0-20180725035823-b12b22c5341f", + sum = "h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=", + version = "v0.0.0-20190523213315-cbe66965904d", ) go_repository( @@ -3357,23 +3856,45 @@ def go_deps(): name = "com_github_stretchr_objx", build_file_proto_mode = "disable_global", importpath = "github.com/stretchr/objx", - sum = "h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=", - version = "v0.4.0", + sum = "h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=", + version = "v0.5.0", ) go_repository( name = "com_github_stretchr_testify", build_file_proto_mode = "disable_global", importpath = "github.com/stretchr/testify", - sum = "h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=", - version = "v1.8.0", + sum = "h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=", + version = "v1.8.1", ) go_repository( name = "com_github_subosito_gotenv", build_file_proto_mode = "disable_global", importpath = "github.com/subosito/gotenv", - sum = "h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=", - version = "v1.4.0", + sum = "h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=", + version = "v1.4.1", + ) + go_repository( + name = "com_github_swaggo_files", + build_file_proto_mode = "disable", + importpath = "github.com/swaggo/files", + sum = "h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=", + version = "v0.0.0-20190704085106-630677cd5c14", + ) + go_repository( + name = "com_github_swaggo_http_swagger", + build_file_proto_mode = "disable", + importpath = "github.com/swaggo/http-swagger", + sum = "h1:lUPlXKqgbqT2SVg2Y+eT9mu5wbqMnG+i/+Q9nK7C0Rs=", + version = "v0.0.0-20200308142732-58ac5e232fba", + ) + go_repository( + name = "com_github_swaggo_swag", + build_file_proto_mode = "disable", + importpath = "github.com/swaggo/swag", + sum = "h1:3pZSSCQ//gAH88lfmxM3Cd1+JCsxV8Md6f36b9hrZ5s=", + version = "v1.8.3", ) + go_repository( name = "com_github_sylvia7788_contextcheck", build_file_proto_mode = "disable", @@ -3381,6 +3902,14 @@ def go_deps(): sum = "h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4=", version = "v1.0.6", ) + go_repository( + name = "com_github_syndtr_goleveldb", + build_file_proto_mode = "disable", + importpath = "github.com/syndtr/goleveldb", + sum = "h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw=", + version = "v1.0.1-0.20190318030020-c3a204f8e965", + ) + go_repository( name = "com_github_tdakkota_asciicheck", build_file_proto_mode = "disable", @@ -3410,6 +3939,13 @@ def go_deps(): sum = "h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw=", version = "v1.4.11", ) + go_repository( + name = "com_github_thoas_go_funk", + build_file_proto_mode = "disable", + importpath = "github.com/thoas/go-funk", + sum = "h1:JP9tKSvnpFVclYgDM0Is7FD9M4fhPvqA0s0BsXmzSRQ=", + version = "v0.8.0", + ) go_repository( name = "com_github_tiancaiamao_appdash", @@ -3418,19 +3954,42 @@ def go_deps(): sum = "h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ=", version = "v0.0.0-20181126055449-889f96f722a2", ) + go_repository( + name = "com_github_tiancaiamao_gp", + build_file_proto_mode = "disable", + importpath = "github.com/tiancaiamao/gp", + sum = "h1:J/YdBZ46WKpXsxsW93SG+q0F8KI+yFrcIDT4c/RNoc4=", + version = "v0.0.0-20221230034425-4025bc8a4d4a", + ) + go_repository( + name = "com_github_tidwall_gjson", + build_file_proto_mode = "disable", + importpath = "github.com/tidwall/gjson", + sum = "h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E=", + version = "v1.9.3", + ) + go_repository( name = "com_github_tikv_client_go_v2", build_file_proto_mode = "disable_global", importpath = "github.com/tikv/client-go/v2", - sum = "h1:/13jzD/AR7v3dCLweFQ2JG8bihh3HLVIci2tbOHHGW0=", - version = "v2.0.1-0.20221012074856-6def8d7b90c4", + sum = "h1:2BmijiUk1Hcv0z58DVk4ypwaNmgutzLc2YJm0SHPEWE=", + version = "v2.0.5-0.20230120021435-f89383775234", ) + go_repository( + name = "com_github_tikv_pd", + build_file_proto_mode = "disable", + importpath = "github.com/tikv/pd", + sum = "h1:cj3bhdIBJcLL2304EDEmd3eX+r73+hbGSYRFn/APiDU=", + version = "v1.1.0-beta.0.20230119114149-402c2bfee2f3", + ) + go_repository( name = "com_github_tikv_pd_client", build_file_proto_mode = "disable_global", importpath = "github.com/tikv/pd/client", - sum = "h1:REQOR1XraH1fT9BCoNBPZs1CAe+w7VPLU+d+si7DLYo=", - version = "v0.0.0-20221010134149-d50e5fe43f14", + sum = "h1:KK5bx0KLcpYUCnuQ06THPYT6QdAMfvwAtRQ0saVGD7k=", + version = "v0.0.0-20230119115149-5c518d079b93", ) go_repository( name = "com_github_timakin_bodyclose", @@ -3439,6 +3998,14 @@ def go_deps(): sum = "h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro=", version = "v0.0.0-20210704033933-f49887972144", ) + go_repository( + name = "com_github_timonwong_loggercheck", + build_file_proto_mode = "disable", + importpath = "github.com/timonwong/loggercheck", + sum = "h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI=", + version = "v0.9.3", + ) + go_repository( name = "com_github_timonwong_logrlint", build_file_proto_mode = "disable", @@ -3472,15 +4039,15 @@ def go_deps(): name = "com_github_tomarrell_wrapcheck_v2", build_file_proto_mode = "disable", importpath = "github.com/tomarrell/wrapcheck/v2", - sum = "h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M=", - version = "v2.6.2", + sum = "h1:J/F8DbSKJC83bAvC6FoZaRjZiZ/iKoueSdrEkmGeacA=", + version = "v2.7.0", ) go_repository( name = "com_github_tommy_muehle_go_mnd_v2", build_file_proto_mode = "disable", importpath = "github.com/tommy-muehle/go-mnd/v2", - sum = "h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s=", - version = "v2.5.0", + sum = "h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=", + version = "v2.5.1", ) go_repository( @@ -3515,8 +4082,8 @@ def go_deps(): name = "com_github_ugorji_go_codec", build_file_proto_mode = "disable_global", importpath = "github.com/ugorji/go/codec", - sum = "h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=", - version = "v0.0.0-20181204163529-d75b2dcb6bc8", + sum = "h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=", + version = "v1.2.7", ) go_repository( name = "com_github_ultraware_funlen", @@ -3532,6 +4099,20 @@ def go_deps(): sum = "h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI=", version = "v0.0.5", ) + go_repository( + name = "com_github_unrolled_render", + build_file_proto_mode = "disable", + importpath = "github.com/unrolled/render", + sum = "h1:VDDnQQVfBMsOsp3VaCJszSO0nkBIVEYoPWeRThk9spY=", + version = "v1.0.1", + ) + go_repository( + name = "com_github_urfave_cli_v2", + build_file_proto_mode = "disable", + importpath = "github.com/urfave/cli/v2", + sum = "h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=", + version = "v2.3.0", + ) go_repository( name = "com_github_urfave_negroni", @@ -3584,13 +4165,43 @@ def go_deps(): sum = "h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=", version = "v0.0.0-20161114210144-ceec8f93295a", ) + go_repository( + name = "com_github_vbauerster_mpb_v7", + build_file_proto_mode = "disable", + importpath = "github.com/vbauerster/mpb/v7", + sum = "h1:BkGfmb6nMrrBQDFECR/Q7RkKCw7ylMetCb4079CGs4w=", + version = "v7.5.3", + ) + go_repository( name = "com_github_vividcortex_ewma", build_file_proto_mode = "disable_global", importpath = "github.com/VividCortex/ewma", - sum = "h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=", - version = "v1.1.1", + sum = "h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=", + version = "v1.2.0", + ) + go_repository( + name = "com_github_vividcortex_mysqlerr", + build_file_proto_mode = "disable", + importpath = "github.com/VividCortex/mysqlerr", + sum = "h1:5pZ2TZA+YnzPgzBfiUWGqWmKDVNBdrkf9g+DNe1Tiq8=", + version = "v1.0.0", ) + go_repository( + name = "com_github_vmihailenco_msgpack_v5", + build_file_proto_mode = "disable", + importpath = "github.com/vmihailenco/msgpack/v5", + sum = "h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=", + version = "v5.3.5", + ) + go_repository( + name = "com_github_vmihailenco_tagparser_v2", + build_file_proto_mode = "disable", + importpath = "github.com/vmihailenco/tagparser/v2", + sum = "h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=", + version = "v2.0.0", + ) + go_repository( name = "com_github_wangjohn_quickselect", build_file_proto_mode = "disable_global", @@ -3633,6 +4244,14 @@ def go_deps(): sum = "h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=", version = "v1.2.0", ) + go_repository( + name = "com_github_xeoncross_go_aesctr_with_hmac", + build_file_proto_mode = "disable", + importpath = "github.com/Xeoncross/go-aesctr-with-hmac", + sum = "h1:L8IbaI/W6h5Cwgh0n4zGeZpVK78r/jBf9ASurHo9+/o=", + version = "v0.0.0-20200623134604-12b17a7ff502", + ) + go_repository( name = "com_github_xiang90_probing", build_file_proto_mode = "disable_global", @@ -3731,151 +4350,960 @@ def go_deps(): name = "com_google_cloud_go", build_file_proto_mode = "disable_global", importpath = "cloud.google.com/go", - sum = "h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=", - version = "v0.100.2", + sum = "h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=", + version = "v0.105.0", ) go_repository( - name = "com_google_cloud_go_bigquery", - build_file_proto_mode = "disable_global", - importpath = "cloud.google.com/go/bigquery", - sum = "h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA=", - version = "v1.8.0", + name = "com_google_cloud_go_accessapproval", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/accessapproval", + sum = "h1:/nTivgnV/n1CaAeo+ekGexTYUsKEU9jUVkoY5359+3Q=", + version = "v1.5.0", ) go_repository( - name = "com_google_cloud_go_compute", - build_file_proto_mode = "disable_global", - importpath = "cloud.google.com/go/compute", - sum = "h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=", - version = "v1.5.0", + name = "com_google_cloud_go_accesscontextmanager", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/accesscontextmanager", + sum = "h1:CFhNhU7pcD11cuDkQdrE6PQJgv0EXNKNv06jIzbLlCU=", + version = "v1.4.0", ) go_repository( - name = "com_google_cloud_go_datastore", - build_file_proto_mode = "disable_global", - importpath = "cloud.google.com/go/datastore", - sum = "h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=", - version = "v1.1.0", + name = "com_google_cloud_go_aiplatform", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/aiplatform", + sum = "h1:DBi3Jk9XjCJ4pkkLM4NqKgj3ozUL1wq4l+d3/jTGXAI=", + version = "v1.27.0", ) go_repository( - name = "com_google_cloud_go_firestore", - build_file_proto_mode = "disable_global", - importpath = "cloud.google.com/go/firestore", - sum = "h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY=", - version = "v1.1.0", + name = "com_google_cloud_go_analytics", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/analytics", + sum = "h1:NKw6PpQi6V1O+KsjuTd+bhip9d0REYu4NevC45vtGp8=", + version = "v0.12.0", ) go_repository( - name = "com_google_cloud_go_iam", - build_file_proto_mode = "disable_global", - importpath = "cloud.google.com/go/iam", - sum = "h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68=", - version = "v0.1.1", + name = "com_google_cloud_go_apigateway", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/apigateway", + sum = "h1:IIoXKR7FKrEAQhMTz5hK2wiDz2WNFHS7eVr/L1lE/rM=", + version = "v1.4.0", ) go_repository( - name = "com_google_cloud_go_pubsub", - build_file_proto_mode = "disable_global", - importpath = "cloud.google.com/go/pubsub", - sum = "h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=", - version = "v1.3.1", + name = "com_google_cloud_go_apigeeconnect", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/apigeeconnect", + sum = "h1:AONoTYJviyv1vS4IkvWzq69gEVdvHx35wKXc+e6wjZQ=", + version = "v1.4.0", ) go_repository( - name = "com_google_cloud_go_storage", - build_file_proto_mode = "disable_global", - importpath = "cloud.google.com/go/storage", - sum = "h1:HwnT2u2D309SFDHQII6m18HlrCi3jAXhUMTLOWXYH14=", - version = "v1.21.0", + name = "com_google_cloud_go_appengine", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/appengine", + sum = "h1:lmG+O5oaR9xNwaRBwE2XoMhwQHsHql5IoiGr1ptdDwU=", + version = "v1.5.0", ) go_repository( - name = "com_shuralyov_dmitri_gpu_mtl", - build_file_proto_mode = "disable_global", - importpath = "dmitri.shuralyov.com/gpu/mtl", - sum = "h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=", - version = "v0.0.0-20190408044501-666a987793e9", + name = "com_google_cloud_go_area120", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/area120", + sum = "h1:TCMhwWEWhCn8d44/Zs7UCICTWje9j3HuV6nVGMjdpYw=", + version = "v0.6.0", ) go_repository( - name = "com_sourcegraph_sourcegraph_appdash", - build_file_proto_mode = "disable_global", - importpath = "sourcegraph.com/sourcegraph/appdash", - sum = "h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM=", - version = "v0.0.0-20190731080439-ebfcffb1b5c0", + name = "com_google_cloud_go_artifactregistry", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/artifactregistry", + sum = "h1:3d0LRAU1K6vfqCahhl9fx2oGHcq+s5gftdix4v8Ibrc=", + version = "v1.9.0", ) go_repository( - name = "com_sourcegraph_sourcegraph_appdash_data", - build_file_proto_mode = "disable_global", - importpath = "sourcegraph.com/sourcegraph/appdash-data", - sum = "h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI=", - version = "v0.0.0-20151005221446-73f23eafcf67", + name = "com_google_cloud_go_asset", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/asset", + sum = "h1:aCrlaLGJWTODJX4G56ZYzJefITKEWNfbjjtHSzWpxW0=", + version = "v1.10.0", ) go_repository( - name = "com_stathat_c_consistent", + name = "com_google_cloud_go_assuredworkloads", build_file_proto_mode = "disable", - importpath = "stathat.com/c/consistent", - sum = "h1:ezyc51EGcRPJUxfHGSgJjWzJdj3NiMU9pNfLNGiXV0c=", - version = "v1.0.0", + importpath = "cloud.google.com/go/assuredworkloads", + sum = "h1:hhIdCOowsT1GG5eMCIA0OwK6USRuYTou/1ZeNxCSRtA=", + version = "v1.9.0", ) - go_repository( - name = "in_gopkg_alecthomas_kingpin_v2", - build_file_proto_mode = "disable_global", - importpath = "gopkg.in/alecthomas/kingpin.v2", - sum = "h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=", - version = "v2.2.6", + name = "com_google_cloud_go_automl", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/automl", + sum = "h1:BMioyXSbg7d7xLibn47cs0elW6RT780IUWr42W8rp2Q=", + version = "v1.8.0", ) go_repository( - name = "in_gopkg_check_v1", - build_file_proto_mode = "disable_global", - importpath = "gopkg.in/check.v1", - sum = "h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=", - version = "v1.0.0-20201130134442-10cb98267c6c", + name = "com_google_cloud_go_baremetalsolution", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/baremetalsolution", + sum = "h1:g9KO6SkakcYPcc/XjAzeuUrEOXlYPnMpuiaywYaGrmQ=", + version = "v0.4.0", ) go_repository( - name = "in_gopkg_errgo_v2", - build_file_proto_mode = "disable_global", - importpath = "gopkg.in/errgo.v2", - sum = "h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=", - version = "v2.1.0", + name = "com_google_cloud_go_batch", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/batch", + sum = "h1:1jvEBY55OH4Sd2FxEXQfxGExFWov1A/IaRe+Z5Z71Fw=", + version = "v0.4.0", ) go_repository( - name = "in_gopkg_fsnotify_fsnotify_v1", + name = "com_google_cloud_go_beyondcorp", build_file_proto_mode = "disable", - importpath = "gopkg.in/fsnotify/fsnotify.v1", - sum = "h1:2fkCHbPQZNYRAyRyIV9VX0bpRkxIorlQDiYRmufHnhA=", - version = "v1.3.1", + importpath = "cloud.google.com/go/beyondcorp", + sum = "h1:w+4kThysgl0JiKshi2MKDCg2NZgOyqOI0wq2eBZyrzA=", + version = "v0.3.0", ) go_repository( - name = "in_gopkg_fsnotify_v1", + name = "com_google_cloud_go_bigquery", build_file_proto_mode = "disable_global", - importpath = "gopkg.in/fsnotify.v1", - sum = "h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=", - version = "v1.4.7", + importpath = "cloud.google.com/go/bigquery", + sum = "h1:Wi4dITi+cf9VYp4VH2T9O41w0kCW0uQTELq2Z6tukN0=", + version = "v1.44.0", ) go_repository( - name = "in_gopkg_go_playground_assert_v1", - build_file_proto_mode = "disable_global", - importpath = "gopkg.in/go-playground/assert.v1", - sum = "h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=", - version = "v1.2.1", + name = "com_google_cloud_go_billing", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/billing", + sum = "h1:Xkii76HWELHwBtkQVZvqmSo9GTr0O+tIbRNnMcGdlg4=", + version = "v1.7.0", ) go_repository( - name = "in_gopkg_go_playground_validator_v8", - build_file_proto_mode = "disable_global", - importpath = "gopkg.in/go-playground/validator.v8", - sum = "h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=", - version = "v8.18.2", + name = "com_google_cloud_go_binaryauthorization", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/binaryauthorization", + sum = "h1:pL70vXWn9TitQYXBWTK2abHl2JHLwkFRjYw6VflRqEA=", + version = "v1.4.0", ) go_repository( - name = "in_gopkg_inf_v0", + name = "com_google_cloud_go_certificatemanager", build_file_proto_mode = "disable", - importpath = "gopkg.in/inf.v0", - sum = "h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=", - version = "v0.9.1", + importpath = "cloud.google.com/go/certificatemanager", + sum = "h1:tzbR4UHBbgsewMWUD93JHi8EBi/gHBoSAcY1/sThFGk=", + version = "v1.4.0", ) - go_repository( - name = "in_gopkg_ini_v1", - build_file_proto_mode = "disable_global", - importpath = "gopkg.in/ini.v1", - sum = "h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI=", - version = "v1.66.6", + name = "com_google_cloud_go_channel", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/channel", + sum = "h1:pNuUlZx0Jb0Ts9P312bmNMuH5IiFWIR4RUtLb70Ke5s=", + version = "v1.9.0", + ) + go_repository( + name = "com_google_cloud_go_cloudbuild", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/cloudbuild", + sum = "h1:TAAmCmAlOJ4uNBu6zwAjwhyl/7fLHHxIEazVhr3QBbQ=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_clouddms", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/clouddms", + sum = "h1:UhzHIlgFfMr6luVYVNydw/pl9/U5kgtjCMJHnSvoVws=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_cloudtasks", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/cloudtasks", + sum = "h1:faUiUgXjW8yVZ7XMnKHKm1WE4OldPBUWWfIRN/3z1dc=", + version = "v1.8.0", + ) + + go_repository( + name = "com_google_cloud_go_compute", + build_file_proto_mode = "disable_global", + importpath = "cloud.google.com/go/compute", + sum = "h1:AYrLkB8NPdDRslNp4Jxmzrhdr03fUAIDbiGFjLWowoU=", + version = "v1.13.0", + ) + go_repository( + name = "com_google_cloud_go_compute_metadata", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/compute/metadata", + sum = "h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48=", + version = "v0.2.1", + ) + go_repository( + name = "com_google_cloud_go_contactcenterinsights", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/contactcenterinsights", + sum = "h1:tTQLI/ZvguUf9Hv+36BkG2+/PeC8Ol1q4pBW+tgCx0A=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_container", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/container", + sum = "h1:nbEK/59GyDRKKlo1SqpohY1TK8LmJ2XNcvS9Gyom2A0=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_containeranalysis", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/containeranalysis", + sum = "h1:2824iym832ljKdVpCBnpqm5K94YT/uHTVhNF+dRTXPI=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_datacatalog", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/datacatalog", + sum = "h1:6kZ4RIOW/uT7QWC5SfPfq/G8sYzr/v+UOmOAxy4Z1TE=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_dataflow", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/dataflow", + sum = "h1:CW3541Fm7KPTyZjJdnX6NtaGXYFn5XbFC5UcjgALKvU=", + version = "v0.7.0", + ) + go_repository( + name = "com_google_cloud_go_dataform", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/dataform", + sum = "h1:vLwowLF2ZB5J5gqiZCzv076lDI/Rd7zYQQFu5XO1PSg=", + version = "v0.5.0", + ) + go_repository( + name = "com_google_cloud_go_datafusion", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/datafusion", + sum = "h1:j5m2hjWovTZDTQak4MJeXAR9yN7O+zMfULnjGw/OOLg=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_datalabeling", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/datalabeling", + sum = "h1:dp8jOF21n/7jwgo/uuA0RN8hvLcKO4q6s/yvwevs2ZM=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_dataplex", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/dataplex", + sum = "h1:cNxeA2DiWliQGi21kPRqnVeQ5xFhNoEjPRt1400Pm8Y=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_dataproc", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/dataproc", + sum = "h1:gVOqNmElfa6n/ccG/QDlfurMWwrK3ezvy2b2eDoCmS0=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_dataqna", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/dataqna", + sum = "h1:gx9jr41ytcA3dXkbbd409euEaWtofCVXYBvJz3iYm18=", + version = "v0.6.0", + ) + + go_repository( + name = "com_google_cloud_go_datastore", + build_file_proto_mode = "disable_global", + importpath = "cloud.google.com/go/datastore", + sum = "h1:4siQRf4zTiAVt/oeH4GureGkApgb2vtPQAtOmhpqQwE=", + version = "v1.10.0", + ) + go_repository( + name = "com_google_cloud_go_datastream", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/datastream", + sum = "h1:PgIgbhedBtYBU6POGXFMn2uSl9vpqubc3ewTNdcU8Mk=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_deploy", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/deploy", + sum = "h1:kI6dxt8Ml0is/x7YZjLveTvR7YPzXAUD/8wQZ2nH5zA=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_dialogflow", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/dialogflow", + sum = "h1:HYHVOkoxQ9bSfNIelSZYNAtUi4CeSrCnROyOsbOqPq8=", + version = "v1.19.0", + ) + go_repository( + name = "com_google_cloud_go_dlp", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/dlp", + sum = "h1:9I4BYeJSVKoSKgjr70fLdRDumqcUeVmHV4fd5f9LR6Y=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_documentai", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/documentai", + sum = "h1:jfq09Fdjtnpnmt/MLyf6A3DM3ynb8B2na0K+vSXvpFM=", + version = "v1.10.0", + ) + go_repository( + name = "com_google_cloud_go_domains", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/domains", + sum = "h1:pu3JIgC1rswIqi5romW0JgNO6CTUydLYX8zyjiAvO1c=", + version = "v0.7.0", + ) + go_repository( + name = "com_google_cloud_go_edgecontainer", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/edgecontainer", + sum = "h1:hd6J2n5dBBRuAqnNUEsKWrp6XNPKsaxwwIyzOPZTokk=", + version = "v0.2.0", + ) + go_repository( + name = "com_google_cloud_go_errorreporting", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/errorreporting", + sum = "h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0=", + version = "v0.3.0", + ) + go_repository( + name = "com_google_cloud_go_essentialcontacts", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/essentialcontacts", + sum = "h1:b6csrQXCHKQmfo9h3dG/pHyoEh+fQG1Yg78a53LAviY=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_eventarc", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/eventarc", + sum = "h1:AgCqrmMMIcel5WWKkzz5EkCUKC3Rl5LNMMYsS+LvsI0=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_filestore", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/filestore", + sum = "h1:yjKOpzvqtDmL5AXbKttLc8j0hL20kuC1qPdy5HPcxp0=", + version = "v1.4.0", + ) + + go_repository( + name = "com_google_cloud_go_firestore", + build_file_proto_mode = "disable_global", + importpath = "cloud.google.com/go/firestore", + sum = "h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA=", + version = "v1.9.0", + ) + go_repository( + name = "com_google_cloud_go_functions", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/functions", + sum = "h1:35tgv1fQOtvKqH/uxJMzX3w6usneJ0zXpsFr9KAVhNE=", + version = "v1.9.0", + ) + go_repository( + name = "com_google_cloud_go_gaming", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/gaming", + sum = "h1:97OAEQtDazAJD7yh/kvQdSCQuTKdR0O+qWAJBZJ4xiA=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_gkebackup", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/gkebackup", + sum = "h1:4K+jiv4ocqt1niN8q5Imd8imRoXBHTrdnJVt/uFFxF4=", + version = "v0.3.0", + ) + go_repository( + name = "com_google_cloud_go_gkeconnect", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/gkeconnect", + sum = "h1:zAcvDa04tTnGdu6TEZewaLN2tdMtUOJJ7fEceULjguA=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_gkehub", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/gkehub", + sum = "h1:JTcTaYQRGsVm+qkah7WzHb6e9sf1C0laYdRPn9aN+vg=", + version = "v0.10.0", + ) + go_repository( + name = "com_google_cloud_go_gkemulticloud", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/gkemulticloud", + sum = "h1:8F1NhJj8ucNj7lK51UZMtAjSWTgP1zO18XF6vkfiPPU=", + version = "v0.4.0", + ) + go_repository( + name = "com_google_cloud_go_grafeas", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/grafeas", + sum = "h1:CYjC+xzdPvbV65gi6Dr4YowKcmLo045pm18L0DhdELM=", + version = "v0.2.0", + ) + + go_repository( + name = "com_google_cloud_go_gsuiteaddons", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/gsuiteaddons", + sum = "h1:TGT2oGmO5q3VH6SjcrlgPUWI0njhYv4kywLm6jag0to=", + version = "v1.4.0", + ) + + go_repository( + name = "com_google_cloud_go_iam", + build_file_proto_mode = "disable_global", + importpath = "cloud.google.com/go/iam", + sum = "h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs=", + version = "v0.7.0", + ) + go_repository( + name = "com_google_cloud_go_iap", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/iap", + sum = "h1:BGEXovwejOCt1zDk8hXq0bOhhRu9haXKWXXXp2B4wBM=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_ids", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/ids", + sum = "h1:LncHK4HHucb5Du310X8XH9/ICtMwZ2PCfK0ScjWiJoY=", + version = "v1.2.0", + ) + go_repository( + name = "com_google_cloud_go_iot", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/iot", + sum = "h1:Y9+oZT9jD4GUZzORXTU45XsnQrhxmDT+TFbPil6pRVQ=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_kms", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/kms", + sum = "h1:OWRZzrPmOZUzurjI2FBGtgY2mB1WaJkqhw6oIwSj0Yg=", + version = "v1.6.0", + ) + go_repository( + name = "com_google_cloud_go_language", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/language", + sum = "h1:3Wa+IUMamL4JH3Zd3cDZUHpwyqplTACt6UZKRD2eCL4=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_lifesciences", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/lifesciences", + sum = "h1:tIqhivE2LMVYkX0BLgG7xL64oNpDaFFI7teunglt1tI=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_logging", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/logging", + sum = "h1:ZBsZK+JG+oCDT+vaxwqF2egKNRjz8soXiS6Xv79benI=", + version = "v1.6.1", + ) + go_repository( + name = "com_google_cloud_go_longrunning", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/longrunning", + sum = "h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=", + version = "v0.3.0", + ) + go_repository( + name = "com_google_cloud_go_managedidentities", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/managedidentities", + sum = "h1:3Kdajn6X25yWQFhFCErmKSYTSvkEd3chJROny//F1A0=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_mediatranslation", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/mediatranslation", + sum = "h1:qAJzpxmEX+SeND10Y/4868L5wfZpo4Y3BIEnIieP4dk=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_memcache", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/memcache", + sum = "h1:yLxUzJkZVSH2kPaHut7k+7sbIBFpvSh1LW9qjM2JDjA=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_metastore", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/metastore", + sum = "h1:3KcShzqWdqxrDEXIBWpYJpOOrgpDj+HlBi07Grot49Y=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_monitoring", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/monitoring", + sum = "h1:c9riaGSPQ4dUKWB+M1Fl0N+iLxstMbCktdEwYSPGDvA=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_networkconnectivity", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/networkconnectivity", + sum = "h1:BVdIKaI68bihnXGdCVL89Jsg9kq2kg+II30fjVqo62E=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_networkmanagement", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/networkmanagement", + sum = "h1:mDHA3CDW00imTvC5RW6aMGsD1bH+FtKwZm/52BxaiMg=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_networksecurity", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/networksecurity", + sum = "h1:qDEX/3sipg9dS5JYsAY+YvgTjPR63cozzAWop8oZS94=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_notebooks", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/notebooks", + sum = "h1:AC8RPjNvel3ExgXjO1YOAz+teg9+j+89TNxa7pIZfww=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_optimization", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/optimization", + sum = "h1:7PxOq9VTT7TMib/6dMoWpMvWS2E4dJEvtYzjvBreaec=", + version = "v1.2.0", + ) + go_repository( + name = "com_google_cloud_go_orchestration", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/orchestration", + sum = "h1:39d6tqvNjd/wsSub1Bn4cEmrYcet5Ur6xpaN+SxOxtY=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_orgpolicy", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/orgpolicy", + sum = "h1:erF5PHqDZb6FeFrUHiYj2JK2BMhsk8CyAg4V4amJ3rE=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_osconfig", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/osconfig", + sum = "h1:NO0RouqCOM7M2S85Eal6urMSSipWwHU8evzwS+siqUI=", + version = "v1.10.0", + ) + go_repository( + name = "com_google_cloud_go_oslogin", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/oslogin", + sum = "h1:pKGDPfeZHDybtw48WsnVLjoIPMi9Kw62kUE5TXCLCN4=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_phishingprotection", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/phishingprotection", + sum = "h1:OrwHLSRSZyaiOt3tnY33dsKSedxbMzsXvqB21okItNQ=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_policytroubleshooter", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/policytroubleshooter", + sum = "h1:NQklJuOUoz1BPP+Epjw81COx7IISWslkZubz/1i0UN8=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_privatecatalog", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/privatecatalog", + sum = "h1:Vz86uiHCtNGm1DeC32HeG2VXmOq5JRYA3VRPf8ZEcSg=", + version = "v0.6.0", + ) + + go_repository( + name = "com_google_cloud_go_pubsub", + build_file_proto_mode = "disable_global", + importpath = "cloud.google.com/go/pubsub", + sum = "h1:q+J/Nfr6Qx4RQeu3rJcnN48SNC0qzlYzSeqkPq93VHs=", + version = "v1.27.1", + ) + go_repository( + name = "com_google_cloud_go_pubsublite", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/pubsublite", + sum = "h1:iqrD8vp3giTb7hI1q4TQQGj77cj8zzgmMPsTZtLnprM=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_recaptchaenterprise", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/recaptchaenterprise", + sum = "h1:u6EznTGzIdsyOsvm+Xkw0aSuKFXQlyjGE9a4exk6iNQ=", + version = "v1.3.1", + ) + + go_repository( + name = "com_google_cloud_go_recaptchaenterprise_v2", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/recaptchaenterprise/v2", + sum = "h1:UqzFfb/WvhwXGDF1eQtdHLrmni+iByZXY4h3w9Kdyv8=", + version = "v2.5.0", + ) + go_repository( + name = "com_google_cloud_go_recommendationengine", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/recommendationengine", + sum = "h1:6w+WxPf2LmUEqX0YyvfCoYb8aBYOcbIV25Vg6R0FLGw=", + version = "v0.6.0", + ) + go_repository( + name = "com_google_cloud_go_recommender", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/recommender", + sum = "h1:9kMZQGeYfcOD/RtZfcNKGKtoex3DdoB4zRgYU/WaIwE=", + version = "v1.8.0", + ) + go_repository( + name = "com_google_cloud_go_redis", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/redis", + sum = "h1:/zTwwBKIAD2DEWTrXZp8WD9yD/gntReF/HkPssVYd0U=", + version = "v1.10.0", + ) + go_repository( + name = "com_google_cloud_go_resourcemanager", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/resourcemanager", + sum = "h1:NDao6CHMwEZIaNsdWy+tuvHaavNeGP06o1tgrR0kLvU=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_resourcesettings", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/resourcesettings", + sum = "h1:eTzOwB13WrfF0kuzG2ZXCfB3TLunSHBur4s+HFU6uSM=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_retail", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/retail", + sum = "h1:N9fa//ecFUOEPsW/6mJHfcapPV0wBSwIUwpVZB7MQ3o=", + version = "v1.11.0", + ) + go_repository( + name = "com_google_cloud_go_run", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/run", + sum = "h1:AWPuzU7Xtaj3Jf+QarDWIs6AJ5hM1VFQ+F6Q+VZ6OT4=", + version = "v0.3.0", + ) + go_repository( + name = "com_google_cloud_go_scheduler", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/scheduler", + sum = "h1:K/mxOewgHGeKuATUJNGylT75Mhtjmx1TOkKukATqMT8=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_secretmanager", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/secretmanager", + sum = "h1:xE6uXljAC1kCR8iadt9+/blg1fvSbmenlsDN4fT9gqw=", + version = "v1.9.0", + ) + go_repository( + name = "com_google_cloud_go_security", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/security", + sum = "h1:KSKzzJMyUoMRQzcz7azIgqAUqxo7rmQ5rYvimMhikqg=", + version = "v1.10.0", + ) + go_repository( + name = "com_google_cloud_go_securitycenter", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/securitycenter", + sum = "h1:QTVtk/Reqnx2bVIZtJKm1+mpfmwRwymmNvlaFez7fQY=", + version = "v1.16.0", + ) + go_repository( + name = "com_google_cloud_go_servicecontrol", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/servicecontrol", + sum = "h1:ImIzbOu6y4jL6ob65I++QzvqgFaoAKgHOG+RU9/c4y8=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_servicedirectory", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/servicedirectory", + sum = "h1:f7M8IMcVzO3T425AqlZbP3yLzeipsBHtRza8vVFYMhQ=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_servicemanagement", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/servicemanagement", + sum = "h1:TpkCO5M7dhKSy1bKUD9o/sSEW/U1Gtx7opA1fsiMx0c=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_serviceusage", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/serviceusage", + sum = "h1:b0EwJxPJLpavSljMQh0RcdHsUrr5DQ+Nelt/3BAs5ro=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_shell", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/shell", + sum = "h1:b1LFhFBgKsG252inyhtmsUUZwchqSz3WTvAIf3JFo4g=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_spanner", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/spanner", + sum = "h1:NvdTpRwf7DTegbfFdPjAWyD7bOVu0VeMqcvR9aCQCAc=", + version = "v1.41.0", + ) + go_repository( + name = "com_google_cloud_go_speech", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/speech", + sum = "h1:yK0ocnFH4Wsf0cMdUyndJQ/hPv02oTJOxzi6AgpBy4s=", + version = "v1.9.0", + ) + + go_repository( + name = "com_google_cloud_go_storage", + build_file_proto_mode = "disable_global", + importpath = "cloud.google.com/go/storage", + sum = "h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ=", + version = "v1.27.0", + ) + go_repository( + name = "com_google_cloud_go_storagetransfer", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/storagetransfer", + sum = "h1:fUe3OydbbvHcAYp07xY+2UpH4AermGbmnm7qdEj3tGE=", + version = "v1.6.0", + ) + go_repository( + name = "com_google_cloud_go_talent", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/talent", + sum = "h1:MrekAGxLqAeAol4Sc0allOVqUGO8j+Iim8NMvpiD7tM=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_texttospeech", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/texttospeech", + sum = "h1:ccPiHgTewxgyAeCWgQWvZvrLmbfQSFABTMAfrSPLPyY=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_tpu", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/tpu", + sum = "h1:ztIdKoma1Xob2qm6QwNh4Xi9/e7N3IfvtwG5AcNsj1g=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_trace", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/trace", + sum = "h1:qO9eLn2esajC9sxpqp1YKX37nXC3L4BfGnPS0Cx9dYo=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_translate", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/translate", + sum = "h1:AOYOH3MspzJ/bH1YXzB+xTE8fMpn3mwhLjugwGXvMPI=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_video", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/video", + sum = "h1:ttlvO4J5c1VGq6FkHqWPD/aH6PfdxujHt+muTJlW1Zk=", + version = "v1.9.0", + ) + go_repository( + name = "com_google_cloud_go_videointelligence", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/videointelligence", + sum = "h1:RPFgVVXbI2b5vnrciZjtsUgpNKVtHO/WIyXUhEfuMhA=", + version = "v1.9.0", + ) + go_repository( + name = "com_google_cloud_go_vision", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/vision", + sum = "h1:/CsSTkbmO9HC8iQpxbK8ATms3OQaX3YQUeTMGCxlaK4=", + version = "v1.2.0", + ) + + go_repository( + name = "com_google_cloud_go_vision_v2", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/vision/v2", + sum = "h1:TQHxRqvLMi19azwm3qYuDbEzZWmiKJNTpGbkNsfRCik=", + version = "v2.5.0", + ) + go_repository( + name = "com_google_cloud_go_vmmigration", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/vmmigration", + sum = "h1:A2Tl2ZmwMRpvEmhV2ibISY85fmQR+Y5w9a0PlRz5P3s=", + version = "v1.3.0", + ) + go_repository( + name = "com_google_cloud_go_vpcaccess", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/vpcaccess", + sum = "h1:woHXXtnW8b9gLFdWO9HLPalAddBQ9V4LT+1vjKwR3W8=", + version = "v1.5.0", + ) + go_repository( + name = "com_google_cloud_go_webrisk", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/webrisk", + sum = "h1:ypSnpGlJnZSXbN9a13PDmAYvVekBLnGKxQ3Q9SMwnYY=", + version = "v1.7.0", + ) + go_repository( + name = "com_google_cloud_go_websecurityscanner", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/websecurityscanner", + sum = "h1:y7yIFg/h/mO+5Y5aCOtVAnpGUOgqCH5rXQ2Oc8Oq2+g=", + version = "v1.4.0", + ) + go_repository( + name = "com_google_cloud_go_workflows", + build_file_proto_mode = "disable", + importpath = "cloud.google.com/go/workflows", + sum = "h1:7Chpin9p50NTU8Tb7qk+I11U/IwVXmDhEoSsdccvInE=", + version = "v1.9.0", + ) + + go_repository( + name = "com_shuralyov_dmitri_gpu_mtl", + build_file_proto_mode = "disable_global", + importpath = "dmitri.shuralyov.com/gpu/mtl", + sum = "h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=", + version = "v0.0.0-20190408044501-666a987793e9", + ) + go_repository( + name = "com_sourcegraph_sourcegraph_appdash", + build_file_proto_mode = "disable_global", + importpath = "sourcegraph.com/sourcegraph/appdash", + sum = "h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM=", + version = "v0.0.0-20190731080439-ebfcffb1b5c0", + ) + go_repository( + name = "com_sourcegraph_sourcegraph_appdash_data", + build_file_proto_mode = "disable_global", + importpath = "sourcegraph.com/sourcegraph/appdash-data", + sum = "h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI=", + version = "v0.0.0-20151005221446-73f23eafcf67", + ) + go_repository( + name = "com_stathat_c_consistent", + build_file_proto_mode = "disable", + importpath = "stathat.com/c/consistent", + sum = "h1:ezyc51EGcRPJUxfHGSgJjWzJdj3NiMU9pNfLNGiXV0c=", + version = "v1.0.0", + ) + + go_repository( + name = "in_gopkg_alecthomas_kingpin_v2", + build_file_proto_mode = "disable_global", + importpath = "gopkg.in/alecthomas/kingpin.v2", + sum = "h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=", + version = "v2.2.6", + ) + go_repository( + name = "in_gopkg_check_v1", + build_file_proto_mode = "disable_global", + importpath = "gopkg.in/check.v1", + sum = "h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=", + version = "v1.0.0-20201130134442-10cb98267c6c", + ) + go_repository( + name = "in_gopkg_errgo_v2", + build_file_proto_mode = "disable_global", + importpath = "gopkg.in/errgo.v2", + sum = "h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=", + version = "v2.1.0", + ) + go_repository( + name = "in_gopkg_fsnotify_fsnotify_v1", + build_file_proto_mode = "disable", + importpath = "gopkg.in/fsnotify/fsnotify.v1", + sum = "h1:2fkCHbPQZNYRAyRyIV9VX0bpRkxIorlQDiYRmufHnhA=", + version = "v1.3.1", + ) + + go_repository( + name = "in_gopkg_fsnotify_v1", + build_file_proto_mode = "disable_global", + importpath = "gopkg.in/fsnotify.v1", + sum = "h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=", + version = "v1.4.7", + ) + go_repository( + name = "in_gopkg_go_playground_assert_v1", + build_file_proto_mode = "disable_global", + importpath = "gopkg.in/go-playground/assert.v1", + sum = "h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=", + version = "v1.2.1", + ) + go_repository( + name = "in_gopkg_go_playground_validator_v8", + build_file_proto_mode = "disable_global", + importpath = "gopkg.in/go-playground/validator.v8", + sum = "h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=", + version = "v8.18.2", + ) + go_repository( + name = "in_gopkg_inf_v0", + build_file_proto_mode = "disable", + importpath = "gopkg.in/inf.v0", + sum = "h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=", + version = "v0.9.1", + ) + + go_repository( + name = "in_gopkg_ini_v1", + build_file_proto_mode = "disable_global", + importpath = "gopkg.in/ini.v1", + sum = "h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=", + version = "v1.67.0", ) go_repository( name = "in_gopkg_jcmturner_aescts_v1", @@ -3961,6 +5389,14 @@ def go_deps(): sum = "h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=", version = "v1.3.6", ) + go_repository( + name = "io_etcd_go_etcd", + build_file_proto_mode = "disable", + importpath = "go.etcd.io/etcd", + sum = "h1:fqmtdYQlwZ/vKWSz5amW+a4cnjg23ojz5iL7rjf08Wg=", + version = "v0.5.0-alpha.5.0.20220915004622-85b640cee793", + ) + go_repository( name = "io_etcd_go_etcd_api_v3", build_file_proto_mode = "disable", @@ -4011,10 +5447,6 @@ def go_deps(): name = "io_etcd_go_etcd_raft_v3", build_file_proto_mode = "disable_global", importpath = "go.etcd.io/etcd/raft/v3", - patch_args = ["-p1"], - patches = [ - "//build/patches:io_etcd_go_etcd_raft_v3.patch", - ], sum = "h1:uCC37qOXqBvKqTGHGyhASsaCsnTuJugl1GvneJNwHWo=", version = "v3.5.2", ) @@ -4032,6 +5464,28 @@ def go_deps(): sum = "h1:uk7/uMGVebpBDl+roivowHt6gJ5Fnqwik3syDkoSKdo=", version = "v3.5.2", ) + go_repository( + name = "io_gorm_driver_mysql", + build_file_proto_mode = "disable", + importpath = "gorm.io/driver/mysql", + sum = "h1:mA0XRPjIKi4bkE9nv+NKs6qj6QWOchqUSdWOcpd3x1E=", + version = "v1.0.6", + ) + go_repository( + name = "io_gorm_driver_sqlite", + build_file_proto_mode = "disable", + importpath = "gorm.io/driver/sqlite", + sum = "h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM=", + version = "v1.1.4", + ) + go_repository( + name = "io_gorm_gorm", + build_file_proto_mode = "disable", + importpath = "gorm.io/gorm", + sum = "h1:INieZtn4P2Pw6xPJ8MzT0G4WUOsHq3RhfuDF1M6GW0E=", + version = "v1.21.9", + ) + go_repository( name = "io_k8s_api", build_file_proto_mode = "disable", @@ -4043,8 +5497,8 @@ def go_deps(): name = "io_k8s_apimachinery", build_file_proto_mode = "disable", importpath = "k8s.io/apimachinery", - sum = "h1:Jmdtdt1ZnoGfWWIIik61Z7nKYgO3J+swQJtPYsP9wHA=", - version = "v0.0.0-20190404173353-6a84e37a896d", + sum = "h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg=", + version = "v0.26.0", ) go_repository( name = "io_k8s_client_go", @@ -4060,27 +5514,56 @@ def go_deps(): sum = "h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=", version = "v0.3.0", ) + go_repository( + name = "io_k8s_klog_v2", + build_file_proto_mode = "disable", + importpath = "k8s.io/klog/v2", + sum = "h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=", + version = "v2.80.1", + ) + go_repository( name = "io_k8s_kube_openapi", build_file_proto_mode = "disable", importpath = "k8s.io/kube-openapi", - sum = "h1:tHgpQvrWaYfrnC8G4N0Oszw5HHCsZxKilDi2R7HuCSM=", - version = "v0.0.0-20180629012420-d83b052f768a", + sum = "h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=", + version = "v0.0.0-20221012153701-172d655c2280", + ) + go_repository( + name = "io_k8s_sigs_json", + build_file_proto_mode = "disable", + importpath = "sigs.k8s.io/json", + sum = "h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=", + version = "v0.0.0-20220713155537-f223a00ba0e2", + ) + go_repository( + name = "io_k8s_sigs_structured_merge_diff_v4", + build_file_proto_mode = "disable", + importpath = "sigs.k8s.io/structured-merge-diff/v4", + sum = "h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=", + version = "v4.2.3", ) go_repository( name = "io_k8s_sigs_yaml", build_file_proto_mode = "disable_global", importpath = "sigs.k8s.io/yaml", - sum = "h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=", - version = "v1.2.0", + sum = "h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=", + version = "v1.3.0", ) go_repository( name = "io_k8s_utils", build_file_proto_mode = "disable", importpath = "k8s.io/utils", - sum = "h1:8r+l4bNWjRlsFYlQJnKJ2p7s1YQPj4XyXiJVqDHRx7c=", - version = "v0.0.0-20190308190857-21c4ce38f2a7", + sum = "h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs=", + version = "v0.0.0-20221107191617-1a15be271d1d", + ) + go_repository( + name = "io_moul_zapgorm2", + build_file_proto_mode = "disable", + importpath = "moul.io/zapgorm2", + sum = "h1:qwAlMBYf+qJkJ7PAzJl4oCe6eS6QGiKAXUPeis0+RBE=", + version = "v1.1.0", ) go_repository( @@ -4208,8 +5691,8 @@ def go_deps(): name = "org_golang_google_api", build_file_proto_mode = "disable_global", importpath = "google.golang.org/api", - sum = "h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE=", - version = "v0.74.0", + sum = "h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ=", + version = "v0.103.0", ) go_repository( name = "org_golang_google_appengine", @@ -4222,15 +5705,15 @@ def go_deps(): name = "org_golang_google_genproto", build_file_proto_mode = "disable_global", importpath = "google.golang.org/genproto", - sum = "h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI=", - version = "v0.0.0-20220324131243-acbaeb5b85eb", + sum = "h1:OjndDrsik+Gt+e6fs45z9AxiewiKyLKYpA45W5Kpkks=", + version = "v0.0.0-20221202195650-67e5cbc046fd", ) go_repository( name = "org_golang_google_grpc", build_file_proto_mode = "disable_global", importpath = "google.golang.org/grpc", - sum = "h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=", - version = "v1.45.0", + sum = "h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=", + version = "v1.51.0", ) go_repository( name = "org_golang_google_grpc_cmd_protoc_gen_go_grpc", @@ -4250,30 +5733,30 @@ def go_deps(): name = "org_golang_x_crypto", build_file_proto_mode = "disable_global", importpath = "golang.org/x/crypto", - sum = "h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=", - version = "v0.0.0-20220411220226-7b82a4e95df4", + sum = "h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=", + version = "v0.5.0", ) go_repository( name = "org_golang_x_exp", build_file_proto_mode = "disable_global", importpath = "golang.org/x/exp", - sum = "h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=", - version = "v0.0.0-20220722155223-a9213eeb770e", + sum = "h1:SkwG94eNiiYJhbeDE018Grw09HIN/KB9NlRmZsrzfWs=", + version = "v0.0.0-20221023144134-a1e5550cf13e", ) go_repository( name = "org_golang_x_exp_typeparams", build_file_proto_mode = "disable", importpath = "golang.org/x/exp/typeparams", - sum = "h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=", - version = "v0.0.0-20220613132600-b0d781184e0d", + sum = "h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk=", + version = "v0.0.0-20220827204233-334a2380cb91", ) go_repository( name = "org_golang_x_image", build_file_proto_mode = "disable_global", importpath = "golang.org/x/image", - sum = "h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=", - version = "v0.0.0-20190802002840-cff245a6509b", + sum = "h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg=", + version = "v0.0.0-20200119044424-58c23975cae1", ) go_repository( name = "org_golang_x_lint", @@ -4293,71 +5776,71 @@ def go_deps(): name = "org_golang_x_mod", build_file_proto_mode = "disable_global", importpath = "golang.org/x/mod", - sum = "h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=", - version = "v0.6.0-dev.0.20220419223038-86c51ed26bb4", + sum = "h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=", + version = "v0.7.0", ) go_repository( name = "org_golang_x_net", build_file_proto_mode = "disable_global", importpath = "golang.org/x/net", - sum = "h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=", - version = "v0.0.0-20220722155237-a158d28d115b", + sum = "h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=", + version = "v0.5.0", ) go_repository( name = "org_golang_x_oauth2", build_file_proto_mode = "disable_global", importpath = "golang.org/x/oauth2", - sum = "h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=", - version = "v0.0.0-20220411215720-9780585627b5", + sum = "h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8=", + version = "v0.3.0", ) go_repository( name = "org_golang_x_sync", build_file_proto_mode = "disable_global", importpath = "golang.org/x/sync", - sum = "h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=", - version = "v0.0.0-20220722155255-886fb9371eb4", + sum = "h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=", + version = "v0.1.0", ) go_repository( name = "org_golang_x_sys", build_file_proto_mode = "disable_global", importpath = "golang.org/x/sys", - sum = "h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=", - version = "v0.0.0-20220928140112-f11e5e49a4ec", + sum = "h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=", + version = "v0.4.0", ) go_repository( name = "org_golang_x_term", build_file_proto_mode = "disable_global", importpath = "golang.org/x/term", - sum = "h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=", - version = "v0.0.0-20210927222741-03fcf44c2211", + sum = "h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=", + version = "v0.4.0", ) go_repository( name = "org_golang_x_text", build_file_proto_mode = "disable_global", importpath = "golang.org/x/text", - sum = "h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=", - version = "v0.3.7", + sum = "h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=", + version = "v0.6.0", ) go_repository( name = "org_golang_x_time", build_file_proto_mode = "disable_global", importpath = "golang.org/x/time", - sum = "h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=", - version = "v0.0.0-20220224211638-0e9765cccd65", + sum = "h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=", + version = "v0.3.0", ) go_repository( name = "org_golang_x_tools", build_file_proto_mode = "disable_global", importpath = "golang.org/x/tools", - sum = "h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=", - version = "v0.1.12", + sum = "h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=", + version = "v0.2.0", ) go_repository( name = "org_golang_x_xerrors", build_file_proto_mode = "disable_global", importpath = "golang.org/x/xerrors", - sum = "h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=", - version = "v0.0.0-20220411194840-2f41105eb62f", + sum = "h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=", + version = "v0.0.0-20220907171357-04be3eba64a2", ) go_repository( name = "org_gonum_v1_gonum", @@ -4464,6 +5947,21 @@ def go_deps(): sum = "h1:CpDZl6aOlLhReez+8S3eEotD7Jx0Os++lemPlMULQP0=", version = "v1.4.0", ) + go_repository( + name = "org_uber_go_dig", + build_file_proto_mode = "disable", + importpath = "go.uber.org/dig", + sum = "h1:pJTDXKEhRqBI8W7rU7kwT5EgyRZuSMVSFcZolOvKK9U=", + version = "v1.9.0", + ) + go_repository( + name = "org_uber_go_fx", + build_file_proto_mode = "disable", + importpath = "go.uber.org/fx", + sum = "h1:+1+3Cz9M0dFMPy9SW9XUIUHye8bnPUm7q7DroNGWYG4=", + version = "v1.12.0", + ) + go_repository( name = "org_uber_go_goleak", build_file_proto_mode = "disable_global", @@ -4475,8 +5973,8 @@ def go_deps(): name = "org_uber_go_multierr", build_file_proto_mode = "disable_global", importpath = "go.uber.org/multierr", - sum = "h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=", - version = "v1.8.0", + sum = "h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=", + version = "v1.9.0", ) go_repository( name = "org_uber_go_tools", @@ -4489,6 +5987,13 @@ def go_deps(): name = "org_uber_go_zap", build_file_proto_mode = "disable_global", importpath = "go.uber.org/zap", - sum = "h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=", - version = "v1.21.0", + sum = "h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=", + version = "v1.24.0", + ) + go_repository( + name = "tools_gotest_gotestsum", + build_file_proto_mode = "disable", + importpath = "gotest.tools/gotestsum", + sum = "h1:RwpqwwFKBAa2h+F6pMEGpE707Edld0etUD3GhqqhDNc=", + version = "v1.7.0", ) diff --git a/Dockerfile b/Dockerfile index e96254e0dd126..f3dae2519f53a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2019 PingCAP, Inc. +# Copyright 2022 PingCAP, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,45 +13,27 @@ # limitations under the License. # Builder image -FROM golang:1.19.1-alpine as builder +FROM rockylinux:9 as builder -RUN apk add --no-cache \ - wget \ - make \ - git \ - gcc \ - binutils-gold \ - musl-dev +ENV GOLANG_VERSION 1.19.3 +ENV ARCH amd64 +ENV GOLANG_DOWNLOAD_URL https://dl.google.com/go/go$GOLANG_VERSION.linux-$ARCH.tar.gz +ENV GOPATH /go +ENV GOROOT /usr/local/go +ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH +RUN yum update -y && yum groupinstall 'Development Tools' -y \ + && curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ + && tar -C /usr/local -xzf golang.tar.gz \ + && rm golang.tar.gz -RUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64 \ - && chmod +x /usr/local/bin/dumb-init +COPY . /tidb +ARG GOPROXY +RUN export GOPROXY=${GOPROXY} && cd /tidb && make server -RUN mkdir -p /go/src/github.com/pingcap/tidb -WORKDIR /go/src/github.com/pingcap/tidb +FROM rockylinux:9-minimal -# Cache dependencies -COPY go.mod . -COPY go.sum . -COPY parser/go.mod parser/go.mod -COPY parser/go.sum parser/go.sum - -RUN GO111MODULE=on go mod download - -# Build real binaries -COPY . . -RUN make - -# Executable image -FROM alpine - -RUN apk add --no-cache \ - curl - -COPY --from=builder /go/src/github.com/pingcap/tidb/bin/tidb-server /tidb-server -COPY --from=builder /usr/local/bin/dumb-init /usr/local/bin/dumb-init +COPY --from=builder /tidb/bin/tidb-server /tidb-server WORKDIR / - EXPOSE 4000 - -ENTRYPOINT ["/usr/local/bin/dumb-init", "/tidb-server"] +ENTRYPOINT ["/tidb-server"] diff --git a/Makefile b/Makefile index bc350cea3a255..b138bfbbd0f04 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ include Makefile.common -.PHONY: all clean test server dev benchkv benchraw check checklist parser tidy ddltest build_br build_lightning build_lightning-ctl build_dumpling ut bazel_build bazel_prepare bazel_test check-file-perm bazel_lint +.PHONY: all clean test server dev benchkv benchraw check checklist parser tidy ddltest build_br build_lightning build_lightning-ctl build_dumpling ut bazel_build bazel_prepare bazel_test check-file-perm check-bazel-prepare bazel_lint default: server buildsucc @@ -31,7 +31,7 @@ dev: checklist check explaintest gogenerate br_unit_test test_part_parser_dev ut # Install the check tools. check-setup:tools/bin/revive -check: parser_yacc check-parallel lint tidy testSuite errdoc +check: parser_yacc check-parallel lint tidy testSuite errdoc check-bazel-prepare fmt: @echo "gofmt (simplify)" @@ -140,30 +140,30 @@ race: failpoint-enable server: ifeq ($(TARGET), "") - CGO_ENABLED=1 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server tidb-server/main.go + CGO_ENABLED=1 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server ./tidb-server else - CGO_ENABLED=1 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' tidb-server/main.go + CGO_ENABLED=1 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' ./tidb-server endif server_debug: ifeq ($(TARGET), "") - CGO_ENABLED=1 $(GOBUILD) -gcflags="all=-N -l" $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server-debug tidb-server/main.go + CGO_ENABLED=1 $(GOBUILD) -gcflags="all=-N -l" $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server-debug ./tidb-server else - CGO_ENABLED=1 $(GOBUILD) -gcflags="all=-N -l" $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' tidb-server/main.go + CGO_ENABLED=1 $(GOBUILD) -gcflags="all=-N -l" $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' ./tidb-server endif server_check: ifeq ($(TARGET), "") - $(GOBUILD) $(RACE_FLAG) -ldflags '$(CHECK_LDFLAGS)' -o bin/tidb-server tidb-server/main.go + $(GOBUILD) $(RACE_FLAG) -ldflags '$(CHECK_LDFLAGS)' -o bin/tidb-server ./tidb-server else - $(GOBUILD) $(RACE_FLAG) -ldflags '$(CHECK_LDFLAGS)' -o '$(TARGET)' tidb-server/main.go + $(GOBUILD) $(RACE_FLAG) -ldflags '$(CHECK_LDFLAGS)' -o '$(TARGET)' ./tidb-server endif linux: ifeq ($(TARGET), "") - GOOS=linux $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server-linux tidb-server/main.go + GOOS=linux $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server-linux ./tidb-server else - GOOS=linux $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' tidb-server/main.go + GOOS=linux $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' ./tidb-server endif server_coverage: @@ -393,6 +393,10 @@ bazel_prepare: bazel run //:gazelle bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro DEPS.bzl%go_deps -build_file_proto_mode=disable +check-bazel-prepare: + @echo "make bazel_prepare" + ./tools/check/check-bazel-prepare.sh + bazel_test: failpoint-enable bazel_ci_prepare bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) \ -- //... -//cmd/... -//tests/graceshutdown/... \ @@ -401,11 +405,7 @@ bazel_test: failpoint-enable bazel_ci_prepare bazel_coverage_test: failpoint-enable bazel_ci_prepare bazel $(BAZEL_GLOBAL_CONFIG) coverage $(BAZEL_CMD_CONFIG) \ - --build_event_json_file=bazel_1.json --@io_bazel_rules_go//go/config:cover_format=go_cover \ - -- //... -//cmd/... -//tests/graceshutdown/... \ - -//tests/globalkilltest/... -//tests/readonlytest/... -//br/pkg/task:task_test -//tests/realtikvtest/... - bazel $(BAZEL_GLOBAL_CONFIG) coverage $(BAZEL_CMD_CONFIG) \ - --build_event_json_file=bazel_2.json --@io_bazel_rules_go//go/config:cover_format=go_cover --define gotags=featuretag \ + --build_event_json_file=bazel_1.json --@io_bazel_rules_go//go/config:cover_format=go_cover --define gotags=deadlock \ -- //... -//cmd/... -//tests/graceshutdown/... \ -//tests/globalkilltest/... -//tests/readonlytest/... -//br/pkg/task:task_test -//tests/realtikvtest/... @@ -413,6 +413,8 @@ bazel_build: bazel_ci_prepare mkdir -p bin bazel $(BAZEL_GLOBAL_CONFIG) build $(BAZEL_CMD_CONFIG) \ //... --//build:with_nogo_flag=true + bazel $(BAZEL_GLOBAL_CONFIG) build $(BAZEL_CMD_CONFIG) \ + //cmd/importer:importer //tidb-server:tidb-server //tidb-server:tidb-server-check --//build:with_nogo_flag=true cp bazel-out/k8-fastbuild/bin/tidb-server/tidb-server_/tidb-server ./bin cp bazel-out/k8-fastbuild/bin/cmd/importer/importer_/importer ./bin cp bazel-out/k8-fastbuild/bin/tidb-server/tidb-server-check_/tidb-server-check ./bin @@ -436,28 +438,34 @@ bazel_golangcilinter: -- run $$($(PACKAGE_DIRECTORIES)) --config ./.golangci.yaml bazel_brietest: failpoint-enable bazel_ci_prepare - bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv \ + bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=deadlock \ -- //tests/realtikvtest/brietest/... bazel_pessimistictest: failpoint-enable bazel_ci_prepare - bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv \ + bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=deadlock \ -- //tests/realtikvtest/pessimistictest/... bazel_sessiontest: failpoint-enable bazel_ci_prepare - bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv \ + bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=deadlock \ -- //tests/realtikvtest/sessiontest/... bazel_statisticstest: failpoint-enable bazel_ci_prepare - bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv \ + bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=deadlock \ -- //tests/realtikvtest/statisticstest/... bazel_txntest: failpoint-enable bazel_ci_prepare - bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv \ + bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=deadlock \ -- //tests/realtikvtest/txntest/... bazel_addindextest: failpoint-enable bazel_ci_prepare - bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv \ + bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=deadlock \ -- //tests/realtikvtest/addindextest/... bazel_lint: bazel_prepare bazel build //... --//build:with_nogo_flag=true + +docker: + docker build -t "$(DOCKERPREFIX)tidb:latest" --build-arg 'GOPROXY=$(shell go env GOPROXY),' -f Dockerfile . + +docker-test: + docker buildx build --platform linux/amd64,linux/arm64 --push -t "$(DOCKERPREFIX)tidb:latest" --build-arg 'GOPROXY=$(shell go env GOPROXY),' -f Dockerfile . diff --git a/Makefile.common b/Makefile.common index 0df4b8e0ff289..e1ff465336c59 100644 --- a/Makefile.common +++ b/Makefile.common @@ -115,6 +115,6 @@ DUMPLING_GOTEST := CGO_ENABLED=1 GO111MODULE=on go test -ldflags '$(DUMPLING_LD TEST_COVERAGE_DIR := "test_coverage" ifneq ("$(CI)", "0") - BAZEL_GLOBAL_CONFIG := --output_user_root=/home/jenkins/.tidb/tmp + BAZEL_GLOBAL_CONFIG := --output_user_root=/home/jenkins/.tidb/tmp --host_jvm_args=-XX:+UnlockExperimentalVMOptions --host_jvm_args=-XX:+UseZGC BAZEL_CMD_CONFIG := --config=ci --repository_cache=/home/jenkins/.tidb/tmp endif diff --git a/README.md b/README.md index 74a81008de990..0901dcf625edc 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,25 @@ -![](docs/logo_with_text.png) +TiDB, a distributed SQL database [![LICENSE](https://img.shields.io/github/license/pingcap/tidb.svg)](https://github.com/pingcap/tidb/blob/master/LICENSE) [![Language](https://img.shields.io/badge/Language-Go-blue.svg)](https://golang.org/) -[![Build Status](https://travis-ci.org/pingcap/tidb.svg?branch=master)](https://travis-ci.org/pingcap/tidb) +[![Build Status](https://prow.tidb.net/badge.svg?jobs=pingcap/tidb/merged_*)](https://prow.tidb.net/?repo=pingcap%2Ftidb&type=postsubmit) [![Go Report Card](https://goreportcard.com/badge/github.com/pingcap/tidb)](https://goreportcard.com/report/github.com/pingcap/tidb) [![GitHub release](https://img.shields.io/github/tag/pingcap/tidb.svg?label=release)](https://github.com/pingcap/tidb/releases) [![GitHub release date](https://img.shields.io/github/release-date/pingcap/tidb.svg)](https://github.com/pingcap/tidb/releases) -[![CircleCI Status](https://circleci.com/gh/pingcap/tidb.svg?style=shield)](https://circleci.com/gh/pingcap/tidb) [![Coverage Status](https://codecov.io/gh/pingcap/tidb/branch/master/graph/badge.svg)](https://codecov.io/gh/pingcap/tidb) [![GoDoc](https://img.shields.io/badge/Godoc-reference-blue.svg)](https://godoc.org/github.com/pingcap/tidb) ## What is TiDB? -TiDB ("Ti" stands for Titanium) is an open-source NewSQL database that supports Hybrid Transactional and Analytical Processing (HTAP) workloads. It is MySQL compatible and features horizontal scalability, strong consistency, and high availability. +TiDB (/’taɪdiːbi:/, "Ti" stands for Titanium) is an open-source distributed SQL database that supports Hybrid Transactional and Analytical Processing (HTAP) workloads. It is MySQL compatible and features horizontal scalability, strong consistency, and high availability. - [Key features](https://docs.pingcap.com/tidb/stable/overview#key-features) - [Architecture](#architecture) -- [MySQL Compatibility](https://docs.pingcap.com/tidb/stable/mysql-compatibility) +- [MySQL compatibility](https://docs.pingcap.com/tidb/stable/mysql-compatibility) -For more details and latest updates, see [TiDB docs](https://docs.pingcap.com/tidb/stable) and [release notes](https://docs.pingcap.com/tidb/dev/release-notes). +For more details and latest updates, see [TiDB documentation](https://docs.pingcap.com/tidb/stable) and [release notes](https://docs.pingcap.com/tidb/dev/release-notes). -For future plans, see [TiDB Roadmap](roadmap.md). +For future plans, see the [TiDB roadmap](roadmap.md). ## Quick start @@ -38,40 +37,43 @@ See [TiDB Quick Start Guide](https://docs.pingcap.com/tidb/stable/quick-start-wi ### Start developing TiDB -See [Get Started](https://pingcap.github.io/tidb-dev-guide/get-started/introduction.html) chapter of [TiDB Dev Guide](https://pingcap.github.io/tidb-dev-guide/index.html). +See the [Get Started](https://pingcap.github.io/tidb-dev-guide/get-started/introduction.html) chapter of [TiDB Development Guide](https://pingcap.github.io/tidb-dev-guide/index.html). ## Community -You can join these groups and chats to discuss and ask TiDB related questions: +You can join the following groups or channels to discuss or ask questions about TiDB, and to keep yourself informed of the latest TiDB updates: -- [TiDB Internals Forum](https://internals.tidb.io/) -- [Slack Channel](https://slack.tidb.io/invite?team=tidb-community&channel=everyone&ref=pingcap-tidb) -- [TiDB User Group Forum (Chinese)](https://asktug.com) - -In addition, you may enjoy following: - -- [@PingCAP](https://twitter.com/PingCAP) on Twitter -- Question tagged [#tidb on StackOverflow](https://stackoverflow.com/questions/tagged/tidb) -- The PingCAP Team [English Blog](https://en.pingcap.com/blog) and [Chinese Blog](https://pingcap.com/blog-cn/) +- Seek help when you use TiDB + - [TiDB Forum](https://ask.pingcap.com/) + - [Chinese TiDB Forum](https://asktug.com) + - Slack channels: [#everyone](https://slack.tidb.io/invite?team=tidb-community&channel=everyone&ref=pingcap-tidb) (English), [#tidb-japan](https://slack.tidb.io/invite?team=tidb-community&channel=tidb-japan&ref=github-tidb) (Japanese) + - [Stack Overflow](https://stackoverflow.com/questions/tagged/tidb) (questions tagged with #tidb) +- Discuss TiDB's implementation and design + - [TiDB Internals forum](https://internals.tidb.io/) +- Get the latest TiDB news or updates + - Follow [@PingCAP](https://twitter.com/PingCAP) on Twitter + - Read the PingCAP [English Blog](https://www.pingcap.com/blog/?from=en) or [Chinese Blog](https://cn.pingcap.com/blog/) For support, please contact [PingCAP](http://bit.ly/contact_us_via_github). ## Contributing -The [community repository](https://github.com/pingcap/community) hosts all information about the TiDB community, including how to contribute to TiDB, how TiDB community is governed, how special interest groups are organized, etc. +The [community repository](https://github.com/pingcap/community) hosts all information about the TiDB community, including [how to contribute](https://github.com/pingcap/community/blob/master/contributors/README.md) to TiDB, how the TiDB community is governed, how [teams](https://github.com/pingcap/community/blob/master/teams/README.md) are organized. + +Contributions are welcomed and greatly appreciated. You can get started with one of the [good first issues](https://github.com/pingcap/tidb/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or [help wanted issues](https://github.com/pingcap/tidb/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). For more details on typical contribution workflows, see [Contribute to TiDB](https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/introduction.html). For more contributing information about where to start, click the contributor icon below. [contribution-map](https://github.com/pingcap/tidb-map/blob/master/maps/contribution-map.md#tidb-is-an-open-source-distributed-htap-database-compatible-with-the-mysql-protocol) -Contributions are welcomed and greatly appreciated. All the contributors are welcomed to claim your reward by filing this [form](https://forms.pingcap.com/f/tidb-contribution-swag). See [Contribution to TiDB](https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/introduction.html) for details on typical contribution workflows. For more contributing information, click on the contributor icon above. +Every contributor is welcome to claim your contribution swag by filling in and submitting this [form](https://forms.pingcap.com/f/tidb-contribution-swag). ## Case studies -- [English](https://pingcap.com/case-studies) -- [简体中文](https://pingcap.com/cases-cn/) +- [Case studies in English](https://www.pingcap.com/customers/) +- [中文用户案例](https://cn.pingcap.com/case/) ## Architecture -![architecture](./docs/architecture.png) +![TiDB architecture](./docs/tidb-architecture.png) ## License diff --git a/WORKSPACE b/WORKSPACE index 35ae55b7388a3..627c7dd5c5575 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -2,10 +2,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "io_bazel_rules_go", - sha256 = "099a9fb96a376ccbbb7d291ed4ecbdfd42f6bc822ab77ae6f1b5cb9e914e94fa", + sha256 = "56d8c5a5c91e1af73eca71a6fab2ced959b67c86d12ba37feedb0a2dfea441a6", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.35.0/rules_go-v0.35.0.zip", - "https://github.com/bazelbuild/rules_go/releases/download/v0.35.0/rules_go-v0.35.0.zip", + "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.37.0/rules_go-v0.37.0.zip", + "https://github.com/bazelbuild/rules_go/releases/download/v0.37.0/rules_go-v0.37.0.zip", ], ) @@ -18,7 +18,7 @@ http_archive( ], ) -load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") +load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk", "go_register_toolchains", "go_rules_dependencies") load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") load("//:DEPS.bzl", "go_deps") @@ -27,9 +27,19 @@ go_deps() go_rules_dependencies() +go_download_sdk( + name = "go_sdk", + urls = [ + "http://ats.apps.svc/golang/{}", + "http://bazel-cache.pingcap.net:8080/golang/{}", + "https://mirrors.aliyun.com/golang/{}", + "https://dl.google.com/go/{}", + ], + version = "1.19.5", +) + go_register_toolchains( nogo = "@//build:tidb_nogo", - version = "1.19.2", ) gazelle_dependencies() @@ -48,3 +58,23 @@ http_archive( load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") protobuf_deps() + +http_archive( + name = "remote_java_tools", + sha256 = "5cd59ea6bf938a1efc1e11ea562d37b39c82f76781211b7cd941a2346ea8484d", + urls = [ + "http://ats.apps.svc/bazel_java_tools/releases/java/v11.9/java_tools-v11.9.zip", + "https://mirror.bazel.build/bazel_java_tools/releases/java/v11.9/java_tools-v11.9.zip", + "https://github.com/bazelbuild/java_tools/releases/download/java_v11.9/java_tools-v11.9.zip", + ], +) + +http_archive( + name = "remote_java_tools_linux", + sha256 = "512582cac5b7ea7974a77b0da4581b21f546c9478f206eedf54687eeac035989", + urls = [ + "http://ats.apps.svc/bazel_java_tools/releases/java/v11.9/java_tools_linux-v11.9.zip", + "https://mirror.bazel.build/bazel_java_tools/releases/java/v11.9/java_tools_linux-v11.9.zip", + "https://github.com/bazelbuild/java_tools/releases/download/java_v11.9/java_tools_linux-v11.9.zip", + ], +) diff --git a/autoid_service/BUILD.bazel b/autoid_service/BUILD.bazel new file mode 100644 index 0000000000000..26eb992c89474 --- /dev/null +++ b/autoid_service/BUILD.bazel @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "autoid_service", + srcs = ["autoid.go"], + importpath = "github.com/pingcap/tidb/autoid_service", + visibility = ["//visibility:public"], + deps = [ + "//config", + "//kv", + "//meta", + "//meta/autoid", + "//metrics", + "//owner", + "//parser/model", + "//util/logutil", + "//util/mathutil", + "@com_github_pingcap_errors//:errors", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_kvproto//pkg/autoid", + "@io_etcd_go_etcd_client_v3//:client", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//keepalive", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "autoid_service_test", + srcs = ["autoid_test.go"], + embed = [":autoid_service"], + deps = [ + "//parser/model", + "//testkit", + "@com_github_pingcap_kvproto//pkg/autoid", + "@com_github_stretchr_testify//require", + "@io_etcd_go_etcd_tests_v3//integration", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials/insecure", + ], +) diff --git a/autoid_service/autoid.go b/autoid_service/autoid.go new file mode 100644 index 0000000000000..aa6c487cb0b48 --- /dev/null +++ b/autoid_service/autoid.go @@ -0,0 +1,526 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package autoid + +import ( + "context" + "crypto/tls" + "math" + "sync" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/failpoint" + "github.com/pingcap/kvproto/pkg/autoid" + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/meta" + autoid1 "github.com/pingcap/tidb/meta/autoid" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/owner" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mathutil" + clientv3 "go.etcd.io/etcd/client/v3" + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" +) + +var ( + errAutoincReadFailed = errors.New("auto increment action failed") +) + +const ( + autoIDLeaderPath = "tidb/autoid/leader" +) + +type autoIDKey struct { + dbID int64 + tblID int64 +} + +type autoIDValue struct { + sync.Mutex + base int64 + end int64 + isUnsigned bool + token chan struct{} +} + +func (alloc *autoIDValue) alloc4Unsigned(ctx context.Context, store kv.Storage, dbID, tblID int64, isUnsigned bool, + n uint64, increment, offset int64) (min int64, max int64, err error) { + // Check offset rebase if necessary. + if uint64(offset-1) > uint64(alloc.base) { + if err := alloc.rebase4Unsigned(ctx, store, dbID, tblID, uint64(offset-1)); err != nil { + return 0, 0, err + } + } + // calcNeededBatchSize calculates the total batch size needed. + n1 := calcNeededBatchSize(alloc.base, int64(n), increment, offset, isUnsigned) + + // The local rest is not enough for alloc, skip it. + if uint64(alloc.base)+uint64(n1) > uint64(alloc.end) || alloc.base == 0 { + var newBase, newEnd int64 + nextStep := int64(batch) + // Although it may skip a segment here, we still treat it as consumed. + + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta) + err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error { + idAcc := meta.NewMeta(txn).GetAutoIDAccessors(dbID, tblID).IncrementID(model.TableInfoVersion5) + var err1 error + newBase, err1 = idAcc.Get() + if err1 != nil { + return err1 + } + // calcNeededBatchSize calculates the total batch size needed on new base. + n1 = calcNeededBatchSize(newBase, int64(n), increment, offset, isUnsigned) + // Although the step is customized by user, we still need to make sure nextStep is big enough for insert batch. + if nextStep < n1 { + nextStep = n1 + } + tmpStep := int64(mathutil.Min(math.MaxUint64-uint64(newBase), uint64(nextStep))) + // The global rest is not enough for alloc. + if tmpStep < n1 { + return errAutoincReadFailed + } + newEnd, err1 = idAcc.Inc(tmpStep) + return err1 + }) + if err != nil { + return 0, 0, err + } + if uint64(newBase) == math.MaxUint64 { + return 0, 0, errAutoincReadFailed + } + alloc.base, alloc.end = newBase, newEnd + } + min = alloc.base + // Use uint64 n directly. + alloc.base = int64(uint64(alloc.base) + uint64(n1)) + return min, alloc.base, nil +} + +func (alloc *autoIDValue) alloc4Signed(ctx context.Context, + store kv.Storage, + dbID, tblID int64, + isUnsigned bool, + n uint64, increment, offset int64) (min int64, max int64, err error) { + // Check offset rebase if necessary. + if offset-1 > alloc.base { + if err := alloc.rebase4Signed(ctx, store, dbID, tblID, offset-1); err != nil { + return 0, 0, err + } + } + // calcNeededBatchSize calculates the total batch size needed. + n1 := calcNeededBatchSize(alloc.base, int64(n), increment, offset, isUnsigned) + + // Condition alloc.base+N1 > alloc.end will overflow when alloc.base + N1 > MaxInt64. So need this. + if math.MaxInt64-alloc.base <= n1 { + return 0, 0, errAutoincReadFailed + } + + // The local rest is not enough for allocN, skip it. + // If alloc.base is 0, the alloc may not be initialized, force fetch from remote. + if alloc.base+n1 > alloc.end || alloc.base == 0 { + var newBase, newEnd int64 + nextStep := int64(batch) + + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta) + err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error { + idAcc := meta.NewMeta(txn).GetAutoIDAccessors(dbID, tblID).IncrementID(model.TableInfoVersion5) + var err1 error + newBase, err1 = idAcc.Get() + if err1 != nil { + return err1 + } + // calcNeededBatchSize calculates the total batch size needed on global base. + n1 = calcNeededBatchSize(newBase, int64(n), increment, offset, isUnsigned) + // Although the step is customized by user, we still need to make sure nextStep is big enough for insert batch. + if nextStep < n1 { + nextStep = n1 + } + tmpStep := mathutil.Min(math.MaxInt64-newBase, nextStep) + // The global rest is not enough for alloc. + if tmpStep < n1 { + return errAutoincReadFailed + } + newEnd, err1 = idAcc.Inc(tmpStep) + return err1 + }) + if err != nil { + return 0, 0, err + } + if newBase == math.MaxInt64 { + return 0, 0, errAutoincReadFailed + } + alloc.base, alloc.end = newBase, newEnd + } + min = alloc.base + alloc.base += n1 + return min, alloc.base, nil +} + +func (alloc *autoIDValue) rebase4Unsigned(ctx context.Context, + store kv.Storage, + dbID, tblID int64, + requiredBase uint64) error { + // Satisfied by alloc.base, nothing to do. + if requiredBase <= uint64(alloc.base) { + return nil + } + // Satisfied by alloc.end, need to update alloc.base. + if requiredBase <= uint64(alloc.end) { + alloc.base = int64(requiredBase) + return nil + } + + var newBase, newEnd uint64 + startTime := time.Now() + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta) + err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error { + idAcc := meta.NewMeta(txn).GetAutoIDAccessors(dbID, tblID).IncrementID(model.TableInfoVersion5) + currentEnd, err1 := idAcc.Get() + if err1 != nil { + return err1 + } + uCurrentEnd := uint64(currentEnd) + newBase = mathutil.Max(uCurrentEnd, requiredBase) + newEnd = mathutil.Min(math.MaxUint64-uint64(batch), newBase) + uint64(batch) + _, err1 = idAcc.Inc(int64(newEnd - uCurrentEnd)) + return err1 + }) + metrics.AutoIDHistogram.WithLabelValues(metrics.TableAutoIDRebase, metrics.RetLabel(err)).Observe(time.Since(startTime).Seconds()) + if err != nil { + return err + } + alloc.base, alloc.end = int64(newBase), int64(newEnd) + return nil +} + +func (alloc *autoIDValue) rebase4Signed(ctx context.Context, store kv.Storage, dbID, tblID int64, requiredBase int64) error { + // Satisfied by alloc.base, nothing to do. + if requiredBase <= alloc.base { + return nil + } + // Satisfied by alloc.end, need to update alloc.base. + if requiredBase <= alloc.end { + alloc.base = requiredBase + return nil + } + + var newBase, newEnd int64 + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta) + err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error { + idAcc := meta.NewMeta(txn).GetAutoIDAccessors(dbID, tblID).IncrementID(model.TableInfoVersion5) + currentEnd, err1 := idAcc.Get() + if err1 != nil { + return err1 + } + newBase = mathutil.Max(currentEnd, requiredBase) + newEnd = mathutil.Min(math.MaxInt64-batch, newBase) + batch + _, err1 = idAcc.Inc(newEnd - currentEnd) + return err1 + }) + if err != nil { + return err + } + alloc.base, alloc.end = newBase, newEnd + return nil +} + +// Service implement the grpc AutoIDAlloc service, defined in kvproto/pkg/autoid. +type Service struct { + autoIDLock sync.Mutex + autoIDMap map[autoIDKey]*autoIDValue + + leaderShip owner.Manager + store kv.Storage +} + +// New return a Service instance. +func New(selfAddr string, etcdAddr []string, store kv.Storage, tlsConfig *tls.Config) *Service { + cfg := config.GetGlobalConfig() + etcdLogCfg := zap.NewProductionConfig() + + cli, err := clientv3.New(clientv3.Config{ + LogConfig: &etcdLogCfg, + Endpoints: etcdAddr, + AutoSyncInterval: 30 * time.Second, + DialTimeout: 5 * time.Second, + DialOptions: []grpc.DialOption{ + grpc.WithBackoffMaxDelay(time.Second * 3), + grpc.WithKeepaliveParams(keepalive.ClientParameters{ + Time: time.Duration(cfg.TiKVClient.GrpcKeepAliveTime) * time.Second, + Timeout: time.Duration(cfg.TiKVClient.GrpcKeepAliveTimeout) * time.Second, + }), + }, + TLS: tlsConfig, + }) + if err != nil { + panic(err) + } + return newWithCli(selfAddr, cli, store) +} + +func newWithCli(selfAddr string, cli *clientv3.Client, store kv.Storage) *Service { + l := owner.NewOwnerManager(context.Background(), cli, "autoid", selfAddr, autoIDLeaderPath) + err := l.CampaignOwner() + if err != nil { + panic(err) + } + + return &Service{ + autoIDMap: make(map[autoIDKey]*autoIDValue), + leaderShip: l, + store: store, + } +} + +type mockClient struct { + Service +} + +func (m *mockClient) AllocAutoID(ctx context.Context, in *autoid.AutoIDRequest, opts ...grpc.CallOption) (*autoid.AutoIDResponse, error) { + return m.Service.AllocAutoID(ctx, in) +} + +func (m *mockClient) Rebase(ctx context.Context, in *autoid.RebaseRequest, opts ...grpc.CallOption) (*autoid.RebaseResponse, error) { + return m.Service.Rebase(ctx, in) +} + +var global = make(map[string]*mockClient) + +// MockForTest is used for testing, the UT test and unistore use this. +func MockForTest(store kv.Storage) autoid.AutoIDAllocClient { + uuid := store.UUID() + ret, ok := global[uuid] + if !ok { + ret = &mockClient{ + Service{ + autoIDMap: make(map[autoIDKey]*autoIDValue), + leaderShip: nil, + store: store, + }, + } + global[uuid] = ret + } + return ret +} + +// Close closes the Service and clean up resource. +func (s *Service) Close() { + if s.leaderShip != nil { + for k, v := range s.autoIDMap { + if v.base > 0 { + err := v.forceRebase(context.Background(), s.store, k.dbID, k.tblID, v.base, v.isUnsigned) + if err != nil { + logutil.BgLogger().Warn("[autoid service] save cached ID fail when service exit", + zap.Int64("db id", k.dbID), + zap.Int64("table id", k.tblID), + zap.Int64("value", v.base), + zap.Error(err)) + } + } + } + s.leaderShip.Cancel() + } +} + +// seekToFirstAutoIDSigned seeks to the next valid signed position. +func seekToFirstAutoIDSigned(base, increment, offset int64) int64 { + nr := (base + increment - offset) / increment + nr = nr*increment + offset + return nr +} + +// seekToFirstAutoIDUnSigned seeks to the next valid unsigned position. +func seekToFirstAutoIDUnSigned(base, increment, offset uint64) uint64 { + nr := (base + increment - offset) / increment + nr = nr*increment + offset + return nr +} + +func calcNeededBatchSize(base, n, increment, offset int64, isUnsigned bool) int64 { + if increment == 1 { + return n + } + if isUnsigned { + // SeekToFirstAutoIDUnSigned seeks to the next unsigned valid position. + nr := seekToFirstAutoIDUnSigned(uint64(base), uint64(increment), uint64(offset)) + // calculate the total batch size needed. + nr += (uint64(n) - 1) * uint64(increment) + return int64(nr - uint64(base)) + } + nr := seekToFirstAutoIDSigned(base, increment, offset) + // calculate the total batch size needed. + nr += (n - 1) * increment + return nr - base +} + +const batch = 4000 + +// AllocAutoID implements gRPC AutoIDAlloc interface. +func (s *Service) AllocAutoID(ctx context.Context, req *autoid.AutoIDRequest) (*autoid.AutoIDResponse, error) { + var res *autoid.AutoIDResponse + for { + var err error + res, err = s.allocAutoID(ctx, req) + if err != nil { + return nil, errors.Trace(err) + } + if res != nil { + break + } + } + return res, nil +} + +func (s *Service) getAlloc(dbID, tblID int64, isUnsigned bool) *autoIDValue { + key := autoIDKey{dbID: dbID, tblID: tblID} + s.autoIDLock.Lock() + defer s.autoIDLock.Unlock() + + val, ok := s.autoIDMap[key] + if !ok { + val = &autoIDValue{ + isUnsigned: isUnsigned, + token: make(chan struct{}, 1), + } + s.autoIDMap[key] = val + } + + return val +} + +func (s *Service) allocAutoID(ctx context.Context, req *autoid.AutoIDRequest) (*autoid.AutoIDResponse, error) { + if s.leaderShip != nil && !s.leaderShip.IsOwner() { + logutil.BgLogger().Info("[autoid service] Alloc AutoID fail, not leader") + return nil, errors.New("not leader") + } + + failpoint.Inject("mockErr", func(val failpoint.Value) { + if val.(bool) { + failpoint.Return(nil, errors.New("mock reload failed")) + } + }) + + val := s.getAlloc(req.DbID, req.TblID, req.IsUnsigned) + + if req.N == 0 { + if val.base != 0 { + return &autoid.AutoIDResponse{ + Min: val.base, + Max: val.base, + }, nil + } + // This item is not initialized, get the data from remote. + var currentEnd int64 + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta) + err := kv.RunInNewTxn(ctx, s.store, true, func(ctx context.Context, txn kv.Transaction) error { + idAcc := meta.NewMeta(txn).GetAutoIDAccessors(req.DbID, req.TblID).RowID() + var err1 error + currentEnd, err1 = idAcc.Get() + if err1 != nil { + return err1 + } + val.end = currentEnd + return nil + }) + if err != nil { + return &autoid.AutoIDResponse{Errmsg: []byte(err.Error())}, nil + } + return &autoid.AutoIDResponse{ + Min: currentEnd, + Max: currentEnd, + }, nil + } + + val.Lock() + defer val.Unlock() + + var min, max int64 + var err error + if req.IsUnsigned { + min, max, err = val.alloc4Unsigned(ctx, s.store, req.DbID, req.TblID, req.IsUnsigned, req.N, req.Increment, req.Offset) + } else { + min, max, err = val.alloc4Signed(ctx, s.store, req.DbID, req.TblID, req.IsUnsigned, req.N, req.Increment, req.Offset) + } + + if err != nil { + return &autoid.AutoIDResponse{Errmsg: []byte(err.Error())}, nil + } + return &autoid.AutoIDResponse{ + Min: min, + Max: max, + }, nil +} + +func (alloc *autoIDValue) forceRebase(ctx context.Context, store kv.Storage, dbID, tblID, requiredBase int64, isUnsigned bool) error { + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta) + err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error { + idAcc := meta.NewMeta(txn).GetAutoIDAccessors(dbID, tblID).IncrementID(model.TableInfoVersion5) + currentEnd, err1 := idAcc.Get() + if err1 != nil { + return err1 + } + var step int64 + if !isUnsigned { + step = requiredBase - currentEnd + } else { + uRequiredBase, uCurrentEnd := uint64(requiredBase), uint64(currentEnd) + step = int64(uRequiredBase - uCurrentEnd) + } + _, err1 = idAcc.Inc(step) + return err1 + }) + if err != nil { + return err + } + alloc.base, alloc.end = requiredBase, requiredBase + return nil +} + +// Rebase implements gRPC AutoIDAlloc interface. +// req.N = 0 is handled specially, it is used to return the current auto ID value. +func (s *Service) Rebase(ctx context.Context, req *autoid.RebaseRequest) (*autoid.RebaseResponse, error) { + if s.leaderShip != nil && !s.leaderShip.IsOwner() { + logutil.BgLogger().Info("[autoid service] Rebase() fail, not leader") + return nil, errors.New("not leader") + } + + val := s.getAlloc(req.DbID, req.TblID, req.IsUnsigned) + if req.Force { + err := val.forceRebase(ctx, s.store, req.DbID, req.TblID, req.Base, req.IsUnsigned) + if err != nil { + return &autoid.RebaseResponse{Errmsg: []byte(err.Error())}, nil + } + } + + var err error + if req.IsUnsigned { + err = val.rebase4Unsigned(ctx, s.store, req.DbID, req.TblID, uint64(req.Base)) + } else { + err = val.rebase4Signed(ctx, s.store, req.DbID, req.TblID, req.Base) + } + if err != nil { + return &autoid.RebaseResponse{Errmsg: []byte(err.Error())}, nil + } + return &autoid.RebaseResponse{}, nil +} + +func init() { + autoid1.MockForTest = MockForTest +} diff --git a/autoid_service/autoid_test.go b/autoid_service/autoid_test.go new file mode 100644 index 0000000000000..df2722309cf6e --- /dev/null +++ b/autoid_service/autoid_test.go @@ -0,0 +1,202 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package autoid + +import ( + "context" + "fmt" + "math" + "net" + "testing" + "time" + + "github.com/pingcap/kvproto/pkg/autoid" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" + "go.etcd.io/etcd/tests/v3/integration" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +type autoIDResp struct { + *autoid.AutoIDResponse + error + *testing.T +} + +func (resp autoIDResp) check(min, max int64) { + require.NoError(resp.T, resp.error) + require.Equal(resp.T, resp.AutoIDResponse, &autoid.AutoIDResponse{Min: min, Max: max}) +} + +func (resp autoIDResp) checkErrmsg() { + require.NoError(resp.T, resp.error) + require.True(resp.T, len(resp.GetErrmsg()) > 0) +} + +type rebaseResp struct { + *autoid.RebaseResponse + error + *testing.T +} + +func (resp rebaseResp) check(msg string) { + require.NoError(resp.T, resp.error) + require.Equal(resp.T, string(resp.RebaseResponse.GetErrmsg()), msg) +} + +func TestAPI(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + cli := MockForTest(store) + tk.MustExec("use test") + tk.MustExec("create table t (id int key auto_increment);") + is := dom.InfoSchema() + dbInfo, ok := is.SchemaByName(model.NewCIStr("test")) + require.True(t, ok) + + tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + tbInfo := tbl.Meta() + + ctx := context.Background() + checkCurrValue := func(t *testing.T, cli autoid.AutoIDAllocClient, min, max int64) { + req := &autoid.AutoIDRequest{DbID: dbInfo.ID, TblID: tbInfo.ID, N: 0} + resp, err := cli.AllocAutoID(ctx, req) + require.NoError(t, err) + require.Equal(t, resp, &autoid.AutoIDResponse{Min: min, Max: max}) + } + autoIDRequest := func(t *testing.T, cli autoid.AutoIDAllocClient, unsigned bool, n uint64, more ...int64) autoIDResp { + increment := int64(1) + offset := int64(1) + if len(more) >= 1 { + increment = more[0] + } + if len(more) >= 2 { + offset = more[1] + } + req := &autoid.AutoIDRequest{DbID: dbInfo.ID, TblID: tbInfo.ID, IsUnsigned: unsigned, N: n, Increment: increment, Offset: offset} + resp, err := cli.AllocAutoID(ctx, req) + return autoIDResp{resp, err, t} + } + rebaseRequest := func(t *testing.T, cli autoid.AutoIDAllocClient, unsigned bool, n int64, force ...struct{}) rebaseResp { + req := &autoid.RebaseRequest{ + DbID: dbInfo.ID, + TblID: tbInfo.ID, + Base: n, + IsUnsigned: unsigned, + Force: len(force) > 0, + } + resp, err := cli.Rebase(ctx, req) + return rebaseResp{resp, err, t} + } + var force = struct{}{} + + // basic auto id operation + autoIDRequest(t, cli, false, 1).check(0, 1) + autoIDRequest(t, cli, false, 10).check(1, 11) + checkCurrValue(t, cli, 11, 11) + autoIDRequest(t, cli, false, 128).check(11, 139) + autoIDRequest(t, cli, false, 1, 10, 5).check(139, 145) + + // basic rebase operation + rebaseRequest(t, cli, false, 666).check("") + autoIDRequest(t, cli, false, 1).check(666, 667) + + rebaseRequest(t, cli, false, 6666).check("") + autoIDRequest(t, cli, false, 1).check(6666, 6667) + + // rebase will not decrease the value without 'force' + rebaseRequest(t, cli, false, 44).check("") + checkCurrValue(t, cli, 6667, 6667) + rebaseRequest(t, cli, false, 44, force).check("") + checkCurrValue(t, cli, 44, 44) + + // max increase 1 + rebaseRequest(t, cli, false, math.MaxInt64, force).check("") + checkCurrValue(t, cli, math.MaxInt64, math.MaxInt64) + autoIDRequest(t, cli, false, 1).checkErrmsg() + + rebaseRequest(t, cli, true, 0, force).check("") + checkCurrValue(t, cli, 0, 0) + autoIDRequest(t, cli, true, 1).check(0, 1) + autoIDRequest(t, cli, true, 10).check(1, 11) + autoIDRequest(t, cli, true, 128).check(11, 139) + autoIDRequest(t, cli, true, 1, 10, 5).check(139, 145) + + // max increase 1 + rebaseRequest(t, cli, true, math.MaxInt64).check("") + checkCurrValue(t, cli, math.MaxInt64, math.MaxInt64) + autoIDRequest(t, cli, true, 1).check(math.MaxInt64, math.MinInt64) + autoIDRequest(t, cli, true, 1).check(math.MinInt64, math.MinInt64+1) + + rebaseRequest(t, cli, true, -1).check("") + checkCurrValue(t, cli, -1, -1) + autoIDRequest(t, cli, true, 1).check(-1, 0) +} + +func TestGRPC(t *testing.T) { + integration.BeforeTestExternal(t) + store := testkit.CreateMockStore(t) + cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) + defer cluster.Terminate(t) + etcdCli := cluster.RandClient() + + var addr string + var listener net.Listener + for port := 10080; ; port++ { + var err error + addr = fmt.Sprintf("127.0.0.1:%d", port) + listener, err = net.Listen("tcp", addr) + if err == nil { + break + } + } + defer listener.Close() + + service := newWithCli(addr, etcdCli, store) + defer service.Close() + + var i int + for !service.leaderShip.IsOwner() { + time.Sleep(100 * time.Millisecond) + i++ + if i >= 20 { + break + } + } + require.Less(t, i, 20) + + grpcServer := grpc.NewServer() + autoid.RegisterAutoIDAllocServer(grpcServer, service) + go func() { + grpcServer.Serve(listener) + }() + defer grpcServer.Stop() + + grpcConn, err := grpc.Dial("127.0.0.1:10080", grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + cli := autoid.NewAutoIDAllocClient(grpcConn) + _, err = cli.AllocAutoID(context.Background(), &autoid.AutoIDRequest{ + DbID: 0, + TblID: 0, + N: 1, + Increment: 1, + Offset: 1, + IsUnsigned: false, + }) + require.NoError(t, err) +} diff --git a/bindinfo/bind_cache.go b/bindinfo/bind_cache.go index 8ce69deedd840..fe67cbbbf9f43 100644 --- a/bindinfo/bind_cache.go +++ b/bindinfo/bind_cache.go @@ -146,6 +146,23 @@ func (c *bindCache) GetBindRecord(hash, normdOrigSQL, db string) *BindRecord { return nil } +// GetBindRecordBySQLDigest gets the BindRecord from the cache. +// The return value is not read-only, but it shouldn't be changed in the caller functions. +// The function is thread-safe. +func (c *bindCache) GetBindRecordBySQLDigest(sqlDigest string) (*BindRecord, error) { + c.lock.Lock() + defer c.lock.Unlock() + bindings := c.get(bindCacheKey(sqlDigest)) + if len(bindings) > 1 { + // currently, we only allow one binding for a sql + return nil, errors.New("more than 1 binding matched") + } + if len(bindings) == 0 || len(bindings[0].Bindings) == 0 { + return nil, errors.New("can't find any binding for '" + sqlDigest + "'") + } + return bindings[0], nil +} + // GetAllBindRecords return all the bindRecords from the bindCache. // The return value is not read-only, but it shouldn't be changed in the caller functions. // The function is thread-safe. diff --git a/bindinfo/bind_record.go b/bindinfo/bind_record.go index 63517d91ac189..6395bbaa278ba 100644 --- a/bindinfo/bind_record.go +++ b/bindinfo/bind_record.go @@ -54,6 +54,8 @@ const ( Evolve = "evolve" // Builtin indicates the binding is a builtin record for internal locking purpose. It is also the status for the builtin binding. Builtin = "builtin" + // History indicate the binding is created from statement summary by plan digest + History = "history" ) // Binding stores the basic bind hint info. @@ -71,7 +73,9 @@ type Binding struct { // Hint is the parsed hints, it is used to bind hints to stmt node. Hint *hint.HintsSet `json:"-"` // ID is the string form of Hint. It would be non-empty only when the status is `Using` or `PendingVerify`. - ID string `json:"-"` + ID string `json:"-"` + SQLDigest string + PlanDigest string } func (b *Binding) isSame(rb *Binding) bool { diff --git a/bindinfo/bind_test.go b/bindinfo/bind_test.go index f34c94ae44b5a..cb8e62687df8f 100644 --- a/bindinfo/bind_test.go +++ b/bindinfo/bind_test.go @@ -29,6 +29,8 @@ import ( "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/util" + utilparser "github.com/pingcap/tidb/util/parser" + "github.com/pingcap/tidb/util/stmtsummary" "github.com/stretchr/testify/require" ) @@ -36,6 +38,7 @@ func TestPrepareCacheWithBinding(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec(`set tidb_enable_prepared_plan_cache=1`) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") tk.MustExec("create table t1(a int, b int, c int, key idx_b(b), key idx_c(c))") @@ -240,7 +243,7 @@ func TestPrepareCacheWithBinding(t *testing.T) { ps = []*util.ProcessInfo{tkProcess} tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10)) - require.False(t, tk.HasPlan4ExplainFor(res, "IndexReader")) + require.True(t, tk.HasPlan4ExplainFor(res, "IndexReader")) tk.MustExec("execute stmt1;") tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) @@ -297,6 +300,7 @@ func TestExplain(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") tk.MustExec("create table t1(id int)") @@ -313,7 +317,7 @@ func TestExplain(t *testing.T) { // Add test for SetOprStmt tk.MustExec("create index index_id on t1(id)") - require.False(t, tk.HasPlan("SELECT * from t1 union SELECT * from t1", "IndexReader")) + require.True(t, tk.HasPlan("SELECT * from t1 union SELECT * from t1", "IndexReader")) require.True(t, tk.HasPlan("SELECT * from t1 use index(index_id) union SELECT * from t1", "IndexReader")) tk.MustExec("create global binding for SELECT * from t1 union SELECT * from t1 using SELECT * from t1 use index(index_id) union SELECT * from t1") @@ -741,12 +745,12 @@ func TestStmtHints(t *testing.T) { tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int, index idx(a))") - tk.MustExec("create global binding for select * from t using select /*+ MAX_EXECUTION_TIME(100), MEMORY_QUOTA(1 GB) */ * from t use index(idx)") + tk.MustExec("create global binding for select * from t using select /*+ MAX_EXECUTION_TIME(100), MEMORY_QUOTA(2 GB) */ * from t use index(idx)") tk.MustQuery("select * from t") - require.Equal(t, int64(1073741824), tk.Session().GetSessionVars().StmtCtx.MemQuotaQuery) + require.Equal(t, int64(2147483648), tk.Session().GetSessionVars().MemTracker.GetBytesLimit()) require.Equal(t, uint64(100), tk.Session().GetSessionVars().StmtCtx.MaxExecutionTime) tk.MustQuery("select a, b from t") - require.Equal(t, int64(0), tk.Session().GetSessionVars().StmtCtx.MemQuotaQuery) + require.Equal(t, int64(1073741824), tk.Session().GetSessionVars().MemTracker.GetBytesLimit()) require.Equal(t, uint64(0), tk.Session().GetSessionVars().StmtCtx.MaxExecutionTime) } @@ -874,6 +878,7 @@ func TestNotEvolvePlanForReadStorageHint(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int, index idx_a(a), index idx_b(b))") tk.MustExec("insert into t values (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9), (10,10)") @@ -918,6 +923,7 @@ func TestBindingWithIsolationRead(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int, index idx_a(a), index idx_b(b))") tk.MustExec("insert into t values (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9), (10,10)") @@ -1237,3 +1243,148 @@ func TestGCBindRecord(t *testing.T) { tk.MustQuery("show global bindings").Check(testkit.Rows()) tk.MustQuery("select status from mysql.bind_info where original_sql = 'select * from `test` . `t` where `a` = ?'").Check(testkit.Rows()) } + +func TestBindSQLDigest(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(pk int primary key, a int, b int, key(a), key(b))") + + cases := []struct { + origin string + hint string + }{ + // agg hints + {"select count(1) from t", "select /*+ hash_agg() */ count(1) from t"}, + {"select count(1) from t", "select /*+ stream_agg() */ count(1) from t"}, + // join hints + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ tidb_smj(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ tidb_hj(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ inl_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ tidb_inlj(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ inl_hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + // index hints + {"select * from t", "select * from t use index(primary)"}, + {"select * from t", "select /*+ use_index(primary) */ * from t"}, + {"select * from t", "select * from t use index(a)"}, + {"select * from t", "select /*+ use_index(a) */ * from t use index(a)"}, + {"select * from t", "select * from t use index(b)"}, + {"select * from t", "select /*+ use_index(b) */ * from t use index(b)"}, + {"select a, b from t where a=1 or b=1", "select /*+ use_index_merge(t, a, b) */ a, b from t where a=1 or b=1"}, + {"select * from t where a=1", "select /*+ ignore_index(t, a) */ * from t where a=1"}, + // push-down hints + {"select * from t limit 10", "select /*+ limit_to_cop() */ * from t limit 10"}, + {"select a, count(*) from t group by a", "select /*+ agg_to_cop() */ a, count(*) from t group by a"}, + // index-merge hints + {"select a, b from t where a>1 or b>1", "select /*+ no_index_merge() */ a, b from t where a>1 or b>1"}, + {"select a, b from t where a>1 or b>1", "select /*+ use_index_merge(t, a, b) */ a, b from t where a>1 or b>1"}, + // runtime hints + {"select * from t", "select /*+ memory_quota(1024 MB) */ * from t"}, + {"select * from t", "select /*+ max_execution_time(1000) */ * from t"}, + // storage hints + {"select * from t", "select /*+ read_from_storage(tikv[t]) */ * from t"}, + // others + {"select t1.a, t1.b from t t1 where t1.a in (select t2.a from t t2)", "select /*+ use_toja(true) */ t1.a, t1.b from t t1 where t1.a in (select t2.a from t t2)"}, + } + for _, c := range cases { + stmtsummary.StmtSummaryByDigestMap.Clear() + utilCleanBindingEnv(tk, dom) + sql := "create global binding for " + c.origin + " using " + c.hint + tk.MustExec(sql) + res := tk.MustQuery(`show global bindings`).Rows() + require.Equal(t, len(res[0]), 11) + + parser4binding := parser.New() + originNode, err := parser4binding.ParseOneStmt(c.origin, "utf8mb4", "utf8mb4_general_ci") + require.NoError(t, err) + _, sqlDigestWithDB := parser.NormalizeDigest(utilparser.RestoreWithDefaultDB(originNode, "test", c.origin)) + require.Equal(t, res[0][9], sqlDigestWithDB.String()) + } +} + +func TestDropBindBySQLDigest(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(pk int primary key, a int, b int, key(a), key(b))") + + cases := []struct { + origin string + hint string + }{ + // agg hints + {"select count(1) from t", "select /*+ hash_agg() */ count(1) from t"}, + {"select count(1) from t", "select /*+ stream_agg() */ count(1) from t"}, + // join hints + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ tidb_smj(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ tidb_hj(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ inl_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ tidb_inlj(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + {"select * from t t1, t t2 where t1.a=t2.a", "select /*+ inl_hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a"}, + // index hints + {"select * from t", "select * from t use index(primary)"}, + {"select * from t", "select /*+ use_index(primary) */ * from t"}, + {"select * from t", "select * from t use index(a)"}, + {"select * from t", "select /*+ use_index(a) */ * from t use index(a)"}, + {"select * from t", "select * from t use index(b)"}, + {"select * from t", "select /*+ use_index(b) */ * from t use index(b)"}, + {"select a, b from t where a=1 or b=1", "select /*+ use_index_merge(t, a, b) */ a, b from t where a=1 or b=1"}, + {"select * from t where a=1", "select /*+ ignore_index(t, a) */ * from t where a=1"}, + // push-down hints + {"select * from t limit 10", "select /*+ limit_to_cop() */ * from t limit 10"}, + {"select a, count(*) from t group by a", "select /*+ agg_to_cop() */ a, count(*) from t group by a"}, + // index-merge hints + {"select a, b from t where a>1 or b>1", "select /*+ no_index_merge() */ a, b from t where a>1 or b>1"}, + {"select a, b from t where a>1 or b>1", "select /*+ use_index_merge(t, a, b) */ a, b from t where a>1 or b>1"}, + // runtime hints + {"select * from t", "select /*+ memory_quota(1024 MB) */ * from t"}, + {"select * from t", "select /*+ max_execution_time(1000) */ * from t"}, + // storage hints + {"select * from t", "select /*+ read_from_storage(tikv[t]) */ * from t"}, + // others + {"select t1.a, t1.b from t t1 where t1.a in (select t2.a from t t2)", "select /*+ use_toja(true) */ t1.a, t1.b from t t1 where t1.a in (select t2.a from t t2)"}, + } + + h := dom.BindHandle() + // global scope + for _, c := range cases { + utilCleanBindingEnv(tk, dom) + sql := "create global binding for " + c.origin + " using " + c.hint + tk.MustExec(sql) + h.ReloadBindings() + res := tk.MustQuery(`show global bindings`).Rows() + + require.Equal(t, len(res), 1) + require.Equal(t, len(res[0]), 11) + drop := fmt.Sprintf("drop global binding for sql digest '%s'", res[0][9]) + tk.MustExec(drop) + require.NoError(t, h.GCBindRecord()) + h.ReloadBindings() + tk.MustQuery("show global bindings").Check(testkit.Rows()) + } + + // session scope + for _, c := range cases { + utilCleanBindingEnv(tk, dom) + sql := "create binding for " + c.origin + " using " + c.hint + tk.MustExec(sql) + res := tk.MustQuery(`show bindings`).Rows() + + require.Equal(t, len(res), 1) + require.Equal(t, len(res[0]), 11) + drop := fmt.Sprintf("drop binding for sql digest '%s'", res[0][9]) + tk.MustExec(drop) + require.NoError(t, h.GCBindRecord()) + tk.MustQuery("show bindings").Check(testkit.Rows()) + } + + // exception cases + tk.MustGetErrMsg(fmt.Sprintf("drop binding for sql digest '%s'", "1"), "can't find any binding for '1'") + tk.MustGetErrMsg(fmt.Sprintf("drop binding for sql digest '%s'", ""), "sql digest is empty") +} diff --git a/bindinfo/capture_test.go b/bindinfo/capture_test.go index bff6b01045c0b..d1f375a6b63d7 100644 --- a/bindinfo/capture_test.go +++ b/bindinfo/capture_test.go @@ -22,9 +22,11 @@ import ( "github.com/pingcap/tidb/bindinfo" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/testkit" + utilparser "github.com/pingcap/tidb/util/parser" "github.com/pingcap/tidb/util/stmtsummary" "github.com/stretchr/testify/require" "go.opencensus.io/stats/view" @@ -397,7 +399,7 @@ func TestConcurrentCapture(t *testing.T) { // Simulate an existing binding generated by concurrent CREATE BINDING, which has not been synchronized to current tidb-server yet. // Actually, it is more common to be generated by concurrent baseline capture, I use Manual just for simpler test verification. tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t`', 'select * from `test` . `t`', '', 'enabled', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustQuery("select original_sql, source from mysql.bind_info where source != 'builtin'").Check(testkit.Rows( "select * from `test` . `t` manual", )) @@ -1011,5 +1013,11 @@ func TestCaptureHints(t *testing.T) { res := tk.MustQuery(`show global bindings`).Rows() require.Equal(t, len(res), 1) // this query is captured, and require.True(t, strings.Contains(res[0][1].(string), capCase.hint)) // the binding contains the expected hint + // test sql digest + parser4binding := parser.New() + originNode, err := parser4binding.ParseOneStmt(capCase.query, "utf8mb4", "utf8mb4_general_ci") + require.NoError(t, err) + _, sqlDigestWithDB := parser.NormalizeDigest(utilparser.RestoreWithDefaultDB(originNode, "test", capCase.query)) + require.Equal(t, res[0][9], sqlDigestWithDB.String()) } } diff --git a/bindinfo/handle.go b/bindinfo/handle.go index c69f3e45fb2bb..59919e2b5ad85 100644 --- a/bindinfo/handle.go +++ b/bindinfo/handle.go @@ -121,7 +121,8 @@ func (h *BindHandle) Reset(ctx sessionctx.Context) { h.bindInfo.parser = parser.New() h.invalidBindRecordMap.Value.Store(make(map[string]*bindRecordUpdate)) h.invalidBindRecordMap.flushFunc = func(record *BindRecord) error { - return h.DropBindRecord(record.OriginalSQL, record.Db, &record.Bindings[0]) + _, err := h.DropBindRecord(record.OriginalSQL, record.Db, &record.Bindings[0]) + return err } h.pendingVerifyBindRecordMap.Value.Store(make(map[string]*bindRecordUpdate)) h.pendingVerifyBindRecordMap.flushFunc = func(record *BindRecord) error { @@ -145,7 +146,7 @@ func (h *BindHandle) Update(fullLoad bool) (err error) { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBindInfo) // No need to acquire the session context lock for ExecRestrictedSQL, it // uses another background session. - rows, _, err := exec.ExecRestrictedSQL(ctx, nil, `SELECT original_sql, bind_sql, default_db, status, create_time, update_time, charset, collation, source + rows, _, err := exec.ExecRestrictedSQL(ctx, nil, `SELECT original_sql, bind_sql, default_db, status, create_time, update_time, charset, collation, source, sql_digest, plan_digest FROM mysql.bind_info WHERE update_time > %? ORDER BY update_time, create_time`, updateTime) if err != nil { @@ -260,7 +261,7 @@ func (h *BindHandle) CreateBindRecord(sctx sessionctx.Context, record *BindRecor record.Bindings[i].UpdateTime = now // Insert the BindRecord to the storage. - _, err = exec.ExecuteInternal(ctx, `INSERT INTO mysql.bind_info VALUES (%?,%?, %?, %?, %?, %?, %?, %?, %?)`, + _, err = exec.ExecuteInternal(ctx, `INSERT INTO mysql.bind_info VALUES (%?,%?, %?, %?, %?, %?, %?, %?, %?, %?, %?)`, record.OriginalSQL, record.Bindings[i].BindSQL, record.Db, @@ -270,6 +271,8 @@ func (h *BindHandle) CreateBindRecord(sctx sessionctx.Context, record *BindRecor record.Bindings[i].Charset, record.Bindings[i].Collation, record.Bindings[i].Source, + record.Bindings[i].SQLDigest, + record.Bindings[i].PlanDigest, ) if err != nil { return err @@ -348,8 +351,18 @@ func (h *BindHandle) AddBindRecord(sctx sessionctx.Context, record *BindRecord) } record.Bindings[i].UpdateTime = now + if record.Bindings[i].SQLDigest == "" { + parser4binding := parser.New() + var originNode ast.StmtNode + originNode, err = parser4binding.ParseOneStmt(record.OriginalSQL, record.Bindings[i].Charset, record.Bindings[i].Collation) + if err != nil { + return err + } + _, sqlDigestWithDB := parser.NormalizeDigest(utilparser.RestoreWithDefaultDB(originNode, record.Db, record.OriginalSQL)) + record.Bindings[i].SQLDigest = sqlDigestWithDB.String() + } // Insert the BindRecord to the storage. - _, err = exec.ExecuteInternal(ctx, `INSERT INTO mysql.bind_info VALUES (%?, %?, %?, %?, %?, %?, %?, %?, %?)`, + _, err = exec.ExecuteInternal(ctx, `INSERT INTO mysql.bind_info VALUES (%?, %?, %?, %?, %?, %?, %?, %?, %?, %?, %?)`, record.OriginalSQL, record.Bindings[i].BindSQL, record.Db, @@ -359,6 +372,8 @@ func (h *BindHandle) AddBindRecord(sctx sessionctx.Context, record *BindRecord) record.Bindings[i].Charset, record.Bindings[i].Collation, record.Bindings[i].Source, + record.Bindings[i].SQLDigest, + record.Bindings[i].PlanDigest, ) if err != nil { return err @@ -368,7 +383,7 @@ func (h *BindHandle) AddBindRecord(sctx sessionctx.Context, record *BindRecord) } // DropBindRecord drops a BindRecord to the storage and BindRecord int the cache. -func (h *BindHandle) DropBindRecord(originalSQL, db string, binding *Binding) (err error) { +func (h *BindHandle) DropBindRecord(originalSQL, db string, binding *Binding) (deletedRows uint64, err error) { db = strings.ToLower(db) h.bindInfo.Lock() h.sctx.Lock() @@ -380,9 +395,8 @@ func (h *BindHandle) DropBindRecord(originalSQL, db string, binding *Binding) (e exec, _ := h.sctx.Context.(sqlexec.SQLExecutor) _, err = exec.ExecuteInternal(ctx, "BEGIN PESSIMISTIC") if err != nil { - return err + return 0, err } - var deleteRows int defer func() { if err != nil { _, err1 := exec.ExecuteInternal(ctx, "ROLLBACK") @@ -391,7 +405,7 @@ func (h *BindHandle) DropBindRecord(originalSQL, db string, binding *Binding) (e } _, err = exec.ExecuteInternal(ctx, "COMMIT") - if err != nil || deleteRows == 0 { + if err != nil || deletedRows == 0 { return } @@ -404,7 +418,7 @@ func (h *BindHandle) DropBindRecord(originalSQL, db string, binding *Binding) (e // Lock mysql.bind_info to synchronize with CreateBindRecord / AddBindRecord / DropBindRecord on other tidb instances. if err = h.lockBindInfoTable(); err != nil { - return err + return 0, err } updateTs := types.NewTime(types.FromGoTime(time.Now()), mysql.TypeTimestamp, 3).String() @@ -416,9 +430,20 @@ func (h *BindHandle) DropBindRecord(originalSQL, db string, binding *Binding) (e _, err = exec.ExecuteInternal(ctx, `UPDATE mysql.bind_info SET status = %?, update_time = %? WHERE original_sql = %? AND update_time < %? AND bind_sql = %? and status != %?`, deleted, updateTs, originalSQL, updateTs, binding.BindSQL, deleted) } + if err != nil { + return 0, err + } - deleteRows = int(h.sctx.Context.GetSessionVars().StmtCtx.AffectedRows()) - return err + return h.sctx.Context.GetSessionVars().StmtCtx.AffectedRows(), nil +} + +// DropBindRecordByDigest drop BindRecord to the storage and BindRecord int the cache. +func (h *BindHandle) DropBindRecordByDigest(sqlDigest string) (deletedRows uint64, err error) { + oldRecord, err := h.GetBindRecordBySQLDigest(sqlDigest) + if err != nil { + return 0, err + } + return h.DropBindRecord(oldRecord.OriginalSQL, strings.ToLower(oldRecord.Db), nil) } // SetBindRecordStatus set a BindRecord's status to the storage and bind cache. @@ -508,6 +533,15 @@ func (h *BindHandle) SetBindRecordStatus(originalSQL string, binding *Binding, n return } +// SetBindRecordStatusByDigest set a BindRecord's status to the storage and bind cache. +func (h *BindHandle) SetBindRecordStatusByDigest(newStatus, sqlDigest string) (ok bool, err error) { + oldRecord, err := h.GetBindRecordBySQLDigest(sqlDigest) + if err != nil { + return false, err + } + return h.SetBindRecordStatus(oldRecord.OriginalSQL, nil, newStatus) +} + // GCBindRecord physically removes the deleted bind records in mysql.bind_info. func (h *BindHandle) GCBindRecord() (err error) { h.bindInfo.Lock() @@ -642,6 +676,11 @@ func (h *BindHandle) GetBindRecord(hash, normdOrigSQL, db string) *BindRecord { return h.bindInfo.Load().(*bindCache).GetBindRecord(hash, normdOrigSQL, db) } +// GetBindRecordBySQLDigest returns the BindRecord of the sql digest. +func (h *BindHandle) GetBindRecordBySQLDigest(sqlDigest string) (*BindRecord, error) { + return h.bindInfo.Load().(*bindCache).GetBindRecordBySQLDigest(sqlDigest) +} + // GetAllBindRecord returns all bind records in cache. func (h *BindHandle) GetAllBindRecord() (bindRecords []*BindRecord) { return h.bindInfo.Load().(*bindCache).GetAllBindRecords() @@ -678,6 +717,8 @@ func (h *BindHandle) newBindRecord(row chunk.Row) (string, *BindRecord, error) { Charset: row.GetString(6), Collation: row.GetString(7), Source: row.GetString(8), + SQLDigest: row.GetString(9), + PlanDigest: row.GetString(10), } bindRecord := &BindRecord{ OriginalSQL: row.GetString(0), @@ -898,6 +939,7 @@ func (h *BindHandle) CaptureBaselines() { Charset: charset, Collation: collation, Source: Capture, + SQLDigest: digest.String(), } // We don't need to pass the `sctx` because the BindSQL has been validated already. err = h.CreateBindRecord(nil, &BindRecord{OriginalSQL: normalizedSQL, Db: dbName, Bindings: []Binding{binding}}) @@ -938,12 +980,12 @@ func getHintsForSQL(sctx sessionctx.Context, sql string) (string, error) { } // GenerateBindSQL generates binding sqls from stmt node and plan hints. -func GenerateBindSQL(ctx context.Context, stmtNode ast.StmtNode, planHint string, captured bool, defaultDB string) string { +func GenerateBindSQL(ctx context.Context, stmtNode ast.StmtNode, planHint string, skipCheckIfHasParam bool, defaultDB string) string { // If would be nil for very simple cases such as point get, we do not need to evolve for them. if planHint == "" { return "" } - if !captured { + if !skipCheckIfHasParam { paramChecker := ¶mMarkerChecker{} stmtNode.Accept(paramChecker) // We need to evolve on current sql, but we cannot restore values for paramMarkers yet, @@ -1119,6 +1161,7 @@ func (h *BindHandle) getRunningDuration(sctx sessionctx.Context, db, sql string, } ctx, cancelFunc := context.WithCancel(ctx) timer := time.NewTimer(maxTime) + defer timer.Stop() resultChan := make(chan error) startTime := time.Now() go runSQL(ctx, sctx, sql, resultChan) @@ -1185,7 +1228,8 @@ func (h *BindHandle) HandleEvolvePlanTask(sctx sessionctx.Context, adminEvolve b // since it is still in the bind record. Now we just drop it and if it is actually retryable, // we will hope for that we can capture this evolve task again. if err != nil { - return h.DropBindRecord(originalSQL, db, &binding) + _, err = h.DropBindRecord(originalSQL, db, &binding) + return err } // If the accepted plan timeouts, it is hard to decide the timeout for verify plan. // Currently we simply mark the verify plan as `using` if it could run successfully within maxTime. @@ -1195,7 +1239,8 @@ func (h *BindHandle) HandleEvolvePlanTask(sctx sessionctx.Context, adminEvolve b sctx.GetSessionVars().UsePlanBaselines = false verifyPlanTime, err := h.getRunningDuration(sctx, db, binding.BindSQL, maxTime) if err != nil { - return h.DropBindRecord(originalSQL, db, &binding) + _, err = h.DropBindRecord(originalSQL, db, &binding) + return err } if verifyPlanTime == -1 || (float64(verifyPlanTime)*acceptFactor > float64(currentPlanTime)) { binding.Status = Rejected diff --git a/bindinfo/handle_test.go b/bindinfo/handle_test.go index 7831dc1358775..ffea398781f8b 100644 --- a/bindinfo/handle_test.go +++ b/bindinfo/handle_test.go @@ -107,7 +107,7 @@ func TestBindingLastUpdateTimeWithInvalidBind(t *testing.T) { require.Equal(t, updateTime0, "0000-00-00 00:00:00") tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t`', 'select * from `test` . `t` use index(`idx`)', 'test', 'enabled', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int)") @@ -137,8 +137,9 @@ func TestBindParse(t *testing.T) { charset := "utf8mb4" collation := "utf8mb4_bin" source := bindinfo.Manual - sql := fmt.Sprintf(`INSERT INTO mysql.bind_info(original_sql,bind_sql,default_db,status,create_time,update_time,charset,collation,source) VALUES ('%s', '%s', '%s', '%s', NOW(), NOW(),'%s', '%s', '%s')`, - originSQL, bindSQL, defaultDb, status, charset, collation, source) + mockDigest := "0f644e22c38ecc71d4592c52df127df7f86b6ca7f7c0ee899113b794578f9396" + sql := fmt.Sprintf(`INSERT INTO mysql.bind_info(original_sql,bind_sql,default_db,status,create_time,update_time,charset,collation,source, sql_digest, plan_digest) VALUES ('%s', '%s', '%s', '%s', NOW(), NOW(),'%s', '%s', '%s', '%s', '%s')`, + originSQL, bindSQL, defaultDb, status, charset, collation, source, mockDigest, mockDigest) tk.MustExec(sql) bindHandle := bindinfo.NewBindHandle(tk.Session()) err := bindHandle.Update(true) @@ -221,7 +222,7 @@ func TestEvolveInvalidBindings(t *testing.T) { tk.MustExec("create global binding for select * from t where a > 10 using select /*+ USE_INDEX(t) */ * from t where a > 10") // Manufacture a rejected binding by hacking mysql.bind_info. tk.MustExec("insert into mysql.bind_info values('select * from test . t where a > ?', 'SELECT /*+ USE_INDEX(t,idx_a) */ * FROM test.t WHERE a > 10', 'test', 'rejected', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustQuery("select bind_sql, status from mysql.bind_info where source != 'builtin'").Sort().Check(testkit.Rows( "SELECT /*+ USE_INDEX(`t` )*/ * FROM `test`.`t` WHERE `a` > 10 enabled", "SELECT /*+ USE_INDEX(t,idx_a) */ * FROM test.t WHERE a > 10 rejected", @@ -242,6 +243,8 @@ func TestEvolveInvalidBindings(t *testing.T) { require.Equal(t, "SELECT /*+ USE_INDEX(t,idx_a) */ * FROM test.t WHERE a > 10", rows[1][1]) status = rows[1][3].(string) require.True(t, status == bindinfo.Enabled || status == bindinfo.Rejected) + _, sqlDigestWithDB := parser.NormalizeDigest("select * from test.t where a > 10") // test sqlDigest if exists after add columns to mysql.bind_info + require.Equal(t, rows[0][9], sqlDigestWithDB.String()) } func TestSetBindingStatus(t *testing.T) { @@ -319,9 +322,9 @@ func TestSetBindingStatusWithoutBindingInCache(t *testing.T) { // Simulate creating bindings on other machines tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t` where `a` > ?', 'SELECT /*+ USE_INDEX(`t` `idx_a`)*/ * FROM `test`.`t` WHERE `a` > 10', 'test', 'deleted', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t` where `a` > ?', 'SELECT /*+ USE_INDEX(`t` `idx_a`)*/ * FROM `test`.`t` WHERE `a` > 10', 'test', 'enabled', '2000-01-02 09:00:00', '2000-01-02 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") dom.BindHandle().Clear() tk.MustExec("set binding disabled for select * from t where a > 10") tk.MustExec("admin reload bindings") @@ -334,9 +337,9 @@ func TestSetBindingStatusWithoutBindingInCache(t *testing.T) { // Simulate creating bindings on other machines tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t` where `a` > ?', 'SELECT * FROM `test`.`t` WHERE `a` > 10', 'test', 'deleted', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t` where `a` > ?', 'SELECT * FROM `test`.`t` WHERE `a` > 10', 'test', 'disabled', '2000-01-02 09:00:00', '2000-01-02 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") dom.BindHandle().Clear() tk.MustExec("set binding enabled for select * from t where a > 10") tk.MustExec("admin reload bindings") @@ -547,6 +550,7 @@ func TestGlobalBinding(t *testing.T) { require.NotNil(t, bind.UpdateTime) _, err = tk.Exec("drop global " + testSQL.dropSQL) + require.Equal(t, uint64(1), tk.Session().AffectedRows()) require.NoError(t, err) bindData = dom.BindHandle().GetBindRecord(hash, sql, "test") require.Nil(t, bindData) diff --git a/bindinfo/main_test.go b/bindinfo/main_test.go index 2d358809e8059..65d9859fbea21 100644 --- a/bindinfo/main_test.go +++ b/bindinfo/main_test.go @@ -25,7 +25,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/bindinfo/session_handle.go b/bindinfo/session_handle.go index e6baebe3ea960..27b8168ef8e17 100644 --- a/bindinfo/session_handle.go +++ b/bindinfo/session_handle.go @@ -33,13 +33,12 @@ import ( // SessionHandle is used to handle all session sql bind operations. type SessionHandle struct { - ch *bindCache - parser *parser.Parser + ch *bindCache } // NewSessionBindHandle creates a new SessionBindHandle. -func NewSessionBindHandle(parser *parser.Parser) *SessionHandle { - sessionHandle := &SessionHandle{parser: parser} +func NewSessionBindHandle() *SessionHandle { + sessionHandle := &SessionHandle{} sessionHandle.ch = newBindCache() return sessionHandle } @@ -98,11 +97,25 @@ func (h *SessionHandle) DropBindRecord(originalSQL, db string, binding *Binding) return nil } +// DropBindRecordByDigest drop BindRecord in the cache. +func (h *SessionHandle) DropBindRecordByDigest(sqlDigest string) error { + oldRecord, err := h.GetBindRecordBySQLDigest(sqlDigest) + if err != nil { + return err + } + return h.DropBindRecord(oldRecord.OriginalSQL, strings.ToLower(oldRecord.Db), nil) +} + // GetBindRecord return the BindMeta of the (normdOrigSQL,db) if BindMeta exist. func (h *SessionHandle) GetBindRecord(hash, normdOrigSQL, db string) *BindRecord { return h.ch.GetBindRecord(hash, normdOrigSQL, db) } +// GetBindRecordBySQLDigest return all BindMeta corresponding to sqlDigest. +func (h *SessionHandle) GetBindRecordBySQLDigest(sqlDigest string) (*BindRecord, error) { + return h.ch.GetBindRecordBySQLDigest(sqlDigest) +} + // GetAllBindRecord return all session bind info. func (h *SessionHandle) GetAllBindRecord() (bindRecords []*BindRecord) { return h.ch.GetAllBindRecords() diff --git a/bindinfo/session_handle_test.go b/bindinfo/session_handle_test.go index a60f8ff41cd12..a9b05c03eda18 100644 --- a/bindinfo/session_handle_test.go +++ b/bindinfo/session_handle_test.go @@ -219,7 +219,7 @@ func TestBaselineDBLowerCase(t *testing.T) { // Simulate existing bindings with upper case default_db. tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t`', 'select * from `spm` . `t`', 'SPM', 'enabled', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustQuery("select original_sql, default_db from mysql.bind_info where original_sql = 'select * from `spm` . `t`'").Check(testkit.Rows( "select * from `spm` . `t` SPM", )) @@ -237,7 +237,7 @@ func TestBaselineDBLowerCase(t *testing.T) { utilCleanBindingEnv(tk, dom) // Simulate existing bindings with upper case default_db. tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t`', 'select * from `spm` . `t`', 'SPM', 'enabled', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustQuery("select original_sql, default_db from mysql.bind_info where original_sql = 'select * from `spm` . `t`'").Check(testkit.Rows( "select * from `spm` . `t` SPM", )) @@ -274,13 +274,13 @@ func TestShowGlobalBindings(t *testing.T) { require.Len(t, rows, 0) // Simulate existing bindings in the mysql.bind_info. tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t`', 'select * from `spm` . `t` USE INDEX (`a`)', 'SPM', 'enabled', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t0`', 'select * from `spm` . `t0` USE INDEX (`a`)', 'SPM', 'enabled', '2000-01-02 09:00:00', '2000-01-02 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t`', 'select /*+ use_index(`t` `a`)*/ * from `spm` . `t`', 'SPM', 'enabled', '2000-01-03 09:00:00', '2000-01-03 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t0`', 'select /*+ use_index(`t0` `a`)*/ * from `spm` . `t0`', 'SPM', 'enabled', '2000-01-04 09:00:00', '2000-01-04 09:00:00', '', '','" + - bindinfo.Manual + "')") + bindinfo.Manual + "', '', '')") tk.MustExec("admin reload bindings") rows = tk.MustQuery("show global bindings").Rows() require.Len(t, rows, 4) @@ -521,3 +521,14 @@ func TestPreparedStmt(t *testing.T) { require.Len(t, tk.Session().GetSessionVars().StmtCtx.IndexNames, 1) require.Equal(t, "t:idx_c", tk.Session().GetSessionVars().StmtCtx.IndexNames[0]) } + +func TestSetVarBinding(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t1 (a int, b varchar(20))") + tk.MustExec("insert into t1 values (1, '111111111111111')") + tk.MustExec("insert into t1 values (2, '222222222222222')") + tk.MustExec("create binding for select group_concat(b) from test.t1 using select /*+ SET_VAR(group_concat_max_len = 4) */ group_concat(b) from test.t1 ;") + tk.MustQuery("select group_concat(b) from test.t1").Check(testkit.Rows("1111")) +} diff --git a/br/COMPATIBILITY_TEST.md b/br/COMPATIBILITY_TEST.md index b5580835baee8..44984ebcd2bfa 100644 --- a/br/COMPATIBILITY_TEST.md +++ b/br/COMPATIBILITY_TEST.md @@ -3,7 +3,7 @@ ## Background We had some incompatibility issues in the past, which made BR cannot restore backed up data in some situations. -So we need a test workflow to check the compatiblity. +So we need a test workflow to check the compatibility. ## Goal diff --git a/br/cmd/br/restore.go b/br/cmd/br/restore.go index 5f91bee91c6a9..e826df0e59e77 100644 --- a/br/cmd/br/restore.go +++ b/br/cmd/br/restore.go @@ -199,6 +199,5 @@ func newStreamRestoreCommand() *cobra.Command { } task.DefineFilterFlags(command, filterOutSysAndMemTables, true) task.DefineStreamRestoreFlags(command) - command.Hidden = true return command } diff --git a/br/cmd/tidb-lightning-ctl/main.go b/br/cmd/tidb-lightning-ctl/main.go index 4dc70af929083..b0d20ae813734 100644 --- a/br/cmd/tidb-lightning-ctl/main.go +++ b/br/cmd/tidb-lightning-ctl/main.go @@ -88,7 +88,7 @@ func run() error { if err != nil { return err } - if err = cfg.TiDB.Security.RegisterMySQL(); err != nil { + if err = cfg.TiDB.Security.BuildTLSConfig(); err != nil { return err } diff --git a/br/pkg/aws/BUILD.bazel b/br/pkg/aws/BUILD.bazel index 6f33637abc5f3..28f58d2a1e1ad 100644 --- a/br/pkg/aws/BUILD.bazel +++ b/br/pkg/aws/BUILD.bazel @@ -25,5 +25,9 @@ go_test( name = "aws_test", srcs = ["ebs_test.go"], embed = [":aws"], - deps = ["@com_github_stretchr_testify//require"], + deps = [ + "@com_github_aws_aws_sdk_go//aws", + "@com_github_aws_aws_sdk_go//service/ec2", + "@com_github_stretchr_testify//require", + ], ) diff --git a/br/pkg/aws/ebs.go b/br/pkg/aws/ebs.go index 9ded291e1f9b9..fb96b95578ffb 100644 --- a/br/pkg/aws/ebs.go +++ b/br/pkg/aws/ebs.go @@ -307,17 +307,9 @@ func (e *EC2Session) WaitVolumesCreated(volumeIDMap map[string]string, progress return 0, errors.Trace(err) } - var unfinishedVolumes []*string - for _, volume := range resp.Volumes { - if *volume.State == ec2.VolumeStateAvailable { - log.Info("volume is available", zap.String("id", *volume.SnapshotId)) - totalVolumeSize += *volume.Size - progress.Inc() - } else { - log.Debug("volume creating...", zap.Stringer("volume", volume)) - unfinishedVolumes = append(unfinishedVolumes, volume.SnapshotId) - } - } + createdVolumeSize, unfinishedVolumes := e.HandleDescribeVolumesResponse(resp) + progress.IncBy(int64(len(pendingVolumes) - len(unfinishedVolumes))) + totalVolumeSize += createdVolumeSize pendingVolumes = unfinishedVolumes } log.Info("all pending volume are created.") @@ -357,3 +349,20 @@ func (e *EC2Session) DeleteVolumes(volumeIDMap map[string]string) { func ec2Tag(key, val string) *ec2.Tag { return &ec2.Tag{Key: &key, Value: &val} } + +func (e *EC2Session) HandleDescribeVolumesResponse(resp *ec2.DescribeVolumesOutput) (int64, []*string) { + totalVolumeSize := int64(0) + + var unfinishedVolumes []*string + for _, volume := range resp.Volumes { + if *volume.State == ec2.VolumeStateAvailable { + log.Info("volume is available", zap.String("id", *volume.VolumeId)) + totalVolumeSize += *volume.Size + } else { + log.Debug("volume creating...", zap.Stringer("volume", volume)) + unfinishedVolumes = append(unfinishedVolumes, volume.VolumeId) + } + } + + return totalVolumeSize, unfinishedVolumes +} diff --git a/br/pkg/aws/ebs_test.go b/br/pkg/aws/ebs_test.go index 695f31a73c477..d7f3be2a4a4a1 100644 --- a/br/pkg/aws/ebs_test.go +++ b/br/pkg/aws/ebs_test.go @@ -16,26 +16,63 @@ package aws import ( "testing" + awsapi "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" "github.com/stretchr/testify/require" ) func TestEC2SessionExtractSnapProgress(t *testing.T) { - strPtr := func(s string) *string { - return &s - } tests := []struct { str *string want int64 }{ {nil, 0}, - {strPtr("12.12%"), 12}, - {strPtr("44.99%"), 44}, - {strPtr(" 89.89% "), 89}, - {strPtr("100%"), 100}, - {strPtr("111111%"), 100}, + {awsapi.String("12.12%"), 12}, + {awsapi.String("44.99%"), 44}, + {awsapi.String(" 89.89% "), 89}, + {awsapi.String("100%"), 100}, + {awsapi.String("111111%"), 100}, } e := &EC2Session{} for _, tt := range tests { require.Equal(t, tt.want, e.extractSnapProgress(tt.str)) } } + +func createVolume(snapshotId string, volumeId string, state string) *ec2.Volume { + return &ec2.Volume{ + Attachments: nil, + AvailabilityZone: awsapi.String("us-west-2"), + CreateTime: nil, + Encrypted: awsapi.Bool(true), + FastRestored: awsapi.Bool(true), + Iops: awsapi.Int64(3000), + KmsKeyId: nil, + MultiAttachEnabled: awsapi.Bool(true), + OutpostArn: awsapi.String("arn:12342"), + Size: awsapi.Int64(1), + SnapshotId: awsapi.String(snapshotId), + State: awsapi.String(state), + Tags: nil, + Throughput: nil, + VolumeId: awsapi.String(volumeId), + VolumeType: awsapi.String("gp3"), + } +} +func TestHandleDescribeVolumesResponse(t *testing.T) { + curentVolumesStates := &ec2.DescribeVolumesOutput{ + NextToken: awsapi.String("fake token"), + Volumes: []*ec2.Volume{ + createVolume("snap-0873674883", "vol-98768979", "available"), + createVolume("snap-0873674883", "vol-98768979", "creating"), + createVolume("snap-0873674883", "vol-98768979", "available"), + createVolume("snap-0873674883", "vol-98768979", "available"), + createVolume("snap-0873674883", "vol-98768979", "available"), + }, + } + + e := &EC2Session{} + createdVolumeSize, unfinishedVolumes := e.HandleDescribeVolumesResponse(curentVolumesStates) + require.Equal(t, int64(4), createdVolumeSize) + require.Equal(t, 1, len(unfinishedVolumes)) +} diff --git a/br/pkg/backup/BUILD.bazel b/br/pkg/backup/BUILD.bazel index c8cad292f4607..65ff4288987a1 100644 --- a/br/pkg/backup/BUILD.bazel +++ b/br/pkg/backup/BUILD.bazel @@ -12,6 +12,7 @@ go_library( importpath = "github.com/pingcap/tidb/br/pkg/backup", visibility = ["//visibility:public"], deps = [ + "//br/pkg/checkpoint", "//br/pkg/checksum", "//br/pkg/conn", "//br/pkg/conn/util", diff --git a/br/pkg/backup/client.go b/br/pkg/backup/client.go index 062fb771c0e5e..927f3937963a0 100644 --- a/br/pkg/backup/client.go +++ b/br/pkg/backup/client.go @@ -3,7 +3,9 @@ package backup import ( + "bytes" "context" + "encoding/base64" "encoding/hex" "encoding/json" "fmt" @@ -21,6 +23,7 @@ import ( "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" + "github.com/pingcap/tidb/br/pkg/checkpoint" "github.com/pingcap/tidb/br/pkg/conn" connutil "github.com/pingcap/tidb/br/pkg/conn/util" berrors "github.com/pingcap/tidb/br/pkg/errors" @@ -90,18 +93,31 @@ type Client struct { backend *backuppb.StorageBackend apiVersion kvrpcpb.APIVersion + cipher *backuppb.CipherInfo + checkpointMeta *checkpoint.CheckpointMetadata + checkpointRunner *checkpoint.CheckpointRunner + gcTTL int64 } // NewBackupClient returns a new backup client. -func NewBackupClient(ctx context.Context, mgr ClientMgr) (*Client, error) { +func NewBackupClient(ctx context.Context, mgr ClientMgr) *Client { log.Info("new backup client") pdClient := mgr.GetPDClient() clusterID := pdClient.GetClusterID(ctx) return &Client{ clusterID: clusterID, mgr: mgr, - }, nil + + cipher: nil, + checkpointMeta: nil, + checkpointRunner: nil, + } +} + +// SetCipher for checkpoint to encrypt sst file's metadata +func (bc *Client) SetCipher(cipher *backuppb.CipherInfo) { + bc.cipher = cipher } // GetTS gets a new timestamp from PD. @@ -120,6 +136,11 @@ func (bc *Client) GetTS(ctx context.Context, duration time.Duration, ts uint64) backupTS uint64 err error ) + + if bc.checkpointMeta != nil { + log.Info("reuse checkpoint BackupTS", zap.Uint64("backup-ts", bc.checkpointMeta.BackupTS)) + return bc.checkpointMeta.BackupTS, nil + } if ts > 0 { backupTS = ts } else { @@ -160,6 +181,15 @@ func (bc *Client) SetLockFile(ctx context.Context) error { "This file exists to remind other backup jobs won't use this path")) } +// GetSafePointID get the gc-safe-point's service-id from either checkpoint or immediate generation +func (bc *Client) GetSafePointID() string { + if bc.checkpointMeta != nil { + log.Info("reuse the checkpoint gc-safepoint service id", zap.String("service-id", bc.checkpointMeta.GCServiceId)) + return bc.checkpointMeta.GCServiceId + } + return utils.MakeSafePointID() +} + // SetGCTTL set gcTTL for client. func (bc *Client) SetGCTTL(ttl int64) { if ttl <= 0 { @@ -183,13 +213,17 @@ func (bc *Client) GetStorage() storage.ExternalStorage { return bc.storage } -// SetStorage set ExternalStorage for client. -func (bc *Client) SetStorage(ctx context.Context, backend *backuppb.StorageBackend, opts *storage.ExternalStorageOptions) error { - var err error - bc.storage, err = storage.New(ctx, backend, opts) +// SetStorageAndCheckNotInUse sets ExternalStorage for client and check storage not in used by others. +func (bc *Client) SetStorageAndCheckNotInUse( + ctx context.Context, + backend *backuppb.StorageBackend, + opts *storage.ExternalStorageOptions, +) error { + err := bc.SetStorage(ctx, backend, opts) if err != nil { return errors.Trace(err) } + // backupmeta already exists exist, err := bc.storage.FileExists(ctx, metautil.MetaFile) if err != nil { @@ -200,14 +234,158 @@ func (bc *Client) SetStorage(ctx context.Context, backend *backuppb.StorageBacke "there may be some backup files in the path already, "+ "please specify a correct backup directory!", bc.storage.URI()+"/"+metautil.MetaFile) } - err = CheckBackupStorageIsLocked(ctx, bc.storage) + // use checkpoint mode if checkpoint meta exists + exist, err = bc.storage.FileExists(ctx, checkpoint.CheckpointMetaPath) if err != nil { - return err + return errors.Annotatef(err, "error occurred when checking %s file", checkpoint.CheckpointMetaPath) } - bc.backend = backend + + // if there is no checkpoint meta, then checkpoint mode is not used + // or it is the first execution + if exist { + // load the config's hash to keep the config unchanged. + log.Info("load the checkpoint meta, so the existence of lockfile is allowed.") + bc.checkpointMeta, err = checkpoint.LoadCheckpointMetadata(ctx, bc.storage) + if err != nil { + return errors.Annotatef(err, "error occurred when loading %s file", checkpoint.CheckpointMetaPath) + } + } else { + err = CheckBackupStorageIsLocked(ctx, bc.storage) + if err != nil { + return err + } + } + return nil } +// CheckCheckpoint check whether the configs are the same +func (bc *Client) CheckCheckpoint(hash []byte) error { + if bc.checkpointMeta != nil && !bytes.Equal(bc.checkpointMeta.ConfigHash, hash) { + return errors.Annotatef(berrors.ErrInvalidArgument, "failed to backup to %v, "+ + "because the checkpoint mode is used, "+ + "but the hashs of the configs are not the same. Please check the config", + bc.storage.URI(), + ) + } + + // first execution or not using checkpoint mode yet + // or using the same config can pass the check + return nil +} + +func (bc *Client) GetCheckpointRunner() *checkpoint.CheckpointRunner { + return bc.checkpointRunner +} + +// StartCheckpointMeta will +// 1. saves the initial status into the external storage; +// 2. load the checkpoint data from external storage +// 3. start checkpoint runner +func (bc *Client) StartCheckpointRunner( + ctx context.Context, + cfgHash []byte, + backupTS uint64, + ranges []rtree.Range, + safePointID string, + progressCallBack func(ProgressUnit), +) (err error) { + if bc.checkpointMeta == nil { + bc.checkpointMeta = &checkpoint.CheckpointMetadata{ + GCServiceId: safePointID, + ConfigHash: cfgHash, + BackupTS: backupTS, + Ranges: ranges, + } + + // sync the checkpoint meta to the external storage at first + if err := checkpoint.SaveCheckpointMetadata(ctx, bc.storage, bc.checkpointMeta); err != nil { + return errors.Trace(err) + } + } else { + // otherwise, the checkpoint meta is loaded from the external storage, + // no need to save it again + // besides, there are exist checkpoint data need to be loaded before start checkpoint runner + bc.checkpointMeta.CheckpointDataMap, err = bc.loadCheckpointRanges(ctx, progressCallBack) + if err != nil { + return errors.Trace(err) + } + } + + bc.checkpointRunner, err = checkpoint.StartCheckpointRunner(ctx, bc.storage, bc.cipher, bc.mgr.GetPDClient()) + return errors.Trace(err) +} + +func (bc *Client) WaitForFinishCheckpoint(ctx context.Context) { + if bc.checkpointRunner != nil { + bc.checkpointRunner.WaitForFinish(ctx) + } +} + +// GetProgressRange loads the checkpoint(finished) sub-ranges of the current range, and calculate its incompleted sub-ranges. +func (bc *Client) GetProgressRange(r rtree.Range) (*rtree.ProgressRange, error) { + // use groupKey to distinguish different ranges + groupKey := base64.URLEncoding.EncodeToString(r.StartKey) + if bc.checkpointMeta != nil && len(bc.checkpointMeta.CheckpointDataMap) > 0 { + rangeTree, exists := bc.checkpointMeta.CheckpointDataMap[groupKey] + if exists { + incomplete := rangeTree.GetIncompleteRange(r.StartKey, r.EndKey) + delete(bc.checkpointMeta.CheckpointDataMap, groupKey) + return &rtree.ProgressRange{ + Res: rangeTree, + Incomplete: incomplete, + Origin: r, + GroupKey: groupKey, + }, nil + } + } + + // the origin range are not recorded in checkpoint + // return the default progress range + return &rtree.ProgressRange{ + Res: rtree.NewRangeTree(), + Incomplete: []rtree.Range{ + r, + }, + Origin: r, + GroupKey: groupKey, + }, nil +} + +// LoadCheckpointRange loads the checkpoint(finished) sub-ranges of the current range, and calculate its incompleted sub-ranges. +func (bc *Client) loadCheckpointRanges(ctx context.Context, progressCallBack func(ProgressUnit)) (map[string]rtree.RangeTree, error) { + rangeDataMap := make(map[string]rtree.RangeTree) + + pastDureTime, err := checkpoint.WalkCheckpointFile(ctx, bc.storage, bc.cipher, func(groupKey string, rg *rtree.Range) { + rangeTree, exists := rangeDataMap[groupKey] + if !exists { + rangeTree = rtree.NewRangeTree() + rangeDataMap[groupKey] = rangeTree + } + rangeTree.Put(rg.StartKey, rg.EndKey, rg.Files) + progressCallBack(RegionUnit) + }) + + // we should adjust start-time of the summary to `pastDureTime` earlier + log.Info("past cost time", zap.Duration("cost", pastDureTime)) + summary.AdjustStartTimeToEarlierTime(pastDureTime) + + return rangeDataMap, errors.Trace(err) +} + +// SetStorage sets ExternalStorage for client. +func (bc *Client) SetStorage( + ctx context.Context, + backend *backuppb.StorageBackend, + opts *storage.ExternalStorageOptions, +) error { + var err error + + bc.backend = backend + bc.storage, err = storage.New(ctx, backend, opts) + return errors.Trace(err) +} + // GetClusterID returns the cluster ID of the tidb cluster to backup. func (bc *Client) GetClusterID() uint64 { return bc.clusterID @@ -223,6 +401,22 @@ func (bc *Client) SetApiVersion(v kvrpcpb.APIVersion) { bc.apiVersion = v } +// Client.BuildBackupRangeAndSchema calls BuildBackupRangeAndSchema, +// if the checkpoint mode is used, return the ranges from checkpoint meta +func (bc *Client) BuildBackupRangeAndSchema( + storage kv.Storage, + tableFilter filter.Filter, + backupTS uint64, + isFullBackup bool, +) ([]rtree.Range, *Schemas, []*backuppb.PlacementPolicy, error) { + if bc.checkpointMeta == nil { + return BuildBackupRangeAndSchema(storage, tableFilter, backupTS, isFullBackup, true) + } + _, schemas, policies, err := BuildBackupRangeAndSchema(storage, tableFilter, backupTS, isFullBackup, false) + schemas.SetCheckpointChecksum(bc.checkpointMeta.CheckpointChecksum) + return bc.checkpointMeta.Ranges, schemas, policies, errors.Trace(err) +} + // CheckBackupStorageIsLocked checks whether backups is locked. // which means we found other backup progress already write // some data files into the same backup directory or cloud prefix. @@ -236,7 +430,7 @@ func CheckBackupStorageIsLocked(ctx context.Context, s storage.ExternalStorage) // should return error to break the walkDir when found lock file and other .sst files. if strings.HasSuffix(path, ".sst") { return errors.Annotatef(berrors.ErrInvalidArgument, "backup lock file and sst file exist in %v, "+ - "there are some backup files in the path already, "+ + "there are some backup files in the path already, but hasn't checkpoint metadata, "+ "please specify a correct backup directory!", s.URI()+"/"+metautil.LockFile) } return nil @@ -274,10 +468,12 @@ func appendRanges(tbl *model.TableInfo, tblID int64) ([]kv.KeyRange, error) { ranges = ranger.FullIntRange(false) } + retRanges := make([]kv.KeyRange, 0, 1+len(tbl.Indices)) kvRanges, err := distsql.TableHandleRangesToKVRanges(nil, []int64{tblID}, tbl.IsCommonHandle, ranges, nil) if err != nil { return nil, errors.Trace(err) } + retRanges = kvRanges.AppendSelfTo(retRanges) for _, index := range tbl.Indices { if index.State != model.StatePublic { @@ -288,9 +484,9 @@ func appendRanges(tbl *model.TableInfo, tblID int64) ([]kv.KeyRange, error) { if err != nil { return nil, errors.Trace(err) } - kvRanges = append(kvRanges, idxRanges...) + retRanges = idxRanges.AppendSelfTo(retRanges) } - return kvRanges, nil + return retRanges, nil } // BuildBackupRangeAndSchema gets KV range and schema of tables. @@ -301,6 +497,7 @@ func BuildBackupRangeAndSchema( tableFilter filter.Filter, backupTS uint64, isFullBackup bool, + buildRange bool, ) ([]rtree.Range, *Schemas, []*backuppb.PlacementPolicy, error) { snapshot := storage.GetSnapshot(kv.NewVersion(backupTS)) m := meta.NewSnapshotMeta(snapshot) @@ -417,15 +614,17 @@ func BuildBackupRangeAndSchema( backupSchemas.AddSchema(dbInfo, tableInfo) - tableRanges, err := BuildTableRanges(tableInfo) - if err != nil { - return nil, nil, nil, errors.Trace(err) - } - for _, r := range tableRanges { - ranges = append(ranges, rtree.Range{ - StartKey: r.StartKey, - EndKey: r.EndKey, - }) + if buildRange { + tableRanges, err := BuildTableRanges(tableInfo) + if err != nil { + return nil, nil, nil, errors.Trace(err) + } + for _, r := range tableRanges { + ranges = append(ranges, rtree.Range{ + StartKey: r.StartKey, + EndKey: r.EndKey, + }) + } } } } @@ -586,10 +785,13 @@ func (bc *Client) BackupRanges( id := id req := request req.StartKey, req.EndKey = r.StartKey, r.EndKey - + pr, err := bc.GetProgressRange(r) + if err != nil { + return errors.Trace(err) + } workerPool.ApplyOnErrorGroup(eg, func() error { elctx := logutil.ContextWithField(ectx, logutil.RedactAny("range-sn", id)) - err := bc.BackupRange(elctx, req, metaWriter, progressCallBack) + err := bc.BackupRange(elctx, req, pr, metaWriter, progressCallBack) if err != nil { // The error due to context cancel, stack trace is meaningless, the stack shall be suspended (also clear) if errors.Cause(err) == context.Canceled { @@ -600,6 +802,7 @@ func (bc *Client) BackupRanges( return nil }) } + return eg.Wait() } @@ -607,7 +810,8 @@ func (bc *Client) BackupRanges( // Returns an array of files backed up. func (bc *Client) BackupRange( ctx context.Context, - req backuppb.BackupRequest, + request backuppb.BackupRequest, + progressRange *rtree.ProgressRange, metaWriter *metautil.MetaWriter, progressCallBack func(ProgressUnit), ) (err error) { @@ -615,17 +819,17 @@ func (bc *Client) BackupRange( defer func() { elapsed := time.Since(start) logutil.CL(ctx).Info("backup range completed", - logutil.Key("startKey", req.StartKey), logutil.Key("endKey", req.EndKey), + logutil.Key("startKey", progressRange.Origin.StartKey), logutil.Key("endKey", progressRange.Origin.EndKey), zap.Duration("take", elapsed)) - key := "range start:" + hex.EncodeToString(req.StartKey) + " end:" + hex.EncodeToString(req.EndKey) + key := "range start:" + hex.EncodeToString(progressRange.Origin.StartKey) + " end:" + hex.EncodeToString(progressRange.Origin.EndKey) if err != nil { summary.CollectFailureUnit(key, err) } }() logutil.CL(ctx).Info("backup range started", - logutil.Key("startKey", req.StartKey), logutil.Key("endKey", req.EndKey), - zap.Uint64("rateLimit", req.RateLimit), - zap.Uint32("concurrency", req.Concurrency)) + logutil.Key("startKey", progressRange.Origin.StartKey), logutil.Key("endKey", progressRange.Origin.EndKey), + zap.Uint64("rateLimit", request.RateLimit), + zap.Uint32("concurrency", request.Concurrency)) var allStores []*metapb.Store allStores, err = conn.GetAllTiKVStoresWithRetry(ctx, bc.mgr.GetPDClient(), connutil.SkipTiFlash) @@ -634,35 +838,57 @@ func (bc *Client) BackupRange( } logutil.CL(ctx).Info("backup push down started") - push := newPushDown(bc.mgr, len(allStores)) - results, err := push.pushBackup(ctx, req, allStores, progressCallBack) - if err != nil { - return errors.Trace(err) + // either the `incomplete` is origin range itself, + // or the `incomplete` is sub-ranges split by checkpoint of origin range + if len(progressRange.Incomplete) > 0 { + // don't make the origin request dirty, + // since fineGrainedBackup need to use it. + req := request + if len(progressRange.Incomplete) > 1 { + subRanges := make([]*kvrpcpb.KeyRange, 0, len(progressRange.Incomplete)) + for _, r := range progressRange.Incomplete { + subRanges = append(subRanges, &kvrpcpb.KeyRange{ + StartKey: r.StartKey, + EndKey: r.EndKey, + }) + } + req.SubRanges = subRanges + } else { + // compatible with older version of TiKV + req.StartKey = progressRange.Incomplete[0].StartKey + req.EndKey = progressRange.Incomplete[0].EndKey + } + + push := newPushDown(bc.mgr, len(allStores)) + err = push.pushBackup(ctx, req, progressRange, allStores, bc.checkpointRunner, progressCallBack) + if err != nil { + return errors.Trace(err) + } } - logutil.CL(ctx).Info("backup push down completed", zap.Int("small-range-count", results.Len())) + logutil.CL(ctx).Info("backup push down completed", zap.Int("small-range-count", progressRange.Res.Len())) // Find and backup remaining ranges. // TODO: test fine grained backup. - if err := bc.fineGrainedBackup(ctx, req, results, progressCallBack); err != nil { + if err := bc.fineGrainedBackup(ctx, request, progressRange, progressCallBack); err != nil { return errors.Trace(err) } // update progress of range unit progressCallBack(RangeUnit) - if req.IsRawKv { + if request.IsRawKv { logutil.CL(ctx).Info("raw ranges backed up", - logutil.Key("startKey", req.StartKey), - logutil.Key("endKey", req.EndKey), - zap.String("cf", req.Cf)) + logutil.Key("startKey", progressRange.Origin.StartKey), + logutil.Key("endKey", progressRange.Origin.EndKey), + zap.String("cf", request.Cf)) } else { logutil.CL(ctx).Info("transactional range backup completed", - zap.Reflect("StartTS", req.StartVersion), - zap.Reflect("EndTS", req.EndVersion)) + zap.Reflect("StartTS", request.StartVersion), + zap.Reflect("EndTS", request.EndVersion)) } var ascendErr error - results.Ascend(func(i btree.Item) bool { + progressRange.Res.Ascend(func(i btree.Item) bool { r := i.(*rtree.Range) for _, f := range r.Files { summary.CollectSuccessUnit(summary.TotalKV, 1, f.TotalKvs) @@ -681,7 +907,7 @@ func (bc *Client) BackupRange( } // Check if there are duplicated files. - checkDupFiles(&results) + checkDupFiles(&progressRange.Res) return nil } @@ -714,7 +940,7 @@ func (bc *Client) findRegionLeader(ctx context.Context, key []byte, isRawKv bool func (bc *Client) fineGrainedBackup( ctx context.Context, req backuppb.BackupRequest, - rangeTree rtree.RangeTree, + pr *rtree.ProgressRange, progressCallBack func(ProgressUnit), ) error { if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { @@ -741,7 +967,7 @@ func (bc *Client) fineGrainedBackup( bo := tikv.NewBackoffer(ctx, backupFineGrainedMaxBackoff) for { // Step1, check whether there is any incomplete range - incomplete := rangeTree.GetIncompleteRange(req.StartKey, req.EndKey) + incomplete := pr.Res.GetIncompleteRange(req.StartKey, req.EndKey) if len(incomplete) == 0 { return nil } @@ -809,7 +1035,18 @@ func (bc *Client) fineGrainedBackup( logutil.Key("fine-grained-range-start", resp.StartKey), logutil.Key("fine-grained-range-end", resp.EndKey), ) - rangeTree.Put(resp.StartKey, resp.EndKey, resp.Files) + if bc.checkpointRunner != nil { + if err := bc.checkpointRunner.Append( + ctx, + pr.GroupKey, + resp.StartKey, + resp.EndKey, + resp.Files, + ); err != nil { + return errors.Annotate(err, "failed to flush checkpoint when fineGrainedBackup") + } + } + pr.Res.Put(resp.StartKey, resp.EndKey, resp.Files) apiVersion := resp.ApiVersion bc.SetApiVersion(apiVersion) diff --git a/br/pkg/backup/client_test.go b/br/pkg/backup/client_test.go index 76d885e04a201..592416e8ec03c 100644 --- a/br/pkg/backup/client_test.go +++ b/br/pkg/backup/client_test.go @@ -57,8 +57,7 @@ func createBackupSuite(t *testing.T) *testBackup { mockMgr := &conn.Mgr{PdController: &pdutil.PdController{}} mockMgr.SetPDClient(s.mockPDClient) mockMgr.SetHTTP([]string{"test"}, nil) - s.backupClient, err = backup.NewBackupClient(s.ctx, mockMgr) - require.NoError(t, err) + s.backupClient = backup.NewBackupClient(s.ctx, mockMgr) s.cluster, err = mock.NewCluster() require.NoError(t, err) diff --git a/br/pkg/backup/main_test.go b/br/pkg/backup/main_test.go index 86aab670ef61a..7c6c43a5743c4 100644 --- a/br/pkg/backup/main_test.go +++ b/br/pkg/backup/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/klauspost/compress/zstd.(*blockDec).startDecoder"), goleak.IgnoreTopFunction("github.com/pingcap/goleveldb/leveldb.(*DB).mpoolDrain"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), diff --git a/br/pkg/backup/push.go b/br/pkg/backup/push.go index 45c2b9acca01c..2ffffe690ffe5 100644 --- a/br/pkg/backup/push.go +++ b/br/pkg/backup/push.go @@ -13,6 +13,7 @@ import ( backuppb "github.com/pingcap/kvproto/pkg/brpb" "github.com/pingcap/kvproto/pkg/errorpb" "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/tidb/br/pkg/checkpoint" berrors "github.com/pingcap/tidb/br/pkg/errors" "github.com/pingcap/tidb/br/pkg/logutil" "github.com/pingcap/tidb/br/pkg/redact" @@ -54,9 +55,11 @@ func newPushDown(mgr ClientMgr, capacity int) *pushDown { func (push *pushDown) pushBackup( ctx context.Context, req backuppb.BackupRequest, + pr *rtree.ProgressRange, stores []*metapb.Store, + checkpointRunner *checkpoint.CheckpointRunner, progressCallBack func(ProgressUnit), -) (rtree.RangeTree, error) { +) error { if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { span1 := span.Tracer().StartSpan("pushDown.pushBackup", opentracing.ChildOf(span.Context())) defer span1.Finish() @@ -64,10 +67,9 @@ func (push *pushDown) pushBackup( } // Push down backup tasks to all tikv instances. - res := rtree.NewRangeTree() failpoint.Inject("noop-backup", func(_ failpoint.Value) { logutil.CL(ctx).Warn("skipping normal backup, jump to fine-grained backup, meow :3", logutil.Key("start-key", req.StartKey), logutil.Key("end-key", req.EndKey)) - failpoint.Return(res, nil) + failpoint.Return(nil) }) wg := new(sync.WaitGroup) @@ -84,7 +86,7 @@ func (push *pushDown) pushBackup( // BR should be able to backup even some of stores disconnected. // The regions managed by this store can be retried at fine-grained backup then. logutil.CL(lctx).Warn("fail to connect store, skipping", zap.Error(err)) - return res, nil + return nil } wg.Add(1) go func() { @@ -125,7 +127,7 @@ func (push *pushDown) pushBackup( store := respAndStore.GetStore() if !ok { // Finished. - return res, nil + return nil } failpoint.Inject("backup-timeout-error", func(val failpoint.Value) { msg := val.(string) @@ -165,7 +167,19 @@ func (push *pushDown) pushBackup( }) if resp.GetError() == nil { // None error means range has been backuped successfully. - res.Put( + if checkpointRunner != nil { + if err := checkpointRunner.Append( + ctx, + pr.GroupKey, + resp.StartKey, + resp.EndKey, + resp.Files, + ); err != nil { + // the error is only from flush operator + return errors.Annotate(err, "failed to flush checkpoint") + } + } + pr.Res.Put( resp.GetStartKey(), resp.GetEndKey(), resp.GetFiles()) // Update progress @@ -181,7 +195,7 @@ func (push *pushDown) pushBackup( case *backuppb.Error_ClusterIdError: logutil.CL(ctx).Error("backup occur cluster ID error", zap.Reflect("error", v)) - return res, errors.Annotatef(berrors.ErrKVClusterIDMismatch, "%v", errPb) + return errors.Annotatef(berrors.ErrKVClusterIDMismatch, "%v", errPb) default: if utils.MessageIsRetryableStorageError(errPb.GetMsg()) { logutil.CL(ctx).Warn("backup occur storage error", zap.String("error", errPb.GetMsg())) @@ -204,7 +218,7 @@ func (push *pushDown) pushBackup( if len(errMsg) <= 0 { errMsg = errPb.Msg } - return res, errors.Annotatef(berrors.ErrKVStorage, "error happen in store %v at %s: %s %s", + return errors.Annotatef(berrors.ErrKVStorage, "error happen in store %v at %s: %s %s", store.GetId(), redact.String(store.GetAddress()), req.StorageBackend.String(), @@ -214,10 +228,10 @@ func (push *pushDown) pushBackup( } case err := <-push.errCh: if !berrors.Is(err, berrors.ErrFailedToConnect) { - return res, errors.Annotatef(err, "failed to backup range [%s, %s)", redact.Key(req.StartKey), redact.Key(req.EndKey)) + return errors.Annotatef(err, "failed to backup range [%s, %s)", redact.Key(req.StartKey), redact.Key(req.EndKey)) } logutil.CL(ctx).Warn("skipping disconnected stores", logutil.ShortError(err)) - return res, nil + return nil } } } diff --git a/br/pkg/backup/schema.go b/br/pkg/backup/schema.go index d3269980fdbb2..bb0cf7f884189 100644 --- a/br/pkg/backup/schema.go +++ b/br/pkg/backup/schema.go @@ -12,6 +12,7 @@ import ( "github.com/pingcap/errors" backuppb "github.com/pingcap/kvproto/pkg/brpb" "github.com/pingcap/log" + "github.com/pingcap/tidb/br/pkg/checkpoint" "github.com/pingcap/tidb/br/pkg/checksum" "github.com/pingcap/tidb/br/pkg/glue" "github.com/pingcap/tidb/br/pkg/logutil" @@ -44,14 +45,22 @@ type schemaInfo struct { type Schemas struct { // name -> schema schemas map[string]*schemaInfo + + // checkpoint: table id -> checksum + checkpointChecksum map[int64]*checkpoint.ChecksumItem } func NewBackupSchemas() *Schemas { return &Schemas{ - schemas: make(map[string]*schemaInfo), + schemas: make(map[string]*schemaInfo), + checkpointChecksum: nil, } } +func (ss *Schemas) SetCheckpointChecksum(checkpointChecksum map[int64]*checkpoint.ChecksumItem) { + ss.checkpointChecksum = checkpointChecksum +} + func (ss *Schemas) AddSchema( dbInfo *model.DBInfo, tableInfo *model.TableInfo, ) { @@ -73,6 +82,7 @@ func (ss *Schemas) AddSchema( func (ss *Schemas) BackupSchemas( ctx context.Context, metaWriter *metautil.MetaWriter, + checkpointRunner *checkpoint.CheckpointRunner, store kv.Storage, statsHandle *handle.Handle, backupTS uint64, @@ -100,6 +110,11 @@ func (ss *Schemas) BackupSchemas( schema.dbInfo.Name = utils.TemporaryDBName(schema.dbInfo.Name.O) } + var checksum *checkpoint.ChecksumItem + var exists bool = false + if ss.checkpointChecksum != nil { + checksum, exists = ss.checkpointChecksum[schema.tableInfo.ID] + } workerPool.ApplyOnErrorGroup(errg, func() error { if schema.tableInfo != nil { logger := log.With( @@ -109,16 +124,38 @@ func (ss *Schemas) BackupSchemas( if !skipChecksum { logger.Info("Calculate table checksum start") - start := time.Now() - err := schema.calculateChecksum(ectx, store.GetClient(), backupTS, copConcurrency) - if err != nil { - return errors.Trace(err) + if exists && checksum != nil { + schema.crc64xor = checksum.Crc64xor + schema.totalKvs = checksum.TotalKvs + schema.totalBytes = checksum.TotalBytes + logger.Info("Calculate table checksum completed (from checkpoint)", + zap.Uint64("Crc64Xor", schema.crc64xor), + zap.Uint64("TotalKvs", schema.totalKvs), + zap.Uint64("TotalBytes", schema.totalBytes)) + } else { + start := time.Now() + err := schema.calculateChecksum(ectx, store.GetClient(), backupTS, copConcurrency) + if err != nil { + return errors.Trace(err) + } + calculateCost := time.Since(start) + var flushCost time.Duration + if checkpointRunner != nil { + // if checkpoint runner is running and the checksum is not from checkpoint + // then flush the checksum by the checkpoint runner + startFlush := time.Now() + if err = checkpointRunner.FlushChecksum(ctx, schema.tableInfo.ID, schema.crc64xor, schema.totalKvs, schema.totalBytes, calculateCost.Seconds()); err != nil { + return errors.Trace(err) + } + flushCost = time.Since(startFlush) + } + logger.Info("Calculate table checksum completed", + zap.Uint64("Crc64Xor", schema.crc64xor), + zap.Uint64("TotalKvs", schema.totalKvs), + zap.Uint64("TotalBytes", schema.totalBytes), + zap.Duration("calculate-take", calculateCost), + zap.Duration("flush-take", flushCost)) } - logger.Info("Calculate table checksum completed", - zap.Uint64("Crc64Xor", schema.crc64xor), - zap.Uint64("TotalKvs", schema.totalKvs), - zap.Uint64("TotalBytes", schema.totalBytes), - zap.Duration("take", time.Since(start))) } if statsHandle != nil { if err := schema.dumpStatsToJSON(statsHandle); err != nil { @@ -181,7 +218,7 @@ func (s *schemaInfo) calculateChecksum( func (s *schemaInfo) dumpStatsToJSON(statsHandle *handle.Handle) error { jsonTable, err := statsHandle.DumpStatsToJSON( - s.dbInfo.Name.String(), s.tableInfo, nil) + s.dbInfo.Name.String(), s.tableInfo, nil, true) if err != nil { return errors.Trace(err) } diff --git a/br/pkg/backup/schema_test.go b/br/pkg/backup/schema_test.go index bed9d834d2e10..08d560bf03c25 100644 --- a/br/pkg/backup/schema_test.go +++ b/br/pkg/backup/schema_test.go @@ -108,7 +108,7 @@ func TestBuildBackupRangeAndSchema(t *testing.T) { testFilter, err := filter.Parse([]string{"test.t1"}) require.NoError(t, err) _, backupSchemas, _, err := backup.BuildBackupRangeAndSchema( - m.Storage, testFilter, math.MaxUint64, false) + m.Storage, testFilter, math.MaxUint64, false, true) require.NoError(t, err) require.NotNil(t, backupSchemas) @@ -116,7 +116,7 @@ func TestBuildBackupRangeAndSchema(t *testing.T) { fooFilter, err := filter.Parse([]string{"foo.t1"}) require.NoError(t, err) _, backupSchemas, _, err = backup.BuildBackupRangeAndSchema( - m.Storage, fooFilter, math.MaxUint64, false) + m.Storage, fooFilter, math.MaxUint64, false, true) require.NoError(t, err) require.Nil(t, backupSchemas) @@ -125,7 +125,7 @@ func TestBuildBackupRangeAndSchema(t *testing.T) { noFilter, err := filter.Parse([]string{"*.*", "!mysql.*"}) require.NoError(t, err) _, backupSchemas, _, err = backup.BuildBackupRangeAndSchema( - m.Storage, noFilter, math.MaxUint64, false) + m.Storage, noFilter, math.MaxUint64, false, true) require.NoError(t, err) require.NotNil(t, backupSchemas) @@ -137,7 +137,7 @@ func TestBuildBackupRangeAndSchema(t *testing.T) { var policies []*backuppb.PlacementPolicy _, backupSchemas, policies, err = backup.BuildBackupRangeAndSchema( - m.Storage, testFilter, math.MaxUint64, false) + m.Storage, testFilter, math.MaxUint64, false, true) require.NoError(t, err) require.Equal(t, 1, backupSchemas.Len()) // we expect no policies collected, because it's not full backup. @@ -151,7 +151,7 @@ func TestBuildBackupRangeAndSchema(t *testing.T) { metaWriter := metautil.NewMetaWriter(es, metautil.MetaFileSize, false, "", &cipher) ctx := context.Background() err = backupSchemas.BackupSchemas( - ctx, metaWriter, m.Storage, nil, math.MaxUint64, 1, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) + ctx, metaWriter, nil, m.Storage, nil, math.MaxUint64, 1, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) require.Equal(t, int64(1), updateCh.get()) require.NoError(t, err) err = metaWriter.FlushBackupMeta(ctx) @@ -170,7 +170,7 @@ func TestBuildBackupRangeAndSchema(t *testing.T) { tk.MustExec("insert into t2 values (11);") _, backupSchemas, policies, err = backup.BuildBackupRangeAndSchema( - m.Storage, noFilter, math.MaxUint64, true) + m.Storage, noFilter, math.MaxUint64, true, true) require.NoError(t, err) require.Equal(t, 2, backupSchemas.Len()) // we expect the policy fivereplicas collected in full backup. @@ -180,7 +180,7 @@ func TestBuildBackupRangeAndSchema(t *testing.T) { es2 := GetRandomStorage(t) metaWriter2 := metautil.NewMetaWriter(es2, metautil.MetaFileSize, false, "", &cipher) err = backupSchemas.BackupSchemas( - ctx, metaWriter2, m.Storage, nil, math.MaxUint64, 2, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) + ctx, metaWriter2, nil, m.Storage, nil, math.MaxUint64, 2, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) require.Equal(t, int64(2), updateCh.get()) require.NoError(t, err) err = metaWriter2.FlushBackupMeta(ctx) @@ -219,7 +219,7 @@ func TestBuildBackupRangeAndSchemaWithBrokenStats(t *testing.T) { f, err := filter.Parse([]string{"test.t3"}) require.NoError(t, err) - _, backupSchemas, _, err := backup.BuildBackupRangeAndSchema(m.Storage, f, math.MaxUint64, false) + _, backupSchemas, _, err := backup.BuildBackupRangeAndSchema(m.Storage, f, math.MaxUint64, false, true) require.NoError(t, err) require.Equal(t, 1, backupSchemas.Len()) @@ -234,7 +234,7 @@ func TestBuildBackupRangeAndSchemaWithBrokenStats(t *testing.T) { metaWriter := metautil.NewMetaWriter(es, metautil.MetaFileSize, false, "", &cipher) ctx := context.Background() err = backupSchemas.BackupSchemas( - ctx, metaWriter, m.Storage, nil, math.MaxUint64, 1, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) + ctx, metaWriter, nil, m.Storage, nil, math.MaxUint64, 1, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) require.NoError(t, err) err = metaWriter.FlushBackupMeta(ctx) require.NoError(t, err) @@ -253,7 +253,7 @@ func TestBuildBackupRangeAndSchemaWithBrokenStats(t *testing.T) { // recover the statistics. tk.MustExec("analyze table t3;") - _, backupSchemas, _, err = backup.BuildBackupRangeAndSchema(m.Storage, f, math.MaxUint64, false) + _, backupSchemas, _, err = backup.BuildBackupRangeAndSchema(m.Storage, f, math.MaxUint64, false, true) require.NoError(t, err) require.Equal(t, 1, backupSchemas.Len()) @@ -262,7 +262,7 @@ func TestBuildBackupRangeAndSchemaWithBrokenStats(t *testing.T) { es2 := GetRandomStorage(t) metaWriter2 := metautil.NewMetaWriter(es2, metautil.MetaFileSize, false, "", &cipher) err = backupSchemas.BackupSchemas( - ctx, metaWriter2, m.Storage, statsHandle, math.MaxUint64, 1, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) + ctx, metaWriter2, nil, m.Storage, statsHandle, math.MaxUint64, 1, variable.DefChecksumTableConcurrency, skipChecksum, updateCh) require.NoError(t, err) err = metaWriter2.FlushBackupMeta(ctx) require.NoError(t, err) @@ -294,7 +294,7 @@ func TestBackupSchemasForSystemTable(t *testing.T) { f, err := filter.Parse([]string{"mysql.systable*"}) require.NoError(t, err) - _, backupSchemas, _, err := backup.BuildBackupRangeAndSchema(m.Storage, f, math.MaxUint64, false) + _, backupSchemas, _, err := backup.BuildBackupRangeAndSchema(m.Storage, f, math.MaxUint64, false, true) require.NoError(t, err) require.Equal(t, systemTablesCount, backupSchemas.Len()) @@ -305,7 +305,7 @@ func TestBackupSchemasForSystemTable(t *testing.T) { updateCh := new(simpleProgress) metaWriter2 := metautil.NewMetaWriter(es2, metautil.MetaFileSize, false, "", &cipher) - err = backupSchemas.BackupSchemas(ctx, metaWriter2, m.Storage, nil, + err = backupSchemas.BackupSchemas(ctx, metaWriter2, nil, m.Storage, nil, math.MaxUint64, 1, variable.DefChecksumTableConcurrency, true, updateCh) require.NoError(t, err) err = metaWriter2.FlushBackupMeta(ctx) diff --git a/br/pkg/checkpoint/BUILD.bazel b/br/pkg/checkpoint/BUILD.bazel new file mode 100644 index 0000000000000..20e39dc39025b --- /dev/null +++ b/br/pkg/checkpoint/BUILD.bazel @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "checkpoint", + srcs = ["checkpoint.go"], + importpath = "github.com/pingcap/tidb/br/pkg/checkpoint", + visibility = ["//visibility:public"], + deps = [ + "//br/pkg/logutil", + "//br/pkg/metautil", + "//br/pkg/rtree", + "//br/pkg/storage", + "//br/pkg/summary", + "//br/pkg/utils", + "@com_github_pingcap_errors//:errors", + "@com_github_pingcap_kvproto//pkg/brpb", + "@com_github_pingcap_log//:log", + "@com_github_tikv_client_go_v2//oracle", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "checkpoint_test", + srcs = ["checkpoint_test.go"], + deps = [ + ":checkpoint", + "//br/pkg/rtree", + "//br/pkg/storage", + "@com_github_pingcap_kvproto//pkg/brpb", + "@com_github_pingcap_kvproto//pkg/encryptionpb", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//oracle", + ], +) diff --git a/br/pkg/checkpoint/checkpoint.go b/br/pkg/checkpoint/checkpoint.go new file mode 100644 index 0000000000000..0af1cefdf2594 --- /dev/null +++ b/br/pkg/checkpoint/checkpoint.go @@ -0,0 +1,759 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package checkpoint + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "math/rand" + "strings" + "sync" + "time" + + "github.com/pingcap/errors" + backuppb "github.com/pingcap/kvproto/pkg/brpb" + "github.com/pingcap/log" + "github.com/pingcap/tidb/br/pkg/logutil" + "github.com/pingcap/tidb/br/pkg/metautil" + "github.com/pingcap/tidb/br/pkg/rtree" + "github.com/pingcap/tidb/br/pkg/storage" + "github.com/pingcap/tidb/br/pkg/summary" + "github.com/pingcap/tidb/br/pkg/utils" + "github.com/tikv/client-go/v2/oracle" + "go.uber.org/zap" +) + +const ( + CheckpointMetaPath = "checkpoint.meta" + CheckpointDir = "/checkpoints" + + CheckpointDataDir = CheckpointDir + "/data" + CheckpointChecksumDir = CheckpointDir + "/checksum" + CheckpointLockPath = CheckpointDir + "/checkpoint.lock" +) + +const MaxChecksumTotalCost float64 = 60.0 + +const tickDurationForFlush = 30 * time.Second + +const tickDurationForLock = 4 * time.Minute + +const lockTimeToLive = 5 * time.Minute + +type CheckpointMessage struct { + // start-key of the origin range + GroupKey string + + Group *rtree.Range +} + +// A Checkpoint Range File is like this: +// +// ChecksumData +// +----------------+ RangeGroupData RangeGroups +// | DureTime | +--------------------------+ encrypted +-------------+ +// | RangeGroupData-+---> | RangeGroupsEncriptedData-+----------> | GroupKey | +// | RangeGroupData | | Checksum | | Range | +// | ... | | CipherIv | | ... | +// | RangeGroupData | | Size | | Range | +// +----------------+ +--------------------------+ +-------------+ + +type RangeGroups struct { + GroupKey string `json:"group-key"` + Groups []*rtree.Range `json:"groups"` +} + +type RangeGroupData struct { + RangeGroupsEncriptedData []byte + Checksum []byte + CipherIv []byte + + Size int +} + +type CheckpointData struct { + DureTime time.Duration `json:"dure-time"` + RangeGroupMetas []*RangeGroupData `json:"range-group-metas"` +} + +// A Checkpoint Checksum File is like this: +// +// ChecksumInfo ChecksumItems ChecksumItem +// +-------------+ +--------------+ +--------------+ +// | Content---+-> | ChecksumItem-+---> | TableID | +// | Checksum | | ChecksumItem | | Crc64xor | +// +-------------+ | ... | | TotalKvs | +// | ChecksumItem | | TotalBytes | +// +--------------+ +--------------+ + +type ChecksumItem struct { + TableID int64 `json:"table-id"` + Crc64xor uint64 `json:"crc64-xor"` + TotalKvs uint64 `json:"total-kvs"` + TotalBytes uint64 `json:"total-bytes"` +} + +type ChecksumItems struct { + Items []*ChecksumItem `json:"checksum-items"` +} + +type ChecksumInfo struct { + Content []byte `json:"content"` + Checksum []byte `json:"checksum"` +} + +type ChecksumRunner struct { + sync.Mutex + + checksumItems ChecksumItems + + // when the total time cost is large than the threshold, + // begin to flush checksum + totalCost float64 + + err error + wg sync.WaitGroup + workerPool utils.WorkerPool +} + +func NewChecksumRunner() *ChecksumRunner { + return &ChecksumRunner{ + workerPool: *utils.NewWorkerPool(4, "checksum flush worker"), + } +} + +func (cr *ChecksumRunner) RecordError(err error) { + cr.Lock() + cr.err = err + cr.Unlock() +} + +// FlushChecksum save the checksum in the memory temporarily +// and flush to the external storage if checksum take much time +func (cr *ChecksumRunner) FlushChecksum( + ctx context.Context, + s storage.ExternalStorage, + tableID int64, + crc64xor uint64, + totalKvs uint64, + totalBytes uint64, + timeCost float64, +) error { + checksumItem := &ChecksumItem{ + TableID: tableID, + Crc64xor: crc64xor, + TotalKvs: totalKvs, + TotalBytes: totalBytes, + } + var toBeFlushedChecksumItems *ChecksumItems = nil + cr.Lock() + if cr.err != nil { + err := cr.err + cr.Unlock() + return err + } + if cr.checksumItems.Items == nil { + // reset the checksumInfo + cr.totalCost = 0 + cr.checksumItems.Items = make([]*ChecksumItem, 0) + } + cr.totalCost += timeCost + cr.checksumItems.Items = append(cr.checksumItems.Items, checksumItem) + if cr.totalCost > MaxChecksumTotalCost { + toBeFlushedChecksumItems = &ChecksumItems{ + Items: cr.checksumItems.Items, + } + cr.checksumItems.Items = nil + } + cr.Unlock() + + // now lock is free + if toBeFlushedChecksumItems == nil { + return nil + } + + // create a goroutine to flush checksumInfo to external storage + cr.wg.Add(1) + cr.workerPool.Apply(func() { + defer cr.wg.Done() + + content, err := json.Marshal(toBeFlushedChecksumItems) + if err != nil { + cr.RecordError(err) + return + } + + checksum := sha256.Sum256(content) + checksumInfo := &ChecksumInfo{ + Content: content, + Checksum: checksum[:], + } + + data, err := json.Marshal(checksumInfo) + if err != nil { + cr.RecordError(err) + return + } + + fname := fmt.Sprintf("%s/t%d_and__", CheckpointChecksumDir, tableID) + err = s.WriteFile(ctx, fname, data) + if err != nil { + cr.RecordError(err) + return + } + }) + return nil +} + +type GlobalTimer interface { + GetTS(context.Context) (int64, int64, error) +} + +type CheckpointRunner struct { + lockId uint64 + + meta map[string]*RangeGroups + + checksumRunner *ChecksumRunner + + storage storage.ExternalStorage + cipher *backuppb.CipherInfo + timer GlobalTimer + + appendCh chan *CheckpointMessage + metaCh chan map[string]*RangeGroups + lockCh chan struct{} + errCh chan error + + wg sync.WaitGroup +} + +// only for test +func StartCheckpointRunnerForTest(ctx context.Context, storage storage.ExternalStorage, cipher *backuppb.CipherInfo, tick time.Duration, timer GlobalTimer) (*CheckpointRunner, error) { + runner := &CheckpointRunner{ + meta: make(map[string]*RangeGroups), + + checksumRunner: NewChecksumRunner(), + + storage: storage, + cipher: cipher, + timer: timer, + + appendCh: make(chan *CheckpointMessage), + metaCh: make(chan map[string]*RangeGroups), + lockCh: make(chan struct{}), + errCh: make(chan error, 1), + } + + err := runner.initialLock(ctx) + if err != nil { + return nil, errors.Annotate(err, "Failed to initialize checkpoint lock.") + } + runner.startCheckpointLoop(ctx, tick, tick) + return runner, nil +} + +func StartCheckpointRunner(ctx context.Context, storage storage.ExternalStorage, cipher *backuppb.CipherInfo, timer GlobalTimer) (*CheckpointRunner, error) { + runner := &CheckpointRunner{ + meta: make(map[string]*RangeGroups), + + checksumRunner: NewChecksumRunner(), + + storage: storage, + cipher: cipher, + timer: timer, + + appendCh: make(chan *CheckpointMessage), + metaCh: make(chan map[string]*RangeGroups), + lockCh: make(chan struct{}), + errCh: make(chan error, 1), + } + + err := runner.initialLock(ctx) + if err != nil { + return nil, errors.Trace(err) + } + runner.startCheckpointLoop(ctx, tickDurationForFlush, tickDurationForLock) + return runner, nil +} + +func (r *CheckpointRunner) FlushChecksum(ctx context.Context, tableID int64, crc64xor uint64, totalKvs uint64, totalBytes uint64, timeCost float64) error { + return r.checksumRunner.FlushChecksum(ctx, r.storage, tableID, crc64xor, totalKvs, totalBytes, timeCost) +} + +func (r *CheckpointRunner) Append( + ctx context.Context, + groupKey string, + startKey []byte, + endKey []byte, + files []*backuppb.File, +) error { + select { + case <-ctx.Done(): + return nil + case err := <-r.errCh: + return err + case r.appendCh <- &CheckpointMessage{ + GroupKey: groupKey, + Group: &rtree.Range{ + StartKey: startKey, + EndKey: endKey, + Files: files, + }, + }: + return nil + } +} + +// Note: Cannot be parallel with `Append` function +func (r *CheckpointRunner) WaitForFinish(ctx context.Context) { + // can not append anymore + close(r.appendCh) + // wait the range flusher exit + r.wg.Wait() + // wait the checksum flusher exit + r.checksumRunner.wg.Wait() + // remove the checkpoint lock + err := r.storage.DeleteFile(ctx, CheckpointLockPath) + if err != nil { + log.Warn("failed to remove the checkpoint lock", zap.Error(err)) + } +} + +// Send the meta to the flush goroutine, and reset the CheckpointRunner's meta +func (r *CheckpointRunner) flushMeta(ctx context.Context, errCh chan error) error { + meta := r.meta + r.meta = make(map[string]*RangeGroups) + // do flush + select { + case <-ctx.Done(): + case err := <-errCh: + return err + case r.metaCh <- meta: + } + return nil +} + +func (r *CheckpointRunner) setLock(ctx context.Context, errCh chan error) error { + select { + case <-ctx.Done(): + case err := <-errCh: + return err + case r.lockCh <- struct{}{}: + } + return nil +} + +// start a goroutine to flush the meta, which is sent from `checkpoint looper`, to the external storage +func (r *CheckpointRunner) startCheckpointRunner(ctx context.Context, wg *sync.WaitGroup) chan error { + errCh := make(chan error, 1) + wg.Add(1) + flushWorker := func(ctx context.Context, errCh chan error) { + defer wg.Done() + for { + select { + case <-ctx.Done(): + return + case meta, ok := <-r.metaCh: + if !ok { + log.Info("stop checkpoint flush worker") + return + } + if err := r.doFlush(ctx, meta); err != nil { + errCh <- err + return + } + case _, ok := <-r.lockCh: + if !ok { + log.Info("stop checkpoint flush worker") + return + } + if err := r.updateLock(ctx); err != nil { + errCh <- errors.Annotate(err, "Failed to update checkpoint lock.") + return + } + } + } + } + + go flushWorker(ctx, errCh) + return errCh +} + +func (r *CheckpointRunner) sendError(err error) { + select { + case r.errCh <- err: + default: + log.Error("errCh is blocked", logutil.ShortError(err)) + } + r.checksumRunner.RecordError(err) +} + +func (r *CheckpointRunner) startCheckpointLoop(ctx context.Context, tickDurationForFlush, tickDurationForLock time.Duration) { + r.wg.Add(1) + checkpointLoop := func(ctx context.Context) { + defer r.wg.Done() + cctx, cancel := context.WithCancel(ctx) + defer cancel() + var wg sync.WaitGroup + errCh := r.startCheckpointRunner(cctx, &wg) + flushTicker := time.NewTicker(tickDurationForFlush) + defer flushTicker.Stop() + lockTicker := time.NewTicker(tickDurationForLock) + defer lockTicker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-lockTicker.C: + if err := r.setLock(ctx, errCh); err != nil { + r.sendError(err) + return + } + case <-flushTicker.C: + if err := r.flushMeta(ctx, errCh); err != nil { + r.sendError(err) + return + } + case msg, ok := <-r.appendCh: + if !ok { + log.Info("stop checkpoint runner") + if err := r.flushMeta(ctx, errCh); err != nil { + r.sendError(err) + } + // close the channel to flush worker + // and wait it to consumes all the metas + close(r.metaCh) + close(r.lockCh) + wg.Wait() + return + } + groups, exist := r.meta[msg.GroupKey] + if !exist { + groups = &RangeGroups{ + GroupKey: msg.GroupKey, + Groups: make([]*rtree.Range, 0), + } + r.meta[msg.GroupKey] = groups + } + groups.Groups = append(groups.Groups, msg.Group) + case err := <-errCh: + // pass flush worker's error back + r.sendError(err) + return + } + } + } + + go checkpointLoop(ctx) +} + +// flush the meta to the external storage +func (r *CheckpointRunner) doFlush(ctx context.Context, meta map[string]*RangeGroups) error { + if len(meta) == 0 { + return nil + } + + checkpointData := &CheckpointData{ + DureTime: summary.NowDureTime(), + RangeGroupMetas: make([]*RangeGroupData, 0, len(meta)), + } + + var fname []byte = nil + + for _, group := range meta { + if len(group.Groups) == 0 { + continue + } + + // use the first item's group-key and sub-range-key as the filename + if len(fname) == 0 { + fname = append(append([]byte(group.GroupKey), '.', '.'), group.Groups[0].StartKey...) + } + + // Flush the metaFile to storage + content, err := json.Marshal(group) + if err != nil { + return errors.Trace(err) + } + + encryptBuff, iv, err := metautil.Encrypt(content, r.cipher) + if err != nil { + return errors.Trace(err) + } + + checksum := sha256.Sum256(content) + + checkpointData.RangeGroupMetas = append(checkpointData.RangeGroupMetas, &RangeGroupData{ + RangeGroupsEncriptedData: encryptBuff, + Checksum: checksum[:], + Size: len(content), + CipherIv: iv, + }) + } + + if len(checkpointData.RangeGroupMetas) > 0 { + data, err := json.Marshal(checkpointData) + if err != nil { + return errors.Trace(err) + } + + checksum := sha256.Sum256(fname) + checksumEncoded := base64.URLEncoding.EncodeToString(checksum[:]) + path := fmt.Sprintf("%s/%s_%d.cpt", CheckpointDataDir, checksumEncoded, rand.Uint64()) + if err := r.storage.WriteFile(ctx, path, data); err != nil { + return errors.Trace(err) + } + } + return nil +} + +type CheckpointLock struct { + LockId uint64 `json:"lock-id"` + ExpireAt int64 `json:"expire-at"` +} + +// get ts with retry +func (r *CheckpointRunner) getTS(ctx context.Context) (int64, int64, error) { + var ( + p int64 = 0 + l int64 = 0 + retry int = 0 + ) + errRetry := utils.WithRetry(ctx, func() error { + var err error + p, l, err = r.timer.GetTS(ctx) + if err != nil { + retry++ + log.Info("failed to get ts", zap.Int("retry", retry), zap.Error(err)) + return err + } + + return nil + }, utils.NewPDReqBackoffer()) + + return p, l, errors.Trace(errRetry) +} + +// flush the lock to the external storage +func (r *CheckpointRunner) flushLock(ctx context.Context, p int64) error { + lock := &CheckpointLock{ + LockId: r.lockId, + ExpireAt: p + lockTimeToLive.Milliseconds(), + } + log.Info("start to flush the checkpoint lock", zap.Int64("lock-at", p), zap.Int64("expire-at", lock.ExpireAt)) + data, err := json.Marshal(lock) + if err != nil { + return errors.Trace(err) + } + + err = r.storage.WriteFile(ctx, CheckpointLockPath, data) + return errors.Trace(err) +} + +// check whether this lock belongs to this BR +func (r *CheckpointRunner) checkLockFile(ctx context.Context, now int64) error { + data, err := r.storage.ReadFile(ctx, CheckpointLockPath) + if err != nil { + return errors.Trace(err) + } + lock := &CheckpointLock{} + err = json.Unmarshal(data, lock) + if err != nil { + return errors.Trace(err) + } + if lock.ExpireAt <= now { + if lock.LockId > r.lockId { + return errors.Errorf("There are another BR(%d) running after but setting lock before this one(%d). "+ + "Please check whether the BR is running. If not, you can retry.", lock.LockId, r.lockId) + } + if lock.LockId == r.lockId { + log.Warn("The lock has expired.", zap.Int64("expire-at(ms)", lock.ExpireAt), zap.Int64("now(ms)", now)) + } + } else if lock.LockId != r.lockId { + return errors.Errorf("The existing lock will expire in %d seconds. "+ + "There may be another BR(%d) running. If not, you can wait for the lock to expire, or delete the file `%s%s` manually.", + (lock.ExpireAt-now)/1000, lock.LockId, strings.TrimRight(r.storage.URI(), "/"), CheckpointLockPath) + } + + return nil +} + +// generate a new lock and flush the lock to the external storage +func (r *CheckpointRunner) updateLock(ctx context.Context) error { + p, _, err := r.getTS(ctx) + if err != nil { + return errors.Trace(err) + } + if err = r.checkLockFile(ctx, p); err != nil { + return errors.Trace(err) + } + return errors.Trace(r.flushLock(ctx, p)) +} + +// Attempt to initialize the lock. Need to stop the backup when there is an unexpired locks. +func (r *CheckpointRunner) initialLock(ctx context.Context) error { + p, l, err := r.getTS(ctx) + if err != nil { + return errors.Trace(err) + } + r.lockId = oracle.ComposeTS(p, l) + exist, err := r.storage.FileExists(ctx, CheckpointLockPath) + if err != nil { + return errors.Trace(err) + } + if exist { + if err := r.checkLockFile(ctx, p); err != nil { + return errors.Trace(err) + } + } + if err = r.flushLock(ctx, p); err != nil { + return errors.Trace(err) + } + + // wait for 3 seconds to check whether the lock file is overwritten by another BR + time.Sleep(3 * time.Second) + err = r.checkLockFile(ctx, p) + return errors.Trace(err) +} + +// walk the whole checkpoint range files and retrieve the metadatat of backed up ranges +// and return the total time cost in the past executions +func WalkCheckpointFile(ctx context.Context, s storage.ExternalStorage, cipher *backuppb.CipherInfo, fn func(groupKey string, rg *rtree.Range)) (time.Duration, error) { + // records the total time cost in the past executions + var pastDureTime time.Duration = 0 + err := s.WalkDir(ctx, &storage.WalkOption{SubDir: CheckpointDataDir}, func(path string, size int64) error { + if strings.HasSuffix(path, ".cpt") { + content, err := s.ReadFile(ctx, path) + if err != nil { + return errors.Trace(err) + } + + checkpointData := &CheckpointData{} + if err = json.Unmarshal(content, checkpointData); err != nil { + return errors.Trace(err) + } + + if checkpointData.DureTime > pastDureTime { + pastDureTime = checkpointData.DureTime + } + for _, meta := range checkpointData.RangeGroupMetas { + decryptContent, err := metautil.Decrypt(meta.RangeGroupsEncriptedData, cipher, meta.CipherIv) + if err != nil { + return errors.Trace(err) + } + + checksum := sha256.Sum256(decryptContent) + if !bytes.Equal(meta.Checksum, checksum[:]) { + log.Error("checkpoint checksum info's checksum mismatch, skip it", + zap.ByteString("expect", meta.Checksum), + zap.ByteString("got", checksum[:]), + ) + continue + } + + group := &RangeGroups{} + if err = json.Unmarshal(decryptContent, group); err != nil { + return errors.Trace(err) + } + + for _, g := range group.Groups { + fn(group.GroupKey, g) + } + } + } + return nil + }) + + return pastDureTime, errors.Trace(err) +} + +type CheckpointMetadata struct { + GCServiceId string `json:"gc-service-id"` + ConfigHash []byte `json:"config-hash"` + BackupTS uint64 `json:"backup-ts"` + Ranges []rtree.Range `json:"ranges"` + + CheckpointChecksum map[int64]*ChecksumItem `json:"-"` + CheckpointDataMap map[string]rtree.RangeTree `json:"-"` +} + +// load checkpoint metadata from the external storage +func LoadCheckpointMetadata(ctx context.Context, s storage.ExternalStorage) (*CheckpointMetadata, error) { + data, err := s.ReadFile(ctx, CheckpointMetaPath) + if err != nil { + return nil, errors.Trace(err) + } + m := &CheckpointMetadata{} + err = json.Unmarshal(data, m) + if err != nil { + return nil, errors.Trace(err) + } + m.CheckpointChecksum, err = loadCheckpointChecksum(ctx, s) + return m, errors.Trace(err) +} + +// walk the whole checkpoint checksum files and retrieve checksum information of tables calculated +func loadCheckpointChecksum(ctx context.Context, s storage.ExternalStorage) (map[int64]*ChecksumItem, error) { + checkpointChecksum := make(map[int64]*ChecksumItem) + + err := s.WalkDir(ctx, &storage.WalkOption{SubDir: CheckpointChecksumDir}, func(path string, size int64) error { + data, err := s.ReadFile(ctx, path) + if err != nil { + return errors.Trace(err) + } + info := &ChecksumInfo{} + err = json.Unmarshal(data, info) + if err != nil { + return errors.Trace(err) + } + + checksum := sha256.Sum256(info.Content) + if !bytes.Equal(info.Checksum, checksum[:]) { + log.Error("checkpoint checksum info's checksum mismatch, skip it", + zap.ByteString("expect", info.Checksum), + zap.ByteString("got", checksum[:]), + ) + return nil + } + + items := &ChecksumItems{} + err = json.Unmarshal(info.Content, items) + if err != nil { + return errors.Trace(err) + } + + for _, c := range items.Items { + checkpointChecksum[c.TableID] = c + } + return nil + }) + return checkpointChecksum, errors.Trace(err) +} + +// save the checkpoint metadata into the external storage +func SaveCheckpointMetadata(ctx context.Context, s storage.ExternalStorage, meta *CheckpointMetadata) error { + data, err := json.Marshal(meta) + if err != nil { + return errors.Trace(err) + } + + err = s.WriteFile(ctx, CheckpointMetaPath, data) + return errors.Trace(err) +} diff --git a/br/pkg/checkpoint/checkpoint_test.go b/br/pkg/checkpoint/checkpoint_test.go new file mode 100644 index 0000000000000..29d8b5aa993ac --- /dev/null +++ b/br/pkg/checkpoint/checkpoint_test.go @@ -0,0 +1,229 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package checkpoint_test + +import ( + "context" + "encoding/json" + "os" + "strings" + "testing" + "time" + + backuppb "github.com/pingcap/kvproto/pkg/brpb" + "github.com/pingcap/kvproto/pkg/encryptionpb" + "github.com/pingcap/tidb/br/pkg/checkpoint" + "github.com/pingcap/tidb/br/pkg/rtree" + "github.com/pingcap/tidb/br/pkg/storage" + "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/oracle" +) + +func TestCheckpointMeta(t *testing.T) { + ctx := context.Background() + base := t.TempDir() + s, err := storage.NewLocalStorage(base) + require.NoError(t, err) + + checkpointMeta := &checkpoint.CheckpointMetadata{ + ConfigHash: []byte("123456"), + BackupTS: 123456, + } + + err = checkpoint.SaveCheckpointMetadata(ctx, s, checkpointMeta) + require.NoError(t, err) + + checkpointMeta2, err := checkpoint.LoadCheckpointMetadata(ctx, s) + require.NoError(t, err) + require.Equal(t, checkpointMeta.ConfigHash, checkpointMeta2.ConfigHash) + require.Equal(t, checkpointMeta.BackupTS, checkpointMeta2.BackupTS) +} + +type mockTimer struct { + p int64 + l int64 +} + +func NewMockTimer(p, l int64) *mockTimer { + return &mockTimer{p: p, l: l} +} + +func (t *mockTimer) GetTS(ctx context.Context) (int64, int64, error) { + return t.p, t.l, nil +} + +func TestCheckpointRunner(t *testing.T) { + ctx := context.Background() + base := t.TempDir() + s, err := storage.NewLocalStorage(base) + require.NoError(t, err) + os.MkdirAll(base+checkpoint.CheckpointDataDir, 0o755) + os.MkdirAll(base+checkpoint.CheckpointChecksumDir, 0o755) + + cipher := &backuppb.CipherInfo{ + CipherType: encryptionpb.EncryptionMethod_AES256_CTR, + CipherKey: []byte("01234567890123456789012345678901"), + } + checkpointRunner, err := checkpoint.StartCheckpointRunnerForTest(ctx, s, cipher, 5*time.Second, NewMockTimer(10, 10)) + require.NoError(t, err) + + data := map[string]struct { + StartKey string + EndKey string + Name string + Name2 string + }{ + "a": { + StartKey: "a", + EndKey: "b", + Name: "c", + Name2: "d", + }, + "A": { + StartKey: "A", + EndKey: "B", + Name: "C", + Name2: "D", + }, + "1": { + StartKey: "1", + EndKey: "2", + Name: "3", + Name2: "4", + }, + } + + data2 := map[string]struct { + StartKey string + EndKey string + Name string + Name2 string + }{ + "+": { + StartKey: "+", + EndKey: "-", + Name: "*", + Name2: "/", + }, + } + + for _, d := range data { + err = checkpointRunner.Append(ctx, "a", []byte(d.StartKey), []byte(d.EndKey), []*backuppb.File{ + {Name: d.Name}, + {Name: d.Name2}, + }) + require.NoError(t, err) + } + + checkpointRunner.FlushChecksum(ctx, 1, 1, 1, 1, checkpoint.MaxChecksumTotalCost-20.0) + checkpointRunner.FlushChecksum(ctx, 2, 2, 2, 2, 40.0) + // now the checksum is flushed, because the total time cost is larger than `MaxChecksumTotalCost` + checkpointRunner.FlushChecksum(ctx, 3, 3, 3, 3, checkpoint.MaxChecksumTotalCost-20.0) + time.Sleep(6 * time.Second) + // the checksum has not been flushed even though after 6 seconds, + // because the total time cost is less than `MaxChecksumTotalCost` + checkpointRunner.FlushChecksum(ctx, 4, 4, 4, 4, 40.0) + + for _, d := range data2 { + err = checkpointRunner.Append(ctx, "+", []byte(d.StartKey), []byte(d.EndKey), []*backuppb.File{ + {Name: d.Name}, + {Name: d.Name2}, + }) + require.NoError(t, err) + } + + checkpointRunner.WaitForFinish(ctx) + + checker := func(groupKey string, resp *rtree.Range) { + require.NotNil(t, resp) + d, ok := data[string(resp.StartKey)] + if !ok { + d, ok = data2[string(resp.StartKey)] + require.True(t, ok) + } + require.Equal(t, d.StartKey, string(resp.StartKey)) + require.Equal(t, d.EndKey, string(resp.EndKey)) + require.Equal(t, d.Name, resp.Files[0].Name) + require.Equal(t, d.Name2, resp.Files[1].Name) + } + + _, err = checkpoint.WalkCheckpointFile(ctx, s, cipher, checker) + require.NoError(t, err) + + checkpointMeta := &checkpoint.CheckpointMetadata{ + ConfigHash: []byte("123456"), + BackupTS: 123456, + } + + err = checkpoint.SaveCheckpointMetadata(ctx, s, checkpointMeta) + require.NoError(t, err) + meta, err := checkpoint.LoadCheckpointMetadata(ctx, s) + require.NoError(t, err) + + var i int64 + for i = 1; i <= 4; i++ { + require.Equal(t, meta.CheckpointChecksum[i].Crc64xor, uint64(i)) + } + + // only 2 checksum files exists, they are t2_and__ and t4_and__ + count := 0 + err = s.WalkDir(ctx, &storage.WalkOption{SubDir: checkpoint.CheckpointChecksumDir}, func(s string, i int64) error { + count += 1 + if !strings.Contains(s, "t2") { + require.True(t, strings.Contains(s, "t4")) + } + return nil + }) + require.NoError(t, err) + require.Equal(t, count, 2) +} + +func getLockData(p, l int64) ([]byte, error) { + lock := checkpoint.CheckpointLock{ + LockId: oracle.ComposeTS(p, l), + ExpireAt: p + 10, + } + return json.Marshal(lock) +} + +func TestCheckpointRunnerLock(t *testing.T) { + ctx := context.Background() + base := t.TempDir() + s, err := storage.NewLocalStorage(base) + require.NoError(t, err) + os.MkdirAll(base+checkpoint.CheckpointDataDir, 0o755) + os.MkdirAll(base+checkpoint.CheckpointChecksumDir, 0o755) + + cipher := &backuppb.CipherInfo{ + CipherType: encryptionpb.EncryptionMethod_AES256_CTR, + CipherKey: []byte("01234567890123456789012345678901"), + } + + data, err := getLockData(10, 20) + require.NoError(t, err) + err = s.WriteFile(ctx, checkpoint.CheckpointLockPath, data) + require.NoError(t, err) + + _, err = checkpoint.StartCheckpointRunnerForTest(ctx, s, cipher, 5*time.Second, NewMockTimer(10, 10)) + require.Error(t, err) + + runner, err := checkpoint.StartCheckpointRunnerForTest(ctx, s, cipher, 5*time.Second, NewMockTimer(30, 10)) + require.NoError(t, err) + + _, err = checkpoint.StartCheckpointRunnerForTest(ctx, s, cipher, 5*time.Second, NewMockTimer(40, 10)) + require.Error(t, err) + + runner.WaitForFinish(ctx) +} diff --git a/br/pkg/checksum/executor_test.go b/br/pkg/checksum/executor_test.go index adcaed9c314f9..876103bc055a2 100644 --- a/br/pkg/checksum/executor_test.go +++ b/br/pkg/checksum/executor_test.go @@ -104,7 +104,7 @@ func TestChecksum(t *testing.T) { first = false ranges, err := backup.BuildTableRanges(tableInfo3) require.NoError(t, err) - require.Equalf(t, ranges[:1], req.KeyRanges, "%v", req.KeyRanges) + require.Equalf(t, ranges[:1], req.KeyRanges.FirstPartitionRange(), "%v", req.KeyRanges.FirstPartitionRange()) } return nil })) diff --git a/br/pkg/checksum/main_test.go b/br/pkg/checksum/main_test.go index 2ce42a4dc3266..f81a602724a92 100644 --- a/br/pkg/checksum/main_test.go +++ b/br/pkg/checksum/main_test.go @@ -24,6 +24,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/klauspost/compress/zstd.(*blockDec).startDecoder"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } diff --git a/br/pkg/conn/conn.go b/br/pkg/conn/conn.go index 5adbe0a33ab1c..157b9cdf794c9 100644 --- a/br/pkg/conn/conn.go +++ b/br/pkg/conn/conn.go @@ -191,7 +191,6 @@ func NewMgr( return nil, errors.Trace(err) } // we must check tidb(tikv version) any time after concurrent ddl feature implemented in v6.2. - // when tidb < 6.2 we need set EnableConcurrentDDL false to make ddl works. // we will keep this check until 7.0, which allow the breaking changes. // NOTE: must call it after domain created! // FIXME: remove this check in v7.0 @@ -281,7 +280,8 @@ func (mgr *Mgr) GetTS(ctx context.Context) (uint64, error) { } // GetMergeRegionSizeAndCount returns the tikv config `coprocessor.region-split-size` and `coprocessor.region-split-key`. -func (mgr *Mgr) GetMergeRegionSizeAndCount(ctx context.Context, client *http.Client) (uint64, uint64, error) { +// returns the default config when failed. +func (mgr *Mgr) GetMergeRegionSizeAndCount(ctx context.Context, client *http.Client) (uint64, uint64) { regionSplitSize := DefaultMergeRegionSizeBytes regionSplitKeys := DefaultMergeRegionKeyCount type coprocessor struct { @@ -310,9 +310,10 @@ func (mgr *Mgr) GetMergeRegionSizeAndCount(ctx context.Context, client *http.Cli return nil }) if err != nil { - return 0, 0, errors.Trace(err) + log.Warn("meet error when getting config from TiKV; using default", logutil.ShortError(err)) + return DefaultMergeRegionSizeBytes, DefaultMergeRegionKeyCount } - return regionSplitSize, regionSplitKeys, nil + return regionSplitSize, regionSplitKeys } // GetConfigFromTiKV get configs from all alive tikv stores. diff --git a/br/pkg/conn/conn_test.go b/br/pkg/conn/conn_test.go index 01ce8bc08203e..fc822fac123d9 100644 --- a/br/pkg/conn/conn_test.go +++ b/br/pkg/conn/conn_test.go @@ -292,6 +292,38 @@ func TestGetMergeRegionSizeAndCount(t *testing.T) { regionSplitSize: DefaultMergeRegionSizeBytes, regionSplitKeys: DefaultMergeRegionKeyCount, }, + { + stores: []*metapb.Store{ + { + Id: 1, + State: metapb.StoreState_Up, + Labels: []*metapb.StoreLabel{ + { + Key: "engine", + Value: "tiflash", + }, + }, + }, + { + Id: 2, + State: metapb.StoreState_Up, + Labels: []*metapb.StoreLabel{ + { + Key: "engine", + Value: "tikv", + }, + }, + }, + }, + content: []string{ + "", + // Assuming the TiKV has failed due to some reason. + "", + }, + // no tikv detected in this case + regionSplitSize: DefaultMergeRegionSizeBytes, + regionSplitKeys: DefaultMergeRegionKeyCount, + }, { stores: []*metapb.Store{ { @@ -388,8 +420,7 @@ func TestGetMergeRegionSizeAndCount(t *testing.T) { httpCli := mockServer.Client() mgr := &Mgr{PdController: &pdutil.PdController{}} mgr.PdController.SetPDClient(pdCli) - rs, rk, err := mgr.GetMergeRegionSizeAndCount(ctx, httpCli) - require.NoError(t, err) + rs, rk := mgr.GetMergeRegionSizeAndCount(ctx, httpCli) require.Equal(t, ca.regionSplitSize, rs) require.Equal(t, ca.regionSplitKeys, rk) mockServer.Close() diff --git a/br/pkg/conn/main_test.go b/br/pkg/conn/main_test.go index 9ab9ec0d31297..f6df9f2c568a4 100644 --- a/br/pkg/conn/main_test.go +++ b/br/pkg/conn/main_test.go @@ -24,6 +24,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/br/pkg/errors/errors.go b/br/pkg/errors/errors.go index 07e9fb6317cb9..2b7d76e28d795 100644 --- a/br/pkg/errors/errors.go +++ b/br/pkg/errors/errors.go @@ -83,8 +83,9 @@ var ( ErrStorageInvalidPermission = errors.Normalize("external storage permission", errors.RFCCodeText("BR:ExternalStorage:ErrStorageInvalidPermission")) // Snapshot restore - ErrRestoreTotalKVMismatch = errors.Normalize("restore total tikvs mismatch", errors.RFCCodeText("BR:EBS:ErrRestoreTotalKVMismatch")) - ErrRestoreInvalidPeer = errors.Normalize("restore met a invalid peer", errors.RFCCodeText("BR:EBS:ErrRestoreInvalidPeer")) + ErrRestoreTotalKVMismatch = errors.Normalize("restore total tikvs mismatch", errors.RFCCodeText("BR:EBS:ErrRestoreTotalKVMismatch")) + ErrRestoreInvalidPeer = errors.Normalize("restore met a invalid peer", errors.RFCCodeText("BR:EBS:ErrRestoreInvalidPeer")) + ErrRestoreRegionWithoutPeer = errors.Normalize("restore met a region without any peer", errors.RFCCodeText("BR:EBS:ErrRestoreRegionWithoutPeer")) // Errors reported from TiKV. ErrKVStorage = errors.Normalize("tikv storage occur I/O error", errors.RFCCodeText("BR:KV:ErrKVStorage")) diff --git a/br/pkg/errors/errors_test.go b/br/pkg/errors/errors_test.go index a6f4c412280cc..fab655ba60c7e 100644 --- a/br/pkg/errors/errors_test.go +++ b/br/pkg/errors/errors_test.go @@ -22,3 +22,9 @@ func TestIsContextCanceled(t *testing.T) { require.True(t, berrors.IsContextCanceled(&url.Error{Err: context.Canceled})) require.True(t, berrors.IsContextCanceled(&url.Error{Err: context.DeadlineExceeded})) } + +func TestEqual(t *testing.T) { + err := errors.Annotate(berrors.ErrPDBatchScanRegion, "test error equla") + r := berrors.ErrPDBatchScanRegion.Equal(err) + require.True(t, r) +} diff --git a/br/pkg/glue/BUILD.bazel b/br/pkg/glue/BUILD.bazel index 0e8dc90913d8c..dc993f47c31d8 100644 --- a/br/pkg/glue/BUILD.bazel +++ b/br/pkg/glue/BUILD.bazel @@ -5,20 +5,22 @@ go_library( srcs = [ "console_glue.go", "glue.go", + "progressing.go", ], importpath = "github.com/pingcap/tidb/br/pkg/glue", visibility = ["//visibility:public"], deps = [ - "//br/pkg/logutil", + "//br/pkg/utils", + "//ddl", "//domain", "//kv", "//parser/model", "//sessionctx", "@com_github_fatih_color//:color", - "@com_github_pingcap_log//:log", "@com_github_tikv_pd_client//:client", + "@com_github_vbauerster_mpb_v7//:mpb", + "@com_github_vbauerster_mpb_v7//decor", "@org_golang_x_term//:term", - "@org_uber_go_zap//:zap", ], ) diff --git a/br/pkg/glue/console_glue.go b/br/pkg/glue/console_glue.go index c69e24302e5ad..7a2ed1127ec5c 100644 --- a/br/pkg/glue/console_glue.go +++ b/br/pkg/glue/console_glue.go @@ -5,19 +5,17 @@ package glue import ( "fmt" "io" - "math" "os" "regexp" "strings" "time" "github.com/fatih/color" - "github.com/pingcap/log" - "github.com/pingcap/tidb/br/pkg/logutil" - "go.uber.org/zap" "golang.org/x/term" ) +const defaultTerminalWidth = 80 + // ConsoleOperations are some operations based on ConsoleGlue. type ConsoleOperations struct { ConsoleGlue @@ -35,7 +33,7 @@ type ExtraField func() [2]string func WithTimeCost() ExtraField { start := time.Now() return func() [2]string { - return [2]string{"take", time.Since(start).String()} + return [2]string{"take", time.Since(start).Round(time.Millisecond).String()} } } @@ -46,6 +44,24 @@ func WithConstExtraField(key string, value interface{}) ExtraField { } } +// WithCallbackExtraField adds an extra field with the callback. +func WithCallbackExtraField(key string, value func() string) ExtraField { + return func() [2]string { + return [2]string{key, value()} + } +} + +func printFinalMessage(extraFields []ExtraField) func() string { + return func() string { + fields := make([]string, 0, len(extraFields)) + for _, fieldFunc := range extraFields { + field := fieldFunc() + fields = append(fields, fmt.Sprintf("%s = %s", field[0], color.New(color.Bold).Sprint(field[1]))) + } + return fmt.Sprintf("%s { %s }", color.HiGreenString("DONE"), strings.Join(fields, ", ")) + } +} + // ShowTask prints a task start information, and mark as finished when the returned function called. // This is for TUI presenting. func (ops ConsoleOperations) ShowTask(message string, extraFields ...ExtraField) func() { @@ -56,7 +72,7 @@ func (ops ConsoleOperations) ShowTask(message string, extraFields ...ExtraField) field := fieldFunc() fields = append(fields, fmt.Sprintf("%s = %s", field[0], color.New(color.Bold).Sprint(field[1]))) } - ops.Printf("%s; %s\n", color.HiGreenString("DONE"), strings.Join(fields, ", ")) + ops.Printf("%s { %s }\n", color.HiGreenString("DONE"), strings.Join(fields, ", ")) } } @@ -90,26 +106,50 @@ func (ops ConsoleOperations) PromptBool(p string) bool { } } -func (ops *ConsoleOperations) CreateTable() *Table { +func (ops ConsoleOperations) IsInteractive() bool { + f, ok := ops.In().(*os.File) + if !ok { + return false + } + return term.IsTerminal(int(f.Fd())) +} + +func (ops ConsoleOperations) Scanln(args ...interface{}) (int, error) { + return fmt.Fscanln(ops.In(), args...) +} + +func (ops ConsoleOperations) GetWidth() int { + f, ok := ops.In().(*os.File) + if !ok { + return defaultTerminalWidth + } + w, _, err := term.GetSize(int(f.Fd())) + if err != nil { + return defaultTerminalWidth + } + return w +} + +func (ops ConsoleOperations) CreateTable() *Table { return &Table{ console: ops, } } func (ops ConsoleOperations) Print(args ...interface{}) { - fmt.Fprint(ops, args...) + _, _ = fmt.Fprint(ops.Out(), args...) } func (ops ConsoleOperations) Println(args ...interface{}) { - fmt.Fprintln(ops, args...) + _, _ = fmt.Fprintln(ops.Out(), args...) } func (ops ConsoleOperations) Printf(format string, args ...interface{}) { - fmt.Fprintf(ops, format, args...) + _, _ = fmt.Fprintf(ops.Out(), format, args...) } type Table struct { - console *ConsoleOperations + console ConsoleOperations items [][2]string } @@ -161,31 +201,25 @@ func (t *Table) Print() { // ConsoleGlue is the glue between BR and some type of console, // which is the port for interact with the user. +// Generally, this is a abstraction of an UNIX terminal. type ConsoleGlue interface { - io.Writer - - // IsInteractive checks whether the shell supports input. - IsInteractive() bool - Scanln(args ...interface{}) (int, error) - GetWidth() int + // Out returns the output port of the console. + Out() io.Writer + // In returns the input of the console. + // Usually is should be an *os.File. + In() io.Reader } +// NoOPConsoleGlue is the glue for "embedded" BR, say, BRIE via SQL. +// This Glue simply drop all console operations. type NoOPConsoleGlue struct{} -func (NoOPConsoleGlue) Write(bs []byte) (int, error) { - return len(bs), nil -} - -func (NoOPConsoleGlue) IsInteractive() bool { - return false -} - -func (NoOPConsoleGlue) Scanln(args ...interface{}) (int, error) { - return 0, nil +func (NoOPConsoleGlue) In() io.Reader { + return strings.NewReader("") } -func (NoOPConsoleGlue) GetWidth() int { - return math.MaxUint32 +func (NoOPConsoleGlue) Out() io.Writer { + return io.Discard } func GetConsole(g Glue) ConsoleOperations { @@ -195,30 +229,16 @@ func GetConsole(g Glue) ConsoleOperations { return ConsoleOperations{ConsoleGlue: NoOPConsoleGlue{}} } +// StdIOGlue is the console glue for CLI applications, like the BR CLI. type StdIOGlue struct{} -func (s StdIOGlue) Write(p []byte) (n int, err error) { - return os.Stdout.Write(p) +func (s StdIOGlue) Out() io.Writer { + return os.Stdout } -// IsInteractive checks whether the shell supports input. -func (s StdIOGlue) IsInteractive() bool { +func (s StdIOGlue) In() io.Reader { // should we detach whether we are in a interactive tty here? - return term.IsTerminal(int(os.Stdin.Fd())) -} - -func (s StdIOGlue) Scanln(args ...interface{}) (int, error) { - return fmt.Scanln(args...) -} - -func (s StdIOGlue) GetWidth() int { - width, _, err := term.GetSize(int(os.Stdin.Fd())) - if err != nil { - log.Warn("failed to get terminal size, using infinity", logutil.ShortError(err), zap.Int("fd", int(os.Stdin.Fd()))) - return math.MaxUint32 - } - log.Debug("terminal width got.", zap.Int("width", width)) - return width + return os.Stdin } // PrettyString is a string with ANSI escape sequence which would change its color. diff --git a/br/pkg/glue/console_glue_test.go b/br/pkg/glue/console_glue_test.go index 61a07ac6fc7ed..871e193ee0998 100644 --- a/br/pkg/glue/console_glue_test.go +++ b/br/pkg/glue/console_glue_test.go @@ -108,8 +108,8 @@ type writerGlue struct { w io.Writer } -func (w writerGlue) Write(b []byte) (int, error) { - return w.w.Write(b) +func (w writerGlue) Out() io.Writer { + return w.w } func testPrintFrame(t *testing.T) { diff --git a/br/pkg/glue/glue.go b/br/pkg/glue/glue.go index cb4681dad4226..450a0b73ec659 100644 --- a/br/pkg/glue/glue.go +++ b/br/pkg/glue/glue.go @@ -5,6 +5,7 @@ package glue import ( "context" + "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" @@ -42,7 +43,7 @@ type Session interface { Execute(ctx context.Context, sql string) error ExecuteInternal(ctx context.Context, sql string, args ...interface{}) error CreateDatabase(ctx context.Context, schema *model.DBInfo) error - CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo) error + CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error CreatePlacementPolicy(ctx context.Context, policy *model.PolicyInfo) error Close() GetGlobalVariable(name string) (string, error) @@ -51,7 +52,7 @@ type Session interface { // BatchCreateTableSession is an interface to batch create table parallelly type BatchCreateTableSession interface { - CreateTables(ctx context.Context, tables map[string][]*model.TableInfo) error + CreateTables(ctx context.Context, tables map[string][]*model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error } // Progress is an interface recording the current execution progress. diff --git a/br/pkg/glue/progressing.go b/br/pkg/glue/progressing.go new file mode 100644 index 0000000000000..8d5808c00c39a --- /dev/null +++ b/br/pkg/glue/progressing.go @@ -0,0 +1,142 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package glue + +import ( + "context" + "fmt" + "io" + "os" + "time" + + "github.com/fatih/color" + "github.com/pingcap/tidb/br/pkg/utils" + "github.com/vbauerster/mpb/v7" + "github.com/vbauerster/mpb/v7/decor" + "golang.org/x/term" +) + +type pbProgress struct { + bar *mpb.Bar + progress *mpb.Progress + ops ConsoleOperations +} + +// Inc increases the progress. This method must be goroutine-safe, and can +// be called from any goroutine. +func (p pbProgress) Inc() { + p.bar.Increment() +} + +// IncBy increases the progress by n. +func (p pbProgress) IncBy(n int64) { + p.bar.IncrBy(int(n)) +} + +func (p pbProgress) GetCurrent() int64 { + return p.bar.Current() +} + +// Close marks the progress as 100% complete and that Inc() can no longer be +// called. +func (p pbProgress) Close() { + if p.bar.Completed() || p.bar.Aborted() { + return + } + p.bar.Abort(false) +} + +// Wait implements the ProgressWaiter interface. +func (p pbProgress) Wait(ctx context.Context) error { + ch := make(chan struct{}) + go func() { + p.progress.Wait() + close(ch) + }() + select { + case <-ctx.Done(): + return ctx.Err() + case <-ch: + return nil + } +} + +// ProgressWaiter is the extended `Progress“: which provides a `wait` method to +// allow caller wait until all unit in the progress finished. +type ProgressWaiter interface { + Progress + Wait(context.Context) error +} + +type noOPWaiter struct { + Progress +} + +func (nw noOPWaiter) Wait(context.Context) error { + return nil +} + +// cbOnComplete like `decor.OnComplete`, however allow the message provided by a function. +func cbOnComplete(decl decor.Decorator, cb func() string) decor.DecorFunc { + return func(s decor.Statistics) string { + if s.Completed { + return cb() + } + return decl.Decor(s) + } +} + +func (ops ConsoleOperations) OutputIsTTY() bool { + f, ok := ops.Out().(*os.File) + if !ok { + return false + } + return term.IsTerminal(int(f.Fd())) +} + +// StartProgressBar starts a progress bar with the console operations. +// Note: This function has overlapped function with `glue.StartProgress`, however this supports display extra fields +// +// after success, and implement by `mpb` (instead of `pb`). +// +// Note': Maybe replace the old `StartProgress` with `mpb` too. +func (ops ConsoleOperations) StartProgressBar(title string, total int, extraFields ...ExtraField) ProgressWaiter { + if !ops.OutputIsTTY() { + return ops.startProgressBarOverDummy(title, total, extraFields...) + } + return ops.startProgressBarOverTTY(title, total, extraFields...) +} + +func (ops ConsoleOperations) startProgressBarOverDummy(title string, total int, extraFields ...ExtraField) ProgressWaiter { + return noOPWaiter{utils.StartProgress(context.TODO(), title, int64(total), true, nil)} +} + +func (ops ConsoleOperations) startProgressBarOverTTY(title string, total int, extraFields ...ExtraField) ProgressWaiter { + pb := mpb.New(mpb.WithOutput(ops.Out()), mpb.WithRefreshRate(400*time.Millisecond)) + greenTitle := color.GreenString(title) + bar := pb.New(int64(total), + // Play as if the old BR style. + mpb.BarStyle().Lbound("<").Filler("-").Padding(".").Rbound(">").Tip("-", "\\", "|", "/", "-").TipOnComplete("-"), + mpb.BarFillerMiddleware(func(bf mpb.BarFiller) mpb.BarFiller { + return mpb.BarFillerFunc(func(w io.Writer, reqWidth int, stat decor.Statistics) { + if stat.Aborted || stat.Completed { + return + } + bf.Fill(w, reqWidth, stat) + }) + }), + mpb.PrependDecorators(decor.OnAbort(decor.OnComplete(decor.Name(greenTitle), fmt.Sprintf("%s ::", title)), fmt.Sprintf("%s ::", title))), + mpb.AppendDecorators(decor.OnAbort(decor.Any(cbOnComplete(decor.NewPercentage("%02.2f"), printFinalMessage(extraFields))), color.RedString("ABORTED"))), + ) + + // If total is zero, finish right now. + if total == 0 { + bar.SetTotal(0, true) + } + + return pbProgress{ + bar: bar, + ops: ops, + progress: pb, + } +} diff --git a/br/pkg/gluetidb/glue.go b/br/pkg/gluetidb/glue.go index 459437e33b091..06af5615ff451 100644 --- a/br/pkg/gluetidb/glue.go +++ b/br/pkg/gluetidb/glue.go @@ -61,6 +61,10 @@ type tidbSession struct { // GetDomain implements glue.Glue. func (Glue) GetDomain(store kv.Storage) (*domain.Domain, error) { + initStatsSe, err := session.CreateSession(store) + if err != nil { + return nil, errors.Trace(err) + } se, err := session.CreateSession(store) if err != nil { return nil, errors.Trace(err) @@ -69,8 +73,12 @@ func (Glue) GetDomain(store kv.Storage) (*domain.Domain, error) { if err != nil { return nil, errors.Trace(err) } + err = session.InitMDLVariable(store) + if err != nil { + return nil, err + } // create stats handler for backup and restore. - err = dom.UpdateTableStatsLoop(se) + err = dom.UpdateTableStatsLoop(se, initStatsSe) if err != nil { return nil, errors.Trace(err) } @@ -132,6 +140,10 @@ func (g Glue) UseOneShotSession(store kv.Storage, closeDomain bool, fn func(glue if err != nil { return errors.Trace(err) } + if err = session.InitMDLVariable(store); err != nil { + return errors.Trace(err) + } + // because domain was created during the whole program exists. // and it will register br info to info syncer. // we'd better close it as soon as possible. @@ -203,11 +215,36 @@ func (gs *tidbSession) CreatePlacementPolicy(ctx context.Context, policy *model. return d.CreatePlacementPolicyWithInfo(gs.se, policy, ddl.OnExistIgnore) } -// CreateTables implements glue.BatchCreateTableSession. -func (gs *tidbSession) CreateTables(ctx context.Context, tables map[string][]*model.TableInfo) error { +// SplitBatchCreateTable provide a way to split batch into small batch when batch size is large than 6 MB. +// The raft entry has limit size of 6 MB, a batch of CreateTables may hit this limitation +// TODO: shall query string be set for each split batch create, it looks does not matter if we set once for all. +func (gs *tidbSession) SplitBatchCreateTable(schema model.CIStr, info []*model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { + var err error d := domain.GetDomain(gs.se).DDL() + if err = d.BatchCreateTableWithInfo(gs.se, schema, info, append(cs, ddl.OnExistIgnore)...); kv.ErrEntryTooLarge.Equal(err) { + if len(info) == 1 { + return err + } + mid := len(info) / 2 + err = gs.SplitBatchCreateTable(schema, info[:mid]) + if err != nil { + return err + } + err = gs.SplitBatchCreateTable(schema, info[mid:]) + if err != nil { + return err + } + return nil + } + return err +} + +// CreateTables implements glue.BatchCreateTableSession. +func (gs *tidbSession) CreateTables(ctx context.Context, tables map[string][]*model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { var dbName model.CIStr + // Disable foreign key check when batch create tables. + gs.se.GetSessionVars().ForeignKeyChecks = false for db, tablesInDB := range tables { dbName = model.NewCIStr(db) queryBuilder := strings.Builder{} @@ -231,8 +268,7 @@ func (gs *tidbSession) CreateTables(ctx context.Context, tables map[string][]*mo cloneTables = append(cloneTables, table) } gs.se.SetValue(sessionctx.QueryString, queryBuilder.String()) - err := d.BatchCreateTableWithInfo(gs.se, dbName, cloneTables, ddl.OnExistIgnore) - if err != nil { + if err := gs.SplitBatchCreateTable(dbName, cloneTables); err != nil { //It is possible to failure when TiDB does not support model.ActionCreateTables. //In this circumstance, BatchCreateTableWithInfo returns errno.ErrInvalidDDLJob, //we fall back to old way that creating table one by one @@ -245,7 +281,7 @@ func (gs *tidbSession) CreateTables(ctx context.Context, tables map[string][]*mo } // CreateTable implements glue.Session. -func (gs *tidbSession) CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo) error { +func (gs *tidbSession) CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { d := domain.GetDomain(gs.se).DDL() query, err := gs.showCreateTable(table) if err != nil { @@ -259,7 +295,8 @@ func (gs *tidbSession) CreateTable(ctx context.Context, dbName model.CIStr, tabl newPartition.Definitions = append([]model.PartitionDefinition{}, table.Partition.Definitions...) table.Partition = &newPartition } - return d.CreateTableWithInfo(gs.se, dbName, table, ddl.OnExistIgnore) + + return d.CreateTableWithInfo(gs.se, dbName, table, append(cs, ddl.OnExistIgnore)...) } // Close implements glue.Session. @@ -302,7 +339,8 @@ func (gs *tidbSession) showCreatePlacementPolicy(policy *model.PolicyInfo) strin // mockSession is used for test. type mockSession struct { - se session.Session + se session.Session + globalVars map[string]string } // GetSessionCtx implements glue.Glue @@ -349,13 +387,13 @@ func (s *mockSession) CreatePlacementPolicy(ctx context.Context, policy *model.P } // CreateTables implements glue.BatchCreateTableSession. -func (s *mockSession) CreateTables(ctx context.Context, tables map[string][]*model.TableInfo) error { +func (s *mockSession) CreateTables(ctx context.Context, tables map[string][]*model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { log.Fatal("unimplemented CreateDatabase for mock session") return nil } // CreateTable implements glue.Session. -func (s *mockSession) CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo) error { +func (s *mockSession) CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { log.Fatal("unimplemented CreateDatabase for mock session") return nil } @@ -367,12 +405,16 @@ func (s *mockSession) Close() { // GetGlobalVariables implements glue.Session. func (s *mockSession) GetGlobalVariable(name string) (string, error) { - return "true", nil + if ret, ok := s.globalVars[name]; ok { + return ret, nil + } + return "True", nil } // MockGlue only used for test type MockGlue struct { - se session.Session + se session.Session + GlobalVars map[string]string } func (m *MockGlue) SetSession(se session.Session) { @@ -387,7 +429,8 @@ func (*MockGlue) GetDomain(store kv.Storage) (*domain.Domain, error) { // CreateSession implements glue.Glue. func (m *MockGlue) CreateSession(store kv.Storage) (glue.Session, error) { glueSession := &mockSession{ - se: m.se, + se: m.se, + globalVars: m.GlobalVars, } return glueSession, nil } diff --git a/br/pkg/lightning/BUILD.bazel b/br/pkg/lightning/BUILD.bazel index 6b3c5f8e3ce31..fc646195c6e2b 100644 --- a/br/pkg/lightning/BUILD.bazel +++ b/br/pkg/lightning/BUILD.bazel @@ -28,7 +28,10 @@ go_library( "//br/pkg/version/build", "//expression", "//planner/core", + "//util", "//util/promutil", + "@com_github_go_sql_driver_mysql//:mysql", + "@com_github_google_uuid//:uuid", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_kvproto//pkg/import_sstpb", @@ -37,6 +40,7 @@ go_library( "@com_github_prometheus_client_golang//prometheus/promhttp", "@com_github_shurcool_httpgzip//:httpgzip", "@org_golang_x_exp//slices", + "@org_uber_go_atomic//:atomic", "@org_uber_go_zap//:zap", "@org_uber_go_zap//zapcore", ], diff --git a/br/pkg/lightning/backend/kv/BUILD.bazel b/br/pkg/lightning/backend/kv/BUILD.bazel index ea2cfefc2440e..b0da8a0e7deb4 100644 --- a/br/pkg/lightning/backend/kv/BUILD.bazel +++ b/br/pkg/lightning/backend/kv/BUILD.bazel @@ -46,13 +46,14 @@ go_test( name = "kv_test", timeout = "short", srcs = [ + "session_internal_test.go", "session_test.go", "sql2kv_test.go", ], + embed = [":kv"], flaky = True, race = "on", deps = [ - ":kv", "//br/pkg/lightning/common", "//br/pkg/lightning/log", "//br/pkg/lightning/verification", @@ -69,6 +70,7 @@ go_test( "//tablecodec", "//types", "//util/mock", + "@com_github_docker_go_units//:go-units", "@com_github_stretchr_testify//require", "@org_uber_go_zap//:zap", "@org_uber_go_zap//zapcore", diff --git a/br/pkg/lightning/backend/kv/allocator.go b/br/pkg/lightning/backend/kv/allocator.go index 02f46ea8c7e36..14703e1143a45 100644 --- a/br/pkg/lightning/backend/kv/allocator.go +++ b/br/pkg/lightning/backend/kv/allocator.go @@ -34,6 +34,7 @@ type panickingAllocator struct { func NewPanickingAllocators(base int64) autoid.Allocators { sharedBase := &base return autoid.NewAllocators( + false, &panickingAllocator{base: sharedBase, ty: autoid.RowIDAllocType}, &panickingAllocator{base: sharedBase, ty: autoid.AutoIncrementType}, &panickingAllocator{base: sharedBase, ty: autoid.AutoRandomType}, diff --git a/br/pkg/lightning/backend/kv/session.go b/br/pkg/lightning/backend/kv/session.go index 1cc261b677fe4..a8c5b5970cdf8 100644 --- a/br/pkg/lightning/backend/kv/session.go +++ b/br/pkg/lightning/backend/kv/session.go @@ -38,6 +38,8 @@ import ( "go.uber.org/zap" ) +const maxAvailableBufSize int = 20 + // invalidIterator is a trimmed down Iterator type which is invalid. type invalidIterator struct { kv.Iterator @@ -92,6 +94,12 @@ func (mb *kvMemBuf) Recycle(buf *bytesBuf) { buf.idx = 0 buf.cap = len(buf.buf) mb.Lock() + if len(mb.availableBufs) >= maxAvailableBufSize { + // too many byte buffers, evict one byte buffer and continue + evictedByteBuf := mb.availableBufs[0] + evictedByteBuf.destroy() + mb.availableBufs = mb.availableBufs[1:] + } mb.availableBufs = append(mb.availableBufs, buf) mb.Unlock() } @@ -99,8 +107,20 @@ func (mb *kvMemBuf) Recycle(buf *bytesBuf) { func (mb *kvMemBuf) AllocateBuf(size int) { mb.Lock() size = mathutil.Max(units.MiB, int(utils.NextPowerOfTwo(int64(size)))*2) - if len(mb.availableBufs) > 0 && mb.availableBufs[0].cap >= size { - mb.buf = mb.availableBufs[0] + var ( + existingBuf *bytesBuf + existingBufIdx int + ) + for i, buf := range mb.availableBufs { + if buf.cap >= size { + existingBuf = buf + existingBufIdx = i + break + } + } + if existingBuf != nil { + mb.buf = existingBuf + mb.availableBufs[existingBufIdx] = mb.availableBufs[0] mb.availableBufs = mb.availableBufs[1:] } else { mb.buf = newBytesBuf(size) diff --git a/br/pkg/lightning/backend/kv/session_internal_test.go b/br/pkg/lightning/backend/kv/session_internal_test.go new file mode 100644 index 0000000000000..97ebd8cc82d1b --- /dev/null +++ b/br/pkg/lightning/backend/kv/session_internal_test.go @@ -0,0 +1,126 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kv + +import ( + "testing" + + "github.com/docker/go-units" + "github.com/stretchr/testify/require" +) + +func TestKVMemBufInterweaveAllocAndRecycle(t *testing.T) { + type testCase struct { + AllocSizes []int + FinalAvailableByteBufCaps []int + } + for _, tc := range []testCase{ + { + AllocSizes: []int{ + 1 * units.MiB, + 2 * units.MiB, + 3 * units.MiB, + 4 * units.MiB, + 5 * units.MiB, + }, + // [2] => [2,4] => [2,4,8] => [4,2,8] => [4,2,8,16] + FinalAvailableByteBufCaps: []int{ + 4 * units.MiB, + 2 * units.MiB, + 8 * units.MiB, + 16 * units.MiB, + }, + }, + { + AllocSizes: []int{ + 5 * units.MiB, + 4 * units.MiB, + 3 * units.MiB, + 2 * units.MiB, + 1 * units.MiB, + }, + // [16] => [16] => [16] => [16] => [16] + FinalAvailableByteBufCaps: []int{16 * units.MiB}, + }, + { + AllocSizes: []int{5, 4, 3, 2, 1}, + // [1] => [1] => [1] => [1] => [1] + FinalAvailableByteBufCaps: []int{1 * units.MiB}, + }, + { + AllocSizes: []int{ + 1 * units.MiB, + 2 * units.MiB, + 3 * units.MiB, + 2 * units.MiB, + 1 * units.MiB, + 5 * units.MiB, + }, + // [2] => [2,4] => [2,4,8] => [2,8,4] => [8,4,2] => [8,4,2,16] + FinalAvailableByteBufCaps: []int{ + 8 * units.MiB, + 4 * units.MiB, + 2 * units.MiB, + 16 * units.MiB, + }, + }, + } { + testKVMemBuf := &kvMemBuf{} + for _, allocSize := range tc.AllocSizes { + testKVMemBuf.AllocateBuf(allocSize) + testKVMemBuf.Recycle(testKVMemBuf.buf) + } + require.Equal(t, len(tc.FinalAvailableByteBufCaps), len(testKVMemBuf.availableBufs)) + for i, bb := range testKVMemBuf.availableBufs { + require.Equal(t, tc.FinalAvailableByteBufCaps[i], bb.cap) + } + } +} + +func TestKVMemBufBatchAllocAndRecycle(t *testing.T) { + type testCase struct { + AllocSizes []int + FinalAvailableByteBufCaps []int + } + testKVMemBuf := &kvMemBuf{} + bBufs := []*bytesBuf{} + for i := 0; i < maxAvailableBufSize; i++ { + testKVMemBuf.AllocateBuf(1 * units.MiB) + bBufs = append(bBufs, testKVMemBuf.buf) + } + for i := 0; i < maxAvailableBufSize; i++ { + testKVMemBuf.AllocateBuf(2 * units.MiB) + bBufs = append(bBufs, testKVMemBuf.buf) + } + for _, bb := range bBufs { + testKVMemBuf.Recycle(bb) + } + require.Equal(t, maxAvailableBufSize, len(testKVMemBuf.availableBufs)) + for _, bb := range testKVMemBuf.availableBufs { + require.Equal(t, 4*units.MiB, bb.cap) + } + bBufs = bBufs[:0] + for i := 0; i < maxAvailableBufSize; i++ { + testKVMemBuf.AllocateBuf(1 * units.MiB) + bb := testKVMemBuf.buf + require.Equal(t, 4*units.MiB, bb.cap) + bBufs = append(bBufs, bb) + require.Equal(t, maxAvailableBufSize-i-1, len(testKVMemBuf.availableBufs)) + } + for _, bb := range bBufs { + testKVMemBuf.Recycle(bb) + } + require.Equal(t, maxAvailableBufSize, len(testKVMemBuf.availableBufs)) +} diff --git a/br/pkg/lightning/backend/kv/sql2kv.go b/br/pkg/lightning/backend/kv/sql2kv.go index 6cebb1e29e329..9ad552ef5f340 100644 --- a/br/pkg/lightning/backend/kv/sql2kv.go +++ b/br/pkg/lightning/backend/kv/sql2kv.go @@ -169,7 +169,7 @@ func collectGeneratedColumns(se *session, meta *model.TableInfo, cols []*table.C var genCols []genCol for i, col := range cols { if col.GeneratedExpr != nil { - expr, err := expression.RewriteAstExpr(se, col.GeneratedExpr, schema, names) + expr, err := expression.RewriteAstExpr(se, col.GeneratedExpr, schema, names, false) if err != nil { return nil, err } diff --git a/br/pkg/lightning/backend/local/BUILD.bazel b/br/pkg/lightning/backend/local/BUILD.bazel index 6e2b5e9a1c43c..9524ab5febc2b 100644 --- a/br/pkg/lightning/backend/local/BUILD.bazel +++ b/br/pkg/lightning/backend/local/BUILD.bazel @@ -94,7 +94,7 @@ go_test( ], embed = [":local"], flaky = True, - shard_count = 20, + shard_count = 40, deps = [ "//br/pkg/errors", "//br/pkg/lightning/backend", @@ -103,6 +103,7 @@ go_test( "//br/pkg/lightning/glue", "//br/pkg/lightning/log", "//br/pkg/lightning/mydump", + "//br/pkg/lightning/worker", "//br/pkg/membuf", "//br/pkg/mock", "//br/pkg/pdutil", diff --git a/br/pkg/lightning/backend/local/duplicate.go b/br/pkg/lightning/backend/local/duplicate.go index b2858a8456f36..8877c16ae7740 100644 --- a/br/pkg/lightning/backend/local/duplicate.go +++ b/br/pkg/lightning/backend/local/duplicate.go @@ -211,7 +211,7 @@ func physicalTableIDs(tableInfo *model.TableInfo) []int64 { } // tableHandleKeyRanges returns all key ranges associated with the tableInfo. -func tableHandleKeyRanges(tableInfo *model.TableInfo) ([]tidbkv.KeyRange, error) { +func tableHandleKeyRanges(tableInfo *model.TableInfo) (*tidbkv.KeyRanges, error) { ranges := ranger.FullIntRange(false) if tableInfo.IsCommonHandle { ranges = ranger.FullRange() @@ -221,18 +221,9 @@ func tableHandleKeyRanges(tableInfo *model.TableInfo) ([]tidbkv.KeyRange, error) } // tableIndexKeyRanges returns all key ranges associated with the tableInfo and indexInfo. -func tableIndexKeyRanges(tableInfo *model.TableInfo, indexInfo *model.IndexInfo) ([]tidbkv.KeyRange, error) { +func tableIndexKeyRanges(tableInfo *model.TableInfo, indexInfo *model.IndexInfo) (*tidbkv.KeyRanges, error) { tableIDs := physicalTableIDs(tableInfo) - //nolint: prealloc - var keyRanges []tidbkv.KeyRange - for _, tid := range tableIDs { - partitionKeysRanges, err := distsql.IndexRangesToKVRanges(nil, tid, indexInfo.ID, ranger.FullRange(), nil) - if err != nil { - return nil, errors.Trace(err) - } - keyRanges = append(keyRanges, partitionKeysRanges...) - } - return keyRanges, nil + return distsql.IndexRangesToKVRangesForTables(nil, tableIDs, indexInfo.ID, ranger.FullRange(), nil) } // DupKVStream is a streaming interface for collecting duplicate key-value pairs. @@ -561,14 +552,23 @@ func (m *DuplicateManager) buildDupTasks() ([]dupTask, error) { if err != nil { return nil, errors.Trace(err) } - tasks := make([]dupTask, 0, len(keyRanges)) - for _, kr := range keyRanges { - tableID := tablecodec.DecodeTableID(kr.StartKey) - tasks = append(tasks, dupTask{ - KeyRange: kr, - tableID: tableID, - }) + tasks := make([]dupTask, 0, keyRanges.TotalRangeNum()*(1+len(m.tbl.Meta().Indices))) + putToTaskFunc := func(ranges []tidbkv.KeyRange, indexInfo *model.IndexInfo) { + if len(ranges) == 0 { + return + } + tid := tablecodec.DecodeTableID(ranges[0].StartKey) + for _, r := range ranges { + tasks = append(tasks, dupTask{ + KeyRange: r, + tableID: tid, + indexInfo: indexInfo, + }) + } } + keyRanges.ForEachPartition(func(ranges []tidbkv.KeyRange) { + putToTaskFunc(ranges, nil) + }) for _, indexInfo := range m.tbl.Meta().Indices { if indexInfo.State != model.StatePublic { continue @@ -577,14 +577,9 @@ func (m *DuplicateManager) buildDupTasks() ([]dupTask, error) { if err != nil { return nil, errors.Trace(err) } - for _, kr := range keyRanges { - tableID := tablecodec.DecodeTableID(kr.StartKey) - tasks = append(tasks, dupTask{ - KeyRange: kr, - tableID: tableID, - indexInfo: indexInfo, - }) - } + keyRanges.ForEachPartition(func(ranges []tidbkv.KeyRange) { + putToTaskFunc(ranges, indexInfo) + }) } return tasks, nil } @@ -598,15 +593,19 @@ func (m *DuplicateManager) buildIndexDupTasks() ([]dupTask, error) { if err != nil { return nil, errors.Trace(err) } - tasks := make([]dupTask, 0, len(keyRanges)) - for _, kr := range keyRanges { - tableID := tablecodec.DecodeTableID(kr.StartKey) - tasks = append(tasks, dupTask{ - KeyRange: kr, - tableID: tableID, - indexInfo: indexInfo, - }) - } + tasks := make([]dupTask, 0, keyRanges.TotalRangeNum()) + keyRanges.ForEachPartition(func(ranges []tidbkv.KeyRange) { + if len(ranges) == 0 { + return + } + tid := tablecodec.DecodeTableID(ranges[0].StartKey) + for _, r := range ranges { + tasks = append(tasks, dupTask{ + KeyRange: r, + tableID: tid, + }) + } + }) return tasks, nil } return nil, nil diff --git a/br/pkg/lightning/backend/local/engine.go b/br/pkg/lightning/backend/local/engine.go index 32d004654233f..9b757ed91fde4 100644 --- a/br/pkg/lightning/backend/local/engine.go +++ b/br/pkg/lightning/backend/local/engine.go @@ -123,6 +123,8 @@ type Engine struct { config backend.LocalEngineConfig tableInfo *checkpoints.TidbTableInfo + dupDetectOpt dupDetectOpt + // total size of SST files waiting to be ingested pendingFileSize atomic.Int64 @@ -981,7 +983,33 @@ func (e *Engine) newKVIter(ctx context.Context, opts *pebble.IterOptions) Iter { zap.String("table", common.UniqueTable(e.tableInfo.DB, e.tableInfo.Name)), zap.Int64("tableID", e.tableInfo.ID), zap.Stringer("engineUUID", e.UUID)) - return newDupDetectIter(ctx, e.db, e.keyAdapter, opts, e.duplicateDB, logger) + return newDupDetectIter(ctx, e.db, e.keyAdapter, opts, e.duplicateDB, logger, e.dupDetectOpt) +} + +func (e *Engine) getFirstAndLastKey(lowerBound, upperBound []byte) ([]byte, []byte, error) { + opt := &pebble.IterOptions{ + LowerBound: lowerBound, + UpperBound: upperBound, + } + + iter := e.newKVIter(context.Background(), opt) + //nolint: errcheck + defer iter.Close() + // Needs seek to first because NewIter returns an iterator that is unpositioned + hasKey := iter.First() + if iter.Error() != nil { + return nil, nil, errors.Annotate(iter.Error(), "failed to read the first key") + } + if !hasKey { + return nil, nil, nil + } + firstKey := append([]byte{}, iter.Key()...) + iter.Last() + if iter.Error() != nil { + return nil, nil, errors.Annotate(iter.Error(), "failed to seek to the last key") + } + lastKey := append([]byte{}, iter.Key()...) + return firstKey, lastKey, nil } type sstMeta struct { diff --git a/br/pkg/lightning/backend/local/engine_test.go b/br/pkg/lightning/backend/local/engine_test.go index c7ffe04b95285..2b935f30bb0c2 100644 --- a/br/pkg/lightning/backend/local/engine_test.go +++ b/br/pkg/lightning/backend/local/engine_test.go @@ -31,8 +31,17 @@ import ( "github.com/stretchr/testify/require" ) -func TestIngestSSTWithClosedEngine(t *testing.T) { +func makePebbleDB(t *testing.T, opt *pebble.Options) (*pebble.DB, string) { dir := t.TempDir() + db, err := pebble.Open(path.Join(dir, "test"), opt) + require.NoError(t, err) + tmpPath := filepath.Join(dir, "test.sst") + err = os.Mkdir(tmpPath, 0o755) + require.NoError(t, err) + return db, tmpPath +} + +func TestIngestSSTWithClosedEngine(t *testing.T) { opt := &pebble.Options{ MemTableSize: 1024 * 1024, MaxConcurrentCompactions: 16, @@ -41,11 +50,7 @@ func TestIngestSSTWithClosedEngine(t *testing.T) { DisableWAL: true, ReadOnly: false, } - db, err := pebble.Open(filepath.Join(dir, "test"), opt) - require.NoError(t, err) - tmpPath := filepath.Join(dir, "test.sst") - err = os.Mkdir(tmpPath, 0o755) - require.NoError(t, err) + db, tmpPath := makePebbleDB(t, opt) _, engineUUID := backend.MakeUUID("ww", 0) engineCtx, cancel := context.WithCancel(context.Background()) @@ -84,3 +89,37 @@ func TestIngestSSTWithClosedEngine(t *testing.T) { }, }), errorEngineClosed) } + +func TestGetFirstAndLastKey(t *testing.T) { + db, tmpPath := makePebbleDB(t, nil) + f := &Engine{ + db: db, + sstDir: tmpPath, + } + err := db.Set([]byte("a"), []byte("a"), nil) + require.NoError(t, err) + err = db.Set([]byte("c"), []byte("c"), nil) + require.NoError(t, err) + err = db.Set([]byte("e"), []byte("e"), nil) + require.NoError(t, err) + + first, last, err := f.getFirstAndLastKey(nil, nil) + require.NoError(t, err) + require.Equal(t, []byte("a"), first) + require.Equal(t, []byte("e"), last) + + first, last, err = f.getFirstAndLastKey([]byte("b"), []byte("d")) + require.NoError(t, err) + require.Equal(t, []byte("c"), first) + require.Equal(t, []byte("c"), last) + + first, last, err = f.getFirstAndLastKey([]byte("b"), []byte("f")) + require.NoError(t, err) + require.Equal(t, []byte("c"), first) + require.Equal(t, []byte("e"), last) + + first, last, err = f.getFirstAndLastKey([]byte("y"), []byte("z")) + require.NoError(t, err) + require.Nil(t, first) + require.Nil(t, last) +} diff --git a/br/pkg/lightning/backend/local/iterator.go b/br/pkg/lightning/backend/local/iterator.go index e2cb3a447cfbb..29ed50b743773 100644 --- a/br/pkg/lightning/backend/local/iterator.go +++ b/br/pkg/lightning/backend/local/iterator.go @@ -21,6 +21,7 @@ import ( "github.com/cockroachdb/pebble" sst "github.com/pingcap/kvproto/pkg/import_sstpb" + "github.com/pingcap/tidb/br/pkg/lightning/common" "github.com/pingcap/tidb/br/pkg/lightning/log" "github.com/pingcap/tidb/br/pkg/logutil" "go.uber.org/multierr" @@ -82,6 +83,11 @@ type dupDetectIter struct { writeBatch *pebble.Batch writeBatchSize int64 logger log.Logger + option dupDetectOpt +} + +type dupDetectOpt struct { + reportErrOnDup bool } func (d *dupDetectIter) Seek(key []byte) bool { @@ -149,6 +155,14 @@ func (d *dupDetectIter) Next() bool { d.curVal = append(d.curVal[:0], d.iter.Value()...) return true } + if d.option.reportErrOnDup { + dupKey := make([]byte, len(d.curKey)) + dupVal := make([]byte, len(d.iter.Value())) + copy(dupKey, d.curKey) + copy(dupVal, d.curVal) + d.err = common.ErrFoundDuplicateKeys.FastGenByArgs(dupKey, dupVal) + return false + } if !recordFirst { d.record(d.curRawKey, d.curKey, d.curVal) recordFirst = true @@ -192,7 +206,7 @@ func (d *dupDetectIter) OpType() sst.Pair_OP { var _ Iter = &dupDetectIter{} func newDupDetectIter(ctx context.Context, db *pebble.DB, keyAdapter KeyAdapter, - opts *pebble.IterOptions, dupDB *pebble.DB, logger log.Logger) *dupDetectIter { + opts *pebble.IterOptions, dupDB *pebble.DB, logger log.Logger, dupOpt dupDetectOpt) *dupDetectIter { newOpts := &pebble.IterOptions{TableFilter: opts.TableFilter} if len(opts.LowerBound) > 0 { newOpts.LowerBound = keyAdapter.Encode(nil, opts.LowerBound, math.MinInt64) @@ -206,6 +220,7 @@ func newDupDetectIter(ctx context.Context, db *pebble.DB, keyAdapter KeyAdapter, keyAdapter: keyAdapter, writeBatch: dupDB.NewBatch(), logger: logger, + option: dupOpt, } } diff --git a/br/pkg/lightning/backend/local/iterator_test.go b/br/pkg/lightning/backend/local/iterator_test.go index 3abb6fbc3b06c..c183963443bae 100644 --- a/br/pkg/lightning/backend/local/iterator_test.go +++ b/br/pkg/lightning/backend/local/iterator_test.go @@ -122,7 +122,7 @@ func TestDupDetectIterator(t *testing.T) { dupDB, err := pebble.Open(filepath.Join(storeDir, "duplicates"), &pebble.Options{}) require.NoError(t, err) var iter Iter - iter = newDupDetectIter(context.Background(), db, keyAdapter, &pebble.IterOptions{}, dupDB, log.L()) + iter = newDupDetectIter(context.Background(), db, keyAdapter, &pebble.IterOptions{}, dupDB, log.L(), dupDetectOpt{}) sort.Slice(pairs, func(i, j int) bool { key1 := keyAdapter.Encode(nil, pairs[i].Key, pairs[i].RowID) key2 := keyAdapter.Encode(nil, pairs[j].Key, pairs[j].RowID) @@ -217,7 +217,7 @@ func TestDupDetectIterSeek(t *testing.T) { dupDB, err := pebble.Open(filepath.Join(storeDir, "duplicates"), &pebble.Options{}) require.NoError(t, err) - iter := newDupDetectIter(context.Background(), db, keyAdapter, &pebble.IterOptions{}, dupDB, log.L()) + iter := newDupDetectIter(context.Background(), db, keyAdapter, &pebble.IterOptions{}, dupDB, log.L(), dupDetectOpt{}) require.True(t, iter.Seek([]byte{1, 2, 3, 1})) require.Equal(t, pairs[1].Val, iter.Value()) diff --git a/br/pkg/lightning/backend/local/local.go b/br/pkg/lightning/backend/local/local.go index 317124d0b8d19..4f8ca6bf3117a 100644 --- a/br/pkg/lightning/backend/local/local.go +++ b/br/pkg/lightning/backend/local/local.go @@ -91,6 +91,7 @@ const ( gRPCKeepAliveTime = 10 * time.Minute gRPCKeepAliveTimeout = 5 * time.Minute gRPCBackOffMaxDelay = 10 * time.Minute + writeStallSleepTime = 10 * time.Second // The max ranges count in a batch to split and scatter. maxBatchSplitRanges = 4096 @@ -369,6 +370,7 @@ type local struct { checkTiKVAvaliable bool duplicateDetection bool + duplicateDetectOpt dupDetectOpt duplicateDB *pebble.DB keyAdapter KeyAdapter errorMgr *errormanager.ErrorManager @@ -381,6 +383,12 @@ type local struct { encBuilder backend.EncodingBuilder targetInfoGetter backend.TargetInfoGetter + + // When TiKV is in normal mode, ingesting too many SSTs will cause TiKV write stall. + // To avoid this, we should check write stall before ingesting SSTs. Note that, we + // must check both leader node and followers in client side, because followers will + // not check write stall as long as ingest command is accepted by leader. + shouldCheckWriteStall bool } func openDuplicateDB(storeDir string) (*pebble.DB, error) { @@ -394,6 +402,13 @@ func openDuplicateDB(storeDir string) (*pebble.DB, error) { return pebble.Open(dbPath, opts) } +var ( + // RunInTest indicates whether the current process is running in test. + RunInTest bool + // LastAlloc is the last ID allocator. + LastAlloc manual.Allocator +) + // NewLocalBackend creates new connections to tikv. func NewLocalBackend( ctx context.Context, @@ -444,7 +459,7 @@ func NewLocalBackend( return backend.MakeBackend(nil), common.ErrCreateKVClient.Wrap(err).GenWithStackByArgs() } rpcCli := tikvclient.NewRPCClient(tikvclient.WithSecurity(tls.ToTiKVSecurityConfig())) - pdCliForTiKV := &tikvclient.CodecPDClient{Client: pdCtl.GetPDClient()} + pdCliForTiKV := tikvclient.NewCodecPDClient(tikvclient.ModeTxn, pdCtl.GetPDClient()) tikvCli, err := tikvclient.NewKVStore("lightning-local-backend", pdCliForTiKV, spkv, rpcCli) if err != nil { return backend.MakeBackend(nil), common.ErrCreateKVClient.Wrap(err).GenWithStackByArgs() @@ -461,6 +476,11 @@ func NewLocalBackend( } else { writeLimiter = noopStoreWriteLimiter{} } + alloc := manual.Allocator{} + if RunInTest { + alloc.RefCnt = new(atomic.Int64) + LastAlloc = alloc + } local := &local{ engines: sync.Map{}, pdCtl: pdCtl, @@ -481,16 +501,18 @@ func NewLocalBackend( engineMemCacheSize: int(cfg.TikvImporter.EngineMemCacheSize), localWriterMemCacheSize: int64(cfg.TikvImporter.LocalWriterMemCacheSize), duplicateDetection: duplicateDetection, + duplicateDetectOpt: dupDetectOpt{duplicateDetection && cfg.TikvImporter.DuplicateResolution == config.DupeResAlgErr}, checkTiKVAvaliable: cfg.App.CheckRequirements, duplicateDB: duplicateDB, keyAdapter: keyAdapter, errorMgr: errorMgr, importClientFactory: importClientFactory, - bufferPool: membuf.NewPool(membuf.WithAllocator(manual.Allocator{})), + bufferPool: membuf.NewPool(membuf.WithAllocator(alloc)), writeLimiter: writeLimiter, logger: log.FromContext(ctx), encBuilder: NewEncodingBuilder(ctx), targetInfoGetter: NewTargetInfoGetter(tls, g, cfg.TiDB.PdAddr), + shouldCheckWriteStall: cfg.Cron.SwitchMode.Duration == 0, } if m, ok := metric.FromContext(ctx); ok { local.metrics = m @@ -784,6 +806,7 @@ func (local *local) OpenEngine(ctx context.Context, cfg *backend.EngineConfig, e config: engineCfg, tableInfo: cfg.TableInfo, duplicateDetection: local.duplicateDetection, + dupDetectOpt: local.duplicateDetectOpt, duplicateDB: local.duplicateDB, errorMgr: local.errorMgr, keyAdapter: local.keyAdapter, @@ -834,6 +857,7 @@ func (local *local) CloseEngine(ctx context.Context, cfg *backend.EngineConfig, tableInfo: cfg.TableInfo, keyAdapter: local.keyAdapter, duplicateDetection: local.duplicateDetection, + dupDetectOpt: local.duplicateDetectOpt, duplicateDB: local.duplicateDB, errorMgr: local.errorMgr, logger: log.FromContext(ctx), @@ -878,9 +902,15 @@ type rangeStats struct { totalBytes int64 } +type tikvWriteResult struct { + sstMeta []*sst.SSTMeta + finishedRange Range + rangeStats rangeStats +} + // WriteToTiKV writer engine key-value pairs to tikv and return the sst meta generated by tikv. // we don't need to do cleanup for the pairs written to tikv if encounters an error, -// tikv will takes the responsibility to do so. +// tikv will take the responsibility to do so. func (local *local) WriteToTiKV( ctx context.Context, engine *Engine, @@ -888,9 +918,9 @@ func (local *local) WriteToTiKV( start, end []byte, regionSplitSize int64, regionSplitKeys int64, -) ([]*sst.SSTMeta, Range, rangeStats, error) { +) (*tikvWriteResult, error) { failpoint.Inject("WriteToTiKVNotEnoughDiskSpace", func(_ failpoint.Value) { - failpoint.Return(nil, Range{}, rangeStats{}, + failpoint.Return(nil, errors.Errorf("The available disk of TiKV (%s) only left %d, and capacity is %d", "", 0, 0)) }) if local.checkTiKVAvaliable { @@ -906,7 +936,7 @@ func (local *local) WriteToTiKV( // The available disk percent of TiKV ratio := store.Status.Available * 100 / store.Status.Capacity if ratio < 10 { - return nil, Range{}, rangeStats{}, errors.Errorf("The available disk of TiKV (%s) only left %d, and capacity is %d", + return nil, errors.Errorf("The available disk of TiKV (%s) only left %d, and capacity is %d", store.Store.Address, store.Status.Available, store.Status.Capacity) } } @@ -919,29 +949,20 @@ func (local *local) WriteToTiKV( } begin := time.Now() regionRange := intersectRange(region.Region, Range{start: start, end: end}) - opt := &pebble.IterOptions{LowerBound: regionRange.start, UpperBound: regionRange.end} - iter := engine.newKVIter(ctx, opt) - //nolint: errcheck - defer iter.Close() - stats := rangeStats{} - iter.First() - if iter.Error() != nil { - return nil, Range{}, stats, errors.Annotate(iter.Error(), "failed to read the first key") + firstKey, lastKey, err := engine.getFirstAndLastKey(regionRange.start, regionRange.end) + if err != nil { + return nil, errors.Trace(err) } - if !iter.Valid() { + if firstKey == nil { log.FromContext(ctx).Info("keys within region is empty, skip ingest", logutil.Key("start", start), logutil.Key("regionStart", region.Region.StartKey), logutil.Key("end", end), logutil.Key("regionEnd", region.Region.EndKey)) - return nil, regionRange, stats, nil - } - firstKey := codec.EncodeBytes([]byte{}, iter.Key()) - iter.Last() - if iter.Error() != nil { - return nil, Range{}, stats, errors.Annotate(iter.Error(), "failed to seek to the last key") + return &tikvWriteResult{sstMeta: nil, finishedRange: regionRange, rangeStats: stats}, nil } - lastKey := codec.EncodeBytes([]byte{}, iter.Key()) + firstKey = codec.EncodeBytes([]byte{}, firstKey) + lastKey = codec.EncodeBytes([]byte{}, lastKey) u := uuid.New() meta := &sst.SSTMeta{ @@ -961,12 +982,12 @@ func (local *local) WriteToTiKV( for _, peer := range region.Region.GetPeers() { cli, err := local.getImportClient(ctx, peer.StoreId) if err != nil { - return nil, Range{}, stats, err + return nil, errors.Trace(err) } wstream, err := cli.Write(ctx) if err != nil { - return nil, Range{}, stats, errors.Trace(err) + return nil, errors.Trace(err) } // Bind uuid for this write request @@ -976,7 +997,7 @@ func (local *local) WriteToTiKV( }, } if err = wstream.Send(req); err != nil { - return nil, Range{}, stats, errors.Trace(err) + return nil, errors.Trace(err) } req.Chunk = &sst.WriteRequest_Batch{ Batch: &sst.WriteBatch{ @@ -1017,6 +1038,11 @@ func (local *local) WriteToTiKV( return nil } + opt := &pebble.IterOptions{LowerBound: regionRange.start, UpperBound: regionRange.end} + iter := engine.newKVIter(ctx, opt) + //nolint: errcheck + defer iter.Close() + for iter.First(); iter.Valid(); iter.Next() { kvSize := int64(len(iter.Key()) + len(iter.Value())) // here we reuse the `*sst.Pair`s to optimize object allocation @@ -1037,7 +1063,7 @@ func (local *local) WriteToTiKV( if count >= local.batchWriteKVPairs || size >= flushLimit { if err := flushKVs(); err != nil { - return nil, Range{}, stats, err + return nil, errors.Trace(err) } count = 0 size = 0 @@ -1049,12 +1075,12 @@ func (local *local) WriteToTiKV( } if iter.Error() != nil { - return nil, Range{}, stats, errors.Trace(iter.Error()) + return nil, errors.Trace(iter.Error()) } if count > 0 { if err := flushKVs(); err != nil { - return nil, Range{}, stats, err + return nil, errors.Trace(err) } count = 0 size = 0 @@ -1065,10 +1091,10 @@ func (local *local) WriteToTiKV( for i, wStream := range clients { resp, closeErr := wStream.CloseAndRecv() if closeErr != nil { - return nil, Range{}, stats, errors.Trace(closeErr) + return nil, errors.Trace(closeErr) } if resp.Error != nil { - return nil, Range{}, stats, errors.New(resp.Error.Message) + return nil, errors.New(resp.Error.Message) } if leaderID == region.Region.Peers[i].GetId() { leaderPeerMetas = resp.Metas @@ -1081,7 +1107,7 @@ func (local *local) WriteToTiKV( log.FromContext(ctx).Warn("write to tikv no leader", logutil.Region(region.Region), logutil.Leader(region.Leader), zap.Uint64("leader_id", leaderID), logutil.SSTMeta(meta), zap.Int64("kv_pairs", totalCount), zap.Int64("total_bytes", size)) - return nil, Range{}, stats, errors.Errorf("write to tikv with no leader returned, region '%d', leader: %d", + return nil, errors.Errorf("write to tikv with no leader returned, region '%d', leader: %d", region.Region.Id, leaderID) } @@ -1103,7 +1129,11 @@ func (local *local) WriteToTiKV( stats.count = totalCount stats.totalBytes = totalSize - return leaderPeerMetas, finishedRange, stats, nil + return &tikvWriteResult{ + sstMeta: leaderPeerMetas, + finishedRange: finishedRange, + rangeStats: stats, + }, nil } func (local *local) Ingest(ctx context.Context, metas []*sst.SSTMeta, region *split.RegionInfo) (*sst.IngestResponse, error) { @@ -1134,6 +1164,16 @@ func (local *local) Ingest(ctx context.Context, metas []*sst.SSTMeta, region *sp return resp, errors.Trace(err) } + if local.shouldCheckWriteStall { + writeStall, resp, err := local.checkWriteStall(ctx, region) + if err != nil { + return nil, errors.Trace(err) + } + if writeStall { + return resp, nil + } + } + req := &sst.MultiIngestRequest{ Context: reqCtx, Ssts: metas, @@ -1142,6 +1182,25 @@ func (local *local) Ingest(ctx context.Context, metas []*sst.SSTMeta, region *sp return resp, errors.Trace(err) } +func (local *local) checkWriteStall(ctx context.Context, region *split.RegionInfo) (bool, *sst.IngestResponse, error) { + for _, peer := range region.Region.GetPeers() { + cli, err := local.getImportClient(ctx, peer.StoreId) + if err != nil { + return false, nil, errors.Trace(err) + } + // currently we use empty MultiIngestRequest to check if TiKV is busy. + // If in future the rate limit feature contains more metrics we can switch to use it. + resp, err := cli.MultiIngest(ctx, &sst.MultiIngestRequest{}) + if err != nil { + return false, nil, errors.Trace(err) + } + if resp.Error != nil && resp.Error.ServerIsBusy != nil { + return true, resp, nil + } + } + return false, nil, nil +} + func splitRangeBySizeProps(fullRange Range, sizeProps *sizeProperties, sizeLimit int64, keysLimit int64) []Range { ranges := make([]Range, 0, sizeProps.totalSize/uint64(sizeLimit)) curSize := uint64(0) @@ -1178,29 +1237,14 @@ func splitRangeBySizeProps(fullRange Range, sizeProps *sizeProperties, sizeLimit } func (local *local) readAndSplitIntoRange(ctx context.Context, engine *Engine, regionSplitSize int64, regionSplitKeys int64) ([]Range, error) { - iter := engine.newKVIter(ctx, &pebble.IterOptions{}) - //nolint: errcheck - defer iter.Close() - - iterError := func(e string) error { - err := iter.Error() - if err != nil { - return errors.Annotate(err, e) - } - return errors.New(e) - } - - var firstKey, lastKey []byte - if iter.First() { - firstKey = append([]byte{}, iter.Key()...) - } else { - return nil, iterError("could not find first pair") + firstKey, lastKey, err := engine.getFirstAndLastKey(nil, nil) + if err != nil { + return nil, err } - if iter.Last() { - lastKey = append([]byte{}, iter.Key()...) - } else { - return nil, iterError("could not find last pair") + if firstKey == nil { + return nil, errors.New("could not find first pair") } + endKey := nextKey(lastKey) engineFileTotalSize := engine.TotalSize.Load() @@ -1230,45 +1274,27 @@ func (local *local) readAndSplitIntoRange(ctx context.Context, engine *Engine, r } func (local *local) writeAndIngestByRange( - ctxt context.Context, + ctx context.Context, engine *Engine, start, end []byte, regionSplitSize int64, regionSplitKeys int64, ) error { - ito := &pebble.IterOptions{ - LowerBound: start, - UpperBound: end, - } - - iter := engine.newKVIter(ctxt, ito) - //nolint: errcheck - defer iter.Close() - // Needs seek to first because NewIter returns an iterator that is unpositioned - hasKey := iter.First() - if iter.Error() != nil { - return errors.Annotate(iter.Error(), "failed to read the first key") + pairStart, pairEnd, err := engine.getFirstAndLastKey(start, end) + if err != nil { + return err } - if !hasKey { - log.FromContext(ctxt).Info("There is no pairs in iterator", + if pairStart == nil { + log.FromContext(ctx).Info("There is no pairs in iterator", logutil.Key("start", start), logutil.Key("end", end)) engine.finishedRanges.add(Range{start: start, end: end}) return nil } - pairStart := append([]byte{}, iter.Key()...) - iter.Last() - if iter.Error() != nil { - return errors.Annotate(iter.Error(), "failed to seek to the last key") - } - pairEnd := append([]byte{}, iter.Key()...) var regions []*split.RegionInfo - var err error - ctx, cancel := context.WithCancel(ctxt) - defer cancel() -WriteAndIngest: +ScanWriteIngest: for retry := 0; retry < maxRetryTimes; { if retry != 0 { select { @@ -1284,7 +1310,7 @@ WriteAndIngest: log.FromContext(ctx).Warn("scan region failed", log.ShortError(err), zap.Int("region_len", len(regions)), logutil.Key("startKey", startKey), logutil.Key("endKey", endKey), zap.Int("retry", retry)) retry++ - continue WriteAndIngest + continue ScanWriteIngest } for _, region := range regions { @@ -1309,7 +1335,7 @@ WriteAndIngest: } log.FromContext(ctx).Info("retry write and ingest kv pairs", logutil.Key("startKey", pairStart), logutil.Key("endKey", end), log.ShortError(err), zap.Int("retry", retry)) - continue WriteAndIngest + continue ScanWriteIngest } } @@ -1325,6 +1351,7 @@ const ( retryNone retryType = iota retryWrite retryIngest + retryBusyIngest ) func (local *local) isRetryableImportTiKVError(err error) bool { @@ -1340,6 +1367,11 @@ func (local *local) isRetryableImportTiKVError(err error) bool { return common.IsRetryableError(err) } +// writeAndIngestPairs writes the kv pairs in the range [start, end) to the peers +// of the region, and then send the ingest command to do RocksDB ingest. +// when return nil, it does not mean the whole task success. The success ranges is +// recorded in the engine.finishedRanges. +// TODO: regionSplitSize and regionSplitKeys can be a member of Engine, no need to pass it in every function. func (local *local) writeAndIngestPairs( ctx context.Context, engine *Engine, @@ -1349,13 +1381,10 @@ func (local *local) writeAndIngestPairs( regionSplitKeys int64, ) error { var err error - + var writeResult *tikvWriteResult loopWrite: for i := 0; i < maxRetryTimes; i++ { - var metas []*sst.SSTMeta - var finishedRange Range - var rangeStats rangeStats - metas, finishedRange, rangeStats, err = local.WriteToTiKV(ctx, engine, region, start, end, regionSplitSize, regionSplitKeys) + writeResult, err = local.WriteToTiKV(ctx, engine, region, start, end, regionSplitSize, regionSplitKeys) if err != nil { if !local.isRetryableImportTiKVError(err) { return err @@ -1364,6 +1393,7 @@ loopWrite: log.FromContext(ctx).Warn("write to tikv failed", log.ShortError(err), zap.Int("retry", i)) continue loopWrite } + metas, finishedRange, rangeStats := writeResult.sstMeta, writeResult.finishedRange, writeResult.rangeStats if len(metas) == 0 { return nil @@ -1430,6 +1460,7 @@ loopWrite: // ingest next meta break } + switch retryTy { case retryNone: log.FromContext(ctx).Warn("ingest failed noretry", log.ShortError(err), logutil.SSTMetas(ingestMetas), @@ -1442,25 +1473,30 @@ loopWrite: case retryIngest: region = newRegion continue + case retryBusyIngest: + log.FromContext(ctx).Warn("meet tikv busy when ingest", log.ShortError(err), logutil.SSTMetas(ingestMetas), + logutil.Region(region.Region)) + // ImportEngine will continue on this unfinished range + return nil } } } - if err != nil { - log.FromContext(ctx).Warn("write and ingest region, will retry import full range", log.ShortError(err), - logutil.Region(region.Region), logutil.Key("start", start), - logutil.Key("end", end)) - } else { + if err == nil { engine.importedKVSize.Add(rangeStats.totalBytes) engine.importedKVCount.Add(rangeStats.count) engine.finishedRanges.add(finishedRange) if local.metrics != nil { local.metrics.BytesCounter.WithLabelValues(metric.BytesStateImported).Add(float64(rangeStats.totalBytes)) } + return nil } + + log.FromContext(ctx).Warn("write and ingest region, will retry import full range", log.ShortError(err), + logutil.Region(region.Region), logutil.Key("start", start), + logutil.Key("end", end)) return errors.Trace(err) } - return errors.Trace(err) } @@ -1959,7 +1995,7 @@ func (local *local) isIngestRetryable( } return retryWrite, newRegion, common.ErrKVRaftProposalDropped.GenWithStack(errPb.GetMessage()) case errPb.ServerIsBusy != nil: - return retryNone, nil, common.ErrKVServerIsBusy.GenWithStack(errPb.GetMessage()) + return retryBusyIngest, nil, common.ErrKVServerIsBusy.GenWithStack(errPb.GetMessage()) case errPb.RegionNotFound != nil: return retryNone, nil, common.ErrKVRegionNotFound.GenWithStack(errPb.GetMessage()) case errPb.ReadIndexNotReady != nil: diff --git a/br/pkg/lightning/backend/local/local_test.go b/br/pkg/lightning/backend/local/local_test.go index 1a399552becf9..a485bdecaca4a 100644 --- a/br/pkg/lightning/backend/local/local_test.go +++ b/br/pkg/lightning/backend/local/local_test.go @@ -18,10 +18,10 @@ import ( "bytes" "context" "encoding/binary" + "fmt" "io" "math" "math/rand" - "os" "path/filepath" "sort" "strings" @@ -42,6 +42,7 @@ import ( "github.com/pingcap/tidb/br/pkg/lightning/backend/kv" "github.com/pingcap/tidb/br/pkg/lightning/common" "github.com/pingcap/tidb/br/pkg/lightning/log" + "github.com/pingcap/tidb/br/pkg/lightning/worker" "github.com/pingcap/tidb/br/pkg/membuf" "github.com/pingcap/tidb/br/pkg/pdutil" "github.com/pingcap/tidb/br/pkg/restore/split" @@ -237,8 +238,6 @@ func TestRangeProperties(t *testing.T) { } func TestRangePropertiesWithPebble(t *testing.T) { - dir := t.TempDir() - sizeDistance := uint64(500) keysDistance := uint64(20) opt := &pebble.Options{ @@ -259,8 +258,7 @@ func TestRangePropertiesWithPebble(t *testing.T) { }, }, } - db, err := pebble.Open(filepath.Join(dir, "test"), opt) - require.NoError(t, err) + db, _ := makePebbleDB(t, opt) defer db.Close() // local collector @@ -277,7 +275,7 @@ func TestRangePropertiesWithPebble(t *testing.T) { key := make([]byte, 8) valueLen := rand.Intn(50) binary.BigEndian.PutUint64(key, uint64(i*100+j)) - err = wb.Set(key, value[:valueLen], writeOpt) + err := wb.Set(key, value[:valueLen], writeOpt) require.NoError(t, err) err = collector.Add(pebble.InternalKey{UserKey: key, Trailer: pebble.InternalKeyKindSet}, value[:valueLen]) require.NoError(t, err) @@ -304,7 +302,6 @@ func TestRangePropertiesWithPebble(t *testing.T) { } func testLocalWriter(t *testing.T, needSort bool, partitialSort bool) { - dir := t.TempDir() opt := &pebble.Options{ MemTableSize: 1024 * 1024, MaxConcurrentCompactions: 16, @@ -313,12 +310,8 @@ func testLocalWriter(t *testing.T, needSort bool, partitialSort bool) { DisableWAL: true, ReadOnly: false, } - db, err := pebble.Open(filepath.Join(dir, "test"), opt) - require.NoError(t, err) + db, tmpPath := makePebbleDB(t, opt) defer db.Close() - tmpPath := filepath.Join(dir, "test.sst") - err = os.Mkdir(tmpPath, 0o755) - require.NoError(t, err) _, engineUUID := backend.MakeUUID("ww", 0) engineCtx, cancel := context.WithCancel(context.Background()) @@ -564,7 +557,6 @@ func (i testIngester) ingest([]*sstMeta) error { } func TestLocalIngestLoop(t *testing.T) { - dir := t.TempDir() opt := &pebble.Options{ MemTableSize: 1024 * 1024, MaxConcurrentCompactions: 16, @@ -573,18 +565,14 @@ func TestLocalIngestLoop(t *testing.T) { DisableWAL: true, ReadOnly: false, } - db, err := pebble.Open(filepath.Join(dir, "test"), opt) - require.NoError(t, err) + db, tmpPath := makePebbleDB(t, opt) defer db.Close() - tmpPath := filepath.Join(dir, "test.sst") - err = os.Mkdir(tmpPath, 0o755) - require.NoError(t, err) _, engineUUID := backend.MakeUUID("ww", 0) engineCtx, cancel := context.WithCancel(context.Background()) f := Engine{ db: db, UUID: engineUUID, - sstDir: "", + sstDir: tmpPath, ctx: engineCtx, cancel: cancel, sstMetasChan: make(chan metaOrFlush, 64), @@ -637,7 +625,7 @@ func TestLocalIngestLoop(t *testing.T) { wg.Wait() f.mutex.RLock() - err = f.flushEngineWithoutLock(engineCtx) + err := f.flushEngineWithoutLock(engineCtx) require.NoError(t, err) f.mutex.RUnlock() @@ -732,7 +720,6 @@ func TestFilterOverlapRange(t *testing.T) { } func testMergeSSTs(t *testing.T, kvs [][]common.KvPair, meta *sstMeta) { - dir := t.TempDir() opt := &pebble.Options{ MemTableSize: 1024 * 1024, MaxConcurrentCompactions: 16, @@ -741,12 +728,8 @@ func testMergeSSTs(t *testing.T, kvs [][]common.KvPair, meta *sstMeta) { DisableWAL: true, ReadOnly: false, } - db, err := pebble.Open(filepath.Join(dir, "test"), opt) - require.NoError(t, err) + db, tmpPath := makePebbleDB(t, opt) defer db.Close() - tmpPath := filepath.Join(dir, "test.sst") - err = os.Mkdir(tmpPath, 0o755) - require.NoError(t, err) _, engineUUID := backend.MakeUUID("ww", 0) engineCtx, cancel := context.WithCancel(context.Background()) @@ -837,49 +820,90 @@ func TestMergeSSTsDuplicated(t *testing.T) { type mockPdClient struct { pd.Client - stores []*metapb.Store + stores []*metapb.Store + regions []*pd.Region } func (c *mockPdClient) GetAllStores(ctx context.Context, opts ...pd.GetStoreOption) ([]*metapb.Store, error) { return c.stores, nil } +func (c *mockPdClient) ScanRegions(ctx context.Context, key, endKey []byte, limit int) ([]*pd.Region, error) { + return c.regions, nil +} + type mockGrpcErr struct{} func (e mockGrpcErr) GRPCStatus() *status.Status { - return status.New(codes.Unimplemented, "unimplmented") + return status.New(codes.Unimplemented, "unimplemented") } func (e mockGrpcErr) Error() string { - return "unimplmented" + return "unimplemented" } type mockImportClient struct { sst.ImportSSTClient store *metapb.Store + resp *sst.IngestResponse err error retry int cnt int multiIngestCheckFn func(s *metapb.Store) bool + apiInvokeRecorder map[string][]uint64 +} + +func newMockImportClient() *mockImportClient { + return &mockImportClient{ + multiIngestCheckFn: func(s *metapb.Store) bool { + return true + }, + } } func (c *mockImportClient) MultiIngest(context.Context, *sst.MultiIngestRequest, ...grpc.CallOption) (*sst.IngestResponse, error) { defer func() { c.cnt++ }() - if c.cnt < c.retry && c.err != nil { - return nil, c.err + if c.apiInvokeRecorder != nil { + c.apiInvokeRecorder["MultiIngest"] = append(c.apiInvokeRecorder["MultiIngest"], c.store.GetId()) + } + if c.cnt < c.retry && (c.err != nil || c.resp != nil) { + return c.resp, c.err } if !c.multiIngestCheckFn(c.store) { return nil, mockGrpcErr{} } - return nil, nil + return &sst.IngestResponse{}, nil +} + +type mockWriteClient struct { + sst.ImportSST_WriteClient + writeResp *sst.WriteResponse +} + +func (m mockWriteClient) Send(request *sst.WriteRequest) error { + return nil +} + +func (m mockWriteClient) CloseAndRecv() (*sst.WriteResponse, error) { + return m.writeResp, nil +} + +func (c *mockImportClient) Write(ctx context.Context, opts ...grpc.CallOption) (sst.ImportSST_WriteClient, error) { + if c.apiInvokeRecorder != nil { + c.apiInvokeRecorder["Write"] = append(c.apiInvokeRecorder["Write"], c.store.GetId()) + } + return mockWriteClient{writeResp: &sst.WriteResponse{Metas: []*sst.SSTMeta{ + {}, {}, {}, + }}}, nil } type mockImportClientFactory struct { - stores []*metapb.Store - createClientFn func(store *metapb.Store) sst.ImportSSTClient + stores []*metapb.Store + createClientFn func(store *metapb.Store) sst.ImportSSTClient + apiInvokeRecorder map[string][]uint64 } func (f *mockImportClientFactory) Create(_ context.Context, storeID uint64) (sst.ImportSSTClient, error) { @@ -888,7 +912,7 @@ func (f *mockImportClientFactory) Create(_ context.Context, storeID uint64) (sst return f.createClientFn(store), nil } } - return nil, errors.New("store not found") + return nil, fmt.Errorf("store %d not found", storeID) } func (f *mockImportClientFactory) Close() {} @@ -1220,3 +1244,77 @@ func TestLocalIsRetryableTiKVWriteError(t *testing.T) { require.True(t, l.isRetryableImportTiKVError(io.EOF)) require.True(t, l.isRetryableImportTiKVError(errors.Trace(io.EOF))) } + +func TestCheckPeersBusy(t *testing.T) { + ctx := context.Background() + pdCli := &mockPdClient{} + pdCtl := &pdutil.PdController{} + pdCtl.SetPDClient(pdCli) + + keys := [][]byte{[]byte(""), []byte("a"), []byte("b"), []byte("")} + splitCli := initTestSplitClient3Replica(keys, nil) + apiInvokeRecorder := map[string][]uint64{} + serverIsBusyResp := &sst.IngestResponse{ + Error: &errorpb.Error{ + ServerIsBusy: &errorpb.ServerIsBusy{}, + }} + + createTimeStore12 := 0 + local := &local{ + pdCtl: pdCtl, + splitCli: splitCli, + importClientFactory: &mockImportClientFactory{ + stores: []*metapb.Store{ + // region ["", "a") is not used, skip (1, 2, 3) + {Id: 11}, {Id: 12}, {Id: 13}, // region ["a", "b") + {Id: 21}, {Id: 22}, {Id: 23}, // region ["b", "") + }, + createClientFn: func(store *metapb.Store) sst.ImportSSTClient { + importCli := newMockImportClient() + importCli.store = store + importCli.apiInvokeRecorder = apiInvokeRecorder + if store.Id == 12 { + createTimeStore12++ + // the second time to checkWriteStall + if createTimeStore12 == 2 { + importCli.retry = 1 + importCli.resp = serverIsBusyResp + } + } + return importCli + }, + }, + logger: log.L(), + ingestConcurrency: worker.NewPool(ctx, 1, "ingest"), + writeLimiter: noopStoreWriteLimiter{}, + bufferPool: membuf.NewPool(), + supportMultiIngest: true, + shouldCheckWriteStall: true, + } + + db, tmpPath := makePebbleDB(t, nil) + _, engineUUID := backend.MakeUUID("ww", 0) + engineCtx, cancel := context.WithCancel(context.Background()) + f := &Engine{ + db: db, + UUID: engineUUID, + sstDir: tmpPath, + ctx: engineCtx, + cancel: cancel, + sstMetasChan: make(chan metaOrFlush, 64), + keyAdapter: noopKeyAdapter{}, + logger: log.L(), + } + err := f.db.Set([]byte("a"), []byte("a"), nil) + require.NoError(t, err) + err = f.db.Set([]byte("b"), []byte("b"), nil) + require.NoError(t, err) + err = local.writeAndIngestByRange(ctx, f, []byte("a"), []byte("c"), 0, 0) + require.NoError(t, err) + + require.Equal(t, []uint64{11, 12, 13, 21, 22, 23}, apiInvokeRecorder["Write"]) + // store 12 has a follower busy, so it will break the workflow for region (11, 12, 13) + require.Equal(t, []uint64{11, 12, 21, 22, 23, 21}, apiInvokeRecorder["MultiIngest"]) + // region (11, 12, 13) has key range ["a", "b"), it's not finished. + require.Equal(t, []Range{{start: []byte("b"), end: []byte("c")}}, f.finishedRanges.ranges) +} diff --git a/br/pkg/lightning/backend/local/localhelper_test.go b/br/pkg/lightning/backend/local/localhelper_test.go index 6cbf7f2f14808..023fade304fae 100644 --- a/br/pkg/lightning/backend/local/localhelper_test.go +++ b/br/pkg/lightning/backend/local/localhelper_test.go @@ -47,7 +47,7 @@ func init() { splitRetryTimes = 2 } -type testClient struct { +type testSplitClient struct { mu sync.RWMutex stores map[uint64]*metapb.Store regions map[uint64]*split.RegionInfo @@ -57,17 +57,17 @@ type testClient struct { hook clientHook } -func newTestClient( +func newTestSplitClient( stores map[uint64]*metapb.Store, regions map[uint64]*split.RegionInfo, nextRegionID uint64, hook clientHook, -) *testClient { +) *testSplitClient { regionsInfo := &pdtypes.RegionTree{} for _, regionInfo := range regions { regionsInfo.SetRegion(pdtypes.NewRegionInfo(regionInfo.Region, regionInfo.Leader)) } - return &testClient{ + return &testSplitClient{ stores: stores, regions: regions, regionsInfo: regionsInfo, @@ -77,17 +77,17 @@ func newTestClient( } // ScatterRegions scatters regions in a batch. -func (c *testClient) ScatterRegions(ctx context.Context, regionInfo []*split.RegionInfo) error { +func (c *testSplitClient) ScatterRegions(ctx context.Context, regionInfo []*split.RegionInfo) error { return nil } -func (c *testClient) GetAllRegions() map[uint64]*split.RegionInfo { +func (c *testSplitClient) GetAllRegions() map[uint64]*split.RegionInfo { c.mu.RLock() defer c.mu.RUnlock() return c.regions } -func (c *testClient) GetStore(ctx context.Context, storeID uint64) (*metapb.Store, error) { +func (c *testSplitClient) GetStore(ctx context.Context, storeID uint64) (*metapb.Store, error) { c.mu.RLock() defer c.mu.RUnlock() store, ok := c.stores[storeID] @@ -97,19 +97,18 @@ func (c *testClient) GetStore(ctx context.Context, storeID uint64) (*metapb.Stor return store, nil } -func (c *testClient) GetRegion(ctx context.Context, key []byte) (*split.RegionInfo, error) { +func (c *testSplitClient) GetRegion(ctx context.Context, key []byte) (*split.RegionInfo, error) { c.mu.RLock() defer c.mu.RUnlock() for _, region := range c.regions { - if bytes.Compare(key, region.Region.StartKey) >= 0 && - (len(region.Region.EndKey) == 0 || bytes.Compare(key, region.Region.EndKey) < 0) { + if bytes.Compare(key, region.Region.StartKey) >= 0 && beforeEnd(key, region.Region.EndKey) { return region, nil } } return nil, errors.Errorf("region not found: key=%s", string(key)) } -func (c *testClient) GetRegionByID(ctx context.Context, regionID uint64) (*split.RegionInfo, error) { +func (c *testSplitClient) GetRegionByID(ctx context.Context, regionID uint64) (*split.RegionInfo, error) { c.mu.RLock() defer c.mu.RUnlock() region, ok := c.regions[regionID] @@ -119,7 +118,7 @@ func (c *testClient) GetRegionByID(ctx context.Context, regionID uint64) (*split return region, nil } -func (c *testClient) SplitRegion( +func (c *testSplitClient) SplitRegion( ctx context.Context, regionInfo *split.RegionInfo, key []byte, @@ -130,7 +129,7 @@ func (c *testClient) SplitRegion( splitKey := codec.EncodeBytes([]byte{}, key) for _, region := range c.regions { if bytes.Compare(splitKey, region.Region.StartKey) >= 0 && - (len(region.Region.EndKey) == 0 || bytes.Compare(splitKey, region.Region.EndKey) < 0) { + beforeEnd(splitKey, region.Region.EndKey) { target = region } } @@ -159,7 +158,7 @@ func (c *testClient) SplitRegion( return newRegion, nil } -func (c *testClient) BatchSplitRegionsWithOrigin( +func (c *testSplitClient) BatchSplitRegionsWithOrigin( ctx context.Context, regionInfo *split.RegionInfo, keys [][]byte, ) (*split.RegionInfo, []*split.RegionInfo, error) { c.mu.Lock() @@ -234,24 +233,24 @@ func (c *testClient) BatchSplitRegionsWithOrigin( return target, newRegions, err } -func (c *testClient) BatchSplitRegions( +func (c *testSplitClient) BatchSplitRegions( ctx context.Context, regionInfo *split.RegionInfo, keys [][]byte, ) ([]*split.RegionInfo, error) { _, newRegions, err := c.BatchSplitRegionsWithOrigin(ctx, regionInfo, keys) return newRegions, err } -func (c *testClient) ScatterRegion(ctx context.Context, regionInfo *split.RegionInfo) error { +func (c *testSplitClient) ScatterRegion(ctx context.Context, regionInfo *split.RegionInfo) error { return nil } -func (c *testClient) GetOperator(ctx context.Context, regionID uint64) (*pdpb.GetOperatorResponse, error) { +func (c *testSplitClient) GetOperator(ctx context.Context, regionID uint64) (*pdpb.GetOperatorResponse, error) { return &pdpb.GetOperatorResponse{ Header: new(pdpb.ResponseHeader), }, nil } -func (c *testClient) ScanRegions(ctx context.Context, key, endKey []byte, limit int) ([]*split.RegionInfo, error) { +func (c *testSplitClient) ScanRegions(ctx context.Context, key, endKey []byte, limit int) ([]*split.RegionInfo, error) { if c.hook != nil { key, endKey, limit = c.hook.BeforeScanRegions(ctx, key, endKey, limit) } @@ -272,19 +271,19 @@ func (c *testClient) ScanRegions(ctx context.Context, key, endKey []byte, limit return regions, err } -func (c *testClient) GetPlacementRule(ctx context.Context, groupID, ruleID string) (r pdtypes.Rule, err error) { +func (c *testSplitClient) GetPlacementRule(ctx context.Context, groupID, ruleID string) (r pdtypes.Rule, err error) { return } -func (c *testClient) SetPlacementRule(ctx context.Context, rule pdtypes.Rule) error { +func (c *testSplitClient) SetPlacementRule(ctx context.Context, rule pdtypes.Rule) error { return nil } -func (c *testClient) DeletePlacementRule(ctx context.Context, groupID, ruleID string) error { +func (c *testSplitClient) DeletePlacementRule(ctx context.Context, groupID, ruleID string) error { return nil } -func (c *testClient) SetStoresLabel(ctx context.Context, stores []uint64, labelKey, labelValue string) error { +func (c *testSplitClient) SetStoresLabel(ctx context.Context, stores []uint64, labelKey, labelValue string) error { return nil } @@ -305,7 +304,7 @@ func cloneRegion(region *split.RegionInfo) *split.RegionInfo { // For keys ["", "aay", "bba", "bbh", "cca", ""], the key ranges of // regions are [, aay), [aay, bba), [bba, bbh), [bbh, cca), [cca, ). -func initTestClient(keys [][]byte, hook clientHook) *testClient { +func initTestSplitClient(keys [][]byte, hook clientHook) *testSplitClient { peers := make([]*metapb.Peer, 1) peers[0] = &metapb.Peer{ Id: 1, @@ -329,13 +328,56 @@ func initTestClient(keys [][]byte, hook clientHook) *testClient { EndKey: endKey, RegionEpoch: &metapb.RegionEpoch{ConfVer: 1, Version: 1}, }, + Leader: peers[0], } } stores := make(map[uint64]*metapb.Store) stores[1] = &metapb.Store{ Id: 1, } - return newTestClient(stores, regions, uint64(len(keys)), hook) + return newTestSplitClient(stores, regions, uint64(len(keys)), hook) +} + +// initTestSplitClient3Replica will create a client that each region has 3 replicas, and their IDs and StoreIDs are +// (1, 2, 3), (11, 12, 13), ... +// For keys ["", "aay", "bba", "bbh", "cca", ""], the key ranges of +// region ranges are [, aay), [aay, bba), [bba, bbh), [bbh, cca), [cca, ). +func initTestSplitClient3Replica(keys [][]byte, hook clientHook) *testSplitClient { + regions := make(map[uint64]*split.RegionInfo) + stores := make(map[uint64]*metapb.Store) + for i := uint64(1); i < uint64(len(keys)); i++ { + startKey := keys[i-1] + if len(startKey) != 0 { + startKey = codec.EncodeBytes([]byte{}, startKey) + } + endKey := keys[i] + if len(endKey) != 0 { + endKey = codec.EncodeBytes([]byte{}, endKey) + } + baseID := (i-1)*10 + 1 + peers := make([]*metapb.Peer, 3) + for j := 0; j < 3; j++ { + peers[j] = &metapb.Peer{ + Id: baseID + uint64(j), + StoreId: baseID + uint64(j), + } + } + + regions[baseID] = &split.RegionInfo{ + Region: &metapb.Region{ + Id: baseID, + Peers: peers, + StartKey: startKey, + EndKey: endKey, + RegionEpoch: &metapb.RegionEpoch{ConfVer: 1, Version: 1}, + }, + Leader: peers[0], + } + stores[baseID] = &metapb.Store{ + Id: baseID, + } + } + return newTestSplitClient(stores, regions, uint64(len(keys)), hook) } func checkRegionRanges(t *testing.T, regions []*split.RegionInfo, keys [][]byte) { @@ -376,7 +418,7 @@ func (h *noopHook) AfterScanRegions(res []*split.RegionInfo, err error) ([]*spli type batchSplitHook interface { setup(t *testing.T) func() - check(t *testing.T, cli *testClient) + check(t *testing.T, cli *testSplitClient) } type defaultHook struct{} @@ -392,7 +434,7 @@ func (d defaultHook) setup(t *testing.T) func() { } } -func (d defaultHook) check(t *testing.T, cli *testClient) { +func (d defaultHook) check(t *testing.T, cli *testSplitClient) { // so with a batch split size of 4, there will be 7 time batch split // 1. region: [aay, bba), keys: [b, ba, bb] // 2. region: [bbh, cca), keys: [bc, bd, be, bf] @@ -414,7 +456,7 @@ func doTestBatchSplitRegionByRanges(ctx context.Context, t *testing.T, hook clie defer deferFunc() keys := [][]byte{[]byte(""), []byte("aay"), []byte("bba"), []byte("bbh"), []byte("cca"), []byte("")} - client := initTestClient(keys, hook) + client := initTestSplitClient(keys, hook) local := &local{ splitCli: client, g: glue.NewExternalTiDBGlue(nil, mysql.ModeNone), @@ -479,7 +521,7 @@ func (h batchSizeHook) setup(t *testing.T) func() { } } -func (h batchSizeHook) check(t *testing.T, cli *testClient) { +func (h batchSizeHook) check(t *testing.T, cli *testSplitClient) { // so with a batch split key size of 6, there will be 9 time batch split // 1. region: [aay, bba), keys: [b, ba, bb] // 2. region: [bbh, cca), keys: [bc, bd, be] @@ -583,7 +625,7 @@ func TestSplitAndScatterRegionInBatches(t *testing.T) { defer deferFunc() keys := [][]byte{[]byte(""), []byte("a"), []byte("b"), []byte("")} - client := initTestClient(keys, nil) + client := initTestSplitClient(keys, nil) local := &local{ splitCli: client, g: glue.NewExternalTiDBGlue(nil, mysql.ModeNone), @@ -670,7 +712,7 @@ func doTestBatchSplitByRangesWithClusteredIndex(t *testing.T, hook clientHook) { keys = append(keys, key) } keys = append(keys, tableEndKey, []byte("")) - client := initTestClient(keys, hook) + client := initTestSplitClient(keys, hook) local := &local{ splitCli: client, g: glue.NewExternalTiDBGlue(nil, mysql.ModeNone), diff --git a/br/pkg/lightning/checkpoints/checkpoints.go b/br/pkg/lightning/checkpoints/checkpoints.go index 44f2349b672b2..d20134660de9c 100644 --- a/br/pkg/lightning/checkpoints/checkpoints.go +++ b/br/pkg/lightning/checkpoints/checkpoints.go @@ -262,6 +262,29 @@ func (ccp *ChunkCheckpoint) DeepCopy() *ChunkCheckpoint { } } +func (ccp *ChunkCheckpoint) UnfinishedSize() int64 { + if ccp.FileMeta.Compression == mydump.CompressionNone { + return ccp.Chunk.EndOffset - ccp.Chunk.Offset + } + return ccp.FileMeta.FileSize - ccp.Chunk.RealOffset +} + +func (ccp *ChunkCheckpoint) TotalSize() int64 { + if ccp.FileMeta.Compression == mydump.CompressionNone { + return ccp.Chunk.EndOffset - ccp.Key.Offset + } + // TODO: compressed file won't be split into chunks, so using FileSize as TotalSize is ok + // change this when we support split compressed file into chunks + return ccp.FileMeta.FileSize +} + +func (ccp *ChunkCheckpoint) FinishedSize() int64 { + if ccp.FileMeta.Compression == mydump.CompressionNone { + return ccp.Chunk.Offset - ccp.Key.Offset + } + return ccp.Chunk.RealOffset - ccp.Key.Offset +} + type EngineCheckpoint struct { Status CheckpointStatus Chunks []*ChunkCheckpoint // a sorted array @@ -517,7 +540,15 @@ func OpenCheckpointsDB(ctx context.Context, cfg *config.Config) (DB, error) { switch cfg.Checkpoint.Driver { case config.CheckpointDriverMySQL: - db, err := common.ConnectMySQL(cfg.Checkpoint.DSN) + var ( + db *sql.DB + err error + ) + if cfg.Checkpoint.MySQLParam != nil { + db, err = cfg.Checkpoint.MySQLParam.Connect() + } else { + db, err = sql.Open("mysql", cfg.Checkpoint.DSN) + } if err != nil { return nil, errors.Trace(err) } @@ -546,7 +577,15 @@ func IsCheckpointsDBExists(ctx context.Context, cfg *config.Config) (bool, error } switch cfg.Checkpoint.Driver { case config.CheckpointDriverMySQL: - db, err := sql.Open("mysql", cfg.Checkpoint.DSN) + var ( + db *sql.DB + err error + ) + if cfg.Checkpoint.MySQLParam != nil { + db, err = cfg.Checkpoint.MySQLParam.Connect() + } else { + db, err = sql.Open("mysql", cfg.Checkpoint.DSN) + } if err != nil { return false, errors.Trace(err) } diff --git a/br/pkg/lightning/checkpoints/main_test.go b/br/pkg/lightning/checkpoints/main_test.go index aa707ae68ea51..2d281fb84dd1e 100644 --- a/br/pkg/lightning/checkpoints/main_test.go +++ b/br/pkg/lightning/checkpoints/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/klauspost/compress/zstd.(*blockDec).startDecoder"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/br/pkg/lightning/common/errors.go b/br/pkg/lightning/common/errors.go index c2fc3dbaa901f..14645217636a4 100644 --- a/br/pkg/lightning/common/errors.go +++ b/br/pkg/lightning/common/errors.go @@ -51,6 +51,7 @@ var ( ErrCheckTableEmpty = errors.Normalize("check table empty error", errors.RFCCodeText("Lightning:PreCheck:ErrCheckTableEmpty")) ErrCheckCSVHeader = errors.Normalize("check csv header error", errors.RFCCodeText("Lightning:PreCheck:ErrCheckCSVHeader")) ErrCheckDataSource = errors.Normalize("check data source error", errors.RFCCodeText("Lightning:PreCheck:ErrCheckDataSource")) + ErrCheckCDCPiTR = errors.Normalize("check TiCDC/PiTR task error", errors.RFCCodeText("Lightning:PreCheck:ErrCheckCDCPiTR")) ErrOpenCheckpoint = errors.Normalize("open checkpoint error", errors.RFCCodeText("Lightning:Checkpoint:ErrOpenCheckpoint")) ErrReadCheckpoint = errors.Normalize("read checkpoint error", errors.RFCCodeText("Lightning:Checkpoint:ErrReadCheckpoint")) @@ -96,6 +97,7 @@ var ( ErrInvalidMetaStatus = errors.Normalize("invalid meta status: '%s'", errors.RFCCodeText("Lightning:Restore:ErrInvalidMetaStatus")) ErrTableIsChecksuming = errors.Normalize("table '%s' is checksuming", errors.RFCCodeText("Lightning:Restore:ErrTableIsChecksuming")) ErrResolveDuplicateRows = errors.Normalize("resolve duplicate rows error on table '%s'", errors.RFCCodeText("Lightning:Restore:ErrResolveDuplicateRows")) + ErrFoundDuplicateKeys = errors.Normalize("found duplicate key '%s', value '%s'", errors.RFCCodeText("Lightning:Restore:ErrFoundDuplicateKey")) ) type withStack struct { diff --git a/br/pkg/lightning/common/main_test.go b/br/pkg/lightning/common/main_test.go index 89c3779ccc1b2..be6188947f62c 100644 --- a/br/pkg/lightning/common/main_test.go +++ b/br/pkg/lightning/common/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) diff --git a/br/pkg/lightning/common/util.go b/br/pkg/lightning/common/util.go index cc03f0ec68dca..b9bdf564403de 100644 --- a/br/pkg/lightning/common/util.go +++ b/br/pkg/lightning/common/util.go @@ -16,6 +16,7 @@ package common import ( "context" + "crypto/tls" "database/sql" "encoding/base64" "encoding/json" @@ -23,7 +24,6 @@ import ( "io" "net" "net/http" - "net/url" "os" "strconv" "strings" @@ -48,38 +48,55 @@ const ( // MySQLConnectParam records the parameters needed to connect to a MySQL database. type MySQLConnectParam struct { - Host string - Port int - User string - Password string - SQLMode string - MaxAllowedPacket uint64 - TLS string - Vars map[string]string + Host string + Port int + User string + Password string + SQLMode string + MaxAllowedPacket uint64 + TLSConfig *tls.Config + AllowFallbackToPlaintext bool + Net string + Vars map[string]string } -func (param *MySQLConnectParam) ToDSN() string { - hostPort := net.JoinHostPort(param.Host, strconv.Itoa(param.Port)) - dsn := fmt.Sprintf("%s:%s@tcp(%s)/?charset=utf8mb4&sql_mode='%s'&maxAllowedPacket=%d&tls=%s", - param.User, param.Password, hostPort, - param.SQLMode, param.MaxAllowedPacket, param.TLS) +func (param *MySQLConnectParam) ToDriverConfig() *mysql.Config { + cfg := mysql.NewConfig() + cfg.Params = make(map[string]string) - for k, v := range param.Vars { - dsn += fmt.Sprintf("&%s='%s'", k, url.QueryEscape(v)) + cfg.User = param.User + cfg.Passwd = param.Password + cfg.Net = "tcp" + if param.Net != "" { + cfg.Net = param.Net } + cfg.Addr = net.JoinHostPort(param.Host, strconv.Itoa(param.Port)) + cfg.Params["charset"] = "utf8mb4" + cfg.Params["sql_mode"] = fmt.Sprintf("'%s'", param.SQLMode) + cfg.MaxAllowedPacket = int(param.MaxAllowedPacket) + + cfg.TLS = param.TLSConfig + cfg.AllowFallbackToPlaintext = param.AllowFallbackToPlaintext - return dsn + for k, v := range param.Vars { + cfg.Params[k] = fmt.Sprintf("'%s'", v) + } + return cfg } -func tryConnectMySQL(dsn string) (*sql.DB, error) { - driverName := "mysql" - failpoint.Inject("MockMySQLDriver", func(val failpoint.Value) { - driverName = val.(string) +func tryConnectMySQL(cfg *mysql.Config) (*sql.DB, error) { + failpoint.Inject("MustMySQLPassword", func(val failpoint.Value) { + pwd := val.(string) + if cfg.Passwd != pwd { + failpoint.Return(nil, &mysql.MySQLError{Number: tmysql.ErrAccessDenied, Message: "access denied"}) + } + failpoint.Return(nil, nil) }) - db, err := sql.Open(driverName, dsn) + c, err := mysql.NewConnector(cfg) if err != nil { return nil, errors.Trace(err) } + db := sql.OpenDB(c) if err = db.Ping(); err != nil { _ = db.Close() return nil, errors.Trace(err) @@ -89,13 +106,9 @@ func tryConnectMySQL(dsn string) (*sql.DB, error) { // ConnectMySQL connects MySQL with the dsn. If access is denied and the password is a valid base64 encoding, // we will try to connect MySQL with the base64 decoding of the password. -func ConnectMySQL(dsn string) (*sql.DB, error) { - cfg, err := mysql.ParseDSN(dsn) - if err != nil { - return nil, errors.Trace(err) - } +func ConnectMySQL(cfg *mysql.Config) (*sql.DB, error) { // Try plain password first. - db, firstErr := tryConnectMySQL(dsn) + db, firstErr := tryConnectMySQL(cfg) if firstErr == nil { return db, nil } @@ -104,9 +117,9 @@ func ConnectMySQL(dsn string) (*sql.DB, error) { // If password is encoded by base64, try the decoded string as well. if password, decodeErr := base64.StdEncoding.DecodeString(cfg.Passwd); decodeErr == nil && string(password) != cfg.Passwd { cfg.Passwd = string(password) - db, err = tryConnectMySQL(cfg.FormatDSN()) + db2, err := tryConnectMySQL(cfg) if err == nil { - return db, nil + return db2, nil } } } @@ -115,7 +128,7 @@ func ConnectMySQL(dsn string) (*sql.DB, error) { } func (param *MySQLConnectParam) Connect() (*sql.DB, error) { - db, err := ConnectMySQL(param.ToDSN()) + db, err := ConnectMySQL(param.ToDriverConfig()) if err != nil { return nil, errors.Trace(err) } diff --git a/br/pkg/lightning/common/util_test.go b/br/pkg/lightning/common/util_test.go index c7c95b44f69bf..a192ecea11906 100644 --- a/br/pkg/lightning/common/util_test.go +++ b/br/pkg/lightning/common/util_test.go @@ -16,16 +16,12 @@ package common_test import ( "context" - "database/sql" - "database/sql/driver" "encoding/base64" "encoding/json" "fmt" "io" - "math/rand" "net/http" "net/http/httptest" - "strconv" "testing" "time" @@ -35,7 +31,6 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/br/pkg/lightning/common" "github.com/pingcap/tidb/br/pkg/lightning/log" - tmysql "github.com/pingcap/tidb/errno" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -85,66 +80,14 @@ func TestGetJSON(t *testing.T) { require.Regexp(t, ".*http status code != 200.*", err.Error()) } -func TestToDSN(t *testing.T) { - param := common.MySQLConnectParam{ - Host: "127.0.0.1", - Port: 4000, - User: "root", - Password: "123456", - SQLMode: "strict", - MaxAllowedPacket: 1234, - TLS: "cluster", - Vars: map[string]string{ - "tidb_distsql_scan_concurrency": "1", - }, - } - require.Equal(t, "root:123456@tcp(127.0.0.1:4000)/?charset=utf8mb4&sql_mode='strict'&maxAllowedPacket=1234&tls=cluster&tidb_distsql_scan_concurrency='1'", param.ToDSN()) - - param.Host = "::1" - require.Equal(t, "root:123456@tcp([::1]:4000)/?charset=utf8mb4&sql_mode='strict'&maxAllowedPacket=1234&tls=cluster&tidb_distsql_scan_concurrency='1'", param.ToDSN()) -} - -type mockDriver struct { - driver.Driver - plainPsw string -} - -func (m *mockDriver) Open(dsn string) (driver.Conn, error) { - cfg, err := mysql.ParseDSN(dsn) - if err != nil { - return nil, err - } - accessDenied := cfg.Passwd != m.plainPsw - return &mockConn{accessDenied: accessDenied}, nil -} - -type mockConn struct { - driver.Conn - driver.Pinger - accessDenied bool -} - -func (c *mockConn) Ping(ctx context.Context) error { - if c.accessDenied { - return &mysql.MySQLError{Number: tmysql.ErrAccessDenied, Message: "access denied"} - } - return nil -} - -func (c *mockConn) Close() error { - return nil -} - func TestConnect(t *testing.T) { plainPsw := "dQAUoDiyb1ucWZk7" - driverName := "mysql-mock-" + strconv.Itoa(rand.Int()) - sql.Register(driverName, &mockDriver{plainPsw: plainPsw}) require.NoError(t, failpoint.Enable( - "github.com/pingcap/tidb/br/pkg/lightning/common/MockMySQLDriver", - fmt.Sprintf("return(\"%s\")", driverName))) + "github.com/pingcap/tidb/br/pkg/lightning/common/MustMySQLPassword", + fmt.Sprintf("return(\"%s\")", plainPsw))) defer func() { - require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/br/pkg/lightning/common/MockMySQLDriver")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/br/pkg/lightning/common/MustMySQLPassword")) }() param := common.MySQLConnectParam{ @@ -155,13 +98,11 @@ func TestConnect(t *testing.T) { SQLMode: "strict", MaxAllowedPacket: 1234, } - db, err := param.Connect() + _, err := param.Connect() require.NoError(t, err) - require.NoError(t, db.Close()) param.Password = base64.StdEncoding.EncodeToString([]byte(plainPsw)) - db, err = param.Connect() + _, err = param.Connect() require.NoError(t, err) - require.NoError(t, db.Close()) } func TestIsContextCanceledError(t *testing.T) { diff --git a/br/pkg/lightning/config/BUILD.bazel b/br/pkg/lightning/config/BUILD.bazel index fba6b5abd7b0c..b69d2fca0d310 100644 --- a/br/pkg/lightning/config/BUILD.bazel +++ b/br/pkg/lightning/config/BUILD.bazel @@ -24,7 +24,6 @@ go_library( "@com_github_carlmjohnson_flagext//:flagext", "@com_github_docker_go_units//:go-units", "@com_github_go_sql_driver_mysql//:mysql", - "@com_github_google_uuid//:uuid", "@com_github_pingcap_errors//:errors", "@org_uber_go_atomic//:atomic", "@org_uber_go_zap//:zap", @@ -43,7 +42,6 @@ go_test( deps = [ ":config", "//br/pkg/lightning/common", - "//parser/mysql", "@com_github_burntsushi_toml//:toml", "@com_github_stretchr_testify//require", ], diff --git a/br/pkg/lightning/config/config.go b/br/pkg/lightning/config/config.go index 4c1af0d2baff3..45d5f1fa334a4 100644 --- a/br/pkg/lightning/config/config.go +++ b/br/pkg/lightning/config/config.go @@ -16,6 +16,7 @@ package config import ( "context" + "crypto/tls" "encoding/json" "fmt" "math" @@ -32,7 +33,6 @@ import ( "github.com/BurntSushi/toml" "github.com/docker/go-units" gomysql "github.com/go-sql-driver/mysql" - "github.com/google/uuid" "github.com/pingcap/errors" "github.com/pingcap/tidb/br/pkg/lightning/common" "github.com/pingcap/tidb/br/pkg/lightning/log" @@ -135,6 +135,9 @@ type DBStore struct { IndexSerialScanConcurrency int `toml:"index-serial-scan-concurrency" json:"index-serial-scan-concurrency"` ChecksumTableConcurrency int `toml:"checksum-table-concurrency" json:"checksum-table-concurrency"` Vars map[string]string `toml:"-" json:"vars"` + + IOTotalBytes *atomic.Uint64 `toml:"-" json:"-"` + UUID string `toml:"-" json:"-"` } type Config struct { @@ -381,6 +384,10 @@ const ( // DupeResAlgRemove records all duplicate records like the 'record' algorithm and remove all information related to the // duplicated rows. Users need to analyze the lightning_task_info.conflict_error_v1 table to add back the correct rows. DupeResAlgRemove + + // DupeResAlgErr reports an error and stops the import process. + // Note: this value is only used for internal. + DupeResAlgErr ) func (dra *DuplicateResolutionAlgorithm) UnmarshalTOML(v interface{}) error { @@ -454,6 +461,7 @@ type MydumperRuntime struct { ReadBlockSize ByteSize `toml:"read-block-size" json:"read-block-size"` BatchSize ByteSize `toml:"batch-size" json:"batch-size"` BatchImportRatio float64 `toml:"batch-import-ratio" json:"batch-import-ratio"` + SourceID string `toml:"source-id" json:"source-id"` SourceDir string `toml:"data-source-dir" json:"data-source-dir"` CharacterSet string `toml:"character-set" json:"character-set"` CSV CSVConfig `toml:"csv" json:"csv"` @@ -553,11 +561,12 @@ type TikvImporter struct { } type Checkpoint struct { - Schema string `toml:"schema" json:"schema"` - DSN string `toml:"dsn" json:"-"` // DSN may contain password, don't expose this to JSON. - Driver string `toml:"driver" json:"driver"` - Enable bool `toml:"enable" json:"enable"` - KeepAfterSuccess CheckpointKeepStrategy `toml:"keep-after-success" json:"keep-after-success"` + Schema string `toml:"schema" json:"schema"` + DSN string `toml:"dsn" json:"-"` // DSN may contain password, don't expose this to JSON. + MySQLParam *common.MySQLConnectParam `toml:"-" json:"-"` // For some security reason, we use MySQLParam instead of DSN. + Driver string `toml:"driver" json:"driver"` + Enable bool `toml:"enable" json:"enable"` + KeepAfterSuccess CheckpointKeepStrategy `toml:"keep-after-success" json:"keep-after-success"` } type Cron struct { @@ -573,9 +582,8 @@ type Security struct { // RedactInfoLog indicates that whether enabling redact log RedactInfoLog bool `toml:"redact-info-log" json:"redact-info-log"` - // TLSConfigName is used to set tls config for lightning in DM, so we don't expose this field to user - // DM may running many lightning instances at same time, so we need to set different tls config name for each lightning - TLSConfigName string `toml:"-" json:"-"` + TLSConfig *tls.Config `toml:"-" json:"-"` + AllowFallbackToPlaintext bool `toml:"-" json:"-"` // When DM/engine uses lightning as a library, it can directly pass in the content CABytes []byte `toml:"-" json:"-"` @@ -583,10 +591,9 @@ type Security struct { KeyBytes []byte `toml:"-" json:"-"` } -// RegisterMySQL registers the TLS config with name "cluster" or security.TLSConfigName -// for use in `sql.Open()`. This method is goroutine-safe. -func (sec *Security) RegisterMySQL() error { - if sec == nil { +// BuildTLSConfig builds the tls config which is used by SQL drier later. +func (sec *Security) BuildTLSConfig() error { + if sec == nil || sec.TLSConfig != nil { return nil } @@ -599,21 +606,10 @@ func (sec *Security) RegisterMySQL() error { if err != nil { return errors.Trace(err) } - if tlsConfig != nil { - // error happens only when the key coincides with the built-in names. - _ = gomysql.RegisterTLSConfig(sec.TLSConfigName, tlsConfig) - } + sec.TLSConfig = tlsConfig return nil } -// DeregisterMySQL deregisters the TLS config with security.TLSConfigName -func (sec *Security) DeregisterMySQL() { - if sec == nil || len(sec.CAPath) == 0 { - return - } - gomysql.DeregisterTLSConfig(sec.TLSConfigName) -} - // A duration which can be deserialized from a TOML string. // Implemented as https://github.com/BurntSushi/toml#using-the-encodingtextunmarshaler-interface type Duration struct { @@ -1134,18 +1130,27 @@ func (cfg *Config) AdjustCheckPoint() { switch cfg.Checkpoint.Driver { case CheckpointDriverMySQL: param := common.MySQLConnectParam{ - Host: cfg.TiDB.Host, - Port: cfg.TiDB.Port, - User: cfg.TiDB.User, - Password: cfg.TiDB.Psw, - SQLMode: mysql.DefaultSQLMode, - MaxAllowedPacket: defaultMaxAllowedPacket, - TLS: cfg.TiDB.TLS, + Host: cfg.TiDB.Host, + Port: cfg.TiDB.Port, + User: cfg.TiDB.User, + Password: cfg.TiDB.Psw, + SQLMode: mysql.DefaultSQLMode, + MaxAllowedPacket: defaultMaxAllowedPacket, + TLSConfig: cfg.TiDB.Security.TLSConfig, + AllowFallbackToPlaintext: cfg.TiDB.Security.AllowFallbackToPlaintext, } - cfg.Checkpoint.DSN = param.ToDSN() + cfg.Checkpoint.MySQLParam = ¶m case CheckpointDriverFile: cfg.Checkpoint.DSN = "/tmp/" + cfg.Checkpoint.Schema + ".pb" } + } else { + // try to remove allowAllFiles + mysqlCfg, err := gomysql.ParseDSN(cfg.Checkpoint.DSN) + if err != nil { + return + } + mysqlCfg.AllowAllFiles = false + cfg.Checkpoint.DSN = mysqlCfg.FormatDSN() } } @@ -1178,22 +1183,22 @@ func (cfg *Config) CheckAndAdjustSecurity() error { } switch cfg.TiDB.TLS { - case "": - if len(cfg.TiDB.Security.CAPath) > 0 || len(cfg.TiDB.Security.CABytes) > 0 || - len(cfg.TiDB.Security.CertPath) > 0 || len(cfg.TiDB.Security.CertBytes) > 0 || - len(cfg.TiDB.Security.KeyPath) > 0 || len(cfg.TiDB.Security.KeyBytes) > 0 { - if cfg.TiDB.Security.TLSConfigName == "" { - cfg.TiDB.Security.TLSConfigName = uuid.NewString() // adjust this the default value + case "skip-verify", "preferred": + if cfg.TiDB.Security.TLSConfig == nil { + /* #nosec G402 */ + cfg.TiDB.Security.TLSConfig = &tls.Config{ + MinVersion: tls.VersionTLS10, + InsecureSkipVerify: true, + NextProtos: []string{"h2", "http/1.1"}, // specify `h2` to let Go use HTTP/2. } - cfg.TiDB.TLS = cfg.TiDB.Security.TLSConfigName - } else { - cfg.TiDB.TLS = "false" + cfg.TiDB.Security.AllowFallbackToPlaintext = true } case "cluster": if len(cfg.Security.CAPath) == 0 { return common.ErrInvalidConfig.GenWithStack("cannot set `tidb.tls` to 'cluster' without a [security] section") } - case "false", "skip-verify", "preferred": + case "", "false": + cfg.TiDB.TLS = "false" return nil default: return common.ErrInvalidConfig.GenWithStack("unsupported `tidb.tls` config %s", cfg.TiDB.TLS) diff --git a/br/pkg/lightning/config/config_test.go b/br/pkg/lightning/config/config_test.go index 2a4dcbe7cdad9..ea0cff40a04c7 100644 --- a/br/pkg/lightning/config/config_test.go +++ b/br/pkg/lightning/config/config_test.go @@ -32,7 +32,6 @@ import ( "github.com/BurntSushi/toml" "github.com/pingcap/tidb/br/pkg/lightning/common" "github.com/pingcap/tidb/br/pkg/lightning/config" - "github.com/pingcap/tidb/parser/mysql" "github.com/stretchr/testify/require" ) @@ -280,31 +279,34 @@ func TestAdjustWillBatchImportRatioInvalid(t *testing.T) { } func TestAdjustSecuritySection(t *testing.T) { - uuidHolder := "" testCases := []struct { - input string - expectedCA string - expectedTLS string + input string + expectedCA string + hasTLS bool + fallback2NoTLS bool }{ { - input: ``, - expectedCA: "", - expectedTLS: "false", + input: ``, + expectedCA: "", + hasTLS: false, + fallback2NoTLS: false, }, { input: ` [security] `, - expectedCA: "", - expectedTLS: "false", + expectedCA: "", + hasTLS: false, + fallback2NoTLS: false, }, { input: ` [security] ca-path = "/path/to/ca.pem" `, - expectedCA: "/path/to/ca.pem", - expectedTLS: uuidHolder, + expectedCA: "/path/to/ca.pem", + hasTLS: false, + fallback2NoTLS: false, }, { input: ` @@ -312,8 +314,9 @@ func TestAdjustSecuritySection(t *testing.T) { ca-path = "/path/to/ca.pem" [tidb.security] `, - expectedCA: "", - expectedTLS: "false", + expectedCA: "", + hasTLS: false, + fallback2NoTLS: false, }, { input: ` @@ -322,8 +325,9 @@ func TestAdjustSecuritySection(t *testing.T) { [tidb.security] ca-path = "/path/to/ca2.pem" `, - expectedCA: "/path/to/ca2.pem", - expectedTLS: uuidHolder, + expectedCA: "/path/to/ca2.pem", + hasTLS: false, + fallback2NoTLS: false, }, { input: ` @@ -331,8 +335,9 @@ func TestAdjustSecuritySection(t *testing.T) { [tidb.security] ca-path = "/path/to/ca2.pem" `, - expectedCA: "/path/to/ca2.pem", - expectedTLS: uuidHolder, + expectedCA: "/path/to/ca2.pem", + hasTLS: false, + fallback2NoTLS: false, }, { input: ` @@ -341,8 +346,20 @@ func TestAdjustSecuritySection(t *testing.T) { tls = "skip-verify" [tidb.security] `, - expectedCA: "", - expectedTLS: "skip-verify", + expectedCA: "", + hasTLS: true, + fallback2NoTLS: true, + }, + { + input: ` + [security] + [tidb] + tls = "false" + [tidb.security] + `, + expectedCA: "", + hasTLS: false, + fallback2NoTLS: false, }, } @@ -358,19 +375,18 @@ func TestAdjustSecuritySection(t *testing.T) { err = cfg.Adjust(context.Background()) require.NoError(t, err, comment) require.Equal(t, tc.expectedCA, cfg.TiDB.Security.CAPath, comment) - if tc.expectedTLS == uuidHolder { - require.NotEmpty(t, cfg.TiDB.TLS, comment) + if tc.hasTLS { + require.NotNil(t, cfg.TiDB.Security.TLSConfig, comment) } else { - require.Equal(t, tc.expectedTLS, cfg.TiDB.TLS, comment) + require.Nil(t, cfg.TiDB.Security.TLSConfig, comment) } + require.Equal(t, tc.fallback2NoTLS, cfg.TiDB.Security.AllowFallbackToPlaintext, comment) } // test different tls config name cfg := config.NewConfig() assignMinimalLegalValue(cfg) cfg.Security.CAPath = "/path/to/ca.pem" - cfg.Security.TLSConfigName = "tidb-tls" require.NoError(t, cfg.Adjust(context.Background())) - require.Equal(t, cfg.TiDB.TLS, cfg.TiDB.Security.TLSConfigName) } func TestInvalidCSV(t *testing.T) { @@ -626,7 +642,9 @@ func TestLoadConfig(t *testing.T) { taskCfg.TiDB.DistSQLScanConcurrency = 1 err = taskCfg.Adjust(context.Background()) require.NoError(t, err) - require.Equal(t, "guest:12345@tcp(172.16.30.11:4001)/?charset=utf8mb4&sql_mode='"+mysql.DefaultSQLMode+"'&maxAllowedPacket=67108864&tls=false", taskCfg.Checkpoint.DSN) + equivalentDSN := taskCfg.Checkpoint.MySQLParam.ToDriverConfig().FormatDSN() + expectedDSN := "guest:12345@tcp(172.16.30.11:4001)/?maxAllowedPacket=67108864&charset=utf8mb4&sql_mode=%27ONLY_FULL_GROUP_BY%2CSTRICT_TRANS_TABLES%2CNO_ZERO_IN_DATE%2CNO_ZERO_DATE%2CERROR_FOR_DIVISION_BY_ZERO%2CNO_AUTO_CREATE_USER%2CNO_ENGINE_SUBSTITUTION%27" + require.Equal(t, expectedDSN, equivalentDSN) result := taskCfg.String() require.Regexp(t, `.*"pd-addr":"172.16.30.11:2379,172.16.30.12:2379".*`, result) @@ -782,6 +800,17 @@ func TestAdjustDiskQuota(t *testing.T) { require.Equal(t, int64(0), int64(cfg.TikvImporter.DiskQuota)) } +func TestRemoveAllowAllFiles(t *testing.T) { + cfg := config.NewConfig() + assignMinimalLegalValue(cfg) + ctx := context.Background() + + cfg.Checkpoint.Driver = config.CheckpointDriverMySQL + cfg.Checkpoint.DSN = "guest:12345@tcp(172.16.30.11:4001)/?tls=false&allowAllFiles=true&charset=utf8mb4" + require.NoError(t, cfg.Adjust(ctx)) + require.Equal(t, "guest:12345@tcp(172.16.30.11:4001)/?tls=false&charset=utf8mb4", cfg.Checkpoint.DSN) +} + func TestDataCharacterSet(t *testing.T) { testCases := []struct { input string diff --git a/br/pkg/lightning/errormanager/errormanager.go b/br/pkg/lightning/errormanager/errormanager.go index 43035716d729c..373ba572779d4 100644 --- a/br/pkg/lightning/errormanager/errormanager.go +++ b/br/pkg/lightning/errormanager/errormanager.go @@ -40,9 +40,10 @@ const ( CREATE SCHEMA IF NOT EXISTS %s; ` - syntaxErrorTableName = "syntax_error_v1" - typeErrorTableName = "type_error_v1" - conflictErrorTableName = "conflict_error_v1" + syntaxErrorTableName = "syntax_error_v1" + typeErrorTableName = "type_error_v1" + // ConflictErrorTableName is the table name for duplicate detection. + ConflictErrorTableName = "conflict_error_v1" createSyntaxErrorTable = ` CREATE TABLE IF NOT EXISTS %s.` + syntaxErrorTableName + ` ( @@ -69,7 +70,7 @@ const ( ` createConflictErrorTable = ` - CREATE TABLE IF NOT EXISTS %s.` + conflictErrorTableName + ` ( + CREATE TABLE IF NOT EXISTS %s.` + ConflictErrorTableName + ` ( task_id bigint NOT NULL, create_time datetime(6) NOT NULL DEFAULT now(6), table_name varchar(261) NOT NULL, @@ -91,7 +92,7 @@ const ( ` insertIntoConflictErrorData = ` - INSERT INTO %s.` + conflictErrorTableName + ` + INSERT INTO %s.` + ConflictErrorTableName + ` (task_id, table_name, index_name, key_data, row_data, raw_key, raw_value, raw_handle, raw_row) VALUES ` @@ -99,7 +100,7 @@ const ( sqlValuesConflictErrorData = "(?,?,'PRIMARY',?,?,?,?,raw_key,raw_value)" insertIntoConflictErrorIndex = ` - INSERT INTO %s.` + conflictErrorTableName + ` + INSERT INTO %s.` + ConflictErrorTableName + ` (task_id, table_name, index_name, key_data, row_data, raw_key, raw_value, raw_handle, raw_row) VALUES ` @@ -108,7 +109,7 @@ const ( selectConflictKeys = ` SELECT _tidb_rowid, raw_handle, raw_row - FROM %s.` + conflictErrorTableName + ` + FROM %s.` + ConflictErrorTableName + ` WHERE table_name = ? AND _tidb_rowid >= ? and _tidb_rowid < ? ORDER BY _tidb_rowid LIMIT ?; ` @@ -468,7 +469,7 @@ func (em *ErrorManager) LogErrorDetails() { em.logger.Warn(fmtErrMsg(errCnt, "data type", "")) } if errCnt := em.conflictError(); errCnt > 0 { - em.logger.Warn(fmtErrMsg(errCnt, "data type", conflictErrorTableName)) + em.logger.Warn(fmtErrMsg(errCnt, "data type", ConflictErrorTableName)) } } @@ -511,7 +512,7 @@ func (em *ErrorManager) Output() string { } if errCnt := em.conflictError(); errCnt > 0 { count++ - t.AppendRow(table.Row{count, "Unique Key Conflict", errCnt, em.fmtTableName(conflictErrorTableName)}) + t.AppendRow(table.Row{count, "Unique Key Conflict", errCnt, em.fmtTableName(ConflictErrorTableName)}) } res := "\nImport Data Error Summary: \n" diff --git a/br/pkg/lightning/lightning.go b/br/pkg/lightning/lightning.go index 3770f7c8f07a4..46c38e112b57d 100644 --- a/br/pkg/lightning/lightning.go +++ b/br/pkg/lightning/lightning.go @@ -33,6 +33,8 @@ import ( "sync" "time" + "github.com/go-sql-driver/mysql" + "github.com/google/uuid" "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/import_sstpb" @@ -53,11 +55,13 @@ import ( "github.com/pingcap/tidb/br/pkg/version/build" _ "github.com/pingcap/tidb/expression" // get rid of `import cycle`: just init expression.RewriteAstExpr,and called at package `backend.kv`. _ "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/promutil" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/shurcooL/httpgzip" + "go.uber.org/atomic" "go.uber.org/zap" "go.uber.org/zap/zapcore" "golang.org/x/exp/slices" @@ -77,6 +81,7 @@ type Lightning struct { promFactory promutil.Factory promRegistry promutil.Registry + metrics *metric.Metrics cancelLock sync.Mutex curTask *config.Config @@ -369,6 +374,36 @@ func (l *Lightning) RunOnceWithOptions(taskCtx context.Context, taskCfg *config. taskCfg.TaskID = int64(val.(int)) }) + failpoint.Inject("SetIOTotalBytes", func(_ failpoint.Value) { + o.logger.Info("set io total bytes") + taskCfg.TiDB.IOTotalBytes = atomic.NewUint64(0) + taskCfg.TiDB.UUID = uuid.New().String() + go func() { + for { + time.Sleep(time.Millisecond * 10) + log.L().Info("IOTotalBytes", zap.Uint64("IOTotalBytes", taskCfg.TiDB.IOTotalBytes.Load())) + } + }() + }) + if taskCfg.TiDB.IOTotalBytes != nil { + o.logger.Info("found IO total bytes counter") + mysql.RegisterDialContext(taskCfg.TiDB.UUID, func(ctx context.Context, addr string) (net.Conn, error) { + o.logger.Debug("connection with IO bytes counter") + d := &net.Dialer{} + conn, err := d.DialContext(ctx, "tcp", addr) + if err != nil { + return nil, err + } + tcpConn := conn.(*net.TCPConn) + // try https://github.com/go-sql-driver/mysql/blob/bcc459a906419e2890a50fc2c99ea6dd927a88f2/connector.go#L56-L64 + err = tcpConn.SetKeepAlive(true) + if err != nil { + o.logger.Warn("set TCP keep alive failed", zap.Error(err)) + } + return util.NewTCPConnWithIOCounter(tcpConn, taskCfg.TiDB.IOTotalBytes), nil + }) + } + return l.run(taskCtx, taskCfg, o) } @@ -388,6 +423,7 @@ func (l *Lightning) run(taskCtx context.Context, taskCfg *config.Config, o *opti defer func() { metrics.UnregisterFrom(o.promRegistry) }() + l.metrics = metrics ctx := metric.NewContext(taskCtx, metrics) ctx = log.NewContext(ctx, o.logger) @@ -433,18 +469,21 @@ func (l *Lightning) run(taskCtx context.Context, taskCfg *config.Config, o *opti } }) - if err := taskCfg.TiDB.Security.RegisterMySQL(); err != nil { + failpoint.Inject("PrintStatus", func() { + defer func() { + finished, total := l.Status() + o.logger.Warn("PrintStatus Failpoint", + zap.Int64("finished", finished), + zap.Int64("total", total), + zap.Bool("equal", finished == total)) + }() + }) + + if err := taskCfg.TiDB.Security.BuildTLSConfig(); err != nil { return common.ErrInvalidTLSConfig.Wrap(err) } - defer func() { - // deregister TLS config with name "cluster" - if taskCfg.TiDB.Security == nil { - return - } - taskCfg.TiDB.Security.DeregisterMySQL() - }() - // initiation of default glue should be after RegisterMySQL, which is ready to be called after taskCfg.Adjust + // initiation of default glue should be after BuildTLSConfig, which is ready to be called after taskCfg.Adjust // and also put it here could avoid injecting another two SkipRunTask failpoint to caller g := o.glue if g == nil { @@ -502,8 +541,6 @@ func (l *Lightning) run(taskCtx context.Context, taskCfg *config.Config, o *opti dbMetas := mdl.GetDatabases() web.BroadcastInitProgress(dbMetas) - var procedure *restore.Controller - param := &restore.ControllerParam{ DBMetas: dbMetas, Status: &l.status, @@ -512,8 +549,10 @@ func (l *Lightning) run(taskCtx context.Context, taskCfg *config.Config, o *opti Glue: g, CheckpointStorage: o.checkpointStorage, CheckpointName: o.checkpointName, + DupIndicator: o.dupIndicator, } + var procedure *restore.Controller procedure, err = restore.NewRestoreController(ctx, taskCfg, param) if err != nil { o.logger.Error("restore failed", log.ShortError(err)) @@ -544,6 +583,12 @@ func (l *Lightning) Status() (finished int64, total int64) { return } +// Metrics returns the metrics of lightning. +// it's inited during `run`, so might return nil. +func (l *Lightning) Metrics() *metric.Metrics { + return l.metrics +} + func writeJSONError(w http.ResponseWriter, code int, prefix string, err error) { type errorResponse struct { Error string `json:"error"` diff --git a/br/pkg/lightning/manual/BUILD.bazel b/br/pkg/lightning/manual/BUILD.bazel index 6d1fc18dd2495..d54902a23c066 100644 --- a/br/pkg/lightning/manual/BUILD.bazel +++ b/br/pkg/lightning/manual/BUILD.bazel @@ -10,4 +10,5 @@ go_library( cgo = True, importpath = "github.com/pingcap/tidb/br/pkg/lightning/manual", visibility = ["//visibility:public"], + deps = ["@org_uber_go_atomic//:atomic"], ) diff --git a/br/pkg/lightning/manual/allocator.go b/br/pkg/lightning/manual/allocator.go index 821eb750c5030..18aa8cc9353c4 100644 --- a/br/pkg/lightning/manual/allocator.go +++ b/br/pkg/lightning/manual/allocator.go @@ -14,8 +14,33 @@ package manual -type Allocator struct{} +import ( + "fmt" -func (Allocator) Alloc(n int) []byte { return New(n) } + "go.uber.org/atomic" +) -func (Allocator) Free(b []byte) { Free(b) } +type Allocator struct { + RefCnt *atomic.Int64 +} + +func (a Allocator) Alloc(n int) []byte { + if a.RefCnt != nil { + a.RefCnt.Add(1) + } + return New(n) +} + +func (a Allocator) Free(b []byte) { + if a.RefCnt != nil { + a.RefCnt.Add(-1) + } + Free(b) +} + +func (a Allocator) CheckRefCnt() error { + if a.RefCnt != nil && a.RefCnt.Load() != 0 { + return fmt.Errorf("memory leak detected, refCnt: %d", a.RefCnt.Load()) + } + return nil +} diff --git a/br/pkg/lightning/mydump/BUILD.bazel b/br/pkg/lightning/mydump/BUILD.bazel index dccd93f84e7ce..d265cad78bce6 100644 --- a/br/pkg/lightning/mydump/BUILD.bazel +++ b/br/pkg/lightning/mydump/BUILD.bazel @@ -23,6 +23,7 @@ go_library( "//br/pkg/lightning/metric", "//br/pkg/lightning/worker", "//br/pkg/storage", + "//config", "//parser/mysql", "//types", "//util/filter", diff --git a/br/pkg/lightning/mydump/csv/split_large_file.csv.zst b/br/pkg/lightning/mydump/csv/split_large_file.csv.zst new file mode 100644 index 0000000000000..9609230bf04a5 Binary files /dev/null and b/br/pkg/lightning/mydump/csv/split_large_file.csv.zst differ diff --git a/br/pkg/lightning/mydump/csv_parser.go b/br/pkg/lightning/mydump/csv_parser.go index 96de51bd49c73..b7d6c6fc21903 100644 --- a/br/pkg/lightning/mydump/csv_parser.go +++ b/br/pkg/lightning/mydump/csv_parser.go @@ -25,6 +25,7 @@ import ( "github.com/pingcap/tidb/br/pkg/lightning/log" "github.com/pingcap/tidb/br/pkg/lightning/metric" "github.com/pingcap/tidb/br/pkg/lightning/worker" + tidbconfig "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/mathutil" ) @@ -33,8 +34,14 @@ var ( errUnterminatedQuotedField = errors.NewNoStackError("syntax error: unterminated quoted field") errDanglingBackslash = errors.NewNoStackError("syntax error: no character after backslash") errUnexpectedQuoteField = errors.NewNoStackError("syntax error: cannot have consecutive fields without separator") + // LargestEntryLimit is the max size for reading file to buf + LargestEntryLimit int ) +func init() { + LargestEntryLimit = tidbconfig.MaxTxnEntrySizeLimit +} + // CSVParser is basically a copy of encoding/csv, but special-cased for MySQL-like input. type CSVParser struct { blockParser @@ -336,6 +343,9 @@ func (parser *CSVParser) readUntil(chars *byteSet) ([]byte, byte, error) { var buf []byte for { buf = append(buf, parser.buf...) + if len(buf) > LargestEntryLimit { + return buf, 0, errors.New("size of row cannot exceed the max value of txn-entry-size-limit") + } parser.buf = nil if err := parser.readBlock(); err != nil || len(parser.buf) == 0 { if err == nil { @@ -447,9 +457,18 @@ outside: func (parser *CSVParser) readQuotedField() error { for { + prevPos := parser.pos content, terminator, err := parser.readUntil(&parser.quoteByteSet) - err = parser.replaceEOF(err, errUnterminatedQuotedField) if err != nil { + if errors.Cause(err) == io.EOF { + // return the position of quote to the caller. + // because we return an error here, the parser won't + // use the `pos` again, so it's safe to modify it here. + parser.pos = prevPos - 1 + // set buf to parser.buf in order to print err log + parser.buf = content + err = parser.replaceEOF(err, errUnterminatedQuotedField) + } return err } parser.recordBuffer = append(parser.recordBuffer, content...) diff --git a/br/pkg/lightning/mydump/csv_parser_test.go b/br/pkg/lightning/mydump/csv_parser_test.go index 2696a6909c96c..da06c15ed39d9 100644 --- a/br/pkg/lightning/mydump/csv_parser_test.go +++ b/br/pkg/lightning/mydump/csv_parser_test.go @@ -1,6 +1,7 @@ package mydump_test import ( + "bytes" "context" "encoding/csv" "fmt" @@ -680,6 +681,29 @@ func TestConsecutiveFields(t *testing.T) { }) } +func TestTooLargeRow(t *testing.T) { + cfg := config.MydumperRuntime{ + CSV: config.CSVConfig{ + Separator: ",", + Delimiter: `"`, + }, + } + var testCase bytes.Buffer + testCase.WriteString("a,b,c,d") + // WARN: will take up 10KB memory here. + mydump.LargestEntryLimit = 10 * 1024 + for i := 0; i < mydump.LargestEntryLimit; i++ { + testCase.WriteByte('d') + } + charsetConvertor, err := mydump.NewCharsetConvertor(cfg.DataCharacterSet, cfg.DataInvalidCharReplace) + require.NoError(t, err) + parser, err := mydump.NewCSVParser(context.Background(), &cfg.CSV, mydump.NewStringReader(testCase.String()), int64(config.ReadBlockSize), ioWorkers, false, charsetConvertor) + require.NoError(t, err) + e := parser.ReadRow() + require.Error(t, e) + require.Contains(t, e.Error(), "size of row cannot exceed the max value of txn-entry-size-limit") +} + func TestSpecialChars(t *testing.T) { cfg := config.MydumperRuntime{ CSV: config.CSVConfig{Separator: ",", Delimiter: `"`}, diff --git a/br/pkg/lightning/mydump/loader.go b/br/pkg/lightning/mydump/loader.go index 5b77af8f851c2..d55bce6f94fc5 100644 --- a/br/pkg/lightning/mydump/loader.go +++ b/br/pkg/lightning/mydump/loader.go @@ -16,6 +16,7 @@ package mydump import ( "context" + "io" "path/filepath" "sort" "strings" @@ -30,6 +31,9 @@ import ( "go.uber.org/zap" ) +// sampleCompressedFileSize represents how many bytes need to be sampled for compressed files +const sampleCompressedFileSize = 4 * 1024 + // MDDatabaseMeta contains some parsed metadata for a database in the source by MyDumper Loader. type MDDatabaseMeta struct { Name string @@ -82,6 +86,9 @@ type SourceFileMeta struct { Compression Compression SortKey string FileSize int64 + // WARNING: variables below are not persistent + ExtendData ExtendColumnData + RealSize int64 } // NewMDTableMeta creates an Mydumper table meta with specified character set. @@ -124,6 +131,8 @@ type MDLoaderSetupConfig struct { // ReturnPartialResultOnError specifies whether the currently scanned files are analyzed, // and return the partial result. ReturnPartialResultOnError bool + // FileIter controls the file iteration policy when constructing a MDLoader. + FileIter FileIterator } // DefaultMDLoaderSetupConfig generates a default MDLoaderSetupConfig. @@ -131,6 +140,7 @@ func DefaultMDLoaderSetupConfig() *MDLoaderSetupConfig { return &MDLoaderSetupConfig{ MaxScanFiles: 0, // By default, the loader will scan all the files. ReturnPartialResultOnError: false, + FileIter: nil, } } @@ -155,6 +165,13 @@ func ReturnPartialResultOnError(supportPartialResult bool) MDLoaderSetupOption { } } +// WithFileIterator generates an option that specifies the file iteration policy. +func WithFileIterator(fileIter FileIterator) MDLoaderSetupOption { + return func(cfg *MDLoaderSetupConfig) { + cfg.FileIter = fileIter + } +} + // MDLoader is for 'Mydumper File Loader', which loads the files in the data source and generates a set of metadata. type MDLoader struct { store storage.ExternalStorage @@ -167,6 +184,7 @@ type MDLoader struct { } type mdLoaderSetup struct { + sourceID string loader *MDLoader dbSchemas []FileInfo tableSchemas []FileInfo @@ -200,6 +218,12 @@ func NewMyDumpLoaderWithStore(ctx context.Context, cfg *config.Config, store sto for _, o := range opts { o(mdLoaderSetupCfg) } + if mdLoaderSetupCfg.FileIter == nil { + mdLoaderSetupCfg.FileIter = &allFileIterator{ + store: store, + maxScanFiles: mdLoaderSetupCfg.MaxScanFiles, + } + } if len(cfg.Routes) > 0 && len(cfg.Mydumper.FileRouters) > 0 { return nil, common.ErrInvalidConfig.GenWithStack("table route is deprecated, can't config both [routes] and [mydumper.files]") @@ -245,13 +269,14 @@ func NewMyDumpLoaderWithStore(ctx context.Context, cfg *config.Config, store sto } setup := mdLoaderSetup{ + sourceID: cfg.Mydumper.SourceID, loader: mdl, dbIndexMap: make(map[string]int), tableIndexMap: make(map[filter.Table]int), setupCfg: mdLoaderSetupCfg, } - if err := setup.setup(ctx, mdl.store); err != nil { + if err := setup.setup(ctx); err != nil { if mdLoaderSetupCfg.ReturnPartialResultOnError { return mdl, errors.Trace(err) } @@ -289,6 +314,12 @@ type FileInfo struct { FileMeta SourceFileMeta } +// ExtendColumnData contains the extended column names and values information for a table. +type ExtendColumnData struct { + Columns []string + Values []string +} + // setup the `s.loader.dbs` slice by scanning all *.sql files inside `dir`. // // The database and tables are inserted in a consistent order, so creating an @@ -303,7 +334,7 @@ type FileInfo struct { // Will sort tables by table size, this means that the big table is imported // at the latest, which to avoid large table take a long time to import and block // small table to release index worker. -func (s *mdLoaderSetup) setup(ctx context.Context, store storage.ExternalStorage) error { +func (s *mdLoaderSetup) setup(ctx context.Context) error { /* Mydumper file names format db —— {db}-schema-create.sql @@ -311,7 +342,11 @@ func (s *mdLoaderSetup) setup(ctx context.Context, store storage.ExternalStorage sql —— {db}.{table}.{part}.sql / {db}.{table}.sql */ var gerr error - if err := s.listFiles(ctx, store); err != nil { + fileIter := s.setupCfg.FileIter + if fileIter == nil { + return errors.New("file iterator is not defined") + } + if err := fileIter.IterateFiles(ctx, s.constructFileInfo); err != nil { if s.setupCfg.ReturnPartialResultOnError { gerr = err } else { @@ -357,7 +392,7 @@ func (s *mdLoaderSetup) setup(ctx context.Context, store storage.ExternalStorage // set a dummy `FileInfo` here without file meta because we needn't restore the table schema tableMeta, _, _ := s.insertTable(FileInfo{TableName: fileInfo.TableName}) tableMeta.DataFiles = append(tableMeta.DataFiles, fileInfo) - tableMeta.TotalSize += fileInfo.FileMeta.FileSize + tableMeta.TotalSize += fileInfo.FileMeta.RealSize } for _, dbMeta := range s.loader.dbs { @@ -380,55 +415,83 @@ func (s *mdLoaderSetup) setup(ctx context.Context, store storage.ExternalStorage return gerr } -func (s *mdLoaderSetup) listFiles(ctx context.Context, store storage.ExternalStorage) error { +// FileHandler is the interface to handle the file give the path and size. +// It is mainly used in the `FileIterator` as parameters. +type FileHandler func(ctx context.Context, path string, size int64) error + +// FileIterator is the interface to iterate files in a data source. +// Use this interface to customize the file iteration policy. +type FileIterator interface { + IterateFiles(ctx context.Context, hdl FileHandler) error +} + +type allFileIterator struct { + store storage.ExternalStorage + maxScanFiles int +} + +func (iter *allFileIterator) IterateFiles(ctx context.Context, hdl FileHandler) error { // `filepath.Walk` yields the paths in a deterministic (lexicographical) order, // meaning the file and chunk orders will be the same everytime it is called // (as long as the source is immutable). totalScannedFileCount := 0 - err := store.WalkDir(ctx, &storage.WalkOption{}, func(path string, size int64) error { - logger := log.FromContext(ctx).With(zap.String("path", path)) + err := iter.store.WalkDir(ctx, &storage.WalkOption{}, func(path string, size int64) error { totalScannedFileCount++ - if s.setupCfg.MaxScanFiles > 0 && totalScannedFileCount > s.setupCfg.MaxScanFiles { + if iter.maxScanFiles > 0 && totalScannedFileCount > iter.maxScanFiles { return common.ErrTooManySourceFiles } - res, err := s.loader.fileRouter.Route(filepath.ToSlash(path)) - if err != nil { - return errors.Annotatef(err, "apply file routing on file '%s' failed", path) - } - if res == nil { - logger.Info("[loader] file is filtered by file router") - return nil - } - - info := FileInfo{ - TableName: filter.Table{Schema: res.Schema, Name: res.Name}, - FileMeta: SourceFileMeta{Path: path, Type: res.Type, Compression: res.Compression, SortKey: res.Key, FileSize: size}, - } + return hdl(ctx, path, size) + }) - if s.loader.shouldSkip(&info.TableName) { - logger.Debug("[filter] ignoring table file") + return errors.Trace(err) +} - return nil - } +func (s *mdLoaderSetup) constructFileInfo(ctx context.Context, path string, size int64) error { + logger := log.FromContext(ctx).With(zap.String("path", path)) + res, err := s.loader.fileRouter.Route(filepath.ToSlash(path)) + if err != nil { + return errors.Annotatef(err, "apply file routing on file '%s' failed", path) + } + if res == nil { + logger.Info("[loader] file is filtered by file router") + return nil + } - switch res.Type { - case SourceTypeSchemaSchema: - s.dbSchemas = append(s.dbSchemas, info) - case SourceTypeTableSchema: - s.tableSchemas = append(s.tableSchemas, info) - case SourceTypeViewSchema: - s.viewSchemas = append(s.viewSchemas, info) - case SourceTypeSQL, SourceTypeCSV, SourceTypeParquet: - s.tableDatas = append(s.tableDatas, info) - } + info := FileInfo{ + TableName: filter.Table{Schema: res.Schema, Name: res.Name}, + FileMeta: SourceFileMeta{Path: path, Type: res.Type, Compression: res.Compression, SortKey: res.Key, FileSize: size, RealSize: size}, + } - logger.Debug("file route result", zap.String("schema", res.Schema), - zap.String("table", res.Name), zap.Stringer("type", res.Type)) + if s.loader.shouldSkip(&info.TableName) { + logger.Debug("[filter] ignoring table file") return nil - }) + } - return errors.Trace(err) + switch res.Type { + case SourceTypeSchemaSchema: + s.dbSchemas = append(s.dbSchemas, info) + case SourceTypeTableSchema: + s.tableSchemas = append(s.tableSchemas, info) + case SourceTypeViewSchema: + s.viewSchemas = append(s.viewSchemas, info) + case SourceTypeSQL, SourceTypeCSV, SourceTypeParquet: + if info.FileMeta.Compression != CompressionNone { + compressRatio, err2 := SampleFileCompressRatio(ctx, info.FileMeta, s.loader.GetStore()) + if err2 != nil { + logger.Error("[loader] fail to calculate data file compress ratio", + zap.String("schema", res.Schema), zap.String("table", res.Name), zap.Stringer("type", res.Type)) + } else { + info.FileMeta.RealSize = int64(compressRatio * float64(info.FileMeta.FileSize)) + } + } + s.tableDatas = append(s.tableDatas, info) + } + + logger.Debug("file route result", zap.String("schema", res.Schema), + zap.String("table", res.Name), zap.Stringer("type", res.Type)) + + return nil } func (l *MDLoader) shouldSkip(table *filter.Table) bool { @@ -488,6 +551,13 @@ func (s *mdLoaderSetup) route() error { knownDBNames[targetDB] = newInfo } arr[i].TableName = filter.Table{Schema: targetDB, Name: targetTable} + extendCols, extendVals := r.FetchExtendColumn(rawDB, rawTable, s.sourceID) + if len(extendCols) > 0 { + arr[i].FileMeta.ExtendData = ExtendColumnData{ + Columns: extendCols, + Values: extendVals, + } + } } return nil } @@ -593,3 +663,81 @@ func (l *MDLoader) GetDatabases() []*MDDatabaseMeta { func (l *MDLoader) GetStore() storage.ExternalStorage { return l.store } + +func calculateFileBytes(ctx context.Context, + dataFile string, + compressType storage.CompressType, + store storage.ExternalStorage, + offset int64) (tot int, pos int64, err error) { + bytes := make([]byte, sampleCompressedFileSize) + reader, err := store.Open(ctx, dataFile) + if err != nil { + return 0, 0, errors.Trace(err) + } + defer reader.Close() + + compressReader, err := storage.NewLimitedInterceptReader(reader, compressType, offset) + if err != nil { + return 0, 0, errors.Trace(err) + } + + readBytes := func() error { + n, err2 := compressReader.Read(bytes) + if err2 != nil && errors.Cause(err2) != io.EOF && errors.Cause(err) != io.ErrUnexpectedEOF { + return err2 + } + tot += n + return err2 + } + + if offset == 0 { + err = readBytes() + if err != nil && errors.Cause(err) != io.EOF && errors.Cause(err) != io.ErrUnexpectedEOF { + return 0, 0, err + } + pos, err = compressReader.Seek(0, io.SeekCurrent) + if err != nil { + return 0, 0, errors.Trace(err) + } + return tot, pos, nil + } + + for { + err = readBytes() + if err != nil { + break + } + } + if err != nil && errors.Cause(err) != io.EOF && errors.Cause(err) != io.ErrUnexpectedEOF { + return 0, 0, errors.Trace(err) + } + return tot, offset, nil +} + +// SampleFileCompressRatio samples the compress ratio of the compressed file. +func SampleFileCompressRatio(ctx context.Context, fileMeta SourceFileMeta, store storage.ExternalStorage) (float64, error) { + if fileMeta.Compression == CompressionNone { + return 1, nil + } + compressType, err := ToStorageCompressType(fileMeta.Compression) + if err != nil { + return 0, err + } + // We use the following method to sample the compress ratio of the first few bytes of the file. + // 1. read first time aiming to find a valid compressed file offset. If we continue read now, the compress reader will + // request more data from file reader buffer them in its memory. We can't compute an accurate compress ratio. + // 2. we use a second reading and limit the file reader only read n bytes(n is the valid position we find in the first reading). + // Then we read all the data out from the compress reader. The data length m we read out is the uncompressed data length. + // Use m/n to compute the compress ratio. + // read first time, aims to find a valid end pos in compressed file + _, pos, err := calculateFileBytes(ctx, fileMeta.Path, compressType, store, 0) + if err != nil { + return 0, err + } + // read second time, original reader ends at first time's valid pos, compute sample data compress ratio + tot, pos, err := calculateFileBytes(ctx, fileMeta.Path, compressType, store, pos) + if err != nil { + return 0, err + } + return float64(tot) / float64(pos), nil +} diff --git a/br/pkg/lightning/mydump/loader_test.go b/br/pkg/lightning/mydump/loader_test.go index 81a10fb078efc..58236d7b626f5 100644 --- a/br/pkg/lightning/mydump/loader_test.go +++ b/br/pkg/lightning/mydump/loader_test.go @@ -15,6 +15,8 @@ package mydump_test import ( + "bytes" + "compress/gzip" "context" "fmt" "os" @@ -990,3 +992,97 @@ func TestMaxScanFilesOption(t *testing.T) { tbl = dbMeta.Tables[0] require.Equal(t, maxScanFilesCount-2, len(tbl.DataFiles)) } + +func TestExternalDataRoutes(t *testing.T) { + s := newTestMydumpLoaderSuite(t) + + s.touch(t, "test_1-schema-create.sql") + s.touch(t, "test_1.t1-schema.sql") + s.touch(t, "test_1.t1.sql") + s.touch(t, "test_2-schema-create.sql") + s.touch(t, "test_2.t2-schema.sql") + s.touch(t, "test_2.t2.sql") + s.touch(t, "test_3-schema-create.sql") + s.touch(t, "test_3.t1-schema.sql") + s.touch(t, "test_3.t1.sql") + s.touch(t, "test_3.t3-schema.sql") + s.touch(t, "test_3.t3.sql") + + s.cfg.Mydumper.SourceID = "mysql-01" + s.cfg.Routes = []*router.TableRule{ + { + TableExtractor: &router.TableExtractor{ + TargetColumn: "c_table", + TableRegexp: "t(.*)", + }, + SchemaExtractor: &router.SchemaExtractor{ + TargetColumn: "c_schema", + SchemaRegexp: "test_(.*)", + }, + SourceExtractor: &router.SourceExtractor{ + TargetColumn: "c_source", + SourceRegexp: "mysql-(.*)", + }, + SchemaPattern: "test_*", + TablePattern: "t*", + TargetSchema: "test", + TargetTable: "t", + }, + } + + mdl, err := md.NewMyDumpLoader(context.Background(), s.cfg) + + require.NoError(t, err) + var database *md.MDDatabaseMeta + for _, db := range mdl.GetDatabases() { + if db.Name == "test" { + require.Nil(t, database) + database = db + } + } + require.NotNil(t, database) + require.Len(t, database.Tables, 1) + require.Len(t, database.Tables[0].DataFiles, 4) + expectExtendCols := []string{"c_table", "c_schema", "c_source"} + expectedExtendVals := [][]string{ + {"1", "1", "01"}, + {"2", "2", "01"}, + {"1", "3", "01"}, + {"3", "3", "01"}, + } + for i, fileInfo := range database.Tables[0].DataFiles { + require.Equal(t, expectExtendCols, fileInfo.FileMeta.ExtendData.Columns) + require.Equal(t, expectedExtendVals[i], fileInfo.FileMeta.ExtendData.Values) + } +} + +func TestSampleFileCompressRatio(t *testing.T) { + s := newTestMydumpLoaderSuite(t) + store, err := storage.NewLocalStorage(s.sourceDir) + require.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + byteArray := make([]byte, 0, 4096) + bf := bytes.NewBuffer(byteArray) + compressWriter := gzip.NewWriter(bf) + csvData := []byte("aaaa\n") + for i := 0; i < 1000; i++ { + _, err = compressWriter.Write(csvData) + require.NoError(t, err) + } + err = compressWriter.Flush() + require.NoError(t, err) + + fileName := "test_1.t1.csv.gz" + err = store.WriteFile(ctx, fileName, bf.Bytes()) + require.NoError(t, err) + + ratio, err := md.SampleFileCompressRatio(ctx, md.SourceFileMeta{ + Path: fileName, + Compression: md.CompressionGZ, + }, store) + require.NoError(t, err) + require.InDelta(t, ratio, 5000.0/float64(bf.Len()), 1e-5) +} diff --git a/br/pkg/lightning/mydump/main_test.go b/br/pkg/lightning/mydump/main_test.go index f2672cd1bbc89..d4a29a47175d3 100644 --- a/br/pkg/lightning/mydump/main_test.go +++ b/br/pkg/lightning/mydump/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("github.com/klauspost/compress/zstd.(*blockDec).startDecoder"), } diff --git a/br/pkg/lightning/mydump/parquet_parser.go b/br/pkg/lightning/mydump/parquet_parser.go index 4c8318aa3efb5..a1b612903c5e8 100644 --- a/br/pkg/lightning/mydump/parquet_parser.go +++ b/br/pkg/lightning/mydump/parquet_parser.go @@ -351,6 +351,12 @@ func (pp *ParquetParser) SetPos(pos int64, rowID int64) error { return nil } +// RealPos implements the Parser interface. +// For parquet it's equal to Pos(). +func (pp *ParquetParser) RealPos() (int64, error) { + return pp.curStart + int64(pp.curIndex), nil +} + // Close closes the parquet file of the parser. // It implements the Parser interface. func (pp *ParquetParser) Close() error { @@ -458,7 +464,7 @@ func setDatumByString(d *types.Datum, v string, meta *parquet.SchemaElement) { ts = ts.UTC() v = ts.Format(utcTimeLayout) } - d.SetString(v, "") + d.SetString(v, "utf8mb4_bin") } func binaryToDecimalStr(rawBytes []byte, scale int) string { @@ -515,20 +521,20 @@ func setDatumByInt(d *types.Datum, v int64, meta *parquet.SchemaElement) error { } val := fmt.Sprintf("%0*d", minLen, v) dotIndex := len(val) - int(*meta.Scale) - d.SetString(val[:dotIndex]+"."+val[dotIndex:], "") + d.SetString(val[:dotIndex]+"."+val[dotIndex:], "utf8mb4_bin") case logicalType.DATE != nil: dateStr := time.Unix(v*86400, 0).Format("2006-01-02") - d.SetString(dateStr, "") + d.SetString(dateStr, "utf8mb4_bin") case logicalType.TIMESTAMP != nil: // convert all timestamp types (datetime/timestamp) to string timeStr := formatTime(v, logicalType.TIMESTAMP.Unit, timeLayout, utcTimeLayout, logicalType.TIMESTAMP.IsAdjustedToUTC) - d.SetString(timeStr, "") + d.SetString(timeStr, "utf8mb4_bin") case logicalType.TIME != nil: // convert all timestamp types (datetime/timestamp) to string timeStr := formatTime(v, logicalType.TIME.Unit, "15:04:05.999999", "15:04:05.999999Z", logicalType.TIME.IsAdjustedToUTC) - d.SetString(timeStr, "") + d.SetString(timeStr, "utf8mb4_bin") default: d.SetInt64(v) } @@ -579,6 +585,12 @@ func (pp *ParquetParser) SetLogger(l log.Logger) { pp.logger = l } +// SetRowID sets the rowID in a parquet file when we start a compressed file. +// It implements the Parser interface. +func (pp *ParquetParser) SetRowID(rowID int64) { + pp.lastRow.RowID = rowID +} + func jdToTime(jd int32, nsec int64) time.Time { sec := int64(jd-jan011970) * secPerDay // it's fine not to check the value of nsec diff --git a/br/pkg/lightning/mydump/parquet_parser_test.go b/br/pkg/lightning/mydump/parquet_parser_test.go index 0475e922f0507..5574ef1dd0ce7 100644 --- a/br/pkg/lightning/mydump/parquet_parser_test.go +++ b/br/pkg/lightning/mydump/parquet_parser_test.go @@ -54,7 +54,7 @@ func TestParquetParser(t *testing.T) { verifyRow := func(i int) { require.Equal(t, int64(i+1), reader.lastRow.RowID) require.Len(t, reader.lastRow.Row, 2) - require.Equal(t, types.NewCollationStringDatum(strconv.Itoa(i), ""), reader.lastRow.Row[0]) + require.Equal(t, types.NewCollationStringDatum(strconv.Itoa(i), "utf8mb4_bin"), reader.lastRow.Row[0]) require.Equal(t, types.NewIntDatum(int64(i)), reader.lastRow.Row[1]) } diff --git a/br/pkg/lightning/mydump/parser.go b/br/pkg/lightning/mydump/parser.go index 1560dd4c14a44..512c3789cfa7f 100644 --- a/br/pkg/lightning/mydump/parser.go +++ b/br/pkg/lightning/mydump/parser.go @@ -94,6 +94,7 @@ type ChunkParser struct { type Chunk struct { Offset int64 EndOffset int64 + RealOffset int64 PrevRowIDMax int64 RowIDMax int64 Columns []string @@ -126,6 +127,7 @@ const ( type Parser interface { Pos() (pos int64, rowID int64) SetPos(pos int64, rowID int64) error + RealPos() (int64, error) Close() error ReadRow() error LastRow() Row @@ -138,6 +140,8 @@ type Parser interface { SetColumns([]string) SetLogger(log.Logger) + + SetRowID(rowID int64) } // NewChunkParser creates a new parser which can read chunks out of a file. @@ -173,7 +177,13 @@ func (parser *blockParser) SetPos(pos int64, rowID int64) error { return nil } +// RealPos gets the read position of current reader. +func (parser *blockParser) RealPos() (int64, error) { + return parser.reader.Seek(0, io.SeekCurrent) +} + // Pos returns the current file offset. +// Attention: for compressed sql/csv files, pos is the position in uncompressed files func (parser *blockParser) Pos() (pos int64, lastRowID int64) { return parser.pos, parser.lastRow.RowID } @@ -205,6 +215,11 @@ func (parser *blockParser) SetLogger(logger log.Logger) { parser.Logger = logger } +// SetRowID changes the reported row ID when we firstly read compressed files. +func (parser *blockParser) SetRowID(rowID int64) { + parser.lastRow.RowID = rowID +} + type token byte const ( @@ -592,3 +607,22 @@ func ReadChunks(parser Parser, minSize int64) ([]Chunk, error) { } } } + +// ReadUntil parses the entire file and splits it into continuous chunks of +// size >= minSize. +func ReadUntil(parser Parser, pos int64) error { + var curOffset int64 + for curOffset < pos { + switch err := parser.ReadRow(); errors.Cause(err) { + case nil: + curOffset, _ = parser.Pos() + + case io.EOF: + return nil + + default: + return errors.Trace(err) + } + } + return nil +} diff --git a/br/pkg/lightning/mydump/reader.go b/br/pkg/lightning/mydump/reader.go index 2988c3675dfa9..4837b35aceab2 100644 --- a/br/pkg/lightning/mydump/reader.go +++ b/br/pkg/lightning/mydump/reader.go @@ -70,6 +70,13 @@ func decodeCharacterSet(data []byte, characterSet string) ([]byte, error) { // ExportStatement exports the SQL statement in the schema file. func ExportStatement(ctx context.Context, store storage.ExternalStorage, sqlFile FileInfo, characterSet string) ([]byte, error) { + if sqlFile.FileMeta.Compression != CompressionNone { + compressType, err := ToStorageCompressType(sqlFile.FileMeta.Compression) + if err != nil { + return nil, errors.Trace(err) + } + store = storage.WithCompression(store, compressType) + } fd, err := store.Open(ctx, sqlFile.FileMeta.Path) if err != nil { return nil, errors.Trace(err) diff --git a/br/pkg/lightning/mydump/reader_test.go b/br/pkg/lightning/mydump/reader_test.go index e7506ea869782..1f67f2c31c43a 100644 --- a/br/pkg/lightning/mydump/reader_test.go +++ b/br/pkg/lightning/mydump/reader_test.go @@ -15,6 +15,7 @@ package mydump_test import ( + "compress/gzip" "context" "errors" "os" @@ -173,3 +174,28 @@ func TestExportStatementHandleNonEOFError(t *testing.T) { _, err := ExportStatement(ctx, mockStorage, f, "auto") require.Contains(t, err.Error(), "read error") } + +func TestExportStatementCompressed(t *testing.T) { + dir := t.TempDir() + file, err := os.Create(filepath.Join(dir, "tidb_lightning_test_reader")) + require.NoError(t, err) + defer os.Remove(file.Name()) + + store, err := storage.NewLocalStorage(dir) + require.NoError(t, err) + + gzipFile := gzip.NewWriter(file) + _, err = gzipFile.Write([]byte("CREATE DATABASE whatever;")) + require.NoError(t, err) + err = gzipFile.Close() + require.NoError(t, err) + stat, err := file.Stat() + require.NoError(t, err) + err = file.Close() + require.NoError(t, err) + + f := FileInfo{FileMeta: SourceFileMeta{Path: stat.Name(), FileSize: stat.Size(), Compression: CompressionGZ}} + data, err := ExportStatement(context.TODO(), store, f, "auto") + require.NoError(t, err) + require.Equal(t, []byte("CREATE DATABASE whatever;"), data) +} diff --git a/br/pkg/lightning/mydump/region.go b/br/pkg/lightning/mydump/region.go index 7e77c9df2a05b..da3b4d0af1a53 100644 --- a/br/pkg/lightning/mydump/region.go +++ b/br/pkg/lightning/mydump/region.go @@ -34,15 +34,21 @@ const ( tableRegionSizeWarningThreshold int64 = 1024 * 1024 * 1024 // the increment ratio of large CSV file size threshold by `region-split-size` largeCSVLowerThresholdRation = 10 + // TableFileSizeINF for compressed size, for lightning 10TB is a relatively big value and will strongly affect efficiency + // It's used to make sure compressed files can be read until EOF. Because we can't get the exact decompressed size of the compressed files. + TableFileSizeINF = 10 * 1024 * tableRegionSizeWarningThreshold + // CompressSizeFactor is used to adjust compressed data size + CompressSizeFactor = 5 ) // TableRegion contains information for a table region during import. type TableRegion struct { EngineID int32 - DB string - Table string - FileMeta SourceFileMeta + DB string + Table string + FileMeta SourceFileMeta + ExtendData ExtendColumnData Chunk Chunk } @@ -170,7 +176,7 @@ func MakeTableRegions( go func() { defer wg.Done() for info := range fileChan { - regions, sizes, err := makeSourceFileRegion(execCtx, meta, info, columns, cfg, ioWorkers, store) + regions, sizes, err := MakeSourceFileRegion(execCtx, meta, info, columns, cfg, ioWorkers, store) select { case resultChan <- fileRegionRes{info: info, regions: regions, sizes: sizes, err: err}: case <-ctx.Done(): @@ -255,7 +261,8 @@ func MakeTableRegions( return filesRegions, nil } -func makeSourceFileRegion( +// MakeSourceFileRegion create a new source file region. +func MakeSourceFileRegion( ctx context.Context, meta *MDTableMeta, fi FileInfo, @@ -283,30 +290,48 @@ func makeSourceFileRegion( // We increase the check threshold by 1/10 of the `max-region-size` because the source file size dumped by tools // like dumpling might be slight exceed the threshold when it is equal `max-region-size`, so we can // avoid split a lot of small chunks. - if isCsvFile && cfg.Mydumper.StrictFormat && dataFileSize > int64(cfg.Mydumper.MaxRegionSize+cfg.Mydumper.MaxRegionSize/largeCSVLowerThresholdRation) { + // If a csv file is compressed, we can't split it now because we can't get the exact size of a row. + if isCsvFile && cfg.Mydumper.StrictFormat && fi.FileMeta.Compression == CompressionNone && + dataFileSize > int64(cfg.Mydumper.MaxRegionSize+cfg.Mydumper.MaxRegionSize/largeCSVLowerThresholdRation) { _, regions, subFileSizes, err := SplitLargeFile(ctx, meta, cfg, fi, divisor, 0, ioWorkers, store) return regions, subFileSizes, err } + fileSize := fi.FileMeta.FileSize + rowIDMax := fileSize / divisor + // for compressed files, suggest the compress ratio is 1% to calculate the rowIDMax. + // set fileSize to INF to make sure compressed files can be read until EOF. Because we can't get the exact size of the compressed files. + if fi.FileMeta.Compression != CompressionNone { + // RealSize the estimated file size. There are some cases that the first few bytes of this compressed file + // has smaller compress ratio than the whole compressed file. So we still need to multiply this factor to + // make sure the rowIDMax computation is correct. + rowIDMax = fi.FileMeta.RealSize * CompressSizeFactor / divisor + fileSize = TableFileSizeINF + } tableRegion := &TableRegion{ DB: meta.DB, Table: meta.Name, FileMeta: fi.FileMeta, Chunk: Chunk{ Offset: 0, - EndOffset: fi.FileMeta.FileSize, + EndOffset: fileSize, + RealOffset: 0, PrevRowIDMax: 0, - RowIDMax: fi.FileMeta.FileSize / divisor, + RowIDMax: rowIDMax, }, } - if tableRegion.Size() > tableRegionSizeWarningThreshold { + regionSize := tableRegion.Size() + if fi.FileMeta.Compression != CompressionNone { + regionSize = fi.FileMeta.RealSize + } + if regionSize > tableRegionSizeWarningThreshold { log.FromContext(ctx).Warn( "file is too big to be processed efficiently; we suggest splitting it at 256 MB each", zap.String("file", fi.FileMeta.Path), - zap.Int64("size", dataFileSize)) + zap.Int64("size", regionSize)) } - return []*TableRegion{tableRegion}, []float64{float64(fi.FileMeta.FileSize)}, nil + return []*TableRegion{tableRegion}, []float64{float64(fi.FileMeta.RealSize)}, nil } // because parquet files can't seek efficiently, there is no benefit in split. diff --git a/br/pkg/lightning/mydump/region_test.go b/br/pkg/lightning/mydump/region_test.go index 5c4bc1c7734b5..5aa2b3a85b752 100644 --- a/br/pkg/lightning/mydump/region_test.go +++ b/br/pkg/lightning/mydump/region_test.go @@ -164,6 +164,117 @@ func TestAllocateEngineIDs(t *testing.T) { }) } +func TestMakeSourceFileRegion(t *testing.T) { + meta := &MDTableMeta{ + DB: "csv", + Name: "large_csv_file", + } + cfg := &config.Config{ + Mydumper: config.MydumperRuntime{ + ReadBlockSize: config.ReadBlockSize, + MaxRegionSize: 1, + CSV: config.CSVConfig{ + Separator: ",", + Delimiter: "", + Header: true, + TrimLastSep: false, + NotNull: false, + Null: "NULL", + BackslashEscape: true, + }, + StrictFormat: true, + Filter: []string{"*.*"}, + }, + } + filePath := "./csv/split_large_file.csv" + dataFileInfo, err := os.Stat(filePath) + require.NoError(t, err) + fileSize := dataFileInfo.Size() + fileInfo := FileInfo{FileMeta: SourceFileMeta{Path: filePath, Type: SourceTypeCSV, FileSize: fileSize}} + colCnt := 3 + columns := []string{"a", "b", "c"} + + ctx := context.Background() + ioWorkers := worker.NewPool(ctx, 4, "io") + store, err := storage.NewLocalStorage(".") + assert.NoError(t, err) + + fileInfo.FileMeta.Compression = CompressionNone + regions, _, err := MakeSourceFileRegion(ctx, meta, fileInfo, colCnt, cfg, ioWorkers, store) + assert.NoError(t, err) + offsets := [][]int64{{6, 12}, {12, 18}, {18, 24}, {24, 30}} + assert.Len(t, regions, len(offsets)) + for i := range offsets { + assert.Equal(t, offsets[i][0], regions[i].Chunk.Offset) + assert.Equal(t, offsets[i][1], regions[i].Chunk.EndOffset) + assert.Equal(t, columns, regions[i].Chunk.Columns) + } + + // test - gzip compression + fileInfo.FileMeta.Compression = CompressionGZ + regions, _, err = MakeSourceFileRegion(ctx, meta, fileInfo, colCnt, cfg, ioWorkers, store) + assert.NoError(t, err) + assert.Len(t, regions, 1) + assert.Equal(t, int64(0), regions[0].Chunk.Offset) + assert.Equal(t, TableFileSizeINF, regions[0].Chunk.EndOffset) + assert.Len(t, regions[0].Chunk.Columns, 0) +} + +func TestCompressedMakeSourceFileRegion(t *testing.T) { + meta := &MDTableMeta{ + DB: "csv", + Name: "large_csv_file", + } + cfg := &config.Config{ + Mydumper: config.MydumperRuntime{ + ReadBlockSize: config.ReadBlockSize, + MaxRegionSize: 1, + CSV: config.CSVConfig{ + Separator: ",", + Delimiter: "", + Header: true, + TrimLastSep: false, + NotNull: false, + Null: "NULL", + BackslashEscape: true, + }, + StrictFormat: true, + Filter: []string{"*.*"}, + }, + } + filePath := "./csv/split_large_file.csv.zst" + dataFileInfo, err := os.Stat(filePath) + require.NoError(t, err) + fileSize := dataFileInfo.Size() + + fileInfo := FileInfo{FileMeta: SourceFileMeta{ + Path: filePath, + Type: SourceTypeCSV, + Compression: CompressionZStd, + FileSize: fileSize, + }} + colCnt := 3 + + ctx := context.Background() + ioWorkers := worker.NewPool(ctx, 4, "io") + store, err := storage.NewLocalStorage(".") + assert.NoError(t, err) + compressRatio, err := SampleFileCompressRatio(ctx, fileInfo.FileMeta, store) + require.NoError(t, err) + fileInfo.FileMeta.RealSize = int64(compressRatio * float64(fileInfo.FileMeta.FileSize)) + + regions, sizes, err := MakeSourceFileRegion(ctx, meta, fileInfo, colCnt, cfg, ioWorkers, store) + assert.NoError(t, err) + assert.Len(t, regions, 1) + assert.Equal(t, int64(0), regions[0].Chunk.Offset) + assert.Equal(t, int64(0), regions[0].Chunk.RealOffset) + assert.Equal(t, TableFileSizeINF, regions[0].Chunk.EndOffset) + rowIDMax := fileInfo.FileMeta.RealSize * CompressSizeFactor / int64(colCnt) + assert.Equal(t, rowIDMax, regions[0].Chunk.RowIDMax) + assert.Len(t, regions[0].Chunk.Columns, 0) + assert.Equal(t, fileInfo.FileMeta.RealSize, int64(sizes[0])) +} + func TestSplitLargeFile(t *testing.T) { meta := &MDTableMeta{ DB: "csv", diff --git a/br/pkg/lightning/mydump/router.go b/br/pkg/lightning/mydump/router.go index 75a9c61a98553..bf0ccba834fe0 100644 --- a/br/pkg/lightning/mydump/router.go +++ b/br/pkg/lightning/mydump/router.go @@ -9,6 +9,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/br/pkg/lightning/config" "github.com/pingcap/tidb/br/pkg/lightning/log" + "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/util/filter" "github.com/pingcap/tidb/util/slice" "go.uber.org/zap" @@ -65,8 +66,28 @@ const ( CompressionZStd // CompressionXZ is the compression type that uses XZ algorithm. CompressionXZ + // CompressionLZO is the compression type that uses LZO algorithm. + CompressionLZO + // CompressionSnappy is the compression type that uses Snappy algorithm. + CompressionSnappy ) +// ToStorageCompressType converts Compression to storage.CompressType. +func ToStorageCompressType(compression Compression) (storage.CompressType, error) { + switch compression { + case CompressionGZ: + return storage.Gzip, nil + case CompressionSnappy: + return storage.Snappy, nil + case CompressionZStd: + return storage.Zstd, nil + case CompressionNone: + return storage.NoCompression, nil + default: + return storage.NoCompression, errors.Errorf("compression %d doesn't have related storage compressType", compression) + } +} + func parseSourceType(t string) (SourceType, error) { switch strings.ToLower(strings.TrimSpace(t)) { case SchemaSchema: @@ -109,14 +130,18 @@ func (s SourceType) String() string { func parseCompressionType(t string) (Compression, error) { switch strings.ToLower(strings.TrimSpace(t)) { - case "gz": + case "gz", "gzip": return CompressionGZ, nil case "lz4": return CompressionLZ4, nil - case "zstd": + case "zstd", "zst": return CompressionZStd, nil case "xz": return CompressionXZ, nil + case "lzo": + return CompressionLZO, nil + case "snappy": + return CompressionSnappy, nil case "": return CompressionNone, nil default: @@ -128,15 +153,17 @@ var expandVariablePattern = regexp.MustCompile(`\$(?:\$|[\pL\p{Nd}_]+|\{[\pL\p{N var defaultFileRouteRules = []*config.FileRouteRule{ // ignore *-schema-trigger.sql, *-schema-post.sql files - {Pattern: `(?i).*(-schema-trigger|-schema-post)\.sql$`, Type: "ignore"}, - // db schema create file pattern, matches files like '{schema}-schema-create.sql' - {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)-schema-create\.sql$`, Schema: "$1", Table: "", Type: SchemaSchema, Unescape: true}, - // table schema create file pattern, matches files like '{schema}.{table}-schema.sql' - {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)\.(.*?)-schema\.sql$`, Schema: "$1", Table: "$2", Type: TableSchema, Unescape: true}, - // view schema create file pattern, matches files like '{schema}.{table}-schema-view.sql' - {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)\.(.*?)-schema-view\.sql$`, Schema: "$1", Table: "$2", Type: ViewSchema, Unescape: true}, - // source file pattern, matches files like '{schema}.{table}.0001.{sql|csv}' - {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)\.(.*?)(?:\.([0-9]+))?\.(sql|csv|parquet)$`, Schema: "$1", Table: "$2", Type: "$4", Key: "$3", Unescape: true}, + {Pattern: `(?i).*(-schema-trigger|-schema-post)\.sql(?:\.(\w*?))?$`, Type: "ignore"}, + // ignore backup files + {Pattern: `(?i).*\.(sql|csv|parquet)(\.(\w+))?\.(bak|BAK)$`, Type: "ignore"}, + // db schema create file pattern, matches files like '{schema}-schema-create.sql[.{compress}]' + {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)-schema-create\.sql(?:\.(\w*?))?$`, Schema: "$1", Table: "", Type: SchemaSchema, Compression: "$2", Unescape: true}, + // table schema create file pattern, matches files like '{schema}.{table}-schema.sql[.{compress}]' + {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)\.(.*?)-schema\.sql(?:\.(\w*?))?$`, Schema: "$1", Table: "$2", Type: TableSchema, Compression: "$3", Unescape: true}, + // view schema create file pattern, matches files like '{schema}.{table}-schema-view.sql[.{compress}]' + {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)\.(.*?)-schema-view\.sql(?:\.(\w*?))?$`, Schema: "$1", Table: "$2", Type: ViewSchema, Compression: "$3", Unescape: true}, + // source file pattern, matches files like '{schema}.{table}.0001.{sql|csv}[.{compress}]' + {Pattern: `(?i)^(?:[^/]*/)*([^/.]+)\.(.*?)(?:\.([0-9]+))?\.(sql|csv|parquet)(?:\.(\w+))?$`, Schema: "$1", Table: "$2", Type: "$4", Key: "$3", Compression: "$5", Unescape: true}, } // FileRouter provides some operations to apply a rule to route file path to target schema/table @@ -176,6 +203,11 @@ func NewFileRouter(cfg []*config.FileRouteRule, logger log.Logger) (FileRouter, return chainRouters(res), nil } +// NewDefaultFileRouter creates a new file router with the default file route rules. +func NewDefaultFileRouter(logger log.Logger) (FileRouter, error) { + return NewFileRouter(defaultFileRouteRules, logger) +} + // RegexRouter is a `FileRouter` implement that apply specific regex pattern to filepath. // if regex pattern match, then each extractors with capture the matched regexp pattern and // set value to target field in `RouteResult` @@ -292,8 +324,8 @@ func (p regexRouterParser) Parse(r *config.FileRouteRule, logger log.Logger) (*R if err != nil { return err } - if compression != CompressionNone { - return errors.New("Currently we don't support restore compressed source file yet") + if result.Type == SourceTypeParquet && compression != CompressionNone { + return errors.Errorf("can't support whole compressed parquet file, should compress parquet files by choosing correct parquet compress writer, path: %s", r.Path) } result.Compression = compression return nil diff --git a/br/pkg/lightning/mydump/router_test.go b/br/pkg/lightning/mydump/router_test.go index 7401027cfbd36..ab97769e30ce8 100644 --- a/br/pkg/lightning/mydump/router_test.go +++ b/br/pkg/lightning/mydump/router_test.go @@ -38,6 +38,42 @@ func TestRouteParser(t *testing.T) { } } +func TestDefaultRouter(t *testing.T) { + r, err := NewFileRouter(defaultFileRouteRules, log.L()) + assert.NoError(t, err) + + inputOutputMap := map[string][]string{ + "a/test-schema-create.sql.bak": nil, + "my_schema.my_table.0001.sql.snappy.BAK": nil, + "a/test-schema-create.sql": {"test", "", "", "", SchemaSchema}, + "test-schema-create.sql.gz": {"test", "", "", "gz", SchemaSchema}, + "c/d/test.t-schema.sql": {"test", "t", "", "", TableSchema}, + "test.t-schema.sql.lzo": {"test", "t", "", "lzo", TableSchema}, + "/bc/dc/test.v1-schema-view.sql": {"test", "v1", "", "", ViewSchema}, + "test.v1-schema-view.sql.snappy": {"test", "v1", "", "snappy", ViewSchema}, + "my_schema.my_table.sql": {"my_schema", "my_table", "", "", "sql"}, + "/test/123/my_schema.my_table.sql.gz": {"my_schema", "my_table", "", "gz", "sql"}, + "my_dir/my_schema.my_table.csv.lzo": {"my_schema", "my_table", "", "lzo", "csv"}, + "my_schema.my_table.0001.sql.snappy": {"my_schema", "my_table", "0001", "snappy", "sql"}, + } + for path, fields := range inputOutputMap { + res, err := r.Route(path) + assert.NoError(t, err) + if len(fields) == 0 { + assert.Equal(t, res.Type, SourceTypeIgnore) + assert.Len(t, res.Schema, 0) + assert.Len(t, res.Name, 0) + continue + } + compress, e := parseCompressionType(fields[3]) + assert.NoError(t, e) + ty, e := parseSourceType(fields[4]) + assert.NoError(t, e) + exp := &RouteResult{filter.Table{Schema: fields[0], Name: fields[1]}, fields[2], compress, ty} + assert.Equal(t, exp, res) + } +} + func TestInvalidRouteRule(t *testing.T) { rule := &config.FileRouteRule{} rules := []*config.FileRouteRule{rule} @@ -112,7 +148,6 @@ func TestSingleRouteRule(t *testing.T) { require.NoError(t, err) require.NotNil(t, r) invalidMatchPaths := []string{ - "my_schema.my_table.sql.gz", "my_schema.my_table.sql.rar", "my_schema.my_table.txt", } @@ -121,6 +156,11 @@ func TestSingleRouteRule(t *testing.T) { assert.Nil(t, res) assert.Error(t, err) } + + res, err := r.Route("my_schema.my_table.sql.gz") + assert.NoError(t, err) + exp := &RouteResult{filter.Table{Schema: "my_schema", Name: "my_table"}, "", CompressionGZ, SourceTypeSQL} + assert.Equal(t, exp, res) } func TestMultiRouteRule(t *testing.T) { @@ -252,3 +292,21 @@ func TestRouteWithPath(t *testing.T) { require.NoError(t, err) require.Nil(t, res) } + +func TestRouteWithCompressedParquet(t *testing.T) { + fileName := "myschema.my_table.000.parquet.gz" + rule := &config.FileRouteRule{ + Pattern: `(?i)^(?:[^/]*/)*([^/.]+)\.(.*?)(?:\.([0-9]+))?\.(sql|csv|parquet)(?:\.(\w+))?$`, + Schema: "$1", + Table: "$2", + Type: "$4", + Key: "$3", + Compression: "$5", + Unescape: true, + } + r := *rule + router, err := NewFileRouter([]*config.FileRouteRule{&r}, log.L()) + require.NoError(t, err) + _, err = router.Route(fileName) + require.Error(t, err) +} diff --git a/br/pkg/lightning/restore/BUILD.bazel b/br/pkg/lightning/restore/BUILD.bazel index fbe316705933e..ef5aeb106585b 100644 --- a/br/pkg/lightning/restore/BUILD.bazel +++ b/br/pkg/lightning/restore/BUILD.bazel @@ -39,6 +39,7 @@ go_library( "//br/pkg/pdutil", "//br/pkg/redact", "//br/pkg/storage", + "//br/pkg/streamhelper", "//br/pkg/utils", "//br/pkg/version", "//br/pkg/version/build", @@ -62,6 +63,8 @@ go_library( "//util/engine", "//util/mathutil", "//util/mock", + "//util/regexpr-router", + "//util/set", "@com_github_coreos_go_semver//semver", "@com_github_docker_go_units//:go-units", "@com_github_go_sql_driver_mysql//:mysql", @@ -75,6 +78,9 @@ go_library( "@com_github_pingcap_tipb//go-tipb", "@com_github_tikv_client_go_v2//oracle", "@com_github_tikv_pd_client//:client", + "@io_etcd_go_etcd_client_v3//:client", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//keepalive", "@org_golang_x_exp//maps", "@org_golang_x_exp//slices", "@org_golang_x_sync//errgroup", @@ -122,6 +128,7 @@ go_test( "//br/pkg/lightning/worker", "//br/pkg/mock", "//br/pkg/storage", + "//br/pkg/streamhelper", "//br/pkg/version/build", "//ddl", "//errno", @@ -140,6 +147,7 @@ go_test( "//util/mock", "//util/promutil", "//util/table-filter", + "//util/table-router", "@com_github_data_dog_go_sqlmock//:go-sqlmock", "@com_github_docker_go_units//:go-units", "@com_github_go_sql_driver_mysql//:mysql", @@ -155,6 +163,8 @@ go_test( "@com_github_tikv_pd_client//:client", "@com_github_xitongsys_parquet_go//writer", "@com_github_xitongsys_parquet_go_source//buffer", + "@io_etcd_go_etcd_client_v3//:client", + "@io_etcd_go_etcd_tests_v3//integration", "@org_uber_go_atomic//:atomic", "@org_uber_go_zap//:zap", ], diff --git a/br/pkg/lightning/restore/check_info.go b/br/pkg/lightning/restore/check_info.go index cc4b3b734ebaa..aab9e5ebacef5 100644 --- a/br/pkg/lightning/restore/check_info.go +++ b/br/pkg/lightning/restore/check_info.go @@ -155,3 +155,10 @@ func (rc *Controller) checkSourceSchema(ctx context.Context) error { } return rc.doPreCheckOnItem(ctx, CheckSourceSchemaValid) } + +func (rc *Controller) checkCDCPiTR(ctx context.Context) error { + if rc.cfg.TikvImporter.Backend == config.BackendTiDB { + return nil + } + return rc.doPreCheckOnItem(ctx, CheckTargetUsingCDCPITR) +} diff --git a/br/pkg/lightning/restore/check_info_test.go b/br/pkg/lightning/restore/check_info_test.go index 3a8a666699164..36903ab93b22c 100644 --- a/br/pkg/lightning/restore/check_info_test.go +++ b/br/pkg/lightning/restore/check_info_test.go @@ -493,11 +493,11 @@ func TestCheckTableEmpty(t *testing.T) { require.NoError(t, err) mock.MatchExpectationsInOrder(false) targetInfoGetter.targetDBGlue = glue.NewExternalTiDBGlue(db, mysql.ModeNone) - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).RowError(0, sql.ErrNoRows)) - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).RowError(0, sql.ErrNoRows)) - mock.ExpectQuery("SELECT 1 FROM `test2`.`tbl1` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test2`.`tbl1` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).RowError(0, sql.ErrNoRows)) rc.checkTemplate = NewSimpleTemplate() err = rc.checkTableEmpty(ctx) @@ -510,13 +510,13 @@ func TestCheckTableEmpty(t *testing.T) { targetInfoGetter.targetDBGlue = glue.NewExternalTiDBGlue(db, mysql.ModeNone) mock.MatchExpectationsInOrder(false) // test auto retry retryable error - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` USE INDEX\\(\\) LIMIT 1"). WillReturnError(&gmysql.MySQLError{Number: errno.ErrPDServerTimeout}) - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).RowError(0, sql.ErrNoRows)) - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).RowError(0, sql.ErrNoRows)) - mock.ExpectQuery("SELECT 1 FROM `test2`.`tbl1` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test2`.`tbl1` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).AddRow(1)) rc.checkTemplate = NewSimpleTemplate() err = rc.checkTableEmpty(ctx) @@ -532,11 +532,11 @@ func TestCheckTableEmpty(t *testing.T) { require.NoError(t, err) targetInfoGetter.targetDBGlue = glue.NewExternalTiDBGlue(db, mysql.ModeNone) mock.MatchExpectationsInOrder(false) - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl1` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).AddRow(1)) - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).RowError(0, sql.ErrNoRows)) - mock.ExpectQuery("SELECT 1 FROM `test2`.`tbl1` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test2`.`tbl1` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).AddRow(1)) rc.checkTemplate = NewSimpleTemplate() err = rc.checkTableEmpty(ctx) @@ -576,7 +576,7 @@ func TestCheckTableEmpty(t *testing.T) { require.NoError(t, err) targetInfoGetter.targetDBGlue = glue.NewExternalTiDBGlue(db, mysql.ModeNone) // only need to check the one that is not in checkpoint - mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test1`.`tbl2` USE INDEX\\(\\) LIMIT 1"). WillReturnRows(sqlmock.NewRows([]string{""}).RowError(0, sql.ErrNoRows)) err = rc.checkTableEmpty(ctx) require.NoError(t, err) diff --git a/br/pkg/lightning/restore/checksum.go b/br/pkg/lightning/restore/checksum.go index 71b02801dc2dc..b30fe14e01fc1 100644 --- a/br/pkg/lightning/restore/checksum.go +++ b/br/pkg/lightning/restore/checksum.go @@ -374,7 +374,7 @@ func newGCTTLManager(pdClient pd.Client) gcTTLManager { func (m *gcTTLManager) addOneJob(ctx context.Context, table string, ts uint64) error { // start gc ttl loop if not started yet. - if m.started.CAS(false, true) { + if m.started.CompareAndSwap(false, true) { m.start(ctx) } m.lock.Lock() diff --git a/br/pkg/lightning/restore/chunk_restore_test.go b/br/pkg/lightning/restore/chunk_restore_test.go index 7a0d0826c6a07..452e82821c9fa 100644 --- a/br/pkg/lightning/restore/chunk_restore_test.go +++ b/br/pkg/lightning/restore/chunk_restore_test.go @@ -15,9 +15,13 @@ package restore import ( + "compress/gzip" "context" + "fmt" + "io" "os" "path/filepath" + "strconv" "sync" "testing" @@ -36,7 +40,14 @@ import ( "github.com/pingcap/tidb/br/pkg/lightning/worker" "github.com/pingcap/tidb/br/pkg/mock" "github.com/pingcap/tidb/br/pkg/storage" + "github.com/pingcap/tidb/ddl" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" + tmock "github.com/pingcap/tidb/util/mock" + filter "github.com/pingcap/tidb/util/table-filter" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) @@ -273,6 +284,65 @@ func (s *chunkRestoreSuite) TestEncodeLoop() { require.Equal(s.T(), s.cr.chunk.Chunk.EndOffset, kvs[0].offset) } +func (s *chunkRestoreSuite) TestEncodeLoopWithExtendData() { + ctx := context.Background() + kvsCh := make(chan []deliveredKVs, 2) + deliverCompleteCh := make(chan deliverResult) + + p := parser.New() + se := tmock.NewContext() + + lastTi := s.tr.tableInfo + defer func() { + s.tr.tableInfo = lastTi + }() + + node, err := p.ParseOneStmt("CREATE TABLE `t1` (`c1` varchar(5) NOT NULL, `c_table` varchar(5), `c_schema` varchar(5), `c_source` varchar(5))", "utf8mb4", "utf8mb4_bin") + require.NoError(s.T(), err) + tableInfo, err := ddl.MockTableInfo(se, node.(*ast.CreateTableStmt), int64(1)) + require.NoError(s.T(), err) + tableInfo.State = model.StatePublic + + schema := "test_1" + tb := "t1" + ti := &checkpoints.TidbTableInfo{ + ID: tableInfo.ID, + DB: schema, + Name: tb, + Core: tableInfo, + } + s.tr.tableInfo = ti + s.cr.chunk.FileMeta.ExtendData = mydump.ExtendColumnData{ + Columns: []string{"c_table", "c_schema", "c_source"}, + Values: []string{"1", "1", "01"}, + } + defer func() { + s.cr.chunk.FileMeta.ExtendData = mydump.ExtendColumnData{} + }() + + kvEncoder, err := kv.NewTableKVEncoder(s.tr.encTable, &kv.SessionOptions{ + SQLMode: s.cfg.TiDB.SQLMode, + Timestamp: 1234567895, + }, nil, log.L()) + require.NoError(s.T(), err) + cfg := config.NewConfig() + rc := &Controller{pauser: DeliverPauser, cfg: cfg} + _, _, err = s.cr.encodeLoop(ctx, kvsCh, s.tr, s.tr.logger, kvEncoder, deliverCompleteCh, rc) + require.NoError(s.T(), err) + require.Len(s.T(), kvsCh, 2) + + kvs := <-kvsCh + require.Len(s.T(), kvs, 1) + require.Equal(s.T(), int64(19), kvs[0].rowID) + require.Equal(s.T(), int64(36), kvs[0].offset) + require.Equal(s.T(), []string{"c1", "c_table", "c_schema", "c_source"}, kvs[0].columns) + + kvs = <-kvsCh + require.Equal(s.T(), 1, len(kvs)) + require.Nil(s.T(), kvs[0].kvs) + require.Equal(s.T(), s.cr.chunk.Chunk.EndOffset, kvs[0].offset) +} + func (s *chunkRestoreSuite) TestEncodeLoopCanceled() { ctx, cancel := context.WithCancel(context.Background()) kvsCh := make(chan []deliveredKVs) @@ -590,3 +660,123 @@ func (s *chunkRestoreSuite) TestRestore() { require.NoError(s.T(), err) require.Len(s.T(), saveCpCh, 2) } + +func TestCompressChunkRestore(t *testing.T) { + // Produce a mock table info + p := parser.New() + p.SetSQLMode(mysql.ModeANSIQuotes) + node, err := p.ParseOneStmt(` + CREATE TABLE "table" ( + a INT, + b INT, + c INT, + KEY (b) + ) +`, "", "") + require.NoError(t, err) + core, err := ddl.BuildTableInfoFromAST(node.(*ast.CreateTableStmt)) + require.NoError(t, err) + core.State = model.StatePublic + + // Write some sample CSV dump + fakeDataDir := t.TempDir() + store, err := storage.NewLocalStorage(fakeDataDir) + require.NoError(t, err) + + fakeDataFiles := make([]mydump.FileInfo, 0) + + csvName := "db.table.1.csv.gz" + file, err := os.Create(filepath.Join(fakeDataDir, csvName)) + require.NoError(t, err) + gzWriter := gzip.NewWriter(file) + + var totalBytes int64 + for i := 0; i < 300; i += 3 { + n, err := gzWriter.Write([]byte(fmt.Sprintf("%d,%d,%d\r\n", i, i+1, i+2))) + require.NoError(t, err) + totalBytes += int64(n) + } + + err = gzWriter.Close() + require.NoError(t, err) + err = file.Close() + require.NoError(t, err) + + fakeDataFiles = append(fakeDataFiles, mydump.FileInfo{ + TableName: filter.Table{Schema: "db", Name: "table"}, + FileMeta: mydump.SourceFileMeta{ + Path: csvName, + Type: mydump.SourceTypeCSV, + Compression: mydump.CompressionGZ, + SortKey: "99", + FileSize: totalBytes, + }, + }) + + chunk := checkpoints.ChunkCheckpoint{ + Key: checkpoints.ChunkCheckpointKey{Path: fakeDataFiles[0].FileMeta.Path, Offset: 0}, + FileMeta: fakeDataFiles[0].FileMeta, + Chunk: mydump.Chunk{ + Offset: 0, + EndOffset: totalBytes, + PrevRowIDMax: 0, + RowIDMax: 100, + }, + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + w := worker.NewPool(ctx, 5, "io") + cfg := config.NewConfig() + cfg.Mydumper.BatchSize = 111 + cfg.App.TableConcurrency = 2 + cfg.Mydumper.CSV.Header = false + + cr, err := newChunkRestore(ctx, 1, cfg, &chunk, w, store, nil) + require.NoError(t, err) + var ( + id, lastID int + offset int64 = 0 + rowID int64 = 0 + ) + for id < 100 { + offset, rowID = cr.parser.Pos() + err = cr.parser.ReadRow() + require.NoError(t, err) + rowData := cr.parser.LastRow().Row + require.Len(t, rowData, 3) + lastID = id + for i := 0; id < 100 && i < 3; i++ { + require.Equal(t, strconv.Itoa(id), rowData[i].GetString()) + id++ + } + } + require.Equal(t, int64(33), rowID) + + // test read starting from compress files' middle + chunk = checkpoints.ChunkCheckpoint{ + Key: checkpoints.ChunkCheckpointKey{Path: fakeDataFiles[0].FileMeta.Path, Offset: offset}, + FileMeta: fakeDataFiles[0].FileMeta, + Chunk: mydump.Chunk{ + Offset: offset, + EndOffset: totalBytes, + PrevRowIDMax: rowID, + RowIDMax: 100, + }, + } + cr, err = newChunkRestore(ctx, 1, cfg, &chunk, w, store, nil) + require.NoError(t, err) + for id = lastID; id < 300; { + err = cr.parser.ReadRow() + require.NoError(t, err) + rowData := cr.parser.LastRow().Row + require.Len(t, rowData, 3) + for i := 0; id < 300 && i < 3; i++ { + require.Equal(t, strconv.Itoa(id), rowData[i].GetString()) + id++ + } + } + _, rowID = cr.parser.Pos() + require.Equal(t, int64(100), rowID) + err = cr.parser.ReadRow() + require.Equal(t, io.EOF, errors.Cause(err)) +} diff --git a/br/pkg/lightning/restore/get_pre_info.go b/br/pkg/lightning/restore/get_pre_info.go index c604b7a5d88b8..4273ff708a89b 100644 --- a/br/pkg/lightning/restore/get_pre_info.go +++ b/br/pkg/lightning/restore/get_pre_info.go @@ -189,7 +189,12 @@ func (g *TargetInfoGetterImpl) IsTableEmpty(ctx context.Context, schemaName stri } var dump int err = exec.QueryRow(ctx, "check table empty", - fmt.Sprintf("SELECT 1 FROM %s LIMIT 1", common.UniqueTable(schemaName, tableName)), + // Here we use the `USE INDEX()` hint to skip fetch the record from index. + // In Lightning, if previous importing is halted half-way, it is possible that + // the data is partially imported, but the index data has not been imported. + // In this situation, if no hint is added, the SQL executor might fetch the record from index, + // which is empty. This will result in missing check. + fmt.Sprintf("SELECT 1 FROM %s USE INDEX() LIMIT 1", common.UniqueTable(schemaName, tableName)), &dump, ) @@ -444,15 +449,7 @@ func (p *PreRestoreInfoGetterImpl) ReadFirstNRowsByTableName(ctx context.Context // ReadFirstNRowsByFileMeta reads the first N rows of an data file. // It implements the PreRestoreInfoGetter interface. func (p *PreRestoreInfoGetterImpl) ReadFirstNRowsByFileMeta(ctx context.Context, dataFileMeta mydump.SourceFileMeta, n int) ([]string, [][]types.Datum, error) { - var ( - reader storage.ReadSeekCloser - err error - ) - if dataFileMeta.Type == mydump.SourceTypeParquet { - reader, err = mydump.OpenParquetReader(ctx, p.srcStorage, dataFileMeta.Path, dataFileMeta.FileSize) - } else { - reader, err = p.srcStorage.Open(ctx, dataFileMeta.Path) - } + reader, err := openReader(ctx, dataFileMeta, p.srcStorage) if err != nil { return nil, nil, errors.Trace(err) } @@ -590,13 +587,7 @@ func (p *PreRestoreInfoGetterImpl) sampleDataFromTable( return resultIndexRatio, isRowOrdered, nil } sampleFile := tableMeta.DataFiles[0].FileMeta - var reader storage.ReadSeekCloser - var err error - if sampleFile.Type == mydump.SourceTypeParquet { - reader, err = mydump.OpenParquetReader(ctx, p.srcStorage, sampleFile.Path, sampleFile.FileSize) - } else { - reader, err = p.srcStorage.Open(ctx, sampleFile.Path) - } + reader, err := openReader(ctx, sampleFile, p.srcStorage) if err != nil { return 0.0, false, errors.Trace(err) } @@ -648,9 +639,12 @@ func (p *PreRestoreInfoGetterImpl) sampleDataFromTable( } initializedColumns := false - var columnPermutation []int - var kvSize uint64 = 0 - var rowSize uint64 = 0 + var ( + columnPermutation []int + kvSize uint64 = 0 + rowSize uint64 = 0 + extendVals []types.Datum + ) rowCount := 0 dataKVs := p.encBuilder.MakeEmptyRows() indexKVs := p.encBuilder.MakeEmptyRows() @@ -665,17 +659,32 @@ outloop: switch errors.Cause(err) { case nil: if !initializedColumns { + ignoreColsMap := igCols.ColumnsMap() if len(columnPermutation) == 0 { columnPermutation, err = createColumnPermutation( columnNames, - igCols.ColumnsMap(), + ignoreColsMap, tableInfo, log.FromContext(ctx)) if err != nil { return 0.0, false, errors.Trace(err) } } + if len(sampleFile.ExtendData.Columns) > 0 { + _, extendVals = filterColumns(columnNames, sampleFile.ExtendData, ignoreColsMap, tableInfo) + } initializedColumns = true + lastRow := parser.LastRow() + lastRowLen := len(lastRow.Row) + extendColsMap := make(map[string]int) + for i, c := range sampleFile.ExtendData.Columns { + extendColsMap[c] = lastRowLen + i + } + for i, col := range tableInfo.Columns { + if p, ok := extendColsMap[col.Name.O]; ok { + columnPermutation[i] = p + } + } } case io.EOF: break outloop @@ -685,6 +694,7 @@ outloop: } lastRow := parser.LastRow() rowCount++ + lastRow.Row = append(lastRow.Row, extendVals...) var dataChecksum, indexChecksum verification.KVChecksum kvs, encodeErr := kvEncoder.Encode(logTask.Logger, lastRow.Row, lastRow.RowID, columnPermutation, sampleFile.Path, offset) diff --git a/br/pkg/lightning/restore/get_pre_info_test.go b/br/pkg/lightning/restore/get_pre_info_test.go index 07195286369e1..71c2810d0b60e 100644 --- a/br/pkg/lightning/restore/get_pre_info_test.go +++ b/br/pkg/lightning/restore/get_pre_info_test.go @@ -14,6 +14,8 @@ package restore import ( + "bytes" + "compress/gzip" "context" "database/sql" "fmt" @@ -24,6 +26,7 @@ import ( mysql_sql_driver "github.com/go-sql-driver/mysql" "github.com/pingcap/errors" "github.com/pingcap/tidb/br/pkg/lightning/config" + "github.com/pingcap/tidb/br/pkg/lightning/mydump" "github.com/pingcap/tidb/br/pkg/lightning/restore/mock" ropts "github.com/pingcap/tidb/br/pkg/lightning/restore/opts" "github.com/pingcap/tidb/errno" @@ -349,15 +352,15 @@ INSERT INTO db01.tbl01 (ival, sval) VALUES (444, 'ddd');` ExpectFirstRowDatums: [][]types.Datum{ { types.NewIntDatum(1), - types.NewCollationStringDatum("name_1", ""), + types.NewCollationStringDatum("name_1", "utf8mb4_bin"), }, { types.NewIntDatum(2), - types.NewCollationStringDatum("name_2", ""), + types.NewCollationStringDatum("name_2", "utf8mb4_bin"), }, { types.NewIntDatum(3), - types.NewCollationStringDatum("name_3", ""), + types.NewCollationStringDatum("name_3", "utf8mb4_bin"), }, }, ExpectColumns: []string{"id", "name"}, @@ -412,6 +415,118 @@ INSERT INTO db01.tbl01 (ival, sval) VALUES (444, 'ddd');` require.Equal(t, theDataInfo.ExpectFirstRowDatums, rowDatums) } +func compressGz(t *testing.T, data []byte) []byte { + t.Helper() + var buf bytes.Buffer + w := gzip.NewWriter(&buf) + _, err := w.Write(data) + require.NoError(t, err) + require.NoError(t, w.Close()) + return buf.Bytes() +} + +func TestGetPreInfoReadCompressedFirstRow(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var ( + testCSVData01 = []byte(`ival,sval +111,"aaa" +222,"bbb" +`) + testSQLData01 = []byte(`INSERT INTO db01.tbl01 (ival, sval) VALUES (333, 'ccc'); +INSERT INTO db01.tbl01 (ival, sval) VALUES (444, 'ddd');`) + ) + + test1CSVCompressed := compressGz(t, testCSVData01) + test1SQLCompressed := compressGz(t, testSQLData01) + + testDataInfos := []struct { + FileName string + Data []byte + FirstN int + CSVConfig *config.CSVConfig + ExpectFirstRowDatums [][]types.Datum + ExpectColumns []string + }{ + { + FileName: "/db01/tbl01/data.001.csv.gz", + Data: test1CSVCompressed, + FirstN: 1, + ExpectFirstRowDatums: [][]types.Datum{ + { + types.NewStringDatum("111"), + types.NewStringDatum("aaa"), + }, + }, + ExpectColumns: []string{"ival", "sval"}, + }, + { + FileName: "/db01/tbl01/data.001.sql.gz", + Data: test1SQLCompressed, + FirstN: 1, + ExpectFirstRowDatums: [][]types.Datum{ + { + types.NewUintDatum(333), + types.NewStringDatum("ccc"), + }, + }, + ExpectColumns: []string{"ival", "sval"}, + }, + } + + tbl01SchemaBytes := []byte("CREATE TABLE db01.tbl01(id INTEGER PRIMARY KEY AUTO_INCREMENT, ival INTEGER, sval VARCHAR(64));") + tbl01SchemaBytesCompressed := compressGz(t, tbl01SchemaBytes) + + tblMockSourceData := &mock.MockTableSourceData{ + DBName: "db01", + TableName: "tbl01", + SchemaFile: &mock.MockSourceFile{ + FileName: "/db01/tbl01/tbl01.schema.sql.gz", + Data: tbl01SchemaBytesCompressed, + }, + DataFiles: []*mock.MockSourceFile{}, + } + for _, testInfo := range testDataInfos { + tblMockSourceData.DataFiles = append(tblMockSourceData.DataFiles, &mock.MockSourceFile{ + FileName: testInfo.FileName, + Data: testInfo.Data, + }) + } + mockDataMap := map[string]*mock.MockDBSourceData{ + "db01": { + Name: "db01", + Tables: map[string]*mock.MockTableSourceData{ + "tbl01": tblMockSourceData, + }, + }, + } + mockSrc, err := mock.NewMockImportSource(mockDataMap) + require.Nil(t, err) + mockTarget := mock.NewMockTargetInfo() + cfg := config.NewConfig() + cfg.TikvImporter.Backend = config.BackendLocal + ig, err := NewPreRestoreInfoGetter(cfg, mockSrc.GetAllDBFileMetas(), mockSrc.GetStorage(), mockTarget, nil, nil) + require.NoError(t, err) + + cfg.Mydumper.CSV.Header = true + tblMeta := mockSrc.GetDBMetaMap()["db01"].Tables[0] + for i, dataFile := range tblMeta.DataFiles { + theDataInfo := testDataInfos[i] + dataFile.FileMeta.Compression = mydump.CompressionGZ + cols, rowDatums, err := ig.ReadFirstNRowsByFileMeta(ctx, dataFile.FileMeta, theDataInfo.FirstN) + require.Nil(t, err) + t.Logf("%v, %v", cols, rowDatums) + require.Equal(t, theDataInfo.ExpectColumns, cols) + require.Equal(t, theDataInfo.ExpectFirstRowDatums, rowDatums) + } + + theDataInfo := testDataInfos[0] + cols, rowDatums, err := ig.ReadFirstNRowsByTableName(ctx, "db01", "tbl01", theDataInfo.FirstN) + require.NoError(t, err) + require.Equal(t, theDataInfo.ExpectColumns, cols) + require.Equal(t, theDataInfo.ExpectFirstRowDatums, rowDatums) +} + func TestGetPreInfoSampleSource(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -497,6 +612,100 @@ func TestGetPreInfoSampleSource(t *testing.T) { } } +func TestGetPreInfoSampleSourceCompressed(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + dataFileName := "/db01/tbl01/tbl01.data.001.csv.gz" + schemaFileData := []byte("CREATE TABLE db01.tbl01 (id INTEGER PRIMARY KEY AUTO_INCREMENT, ival INTEGER, sval VARCHAR(64));") + schemaFileDataCompressed := compressGz(t, schemaFileData) + mockDataMap := map[string]*mock.MockDBSourceData{ + "db01": { + Name: "db01", + Tables: map[string]*mock.MockTableSourceData{ + "tbl01": { + DBName: "db01", + TableName: "tbl01", + SchemaFile: &mock.MockSourceFile{ + FileName: "/db01/tbl01/tbl01.schema.sql.gz", + Data: schemaFileDataCompressed, + }, + DataFiles: []*mock.MockSourceFile{ + { + FileName: dataFileName, + Data: []byte(nil), + }, + }, + }, + }, + }, + } + mockSrc, err := mock.NewMockImportSource(mockDataMap) + require.Nil(t, err) + mockTarget := mock.NewMockTargetInfo() + cfg := config.NewConfig() + cfg.TikvImporter.Backend = config.BackendLocal + ig, err := NewPreRestoreInfoGetter(cfg, mockSrc.GetAllDBFileMetas(), mockSrc.GetStorage(), mockTarget, nil, nil, ropts.WithIgnoreDBNotExist(true)) + require.NoError(t, err) + + mdDBMeta := mockSrc.GetAllDBFileMetas()[0] + mdTblMeta := mdDBMeta.Tables[0] + dbInfos, err := ig.GetAllTableStructures(ctx) + require.NoError(t, err) + + data := [][]byte{ + []byte(`id,ival,sval +1,111,"aaa" +2,222,"bbb" +`), + []byte(`sval,ival,id +"aaa",111,1 +"bbb",222,2 +`), + []byte(`id,ival,sval +2,222,"bbb" +1,111,"aaa" +`), + []byte(`sval,ival,id +"aaa",111,2 +"bbb",222,1 +`), + } + compressedData := make([][]byte, 0, 4) + for _, d := range data { + compressedData = append(compressedData, compressGz(t, d)) + } + + subTests := []struct { + Data []byte + ExpectIsOrdered bool + }{ + { + Data: compressedData[0], + ExpectIsOrdered: true, + }, + { + Data: compressedData[1], + ExpectIsOrdered: true, + }, + { + Data: compressedData[2], + ExpectIsOrdered: false, + }, + { + Data: compressedData[3], + ExpectIsOrdered: false, + }, + } + for _, subTest := range subTests { + require.NoError(t, mockSrc.GetStorage().WriteFile(ctx, dataFileName, subTest.Data)) + sampledIndexRatio, isRowOrderedFromSample, err := ig.sampleDataFromTable(ctx, "db01", mdTblMeta, dbInfos["db01"].Tables["tbl01"].Core, nil, defaultImportantVariables) + require.NoError(t, err) + t.Logf("%v, %v", sampledIndexRatio, isRowOrderedFromSample) + require.Greater(t, sampledIndexRatio, 1.0) + require.Equal(t, subTest.ExpectIsOrdered, isRowOrderedFromSample) + } +} + func TestGetPreInfoEstimateSourceSize(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -553,7 +762,7 @@ func TestGetPreInfoIsTableEmpty(t *testing.T) { require.NoError(t, err) require.Equal(t, lnConfig, targetGetter.cfg) - mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` USE INDEX\\(\\) LIMIT 1"). WillReturnError(&mysql_sql_driver.MySQLError{ Number: errno.ErrNoSuchTable, Message: "Table 'test_db.test_tbl' doesn't exist", @@ -563,7 +772,7 @@ func TestGetPreInfoIsTableEmpty(t *testing.T) { require.NotNil(t, pIsEmpty) require.Equal(t, true, *pIsEmpty) - mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` USE INDEX\\(\\) LIMIT 1"). WillReturnRows( sqlmock.NewRows([]string{"1"}). RowError(0, sql.ErrNoRows), @@ -573,7 +782,7 @@ func TestGetPreInfoIsTableEmpty(t *testing.T) { require.NotNil(t, pIsEmpty) require.Equal(t, true, *pIsEmpty) - mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` USE INDEX\\(\\) LIMIT 1"). WillReturnRows( sqlmock.NewRows([]string{"1"}).AddRow(1), ) @@ -582,7 +791,7 @@ func TestGetPreInfoIsTableEmpty(t *testing.T) { require.NotNil(t, pIsEmpty) require.Equal(t, false, *pIsEmpty) - mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` LIMIT 1"). + mock.ExpectQuery("SELECT 1 FROM `test_db`.`test_tbl` USE INDEX\\(\\) LIMIT 1"). WillReturnError(errors.New("some dummy error")) _, err = targetGetter.IsTableEmpty(ctx, "test_db", "test_tbl") require.Error(t, err) diff --git a/br/pkg/lightning/restore/meta_manager.go b/br/pkg/lightning/restore/meta_manager.go index 659a33c579ef0..2d9875ad56960 100644 --- a/br/pkg/lightning/restore/meta_manager.go +++ b/br/pkg/lightning/restore/meta_manager.go @@ -1186,9 +1186,12 @@ func getGlobalAutoIDAlloc(store kv.Storage, dbID int64, tblInfo *model.TableInfo return nil, errors.New("internal error: dbID should not be 0") } - // We don't need the cache here because we allocate all IDs at once. - // The argument for CustomAutoIncCacheOption is the cache step. step 1 means no cache. - noCache := autoid.CustomAutoIncCacheOption(1) + // We don't need autoid cache here because we allocate all IDs at once. + // The argument for CustomAutoIncCacheOption is the cache step. Step 1 means no cache, + // but step 1 will enable an experimental feature, so we use step 2 here. + // + // See https://github.com/pingcap/tidb/issues/38442 for more details. + noCache := autoid.CustomAutoIncCacheOption(2) tblVer := autoid.AllocOptionTableInfoVersion(tblInfo.Version) hasRowID := common.TableHasAutoRowID(tblInfo) diff --git a/br/pkg/lightning/restore/mock/mock.go b/br/pkg/lightning/restore/mock/mock.go index f43e6c022673e..24e287f11c5f0 100644 --- a/br/pkg/lightning/restore/mock/mock.go +++ b/br/pkg/lightning/restore/mock/mock.go @@ -77,14 +77,19 @@ func NewMockImportSource(dbSrcDataMap map[string]*MockDBSourceData) (*MockImport tblMeta := mydump.NewMDTableMeta("binary") tblMeta.DB = dbName tblMeta.Name = tblName + compression := mydump.CompressionNone + if strings.HasSuffix(tblData.SchemaFile.FileName, ".gz") { + compression = mydump.CompressionGZ + } tblMeta.SchemaFile = mydump.FileInfo{ TableName: filter.Table{ Schema: dbName, Name: tblName, }, FileMeta: mydump.SourceFileMeta{ - Path: tblData.SchemaFile.FileName, - Type: mydump.SourceTypeTableSchema, + Path: tblData.SchemaFile.FileName, + Type: mydump.SourceTypeTableSchema, + Compression: compression, }, } tblMeta.DataFiles = []mydump.FileInfo{} @@ -106,14 +111,20 @@ func NewMockImportSource(dbSrcDataMap map[string]*MockDBSourceData) (*MockImport FileMeta: mydump.SourceFileMeta{ Path: tblDataFile.FileName, FileSize: int64(fileSize), + RealSize: int64(fileSize), }, } + fileName := tblDataFile.FileName + if strings.HasSuffix(fileName, ".gz") { + fileName = strings.TrimSuffix(tblDataFile.FileName, ".gz") + fileInfo.FileMeta.Compression = mydump.CompressionGZ + } switch { - case strings.HasSuffix(tblDataFile.FileName, ".csv"): + case strings.HasSuffix(fileName, ".csv"): fileInfo.FileMeta.Type = mydump.SourceTypeCSV - case strings.HasSuffix(tblDataFile.FileName, ".sql"): + case strings.HasSuffix(fileName, ".sql"): fileInfo.FileMeta.Type = mydump.SourceTypeSQL - case strings.HasSuffix(tblDataFile.FileName, ".parquet"): + case strings.HasSuffix(fileName, ".parquet"): fileInfo.FileMeta.Type = mydump.SourceTypeParquet default: return nil, errors.Errorf("unsupported file type: %s", tblDataFile.FileName) diff --git a/br/pkg/lightning/restore/precheck.go b/br/pkg/lightning/restore/precheck.go index 7dc578053492d..f078fe50f473c 100644 --- a/br/pkg/lightning/restore/precheck.go +++ b/br/pkg/lightning/restore/precheck.go @@ -25,6 +25,7 @@ const ( CheckTargetClusterVersion CheckItemID = "CHECK_TARGET_CLUSTER_VERSION" CheckLocalDiskPlacement CheckItemID = "CHECK_LOCAL_DISK_PLACEMENT" CheckLocalTempKVDir CheckItemID = "CHECK_LOCAL_TEMP_KV_DIR" + CheckTargetUsingCDCPITR CheckItemID = "CHECK_TARGET_USING_CDC_PITR" ) type CheckResult struct { @@ -138,7 +139,9 @@ func (b *PrecheckItemBuilder) BuildPrecheckItem(checkID CheckItemID) (PrecheckIt case CheckLocalDiskPlacement: return NewLocalDiskPlacementCheckItem(b.cfg), nil case CheckLocalTempKVDir: - return NewLocalTempKVDirCheckItem(b.cfg, b.preInfoGetter), nil + return NewLocalTempKVDirCheckItem(b.cfg, b.preInfoGetter, b.dbMetas), nil + case CheckTargetUsingCDCPITR: + return NewCDCPITRCheckItem(b.cfg), nil default: return nil, errors.Errorf("unsupported check item: %v", checkID) } diff --git a/br/pkg/lightning/restore/precheck_impl.go b/br/pkg/lightning/restore/precheck_impl.go index 9305b676e0279..f412b101ff08b 100644 --- a/br/pkg/lightning/restore/precheck_impl.go +++ b/br/pkg/lightning/restore/precheck_impl.go @@ -14,6 +14,7 @@ package restore import ( + "bytes" "context" "fmt" "path/filepath" @@ -21,6 +22,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/docker/go-units" "github.com/pingcap/errors" @@ -32,6 +34,7 @@ import ( "github.com/pingcap/tidb/br/pkg/lightning/log" "github.com/pingcap/tidb/br/pkg/lightning/mydump" "github.com/pingcap/tidb/br/pkg/storage" + "github.com/pingcap/tidb/br/pkg/streamhelper" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/store/pdtypes" @@ -39,9 +42,13 @@ import ( "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/engine" "github.com/pingcap/tidb/util/mathutil" + "github.com/pingcap/tidb/util/set" + clientv3 "go.etcd.io/etcd/client/v3" "go.uber.org/zap" "golang.org/x/exp/slices" "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" ) type clusterResourceCheckItem struct { @@ -427,7 +434,7 @@ func (ci *largeFileCheckItem) Check(ctx context.Context) (*CheckResult, error) { for _, db := range ci.dbMetas { for _, t := range db.Tables { for _, f := range t.DataFiles { - if f.FileMeta.FileSize > defaultCSVSize { + if f.FileMeta.RealSize > defaultCSVSize { theResult.Message = fmt.Sprintf("large csv: %s file exists and it will slow down import performance", f.FileMeta.Path) theResult.Passed = false } @@ -477,12 +484,14 @@ func (ci *localDiskPlacementCheckItem) Check(ctx context.Context) (*CheckResult, type localTempKVDirCheckItem struct { cfg *config.Config preInfoGetter PreRestoreInfoGetter + dbMetas []*mydump.MDDatabaseMeta } -func NewLocalTempKVDirCheckItem(cfg *config.Config, preInfoGetter PreRestoreInfoGetter) PrecheckItem { +func NewLocalTempKVDirCheckItem(cfg *config.Config, preInfoGetter PreRestoreInfoGetter, dbMetas []*mydump.MDDatabaseMeta) PrecheckItem { return &localTempKVDirCheckItem{ cfg: cfg, preInfoGetter: preInfoGetter, + dbMetas: dbMetas, } } @@ -490,10 +499,28 @@ func (ci *localTempKVDirCheckItem) GetCheckItemID() CheckItemID { return CheckLocalTempKVDir } +func (ci *localTempKVDirCheckItem) hasCompressedFiles() bool { + for _, dbMeta := range ci.dbMetas { + for _, tbMeta := range dbMeta.Tables { + for _, file := range tbMeta.DataFiles { + if file.FileMeta.Compression != mydump.CompressionNone { + return true + } + } + } + } + return false +} + func (ci *localTempKVDirCheckItem) Check(ctx context.Context) (*CheckResult, error) { + severity := Critical + // for cases that have compressed files, the estimated size may not be accurate, set severity to Warn to avoid failure + if ci.hasCompressedFiles() { + severity = Warn + } theResult := &CheckResult{ Item: ci.GetCheckItemID(), - Severity: Critical, + Severity: severity, } storageSize, err := common.GetStorageSize(ci.cfg.TikvImporter.SortedKVDir) if err != nil { @@ -671,6 +698,154 @@ func (ci *checkpointCheckItem) checkpointIsValid(ctx context.Context, tableInfo return msgs, nil } +// CDCPITRCheckItem check downstream has enabled CDC or PiTR. It's exposed to let +// caller override the Instruction message. +type CDCPITRCheckItem struct { + cfg *config.Config + Instruction string + // used in test + etcdCli *clientv3.Client +} + +// NewCDCPITRCheckItem creates a checker to check downstream has enabled CDC or PiTR. +func NewCDCPITRCheckItem(cfg *config.Config) PrecheckItem { + return &CDCPITRCheckItem{ + cfg: cfg, + Instruction: "local backend is not compatible with them. Please switch to tidb backend then try again.", + } +} + +// GetCheckItemID implements PrecheckItem interface. +func (ci *CDCPITRCheckItem) GetCheckItemID() CheckItemID { + return CheckTargetUsingCDCPITR +} + +func dialEtcdWithCfg(ctx context.Context, cfg *config.Config) (*clientv3.Client, error) { + cfg2, err := cfg.ToTLS() + if err != nil { + return nil, err + } + tlsConfig := cfg2.TLSConfig() + + return clientv3.New(clientv3.Config{ + TLS: tlsConfig, + Endpoints: []string{cfg.TiDB.PdAddr}, + AutoSyncInterval: 30 * time.Second, + DialTimeout: 5 * time.Second, + DialOptions: []grpc.DialOption{ + grpc.WithKeepaliveParams(keepalive.ClientParameters{ + Time: 10 * time.Second, + Timeout: 3 * time.Second, + PermitWithoutStream: false, + }), + grpc.WithBlock(), + grpc.WithReturnConnectionError(), + }, + Context: ctx, + }) +} + +// Check implements PrecheckItem interface. +func (ci *CDCPITRCheckItem) Check(ctx context.Context) (*CheckResult, error) { + theResult := &CheckResult{ + Item: ci.GetCheckItemID(), + Severity: Critical, + } + + if ci.cfg.TikvImporter.Backend != config.BackendLocal { + theResult.Passed = true + theResult.Message = "TiDB Lightning is not using local backend, skip this check" + return theResult, nil + } + + if ci.etcdCli == nil { + var err error + ci.etcdCli, err = dialEtcdWithCfg(ctx, ci.cfg) + if err != nil { + return nil, errors.Trace(err) + } + //nolint: errcheck + defer ci.etcdCli.Close() + } + + errorMsg := make([]string, 0, 2) + + pitrCli := streamhelper.NewMetaDataClient(ci.etcdCli) + tasks, err := pitrCli.GetAllTasks(ctx) + if err != nil { + return nil, errors.Trace(err) + } + if len(tasks) > 0 { + names := make([]string, 0, len(tasks)) + for _, task := range tasks { + names = append(names, task.Info.GetName()) + } + errorMsg = append(errorMsg, fmt.Sprintf("found PiTR log streaming task(s): %v,", names)) + } + + // check etcd KV of CDC >= v6.2 + cdcPrefix := "/tidb/cdc/" + capturePath := []byte("/__cdc_meta__/capture/") + nameSet := make(map[string][]string, 1) + resp, err := ci.etcdCli.Get(ctx, cdcPrefix, clientv3.WithPrefix(), clientv3.WithKeysOnly()) + if err != nil { + return nil, errors.Trace(err) + } + for _, kv := range resp.Kvs { + // example: /tidb/cdc//__cdc_meta__/capture/ + k := kv.Key[len(cdcPrefix):] + clusterID, captureID, found := bytes.Cut(k, capturePath) + if found { + nameSet[string(clusterID)] = append(nameSet[string(clusterID)], string(captureID)) + } + } + if len(nameSet) == 0 { + // check etcd KV of CDC <= v6.1 + cdcPrefixV61 := "/tidb/cdc/capture/" + resp, err = ci.etcdCli.Get(ctx, cdcPrefixV61, clientv3.WithPrefix(), clientv3.WithKeysOnly()) + if err != nil { + return nil, errors.Trace(err) + } + for _, kv := range resp.Kvs { + // example: /tidb/cdc/capture/ + k := kv.Key[len(cdcPrefixV61):] + if len(k) == 0 { + continue + } + nameSet[""] = append(nameSet[""], string(k)) + } + } + + if len(nameSet) > 0 { + var captureMsgBuf strings.Builder + captureMsgBuf.WriteString("found CDC capture(s): ") + isFirst := true + for clusterID, captureIDs := range nameSet { + if !isFirst { + captureMsgBuf.WriteString(", ") + } + isFirst = false + captureMsgBuf.WriteString("clusterID: ") + captureMsgBuf.WriteString(clusterID) + captureMsgBuf.WriteString(" captureID(s): ") + captureMsgBuf.WriteString(fmt.Sprintf("%v", captureIDs)) + } + captureMsgBuf.WriteString(",") + errorMsg = append(errorMsg, captureMsgBuf.String()) + } + + if len(errorMsg) > 0 { + errorMsg = append(errorMsg, ci.Instruction) + theResult.Passed = false + theResult.Message = strings.Join(errorMsg, "\n") + } else { + theResult.Passed = true + theResult.Message = "no CDC or PiTR task found" + } + + return theResult, nil +} + type schemaCheckItem struct { cfg *config.Config preInfoGetter PreRestoreInfoGetter @@ -749,15 +924,73 @@ func (ci *schemaCheckItem) SchemaIsValid(ctx context.Context, tableInfo *mydump. } igCols := igCol.ColumnsMap() + fullExtendColsSet := make(set.StringSet) + for _, fileInfo := range tableInfo.DataFiles { + for _, col := range fileInfo.FileMeta.ExtendData.Columns { + if _, ok = igCols[col]; ok { + msgs = append(msgs, fmt.Sprintf("extend column %s is also assigned in ignore-column for table `%s`.`%s`, "+ + "please keep only either one of them", col, tableInfo.DB, tableInfo.Name)) + } + fullExtendColsSet.Insert(col) + } + } + if len(msgs) > 0 { + return msgs, nil + } + colCountFromTiDB := len(info.Core.Columns) + if len(fullExtendColsSet) > 0 { + log.FromContext(ctx).Info("check extend column count through data files", zap.String("db", tableInfo.DB), + zap.String("table", tableInfo.Name)) + igColCnt := 0 + for _, col := range info.Core.Columns { + if _, ok = igCols[col.Name.L]; ok { + igColCnt++ + } + } + for _, f := range tableInfo.DataFiles { + cols, previewRows, err := ci.preInfoGetter.ReadFirstNRowsByFileMeta(ctx, f.FileMeta, 1) + if err != nil { + return nil, errors.Trace(err) + } + if len(cols) > 0 { + colsSet := set.NewStringSet(cols...) + for _, extendCol := range f.FileMeta.ExtendData.Columns { + if colsSet.Exist(strings.ToLower(extendCol)) { + msgs = append(msgs, fmt.Sprintf("extend column %s is contained in table `%s`.`%s`'s header, "+ + "please remove this column in data or remove this extend rule", extendCol, tableInfo.DB, tableInfo.Name)) + } + } + } else if len(previewRows) > 0 && len(previewRows[0])+len(f.FileMeta.ExtendData.Columns) > colCountFromTiDB+igColCnt { + msgs = append(msgs, fmt.Sprintf("row count %d adding with extend column length %d is larger than columnCount %d plus ignore column count %d for table `%s`.`%s`, "+ + "please make sure your source data don't have extend columns and target schema has all of them", len(previewRows[0]), len(f.FileMeta.ExtendData.Columns), colCountFromTiDB, igColCnt, tableInfo.DB, tableInfo.Name)) + } + } + } + if len(msgs) > 0 { + return msgs, nil + } + core := info.Core defaultCols := make(map[string]struct{}) for _, col := range core.Columns { - if hasDefault(col) || (info.Core.ContainsAutoRandomBits() && mysql.HasPriKeyFlag(col.GetFlag())) { + // we can extend column the same with columns with default values + if _, isExtendCol := fullExtendColsSet[col.Name.O]; isExtendCol || hasDefault(col) || (info.Core.ContainsAutoRandomBits() && mysql.HasPriKeyFlag(col.GetFlag())) { // this column has default value or it's auto random id, so we can ignore it defaultCols[col.Name.L] = struct{}{} } + delete(fullExtendColsSet, col.Name.O) } + if len(fullExtendColsSet) > 0 { + extendCols := make([]string, 0, len(fullExtendColsSet)) + for col := range fullExtendColsSet { + extendCols = append(extendCols, col) + } + msgs = append(msgs, fmt.Sprintf("extend column [%s] don't exist in target table `%s`.`%s` schema, "+ + "please add these extend columns manually in downstream database/schema file", strings.Join(extendCols, ","), tableInfo.DB, tableInfo.Name)) + return msgs, nil + } + // tidb_rowid have a default value. defaultCols[model.ExtraHandleName.String()] = struct{}{} diff --git a/br/pkg/lightning/restore/precheck_impl_test.go b/br/pkg/lightning/restore/precheck_impl_test.go index 88f3cf8f9a30b..7842bd1fd75e7 100644 --- a/br/pkg/lightning/restore/precheck_impl_test.go +++ b/br/pkg/lightning/restore/precheck_impl_test.go @@ -24,7 +24,11 @@ import ( "github.com/pingcap/tidb/br/pkg/lightning/log" "github.com/pingcap/tidb/br/pkg/lightning/restore/mock" ropts "github.com/pingcap/tidb/br/pkg/lightning/restore/opts" + "github.com/pingcap/tidb/br/pkg/storage" + "github.com/pingcap/tidb/br/pkg/streamhelper" "github.com/stretchr/testify/suite" + clientv3 "go.etcd.io/etcd/client/v3" + "go.etcd.io/etcd/tests/v3/integration" ) type precheckImplSuite struct { @@ -377,7 +381,7 @@ func (s *precheckImplSuite) TestLocalTempKVDirCheckBasic() { defer cancel() s.cfg.TikvImporter.SortedKVDir = "/tmp/" - ci = NewLocalTempKVDirCheckItem(s.cfg, s.preInfoGetter) + ci = NewLocalTempKVDirCheckItem(s.cfg, s.preInfoGetter, s.mockSrc.GetAllDBFileMetas()) s.Require().Equal(CheckLocalTempKVDir, ci.GetCheckItemID()) result, err = ci.Check(ctx) s.Require().NoError(err) @@ -396,7 +400,7 @@ func (s *precheckImplSuite) TestLocalTempKVDirCheckBasic() { }, ) s.Require().NoError(s.setMockImportData(testMockSrcData)) - ci = NewLocalTempKVDirCheckItem(s.cfg, s.preInfoGetter) + ci = NewLocalTempKVDirCheckItem(s.cfg, s.preInfoGetter, s.mockSrc.GetAllDBFileMetas()) s.Require().Equal(CheckLocalTempKVDir, ci.GetCheckItemID()) result, err = ci.Check(ctx) s.Require().NoError(err) @@ -581,3 +585,86 @@ func (s *precheckImplSuite) TestTableEmptyCheckBasic() { s.T().Logf("check result message: %s", result.Message) s.Require().False(result.Passed) } + +func (s *precheckImplSuite) TestCDCPITRCheckItem() { + integration.BeforeTestExternal(s.T()) + testEtcdCluster := integration.NewClusterV3(s.T(), &integration.ClusterConfig{Size: 1}) + defer testEtcdCluster.Terminate(s.T()) + + ctx := context.Background() + cfg := &config.Config{ + TikvImporter: config.TikvImporter{ + Backend: config.BackendLocal, + }, + } + ci := NewCDCPITRCheckItem(cfg) + checker := ci.(*CDCPITRCheckItem) + checker.etcdCli = testEtcdCluster.RandClient() + result, err := ci.Check(ctx) + s.Require().NoError(err) + s.Require().NotNil(result) + s.Require().Equal(ci.GetCheckItemID(), result.Item) + s.Require().Equal(Critical, result.Severity) + s.Require().True(result.Passed) + s.Require().Equal("no CDC or PiTR task found", result.Message) + + cli := testEtcdCluster.RandClient() + brCli := streamhelper.NewMetaDataClient(cli) + backend, _ := storage.ParseBackend("noop://", nil) + taskInfo, err := streamhelper.NewTaskInfo("br_name"). + FromTS(1). + UntilTS(1000). + WithTableFilter("*.*", "!mysql"). + ToStorage(backend). + Check() + s.Require().NoError(err) + err = brCli.PutTask(ctx, *taskInfo) + s.Require().NoError(err) + checkEtcdPut := func(key string) { + _, err := cli.Put(ctx, key, "") + s.Require().NoError(err) + } + // TiCDC >= v6.2 + checkEtcdPut("/tidb/cdc/default/__cdc_meta__/capture/3ecd5c98-0148-4086-adfd-17641995e71f") + checkEtcdPut("/tidb/cdc/default/__cdc_meta__/meta/meta-version") + checkEtcdPut("/tidb/cdc/default/__cdc_meta__/meta/ticdc-delete-etcd-key-count") + checkEtcdPut("/tidb/cdc/default/__cdc_meta__/owner/22318498f4dd6639") + checkEtcdPut("/tidb/cdc/default/default/changefeed/info/test") + checkEtcdPut("/tidb/cdc/default/default/changefeed/info/test-1") + checkEtcdPut("/tidb/cdc/default/default/changefeed/status/test") + checkEtcdPut("/tidb/cdc/default/default/changefeed/status/test-1") + checkEtcdPut("/tidb/cdc/default/default/task/position/3ecd5c98-0148-4086-adfd-17641995e71f/test-1") + checkEtcdPut("/tidb/cdc/default/default/upstream/7168358383033671922") + + result, err = ci.Check(ctx) + s.Require().NoError(err) + s.Require().False(result.Passed) + s.Require().Equal("found PiTR log streaming task(s): [br_name],\n"+ + "found CDC capture(s): clusterID: default captureID(s): [3ecd5c98-0148-4086-adfd-17641995e71f],\n"+ + "local backend is not compatible with them. Please switch to tidb backend then try again.", + result.Message) + + _, err = cli.Delete(ctx, "/tidb/cdc/", clientv3.WithPrefix()) + s.Require().NoError(err) + + // TiCDC <= v6.1 + checkEtcdPut("/tidb/cdc/capture/f14cb04d-5ba1-410e-a59b-ccd796920e9d") + checkEtcdPut("/tidb/cdc/changefeed/info/test") + checkEtcdPut("/tidb/cdc/job/test") + checkEtcdPut("/tidb/cdc/owner/223184ad80a88b0b") + checkEtcdPut("/tidb/cdc/task/position/f14cb04d-5ba1-410e-a59b-ccd796920e9d/test") + + result, err = ci.Check(ctx) + s.Require().NoError(err) + s.Require().False(result.Passed) + s.Require().Equal("found PiTR log streaming task(s): [br_name],\n"+ + "found CDC capture(s): clusterID: captureID(s): [f14cb04d-5ba1-410e-a59b-ccd796920e9d],\n"+ + "local backend is not compatible with them. Please switch to tidb backend then try again.", + result.Message) + + checker.cfg.TikvImporter.Backend = config.BackendTiDB + result, err = ci.Check(ctx) + s.Require().NoError(err) + s.Require().True(result.Passed) + s.Require().Equal("TiDB Lightning is not using local backend, skip this check", result.Message) +} diff --git a/br/pkg/lightning/restore/restore.go b/br/pkg/lightning/restore/restore.go index ba8faac2996a3..543eddc3435fd 100644 --- a/br/pkg/lightning/restore/restore.go +++ b/br/pkg/lightning/restore/restore.go @@ -21,6 +21,7 @@ import ( "io" "math" "os" + "path/filepath" "strings" "sync" "time" @@ -57,8 +58,11 @@ import ( "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/store/driver" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/mathutil" + regexprrouter "github.com/pingcap/tidb/util/regexpr-router" + "github.com/pingcap/tidb/util/set" pd "github.com/tikv/pd/client" "go.uber.org/atomic" "go.uber.org/multierr" @@ -223,12 +227,21 @@ type Controller struct { diskQuotaState atomic.Int32 compactState atomic.Int32 status *LightningStatus + dupIndicator *atomic.Bool preInfoGetter PreRestoreInfoGetter precheckItemBuilder *PrecheckItemBuilder } +// LightningStatus provides the finished bytes and total bytes of the current task. +// It should keep the value after restart from checkpoint. +// When it is tidb backend, FinishedFileSize can be counted after chunk data is +// restored to tidb. When it is local backend it's counted after whole engine is +// imported. +// TotalFileSize may be an estimated value, so when the task is finished, it may +// not equal to FinishedFileSize. type LightningStatus struct { + backend string FinishedFileSize atomic.Int64 TotalFileSize atomic.Int64 } @@ -251,6 +264,8 @@ type ControllerParam struct { CheckpointStorage storage.ExternalStorage // when CheckpointStorage is not nil, save file checkpoint to it with this name CheckpointName string + // DupIndicator can expose the duplicate detection result to the caller + DupIndicator *atomic.Bool } func NewRestoreController( @@ -349,6 +364,7 @@ func NewRestoreControllerWithPauser( default: return nil, common.ErrUnknownBackend.GenWithStackByArgs(cfg.TikvImporter.Backend) } + p.Status.backend = cfg.TikvImporter.Backend var metaBuilder metaMgrBuilder isSSTImport := cfg.TikvImporter.Backend == config.BackendLocal @@ -417,6 +433,7 @@ func NewRestoreControllerWithPauser( errorMgr: errorMgr, status: p.Status, taskMgr: nil, + dupIndicator: p.DupIndicator, preInfoGetter: preInfoGetter, precheckItemBuilder: preCheckBuilder, @@ -921,7 +938,7 @@ func (rc *Controller) estimateChunkCountIntoMetrics(ctx context.Context) error { if _, ok := fileChunks[c.Key.Path]; !ok { fileChunks[c.Key.Path] = 0.0 } - remainChunkCnt := float64(c.Chunk.EndOffset-c.Chunk.Offset) / float64(c.Chunk.EndOffset-c.Key.Offset) + remainChunkCnt := float64(c.UnfinishedSize()) / float64(c.TotalSize()) fileChunks[c.Key.Path] += remainChunkCnt } } @@ -936,7 +953,8 @@ func (rc *Controller) estimateChunkCountIntoMetrics(ctx context.Context) error { } if fileMeta.FileMeta.Type == mydump.SourceTypeCSV { cfg := rc.cfg.Mydumper - if fileMeta.FileMeta.FileSize > int64(cfg.MaxRegionSize) && cfg.StrictFormat && !cfg.CSV.Header { + if fileMeta.FileMeta.FileSize > int64(cfg.MaxRegionSize) && cfg.StrictFormat && + !cfg.CSV.Header && fileMeta.FileMeta.Compression == mydump.CompressionNone { estimatedChunkCount += math.Round(float64(fileMeta.FileMeta.FileSize) / float64(cfg.MaxRegionSize)) } else { estimatedChunkCount++ @@ -1602,7 +1620,7 @@ func (rc *Controller) restoreTables(ctx context.Context) (finalErr error) { } else { for _, eng := range cp.Engines { for _, chunk := range eng.Chunks { - totalDataSizeToRestore += chunk.Chunk.EndOffset - chunk.Chunk.Offset + totalDataSizeToRestore += chunk.UnfinishedSize() } } } @@ -1657,6 +1675,53 @@ func (rc *Controller) restoreTables(ctx context.Context) (finalErr error) { return nil } +func addExtendDataForCheckpoint( + ctx context.Context, + cfg *config.Config, + cp *checkpoints.TableCheckpoint, +) error { + if len(cfg.Routes) == 0 { + return nil + } + hasExtractor := false + for _, route := range cfg.Routes { + hasExtractor = hasExtractor || route.TableExtractor != nil || route.SchemaExtractor != nil || route.SourceExtractor != nil + if hasExtractor { + break + } + } + if !hasExtractor { + return nil + } + + // Use default file router directly because fileRouter and router are not compatible + fileRouter, err := mydump.NewDefaultFileRouter(log.FromContext(ctx)) + if err != nil { + return err + } + var router *regexprrouter.RouteTable + router, err = regexprrouter.NewRegExprRouter(cfg.Mydumper.CaseSensitive, cfg.Routes) + if err != nil { + return err + } + for _, engine := range cp.Engines { + for _, chunk := range engine.Chunks { + _, file := filepath.Split(chunk.FileMeta.Path) + var res *mydump.RouteResult + res, err = fileRouter.Route(file) + if err != nil { + return err + } + extendCols, extendData := router.FetchExtendColumn(res.Schema, res.Name, cfg.Mydumper.SourceID) + chunk.FileMeta.ExtendData = mydump.ExtendColumnData{ + Columns: extendCols, + Values: extendData, + } + } + } + return nil +} + func (tr *TableRestore) restoreTable( ctx context.Context, rc *Controller, @@ -1676,6 +1741,10 @@ func (tr *TableRestore) restoreTable( zap.Int("enginesCnt", len(cp.Engines)), zap.Int("filesCnt", cp.CountChunks()), ) + err := addExtendDataForCheckpoint(ctx, rc.cfg, cp) + if err != nil { + return false, errors.Trace(err) + } } else if cp.Status < checkpoints.CheckpointStatusAllWritten { if err := tr.populateChunks(ctx, rc, cp); err != nil { return false, errors.Trace(err) @@ -1777,7 +1846,7 @@ func (rc *Controller) fullCompact(ctx context.Context) error { // wait until any existing level-1 compact to complete first. task := log.FromContext(ctx).Begin(zap.InfoLevel, "wait for completion of existing level 1 compaction") - for !rc.compactState.CAS(compactStateIdle, compactStateDoing) { + for !rc.compactState.CompareAndSwap(compactStateIdle, compactStateDoing) { time.Sleep(100 * time.Millisecond) } task.End(zap.ErrorLevel, nil) @@ -1837,7 +1906,7 @@ func (rc *Controller) switchTiKVMode(ctx context.Context, mode sstpb.SwitchMode) } func (rc *Controller) enforceDiskQuota(ctx context.Context) { - if !rc.diskQuotaState.CAS(diskQuotaStateIdle, diskQuotaStateChecking) { + if !rc.diskQuotaState.CompareAndSwap(diskQuotaStateIdle, diskQuotaStateChecking) { // do not run multiple the disk quota check / import simultaneously. // (we execute the lock check in background to avoid blocking the cron thread) return @@ -2072,6 +2141,10 @@ func (rc *Controller) preCheckRequirements(ctx context.Context) error { return common.ErrCheckClusterRegion.Wrap(err).GenWithStackByArgs() } } + // even if checkpoint exists, we still need to make sure CDC/PiTR task is not running. + if err := rc.checkCDCPiTR(ctx); err != nil { + return common.ErrCheckCDCPiTR.Wrap(err).GenWithStackByArgs() + } } } @@ -2135,13 +2208,7 @@ func newChunkRestore( ) (*chunkRestore, error) { blockBufSize := int64(cfg.Mydumper.ReadBlockSize) - var reader storage.ReadSeekCloser - var err error - if chunk.FileMeta.Type == mydump.SourceTypeParquet { - reader, err = mydump.OpenParquetReader(ctx, store, chunk.FileMeta.Path, chunk.FileMeta.FileSize) - } else { - reader, err = store.Open(ctx, chunk.FileMeta.Path) - } + reader, err := openReader(ctx, chunk.FileMeta, store) if err != nil { return nil, errors.Trace(err) } @@ -2170,8 +2237,15 @@ func newChunkRestore( panic(fmt.Sprintf("file '%s' with unknown source type '%s'", chunk.Key.Path, chunk.FileMeta.Type.String())) } - if err = parser.SetPos(chunk.Chunk.Offset, chunk.Chunk.PrevRowIDMax); err != nil { - return nil, errors.Trace(err) + if chunk.FileMeta.Compression == mydump.CompressionNone { + if err = parser.SetPos(chunk.Chunk.Offset, chunk.Chunk.PrevRowIDMax); err != nil { + return nil, errors.Trace(err) + } + } else { + if err = mydump.ReadUntil(parser, chunk.Chunk.Offset); err != nil { + return nil, errors.Trace(err) + } + parser.SetRowID(chunk.Chunk.PrevRowIDMax) } if len(chunk.ColumnPermutation) > 0 { parser.SetColumns(getColumnNames(tableInfo.Core, chunk.ColumnPermutation)) @@ -2226,6 +2300,8 @@ type deliveredKVs struct { columns []string offset int64 rowID int64 + + realOffset int64 // indicates file reader's current position, only used for compressed files } type deliverResult struct { @@ -2254,6 +2330,8 @@ func (cr *chunkRestore) deliverLoop( dataSynced := true hasMoreKVs := true + var startRealOffset, currRealOffset int64 // save to 0 at first + for hasMoreKVs { var dataChecksum, indexChecksum verify.KVChecksum var columns []string @@ -2262,6 +2340,8 @@ func (cr *chunkRestore) deliverLoop( // chunk checkpoint should stay the same startOffset := cr.chunk.Chunk.Offset currOffset := startOffset + startRealOffset = cr.chunk.Chunk.RealOffset + currRealOffset = startRealOffset rowID := cr.chunk.Chunk.PrevRowIDMax populate: @@ -2276,12 +2356,14 @@ func (cr *chunkRestore) deliverLoop( if p.kvs == nil { // This is the last message. currOffset = p.offset + currRealOffset = p.realOffset hasMoreKVs = false break populate } p.kvs.ClassifyAndAppend(&dataKVs, &dataChecksum, &indexKVs, &indexChecksum) columns = p.columns currOffset = p.offset + currRealOffset = p.realOffset rowID = p.rowID } case <-ctx.Done(): @@ -2348,6 +2430,7 @@ func (cr *chunkRestore) deliverLoop( cr.chunk.Checksum.Add(&dataChecksum) cr.chunk.Checksum.Add(&indexChecksum) cr.chunk.Chunk.Offset = currOffset + cr.chunk.Chunk.RealOffset = currRealOffset cr.chunk.Chunk.PrevRowIDMax = rowID if m, ok := metric.FromContext(ctx); ok { @@ -2355,11 +2438,21 @@ func (cr *chunkRestore) deliverLoop( // comes from chunk.Chunk.Offset. so it shouldn't happen that currOffset - startOffset < 0. // but we met it one time, but cannot reproduce it now, we add this check to make code more robust // TODO: reproduce and find the root cause and fix it completely - if currOffset >= startOffset { - m.BytesCounter.WithLabelValues(metric.BytesStateRestored).Add(float64(currOffset - startOffset)) + var lowOffset, highOffset int64 + if cr.chunk.FileMeta.Compression != mydump.CompressionNone { + lowOffset, highOffset = startRealOffset, currRealOffset + } else { + lowOffset, highOffset = startOffset, currOffset + } + delta := highOffset - lowOffset + if delta >= 0 { + m.BytesCounter.WithLabelValues(metric.BytesStateRestored).Add(float64(delta)) + if rc.status != nil && rc.status.backend == config.BackendTiDB { + rc.status.FinishedFileSize.Add(delta) + } } else { - deliverLogger.Warn("offset go back", zap.Int64("curr", currOffset), - zap.Int64("start", startOffset)) + deliverLogger.Warn("offset go back", zap.Int64("curr", highOffset), + zap.Int64("start", lowOffset)) } } @@ -2369,6 +2462,11 @@ func (cr *chunkRestore) deliverLoop( } failpoint.Inject("SlowDownWriteRows", func() { deliverLogger.Warn("Slowed down write rows") + finished := rc.status.FinishedFileSize.Load() + total := rc.status.TotalFileSize.Load() + deliverLogger.Warn("PrintStatus Failpoint", + zap.Int64("finished", finished), + zap.Int64("total", total)) }) failpoint.Inject("FailAfterWriteRows", nil) // TODO: for local backend, we may save checkpoint more frequently, e.g. after written @@ -2431,6 +2529,52 @@ func saveCheckpoint(rc *Controller, t *TableRestore, engineID int32, chunk *chec } } +// filterColumns filter columns and extend columns. +// It accepts: +// - columnsNames, header in the data files; +// - extendData, extendData fetched through data file name, that is to say, table info; +// - ignoreColsMap, columns to be ignored when we import; +// - tableInfo, tableInfo of the target table; +// It returns: +// - filteredColumns, columns of the original data to import. +// - extendValueDatums, extended Data to import. +// The data we import will use filteredColumns as columns, use (parser.LastRow+extendValueDatums) as data +// ColumnPermutation will be modified to make sure the correspondence relationship is correct. +// if len(columnsNames) > 0, it means users has specified each field definition, we can just use users +func filterColumns(columnNames []string, extendData mydump.ExtendColumnData, ignoreColsMap map[string]struct{}, tableInfo *model.TableInfo) ([]string, []types.Datum) { + extendCols, extendVals := extendData.Columns, extendData.Values + extendColsSet := set.NewStringSet(extendCols...) + filteredColumns := make([]string, 0, len(columnNames)) + if len(columnNames) > 0 { + if len(ignoreColsMap) > 0 { + for _, c := range columnNames { + _, ok := ignoreColsMap[c] + if !ok { + filteredColumns = append(filteredColumns, c) + } + } + } else { + filteredColumns = columnNames + } + } else if len(ignoreColsMap) > 0 || len(extendCols) > 0 { + // init column names by table schema + // after filtered out some columns, we must explicitly set the columns for TiDB backend + for _, col := range tableInfo.Columns { + _, ok := ignoreColsMap[col.Name.L] + // ignore all extend row values specified by users + if !col.Hidden && !ok && !extendColsSet.Exist(col.Name.O) { + filteredColumns = append(filteredColumns, col.Name.O) + } + } + } + extendValueDatums := make([]types.Datum, 0) + filteredColumns = append(filteredColumns, extendCols...) + for _, extendVal := range extendVals { + extendValueDatums = append(extendValueDatums, types.NewStringDatum(extendVal)) + } + return filteredColumns, extendValueDatums +} + //nolint:nakedret // TODO: refactor func (cr *chunkRestore) encodeLoop( ctx context.Context, @@ -2467,7 +2611,10 @@ func (cr *chunkRestore) encodeLoop( // WARN: this might be not correct when different SQL statements contains different fields, // but since ColumnPermutation also depends on the hypothesis that the columns in one source file is the same // so this should be ok. - var filteredColumns []string + var ( + filteredColumns []string + extendVals []types.Datum + ) ignoreColumns, err1 := rc.cfg.Mydumper.IgnoreColumns.GetIgnoreColumns(t.dbInfo.Name, t.tableInfo.Core.Name.O, rc.cfg.Mydumper.CaseSensitive) if err1 != nil { err = err1 @@ -2486,14 +2633,22 @@ func (cr *chunkRestore) encodeLoop( canDeliver := false kvPacket := make([]deliveredKVs, 0, maxKvPairsCnt) curOffset := offset - var newOffset, rowID int64 + var newOffset, rowID, realOffset int64 var kvSize uint64 + var realOffsetErr error outLoop: for !canDeliver { readDurStart := time.Now() err = cr.parser.ReadRow() columnNames := cr.parser.Columns() newOffset, rowID = cr.parser.Pos() + if cr.chunk.FileMeta.Compression != mydump.CompressionNone { + realOffset, realOffsetErr = cr.parser.RealPos() + if realOffsetErr != nil { + logger.Warn("fail to get data engine RealPos, progress may not be accurate", + log.ShortError(realOffsetErr), zap.String("file", cr.chunk.FileMeta.Path)) + } + } switch errors.Cause(err) { case nil: @@ -2504,23 +2659,19 @@ func (cr *chunkRestore) encodeLoop( } } filteredColumns = columnNames - if ignoreColumns != nil && len(ignoreColumns.Columns) > 0 { - filteredColumns = make([]string, 0, len(columnNames)) - ignoreColsMap := ignoreColumns.ColumnsMap() - if len(columnNames) > 0 { - for _, c := range columnNames { - if _, ok := ignoreColsMap[c]; !ok { - filteredColumns = append(filteredColumns, c) - } - } - } else { - // init column names by table schema - // after filtered out some columns, we must explicitly set the columns for TiDB backend - for _, col := range t.tableInfo.Core.Columns { - if _, ok := ignoreColsMap[col.Name.L]; !col.Hidden && !ok { - filteredColumns = append(filteredColumns, col.Name.O) - } - } + ignoreColsMap := ignoreColumns.ColumnsMap() + if len(ignoreColsMap) > 0 || len(cr.chunk.FileMeta.ExtendData.Columns) > 0 { + filteredColumns, extendVals = filterColumns(columnNames, cr.chunk.FileMeta.ExtendData, ignoreColsMap, t.tableInfo.Core) + } + lastRow := cr.parser.LastRow() + lastRowLen := len(lastRow.Row) + extendColsMap := make(map[string]int) + for i, c := range cr.chunk.FileMeta.ExtendData.Columns { + extendColsMap[c] = lastRowLen + i + } + for i, col := range t.tableInfo.Core.Columns { + if p, ok := extendColsMap[col.Name.O]; ok { + cr.chunk.ColumnPermutation[i] = p } } initializedColumns = true @@ -2535,6 +2686,7 @@ func (cr *chunkRestore) encodeLoop( readDur += time.Since(readDurStart) encodeDurStart := time.Now() lastRow := cr.parser.LastRow() + lastRow.Row = append(lastRow.Row, extendVals...) // sql -> kv kvs, encodeErr := kvEncoder.Encode(logger, lastRow.Row, lastRow.RowID, cr.chunk.ColumnPermutation, cr.chunk.Key.Path, curOffset) encodeDur += time.Since(encodeDurStart) @@ -2558,7 +2710,8 @@ func (cr *chunkRestore) encodeLoop( continue } - kvPacket = append(kvPacket, deliveredKVs{kvs: kvs, columns: filteredColumns, offset: newOffset, rowID: rowID}) + kvPacket = append(kvPacket, deliveredKVs{kvs: kvs, columns: filteredColumns, offset: newOffset, + rowID: rowID, realOffset: realOffset}) kvSize += kvs.Size() failpoint.Inject("mock-kv-size", func(val failpoint.Value) { kvSize += uint64(val.(int)) @@ -2590,7 +2743,7 @@ func (cr *chunkRestore) encodeLoop( } } - err = send([]deliveredKVs{{offset: cr.chunk.Chunk.EndOffset}}) + err = send([]deliveredKVs{{offset: cr.chunk.Chunk.EndOffset, realOffset: cr.chunk.FileMeta.FileSize}}) return } @@ -2653,3 +2806,20 @@ func (cr *chunkRestore) restore( } return errors.Trace(firstErr(encodeErr, deliverErr)) } + +func openReader(ctx context.Context, fileMeta mydump.SourceFileMeta, store storage.ExternalStorage) ( + reader storage.ReadSeekCloser, err error) { + switch { + case fileMeta.Type == mydump.SourceTypeParquet: + reader, err = mydump.OpenParquetReader(ctx, store, fileMeta.Path, fileMeta.FileSize) + case fileMeta.Compression != mydump.CompressionNone: + compressType, err2 := mydump.ToStorageCompressType(fileMeta.Compression) + if err2 != nil { + return nil, err2 + } + reader, err = storage.WithCompression(store, compressType).Open(ctx, fileMeta.Path) + default: + reader, err = store.Open(ctx, fileMeta.Path) + } + return +} diff --git a/br/pkg/lightning/restore/restore_test.go b/br/pkg/lightning/restore/restore_test.go index 0fb74c068700b..82613b64fe662 100644 --- a/br/pkg/lightning/restore/restore_test.go +++ b/br/pkg/lightning/restore/restore_test.go @@ -36,7 +36,9 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/types" tmock "github.com/pingcap/tidb/util/mock" + router "github.com/pingcap/tidb/util/table-router" "github.com/stretchr/testify/require" ) @@ -260,3 +262,163 @@ func TestPreCheckFailed(t *testing.T) { require.Equal(t, err.Error(), err1.Error()) require.NoError(t, mock.ExpectationsWereMet()) } + +func TestAddExtendDataForCheckpoint(t *testing.T) { + cfg := config.NewConfig() + + cfg.Mydumper.SourceID = "mysql-01" + cfg.Routes = []*router.TableRule{ + { + TableExtractor: &router.TableExtractor{ + TargetColumn: "c_table", + TableRegexp: "t(.*)", + }, + SchemaExtractor: &router.SchemaExtractor{ + TargetColumn: "c_schema", + SchemaRegexp: "test_(.*)", + }, + SourceExtractor: &router.SourceExtractor{ + TargetColumn: "c_source", + SourceRegexp: "mysql-(.*)", + }, + SchemaPattern: "test_*", + TablePattern: "t*", + TargetSchema: "test", + TargetTable: "t", + }, + } + + cp := &checkpoints.TableCheckpoint{ + Engines: map[int32]*checkpoints.EngineCheckpoint{ + -1: { + Status: checkpoints.CheckpointStatusLoaded, + Chunks: []*checkpoints.ChunkCheckpoint{}, + }, + 0: { + Status: checkpoints.CheckpointStatusImported, + Chunks: []*checkpoints.ChunkCheckpoint{{ + FileMeta: mydump.SourceFileMeta{ + Path: "tmp/test_1.t1.000000000.sql", + }, + }, { + FileMeta: mydump.SourceFileMeta{ + Path: "./test/tmp/test_1.t2.000000000.sql", + }, + }, { + FileMeta: mydump.SourceFileMeta{ + Path: "test_2.t3.000000000.sql", + }, + }}, + }, + }, + } + require.NoError(t, addExtendDataForCheckpoint(context.Background(), cfg, cp)) + expectExtendCols := []string{"c_table", "c_schema", "c_source"} + expectedExtendVals := [][]string{ + {"1", "1", "01"}, + {"2", "1", "01"}, + {"3", "2", "01"}, + } + chunks := cp.Engines[0].Chunks + require.Len(t, chunks, 3) + for i, chunk := range chunks { + require.Equal(t, expectExtendCols, chunk.FileMeta.ExtendData.Columns) + require.Equal(t, expectedExtendVals[i], chunk.FileMeta.ExtendData.Values) + } +} + +func TestFilterColumns(t *testing.T) { + p := parser.New() + se := tmock.NewContext() + + testCases := []struct { + columnNames []string + extendData mydump.ExtendColumnData + ignoreColsMap map[string]struct{} + createTableSql string + + expectedFilteredColumns []string + expectedExtendValues []string + }{ + { + []string{"a", "b"}, + mydump.ExtendColumnData{}, + nil, + "CREATE TABLE t (a int primary key, b int)", + []string{"a", "b"}, + []string{}, + }, + { + []string{}, + mydump.ExtendColumnData{}, + nil, + "CREATE TABLE t (a int primary key, b int)", + []string{}, + []string{}, + }, + { + columnNames: []string{"a", "b"}, + extendData: mydump.ExtendColumnData{ + Columns: []string{"c_source", "c_schema", "c_table"}, + Values: []string{"01", "1", "1"}, + }, + createTableSql: "CREATE TABLE t (a int primary key, b int, c_source varchar(11), c_schema varchar(11), c_table varchar(11))", + expectedFilteredColumns: []string{"a", "b", "c_source", "c_schema", "c_table"}, + expectedExtendValues: []string{"01", "1", "1"}, + }, + { + columnNames: []string{}, + extendData: mydump.ExtendColumnData{ + Columns: []string{"c_source", "c_schema", "c_table"}, + Values: []string{"01", "1", "1"}, + }, + createTableSql: "CREATE TABLE t (a int primary key, b int, c_source varchar(11), c_schema varchar(11), c_table varchar(11))", + expectedFilteredColumns: []string{"a", "b", "c_source", "c_schema", "c_table"}, + expectedExtendValues: []string{"01", "1", "1"}, + }, + { + []string{"a", "b"}, + mydump.ExtendColumnData{}, + map[string]struct{}{"a": {}}, + "CREATE TABLE t (a int primary key, b int)", + []string{"b"}, + []string{}, + }, + { + []string{}, + mydump.ExtendColumnData{}, + map[string]struct{}{"a": {}}, + "CREATE TABLE t (a int primary key, b int)", + []string{"b"}, + []string{}, + }, + { + columnNames: []string{"a", "b"}, + extendData: mydump.ExtendColumnData{ + Columns: []string{"c_source", "c_schema", "c_table"}, + Values: []string{"01", "1", "1"}, + }, + ignoreColsMap: map[string]struct{}{"a": {}}, + createTableSql: "CREATE TABLE t (a int primary key, b int, c_source varchar(11), c_schema varchar(11), c_table varchar(11))", + expectedFilteredColumns: []string{"b", "c_source", "c_schema", "c_table"}, + expectedExtendValues: []string{"01", "1", "1"}, + }, + } + for i, tc := range testCases { + t.Logf("test case #%d", i) + node, err := p.ParseOneStmt(tc.createTableSql, "utf8mb4", "utf8mb4_bin") + require.NoError(t, err) + tableInfo, err := ddl.MockTableInfo(se, node.(*ast.CreateTableStmt), int64(i+1)) + require.NoError(t, err) + tableInfo.State = model.StatePublic + + expectedDatums := make([]types.Datum, 0, len(tc.expectedExtendValues)) + for _, expectedValue := range tc.expectedExtendValues { + expectedDatums = append(expectedDatums, types.NewStringDatum(expectedValue)) + } + + filteredColumns, extendDatums := filterColumns(tc.columnNames, tc.extendData, tc.ignoreColsMap, tableInfo) + require.Equal(t, tc.expectedFilteredColumns, filteredColumns) + require.Equal(t, expectedDatums, extendDatums) + } +} diff --git a/br/pkg/lightning/restore/table_restore.go b/br/pkg/lightning/restore/table_restore.go index 11038d62195ea..37ba113c82eed 100644 --- a/br/pkg/lightning/restore/table_restore.go +++ b/br/pkg/lightning/restore/table_restore.go @@ -235,10 +235,12 @@ func (tr *TableRestore) restoreEngines(pCtx context.Context, rc *Controller, cp // data-engines that need to be restore or import. Otherwise, all data-engines should // be finished already. + handleDataEngineThisRun := false idxEngineCfg := &backend.EngineConfig{ TableInfo: tr.tableInfo, } if indexEngineCp.Status < checkpoints.CheckpointStatusClosed { + handleDataEngineThisRun = true indexWorker := rc.indexWorkers.Apply() defer rc.indexWorkers.Recycle(indexWorker) @@ -248,7 +250,7 @@ func (tr *TableRestore) restoreEngines(pCtx context.Context, rc *Controller, cp if !common.TableHasAutoRowID(tr.tableInfo.Core) { idxCnt-- } - threshold := estimateCompactionThreshold(cp, int64(idxCnt)) + threshold := estimateCompactionThreshold(tr.tableMeta.DataFiles, cp, int64(idxCnt)) idxEngineCfg.Local = &backend.LocalEngineConfig{ Compact: threshold > 0, CompactConcurrency: 4, @@ -327,9 +329,9 @@ func (tr *TableRestore) restoreEngines(pCtx context.Context, rc *Controller, cp dataWorker := rc.closedEngineLimit.Apply() defer rc.closedEngineLimit.Recycle(dataWorker) err = tr.importEngine(ctx, dataClosedEngine, rc, eid, ecp) - if rc.status != nil { + if rc.status != nil && rc.status.backend == config.BackendLocal { for _, chunk := range ecp.Chunks { - rc.status.FinishedFileSize.Add(chunk.Chunk.EndOffset - chunk.Key.Offset) + rc.status.FinishedFileSize.Add(chunk.TotalSize()) } } } @@ -339,7 +341,7 @@ func (tr *TableRestore) restoreEngines(pCtx context.Context, rc *Controller, cp }(restoreWorker, engineID, engine) } else { for _, chunk := range engine.Chunks { - rc.status.FinishedFileSize.Add(chunk.Chunk.EndOffset - chunk.Key.Offset) + rc.status.FinishedFileSize.Add(chunk.TotalSize()) } } } @@ -370,11 +372,31 @@ func (tr *TableRestore) restoreEngines(pCtx context.Context, rc *Controller, cp return errors.Trace(restoreErr) } + // if data engine is handled in previous run and we continue importing from checkpoint + if !handleDataEngineThisRun { + for _, engine := range cp.Engines { + for _, chunk := range engine.Chunks { + rc.status.FinishedFileSize.Add(chunk.Chunk.EndOffset - chunk.Key.Offset) + } + } + } + if cp.Status < checkpoints.CheckpointStatusIndexImported { var err error if indexEngineCp.Status < checkpoints.CheckpointStatusImported { + failpoint.Inject("FailBeforeStartImportingIndexEngine", func() { + errMsg := "fail before importing index KV data" + tr.logger.Warn(errMsg) + failpoint.Return(errors.New(errMsg)) + }) err = tr.importKV(ctx, closedIndexEngine, rc, indexEngineID) failpoint.Inject("FailBeforeIndexEngineImported", func() { + finished := rc.status.FinishedFileSize.Load() + total := rc.status.TotalFileSize.Load() + tr.logger.Warn("print lightning status", + zap.Int64("finished", finished), + zap.Int64("total", total), + zap.Bool("equal", finished == total)) panic("forcing failure due to FailBeforeIndexEngineImported") }) } @@ -406,6 +428,11 @@ func (tr *TableRestore) restoreEngine( if err != nil { return closedEngine, errors.Trace(err) } + if rc.status != nil && rc.status.backend == config.BackendTiDB { + for _, chunk := range cp.Chunks { + rc.status.FinishedFileSize.Add(chunk.Chunk.EndOffset - chunk.Key.Offset) + } + } return closedEngine, nil } @@ -475,6 +502,9 @@ func (tr *TableRestore) restoreEngine( // Restore table data for chunkIndex, chunk := range cp.Chunks { + if rc.status != nil && rc.status.backend == config.BackendTiDB { + rc.status.FinishedFileSize.Add(chunk.Chunk.Offset - chunk.Key.Offset) + } if chunk.Chunk.Offset >= chunk.Chunk.EndOffset { continue } @@ -516,7 +546,7 @@ func (tr *TableRestore) restoreEngine( } var remainChunkCnt float64 if chunk.Chunk.Offset < chunk.Chunk.EndOffset { - remainChunkCnt = float64(chunk.Chunk.EndOffset-chunk.Chunk.Offset) / float64(chunk.Chunk.EndOffset-chunk.Key.Offset) + remainChunkCnt = float64(chunk.UnfinishedSize()) / float64(chunk.TotalSize()) if metrics != nil { metrics.ChunkCounter.WithLabelValues(metric.ChunkStatePending).Add(remainChunkCnt) } @@ -591,7 +621,7 @@ func (tr *TableRestore) restoreEngine( totalSQLSize := int64(0) for _, chunk := range cp.Chunks { totalKVSize += chunk.Checksum.SumSize() - totalSQLSize += chunk.Chunk.EndOffset - chunk.Chunk.Offset + totalSQLSize += chunk.UnfinishedSize() } err = chunkErr.Get() @@ -675,7 +705,7 @@ func (tr *TableRestore) importEngine( } // 2. perform a level-1 compact if idling. - if rc.cfg.PostRestore.Level1Compact && rc.compactState.CAS(compactStateIdle, compactStateDoing) { + if rc.cfg.PostRestore.Level1Compact && rc.compactState.CompareAndSwap(compactStateIdle, compactStateDoing) { go func() { // we ignore level-1 compact failure since it is not fatal. // no need log the error, it is done in (*Importer).Compact already. @@ -788,6 +818,11 @@ func (tr *TableRestore) postProcess( } } + if rc.dupIndicator != nil { + tr.logger.Debug("set dupIndicator", zap.Bool("has-duplicate", hasDupe)) + rc.dupIndicator.CompareAndSwap(false, hasDupe) + } + nextStage := checkpoints.CheckpointStatusChecksummed if rc.cfg.PostRestore.Checksum != config.OpLevelOff && !hasDupe && needChecksum { if cp.Checksum.SumKVS() > 0 || baseTotalChecksum.SumKVS() > 0 { @@ -1015,15 +1050,23 @@ func (tr *TableRestore) analyzeTable(ctx context.Context, g glue.SQLExecutor) er // Try to limit the total SST files number under 500. But size compress 32GB SST files cost about 20min, // we set the upper bound to 32GB to avoid too long compression time. // factor is the non-clustered(1 for data engine and number of non-clustered index count for index engine). -func estimateCompactionThreshold(cp *checkpoints.TableCheckpoint, factor int64) int64 { +func estimateCompactionThreshold(files []mydump.FileInfo, cp *checkpoints.TableCheckpoint, factor int64) int64 { totalRawFileSize := int64(0) var lastFile string + fileSizeMap := make(map[string]int64, len(files)) + for _, file := range files { + fileSizeMap[file.FileMeta.Path] = file.FileMeta.RealSize + } + for _, engineCp := range cp.Engines { for _, chunk := range engineCp.Chunks { if chunk.FileMeta.Path == lastFile { continue } - size := chunk.FileMeta.FileSize + size, ok := fileSizeMap[chunk.FileMeta.Path] + if !ok { + size = chunk.FileMeta.FileSize + } if chunk.FileMeta.Type == mydump.SourceTypeParquet { // parquet file is compressed, thus estimates with a factor of 2 size *= 2 diff --git a/br/pkg/lightning/restore/table_restore_test.go b/br/pkg/lightning/restore/table_restore_test.go index fb9f3df8a1ab2..5cfaeabc804d9 100644 --- a/br/pkg/lightning/restore/table_restore_test.go +++ b/br/pkg/lightning/restore/table_restore_test.go @@ -129,6 +129,7 @@ func (s *tableRestoreSuiteBase) setupSuite(t *testing.T) { Type: mydump.SourceTypeSQL, SortKey: strconv.Itoa(i), FileSize: 37, + RealSize: 37, }, }) } @@ -144,6 +145,7 @@ func (s *tableRestoreSuiteBase) setupSuite(t *testing.T) { Type: mydump.SourceTypeCSV, SortKey: "99", FileSize: 14, + RealSize: 14, }, }) @@ -427,7 +429,7 @@ func (s *tableRestoreSuite) TestPopulateChunksCSVHeader() { require.NoError(s.T(), err) fakeDataFiles = append(fakeDataFiles, mydump.FileInfo{ TableName: filter.Table{Schema: "db", Name: "table"}, - FileMeta: mydump.SourceFileMeta{Path: csvName, Type: mydump.SourceTypeCSV, SortKey: fmt.Sprintf("%02d", i), FileSize: int64(len(str))}, + FileMeta: mydump.SourceFileMeta{Path: csvName, Type: mydump.SourceTypeCSV, SortKey: fmt.Sprintf("%02d", i), FileSize: int64(len(str)), RealSize: int64(len(str))}, }) total += len(str) } @@ -1349,6 +1351,7 @@ func (s *tableRestoreSuite) TestCheckHasLargeCSV() { { FileMeta: mydump.SourceFileMeta{ FileSize: 1 * units.TiB, + RealSize: 1 * units.TiB, Path: "/testPath", }, }, @@ -1469,6 +1472,10 @@ func (s *tableRestoreSuite) TestSchemaIsValid() { err = mockStore.WriteFile(ctx, case2File, []byte("\"colA\",\"colB\"\n\"a\",\"b\"")) require.NoError(s.T(), err) + case3File := "db1.table3.csv" + err = mockStore.WriteFile(ctx, case3File, []byte("\"a\",\"b\"")) + require.NoError(s.T(), err) + cases := []struct { ignoreColumns []*config.IgnoreColumns expectMsg string @@ -1830,9 +1837,300 @@ func (s *tableRestoreSuite) TestSchemaIsValid() { }, }, }, + // Case 5: + // table has two datafiles for table. + // ignore column and extended column are overlapped, + // we expect the check failed. + { + []*config.IgnoreColumns{ + { + DB: "db", + Table: "table", + Columns: []string{"colA"}, + }, + }, + "extend column colA is also assigned in ignore-column(.*)", + 1, + true, + map[string]*checkpoints.TidbDBInfo{ + "db": { + Name: "db", + Tables: map[string]*checkpoints.TidbTableInfo{ + "table": { + ID: 1, + DB: "db1", + Name: "table2", + Core: &model.TableInfo{ + Columns: []*model.ColumnInfo{ + { + Name: model.NewCIStr("colA"), + }, + { + Name: model.NewCIStr("colB"), + }, + }, + }, + }, + }, + }, + }, + &mydump.MDTableMeta{ + DB: "db", + Name: "table", + DataFiles: []mydump.FileInfo{ + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case2File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{"colA"}, + Values: []string{"a"}, + }, + }, + }, + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case2File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{}, + Values: []string{}, + }, + }, + }, + }, + }, + }, + // Case 6: + // table has one datafile for table. + // we expect the check failed because csv header contains extend column. + { + nil, + "extend column colA is contained in table(.*)", + 1, + true, + map[string]*checkpoints.TidbDBInfo{ + "db": { + Name: "db", + Tables: map[string]*checkpoints.TidbTableInfo{ + "table": { + ID: 1, + DB: "db1", + Name: "table2", + Core: &model.TableInfo{ + Columns: []*model.ColumnInfo{ + { + Name: model.NewCIStr("colA"), + }, + { + Name: model.NewCIStr("colB"), + }, + }, + }, + }, + }, + }, + }, + &mydump.MDTableMeta{ + DB: "db", + Name: "table", + DataFiles: []mydump.FileInfo{ + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case2File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{"colA"}, + Values: []string{"a"}, + }, + }, + }, + }, + }, + }, + // Case 7: + // table has one datafile for table. + // we expect the check failed because csv data columns plus extend columns is greater than target schema's columns. + { + nil, + "row count 2 adding with extend column length 1 is larger than columnCount 2 plus ignore column count 0 for(.*)", + 1, + false, + map[string]*checkpoints.TidbDBInfo{ + "db": { + Name: "db", + Tables: map[string]*checkpoints.TidbTableInfo{ + "table": { + ID: 1, + DB: "db1", + Name: "table2", + Core: &model.TableInfo{ + Columns: []*model.ColumnInfo{ + { + Name: model.NewCIStr("colA"), + }, + { + Name: model.NewCIStr("colB"), + }, + }, + }, + }, + }, + }, + }, + &mydump.MDTableMeta{ + DB: "db", + Name: "table", + DataFiles: []mydump.FileInfo{ + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case3File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{"colA"}, + Values: []string{"a"}, + }, + }, + }, + }, + }, + }, + // Case 8: + // table has two datafiles for table. + // we expect the check failed because target schema doesn't contain extend column. + { + nil, + "extend column \\[colC\\] don't exist in target table(.*)", + 1, + true, + map[string]*checkpoints.TidbDBInfo{ + "db": { + Name: "db", + Tables: map[string]*checkpoints.TidbTableInfo{ + "table": { + ID: 1, + DB: "db1", + Name: "table2", + Core: &model.TableInfo{ + Columns: []*model.ColumnInfo{ + { + Name: model.NewCIStr("colA"), + }, + { + Name: model.NewCIStr("colB"), + }, + }, + }, + }, + }, + }, + }, + &mydump.MDTableMeta{ + DB: "db", + Name: "table", + DataFiles: []mydump.FileInfo{ + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case2File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{"colC"}, + Values: []string{"a"}, + }, + }, + }, + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case2File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{"colC"}, + Values: []string{"b"}, + }, + }, + }, + }, + }, + }, + // Case 9: + // table has two datafiles and extend data for table. + // we expect the check succeed. + { + []*config.IgnoreColumns{ + { + DB: "db", + Table: "table", + Columns: []string{"colb"}, + }, + }, + "", + 0, + true, + map[string]*checkpoints.TidbDBInfo{ + "db": { + Name: "db", + Tables: map[string]*checkpoints.TidbTableInfo{ + "table": { + ID: 1, + DB: "db1", + Name: "table2", + Core: &model.TableInfo{ + Columns: []*model.ColumnInfo{ + { + Name: model.NewCIStr("colA"), + }, + { + Name: model.NewCIStr("colB"), + DefaultIsExpr: true, + }, + { + Name: model.NewCIStr("colC"), + }, + }, + }, + }, + }, + }, + }, + &mydump.MDTableMeta{ + DB: "db", + Name: "table", + DataFiles: []mydump.FileInfo{ + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case2File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{"colC"}, + Values: []string{"a"}, + }, + }, + }, + { + FileMeta: mydump.SourceFileMeta{ + FileSize: 1 * units.TiB, + Path: case2File, + Type: mydump.SourceTypeCSV, + ExtendData: mydump.ExtendColumnData{ + Columns: []string{"colC"}, + Values: []string{"b"}, + }, + }, + }, + }, + }, + }, } - for _, ca := range cases { + for i, ca := range cases { + s.T().Logf("running testCase: #%d", i+1) cfg := &config.Config{ Mydumper: config.MydumperRuntime{ ReadBlockSize: config.ReadBlockSize, diff --git a/br/pkg/lightning/restore/tidb.go b/br/pkg/lightning/restore/tidb.go index 0e114bc035a56..98c780e65dc98 100644 --- a/br/pkg/lightning/restore/tidb.go +++ b/br/pkg/lightning/restore/tidb.go @@ -66,13 +66,15 @@ type TiDBManager struct { func DBFromConfig(ctx context.Context, dsn config.DBStore) (*sql.DB, error) { param := common.MySQLConnectParam{ - Host: dsn.Host, - Port: dsn.Port, - User: dsn.User, - Password: dsn.Psw, - SQLMode: dsn.StrSQLMode, - MaxAllowedPacket: dsn.MaxAllowedPacket, - TLS: dsn.TLS, + Host: dsn.Host, + Port: dsn.Port, + User: dsn.User, + Password: dsn.Psw, + SQLMode: dsn.StrSQLMode, + MaxAllowedPacket: dsn.MaxAllowedPacket, + TLSConfig: dsn.Security.TLSConfig, + AllowFallbackToPlaintext: dsn.Security.AllowFallbackToPlaintext, + Net: dsn.UUID, } db, err := param.Connect() @@ -93,8 +95,10 @@ func DBFromConfig(ctx context.Context, dsn config.DBStore) (*sql.DB, error) { "tidb_opt_write_row_id": "1", // always set auto-commit to ON "autocommit": "1", - // alway set transaction mode to optimistic + // always set transaction mode to optimistic "tidb_txn_mode": "optimistic", + // disable foreign key checks + "foreign_key_checks": "0", } if dsn.Vars != nil { @@ -141,47 +145,6 @@ func (timgr *TiDBManager) Close() { timgr.db.Close() } -func InitSchema(ctx context.Context, g glue.Glue, database string, tablesSchema map[string]string) error { - logger := log.FromContext(ctx).With(zap.String("db", database)) - sqlExecutor := g.GetSQLExecutor() - - var createDatabase strings.Builder - createDatabase.WriteString("CREATE DATABASE IF NOT EXISTS ") - common.WriteMySQLIdentifier(&createDatabase, database) - err := sqlExecutor.ExecuteWithLog(ctx, createDatabase.String(), "create database", logger) - if err != nil { - return errors.Trace(err) - } - - task := logger.Begin(zap.InfoLevel, "create tables") - var sqlCreateStmts []string -loopCreate: - for tbl, sqlCreateTable := range tablesSchema { - task.Debug("create table", zap.String("schema", sqlCreateTable)) - - sqlCreateStmts, err = createIfNotExistsStmt(g.GetParser(), sqlCreateTable, database, tbl) - if err != nil { - break - } - - // TODO: maybe we should put these createStems into a transaction - for _, s := range sqlCreateStmts { - err = sqlExecutor.ExecuteWithLog( - ctx, - s, - "create table", - logger.With(zap.String("table", common.UniqueTable(database, tbl))), - ) - if err != nil { - break loopCreate - } - } - } - task.End(zap.ErrorLevel, err) - - return errors.Trace(err) -} - func createIfNotExistsStmt(p *parser.Parser, createTable, dbName, tblName string) ([]string, error) { stmts, _, err := p.ParseSQL(createTable) if err != nil { @@ -189,7 +152,7 @@ func createIfNotExistsStmt(p *parser.Parser, createTable, dbName, tblName string } var res strings.Builder - ctx := format.NewRestoreCtx(format.DefaultRestoreFlags|format.RestoreTiDBSpecialComment, &res) + ctx := format.NewRestoreCtx(format.DefaultRestoreFlags|format.RestoreTiDBSpecialComment|format.RestoreWithTTLEnableOff, &res) retStmts := make([]string, 0, len(stmts)) for _, stmt := range stmts { @@ -197,6 +160,9 @@ func createIfNotExistsStmt(p *parser.Parser, createTable, dbName, tblName string case *ast.CreateDatabaseStmt: node.Name = model.NewCIStr(dbName) node.IfNotExists = true + case *ast.DropDatabaseStmt: + node.Name = model.NewCIStr(dbName) + node.IfExists = true case *ast.CreateTableStmt: node.Table.Schema = model.NewCIStr(dbName) node.Table.Name = model.NewCIStr(tblName) diff --git a/br/pkg/lightning/restore/tidb_test.go b/br/pkg/lightning/restore/tidb_test.go index 9b204b2da22b1..a3710d822d2dd 100644 --- a/br/pkg/lightning/restore/tidb_test.go +++ b/br/pkg/lightning/restore/tidb_test.go @@ -165,97 +165,6 @@ func TestCreateTableIfNotExistsStmt(t *testing.T) { `, "m")) } -func TestInitSchema(t *testing.T) { - s := newTiDBSuite(t) - ctx := context.Background() - - s.mockDB. - ExpectExec("CREATE DATABASE IF NOT EXISTS `db`"). - WillReturnResult(sqlmock.NewResult(1, 1)) - s.mockDB. - ExpectExec("\\QCREATE TABLE IF NOT EXISTS `db`.`t1` (`a` INT PRIMARY KEY,`b` VARCHAR(200));\\E"). - WillReturnResult(sqlmock.NewResult(2, 1)) - s.mockDB. - ExpectExec("\\QSET @@SESSION.`FOREIGN_KEY_CHECKS`=0;\\E"). - WillReturnResult(sqlmock.NewResult(0, 0)) - s.mockDB. - ExpectExec("\\QCREATE TABLE IF NOT EXISTS `db`.`t2` (`xx` TEXT) AUTO_INCREMENT = 11203;\\E"). - WillReturnResult(sqlmock.NewResult(2, 1)) - s.mockDB. - ExpectClose() - - s.mockDB.MatchExpectationsInOrder(false) // maps are unordered. - err := InitSchema(ctx, s.tiGlue, "db", map[string]string{ - "t1": "create table t1 (a int primary key, b varchar(200));", - "t2": "/*!40014 SET FOREIGN_KEY_CHECKS=0*/;CREATE TABLE `db`.`t2` (xx TEXT) AUTO_INCREMENT=11203;", - }) - s.mockDB.MatchExpectationsInOrder(true) - require.NoError(t, err) -} - -func TestInitSchemaSyntaxError(t *testing.T) { - s := newTiDBSuite(t) - ctx := context.Background() - - s.mockDB. - ExpectExec("CREATE DATABASE IF NOT EXISTS `db`"). - WillReturnResult(sqlmock.NewResult(1, 1)) - s.mockDB. - ExpectClose() - - err := InitSchema(ctx, s.tiGlue, "db", map[string]string{ - "t1": "create table `t1` with invalid syntax;", - }) - require.Error(t, err) -} - -func TestInitSchemaErrorLost(t *testing.T) { - s := newTiDBSuite(t) - ctx := context.Background() - - s.mockDB. - ExpectExec("CREATE DATABASE IF NOT EXISTS `db`"). - WillReturnResult(sqlmock.NewResult(1, 1)) - - s.mockDB. - ExpectExec("CREATE TABLE IF NOT EXISTS.*"). - WillReturnError(&mysql.MySQLError{ - Number: tmysql.ErrTooBigFieldlength, - Message: "Column length too big", - }) - - s.mockDB. - ExpectClose() - - err := InitSchema(ctx, s.tiGlue, "db", map[string]string{ - "t1": "create table `t1` (a int);", - "t2": "create table t2 (a int primary key, b varchar(200));", - }) - require.Regexp(t, ".*Column length too big.*", err.Error()) -} - -func TestInitSchemaUnsupportedSchemaError(t *testing.T) { - s := newTiDBSuite(t) - ctx := context.Background() - - s.mockDB. - ExpectExec("CREATE DATABASE IF NOT EXISTS `db`"). - WillReturnResult(sqlmock.NewResult(1, 1)) - s.mockDB. - ExpectExec("CREATE TABLE IF NOT EXISTS `db`.`t1`.*"). - WillReturnError(&mysql.MySQLError{ - Number: tmysql.ErrTooBigFieldlength, - Message: "Column length too big", - }) - s.mockDB. - ExpectClose() - - err := InitSchema(ctx, s.tiGlue, "db", map[string]string{ - "t1": "create table `t1` (a VARCHAR(999999999));", - }) - require.Regexp(t, ".*Column length too big.*", err.Error()) -} - func TestDropTable(t *testing.T) { s := newTiDBSuite(t) ctx := context.Background() diff --git a/br/pkg/lightning/run_options.go b/br/pkg/lightning/run_options.go index a7b5b90770c02..169c2e47088dd 100644 --- a/br/pkg/lightning/run_options.go +++ b/br/pkg/lightning/run_options.go @@ -19,6 +19,7 @@ import ( "github.com/pingcap/tidb/br/pkg/lightning/log" "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/util/promutil" + "go.uber.org/atomic" "go.uber.org/zap" ) @@ -30,6 +31,7 @@ type options struct { promFactory promutil.Factory promRegistry promutil.Registry logger log.Logger + dupIndicator *atomic.Bool } type Option func(*options) @@ -81,3 +83,10 @@ func WithLogger(logger *zap.Logger) Option { o.logger = log.Logger{Logger: logger} } } + +// WithDupIndicator sets a *bool to indicate duplicate detection has found duplicate data. +func WithDupIndicator(b *atomic.Bool) Option { + return func(o *options) { + o.dupIndicator = b + } +} diff --git a/br/pkg/lightning/web/progress.go b/br/pkg/lightning/web/progress.go index 8a3412087b94f..d5f3494a14040 100644 --- a/br/pkg/lightning/web/progress.go +++ b/br/pkg/lightning/web/progress.go @@ -64,7 +64,7 @@ func (cpm *checkpointsMap) update(diffs map[string]*checkpoints.TableCheckpointD for _, engine := range cp.Engines { for _, chunk := range engine.Chunks { if engine.Status >= checkpoints.CheckpointStatusAllWritten { - tw += chunk.Chunk.EndOffset - chunk.Key.Offset + tw += chunk.TotalSize() } else { tw += chunk.Chunk.Offset - chunk.Key.Offset } diff --git a/br/pkg/logutil/logging.go b/br/pkg/logutil/logging.go index 028cfc00e5f43..41b8e135c220f 100644 --- a/br/pkg/logutil/logging.go +++ b/br/pkg/logutil/logging.go @@ -306,3 +306,13 @@ func (rng StringifyRange) String() string { sb.WriteString(")") return sb.String() } + +// StringifyMany returns an array marshaler for a slice of stringers. +func StringifyMany[T fmt.Stringer](items []T) zapcore.ArrayMarshaler { + return zapcore.ArrayMarshalerFunc(func(ae zapcore.ArrayEncoder) error { + for _, item := range items { + ae.AppendString(item.String()) + } + return nil + }) +} diff --git a/br/pkg/metautil/main_test.go b/br/pkg/metautil/main_test.go index 700d234b0182d..2b87f6047b950 100644 --- a/br/pkg/metautil/main_test.go +++ b/br/pkg/metautil/main_test.go @@ -24,6 +24,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } testsetup.SetupForCommonTest() diff --git a/br/pkg/mock/mock_cluster_test.go b/br/pkg/mock/mock_cluster_test.go index 8a81c6e1ef6ee..37f24e8a7eca6 100644 --- a/br/pkg/mock/mock_cluster_test.go +++ b/br/pkg/mock/mock_cluster_test.go @@ -14,9 +14,11 @@ func TestSmoke(t *testing.T) { defer goleak.VerifyNone( t, goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/klauspost/compress/zstd.(*blockDec).startDecoder"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), - goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start")) + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + ) m, err := mock.NewCluster() require.NoError(t, err) require.NoError(t, m.Start()) diff --git a/br/pkg/pdutil/main_test.go b/br/pkg/pdutil/main_test.go index 86b9c6e1a61ad..8af7ac001aaa4 100644 --- a/br/pkg/pdutil/main_test.go +++ b/br/pkg/pdutil/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/br/pkg/restore/BUILD.bazel b/br/pkg/restore/BUILD.bazel index d470d9d5a2655..d4f70e278fd2c 100644 --- a/br/pkg/restore/BUILD.bazel +++ b/br/pkg/restore/BUILD.bazel @@ -9,6 +9,7 @@ go_library( "db.go", "import.go", "import_retry.go", + "log_client.go", "merge.go", "pipeline_items.go", "range.go", @@ -33,6 +34,7 @@ go_library( "//br/pkg/metautil", "//br/pkg/pdutil", "//br/pkg/redact", + "//br/pkg/restore/prealloc_table_id", "//br/pkg/restore/split", "//br/pkg/restore/tiflashrec", "//br/pkg/rtree", @@ -40,7 +42,10 @@ go_library( "//br/pkg/stream", "//br/pkg/summary", "//br/pkg/utils", + "//br/pkg/utils/iter", + "//br/pkg/version", "//config", + "//ddl", "//ddl/util", "//domain", "//kv", @@ -53,8 +58,10 @@ go_library( "//tablecodec", "//util", "//util/codec", + "//util/collate", "//util/hack", "//util/mathutil", + "//util/sqlexec", "//util/table-filter", "@com_github_emirpasic_gods//maps/treemap", "@com_github_go_sql_driver_mysql//:mysql", @@ -74,6 +81,8 @@ go_library( "@com_github_tikv_client_go_v2//kv", "@com_github_tikv_client_go_v2//oracle", "@com_github_tikv_client_go_v2//rawkv", + "@com_github_tikv_client_go_v2//tikv", + "@com_github_tikv_client_go_v2//txnkv/rangetask", "@com_github_tikv_pd_client//:client", "@org_golang_google_grpc//:grpc", "@org_golang_google_grpc//backoff", @@ -107,12 +116,13 @@ go_test( "search_test.go", "split_test.go", "stream_metas_test.go", + "systable_restore_test.go", "util_test.go", ], embed = [":restore"], flaky = True, race = "on", - shard_count = 20, + shard_count = 50, deps = [ "//br/pkg/backup", "//br/pkg/conn", @@ -129,6 +139,7 @@ go_test( "//br/pkg/storage", "//br/pkg/stream", "//br/pkg/utils", + "//br/pkg/utils/iter", "//infoschema", "//kv", "//meta/autoid", @@ -142,7 +153,6 @@ go_test( "//testkit/testsetup", "//types", "//util/codec", - "//util/mathutil", "@com_github_fsouza_fake_gcs_server//fakestorage", "@com_github_golang_protobuf//proto", "@com_github_pingcap_errors//:errors", diff --git a/br/pkg/restore/client.go b/br/pkg/restore/client.go index 17a788f0e0cf2..c0f58817ec0af 100644 --- a/br/pkg/restore/client.go +++ b/br/pkg/restore/client.go @@ -5,7 +5,6 @@ package restore import ( "bytes" "context" - "crypto/sha256" "crypto/tls" "encoding/hex" "encoding/json" @@ -32,6 +31,7 @@ import ( "github.com/pingcap/tidb/br/pkg/metautil" "github.com/pingcap/tidb/br/pkg/pdutil" "github.com/pingcap/tidb/br/pkg/redact" + tidalloc "github.com/pingcap/tidb/br/pkg/restore/prealloc_table_id" "github.com/pingcap/tidb/br/pkg/restore/split" "github.com/pingcap/tidb/br/pkg/restore/tiflashrec" "github.com/pingcap/tidb/br/pkg/rtree" @@ -39,6 +39,7 @@ import ( "github.com/pingcap/tidb/br/pkg/stream" "github.com/pingcap/tidb/br/pkg/summary" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/br/pkg/version" "github.com/pingcap/tidb/config" ddlutil "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/domain" @@ -50,7 +51,9 @@ import ( "github.com/pingcap/tidb/store/pdtypes" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/mathutil" + "github.com/pingcap/tidb/util/sqlexec" filter "github.com/pingcap/tidb/util/table-filter" "github.com/tikv/client-go/v2/oracle" pd "github.com/tikv/pd/client" @@ -136,24 +139,13 @@ type Client struct { supportPolicy bool - // startTS and restoreTS are used for kv file restore. - // TiKV will filter the key space that don't belong to [startTS, restoreTS]. - startTS uint64 - restoreTS uint64 - - // If the commitTS of txn-entry belong to [startTS, restoreTS], - // the startTS of txn-entry may be smaller than startTS. - // We need maintain and restore more entries in default cf - // (the startTS in these entries belong to [shiftStartTS, startTS]). - shiftStartTS uint64 - // currentTS is used for rewrite meta kv when restore stream. // Can not use `restoreTS` directly, because schema created in `full backup` maybe is new than `restoreTS`. currentTS uint64 - storage storage.ExternalStorage + *logFileManager - helper *stream.MetadataHelper + storage storage.ExternalStorage // if fullClusterRestore = true: // - if there's system tables in the backup(backup data since br 5.1.0), the cluster should be a fresh cluster @@ -173,6 +165,9 @@ type Client struct { // see RestoreCommonConfig.WithSysTable withSysTable bool + + // the successfully preallocated table IDs. + preallocedTableIDs *tidalloc.PreallocIDs } // NewRestoreClient returns a new RestoreClient. @@ -237,6 +232,26 @@ func (rc *Client) Init(g glue.Glue, store kv.Storage) error { return errors.Trace(err) } +func (rc *Client) allocTableIDs(ctx context.Context, tables []*metautil.Table) error { + rc.preallocedTableIDs = tidalloc.New(tables) + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnBR) + err := kv.RunInNewTxn(ctx, rc.GetDomain().Store(), true, func(_ context.Context, txn kv.Transaction) error { + return rc.preallocedTableIDs.Alloc(meta.NewMeta(txn)) + }) + if err != nil { + return err + } + + log.Info("registering the table IDs", zap.Stringer("ids", rc.preallocedTableIDs)) + for i := range rc.dbPool { + rc.dbPool[i].registerPreallocatedIDs(rc.preallocedTableIDs) + } + if rc.db != nil { + rc.db.registerPreallocatedIDs(rc.preallocedTableIDs) + } + return nil +} + // SetPlacementPolicyMode to policy mode. func (rc *Client) SetPlacementPolicyMode(withPlacementPolicy string) { switch strings.ToUpper(withPlacementPolicy) { @@ -314,14 +329,6 @@ func (rc *Client) Close() { log.Info("Restore client closed") } -func (rc *Client) SetRestoreRangeTS(startTs, restoreTS, shiftStartTS uint64) { - rc.startTS = startTs - rc.restoreTS = restoreTS - rc.shiftStartTS = shiftStartTS - log.Info("set restore range ts", zap.Uint64("shift-start-ts", shiftStartTS), - zap.Uint64("start-ts", startTs), zap.Uint64("restored-ts", restoreTS)) -} - func (rc *Client) SetCurrentTS(ts uint64) { rc.currentTS = ts } @@ -384,10 +391,6 @@ func (rc *Client) IsRawKvMode() bool { return rc.backupMeta.IsRawKv } -func (rc *Client) InitMetadataHelper() { - rc.helper = stream.NewMetadataHelper() -} - // GetFilesInRawRange gets all files that are in the given range or intersects with the given range. func (rc *Client) GetFilesInRawRange(startKey []byte, endKey []byte, cf string) ([]*backuppb.File, error) { if !rc.IsRawKvMode() { @@ -446,7 +449,7 @@ func (rc *Client) GetFilesInRawRange(startKey []byte, endKey []byte, cf string) // SetConcurrency sets the concurrency of dbs tables files. func (rc *Client) SetConcurrency(c uint) { - log.Debug("new worker pool", zap.Uint("currency-count", c)) + log.Info("new worker pool", zap.Uint("currency-count", c)) rc.workerPool = utils.NewWorkerPool(c, "file") } @@ -470,6 +473,35 @@ func (rc *Client) GetTS(ctx context.Context) (uint64, error) { return restoreTS, nil } +// GetTSWithRetry gets a new timestamp with retry from PD. +func (rc *Client) GetTSWithRetry(ctx context.Context) (uint64, error) { + var ( + startTS uint64 + getTSErr error + retry uint + ) + + err := utils.WithRetry(ctx, func() error { + startTS, getTSErr = rc.GetTS(ctx) + failpoint.Inject("get-ts-error", func(val failpoint.Value) { + if val.(bool) && retry < 3 { + getTSErr = errors.Errorf("rpc error: code = Unknown desc = [PD:tso:ErrGenerateTimestamp]generate timestamp failed, requested pd is not leader of cluster") + } + }) + + retry++ + if getTSErr != nil { + log.Warn("failed to get TS, retry it", zap.Uint("retry time", retry), logutil.ShortError(getTSErr)) + } + return getTSErr + }, utils.NewPDReqBackoffer()) + + if err != nil { + log.Error("failed to get TS", zap.Error(err)) + } + return startTS, errors.Trace(err) +} + // ResetTS resets the timestamp of PD to a bigger value. func (rc *Client) ResetTS(ctx context.Context, pdCtrl *pdutil.PdController) error { restoreTS := rc.backupMeta.GetEndVersion() @@ -724,6 +756,11 @@ func (rc *Client) GoCreateTables( } outCh := make(chan CreatedTable, len(tables)) rater := logutil.TraceRateOver(logutil.MetricTableCreatedCounter) + if err := rc.allocTableIDs(ctx, tables); err != nil { + errCh <- err + close(outCh) + return outCh + } var err error @@ -904,7 +941,9 @@ func (rc *Client) CheckSysTableCompatibility(dom *domain.Domain, tables []*metau return errors.Annotate(berrors.ErrRestoreIncompatibleSys, "missed system table: "+table.Info.Name.O) } backupTi := table.Info - if len(ti.Columns) != len(backupTi.Columns) { + // skip checking the number of columns in mysql.user table, + // because higher versions of TiDB may add new columns. + if len(ti.Columns) != len(backupTi.Columns) && backupTi.Name.L != sysUserTableName { log.Error("column count mismatch", zap.Stringer("table", table.Info.Name), zap.Int("col in cluster", len(ti.Columns)), @@ -923,6 +962,13 @@ func (rc *Client) CheckSysTableCompatibility(dom *domain.Domain, tables []*metau col := ti.Columns[i] backupCol := backupColMap[col.Name.L] if backupCol == nil { + // skip when the backed up mysql.user table is missing columns. + if backupTi.Name.L == sysUserTableName { + log.Warn("missing column in backup data", + zap.Stringer("table", table.Info.Name), + zap.String("col", fmt.Sprintf("%s %s", col.Name, col.FieldType.String()))) + continue + } log.Error("missing column in backup data", zap.Stringer("table", table.Info.Name), zap.String("col", fmt.Sprintf("%s %s", col.Name, col.FieldType.String()))) @@ -943,6 +989,29 @@ func (rc *Client) CheckSysTableCompatibility(dom *domain.Domain, tables []*metau backupCol.Name, backupCol.FieldType.String()) } } + + if backupTi.Name.L == sysUserTableName { + // check whether the columns of table in cluster are less than the backup data + clusterColMap := make(map[string]*model.ColumnInfo) + for i := range ti.Columns { + col := ti.Columns[i] + clusterColMap[col.Name.L] = col + } + // order can be different + for i := range backupTi.Columns { + col := backupTi.Columns[i] + clusterCol := clusterColMap[col.Name.L] + if clusterCol == nil { + log.Error("missing column in cluster data", + zap.Stringer("table", table.Info.Name), + zap.String("col", fmt.Sprintf("%s %s", col.Name, col.FieldType.String()))) + return errors.Annotatef(berrors.ErrRestoreIncompatibleSys, + "missing column in cluster data, table: %s, col: %s %s", + table.Info.Name.O, + col.Name, col.FieldType.String()) + } + } + } } return nil } @@ -1058,6 +1127,18 @@ func (rc *Client) SplitRanges(ctx context.Context, return SplitRanges(ctx, rc, ranges, rewriteRules, updateCh, isRawKv) } +func (rc *Client) WrapLogFilesIterWithSplitHelper(iter LogIter, rules map[int64]*RewriteRules, g glue.Glue, store kv.Storage) (LogIter, error) { + se, err := g.CreateSession(store) + if err != nil { + return nil, errors.Trace(err) + } + execCtx := se.GetSessionCtx().(sqlexec.RestrictedSQLExecutor) + splitSize, splitKeys := utils.GetRegionSplitInfo(execCtx) + log.Info("get split threshold from tikv config", zap.Uint64("split-size", splitSize), zap.Int64("split-keys", splitKeys)) + client := split.NewSplitClient(rc.GetPDClient(), rc.GetTLSConfig(), false) + return NewLogFilesIterWithSplitHelper(iter, rules, client, splitSize, splitKeys), nil +} + // RestoreSSTFiles tries to restore the files. func (rc *Client) RestoreSSTFiles( ctx context.Context, @@ -1345,7 +1426,7 @@ func (rc *Client) execChecksum( ctx = opentracing.ContextWithSpan(ctx, span1) } - startTS, err := rc.GetTS(ctx) + startTS, err := rc.GetTSWithRetry(ctx) if err != nil { return errors.Trace(err) } @@ -1393,7 +1474,7 @@ func (rc *Client) updateMetaAndLoadStats(ctx context.Context, input <-chan *Crea } // Not need to return err when failed because of update analysis-meta - restoreTS, err := rc.GetTS(ctx) + restoreTS, err := rc.GetTSWithRetry(ctx) if err != nil { log.Error("getTS failed", zap.Error(err)) } else { @@ -1700,109 +1781,18 @@ func (rc *Client) PreCheckTableClusterIndex( return nil } -func (rc *Client) GetShiftTS(ctx context.Context, startTS uint64, restoreTS uint64) (uint64, error) { - shiftTS := struct { - sync.Mutex - value uint64 - exists bool - }{} - err := stream.FastUnmarshalMetaData(ctx, rc.storage, func(path string, raw []byte) error { - m, err := rc.helper.ParseToMetadata(raw) - if err != nil { - return err - } - shiftTS.Lock() - defer shiftTS.Unlock() - - ts, ok := UpdateShiftTS(m, startTS, restoreTS) - if ok && (!shiftTS.exists || shiftTS.value > ts) { - shiftTS.value = ts - shiftTS.exists = true - } - return nil - }) - if err != nil { - return 0, err - } - if !shiftTS.exists { - return startTS, nil +func (rc *Client) InstallLogFileManager(ctx context.Context, startTS, restoreTS uint64) error { + init := LogFileManagerInit{ + StartTS: startTS, + RestoreTS: restoreTS, + Storage: rc.storage, } - return shiftTS.value, nil -} - -// ReadStreamMetaByTS is used for streaming task. collect all meta file by TS. -func (rc *Client) ReadStreamMetaByTS(ctx context.Context, shiftedStartTS uint64, restoreTS uint64) ([]*backuppb.Metadata, error) { - streamBackupMetaFiles := struct { - sync.Mutex - metas []*backuppb.Metadata - }{} - streamBackupMetaFiles.metas = make([]*backuppb.Metadata, 0, 128) - - err := stream.FastUnmarshalMetaData(ctx, rc.storage, func(path string, raw []byte) error { - metadata, err := rc.helper.ParseToMetadata(raw) - if err != nil { - return err - } - streamBackupMetaFiles.Lock() - if restoreTS >= metadata.MinTs && metadata.MaxTs >= shiftedStartTS { - streamBackupMetaFiles.metas = append(streamBackupMetaFiles.metas, metadata) - } - streamBackupMetaFiles.Unlock() - return nil - }) + var err error + rc.logFileManager, err = CreateLogFileManager(ctx, init) if err != nil { - return nil, errors.Trace(err) - } - return streamBackupMetaFiles.metas, nil -} - -// ReadStreamDataFiles is used for streaming task. collect all meta file by TS. -func (rc *Client) ReadStreamDataFiles( - ctx context.Context, - metas []*backuppb.Metadata, -) (dataFiles, metaFiles []*backuppb.DataFileInfo, err error) { - dFiles := make([]*backuppb.DataFileInfo, 0) - mFiles := make([]*backuppb.DataFileInfo, 0) - - for _, m := range metas { - _, exists := backuppb.MetaVersion_name[int32(m.MetaVersion)] - if !exists { - log.Warn("metaversion too new", zap.Reflect("version id", m.MetaVersion)) - } - for _, ds := range m.FileGroups { - metaRef := 0 - for _, d := range ds.DataFilesInfo { - if d.MinTs > rc.restoreTS { - continue - } else if d.Cf == stream.WriteCF && d.MaxTs < rc.startTS { - continue - } else if d.Cf == stream.DefaultCF && d.MaxTs < rc.shiftStartTS { - continue - } - - // If ds.Path is empty, it is MetadataV1. - // Try to be compatible with newer metadata version - if m.MetaVersion > backuppb.MetaVersion_V1 { - d.Path = ds.Path - } - - if d.IsMeta { - mFiles = append(mFiles, d) - metaRef += 1 - } else { - dFiles = append(dFiles, d) - } - log.Debug("backup stream collect data partition", zap.Uint64("offset", d.RangeOffset), zap.Uint64("length", d.Length)) - } - // metadatav1 doesn't use cache - // Try to be compatible with newer metadata version - if m.MetaVersion > backuppb.MetaVersion_V1 { - rc.helper.InitCacheEntry(ds.Path, metaRef) - } - } + return err } - - return dFiles, mFiles, nil + return nil } // FixIndex tries to fix a single index. @@ -1864,25 +1854,184 @@ func (rc *Client) FixIndicesOfTable(ctx context.Context, schema string, table *m return nil } +type FilesInRegion struct { + defaultSize uint64 + defaultKVCount int64 + writeSize uint64 + writeKVCount int64 + + defaultFiles []*backuppb.DataFileInfo + writeFiles []*backuppb.DataFileInfo + deleteFiles []*backuppb.DataFileInfo +} + +type FilesInTable struct { + regionMapFiles map[int64]*FilesInRegion +} + +func ApplyKVFilesWithBatchMethod( + ctx context.Context, + iter LogIter, + batchCount int, + batchSize uint64, + applyFunc func(files []*backuppb.DataFileInfo, kvCount int64, size uint64), +) error { + var ( + tableMapFiles = make(map[int64]*FilesInTable) + tmpFiles = make([]*backuppb.DataFileInfo, 0, batchCount) + tmpSize uint64 = 0 + tmpKVCount int64 = 0 + ) + for r := iter.TryNext(ctx); !r.Finished; r = iter.TryNext(ctx) { + if r.Err != nil { + return r.Err + } + + f := r.Item + if f.GetType() == backuppb.FileType_Put && f.GetLength() >= batchSize { + applyFunc([]*backuppb.DataFileInfo{f}, f.GetNumberOfEntries(), f.GetLength()) + continue + } + + fit, exist := tableMapFiles[f.TableId] + if !exist { + fit = &FilesInTable{ + regionMapFiles: make(map[int64]*FilesInRegion), + } + tableMapFiles[f.TableId] = fit + } + fs, exist := fit.regionMapFiles[f.RegionId] + if !exist { + fs = &FilesInRegion{} + fit.regionMapFiles[f.RegionId] = fs + } + + if f.GetType() == backuppb.FileType_Delete { + if fs.defaultFiles == nil { + fs.deleteFiles = make([]*backuppb.DataFileInfo, 0) + } + fs.deleteFiles = append(fs.deleteFiles, f) + } else { + if f.GetCf() == stream.DefaultCF { + if fs.defaultFiles == nil { + fs.defaultFiles = make([]*backuppb.DataFileInfo, 0, batchCount) + } + fs.defaultFiles = append(fs.defaultFiles, f) + fs.defaultSize += f.Length + fs.defaultKVCount += f.GetNumberOfEntries() + if len(fs.defaultFiles) >= batchCount || fs.defaultSize >= batchSize { + applyFunc(fs.defaultFiles, fs.defaultKVCount, fs.defaultSize) + fs.defaultFiles = nil + fs.defaultSize = 0 + fs.defaultKVCount = 0 + } + } else { + if fs.writeFiles == nil { + fs.writeFiles = make([]*backuppb.DataFileInfo, 0, batchCount) + } + fs.writeFiles = append(fs.writeFiles, f) + fs.writeSize += f.GetLength() + fs.writeKVCount += f.GetNumberOfEntries() + if len(fs.writeFiles) >= batchCount || fs.writeSize >= batchSize { + applyFunc(fs.writeFiles, fs.writeKVCount, fs.writeSize) + fs.writeFiles = nil + fs.writeSize = 0 + fs.writeKVCount = 0 + } + } + } + } + + for _, fwt := range tableMapFiles { + for _, fs := range fwt.regionMapFiles { + if len(fs.defaultFiles) > 0 { + applyFunc(fs.defaultFiles, fs.defaultKVCount, fs.defaultSize) + } + if len(fs.writeFiles) > 0 { + applyFunc(fs.writeFiles, fs.writeKVCount, fs.writeSize) + } + } + } + + for _, fwt := range tableMapFiles { + for _, fs := range fwt.regionMapFiles { + for _, d := range fs.deleteFiles { + tmpFiles = append(tmpFiles, d) + tmpSize += d.GetLength() + tmpKVCount += d.GetNumberOfEntries() + + if len(tmpFiles) >= batchCount || tmpSize >= batchSize { + applyFunc(tmpFiles, tmpKVCount, tmpSize) + tmpFiles = make([]*backuppb.DataFileInfo, 0, batchCount) + tmpSize = 0 + tmpKVCount = 0 + } + } + if len(tmpFiles) > 0 { + applyFunc(tmpFiles, tmpKVCount, tmpSize) + tmpFiles = make([]*backuppb.DataFileInfo, 0, batchCount) + tmpSize = 0 + tmpKVCount = 0 + } + } + } + + return nil +} + +func ApplyKVFilesWithSingelMethod( + ctx context.Context, + files LogIter, + applyFunc func(file []*backuppb.DataFileInfo, kvCount int64, size uint64), +) error { + deleteKVFiles := make([]*backuppb.DataFileInfo, 0) + + for r := files.TryNext(ctx); !r.Finished; r = files.TryNext(ctx) { + if r.Err != nil { + return r.Err + } + + f := r.Item + if f.GetType() == backuppb.FileType_Delete { + deleteKVFiles = append(deleteKVFiles, f) + continue + } + applyFunc([]*backuppb.DataFileInfo{f}, f.GetNumberOfEntries(), f.GetLength()) + } + + log.Info("restore delete files", zap.Int("count", len(deleteKVFiles))) + for _, file := range deleteKVFiles { + f := file + applyFunc([]*backuppb.DataFileInfo{f}, f.GetNumberOfEntries(), f.GetLength()) + } + + return nil +} + func (rc *Client) RestoreKVFiles( ctx context.Context, rules map[int64]*RewriteRules, - files []*backuppb.DataFileInfo, + iter LogIter, + pitrBatchCount uint32, + pitrBatchSize uint32, updateStats func(kvCount uint64, size uint64), - onProgress func(), + onProgress func(cnt int64), ) error { - var err error - start := time.Now() + var ( + err error + fileCount = 0 + start = time.Now() + supportBatch = version.CheckPITRSupportBatchKVFiles() + skipFile = 0 + ) defer func() { - elapsed := time.Since(start) if err == nil { + elapsed := time.Since(start) log.Info("Restore KV files", zap.Duration("take", elapsed)) - summary.CollectSuccessUnit("files", len(files), elapsed) + summary.CollectSuccessUnit("files", fileCount, elapsed) } }() - log.Debug("start to restore files", zap.Int("files", len(files))) - if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { span1 := span.Tracer().StartSpan("Client.RestoreKVFiles", opentracing.ChildOf(span.Context())) defer span1.Finish() @@ -1890,54 +2039,54 @@ func (rc *Client) RestoreKVFiles( } eg, ectx := errgroup.WithContext(ctx) - skipFile := 0 - deleteFiles := make([]*backuppb.DataFileInfo, 0) - - applyFunc := func(file *backuppb.DataFileInfo) { - // get rewrite rule from table id - rule, ok := rules[file.TableId] + applyFunc := func(files []*backuppb.DataFileInfo, kvCount int64, size uint64) { + if len(files) == 0 { + return + } + // get rewrite rule from table id. + // because the tableID of files is the same. + rule, ok := rules[files[0].TableId] if !ok { // TODO handle new created table // For this version we do not handle new created table after full backup. // in next version we will perform rewrite and restore meta key to restore new created tables. // so we can simply skip the file that doesn't have the rule here. - onProgress() - summary.CollectInt("FileSkip", 1) - log.Debug("skip file due to table id not matched", zap.String("file", file.Path), zap.Int64("tableId", file.TableId)) - skipFile++ + onProgress(int64(len(files))) + summary.CollectInt("FileSkip", len(files)) + log.Debug("skip file due to table id not matched", zap.Int64("table-id", files[0].TableId)) + skipFile += len(files) } else { - rc.workerPool.ApplyOnErrorGroup(eg, func() error { + rc.workerPool.ApplyOnErrorGroup(eg, func() (err error) { fileStart := time.Now() defer func() { - onProgress() - updateStats(uint64(file.NumberOfEntries), file.Length) - summary.CollectInt("File", 1) - log.Info("import files done", zap.String("name", file.Path), zap.Duration("take", time.Since(fileStart))) + onProgress(int64(len(files))) + updateStats(uint64(kvCount), size) + summary.CollectInt("File", len(files)) + + if err == nil { + filenames := make([]string, 0, len(files)) + for _, f := range files { + filenames = append(filenames, f.Path+", ") + } + log.Info("import files done", zap.Int("batch-count", len(files)), zap.Uint64("batch-size", size), + zap.Duration("take", time.Since(fileStart)), zap.Strings("files", filenames)) + } }() - startTS := rc.startTS - if file.Cf == stream.DefaultCF { - startTS = rc.shiftStartTS - } - return rc.fileImporter.ImportKVFiles(ectx, file, rule, startTS, rc.restoreTS) + + return rc.fileImporter.ImportKVFiles(ectx, files, rule, rc.shiftStartTS, rc.startTS, rc.restoreTS, supportBatch) }) } } - for _, file := range files { - if file.Type == backuppb.FileType_Delete { - // collect delete type file and apply it later. - deleteFiles = append(deleteFiles, file) - continue + + rc.workerPool.ApplyOnErrorGroup(eg, func() error { + if supportBatch { + err = ApplyKVFilesWithBatchMethod(ectx, iter, int(pitrBatchCount), uint64(pitrBatchSize), applyFunc) + } else { + err = ApplyKVFilesWithSingelMethod(ectx, iter, applyFunc) } - fileReplica := file - applyFunc(fileReplica) - } - if len(deleteFiles) > 0 { - log.Info("restore delete files", zap.Int("count", len(deleteFiles))) - } - for _, file := range deleteFiles { - fileReplica := file - applyFunc(fileReplica) - } + return errors.Trace(err) + }) + log.Info("total skip files due to table id not matched", zap.Int("count", skipFile)) if skipFile > 0 { log.Debug("table id in full backup storage", zap.Any("tables", rules)) @@ -1945,13 +2094,9 @@ func (rc *Client) RestoreKVFiles( if err = eg.Wait(); err != nil { summary.CollectFailureUnit("file", err) - log.Error( - "restore files failed", - zap.Error(err), - ) - return errors.Trace(err) + log.Error("restore files failed", zap.Error(err)) } - return nil + return errors.Trace(err) } func (rc *Client) CleanUpKVFiles( @@ -2216,7 +2361,7 @@ func (rc *Client) RestoreBatchMetaKVFiles( // read all of entries from files. for _, f := range files { - es, nextEs, err := rc.readAllEntries(ctx, f, filterTS) + es, nextEs, err := rc.ReadAllEntries(ctx, f, filterTS) if err != nil { return nextKvEntries, errors.Trace(err) } @@ -2243,72 +2388,6 @@ func (rc *Client) RestoreBatchMetaKVFiles( return nextKvEntries, nil } -func (rc *Client) readAllEntries( - ctx context.Context, - file *backuppb.DataFileInfo, - filterTS uint64, -) ([]*KvEntryWithTS, []*KvEntryWithTS, error) { - kvEntries := make([]*KvEntryWithTS, 0) - nextKvEntries := make([]*KvEntryWithTS, 0) - - buff, err := rc.helper.ReadFile(ctx, file.Path, file.RangeOffset, file.RangeLength, file.CompressionType, rc.storage) - if err != nil { - return nil, nil, errors.Trace(err) - } - - if checksum := sha256.Sum256(buff); !bytes.Equal(checksum[:], file.GetSha256()) { - return nil, nil, errors.Annotatef(berrors.ErrInvalidMetaFile, - "checksum mismatch expect %x, got %x", file.GetSha256(), checksum[:]) - } - - iter := stream.NewEventIterator(buff) - for iter.Valid() { - iter.Next() - if iter.GetError() != nil { - return nil, nil, errors.Trace(iter.GetError()) - } - - txnEntry := kv.Entry{Key: iter.Key(), Value: iter.Value()} - - if !stream.MaybeDBOrDDLJobHistoryKey(txnEntry.Key) { - // only restore mDB and mDDLHistory - continue - } - - ts, err := GetKeyTS(txnEntry.Key) - if err != nil { - return nil, nil, errors.Trace(err) - } - - // The commitTs in write CF need be limited on [startTs, restoreTs]. - // We can restore more key-value in default CF. - if ts > rc.restoreTS { - continue - } else if file.Cf == stream.WriteCF && ts < rc.startTS { - continue - } else if file.Cf == stream.DefaultCF && ts < rc.shiftStartTS { - continue - } - - if len(txnEntry.Value) == 0 { - // we might record duplicated prewrite keys in some conor cases. - // the first prewrite key has the value but the second don't. - // so we can ignore the empty value key. - // see details at https://github.com/pingcap/tiflow/issues/5468. - log.Warn("txn entry is null", zap.Uint64("key-ts", ts), zap.ByteString("tnxKey", txnEntry.Key)) - continue - } - - if ts < filterTS { - kvEntries = append(kvEntries, &KvEntryWithTS{e: txnEntry, ts: ts}) - } else { - nextKvEntries = append(nextKvEntries, &KvEntryWithTS{e: txnEntry, ts: ts}) - } - } - - return kvEntries, nextKvEntries, nil -} - func (rc *Client) restoreMetaKvEntries( ctx context.Context, sr *stream.SchemasReplace, @@ -2517,7 +2596,7 @@ func (rc *Client) RunGCRowsLoader(ctx context.Context) { func (rc *Client) InsertGCRows(ctx context.Context) error { close(rc.deleteRangeQueryCh) rc.deleteRangeQueryWaitGroup.Wait() - ts, err := rc.GetTS(ctx) + ts, err := rc.GetTSWithRetry(ctx) if err != nil { return errors.Trace(err) } @@ -2551,7 +2630,7 @@ func (rc *Client) SaveSchemas( schemas := TidyOldSchemas(sr) schemasConcurrency := uint(mathutil.Min(64, schemas.Len())) - err := schemas.BackupSchemas(ctx, metaWriter, nil, nil, rc.restoreTS, schemasConcurrency, 0, true, nil) + err := schemas.BackupSchemas(ctx, metaWriter, nil, nil, nil, rc.restoreTS, schemasConcurrency, 0, true, nil) if err != nil { return errors.Trace(err) } @@ -2582,6 +2661,74 @@ func (rc *Client) SetWithSysTable(withSysTable bool) { rc.withSysTable = withSysTable } +func (rc *Client) ResetTiFlashReplicas(ctx context.Context, g glue.Glue, storage kv.Storage) error { + dom, err := g.GetDomain(storage) + if err != nil { + return errors.Trace(err) + } + info := dom.InfoSchema() + allSchema := info.AllSchemas() + recorder := tiflashrec.New() + + expectTiFlashStoreCount := uint64(0) + needTiFlash := false + for _, s := range allSchema { + for _, t := range s.Tables { + if t.TiFlashReplica != nil { + expectTiFlashStoreCount = mathutil.Max(expectTiFlashStoreCount, t.TiFlashReplica.Count) + recorder.AddTable(t.ID, *t.TiFlashReplica) + needTiFlash = true + } + } + } + if !needTiFlash { + log.Info("no need to set tiflash replica, since there is no tables enable tiflash replica") + return nil + } + // we wait for ten minutes to wait tiflash starts. + // since tiflash only starts when set unmark recovery mode finished. + timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Minute) + defer cancel() + err = utils.WithRetry(timeoutCtx, func() error { + tiFlashStoreCount, err := rc.getTiFlashNodeCount(ctx) + log.Info("get tiflash store count for resetting TiFlash Replica", + zap.Uint64("count", tiFlashStoreCount)) + if err != nil { + return errors.Trace(err) + } + if tiFlashStoreCount < expectTiFlashStoreCount { + log.Info("still waiting for enough tiflash store start", + zap.Uint64("expect", expectTiFlashStoreCount), + zap.Uint64("actual", tiFlashStoreCount), + ) + return errors.New("tiflash store count is less than expected") + } + return nil + }, &waitTiFlashBackoffer{ + Attempts: 30, + BaseBackoff: 4 * time.Second, + }) + if err != nil { + return err + } + + sqls := recorder.GenerateResetAlterTableDDLs(info) + log.Info("Generating SQLs for resetting tiflash replica", + zap.Strings("sqls", sqls)) + + return g.UseOneShotSession(storage, false, func(se glue.Session) error { + for _, sql := range sqls { + if errExec := se.ExecuteInternal(ctx, sql); errExec != nil { + logutil.WarnTerm("Failed to restore tiflash replica config, you may execute the sql restore it manually.", + logutil.ShortError(errExec), + zap.String("sql", sql), + ) + } + } + return nil + }) +} + // MockClient create a fake client used to test. func MockClient(dbs map[string]*utils.Database) *Client { return &Client{databases: dbs} @@ -2613,3 +2760,71 @@ func TidyOldSchemas(sr *stream.SchemasReplace) *backup.Schemas { } return schemas } + +func CheckNewCollationEnable( + backupNewCollationEnable string, + g glue.Glue, + storage kv.Storage, + CheckRequirements bool, +) error { + if backupNewCollationEnable == "" { + if CheckRequirements { + return errors.Annotatef(berrors.ErrUnknown, + "the config 'new_collations_enabled_on_first_bootstrap' not found in backupmeta. "+ + "you can use \"show config WHERE name='new_collations_enabled_on_first_bootstrap';\" to manually check the config. "+ + "if you ensure the config 'new_collations_enabled_on_first_bootstrap' in backup cluster is as same as restore cluster, "+ + "use --check-requirements=false to skip this check") + } + log.Warn("the config 'new_collations_enabled_on_first_bootstrap' is not in backupmeta") + return nil + } + + se, err := g.CreateSession(storage) + if err != nil { + return errors.Trace(err) + } + + newCollationEnable, err := se.GetGlobalVariable(utils.GetTidbNewCollationEnabled()) + if err != nil { + return errors.Trace(err) + } + + if !strings.EqualFold(backupNewCollationEnable, newCollationEnable) { + return errors.Annotatef(berrors.ErrUnknown, + "the config 'new_collations_enabled_on_first_bootstrap' not match, upstream:%v, downstream: %v", + backupNewCollationEnable, newCollationEnable) + } + + // collate.newCollationEnabled is set to 1 when the collate package is initialized, + // so we need to modify this value according to the config of the cluster + // before using the collate package. + enabled := newCollationEnable == "True" + // modify collate.newCollationEnabled according to the config of the cluster + collate.SetNewCollationEnabledForTest(enabled) + log.Info("set new_collation_enabled", zap.Bool("new_collation_enabled", enabled)) + return nil +} + +type waitTiFlashBackoffer struct { + Attempts int + BaseBackoff time.Duration +} + +// NextBackoff returns a duration to wait before retrying again +func (b *waitTiFlashBackoffer) NextBackoff(error) time.Duration { + bo := b.BaseBackoff + b.Attempts-- + if b.Attempts == 0 { + return 0 + } + b.BaseBackoff *= 2 + if b.BaseBackoff > 32*time.Second { + b.BaseBackoff = 32 * time.Second + } + return bo +} + +// Attempt returns the remain attempt times +func (b *waitTiFlashBackoffer) Attempt() int { + return b.Attempts +} diff --git a/br/pkg/restore/client_test.go b/br/pkg/restore/client_test.go index f44eff5d36b67..ae943a96f276b 100644 --- a/br/pkg/restore/client_test.go +++ b/br/pkg/restore/client_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/pingcap/errors" "github.com/pingcap/failpoint" backuppb "github.com/pingcap/kvproto/pkg/brpb" "github.com/pingcap/kvproto/pkg/import_sstpb" @@ -24,6 +25,7 @@ import ( "github.com/pingcap/tidb/br/pkg/restore/tiflashrec" "github.com/pingcap/tidb/br/pkg/stream" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/br/pkg/utils/iter" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/types" @@ -193,32 +195,33 @@ func TestCheckSysTableCompatibility(t *testing.T) { userTI, err := client.GetTableSchema(cluster.Domain, sysDB, model.NewCIStr("user")) require.NoError(t, err) - // column count mismatch + // user table in cluster have more columns(success) mockedUserTI := userTI.Clone() - mockedUserTI.Columns = mockedUserTI.Columns[:len(mockedUserTI.Columns)-1] + userTI.Columns = append(userTI.Columns, &model.ColumnInfo{Name: model.NewCIStr("new-name")}) err = client.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{ DB: tmpSysDB, Info: mockedUserTI, }}) - require.True(t, berrors.ErrRestoreIncompatibleSys.Equal(err)) + require.NoError(t, err) + userTI.Columns = userTI.Columns[:len(userTI.Columns)-1] - // column order mismatch(success) + // user table in cluster have less columns(failed) mockedUserTI = userTI.Clone() - mockedUserTI.Columns[4], mockedUserTI.Columns[5] = mockedUserTI.Columns[5], mockedUserTI.Columns[4] + mockedUserTI.Columns = append(mockedUserTI.Columns, &model.ColumnInfo{Name: model.NewCIStr("new-name")}) err = client.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{ DB: tmpSysDB, Info: mockedUserTI, }}) - require.NoError(t, err) + require.True(t, berrors.ErrRestoreIncompatibleSys.Equal(err)) - // missing column + // column order mismatch(success) mockedUserTI = userTI.Clone() - mockedUserTI.Columns[0].Name = model.NewCIStr("new-name") + mockedUserTI.Columns[4], mockedUserTI.Columns[5] = mockedUserTI.Columns[5], mockedUserTI.Columns[4] err = client.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{ DB: tmpSysDB, Info: mockedUserTI, }}) - require.True(t, berrors.ErrRestoreIncompatibleSys.Equal(err)) + require.NoError(t, err) // incompatible column type mockedUserTI = userTI.Clone() @@ -236,6 +239,19 @@ func TestCheckSysTableCompatibility(t *testing.T) { Info: mockedUserTI, }}) require.NoError(t, err) + + // use the mysql.db table to test for column count mismatch. + dbTI, err := client.GetTableSchema(cluster.Domain, sysDB, model.NewCIStr("db")) + require.NoError(t, err) + + // other system tables in cluster have more columns(failed) + mockedDBTI := dbTI.Clone() + dbTI.Columns = append(dbTI.Columns, &model.ColumnInfo{Name: model.NewCIStr("new-name")}) + err = client.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{ + DB: tmpSysDB, + Info: mockedDBTI, + }}) + require.True(t, berrors.ErrRestoreIncompatibleSys.Equal(err)) } func TestInitFullClusterRestore(t *testing.T) { @@ -330,12 +346,53 @@ func TestPreCheckTableClusterIndex(t *testing.T) { type fakePDClient struct { pd.Client stores []*metapb.Store + + notLeader bool + retryTimes *int } func (fpdc fakePDClient) GetAllStores(context.Context, ...pd.GetStoreOption) ([]*metapb.Store, error) { return append([]*metapb.Store{}, fpdc.stores...), nil } +func (fpdc fakePDClient) GetTS(ctx context.Context) (int64, int64, error) { + (*fpdc.retryTimes)++ + if *fpdc.retryTimes >= 3 { // the mock PD leader switched successfully + fpdc.notLeader = false + } + + if fpdc.notLeader { + return 0, 0, errors.Errorf("rpc error: code = Unknown desc = [PD:tso:ErrGenerateTimestamp]generate timestamp failed, requested pd is not leader of cluster") + } + return 1, 1, nil +} + +func TestGetTSWithRetry(t *testing.T) { + t.Run("PD leader is healthy:", func(t *testing.T) { + retryTimes := -1000 + pDClient := fakePDClient{notLeader: false, retryTimes: &retryTimes} + client := restore.NewRestoreClient(pDClient, nil, defaultKeepaliveCfg, false) + _, err := client.GetTSWithRetry(context.Background()) + require.NoError(t, err) + }) + + t.Run("PD leader failure:", func(t *testing.T) { + retryTimes := -1000 + pDClient := fakePDClient{notLeader: true, retryTimes: &retryTimes} + client := restore.NewRestoreClient(pDClient, nil, defaultKeepaliveCfg, false) + _, err := client.GetTSWithRetry(context.Background()) + require.Error(t, err) + }) + + t.Run("PD leader switch successfully", func(t *testing.T) { + retryTimes := 0 + pDClient := fakePDClient{notLeader: true, retryTimes: &retryTimes} + client := restore.NewRestoreClient(pDClient, nil, defaultKeepaliveCfg, false) + _, err := client.GetTSWithRetry(context.Background()) + require.NoError(t, err) + }) +} + func TestPreCheckTableTiFlashReplicas(t *testing.T) { m := mc mockStores := []*metapb.Store{ @@ -1053,3 +1110,458 @@ func TestSortMetaKVFiles(t *testing.T) { require.Equal(t, files[3].Path, "f4") require.Equal(t, files[4].Path, "f5") } + +func TestApplyKVFilesWithSingelMethod(t *testing.T) { + var ( + totalKVCount int64 = 0 + totalSize uint64 = 0 + logs = make([]string, 0) + ) + ds := []*backuppb.DataFileInfo{ + { + Path: "log3", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Delete, + }, + { + Path: "log1", + NumberOfEntries: 5, + Length: 100, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + }, { + Path: "log2", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + }, + } + applyFunc := func( + files []*backuppb.DataFileInfo, + kvCount int64, + size uint64, + ) { + totalKVCount += kvCount + totalSize += size + for _, f := range files { + logs = append(logs, f.GetPath()) + } + } + + restore.ApplyKVFilesWithSingelMethod( + context.TODO(), + iter.FromSlice(ds), + applyFunc, + ) + + require.Equal(t, totalKVCount, int64(15)) + require.Equal(t, totalSize, uint64(300)) + require.Equal(t, logs, []string{"log1", "log2", "log3"}) +} + +func TestApplyKVFilesWithBatchMethod1(t *testing.T) { + var ( + runCount = 0 + batchCount int = 3 + batchSize uint64 = 1000 + totalKVCount int64 = 0 + logs = make([][]string, 0) + ) + ds := []*backuppb.DataFileInfo{ + { + Path: "log5", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Delete, + RegionId: 1, + }, { + Path: "log3", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, { + Path: "log4", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, { + Path: "log1", + NumberOfEntries: 5, + Length: 800, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, + { + Path: "log2", + NumberOfEntries: 5, + Length: 200, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, + } + applyFunc := func( + files []*backuppb.DataFileInfo, + kvCount int64, + size uint64, + ) { + runCount += 1 + totalKVCount += kvCount + log := make([]string, 0, len(files)) + for _, f := range files { + log = append(log, f.GetPath()) + } + logs = append(logs, log) + } + + restore.ApplyKVFilesWithBatchMethod( + context.TODO(), + iter.FromSlice(ds), + batchCount, + batchSize, + applyFunc, + ) + + require.Equal(t, runCount, 3) + require.Equal(t, totalKVCount, int64(25)) + require.Equal(t, + logs, + [][]string{ + {"log1", "log2"}, + {"log3", "log4"}, + {"log5"}, + }, + ) +} + +func TestApplyKVFilesWithBatchMethod2(t *testing.T) { + var ( + runCount = 0 + batchCount int = 2 + batchSize uint64 = 1500 + totalKVCount int64 = 0 + logs = make([][]string, 0) + ) + ds := []*backuppb.DataFileInfo{ + { + Path: "log1", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Delete, + RegionId: 1, + }, { + Path: "log2", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, { + Path: "log3", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, { + Path: "log4", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, { + Path: "log5", + NumberOfEntries: 5, + Length: 800, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, + { + Path: "log6", + NumberOfEntries: 5, + Length: 200, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, + } + applyFunc := func( + files []*backuppb.DataFileInfo, + kvCount int64, + size uint64, + ) { + runCount += 1 + totalKVCount += kvCount + log := make([]string, 0, len(files)) + for _, f := range files { + log = append(log, f.GetPath()) + } + logs = append(logs, log) + } + + restore.ApplyKVFilesWithBatchMethod( + context.TODO(), + iter.FromSlice(ds), + batchCount, + batchSize, + applyFunc, + ) + + require.Equal(t, runCount, 4) + require.Equal(t, totalKVCount, int64(30)) + require.Equal(t, + logs, + [][]string{ + {"log2", "log3"}, + {"log5", "log6"}, + {"log4"}, + {"log1"}, + }, + ) +} + +func TestApplyKVFilesWithBatchMethod3(t *testing.T) { + var ( + runCount = 0 + batchCount int = 2 + batchSize uint64 = 1500 + totalKVCount int64 = 0 + logs = make([][]string, 0) + ) + ds := []*backuppb.DataFileInfo{ + { + Path: "log1", + NumberOfEntries: 5, + Length: 2000, + Cf: stream.WriteCF, + Type: backuppb.FileType_Delete, + RegionId: 1, + }, { + Path: "log2", + NumberOfEntries: 5, + Length: 2000, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, { + Path: "log3", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + RegionId: 1, + }, { + Path: "log5", + NumberOfEntries: 5, + Length: 800, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + RegionId: 3, + }, + { + Path: "log6", + NumberOfEntries: 5, + Length: 200, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + RegionId: 3, + }, + } + applyFunc := func( + files []*backuppb.DataFileInfo, + kvCount int64, + size uint64, + ) { + runCount += 1 + totalKVCount += kvCount + log := make([]string, 0, len(files)) + for _, f := range files { + log = append(log, f.GetPath()) + } + logs = append(logs, log) + } + + restore.ApplyKVFilesWithBatchMethod( + context.TODO(), + iter.FromSlice(ds), + batchCount, + batchSize, + applyFunc, + ) + + require.Equal(t, totalKVCount, int64(25)) + require.Equal(t, + logs, + [][]string{ + {"log2"}, + {"log5", "log6"}, + {"log3"}, + {"log1"}, + }, + ) +} + +func TestApplyKVFilesWithBatchMethod4(t *testing.T) { + var ( + runCount = 0 + batchCount int = 2 + batchSize uint64 = 1500 + totalKVCount int64 = 0 + logs = make([][]string, 0) + ) + ds := []*backuppb.DataFileInfo{ + { + Path: "log1", + NumberOfEntries: 5, + Length: 2000, + Cf: stream.WriteCF, + Type: backuppb.FileType_Delete, + TableId: 1, + }, { + Path: "log2", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + TableId: 1, + }, { + Path: "log3", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + TableId: 2, + }, { + Path: "log4", + NumberOfEntries: 5, + Length: 100, + Cf: stream.WriteCF, + Type: backuppb.FileType_Put, + TableId: 1, + }, { + Path: "log5", + NumberOfEntries: 5, + Length: 100, + Cf: stream.DefaultCF, + Type: backuppb.FileType_Put, + TableId: 2, + }, + } + applyFunc := func( + files []*backuppb.DataFileInfo, + kvCount int64, + size uint64, + ) { + runCount += 1 + totalKVCount += kvCount + log := make([]string, 0, len(files)) + for _, f := range files { + log = append(log, f.GetPath()) + } + logs = append(logs, log) + } + + restore.ApplyKVFilesWithBatchMethod( + context.TODO(), + iter.FromSlice(ds), + batchCount, + batchSize, + applyFunc, + ) + + require.Equal(t, runCount, 4) + require.Equal(t, totalKVCount, int64(25)) + require.Equal(t, + logs, + [][]string{ + {"log2", "log4"}, + {"log5"}, + {"log3"}, + {"log1"}, + }, + ) +} + +func TestCheckNewCollationEnable(t *testing.T) { + caseList := []struct { + backupMeta *backuppb.BackupMeta + newCollationEnableInCluster string + CheckRequirements bool + isErr bool + }{ + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: "True"}, + newCollationEnableInCluster: "True", + CheckRequirements: true, + isErr: false, + }, + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: "True"}, + newCollationEnableInCluster: "False", + CheckRequirements: true, + isErr: true, + }, + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: "False"}, + newCollationEnableInCluster: "True", + CheckRequirements: true, + isErr: true, + }, + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: "False"}, + newCollationEnableInCluster: "false", + CheckRequirements: true, + isErr: false, + }, + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: "False"}, + newCollationEnableInCluster: "True", + CheckRequirements: false, + isErr: true, + }, + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: "True"}, + newCollationEnableInCluster: "False", + CheckRequirements: false, + isErr: true, + }, + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: ""}, + newCollationEnableInCluster: "True", + CheckRequirements: false, + isErr: false, + }, + { + backupMeta: &backuppb.BackupMeta{NewCollationsEnabled: ""}, + newCollationEnableInCluster: "True", + CheckRequirements: true, + isErr: true, + }, + } + + for i, ca := range caseList { + g := &gluetidb.MockGlue{ + GlobalVars: map[string]string{"new_collation_enabled": ca.newCollationEnableInCluster}, + } + err := restore.CheckNewCollationEnable(ca.backupMeta.GetNewCollationsEnabled(), g, nil, ca.CheckRequirements) + + t.Logf("[%d] Got Error: %v\n", i, err) + if ca.isErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + } +} diff --git a/br/pkg/restore/data.go b/br/pkg/restore/data.go index 73ef3130f2a20..b4ed1c1144dd8 100644 --- a/br/pkg/restore/data.go +++ b/br/pkg/restore/data.go @@ -4,6 +4,7 @@ package restore import ( "context" "io" + "sync/atomic" "github.com/pingcap/errors" "github.com/pingcap/kvproto/pkg/metapb" @@ -13,7 +14,11 @@ import ( "github.com/pingcap/tidb/br/pkg/conn" "github.com/pingcap/tidb/br/pkg/glue" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/util/mathutil" + tikvstore "github.com/tikv/client-go/v2/kv" + "github.com/tikv/client-go/v2/tikv" + "github.com/tikv/client-go/v2/txnkv/rangetask" "go.uber.org/zap" "golang.org/x/sync/errgroup" "google.golang.org/grpc" @@ -25,9 +30,10 @@ import ( // 2. make recovery plan and then recovery max allocate ID firstly // 3. send the recover plan and the wait tikv to apply, in waitapply, all assigned region leader will check apply log to the last log // 4. ensure all region apply to last log -// 5. send the resolvedTs to tikv for deleting data. -func RecoverData(ctx context.Context, resolvedTs uint64, allStores []*metapb.Store, mgr *conn.Mgr, progress glue.Progress) (int, error) { - var recovery = NewRecovery(allStores, mgr, progress) +// 5. prepare the flashback +// 6. flashback to resolveTS +func RecoverData(ctx context.Context, resolveTS uint64, allStores []*metapb.Store, mgr *conn.Mgr, progress glue.Progress, restoreTS uint64, concurrency uint32) (int, error) { + var recovery = NewRecovery(allStores, mgr, progress, concurrency) if err := recovery.ReadRegionMeta(ctx); err != nil { return 0, errors.Trace(err) } @@ -51,7 +57,11 @@ func RecoverData(ctx context.Context, resolvedTs uint64, allStores []*metapb.Sto return totalRegions, errors.Trace(err) } - if err := recovery.ResolveData(ctx, resolvedTs); err != nil { + if err := recovery.PrepareFlashbackToVersion(ctx, resolveTS, restoreTS-1); err != nil { + return totalRegions, errors.Trace(err) + } + + if err := recovery.FlashbackToVersion(ctx, resolveTS, restoreTS); err != nil { return totalRegions, errors.Trace(err) } @@ -70,33 +80,36 @@ func NewStoreMeta(storeId uint64) StoreMeta { // for test type Recovery struct { - allStores []*metapb.Store - StoreMetas []StoreMeta - RecoveryPlan map[uint64][]*recovpb.RecoverRegionRequest - MaxAllocID uint64 - mgr *conn.Mgr - progress glue.Progress + allStores []*metapb.Store + StoreMetas []StoreMeta + RecoveryPlan map[uint64][]*recovpb.RecoverRegionRequest + MaxAllocID uint64 + mgr *conn.Mgr + progress glue.Progress + concurrency uint32 + totalFlashbackRegions uint64 } -func NewRecovery(allStores []*metapb.Store, mgr *conn.Mgr, progress glue.Progress) Recovery { +func NewRecovery(allStores []*metapb.Store, mgr *conn.Mgr, progress glue.Progress, concurrency uint32) Recovery { totalStores := len(allStores) var StoreMetas = make([]StoreMeta, totalStores) var regionRecovers = make(map[uint64][]*recovpb.RecoverRegionRequest, totalStores) return Recovery{ - allStores: allStores, - StoreMetas: StoreMetas, - RecoveryPlan: regionRecovers, - MaxAllocID: 0, - mgr: mgr, - progress: progress} + allStores: allStores, + StoreMetas: StoreMetas, + RecoveryPlan: regionRecovers, + MaxAllocID: 0, + mgr: mgr, + progress: progress, + concurrency: concurrency, + totalFlashbackRegions: 0} } func (recovery *Recovery) newRecoveryClient(ctx context.Context, storeAddr string) (recovpb.RecoverDataClient, *grpc.ClientConn, error) { // Connect to the Recovery service on the given TiKV node. bfConf := backoff.DefaultConfig bfConf.MaxDelay = gRPCBackOffMaxDelay - //TODO: connection may need some adjust - //keepaliveConf keepalive.ClientParameters + conn, err := utils.GRPCConn(ctx, storeAddr, recovery.mgr.GetTLSConfig(), grpc.WithConnectParams(grpc.ConnectParams{Backoff: bfConf}), grpc.WithKeepaliveParams(recovery.mgr.GetKeepalive()), @@ -190,8 +203,6 @@ func (recovery *Recovery) ReadRegionMeta(ctx context.Context) error { return eg.Wait() } -// TODO: map may be more suitable for this function - func (recovery *Recovery) GetTotalRegions() int { // Group region peer info by region id. var regions = make(map[uint64]struct{}, 0) @@ -292,51 +303,63 @@ func (recovery *Recovery) WaitApply(ctx context.Context) (err error) { return eg.Wait() } -// ResolveData a worker pool to all tikv for execute delete all data whose has ts > resolvedTs -func (recovery *Recovery) ResolveData(ctx context.Context, resolvedTs uint64) (err error) { - eg, ectx := errgroup.WithContext(ctx) - totalStores := len(recovery.allStores) - workers := utils.NewWorkerPool(uint(mathutil.Min(totalStores, common.MaxStoreConcurrency)), "resolve data from tikv") +// prepare the region for flashback the data, the purpose is to stop region service, put region in flashback state +func (recovery *Recovery) PrepareFlashbackToVersion(ctx context.Context, resolveTS uint64, startTS uint64) (err error) { + var totalRegions atomic.Uint64 + totalRegions.Store(0) - // TODO: what if the resolved data take long time take long time?, it look we need some handling here, at least some retry may necessary - // TODO: what if the network disturbing, a retry machanism may need here - for _, store := range recovery.allStores { - if err := ectx.Err(); err != nil { - break - } - storeAddr := getStoreAddress(recovery.allStores, store.Id) - storeId := store.Id - workers.ApplyOnErrorGroup(eg, func() error { - recoveryClient, conn, err := recovery.newRecoveryClient(ectx, storeAddr) - if err != nil { - return errors.Trace(err) - } - defer conn.Close() - log.Info("resolve data to tikv", zap.String("tikv address", storeAddr), zap.Uint64("store id", storeId)) - req := &recovpb.ResolveKvDataRequest{ResolvedTs: resolvedTs} - stream, err := recoveryClient.ResolveKvData(ectx, req) - if err != nil { - log.Error("send the resolve kv data failed", zap.Uint64("store id", storeId)) - return errors.Trace(err) - } - // for a TiKV, received the stream - for { - var resp *recovpb.ResolveKvDataResponse - if resp, err = stream.Recv(); err == nil { - log.Info("current delete key", zap.Uint64("resolved key num", resp.ResolvedKeyCount), zap.Uint64("store id", resp.StoreId)) - } else if err == io.EOF { - break - } else { - return errors.Trace(err) - } - } - recovery.progress.Inc() - log.Info("resolve kv data done", zap.String("tikv address", storeAddr), zap.Uint64("store id", storeId)) - return nil - }) + handler := func(ctx context.Context, r tikvstore.KeyRange) (rangetask.TaskStat, error) { + stats, err := ddl.SendPrepareFlashbackToVersionRPC(ctx, recovery.mgr.GetStorage().(tikv.Storage), resolveTS, startTS, r) + totalRegions.Add(uint64(stats.CompletedRegions)) + return stats, err } - // Wait for all TiKV instances force leader and wait apply to last log. - return eg.Wait() + + runner := rangetask.NewRangeTaskRunner("br-flashback-prepare-runner", recovery.mgr.GetStorage().(tikv.Storage), int(recovery.concurrency), handler) + // Run prepare flashback on the entire TiKV cluster. Empty keys means the range is unbounded. + err = runner.RunOnRange(ctx, []byte(""), []byte("")) + if err != nil { + log.Error("region flashback prepare get error") + return errors.Trace(err) + } + + recovery.totalFlashbackRegions = totalRegions.Load() + log.Info("region flashback prepare complete", zap.Int("regions", runner.CompletedRegions())) + + return nil +} + +// flashback the region data to version resolveTS +func (recovery *Recovery) FlashbackToVersion(ctx context.Context, resolveTS uint64, commitTS uint64) (err error) { + var completedRegions atomic.Uint64 + + // only know the total progress of tikv, progress is total state of the whole restore flow. + ratio := int(recovery.totalFlashbackRegions) / len(recovery.allStores) + + handler := func(ctx context.Context, r tikvstore.KeyRange) (rangetask.TaskStat, error) { + stats, err := ddl.SendFlashbackToVersionRPC(ctx, recovery.mgr.GetStorage().(tikv.Storage), resolveTS, commitTS-1, commitTS, r) + completedRegions.Add(uint64(stats.CompletedRegions)) + return stats, err + } + + runner := rangetask.NewRangeTaskRunner("br-flashback-runner", recovery.mgr.GetStorage().(tikv.Storage), int(recovery.concurrency), handler) + // Run flashback on the entire TiKV cluster. Empty keys means the range is unbounded. + err = runner.RunOnRange(ctx, []byte(""), []byte("")) + if err != nil { + log.Error("region flashback get error", + zap.Uint64("resolveTS", resolveTS), + zap.Uint64("commitTS", commitTS), + zap.Int("regions", runner.CompletedRegions())) + return errors.Trace(err) + } + + recovery.progress.IncBy(int64(completedRegions.Load()) / int64(ratio)) + + log.Info("region flashback complete", + zap.Uint64("resolveTS", resolveTS), + zap.Uint64("commitTS", commitTS), + zap.Int("regions", runner.CompletedRegions())) + + return nil } type RecoverRegion struct { @@ -349,6 +372,7 @@ type RecoverRegion struct { // 2. build a leader list for all region during the tikv startup // 3. get max allocate id func (recovery *Recovery) MakeRecoveryPlan() error { + storeBalanceScore := make(map[uint64]int, len(recovery.allStores)) // Group region peer info by region id. find the max allocateId // region [id] [peer[0-n]] var regions = make(map[uint64][]*RecoverRegion, 0) @@ -387,16 +411,20 @@ func (recovery *Recovery) MakeRecoveryPlan() error { } } else { // Generate normal commands. - log.Debug("detected valid peer", zap.Uint64("region id", regionId)) - for i, peer := range peers { - log.Debug("make plan", zap.Uint64("store id", peer.StoreId), zap.Uint64("region id", peer.RegionId)) - plan := &recovpb.RecoverRegionRequest{RegionId: peer.RegionId, AsLeader: i == 0} - // sorted by log term -> last index -> commit index in a region - if plan.AsLeader { - log.Debug("as leader peer", zap.Uint64("store id", peer.StoreId), zap.Uint64("region id", peer.RegionId)) - recovery.RecoveryPlan[peer.StoreId] = append(recovery.RecoveryPlan[peer.StoreId], plan) - } + log.Debug("detected valid region", zap.Uint64("region id", regionId)) + // calc the leader candidates + leaderCandidates, err := LeaderCandidates(peers) + if err != nil { + log.Warn("region without peer", zap.Uint64("region id", regionId)) + return errors.Trace(err) } + + // select the leader base on tikv storeBalanceScore + leader := SelectRegionLeader(storeBalanceScore, leaderCandidates) + log.Debug("as leader peer", zap.Uint64("store id", leader.StoreId), zap.Uint64("region id", leader.RegionId)) + plan := &recovpb.RecoverRegionRequest{RegionId: leader.RegionId, AsLeader: true} + recovery.RecoveryPlan[leader.StoreId] = append(recovery.RecoveryPlan[leader.StoreId], plan) + storeBalanceScore[leader.StoreId] += 1 } } return nil diff --git a/br/pkg/restore/data_test.go b/br/pkg/restore/data_test.go index a864494249308..bb85ab1c6e7a4 100644 --- a/br/pkg/restore/data_test.go +++ b/br/pkg/restore/data_test.go @@ -97,7 +97,7 @@ func createDataSuite(t *testing.T) *testData { fakeProgress := mockGlue.StartProgress(ctx, "Restore Data", int64(numOnlineStore*3), false) - var recovery = restore.NewRecovery(createStores(), mockMgr, fakeProgress) + var recovery = restore.NewRecovery(createStores(), mockMgr, fakeProgress, 64) tikvClient.Close() return &testData{ ctx: ctx, diff --git a/br/pkg/restore/db.go b/br/pkg/restore/db.go index c761d53693364..1f3f5d949e26e 100644 --- a/br/pkg/restore/db.go +++ b/br/pkg/restore/db.go @@ -11,7 +11,9 @@ import ( "github.com/pingcap/log" "github.com/pingcap/tidb/br/pkg/glue" "github.com/pingcap/tidb/br/pkg/metautil" + prealloctableid "github.com/pingcap/tidb/br/pkg/restore/prealloc_table_id" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" @@ -24,7 +26,8 @@ import ( // DB is a TiDB instance, not thread-safe. type DB struct { - se glue.Session + se glue.Session + preallocedIDs *prealloctableid.PreallocIDs } type UniqueTableName struct { @@ -78,6 +81,10 @@ func NewDB(g glue.Glue, store kv.Storage, policyMode string) (*DB, bool, error) }, supportPolicy, nil } +func (db *DB) registerPreallocatedIDs(ids *prealloctableid.PreallocIDs) { + db.preallocedIDs = ids +} + // ExecDDL executes the query of a ddl job. func (db *DB) ExecDDL(ctx context.Context, ddlJob *model.Job) error { var err error @@ -272,6 +279,19 @@ func (db *DB) CreateTablePostRestore(ctx context.Context, table *metautil.Table, return nil } +func (db *DB) tableIDAllocFilter() ddl.AllocTableIDIf { + return func(ti *model.TableInfo) bool { + if db.preallocedIDs == nil { + return true + } + prealloced := db.preallocedIDs.PreallocedFor(ti) + if prealloced { + log.Info("reusing table ID", zap.Stringer("table", ti.Name)) + } + return !prealloced + } +} + // CreateTables execute a internal CREATE TABLES. func (db *DB) CreateTables(ctx context.Context, tables []*metautil.Table, ddlTables map[UniqueTableName]bool, supportPolicy bool, policyMap *sync.Map) error { @@ -288,8 +308,12 @@ func (db *DB) CreateTables(ctx context.Context, tables []*metautil.Table, return errors.Trace(err) } } + + if ttlInfo := table.Info.TTLInfo; ttlInfo != nil { + ttlInfo.Enable = false + } } - if err := batchSession.CreateTables(ctx, m); err != nil { + if err := batchSession.CreateTables(ctx, m, db.tableIDAllocFilter()); err != nil { return err } @@ -316,7 +340,11 @@ func (db *DB) CreateTable(ctx context.Context, table *metautil.Table, } } - err := db.se.CreateTable(ctx, table.DB.Name, table.Info) + if ttlInfo := table.Info.TTLInfo; ttlInfo != nil { + ttlInfo.Enable = false + } + + err := db.se.CreateTable(ctx, table.DB.Name, table.Info, db.tableIDAllocFilter()) if err != nil { log.Error("create table failed", zap.Stringer("db", table.DB.Name), diff --git a/br/pkg/restore/db_test.go b/br/pkg/restore/db_test.go index 8801a6af34727..3a5416501e4df 100644 --- a/br/pkg/restore/db_test.go +++ b/br/pkg/restore/db_test.go @@ -381,7 +381,7 @@ func TestGetExistedUserDBs(t *testing.T) { {Name: model.NewCIStr("mysql")}, {Name: model.NewCIStr("test")}, }, - nil, 1) + nil, nil, 1) require.Nil(t, err) dom.MockInfoCacheAndLoadInfoSchema(builder.Build()) dbs = restore.GetExistedUserDBs(dom) @@ -393,7 +393,7 @@ func TestGetExistedUserDBs(t *testing.T) { {Name: model.NewCIStr("test")}, {Name: model.NewCIStr("d1")}, }, - nil, 1) + nil, nil, 1) require.Nil(t, err) dom.MockInfoCacheAndLoadInfoSchema(builder.Build()) dbs = restore.GetExistedUserDBs(dom) @@ -409,7 +409,7 @@ func TestGetExistedUserDBs(t *testing.T) { State: model.StatePublic, }, }, - nil, 1) + nil, nil, 1) require.Nil(t, err) dom.MockInfoCacheAndLoadInfoSchema(builder.Build()) dbs = restore.GetExistedUserDBs(dom) diff --git a/br/pkg/restore/import.go b/br/pkg/restore/import.go index 0245add57554b..5004639c1a00d 100644 --- a/br/pkg/restore/import.go +++ b/br/pkg/restore/import.go @@ -6,6 +6,8 @@ import ( "bytes" "context" "crypto/tls" + "fmt" + "math/rand" "strings" "sync" "sync/atomic" @@ -24,8 +26,10 @@ import ( berrors "github.com/pingcap/tidb/br/pkg/errors" "github.com/pingcap/tidb/br/pkg/logutil" "github.com/pingcap/tidb/br/pkg/restore/split" + "github.com/pingcap/tidb/br/pkg/stream" "github.com/pingcap/tidb/br/pkg/summary" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/kv" pd "github.com/tikv/pd/client" "go.uber.org/multierr" "go.uber.org/zap" @@ -245,6 +249,8 @@ type FileImporter struct { rawStartKey []byte rawEndKey []byte supportMultiIngest bool + + cacheKey string } // NewFileImporter returns a new file importClient. @@ -259,6 +265,7 @@ func NewFileImporter( backend: backend, importClient: importClient, isRawKvMode: isRawKvMode, + cacheKey: fmt.Sprintf("BR-%s-%d", time.Now().Format("20060102150405"), rand.Int63()), } } @@ -332,14 +339,16 @@ func (importer *FileImporter) getKeyRangeForFiles( // Import tries to import a file. func (importer *FileImporter) ImportKVFileForRegion( ctx context.Context, - file *backuppb.DataFileInfo, + files []*backuppb.DataFileInfo, rule *RewriteRules, + shiftStartTS uint64, startTS uint64, restoreTS uint64, info *split.RegionInfo, + supportBatch bool, ) RPCResult { // Try to download file. - result := importer.downloadAndApplyKVFile(ctx, file, rule, info, startTS, restoreTS) + result := importer.downloadAndApplyKVFile(ctx, files, rule, info, shiftStartTS, startTS, restoreTS, supportBatch) if !result.OK() { errDownload := result.Err for _, e := range multierr.Errors(errDownload) { @@ -380,39 +389,85 @@ func (importer *FileImporter) ClearFiles(ctx context.Context, pdClient pd.Client return nil } +func FilterFilesByRegion( + files []*backuppb.DataFileInfo, + ranges []kv.KeyRange, + r *split.RegionInfo, +) ([]*backuppb.DataFileInfo, error) { + if len(files) != len(ranges) { + return nil, errors.Annotatef(berrors.ErrInvalidArgument, + "count of files no equals count of ranges, file-count:%v, ranges-count:%v", + len(files), len(ranges)) + } + + output := make([]*backuppb.DataFileInfo, 0, len(files)) + if r != nil && r.Region != nil { + for i, f := range files { + if bytes.Compare(r.Region.StartKey, ranges[i].EndKey) <= 0 && + (len(r.Region.EndKey) == 0 || bytes.Compare(r.Region.EndKey, ranges[i].StartKey) >= 0) { + output = append(output, f) + } + } + } else { + output = files + } + + return output, nil +} + // ImportKVFiles restores the kv events. func (importer *FileImporter) ImportKVFiles( ctx context.Context, - file *backuppb.DataFileInfo, + files []*backuppb.DataFileInfo, rule *RewriteRules, + shiftStartTS uint64, startTS uint64, restoreTS uint64, + supportBatch bool, ) error { - startTime := time.Now() - log.Debug("import kv files", zap.String("file", file.Path)) - startKey, endKey, err := GetRewriteEncodedKeys(file, rule) - if err != nil { - return errors.Trace(err) + var ( + startKey []byte + endKey []byte + ranges = make([]kv.KeyRange, len(files)) + err error + ) + + if !supportBatch && len(files) > 1 { + return errors.Annotatef(berrors.ErrInvalidArgument, + "do not support batch apply but files count:%v > 1", len(files)) + } + log.Debug("import kv files", zap.Int("batch file count", len(files))) + + for i, f := range files { + ranges[i].StartKey, ranges[i].EndKey, err = GetRewriteEncodedKeys(f, rule) + if err != nil { + return errors.Trace(err) + } + + if len(startKey) == 0 || bytes.Compare(ranges[i].StartKey, startKey) < 0 { + startKey = ranges[i].StartKey + } + if len(endKey) == 0 || bytes.Compare(ranges[i].EndKey, endKey) > 0 { + endKey = ranges[i].EndKey + } } log.Debug("rewrite file keys", - zap.String("name", file.Path), - logutil.Key("startKey", startKey), - logutil.Key("endKey", endKey)) + logutil.Key("startKey", startKey), logutil.Key("endKey", endKey)) - // This RetryState will retry 48 time, for 5 min - 6 min. - rs := utils.InitialRetryState(48, 100*time.Millisecond, 8*time.Second) + // This RetryState will retry 45 time, about 10 min. + rs := utils.InitialRetryState(45, 100*time.Millisecond, 15*time.Second) ctl := OverRegionsInRange(startKey, endKey, importer.metaClient, &rs) err = ctl.Run(ctx, func(ctx context.Context, r *split.RegionInfo) RPCResult { - return importer.ImportKVFileForRegion(ctx, file, rule, startTS, restoreTS, r) + subfiles, errFilter := FilterFilesByRegion(files, ranges, r) + if errFilter != nil { + return RPCResultFromError(errFilter) + } + if len(subfiles) == 0 { + return RPCResultOK() + } + return importer.ImportKVFileForRegion(ctx, subfiles, rule, shiftStartTS, startTS, restoreTS, r, supportBatch) }) - - log.Debug("download and apply file done", - zap.String("file", file.Path), - zap.Stringer("take", time.Since(startTime)), - logutil.Key("fileStart", file.StartKey), - logutil.Key("fileEnd", file.EndKey), - ) return errors.Trace(err) } @@ -586,6 +641,7 @@ func (importer *FileImporter) downloadSST( Name: file.GetName(), RewriteRule: rule, CipherInfo: cipher, + StorageCacheId: importer.cacheKey, } log.Debug("download SST", logutil.SSTMeta(&sstMeta), @@ -665,6 +721,7 @@ func (importer *FileImporter) downloadRawKVSST( RewriteRule: rule, IsRawKv: true, CipherInfo: cipher, + StorageCacheId: importer.cacheKey, } log.Debug("download SST", logutil.SSTMeta(&sstMeta), logutil.Region(regionInfo.Region)) @@ -801,41 +858,57 @@ func (importer *FileImporter) ingestSSTs( func (importer *FileImporter) downloadAndApplyKVFile( ctx context.Context, - file *backuppb.DataFileInfo, + files []*backuppb.DataFileInfo, rules *RewriteRules, regionInfo *split.RegionInfo, + shiftStartTS uint64, startTS uint64, restoreTS uint64, + supportBatch bool, ) RPCResult { leader := regionInfo.Leader if leader == nil { return RPCResultFromError(errors.Annotatef(berrors.ErrPDLeaderNotFound, "region id %d has no leader", regionInfo.Region.Id)) } - // Get the rewrite rule for the file. - fileRule := findMatchedRewriteRule(file, rules) - if fileRule == nil { - return RPCResultFromError(errors.Annotatef(berrors.ErrKVRewriteRuleNotFound, - "rewrite rule for file %+v not find (in %+v)", file, rules)) - } - rule := import_sstpb.RewriteRule{ - OldKeyPrefix: encodeKeyPrefix(fileRule.GetOldKeyPrefix()), - NewKeyPrefix: encodeKeyPrefix(fileRule.GetNewKeyPrefix()), - } - meta := &import_sstpb.KVMeta{ - Name: file.Path, - Cf: file.Cf, - RangeOffset: file.RangeOffset, - Length: file.Length, - RangeLength: file.RangeLength, - IsDelete: file.Type == backuppb.FileType_Delete, - StartSnapshotTs: startTS, - RestoreTs: restoreTS, - StartKey: regionInfo.Region.GetStartKey(), - EndKey: regionInfo.Region.GetEndKey(), - Sha256: file.GetSha256(), - CompressionType: file.CompressionType, + metas := make([]*import_sstpb.KVMeta, 0, len(files)) + rewriteRules := make([]*import_sstpb.RewriteRule, 0, len(files)) + + for _, file := range files { + // Get the rewrite rule for the file. + fileRule := findMatchedRewriteRule(file, rules) + if fileRule == nil { + return RPCResultFromError(errors.Annotatef(berrors.ErrKVRewriteRuleNotFound, + "rewrite rule for file %+v not find (in %+v)", file, rules)) + } + rule := import_sstpb.RewriteRule{ + OldKeyPrefix: encodeKeyPrefix(fileRule.GetOldKeyPrefix()), + NewKeyPrefix: encodeKeyPrefix(fileRule.GetNewKeyPrefix()), + } + + meta := &import_sstpb.KVMeta{ + Name: file.Path, + Cf: file.Cf, + RangeOffset: file.RangeOffset, + Length: file.Length, + RangeLength: file.RangeLength, + IsDelete: file.Type == backuppb.FileType_Delete, + StartTs: func() uint64 { + if file.Cf == stream.DefaultCF { + return shiftStartTS + } + return startTS + }(), + RestoreTs: restoreTS, + StartKey: regionInfo.Region.GetStartKey(), + EndKey: regionInfo.Region.GetEndKey(), + Sha256: file.GetSha256(), + CompressionType: file.CompressionType, + } + + metas = append(metas, meta) + rewriteRules = append(rewriteRules, &rule) } reqCtx := &kvrpcpb.Context{ @@ -844,12 +917,23 @@ func (importer *FileImporter) downloadAndApplyKVFile( Peer: leader, } - req := &import_sstpb.ApplyRequest{ - Meta: meta, - StorageBackend: importer.backend, - RewriteRule: rule, - Context: reqCtx, + var req *import_sstpb.ApplyRequest + if supportBatch { + req = &import_sstpb.ApplyRequest{ + Metas: metas, + StorageBackend: importer.backend, + RewriteRules: rewriteRules, + Context: reqCtx, + } + } else { + req = &import_sstpb.ApplyRequest{ + Meta: metas[0], + StorageBackend: importer.backend, + RewriteRule: *rewriteRules[0], + Context: reqCtx, + } } + log.Debug("apply kv file", logutil.Leader(leader)) resp, err := importer.importClient.ApplyKVFile(ctx, leader.GetStoreId(), req) if err != nil { diff --git a/br/pkg/restore/import_retry.go b/br/pkg/restore/import_retry.go index 7dcdb01a6c765..6f3b9fc1cca53 100644 --- a/br/pkg/restore/import_retry.go +++ b/br/pkg/restore/import_retry.go @@ -224,7 +224,8 @@ func (r *RPCResult) StrategyForRetryStoreError() RetryStrategy { if r.StoreError.GetServerIsBusy() != nil || r.StoreError.GetRegionNotInitialized() != nil || - r.StoreError.GetNotLeader() != nil { + r.StoreError.GetNotLeader() != nil || + r.StoreError.GetServerIsBusy() != nil { return StrategyFromThisRegion } diff --git a/br/pkg/restore/import_retry_test.go b/br/pkg/restore/import_retry_test.go index d79e2a317a4c0..6f3d8f490ef13 100644 --- a/br/pkg/restore/import_retry_test.go +++ b/br/pkg/restore/import_retry_test.go @@ -12,12 +12,15 @@ import ( "time" "github.com/pingcap/errors" + backuppb "github.com/pingcap/kvproto/pkg/brpb" "github.com/pingcap/kvproto/pkg/errorpb" "github.com/pingcap/kvproto/pkg/import_sstpb" "github.com/pingcap/kvproto/pkg/metapb" + berrors "github.com/pingcap/tidb/br/pkg/errors" "github.com/pingcap/tidb/br/pkg/restore" "github.com/pingcap/tidb/br/pkg/restore/split" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/store/pdtypes" "github.com/pingcap/tidb/util/codec" "github.com/stretchr/testify/require" @@ -127,6 +130,41 @@ func TestNotLeader(t *testing.T) { assertRegions(t, meetRegions, "", "aay", "bba", "bbh", "cca", "") } +func TestServerIsBusy(t *testing.T) { + // region: [, aay), [aay, bba), [bba, bbh), [bbh, cca), [cca, ) + cli := initTestClient(false) + rs := utils.InitialRetryState(2, 0, 0) + ctl := restore.OverRegionsInRange([]byte(""), []byte(""), cli, &rs) + ctx := context.Background() + + serverIsBusy := errorpb.Error{ + Message: "server is busy", + ServerIsBusy: &errorpb.ServerIsBusy{ + Reason: "memory is out", + }, + } + // record the regions we didn't touch. + meetRegions := []*split.RegionInfo{} + // record all regions we meet with id == 2. + idEqualsTo2Regions := []*split.RegionInfo{} + theFirstRun := true + err := ctl.Run(ctx, func(ctx context.Context, r *split.RegionInfo) restore.RPCResult { + if theFirstRun && r.Region.Id == 2 { + idEqualsTo2Regions = append(idEqualsTo2Regions, r) + theFirstRun = false + return restore.RPCResult{ + StoreError: &serverIsBusy, + } + } + meetRegions = append(meetRegions, r) + return restore.RPCResultOK() + }) + + require.NoError(t, err) + assertRegions(t, idEqualsTo2Regions, "aay", "bba") + assertRegions(t, meetRegions, "", "aay", "bba", "bbh", "cca", "") +} + func printRegion(name string, infos []*split.RegionInfo) { fmt.Printf(">>>>> %s <<<<<\n", name) for _, info := range infos { @@ -345,3 +383,166 @@ func TestPaginateScanLeader(t *testing.T) { }) assertRegions(t, collectedRegions, "", "aay", "bba") } + +func TestImportKVFiles(t *testing.T) { + var ( + importer = restore.FileImporter{} + ctx = context.Background() + shiftStartTS uint64 = 100 + startTS uint64 = 200 + restoreTS uint64 = 300 + ) + + err := importer.ImportKVFiles( + ctx, + []*backuppb.DataFileInfo{ + { + Path: "log3", + }, + { + Path: "log1", + }, + }, + nil, + shiftStartTS, + startTS, + restoreTS, + false, + ) + require.True(t, berrors.ErrInvalidArgument.Equal(err)) +} + +func TestFilterFilesByRegion(t *testing.T) { + files := []*backuppb.DataFileInfo{ + { + Path: "log1", + }, + { + Path: "log2", + }, + } + ranges := []kv.KeyRange{ + { + StartKey: []byte("1111"), + EndKey: []byte("2222"), + }, { + StartKey: []byte("3333"), + EndKey: []byte("4444"), + }, + } + + testCases := []struct { + r split.RegionInfo + subfiles []*backuppb.DataFileInfo + err error + }{ + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("0000"), + EndKey: []byte("1110"), + }, + }, + subfiles: []*backuppb.DataFileInfo{}, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("0000"), + EndKey: []byte("1111"), + }, + }, + subfiles: []*backuppb.DataFileInfo{ + files[0], + }, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("0000"), + EndKey: []byte("2222"), + }, + }, + subfiles: []*backuppb.DataFileInfo{ + files[0], + }, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("2222"), + EndKey: []byte("3332"), + }, + }, + subfiles: []*backuppb.DataFileInfo{ + files[0], + }, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("2223"), + EndKey: []byte("3332"), + }, + }, + subfiles: []*backuppb.DataFileInfo{}, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("3332"), + EndKey: []byte("3333"), + }, + }, + subfiles: []*backuppb.DataFileInfo{ + files[1], + }, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("4444"), + EndKey: []byte("5555"), + }, + }, + subfiles: []*backuppb.DataFileInfo{ + files[1], + }, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("4444"), + EndKey: nil, + }, + }, + subfiles: []*backuppb.DataFileInfo{ + files[1], + }, + err: nil, + }, + { + r: split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte("0000"), + EndKey: nil, + }, + }, + subfiles: files, + err: nil, + }, + } + + for _, c := range testCases { + subfile, err := restore.FilterFilesByRegion(files, ranges, &c.r) + require.Equal(t, err, c.err) + require.Equal(t, subfile, c.subfiles) + } +} diff --git a/br/pkg/restore/log_client.go b/br/pkg/restore/log_client.go new file mode 100644 index 0000000000000..cce295090ba02 --- /dev/null +++ b/br/pkg/restore/log_client.go @@ -0,0 +1,345 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package restore + +import ( + "bytes" + "context" + "crypto/sha256" + "strings" + "sync" + + "github.com/pingcap/errors" + backuppb "github.com/pingcap/kvproto/pkg/brpb" + "github.com/pingcap/log" + berrors "github.com/pingcap/tidb/br/pkg/errors" + "github.com/pingcap/tidb/br/pkg/storage" + "github.com/pingcap/tidb/br/pkg/stream" + "github.com/pingcap/tidb/br/pkg/utils/iter" + "github.com/pingcap/tidb/kv" + "go.uber.org/zap" +) + +const ( + readMetaConcurrency = 128 + readMetaBatchSize = 512 +) + +// MetaIter is the type of iterator of metadata files' content. +type MetaIter = iter.TryNextor[*backuppb.Metadata] + +// LogIter is the type of iterator of each log files' meta information. +type LogIter = iter.TryNextor[*backuppb.DataFileInfo] + +// MetaGroupIter is the iterator of flushes of metadata. +type MetaGroupIter = iter.TryNextor[DDLMetaGroup] + +// Meta is the metadata of files. +type Meta = *backuppb.Metadata + +// Log is the metadata of one file recording KV sequences. +type Log = *backuppb.DataFileInfo + +// logFileManager is the manager for log files of a certain restoration, +// which supports read / filter from the log backup archive with static start TS / restore TS. +type logFileManager struct { + // startTS and restoreTS are used for kv file restore. + // TiKV will filter the key space that don't belong to [startTS, restoreTS]. + startTS uint64 + restoreTS uint64 + + // If the commitTS of txn-entry belong to [startTS, restoreTS], + // the startTS of txn-entry may be smaller than startTS. + // We need maintain and restore more entries in default cf + // (the startTS in these entries belong to [shiftStartTS, startTS]). + shiftStartTS uint64 + + storage storage.ExternalStorage + helper *stream.MetadataHelper +} + +// LogFileManagerInit is the config needed for initializing the log file manager. +type LogFileManagerInit struct { + StartTS uint64 + RestoreTS uint64 + Storage storage.ExternalStorage +} + +type DDLMetaGroup struct { + Path string + FileMetas []*backuppb.DataFileInfo +} + +// CreateLogFileManager creates a log file manager using the specified config. +// Generally the config cannot be changed during its lifetime. +func CreateLogFileManager(ctx context.Context, init LogFileManagerInit) (*logFileManager, error) { + fm := &logFileManager{ + startTS: init.StartTS, + restoreTS: init.RestoreTS, + storage: init.Storage, + helper: stream.NewMetadataHelper(), + } + err := fm.loadShiftTS(ctx) + if err != nil { + return nil, err + } + return fm, nil +} + +func (rc *logFileManager) ShiftTS() uint64 { + return rc.shiftStartTS +} + +func (rc *logFileManager) loadShiftTS(ctx context.Context) error { + shiftTS := struct { + sync.Mutex + value uint64 + exists bool + }{} + err := stream.FastUnmarshalMetaData(ctx, rc.storage, func(path string, raw []byte) error { + m, err := rc.helper.ParseToMetadata(raw) + if err != nil { + return err + } + log.Info("read meta from storage and parse", zap.String("path", path), zap.Uint64("min-ts", m.MinTs), + zap.Uint64("max-ts", m.MaxTs), zap.Int32("meta-version", int32(m.MetaVersion))) + + ts, ok := UpdateShiftTS(m, rc.startTS, rc.restoreTS) + shiftTS.Lock() + if ok && (!shiftTS.exists || shiftTS.value > ts) { + shiftTS.value = ts + shiftTS.exists = true + } + shiftTS.Unlock() + + return nil + }) + if err != nil { + return err + } + if !shiftTS.exists { + rc.shiftStartTS = rc.startTS + return nil + } + rc.shiftStartTS = shiftTS.value + return nil +} + +func (rc *logFileManager) streamingMeta(ctx context.Context) (MetaIter, error) { + return rc.streamingMetaByTS(ctx, rc.restoreTS) +} + +func (rc *logFileManager) streamingMetaByTS(ctx context.Context, restoreTS uint64) (MetaIter, error) { + it, err := rc.createMetaIterOver(ctx, rc.storage) + if err != nil { + return nil, err + } + filtered := iter.FilterOut(it, func(metadata *backuppb.Metadata) bool { + return restoreTS < metadata.MinTs || metadata.MaxTs < rc.shiftStartTS + }) + return filtered, nil +} + +func (rc *logFileManager) createMetaIterOver(ctx context.Context, s storage.ExternalStorage) (MetaIter, error) { + opt := &storage.WalkOption{SubDir: stream.GetStreamBackupMetaPrefix()} + names := []string{} + err := s.WalkDir(ctx, opt, func(path string, size int64) error { + if !strings.HasSuffix(path, ".meta") { + return nil + } + names = append(names, path) + return nil + }) + if err != nil { + return nil, err + } + namesIter := iter.FromSlice(names) + readMeta := func(ctx context.Context, name string) (*backuppb.Metadata, error) { + f, err := s.ReadFile(ctx, name) + if err != nil { + return nil, errors.Annotatef(err, "failed during reading file %s", name) + } + meta, err := rc.helper.ParseToMetadata(f) + if err != nil { + return nil, errors.Annotatef(err, "failed to parse metadata of file %s", name) + } + return meta, nil + } + reader := iter.Transform(namesIter, readMeta, + iter.WithChunkSize(readMetaBatchSize), iter.WithConcurrency(readMetaConcurrency)) + return reader, nil +} + +func (rc *logFileManager) FilterDataFiles(ms MetaIter) LogIter { + return iter.FlatMap(ms, func(m *backuppb.Metadata) LogIter { + return iter.FlatMap(iter.FromSlice(m.FileGroups), func(g *backuppb.DataFileGroup) LogIter { + return iter.FilterOut(iter.FromSlice(g.DataFilesInfo), func(d *backuppb.DataFileInfo) bool { + // Modify the data internally, a little hacky. + if m.MetaVersion > backuppb.MetaVersion_V1 { + d.Path = g.Path + } + return d.IsMeta || rc.ShouldFilterOut(d) + }) + }) + }) +} + +// ShouldFilterOut checks whether a file should be filtered out via the current client. +func (rc *logFileManager) ShouldFilterOut(d *backuppb.DataFileInfo) bool { + return d.MinTs > rc.restoreTS || + (d.Cf == stream.WriteCF && d.MaxTs < rc.startTS) || + (d.Cf == stream.DefaultCF && d.MaxTs < rc.shiftStartTS) +} + +func (rc *logFileManager) collectDDLFilesAndPrepareCache( + ctx context.Context, + files MetaGroupIter, +) ([]Log, error) { + fs := iter.CollectAll(ctx, files) + if fs.Err != nil { + return nil, errors.Annotatef(fs.Err, "failed to collect from files") + } + + dataFileInfos := make([]*backuppb.DataFileInfo, 0) + for _, g := range fs.Item { + rc.helper.InitCacheEntry(g.Path, len(g.FileMetas)) + dataFileInfos = append(dataFileInfos, g.FileMetas...) + } + + return dataFileInfos, nil +} + +// LoadDDLFilesAndCountDMLFiles loads all DDL files needs to be restored in the restoration. +// At the same time, if the `counter` isn't nil, counting the DML file needs to be restored into `counter`. +// This function returns all DDL files needing directly because we need sort all of them. +func (rc *logFileManager) LoadDDLFilesAndCountDMLFiles(ctx context.Context, counter *int) ([]Log, error) { + m, err := rc.streamingMeta(ctx) + if err != nil { + return nil, err + } + if counter != nil { + m = iter.Tap(m, func(m Meta) { + for _, fg := range m.FileGroups { + for _, f := range fg.DataFilesInfo { + if !f.IsMeta && !rc.ShouldFilterOut(f) { + *counter += 1 + } + } + } + }) + } + mg := rc.FilterMetaFiles(m) + + return rc.collectDDLFilesAndPrepareCache(ctx, mg) +} + +// LoadDMLFiles loads all DML files needs to be restored in the restoration. +// This function returns a stream, because there are usually many DML files need to be restored. +func (rc *logFileManager) LoadDMLFiles(ctx context.Context) (LogIter, error) { + m, err := rc.streamingMeta(ctx) + if err != nil { + return nil, err + } + + mg := rc.FilterDataFiles(m) + return mg, nil +} + +// readStreamMetaByTS is used for streaming task. collect all meta file by TS, it is for test usage. +func (rc *logFileManager) readStreamMeta(ctx context.Context) ([]Meta, error) { + metas, err := rc.streamingMeta(ctx) + if err != nil { + return nil, err + } + r := iter.CollectAll(ctx, metas) + if r.Err != nil { + return nil, errors.Trace(r.Err) + } + return r.Item, nil +} + +func (rc *logFileManager) FilterMetaFiles(ms MetaIter) MetaGroupIter { + return iter.FlatMap(ms, func(m Meta) MetaGroupIter { + return iter.Map(iter.FromSlice(m.FileGroups), func(g *backuppb.DataFileGroup) DDLMetaGroup { + metas := iter.FilterOut(iter.FromSlice(g.DataFilesInfo), func(d Log) bool { + // Modify the data internally, a little hacky. + if m.MetaVersion > backuppb.MetaVersion_V1 { + d.Path = g.Path + } + return !d.IsMeta || rc.ShouldFilterOut(d) + }) + return DDLMetaGroup{ + Path: g.Path, + // NOTE: the metas iterator is pure. No context or cancel needs. + FileMetas: iter.CollectAll(context.Background(), metas).Item, + } + }) + }) +} + +// ReadAllEntries loads content of a log file, with filtering out no needed entries. +func (rc *logFileManager) ReadAllEntries( + ctx context.Context, + file Log, + filterTS uint64, +) ([]*KvEntryWithTS, []*KvEntryWithTS, error) { + kvEntries := make([]*KvEntryWithTS, 0) + nextKvEntries := make([]*KvEntryWithTS, 0) + + buff, err := rc.helper.ReadFile(ctx, file.Path, file.RangeOffset, file.RangeLength, file.CompressionType, rc.storage) + if err != nil { + return nil, nil, errors.Trace(err) + } + + if checksum := sha256.Sum256(buff); !bytes.Equal(checksum[:], file.GetSha256()) { + return nil, nil, errors.Annotatef(berrors.ErrInvalidMetaFile, + "checksum mismatch expect %x, got %x", file.GetSha256(), checksum[:]) + } + + iter := stream.NewEventIterator(buff) + for iter.Valid() { + iter.Next() + if iter.GetError() != nil { + return nil, nil, errors.Trace(iter.GetError()) + } + + txnEntry := kv.Entry{Key: iter.Key(), Value: iter.Value()} + + if !stream.MaybeDBOrDDLJobHistoryKey(txnEntry.Key) { + // only restore mDB and mDDLHistory + continue + } + + ts, err := GetKeyTS(txnEntry.Key) + if err != nil { + return nil, nil, errors.Trace(err) + } + + // The commitTs in write CF need be limited on [startTs, restoreTs]. + // We can restore more key-value in default CF. + if ts > rc.restoreTS { + continue + } else if file.Cf == stream.WriteCF && ts < rc.startTS { + continue + } else if file.Cf == stream.DefaultCF && ts < rc.shiftStartTS { + continue + } + + if len(txnEntry.Value) == 0 { + // we might record duplicated prewrite keys in some conor cases. + // the first prewrite key has the value but the second don't. + // so we can ignore the empty value key. + // see details at https://github.com/pingcap/tiflow/issues/5468. + log.Warn("txn entry is null", zap.Uint64("key-ts", ts), zap.ByteString("tnxKey", txnEntry.Key)) + continue + } + + if ts < filterTS { + kvEntries = append(kvEntries, &KvEntryWithTS{e: txnEntry, ts: ts}) + } else { + nextKvEntries = append(nextKvEntries, &KvEntryWithTS{e: txnEntry, ts: ts}) + } + } + + return kvEntries, nextKvEntries, nil +} diff --git a/br/pkg/restore/log_client_test.go b/br/pkg/restore/log_client_test.go index b6240819dad71..71db52cf7678f 100644 --- a/br/pkg/restore/log_client_test.go +++ b/br/pkg/restore/log_client_test.go @@ -11,6 +11,8 @@ import ( "math" "os" "path" + "sort" + "strings" "sync/atomic" "testing" @@ -19,6 +21,7 @@ import ( "github.com/pingcap/log" "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/br/pkg/stream" + "github.com/pingcap/tidb/br/pkg/utils/iter" "github.com/stretchr/testify/require" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -26,8 +29,22 @@ import ( var id uint64 -// wd is the shortcut for making a fake data file from write CF. -func wd(start, end uint64, minBegin uint64) *backuppb.DataFileInfo { +type metaMaker = func(files ...*backuppb.DataFileInfo) *backuppb.Metadata + +func wm(start, end, minBegin uint64) *backuppb.DataFileInfo { + i := wr(start, end, minBegin) + i.IsMeta = true + return i +} + +func dm(start, end uint64) *backuppb.DataFileInfo { + i := dr(start, end) + i.IsMeta = true + return i +} + +// wr is the shortcut for making a fake data file from write CF. +func wr(start, end uint64, minBegin uint64) *backuppb.DataFileInfo { id := atomic.AddUint64(&id, 1) return &backuppb.DataFileInfo{ Path: fmt.Sprintf("default-%06d", id), @@ -38,8 +55,8 @@ func wd(start, end uint64, minBegin uint64) *backuppb.DataFileInfo { } } -// dd is the shortcut for making a fake data file from default CF. -func dd(start, end uint64) *backuppb.DataFileInfo { +// dr is the shortcut for making a fake data file from default CF. +func dr(start, end uint64) *backuppb.DataFileInfo { id := atomic.AddUint64(&id, 1) return &backuppb.DataFileInfo{ Path: fmt.Sprintf("write-%06d", id), @@ -76,12 +93,14 @@ func m2(files ...*backuppb.DataFileInfo) *backuppb.Metadata { MinTs: uint64(math.MaxUint64), MetaVersion: backuppb.MetaVersion_V2, } - fileGroups := &backuppb.DataFileGroup{} + fileGroups := &backuppb.DataFileGroup{ + MinTs: uint64(math.MaxUint64), + } for _, file := range files { - if meta.MaxTs < file.MaxTs { + if fileGroups.MaxTs < file.MaxTs { fileGroups.MaxTs = file.MaxTs } - if meta.MinTs > file.MinTs { + if fileGroups.MinTs > file.MinTs { fileGroups.MinTs = file.MinTs } fileGroups.DataFilesInfo = append(fileGroups.DataFilesInfo, file) @@ -138,7 +157,7 @@ func (b *mockMetaBuilder) b(useV2 bool) (*storage.LocalStorage, string) { return s, path } -func TestReadMetaBetweenTS(t *testing.T) { +func testReadMetaBetweenTSWithVersion(t *testing.T, m metaMaker) { log.SetLevel(zapcore.DebugLevel) type Case struct { items []*backuppb.Metadata @@ -151,9 +170,9 @@ func TestReadMetaBetweenTS(t *testing.T) { cases := []Case{ { items: []*backuppb.Metadata{ - m(wd(4, 10, 3), wd(5, 13, 5)), - m(dd(1, 3)), - m(wd(10, 42, 9), dd(6, 9)), + m(wr(4, 10, 3), wr(5, 13, 5)), + m(dr(1, 3)), + m(wr(10, 42, 9), dr(6, 9)), }, startTS: 4, endTS: 5, @@ -162,8 +181,8 @@ func TestReadMetaBetweenTS(t *testing.T) { }, { items: []*backuppb.Metadata{ - m(wd(1, 100, 1), wd(5, 13, 5), dd(1, 101)), - m(wd(100, 200, 98), dd(100, 200)), + m(wr(1, 100, 1), wr(5, 13, 5), dr(1, 101)), + m(wr(100, 200, 98), dr(100, 200)), }, startTS: 50, endTS: 99, @@ -172,9 +191,9 @@ func TestReadMetaBetweenTS(t *testing.T) { }, { items: []*backuppb.Metadata{ - m(wd(1, 100, 1), wd(5, 13, 5), dd(1, 101)), - m(wd(100, 200, 98), dd(100, 200)), - m(wd(200, 300, 200), dd(200, 300)), + m(wr(1, 100, 1), wr(5, 13, 5), dr(1, 101)), + m(wr(100, 200, 98), dr(100, 200)), + m(wr(200, 300, 200), dr(200, 300)), }, startTS: 150, endTS: 199, @@ -183,9 +202,9 @@ func TestReadMetaBetweenTS(t *testing.T) { }, { items: []*backuppb.Metadata{ - m(wd(1, 100, 1), wd(5, 13, 5)), - m(wd(101, 200, 101), dd(100, 200)), - m(wd(200, 300, 200), dd(200, 300)), + m(wr(1, 100, 1), wr(5, 13, 5)), + m(wr(101, 200, 101), dr(100, 200)), + m(wr(200, 300, 200), dr(200, 300)), }, startTS: 150, endTS: 199, @@ -206,14 +225,15 @@ func TestReadMetaBetweenTS(t *testing.T) { os.RemoveAll(temp) } }() - cli := Client{ - storage: loc, - helper: stream.NewMetadataHelper(), + init := LogFileManagerInit{ + StartTS: c.startTS, + RestoreTS: c.endTS, + Storage: loc, } - shift, err := cli.GetShiftTS(ctx, c.startTS, c.endTS) - req.Equal(shift, c.expectedShiftTS) + cli, err := CreateLogFileManager(ctx, init) + req.Equal(cli.ShiftTS(), c.expectedShiftTS) req.NoError(err) - metas, err := cli.ReadStreamMetaByTS(ctx, shift, c.endTS) + metas, err := cli.readStreamMeta(ctx) req.NoError(err) actualStoreIDs := make([]int64, 0, len(metas)) for _, meta := range metas { @@ -233,102 +253,12 @@ func TestReadMetaBetweenTS(t *testing.T) { } } -func TestReadMetaBetweenTSV2(t *testing.T) { - log.SetLevel(zapcore.DebugLevel) - type Case struct { - items []*backuppb.Metadata - startTS uint64 - endTS uint64 - expectedShiftTS uint64 - expected []int - } - - cases := []Case{ - { - items: []*backuppb.Metadata{ - m2(wd(4, 10, 3), wd(5, 13, 5)), - m2(dd(1, 3)), - m2(wd(10, 42, 9), dd(6, 9)), - }, - startTS: 4, - endTS: 5, - expectedShiftTS: 3, - expected: []int{0, 1}, - }, - { - items: []*backuppb.Metadata{ - m2(wd(1, 100, 1), wd(5, 13, 5), dd(1, 101)), - m2(wd(100, 200, 98), dd(100, 200)), - }, - startTS: 50, - endTS: 99, - expectedShiftTS: 1, - expected: []int{0}, - }, - { - items: []*backuppb.Metadata{ - m2(wd(1, 100, 1), wd(5, 13, 5), dd(1, 101)), - m2(wd(100, 200, 98), dd(100, 200)), - m2(wd(200, 300, 200), dd(200, 300)), - }, - startTS: 150, - endTS: 199, - expectedShiftTS: 98, - expected: []int{1, 0}, - }, - { - items: []*backuppb.Metadata{ - m2(wd(1, 100, 1), wd(5, 13, 5)), - m2(wd(101, 200, 101), dd(100, 200)), - m2(wd(200, 300, 200), dd(200, 300)), - }, - startTS: 150, - endTS: 199, - expectedShiftTS: 101, - expected: []int{1}, - }, - } - - run := func(t *testing.T, c Case) { - req := require.New(t) - ctx := context.Background() - loc, temp := (&mockMetaBuilder{ - metas: c.items, - }).b(true) - defer func() { - t.Log("temp dir", temp) - if !t.Failed() { - os.RemoveAll(temp) - } - }() - cli := Client{ - storage: loc, - helper: stream.NewMetadataHelper(), - } - shift, err := cli.GetShiftTS(ctx, c.startTS, c.endTS) - req.Equal(shift, c.expectedShiftTS) - req.NoError(err) - metas, err := cli.ReadStreamMetaByTS(ctx, shift, c.endTS) - req.NoError(err) - actualStoreIDs := make([]int64, 0, len(metas)) - for _, meta := range metas { - actualStoreIDs = append(actualStoreIDs, meta.StoreId) - } - expectedStoreIDs := make([]int64, 0, len(c.expected)) - for _, meta := range c.expected { - expectedStoreIDs = append(expectedStoreIDs, c.items[meta].StoreId) - } - req.ElementsMatch(actualStoreIDs, expectedStoreIDs) - } - - for i, c := range cases { - t.Run(fmt.Sprintf("case#%d", i), func(t *testing.T) { - run(t, c) - }) - } +func TestReadMetaBetweenTS(t *testing.T) { + t.Run("MetaV1", func(t *testing.T) { testReadMetaBetweenTSWithVersion(t, m) }) + t.Run("MetaV2", func(t *testing.T) { testReadMetaBetweenTSWithVersion(t, m2) }) } -func TestReadFromMetadata(t *testing.T) { +func testReadFromMetadataWithVersion(t *testing.T, m metaMaker) { type Case struct { items []*backuppb.Metadata untilTS uint64 @@ -338,17 +268,17 @@ func TestReadFromMetadata(t *testing.T) { cases := []Case{ { items: []*backuppb.Metadata{ - m(wd(4, 10, 3), wd(5, 13, 5)), - m(dd(1, 3)), - m(wd(10, 42, 9), dd(6, 9)), + m(wr(4, 10, 3), wr(5, 13, 5)), + m(dr(1, 3)), + m(wr(10, 42, 9), dr(6, 9)), }, untilTS: 10, expected: []int{0, 1, 2}, }, { items: []*backuppb.Metadata{ - m(wd(1, 100, 1), wd(5, 13, 5), dd(1, 101)), - m(wd(100, 200, 98), dd(100, 200)), + m(wr(1, 100, 1), wr(5, 13, 5), dr(1, 101)), + m(wr(100, 200, 98), dr(100, 200)), }, untilTS: 99, expected: []int{0}, @@ -370,12 +300,19 @@ func TestReadFromMetadata(t *testing.T) { meta := new(StreamMetadataSet) meta.Helper = stream.NewMetadataHelper() - meta.LoadUntil(ctx, loc, c.untilTS) + meta.LoadUntilAndCalculateShiftTS(ctx, loc, c.untilTS) var metas []*backuppb.Metadata - for _, m := range meta.metadata { + for path := range meta.metadataInfos { + data, err := loc.ReadFile(ctx, path) + require.NoError(t, err) + + m, err := meta.Helper.ParseToMetadataHard(data) + require.NoError(t, err) + metas = append(metas, m) } + actualStoreIDs := make([]int64, 0, len(metas)) for _, meta := range metas { actualStoreIDs = append(actualStoreIDs, meta.StoreId) @@ -394,38 +331,122 @@ func TestReadFromMetadata(t *testing.T) { } } -func TestReadFromMetadataV2(t *testing.T) { +func TestReadFromMetadata(t *testing.T) { + t.Run("MetaV1", func(t *testing.T) { testReadFromMetadataWithVersion(t, m) }) + t.Run("MetaV2", func(t *testing.T) { testReadFromMetadataWithVersion(t, m2) }) +} + +func dataFileInfoMatches(t *testing.T, listA []*backuppb.DataFileInfo, listB ...*backuppb.DataFileInfo) { + sortL := func(l []*backuppb.DataFileInfo) { + sort.Slice(l, func(i, j int) bool { + return l[i].MinTs < l[j].MinTs + }) + } + + sortL(listA) + sortL(listB) + + if len(listA) != len(listB) { + t.Fatalf("failed: list length not match: %s vs %s", formatL(listA), formatL(listB)) + } + + for i := range listA { + require.True(t, equals(listA[i], listB[i]), "remaining: %s vs %s", formatL(listA[i:]), formatL(listB[i:])) + } +} + +func equals(a, b *backuppb.DataFileInfo) bool { + return a.IsMeta == b.IsMeta && + a.MinTs == b.MinTs && + a.MaxTs == b.MaxTs && + a.Cf == b.Cf && + a.MinBeginTsInDefaultCf == b.MinBeginTsInDefaultCf +} + +func formatI(i *backuppb.DataFileInfo) string { + ty := "d" + if i.Cf == "write" { + ty = "w" + } + isMeta := "r" + if i.IsMeta { + isMeta = "m" + } + shift := "" + if i.MinBeginTsInDefaultCf > 0 { + shift = fmt.Sprintf(", %d", i.MinBeginTsInDefaultCf) + } + + return fmt.Sprintf("%s%s(%d, %d%s)", ty, isMeta, i.MinTs, i.MaxTs, shift) +} + +func formatL(l []*backuppb.DataFileInfo) string { + r := iter.CollectAll(context.TODO(), iter.Map(iter.FromSlice(l), formatI)) + return "[" + strings.Join(r.Item, ", ") + "]" +} + +func testFileManagerWithMeta(t *testing.T, m metaMaker) { type Case struct { - items []*backuppb.Metadata - untilTS uint64 - expected []int + Metadata []*backuppb.Metadata + StartTS int + RestoreTS int + + SearchMeta bool + DMLFileCount *int + + Requires []*backuppb.DataFileInfo } + indirect := func(i int) *int { return &i } cases := []Case{ { - items: []*backuppb.Metadata{ - m2(wd(4, 10, 3), wd(5, 13, 5)), - m2(dd(1, 3)), - m2(wd(10, 42, 9), dd(6, 9)), + Metadata: []*backuppb.Metadata{ + m(wm(5, 10, 1), dm(1, 8), dr(2, 6), wr(4, 5, 2)), + m(wr(50, 54, 42), dr(42, 50), wr(70, 78, 0)), + m(dr(100, 101), wr(102, 104, 100)), + }, + StartTS: 2, + RestoreTS: 60, + Requires: []*backuppb.DataFileInfo{ + dr(2, 6), wr(4, 5, 2), wr(50, 54, 42), dr(42, 50), }, - untilTS: 10, - expected: []int{0, 1, 2}, }, { - items: []*backuppb.Metadata{ - m2(wd(1, 100, 1), wd(5, 13, 5), dd(1, 101)), - m2(wd(100, 200, 98), dd(100, 200)), + Metadata: []*backuppb.Metadata{ + m(wm(4, 10, 1), dm(1, 8), dr(2, 6), wr(4, 5, 2)), + m(wr(50, 54, 42), dr(42, 50), wr(70, 78, 0), wm(80, 81, 0), wm(90, 92, 0)), + m(dr(100, 101), wr(102, 104, 100)), }, - untilTS: 99, - expected: []int{0}, + StartTS: 5, + RestoreTS: 80, + Requires: []*backuppb.DataFileInfo{ + wm(80, 81, 0), wm(4, 10, 1), dm(1, 8), + }, + SearchMeta: true, + DMLFileCount: indirect(5), + }, + { + Metadata: []*backuppb.Metadata{ + m(wm(5, 10, 1), dm(1, 8), dr(2, 6), wr(4, 5, 2)), + m(wr(50, 54, 42), dr(42, 50), wr(70, 78, 0), wm(80, 81, 0), wm(90, 92, 0)), + m(dr(100, 101), wr(102, 104, 100)), + }, + StartTS: 6, + RestoreTS: 80, + Requires: []*backuppb.DataFileInfo{ + wm(80, 81, 0), wm(5, 10, 1), dm(1, 8), + }, + SearchMeta: true, }, } run := func(t *testing.T, c Case) { req := require.New(t) - ctx := context.Background() + items := c.Metadata + start := uint64(c.StartTS) + end := uint64(c.RestoreTS) loc, temp := (&mockMetaBuilder{ - metas: c.items, + metas: items, }).b(true) defer func() { t.Log("temp dir", temp) @@ -433,29 +454,40 @@ func TestReadFromMetadataV2(t *testing.T) { os.RemoveAll(temp) } }() + ctx := context.Background() + fm, err := CreateLogFileManager(ctx, LogFileManagerInit{ + StartTS: start, + RestoreTS: end, + Storage: loc, + }) + req.NoError(err) - meta := new(StreamMetadataSet) - meta.Helper = stream.NewMetadataHelper() - meta.LoadUntil(ctx, loc, c.untilTS) - - var metas []*backuppb.Metadata - for _, m := range meta.metadata { - metas = append(metas, m) - } - actualStoreIDs := make([]int64, 0, len(metas)) - for _, meta := range metas { - actualStoreIDs = append(actualStoreIDs, meta.StoreId) - } - expectedStoreIDs := make([]int64, 0, len(c.expected)) - for _, meta := range c.expected { - expectedStoreIDs = append(expectedStoreIDs, c.items[meta].StoreId) + var datas LogIter + if !c.SearchMeta { + datas, err = fm.LoadDMLFiles(ctx) + req.NoError(err) + } else { + var counter *int + if c.DMLFileCount != nil { + counter = new(int) + } + data, err := fm.LoadDDLFilesAndCountDMLFiles(ctx, counter) + req.NoError(err) + if counter != nil { + req.Equal(*c.DMLFileCount, *counter) + } + datas = iter.FromSlice(data) } - req.ElementsMatch(actualStoreIDs, expectedStoreIDs) + r := iter.CollectAll(ctx, datas) + dataFileInfoMatches(t, r.Item, c.Requires...) } for i, c := range cases { - t.Run(fmt.Sprintf("case#%d", i), func(t *testing.T) { - run(t, c) - }) + t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { run(t, c) }) } } + +func TestFileManger(t *testing.T) { + t.Run("MetaV1", func(t *testing.T) { testFileManagerWithMeta(t, m) }) + t.Run("MetaV2", func(t *testing.T) { testFileManagerWithMeta(t, m2) }) +} diff --git a/br/pkg/restore/main_test.go b/br/pkg/restore/main_test.go index 43df5b07d486d..a71c8db57c79f 100644 --- a/br/pkg/restore/main_test.go +++ b/br/pkg/restore/main_test.go @@ -28,6 +28,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/klauspost/compress/zstd.(*blockDec).startDecoder"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), diff --git a/br/pkg/restore/prealloc_table_id/BUILD.bazel b/br/pkg/restore/prealloc_table_id/BUILD.bazel new file mode 100644 index 0000000000000..cfdb0432fd446 --- /dev/null +++ b/br/pkg/restore/prealloc_table_id/BUILD.bazel @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "prealloc_table_id", + srcs = ["alloc.go"], + importpath = "github.com/pingcap/tidb/br/pkg/restore/prealloc_table_id", + visibility = ["//visibility:public"], + deps = [ + "//br/pkg/metautil", + "//parser/model", + ], +) + +go_test( + name = "prealloc_table_id_test", + srcs = ["alloc_test.go"], + flaky = True, + race = "on", + deps = [ + ":prealloc_table_id", + "//br/pkg/metautil", + "//parser/model", + "@com_github_stretchr_testify//require", + ], +) diff --git a/br/pkg/restore/prealloc_table_id/alloc.go b/br/pkg/restore/prealloc_table_id/alloc.go new file mode 100644 index 0000000000000..8554de5e9891b --- /dev/null +++ b/br/pkg/restore/prealloc_table_id/alloc.go @@ -0,0 +1,111 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package prealloctableid + +import ( + "fmt" + "math" + + "github.com/pingcap/tidb/br/pkg/metautil" + "github.com/pingcap/tidb/parser/model" +) + +const ( + // insaneTableIDThreshold is the threshold for "normal" table ID. + // Sometimes there might be some tables with huge table ID. + // For example, DDL metadata relative tables may have table ID up to 1 << 48. + // When calculating the max table ID, we would ignore tables with table ID greater than this. + // NOTE: In fact this could be just `1 << 48 - 1000` (the max available global ID), + // however we are going to keep some gap here for some not-yet-known scenario, which means + // at least, BR won't exhaust all global IDs. + insaneTableIDThreshold = math.MaxUint32 +) + +// Allocator is the interface needed to allocate table IDs. +type Allocator interface { + GetGlobalID() (int64, error) + AdvanceGlobalIDs(n int) (int64, error) +} + +// PreallocIDs mantains the state of preallocated table IDs. +type PreallocIDs struct { + end int64 + + allocedFrom int64 +} + +// New collects the requirement of prealloc IDs and return a +// not-yet-allocated PreallocIDs. +func New(tables []*metautil.Table) *PreallocIDs { + if len(tables) == 0 { + return &PreallocIDs{ + allocedFrom: math.MaxInt64, + } + } + + max := int64(0) + + for _, t := range tables { + if t.Info.ID > max && t.Info.ID < insaneTableIDThreshold { + max = t.Info.ID + } + + if t.Info.Partition != nil && t.Info.Partition.Definitions != nil { + for _, part := range t.Info.Partition.Definitions { + if part.ID > max && part.ID < insaneTableIDThreshold { + max = part.ID + } + } + } + } + return &PreallocIDs{ + end: max + 1, + + allocedFrom: math.MaxInt64, + } +} + +// String implements fmt.Stringer. +func (p *PreallocIDs) String() string { + if p.allocedFrom >= p.end { + return fmt.Sprintf("ID:empty(end=%d)", p.end) + } + return fmt.Sprintf("ID:[%d,%d)", p.allocedFrom, p.end) +} + +// preallocTableIDs peralloc the id for [start, end) +func (p *PreallocIDs) Alloc(m Allocator) error { + currentId, err := m.GetGlobalID() + if err != nil { + return err + } + if currentId > p.end { + return nil + } + + alloced, err := m.AdvanceGlobalIDs(int(p.end - currentId)) + if err != nil { + return err + } + p.allocedFrom = alloced + return nil +} + +// Prealloced checks whether a table ID has been successfully allocated. +func (p *PreallocIDs) Prealloced(tid int64) bool { + return p.allocedFrom <= tid && tid < p.end +} + +func (p *PreallocIDs) PreallocedFor(ti *model.TableInfo) bool { + if !p.Prealloced(ti.ID) { + return false + } + if ti.Partition != nil && ti.Partition.Definitions != nil { + for _, part := range ti.Partition.Definitions { + if !p.Prealloced(part.ID) { + return false + } + } + } + return true +} diff --git a/br/pkg/restore/prealloc_table_id/alloc_test.go b/br/pkg/restore/prealloc_table_id/alloc_test.go new file mode 100644 index 0000000000000..c1c3f018a2de8 --- /dev/null +++ b/br/pkg/restore/prealloc_table_id/alloc_test.go @@ -0,0 +1,117 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package prealloctableid_test + +import ( + "fmt" + "testing" + + "github.com/pingcap/tidb/br/pkg/metautil" + prealloctableid "github.com/pingcap/tidb/br/pkg/restore/prealloc_table_id" + "github.com/pingcap/tidb/parser/model" + "github.com/stretchr/testify/require" +) + +type testAllocator int64 + +func (t *testAllocator) GetGlobalID() (int64, error) { + return int64(*t), nil +} + +func (t *testAllocator) AdvanceGlobalIDs(n int) (int64, error) { + old := int64(*t) + *t = testAllocator(int64(*t) + int64(n)) + return old, nil +} + +func TestAllocator(t *testing.T) { + type Case struct { + tableIDs []int64 + partitions map[int64][]int64 + hasAllocatedTo int64 + successfullyAllocated []int64 + shouldAllocatedTo int64 + } + + cases := []Case{ + { + tableIDs: []int64{1, 2, 5, 6, 7}, + hasAllocatedTo: 6, + successfullyAllocated: []int64{6, 7}, + shouldAllocatedTo: 8, + }, + { + tableIDs: []int64{4, 6, 9, 2}, + hasAllocatedTo: 1, + successfullyAllocated: []int64{2, 4, 6, 9}, + shouldAllocatedTo: 10, + }, + { + tableIDs: []int64{1, 2, 3, 4}, + hasAllocatedTo: 5, + successfullyAllocated: []int64{}, + shouldAllocatedTo: 5, + }, + { + tableIDs: []int64{1, 2, 5, 6, 1 << 50, 1<<50 + 2479}, + hasAllocatedTo: 3, + successfullyAllocated: []int64{5, 6}, + shouldAllocatedTo: 7, + }, + { + tableIDs: []int64{1, 2, 5, 6, 7}, + hasAllocatedTo: 6, + successfullyAllocated: []int64{6, 7}, + shouldAllocatedTo: 13, + partitions: map[int64][]int64{ + 7: {8, 9, 10, 11, 12}, + }, + }, + { + tableIDs: []int64{1, 2, 5, 6, 7, 13}, + hasAllocatedTo: 9, + successfullyAllocated: []int64{13}, + shouldAllocatedTo: 14, + partitions: map[int64][]int64{ + 7: {8, 9, 10, 11, 12}, + }, + }, + } + + run := func(t *testing.T, c Case) { + tables := make([]*metautil.Table, 0, len(c.tableIDs)) + for _, id := range c.tableIDs { + table := metautil.Table{ + Info: &model.TableInfo{ + ID: id, + Partition: &model.PartitionInfo{}, + }, + } + if c.partitions != nil { + for _, part := range c.partitions[id] { + table.Info.Partition.Definitions = append(table.Info.Partition.Definitions, model.PartitionDefinition{ID: part}) + } + } + tables = append(tables, &table) + } + + ids := prealloctableid.New(tables) + allocator := testAllocator(c.hasAllocatedTo) + require.NoError(t, ids.Alloc(&allocator)) + + allocated := make([]int64, 0, len(c.successfullyAllocated)) + for _, t := range tables { + if ids.PreallocedFor(t.Info) { + allocated = append(allocated, t.Info.ID) + } + } + require.ElementsMatch(t, allocated, c.successfullyAllocated) + require.Equal(t, int64(allocator), c.shouldAllocatedTo) + } + + for i, c := range cases { + t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { + run(t, c) + }) + } +} diff --git a/br/pkg/restore/split.go b/br/pkg/restore/split.go index a707d0f086ce9..17e04486587b9 100644 --- a/br/pkg/restore/split.go +++ b/br/pkg/restore/split.go @@ -5,12 +5,15 @@ package restore import ( "bytes" "context" + "sort" "strconv" "strings" + "sync" "time" "github.com/opentracing/opentracing-go" "github.com/pingcap/errors" + backuppb "github.com/pingcap/kvproto/pkg/brpb" sst "github.com/pingcap/kvproto/pkg/import_sstpb" "github.com/pingcap/kvproto/pkg/pdpb" "github.com/pingcap/log" @@ -19,9 +22,12 @@ import ( "github.com/pingcap/tidb/br/pkg/restore/split" "github.com/pingcap/tidb/br/pkg/rtree" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/br/pkg/utils/iter" + "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/util/codec" "go.uber.org/multierr" "go.uber.org/zap" + "golang.org/x/sync/errgroup" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -428,3 +434,426 @@ func replacePrefix(s []byte, rewriteRules *RewriteRules) ([]byte, *sst.RewriteRu return s, nil } + +type rewriteSplitter struct { + rewriteKey []byte + tableID int64 + rule *RewriteRules + splitter *split.SplitHelper +} + +type splitHelperIterator struct { + tableSplitters []*rewriteSplitter +} + +func (iter *splitHelperIterator) Traverse(fn func(v split.Valued, endKey []byte, rule *RewriteRules) bool) { + for _, entry := range iter.tableSplitters { + endKey := codec.EncodeBytes([]byte{}, tablecodec.EncodeTablePrefix(entry.tableID+1)) + rule := entry.rule + entry.splitter.Traverse(func(v split.Valued) bool { + return fn(v, endKey, rule) + }) + } +} + +func NewSplitHelperIteratorForTest(helper *split.SplitHelper, tableID int64, rule *RewriteRules) *splitHelperIterator { + return &splitHelperIterator{ + tableSplitters: []*rewriteSplitter{ + { + tableID: tableID, + rule: rule, + splitter: helper, + }, + }, + } +} + +type LogSplitHelper struct { + tableSplitter map[int64]*split.SplitHelper + rules map[int64]*RewriteRules + client split.SplitClient + pool *utils.WorkerPool + eg *errgroup.Group + regionsCh chan []*split.RegionInfo + + splitThreSholdSize uint64 + splitThreSholdKeys int64 +} + +func NewLogSplitHelper(rules map[int64]*RewriteRules, client split.SplitClient, splitSize uint64, splitKeys int64) *LogSplitHelper { + return &LogSplitHelper{ + tableSplitter: make(map[int64]*split.SplitHelper), + rules: rules, + client: client, + pool: utils.NewWorkerPool(128, "split region"), + eg: nil, + + splitThreSholdSize: splitSize, + splitThreSholdKeys: splitKeys, + } +} + +func (helper *LogSplitHelper) iterator() *splitHelperIterator { + tableSplitters := make([]*rewriteSplitter, 0, len(helper.tableSplitter)) + for tableID, splitter := range helper.tableSplitter { + delete(helper.tableSplitter, tableID) + rewriteRule, exists := helper.rules[tableID] + if !exists { + log.Info("skip splitting due to no table id matched", zap.Int64("tableID", tableID)) + continue + } + newTableID := GetRewriteTableID(tableID, rewriteRule) + if newTableID == 0 { + log.Warn("failed to get the rewrite table id", zap.Int64("tableID", tableID)) + continue + } + tableSplitters = append(tableSplitters, &rewriteSplitter{ + rewriteKey: codec.EncodeBytes([]byte{}, tablecodec.EncodeTablePrefix(newTableID)), + tableID: newTableID, + rule: rewriteRule, + splitter: splitter, + }) + } + sort.Slice(tableSplitters, func(i, j int) bool { + return bytes.Compare(tableSplitters[i].rewriteKey, tableSplitters[j].rewriteKey) < 0 + }) + return &splitHelperIterator{ + tableSplitters: tableSplitters, + } +} + +const splitFileThreshold = 1024 * 1024 // 1 MB + +func (helper *LogSplitHelper) skipFile(file *backuppb.DataFileInfo) bool { + _, exist := helper.rules[file.TableId] + return file.Length < splitFileThreshold || file.IsMeta || !exist +} + +func (helper *LogSplitHelper) Merge(file *backuppb.DataFileInfo) { + if helper.skipFile(file) { + return + } + splitHelper, exist := helper.tableSplitter[file.TableId] + if !exist { + splitHelper = split.NewSplitHelper() + helper.tableSplitter[file.TableId] = splitHelper + } + + splitHelper.Merge(split.Valued{ + Key: split.Span{ + StartKey: file.StartKey, + EndKey: file.EndKey, + }, + Value: split.Value{ + Size: file.Length, + Number: file.NumberOfEntries, + }, + }) +} + +type splitFunc = func(context.Context, *RegionSplitter, uint64, int64, *split.RegionInfo, []split.Valued) error + +func (helper *LogSplitHelper) splitRegionByPoints( + ctx context.Context, + regionSplitter *RegionSplitter, + initialLength uint64, + initialNumber int64, + region *split.RegionInfo, + valueds []split.Valued, +) error { + var ( + splitPoints [][]byte = make([][]byte, 0) + lastKey []byte = region.Region.StartKey + length uint64 = initialLength + number int64 = initialNumber + ) + for _, v := range valueds { + // decode will discard ts behind the key, which results in the same key for consecutive ranges + if !bytes.Equal(lastKey, v.GetStartKey()) && (v.Value.Size+length > helper.splitThreSholdSize || v.Value.Number+number > helper.splitThreSholdKeys) { + _, rawKey, _ := codec.DecodeBytes(v.GetStartKey(), nil) + splitPoints = append(splitPoints, rawKey) + length = 0 + number = 0 + } + lastKey = v.GetStartKey() + length += v.Value.Size + number += v.Value.Number + } + + if len(splitPoints) == 0 { + return nil + } + + helper.pool.ApplyOnErrorGroup(helper.eg, func() error { + newRegions, errSplit := regionSplitter.splitAndScatterRegions(ctx, region, splitPoints) + if errSplit != nil { + log.Warn("failed to split the scaned region", zap.Error(errSplit)) + _, startKey, _ := codec.DecodeBytes(region.Region.StartKey, nil) + ranges := make([]rtree.Range, 0, len(splitPoints)) + for _, point := range splitPoints { + ranges = append(ranges, rtree.Range{StartKey: startKey, EndKey: point}) + startKey = point + } + + return regionSplitter.Split(ctx, ranges, nil, false, func([][]byte) {}) + } + select { + case <-ctx.Done(): + return nil + case helper.regionsCh <- newRegions: + } + log.Info("split the region", zap.Uint64("region-id", region.Region.Id), zap.Int("split-point-number", len(splitPoints))) + return nil + }) + return nil +} + +// GetRewriteTableID gets rewrite table id by the rewrite rule and original table id +func GetRewriteTableID(tableID int64, rewriteRules *RewriteRules) int64 { + tableKey := tablecodec.GenTableRecordPrefix(tableID) + rule := matchOldPrefix(tableKey, rewriteRules) + if rule == nil { + return 0 + } + + return tablecodec.DecodeTableID(rule.GetNewKeyPrefix()) +} + +// SplitPoint selects ranges overlapped with each region, and calls `splitF` to split the region +func SplitPoint( + ctx context.Context, + iter *splitHelperIterator, + client split.SplitClient, + splitF splitFunc, +) (err error) { + // common status + var ( + regionSplitter *RegionSplitter = NewRegionSplitter(client) + ) + // region traverse status + var ( + // the region buffer of each scan + regions []*split.RegionInfo = nil + regionIndex int = 0 + ) + // region split status + var ( + // range span +----------------+------+---+-------------+ + // region span +------------------------------------+ + // +initial length+ +end valued+ + // regionValueds is the ranges array overlapped with `regionInfo` + regionValueds []split.Valued = nil + // regionInfo is the region to be split + regionInfo *split.RegionInfo = nil + // intialLength is the length of the part of the first range overlapped with the region + initialLength uint64 = 0 + initialNumber int64 = 0 + ) + // range status + var ( + // regionOverCount is the number of regions overlapped with the range + regionOverCount uint64 = 0 + ) + + iter.Traverse(func(v split.Valued, endKey []byte, rule *RewriteRules) bool { + if v.Value.Number == 0 || v.Value.Size == 0 { + return true + } + var ( + vStartKey []byte + vEndKey []byte + ) + // use `vStartKey` and `vEndKey` to compare with region's key + vStartKey, vEndKey, err = GetRewriteEncodedKeys(v, rule) + if err != nil { + return false + } + // traverse to the first region overlapped with the range + for ; regionIndex < len(regions); regionIndex++ { + if bytes.Compare(vStartKey, regions[regionIndex].Region.EndKey) < 0 { + break + } + } + // cannot find any regions overlapped with the range + // need to scan regions again + if regionIndex == len(regions) { + regions = nil + } + regionOverCount = 0 + for { + if regionIndex >= len(regions) { + var startKey []byte + if len(regions) > 0 { + // has traversed over the region buffer, should scan from the last region's end-key of the region buffer + startKey = regions[len(regions)-1].Region.EndKey + } else { + // scan from the range's start-key + startKey = vStartKey + } + // scan at most 64 regions into the region buffer + regions, err = split.ScanRegionsWithRetry(ctx, client, startKey, endKey, 64) + if err != nil { + return false + } + regionIndex = 0 + } + + region := regions[regionIndex] + // this region must be overlapped with the range + regionOverCount++ + // the region is the last one overlapped with the range, + // should split the last recorded region, + // and then record this region as the region to be split + if bytes.Compare(vEndKey, region.Region.EndKey) < 0 { + endLength := v.Value.Size / regionOverCount + endNumber := v.Value.Number / int64(regionOverCount) + if len(regionValueds) > 0 && regionInfo != region { + // add a part of the range as the end part + if bytes.Compare(vStartKey, regionInfo.Region.EndKey) < 0 { + regionValueds = append(regionValueds, split.NewValued(vStartKey, regionInfo.Region.EndKey, split.Value{Size: endLength, Number: endNumber})) + } + // try to split the region + err = splitF(ctx, regionSplitter, initialLength, initialNumber, regionInfo, regionValueds) + if err != nil { + return false + } + regionValueds = make([]split.Valued, 0) + } + if regionOverCount == 1 { + // the region completely contains the range + regionValueds = append(regionValueds, split.Valued{ + Key: split.Span{ + StartKey: vStartKey, + EndKey: vEndKey, + }, + Value: v.Value, + }) + } else { + // the region is overlapped with the last part of the range + initialLength = endLength + initialNumber = endNumber + } + regionInfo = region + // try the next range + return true + } + + // try the next region + regionIndex++ + } + }) + + if err != nil { + return errors.Trace(err) + } + if len(regionValueds) > 0 { + // try to split the region + err = splitF(ctx, regionSplitter, initialLength, initialNumber, regionInfo, regionValueds) + if err != nil { + return errors.Trace(err) + } + } + + return nil +} + +func (helper *LogSplitHelper) Split(ctx context.Context) error { + var ectx context.Context + var wg sync.WaitGroup + helper.eg, ectx = errgroup.WithContext(ctx) + helper.regionsCh = make(chan []*split.RegionInfo, 1024) + wg.Add(1) + go func() { + defer wg.Done() + scatterRegions := make([]*split.RegionInfo, 0) + receiveNewRegions: + for { + select { + case <-ectx.Done(): + return + case newRegions, ok := <-helper.regionsCh: + if !ok { + break receiveNewRegions + } + + scatterRegions = append(scatterRegions, newRegions...) + } + } + + startTime := time.Now() + regionSplitter := NewRegionSplitter(helper.client) + for _, region := range scatterRegions { + regionSplitter.waitForScatterRegion(ctx, region) + // It is too expensive to stop recovery and wait for a small number of regions + // to complete scatter, so the maximum waiting time is reduced to 1 minute. + if time.Since(startTime) > time.Minute { + break + } + } + }() + + iter := helper.iterator() + if err := SplitPoint(ectx, iter, helper.client, helper.splitRegionByPoints); err != nil { + return errors.Trace(err) + } + + // wait for completion of splitting regions + if err := helper.eg.Wait(); err != nil { + return errors.Trace(err) + } + + // wait for completion of scattering regions + close(helper.regionsCh) + wg.Wait() + + return nil +} + +type LogFilesIterWithSplitHelper struct { + iter LogIter + helper *LogSplitHelper + buffer []*backuppb.DataFileInfo + next int +} + +const SplitFilesBufferSize = 4096 + +func NewLogFilesIterWithSplitHelper(iter LogIter, rules map[int64]*RewriteRules, client split.SplitClient, splitSize uint64, splitKeys int64) LogIter { + return &LogFilesIterWithSplitHelper{ + iter: iter, + helper: NewLogSplitHelper(rules, client, splitSize, splitKeys), + buffer: nil, + next: 0, + } +} + +func (splitIter *LogFilesIterWithSplitHelper) TryNext(ctx context.Context) iter.IterResult[*backuppb.DataFileInfo] { + if splitIter.next >= len(splitIter.buffer) { + splitIter.buffer = make([]*backuppb.DataFileInfo, 0, SplitFilesBufferSize) + for r := splitIter.iter.TryNext(ctx); !r.Finished; r = splitIter.iter.TryNext(ctx) { + if r.Err != nil { + return r + } + f := r.Item + splitIter.helper.Merge(f) + splitIter.buffer = append(splitIter.buffer, f) + if len(splitIter.buffer) >= SplitFilesBufferSize { + break + } + } + splitIter.next = 0 + if len(splitIter.buffer) == 0 { + return iter.Done[*backuppb.DataFileInfo]() + } + log.Info("start to split the regions") + startTime := time.Now() + if err := splitIter.helper.Split(ctx); err != nil { + return iter.Throw[*backuppb.DataFileInfo](errors.Trace(err)) + } + log.Info("end to split the regions", zap.Duration("takes", time.Since(startTime))) + } + + res := iter.Emit(splitIter.buffer[splitIter.next]) + splitIter.next += 1 + return res +} diff --git a/br/pkg/restore/split/BUILD.bazel b/br/pkg/restore/split/BUILD.bazel index 49fbec82c543c..ac9eb50eb4d20 100644 --- a/br/pkg/restore/split/BUILD.bazel +++ b/br/pkg/restore/split/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "split", @@ -6,6 +6,7 @@ go_library( "client.go", "region.go", "split.go", + "sum_sorted.go", ], importpath = "github.com/pingcap/tidb/br/pkg/restore/split", visibility = ["//visibility:public"], @@ -16,7 +17,9 @@ go_library( "//br/pkg/logutil", "//br/pkg/redact", "//br/pkg/utils", + "//kv", "//store/pdtypes", + "@com_github_google_btree//:btree", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_kvproto//pkg/errorpb", @@ -34,3 +37,12 @@ go_library( "@org_uber_go_zap//:zap", ], ) + +go_test( + name = "split_test", + srcs = ["sum_sorted_test.go"], + deps = [ + ":split", + "@com_github_stretchr_testify//require", + ], +) diff --git a/br/pkg/restore/split/split.go b/br/pkg/restore/split/split.go index 6af36a400a03f..e06c8ab1c93d5 100644 --- a/br/pkg/restore/split/split.go +++ b/br/pkg/restore/split/split.go @@ -18,7 +18,7 @@ import ( ) var ( - ScanRegionAttemptTimes = 60 + ScanRegionAttemptTimes = 128 ) // Constants for split retry machinery. @@ -121,6 +121,65 @@ func PaginateScanRegion( return regions, err } +// CheckPartRegionConsistency only checks the continuity of regions and the first region consistency. +func CheckPartRegionConsistency(startKey, endKey []byte, regions []*RegionInfo) error { + // current pd can't guarantee the consistency of returned regions + if len(regions) == 0 { + return errors.Annotatef(berrors.ErrPDBatchScanRegion, "scan region return empty result, startKey: %s, endKey: %s", + redact.Key(startKey), redact.Key(endKey)) + } + + if bytes.Compare(regions[0].Region.StartKey, startKey) > 0 { + return errors.Annotatef(berrors.ErrPDBatchScanRegion, "first region's startKey > startKey, startKey: %s, regionStartKey: %s", + redact.Key(startKey), redact.Key(regions[0].Region.StartKey)) + } + + cur := regions[0] + for _, r := range regions[1:] { + if !bytes.Equal(cur.Region.EndKey, r.Region.StartKey) { + return errors.Annotatef(berrors.ErrPDBatchScanRegion, "region endKey not equal to next region startKey, endKey: %s, startKey: %s", + redact.Key(cur.Region.EndKey), redact.Key(r.Region.StartKey)) + } + cur = r + } + + return nil +} + +func ScanRegionsWithRetry( + ctx context.Context, client SplitClient, startKey, endKey []byte, limit int, +) ([]*RegionInfo, error) { + if len(endKey) != 0 && bytes.Compare(startKey, endKey) > 0 { + return nil, errors.Annotatef(berrors.ErrRestoreInvalidRange, "startKey > endKey, startKey: %s, endkey: %s", + hex.EncodeToString(startKey), hex.EncodeToString(endKey)) + } + + var regions []*RegionInfo + var err error + // we don't need to return multierr. since there only 3 times retry. + // in most case 3 times retry have the same error. so we just return the last error. + // actually we'd better remove all multierr in br/lightning. + // because it's not easy to check multierr equals normal error. + // see https://github.com/pingcap/tidb/issues/33419. + _ = utils.WithRetry(ctx, func() error { + regions, err = client.ScanRegions(ctx, startKey, endKey, limit) + if err != nil { + err = errors.Annotatef(berrors.ErrPDBatchScanRegion, "scan regions from start-key:%s, err: %s", + redact.Key(startKey), err.Error()) + return err + } + + if err = CheckPartRegionConsistency(startKey, endKey, regions); err != nil { + log.Warn("failed to scan region, retrying", logutil.ShortError(err)) + return err + } + + return nil + }, newScanRegionBackoffer()) + + return regions, err +} + type scanRegionBackoffer struct { attempt int } diff --git a/br/pkg/restore/split/sum_sorted.go b/br/pkg/restore/split/sum_sorted.go new file mode 100644 index 0000000000000..c4e9657900e35 --- /dev/null +++ b/br/pkg/restore/split/sum_sorted.go @@ -0,0 +1,204 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. +package split + +import ( + "bytes" + "fmt" + + "github.com/google/btree" + "github.com/pingcap/tidb/br/pkg/logutil" + "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/kv" +) + +// Value is the value type of stored in the span tree. +type Value struct { + Size uint64 + Number int64 +} + +// join finds the upper bound of two values. +func join(a, b Value) Value { + return Value{ + Size: a.Size + b.Size, + Number: a.Number + b.Number, + } +} + +// Span is the type of an adjacent sub key space. +type Span = kv.KeyRange + +// Valued is span binding to a value, which is the entry type of span tree. +type Valued struct { + Key Span + Value Value +} + +func NewValued(startKey, endKey []byte, value Value) Valued { + return Valued{ + Key: Span{ + StartKey: startKey, + EndKey: endKey, + }, + Value: value, + } +} + +func (v Valued) String() string { + return fmt.Sprintf("(%s, %.2f MB, %d)", logutil.StringifyRange(v.Key), float64(v.Value.Size)/1024/1024, v.Value.Number) +} + +func (v Valued) Less(other btree.Item) bool { + return bytes.Compare(v.Key.StartKey, other.(Valued).Key.StartKey) < 0 +} + +// implement for `AppliedFile` +func (v Valued) GetStartKey() []byte { + return v.Key.StartKey +} + +// implement for `AppliedFile` +func (v Valued) GetEndKey() []byte { + return v.Key.EndKey +} + +// SplitHelper represents a set of valued ranges, which doesn't overlap and union of them all is the full key space. +type SplitHelper struct { + inner *btree.BTree +} + +// NewSplitHelper creates a set of a subset of spans, with the full key space as initial status +func NewSplitHelper() *SplitHelper { + t := btree.New(16) + t.ReplaceOrInsert(Valued{Value: Value{Size: 0, Number: 0}, Key: Span{StartKey: []byte(""), EndKey: []byte("")}}) + return &SplitHelper{inner: t} +} + +func (f *SplitHelper) Merge(val Valued) { + if len(val.Key.StartKey) == 0 || len(val.Key.EndKey) == 0 { + return + } + overlaps := make([]Valued, 0, 8) + f.overlapped(val.Key, &overlaps) + f.mergeWithOverlap(val, overlaps) +} + +// traverse the items in ascend order +func (f *SplitHelper) Traverse(m func(Valued) bool) { + f.inner.Ascend(func(item btree.Item) bool { + return m(item.(Valued)) + }) +} + +func (f *SplitHelper) mergeWithOverlap(val Valued, overlapped []Valued) { + // There isn't any range overlaps with the input range, perhaps the input range is empty. + // do nothing for this case. + if len(overlapped) == 0 { + return + } + + for _, r := range overlapped { + f.inner.Delete(r) + } + // Assert All overlapped ranges are deleted. + + // the new valued item's Value is equally dividedd into `len(overlapped)` shares + appendValue := Value{ + Size: val.Value.Size / uint64(len(overlapped)), + Number: val.Value.Number / int64(len(overlapped)), + } + var ( + rightTrail *Valued + leftTrail *Valued + // overlapped ranges +-------------+----------+ + // new valued item +-------------+ + // a b c d e + // the part [a,b] is `standalone` because it is not overlapped with the new valued item + // the part [a,b] and [b,c] are `split` because they are from range [a,c] + emitToCollected = func(rng Valued, standalone bool, split bool) { + merged := rng.Value + if split { + merged.Size /= 2 + merged.Number /= 2 + } + if !standalone { + merged = join(appendValue, merged) + } + rng.Value = merged + f.inner.ReplaceOrInsert(rng) + } + ) + + leftmost := overlapped[0] + if bytes.Compare(leftmost.Key.StartKey, val.Key.StartKey) < 0 { + leftTrail = &Valued{ + Key: Span{StartKey: leftmost.Key.StartKey, EndKey: val.Key.StartKey}, + Value: leftmost.Value, + } + overlapped[0].Key.StartKey = val.Key.StartKey + } + + rightmost := overlapped[len(overlapped)-1] + if utils.CompareBytesExt(rightmost.Key.EndKey, true, val.Key.EndKey, true) > 0 { + rightTrail = &Valued{ + Key: Span{StartKey: val.Key.EndKey, EndKey: rightmost.Key.EndKey}, + Value: rightmost.Value, + } + overlapped[len(overlapped)-1].Key.EndKey = val.Key.EndKey + if len(overlapped) == 1 && leftTrail != nil { + // (split) (split) (split) + // overlapped ranges +-----------------------------+ + // new valued item +-------------+ + // a b c d + // now the overlapped range should be divided into 3 equal parts + // so modify the value to the 2/3x to be compatible with function `emitToCollected` + val := Value{ + Size: rightTrail.Value.Size * 2 / 3, + Number: rightTrail.Value.Number * 2 / 3, + } + leftTrail.Value = val + overlapped[0].Value = val + rightTrail.Value = val + } + } + + if leftTrail != nil { + emitToCollected(*leftTrail, true, true) + } + + for i, rng := range overlapped { + split := (i == 0 && leftTrail != nil) || (i == len(overlapped)-1 && rightTrail != nil) + emitToCollected(rng, false, split) + } + + if rightTrail != nil { + emitToCollected(*rightTrail, true, true) + } +} + +// overlapped inserts the overlapped ranges of the span into the `result` slice. +func (f *SplitHelper) overlapped(k Span, result *[]Valued) { + var first Span + f.inner.DescendLessOrEqual(Valued{Key: k}, func(item btree.Item) bool { + first = item.(Valued).Key + return false + }) + + f.inner.AscendGreaterOrEqual(Valued{Key: first}, func(item btree.Item) bool { + r := item.(Valued) + if !checkOverlaps(r.Key, k) { + return false + } + *result = append(*result, r) + return true + }) +} + +// checkOverlaps checks whether two spans have overlapped part. +// `ap` should be a finite range +func checkOverlaps(a, ap Span) bool { + if len(a.EndKey) == 0 { + return bytes.Compare(ap.EndKey, a.StartKey) > 0 + } + return bytes.Compare(a.StartKey, ap.EndKey) < 0 && bytes.Compare(ap.StartKey, a.EndKey) < 0 +} diff --git a/br/pkg/restore/split/sum_sorted_test.go b/br/pkg/restore/split/sum_sorted_test.go new file mode 100644 index 0000000000000..3a3b3db6d90eb --- /dev/null +++ b/br/pkg/restore/split/sum_sorted_test.go @@ -0,0 +1,141 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. +package split_test + +import ( + "testing" + + "github.com/pingcap/tidb/br/pkg/restore/split" + "github.com/stretchr/testify/require" +) + +func v(s, e string, val split.Value) split.Valued { + return split.Valued{ + Key: split.Span{ + StartKey: []byte(s), + EndKey: []byte(e), + }, + Value: val, + } +} + +func mb(b uint64) split.Value { + return split.Value{ + Size: b * 1024 * 1024, + Number: int64(b), + } +} + +func TestSumSorted(t *testing.T) { + cases := []struct { + values []split.Valued + result []uint64 + }{ + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("d", "g", mb(100)), + }, + result: []uint64{0, 250, 25, 75, 50, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("d", "f", mb(100)), + }, + result: []uint64{0, 250, 25, 125, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + }, + result: []uint64{0, 250, 150, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + v("da", "db", mb(100)), + }, + result: []uint64{0, 250, 50, 150, 50, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + v("da", "db", mb(100)), + v("cb", "db", mb(100)), + }, + result: []uint64{0, 250, 25, 75, 200, 50, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + v("da", "db", mb(100)), + v("cb", "f", mb(150)), + }, + result: []uint64{0, 250, 25, 75, 200, 100, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + v("da", "db", mb(100)), + v("cb", "df", mb(150)), + }, + result: []uint64{0, 250, 25, 75, 200, 75, 25, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + v("da", "db", mb(100)), + v("cb", "df", mb(150)), + }, + result: []uint64{0, 250, 25, 75, 200, 75, 25, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + v("da", "db", mb(100)), + v("c", "df", mb(150)), + }, + result: []uint64{0, 250, 100, 200, 75, 25, 0}, + }, + { + values: []split.Valued{ + v("a", "f", mb(100)), + v("a", "c", mb(200)), + v("c", "f", mb(100)), + v("da", "db", mb(100)), + v("c", "f", mb(150)), + }, + result: []uint64{0, 250, 100, 200, 100, 0}, + }, + } + + for _, ca := range cases { + full := split.NewSplitHelper() + for _, v := range ca.values { + full.Merge(v) + } + + i := 0 + full.Traverse(func(v split.Valued) bool { + require.Equal(t, mb(ca.result[i]), v.Value) + i++ + return true + }) + } +} diff --git a/br/pkg/restore/split_test.go b/br/pkg/restore/split_test.go index b726a5ec78729..1b560a4e1474d 100644 --- a/br/pkg/restore/split_test.go +++ b/br/pkg/restore/split_test.go @@ -5,6 +5,7 @@ package restore_test import ( "bytes" "context" + "fmt" "sync" "testing" "time" @@ -22,7 +23,9 @@ import ( "github.com/pingcap/tidb/br/pkg/restore/split" "github.com/pingcap/tidb/br/pkg/rtree" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/br/pkg/utils/iter" "github.com/pingcap/tidb/store/pdtypes" + "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/util/codec" "github.com/stretchr/testify/require" "go.uber.org/multierr" @@ -729,3 +732,316 @@ func TestSplitFailed(t *testing.T) { require.GreaterOrEqual(t, len(r.splitRanges), 2) require.Len(t, r.restoredFiles, 0) } + +func keyWithTablePrefix(tableID int64, key string) []byte { + rawKey := append(tablecodec.GenTableRecordPrefix(tableID), []byte(key)...) + return codec.EncodeBytes([]byte{}, rawKey) +} + +func TestSplitPoint(t *testing.T) { + ctx := context.Background() + var oldTableID int64 = 50 + var tableID int64 = 100 + rewriteRules := &restore.RewriteRules{ + Data: []*import_sstpb.RewriteRule{ + { + OldKeyPrefix: tablecodec.EncodeTablePrefix(oldTableID), + NewKeyPrefix: tablecodec.EncodeTablePrefix(tableID), + }, + }, + } + + // range: b c d e g i + // +---+ +---+ +---------+ + // +-------------+----------+---------+ + // region: a f h j + splitHelper := split.NewSplitHelper() + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "b"), EndKey: keyWithTablePrefix(oldTableID, "c")}, Value: split.Value{Size: 100, Number: 100}}) + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "d"), EndKey: keyWithTablePrefix(oldTableID, "e")}, Value: split.Value{Size: 200, Number: 200}}) + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "g"), EndKey: keyWithTablePrefix(oldTableID, "i")}, Value: split.Value{Size: 300, Number: 300}}) + client := NewFakeSplitClient() + client.AppendRegion(keyWithTablePrefix(tableID, "a"), keyWithTablePrefix(tableID, "f")) + client.AppendRegion(keyWithTablePrefix(tableID, "f"), keyWithTablePrefix(tableID, "h")) + client.AppendRegion(keyWithTablePrefix(tableID, "h"), keyWithTablePrefix(tableID, "j")) + client.AppendRegion(keyWithTablePrefix(tableID, "j"), keyWithTablePrefix(tableID+1, "a")) + + iter := restore.NewSplitHelperIteratorForTest(splitHelper, tableID, rewriteRules) + err := restore.SplitPoint(ctx, iter, client, func(ctx context.Context, rs *restore.RegionSplitter, u uint64, o int64, ri *split.RegionInfo, v []split.Valued) error { + require.Equal(t, u, uint64(0)) + require.Equal(t, o, int64(0)) + require.Equal(t, ri.Region.StartKey, keyWithTablePrefix(tableID, "a")) + require.Equal(t, ri.Region.EndKey, keyWithTablePrefix(tableID, "f")) + require.EqualValues(t, v[0].Key.StartKey, keyWithTablePrefix(tableID, "b")) + require.EqualValues(t, v[0].Key.EndKey, keyWithTablePrefix(tableID, "c")) + require.EqualValues(t, v[1].Key.StartKey, keyWithTablePrefix(tableID, "d")) + require.EqualValues(t, v[1].Key.EndKey, keyWithTablePrefix(tableID, "e")) + require.Equal(t, len(v), 2) + return nil + }) + require.NoError(t, err) +} + +func getCharFromNumber(prefix string, i int) string { + c := '1' + (i % 10) + b := '1' + (i%100)/10 + a := '1' + i/100 + return fmt.Sprintf("%s%c%c%c", prefix, a, b, c) +} + +func TestSplitPoint2(t *testing.T) { + ctx := context.Background() + var oldTableID int64 = 50 + var tableID int64 = 100 + rewriteRules := &restore.RewriteRules{ + Data: []*import_sstpb.RewriteRule{ + { + OldKeyPrefix: tablecodec.EncodeTablePrefix(oldTableID), + NewKeyPrefix: tablecodec.EncodeTablePrefix(tableID), + }, + }, + } + + // range: b c d e f i j k l n + // +---+ +---+ +-----------------+ +----+ +--------+ + // +---------------+--+.....+----+------------+---------+ + // region: a g >128 h m o + splitHelper := split.NewSplitHelper() + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "b"), EndKey: keyWithTablePrefix(oldTableID, "c")}, Value: split.Value{Size: 100, Number: 100}}) + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "d"), EndKey: keyWithTablePrefix(oldTableID, "e")}, Value: split.Value{Size: 200, Number: 200}}) + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "f"), EndKey: keyWithTablePrefix(oldTableID, "i")}, Value: split.Value{Size: 300, Number: 300}}) + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "j"), EndKey: keyWithTablePrefix(oldTableID, "k")}, Value: split.Value{Size: 200, Number: 200}}) + splitHelper.Merge(split.Valued{Key: split.Span{StartKey: keyWithTablePrefix(oldTableID, "l"), EndKey: keyWithTablePrefix(oldTableID, "n")}, Value: split.Value{Size: 200, Number: 200}}) + client := NewFakeSplitClient() + client.AppendRegion(keyWithTablePrefix(tableID, "a"), keyWithTablePrefix(tableID, "g")) + client.AppendRegion(keyWithTablePrefix(tableID, "g"), keyWithTablePrefix(tableID, getCharFromNumber("g", 0))) + for i := 0; i < 256; i++ { + client.AppendRegion(keyWithTablePrefix(tableID, getCharFromNumber("g", i)), keyWithTablePrefix(tableID, getCharFromNumber("g", i+1))) + } + client.AppendRegion(keyWithTablePrefix(tableID, getCharFromNumber("g", 256)), keyWithTablePrefix(tableID, "h")) + client.AppendRegion(keyWithTablePrefix(tableID, "h"), keyWithTablePrefix(tableID, "m")) + client.AppendRegion(keyWithTablePrefix(tableID, "m"), keyWithTablePrefix(tableID, "o")) + client.AppendRegion(keyWithTablePrefix(tableID, "o"), keyWithTablePrefix(tableID+1, "a")) + + firstSplit := true + iter := restore.NewSplitHelperIteratorForTest(splitHelper, tableID, rewriteRules) + err := restore.SplitPoint(ctx, iter, client, func(ctx context.Context, rs *restore.RegionSplitter, u uint64, o int64, ri *split.RegionInfo, v []split.Valued) error { + if firstSplit { + require.Equal(t, u, uint64(0)) + require.Equal(t, o, int64(0)) + require.Equal(t, ri.Region.StartKey, keyWithTablePrefix(tableID, "a")) + require.Equal(t, ri.Region.EndKey, keyWithTablePrefix(tableID, "g")) + require.EqualValues(t, v[0].Key.StartKey, keyWithTablePrefix(tableID, "b")) + require.EqualValues(t, v[0].Key.EndKey, keyWithTablePrefix(tableID, "c")) + require.EqualValues(t, v[1].Key.StartKey, keyWithTablePrefix(tableID, "d")) + require.EqualValues(t, v[1].Key.EndKey, keyWithTablePrefix(tableID, "e")) + require.EqualValues(t, v[2].Key.StartKey, keyWithTablePrefix(tableID, "f")) + require.EqualValues(t, v[2].Key.EndKey, keyWithTablePrefix(tableID, "g")) + require.Equal(t, v[2].Value.Size, uint64(1)) + require.Equal(t, v[2].Value.Number, int64(1)) + require.Equal(t, len(v), 3) + firstSplit = false + } else { + require.Equal(t, u, uint64(1)) + require.Equal(t, o, int64(1)) + require.Equal(t, ri.Region.StartKey, keyWithTablePrefix(tableID, "h")) + require.Equal(t, ri.Region.EndKey, keyWithTablePrefix(tableID, "m")) + require.EqualValues(t, v[0].Key.StartKey, keyWithTablePrefix(tableID, "j")) + require.EqualValues(t, v[0].Key.EndKey, keyWithTablePrefix(tableID, "k")) + require.EqualValues(t, v[1].Key.StartKey, keyWithTablePrefix(tableID, "l")) + require.EqualValues(t, v[1].Key.EndKey, keyWithTablePrefix(tableID, "m")) + require.Equal(t, v[1].Value.Size, uint64(100)) + require.Equal(t, v[1].Value.Number, int64(100)) + require.Equal(t, len(v), 2) + } + return nil + }) + require.NoError(t, err) +} + +type fakeSplitClient struct { + regions []*split.RegionInfo +} + +func NewFakeSplitClient() *fakeSplitClient { + return &fakeSplitClient{ + regions: make([]*split.RegionInfo, 0), + } +} + +func (f *fakeSplitClient) AppendRegion(startKey, endKey []byte) { + f.regions = append(f.regions, &split.RegionInfo{ + Region: &metapb.Region{ + StartKey: startKey, + EndKey: endKey, + }, + }) +} + +func (*fakeSplitClient) GetStore(ctx context.Context, storeID uint64) (*metapb.Store, error) { + return nil, nil +} +func (*fakeSplitClient) GetRegion(ctx context.Context, key []byte) (*split.RegionInfo, error) { + return nil, nil +} +func (*fakeSplitClient) GetRegionByID(ctx context.Context, regionID uint64) (*split.RegionInfo, error) { + return nil, nil +} +func (*fakeSplitClient) SplitRegion(ctx context.Context, regionInfo *split.RegionInfo, key []byte) (*split.RegionInfo, error) { + return nil, nil +} +func (*fakeSplitClient) BatchSplitRegions(ctx context.Context, regionInfo *split.RegionInfo, keys [][]byte) ([]*split.RegionInfo, error) { + return nil, nil +} +func (*fakeSplitClient) BatchSplitRegionsWithOrigin(ctx context.Context, regionInfo *split.RegionInfo, keys [][]byte) (*split.RegionInfo, []*split.RegionInfo, error) { + return nil, nil, nil +} +func (*fakeSplitClient) ScatterRegion(ctx context.Context, regionInfo *split.RegionInfo) error { + return nil +} +func (*fakeSplitClient) ScatterRegions(ctx context.Context, regionInfo []*split.RegionInfo) error { + return nil +} +func (*fakeSplitClient) GetOperator(ctx context.Context, regionID uint64) (*pdpb.GetOperatorResponse, error) { + return nil, nil +} +func (f *fakeSplitClient) ScanRegions(ctx context.Context, startKey, endKey []byte, limit int) ([]*split.RegionInfo, error) { + result := make([]*split.RegionInfo, 0) + count := 0 + for _, rng := range f.regions { + if bytes.Compare(rng.Region.StartKey, endKey) <= 0 && bytes.Compare(rng.Region.EndKey, startKey) > 0 { + result = append(result, rng) + count++ + } + if count >= limit { + break + } + } + return result, nil +} +func (*fakeSplitClient) GetPlacementRule(ctx context.Context, groupID, ruleID string) (pdtypes.Rule, error) { + return pdtypes.Rule{}, nil +} +func (*fakeSplitClient) SetPlacementRule(ctx context.Context, rule pdtypes.Rule) error { return nil } +func (*fakeSplitClient) DeletePlacementRule(ctx context.Context, groupID, ruleID string) error { + return nil +} +func (*fakeSplitClient) SetStoresLabel(ctx context.Context, stores []uint64, labelKey, labelValue string) error { + return nil +} + +func TestGetRewriteTableID(t *testing.T) { + var tableID int64 = 76 + var oldTableID int64 = 80 + { + rewriteRules := &restore.RewriteRules{ + Data: []*import_sstpb.RewriteRule{ + { + OldKeyPrefix: tablecodec.EncodeTablePrefix(oldTableID), + NewKeyPrefix: tablecodec.EncodeTablePrefix(tableID), + }, + }, + } + + newTableID := restore.GetRewriteTableID(oldTableID, rewriteRules) + require.Equal(t, tableID, newTableID) + } + + { + rewriteRules := &restore.RewriteRules{ + Data: []*import_sstpb.RewriteRule{ + { + OldKeyPrefix: tablecodec.GenTableRecordPrefix(oldTableID), + NewKeyPrefix: tablecodec.GenTableRecordPrefix(tableID), + }, + }, + } + + newTableID := restore.GetRewriteTableID(oldTableID, rewriteRules) + require.Equal(t, tableID, newTableID) + } +} + +type mockLogIter struct { + next int +} + +func (m *mockLogIter) TryNext(ctx context.Context) iter.IterResult[*backuppb.DataFileInfo] { + if m.next > 10000 { + return iter.Done[*backuppb.DataFileInfo]() + } + m.next += 1 + return iter.Emit(&backuppb.DataFileInfo{ + StartKey: []byte(fmt.Sprintf("a%d", m.next)), + EndKey: []byte("b"), + Length: 1024, // 1 KB + }) +} + +func TestLogFilesIterWithSplitHelper(t *testing.T) { + var tableID int64 = 76 + var oldTableID int64 = 80 + rewriteRules := &restore.RewriteRules{ + Data: []*import_sstpb.RewriteRule{ + { + OldKeyPrefix: tablecodec.EncodeTablePrefix(oldTableID), + NewKeyPrefix: tablecodec.EncodeTablePrefix(tableID), + }, + }, + } + rewriteRulesMap := map[int64]*restore.RewriteRules{ + oldTableID: rewriteRules, + } + mockIter := &mockLogIter{} + ctx := context.Background() + logIter := restore.NewLogFilesIterWithSplitHelper(mockIter, rewriteRulesMap, NewFakeSplitClient(), 144*1024*1024, 1440000) + next := 0 + for r := logIter.TryNext(ctx); !r.Finished; r = logIter.TryNext(ctx) { + require.NoError(t, r.Err) + next += 1 + require.Equal(t, []byte(fmt.Sprintf("a%d", next)), r.Item.StartKey) + } +} + +func regionInfo(startKey, endKey string) *split.RegionInfo { + return &split.RegionInfo{ + Region: &metapb.Region{ + StartKey: []byte(startKey), + EndKey: []byte(endKey), + }, + } +} + +func TestSplitCheckPartRegionConsistency(t *testing.T) { + var ( + startKey []byte = []byte("a") + endKey []byte = []byte("f") + err error + ) + err = split.CheckPartRegionConsistency(startKey, endKey, nil) + require.Error(t, err) + err = split.CheckPartRegionConsistency(startKey, endKey, []*split.RegionInfo{ + regionInfo("b", "c"), + }) + require.Error(t, err) + err = split.CheckPartRegionConsistency(startKey, endKey, []*split.RegionInfo{ + regionInfo("a", "c"), + regionInfo("d", "e"), + }) + require.Error(t, err) + err = split.CheckPartRegionConsistency(startKey, endKey, []*split.RegionInfo{ + regionInfo("a", "c"), + regionInfo("c", "d"), + }) + require.NoError(t, err) + err = split.CheckPartRegionConsistency(startKey, endKey, []*split.RegionInfo{ + regionInfo("a", "c"), + regionInfo("c", "d"), + regionInfo("d", "f"), + }) + require.NoError(t, err) + err = split.CheckPartRegionConsistency(startKey, endKey, []*split.RegionInfo{ + regionInfo("a", "c"), + regionInfo("c", "z"), + }) + require.NoError(t, err) +} diff --git a/br/pkg/restore/stream_metas.go b/br/pkg/restore/stream_metas.go index 7468573ce6ba8..2aa9c8f11a9db 100644 --- a/br/pkg/restore/stream_metas.go +++ b/br/pkg/restore/stream_metas.go @@ -12,62 +12,116 @@ import ( backuppb "github.com/pingcap/kvproto/pkg/brpb" "github.com/pingcap/log" berrors "github.com/pingcap/tidb/br/pkg/errors" + "github.com/pingcap/tidb/br/pkg/logutil" "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/br/pkg/stream" + "github.com/pingcap/tidb/br/pkg/utils" "github.com/pingcap/tidb/util/mathutil" "go.uber.org/zap" + "golang.org/x/sync/errgroup" ) +const notDeletedBecameFatalThreshold = 128 + type StreamMetadataSet struct { - metadata map[string]*backuppb.Metadata - // The metadata after changed that needs to be write back. - writeback map[string]*backuppb.Metadata + // if set true, the metadata and datafile won't be removed + DryRun bool + + // keeps the meta-information of metadata as little as possible + // to save the memory + metadataInfos map[string]*MetadataInfo + // a parser of metadata Helper *stream.MetadataHelper - BeforeDoWriteBack func(path string, last, current *backuppb.Metadata) (skip bool) + // for test + BeforeDoWriteBack func(path string, replaced *backuppb.Metadata) (skip bool) } -// LoadUntil loads the metadata until the specified timestamp. -// This would load all metadata files that *may* contain data from transaction committed before that TS. -// Note: maybe record the timestamp and reject reading data files after this TS? -func (ms *StreamMetadataSet) LoadUntil(ctx context.Context, s storage.ExternalStorage, until uint64) error { +// keep these meta-information for statistics and filtering +type FileGroupInfo struct { + MaxTS uint64 + Length uint64 + KVCount int64 +} + +// keep these meta-information for statistics and filtering +type MetadataInfo struct { + MinTS uint64 + FileGroupInfos []*FileGroupInfo +} + +// LoadUntilAndCalculateShiftTS loads the metadata until the specified timestamp and calculate the shift-until-ts by the way. +// This would record all metadata files that *may* contain data from transaction committed before that TS. +func (ms *StreamMetadataSet) LoadUntilAndCalculateShiftTS(ctx context.Context, s storage.ExternalStorage, until uint64) (uint64, error) { metadataMap := struct { sync.Mutex - metas map[string]*backuppb.Metadata + metas map[string]*MetadataInfo + shiftUntilTS uint64 }{} - ms.writeback = make(map[string]*backuppb.Metadata) - metadataMap.metas = make(map[string]*backuppb.Metadata) + metadataMap.metas = make(map[string]*MetadataInfo) + // `shiftUntilTS` must be less than `until` + metadataMap.shiftUntilTS = until err := stream.FastUnmarshalMetaData(ctx, s, func(path string, raw []byte) error { m, err := ms.Helper.ParseToMetadataHard(raw) if err != nil { return err } - metadataMap.Lock() // If the meta file contains only files with ts grater than `until`, when the file is from // `Default`: it should be kept, because its corresponding `write` must has commit ts grater than it, which should not be considered. // `Write`: it should trivially not be considered. if m.MinTs <= until { - metadataMap.metas[path] = m + // record these meta-information for statistics and filtering + fileGroupInfos := make([]*FileGroupInfo, 0, len(m.FileGroups)) + for _, group := range m.FileGroups { + var kvCount int64 = 0 + for _, file := range group.DataFilesInfo { + kvCount += file.NumberOfEntries + } + fileGroupInfos = append(fileGroupInfos, &FileGroupInfo{ + MaxTS: group.MaxTs, + Length: group.Length, + KVCount: kvCount, + }) + } + metadataMap.Lock() + metadataMap.metas[path] = &MetadataInfo{ + MinTS: m.MinTs, + FileGroupInfos: fileGroupInfos, + } + metadataMap.Unlock() + } + // filter out the metadatas whose ts-range is overlap with [until, +inf) + // and calculate their minimum begin-default-ts + ts, ok := UpdateShiftTS(m, until, mathutil.MaxUint) + if ok { + metadataMap.Lock() + if ts < metadataMap.shiftUntilTS { + metadataMap.shiftUntilTS = ts + } + metadataMap.Unlock() } - metadataMap.Unlock() return nil }) if err != nil { - return errors.Trace(err) + return 0, errors.Trace(err) } - ms.metadata = metadataMap.metas - return nil + ms.metadataInfos = metadataMap.metas + if metadataMap.shiftUntilTS != until { + log.Warn("calculate shift-ts", zap.Uint64("start-ts", until), zap.Uint64("shift-ts", metadataMap.shiftUntilTS)) + } + return metadataMap.shiftUntilTS, nil } -// LoadFrom loads data from an external storage into the stream metadata set. +// LoadFrom loads data from an external storage into the stream metadata set. (Now only for test) func (ms *StreamMetadataSet) LoadFrom(ctx context.Context, s storage.ExternalStorage) error { - return ms.LoadUntil(ctx, s, math.MaxUint64) + _, err := ms.LoadUntilAndCalculateShiftTS(ctx, s, math.MaxUint64) + return err } -func (ms *StreamMetadataSet) iterateDataFiles(f func(d *backuppb.DataFileGroup) (shouldBreak bool)) { - for _, m := range ms.metadata { - for _, d := range m.FileGroups { +func (ms *StreamMetadataSet) iterateDataFiles(f func(d *FileGroupInfo) (shouldBreak bool)) { + for _, m := range ms.metadataInfos { + for _, d := range m.FileGroupInfos { if f(d) { return } @@ -75,21 +129,6 @@ func (ms *StreamMetadataSet) iterateDataFiles(f func(d *backuppb.DataFileGroup) } } -// CalculateShiftTS calculates the shift-ts. -func (ms *StreamMetadataSet) CalculateShiftTS(startTS uint64) uint64 { - metadatas := make([]*backuppb.Metadata, 0, len(ms.metadata)) - for _, m := range ms.metadata { - metadatas = append(metadatas, m) - } - - minBeginTS, exist := CalculateShiftTS(metadatas, startTS, mathutil.MaxUint) - if !exist { - minBeginTS = startTS - } - log.Warn("calculate shift-ts", zap.Uint64("start-ts", startTS), zap.Uint64("shift-ts", minBeginTS)) - return minBeginTS -} - // IterateFilesFullyBefore runs the function over all files contain data before the timestamp only. // // 0 before @@ -98,78 +137,145 @@ func (ms *StreamMetadataSet) CalculateShiftTS(startTS uint64) uint64 { // |-file2--------------| <- File contains any record out of this won't be found. // // This function would call the `f` over file1 only. -func (ms *StreamMetadataSet) IterateFilesFullyBefore(before uint64, f func(d *backuppb.DataFileGroup) (shouldBreak bool)) { - ms.iterateDataFiles(func(d *backuppb.DataFileGroup) (shouldBreak bool) { - if d.MaxTs >= before { +func (ms *StreamMetadataSet) IterateFilesFullyBefore(before uint64, f func(d *FileGroupInfo) (shouldBreak bool)) { + ms.iterateDataFiles(func(d *FileGroupInfo) (shouldBreak bool) { + if d.MaxTS >= before { return false } return f(d) }) } -// RemoveDataBefore would find files contains only records before the timestamp, mark them as removed from meta, -// and returning their information. -func (ms *StreamMetadataSet) RemoveDataBefore(from uint64) []*backuppb.DataFileGroup { - removed := []*backuppb.DataFileGroup{} - for metaPath, m := range ms.metadata { - remainedDataFiles := make([]*backuppb.DataFileGroup, 0) - // can we assume those files are sorted to avoid traversing here? (by what?) - for _, ds := range m.FileGroups { - if ds.MaxTs < from { - removed = append(removed, ds) - } else { - remainedDataFiles = append(remainedDataFiles, ds) +// RemoveDataFilesAndUpdateMetadataInBatch concurrently remove datafilegroups and update metadata. +// Only one metadata is processed in each thread, including deleting its datafilegroup and updating it. +// Returns the not deleted datafilegroups. +func (ms *StreamMetadataSet) RemoveDataFilesAndUpdateMetadataInBatch(ctx context.Context, from uint64, storage storage.ExternalStorage, updateFn func(num int64)) ([]string, error) { + var notDeleted struct { + item []string + sync.Mutex + } + worker := utils.NewWorkerPool(128, "delete files") + eg, cx := errgroup.WithContext(ctx) + for path, metaInfo := range ms.metadataInfos { + path := path + minTS := metaInfo.MinTS + // It's safety to remove the item within a range loop + delete(ms.metadataInfos, path) + if minTS >= from { + // That means all the datafiles wouldn't be removed, + // so that the metadata is skipped. + continue + } + worker.ApplyOnErrorGroup(eg, func() error { + if cx.Err() != nil { + return cx.Err() + } + + data, err := storage.ReadFile(ctx, path) + if err != nil { + return err + } + + meta, err := ms.Helper.ParseToMetadataHard(data) + if err != nil { + return err + } + + num, notDeletedItems, err := ms.removeDataFilesAndUpdateMetadata(ctx, storage, from, meta, path) + if err != nil { + return err } + + updateFn(num) + + notDeleted.Lock() + notDeleted.item = append(notDeleted.item, notDeletedItems...) + notDeleted.Unlock() + return nil + }) + } + + if err := eg.Wait(); err != nil { + return nil, errors.Trace(err) + } + + return notDeleted.item, nil +} + +// removeDataFilesAndUpdateMetadata removes some datafilegroups of the metadata, if their max-ts is less than `from` +func (ms *StreamMetadataSet) removeDataFilesAndUpdateMetadata(ctx context.Context, storage storage.ExternalStorage, from uint64, meta *backuppb.Metadata, metaPath string) (num int64, notDeleted []string, err error) { + removed := make([]*backuppb.DataFileGroup, 0) + remainedDataFiles := make([]*backuppb.DataFileGroup, 0) + notDeleted = make([]string, 0) + // can we assume those files are sorted to avoid traversing here? (by what?) + for _, ds := range meta.FileGroups { + if ds.MaxTs < from { + removed = append(removed, ds) + } else { + // That means some kvs in the datafilegroup shouldn't be removed, + // so it will be kept out being removed. + remainedDataFiles = append(remainedDataFiles, ds) } - if len(remainedDataFiles) != len(m.FileGroups) { - mCopy := *m - mCopy.FileGroups = remainedDataFiles - ms.WriteBack(metaPath, &mCopy) + } + + num = int64(len(removed)) + + if ms.DryRun { + log.Debug("dry run, skip deletion ...") + return num, notDeleted, nil + } + + // remove data file groups + for _, f := range removed { + log.Debug("Deleting file", zap.String("path", f.Path)) + if err := storage.DeleteFile(ctx, f.Path); err != nil { + log.Warn("File not deleted.", zap.String("path", f.Path), logutil.ShortError(err)) + notDeleted = append(notDeleted, f.Path) + if len(notDeleted) > notDeletedBecameFatalThreshold { + return num, notDeleted, errors.Annotatef(berrors.ErrPiTRMalformedMetadata, "too many failure when truncating") + } } } - return removed -} -func (ms *StreamMetadataSet) WriteBack(path string, file *backuppb.Metadata) { - ms.writeback[path] = file -} + // update metadata + if len(remainedDataFiles) != len(meta.FileGroups) { + // rewrite metadata + log.Info("Updating metadata.", zap.String("file", metaPath), + zap.Int("data-file-before", len(meta.FileGroups)), + zap.Int("data-file-after", len(remainedDataFiles))) + + // replace the filegroups and update the ts of the replaced metadata + ReplaceMetadata(meta, remainedDataFiles) -func (ms *StreamMetadataSet) doWriteBackForFile(ctx context.Context, s storage.ExternalStorage, path string) error { - data, ok := ms.writeback[path] - if !ok { - return errors.Annotatef(berrors.ErrInvalidArgument, "There is no write back for path %s", path) + if ms.BeforeDoWriteBack != nil && ms.BeforeDoWriteBack(metaPath, meta) { + return num, notDeleted, nil + } + + if err := ms.doWriteBackForFile(ctx, storage, metaPath, meta); err != nil { + // NOTE: Maybe we'd better roll back all writebacks? (What will happen if roll back fails too?) + return num, notDeleted, errors.Annotatef(err, "failed to write back file %s", metaPath) + } } + + return num, notDeleted, nil +} + +func (ms *StreamMetadataSet) doWriteBackForFile(ctx context.Context, s storage.ExternalStorage, path string, meta *backuppb.Metadata) error { // If the metadata file contains no data file, remove it due to it is meanless. - if len(data.FileGroups) == 0 { + if len(meta.FileGroups) == 0 { if err := s.DeleteFile(ctx, path); err != nil { return errors.Annotatef(err, "failed to remove the empty meta %s", path) } return nil } - bs, err := ms.Helper.Marshal(data) + bs, err := ms.Helper.Marshal(meta) if err != nil { return errors.Annotatef(err, "failed to marshal the file %s", path) } return truncateAndWrite(ctx, s, path, bs) } -func (ms *StreamMetadataSet) DoWriteBack(ctx context.Context, s storage.ExternalStorage) error { - for path := range ms.writeback { - if ms.BeforeDoWriteBack != nil && ms.BeforeDoWriteBack(path, ms.metadata[path], ms.writeback[path]) { - return nil - } - err := ms.doWriteBackForFile(ctx, s, path) - // NOTE: Maybe we'd better roll back all writebacks? (What will happen if roll back fails too?) - if err != nil { - return errors.Annotatef(err, "failed to write back file %s", path) - } - - delete(ms.writeback, path) - } - return nil -} - func truncateAndWrite(ctx context.Context, s storage.ExternalStorage, path string, data []byte) error { // Performance hack: the `Write` implemention would truncate the file if it exists. if err := s.WriteFile(ctx, path, data); err != nil { @@ -248,26 +354,30 @@ func UpdateShiftTS(m *backuppb.Metadata, startTS uint64, restoreTS uint64) (uint return minBeginTS, isExist } -// CalculateShiftTS gets the minimal begin-ts about transaction according to the kv-event in write-cf. -func CalculateShiftTS( - metas []*backuppb.Metadata, - startTS uint64, - restoreTS uint64, -) (uint64, bool) { - var ( - minBeginTS uint64 - isExist bool - ) - for _, m := range metas { - if len(m.FileGroups) == 0 || m.MinTs > restoreTS || m.MaxTs < startTS { - continue +// replace the filegroups and update the ts of the replaced metadata +func ReplaceMetadata(meta *backuppb.Metadata, filegroups []*backuppb.DataFileGroup) { + // replace the origin metadata + meta.FileGroups = filegroups + + if len(meta.FileGroups) == 0 { + meta.MinTs = 0 + meta.MaxTs = 0 + meta.ResolvedTs = 0 + return + } + + meta.MinTs = meta.FileGroups[0].MinTs + meta.MaxTs = meta.FileGroups[0].MaxTs + meta.ResolvedTs = meta.FileGroups[0].MinResolvedTs + for _, group := range meta.FileGroups { + if group.MinTs < meta.MinTs { + meta.MinTs = group.MinTs + } + if group.MaxTs > meta.MaxTs { + meta.MaxTs = group.MaxTs } - ts, ok := UpdateShiftTS(m, startTS, restoreTS) - if ok && (!isExist || ts < minBeginTS) { - minBeginTS = ts - isExist = true + if group.MinResolvedTs < meta.ResolvedTs { + meta.ResolvedTs = group.MinResolvedTs } } - - return minBeginTS, isExist } diff --git a/br/pkg/restore/stream_metas_test.go b/br/pkg/restore/stream_metas_test.go index 8e75f7544885e..407f5a0154ca3 100644 --- a/br/pkg/restore/stream_metas_test.go +++ b/br/pkg/restore/stream_metas_test.go @@ -6,7 +6,10 @@ import ( "context" "fmt" "math/rand" + "os" + "path" "path/filepath" + "sync" "testing" "github.com/fsouza/fake-gcs-server/fakestorage" @@ -16,7 +19,6 @@ import ( "github.com/pingcap/tidb/br/pkg/restore" "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/br/pkg/stream" - "github.com/pingcap/tidb/util/mathutil" "github.com/stretchr/testify/require" "go.uber.org/zap" ) @@ -36,13 +38,59 @@ func fakeDataFiles(s storage.ExternalStorage, base, item int) (result []*backupp return } +func fakeDataFilesV2(s storage.ExternalStorage, base, item int) (result []*backuppb.DataFileGroup) { + ctx := context.Background() + for i := base; i < base+item; i++ { + path := fmt.Sprintf("%04d_to_%04d.log", i, i+2) + s.WriteFile(ctx, path, []byte("test")) + data := &backuppb.DataFileGroup{ + Path: path, + MinTs: uint64(i), + MaxTs: uint64(i + 2), + } + result = append(result, data) + } + return +} + +func tsOfFile(dfs []*backuppb.DataFileInfo) (uint64, uint64) { + var minTS uint64 = 9876543210 + var maxTS uint64 = 0 + for _, df := range dfs { + if df.MaxTs > maxTS { + maxTS = df.MaxTs + } + if df.MinTs < minTS { + minTS = df.MinTs + } + } + return minTS, maxTS +} + +func tsOfFileGroup(dfs []*backuppb.DataFileGroup) (uint64, uint64) { + var minTS uint64 = 9876543210 + var maxTS uint64 = 0 + for _, df := range dfs { + if df.MaxTs > maxTS { + maxTS = df.MaxTs + } + if df.MinTs < minTS { + minTS = df.MinTs + } + } + return minTS, maxTS +} + func fakeStreamBackup(s storage.ExternalStorage) error { ctx := context.Background() base := 0 for i := 0; i < 6; i++ { dfs := fakeDataFiles(s, base, 4) base += 4 + minTS, maxTS := tsOfFile(dfs) meta := &backuppb.Metadata{ + MinTs: minTS, + MaxTs: maxTS, Files: dfs, StoreId: int64(i%3 + 1), } @@ -64,43 +112,13 @@ func fakeStreamBackupV2(s storage.ExternalStorage) error { ctx := context.Background() base := 0 for i := 0; i < 6; i++ { - dfs := fakeDataFiles(s, base, 4) - minTs1 := uint64(18446744073709551615) - maxTs1 := uint64(0) - for _, f := range dfs[0:2] { - f.Path = fmt.Sprintf("%d", i) - if minTs1 > f.MinTs { - minTs1 = f.MinTs - } - if maxTs1 < f.MaxTs { - maxTs1 = f.MaxTs - } - } - minTs2 := uint64(18446744073709551615) - maxTs2 := uint64(0) - for _, f := range dfs[2:] { - f.Path = fmt.Sprintf("%d", i) - if minTs2 > f.MinTs { - minTs2 = f.MinTs - } - if maxTs2 < f.MaxTs { - maxTs2 = f.MaxTs - } - } + dfs := fakeDataFilesV2(s, base, 4) base += 4 + minTS, maxTS := tsOfFileGroup(dfs) meta := &backuppb.Metadata{ - FileGroups: []*backuppb.DataFileGroup{ - { - DataFilesInfo: dfs[0:2], - MinTs: minTs1, - MaxTs: maxTs1, - }, - { - DataFilesInfo: dfs[2:], - MinTs: minTs2, - MaxTs: maxTs2, - }, - }, + MinTs: minTS, + MaxTs: maxTS, + FileGroups: dfs, StoreId: int64(i%3 + 1), MetaVersion: backuppb.MetaVersion_V2, } @@ -135,42 +153,59 @@ func TestTruncateLog(t *testing.T) { } require.NoError(t, s.LoadFrom(ctx, l)) - fs := []*backuppb.DataFileGroup{} - s.IterateFilesFullyBefore(17, func(d *backuppb.DataFileGroup) (shouldBreak bool) { + fs := []*restore.FileGroupInfo{} + s.IterateFilesFullyBefore(17, func(d *restore.FileGroupInfo) (shouldBreak bool) { fs = append(fs, d) - require.Less(t, d.MaxTs, uint64(17)) + require.Less(t, d.MaxTS, uint64(17)) return false }) require.Len(t, fs, 15) - s.RemoveDataBefore(17) - deletedFiles := []string{} - modifiedFiles := []string{} - s.BeforeDoWriteBack = func(path string, last, current *backuppb.Metadata) bool { - require.NotNil(t, last) - if len(current.GetFileGroups()) == 0 { - deletedFiles = append(deletedFiles, path) - } else if len(current.GetFileGroups()) != len(last.GetFileGroups()) { - modifiedFiles = append(modifiedFiles, path) + var lock sync.Mutex + remainedFiles := []string{} + remainedDataFiles := []string{} + removedMetaFiles := []string{} + s.BeforeDoWriteBack = func(path string, replaced *backuppb.Metadata) bool { + lock.Lock() + require.NotNil(t, replaced) + if len(replaced.GetFileGroups()) > 0 { + remainedFiles = append(remainedFiles, path) + for _, ds := range replaced.FileGroups { + remainedDataFiles = append(remainedDataFiles, ds.Path) + } + } else { + removedMetaFiles = append(removedMetaFiles, path) } + lock.Unlock() return false } - require.NoError(t, s.DoWriteBack(ctx, l)) - require.ElementsMatch(t, deletedFiles, []string{"v1/backupmeta/0000.meta", "v1/backupmeta/0001.meta", "v1/backupmeta/0002.meta"}) - require.ElementsMatch(t, modifiedFiles, []string{"v1/backupmeta/0003.meta"}) + + var total int64 = 0 + notDeleted, err := s.RemoveDataFilesAndUpdateMetadataInBatch(ctx, 17, l, func(num int64) { + lock.Lock() + total += num + lock.Unlock() + }) + require.NoError(t, err) + require.Equal(t, len(notDeleted), 0) + require.ElementsMatch(t, remainedFiles, []string{"v1/backupmeta/0003.meta"}) + require.ElementsMatch(t, removedMetaFiles, []string{"v1/backupmeta/0000.meta", "v1/backupmeta/0001.meta", "v1/backupmeta/0002.meta"}) + require.ElementsMatch(t, remainedDataFiles, []string{"0015_to_0017.log"}) + require.Equal(t, total, int64(15)) require.NoError(t, s.LoadFrom(ctx, l)) - s.IterateFilesFullyBefore(17, func(d *backuppb.DataFileGroup) (shouldBreak bool) { + s.IterateFilesFullyBefore(17, func(d *restore.FileGroupInfo) (shouldBreak bool) { t.Errorf("some of log files still not truncated, it is %#v", d) return true }) - l.WalkDir(ctx, &storage.WalkOption{ + err = l.WalkDir(ctx, &storage.WalkOption{ SubDir: stream.GetStreamBackupMetaPrefix(), }, func(s string, i int64) error { - require.NotContains(t, deletedFiles, s) + require.NotContains(t, removedMetaFiles, s) return nil }) + require.NoError(t, err) } func TestTruncateLogV2(t *testing.T) { @@ -190,42 +225,59 @@ func TestTruncateLogV2(t *testing.T) { } require.NoError(t, s.LoadFrom(ctx, l)) - fs := []*backuppb.DataFileGroup{} - s.IterateFilesFullyBefore(17, func(d *backuppb.DataFileGroup) (shouldBreak bool) { + fs := []*restore.FileGroupInfo{} + s.IterateFilesFullyBefore(17, func(d *restore.FileGroupInfo) (shouldBreak bool) { fs = append(fs, d) - require.Less(t, d.MaxTs, uint64(17)) + require.Less(t, d.MaxTS, uint64(17)) return false }) - require.Len(t, fs, 7) - - s.RemoveDataBefore(17) - deletedFiles := []string{} - modifiedFiles := []string{} - s.BeforeDoWriteBack = func(path string, last, current *backuppb.Metadata) bool { - require.NotNil(t, last) - if len(current.GetFileGroups()) == 0 { - deletedFiles = append(deletedFiles, path) - } else if len(current.GetFileGroups()) != len(last.GetFileGroups()) { - modifiedFiles = append(modifiedFiles, path) + require.Len(t, fs, 15) + + var lock sync.Mutex + remainedFiles := []string{} + remainedDataFiles := []string{} + removedMetaFiles := []string{} + s.BeforeDoWriteBack = func(path string, replaced *backuppb.Metadata) bool { + lock.Lock() + require.NotNil(t, replaced) + if len(replaced.GetFileGroups()) > 0 { + remainedFiles = append(remainedFiles, path) + for _, ds := range replaced.FileGroups { + remainedDataFiles = append(remainedDataFiles, ds.Path) + } + } else { + removedMetaFiles = append(removedMetaFiles, path) } + lock.Unlock() return false } - require.NoError(t, s.DoWriteBack(ctx, l)) - require.ElementsMatch(t, deletedFiles, []string{"v1/backupmeta/0000.meta", "v1/backupmeta/0001.meta", "v1/backupmeta/0002.meta"}) - require.ElementsMatch(t, modifiedFiles, []string{"v1/backupmeta/0003.meta"}) + + var total int64 = 0 + notDeleted, err := s.RemoveDataFilesAndUpdateMetadataInBatch(ctx, 17, l, func(num int64) { + lock.Lock() + total += num + lock.Unlock() + }) + require.NoError(t, err) + require.Equal(t, len(notDeleted), 0) + require.ElementsMatch(t, remainedFiles, []string{"v1/backupmeta/0003.meta"}) + require.ElementsMatch(t, removedMetaFiles, []string{"v1/backupmeta/0000.meta", "v1/backupmeta/0001.meta", "v1/backupmeta/0002.meta"}) + require.ElementsMatch(t, remainedDataFiles, []string{"0015_to_0017.log"}) + require.Equal(t, total, int64(15)) require.NoError(t, s.LoadFrom(ctx, l)) - s.IterateFilesFullyBefore(17, func(d *backuppb.DataFileGroup) (shouldBreak bool) { + s.IterateFilesFullyBefore(17, func(d *restore.FileGroupInfo) (shouldBreak bool) { t.Errorf("some of log files still not truncated, it is %#v", d) return true }) - l.WalkDir(ctx, &storage.WalkOption{ + err = l.WalkDir(ctx, &storage.WalkOption{ SubDir: stream.GetStreamBackupMetaPrefix(), }, func(s string, i int64) error { - require.NotContains(t, deletedFiles, s) + require.NotContains(t, removedMetaFiles, s) return nil }) + require.NoError(t, err) } func TestTruncateSafepoint(t *testing.T) { @@ -265,7 +317,7 @@ func TestTruncateSafepointForGCS(t *testing.T) { CredentialsBlob: "Fake Credentials", } - l, err := storage.NewGCSStorageForTest(ctx, gcs, &storage.ExternalStorageOptions{ + l, err := storage.NewGCSStorage(ctx, gcs, &storage.ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []storage.Permission{storage.AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -425,52 +477,1835 @@ func fakeMetaDataV2s(t *testing.T, helper *stream.MetadataHelper, cf string) []* return m2s } +func ff(minTS, maxTS uint64) *backuppb.DataFileGroup { + return f(0, minTS, maxTS, stream.DefaultCF, 0) +} + +func TestReplaceMetadataTs(t *testing.T) { + m := &backuppb.Metadata{} + restore.ReplaceMetadata(m, []*backuppb.DataFileGroup{ + ff(1, 3), + ff(4, 5), + }) + require.Equal(t, m.MinTs, uint64(1)) + require.Equal(t, m.MaxTs, uint64(5)) + + restore.ReplaceMetadata(m, []*backuppb.DataFileGroup{ + ff(1, 4), + ff(3, 5), + }) + require.Equal(t, m.MinTs, uint64(1)) + require.Equal(t, m.MaxTs, uint64(5)) + + restore.ReplaceMetadata(m, []*backuppb.DataFileGroup{ + ff(1, 6), + ff(0, 5), + }) + require.Equal(t, m.MinTs, uint64(0)) + require.Equal(t, m.MaxTs, uint64(6)) + + restore.ReplaceMetadata(m, []*backuppb.DataFileGroup{ + ff(1, 3), + }) + require.Equal(t, m.MinTs, uint64(1)) + require.Equal(t, m.MaxTs, uint64(3)) + + restore.ReplaceMetadata(m, []*backuppb.DataFileGroup{}) + require.Equal(t, m.MinTs, uint64(0)) + require.Equal(t, m.MaxTs, uint64(0)) + + restore.ReplaceMetadata(m, []*backuppb.DataFileGroup{ + ff(1, 3), + ff(2, 4), + ff(0, 2), + }) + require.Equal(t, m.MinTs, uint64(0)) + require.Equal(t, m.MaxTs, uint64(4)) +} + +func m(storeId int64, minTS, maxTS uint64) *backuppb.Metadata { + return &backuppb.Metadata{ + StoreId: storeId, + MinTs: minTS, + MaxTs: maxTS, + MetaVersion: backuppb.MetaVersion_V2, + } +} + +func f(storeId int64, minTS, maxTS uint64, cf string, defaultTS uint64) *backuppb.DataFileGroup { + return &backuppb.DataFileGroup{ + Path: logName(storeId, minTS, maxTS), + DataFilesInfo: []*backuppb.DataFileInfo{ + { + NumberOfEntries: 1, + MinTs: minTS, + MaxTs: maxTS, + Cf: cf, + MinBeginTsInDefaultCf: defaultTS, + }, + }, + MinTs: minTS, + MaxTs: maxTS, + } +} + +// get the metadata with only one datafilegroup +func m_1(storeId int64, minTS, maxTS uint64, cf string, defaultTS uint64) *backuppb.Metadata { + meta := m(storeId, minTS, maxTS) + meta.FileGroups = []*backuppb.DataFileGroup{ + f(storeId, minTS, maxTS, cf, defaultTS), + } + return meta +} + +// get the metadata with 2 datafilegroup +func m_2( + storeId int64, + minTSL, maxTSL uint64, cfL string, defaultTSL uint64, + minTSR, maxTSR uint64, cfR string, defaultTSR uint64, +) *backuppb.Metadata { + meta := m(storeId, minTSL, maxTSR) + meta.FileGroups = []*backuppb.DataFileGroup{ + f(storeId, minTSL, maxTSL, cfL, defaultTSL), + f(storeId, minTSR, maxTSR, cfR, defaultTSR), + } + return meta +} + +// clean the files in the external storage +func cleanFiles(ctx context.Context, s storage.ExternalStorage) error { + names := make([]string, 0) + err := s.WalkDir(ctx, &storage.WalkOption{}, func(path string, size int64) error { + names = append(names, path) + return nil + }) + if err != nil { + return err + } + for _, path := range names { + err := s.DeleteFile(ctx, path) + if err != nil { + return err + } + } + return nil +} + +func metaName(storeId int64) string { + return fmt.Sprintf("%s/%04d.meta", stream.GetStreamBackupMetaPrefix(), storeId) +} + +func logName(storeId int64, minTS, maxTS uint64) string { + return fmt.Sprintf("%04d_%04d_%04d.log", storeId, minTS, maxTS) +} + +// generate the files to the external storage +func generateFiles(ctx context.Context, s storage.ExternalStorage, metas []*backuppb.Metadata, tmpDir string) error { + if err := cleanFiles(ctx, s); err != nil { + return err + } + fname := path.Join(tmpDir, stream.GetStreamBackupMetaPrefix()) + os.MkdirAll(fname, 0777) + for _, meta := range metas { + data, err := meta.Marshal() + if err != nil { + return err + } + + fname := metaName(meta.StoreId) + err = s.WriteFile(ctx, fname, data) + if err != nil { + return err + } + + for _, group := range meta.FileGroups { + fname := logName(meta.StoreId, group.MinTs, group.MaxTs) + err = s.WriteFile(ctx, fname, []byte("test")) + if err != nil { + return err + } + } + } + + return nil +} + +// check the files in the external storage +func checkFiles(ctx context.Context, s storage.ExternalStorage, metas []*backuppb.Metadata, t *testing.T) { + pathSet := make(map[string]struct{}) + for _, meta := range metas { + metaPath := metaName(meta.StoreId) + pathSet[metaPath] = struct{}{} + exists, err := s.FileExists(ctx, metaPath) + require.NoError(t, err) + require.True(t, exists) + + data, err := s.ReadFile(ctx, metaPath) + require.NoError(t, err) + metaRead := &backuppb.Metadata{} + err = metaRead.Unmarshal(data) + require.NoError(t, err) + require.Equal(t, meta.MinTs, metaRead.MinTs) + require.Equal(t, meta.MaxTs, metaRead.MaxTs) + for i, group := range meta.FileGroups { + require.Equal(t, metaRead.FileGroups[i].Path, group.Path) + logPath := logName(meta.StoreId, group.MinTs, group.MaxTs) + pathSet[logPath] = struct{}{} + exists, err := s.FileExists(ctx, logPath) + require.NoError(t, err) + require.True(t, exists) + } + } + + err := s.WalkDir(ctx, &storage.WalkOption{}, func(path string, size int64) error { + _, exists := pathSet[path] + require.True(t, exists, path) + return nil + }) + require.NoError(t, err) +} + +type testParam struct { + until []uint64 + shiftUntilTS uint64 + restMetadata []*backuppb.Metadata +} + +func TestTruncate1(t *testing.T) { + ctx := context.Background() + tmpDir := t.TempDir() + s, err := storage.NewLocalStorage(tmpDir) + require.NoError(t, err) + + cases := []struct { + metas []*backuppb.Metadata + testParams []*testParam + }{ + { + // metadata 10-----------20 + // ↑ ↑ + // +-----------+ + // ↓ ↓ + // filegroup 10-----d-----20 + metas: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + }, + testParams: []*testParam{ + { + until: []uint64{5}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + }, + }, { + until: []uint64{10}, + shiftUntilTS: 10, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + }, + }, { + until: []uint64{15}, + shiftUntilTS: 15, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + }, + }, { + until: []uint64{20}, + shiftUntilTS: 20, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // ↑ ↑ + // +-----------+ + // ↓ ↓ + // filegroup 5-d--10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 7, 10, 15, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 5----8 10-----------20 + // ↑ ↑ ↑ ↑ + // +----+ +-----------+ + // ↓ ↓ ↓ ↓ + // filegroup 5--d-8 ↓ ↓ + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 5, 8, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 8, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 9, 10, 15, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 8, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata 5------10 ↑ + // ↑ ↑ ↑ + // +-------+-----------+ + // ↓ ↓ ↓ + // filegroup 5--d---10 ↓ + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 5, 10, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 10, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 9, 10, 15, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 10, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata 5-------↑-12 ↑ + // ↑ ↑ ↑ ↑ + // +-------+-+---------+ + // ↓ ↓ ↓ ↓ + // filegroup 5--d----↓-12 ↓ + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 5, 12, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 12, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 9, 10, 15, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 12, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata 5-------↑-----------20 + // ↑ ↑ ↑ + // +-------+-----------+ + // ↓ ↓ ↓ + // filegroup 5--d----↓-----------20 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 5, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 15, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata 5-------↑-----------↑--22 + // ↑ ↑ ↑ ↑ + // +-------+-----------+--+ + // ↓ ↓ ↓ ↓ + // filegroup 5--d----↓-----------↓--22 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 5, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 15, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{21}, + shiftUntilTS: 21, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{22}, + shiftUntilTS: 22, restMetadata: []*backuppb.Metadata{ + m_1(1, 5, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata 10---14 ↑ + // ↑ ↑ ↑ + // +----+-------+ + // ↓ ↓ ↓ + // filegroup 10-d-14 ↓ + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 10, 14, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 14, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 12, 14, 18, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 14, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata 10-----------20 + // ↑ ↑ + // +------------+ + // ↓ ↓ + // filegroup 10----d------20 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 14, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata 10------------↑--22 + // ↑ ↑ ↑ + // +------------+---+ + // ↓ ↓ ↓ + // filegroup 10----d-------↓--22 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 10, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 14, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{21}, + shiftUntilTS: 21, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{22}, + shiftUntilTS: 22, restMetadata: []*backuppb.Metadata{ + m_1(1, 10, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata ↑ 12-----18 ↑ + // ↑ ↑ ↑ ↑ + // +--+------+--+ + // ↓ ↓ ↓ ↓ + // filegroup ↓ 12--d--18 ↓ + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 12, 18, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 12, 18, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 11, 12, 15, 18, 19, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 12, 18, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata ↑ 14----20 + // ↑ ↑ ↑ + // +------+-----+ + // ↓ ↓ ↓ + // filegroup ↓ 14--d-20 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 14, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 14, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 14, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 14, 20, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata ↑ 14-----↑--22 + // ↑ ↑ ↑ ↑ + // +------+-----+---+ + // ↓ ↓ ↓ ↓ + // filegroup ↓ 14-d--↓--22 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 14, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 14, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 14, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 14, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{21}, + shiftUntilTS: 21, restMetadata: []*backuppb.Metadata{ + m_1(1, 14, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{22}, + shiftUntilTS: 22, restMetadata: []*backuppb.Metadata{ + m_1(1, 14, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata ↑ 20--22 + // ↑ ↑ ↑ + // +------------+---+ + // ↓ ↓ ↓ + // filegroup ↓ 20--22 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 20, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 20, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 14, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 20, 22, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{21}, + shiftUntilTS: 21, restMetadata: []*backuppb.Metadata{ + m_1(1, 20, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{22}, + shiftUntilTS: 22, restMetadata: []*backuppb.Metadata{ + m_1(1, 20, 22, stream.DefaultCF, 0), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 10-----------20 + // metadata ↑ ↑ 21---24 + // ↑ ↑ ↑ ↑ + // +------------+--+----+ + // ↓ ↓ ↓ ↓ + // filegroup ↓ ↓ 21-d-24 + // filegroup 5--d---10-----w-----20 + metas: []*backuppb.Metadata{ + m_1(1, 21, 24, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + testParams: []*testParam{ + { + until: []uint64{3}, + shiftUntilTS: 3, restMetadata: []*backuppb.Metadata{ + m_1(1, 21, 24, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{5, 8, 10, 14, 20}, + shiftUntilTS: 5, restMetadata: []*backuppb.Metadata{ + m_1(1, 21, 24, stream.DefaultCF, 0), + m_1(2, 10, 20, stream.WriteCF, 5), + }, + }, { + until: []uint64{21}, + shiftUntilTS: 21, restMetadata: []*backuppb.Metadata{ + m_1(1, 21, 24, stream.DefaultCF, 0), + }, + }, { + until: []uint64{22}, + shiftUntilTS: 22, restMetadata: []*backuppb.Metadata{ + m_1(1, 21, 24, stream.DefaultCF, 0), + }, + }, { + until: []uint64{25}, + shiftUntilTS: 25, restMetadata: []*backuppb.Metadata{}, + }, + }, + }, + } + + for i, cs := range cases { + for j, ts := range cs.testParams { + for _, until := range ts.until { + t.Logf("case %d, param %d, until %d", i, j, until) + metas := restore.StreamMetadataSet{ + Helper: stream.NewMetadataHelper(), + } + err := generateFiles(ctx, s, cs.metas, tmpDir) + require.NoError(t, err) + shiftUntilTS, err := metas.LoadUntilAndCalculateShiftTS(ctx, s, until) + require.NoError(t, err) + require.Equal(t, shiftUntilTS, ts.shiftUntilTS) + n, err := metas.RemoveDataFilesAndUpdateMetadataInBatch(ctx, shiftUntilTS, s, func(num int64) {}) + require.Equal(t, len(n), 0) + require.NoError(t, err) + + // check the result + checkFiles(ctx, s, ts.restMetadata, t) + } + } + } +} + +type testParam2 struct { + until []uint64 + shiftUntilTS func(uint64) uint64 + restMetadata []*backuppb.Metadata +} + +func returnV(v uint64) func(uint64) uint64 { + return func(uint64) uint64 { + return v + } +} + +func returnSelf() func(uint64) uint64 { + return func(u uint64) uint64 { + return u + } +} + +func TestTruncate2(t *testing.T) { + ctx := context.Background() + tmpDir := t.TempDir() + s, err := storage.NewLocalStorage(tmpDir) + require.NoError(t, err) + + cases := []struct { + metas []*backuppb.Metadata + testParams []*testParam2 + }{ + { + // metadata 10-----------20 + // ↑ ↑ + // +-----------+ + // ↓ ↓ ↓ ↓ + // filegroup 10-d-13 ↓ ↓ + // filegroup 8----d--15-w-20 + metas: []*backuppb.Metadata{ + m_2(1, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{5}, + shiftUntilTS: returnV(5), restMetadata: []*backuppb.Metadata{ + m_2(1, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{8, 9, 10, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(8), restMetadata: []*backuppb.Metadata{ + m_2(1, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +-----------+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3 6 10-d-13 ↓ ↓ + // filegroup 1-----------d--15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 1, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{0}, + shiftUntilTS: returnV(0), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{1, 2, 3, 4, 6, 9, 10, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(1), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +-----------+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3 6 10-d-13 ↓ ↓ + // filegroup 3----------d--15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 3, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2}, + shiftUntilTS: returnV(2), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 3, + ), + }, + }, { + until: []uint64{3, 4, 6, 9, 10, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(3), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 3, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---7 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+-+----+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3 7 10-d-13 ↓ ↓ + // filegroup 5--------d--15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 7, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 5, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 7, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 5, + ), + }, + }, { + until: []uint64{5, 6, 7, 9, 10, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(5), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 7, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 5, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---7 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+-+----+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3 7 10-d-13 ↓ ↓ + // filegroup 7------d--15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 7, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 7, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4, 6, 7}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 7, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 7, + ), + }, + }, { + until: []uint64{9, 10, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(7), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 7, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 7, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+-+----+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3-d-6 10-d-13 ↓ ↓ + // filegroup 8----d--15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4, 6}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{7}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{8, 9, 10, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(8), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+-+----+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3-d-6 10-d-13 ↓ ↓ + // filegroup 10--d--15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 10, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4, 6}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 10, + ), + }, + }, { + until: []uint64{7, 8, 9}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 10, + ), + }, + }, { + until: []uint64{10, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(10), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 10, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+-+----+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3-d-6 9-d-13 ↓ ↓ + // filegroup 11-d-15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 9, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 11, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4, 6}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 9, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 11, + ), + }, + }, { + until: []uint64{7, 8, 9, 10}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(2, + 9, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 11, + ), + }, + }, { + until: []uint64{11, 12, 13, 14, 15, 18, 20}, + shiftUntilTS: returnV(11), restMetadata: []*backuppb.Metadata{ + m_2(2, + 9, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 11, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+-+----+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3-d-6 10-d-13 ↓ ↓ + // filegroup 13d15-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 13, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4, 6}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 13, + ), + }, + }, { + until: []uint64{7, 8, 9, 10, 12}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 13, + ), + }, + }, { + until: []uint64{13, 14, 15, 18, 20}, + shiftUntilTS: returnV(13), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 13, stream.DefaultCF, 0, + 15, 20, stream.WriteCF, 13, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+--+---+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3-d-6 10-d-12 ↓ ↓ + // filegroup 14d16-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 12, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4, 6}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 12, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{7, 8, 9, 10, 11, 12}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 12, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{13}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(2, 16, 20, stream.WriteCF, 14), + }, + }, { + until: []uint64{14, 15, 18, 20}, + shiftUntilTS: returnV(14), restMetadata: []*backuppb.Metadata{ + m_1(2, 16, 20, stream.WriteCF, 14), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 3---6 10----------20 + // ↑ ↑ ↑ ↑ + // +---+ +----+--+---+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3-d-6 10-d-12 ↓ ↓ + // filegroup 14d16-w-20 + metas: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 12, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2, 3, 4, 6}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, 3, 6, stream.DefaultCF, 0), + m_2(2, + 10, 12, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{7, 8, 9, 10, 11, 12}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(2, + 10, 12, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{13}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(2, 16, 20, stream.WriteCF, 14), + }, + }, { + until: []uint64{14, 15, 18, 20}, + shiftUntilTS: returnV(14), restMetadata: []*backuppb.Metadata{ + m_1(2, 16, 20, stream.WriteCF, 14), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, + } + + for i, cs := range cases { + for j, ts := range cs.testParams { + for _, until := range ts.until { + t.Logf("case %d, param %d, until %d", i, j, until) + metas := restore.StreamMetadataSet{ + Helper: stream.NewMetadataHelper(), + } + err := generateFiles(ctx, s, cs.metas, tmpDir) + require.NoError(t, err) + shiftUntilTS, err := metas.LoadUntilAndCalculateShiftTS(ctx, s, until) + require.NoError(t, err) + require.Equal(t, shiftUntilTS, ts.shiftUntilTS(until)) + n, err := metas.RemoveDataFilesAndUpdateMetadataInBatch(ctx, shiftUntilTS, s, func(num int64) {}) + require.Equal(t, len(n), 0) + require.NoError(t, err) + + // check the result + checkFiles(ctx, s, ts.restMetadata, t) + } + } + } +} + +func TestTruncate3(t *testing.T) { + ctx := context.Background() + tmpDir := t.TempDir() + s, err := storage.NewLocalStorage(tmpDir) + require.NoError(t, err) + + cases := []struct { + metas []*backuppb.Metadata + testParams []*testParam2 + }{ + { + // metadata 3------10 12----------20 + // ↑ ↑ ↑ ↑ + // +-+--+--+ +----+--+---+ + // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 3--d-7 ↓ ↓ ↓ ↓ ↓ + // filegroup 5--d-10 ↓ ↓ ↓ ↓ + // filegroup 3----d-----12---w--18 ↓ + // filegroup 5----d--------15--w--20 + metas: []*backuppb.Metadata{ + m_2(1, + 3, 7, stream.DefaultCF, 0, + 5, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 3, + 15, 20, stream.WriteCF, 5, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{2}, + shiftUntilTS: returnV(2), restMetadata: []*backuppb.Metadata{ + m_2(1, + 3, 7, stream.DefaultCF, 0, + 5, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 3, + 15, 20, stream.WriteCF, 5, + ), + }, + }, { + until: []uint64{3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18}, + shiftUntilTS: returnV(3), restMetadata: []*backuppb.Metadata{ + m_2(1, + 3, 7, stream.DefaultCF, 0, + 5, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 3, + 15, 20, stream.WriteCF, 5, + ), + }, + }, { + until: []uint64{19, 20}, + shiftUntilTS: returnV(5), restMetadata: []*backuppb.Metadata{ + m_2(1, + 3, 7, stream.DefaultCF, 0, + 5, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 3, + 15, 20, stream.WriteCF, 5, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 2------10 12----------20 + // ↑ ↑ ↑ ↑ + // +-+--+--+ +----+--+---+ + // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 2--d-6 ↓ ↓ ↓ ↓ ↓ + // filegroup 4--d-10 ↓ ↓ ↓ ↓ + // filegroup 2----d-----12---w--18 ↓ + // filegroup 8---d----15--w--20 + metas: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 4, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 2, + 15, 20, stream.WriteCF, 8, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{1}, + shiftUntilTS: returnV(1), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 4, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 2, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18}, + shiftUntilTS: returnV(2), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 4, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 2, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{19, 20}, + shiftUntilTS: returnV(8), restMetadata: []*backuppb.Metadata{ + m_1(1, + 4, 10, stream.DefaultCF, 0, + ), + m_2(2, + 12, 18, stream.WriteCF, 2, + 15, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 2------10 14----------20 + // ↑ ↑ ↑ ↑ + // +-+--+--+ +----+--+---+ + // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 2--d-6 ↓ ↓ ↓ ↓ ↓ + // filegroup 4--d-10 ↓ ↓ ↓ ↓ + // filegroup 2----d-------14---w--18 ↓ + // filegroup 12---d--16--w--20 + metas: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 4, 10, stream.DefaultCF, 0, + ), + m_2(2, + 14, 18, stream.WriteCF, 2, + 16, 20, stream.WriteCF, 12, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{1}, + shiftUntilTS: returnV(1), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 4, 10, stream.DefaultCF, 0, + ), + m_2(2, + 14, 18, stream.WriteCF, 2, + 16, 20, stream.WriteCF, 12, + ), + }, + }, { + until: []uint64{2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18}, + shiftUntilTS: returnV(2), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 4, 10, stream.DefaultCF, 0, + ), + m_2(2, + 14, 18, stream.WriteCF, 2, + 16, 20, stream.WriteCF, 12, + ), + }, + }, { + until: []uint64{19, 20}, + shiftUntilTS: returnV(12), restMetadata: []*backuppb.Metadata{ + m_2(2, + 14, 18, stream.WriteCF, 2, + 16, 20, stream.WriteCF, 8, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 2-------10 14----------20 + // ↑ ↑ ↑ ↑ + // +-+--+---+ +----+--+---+ + // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 2--d-6 ↓ ↓ ↓ ↓ ↓ + // filegroup 4-d-8w10 ↓ ↓ ↓ ↓ + // filegroup 14--d---18 ↓ + // filegroup 14-d--16-w--20 + metas: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 8, 10, stream.WriteCF, 4, + ), + m_2(2, + 14, 18, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{1}, + shiftUntilTS: returnV(1), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 8, 10, stream.WriteCF, 4, + ), + m_2(2, + 14, 18, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{2, 3}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 8, 10, stream.WriteCF, 4, + ), + m_2(2, + 14, 18, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{4, 5, 6, 7, 8, 9, 10}, + shiftUntilTS: returnV(4), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 8, 10, stream.WriteCF, 4, + ), + m_2(2, + 14, 18, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{12}, + shiftUntilTS: returnV(12), restMetadata: []*backuppb.Metadata{ + m_2(2, + 14, 18, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{14, 15, 16, 17, 18, 19, 20}, + shiftUntilTS: returnV(14), restMetadata: []*backuppb.Metadata{ + m_2(2, + 14, 18, stream.DefaultCF, 0, + 16, 20, stream.WriteCF, 14, + ), + }, + }, { + until: []uint64{25}, + shiftUntilTS: returnV(25), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, { + // metadata 2-------10 14----------22 24-w-26 + // ↑ ↑ ↑ ↑ ↑ ↑ + // +-+--+---+ +----+--+---+ +----+ + // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 2--d-6 ↓ ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 8d10 ↓ ↓ ↓ ↓ ↓ ↓ + // filegroup 9--d--14--w---18 ↓ ↓ ↓ + // filegroup 16-d--22 ↓ ↓ + // filegroup 20---d-24-w-26 + metas: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 8, 10, stream.DefaultCF, 0, + ), + m_2(2, + 14, 18, stream.WriteCF, 9, + 16, 22, stream.DefaultCF, 0, + ), + m_1(3, + 24, 26, stream.WriteCF, 20, + ), + }, + testParams: []*testParam2{ + { + until: []uint64{1, 2, 3, 6}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_2(1, + 2, 6, stream.DefaultCF, 0, + 8, 10, stream.DefaultCF, 0, + ), + m_2(2, + 14, 18, stream.WriteCF, 9, + 16, 22, stream.DefaultCF, 0, + ), + m_1(3, + 24, 26, stream.WriteCF, 20, + ), + }, + }, { + until: []uint64{7, 8}, + shiftUntilTS: returnSelf(), restMetadata: []*backuppb.Metadata{ + m_1(1, + 8, 10, stream.DefaultCF, 0, + ), + m_2(2, + 14, 18, stream.WriteCF, 9, + 16, 22, stream.DefaultCF, 0, + ), + m_1(3, + 24, 26, stream.WriteCF, 20, + ), + }, + }, { + until: []uint64{9, 10, 11, 14, 15, 16, 17, 18}, + shiftUntilTS: returnV(9), restMetadata: []*backuppb.Metadata{ + m_1(1, + 8, 10, stream.DefaultCF, 0, + ), + m_2(2, + 14, 18, stream.WriteCF, 9, + 16, 22, stream.DefaultCF, 0, + ), + m_1(3, + 24, 26, stream.WriteCF, 20, + ), + }, + }, { + until: []uint64{19}, + shiftUntilTS: returnV(19), restMetadata: []*backuppb.Metadata{ + m_1(2, + 16, 22, stream.DefaultCF, 0, + ), + m_1(3, + 24, 26, stream.WriteCF, 20, + ), + }, + }, { + until: []uint64{20, 21, 22, 23, 24, 25, 26}, + shiftUntilTS: returnV(20), restMetadata: []*backuppb.Metadata{ + m_1(2, + 16, 22, stream.DefaultCF, 0, + ), + m_1(3, + 24, 26, stream.WriteCF, 20, + ), + }, + }, { + until: []uint64{28}, + shiftUntilTS: returnV(28), restMetadata: []*backuppb.Metadata{}, + }, + }, + }, + } + + for i, cs := range cases { + for j, ts := range cs.testParams { + for _, until := range ts.until { + t.Logf("case %d, param %d, until %d", i, j, until) + metas := restore.StreamMetadataSet{ + Helper: stream.NewMetadataHelper(), + } + err := generateFiles(ctx, s, cs.metas, tmpDir) + require.NoError(t, err) + shiftUntilTS, err := metas.LoadUntilAndCalculateShiftTS(ctx, s, until) + require.NoError(t, err) + require.Equal(t, shiftUntilTS, ts.shiftUntilTS(until)) + n, err := metas.RemoveDataFilesAndUpdateMetadataInBatch(ctx, shiftUntilTS, s, func(num int64) {}) + require.Equal(t, len(n), 0) + require.NoError(t, err) + + // check the result + checkFiles(ctx, s, ts.restMetadata, t) + } + } + } +} + +type testParam3 struct { + until []uint64 + shiftUntilTS func(uint64) uint64 +} + +func fi(minTS, maxTS uint64, cf string, defaultTS uint64) *backuppb.DataFileInfo { + return &backuppb.DataFileInfo{ + NumberOfEntries: 1, + MinTs: minTS, + MaxTs: maxTS, + Cf: cf, + MinBeginTsInDefaultCf: defaultTS, + } +} + +func getTsFromFiles(files []*backuppb.DataFileInfo) (uint64, uint64, uint64) { + if len(files) == 0 { + return 0, 0, 0 + } + f := files[0] + minTs, maxTs, resolvedTs := f.MinTs, f.MaxTs, f.ResolvedTs + for _, file := range files { + if file.MinTs < minTs { + minTs = file.MinTs + } + if file.MaxTs > maxTs { + maxTs = file.MaxTs + } + if file.ResolvedTs < resolvedTs { + resolvedTs = file.ResolvedTs + } + } + return minTs, maxTs, resolvedTs +} + +func mf(id int64, filess [][]*backuppb.DataFileInfo) *backuppb.Metadata { + filegroups := make([]*backuppb.DataFileGroup, 0) + for _, files := range filess { + minTs, maxTs, resolvedTs := getTsFromFiles(files) + filegroups = append(filegroups, &backuppb.DataFileGroup{ + DataFilesInfo: files, + MinTs: minTs, + MaxTs: maxTs, + MinResolvedTs: resolvedTs, + }) + } + + m := &backuppb.Metadata{ + StoreId: id, + MetaVersion: backuppb.MetaVersion_V2, + } + restore.ReplaceMetadata(m, filegroups) + return m +} + func TestCalculateShiftTS(t *testing.T) { - var ( - startTs uint64 = 2900 - restoreTS uint64 = 4500 - ) - - helper := stream.NewMetadataHelper() - ms := fakeMetaDatas(t, helper, stream.WriteCF) - shiftTS, exist := restore.CalculateShiftTS(ms, startTs, restoreTS) - require.Equal(t, shiftTS, uint64(2000)) - require.Equal(t, exist, true) - - shiftTS, exist = restore.CalculateShiftTS(ms, startTs, mathutil.MaxUint) - require.Equal(t, shiftTS, uint64(1800)) - require.Equal(t, exist, true) - - shiftTS, exist = restore.CalculateShiftTS(ms, 1999, 3001) - require.Equal(t, shiftTS, uint64(800)) - require.Equal(t, exist, true) - - ms = fakeMetaDatas(t, helper, stream.DefaultCF) - _, exist = restore.CalculateShiftTS(ms, startTs, restoreTS) - require.Equal(t, exist, false) -} - -func TestCalculateShiftTSV2(t *testing.T) { - var ( - startTs uint64 = 2900 - restoreTS uint64 = 5100 - ) - - helper := stream.NewMetadataHelper() - ms := fakeMetaDataV2s(t, helper, stream.WriteCF) - shiftTS, exist := restore.CalculateShiftTS(ms, startTs, restoreTS) - require.Equal(t, shiftTS, uint64(1800)) - require.Equal(t, exist, true) - - shiftTS, exist = restore.CalculateShiftTS(ms, startTs, mathutil.MaxUint) - require.Equal(t, shiftTS, uint64(1700)) - require.Equal(t, exist, true) - - shiftTS, exist = restore.CalculateShiftTS(ms, 1999, 3001) - require.Equal(t, shiftTS, uint64(800)) - require.Equal(t, exist, true) - - ms = fakeMetaDataV2s(t, helper, stream.DefaultCF) - _, exist = restore.CalculateShiftTS(ms, startTs, restoreTS) - require.Equal(t, exist, false) + ctx := context.Background() + tmpDir := t.TempDir() + s, err := storage.NewLocalStorage(tmpDir) + require.NoError(t, err) + + cases := []struct { + metas []*backuppb.Metadata + testParams []*testParam3 + }{ + { + // filegroup 10 35 + // ↑ ↑ + // +----+-++---+ + // ↓ ↓ ↓↓ ↓ + // fileinfo 10-d-20 + // fileinfo 8--d-15--w-30 + // fileinfo 11-d-25-w-35 + metas: []*backuppb.Metadata{ + mf(1, [][]*backuppb.DataFileInfo{ + { + fi(10, 20, stream.DefaultCF, 0), + fi(15, 30, stream.WriteCF, 8), + fi(25, 35, stream.WriteCF, 11), + }, + }), + }, + testParams: []*testParam3{ + { + until: []uint64{3}, + shiftUntilTS: returnV(3), + }, { + until: []uint64{8, 9, 10, 11, 12, 15, 16, 20, 21, 25, 26, 30}, + shiftUntilTS: returnV(8), + }, { + until: []uint64{31, 35}, + shiftUntilTS: returnV(11), + }, { + until: []uint64{36}, + shiftUntilTS: returnV(36), + }, + }, + }, { + // filegroup 50 85 + // ↑ ↑ + // +-+-+--+--+------+ + // ↓ ↓ ↓ ↓ ↓ ↓ + // fileinfo 55-d-65-70 + // fileinfo 50-d60 + // fileinfo 72d80w85 + metas: []*backuppb.Metadata{ + mf(1, [][]*backuppb.DataFileInfo{ + { + fi(65, 70, stream.WriteCF, 55), + fi(50, 60, stream.DefaultCF, 0), + fi(80, 85, stream.WriteCF, 72), + }, + }), + }, + testParams: []*testParam3{ + { + until: []uint64{45, 50, 52}, + shiftUntilTS: returnSelf(), + }, { + until: []uint64{55, 56, 60, 61, 65, 66, 70}, + shiftUntilTS: returnV(55), + }, { + until: []uint64{71}, + shiftUntilTS: returnV(71), + }, { + until: []uint64{72, 73, 80, 81, 85}, + shiftUntilTS: returnV(72), + }, { + until: []uint64{86}, + shiftUntilTS: returnV(86), + }, + }, + }, { + // filegroup 10 35 50 85 + // ↑ ↑ ↑ ↑ + // +----+-++---+ +-+-+--+--+------+ + // ↓ ↓ ↓↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ + // fileinfo 10-d-20 55-d-65-70 + // fileinfo 8--d-15--w-30 50-d60 + // fileinfo 11-d-25-w-35 72d80w85 + metas: []*backuppb.Metadata{ + mf(1, [][]*backuppb.DataFileInfo{ + { + fi(10, 20, stream.DefaultCF, 0), + fi(15, 30, stream.WriteCF, 8), + fi(25, 35, stream.WriteCF, 11), + }, + }), + mf(2, [][]*backuppb.DataFileInfo{ + { + fi(65, 70, stream.WriteCF, 55), + fi(50, 60, stream.DefaultCF, 0), + fi(80, 85, stream.WriteCF, 72), + }, + }), + }, + testParams: []*testParam3{ + { + until: []uint64{3}, + shiftUntilTS: returnV(3), + }, { + until: []uint64{8, 9, 10, 11, 12, 15, 16, 20, 21, 25, 26, 30}, + shiftUntilTS: returnV(8), + }, { + until: []uint64{31, 35}, + shiftUntilTS: returnV(11), + }, { + until: []uint64{36}, + shiftUntilTS: returnV(36), + }, { + until: []uint64{45, 50, 52}, + shiftUntilTS: returnSelf(), + }, { + until: []uint64{55, 56, 60, 61, 65, 66, 70}, + shiftUntilTS: returnV(55), + }, { + until: []uint64{71}, + shiftUntilTS: returnV(71), + }, { + until: []uint64{72, 73, 80, 81, 85}, + shiftUntilTS: returnV(72), + }, { + until: []uint64{86}, + shiftUntilTS: returnV(86), + }, + }, + }, + } + + for i, cs := range cases { + for j, ts := range cs.testParams { + for _, until := range ts.until { + t.Logf("case %d, param %d, until %d", i, j, until) + metas := restore.StreamMetadataSet{ + Helper: stream.NewMetadataHelper(), + } + err := generateFiles(ctx, s, cs.metas, tmpDir) + require.NoError(t, err) + shiftUntilTS, err := metas.LoadUntilAndCalculateShiftTS(ctx, s, until) + require.NoError(t, err) + require.Equal(t, shiftUntilTS, ts.shiftUntilTS(until), cs.metas) + } + } + } } diff --git a/br/pkg/restore/systable_restore.go b/br/pkg/restore/systable_restore.go index 40e3450c772f2..ac21b0dba7e42 100644 --- a/br/pkg/restore/systable_restore.go +++ b/br/pkg/restore/systable_restore.go @@ -19,6 +19,12 @@ import ( "go.uber.org/zap" ) +const ( + rootUser = "root" + sysUserTableName = "user" + cloudAdminUser = "cloud_admin" +) + var statsTables = map[string]struct{}{ "stats_buckets": {}, "stats_extended": {}, @@ -49,14 +55,14 @@ var unRecoverableTable = map[string]struct{}{ // skip clearing or restoring 'cloud_admin'@'%' which is a special // user on TiDB Cloud var sysPrivilegeTableMap = map[string]string{ - "user": "not (user = 'cloud_admin' and host = '%')", // since v1.0.0 - "db": "not (user = 'cloud_admin' and host = '%')", // since v1.0.0 - "tables_priv": "not (user = 'cloud_admin' and host = '%')", // since v1.0.0 - "columns_priv": "not (user = 'cloud_admin' and host = '%')", // since v1.0.0 - "default_roles": "not (user = 'cloud_admin' and host = '%')", // since v3.0.0 - "role_edges": "not (to_user = 'cloud_admin' and to_host = '%')", // since v3.0.0 - "global_priv": "not (user = 'cloud_admin' and host = '%')", // since v3.0.8 - "global_grants": "not (user = 'cloud_admin' and host = '%')", // since v5.0.3 + "user": "(user = '%s' and host = '%%')", // since v1.0.0 + "db": "(user = '%s' and host = '%%')", // since v1.0.0 + "tables_priv": "(user = '%s' and host = '%%')", // since v1.0.0 + "columns_priv": "(user = '%s' and host = '%%')", // since v1.0.0 + "default_roles": "(user = '%s' and host = '%%')", // since v3.0.0 + "role_edges": "(to_user = '%s' and to_host = '%%')", // since v3.0.0 + "global_priv": "(user = '%s' and host = '%%')", // since v3.0.8 + "global_grants": "(user = '%s' and host = '%%')", // since v5.0.3 } func isUnrecoverableTable(tableName string) bool { @@ -69,6 +75,78 @@ func isStatsTable(tableName string) bool { return ok } +func generateResetSQLs(db *database, resetUsers []string) []string { + if db.Name.L != mysql.SystemDB { + return nil + } + sqls := make([]string, 0, 10) + // we only need reset root password once + rootReset := false + for tableName := range db.ExistingTables { + if sysPrivilegeTableMap[tableName] != "" { + for _, name := range resetUsers { + if strings.ToLower(name) == rootUser { + if !rootReset { + updateSQL := fmt.Sprintf("UPDATE %s.%s SET authentication_string='',"+ + " Shutdown_priv='Y',"+ + " Config_priv='Y'"+ + " WHERE USER='root' AND Host='%%';", + db.Name.L, sysUserTableName) + sqls = append(sqls, updateSQL) + rootReset = true + } else { + continue + } + } else { + /* #nosec G202: SQL string concatenation */ + whereClause := fmt.Sprintf("WHERE "+sysPrivilegeTableMap[tableName], name) + deleteSQL := fmt.Sprintf("DELETE FROM %s %s;", + utils.EncloseDBAndTable(db.Name.L, tableName), whereClause) + sqls = append(sqls, deleteSQL) + } + } + } + } + return sqls +} + +// ClearSystemUsers is used for volume-snapshot restoration. +// because we can not support restore user in some scenarios, for example in cloud. +// we'd better use this function to drop cloud_admin user after volume-snapshot restore. +func (rc *Client) ClearSystemUsers(ctx context.Context, resetUsers []string) error { + sysDB := mysql.SystemDB + db, ok := rc.getDatabaseByName(sysDB) + if !ok { + log.Warn("target database not exist, aborting", zap.String("database", sysDB)) + return nil + } + execSQL := func(sql string) error { + // SQLs here only contain table name and database name, seems it is no need to redact them. + if err := rc.db.se.Execute(ctx, sql); err != nil { + log.Warn("failed to clear system users", + zap.Stringer("database", db.Name), + zap.String("sql", sql), + zap.Error(err), + ) + return berrors.ErrUnknown.Wrap(err).GenWithStack("failed to execute %s", sql) + } + log.Info("successfully clear system users after restoration", + zap.Stringer("database", db.Name), + zap.String("sql", sql), + ) + return nil + } + + sqls := generateResetSQLs(db, resetUsers) + for _, sql := range sqls { + log.Info("reset system user for cloud", zap.String("sql", sql)) + if err := execSQL(sql); err != nil { + return err + } + } + return nil +} + // RestoreSystemSchemas restores the system schema(i.e. the `mysql` schema). // Detail see https://github.com/pingcap/br/issues/679#issuecomment-762592254. func (rc *Client) RestoreSystemSchemas(ctx context.Context, f filter.Filter) { @@ -201,14 +279,15 @@ func (rc *Client) replaceTemporaryTableToSystable(ctx context.Context, ti *model } if db.ExistingTables[tableName] != nil { - whereClause := "" + whereNotClause := "" if rc.fullClusterRestore && sysPrivilegeTableMap[tableName] != "" { // cloud_admin is a special user on tidb cloud, need to skip it. - whereClause = fmt.Sprintf("WHERE %s", sysPrivilegeTableMap[tableName]) + /* #nosec G202: SQL string concatenation */ + whereNotClause = fmt.Sprintf("WHERE NOT "+sysPrivilegeTableMap[tableName], cloudAdminUser) log.Info("full cluster restore, delete existing data", zap.String("table", tableName), zap.Stringer("schema", db.Name)) deleteSQL := fmt.Sprintf("DELETE FROM %s %s;", - utils.EncloseDBAndTable(db.Name.L, tableName), whereClause) + utils.EncloseDBAndTable(db.Name.L, tableName), whereNotClause) if err := execSQL(deleteSQL); err != nil { return err } @@ -226,7 +305,7 @@ func (rc *Client) replaceTemporaryTableToSystable(ctx context.Context, ti *model utils.EncloseDBAndTable(db.Name.L, tableName), colListStr, colListStr, utils.EncloseDBAndTable(db.TemporaryName.L, tableName), - whereClause) + whereNotClause) return execSQL(replaceIntoSQL) } diff --git a/br/pkg/restore/systable_restore_test.go b/br/pkg/restore/systable_restore_test.go new file mode 100644 index 0000000000000..2371f066a43a1 --- /dev/null +++ b/br/pkg/restore/systable_restore_test.go @@ -0,0 +1,72 @@ +// Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0. + +package restore + +import ( + "regexp" + "testing" + + "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/parser/model" + "github.com/stretchr/testify/require" +) + +func testTableInfo(name string) *model.TableInfo { + return &model.TableInfo{ + Name: model.NewCIStr(name), + } +} + +func TestGenerateResetSQL(t *testing.T) { + // case #1: ignore non-mysql databases + mockDB := &database{ + ExistingTables: map[string]*model.TableInfo{}, + Name: model.NewCIStr("non-mysql"), + TemporaryName: utils.TemporaryDBName("non-mysql"), + } + for name := range sysPrivilegeTableMap { + mockDB.ExistingTables[name] = testTableInfo(name) + } + resetUsers := []string{"cloud_admin", "root"} + require.Equal(t, 0, len(generateResetSQLs(mockDB, resetUsers))) + + // case #2: ignore non expected table + mockDB = &database{ + ExistingTables: map[string]*model.TableInfo{}, + Name: model.NewCIStr("mysql"), + TemporaryName: utils.TemporaryDBName("mysql"), + } + for name := range sysPrivilegeTableMap { + name += "non_available" + mockDB.ExistingTables[name] = testTableInfo(name) + } + resetUsers = []string{"cloud_admin", "root"} + require.Equal(t, 0, len(generateResetSQLs(mockDB, resetUsers))) + + // case #3: only reset cloud admin account + for name := range sysPrivilegeTableMap { + mockDB.ExistingTables[name] = testTableInfo(name) + } + resetUsers = []string{"cloud_admin"} + sqls := generateResetSQLs(mockDB, resetUsers) + require.Equal(t, 8, len(sqls)) + for _, sql := range sqls { + // for cloud_admin we only generate DELETE sql + require.Regexp(t, regexp.MustCompile("DELETE*"), sql) + } + + // case #4: reset cloud admin/other account + resetUsers = []string{"cloud_admin", "cloud_other"} + sqls = generateResetSQLs(mockDB, resetUsers) + require.Equal(t, 16, len(sqls)) + for _, sql := range sqls { + // for cloud_admin/cloud_other we only generate DELETE sql + require.Regexp(t, regexp.MustCompile("DELETE*"), sql) + } + + // case #5: reset cloud admin && root account + resetUsers = []string{"cloud_admin", "root"} + sqls = generateResetSQLs(mockDB, resetUsers) + // 8 DELETE sqls for cloud admin and 1 UPDATE sql for root + require.Equal(t, 9, len(sqls)) +} diff --git a/br/pkg/restore/tiflashrec/tiflash_recorder.go b/br/pkg/restore/tiflashrec/tiflash_recorder.go index 31dde982a7b69..84707f05e1f1b 100644 --- a/br/pkg/restore/tiflashrec/tiflash_recorder.go +++ b/br/pkg/restore/tiflashrec/tiflash_recorder.go @@ -79,6 +79,46 @@ func (r *TiFlashRecorder) Rewrite(oldID int64, newID int64) { } } +func (r *TiFlashRecorder) GenerateResetAlterTableDDLs(info infoschema.InfoSchema) []string { + items := make([]string, 0, len(r.items)) + r.Iterate(func(id int64, replica model.TiFlashReplicaInfo) { + table, ok := info.TableByID(id) + if !ok { + log.Warn("Table do not exist, skipping", zap.Int64("id", id)) + return + } + schema, ok := info.SchemaByTable(table.Meta()) + if !ok { + log.Warn("Schema do not exist, skipping", zap.Int64("id", id), zap.Stringer("table", table.Meta().Name)) + return + } + // Currently, we didn't backup tiflash cluster volume during volume snapshot backup, + // But the table has replica info after volume restoration. + // We should reset it to 0, then set it back. otherwise, it will return error when alter tiflash replica. + altTableSpec, err := alterTableSpecOf(replica, true) + if err != nil { + log.Warn("Failed to generate the alter table spec", logutil.ShortError(err), zap.Any("replica", replica)) + return + } + items = append(items, fmt.Sprintf( + "ALTER TABLE %s %s", + utils.EncloseDBAndTable(schema.Name.O, table.Meta().Name.O), + altTableSpec), + ) + altTableSpec, err = alterTableSpecOf(replica, false) + if err != nil { + log.Warn("Failed to generate the alter table spec", logutil.ShortError(err), zap.Any("replica", replica)) + return + } + items = append(items, fmt.Sprintf( + "ALTER TABLE %s %s", + utils.EncloseDBAndTable(schema.Name.O, table.Meta().Name.O), + altTableSpec), + ) + }) + return items +} + func (r *TiFlashRecorder) GenerateAlterTableDDLs(info infoschema.InfoSchema) []string { items := make([]string, 0, len(r.items)) r.Iterate(func(id int64, replica model.TiFlashReplicaInfo) { @@ -92,7 +132,7 @@ func (r *TiFlashRecorder) GenerateAlterTableDDLs(info infoschema.InfoSchema) []s log.Warn("Schema do not exist, skipping", zap.Int64("id", id), zap.Stringer("table", table.Meta().Name)) return } - altTableSpec, err := alterTableSpecOf(replica) + altTableSpec, err := alterTableSpecOf(replica, false) if err != nil { log.Warn("Failed to generate the alter table spec", logutil.ShortError(err), zap.Any("replica", replica)) return @@ -106,7 +146,7 @@ func (r *TiFlashRecorder) GenerateAlterTableDDLs(info infoschema.InfoSchema) []s return items } -func alterTableSpecOf(replica model.TiFlashReplicaInfo) (string, error) { +func alterTableSpecOf(replica model.TiFlashReplicaInfo, reset bool) (string, error) { spec := &ast.AlterTableSpec{ Tp: ast.AlterTableSetTiFlashReplica, TiFlashReplica: &ast.TiFlashReplicaSpec{ @@ -114,6 +154,14 @@ func alterTableSpecOf(replica model.TiFlashReplicaInfo) (string, error) { Labels: replica.LocationLabels, }, } + if reset { + spec = &ast.AlterTableSpec{ + Tp: ast.AlterTableSetTiFlashReplica, + TiFlashReplica: &ast.TiFlashReplicaSpec{ + Count: 0, + }, + } + } buf := bytes.NewBuffer(make([]byte, 0, 32)) restoreCx := format.NewRestoreCtx( diff --git a/br/pkg/restore/tiflashrec/tiflash_recorder_test.go b/br/pkg/restore/tiflashrec/tiflash_recorder_test.go index b01272caeddc5..f7316a1ed3133 100644 --- a/br/pkg/restore/tiflashrec/tiflash_recorder_test.go +++ b/br/pkg/restore/tiflashrec/tiflash_recorder_test.go @@ -170,3 +170,32 @@ func TestGenSql(t *testing.T) { "ALTER TABLE `test`.`evils` SET TIFLASH REPLICA 1 LOCATION LABELS 'kIll''; OR DROP DATABASE test --', 'dEaTh with " + `\\"quoting\\"` + "'", }) } + +func TestGenResetSql(t *testing.T) { + tInfo := func(id int, name string) *model.TableInfo { + return &model.TableInfo{ + ID: int64(id), + Name: model.NewCIStr(name), + } + } + fakeInfo := infoschema.MockInfoSchema([]*model.TableInfo{ + tInfo(1, "fruits"), + tInfo(2, "whisper"), + }) + rec := tiflashrec.New() + rec.AddTable(1, model.TiFlashReplicaInfo{ + Count: 1, + }) + rec.AddTable(2, model.TiFlashReplicaInfo{ + Count: 2, + LocationLabels: []string{"climate"}, + }) + + sqls := rec.GenerateResetAlterTableDDLs(fakeInfo) + require.ElementsMatch(t, sqls, []string{ + "ALTER TABLE `test`.`whisper` SET TIFLASH REPLICA 0", + "ALTER TABLE `test`.`whisper` SET TIFLASH REPLICA 2 LOCATION LABELS 'climate'", + "ALTER TABLE `test`.`fruits` SET TIFLASH REPLICA 0", + "ALTER TABLE `test`.`fruits` SET TIFLASH REPLICA 1", + }) +} diff --git a/br/pkg/restore/util.go b/br/pkg/restore/util.go index 259d3fa28d888..73a4411c445c1 100644 --- a/br/pkg/restore/util.go +++ b/br/pkg/restore/util.go @@ -750,3 +750,43 @@ func CheckConsistencyAndValidPeer(regionInfos []*RecoverRegionInfo) (map[uint64] } return validPeers, nil } + +// in cloud, since iops and bandwidth limitation, write operator in raft is slow, so raft state (logterm, lastlog, commitlog...) are the same among the peers +// LeaderCandidates select all peers can be select as a leader during the restore +func LeaderCandidates(peers []*RecoverRegion) ([]*RecoverRegion, error) { + if peers == nil { + return nil, errors.Annotatef(berrors.ErrRestoreRegionWithoutPeer, + "invalid region range") + } + candidates := make([]*RecoverRegion, 0, len(peers)) + // by default, the peers[0] to be assign as a leader, since peers already sorted by leader selection rule + leader := peers[0] + candidates = append(candidates, leader) + for _, peer := range peers[1:] { + // qualificated candidate is leader.logterm = candidate.logterm && leader.lastindex = candidate.lastindex && && leader.commitindex = candidate.commitindex + if peer.LastLogTerm == leader.LastLogTerm && peer.LastIndex == leader.LastIndex && peer.CommitIndex == leader.CommitIndex { + log.Debug("leader candidate", zap.Uint64("store id", peer.StoreId), zap.Uint64("region id", peer.RegionId), zap.Uint64("peer id", peer.PeerId)) + candidates = append(candidates, peer) + } + } + return candidates, nil +} + +// for region A, has candidate leader x, y, z +// peer x on store 1 with storeBalanceScore 3 +// peer y on store 3 with storeBalanceScore 2 +// peer z on store 4 with storeBalanceScore 1 +// result: peer z will be select as leader on store 4 +func SelectRegionLeader(storeBalanceScore map[uint64]int, peers []*RecoverRegion) *RecoverRegion { + // by default, the peers[0] to be assign as a leader + leader := peers[0] + minLeaderStore := storeBalanceScore[leader.StoreId] + for _, peer := range peers[1:] { + log.Debug("leader candidate", zap.Int("score", storeBalanceScore[peer.StoreId]), zap.Int("min-score", minLeaderStore), zap.Uint64("store id", peer.StoreId), zap.Uint64("region id", peer.RegionId), zap.Uint64("peer id", peer.PeerId)) + if storeBalanceScore[peer.StoreId] < minLeaderStore { + minLeaderStore = storeBalanceScore[peer.StoreId] + leader = peer + } + } + return leader +} diff --git a/br/pkg/restore/util_test.go b/br/pkg/restore/util_test.go index 44620e9cb4e5c..482818a1ad958 100644 --- a/br/pkg/restore/util_test.go +++ b/br/pkg/restore/util_test.go @@ -460,3 +460,52 @@ func TestCheckConsistencyAndValidPeer(t *testing.T) { require.Error(t, err) require.Regexp(t, ".*invalid restore range.*", err.Error()) } + +func TestLeaderCandidates(t *testing.T) { + //key space is continuous + validPeer1 := newPeerMeta(9, 11, 2, []byte(""), []byte("bb"), 2, 1, 0, 0, false) + validPeer2 := newPeerMeta(19, 22, 3, []byte("bb"), []byte("cc"), 2, 1, 0, 1, false) + validPeer3 := newPeerMeta(29, 30, 1, []byte("cc"), []byte(""), 2, 1, 0, 2, false) + + peers := []*restore.RecoverRegion{ + validPeer1, + validPeer2, + validPeer3, + } + + candidates, err := restore.LeaderCandidates(peers) + require.NoError(t, err) + require.Equal(t, 3, len(candidates)) +} + +func TestSelectRegionLeader(t *testing.T) { + validPeer1 := newPeerMeta(9, 11, 2, []byte(""), []byte("bb"), 2, 1, 0, 0, false) + validPeer2 := newPeerMeta(19, 22, 3, []byte("bb"), []byte("cc"), 2, 1, 0, 1, false) + validPeer3 := newPeerMeta(29, 30, 1, []byte("cc"), []byte(""), 2, 1, 0, 2, false) + + peers := []*restore.RecoverRegion{ + validPeer1, + validPeer2, + validPeer3, + } + // init store banlance score all is 0 + storeBalanceScore := make(map[uint64]int, len(peers)) + leader := restore.SelectRegionLeader(storeBalanceScore, peers) + require.Equal(t, validPeer1, leader) + + // change store banlance store + storeBalanceScore[2] = 3 + storeBalanceScore[3] = 2 + storeBalanceScore[1] = 1 + leader = restore.SelectRegionLeader(storeBalanceScore, peers) + require.Equal(t, validPeer3, leader) + + // one peer + peer := []*restore.RecoverRegion{ + validPeer3, + } + // init store banlance score all is 0 + storeScore := make(map[uint64]int, len(peer)) + leader = restore.SelectRegionLeader(storeScore, peer) + require.Equal(t, validPeer3, leader) +} diff --git a/br/pkg/rtree/main_test.go b/br/pkg/rtree/main_test.go index 6c415ec6e7593..dc57d20e599d0 100644 --- a/br/pkg/rtree/main_test.go +++ b/br/pkg/rtree/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/br/pkg/rtree/rtree.go b/br/pkg/rtree/rtree.go index 9f12b22daca75..f17ebf38df510 100644 --- a/br/pkg/rtree/rtree.go +++ b/br/pkg/rtree/rtree.go @@ -217,3 +217,10 @@ func (rangeTree *RangeTree) GetIncompleteRange( } return incomplete } + +type ProgressRange struct { + Res RangeTree + Incomplete []Range + Origin Range + GroupKey string +} diff --git a/br/pkg/storage/BUILD.bazel b/br/pkg/storage/BUILD.bazel index e7773cb35c149..8c98a13e59500 100644 --- a/br/pkg/storage/BUILD.bazel +++ b/br/pkg/storage/BUILD.bazel @@ -35,9 +35,12 @@ go_library( "@com_github_aws_aws_sdk_go//service/s3", "@com_github_aws_aws_sdk_go//service/s3/s3iface", "@com_github_aws_aws_sdk_go//service/s3/s3manager", + "@com_github_azure_azure_sdk_for_go_sdk_azcore//policy", "@com_github_azure_azure_sdk_for_go_sdk_azidentity//:azidentity", "@com_github_azure_azure_sdk_for_go_sdk_storage_azblob//:azblob", + "@com_github_golang_snappy//:snappy", "@com_github_google_uuid//:uuid", + "@com_github_klauspost_compress//zstd", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_kvproto//pkg/brpb", "@com_github_pingcap_log//:log", diff --git a/br/pkg/storage/azblob.go b/br/pkg/storage/azblob.go index c557a79e3ac8f..41d8fa88f559f 100644 --- a/br/pkg/storage/azblob.go +++ b/br/pkg/storage/azblob.go @@ -12,6 +12,7 @@ import ( "path" "strings" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" "github.com/google/uuid" @@ -30,6 +31,16 @@ const ( azblobAccountKey = "azblob.account-key" ) +const azblobRetryTimes int32 = 5 + +func getDefaultClientOptions() *azblob.ClientOptions { + return &azblob.ClientOptions{ + Retry: policy.RetryOptions{ + MaxRetries: azblobRetryTimes, + }, + } +} + // AzblobBackendOptions is the options for Azure Blob storage. type AzblobBackendOptions struct { Endpoint string `json:"endpoint" toml:"endpoint"` @@ -99,7 +110,7 @@ type sharedKeyClientBuilder struct { } func (b *sharedKeyClientBuilder) GetServiceClient() (azblob.ServiceClient, error) { - return azblob.NewServiceClientWithSharedKey(b.serviceURL, b.cred, nil) + return azblob.NewServiceClientWithSharedKey(b.serviceURL, b.cred, getDefaultClientOptions()) } func (b *sharedKeyClientBuilder) GetAccountName() string { @@ -114,7 +125,7 @@ type tokenClientBuilder struct { } func (b *tokenClientBuilder) GetServiceClient() (azblob.ServiceClient, error) { - return azblob.NewServiceClient(b.serviceURL, b.cred, nil) + return azblob.NewServiceClient(b.serviceURL, b.cred, getDefaultClientOptions()) } func (b *tokenClientBuilder) GetAccountName() string { @@ -285,7 +296,9 @@ func (s *AzureBlobStorage) ReadFile(ctx context.Context, name string) ([]byte, e return nil, errors.Annotatef(err, "Failed to download azure blob file, file info: bucket(container)='%s', key='%s'", s.options.Bucket, s.withPrefix(name)) } defer resp.RawResponse.Body.Close() - data, err := io.ReadAll(resp.Body(azblob.RetryReaderOptions{})) + data, err := io.ReadAll(resp.Body(azblob.RetryReaderOptions{ + MaxRetryRequests: int(azblobRetryTimes), + })) if err != nil { return nil, errors.Annotatef(err, "Failed to read azure blob file, file info: bucket(container)='%s', key='%s'", s.options.Bucket, s.withPrefix(name)) } diff --git a/br/pkg/storage/azblob_test.go b/br/pkg/storage/azblob_test.go index c099037ea51b2..74ddfa7125699 100644 --- a/br/pkg/storage/azblob_test.go +++ b/br/pkg/storage/azblob_test.go @@ -4,9 +4,13 @@ package storage import ( "context" + "fmt" "io" + "net/http" + "net/http/httptest" "os" "strings" + "sync" "testing" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" @@ -298,3 +302,52 @@ func TestNewAzblobStorage(t *testing.T) { require.Equal(t, "http://127.0.0.1:1000", b.serviceURL) } } + +type fakeClientBuilder struct { + Endpoint string +} + +func (b *fakeClientBuilder) GetServiceClient() (azblob.ServiceClient, error) { + connStr := fmt.Sprintf("DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=%s/devstoreaccount1;", b.Endpoint) + return azblob.NewServiceClientFromConnectionString(connStr, getDefaultClientOptions()) +} + +func (b *fakeClientBuilder) GetAccountName() string { + return "devstoreaccount1" +} + +func TestDownloadRetry(t *testing.T) { + var count int32 = 0 + var lock sync.Mutex + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + t.Log(r.URL) + if strings.Contains(r.URL.String(), "restype=container") { + w.WriteHeader(201) + return + } + lock.Lock() + count += 1 + lock.Unlock() + header := w.Header() + header.Add("Etag", "0x1") + header.Add("Content-Length", "5") + w.WriteHeader(200) + w.Write([]byte("1234567")) + })) + + defer server.Close() + t.Log(server.URL) + + options := &backuppb.AzureBlobStorage{ + Bucket: "test", + Prefix: "a/b/", + } + + ctx := context.Background() + builder := &fakeClientBuilder{Endpoint: server.URL} + s, err := newAzureBlobStorageWithClientBuilder(ctx, options, builder) + require.NoError(t, err) + _, err = s.ReadFile(ctx, "c") + require.Error(t, err) + require.Less(t, azblobRetryTimes, count) +} diff --git a/br/pkg/storage/compress.go b/br/pkg/storage/compress.go index 96258221d9b62..36c07846f3271 100644 --- a/br/pkg/storage/compress.go +++ b/br/pkg/storage/compress.go @@ -80,8 +80,11 @@ func (w *withCompression) ReadFile(ctx context.Context, name string) ([]byte, er return io.ReadAll(compressBf) } +// compressReader is a wrapper for compress.Reader type compressReader struct { - io.ReadCloser + io.Reader + io.Seeker + io.Closer } // nolint:interfacer @@ -94,12 +97,37 @@ func newInterceptReader(fileReader ExternalFileReader, compressType CompressType return nil, errors.Trace(err) } return &compressReader{ - ReadCloser: r, + Reader: r, + Closer: fileReader, + Seeker: fileReader, }, nil } -func (*compressReader) Seek(_ int64, _ int) (int64, error) { - return int64(0), errors.Annotatef(berrors.ErrStorageInvalidConfig, "compressReader doesn't support Seek now") +func NewLimitedInterceptReader(fileReader ExternalFileReader, compressType CompressType, n int64) (ExternalFileReader, error) { + newFileReader := fileReader + if n < 0 { + return nil, errors.Annotatef(berrors.ErrStorageInvalidConfig, "compressReader doesn't support negative limit, n: %d", n) + } else if n > 0 { + newFileReader = &compressReader{ + Reader: io.LimitReader(fileReader, n), + Seeker: fileReader, + Closer: fileReader, + } + } + return newInterceptReader(newFileReader, compressType) +} + +func (c *compressReader) Seek(offset int64, whence int) (int64, error) { + // only support get original reader's current offset + if offset == 0 && whence == io.SeekCurrent { + return c.Seeker.Seek(offset, whence) + } + return int64(0), errors.Annotatef(berrors.ErrStorageInvalidConfig, "compressReader doesn't support Seek now, offset %d, whence %d", offset, whence) +} + +func (c *compressReader) Close() error { + err := c.Closer.Close() + return err } type flushStorageWriter struct { diff --git a/br/pkg/storage/gcs.go b/br/pkg/storage/gcs.go index 063100a52ad59..ac5098ed16973 100644 --- a/br/pkg/storage/gcs.go +++ b/br/pkg/storage/gcs.go @@ -90,24 +90,36 @@ func (options *GCSBackendOptions) parseFromFlags(flags *pflag.FlagSet) error { return nil } -type gcsStorage struct { +// GCSStorage defines some standard operations for BR/Lightning on the GCS storage. +// It implements the `ExternalStorage` interface. +type GCSStorage struct { gcs *backuppb.GCS bucket *storage.BucketHandle } +// GetBucketHandle gets the handle to the GCS API on the bucket. +func (s *GCSStorage) GetBucketHandle() *storage.BucketHandle { + return s.bucket +} + +// GetOptions gets the external storage operations for the GCS. +func (s *GCSStorage) GetOptions() *backuppb.GCS { + return s.gcs +} + // DeleteFile delete the file in storage -func (s *gcsStorage) DeleteFile(ctx context.Context, name string) error { +func (s *GCSStorage) DeleteFile(ctx context.Context, name string) error { object := s.objectName(name) err := s.bucket.Object(object).Delete(ctx) return errors.Trace(err) } -func (s *gcsStorage) objectName(name string) string { +func (s *GCSStorage) objectName(name string) string { return path.Join(s.gcs.Prefix, name) } // WriteFile writes data to a file to storage. -func (s *gcsStorage) WriteFile(ctx context.Context, name string, data []byte) error { +func (s *GCSStorage) WriteFile(ctx context.Context, name string, data []byte) error { object := s.objectName(name) wc := s.bucket.Object(object).NewWriter(ctx) wc.StorageClass = s.gcs.StorageClass @@ -120,7 +132,7 @@ func (s *gcsStorage) WriteFile(ctx context.Context, name string, data []byte) er } // ReadFile reads the file from the storage and returns the contents. -func (s *gcsStorage) ReadFile(ctx context.Context, name string) ([]byte, error) { +func (s *GCSStorage) ReadFile(ctx context.Context, name string) ([]byte, error) { object := s.objectName(name) rc, err := s.bucket.Object(object).NewReader(ctx) if err != nil { @@ -143,7 +155,7 @@ func (s *gcsStorage) ReadFile(ctx context.Context, name string) ([]byte, error) } // FileExists return true if file exists. -func (s *gcsStorage) FileExists(ctx context.Context, name string) (bool, error) { +func (s *GCSStorage) FileExists(ctx context.Context, name string) (bool, error) { object := s.objectName(name) _, err := s.bucket.Object(object).Attrs(ctx) if err != nil { @@ -156,7 +168,7 @@ func (s *gcsStorage) FileExists(ctx context.Context, name string) (bool, error) } // Open a Reader by file path. -func (s *gcsStorage) Open(ctx context.Context, path string) (ExternalFileReader, error) { +func (s *GCSStorage) Open(ctx context.Context, path string) (ExternalFileReader, error) { object := s.objectName(path) handle := s.bucket.Object(object) @@ -182,7 +194,7 @@ func (s *gcsStorage) Open(ctx context.Context, path string) (ExternalFileReader, // The first argument is the file path that can be used in `Open` // function; the second argument is the size in byte of the file determined // by path. -func (s *gcsStorage) WalkDir(ctx context.Context, opt *WalkOption, fn func(string, int64) error) error { +func (s *GCSStorage) WalkDir(ctx context.Context, opt *WalkOption, fn func(string, int64) error) error { if opt == nil { opt = &WalkOption{} } @@ -221,12 +233,12 @@ func (s *gcsStorage) WalkDir(ctx context.Context, opt *WalkOption, fn func(strin return nil } -func (s *gcsStorage) URI() string { +func (s *GCSStorage) URI() string { return "gcs://" + s.gcs.Bucket + "/" + s.gcs.Prefix } // Create implements ExternalStorage interface. -func (s *gcsStorage) Create(ctx context.Context, name string) (ExternalFileWriter, error) { +func (s *GCSStorage) Create(ctx context.Context, name string) (ExternalFileWriter, error) { object := s.objectName(name) wc := s.bucket.Object(object).NewWriter(ctx) wc.StorageClass = s.gcs.StorageClass @@ -235,7 +247,7 @@ func (s *gcsStorage) Create(ctx context.Context, name string) (ExternalFileWrite } // Rename file name from oldFileName to newFileName. -func (s *gcsStorage) Rename(ctx context.Context, oldFileName, newFileName string) error { +func (s *GCSStorage) Rename(ctx context.Context, oldFileName, newFileName string) error { data, err := s.ReadFile(ctx, oldFileName) if err != nil { return errors.Trace(err) @@ -247,7 +259,8 @@ func (s *gcsStorage) Rename(ctx context.Context, oldFileName, newFileName string return s.DeleteFile(ctx, oldFileName) } -func newGCSStorage(ctx context.Context, gcs *backuppb.GCS, opts *ExternalStorageOptions) (*gcsStorage, error) { +// NewGCSStorage creates a GCS external storage implementation. +func NewGCSStorage(ctx context.Context, gcs *backuppb.GCS, opts *ExternalStorageOptions) (*GCSStorage, error) { var clientOps []option.ClientOption if opts.NoCredentials { clientOps = append(clientOps, option.WithoutAuthentication()) @@ -301,12 +314,7 @@ func newGCSStorage(ctx context.Context, gcs *backuppb.GCS, opts *ExternalStorage // so we need find sst in slash directory gcs.Prefix += "//" } - return &gcsStorage{gcs: gcs, bucket: bucket}, nil -} - -// only for unit test -func NewGCSStorageForTest(ctx context.Context, gcs *backuppb.GCS, opts *ExternalStorageOptions) (*gcsStorage, error) { - return newGCSStorage(ctx, gcs, opts) + return &GCSStorage{gcs: gcs, bucket: bucket}, nil } func hasSSTFiles(ctx context.Context, bucket *storage.BucketHandle, prefix string) bool { @@ -332,7 +340,7 @@ func hasSSTFiles(ctx context.Context, bucket *storage.BucketHandle, prefix strin // gcsObjectReader wrap storage.Reader and add the `Seek` method. type gcsObjectReader struct { - storage *gcsStorage + storage *GCSStorage name string objHandle *storage.ObjectHandle reader io.ReadCloser diff --git a/br/pkg/storage/gcs_test.go b/br/pkg/storage/gcs_test.go index 5801adccf04b7..daefb2bd686d3 100644 --- a/br/pkg/storage/gcs_test.go +++ b/br/pkg/storage/gcs_test.go @@ -32,7 +32,7 @@ func TestGCS(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "Fake Credentials", } - stg, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + stg, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -86,7 +86,7 @@ func TestGCS(t *testing.T) { require.NoError(t, err) require.False(t, exist) - checkWalkDir := func(stg *gcsStorage, opt *WalkOption) { + checkWalkDir := func(stg *GCSStorage, opt *WalkOption) { var totalSize int64 = 0 err = stg.WalkDir(ctx, opt, func(name string, size int64) error { totalSize += size @@ -112,7 +112,7 @@ func TestGCS(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "Fake Credentials", } - stg, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + stg, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -130,7 +130,7 @@ func TestGCS(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "Fake Credentials", } - stg, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + stg, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -147,7 +147,7 @@ func TestGCS(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "Fake Credentials", } - stg, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + stg, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -254,7 +254,7 @@ func TestNewGCSStorage(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "FakeCredentials", } - _, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + _, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: true, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -271,7 +271,7 @@ func TestNewGCSStorage(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "FakeCredentials", } - _, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + _, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -302,7 +302,7 @@ func TestNewGCSStorage(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "", } - _, err = newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + _, err = NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: true, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -333,7 +333,7 @@ func TestNewGCSStorage(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "", } - s, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + s, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -352,7 +352,7 @@ func TestNewGCSStorage(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "", } - _, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + _, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: true, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), @@ -368,7 +368,7 @@ func TestNewGCSStorage(t *testing.T) { PredefinedAcl: "private", CredentialsBlob: "FakeCredentials", } - s, err := newGCSStorage(ctx, gcs, &ExternalStorageOptions{ + s, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{ SendCredentials: false, CheckPermissions: []Permission{AccessBuckets}, HTTPClient: server.HTTPClient(), diff --git a/br/pkg/storage/local.go b/br/pkg/storage/local.go index 68dc760cc1c9a..0259e715c7968 100644 --- a/br/pkg/storage/local.go +++ b/br/pkg/storage/local.go @@ -9,7 +9,10 @@ import ( "path/filepath" "strings" + "github.com/google/uuid" "github.com/pingcap/errors" + "github.com/pingcap/log" + "go.uber.org/zap" ) const ( @@ -36,9 +39,23 @@ func (l *LocalStorage) DeleteFile(_ context.Context, name string) error { func (l *LocalStorage) WriteFile(_ context.Context, name string, data []byte) error { // because `os.WriteFile` is not atomic, directly write into it may reset the file // to an empty file if write is not finished. - tmpPath := filepath.Join(l.base, name) + ".tmp" + tmpPath := filepath.Join(l.base, name) + ".tmp." + uuid.NewString() if err := os.WriteFile(tmpPath, data, localFilePerm); err != nil { - return errors.Trace(err) + path := filepath.Dir(tmpPath) + log.Info("failed to write file, try to mkdir the path", zap.String("path", path)) + exists, existErr := pathExists(path) + if existErr != nil { + return errors.Annotatef(err, "after failed to write file, failed to check path exists : %v", existErr) + } + if exists { + return errors.Trace(err) + } + if mkdirErr := mkdirAll(path); mkdirErr != nil { + return errors.Annotatef(err, "after failed to write file, failed to mkdir : %v", mkdirErr) + } + if err := os.WriteFile(tmpPath, data, localFilePerm); err != nil { + return errors.Trace(err) + } } if err := os.Rename(tmpPath, filepath.Join(l.base, name)); err != nil { return errors.Trace(err) diff --git a/br/pkg/storage/local_test.go b/br/pkg/storage/local_test.go index 82e7435ae29be..db1ba424b9d6b 100644 --- a/br/pkg/storage/local_test.go +++ b/br/pkg/storage/local_test.go @@ -9,6 +9,7 @@ import ( "runtime" "testing" + "github.com/pingcap/errors" "github.com/stretchr/testify/require" ) @@ -99,4 +100,30 @@ func TestWalkDirWithSoftLinkFile(t *testing.T) { }) require.NoError(t, err) require.Equal(t, 1, i) + + // test file not exists + exists, err := store.FileExists(context.TODO(), "/123/456") + require.NoError(t, err) + require.False(t, exists) + + // test walk nonexistent directory + err = store.WalkDir(context.TODO(), &WalkOption{SubDir: "123/456"}, func(path string, size int64) error { + return errors.New("find file") + }) + require.NoError(t, err) + // write file to a nonexistent directory + err = store.WriteFile(context.TODO(), "/123/456/789.txt", []byte(data)) + require.NoError(t, err) + exists, err = store.FileExists(context.TODO(), "/123/456") + require.NoError(t, err) + require.True(t, exists) + + // test walk existent directory + err = store.WalkDir(context.TODO(), &WalkOption{SubDir: "123/456"}, func(path string, size int64) error { + if path == "123/456/789.txt" { + return nil + } + return errors.Errorf("find other file: %s", path) + }) + require.NoError(t, err) } diff --git a/br/pkg/storage/memstore_test.go b/br/pkg/storage/memstore_test.go index a85a2ff467fa1..3ae9a08d168bc 100644 --- a/br/pkg/storage/memstore_test.go +++ b/br/pkg/storage/memstore_test.go @@ -17,7 +17,6 @@ import ( "bytes" "context" "io" - "io/ioutil" "sync" "testing" "time" @@ -70,7 +69,7 @@ func TestMemStoreBasic(t *testing.T) { require.Nil(t, err) r2, err := store.Open(ctx, "/hello.txt") require.Nil(t, err) - fileContent, err = ioutil.ReadAll(r) + fileContent, err = io.ReadAll(r) require.Nil(t, err) require.True(t, bytes.Equal([]byte("hello world 3"), fileContent)) require.Nil(t, r.Close()) @@ -83,7 +82,7 @@ func TestMemStoreBasic(t *testing.T) { _, err = r2.Seek(5, io.SeekStart) require.Nil(t, err) - fileContent, err = ioutil.ReadAll(r2) + fileContent, err = io.ReadAll(r2) require.Nil(t, err) require.True(t, bytes.Equal([]byte(" world 3"), fileContent)) diff --git a/br/pkg/storage/parse.go b/br/pkg/storage/parse.go index 39aa8743f6d53..05c586fb5c322 100644 --- a/br/pkg/storage/parse.go +++ b/br/pkg/storage/parse.go @@ -35,6 +35,12 @@ func ParseRawURL(rawURL string) (*url.URL, error) { return u, nil } +// ParseBackendFromURL constructs a structured backend description from the +// *url.URL. +func ParseBackendFromURL(u *url.URL, options *BackendOptions) (*backuppb.StorageBackend, error) { + return parseBackend(u, "", options) +} + // ParseBackend constructs a structured backend description from the // storage URL. func ParseBackend(rawURL string, options *BackendOptions) (*backuppb.StorageBackend, error) { @@ -45,6 +51,14 @@ func ParseBackend(rawURL string, options *BackendOptions) (*backuppb.StorageBack if err != nil { return nil, errors.Trace(err) } + return parseBackend(u, rawURL, options) +} + +func parseBackend(u *url.URL, rawURL string, options *BackendOptions) (*backuppb.StorageBackend, error) { + if rawURL == "" { + // try to handle hdfs for ParseBackendFromURL caller + rawURL = u.String() + } switch u.Scheme { case "": absPath, err := filepath.Abs(rawURL) diff --git a/br/pkg/storage/s3.go b/br/pkg/storage/s3.go index ff2cbae25d030..a239de8ad794c 100644 --- a/br/pkg/storage/s3.go +++ b/br/pkg/storage/s3.go @@ -68,13 +68,24 @@ var permissionCheckFn = map[Permission]func(*s3.S3, *backuppb.S3) error{ GetObject: getObject, } -// S3Storage info for s3 storage. +// S3Storage defines some standard operations for BR/Lightning on the S3 storage. +// It implements the `ExternalStorage` interface. type S3Storage struct { session *session.Session svc s3iface.S3API options *backuppb.S3 } +// GetS3APIHandle gets the handle to the S3 API. +func (rs *S3Storage) GetS3APIHandle() s3iface.S3API { + return rs.svc +} + +// GetOptions gets the external storage operations for the S3. +func (rs *S3Storage) GetOptions() *backuppb.S3 { + return rs.options +} + // S3Uploader does multi-part upload to s3. type S3Uploader struct { svc s3iface.S3API @@ -248,19 +259,6 @@ func NewS3StorageForTest(svc s3iface.S3API, options *backuppb.S3) *S3Storage { } } -// NewS3Storage initialize a new s3 storage for metadata. -// -// Deprecated: Create the storage via `New()` instead of using this. -func NewS3Storage( // revive:disable-line:flag-parameter - backend *backuppb.S3, - sendCredential bool, -) (*S3Storage, error) { - return newS3Storage(backend, &ExternalStorageOptions{ - SendCredentials: sendCredential, - CheckPermissions: []Permission{AccessBuckets}, - }) -} - // auto access without ak / sk. func autoNewCred(qs *backuppb.S3) (cred *credentials.Credentials, err error) { if qs.AccessKey != "" && qs.SecretAccessKey != "" { @@ -288,7 +286,8 @@ func createOssRAMCred() (*credentials.Credentials, error) { return credentials.NewStaticCredentials(ncred.AccessKeyId, ncred.AccessKeySecret, ncred.AccessKeyStsToken), nil } -func newS3Storage(backend *backuppb.S3, opts *ExternalStorageOptions) (obj *S3Storage, errRet error) { +// NewS3Storage initialize a new s3 storage for metadata. +func NewS3Storage(backend *backuppb.S3, opts *ExternalStorageOptions) (obj *S3Storage, errRet error) { qs := *backend awsConfig := aws.NewConfig(). WithS3ForcePathStyle(qs.ForcePathStyle). @@ -355,13 +354,18 @@ func newS3Storage(backend *backuppb.S3, opts *ExternalStorageOptions) (obj *S3St ) } c := s3.New(ses, s3CliConfigs...) - // s3manager.GetBucketRegionWithClient will set credential anonymous, which works with s3. - // we need reassign credential to be compatible with minio authentication. confCred := ses.Config.Credentials setCredOpt := func(req *request.Request) { + // s3manager.GetBucketRegionWithClient will set credential anonymous, which works with s3. + // we need reassign credential to be compatible with minio authentication. if confCred != nil { req.Config.Credentials = confCred } + // s3manager.GetBucketRegionWithClient use path style addressing default. + // we need set S3ForcePathStyle by our config if we set endpoint. + if qs.Endpoint != "" { + req.Config.S3ForcePathStyle = ses.Config.S3ForcePathStyle + } } region, err := s3manager.GetBucketRegionWithClient(context.Background(), c, qs.Bucket, setCredOpt) if err != nil { @@ -400,7 +404,7 @@ func newS3Storage(backend *backuppb.S3, opts *ExternalStorageOptions) (obj *S3St options: &qs, } if opts.CheckS3ObjectLockOptions { - backend.ObjectLockEnabled = s3Storage.isObjectLockEnabled() + backend.ObjectLockEnabled = s3Storage.IsObjectLockEnabled() } return s3Storage, nil } @@ -447,7 +451,7 @@ func getObject(svc *s3.S3, qs *backuppb.S3) error { return nil } -func (rs *S3Storage) isObjectLockEnabled() bool { +func (rs *S3Storage) IsObjectLockEnabled() bool { input := &s3.GetObjectLockConfigurationInput{ Bucket: aws.String(rs.options.Bucket), } @@ -456,8 +460,8 @@ func (rs *S3Storage) isObjectLockEnabled() bool { log.Warn("failed to check object lock for bucket", zap.String("bucket", rs.options.Bucket), zap.Error(err)) return false } - if resp.ObjectLockConfiguration != nil { - if s3.ObjectLockEnabledEnabled == *resp.ObjectLockConfiguration.ObjectLockEnabled { + if resp != nil && resp.ObjectLockConfiguration != nil { + if s3.ObjectLockEnabledEnabled == aws.StringValue(resp.ObjectLockConfiguration.ObjectLockEnabled) { return true } } diff --git a/br/pkg/storage/s3_test.go b/br/pkg/storage/s3_test.go index 3990e5eb82bc1..3600a757ef0c4 100644 --- a/br/pkg/storage/s3_test.go +++ b/br/pkg/storage/s3_test.go @@ -314,10 +314,11 @@ func TestS3Storage(t *testing.T) { { name: "no region", s3: &backuppb.S3{ - Region: "", - Endpoint: s.URL, - Bucket: "bucket", - Prefix: "prefix", + Region: "", + Endpoint: s.URL, + Bucket: "bucket", + Prefix: "prefix", + ForcePathStyle: true, }, errReturn: false, sendCredential: true, @@ -325,10 +326,11 @@ func TestS3Storage(t *testing.T) { { name: "wrong region", s3: &backuppb.S3{ - Region: "us-east-2", - Endpoint: s.URL, - Bucket: "bucket", - Prefix: "prefix", + Region: "us-east-2", + Endpoint: s.URL, + Bucket: "bucket", + Prefix: "prefix", + ForcePathStyle: true, }, errReturn: true, sendCredential: true, @@ -336,10 +338,11 @@ func TestS3Storage(t *testing.T) { { name: "right region", s3: &backuppb.S3{ - Region: "us-west-2", - Endpoint: s.URL, - Bucket: "bucket", - Prefix: "prefix", + Region: "us-west-2", + Endpoint: s.URL, + Bucket: "bucket", + Prefix: "prefix", + ForcePathStyle: true, }, errReturn: false, sendCredential: true, @@ -353,6 +356,7 @@ func TestS3Storage(t *testing.T) { SecretAccessKey: "cd", Bucket: "bucket", Prefix: "prefix", + ForcePathStyle: true, }, errReturn: false, sendCredential: true, @@ -365,6 +369,7 @@ func TestS3Storage(t *testing.T) { SecretAccessKey: "cd", Bucket: "bucket", Prefix: "prefix", + ForcePathStyle: true, }, errReturn: false, sendCredential: true, @@ -372,11 +377,12 @@ func TestS3Storage(t *testing.T) { { name: "no secret access key", s3: &backuppb.S3{ - Region: "us-west-2", - Endpoint: s.URL, - AccessKey: "ab", - Bucket: "bucket", - Prefix: "prefix", + Region: "us-west-2", + Endpoint: s.URL, + AccessKey: "ab", + Bucket: "bucket", + Prefix: "prefix", + ForcePathStyle: true, }, errReturn: false, sendCredential: true, @@ -384,11 +390,12 @@ func TestS3Storage(t *testing.T) { { name: "no secret access key", s3: &backuppb.S3{ - Region: "us-west-2", - Endpoint: s.URL, - AccessKey: "ab", - Bucket: "bucket", - Prefix: "prefix", + Region: "us-west-2", + Endpoint: s.URL, + AccessKey: "ab", + Bucket: "bucket", + Prefix: "prefix", + ForcePathStyle: true, }, errReturn: false, sendCredential: false, @@ -1141,3 +1148,48 @@ func TestSendCreds(t *testing.T) { sentSecretAccessKey = backend.GetS3().SecretAccessKey require.Equal(t, "", sentSecretAccessKey) } + +func TestObjectLock(t *testing.T) { + s := createS3Suite(t) + // resp is nil + s.s3.EXPECT().GetObjectLockConfiguration(gomock.Any()).Return(nil, nil) + require.Equal(t, false, s.storage.IsObjectLockEnabled()) + + // resp is not nil, but resp.ObjectLockConfiguration is nil + s.s3.EXPECT().GetObjectLockConfiguration(gomock.Any()).Return( + &s3.GetObjectLockConfigurationOutput{ + ObjectLockConfiguration: nil, + }, nil, + ) + require.Equal(t, false, s.storage.IsObjectLockEnabled()) + + // resp.ObjectLockConfiguration is not nil, but resp.ObjectLockConfiguration.ObjectLockEnabled is nil + s.s3.EXPECT().GetObjectLockConfiguration(gomock.Any()).Return( + &s3.GetObjectLockConfigurationOutput{ + ObjectLockConfiguration: &s3.ObjectLockConfiguration{ + ObjectLockEnabled: nil, + }, + }, nil, + ) + require.Equal(t, false, s.storage.IsObjectLockEnabled()) + + // resp.ObjectLockConfiguration.ObjectLockEnabled is illegal string + s.s3.EXPECT().GetObjectLockConfiguration(gomock.Any()).Return( + &s3.GetObjectLockConfigurationOutput{ + ObjectLockConfiguration: &s3.ObjectLockConfiguration{ + ObjectLockEnabled: aws.String("EnaBled"), + }, + }, nil, + ) + require.Equal(t, false, s.storage.IsObjectLockEnabled()) + + // resp.ObjectLockConfiguration.ObjectLockEnabled is enabled + s.s3.EXPECT().GetObjectLockConfiguration(gomock.Any()).Return( + &s3.GetObjectLockConfigurationOutput{ + ObjectLockConfiguration: &s3.ObjectLockConfiguration{ + ObjectLockEnabled: aws.String("Enabled"), + }, + }, nil, + ) + require.Equal(t, true, s.storage.IsObjectLockEnabled()) +} diff --git a/br/pkg/storage/storage.go b/br/pkg/storage/storage.go index b73181e582158..1aa2df5f5e36a 100644 --- a/br/pkg/storage/storage.go +++ b/br/pkg/storage/storage.go @@ -158,6 +158,9 @@ func Create(ctx context.Context, backend *backuppb.StorageBackend, sendCreds boo // New creates an ExternalStorage with options. func New(ctx context.Context, backend *backuppb.StorageBackend, opts *ExternalStorageOptions) (ExternalStorage, error) { + if opts == nil { + opts = &ExternalStorageOptions{} + } switch backend := backend.Backend.(type) { case *backuppb.StorageBackend_Local: if backend.Local == nil { @@ -173,14 +176,14 @@ func New(ctx context.Context, backend *backuppb.StorageBackend, opts *ExternalSt if backend.S3 == nil { return nil, errors.Annotate(berrors.ErrStorageInvalidConfig, "s3 config not found") } - return newS3Storage(backend.S3, opts) + return NewS3Storage(backend.S3, opts) case *backuppb.StorageBackend_Noop: return newNoopStorage(), nil case *backuppb.StorageBackend_Gcs: if backend.Gcs == nil { return nil, errors.Annotate(berrors.ErrStorageInvalidConfig, "GCS config not found") } - return newGCSStorage(ctx, backend.Gcs, opts) + return NewGCSStorage(ctx, backend.Gcs, opts) case *backuppb.StorageBackend_AzureBlobStorage: return newAzureBlobStorage(ctx, backend.AzureBlobStorage, opts) default: diff --git a/br/pkg/storage/writer.go b/br/pkg/storage/writer.go index 455cc9c3c3411..f61d30fa530d9 100644 --- a/br/pkg/storage/writer.go +++ b/br/pkg/storage/writer.go @@ -6,7 +6,11 @@ import ( "context" "io" + "github.com/golang/snappy" + "github.com/klauspost/compress/zstd" "github.com/pingcap/errors" + "github.com/pingcap/log" + "go.uber.org/zap" ) // CompressType represents the type of compression. @@ -17,6 +21,10 @@ const ( NoCompression CompressType = iota // Gzip will compress given bytes in gzip format. Gzip + // Snappy will compress given bytes in snappy format. + Snappy + // Zstd will compress given bytes in zstd format. + Zstd ) type flusher interface { @@ -39,6 +47,21 @@ type interceptBuffer interface { Compressed() bool } +func createSuffixString(compressType CompressType) string { + txtSuffix := ".txt" + switch compressType { + case Gzip: + txtSuffix += ".gz" + case Snappy: + txtSuffix += ".snappy" + case Zstd: + txtSuffix += ".zst" + default: + return "" + } + return txtSuffix +} + func newInterceptBuffer(chunkSize int, compressType CompressType) interceptBuffer { if compressType == NoCompression { return newNoCompressionBuffer(chunkSize) @@ -50,15 +73,27 @@ func newCompressWriter(compressType CompressType, w io.Writer) simpleCompressWri switch compressType { case Gzip: return gzip.NewWriter(w) + case Snappy: + return snappy.NewBufferedWriter(w) + case Zstd: + newWriter, err := zstd.NewWriter(w) + if err != nil { + log.Warn("Met error when creating new writer for Zstd type file", zap.Error(err)) + } + return newWriter default: return nil } } -func newCompressReader(compressType CompressType, r io.Reader) (io.ReadCloser, error) { +func newCompressReader(compressType CompressType, r io.Reader) (io.Reader, error) { switch compressType { case Gzip: return gzip.NewReader(r) + case Snappy: + return snappy.NewReader(r), nil + case Zstd: + return zstd.NewReader(r) default: return nil, nil } diff --git a/br/pkg/storage/writer_test.go b/br/pkg/storage/writer_test.go index c3d4080123f4f..22fa87d34de47 100644 --- a/br/pkg/storage/writer_test.go +++ b/br/pkg/storage/writer_test.go @@ -102,8 +102,9 @@ func TestCompressReaderWriter(t *testing.T) { ctx := context.Background() storage, err := Create(ctx, backend, true) require.NoError(t, err) - storage = WithCompression(storage, Gzip) - fileName := strings.ReplaceAll(test.name, " ", "-") + ".txt.gz" + storage = WithCompression(storage, test.compressType) + suffix := createSuffixString(test.compressType) + fileName := strings.ReplaceAll(test.name, " ", "-") + suffix writer, err := storage.Create(ctx, fileName) require.NoError(t, err) for _, str := range test.content { @@ -124,7 +125,6 @@ func TestCompressReaderWriter(t *testing.T) { _, err = bf.ReadFrom(r) require.NoError(t, err) require.Equal(t, strings.Join(test.content, ""), bf.String()) - require.Nil(t, r.Close()) // test withCompression Open r, err = storage.Open(ctx, fileName) @@ -135,7 +135,8 @@ func TestCompressReaderWriter(t *testing.T) { require.Nil(t, file.Close()) } - compressTypeArr := []CompressType{Gzip} + compressTypeArr := []CompressType{Gzip, Snappy, Zstd} + tests := []testcase{ { name: "long text medium chunks", diff --git a/br/pkg/stream/BUILD.bazel b/br/pkg/stream/BUILD.bazel index f75f9f37d81ea..e5fbc5c87b870 100644 --- a/br/pkg/stream/BUILD.bazel +++ b/br/pkg/stream/BUILD.bazel @@ -56,8 +56,11 @@ go_test( "//br/pkg/storage", "//br/pkg/streamhelper", "//meta", + "//parser/ast", "//parser/model", + "//parser/mysql", "//tablecodec", + "//types", "//util/codec", "//util/table-filter", "@com_github_pingcap_kvproto//pkg/brpb", diff --git a/br/pkg/stream/meta_kv.go b/br/pkg/stream/meta_kv.go index 9d054f0bef454..fb7c2f79f17d1 100644 --- a/br/pkg/stream/meta_kv.go +++ b/br/pkg/stream/meta_kv.go @@ -111,15 +111,34 @@ const ( flagShortValuePrefix = byte('v') flagOverlappedRollback = byte('R') flagGCFencePrefix = byte('F') + flagLastChangePrefix = byte('l') + flagTxnSourcePrefix = byte('S') ) +// RawWriteCFValue represents the value in write columnFamily. +// Detail see line: https://github.com/tikv/tikv/blob/release-6.5/components/txn_types/src/write.rs#L70 type RawWriteCFValue struct { t WriteType startTs uint64 shortValue []byte hasOverlappedRollback bool - hasGCFence bool - gcFence uint64 + + // Records the next version after this version when overlapping rollback + // happens on an already existed commit record. + // + // See [`Write::gc_fence`] for more detail. + hasGCFence bool + gcFence uint64 + + // The number of versions that need skipping from this record + // to find the latest PUT/DELETE record. + // If versions_to_last_change > 0 but last_change_ts == 0, the key does not + // have a PUT/DELETE record before this write record. + lastChangeTs uint64 + versionsToLastChange uint64 + + // The source of this txn. + txnSource uint64 } // ParseFrom decodes the value to get the struct `RawWriteCFValue`. @@ -146,6 +165,10 @@ l_for: switch data[0] { case flagShortValuePrefix: vlen := data[1] + if len(data[2:]) < int(vlen) { + return errors.Annotatef(berrors.ErrInvalidArgument, + "the length of short value is invalid, vlen: %v", int(vlen)) + } v.shortValue = data[2 : vlen+2] data = data[vlen+2:] case flagOverlappedRollback: @@ -157,6 +180,20 @@ l_for: if err != nil { return errors.Annotate(berrors.ErrInvalidArgument, "decode gc fence failed") } + case flagLastChangePrefix: + data, v.lastChangeTs, err = codec.DecodeUint(data[1:]) + if err != nil { + return errors.Annotate(berrors.ErrInvalidArgument, "decode last change ts failed") + } + data, v.versionsToLastChange, err = codec.DecodeUvarint(data) + if err != nil { + return errors.Annotate(berrors.ErrInvalidArgument, "decode versions to last change failed") + } + case flagTxnSourcePrefix: + data, v.txnSource, err = codec.DecodeUvarint(data[1:]) + if err != nil { + return errors.Annotate(berrors.ErrInvalidArgument, "decode txn source failed") + } default: break l_for } @@ -164,6 +201,16 @@ l_for: return nil } +// IsRollback checks whether the value in cf is a `rollback` record. +func (v *RawWriteCFValue) IsRollback() bool { + return v.GetWriteType() == WriteTypeRollback +} + +// IsRollback checks whether the value in cf is a `delete` record. +func (v *RawWriteCFValue) IsDelete() bool { + return v.GetWriteType() == WriteTypeDelete +} + // HasShortValue checks whether short value is stored in write cf. func (v *RawWriteCFValue) HasShortValue() bool { return len(v.shortValue) > 0 @@ -204,5 +251,14 @@ func (v *RawWriteCFValue) EncodeTo() []byte { data = append(data, flagGCFencePrefix) data = codec.EncodeUint(data, v.gcFence) } + if v.lastChangeTs > 0 || v.versionsToLastChange > 0 { + data = append(data, flagLastChangePrefix) + data = codec.EncodeUint(data, v.lastChangeTs) + data = codec.EncodeUvarint(data, v.versionsToLastChange) + } + if v.txnSource > 0 { + data = append(data, flagTxnSourcePrefix) + data = codec.EncodeUvarint(data, v.txnSource) + } return data } diff --git a/br/pkg/stream/meta_kv_test.go b/br/pkg/stream/meta_kv_test.go index eaebf64526243..7a8c5e4fed8b6 100644 --- a/br/pkg/stream/meta_kv_test.go +++ b/br/pkg/stream/meta_kv_test.go @@ -68,29 +68,49 @@ func TestWriteType(t *testing.T) { } func TestWriteCFValueNoShortValue(t *testing.T) { + var ( + ts uint64 = 400036290571534337 + txnSource uint64 = 9527 + ) + buff := make([]byte, 0, 9) - buff = append(buff, byte('P')) - buff = codec.EncodeUvarint(buff, 400036290571534337) + buff = append(buff, WriteTypePut) + buff = codec.EncodeUvarint(buff, ts) + buff = append(buff, flagTxnSourcePrefix) + buff = codec.EncodeUvarint(buff, txnSource) v := new(RawWriteCFValue) err := v.ParseFrom(buff) require.NoError(t, err) + require.False(t, v.IsDelete()) + require.False(t, v.IsRollback()) require.False(t, v.HasShortValue()) + require.False(t, v.hasGCFence) + require.Equal(t, v.lastChangeTs, uint64(0)) + require.Equal(t, v.versionsToLastChange, uint64(0)) + require.Equal(t, v.txnSource, txnSource) encodedBuff := v.EncodeTo() require.True(t, bytes.Equal(buff, encodedBuff)) } func TestWriteCFValueWithShortValue(t *testing.T) { - var ts uint64 = 400036290571534337 - shortValue := []byte("pingCAP") + var ( + ts uint64 = 400036290571534337 + shortValue = []byte("pingCAP") + lastChangeTs uint64 = 9527 + versionsToLastChange uint64 = 95271 + ) buff := make([]byte, 0, 9) - buff = append(buff, byte('P')) + buff = append(buff, WriteTypePut) buff = codec.EncodeUvarint(buff, ts) buff = append(buff, flagShortValuePrefix) buff = append(buff, byte(len(shortValue))) buff = append(buff, shortValue...) + buff = append(buff, flagLastChangePrefix) + buff = codec.EncodeUint(buff, lastChangeTs) + buff = codec.EncodeUvarint(buff, versionsToLastChange) v := new(RawWriteCFValue) err := v.ParseFrom(buff) @@ -99,7 +119,78 @@ func TestWriteCFValueWithShortValue(t *testing.T) { require.True(t, bytes.Equal(v.GetShortValue(), shortValue)) require.False(t, v.hasGCFence) require.False(t, v.hasOverlappedRollback) + require.Equal(t, v.lastChangeTs, lastChangeTs) + require.Equal(t, v.versionsToLastChange, versionsToLastChange) + require.Equal(t, v.txnSource, uint64(0)) data := v.EncodeTo() require.True(t, bytes.Equal(data, buff)) } + +func TestWriteCFValueWithRollback(t *testing.T) { + var ( + ts uint64 = 400036290571534337 + protectedRollbackShortValue = []byte{'P'} + ) + + buff := make([]byte, 0, 9) + buff = append(buff, WriteTypeRollback) + buff = codec.EncodeUvarint(buff, ts) + buff = append(buff, flagShortValuePrefix, byte(len(protectedRollbackShortValue))) + buff = append(buff, protectedRollbackShortValue...) + + v := new(RawWriteCFValue) + err := v.ParseFrom(buff) + require.NoError(t, err) + require.True(t, v.IsRollback()) + require.True(t, v.HasShortValue()) + require.Equal(t, v.GetShortValue(), protectedRollbackShortValue) + require.Equal(t, v.startTs, ts) + require.Equal(t, v.lastChangeTs, uint64(0)) + require.Equal(t, v.versionsToLastChange, uint64(0)) + require.Equal(t, v.txnSource, uint64(0)) + + data := v.EncodeTo() + require.Equal(t, data, buff) +} + +func TestWriteCFValueWithDelete(t *testing.T) { + var ts uint64 = 400036290571534337 + buff := make([]byte, 0, 9) + buff = append(buff, byte('D')) + buff = codec.EncodeUvarint(buff, ts) + + v := new(RawWriteCFValue) + err := v.ParseFrom(buff) + require.NoError(t, err) + require.True(t, v.IsDelete()) + require.False(t, v.HasShortValue()) + + data := v.EncodeTo() + require.Equal(t, data, buff) +} + +func TestWriteCFValueWithGcFence(t *testing.T) { + var ( + ts uint64 = 400036290571534337 + gcFence uint64 = 9527 + ) + + buff := make([]byte, 0, 9) + buff = append(buff, WriteTypePut) + buff = codec.EncodeUvarint(buff, ts) + buff = append(buff, flagOverlappedRollback) + buff = append(buff, flagGCFencePrefix) + buff = codec.EncodeUint(buff, gcFence) + + v := new(RawWriteCFValue) + err := v.ParseFrom(buff) + require.NoError(t, err) + require.Equal(t, v.startTs, ts) + require.True(t, v.hasGCFence) + require.Equal(t, v.gcFence, gcFence) + require.True(t, v.hasOverlappedRollback) + + data := v.EncodeTo() + require.Equal(t, data, buff) +} diff --git a/br/pkg/stream/rewrite_meta_rawkv.go b/br/pkg/stream/rewrite_meta_rawkv.go index 40e76a6130358..3c559ec124ad8 100644 --- a/br/pkg/stream/rewrite_meta_rawkv.go +++ b/br/pkg/stream/rewrite_meta_rawkv.go @@ -336,6 +336,11 @@ func (sr *SchemasReplace) rewriteTableInfo(value []byte, dbID int64) ([]byte, bo } } + // Force to disable TTL_ENABLE when restore + if newTableInfo.TTLInfo != nil { + newTableInfo.TTLInfo.Enable = false + } + if sr.AfterTableRewritten != nil { sr.AfterTableRewritten(false, newTableInfo) } @@ -451,13 +456,20 @@ func (sr *SchemasReplace) rewriteValueV2(value []byte, cf string, rewrite func([ return rewriteResult{}, errors.Trace(err) } - if rawWriteCFValue.t == WriteTypeDelete { + if rawWriteCFValue.IsDelete() { return rewriteResult{ NewValue: value, NeedRewrite: true, Deleted: true, }, nil } + if rawWriteCFValue.IsRollback() { + return rewriteResult{ + NewValue: value, + NeedRewrite: true, + Deleted: false, + }, nil + } if !rawWriteCFValue.HasShortValue() { return rewriteResult{ NewValue: value, @@ -467,6 +479,9 @@ func (sr *SchemasReplace) rewriteValueV2(value []byte, cf string, rewrite func([ shortValue, needWrite, err := rewrite(rawWriteCFValue.GetShortValue()) if err != nil { + log.Info("failed to rewrite short value", + zap.ByteString("write-type", []byte{rawWriteCFValue.GetWriteType()}), + zap.Int("short-value-len", len(rawWriteCFValue.GetShortValue()))) return rewriteResult{}, errors.Trace(err) } if !needWrite { diff --git a/br/pkg/stream/rewrite_meta_rawkv_test.go b/br/pkg/stream/rewrite_meta_rawkv_test.go index d2cbe24e8295d..cd3cf00d46305 100644 --- a/br/pkg/stream/rewrite_meta_rawkv_test.go +++ b/br/pkg/stream/rewrite_meta_rawkv_test.go @@ -7,7 +7,10 @@ import ( "encoding/json" "testing" + "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/types" filter "github.com/pingcap/tidb/util/table-filter" "github.com/stretchr/testify/require" ) @@ -312,6 +315,52 @@ func TestRewriteValueForExchangePartition(t *testing.T) { require.Equal(t, tableInfo.ID, pt1ID+100) } +func TestRewriteValueForTTLTable(t *testing.T) { + var ( + dbId int64 = 40 + tableID int64 = 100 + colID int64 = 1000 + colName = "t" + tableName = "t1" + tableInfo model.TableInfo + ) + + tbl := model.TableInfo{ + ID: tableID, + Name: model.NewCIStr(tableName), + Columns: []*model.ColumnInfo{ + { + ID: colID, + Name: model.NewCIStr(colName), + FieldType: *types.NewFieldType(mysql.TypeTimestamp), + }, + }, + TTLInfo: &model.TTLInfo{ + ColumnName: model.NewCIStr(colName), + IntervalExprStr: "1", + IntervalTimeUnit: int(ast.TimeUnitDay), + Enable: true, + }, + } + value, err := json.Marshal(&tbl) + require.Nil(t, err) + + sr := MockEmptySchemasReplace(nil) + newValue, needRewrite, err := sr.rewriteTableInfo(value, dbId) + require.Nil(t, err) + require.True(t, needRewrite) + + err = json.Unmarshal(newValue, &tableInfo) + require.Nil(t, err) + require.Equal(t, tableInfo.Name.String(), tableName) + require.Equal(t, tableInfo.ID, sr.DbMap[dbId].TableMap[tableID].NewTableID) + require.NotNil(t, tableInfo.TTLInfo) + require.Equal(t, colName, tableInfo.TTLInfo.ColumnName.O) + require.Equal(t, "1", tableInfo.TTLInfo.IntervalExprStr) + require.Equal(t, int(ast.TimeUnitDay), tableInfo.TTLInfo.IntervalTimeUnit) + require.False(t, tableInfo.TTLInfo.Enable) +} + // db:70->80 - // | - t0:71->81 - // | | - p0:72->82 diff --git a/br/pkg/stream/stream_mgr.go b/br/pkg/stream/stream_mgr.go index 61c3e6772a431..5ee184ba04f03 100644 --- a/br/pkg/stream/stream_mgr.go +++ b/br/pkg/stream/stream_mgr.go @@ -312,7 +312,6 @@ func FastUnmarshalMetaData( } readPath := path pool.ApplyOnErrorGroup(eg, func() error { - log.Info("fast read meta file from storage", zap.String("path", readPath)) b, err := s.ReadFile(ectx, readPath) if err != nil { log.Error("failed to read file", zap.String("file", readPath)) diff --git a/br/pkg/streamhelper/BUILD.bazel b/br/pkg/streamhelper/BUILD.bazel index 93e13b1f8d543..3c281563439de 100644 --- a/br/pkg/streamhelper/BUILD.bazel +++ b/br/pkg/streamhelper/BUILD.bazel @@ -9,10 +9,10 @@ go_library( "advancer_env.go", "client.go", "collector.go", + "flush_subscriber.go", "models.go", "prefix_scanner.go", "regioniter.go", - "tsheap.go", ], importpath = "github.com/pingcap/tidb/br/pkg/streamhelper", visibility = ["//visibility:public"], @@ -21,15 +21,17 @@ go_library( "//br/pkg/logutil", "//br/pkg/redact", "//br/pkg/streamhelper/config", + "//br/pkg/streamhelper/spans", "//br/pkg/utils", "//config", "//kv", "//metrics", "//owner", + "//util/codec", + "//util/engine", "//util/mathutil", "@com_github_gogo_protobuf//proto", "@com_github_golang_protobuf//proto", - "@com_github_google_btree//:btree", "@com_github_google_uuid//:uuid", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_kvproto//pkg/brpb", @@ -41,10 +43,12 @@ go_library( "@com_github_tikv_pd_client//:client", "@io_etcd_go_etcd_client_v3//:client", "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//codes", "@org_golang_google_grpc//keepalive", + "@org_golang_google_grpc//status", "@org_golang_x_sync//errgroup", + "@org_uber_go_multierr//:multierr", "@org_uber_go_zap//:zap", - "@org_uber_go_zap//zapcore", ], ) @@ -56,7 +60,7 @@ go_test( "basic_lib_for_test.go", "integration_test.go", "regioniter_test.go", - "tsheap_test.go", + "subscription_test.go", ], flaky = True, race = "on", @@ -68,9 +72,11 @@ go_test( "//br/pkg/redact", "//br/pkg/storage", "//br/pkg/streamhelper/config", + "//br/pkg/streamhelper/spans", "//br/pkg/utils", "//kv", "//tablecodec", + "//util/codec", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_kvproto//pkg/brpb", "@com_github_pingcap_kvproto//pkg/errorpb", @@ -84,6 +90,7 @@ go_test( "@io_etcd_go_etcd_server_v3//mvcc", "@org_golang_google_grpc//:grpc", "@org_golang_google_grpc//codes", + "@org_golang_google_grpc//metadata", "@org_golang_google_grpc//status", "@org_uber_go_zap//:zap", "@org_uber_go_zap//zapcore", diff --git a/br/pkg/streamhelper/advancer.go b/br/pkg/streamhelper/advancer.go index ac01c5167ffc7..b29cbd6956ae2 100644 --- a/br/pkg/streamhelper/advancer.go +++ b/br/pkg/streamhelper/advancer.go @@ -3,11 +3,7 @@ package streamhelper import ( - "bytes" "context" - "math" - "reflect" - "sort" "strings" "sync" "time" @@ -17,10 +13,12 @@ import ( "github.com/pingcap/log" "github.com/pingcap/tidb/br/pkg/logutil" "github.com/pingcap/tidb/br/pkg/streamhelper/config" + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" "github.com/pingcap/tidb/br/pkg/utils" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" "github.com/tikv/client-go/v2/oracle" + "go.uber.org/multierr" "go.uber.org/zap" "golang.org/x/sync/errgroup" ) @@ -60,81 +58,31 @@ type CheckpointAdvancer struct { // once tick begin, this should not be changed for now. cfg config.Config - // the cache of region checkpoints. - // so we can advance only ranges with huge gap. - cache CheckpointsCache - - // the internal state of advancer. - state advancerState // the cached last checkpoint. // if no progress, this cache can help us don't to send useless requests. lastCheckpoint uint64 -} -// advancerState is the sealed type for the state of advancer. -// the advancer has two stage: full scan and update small tree. -type advancerState interface { - // Note: - // Go doesn't support sealed classes or ADTs currently. - // (it can only be used at generic constraints...) - // Leave it empty for now. - - // ~*fullScan | ~*updateSmallTree -} + checkpoints *spans.ValueSortedFull + checkpointsMu sync.Mutex -// fullScan is the initial state of advancer. -// in this stage, we would "fill" the cache: -// insert ranges that union of them become the full range of task. -type fullScan struct { - fullScanTick int -} - -// updateSmallTree is the "incremental stage" of advancer. -// we have build a "filled" cache, and we can pop a subrange of it, -// try to advance the checkpoint of those ranges. -type updateSmallTree struct { - consistencyCheckTick int + subscriber *FlushSubscriber + subscriberMu sync.Mutex } // NewCheckpointAdvancer creates a checkpoint advancer with the env. func NewCheckpointAdvancer(env Env) *CheckpointAdvancer { return &CheckpointAdvancer{ - env: env, - cfg: config.Default(), - cache: NewCheckpoints(), - state: &fullScan{}, + env: env, + cfg: config.Default(), } } -// disableCache removes the cache. -// note this won't lock the checkpoint advancer at `fullScan` state forever, -// you may need to change the config `AdvancingByCache`. -func (c *CheckpointAdvancer) disableCache() { - c.cache = NoOPCheckpointCache{} - c.state = &fullScan{} -} - -// enable the cache. -// also check `AdvancingByCache` in the config. -func (c *CheckpointAdvancer) enableCache() { - c.cache = NewCheckpoints() - c.state = &fullScan{} -} - // UpdateConfig updates the config for the advancer. // Note this should be called before starting the loop, because there isn't locks, // TODO: support updating config when advancer starts working. // (Maybe by applying changes at begin of ticking, and add locks.) func (c *CheckpointAdvancer) UpdateConfig(newConf config.Config) { - needRefreshCache := newConf.AdvancingByCache != c.cfg.AdvancingByCache c.cfg = newConf - if needRefreshCache { - if c.cfg.AdvancingByCache { - c.enableCache() - } else { - c.disableCache() - } - } } // UpdateConfigWith updates the config by modifying the current config. @@ -161,7 +109,7 @@ func (c *CheckpointAdvancer) GetCheckpointInRange(ctx context.Context, start, en } log.Debug("scan region", zap.Int("len", len(rs))) for _, r := range rs { - err := collector.collectRegion(r) + err := collector.CollectRegion(r) if err != nil { log.Warn("meet error during getting checkpoint", logutil.ShortError(err)) return err @@ -183,28 +131,24 @@ func (c *CheckpointAdvancer) recordTimeCost(message string, fields ...zap.Field) } // tryAdvance tries to advance the checkpoint ts of a set of ranges which shares the same checkpoint. -func (c *CheckpointAdvancer) tryAdvance(ctx context.Context, rst RangesSharesTS) (err error) { - defer c.recordTimeCost("try advance", zap.Uint64("checkpoint", rst.TS), zap.Int("len", len(rst.Ranges)))() - defer func() { - if err != nil { - log.Warn("failed to advance", logutil.ShortError(err), zap.Object("target", rst.Zap())) - c.cache.InsertRanges(rst) - } - }() +func (c *CheckpointAdvancer) tryAdvance(ctx context.Context, length int, getRange func(int) kv.KeyRange) (err error) { + defer c.recordTimeCost("try advance", zap.Int("len", length))() defer utils.PanicToErr(&err) - ranges := CollapseRanges(len(rst.Ranges), func(i int) kv.KeyRange { - return rst.Ranges[i] - }) - workers := utils.NewWorkerPool(4, "sub ranges") + ranges := spans.Collapse(length, getRange) + workers := utils.NewWorkerPool(uint(config.DefaultMaxConcurrencyAdvance)*4, "sub ranges") eg, cx := errgroup.WithContext(ctx) collector := NewClusterCollector(ctx, c.env) - collector.setOnSuccessHook(c.cache.InsertRange) + collector.SetOnSuccessHook(func(u uint64, kr kv.KeyRange) { + c.checkpointsMu.Lock() + defer c.checkpointsMu.Unlock() + c.checkpoints.Merge(spans.Valued{Key: kr, Value: u}) + }) clampedRanges := utils.IntersectAll(ranges, utils.CloneSlice(c.taskRange)) for _, r := range clampedRanges { r := r workers.ApplyOnErrorGroup(eg, func() (e error) { - defer c.recordTimeCost("get regions in range", zap.Uint64("checkpoint", rst.TS))() + defer c.recordTimeCost("get regions in range")() defer utils.PanicToErr(&e) return c.GetCheckpointInRange(cx, r.StartKey, r.EndKey, collector) }) @@ -214,121 +158,47 @@ func (c *CheckpointAdvancer) tryAdvance(ctx context.Context, rst RangesSharesTS) return err } - result, err := collector.Finish(ctx) + _, err = collector.Finish(ctx) if err != nil { return err } - fr := result.FailureSubRanges - if len(fr) != 0 { - log.Debug("failure regions collected", zap.Int("size", len(fr))) - c.cache.InsertRanges(RangesSharesTS{ - TS: rst.TS, - Ranges: fr, - }) - } return nil } -// CalculateGlobalCheckpointLight tries to advance the global checkpoint by the cache. -func (c *CheckpointAdvancer) CalculateGlobalCheckpointLight(ctx context.Context) (uint64, error) { - log.Info("[log backup advancer hint] advancer with cache: current tree", zap.Stringer("ct", c.cache)) - rsts := c.cache.PopRangesWithGapGT(config.DefaultTryAdvanceThreshold) - if len(rsts) == 0 { - return 0, nil +func tsoBefore(n time.Duration) uint64 { + now := time.Now() + return oracle.ComposeTS(now.UnixMilli()-n.Milliseconds(), 0) +} + +func (c *CheckpointAdvancer) CalculateGlobalCheckpointLight(ctx context.Context, threshold time.Duration) (uint64, error) { + var targets []spans.Valued + c.checkpoints.TraverseValuesLessThan(tsoBefore(threshold), func(v spans.Valued) bool { + targets = append(targets, v) + return true + }) + if len(targets) == 0 { + c.checkpointsMu.Lock() + defer c.checkpointsMu.Unlock() + return c.checkpoints.MinValue(), nil } - samples := rsts - if len(rsts) > 3 { - samples = rsts[:3] + samples := targets + if len(targets) > 3 { + samples = targets[:3] } for _, sample := range samples { - log.Info("[log backup advancer hint] sample range.", zap.Object("range", sample.Zap()), zap.Int("total-len", len(rsts))) + log.Info("[log backup advancer hint] sample range.", zap.Stringer("sample", sample), zap.Int("total-len", len(targets))) } - workers := utils.NewWorkerPool(uint(config.DefaultMaxConcurrencyAdvance), "regions") - eg, cx := errgroup.WithContext(ctx) - for _, rst := range rsts { - rst := rst - workers.ApplyOnErrorGroup(eg, func() (err error) { - return c.tryAdvance(cx, *rst) - }) - } - err := eg.Wait() + err := c.tryAdvance(ctx, len(targets), func(i int) kv.KeyRange { return targets[i].Key }) if err != nil { return 0, err } - ts := c.cache.CheckpointTS() + c.checkpointsMu.Lock() + ts := c.checkpoints.MinValue() + c.checkpointsMu.Unlock() return ts, nil } -// CalculateGlobalCheckpoint calculates the global checkpoint, which won't use the cache. -func (c *CheckpointAdvancer) CalculateGlobalCheckpoint(ctx context.Context) (uint64, error) { - var ( - cp = uint64(math.MaxInt64) - thisRun []kv.KeyRange = c.taskRange - nextRun []kv.KeyRange - ) - defer c.recordTimeCost("record all") - for { - coll := NewClusterCollector(ctx, c.env) - coll.setOnSuccessHook(c.cache.InsertRange) - for _, u := range thisRun { - err := c.GetCheckpointInRange(ctx, u.StartKey, u.EndKey, coll) - if err != nil { - return 0, err - } - } - result, err := coll.Finish(ctx) - if err != nil { - return 0, err - } - log.Debug("full: a run finished", zap.Any("checkpoint", result)) - - nextRun = append(nextRun, result.FailureSubRanges...) - if cp > result.Checkpoint { - cp = result.Checkpoint - } - if len(nextRun) == 0 { - return cp, nil - } - thisRun = nextRun - nextRun = nil - log.Debug("backoffing with subranges", zap.Int("subranges", len(thisRun))) - time.Sleep(c.cfg.BackoffTime) - } -} - -// CollapseRanges collapse ranges overlapping or adjacent. -// Example: -// CollapseRanges({[1, 4], [2, 8], [3, 9]}) == {[1, 9]} -// CollapseRanges({[1, 3], [4, 7], [2, 3]}) == {[1, 3], [4, 7]} -func CollapseRanges(length int, getRange func(int) kv.KeyRange) []kv.KeyRange { - frs := make([]kv.KeyRange, 0, length) - for i := 0; i < length; i++ { - frs = append(frs, getRange(i)) - } - - sort.Slice(frs, func(i, j int) bool { - return bytes.Compare(frs[i].StartKey, frs[j].StartKey) < 0 - }) - - result := make([]kv.KeyRange, 0, len(frs)) - i := 0 - for i < len(frs) { - item := frs[i] - for { - i++ - if i >= len(frs) || (len(item.EndKey) != 0 && bytes.Compare(frs[i].StartKey, item.EndKey) > 0) { - break - } - if len(item.EndKey) != 0 && bytes.Compare(item.EndKey, frs[i].EndKey) < 0 || len(frs[i].EndKey) == 0 { - item.EndKey = frs[i].EndKey - } - } - result = append(result, item) - } - return result -} - func (c *CheckpointAdvancer) consumeAllTask(ctx context.Context, ch <-chan TaskEvent) error { for { select { @@ -414,24 +284,42 @@ func (c *CheckpointAdvancer) onTaskEvent(ctx context.Context, e TaskEvent) error case EventAdd: utils.LogBackupTaskCountInc() c.task = e.Info - c.taskRange = CollapseRanges(len(e.Ranges), func(i int) kv.KeyRange { return e.Ranges[i] }) + c.taskRange = spans.Collapse(len(e.Ranges), func(i int) kv.KeyRange { return e.Ranges[i] }) + c.checkpoints = spans.Sorted(spans.NewFullWith(e.Ranges, 0)) + c.lastCheckpoint = e.Info.StartTs log.Info("added event", zap.Stringer("task", e.Info), zap.Stringer("ranges", logutil.StringifyKeys(c.taskRange))) case EventDel: utils.LogBackupTaskCountDec() c.task = nil c.taskRange = nil - c.state = &fullScan{} + c.checkpoints = nil + // This would be synced by `taskMu`, perhaps we'd better rename that to `tickMu`. + // Do the null check because some of test cases won't equip the advancer with subscriber. + if c.subscriber != nil { + c.subscriber.Clear() + } if err := c.env.ClearV3GlobalCheckpointForTask(ctx, e.Name); err != nil { log.Warn("failed to clear global checkpoint", logutil.ShortError(err)) } metrics.LastCheckpoint.DeleteLabelValues(e.Name) - c.cache.Clear() case EventErr: return e.Err } return nil } +func (c *CheckpointAdvancer) setCheckpoint(cp uint64) bool { + if cp < c.lastCheckpoint { + log.Warn("failed to update global checkpoint: stale", zap.Uint64("old", c.lastCheckpoint), zap.Uint64("new", cp)) + return false + } + if cp <= c.lastCheckpoint { + return false + } + c.lastCheckpoint = cp + return true +} + // advanceCheckpointBy advances the checkpoint by a checkpoint getter function. func (c *CheckpointAdvancer) advanceCheckpointBy(ctx context.Context, getCheckpoint func(context.Context) (uint64, error)) error { start := time.Now() @@ -439,79 +327,111 @@ func (c *CheckpointAdvancer) advanceCheckpointBy(ctx context.Context, getCheckpo if err != nil { return err } - log.Info("get checkpoint", zap.Uint64("old", c.lastCheckpoint), zap.Uint64("new", cp)) - if cp < c.lastCheckpoint { - log.Warn("failed to update global checkpoint: stale", zap.Uint64("old", c.lastCheckpoint), zap.Uint64("new", cp)) + + if c.setCheckpoint(cp) { + log.Info("uploading checkpoint for task", + zap.Stringer("checkpoint", oracle.GetTimeFromTS(cp)), + zap.Uint64("checkpoint", cp), + zap.String("task", c.task.Name), + zap.Stringer("take", time.Since(start))) + metrics.LastCheckpoint.WithLabelValues(c.task.GetName()).Set(float64(c.lastCheckpoint)) } - if cp <= c.lastCheckpoint { + return nil +} + +func (c *CheckpointAdvancer) stopSubscriber() { + c.subscriberMu.Lock() + defer c.subscriberMu.Unlock() + c.subscriber.Drop() + c.subscriber = nil +} + +func (c *CheckpointAdvancer) spawnSubscriptionHandler(ctx context.Context) { + c.subscriberMu.Lock() + defer c.subscriberMu.Unlock() + c.subscriber = NewSubscriber(c.env, c.env, WithMasterContext(ctx)) + es := c.subscriber.Events() + + go func() { + for { + select { + case <-ctx.Done(): + return + case event, ok := <-es: + if !ok { + return + } + c.checkpointsMu.Lock() + log.Debug("Accepting region flush event.", + zap.Stringer("range", logutil.StringifyRange(event.Key)), + zap.Uint64("checkpoint", event.Value)) + c.checkpoints.Merge(event) + c.checkpointsMu.Unlock() + } + } + }() +} + +func (c *CheckpointAdvancer) subscribeTick(ctx context.Context) error { + if c.subscriber == nil { return nil } + if err := c.subscriber.UpdateStoreTopology(ctx); err != nil { + log.Warn("[log backup advancer] Error when updating store topology.", logutil.ShortError(err)) + } + c.subscriber.HandleErrors(ctx) + return c.subscriber.PendingErrors() +} - log.Info("uploading checkpoint for task", - zap.Stringer("checkpoint", oracle.GetTimeFromTS(cp)), - zap.Uint64("checkpoint", cp), - zap.String("task", c.task.Name), - zap.Stringer("take", time.Since(start))) - if err := c.env.UploadV3GlobalCheckpointForTask(ctx, c.task.Name, cp); err != nil { +func (c *CheckpointAdvancer) importantTick(ctx context.Context) error { + c.checkpointsMu.Lock() + c.setCheckpoint(c.checkpoints.MinValue()) + c.checkpointsMu.Unlock() + if err := c.env.UploadV3GlobalCheckpointForTask(ctx, c.task.Name, c.lastCheckpoint); err != nil { return errors.Annotate(err, "failed to upload global checkpoint") } - c.lastCheckpoint = cp - metrics.LastCheckpoint.WithLabelValues(c.task.GetName()).Set(float64(c.lastCheckpoint)) return nil } -func (c *CheckpointAdvancer) onConsistencyCheckTick(s *updateSmallTree) error { - if s.consistencyCheckTick > 0 { - s.consistencyCheckTick-- - return nil +func (c *CheckpointAdvancer) optionalTick(cx context.Context) error { + threshold := c.Config().GetDefaultStartPollThreshold() + if err := c.subscribeTick(cx); err != nil { + log.Warn("[log backup advancer] Subscriber meet error, would polling the checkpoint.", logutil.ShortError(err)) + threshold = c.Config().GetSubscriberErrorStartPollThreshold() } - defer c.recordTimeCost("consistency check")() - err := c.cache.ConsistencyCheck(c.taskRange) + + err := c.advanceCheckpointBy(cx, func(cx context.Context) (uint64, error) { + return c.CalculateGlobalCheckpointLight(cx, threshold) + }) if err != nil { - log.Error("consistency check failed! log backup may lose data! rolling back to full scan for saving.", logutil.ShortError(err)) - c.state = &fullScan{} return err } - log.Debug("consistency check passed.") - s.consistencyCheckTick = config.DefaultConsistencyCheckTick return nil } func (c *CheckpointAdvancer) tick(ctx context.Context) error { c.taskMu.Lock() defer c.taskMu.Unlock() + if c.task == nil { + log.Debug("No tasks yet, skipping advancing.") + return nil + } - switch s := c.state.(type) { - case *fullScan: - if s.fullScanTick > 0 { - s.fullScanTick-- - break - } - if c.task == nil { - log.Debug("No tasks yet, skipping advancing.") - return nil - } - defer func() { - s.fullScanTick = c.cfg.FullScanTick - }() - err := c.advanceCheckpointBy(ctx, c.CalculateGlobalCheckpoint) - if err != nil { - return err - } + var errs error - if c.cfg.AdvancingByCache { - c.state = &updateSmallTree{} - } - case *updateSmallTree: - if err := c.onConsistencyCheckTick(s); err != nil { - return err - } - err := c.advanceCheckpointBy(ctx, c.CalculateGlobalCheckpointLight) - if err != nil { - return err - } - default: - log.Error("Unknown state type, skipping tick", zap.Stringer("type", reflect.TypeOf(c.state))) + cx, cancel := context.WithTimeout(ctx, c.Config().TickTimeout()) + defer cancel() + err := c.optionalTick(cx) + if err != nil { + log.Warn("[log backup advancer] option tick failed.", logutil.ShortError(err)) + errs = multierr.Append(errs, err) } - return nil + + err = c.importantTick(ctx) + if err != nil { + log.Warn("[log backup advancer] important tick failed.", logutil.ShortError(err)) + errs = multierr.Append(errs, err) + } + + return errs } diff --git a/br/pkg/streamhelper/advancer_cliext.go b/br/pkg/streamhelper/advancer_cliext.go index 611ad3744dfa8..059475e62b2b2 100644 --- a/br/pkg/streamhelper/advancer_cliext.go +++ b/br/pkg/streamhelper/advancer_cliext.go @@ -5,15 +5,19 @@ package streamhelper import ( "bytes" "context" + "encoding/binary" "fmt" "strings" "github.com/golang/protobuf/proto" "github.com/pingcap/errors" backuppb "github.com/pingcap/kvproto/pkg/brpb" + "github.com/pingcap/log" berrors "github.com/pingcap/tidb/br/pkg/errors" + "github.com/pingcap/tidb/br/pkg/redact" "github.com/pingcap/tidb/kv" clientv3 "go.etcd.io/etcd/client/v3" + "go.uber.org/zap" ) type EventType int @@ -181,11 +185,43 @@ func (t AdvancerExt) Begin(ctx context.Context, ch chan<- TaskEvent) error { return nil } +func (t AdvancerExt) GetGlobalCheckpointForTask(ctx context.Context, taskName string) (uint64, error) { + key := GlobalCheckpointOf(taskName) + resp, err := t.KV.Get(ctx, key) + if err != nil { + return 0, err + } + + if len(resp.Kvs) == 0 { + return 0, nil + } + + firstKV := resp.Kvs[0] + value := firstKV.Value + if len(value) != 8 { + return 0, errors.Annotatef(berrors.ErrPiTRMalformedMetadata, + "the global checkpoint isn't 64bits (it is %d bytes, value = %s)", + len(value), + redact.Key(value)) + } + + return binary.BigEndian.Uint64(value), nil +} + func (t AdvancerExt) UploadV3GlobalCheckpointForTask(ctx context.Context, taskName string, checkpoint uint64) error { key := GlobalCheckpointOf(taskName) value := string(encodeUint64(checkpoint)) - _, err := t.KV.Put(ctx, key, value) + oldValue, err := t.GetGlobalCheckpointForTask(ctx, taskName) + if err != nil { + return err + } + + if checkpoint < oldValue { + log.Warn("[log backup advancer] skipping upload global checkpoint", zap.Uint64("old", oldValue), zap.Uint64("new", checkpoint)) + return nil + } + _, err = t.KV.Put(ctx, key, value) if err != nil { return err } diff --git a/br/pkg/streamhelper/advancer_daemon.go b/br/pkg/streamhelper/advancer_daemon.go index 263d3a761b518..10f43e105ccbe 100644 --- a/br/pkg/streamhelper/advancer_daemon.go +++ b/br/pkg/streamhelper/advancer_daemon.go @@ -30,6 +30,7 @@ func (c *CheckpointAdvancer) OnTick(ctx context.Context) (err error) { func (c *CheckpointAdvancer) OnStart(ctx context.Context) { metrics.AdvancerOwner.Set(1.0) c.StartTaskListener(ctx) + c.spawnSubscriptionHandler(ctx) go func() { <-ctx.Done() c.onStop() @@ -43,6 +44,7 @@ func (c *CheckpointAdvancer) Name() string { func (c *CheckpointAdvancer) onStop() { metrics.AdvancerOwner.Set(0.0) + c.stopSubscriber() } func OwnerManagerForLogBackup(ctx context.Context, etcdCli *clientv3.Client) owner.Manager { diff --git a/br/pkg/streamhelper/advancer_env.go b/br/pkg/streamhelper/advancer_env.go index 181d8933449d4..cf27fda7d5c5b 100644 --- a/br/pkg/streamhelper/advancer_env.go +++ b/br/pkg/streamhelper/advancer_env.go @@ -9,6 +9,7 @@ import ( logbackup "github.com/pingcap/kvproto/pkg/logbackuppb" "github.com/pingcap/tidb/br/pkg/utils" "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/util/engine" pd "github.com/tikv/pd/client" clientv3 "go.etcd.io/etcd/client/v3" "google.golang.org/grpc" @@ -18,7 +19,7 @@ import ( // Env is the interface required by the advancer. type Env interface { // The region scanner provides the region information. - RegionScanner + TiKVClusterMeta // LogBackupService connects to the TiKV, so we can collect the region checkpoints. LogBackupService // StreamMeta connects to the metadata service (normally PD). @@ -48,6 +49,23 @@ func (c PDRegionScanner) RegionScan(ctx context.Context, key []byte, endKey []by return rls, nil } +func (c PDRegionScanner) Stores(ctx context.Context) ([]Store, error) { + res, err := c.Client.GetAllStores(ctx, pd.WithExcludeTombstone()) + if err != nil { + return nil, err + } + r := make([]Store, 0, len(res)) + for _, re := range res { + if !engine.IsTiFlash(re) { + r = append(r, Store{ + BootAt: uint64(re.StartTimestamp), + ID: re.GetId(), + }) + } + } + return r, nil +} + // clusterEnv is the environment for running in the real cluster. type clusterEnv struct { clis *utils.StoreManager diff --git a/br/pkg/streamhelper/advancer_test.go b/br/pkg/streamhelper/advancer_test.go index aeaadf820af7a..7dd4c71d35b9c 100644 --- a/br/pkg/streamhelper/advancer_test.go +++ b/br/pkg/streamhelper/advancer_test.go @@ -9,6 +9,8 @@ import ( "testing" "time" + "github.com/pingcap/errors" + logbackup "github.com/pingcap/kvproto/pkg/logbackuppb" "github.com/pingcap/log" "github.com/pingcap/tidb/br/pkg/streamhelper" "github.com/pingcap/tidb/br/pkg/streamhelper/config" @@ -51,9 +53,6 @@ func TestTick(t *testing.T) { env := &testEnv{fakeCluster: c, testCtx: t} adv := streamhelper.NewCheckpointAdvancer(env) adv.StartTaskListener(ctx) - adv.UpdateConfigWith(func(cac *config.Config) { - cac.FullScanTick = 0 - }) require.NoError(t, adv.OnTick(ctx)) for i := 0; i < 5; i++ { cp := c.advanceCheckpoints() @@ -76,9 +75,6 @@ func TestWithFailure(t *testing.T) { env := &testEnv{fakeCluster: c, testCtx: t} adv := streamhelper.NewCheckpointAdvancer(env) adv.StartTaskListener(ctx) - adv.UpdateConfigWith(func(cac *config.Config) { - cac.FullScanTick = 0 - }) require.NoError(t, adv.OnTick(ctx)) cp := c.advanceCheckpoints() @@ -226,3 +222,36 @@ func TestTaskRangesWithSplit(t *testing.T) { shouldFinishInTime(t, 10*time.Second, "second advancing", func() { require.NoError(t, adv.OnTick(ctx)) }) require.Greater(t, env.getCheckpoint(), fstCheckpoint) } + +func TestBlocked(t *testing.T) { + log.SetLevel(zapcore.DebugLevel) + c := createFakeCluster(t, 4, true) + ctx := context.Background() + req := require.New(t) + c.splitAndScatter("0012", "0034", "0048") + marked := false + for _, s := range c.stores { + s.clientMu.Lock() + s.onGetRegionCheckpoint = func(glftrr *logbackup.GetLastFlushTSOfRegionRequest) error { + // blocking the thread. + // this may happen when TiKV goes down or too busy. + <-(chan struct{})(nil) + return nil + } + s.clientMu.Unlock() + marked = true + } + req.True(marked, "failed to mark the cluster: ") + env := &testEnv{fakeCluster: c, testCtx: t} + adv := streamhelper.NewCheckpointAdvancer(env) + adv.StartTaskListener(ctx) + adv.UpdateConfigWith(func(c *config.Config) { + // ... So the tick timeout would be 100ms + c.TickDuration = 10 * time.Millisecond + }) + var err error + shouldFinishInTime(t, time.Second, "ticking", func() { + err = adv.OnTick(ctx) + }) + req.ErrorIs(errors.Cause(err), context.DeadlineExceeded) +} diff --git a/br/pkg/streamhelper/basic_lib_for_test.go b/br/pkg/streamhelper/basic_lib_for_test.go index 9e438c32f0f1f..1dff77dd72864 100644 --- a/br/pkg/streamhelper/basic_lib_for_test.go +++ b/br/pkg/streamhelper/basic_lib_for_test.go @@ -7,6 +7,7 @@ import ( "context" "encoding/hex" "fmt" + "io" "math" "math/rand" "sort" @@ -21,10 +22,15 @@ import ( "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" "github.com/pingcap/tidb/br/pkg/streamhelper" + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" "github.com/pingcap/tidb/br/pkg/utils" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/util/codec" "go.uber.org/zap" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" ) type flushSimulator struct { @@ -58,7 +64,7 @@ func (c *flushSimulator) fork() flushSimulator { } type region struct { - rng kv.KeyRange + rng spans.Span leader uint64 epoch uint64 id uint64 @@ -70,6 +76,12 @@ type region struct { type fakeStore struct { id uint64 regions map[uint64]*region + + clientMu sync.Mutex + supportsSub bool + bootstrapAt uint64 + fsub func(logbackup.SubscribeFlushEventResponse) + onGetRegionCheckpoint func(*logbackup.GetLastFlushTSOfRegionRequest) error } type fakeCluster struct { @@ -82,16 +94,6 @@ type fakeCluster struct { onGetClient func(uint64) error } -func overlaps(a, b kv.KeyRange) bool { - if len(b.EndKey) == 0 { - return len(a.EndKey) == 0 || bytes.Compare(a.EndKey, b.StartKey) > 0 - } - if len(a.EndKey) == 0 { - return len(b.EndKey) == 0 || bytes.Compare(b.EndKey, a.StartKey) > 0 - } - return bytes.Compare(a.StartKey, b.EndKey) < 0 && bytes.Compare(b.StartKey, a.EndKey) < 0 -} - func (r *region) splitAt(newID uint64, k string) *region { newRegion := ®ion{ rng: kv.KeyRange{StartKey: []byte(k), EndKey: r.rng.EndKey}, @@ -111,7 +113,84 @@ func (r *region) flush() { r.fsim.flushedEpoch.Store(r.epoch) } +type trivialFlushStream struct { + c <-chan logbackup.SubscribeFlushEventResponse + cx context.Context +} + +func (t trivialFlushStream) Recv() (*logbackup.SubscribeFlushEventResponse, error) { + select { + case item, ok := <-t.c: + if !ok { + return nil, io.EOF + } + return &item, nil + case <-t.cx.Done(): + select { + case item, ok := <-t.c: + if !ok { + return nil, io.EOF + } + return &item, nil + default: + } + return nil, status.Error(codes.Canceled, t.cx.Err().Error()) + } +} + +func (t trivialFlushStream) Header() (metadata.MD, error) { + return make(metadata.MD), nil +} + +func (t trivialFlushStream) Trailer() metadata.MD { + return make(metadata.MD) +} + +func (t trivialFlushStream) CloseSend() error { + return nil +} + +func (t trivialFlushStream) Context() context.Context { + return t.cx +} + +func (t trivialFlushStream) SendMsg(m interface{}) error { + return nil +} + +func (t trivialFlushStream) RecvMsg(m interface{}) error { + return nil +} + +func (f *fakeStore) SubscribeFlushEvent(ctx context.Context, in *logbackup.SubscribeFlushEventRequest, opts ...grpc.CallOption) (logbackup.LogBackup_SubscribeFlushEventClient, error) { + f.clientMu.Lock() + defer f.clientMu.Unlock() + if !f.supportsSub { + return nil, status.Error(codes.Unimplemented, "meow?") + } + + ch := make(chan logbackup.SubscribeFlushEventResponse, 1024) + f.fsub = func(glftrr logbackup.SubscribeFlushEventResponse) { + ch <- glftrr + } + return trivialFlushStream{c: ch, cx: ctx}, nil +} + +func (f *fakeStore) SetSupportFlushSub(b bool) { + f.clientMu.Lock() + defer f.clientMu.Unlock() + + f.bootstrapAt += 1 + f.supportsSub = b +} + func (f *fakeStore) GetLastFlushTSOfRegion(ctx context.Context, in *logbackup.GetLastFlushTSOfRegionRequest, opts ...grpc.CallOption) (*logbackup.GetLastFlushTSOfRegionResponse, error) { + if f.onGetRegionCheckpoint != nil { + err := f.onGetRegionCheckpoint(in) + if err != nil { + return nil, err + } + } resp := &logbackup.GetLastFlushTSOfRegionResponse{ Checkpoints: []*logbackup.RegionCheckpoint{}, } @@ -174,7 +253,7 @@ func (f *fakeCluster) RegionScan(ctx context.Context, key []byte, endKey []byte, result := make([]streamhelper.RegionWithLeader, 0, limit) for _, region := range f.regions { - if overlaps(kv.KeyRange{StartKey: key, EndKey: endKey}, region.rng) && len(result) < limit { + if spans.Overlaps(kv.KeyRange{StartKey: key, EndKey: endKey}, region.rng) && len(result) < limit { regionInfo := streamhelper.RegionWithLeader{ Region: &metapb.Region{ Id: region.id, @@ -210,6 +289,15 @@ func (f *fakeCluster) GetLogBackupClient(ctx context.Context, storeID uint64) (l return cli, nil } +// Stores returns the store metadata from the cluster. +func (f *fakeCluster) Stores(ctx context.Context) ([]streamhelper.Store, error) { + r := make([]streamhelper.Store, 0, len(f.stores)) + for id, s := range f.stores { + r = append(r, streamhelper.Store{ID: id, BootAt: s.bootstrapAt}) + } + return r, nil +} + func (f *fakeCluster) findRegionById(rid uint64) *region { for _, r := range f.regions { if r.id == rid { @@ -304,6 +392,34 @@ func (f *fakeCluster) splitAndScatter(keys ...string) { } } +// Remove a store. +// Note: this won't add new peer for regions from the store. +func (f *fakeCluster) removeStore(id uint64) { + f.mu.Lock() + defer f.mu.Unlock() + + s := f.stores[id] + for _, r := range s.regions { + if r.leader == id { + f.updateRegion(r.id, func(r *region) { + ps := f.findPeers(r.id) + for _, p := range ps { + if p != r.leader { + log.Info("remove store: transforming leader", + zap.Uint64("region", r.id), + zap.Uint64("new-leader", p), + zap.Uint64("old-leader", r.leader)) + r.leader = p + break + } + } + }) + } + } + + delete(f.stores, id) +} + // a stub once in the future we want to make different stores hold different region instances. func (f *fakeCluster) updateRegion(rid uint64, mut func(*region)) { r := f.findRegionById(rid) @@ -362,7 +478,7 @@ func createFakeCluster(t *testing.T, n int, simEnabled bool) *fakeCluster { } func (r *region) String() string { - return fmt.Sprintf("%d(%d):[%s,%s);%dL%dF%d", + return fmt.Sprintf("%d(%d):[%s, %s);%dL%dF%d", r.id, r.epoch, hex.EncodeToString(r.rng.StartKey), @@ -382,14 +498,24 @@ func (f *fakeStore) String() string { } func (f *fakeCluster) flushAll() { - for _, r := range f.regions { + for _, r := range f.stores { r.flush() } } func (f *fakeCluster) flushAllExcept(keys ...string) { + for _, s := range f.stores { + s.flushExcept(keys...) + } +} + +func (f *fakeStore) flushExcept(keys ...string) { + resp := make([]*logbackup.FlushEvent, 0, len(f.regions)) outer: for _, r := range f.regions { + if r.leader != f.id { + continue + } // Note: can we make it faster? for _, key := range keys { if utils.CompareBytesExt(r.rng.StartKey, false, []byte(key), false) <= 0 && @@ -397,16 +523,25 @@ outer: continue outer } } - r.flush() - } -} - -func (f *fakeStore) flush() { - for _, r := range f.regions { if r.leader == f.id { r.flush() + resp = append(resp, &logbackup.FlushEvent{ + StartKey: codec.EncodeBytes(nil, r.rng.StartKey), + EndKey: codec.EncodeBytes(nil, r.rng.EndKey), + Checkpoint: r.checkpoint.Load(), + }) } } + + if f.fsub != nil { + f.fsub(logbackup.SubscribeFlushEventResponse{ + Events: resp, + }) + } +} + +func (f *fakeStore) flush() { + f.flushExcept() } func (f *fakeCluster) String() string { diff --git a/br/pkg/streamhelper/client.go b/br/pkg/streamhelper/client.go index 2e27bf97a399e..3a004fc80d3e1 100644 --- a/br/pkg/streamhelper/client.go +++ b/br/pkg/streamhelper/client.go @@ -163,6 +163,8 @@ func (c *MetaDataClient) DeleteTask(ctx context.Context, taskName string) error clientv3.OpDelete(CheckPointsOf(taskName), clientv3.WithPrefix()), clientv3.OpDelete(Pause(taskName)), clientv3.OpDelete(LastErrorPrefixOf(taskName), clientv3.WithPrefix()), + clientv3.OpDelete(GlobalCheckpointOf(taskName)), + clientv3.OpDelete(StorageCheckpointOf(taskName), clientv3.WithPrefix()), ). Commit() if err != nil { @@ -372,28 +374,6 @@ func (t *Task) GetStorageCheckpoint(ctx context.Context) (uint64, error) { return storageCheckpoint, nil } -// MinNextBackupTS query the all next backup ts of a store, returning the minimal next backup ts of the store. -func (t *Task) MinNextBackupTS(ctx context.Context, store uint64) (uint64, error) { - key := CheckPointOf(t.Info.Name, store) - resp, err := t.cli.KV.Get(ctx, key) - if err != nil { - return 0, errors.Annotatef(err, "failed to get checkpoints of %s", t.Info.Name) - } - if resp.Count != 1 { - return 0, nil - } - kv := resp.Kvs[0] - if len(kv.Value) != 8 { - return 0, errors.Annotatef(berrors.ErrPiTRMalformedMetadata, - "the next backup ts of store %d isn't 64bits (it is %d bytes, value = %s)", - store, - len(kv.Value), - redact.Key(kv.Value)) - } - nextBackupTS := binary.BigEndian.Uint64(kv.Value) - return nextBackupTS, nil -} - // GetGlobalCheckPointTS gets the global checkpoint timestamp according to log task. func (t *Task) GetGlobalCheckPointTS(ctx context.Context) (uint64, error) { checkPointMap, err := t.NextBackupTSList(ctx) @@ -404,23 +384,22 @@ func (t *Task) GetGlobalCheckPointTS(ctx context.Context) (uint64, error) { initialized := false checkpoint := t.Info.StartTs for _, cp := range checkPointMap { - if !initialized || cp.TS < checkpoint { + if cp.Type() == CheckpointTypeGlobal { + return cp.TS, nil + } + + if cp.Type() == CheckpointTypeStore && (!initialized || cp.TS < checkpoint) { initialized = true checkpoint = cp.TS } } - return checkpoint, nil -} - -// Step forwards the progress (next_backup_ts) of some region. -// The task should be done by TiKV. This function should only be used for test cases. -func (t *Task) Step(ctx context.Context, store uint64, ts uint64) error { - _, err := t.cli.KV.Put(ctx, CheckPointOf(t.Info.Name, store), string(encodeUint64(ts))) + ts, err := t.GetStorageCheckpoint(ctx) if err != nil { - return errors.Annotatef(err, "failed forward the progress of %s to %d", t.Info.Name, ts) + return 0, errors.Trace(err) } - return nil + + return mathutil.Max(checkpoint, ts), nil } func (t *Task) UploadGlobalCheckpoint(ctx context.Context, ts uint64) error { diff --git a/br/pkg/streamhelper/collector.go b/br/pkg/streamhelper/collector.go index ad53acb03b577..bc9285e05e8a8 100644 --- a/br/pkg/streamhelper/collector.go +++ b/br/pkg/streamhelper/collector.go @@ -266,13 +266,13 @@ func NewClusterCollector(ctx context.Context, srv LogBackupService) *clusterColl } } -// setOnSuccessHook sets the hook when getting checkpoint of some region. -func (c *clusterCollector) setOnSuccessHook(hook onSuccessHook) { +// SetOnSuccessHook sets the hook when getting checkpoint of some region. +func (c *clusterCollector) SetOnSuccessHook(hook onSuccessHook) { c.onSuccess = hook } -// collectRegion adds a region to the collector. -func (c *clusterCollector) collectRegion(r RegionWithLeader) error { +// CollectRegion adds a region to the collector. +func (c *clusterCollector) CollectRegion(r RegionWithLeader) error { c.mu.Lock() defer c.mu.Unlock() if c.masterCtx.Err() != nil { diff --git a/br/pkg/streamhelper/config/advancer_conf.go b/br/pkg/streamhelper/config/advancer_conf.go index 548ea2472b172..1440a81f932f9 100644 --- a/br/pkg/streamhelper/config/advancer_conf.go +++ b/br/pkg/streamhelper/config/advancer_conf.go @@ -9,13 +9,14 @@ import ( ) const ( - flagBackoffTime = "backoff-time" - flagTickInterval = "tick-interval" - flagFullScanDiffTick = "full-scan-tick" - flagAdvancingByCache = "advancing-by-cache" + flagBackoffTime = "backoff-time" + flagTickInterval = "tick-interval" + flagFullScanDiffTick = "full-scan-tick" + flagAdvancingByCache = "advancing-by-cache" + flagTryAdvanceThreshold = "try-advance-threshold" DefaultConsistencyCheckTick = 5 - DefaultTryAdvanceThreshold = 108 * time.Second + DefaultTryAdvanceThreshold = 4 * time.Minute DefaultBackOffTime = 5 * time.Second DefaultTickInterval = 12 * time.Second DefaultFullScanTick = 4 @@ -31,27 +32,21 @@ type Config struct { BackoffTime time.Duration `toml:"backoff-time" json:"backoff-time"` // The gap between calculating checkpoints. TickDuration time.Duration `toml:"tick-interval" json:"tick-interval"` - // The backoff time of full scan. - FullScanTick int `toml:"full-scan-tick" json:"full-scan-tick"` - - // Whether enable the optimization -- use a cached heap to advancing the global checkpoint. - // This may reduce the gap of checkpoint but may cost more CPU. - AdvancingByCache bool `toml:"advancing-by-cache" json:"advancing-by-cache"` + // The threshold for polling TiKV for checkpoint of some range. + TryAdvanceThreshold time.Duration `toml:"try-advance-threshold" json:"try-advance-threshold"` } func DefineFlagsForCheckpointAdvancerConfig(f *pflag.FlagSet) { f.Duration(flagBackoffTime, DefaultBackOffTime, "The gap between two retries.") f.Duration(flagTickInterval, DefaultTickInterval, "From how long we trigger the tick (advancing the checkpoint).") - f.Bool(flagAdvancingByCache, DefaultAdvanceByCache, "Whether enable the optimization -- use a cached heap to advancing the global checkpoint.") - f.Int(flagFullScanDiffTick, DefaultFullScanTick, "The backoff of full scan.") + f.Duration(flagTryAdvanceThreshold, DefaultTryAdvanceThreshold, "If the checkpoint lag is greater than how long, we would try to poll TiKV for checkpoints.") } func Default() Config { return Config{ - BackoffTime: DefaultBackOffTime, - TickDuration: DefaultTickInterval, - FullScanTick: DefaultFullScanTick, - AdvancingByCache: DefaultAdvanceByCache, + BackoffTime: DefaultBackOffTime, + TickDuration: DefaultTickInterval, + TryAdvanceThreshold: DefaultTryAdvanceThreshold, } } @@ -65,13 +60,34 @@ func (conf *Config) GetFromFlags(f *pflag.FlagSet) error { if err != nil { return err } - conf.FullScanTick, err = f.GetInt(flagFullScanDiffTick) - if err != nil { - return err - } - conf.AdvancingByCache, err = f.GetBool(flagAdvancingByCache) + conf.TryAdvanceThreshold, err = f.GetDuration(flagTryAdvanceThreshold) if err != nil { return err } return nil } + +// GetDefaultStartPollThreshold returns the threshold of begin polling the checkpoint +// in the normal condition (the subscribe manager is available.) +func (conf Config) GetDefaultStartPollThreshold() time.Duration { + return conf.TryAdvanceThreshold +} + +// GetSubscriberErrorStartPollThreshold returns the threshold of begin polling the checkpoint +// when the subscriber meets error. +func (conf Config) GetSubscriberErrorStartPollThreshold() time.Duration { + // 0.45x of the origin threshold. + // The origin threshold is 0.8x the target RPO, + // and the default flush interval is about 0.5x the target RPO. + // So the relationship between the RPO and the threshold is: + // When subscription is all available, it is 1.7x of the flush interval (which allow us to save in abnormal condition). + // When some of subscriptions are not available, it is 0.75x of the flush interval. + // NOTE: can we make subscription better and give up the poll model? + return conf.TryAdvanceThreshold * 9 / 20 +} + +// TickTimeout returns the max duration for each tick. +func (conf Config) TickTimeout() time.Duration { + // If a tick blocks longer than the interval of ticking, we may need to break it and retry. + return conf.TickDuration +} diff --git a/br/pkg/streamhelper/flush_subscriber.go b/br/pkg/streamhelper/flush_subscriber.go new file mode 100644 index 0000000000000..70cd4d8e4501d --- /dev/null +++ b/br/pkg/streamhelper/flush_subscriber.go @@ -0,0 +1,329 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package streamhelper + +import ( + "context" + "io" + "strconv" + "sync" + "time" + + "github.com/google/uuid" + "github.com/pingcap/errors" + logbackup "github.com/pingcap/kvproto/pkg/logbackuppb" + "github.com/pingcap/log" + "github.com/pingcap/tidb/br/pkg/logutil" + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/util/codec" + "go.uber.org/multierr" + "go.uber.org/zap" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// FlushSubscriber maintains the state of subscribing to the cluster. +type FlushSubscriber struct { + dialer LogBackupService + cluster TiKVClusterMeta + + // Current connections. + subscriptions map[uint64]*subscription + // The output channel. + eventsTunnel chan spans.Valued + // The background context for subscribes. + masterCtx context.Context +} + +// SubscriberConfig is a config which cloud be applied into the subscriber. +type SubscriberConfig func(*FlushSubscriber) + +// WithMasterContext sets the "master context" for the subscriber, +// that context would be the "background" context for every subtasks created by the subscription manager. +func WithMasterContext(ctx context.Context) SubscriberConfig { + return func(fs *FlushSubscriber) { fs.masterCtx = ctx } +} + +// NewSubscriber creates a new subscriber via the environment and optional configs. +func NewSubscriber(dialer LogBackupService, cluster TiKVClusterMeta, config ...SubscriberConfig) *FlushSubscriber { + subs := &FlushSubscriber{ + dialer: dialer, + cluster: cluster, + + subscriptions: map[uint64]*subscription{}, + eventsTunnel: make(chan spans.Valued, 1024), + masterCtx: context.Background(), + } + + for _, c := range config { + c(subs) + } + + return subs +} + +// UpdateStoreTopology fetches the current store topology and try to adapt the subscription state with it. +func (f *FlushSubscriber) UpdateStoreTopology(ctx context.Context) error { + stores, err := f.cluster.Stores(ctx) + if err != nil { + return errors.Annotate(err, "failed to get store list") + } + + storeSet := map[uint64]struct{}{} + for _, store := range stores { + sub, ok := f.subscriptions[store.ID] + if !ok { + f.addSubscription(ctx, store) + f.subscriptions[store.ID].connect(f.masterCtx, f.dialer) + } else if sub.storeBootAt != store.BootAt { + sub.storeBootAt = store.BootAt + sub.connect(f.masterCtx, f.dialer) + } + storeSet[store.ID] = struct{}{} + } + + for id := range f.subscriptions { + _, ok := storeSet[id] + if !ok { + f.removeSubscription(id) + } + } + return nil +} + +// Clear clears all the subscriptions. +func (f *FlushSubscriber) Clear() { + log.Info("[log backup flush subscriber] Clearing.") + for id := range f.subscriptions { + f.removeSubscription(id) + } +} + +// Drop terminates the lifetime of the subscriber. +// This subscriber would be no more usable. +func (f *FlushSubscriber) Drop() { + f.Clear() + close(f.eventsTunnel) +} + +// HandleErrors execute the handlers over all pending errors. +// Note that the handler may cannot handle the pending errors, at that time, +// you can fetch the errors via `PendingErrors` call. +func (f *FlushSubscriber) HandleErrors(ctx context.Context) { + for id, sub := range f.subscriptions { + err := sub.loadError() + if err != nil { + retry := f.canBeRetried(err) + log.Warn("[log backup flush subscriber] Meet error.", logutil.ShortError(err), zap.Bool("can-retry?", retry), zap.Uint64("store", id)) + if retry { + sub.connect(f.masterCtx, f.dialer) + } + } + } +} + +// Events returns the output channel of the events. +func (f *FlushSubscriber) Events() <-chan spans.Valued { + return f.eventsTunnel +} + +type eventStream = logbackup.LogBackup_SubscribeFlushEventClient + +type joinHandle <-chan struct{} + +func (jh joinHandle) WaitTimeOut(dur time.Duration) { + var t <-chan time.Time + if dur > 0 { + t = time.After(dur) + } + select { + case <-jh: + case <-t: + log.Warn("join handle timed out.") + } +} + +func spawnJoinable(f func()) joinHandle { + c := make(chan struct{}) + go func() { + defer close(c) + f() + }() + return c +} + +// subscription is the state of subscription of one store. +// initially, it is IDLE, where cancel == nil. +// once `connect` called, it goto CONNECTED, where cancel != nil and err == nil. +// once some error (both foreground or background) happens, it goto ERROR, where err != nil. +type subscription struct { + // the handle to cancel the worker goroutine. + cancel context.CancelFunc + // the handle to wait until the worker goroutine exits. + background joinHandle + errMu sync.Mutex + err error + + // Immutable state. + storeID uint64 + // We record start bootstrap time and once a store restarts + // we need to try reconnect even there is a error cannot be retry. + storeBootAt uint64 + output chan<- spans.Valued +} + +func (s *subscription) emitError(err error) { + s.errMu.Lock() + defer s.errMu.Unlock() + + s.err = err +} + +func (s *subscription) loadError() error { + s.errMu.Lock() + defer s.errMu.Unlock() + + return s.err +} + +func (s *subscription) clearError() { + s.errMu.Lock() + defer s.errMu.Unlock() + + s.err = nil +} + +func newSubscription(toStore Store, output chan<- spans.Valued) *subscription { + return &subscription{ + storeID: toStore.ID, + storeBootAt: toStore.BootAt, + output: output, + } +} + +func (s *subscription) connect(ctx context.Context, dialer LogBackupService) { + err := s.doConnect(ctx, dialer) + if err != nil { + s.emitError(err) + } +} + +func (s *subscription) doConnect(ctx context.Context, dialer LogBackupService) error { + log.Info("[log backup subscription manager] Adding subscription.", zap.Uint64("store", s.storeID), zap.Uint64("boot", s.storeBootAt)) + // We should shutdown the background task firstly. + // Once it yields some error during shuting down, the error won't be brought to next run. + s.close() + s.clearError() + + c, err := dialer.GetLogBackupClient(ctx, s.storeID) + if err != nil { + return errors.Annotate(err, "failed to get log backup client") + } + cx, cancel := context.WithCancel(ctx) + cli, err := c.SubscribeFlushEvent(cx, &logbackup.SubscribeFlushEventRequest{ + ClientId: uuid.NewString(), + }) + if err != nil { + cancel() + return errors.Annotate(err, "failed to subscribe events") + } + s.cancel = cancel + s.background = spawnJoinable(func() { s.listenOver(cli) }) + return nil +} + +func (s *subscription) close() { + if s.cancel != nil { + s.cancel() + s.background.WaitTimeOut(1 * time.Minute) + } + // HACK: don't close the internal channel here, + // because it is a ever-sharing channel. +} + +func (s *subscription) listenOver(cli eventStream) { + storeID := s.storeID + log.Info("[log backup flush subscriber] Listen starting.", zap.Uint64("store", storeID)) + for { + // Shall we use RecvMsg for better performance? + // Note that the spans.Full requires the input slice be immutable. + msg, err := cli.Recv() + if err != nil { + log.Info("[log backup flush subscriber] Listen stopped.", zap.Uint64("store", storeID), logutil.ShortError(err)) + if err == io.EOF || err == context.Canceled || status.Code(err) == codes.Canceled { + return + } + s.emitError(errors.Annotatef(err, "while receiving from store id %d", storeID)) + return + } + + for _, m := range msg.Events { + start, err := decodeKey(m.StartKey) + if err != nil { + log.Warn("start key not encoded, skipping", logutil.Key("event", m.StartKey), logutil.ShortError(err)) + continue + } + end, err := decodeKey(m.EndKey) + if err != nil { + log.Warn("end key not encoded, skipping", logutil.Key("event", m.EndKey), logutil.ShortError(err)) + continue + } + s.output <- spans.Valued{ + Key: spans.Span{ + StartKey: start, + EndKey: end, + }, + Value: m.Checkpoint, + } + } + metrics.RegionCheckpointSubscriptionEvent.WithLabelValues(strconv.Itoa(int(storeID))).Add(float64(len(msg.Events))) + } +} + +func (f *FlushSubscriber) addSubscription(ctx context.Context, toStore Store) { + f.subscriptions[toStore.ID] = newSubscription(toStore, f.eventsTunnel) +} + +func (f *FlushSubscriber) removeSubscription(toStore uint64) { + subs, ok := f.subscriptions[toStore] + if ok { + log.Info("[log backup subscription manager] Removing subscription.", zap.Uint64("store", toStore)) + subs.close() + delete(f.subscriptions, toStore) + } +} + +// decodeKey decodes the key from TiKV, because the region range is encoded in TiKV. +func decodeKey(key []byte) ([]byte, error) { + if len(key) == 0 { + return key, nil + } + // Ignore the timestamp... + _, data, err := codec.DecodeBytes(key, nil) + if err != nil { + return key, err + } + return data, err +} + +func (f *FlushSubscriber) canBeRetried(err error) bool { + for _, e := range multierr.Errors(errors.Cause(err)) { + s := status.Convert(e) + // Is there any other error cannot be retried? + if s.Code() == codes.Unimplemented { + return false + } + } + return true +} + +func (f *FlushSubscriber) PendingErrors() error { + var allErr error + for _, s := range f.subscriptions { + if err := s.loadError(); err != nil { + allErr = multierr.Append(allErr, errors.Annotatef(err, "store %d has error", s.storeID)) + } + } + return allErr +} diff --git a/br/pkg/streamhelper/integration_test.go b/br/pkg/streamhelper/integration_test.go index 8485bac19ce0f..81572f6b7890d 100644 --- a/br/pkg/streamhelper/integration_test.go +++ b/br/pkg/streamhelper/integration_test.go @@ -13,6 +13,7 @@ import ( "testing" "github.com/pingcap/errors" + backuppb "github.com/pingcap/kvproto/pkg/brpb" "github.com/pingcap/log" berrors "github.com/pingcap/tidb/br/pkg/errors" "github.com/pingcap/tidb/br/pkg/logutil" @@ -137,10 +138,11 @@ func TestIntegration(t *testing.T) { defer etcd.Server.Stop() metaCli := streamhelper.MetaDataClient{Client: cli} t.Run("TestBasic", func(t *testing.T) { testBasic(t, metaCli, etcd) }) - t.Run("TestForwardProgress", func(t *testing.T) { testForwardProgress(t, metaCli, etcd) }) - t.Run("testGetStorageCheckpoint", func(t *testing.T) { testGetStorageCheckpoint(t, metaCli, etcd) }) + t.Run("testGetStorageCheckpoint", func(t *testing.T) { testGetStorageCheckpoint(t, metaCli) }) + t.Run("testGetGlobalCheckPointTS", func(t *testing.T) { testGetGlobalCheckPointTS(t, metaCli) }) t.Run("TestStreamListening", func(t *testing.T) { testStreamListening(t, streamhelper.AdvancerExt{MetaDataClient: metaCli}) }) t.Run("TestStreamCheckpoint", func(t *testing.T) { testStreamCheckpoint(t, streamhelper.AdvancerExt{MetaDataClient: metaCli}) }) + t.Run("testStoptask", func(t *testing.T) { testStoptask(t, streamhelper.AdvancerExt{MetaDataClient: metaCli}) }) } func TestChecking(t *testing.T) { @@ -208,32 +210,44 @@ func testBasic(t *testing.T, metaCli streamhelper.MetaDataClient, etcd *embed.Et rangeIsEmpty(t, []byte(streamhelper.RangesOf(taskName)), etcd) } -func testForwardProgress(t *testing.T, metaCli streamhelper.MetaDataClient, etcd *embed.Etcd) { - ctx := context.Background() - taskName := "many_tables" - taskInfo := simpleTask(taskName, 65) - defer func() { - require.NoError(t, metaCli.DeleteTask(ctx, taskName)) - }() +func testGetStorageCheckpoint(t *testing.T, metaCli streamhelper.MetaDataClient) { + var ( + taskName = "my_task" + ctx = context.Background() + value = make([]byte, 8) + ) - require.NoError(t, metaCli.PutTask(ctx, taskInfo)) - task, err := metaCli.GetTask(ctx, taskName) - require.NoError(t, err) - require.NoError(t, task.Step(ctx, 1, 41)) - require.NoError(t, task.Step(ctx, 1, 42)) - require.NoError(t, task.Step(ctx, 2, 40)) - rs, err := task.Ranges(ctx) - require.NoError(t, err) - require.Equal(t, simpleRanges(65), rs) - store1Checkpoint, err := task.MinNextBackupTS(ctx, 1) + cases := []struct { + storeID string + storageCheckPoint uint64 + }{ + { + "1", + 10001, + }, { + "2", + 10002, + }, + } + for _, c := range cases { + key := path.Join(streamhelper.StorageCheckpointOf(taskName), c.storeID) + binary.BigEndian.PutUint64(value, c.storageCheckPoint) + _, err := metaCli.Put(ctx, key, string(value)) + require.NoError(t, err) + } + + taskInfo := simpleTask(taskName, 1) + task := streamhelper.NewTask(&metaCli, taskInfo.PBInfo) + ts, err := task.GetStorageCheckpoint(ctx) require.NoError(t, err) - require.Equal(t, store1Checkpoint, uint64(42)) - store2Checkpoint, err := task.MinNextBackupTS(ctx, 2) + require.Equal(t, uint64(10002), ts) + + ts, err = task.GetGlobalCheckPointTS(ctx) require.NoError(t, err) - require.Equal(t, store2Checkpoint, uint64(40)) + require.Equal(t, uint64(10002), ts) } -func testGetStorageCheckpoint(t *testing.T, metaCli streamhelper.MetaDataClient, etcd *embed.Etcd) { +func testGetGlobalCheckPointTS(t *testing.T, metaCli streamhelper.MetaDataClient) { var ( taskName = "my_task" ctx = context.Background() @@ -259,11 +273,12 @@ func testGetStorageCheckpoint(t *testing.T, metaCli streamhelper.MetaDataClient, require.NoError(t, err) } - taskInfo := simpleTask(taskName, 1) - task := streamhelper.NewTask(&metaCli, taskInfo.PBInfo) - ts, err := task.GetStorageCheckpoint(ctx) + task := streamhelper.NewTask(&metaCli, backuppb.StreamBackupTaskInfo{Name: taskName}) + task.UploadGlobalCheckpoint(ctx, 1003) + + globalTS, err := task.GetGlobalCheckPointTS(ctx) require.NoError(t, err) - require.Equal(t, uint64(10002), ts) + require.Equal(t, globalTS, uint64(1003)) } func testStreamListening(t *testing.T, metaCli streamhelper.AdvancerExt) { @@ -303,19 +318,86 @@ func testStreamCheckpoint(t *testing.T, metaCli streamhelper.AdvancerExt) { ctx := context.Background() task := "simple" req := require.New(t) - getCheckpoint := func() uint64 { - resp, err := metaCli.KV.Get(ctx, streamhelper.GlobalCheckpointOf(task)) - req.NoError(err) - if len(resp.Kvs) == 0 { - return 0 + + req.NoError(metaCli.UploadV3GlobalCheckpointForTask(ctx, task, 5)) + ts, err := metaCli.GetGlobalCheckpointForTask(ctx, task) + req.NoError(err) + req.EqualValues(5, ts) + req.NoError(metaCli.UploadV3GlobalCheckpointForTask(ctx, task, 18)) + ts, err = metaCli.GetGlobalCheckpointForTask(ctx, task) + req.NoError(err) + req.EqualValues(18, ts) + req.NoError(metaCli.UploadV3GlobalCheckpointForTask(ctx, task, 16)) + ts, err = metaCli.GetGlobalCheckpointForTask(ctx, task) + req.NoError(err) + req.EqualValues(18, ts) + req.NoError(metaCli.ClearV3GlobalCheckpointForTask(ctx, task)) + ts, err = metaCli.GetGlobalCheckpointForTask(ctx, task) + req.NoError(err) + req.EqualValues(0, ts) +} + +func testStoptask(t *testing.T, metaCli streamhelper.AdvancerExt) { + var ( + ctx = context.Background() + taskName = "stop_task" + req = require.New(t) + taskInfo = streamhelper.TaskInfo{ + PBInfo: backuppb.StreamBackupTaskInfo{ + Name: taskName, + StartTs: 0, + }, } - req.Len(resp.Kvs, 1) - return binary.BigEndian.Uint64(resp.Kvs[0].Value) - } - metaCli.UploadV3GlobalCheckpointForTask(ctx, task, 5) - req.EqualValues(5, getCheckpoint()) - metaCli.UploadV3GlobalCheckpointForTask(ctx, task, 18) - req.EqualValues(18, getCheckpoint()) - metaCli.ClearV3GlobalCheckpointForTask(ctx, task) - req.EqualValues(0, getCheckpoint()) + storeID = "5" + storageCheckpoint = make([]byte, 8) + ) + + // put task + req.NoError(metaCli.PutTask(ctx, taskInfo)) + t2, err := metaCli.GetTask(ctx, taskName) + req.NoError(err) + req.EqualValues(taskInfo.PBInfo.Name, t2.Info.Name) + + // upload global checkpoint + req.NoError(metaCli.UploadV3GlobalCheckpointForTask(ctx, taskName, 100)) + ts, err := metaCli.GetGlobalCheckpointForTask(ctx, taskName) + req.NoError(err) + req.EqualValues(100, ts) + + //upload storage checkpoint + key := path.Join(streamhelper.StorageCheckpointOf(taskName), storeID) + binary.BigEndian.PutUint64(storageCheckpoint, 90) + _, err = metaCli.Put(ctx, key, string(storageCheckpoint)) + req.NoError(err) + + task := streamhelper.NewTask(&metaCli.MetaDataClient, taskInfo.PBInfo) + ts, err = task.GetStorageCheckpoint(ctx) + req.NoError(err) + req.EqualValues(ts, 90) + + // pause task + req.NoError(metaCli.PauseTask(ctx, taskName)) + resp, err := metaCli.KV.Get(ctx, streamhelper.Pause(taskName)) + req.NoError(err) + req.EqualValues(1, len(resp.Kvs)) + + // stop task + err = metaCli.DeleteTask(ctx, taskName) + req.NoError(err) + + // check task and other meta infomations not existed + _, err = metaCli.GetTask(ctx, taskName) + req.Error(err) + + ts, err = task.GetStorageCheckpoint(ctx) + req.NoError(err) + req.EqualValues(ts, 0) + + ts, err = metaCli.GetGlobalCheckpointForTask(ctx, taskName) + req.NoError(err) + req.EqualValues(0, ts) + + resp, err = metaCli.KV.Get(ctx, streamhelper.Pause(taskName)) + req.NoError(err) + req.EqualValues(0, len(resp.Kvs)) } diff --git a/br/pkg/streamhelper/models.go b/br/pkg/streamhelper/models.go index 8aebfbaaf5aa9..7678e655d216a 100644 --- a/br/pkg/streamhelper/models.go +++ b/br/pkg/streamhelper/models.go @@ -61,12 +61,6 @@ func RangeKeyOf(name string, startKey []byte) string { return RangesOf(name) + string(startKey) } -func writeUint64(buf *bytes.Buffer, num uint64) { - items := [8]byte{} - binary.BigEndian.PutUint64(items[:], num) - buf.Write(items[:]) -} - func encodeUint64(num uint64) []byte { items := [8]byte{} binary.BigEndian.PutUint64(items[:], num) @@ -83,25 +77,17 @@ func CheckPointsOf(task string) string { } // GlobalCheckpointOf returns the path to the "global" checkpoint of some task. +// Normally it would be /checkpoint//central_globa. func GlobalCheckpointOf(task string) string { return path.Join(streamKeyPrefix, taskCheckpointPath, task, checkpointTypeGlobal) } // StorageCheckpointOf get the prefix path of the `storage checkpoint status` of a task. +// Normally it would be /storage-checkpoint/. func StorageCheckpointOf(task string) string { return path.Join(streamKeyPrefix, storageCheckPoint, task) } -// CheckpointOf returns the checkpoint prefix of some store. -// Normally it would be /checkpoint//. -func CheckPointOf(task string, store uint64) string { - buf := bytes.NewBuffer(nil) - buf.WriteString(strings.TrimSuffix(path.Join(streamKeyPrefix, taskCheckpointPath, task), "/")) - buf.WriteRune('/') - writeUint64(buf, store) - return buf.String() -} - // Pause returns the path for pausing the task. // Normally it would be /pause/. func Pause(task string) string { diff --git a/br/pkg/streamhelper/regioniter.go b/br/pkg/streamhelper/regioniter.go index 9dc75e38553fc..239c710db1ba4 100644 --- a/br/pkg/streamhelper/regioniter.go +++ b/br/pkg/streamhelper/regioniter.go @@ -28,14 +28,22 @@ type RegionWithLeader struct { Leader *metapb.Peer } -type RegionScanner interface { +type TiKVClusterMeta interface { // RegionScan gets a list of regions, starts from the region that contains key. // Limit limits the maximum number of regions returned. RegionScan(ctx context.Context, key, endKey []byte, limit int) ([]RegionWithLeader, error) + + // Stores returns the store metadata from the cluster. + Stores(ctx context.Context) ([]Store, error) +} + +type Store struct { + ID uint64 + BootAt uint64 } type RegionIter struct { - cli RegionScanner + cli TiKVClusterMeta startKey, endKey []byte currentStartKey []byte // When the endKey become "", we cannot check whether the scan is done by @@ -57,7 +65,7 @@ func (r *RegionIter) String() string { } // IterateRegion creates an iterater over the region range. -func IterateRegion(cli RegionScanner, startKey, endKey []byte) *RegionIter { +func IterateRegion(cli TiKVClusterMeta, startKey, endKey []byte) *RegionIter { return &RegionIter{ cli: cli, startKey: startKey, diff --git a/br/pkg/streamhelper/regioniter_test.go b/br/pkg/streamhelper/regioniter_test.go index 04ccc04da8a66..1c0d6a28ab0fe 100644 --- a/br/pkg/streamhelper/regioniter_test.go +++ b/br/pkg/streamhelper/regioniter_test.go @@ -13,8 +13,11 @@ import ( "github.com/pingcap/tidb/br/pkg/logutil" "github.com/pingcap/tidb/br/pkg/redact" "github.com/pingcap/tidb/br/pkg/streamhelper" + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" "github.com/pingcap/tidb/kv" "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type constantRegions []streamhelper.RegionWithLeader @@ -55,7 +58,7 @@ func (c constantRegions) String() string { func (c constantRegions) RegionScan(ctx context.Context, key []byte, endKey []byte, limit int) ([]streamhelper.RegionWithLeader, error) { result := make([]streamhelper.RegionWithLeader, 0, limit) for _, region := range c { - if overlaps(kv.KeyRange{StartKey: key, EndKey: endKey}, kv.KeyRange{StartKey: region.Region.StartKey, EndKey: region.Region.EndKey}) && len(result) < limit { + if spans.Overlaps(kv.KeyRange{StartKey: key, EndKey: endKey}, kv.KeyRange{StartKey: region.Region.StartKey, EndKey: region.Region.EndKey}) && len(result) < limit { result = append(result, region) } else if bytes.Compare(region.Region.StartKey, key) > 0 { break @@ -66,6 +69,11 @@ func (c constantRegions) RegionScan(ctx context.Context, key []byte, endKey []by return result, nil } +// Stores returns the store metadata from the cluster. +func (c constantRegions) Stores(ctx context.Context) ([]streamhelper.Store, error) { + return nil, status.Error(codes.Unimplemented, "Unsupported operation") +} + func makeSubrangeRegions(keys ...string) constantRegions { if len(keys) == 0 { return nil diff --git a/br/pkg/streamhelper/spans/BUILD.bazel b/br/pkg/streamhelper/spans/BUILD.bazel new file mode 100644 index 0000000000000..899f6f6ade6b1 --- /dev/null +++ b/br/pkg/streamhelper/spans/BUILD.bazel @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "spans", + srcs = [ + "sorted.go", + "utils.go", + "value_sorted.go", + ], + importpath = "github.com/pingcap/tidb/br/pkg/streamhelper/spans", + visibility = ["//visibility:public"], + deps = [ + "//br/pkg/logutil", + "//br/pkg/utils", + "//kv", + "@com_github_google_btree//:btree", + ], +) + +go_test( + name = "spans_test", + srcs = [ + "sorted_test.go", + "utils_test.go", + "value_sorted_test.go", + ], + deps = [ + ":spans", + "@com_github_stretchr_testify//require", + ], +) diff --git a/br/pkg/streamhelper/spans/sorted.go b/br/pkg/streamhelper/spans/sorted.go new file mode 100644 index 0000000000000..a15138bf8124c --- /dev/null +++ b/br/pkg/streamhelper/spans/sorted.go @@ -0,0 +1,186 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package spans + +import ( + "bytes" + "fmt" + + "github.com/google/btree" + "github.com/pingcap/tidb/br/pkg/logutil" + "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/kv" +) + +// Value is the value type of stored in the span tree. +type Value = uint64 + +// join finds the upper bound of two values. +func join(a, b Value) Value { + if a > b { + return a + } + return b +} + +// Span is the type of an adjacent sub key space. +type Span = kv.KeyRange + +// Valued is span binding to a value, which is the entry type of span tree. +type Valued struct { + Key Span + Value Value +} + +func (r Valued) String() string { + return fmt.Sprintf("(%s, %d)", logutil.StringifyRange(r.Key), r.Value) +} + +func (r Valued) Less(other btree.Item) bool { + return bytes.Compare(r.Key.StartKey, other.(Valued).Key.StartKey) < 0 +} + +// ValuedFull represents a set of valued ranges, which doesn't overlap and union of them all is the full key space. +type ValuedFull struct { + inner *btree.BTree +} + +// NewFullWith creates a set of a subset of spans. +func NewFullWith(initSpans []Span, init Value) *ValuedFull { + t := btree.New(16) + for _, r := range Collapse(len(initSpans), func(i int) Span { return initSpans[i] }) { + t.ReplaceOrInsert(Valued{Value: init, Key: r}) + } + return &ValuedFull{inner: t} +} + +// Merge merges a new interval into the span set. The value of overlapped +// part with other spans would be "merged" by the `join` function. +// An example: +/* +|___________________________________________________________________________| +^-----------------^-----------------^-----------------^---------------------^ +| c = 42 | c = 43 | c = 45 | c = 41 | + ^--------------------------^ + merge(| c = 44 |) +Would Give: +|___________________________________________________________________________| +^-----------------^----^------------^-------------^---^---------------------^ +| c = 42 | 43 | c = 44 | c = 45 | c = 41 | + |-------------| + Unchanged, because 44 < 45. +*/ +func (f *ValuedFull) Merge(val Valued) { + overlaps := make([]Valued, 0, 16) + f.overlapped(val.Key, &overlaps) + f.mergeWithOverlap(val, overlaps, nil) +} + +// Traverse traverses all ranges by order. +func (f *ValuedFull) Traverse(m func(Valued) bool) { + f.inner.Ascend(func(item btree.Item) bool { + return m(item.(Valued)) + }) +} + +func (f *ValuedFull) mergeWithOverlap(val Valued, overlapped []Valued, newItems *[]Valued) { + // There isn't any range overlaps with the input range, perhaps the input range is empty. + // do nothing for this case. + if len(overlapped) == 0 { + return + } + + for _, r := range overlapped { + f.inner.Delete(r) + // Assert All overlapped ranges are deleted. + } + + var ( + initialized = false + collected Valued + rightTrail *Valued + flushCollected = func() { + if initialized { + f.inner.ReplaceOrInsert(collected) + if newItems != nil { + *newItems = append(*newItems, collected) + } + } + } + emitToCollected = func(rng Valued, standalone bool) { + merged := rng.Value + if !standalone { + merged = join(val.Value, rng.Value) + } + if !initialized { + collected = rng + collected.Value = merged + initialized = true + return + } + if merged == collected.Value && utils.CompareBytesExt(collected.Key.EndKey, true, rng.Key.StartKey, false) == 0 { + collected.Key.EndKey = rng.Key.EndKey + } else { + flushCollected() + collected = Valued{ + Key: rng.Key, + Value: merged, + } + } + } + ) + + leftmost := overlapped[0] + if bytes.Compare(leftmost.Key.StartKey, val.Key.StartKey) < 0 { + emitToCollected(Valued{ + Key: Span{StartKey: leftmost.Key.StartKey, EndKey: val.Key.StartKey}, + Value: leftmost.Value, + }, true) + overlapped[0].Key.StartKey = val.Key.StartKey + } + + rightmost := overlapped[len(overlapped)-1] + if utils.CompareBytesExt(rightmost.Key.EndKey, true, val.Key.EndKey, true) > 0 { + rightTrail = &Valued{ + Key: Span{StartKey: val.Key.EndKey, EndKey: rightmost.Key.EndKey}, + Value: rightmost.Value, + } + overlapped[len(overlapped)-1].Key.EndKey = val.Key.EndKey + } + + for _, rng := range overlapped { + emitToCollected(rng, false) + } + + if rightTrail != nil { + emitToCollected(*rightTrail, true) + } + + flushCollected() +} + +// overlapped inserts the overlapped ranges of the span into the `result` slice. +func (f *ValuedFull) overlapped(k Span, result *[]Valued) { + var ( + first Span + hasFirst bool + ) + // Firstly, let's find whether there is a overlapped region with less start key. + f.inner.DescendLessOrEqual(Valued{Key: k}, func(item btree.Item) bool { + first = item.(Valued).Key + hasFirst = true + return false + }) + if !hasFirst || !Overlaps(first, k) { + first = k + } + + f.inner.AscendGreaterOrEqual(Valued{Key: first}, func(item btree.Item) bool { + r := item.(Valued) + if !Overlaps(r.Key, k) { + return false + } + *result = append(*result, r) + return true + }) +} diff --git a/br/pkg/streamhelper/spans/sorted_test.go b/br/pkg/streamhelper/spans/sorted_test.go new file mode 100644 index 0000000000000..c56c2236a6690 --- /dev/null +++ b/br/pkg/streamhelper/spans/sorted_test.go @@ -0,0 +1,211 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package spans_test + +import ( + "fmt" + "testing" + + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" + "github.com/stretchr/testify/require" +) + +func s(a, b string) spans.Span { + return spans.Span{ + StartKey: []byte(a), + EndKey: []byte(b), + } +} + +func kv(s spans.Span, v spans.Value) spans.Valued { + return spans.Valued{ + Key: s, + Value: v, + } +} + +func TestBasic(t *testing.T) { + type Case struct { + InputSequence []spans.Valued + Result []spans.Valued + } + + run := func(t *testing.T, c Case) { + full := spans.NewFullWith(spans.Full(), 0) + fmt.Println(t.Name()) + for _, i := range c.InputSequence { + full.Merge(i) + var result []spans.Valued + full.Traverse(func(v spans.Valued) bool { + result = append(result, v) + return true + }) + fmt.Printf("%s -> %s\n", i, result) + } + + var result []spans.Valued + full.Traverse(func(v spans.Valued) bool { + result = append(result, v) + return true + }) + + require.True(t, spans.ValuedSetEquals(result, c.Result), "%s\nvs\n%s", result, c.Result) + } + + cases := []Case{ + { + InputSequence: []spans.Valued{ + kv(s("0001", "0002"), 1), + kv(s("0002", "0003"), 2), + }, + Result: []spans.Valued{ + kv(s("", "0001"), 0), + kv(s("0001", "0002"), 1), + kv(s("0002", "0003"), 2), + kv(s("0003", ""), 0), + }, + }, + { + InputSequence: []spans.Valued{ + kv(s("0001", "0002"), 1), + kv(s("0002", "0003"), 2), + kv(s("0001", "0003"), 4), + }, + Result: []spans.Valued{ + kv(s("", "0001"), 0), + kv(s("0001", "0003"), 4), + kv(s("0003", ""), 0), + }, + }, + { + InputSequence: []spans.Valued{ + kv(s("0001", "0004"), 3), + kv(s("0004", "0008"), 5), + kv(s("0001", "0007"), 4), + kv(s("", "0002"), 2), + }, + Result: []spans.Valued{ + kv(s("", "0001"), 2), + kv(s("0001", "0004"), 4), + kv(s("0004", "0008"), 5), + kv(s("0008", ""), 0), + }, + }, + { + InputSequence: []spans.Valued{ + kv(s("0001", "0004"), 3), + kv(s("0004", "0008"), 5), + kv(s("0001", "0009"), 4), + }, + Result: []spans.Valued{ + kv(s("", "0001"), 0), + kv(s("0001", "0004"), 4), + kv(s("0004", "0008"), 5), + kv(s("0008", "0009"), 4), + kv(s("0009", ""), 0), + }, + }, + } + + for i, c := range cases { + t.Run(fmt.Sprintf("#%d", i+1), func(t *testing.T) { run(t, c) }) + } +} + +func TestSubRange(t *testing.T) { + type Case struct { + Range []spans.Span + InputSequence []spans.Valued + Result []spans.Valued + } + + run := func(t *testing.T, c Case) { + full := spans.NewFullWith(c.Range, 0) + fmt.Println(t.Name()) + for _, i := range c.InputSequence { + full.Merge(i) + var result []spans.Valued + full.Traverse(func(v spans.Valued) bool { + result = append(result, v) + return true + }) + fmt.Printf("%s -> %s\n", i, result) + } + + var result []spans.Valued + full.Traverse(func(v spans.Valued) bool { + result = append(result, v) + return true + }) + + require.True(t, spans.ValuedSetEquals(result, c.Result), "%s\nvs\n%s", result, c.Result) + } + + cases := []Case{ + { + Range: []spans.Span{s("0001", "0004"), s("0008", "")}, + InputSequence: []spans.Valued{ + kv(s("0001", "0007"), 42), + kv(s("0000", "0009"), 41), + kv(s("0002", "0005"), 43), + }, + Result: []spans.Valued{ + kv(s("0001", "0002"), 42), + kv(s("0002", "0004"), 43), + kv(s("0008", "0009"), 41), + kv(s("0009", ""), 0), + }, + }, + { + Range: []spans.Span{ + s("0001", "0004"), + s("0008", "")}, + InputSequence: []spans.Valued{kv(s("", ""), 42)}, + Result: []spans.Valued{ + kv(s("0001", "0004"), 42), + kv(s("0008", ""), 42), + }, + }, + { + Range: []spans.Span{ + s("0001", "0004"), + s("0005", "0008"), + }, + InputSequence: []spans.Valued{ + kv(s("0001", "0002"), 42), + kv(s("0002", "0008"), 43), + kv(s("0004", "0007"), 45), + kv(s("0000", "00015"), 48), + }, + Result: []spans.Valued{ + kv(s("0001", "00015"), 48), + kv(s("00015", "0002"), 42), + kv(s("0002", "0004"), 43), + kv(s("0005", "0007"), 45), + kv(s("0007", "0008"), 43), + }, + }, + { + Range: []spans.Span{ + s("0001", "0004"), + s("0005", "0008"), + }, + InputSequence: []spans.Valued{ + kv(s("0004", "0008"), 32), + kv(s("00041", "0007"), 33), + kv(s("0004", "00041"), 99999), + kv(s("0005", "0006"), 34), + }, + Result: []spans.Valued{ + kv(s("0001", "0004"), 0), + kv(s("0005", "0006"), 34), + kv(s("0006", "0007"), 33), + kv(s("0007", "0008"), 32), + }, + }, + } + + for i, c := range cases { + t.Run(fmt.Sprintf("#%d", i+1), func(t *testing.T) { run(t, c) }) + } +} diff --git a/br/pkg/streamhelper/spans/utils.go b/br/pkg/streamhelper/spans/utils.go new file mode 100644 index 0000000000000..621173983185d --- /dev/null +++ b/br/pkg/streamhelper/spans/utils.go @@ -0,0 +1,150 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package spans + +import ( + "bytes" + "fmt" + "math" + "sort" + + "github.com/pingcap/tidb/br/pkg/utils" +) + +// Overlaps checks whether two spans have overlapped part. +func Overlaps(a, b Span) bool { + if len(b.EndKey) == 0 { + return len(a.EndKey) == 0 || bytes.Compare(a.EndKey, b.StartKey) > 0 + } + if len(a.EndKey) == 0 { + return len(b.EndKey) == 0 || bytes.Compare(b.EndKey, a.StartKey) > 0 + } + return bytes.Compare(a.StartKey, b.EndKey) < 0 && bytes.Compare(b.StartKey, a.EndKey) < 0 +} + +func Debug(full *ValueSortedFull) { + var result []Valued + full.Traverse(func(v Valued) bool { + result = append(result, v) + return true + }) + var idx []Valued + full.TraverseValuesLessThan(math.MaxUint64, func(v Valued) bool { + idx = append(idx, v) + return true + }) + fmt.Printf("%s\n\tidx = %s\n", result, idx) +} + +// Collapse collapse ranges overlapping or adjacent. +// Example: +// Collapse({[1, 4], [2, 8], [3, 9]}) == {[1, 9]} +// Collapse({[1, 3], [4, 7], [2, 3]}) == {[1, 3], [4, 7]} +func Collapse(length int, getRange func(int) Span) []Span { + frs := make([]Span, 0, length) + for i := 0; i < length; i++ { + frs = append(frs, getRange(i)) + } + + sort.Slice(frs, func(i, j int) bool { + start := bytes.Compare(frs[i].StartKey, frs[j].StartKey) + if start != 0 { + return start < 0 + } + return utils.CompareBytesExt(frs[i].EndKey, true, frs[j].EndKey, true) < 0 + }) + + result := make([]Span, 0, len(frs)) + i := 0 + for i < len(frs) { + item := frs[i] + for { + i++ + if i >= len(frs) || (len(item.EndKey) != 0 && bytes.Compare(frs[i].StartKey, item.EndKey) > 0) { + break + } + if len(item.EndKey) != 0 && bytes.Compare(item.EndKey, frs[i].EndKey) < 0 || len(frs[i].EndKey) == 0 { + item.EndKey = frs[i].EndKey + } + } + result = append(result, item) + } + return result +} + +// Full returns a full span crossing the key space. +func Full() []Span { + return []Span{{}} +} + +func (x Valued) Equals(y Valued) bool { + return x.Value == y.Value && bytes.Equal(x.Key.StartKey, y.Key.StartKey) && bytes.Equal(x.Key.EndKey, y.Key.EndKey) +} + +func ValuedSetEquals(xs, ys []Valued) bool { + if len(xs) == 0 || len(ys) == 0 { + return len(ys) == len(xs) + } + + sort.Slice(xs, func(i, j int) bool { + start := bytes.Compare(xs[i].Key.StartKey, xs[j].Key.StartKey) + if start != 0 { + return start < 0 + } + return utils.CompareBytesExt(xs[i].Key.EndKey, true, xs[j].Key.EndKey, true) < 0 + }) + sort.Slice(ys, func(i, j int) bool { + start := bytes.Compare(ys[i].Key.StartKey, ys[j].Key.StartKey) + if start != 0 { + return start < 0 + } + return utils.CompareBytesExt(ys[i].Key.EndKey, true, ys[j].Key.EndKey, true) < 0 + }) + + xi := 0 + yi := 0 + + for { + if xi >= len(xs) || yi >= len(ys) { + return (xi >= len(xs)) == (yi >= len(ys)) + } + x := xs[xi] + y := ys[yi] + + if !bytes.Equal(x.Key.StartKey, y.Key.StartKey) { + return false + } + + for { + if xi >= len(xs) || yi >= len(ys) { + return (xi >= len(xs)) == (yi >= len(ys)) + } + x := xs[xi] + y := ys[yi] + + if x.Value != y.Value { + return false + } + + c := utils.CompareBytesExt(x.Key.EndKey, true, y.Key.EndKey, true) + if c == 0 { + xi++ + yi++ + break + } + if c < 0 { + xi++ + // If not adjacent key, return false directly. + if xi < len(xs) && utils.CompareBytesExt(x.Key.EndKey, true, xs[xi].Key.StartKey, false) != 0 { + return false + } + } + if c > 0 { + yi++ + if yi < len(ys) && utils.CompareBytesExt(y.Key.EndKey, true, ys[yi].Key.StartKey, false) != 0 { + return false + } + } + } + } +} diff --git a/br/pkg/streamhelper/spans/utils_test.go b/br/pkg/streamhelper/spans/utils_test.go new file mode 100644 index 0000000000000..48b8fc7f411a5 --- /dev/null +++ b/br/pkg/streamhelper/spans/utils_test.go @@ -0,0 +1,83 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package spans_test + +import ( + "fmt" + "testing" + + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" + "github.com/stretchr/testify/require" +) + +func TestValuedEquals(t *testing.T) { + s := func(start, end string, val spans.Value) spans.Valued { + return spans.Valued{ + Key: spans.Span{ + StartKey: []byte(start), + EndKey: []byte(end), + }, + Value: val, + } + } + type Case struct { + inputA []spans.Valued + inputB []spans.Valued + required bool + } + cases := []Case{ + { + inputA: []spans.Valued{s("0001", "0002", 3)}, + inputB: []spans.Valued{s("0001", "0003", 3)}, + required: false, + }, + { + inputA: []spans.Valued{s("0001", "0002", 3)}, + inputB: []spans.Valued{s("0001", "0002", 3)}, + required: true, + }, + { + inputA: []spans.Valued{s("0001", "0003", 3)}, + inputB: []spans.Valued{s("0001", "0002", 3), s("0002", "0003", 3)}, + required: true, + }, + { + inputA: []spans.Valued{s("0001", "0003", 4)}, + inputB: []spans.Valued{s("0001", "0002", 3), s("0002", "0003", 3)}, + required: false, + }, + { + inputA: []spans.Valued{s("0001", "0003", 3)}, + inputB: []spans.Valued{s("0001", "0002", 4), s("0002", "0003", 3)}, + required: false, + }, + { + inputA: []spans.Valued{s("0001", "0003", 3)}, + inputB: []spans.Valued{s("0001", "0002", 3), s("0002", "0004", 3)}, + required: false, + }, + { + inputA: []spans.Valued{s("", "0003", 3)}, + inputB: []spans.Valued{s("0001", "0002", 3), s("0002", "0003", 3)}, + required: false, + }, + { + inputA: []spans.Valued{s("0001", "", 1)}, + inputB: []spans.Valued{s("0001", "0003", 1), s("0004", "", 1)}, + required: false, + }, + { + inputA: []spans.Valued{s("0001", "0004", 1), s("0001", "0002", 1)}, + inputB: []spans.Valued{s("0001", "0002", 1), s("0001", "0004", 1)}, + required: true, + }, + } + run := func(t *testing.T, c Case) { + require.Equal(t, c.required, spans.ValuedSetEquals(c.inputA, c.inputB)) + require.Equal(t, c.required, spans.ValuedSetEquals(c.inputB, c.inputA)) + } + + for i, c := range cases { + t.Run(fmt.Sprintf("#%d", i+1), func(t *testing.T) { run(t, c) }) + } +} diff --git a/br/pkg/streamhelper/spans/value_sorted.go b/br/pkg/streamhelper/spans/value_sorted.go new file mode 100644 index 0000000000000..2fc1ff2cdbbbc --- /dev/null +++ b/br/pkg/streamhelper/spans/value_sorted.go @@ -0,0 +1,69 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package spans + +import "github.com/google/btree" + +type sortedByValueThenStartKey Valued + +func (s sortedByValueThenStartKey) Less(o btree.Item) bool { + other := o.(sortedByValueThenStartKey) + if s.Value != other.Value { + return s.Value < other.Value + } + return Valued(s).Less(Valued(other)) +} + +// ValueSortedFull is almost the same as `Valued`, however it added an +// extra index hence enabled query range by theirs value. +type ValueSortedFull struct { + *ValuedFull + valueIdx *btree.BTree +} + +// Sorted takes the ownership of a raw `ValuedFull` and then wrap it with `ValueSorted`. +func Sorted(f *ValuedFull) *ValueSortedFull { + vf := &ValueSortedFull{ + ValuedFull: f, + valueIdx: btree.New(16), + } + f.Traverse(func(v Valued) bool { + vf.valueIdx.ReplaceOrInsert(sortedByValueThenStartKey(v)) + return true + }) + return vf +} + +func (v *ValueSortedFull) Merge(newItem Valued) { + v.MergeAll([]Valued{newItem}) +} + +func (v *ValueSortedFull) MergeAll(newItems []Valued) { + var overlapped []Valued + var inserted []Valued + + for _, item := range newItems { + overlapped = overlapped[:0] + inserted = inserted[:0] + + v.overlapped(item.Key, &overlapped) + v.mergeWithOverlap(item, overlapped, &inserted) + + for _, o := range overlapped { + v.valueIdx.Delete(sortedByValueThenStartKey(o)) + } + for _, i := range inserted { + v.valueIdx.ReplaceOrInsert(sortedByValueThenStartKey(i)) + } + } +} + +func (v *ValueSortedFull) TraverseValuesLessThan(n Value, action func(Valued) bool) { + v.valueIdx.AscendLessThan(sortedByValueThenStartKey{Value: n}, func(item btree.Item) bool { + return action(Valued(item.(sortedByValueThenStartKey))) + }) +} + +func (v *ValueSortedFull) MinValue() Value { + return v.valueIdx.Min().(sortedByValueThenStartKey).Value +} diff --git a/br/pkg/streamhelper/spans/value_sorted_test.go b/br/pkg/streamhelper/spans/value_sorted_test.go new file mode 100644 index 0000000000000..ee1a5a8af6500 --- /dev/null +++ b/br/pkg/streamhelper/spans/value_sorted_test.go @@ -0,0 +1,98 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package spans_test + +import ( + "fmt" + "testing" + + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" + "github.com/stretchr/testify/require" +) + +func TestSortedBasic(t *testing.T) { + type Case struct { + InputSequence []spans.Valued + RetainLessThan spans.Value + Result []spans.Valued + } + + run := func(t *testing.T, c Case) { + full := spans.Sorted(spans.NewFullWith(spans.Full(), 0)) + fmt.Println(t.Name()) + for _, i := range c.InputSequence { + full.Merge(i) + spans.Debug(full) + } + + var result []spans.Valued + full.TraverseValuesLessThan(c.RetainLessThan, func(v spans.Valued) bool { + result = append(result, v) + return true + }) + + require.True(t, spans.ValuedSetEquals(result, c.Result), "%s\nvs\n%s", result, c.Result) + } + + cases := []Case{ + { + InputSequence: []spans.Valued{ + kv(s("0001", "0002"), 1), + kv(s("0002", "0003"), 2), + }, + Result: []spans.Valued{ + kv(s("", "0001"), 0), + kv(s("0001", "0002"), 1), + kv(s("0002", "0003"), 2), + kv(s("0003", ""), 0), + }, + RetainLessThan: 10, + }, + { + InputSequence: []spans.Valued{ + kv(s("0001", "0002"), 1), + kv(s("0002", "0003"), 2), + kv(s("0001", "0003"), 4), + }, + RetainLessThan: 1, + Result: []spans.Valued{ + kv(s("", "0001"), 0), + kv(s("0003", ""), 0), + }, + }, + { + InputSequence: []spans.Valued{ + kv(s("0001", "0004"), 3), + kv(s("0004", "0008"), 5), + kv(s("0001", "0007"), 4), + kv(s("", "0002"), 2), + }, + RetainLessThan: 5, + Result: []spans.Valued{ + kv(s("", "0001"), 2), + kv(s("0001", "0004"), 4), + kv(s("0008", ""), 0), + }, + }, + { + InputSequence: []spans.Valued{ + kv(s("0001", "0004"), 3), + kv(s("0004", "0008"), 5), + kv(s("0001", "0007"), 4), + kv(s("", "0002"), 2), + kv(s("0001", "0004"), 5), + kv(s("0008", ""), 10), + kv(s("", "0001"), 20), + }, + RetainLessThan: 11, + Result: []spans.Valued{ + kv(s("0001", "0008"), 5), + kv(s("0008", ""), 10), + }, + }, + } + + for i, c := range cases { + t.Run(fmt.Sprintf("#%d", i+1), func(t *testing.T) { run(t, c) }) + } +} diff --git a/br/pkg/streamhelper/subscription_test.go b/br/pkg/streamhelper/subscription_test.go new file mode 100644 index 0000000000000..2341cb05dc01e --- /dev/null +++ b/br/pkg/streamhelper/subscription_test.go @@ -0,0 +1,226 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package streamhelper_test + +import ( + "context" + "fmt" + "sync" + "testing" + + "github.com/pingcap/tidb/br/pkg/streamhelper" + "github.com/pingcap/tidb/br/pkg/streamhelper/spans" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func installSubscribeSupport(c *fakeCluster) { + for _, s := range c.stores { + s.SetSupportFlushSub(true) + } +} + +func installSubscribeSupportForRandomN(c *fakeCluster, n int) { + i := 0 + for _, s := range c.stores { + if i == n { + break + } + s.SetSupportFlushSub(true) + i++ + } +} + +func TestSubBasic(t *testing.T) { + req := require.New(t) + ctx := context.Background() + c := createFakeCluster(t, 4, true) + c.splitAndScatter("0001", "0002", "0003", "0008", "0009") + installSubscribeSupport(c) + sub := streamhelper.NewSubscriber(c, c) + req.NoError(sub.UpdateStoreTopology(ctx)) + var cp uint64 + for i := 0; i < 10; i++ { + cp = c.advanceCheckpoints() + c.flushAll() + } + sub.HandleErrors(ctx) + req.NoError(sub.PendingErrors()) + sub.Drop() + s := spans.Sorted(spans.NewFullWith(spans.Full(), 1)) + for k := range sub.Events() { + s.Merge(k) + } + defer func() { + if t.Failed() { + fmt.Println(c) + spans.Debug(s) + } + }() + + req.Equal(cp, s.MinValue(), "%d vs %d", cp, s.MinValue()) +} + +func TestNormalError(t *testing.T) { + req := require.New(t) + ctx := context.Background() + c := createFakeCluster(t, 4, true) + c.splitAndScatter("0001", "0002", "0003", "0008", "0009") + installSubscribeSupport(c) + + sub := streamhelper.NewSubscriber(c, c) + c.onGetClient = oneStoreFailure() + req.NoError(sub.UpdateStoreTopology(ctx)) + c.onGetClient = nil + req.Error(sub.PendingErrors()) + sub.HandleErrors(ctx) + req.NoError(sub.PendingErrors()) + var cp uint64 + for i := 0; i < 10; i++ { + cp = c.advanceCheckpoints() + c.flushAll() + } + sub.Drop() + s := spans.Sorted(spans.NewFullWith(spans.Full(), 1)) + for k := range sub.Events() { + s.Merge(k) + } + req.Equal(cp, s.MinValue(), "%d vs %d", cp, s.MinValue()) +} + +func TestHasFailureStores(t *testing.T) { + req := require.New(t) + ctx := context.Background() + c := createFakeCluster(t, 4, true) + c.splitAndScatter("0001", "0002", "0003", "0008", "0009") + + installSubscribeSupportForRandomN(c, 3) + sub := streamhelper.NewSubscriber(c, c) + req.NoError(sub.UpdateStoreTopology(ctx)) + sub.HandleErrors(ctx) + req.Error(sub.PendingErrors()) + + installSubscribeSupport(c) + req.NoError(sub.UpdateStoreTopology(ctx)) + sub.HandleErrors(ctx) + req.NoError(sub.PendingErrors()) +} + +func TestStoreOffline(t *testing.T) { + req := require.New(t) + ctx := context.Background() + c := createFakeCluster(t, 4, true) + c.splitAndScatter("0001", "0002", "0003", "0008", "0009") + installSubscribeSupport(c) + + c.onGetClient = func(u uint64) error { + return status.Error(codes.DataLoss, "upon an eclipsed night, some of data (not all data) have fled from the dataset") + } + sub := streamhelper.NewSubscriber(c, c) + req.NoError(sub.UpdateStoreTopology(ctx)) + req.Error(sub.PendingErrors()) + + c.onGetClient = nil + sub.HandleErrors(ctx) + req.NoError(sub.PendingErrors()) +} + +func TestStoreRemoved(t *testing.T) { + req := require.New(t) + ctx := context.Background() + c := createFakeCluster(t, 4, true) + c.splitAndScatter("0001", "0002", "0003", "0008", "0009", "0010", "0100", "0956", "1000") + + installSubscribeSupport(c) + sub := streamhelper.NewSubscriber(c, c) + req.NoError(sub.UpdateStoreTopology(ctx)) + + var cp uint64 + for i := 0; i < 10; i++ { + cp = c.advanceCheckpoints() + c.flushAll() + } + sub.HandleErrors(ctx) + req.NoError(sub.PendingErrors()) + for _, s := range c.stores { + c.removeStore(s.id) + break + } + req.NoError(sub.UpdateStoreTopology(ctx)) + for i := 0; i < 10; i++ { + cp = c.advanceCheckpoints() + c.flushAll() + } + sub.HandleErrors(ctx) + req.NoError(sub.PendingErrors()) + + sub.Drop() + s := spans.Sorted(spans.NewFullWith(spans.Full(), 1)) + for k := range sub.Events() { + s.Merge(k) + } + + defer func() { + if t.Failed() { + fmt.Println(c) + spans.Debug(s) + } + }() + + req.Equal(cp, s.MinValue(), "cp = %d, s = %d", cp, s.MinValue()) +} + +func TestSomeOfStoreUnsupported(t *testing.T) { + req := require.New(t) + ctx := context.Background() + c := createFakeCluster(t, 4, true) + c.splitAndScatter("0001", "0002", "0003", "0008", "0009", "0010", "0100", "0956", "1000") + + sub := streamhelper.NewSubscriber(c, c) + installSubscribeSupportForRandomN(c, 3) + req.NoError(sub.UpdateStoreTopology(ctx)) + + var cp uint64 + for i := 0; i < 10; i++ { + cp = c.advanceCheckpoints() + c.flushAll() + } + s := spans.Sorted(spans.NewFullWith(spans.Full(), 1)) + m := new(sync.Mutex) + sub.Drop() + for k := range sub.Events() { + s.Merge(k) + } + + rngs := make([]spans.Span, 0) + s.TraverseValuesLessThan(cp, func(v spans.Valued) bool { + rngs = append(rngs, v.Key) + return true + }) + coll := streamhelper.NewClusterCollector(ctx, c) + coll.SetOnSuccessHook(func(u uint64, kr spans.Span) { + m.Lock() + defer m.Unlock() + s.Merge(spans.Valued{Key: kr, Value: u}) + }) + ld := uint64(0) + for _, rng := range rngs { + iter := streamhelper.IterateRegion(c, rng.StartKey, rng.EndKey) + for !iter.Done() { + rs, err := iter.Next(ctx) + req.NoError(err) + for _, r := range rs { + if ld == 0 { + ld = r.Leader.StoreId + } else { + req.Equal(r.Leader.StoreId, ld, "the leader is from different store: some of events not pushed") + } + coll.CollectRegion(r) + } + } + } + _, err := coll.Finish(ctx) + req.NoError(err) + req.Equal(cp, s.MinValue()) +} diff --git a/br/pkg/streamhelper/tsheap.go b/br/pkg/streamhelper/tsheap.go deleted file mode 100644 index 6c2fb510776e7..0000000000000 --- a/br/pkg/streamhelper/tsheap.go +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. - -package streamhelper - -import ( - "encoding/hex" - "fmt" - "strings" - "sync" - "time" - - "github.com/google/btree" - "github.com/pingcap/errors" - berrors "github.com/pingcap/tidb/br/pkg/errors" - "github.com/pingcap/tidb/br/pkg/logutil" - "github.com/pingcap/tidb/br/pkg/redact" - "github.com/pingcap/tidb/br/pkg/utils" - "github.com/pingcap/tidb/kv" - "github.com/tikv/client-go/v2/oracle" - "go.uber.org/zap/zapcore" -) - -// CheckpointsCache is the heap-like cache for checkpoints. -// -// "Checkpoint" is the "Resolved TS" of some range. -// A resolved ts is a "watermark" for the system, which: -// - implies there won't be any transactions (in some range) commit with `commit_ts` smaller than this TS. -// - is monotonic increasing. -// A "checkpoint" is a "safe" Resolved TS, which: -// - is a TS *less than* the real resolved ts of now. -// - is based on range (it only promises there won't be new committed txns in the range). -// - the checkpoint of union of ranges is the minimal checkpoint of all ranges. -// As an example: -/* - +----------------------------------+ - ^-----------^ (Checkpoint = 42) - ^---------------^ (Checkpoint = 76) - ^-----------------------^ (Checkpoint = min(42, 76) = 42) -*/ -// For calculating the global checkpoint, we can make a heap-like structure: -// Checkpoint Ranges -// 42 -> {[0, 8], [16, 100]} -// 1002 -> {[8, 16]} -// 1082 -> {[100, inf]} -// For now, the checkpoint of range [8, 16] and [100, inf] won't affect the global checkpoint -// directly, so we can try to advance only the ranges of {[0, 8], [16, 100]} (which's checkpoint is steal). -// Once them get advance, the global checkpoint would be advanced then, -// and we don't need to update all ranges (because some new ranges don't need to be advanced so quickly.) -type CheckpointsCache interface { - fmt.Stringer - // InsertRange inserts a range with specified TS to the cache. - InsertRange(ts uint64, rng kv.KeyRange) - // InsertRanges inserts a set of ranges that sharing checkpoint to the cache. - InsertRanges(rst RangesSharesTS) - // CheckpointTS returns the now global (union of all ranges) checkpoint of the cache. - CheckpointTS() uint64 - // PopRangesWithGapGT pops the ranges which's checkpoint is - PopRangesWithGapGT(d time.Duration) []*RangesSharesTS - // Check whether the ranges in the cache is integrate. - ConsistencyCheck(ranges []kv.KeyRange) error - // Clear the cache. - Clear() -} - -// NoOPCheckpointCache is used when cache disabled. -type NoOPCheckpointCache struct{} - -func (NoOPCheckpointCache) InsertRange(ts uint64, rng kv.KeyRange) {} - -func (NoOPCheckpointCache) InsertRanges(rst RangesSharesTS) {} - -func (NoOPCheckpointCache) Clear() {} - -func (NoOPCheckpointCache) String() string { - return "NoOPCheckpointCache" -} - -func (NoOPCheckpointCache) CheckpointTS() uint64 { - panic("invalid state: NoOPCheckpointCache should never be used in advancing!") -} - -func (NoOPCheckpointCache) PopRangesWithGapGT(d time.Duration) []*RangesSharesTS { - panic("invalid state: NoOPCheckpointCache should never be used in advancing!") -} - -func (NoOPCheckpointCache) ConsistencyCheck([]kv.KeyRange) error { - return errors.Annotatef(berrors.ErrUnsupportedOperation, "invalid state: NoOPCheckpointCache should never be used in advancing!") -} - -// RangesSharesTS is a set of ranges shares the same timestamp. -type RangesSharesTS struct { - TS uint64 - Ranges []kv.KeyRange -} - -func (rst *RangesSharesTS) Zap() zapcore.ObjectMarshaler { - return zapcore.ObjectMarshalerFunc(func(oe zapcore.ObjectEncoder) error { - rngs := rst.Ranges - if len(rst.Ranges) > 3 { - rngs = rst.Ranges[:3] - } - - oe.AddUint64("checkpoint", rst.TS) - return oe.AddArray("items", zapcore.ArrayMarshalerFunc(func(ae zapcore.ArrayEncoder) error { - return ae.AppendObject(zapcore.ObjectMarshalerFunc(func(oe1 zapcore.ObjectEncoder) error { - for _, rng := range rngs { - oe1.AddString("start-key", redact.String(hex.EncodeToString(rng.StartKey))) - oe1.AddString("end-key", redact.String(hex.EncodeToString(rng.EndKey))) - } - return nil - })) - })) - }) -} - -func (rst *RangesSharesTS) String() string { - // Make a more friendly string. - return fmt.Sprintf("@%sR%d", oracle.GetTimeFromTS(rst.TS).Format("0405"), len(rst.Ranges)) -} - -func (rst *RangesSharesTS) Less(other btree.Item) bool { - return rst.TS < other.(*RangesSharesTS).TS -} - -// Checkpoints is a heap that collects all checkpoints of -// regions, it supports query the latest checkpoint fast. -// This structure is thread safe. -type Checkpoints struct { - tree *btree.BTree - - mu sync.Mutex -} - -func NewCheckpoints() *Checkpoints { - return &Checkpoints{ - tree: btree.New(32), - } -} - -// String formats the slowest 5 ranges sharing TS to string. -func (h *Checkpoints) String() string { - h.mu.Lock() - defer h.mu.Unlock() - - b := new(strings.Builder) - count := 0 - total := h.tree.Len() - h.tree.Ascend(func(i btree.Item) bool { - rst := i.(*RangesSharesTS) - b.WriteString(rst.String()) - b.WriteString(";") - count++ - return count < 5 - }) - if total-count > 0 { - fmt.Fprintf(b, "O%d", total-count) - } - return b.String() -} - -// InsertRanges insert a RangesSharesTS directly to the tree. -func (h *Checkpoints) InsertRanges(r RangesSharesTS) { - h.mu.Lock() - defer h.mu.Unlock() - if items := h.tree.Get(&r); items != nil { - i := items.(*RangesSharesTS) - i.Ranges = append(i.Ranges, r.Ranges...) - } else { - h.tree.ReplaceOrInsert(&r) - } -} - -// InsertRange inserts the region and its TS into the region tree. -func (h *Checkpoints) InsertRange(ts uint64, rng kv.KeyRange) { - h.mu.Lock() - defer h.mu.Unlock() - r := h.tree.Get(&RangesSharesTS{TS: ts}) - if r == nil { - r = &RangesSharesTS{TS: ts} - h.tree.ReplaceOrInsert(r) - } - rr := r.(*RangesSharesTS) - rr.Ranges = append(rr.Ranges, rng) -} - -// Clear removes all records in the checkpoint cache. -func (h *Checkpoints) Clear() { - h.mu.Lock() - defer h.mu.Unlock() - h.tree.Clear(false) -} - -// PopRangesWithGapGT pops ranges with gap greater than the specified duration. -// NOTE: maybe make something like `DrainIterator` for better composing? -func (h *Checkpoints) PopRangesWithGapGT(d time.Duration) []*RangesSharesTS { - h.mu.Lock() - defer h.mu.Unlock() - result := []*RangesSharesTS{} - for { - item, ok := h.tree.Min().(*RangesSharesTS) - if !ok { - return result - } - if time.Since(oracle.GetTimeFromTS(item.TS)) >= d { - result = append(result, item) - h.tree.DeleteMin() - } else { - return result - } - } -} - -// CheckpointTS returns the cached checkpoint TS by the current state of the cache. -func (h *Checkpoints) CheckpointTS() uint64 { - h.mu.Lock() - defer h.mu.Unlock() - item, ok := h.tree.Min().(*RangesSharesTS) - if !ok { - return 0 - } - return item.TS -} - -// ConsistencyCheck checks whether the tree contains the full range of key space. -func (h *Checkpoints) ConsistencyCheck(rangesIn []kv.KeyRange) error { - h.mu.Lock() - rangesReal := make([]kv.KeyRange, 0, 1024) - h.tree.Ascend(func(i btree.Item) bool { - rangesReal = append(rangesReal, i.(*RangesSharesTS).Ranges...) - return true - }) - h.mu.Unlock() - - r := CollapseRanges(len(rangesReal), func(i int) kv.KeyRange { return rangesReal[i] }) - ri := CollapseRanges(len(rangesIn), func(i int) kv.KeyRange { return rangesIn[i] }) - - return errors.Annotatef(checkIntervalIsSubset(r, ri), "ranges: (current) %s (not in) %s", logutil.StringifyKeys(r), - logutil.StringifyKeys(ri)) -} - -// A simple algorithm to detect non-overlapped ranges. -// It maintains the "current" probe, and let the ranges to check "consume" it. -// For example: -// toCheck: |_____________________| |_____________| -// . ^checking -// subsetOf: |_________| |_______| |__________| -// . ^probing -// probing is the subrange of checking, consume it and move forward the probe. -// toCheck: |_____________________| |_____________| -// . ^checking -// subsetOf: |_________| |_______| |__________| -// . ^probing -// consume it, too. -// toCheck: |_____________________| |_____________| -// . ^checking -// subsetOf: |_________| |_______| |__________| -// . ^probing -// checking is at the left of probing and no overlaps, moving it forward. -// toCheck: |_____________________| |_____________| -// . ^checking -// subsetOf: |_________| |_______| |__________| -// . ^probing -// consume it. all subset ranges are consumed, check passed. -func checkIntervalIsSubset(toCheck []kv.KeyRange, subsetOf []kv.KeyRange) error { - i := 0 - si := 0 - - for { - // We have checked all ranges. - if si >= len(subsetOf) { - return nil - } - // There are some ranges doesn't reach the end. - if i >= len(toCheck) { - return errors.Annotatef(berrors.ErrPiTRMalformedMetadata, - "there remains a range doesn't be fully consumed: %s", - logutil.StringifyRange(subsetOf[si])) - } - - checking := toCheck[i] - probing := subsetOf[si] - // checking: |___________| - // probing: |_________| - // A rare case: the "first" range is out of bound or not fully covers the probing range. - if utils.CompareBytesExt(checking.StartKey, false, probing.StartKey, false) > 0 { - holeEnd := checking.StartKey - if utils.CompareBytesExt(holeEnd, false, probing.EndKey, true) > 0 { - holeEnd = probing.EndKey - } - return errors.Annotatef(berrors.ErrPiTRMalformedMetadata, "probably a hole in key ranges: %s", logutil.StringifyRange{ - StartKey: probing.StartKey, - EndKey: holeEnd, - }) - } - - // checking: |_____| - // probing: |_______| - // Just move forward checking. - if utils.CompareBytesExt(checking.EndKey, true, probing.StartKey, false) < 0 { - i += 1 - continue - } - - // checking: |_________| - // probing: |__________________| - // Given all of the ranges are "collapsed", the next checking range must - // not be adjacent with the current checking range. - // And hence there must be a "hole" in the probing key space. - if utils.CompareBytesExt(checking.EndKey, true, probing.EndKey, true) < 0 { - next := probing.EndKey - if i+1 < len(toCheck) { - next = toCheck[i+1].EndKey - } - return errors.Annotatef(berrors.ErrPiTRMalformedMetadata, "probably a hole in key ranges: %s", logutil.StringifyRange{ - StartKey: checking.EndKey, - EndKey: next, - }) - } - // checking: |________________| - // probing: |_____________| - // The current checking range fills the current probing range, - // or the current checking range is out of the current range. - // let's move the probing forward. - si += 1 - } -} diff --git a/br/pkg/streamhelper/tsheap_test.go b/br/pkg/streamhelper/tsheap_test.go deleted file mode 100644 index 173bc2e0a0334..0000000000000 --- a/br/pkg/streamhelper/tsheap_test.go +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. -package streamhelper_test - -import ( - "fmt" - "math" - "math/rand" - "testing" - - "github.com/pingcap/tidb/br/pkg/streamhelper" - "github.com/pingcap/tidb/kv" - "github.com/stretchr/testify/require" -) - -func TestInsert(t *testing.T) { - cases := []func(func(ts uint64, a, b string)){ - func(insert func(ts uint64, a, b string)) { - insert(1, "", "01") - insert(1, "01", "02") - insert(2, "02", "022") - insert(4, "022", "") - }, - func(insert func(ts uint64, a, b string)) { - insert(1, "", "01") - insert(2, "", "01") - insert(2, "011", "02") - insert(1, "", "") - insert(65, "03", "04") - }, - } - - for _, c := range cases { - cps := streamhelper.NewCheckpoints() - expected := map[uint64]*streamhelper.RangesSharesTS{} - checkpoint := uint64(math.MaxUint64) - insert := func(ts uint64, a, b string) { - cps.InsertRange(ts, kv.KeyRange{ - StartKey: []byte(a), - EndKey: []byte(b), - }) - i, ok := expected[ts] - if !ok { - expected[ts] = &streamhelper.RangesSharesTS{TS: ts, Ranges: []kv.KeyRange{{StartKey: []byte(a), EndKey: []byte(b)}}} - } else { - i.Ranges = append(i.Ranges, kv.KeyRange{StartKey: []byte(a), EndKey: []byte(b)}) - } - if ts < checkpoint { - checkpoint = ts - } - } - c(insert) - require.Equal(t, checkpoint, cps.CheckpointTS()) - rngs := cps.PopRangesWithGapGT(0) - for _, rng := range rngs { - other := expected[rng.TS] - require.Equal(t, other, rng) - } - } -} - -func TestMergeRanges(t *testing.T) { - r := func(a, b string) kv.KeyRange { - return kv.KeyRange{StartKey: []byte(a), EndKey: []byte(b)} - } - type Case struct { - expected []kv.KeyRange - parameter []kv.KeyRange - } - cases := []Case{ - { - parameter: []kv.KeyRange{r("01", "01111"), r("0111", "0112")}, - expected: []kv.KeyRange{r("01", "0112")}, - }, - { - parameter: []kv.KeyRange{r("01", "03"), r("02", "04")}, - expected: []kv.KeyRange{r("01", "04")}, - }, - { - parameter: []kv.KeyRange{r("04", "08"), r("09", "10")}, - expected: []kv.KeyRange{r("04", "08"), r("09", "10")}, - }, - { - parameter: []kv.KeyRange{r("01", "03"), r("02", "04"), r("05", "07"), r("08", "09")}, - expected: []kv.KeyRange{r("01", "04"), r("05", "07"), r("08", "09")}, - }, - { - parameter: []kv.KeyRange{r("01", "02"), r("012", "")}, - expected: []kv.KeyRange{r("01", "")}, - }, - { - parameter: []kv.KeyRange{r("", "01"), r("02", "03"), r("021", "")}, - expected: []kv.KeyRange{r("", "01"), r("02", "")}, - }, - { - parameter: []kv.KeyRange{r("", "01"), r("001", "")}, - expected: []kv.KeyRange{r("", "")}, - }, - { - parameter: []kv.KeyRange{r("", "01"), r("", ""), r("", "02")}, - expected: []kv.KeyRange{r("", "")}, - }, - { - parameter: []kv.KeyRange{r("", "01"), r("01", ""), r("", "02"), r("", "03"), r("01", "02")}, - expected: []kv.KeyRange{r("", "")}, - }, - { - parameter: []kv.KeyRange{r("", ""), r("", "01"), r("01", ""), r("01", "02")}, - expected: []kv.KeyRange{r("", "")}, - }, - } - - for i, c := range cases { - result := streamhelper.CollapseRanges(len(c.parameter), func(i int) kv.KeyRange { - return c.parameter[i] - }) - require.Equal(t, c.expected, result, "case = %d", i) - } -} - -func TestInsertRanges(t *testing.T) { - r := func(a, b string) kv.KeyRange { - return kv.KeyRange{StartKey: []byte(a), EndKey: []byte(b)} - } - rs := func(ts uint64, ranges ...kv.KeyRange) streamhelper.RangesSharesTS { - return streamhelper.RangesSharesTS{TS: ts, Ranges: ranges} - } - - type Case struct { - Expected []streamhelper.RangesSharesTS - Parameters []streamhelper.RangesSharesTS - } - - cases := []Case{ - { - Parameters: []streamhelper.RangesSharesTS{ - rs(1, r("0", "1"), r("1", "2")), - rs(1, r("2", "3"), r("3", "4")), - }, - Expected: []streamhelper.RangesSharesTS{ - rs(1, r("0", "1"), r("1", "2"), r("2", "3"), r("3", "4")), - }, - }, - { - Parameters: []streamhelper.RangesSharesTS{ - rs(1, r("0", "1")), - rs(2, r("2", "3")), - rs(1, r("4", "5"), r("6", "7")), - }, - Expected: []streamhelper.RangesSharesTS{ - rs(1, r("0", "1"), r("4", "5"), r("6", "7")), - rs(2, r("2", "3")), - }, - }, - } - - for _, c := range cases { - theTree := streamhelper.NewCheckpoints() - for _, p := range c.Parameters { - theTree.InsertRanges(p) - } - ranges := theTree.PopRangesWithGapGT(0) - for i, rs := range ranges { - require.ElementsMatch(t, c.Expected[i].Ranges, rs.Ranges, "case = %#v", c) - } - } -} - -func TestConsistencyCheckOverRange(t *testing.T) { - r := func(a, b string) kv.KeyRange { - return kv.KeyRange{StartKey: []byte(a), EndKey: []byte(b)} - } - type Case struct { - checking []kv.KeyRange - probing []kv.KeyRange - isSubset bool - } - - cases := []Case{ - // basic: exactly match. - { - checking: []kv.KeyRange{r("0001", "0002"), r("0002", "0003"), r("0004", "0005")}, - probing: []kv.KeyRange{r("0001", "0003"), r("0004", "0005")}, - isSubset: true, - }, - // not fully match, probing longer. - { - checking: []kv.KeyRange{r("0001", "0002"), r("0002", "0003"), r("0004", "0005")}, - probing: []kv.KeyRange{r("0000", "0003"), r("0004", "00051")}, - isSubset: false, - }, - // with infinity end keys. - { - checking: []kv.KeyRange{r("0001", "0002"), r("0002", "0003"), r("0004", "")}, - probing: []kv.KeyRange{r("0001", "0003"), r("0004", "")}, - isSubset: true, - }, - { - checking: []kv.KeyRange{r("0001", "0002"), r("0002", "0003"), r("0004", "")}, - probing: []kv.KeyRange{r("0001", "0003"), r("0004", "0005")}, - isSubset: true, - }, - { - checking: []kv.KeyRange{r("0001", "0002"), r("0002", "0003"), r("0004", "0005")}, - probing: []kv.KeyRange{r("0001", "0003"), r("0004", "")}, - isSubset: false, - }, - // overlapped probe. - { - checking: []kv.KeyRange{r("0001", "0002"), r("0002", "0003"), r("0004", "0007")}, - probing: []kv.KeyRange{r("0001", "0008")}, - isSubset: false, - }, - { - checking: []kv.KeyRange{r("0001", "0008")}, - probing: []kv.KeyRange{r("0001", "0002"), r("0002", "0003"), r("0004", "0007")}, - isSubset: true, - }, - { - checking: []kv.KeyRange{r("0100", "0120"), r("0130", "0141")}, - probing: []kv.KeyRange{r("0000", "0001")}, - isSubset: false, - }, - { - checking: []kv.KeyRange{r("0100", "0120")}, - probing: []kv.KeyRange{r("0090", "0110"), r("0115", "0120")}, - isSubset: false, - }, - } - - run := func(t *testing.T, c Case) { - tree := streamhelper.NewCheckpoints() - for _, r := range c.checking { - tree.InsertRange(rand.Uint64()%10, r) - } - err := tree.ConsistencyCheck(c.probing) - if c.isSubset { - require.NoError(t, err) - } else { - require.Error(t, err) - } - } - - for i, c := range cases { - t.Run(fmt.Sprintf("#%d", i), func(tc *testing.T) { - run(tc, c) - }) - } -} diff --git a/br/pkg/summary/collector.go b/br/pkg/summary/collector.go index 705c26df3e4ac..1a16fb6dc9cfc 100644 --- a/br/pkg/summary/collector.go +++ b/br/pkg/summary/collector.go @@ -46,6 +46,10 @@ type LogCollector interface { SetSuccessStatus(success bool) + NowDureTime() time.Duration + + AdjustStartTimeToEarlierTime(t time.Duration) + Summary(name string) Log(msg string, fields ...zap.Field) @@ -163,6 +167,18 @@ func logKeyFor(key string) string { return strings.ReplaceAll(key, " ", "-") } +func (tc *logCollector) NowDureTime() time.Duration { + tc.mu.Lock() + defer tc.mu.Unlock() + return time.Since(tc.startTime) +} + +func (tc *logCollector) AdjustStartTimeToEarlierTime(t time.Duration) { + tc.mu.Lock() + defer tc.mu.Unlock() + tc.startTime = tc.startTime.Add(-t) +} + func (tc *logCollector) Summary(name string) { tc.mu.Lock() defer func() { diff --git a/br/pkg/summary/main_test.go b/br/pkg/summary/main_test.go index 48d22e0e5ea11..e167e079b78ff 100644 --- a/br/pkg/summary/main_test.go +++ b/br/pkg/summary/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/br/pkg/summary/summary.go b/br/pkg/summary/summary.go index 7ae488785760e..45c8fbbc55997 100644 --- a/br/pkg/summary/summary.go +++ b/br/pkg/summary/summary.go @@ -43,6 +43,15 @@ func SetSuccessStatus(success bool) { collector.SetSuccessStatus(success) } +// NowDureTime returns the duration between start time and current time +func NowDureTime() time.Duration { + return collector.NowDureTime() +} + +func AdjustStartTimeToEarlierTime(t time.Duration) { + collector.AdjustStartTimeToEarlierTime(t) +} + // Summary outputs summary log. func Summary(name string) { collector.Summary(name) diff --git a/br/pkg/task/BUILD.bazel b/br/pkg/task/BUILD.bazel index a1703ac98a2ff..979afd1ba9110 100644 --- a/br/pkg/task/BUILD.bazel +++ b/br/pkg/task/BUILD.bazel @@ -96,6 +96,7 @@ go_test( flaky = True, deps = [ "//br/pkg/conn", + "//br/pkg/errors", "//br/pkg/metautil", "//br/pkg/restore", "//br/pkg/storage", diff --git a/br/pkg/task/backup.go b/br/pkg/task/backup.go index 6654409c46a6a..0033324037e90 100644 --- a/br/pkg/task/backup.go +++ b/br/pkg/task/backup.go @@ -4,6 +4,8 @@ package task import ( "context" + "crypto/sha256" + "encoding/json" "fmt" "os" "strconv" @@ -26,6 +28,7 @@ import ( "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/br/pkg/summary" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/br/pkg/version" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/statistics/handle" @@ -45,11 +48,13 @@ const ( flagRemoveSchedulers = "remove-schedulers" flagIgnoreStats = "ignore-stats" flagUseBackupMetaV2 = "use-backupmeta-v2" + flagUseCheckpoint = "use-checkpoint" flagGCTTL = "gcttl" defaultBackupConcurrency = 4 maxBackupConcurrency = 256 + checkpointDefaultGCTTL = 72 * 60 // 72 minutes ) const ( @@ -77,6 +82,7 @@ type BackupConfig struct { RemoveSchedulers bool `json:"remove-schedulers" toml:"remove-schedulers"` IgnoreStats bool `json:"ignore-stats" toml:"ignore-stats"` UseBackupMetaV2 bool `json:"use-backupmeta-v2"` + UseCheckpoint bool `json:"use-checkpoint" toml:"use-checkpoint"` CompressionConfig // for ebs-based backup @@ -126,6 +132,9 @@ func DefineBackupFlags(flags *pflag.FlagSet) { // but will generate v1 meta due to this flag is false. the behaviour is as same as v4.0.15, v4.0.16. // finally v4.0.17 will set this flag to true, and generate v2 meta. _ = flags.MarkHidden(flagUseBackupMetaV2) + + flags.Bool(flagUseCheckpoint, true, "use checkpoint mode") + _ = flags.MarkHidden(flagUseCheckpoint) } // ParseFromFlags parses the backup-related flags from the flag set. @@ -150,10 +159,34 @@ func (cfg *BackupConfig) ParseFromFlags(flags *pflag.FlagSet) error { if err != nil { return errors.Trace(err) } + cfg.UseBackupMetaV2, err = flags.GetBool(flagUseBackupMetaV2) + if err != nil { + return errors.Trace(err) + } + cfg.UseCheckpoint, err = flags.GetBool(flagUseCheckpoint) + if err != nil { + return errors.Trace(err) + } + if cfg.LastBackupTS > 0 { + // TODO: compatible with incremental backup + cfg.UseCheckpoint = false + log.Info("since incremental backup is used, turn off checkpoint mode") + } + if cfg.UseBackupMetaV2 { + // TODO: compatible with backup meta v2, maybe just clean the meta files + cfg.UseCheckpoint = false + log.Info("since backup meta v2 is used, turn off checkpoint mode") + } gcTTL, err := flags.GetInt64(flagGCTTL) if err != nil { return errors.Trace(err) } + // if use checkpoint and gcTTL is the default value + // update gcttl to checkpoint's default gc ttl + if cfg.UseCheckpoint && gcTTL == utils.DefaultBRGCSafePointTTL { + gcTTL = checkpointDefaultGCTTL + log.Info("use checkpoint's default GC TTL", zap.Int64("GC TTL", gcTTL)) + } cfg.GCTTL = gcTTL compressionCfg, err := parseCompressionFlags(flags) @@ -173,10 +206,6 @@ func (cfg *BackupConfig) ParseFromFlags(flags *pflag.FlagSet) error { if err != nil { return errors.Trace(err) } - cfg.UseBackupMetaV2, err = flags.GetBool(flagUseBackupMetaV2) - if err != nil { - return errors.Trace(err) - } if flags.Lookup(flagFullBackupType) != nil { // for backup full @@ -269,6 +298,23 @@ func (cfg *BackupConfig) Adjust() { } } +// a rough hash for checkpoint checker +func (cfg *BackupConfig) Hash() ([]byte, error) { + config := &BackupConfig{ + LastBackupTS: cfg.LastBackupTS, + IgnoreStats: cfg.IgnoreStats, + UseCheckpoint: cfg.UseCheckpoint, + Config: cfg.Config, + } + data, err := json.Marshal(config) + if err != nil { + return nil, errors.Trace(err) + } + hash := sha256.Sum256(data) + + return hash[:], nil +} + func isFullBackup(cmdName string) bool { return cmdName == FullBackupCmd } @@ -301,6 +347,14 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig return errors.Trace(err) } defer mgr.Close() + // after version check, check the cluster whether support checkpoint mode + if cfg.UseCheckpoint { + err = version.CheckCheckpointSupport() + if err != nil { + log.Warn("unable to use checkpoint mode, fall back to normal mode", zap.Error(err)) + cfg.UseCheckpoint = false + } + } var statsHandle *handle.Handle if !skipStats { statsHandle = mgr.GetDomain().StatsHandle() @@ -308,28 +362,39 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig var newCollationEnable string err = g.UseOneShotSession(mgr.GetStorage(), !needDomain, func(se glue.Session) error { - newCollationEnable, err = se.GetGlobalVariable(tidbNewCollationEnabled) + newCollationEnable, err = se.GetGlobalVariable(utils.GetTidbNewCollationEnabled()) if err != nil { return errors.Trace(err) } log.Info("get new_collations_enabled_on_first_bootstrap config from system table", - zap.String(tidbNewCollationEnabled, newCollationEnable)) + zap.String(utils.GetTidbNewCollationEnabled(), newCollationEnable)) return nil }) if err != nil { return errors.Trace(err) } - client, err := backup.NewBackupClient(ctx, mgr) - if err != nil { - return errors.Trace(err) - } + client := backup.NewBackupClient(ctx, mgr) + + // set cipher only for checkpoint + client.SetCipher(&cfg.CipherInfo) + opts := storage.ExternalStorageOptions{ NoCredentials: cfg.NoCreds, SendCredentials: cfg.SendCreds, CheckS3ObjectLockOptions: true, } - if err = client.SetStorage(ctx, u, &opts); err != nil { + if err = client.SetStorageAndCheckNotInUse(ctx, u, &opts); err != nil { + return errors.Trace(err) + } + // if checkpoint mode is unused at this time but there is checkpoint meta, + // CheckCheckpoint will stop backing up + cfgHash, err := cfg.Hash() + if err != nil { + return errors.Trace(err) + } + err = client.CheckCheckpoint(cfgHash) + if err != nil { return errors.Trace(err) } err = client.SetLockFile(ctx) @@ -343,24 +408,45 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig return errors.Trace(err) } g.Record("BackupTS", backupTS) + safePointID := client.GetSafePointID() sp := utils.BRServiceSafePoint{ BackupTS: backupTS, TTL: client.GetGCTTL(), - ID: utils.MakeSafePointID(), + ID: safePointID, } + // use lastBackupTS as safePoint if exists - if cfg.LastBackupTS > 0 { + isIncrementalBackup := cfg.LastBackupTS > 0 + if isIncrementalBackup { sp.BackupTS = cfg.LastBackupTS } log.Info("current backup safePoint job", zap.Object("safePoint", sp)) - err = utils.StartServiceSafePointKeeper(ctx, mgr.GetPDClient(), sp) + cctx, gcSafePointKeeperCancel := context.WithCancel(ctx) + gcSafePointKeeperRemovable := false + defer func() { + // don't reset the gc-safe-point if checkpoint mode is used and backup is not finished + if cfg.UseCheckpoint && !gcSafePointKeeperRemovable { + log.Info("skip removing gc-safepoint keeper for next retry", zap.String("gc-id", sp.ID)) + return + } + log.Info("start to remove gc-safepoint keeper") + // close the gc safe point keeper at first + gcSafePointKeeperCancel() + // set the ttl to 0 to remove the gc-safe-point + sp.TTL = 0 + if err := utils.UpdateServiceSafePoint(ctx, mgr.GetPDClient(), sp); err != nil { + log.Warn("failed to update service safe point, backup may fail if gc triggered", + zap.Error(err), + ) + } + log.Info("finish removing gc-safepoint keeper") + }() + err = utils.StartServiceSafePointKeeper(cctx, mgr.GetPDClient(), sp) if err != nil { return errors.Trace(err) } - isIncrementalBackup := cfg.LastBackupTS > 0 - if cfg.RemoveSchedulers { log.Debug("removing some PD schedulers") restore, e := mgr.RemoveSchedulers(ctx) @@ -395,7 +481,7 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig return errors.Trace(err) } - ranges, schemas, policies, err := backup.BuildBackupRangeAndSchema(mgr.GetStorage(), cfg.TableFilter, backupTS, isFullBackup(cmdName)) + ranges, schemas, policies, err := client.BuildBackupRangeAndSchema(mgr.GetStorage(), cfg.TableFilter, backupTS, isFullBackup(cmdName)) if err != nil { return errors.Trace(err) } @@ -422,7 +508,7 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig } // nothing to backup - if ranges == nil || len(ranges) <= 0 { + if len(ranges) == 0 { pdAddress := strings.Join(cfg.PD, ",") log.Warn("Nothing to backup, maybe connected to cluster for restoring", zap.String("PD address", pdAddress)) @@ -503,6 +589,18 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig }) } } + + if cfg.UseCheckpoint { + if err = client.StartCheckpointRunner(ctx, cfgHash, backupTS, ranges, safePointID, progressCallBack); err != nil { + return errors.Trace(err) + } + defer func() { + if !gcSafePointKeeperRemovable { + log.Info("wait for flush checkpoint...") + client.WaitForFinishCheckpoint(ctx) + } + }() + } metawriter.StartWriteMetasAsync(ctx, metautil.AppendDataFile) err = client.BackupRanges(ctx, ranges, req, uint(cfg.Concurrency), metawriter, progressCallBack) if err != nil { @@ -532,7 +630,7 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig schemasConcurrency := uint(mathutil.Min(backup.DefaultSchemaConcurrency, schemas.Len())) err = schemas.BackupSchemas( - ctx, metawriter, mgr.GetStorage(), statsHandle, backupTS, schemasConcurrency, cfg.ChecksumConcurrency, skipChecksum, updateCh) + ctx, metawriter, client.GetCheckpointRunner(), mgr.GetStorage(), statsHandle, backupTS, schemasConcurrency, cfg.ChecksumConcurrency, skipChecksum, updateCh) if err != nil { return errors.Trace(err) } @@ -541,6 +639,9 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig if err != nil { return errors.Trace(err) } + // Since backupmeta is flushed on the external storage, + // we can remove the gc safepoint keeper + gcSafePointKeeperRemovable = true // Checksum has finished, close checksum progress. updateCh.Close() diff --git a/br/pkg/task/backup_ebs.go b/br/pkg/task/backup_ebs.go index ec836fa83722c..ff0fb6a01a461 100644 --- a/br/pkg/task/backup_ebs.go +++ b/br/pkg/task/backup_ebs.go @@ -111,16 +111,13 @@ func RunBackupEBS(c context.Context, g glue.Glue, cfg *BackupConfig) error { return errors.Trace(err) } defer mgr.Close() - client, err := backup.NewBackupClient(ctx, mgr) - if err != nil { - return errors.Trace(err) - } + client := backup.NewBackupClient(ctx, mgr) opts := storage.ExternalStorageOptions{ NoCredentials: cfg.NoCreds, SendCredentials: cfg.SendCreds, } - if err = client.SetStorage(ctx, backend, &opts); err != nil { + if err = client.SetStorageAndCheckNotInUse(ctx, backend, &opts); err != nil { return errors.Trace(err) } err = client.SetLockFile(ctx) @@ -186,7 +183,7 @@ func RunBackupEBS(c context.Context, g glue.Glue, cfg *BackupConfig) error { // Step.2 starts call ebs snapshot api to back up volume data. // NOTE: we should start snapshot in specify order. - progress := g.StartProgress(ctx, "backup", int64(storeCount), !cfg.LogProgress) + progress := g.StartProgress(ctx, "backup", int64(storeCount)*100, !cfg.LogProgress) go progressFileWriterRoutine(ctx, progress, int64(storeCount)*100, cfg.ProgressFile) ec2Session, err := aws.NewEC2Session(cfg.CloudAPIConcurrency) diff --git a/br/pkg/task/backup_raw.go b/br/pkg/task/backup_raw.go index 8a3ca2b17b622..2b46347327501 100644 --- a/br/pkg/task/backup_raw.go +++ b/br/pkg/task/backup_raw.go @@ -144,16 +144,13 @@ func RunBackupRaw(c context.Context, g glue.Glue, cmdName string, cfg *RawKvConf } defer mgr.Close() - client, err := backup.NewBackupClient(ctx, mgr) - if err != nil { - return errors.Trace(err) - } + client := backup.NewBackupClient(ctx, mgr) opts := storage.ExternalStorageOptions{ NoCredentials: cfg.NoCreds, SendCredentials: cfg.SendCreds, CheckS3ObjectLockOptions: true, } - if err = client.SetStorage(ctx, u, &opts); err != nil { + if err = client.SetStorageAndCheckNotInUse(ctx, u, &opts); err != nil { return errors.Trace(err) } @@ -216,9 +213,18 @@ func RunBackupRaw(c context.Context, g glue.Glue, cmdName string, cfg *RawKvConf CompressionLevel: cfg.CompressionLevel, CipherInfo: &cfg.CipherInfo, } + rg := rtree.Range{ + StartKey: backupRange.StartKey, + EndKey: backupRange.EndKey, + } + progressRange := &rtree.ProgressRange{ + Res: rtree.NewRangeTree(), + Incomplete: []rtree.Range{rg}, + Origin: rg, + } metaWriter := metautil.NewMetaWriter(client.GetStorage(), metautil.MetaFileSize, false, metautil.MetaFile, &cfg.CipherInfo) metaWriter.StartWriteMetasAsync(ctx, metautil.AppendDataFile) - err = client.BackupRange(ctx, req, metaWriter, progressCallBack) + err = client.BackupRange(ctx, req, progressRange, metaWriter, progressCallBack) if err != nil { return errors.Trace(err) } diff --git a/br/pkg/task/common.go b/br/pkg/task/common.go index 5d76a2db4f85b..2d04f916d98ec 100644 --- a/br/pkg/task/common.go +++ b/br/pkg/task/common.go @@ -96,8 +96,6 @@ const ( crypterAES192KeyLen = 24 crypterAES256KeyLen = 32 - tidbNewCollationEnabled = "new_collation_enabled" - flagFullBackupType = "type" ) diff --git a/br/pkg/task/restore.go b/br/pkg/task/restore.go index 7dcdc1274413a..8a5cd0425e221 100644 --- a/br/pkg/task/restore.go +++ b/br/pkg/task/restore.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/br/pkg/utils" "github.com/pingcap/tidb/br/pkg/version" "github.com/pingcap/tidb/config" - "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/mathutil" "github.com/spf13/cobra" @@ -58,14 +57,22 @@ const ( FlagStreamRestoreTS = "restored-ts" // FlagStreamFullBackupStorage is used for log restore, represents the full backup storage. FlagStreamFullBackupStorage = "full-backup-storage" - - defaultRestoreConcurrency = 128 - defaultRestoreStreamConcurrency = 16 - maxRestoreBatchSizeLimit = 10240 - defaultPDConcurrency = 1 - defaultBatchFlushInterval = 16 * time.Second - defaultFlagDdlBatchSize = 128 - resetSpeedLimitRetryTimes = 3 + // FlagPiTRBatchCount and FlagPiTRBatchSize are used for restore log with batch method. + FlagPiTRBatchCount = "pitr-batch-count" + FlagPiTRBatchSize = "pitr-batch-size" + FlagPiTRConcurrency = "pitr-concurrency" + + FlagResetSysUsers = "reset-sys-users" + + defaultPiTRBatchCount = 8 + defaultPiTRBatchSize = 16 * 1024 * 1024 + defaultRestoreConcurrency = 128 + defaultPiTRConcurrency = 16 + maxRestoreBatchSizeLimit = 10240 + defaultPDConcurrency = 1 + defaultBatchFlushInterval = 16 * time.Second + defaultFlagDdlBatchSize = 128 + resetSpeedLimitRetryTimes = 3 ) const ( @@ -88,6 +95,8 @@ type RestoreCommonConfig struct { // determines whether enable restore sys table on default, see fullClusterRestore in restore/client.go WithSysTable bool `json:"with-sys-table" toml:"with-sys-table"` + + ResetSysUsers []string `json:"reset-sys-users" toml:"reset-sys-users"` } // adjust adjusts the abnormal config value in the current config. @@ -113,10 +122,12 @@ func DefineRestoreCommonFlags(flags *pflag.FlagSet) { flags.Uint(FlagPDConcurrency, defaultPDConcurrency, "concurrency pd-relative operations like split & scatter.") flags.Duration(FlagBatchFlushInterval, defaultBatchFlushInterval, - "after how long a restore batch would be auto sended.") + "after how long a restore batch would be auto sent.") flags.Uint(FlagDdlBatchSize, defaultFlagDdlBatchSize, - "batch size for ddl to create a batch of tabes once.") + "batch size for ddl to create a batch of tables once.") flags.Bool(flagWithSysTable, false, "whether restore system privilege tables on default setting") + flags.StringArrayP(FlagResetSysUsers, "", []string{"cloud_admin", "root"}, "whether reset these users after restoration") + _ = flags.MarkHidden(FlagResetSysUsers) _ = flags.MarkHidden(FlagMergeRegionSizeBytes) _ = flags.MarkHidden(FlagMergeRegionKeyCount) _ = flags.MarkHidden(FlagPDConcurrency) @@ -145,6 +156,10 @@ func (cfg *RestoreCommonConfig) ParseFromFlags(flags *pflag.FlagSet) error { return errors.Trace(err) } } + cfg.ResetSysUsers, err = flags.GetStringArray(FlagResetSysUsers) + if err != nil { + return errors.Trace(err) + } return errors.Trace(err) } @@ -169,6 +184,9 @@ type RestoreConfig struct { StartTS uint64 `json:"start-ts" toml:"start-ts"` RestoreTS uint64 `json:"restore-ts" toml:"restore-ts"` tiflashRecorder *tiflashrec.TiFlashRecorder `json:"-" toml:"-"` + PitrBatchCount uint32 `json:"pitr-batch-count" toml:"pitr-batch-count"` + PitrBatchSize uint32 `json:"pitr-batch-size" toml:"pitr-batch-size"` + PitrConcurrency uint32 `json:"-" toml:"-"` // for ebs-based restore FullBackupType FullBackupType `json:"full-backup-type" toml:"full-backup-type"` @@ -200,6 +218,9 @@ func DefineStreamRestoreFlags(command *cobra.Command) { "support TSO or datetime, e.g. '400036290571534337' or '2018-05-11 01:42:23+0800'") command.Flags().String(FlagStreamFullBackupStorage, "", "specify the backup full storage. "+ "fill it if want restore full backup before restore log.") + command.Flags().Uint32(FlagPiTRBatchCount, defaultPiTRBatchCount, "specify the batch count to restore log.") + command.Flags().Uint32(FlagPiTRBatchSize, defaultPiTRBatchSize, "specify the batch size to retore log.") + command.Flags().Uint32(FlagPiTRConcurrency, defaultPiTRConcurrency, "specify the concurrency to restore log.") } // ParseStreamRestoreFlags parses the `restore stream` flags from the flag set. @@ -228,6 +249,15 @@ func (cfg *RestoreConfig) ParseStreamRestoreFlags(flags *pflag.FlagSet) error { FlagStreamStartTS, FlagStreamFullBackupStorage) } + if cfg.PitrBatchCount, err = flags.GetUint32(FlagPiTRBatchCount); err != nil { + return errors.Trace(err) + } + if cfg.PitrBatchSize, err = flags.GetUint32(FlagPiTRBatchSize); err != nil { + return errors.Trace(err) + } + if cfg.PitrConcurrency, err = flags.GetUint32(FlagPiTRConcurrency); err != nil { + return errors.Trace(err) + } return nil } @@ -354,10 +384,19 @@ func (cfg *RestoreConfig) Adjust() { } func (cfg *RestoreConfig) adjustRestoreConfigForStreamRestore() { - if cfg.Config.Concurrency == 0 || cfg.Config.Concurrency > defaultRestoreStreamConcurrency { - log.Info("set restore kv files concurrency", zap.Int("concurrency", defaultRestoreStreamConcurrency)) - cfg.Config.Concurrency = defaultRestoreStreamConcurrency + if cfg.PitrConcurrency == 0 { + cfg.PitrConcurrency = defaultPiTRConcurrency + } + if cfg.PitrBatchCount == 0 { + cfg.PitrBatchCount = defaultPiTRBatchCount + } + if cfg.PitrBatchSize == 0 { + cfg.PitrBatchSize = defaultPiTRBatchSize } + // another goroutine is used to iterate the backup file + cfg.PitrConcurrency += 1 + log.Info("set restore kv files concurrency", zap.Int("concurrency", int(cfg.PitrConcurrency))) + cfg.Config.Concurrency = cfg.PitrConcurrency } func configureRestoreClient(ctx context.Context, client *restore.Client, cfg *RestoreConfig) error { @@ -424,42 +463,6 @@ func CheckRestoreDBAndTable(client *restore.Client, cfg *RestoreConfig) error { return nil } -func CheckNewCollationEnable( - backupNewCollationEnable string, - g glue.Glue, - storage kv.Storage, - CheckRequirements bool, -) error { - if backupNewCollationEnable == "" { - if CheckRequirements { - return errors.Annotatef(berrors.ErrUnknown, - "the config 'new_collations_enabled_on_first_bootstrap' not found in backupmeta. "+ - "you can use \"show config WHERE name='new_collations_enabled_on_first_bootstrap';\" to manually check the config. "+ - "if you ensure the config 'new_collations_enabled_on_first_bootstrap' in backup cluster is as same as restore cluster, "+ - "use --check-requirements=false to skip this check") - } - log.Warn("the config 'new_collations_enabled_on_first_bootstrap' is not in backupmeta") - return nil - } - - se, err := g.CreateSession(storage) - if err != nil { - return errors.Trace(err) - } - - newCollationEnable, err := se.GetGlobalVariable(tidbNewCollationEnabled) - if err != nil { - return errors.Trace(err) - } - - if !strings.EqualFold(backupNewCollationEnable, newCollationEnable) { - return errors.Annotatef(berrors.ErrUnknown, - "the config 'new_collations_enabled_on_first_bootstrap' not match, upstream:%v, downstream: %v", - backupNewCollationEnable, newCollationEnable) - } - return nil -} - func isFullRestore(cmdName string) bool { return cmdName == FullRestoreCmd } @@ -502,10 +505,7 @@ func RunRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf // according to https://github.com/pingcap/tidb/issues/34167. // we should get the real config from tikv to adapt the dynamic region. httpCli := httputil.NewClient(mgr.GetTLSConfig()) - mergeRegionSize, mergeRegionCount, err = mgr.GetMergeRegionSizeAndCount(ctx, httpCli) - if err != nil { - return errors.Trace(err) - } + mergeRegionSize, mergeRegionCount = mgr.GetMergeRegionSizeAndCount(ctx, httpCli) } keepaliveCfg.PermitWithoutStream = true @@ -531,7 +531,7 @@ func RunRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf return errors.Trace(versionErr) } } - if err = CheckNewCollationEnable(backupMeta.GetNewCollationsEnabled(), g, mgr.GetStorage(), cfg.CheckRequirements); err != nil { + if err = restore.CheckNewCollationEnable(backupMeta.GetNewCollationsEnabled(), g, mgr.GetStorage(), cfg.CheckRequirements); err != nil { return errors.Trace(err) } @@ -550,11 +550,12 @@ func RunRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf if len(dbs) == 0 && len(tables) != 0 { return errors.Annotate(berrors.ErrRestoreInvalidBackup, "contain tables but no databases") } + archiveSize := reader.ArchiveSize(ctx, files) g.Record(summary.RestoreDataSize, archiveSize) //restore from tidb will fetch a general Size issue https://github.com/pingcap/tidb/issues/27247 g.Record("Size", archiveSize) - restoreTS, err := client.GetTS(ctx) + restoreTS, err := client.GetTSWithRetry(ctx) if err != nil { return errors.Trace(err) } @@ -652,6 +653,7 @@ func RunRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf // We make bigger errCh so we won't block on multi-part failed. errCh := make(chan error, 32) + tableStream := client.GoCreateTables(ctx, mgr.GetDomain(), tables, newTS, errCh) if len(files) == 0 { log.Info("no files, empty databases and tables are restored") diff --git a/br/pkg/task/restore_data.go b/br/pkg/task/restore_data.go index 27b038110f5bb..5b177faa9c055 100644 --- a/br/pkg/task/restore_data.go +++ b/br/pkg/task/restore_data.go @@ -19,6 +19,7 @@ import ( "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/br/pkg/summary" "github.com/pingcap/tidb/br/pkg/utils" + tidbconfig "github.com/pingcap/tidb/config" "go.uber.org/zap" ) @@ -51,17 +52,17 @@ func RunResolveKvData(c context.Context, g glue.Glue, cmdName string, cfg *Resto } // read the backup meta resolved ts and total tikvs from backup storage - var resolveTs uint64 + var resolveTS uint64 _, externStorage, err := GetStorage(ctx, cfg.Config.Storage, &cfg.Config) if err != nil { return errors.Trace(err) } - resolveTs, numBackupStore, err := ReadBackupMetaData(ctx, externStorage) + resolveTS, numBackupStore, err := ReadBackupMetaData(ctx, externStorage) if err != nil { return errors.Trace(err) } - summary.CollectUint("resolve-ts", resolveTs) + summary.CollectUint("resolve-ts", resolveTS) keepaliveCfg := GetKeepalive(&cfg.Config) mgr, err := NewMgr(ctx, g, cfg.PD, cfg.TLS, keepaliveCfg, cfg.CheckRequirements, false, conn.NormalVersionChecker) @@ -71,6 +72,11 @@ func RunResolveKvData(c context.Context, g glue.Glue, cmdName string, cfg *Resto defer mgr.Close() keepaliveCfg.PermitWithoutStream = true + tc := tidbconfig.GetGlobalConfig() + tc.SkipRegisterToDashboard = true + tc.EnableGlobalKill = false + tidbconfig.StoreGlobalConfig(tc) + client := restore.NewRestoreClient(mgr.GetPDClient(), mgr.GetTLSConfig(), keepaliveCfg, false) restoreTS, err := client.GetTS(ctx) @@ -85,6 +91,8 @@ func RunResolveKvData(c context.Context, g glue.Glue, cmdName string, cfg *Resto ID: utils.MakeSafePointID(), } + // TODO: since data restore does not have tidb up, it looks we can remove this keeper + // it requires to do more test, then remove this part of code. err = utils.StartServiceSafePointKeeper(ctx, mgr.GetPDClient(), sp) if err != nil { return errors.Trace(err) @@ -131,14 +139,14 @@ func RunResolveKvData(c context.Context, g glue.Glue, cmdName string, cfg *Resto } log.Debug("total tikv", zap.Int("total", numBackupStore), zap.String("progress file", cfg.ProgressFile)) - // progress = read meta + send recovery + iterate tikv + resolve kv data. + // progress = read meta + send recovery + iterate tikv + flashback. progress := g.StartProgress(ctx, cmdName, int64(numBackupStore*4), !cfg.LogProgress) go progressFileWriterRoutine(ctx, progress, int64(numBackupStore*4), cfg.ProgressFile) // restore tikv data from a snapshot volume var totalRegions int - totalRegions, err = restore.RecoverData(ctx, resolveTs, allStores, mgr, progress) + totalRegions, err = restore.RecoverData(ctx, resolveTS, allStores, mgr, progress, restoreTS, cfg.Concurrency) if err != nil { return errors.Trace(err) } @@ -151,7 +159,23 @@ func RunResolveKvData(c context.Context, g glue.Glue, cmdName string, cfg *Resto //TODO: restore volume type into origin type //ModifyVolume(*ec2.ModifyVolumeInput) (*ec2.ModifyVolumeOutput, error) by backupmeta + // this is used for cloud restoration + err = client.Init(g, mgr.GetStorage()) + if err != nil { + return errors.Trace(err) + } + defer client.Close() + log.Info("start to clear system user for cloud") + err = client.ClearSystemUsers(ctx, cfg.ResetSysUsers) + + if err != nil { + return errors.Trace(err) + } + // since we cannot reset tiflash automaticlly. so we should start it manually + if err = client.ResetTiFlashReplicas(ctx, g, mgr.GetStorage()); err != nil { + return errors.Trace(err) + } progress.Close() summary.CollectDuration("restore duration", time.Since(startAll)) summary.SetSuccessStatus(true) diff --git a/br/pkg/task/restore_raw.go b/br/pkg/task/restore_raw.go index 6c15cd9989512..7b80ac18b4d87 100644 --- a/br/pkg/task/restore_raw.go +++ b/br/pkg/task/restore_raw.go @@ -80,10 +80,7 @@ func RunRestoreRaw(c context.Context, g glue.Glue, cmdName string, cfg *RestoreR // according to https://github.com/pingcap/tidb/issues/34167. // we should get the real config from tikv to adapt the dynamic region. httpCli := httputil.NewClient(mgr.GetTLSConfig()) - mergeRegionSize, mergeRegionCount, err = mgr.GetMergeRegionSizeAndCount(ctx, httpCli) - if err != nil { - return errors.Trace(err) - } + mergeRegionSize, mergeRegionCount = mgr.GetMergeRegionSizeAndCount(ctx, httpCli) } keepaliveCfg := GetKeepalive(&cfg.Config) diff --git a/br/pkg/task/restore_test.go b/br/pkg/task/restore_test.go index 94bbcb3c3692c..b13ecf0eccc08 100644 --- a/br/pkg/task/restore_test.go +++ b/br/pkg/task/restore_test.go @@ -63,6 +63,16 @@ func TestConfigureRestoreClient(t *testing.T) { require.True(t, client.IsOnline()) } +func TestAdjustRestoreConfigForStreamRestore(t *testing.T) { + restoreCfg := RestoreConfig{} + + restoreCfg.adjustRestoreConfigForStreamRestore() + require.Equal(t, restoreCfg.PitrBatchCount, uint32(defaultPiTRBatchCount)) + require.Equal(t, restoreCfg.PitrBatchSize, uint32(defaultPiTRBatchSize)) + require.Equal(t, restoreCfg.PitrConcurrency, uint32(defaultPiTRConcurrency)) + require.Equal(t, restoreCfg.Concurrency, restoreCfg.PitrConcurrency) +} + func TestCheckRestoreDBAndTable(t *testing.T) { cases := []struct { cfgSchemas map[string]struct{} diff --git a/br/pkg/task/stream.go b/br/pkg/task/stream.go index 9a1a06eff9693..2ffa7bc7dd9af 100644 --- a/br/pkg/task/stream.go +++ b/br/pkg/task/stream.go @@ -307,6 +307,8 @@ func NewStreamMgr(ctx context.Context, cfg *StreamConfig, g glue.Glue, isStreamS mgr: mgr, } if isStreamStart { + client := backup.NewBackupClient(ctx, mgr) + backend, err := storage.ParseBackend(cfg.Storage, &cfg.BackendOptions) if err != nil { return nil, errors.Trace(err) @@ -316,11 +318,6 @@ func NewStreamMgr(ctx context.Context, cfg *StreamConfig, g glue.Glue, isStreamS NoCredentials: cfg.NoCreds, SendCredentials: cfg.SendCreds, } - client, err := backup.NewBackupClient(ctx, mgr) - if err != nil { - return nil, errors.Trace(err) - } - if err = client.SetStorage(ctx, backend, &opts); err != nil { return nil, errors.Trace(err) } @@ -336,6 +333,10 @@ func (s *streamMgr) close() { s.mgr.Close() } +func (s *streamMgr) checkLock(ctx context.Context) (bool, error) { + return s.bc.GetStorage().FileExists(ctx, metautil.LockFile) +} + func (s *streamMgr) setLock(ctx context.Context) error { return s.bc.SetLockFile(ctx) } @@ -352,7 +353,7 @@ func (s *streamMgr) adjustAndCheckStartTS(ctx context.Context) error { s.cfg.StartTS = currentTS } - if currentTS < s.cfg.StartTS || s.cfg.EndTS <= currentTS { + if currentTS < s.cfg.StartTS { return errors.Annotatef(berrors.ErrInvalidArgument, "invalid timestamps, startTS %d should be smaller than currentTS %d", s.cfg.StartTS, currentTS) @@ -423,7 +424,7 @@ func (s *streamMgr) backupFullSchemas(ctx context.Context, g glue.Glue) error { } schemasConcurrency := uint(mathutil.Min(backup.DefaultSchemaConcurrency, schemas.Len())) - err = schemas.BackupSchemas(ctx, metaWriter, s.mgr.GetStorage(), nil, + err = schemas.BackupSchemas(ctx, metaWriter, nil, s.mgr.GetStorage(), nil, s.cfg.StartTS, schemasConcurrency, 0, true, nil) if err != nil { return errors.Trace(err) @@ -435,6 +436,61 @@ func (s *streamMgr) backupFullSchemas(ctx context.Context, g glue.Glue) error { return nil } +func (s *streamMgr) checkStreamStartEnable(g glue.Glue) error { + se, err := g.CreateSession(s.mgr.GetStorage()) + if err != nil { + return errors.Trace(err) + } + execCtx := se.GetSessionCtx().(sqlexec.RestrictedSQLExecutor) + supportStream, err := utils.IsLogBackupEnabled(execCtx) + if err != nil { + return errors.Trace(err) + } + if !supportStream { + return errors.New("Unable to create task about log-backup. " + + "please set TiKV config `log-backup.enable` to true and restart TiKVs.") + } + if !ddl.IngestJobsNotExisted(se.GetSessionCtx()) { + return errors.Annotate(berrors.ErrUnknown, + "Unable to create log backup task. Please wait until the DDL jobs(add index with ingest method) are finished.") + } + + return nil +} + +type RestoreFunc func() error + +// KeepGcDisabled keeps GC disabled and return a function that used to gc enabled. +// gc.ratio-threshold = "-1.0", which represents disable gc in TiKV. +func KeepGcDisabled(g glue.Glue, store kv.Storage) (RestoreFunc, error) { + se, err := g.CreateSession(store) + if err != nil { + return nil, errors.Trace(err) + } + + execCtx := se.GetSessionCtx().(sqlexec.RestrictedSQLExecutor) + oldRatio, err := utils.GetGcRatio(execCtx) + if err != nil { + return nil, errors.Trace(err) + } + + newRatio := "-1.0" + err = utils.SetGcRatio(execCtx, newRatio) + if err != nil { + return nil, errors.Trace(err) + } + + // If the oldRatio is negative, which is not normal status. + // It should set default value "1.1" after PiTR finished. + if strings.HasPrefix(oldRatio, "-") { + oldRatio = "1.1" + } + + return func() error { + return utils.SetGcRatio(execCtx, oldRatio) + }, nil +} + // RunStreamCommand run all kinds of `stream task` func RunStreamCommand( ctx context.Context, @@ -485,38 +541,13 @@ func RunStreamStart( } defer streamMgr.close() - se, err := g.CreateSession(streamMgr.mgr.GetStorage()) - if err != nil { + if err = streamMgr.checkStreamStartEnable(g); err != nil { return errors.Trace(err) } - execCtx := se.GetSessionCtx().(sqlexec.RestrictedSQLExecutor) - supportStream, err := utils.IsLogBackupEnabled(execCtx) - if err != nil { - return errors.Trace(err) - } - if !supportStream { - return errors.New("Unable to create task about log-backup. " + - "please set TiKV config `log-backup.enable` to true and restart TiKVs.") - } - if !ddl.IngestJobsNotExisted(se.GetSessionCtx()) { - return errors.Annotate(berrors.ErrUnknown, "Unable to create log backup task. Please wait until the DDL jobs(add index with ingest method) are finished.") - } - if err = streamMgr.adjustAndCheckStartTS(ctx); err != nil { return errors.Trace(err) } - if err = streamMgr.setGCSafePoint( - ctx, - utils.BRServiceSafePoint{ - ID: utils.MakeSafePointID(), - TTL: cfg.SafePointTTL, - BackupTS: cfg.StartTS, - }, - ); err != nil { - return errors.Trace(err) - } - cli := streamhelper.NewMetaDataClient(streamMgr.mgr.GetDomain().GetEtcdClient()) // It supports single stream log task currently. if count, err := cli.GetTaskCount(ctx); err != nil { @@ -525,12 +556,50 @@ func RunStreamStart( return errors.Annotate(berrors.ErrStreamLogTaskExist, "It supports single stream log task currently") } - if err = streamMgr.setLock(ctx); err != nil { + exist, err := streamMgr.checkLock(ctx) + if err != nil { return errors.Trace(err) } + // exist is true, which represents restart a stream task. Or create a new stream task. + if exist { + logInfo, err := getLogRange(ctx, &cfg.Config) + if err != nil { + return errors.Trace(err) + } + if logInfo.clusterID > 0 && logInfo.clusterID != streamMgr.bc.GetClusterID() { + return errors.Annotatef(berrors.ErrInvalidArgument, + "the stream log files from cluster ID:%v and current cluster ID:%v ", + logInfo.clusterID, streamMgr.bc.GetClusterID()) + } - if err = streamMgr.backupFullSchemas(ctx, g); err != nil { - return errors.Trace(err) + cfg.StartTS = logInfo.logMaxTS + if err = streamMgr.setGCSafePoint( + ctx, + utils.BRServiceSafePoint{ + ID: utils.MakeSafePointID(), + TTL: cfg.SafePointTTL, + BackupTS: cfg.StartTS, + }, + ); err != nil { + return errors.Trace(err) + } + } else { + if err = streamMgr.setGCSafePoint( + ctx, + utils.BRServiceSafePoint{ + ID: utils.MakeSafePointID(), + TTL: cfg.SafePointTTL, + BackupTS: cfg.StartTS, + }, + ); err != nil { + return errors.Trace(err) + } + if err = streamMgr.setLock(ctx); err != nil { + return errors.Trace(err) + } + if err = streamMgr.backupFullSchemas(ctx, g); err != nil { + return errors.Trace(err) + } } ranges, err := streamMgr.buildObserveRanges(ctx) @@ -556,7 +625,6 @@ func RunStreamStart( Ranges: ranges, Pausing: false, } - if err = cli.PutTask(ctx, ti); err != nil { return errors.Trace(err) } @@ -636,7 +704,7 @@ func RunStreamStop( if err := streamMgr.setGCSafePoint(ctx, utils.BRServiceSafePoint{ ID: buildPauseSafePointName(ti.Info.Name), - TTL: 0, + TTL: utils.DefaultStreamStartSafePointTTL, BackupTS: 0, }, ); err != nil { @@ -690,7 +758,7 @@ func RunStreamPause( utils.BRServiceSafePoint{ ID: buildPauseSafePointName(ti.Info.Name), TTL: cfg.SafePointTTL, - BackupTS: globalCheckPointTS - 1, + BackupTS: globalCheckPointTS, }, ); err != nil { return errors.Trace(err) @@ -763,7 +831,7 @@ func RunStreamResume( if err := streamMgr.setGCSafePoint(ctx, utils.BRServiceSafePoint{ ID: buildPauseSafePointName(ti.Info.Name), - TTL: 0, + TTL: utils.DefaultStreamStartSafePointTTL, BackupTS: globalCheckPointTS, }, ); err != nil { @@ -896,31 +964,24 @@ func RunStreamTruncate(c context.Context, g glue.Glue, cmdName string, cfg *Stre readMetaDone := console.ShowTask("Reading Metadata... ", glue.WithTimeCost()) metas := restore.StreamMetadataSet{ Helper: stream.NewMetadataHelper(), - BeforeDoWriteBack: func(path string, last, current *backuppb.Metadata) (skip bool) { - log.Info("Updating metadata.", zap.String("file", path), - zap.Int("data-file-before", len(last.GetFileGroups())), - zap.Int("data-file-after", len(current.GetFileGroups()))) - return cfg.DryRun - }, + DryRun: cfg.DryRun, } - if err := metas.LoadUntil(ctx, storage, cfg.Until); err != nil { + shiftUntilTS, err := metas.LoadUntilAndCalculateShiftTS(ctx, storage, cfg.Until) + if err != nil { return err } readMetaDone() var ( - fileCount uint64 = 0 - kvCount int64 = 0 - totalSize uint64 = 0 - shiftUntilTS = metas.CalculateShiftTS(cfg.Until) + fileCount int = 0 + kvCount int64 = 0 + totalSize uint64 = 0 ) - metas.IterateFilesFullyBefore(shiftUntilTS, func(d *backuppb.DataFileGroup) (shouldBreak bool) { + metas.IterateFilesFullyBefore(shiftUntilTS, func(d *restore.FileGroupInfo) (shouldBreak bool) { fileCount++ totalSize += d.Length - for _, f := range d.DataFilesInfo { - kvCount += f.NumberOfEntries - } + kvCount += d.KVCount return }) console.Printf("We are going to remove %s files, until %s.\n", @@ -938,40 +999,38 @@ func RunStreamTruncate(c context.Context, g glue.Glue, cmdName string, cfg *Stre } } - removed := metas.RemoveDataBefore(shiftUntilTS) - - // remove log - clearDataFileDone := console.ShowTask( - "Clearing data files... ", glue.WithTimeCost(), + // begin to remove + p := console.StartProgressBar( + "Clearing Data Files and Metadata", fileCount, + glue.WithTimeCost(), glue.WithConstExtraField("kv-count", kvCount), glue.WithConstExtraField("kv-size", fmt.Sprintf("%d(%s)", totalSize, units.HumanSize(float64(totalSize)))), ) - worker := utils.NewWorkerPool(128, "delete files") - wg := new(sync.WaitGroup) - for _, f := range removed { - if !cfg.DryRun { - wg.Add(1) - finalFile := f - worker.Apply(func() { - defer wg.Done() - if err := storage.DeleteFile(ctx, finalFile.Path); err != nil { - log.Warn("File not deleted.", zap.String("path", finalFile.Path), logutil.ShortError(err)) - console.Print("\n"+em(finalFile.Path), "not deleted, you may clear it manually:", warn(err)) - } - }) - } + defer p.Close() + + notDeleted, err := metas.RemoveDataFilesAndUpdateMetadataInBatch(ctx, shiftUntilTS, storage, p.IncBy) + if err != nil { + return err } - wg.Wait() - clearDataFileDone() - // remove metadata - removeMetaDone := console.ShowTask("Removing metadata... ", glue.WithTimeCost()) - if !cfg.DryRun { - if err := metas.DoWriteBack(ctx, storage); err != nil { - return err + if err := p.Wait(ctx); err != nil { + return err + } + + if len(notDeleted) > 0 { + const keepFirstNFailure = 16 + console.Println("Files below are not deleted due to error, you may clear it manually, check log for detail error:") + console.Println("- Total", em(len(notDeleted)), "items.") + if len(notDeleted) > keepFirstNFailure { + console.Println("-", em(len(notDeleted)-keepFirstNFailure), "items omitted.") + // TODO: maybe don't add them at the very first. + notDeleted = notDeleted[:keepFirstNFailure] + } + for _, f := range notDeleted { + console.Println(f) } } - removeMetaDone() + return nil } @@ -1103,7 +1162,7 @@ func restoreStream( } defer client.Close() - currentTS, err := client.GetTS(ctx) + currentTS, err := client.GetTSWithRetry(ctx) if err != nil { return errors.Trace(err) } @@ -1117,31 +1176,21 @@ func restoreStream( // mode or emptied schedulers defer restorePostWork(ctx, client, restoreSchedulers) - shiftStartTS, err := client.GetShiftTS(ctx, cfg.StartTS, cfg.RestoreTS) - if err != nil { - return errors.Annotate(err, "failed to get shift TS") - } - - // read meta by given ts. - metas, err := client.ReadStreamMetaByTS(ctx, shiftStartTS, cfg.RestoreTS) + // It need disable GC in TiKV when PiTR. + // because the process of PITR is concurrent and kv events isn't sorted by tso. + restoreGc, err := KeepGcDisabled(g, mgr.GetStorage()) if err != nil { return errors.Trace(err) } - if len(metas) == 0 { - log.Info("nothing to restore.") - return nil - } - - client.SetRestoreRangeTS(cfg.StartTS, cfg.RestoreTS, shiftStartTS) + defer func() { + if err := restoreGc(); err != nil { + log.Error("failed to set gc enabled", zap.Error(err)) + } + }() - // read data file by given ts. - dmlFiles, ddlFiles, err := client.ReadStreamDataFiles(ctx, metas) + err = client.InstallLogFileManager(ctx, cfg.StartTS, cfg.RestoreTS) if err != nil { - return errors.Trace(err) - } - if len(dmlFiles) == 0 && len(ddlFiles) == 0 { - log.Info("nothing to restore.") - return nil + return err } // get full backup meta to generate rewrite rules. @@ -1173,6 +1222,11 @@ func restoreStream( totalKVCount += kvCount totalSize += size } + dataFileCount := 0 + ddlFiles, err := client.LoadDDLFilesAndCountDMLFiles(ctx, &dataFileCount) + if err != nil { + return err + } pm := g.StartProgress(ctx, "Restore Meta Files", int64(len(ddlFiles)), !cfg.LogProgress) if err = withProgress(pm, func(p glue.Progress) error { client.RunGCRowsLoader(ctx) @@ -1188,9 +1242,17 @@ func restoreStream( } updateRewriteRules(rewriteRules, schemasReplace) - pd := g.StartProgress(ctx, "Restore KV Files", int64(len(dmlFiles)), !cfg.LogProgress) + logFilesIter, err := client.LoadDMLFiles(ctx) + if err != nil { + return errors.Trace(err) + } + logFilesIterWithSplit, err := client.WrapLogFilesIterWithSplitHelper(logFilesIter, rewriteRules, g, mgr.GetStorage()) + if err != nil { + return errors.Trace(err) + } + pd := g.StartProgress(ctx, "Restore KV Files", int64(dataFileCount), !cfg.LogProgress) err = withProgress(pd, func(p glue.Progress) error { - return client.RestoreKVFiles(ctx, rewriteRules, dmlFiles, updateStats, p.Inc) + return client.RestoreKVFiles(ctx, rewriteRules, logFilesIterWithSplit, cfg.PitrBatchCount, cfg.PitrBatchSize, updateStats, p.IncBy) }) if err != nil { return errors.Annotate(err, "failed to restore kv files") @@ -1275,8 +1337,6 @@ func createRestoreClient(ctx context.Context, g glue.Glue, cfg *RestoreConfig, m return nil, errors.Trace(err) } - client.InitMetadataHelper() - return client, nil } @@ -1336,6 +1396,11 @@ func getLogRange( if err = backupMeta.Unmarshal(metaData); err != nil { return backupLogInfo{}, errors.Trace(err) } + // endVersion > 0 represents that the storage has been used for `br backup` + if backupMeta.GetEndVersion() > 0 { + return backupLogInfo{}, errors.Annotate(berrors.ErrStorageUnknown, + "the storage has been used for full backup") + } logStartTS := backupMeta.GetStartVersion() // truncateTS: get log truncate ts from TruncateSafePointFileName. @@ -1533,7 +1598,7 @@ func initRewriteRules(client *restore.Client, tables map[int64]*metautil.Table) zap.Stringer("database", t.DB.Name), zap.Int("old-id", int(t.Info.ID)), zap.Array("rewrite-rules", zapcore.ArrayMarshalerFunc(func(ae zapcore.ArrayEncoder) error { - for _, r := range rules { + for _, r := range tableRules { for _, rule := range r.Data { if err := ae.AppendObject(logutil.RewriteRuleObject(rule)); err != nil { return err diff --git a/br/pkg/task/stream_test.go b/br/pkg/task/stream_test.go index 7477e5d622096..3ef57a71a07ef 100644 --- a/br/pkg/task/stream_test.go +++ b/br/pkg/task/stream_test.go @@ -21,8 +21,11 @@ import ( "path/filepath" "testing" + "github.com/golang/protobuf/proto" "github.com/pingcap/errors" backuppb "github.com/pingcap/kvproto/pkg/brpb" + berrors "github.com/pingcap/tidb/br/pkg/errors" + "github.com/pingcap/tidb/br/pkg/metautil" "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/br/pkg/stream" "github.com/stretchr/testify/require" @@ -261,3 +264,49 @@ func TestGetGlobalCheckpointFromStorage(t *testing.T) { require.Nil(t, err) require.Equal(t, ts, uint64(99)) } + +func TestGetLogRangeWithFullBackupDir(t *testing.T) { + var fullBackupTS uint64 = 123456 + testDir := t.TempDir() + storage, err := storage.NewLocalStorage(testDir) + require.Nil(t, err) + + m := backuppb.BackupMeta{ + EndVersion: fullBackupTS, + } + data, err := proto.Marshal(&m) + require.Nil(t, err) + + err = storage.WriteFile(context.TODO(), metautil.MetaFile, data) + require.Nil(t, err) + + cfg := Config{ + Storage: testDir, + } + _, err = getLogRange(context.TODO(), &cfg) + require.Error(t, err, errors.Annotate(berrors.ErrStorageUnknown, + "the storage has been used for full backup")) +} + +func TestGetLogRangeWithLogBackupDir(t *testing.T) { + var startLogBackupTS uint64 = 123456 + testDir := t.TempDir() + storage, err := storage.NewLocalStorage(testDir) + require.Nil(t, err) + + m := backuppb.BackupMeta{ + StartVersion: startLogBackupTS, + } + data, err := proto.Marshal(&m) + require.Nil(t, err) + + err = storage.WriteFile(context.TODO(), metautil.MetaFile, data) + require.Nil(t, err) + + cfg := Config{ + Storage: testDir, + } + logInfo, err := getLogRange(context.TODO(), &cfg) + require.Nil(t, err) + require.Equal(t, logInfo.logMinTS, startLogBackupTS) +} diff --git a/br/pkg/trace/main_test.go b/br/pkg/trace/main_test.go index 3447b03df11db..299dc7a11398f 100644 --- a/br/pkg/trace/main_test.go +++ b/br/pkg/trace/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/br/pkg/utils/BUILD.bazel b/br/pkg/utils/BUILD.bazel index 0ae948d18a779..1cad8d5628dee 100644 --- a/br/pkg/utils/BUILD.bazel +++ b/br/pkg/utils/BUILD.bazel @@ -38,6 +38,7 @@ go_library( "//util", "//util/sqlexec", "@com_github_cheggaaa_pb_v3//:pb", + "@com_github_docker_go_units//:go-units", "@com_github_google_uuid//:uuid", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", @@ -79,6 +80,7 @@ go_test( ], embed = [":utils"], flaky = True, + shard_count = 20, deps = [ "//br/pkg/errors", "//br/pkg/metautil", diff --git a/br/pkg/utils/db.go b/br/pkg/utils/db.go index be2bd87a6ccb8..060df603d16cb 100644 --- a/br/pkg/utils/db.go +++ b/br/pkg/utils/db.go @@ -5,16 +5,24 @@ package utils import ( "context" "database/sql" + "strconv" "strings" "sync" + "github.com/docker/go-units" + "github.com/pingcap/errors" "github.com/pingcap/log" + "github.com/pingcap/tidb/br/pkg/logutil" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/util/sqlexec" "go.uber.org/zap" ) +const ( + tidbNewCollationEnabled = "new_collation_enabled" +) + var ( // check sql.DB and sql.Conn implement QueryExecutor and DBExecutor _ DBExecutor = &sql.DB{} @@ -71,7 +79,7 @@ func CheckLogBackupEnabled(ctx sessionctx.Context) bool { // we use `sqlexec.RestrictedSQLExecutor` as parameter because it's easy to mock. // it should return error. func IsLogBackupEnabled(ctx sqlexec.RestrictedSQLExecutor) (bool, error) { - valStr := "show config where name = 'log-backup.enable'" + valStr := "show config where name = 'log-backup.enable' and type = 'tikv'" internalCtx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBR) rows, fields, errSQL := ctx.ExecRestrictedSQL(internalCtx, nil, valStr) if errSQL != nil { @@ -94,14 +102,113 @@ func IsLogBackupEnabled(ctx sqlexec.RestrictedSQLExecutor) (bool, error) { return true, nil } -// CheckLogBackupTaskExist increases the count of log backup task. +func GetRegionSplitInfo(ctx sqlexec.RestrictedSQLExecutor) (uint64, int64) { + return GetSplitSize(ctx), GetSplitKeys(ctx) +} + +func GetSplitSize(ctx sqlexec.RestrictedSQLExecutor) uint64 { + const defaultSplitSize = 96 * 1024 * 1024 + varStr := "show config where name = 'coprocessor.region-split-size' and type = 'tikv'" + rows, fields, err := ctx.ExecRestrictedSQL( + kv.WithInternalSourceType(context.Background(), kv.InternalTxnBR), + nil, + varStr, + ) + if err != nil { + log.Warn("failed to get split size, use default value", logutil.ShortError(err)) + return defaultSplitSize + } + if len(rows) == 0 { + // use the default value + return defaultSplitSize + } + + d := rows[0].GetDatum(3, &fields[3].Column.FieldType) + splitSizeStr, err := d.ToString() + if err != nil { + log.Warn("failed to get split size, use default value", logutil.ShortError(err)) + return defaultSplitSize + } + splitSize, err := units.FromHumanSize(splitSizeStr) + if err != nil { + log.Warn("failed to get split size, use default value", logutil.ShortError(err)) + return defaultSplitSize + } + return uint64(splitSize) +} + +func GetSplitKeys(ctx sqlexec.RestrictedSQLExecutor) int64 { + const defaultSplitKeys = 960000 + varStr := "show config where name = 'coprocessor.region-split-keys' and type = 'tikv'" + rows, fields, err := ctx.ExecRestrictedSQL( + kv.WithInternalSourceType(context.Background(), kv.InternalTxnBR), + nil, + varStr, + ) + if err != nil { + log.Warn("failed to get split keys, use default value", logutil.ShortError(err)) + return defaultSplitKeys + } + if len(rows) == 0 { + // use the default value + return defaultSplitKeys + } + + d := rows[0].GetDatum(3, &fields[3].Column.FieldType) + splitKeysStr, err := d.ToString() + if err != nil { + log.Warn("failed to get split keys, use default value", logutil.ShortError(err)) + return defaultSplitKeys + } + splitKeys, err := strconv.ParseInt(splitKeysStr, 10, 64) + if err != nil { + log.Warn("failed to get split keys, use default value", logutil.ShortError(err)) + return defaultSplitKeys + } + return splitKeys +} + +func GetGcRatio(ctx sqlexec.RestrictedSQLExecutor) (string, error) { + valStr := "show config where name = 'gc.ratio-threshold' and type = 'tikv'" + rows, fields, errSQL := ctx.ExecRestrictedSQL( + kv.WithInternalSourceType(context.Background(), kv.InternalTxnBR), + nil, + valStr, + ) + if errSQL != nil { + return "", errSQL + } + if len(rows) == 0 { + // no rows mean not support log backup. + return "", nil + } + + d := rows[0].GetDatum(3, &fields[3].Column.FieldType) + return d.ToString() +} + +func SetGcRatio(ctx sqlexec.RestrictedSQLExecutor, ratio string) error { + _, _, err := ctx.ExecRestrictedSQL( + kv.WithInternalSourceType(context.Background(), kv.InternalTxnBR), + nil, + "set config tikv `gc.ratio-threshold`=%?", + ratio, + ) + if err != nil { + return errors.Annotatef(err, "failed to set config `gc.ratio-threshold`=%s", ratio) + } + log.Warn("set config tikv gc.ratio-threshold", zap.String("ratio", ratio)) + return nil +} + +// LogBackupTaskCountInc increases the count of log backup task. func LogBackupTaskCountInc() { LogBackupTaskMutex.Lock() logBackupTaskCount++ LogBackupTaskMutex.Unlock() } -// CheckLogBackupTaskExist decreases the count of log backup task. +// LogBackupTaskCountDec decreases the count of log backup task. func LogBackupTaskCountDec() { LogBackupTaskMutex.Lock() logBackupTaskCount-- @@ -117,3 +224,8 @@ func CheckLogBackupTaskExist() bool { func IsLogBackupInUse(ctx sessionctx.Context) bool { return CheckLogBackupEnabled(ctx) && CheckLogBackupTaskExist() } + +// GetTidbNewCollationEnabled returns the variable name of NewCollationEnabled. +func GetTidbNewCollationEnabled() string { + return tidbNewCollationEnabled +} diff --git a/br/pkg/utils/db_test.go b/br/pkg/utils/db_test.go index 08eac1e82594c..1004764b0d206 100644 --- a/br/pkg/utils/db_test.go +++ b/br/pkg/utils/db_test.go @@ -4,6 +4,7 @@ package utils_test import ( "context" + "strings" "testing" "github.com/pingcap/errors" @@ -35,7 +36,19 @@ func (m *mockRestrictedSQLExecutor) ExecRestrictedSQL(ctx context.Context, opts if m.errHappen { return nil, nil, errors.New("injected error") } - return m.rows, m.fields, nil + + if strings.Contains(sql, "show config") { + return m.rows, m.fields, nil + } else if strings.Contains(sql, "set config") && strings.Contains(sql, "gc.ratio-threshold") { + value := args[0].(string) + + for _, r := range m.rows { + d := types.Datum{} + d.SetString(value, "") + chunk.MutRow(r).SetDatum(3, d) + } + } + return nil, nil, nil } func TestIsLogBackupEnabled(t *testing.T) { @@ -115,3 +128,84 @@ func TestCheckLogBackupTaskExist(t *testing.T) { utils.LogBackupTaskCountDec() require.False(t, utils.CheckLogBackupTaskExist()) } + +func TestGc(t *testing.T) { + // config format: + // MySQL [(none)]> show config where name = 'gc.ratio-threshold'; + // +------+-------------------+--------------------+-------+ + // | Type | Instance | Name | Value | + // +------+-------------------+--------------------+-------+ + // | tikv | 172.16.6.46:3460 | gc.ratio-threshold | 1.1 | + // | tikv | 172.16.6.47:3460 | gc.ratio-threshold | 1.1 | + // +------+-------------------+--------------------+-------+ + fields := make([]*ast.ResultField, 4) + tps := []*types.FieldType{ + types.NewFieldType(mysql.TypeString), + types.NewFieldType(mysql.TypeString), + types.NewFieldType(mysql.TypeString), + types.NewFieldType(mysql.TypeString), + } + for i := 0; i < len(tps); i++ { + rf := new(ast.ResultField) + rf.Column = new(model.ColumnInfo) + rf.Column.FieldType = *tps[i] + fields[i] = rf + } + rows := make([]chunk.Row, 0, 2) + row := chunk.MutRowFromValues("tikv", " 127.0.0.1:20161", "log-backup.enable", "1.1").ToRow() + rows = append(rows, row) + row = chunk.MutRowFromValues("tikv", " 127.0.0.1:20162", "log-backup.enable", "1.1").ToRow() + rows = append(rows, row) + + s := &mockRestrictedSQLExecutor{rows: rows, fields: fields} + ratio, err := utils.GetGcRatio(s) + require.Nil(t, err) + require.Equal(t, ratio, "1.1") + + err = utils.SetGcRatio(s, "-1.0") + require.Nil(t, err) + ratio, err = utils.GetGcRatio(s) + require.Nil(t, err) + require.Equal(t, ratio, "-1.0") +} + +func TestRegionSplitInfo(t *testing.T) { + // config format: + // MySQL [(none)]> show config where name = 'coprocessor.region-split-size'; + // +------+-------------------+-------------------------------+-------+ + // | Type | Instance | Name | Value | + // +------+-------------------+-------------------------------+-------+ + // | tikv | 127.0.0.1:20161 | coprocessor.region-split-size | 10MB | + // +------+-------------------+-------------------------------+-------+ + // MySQL [(none)]> show config where name = 'coprocessor.region-split-keys'; + // +------+-------------------+-------------------------------+--------+ + // | Type | Instance | Name | Value | + // +------+-------------------+-------------------------------+--------+ + // | tikv | 127.0.0.1:20161 | coprocessor.region-split-keys | 100000 | + // +------+-------------------+-------------------------------+--------+ + + fields := make([]*ast.ResultField, 4) + tps := []*types.FieldType{ + types.NewFieldType(mysql.TypeString), + types.NewFieldType(mysql.TypeString), + types.NewFieldType(mysql.TypeString), + types.NewFieldType(mysql.TypeString), + } + for i := 0; i < len(tps); i++ { + rf := new(ast.ResultField) + rf.Column = new(model.ColumnInfo) + rf.Column.FieldType = *tps[i] + fields[i] = rf + } + rows := make([]chunk.Row, 0, 1) + row := chunk.MutRowFromValues("tikv", "127.0.0.1:20161", "coprocessor.region-split-size", "10MB").ToRow() + rows = append(rows, row) + s := &mockRestrictedSQLExecutor{rows: rows, fields: fields} + require.Equal(t, utils.GetSplitSize(s), uint64(10000000)) + + rows = make([]chunk.Row, 0, 1) + row = chunk.MutRowFromValues("tikv", "127.0.0.1:20161", "coprocessor.region-split-keys", "100000").ToRow() + rows = append(rows, row) + s = &mockRestrictedSQLExecutor{rows: rows, fields: fields} + require.Equal(t, utils.GetSplitKeys(s), int64(100000)) +} diff --git a/br/pkg/utils/iter/BUILD.bazel b/br/pkg/utils/iter/BUILD.bazel new file mode 100644 index 0000000000000..0e4c55ed67d56 --- /dev/null +++ b/br/pkg/utils/iter/BUILD.bazel @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "iter", + srcs = [ + "combinator_types.go", + "combinators.go", + "iter.go", + "source.go", + "source_types.go", + ], + importpath = "github.com/pingcap/tidb/br/pkg/utils/iter", + visibility = ["//visibility:public"], + deps = [ + "//br/pkg/utils", + "@org_golang_x_exp//constraints", + "@org_golang_x_sync//errgroup", + ], +) + +go_test( + name = "iter_test", + srcs = ["combinator_test.go"], + flaky = True, + race = "on", + deps = [ + ":iter", + "@com_github_stretchr_testify//require", + ], +) diff --git a/br/pkg/utils/iter/combinator_test.go b/br/pkg/utils/iter/combinator_test.go new file mode 100644 index 0000000000000..97d847f769783 --- /dev/null +++ b/br/pkg/utils/iter/combinator_test.go @@ -0,0 +1,100 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package iter_test + +import ( + "context" + "errors" + "sync/atomic" + "testing" + "time" + + "github.com/pingcap/tidb/br/pkg/utils/iter" + "github.com/stretchr/testify/require" +) + +func TestParTrans(t *testing.T) { + items := iter.OfRange(0, 200) + mapped := iter.Transform(items, func(c context.Context, i int) (int, error) { + select { + case <-c.Done(): + return 0, c.Err() + case <-time.After(100 * time.Millisecond): + } + return i + 100, nil + }, iter.WithChunkSize(128), iter.WithConcurrency(64)) + cx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + r := iter.CollectAll(cx, mapped) + require.NoError(t, r.Err) + require.Len(t, r.Item, 200) + require.Equal(t, r.Item, iter.CollectAll(cx, iter.OfRange(100, 300)).Item) +} + +func TestFilter(t *testing.T) { + items := iter.OfRange(0, 10) + items = iter.FlatMap(items, func(n int) iter.TryNextor[int] { + return iter.Map(iter.OfRange(n, 10), func(i int) int { return n * i }) + }) + items = iter.FilterOut(items, func(n int) bool { return n == 0 || (n+1)%13 != 0 }) + coll := iter.CollectAll(context.Background(), items) + require.Equal(t, []int{12, 12, 25, 64}, coll.Item, "%s", coll) +} + +func TestFailure(t *testing.T) { + items := iter.ConcatAll(iter.OfRange(0, 5), iter.Fail[int](errors.New("meow?")), iter.OfRange(5, 10)) + items = iter.FlatMap(items, func(n int) iter.TryNextor[int] { + return iter.Map(iter.OfRange(n, 10), func(i int) int { return n * i }) + }) + items = iter.FilterOut(items, func(n int) bool { return n == 0 || (n+1)%13 != 0 }) + coll := iter.CollectAll(context.Background(), items) + require.Error(t, coll.Err, "%s", coll) + require.Nil(t, coll.Item) +} + +func TestCollect(t *testing.T) { + items := iter.OfRange(0, 100) + ctx := context.Background() + coll := iter.CollectMany(ctx, items, 10) + require.Len(t, coll.Item, 10, "%s", coll) + require.Equal(t, coll.Item, iter.CollectAll(ctx, iter.OfRange(0, 10)).Item) +} + +func TestTapping(t *testing.T) { + items := iter.OfRange(0, 101) + ctx := context.Background() + n := 0 + + items = iter.Tap(items, func(i int) { n += i }) + iter.CollectAll(ctx, items) + require.Equal(t, 5050, n) +} + +func TestSome(t *testing.T) { + req := require.New(t) + it := iter.OfRange(0, 2) + c := context.Background() + req.Equal(it.TryNext(c), iter.Emit(0)) + req.Equal(it.TryNext(c), iter.Emit(1)) + req.Equal(it.TryNext(c), iter.Done[int]()) + req.Equal(it.TryNext(c), iter.Done[int]()) +} + +func TestErrorDuringTransforming(t *testing.T) { + req := require.New(t) + items := iter.OfRange(1, 20) + running := new(atomic.Int32) + items = iter.Transform(items, func(ctx context.Context, i int) (int, error) { + if i == 10 { + return 0, errors.New("meow") + } + running.Add(1) + return i, nil + }, iter.WithChunkSize(16), iter.WithConcurrency(8)) + + coll := iter.CollectAll(context.TODO(), items) + req.Greater(running.Load(), int32(8)) + // Should be melted down. + req.Less(running.Load(), int32(16)) + req.ErrorContains(coll.Err, "meow") +} diff --git a/br/pkg/utils/iter/combinator_types.go b/br/pkg/utils/iter/combinator_types.go new file mode 100644 index 0000000000000..c08f37e81a655 --- /dev/null +++ b/br/pkg/utils/iter/combinator_types.go @@ -0,0 +1,129 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package iter + +import ( + "context" + + "github.com/pingcap/tidb/br/pkg/utils" + "golang.org/x/sync/errgroup" +) + +type chunkMappingCfg struct { + chunkSize uint + quota *utils.WorkerPool +} + +type chunkMapping[T, R any] struct { + chunkMappingCfg + inner TryNextor[T] + mapper func(context.Context, T) (R, error) + + buffer fromSlice[R] +} + +func (m *chunkMapping[T, R]) fillChunk(ctx context.Context) IterResult[fromSlice[R]] { + eg, cx := errgroup.WithContext(ctx) + s := CollectMany(ctx, m.inner, m.chunkSize) + if s.FinishedOrError() { + return DoneBy[fromSlice[R]](s) + } + r := make([]R, len(s.Item)) + for i := 0; i < len(s.Item); i++ { + i := i + m.quota.ApplyOnErrorGroup(eg, func() error { + var err error + r[i], err = m.mapper(cx, s.Item[i]) + return err + }) + } + if err := eg.Wait(); err != nil { + return Throw[fromSlice[R]](err) + } + if len(r) > 0 { + return Emit(fromSlice[R](r)) + } + return Done[fromSlice[R]]() +} + +func (m *chunkMapping[T, R]) TryNext(ctx context.Context) IterResult[R] { + r := m.buffer.TryNext(ctx) + if !r.FinishedOrError() { + return Emit(r.Item) + } + + r2 := m.fillChunk(ctx) + if !r2.FinishedOrError() { + m.buffer = r2.Item + return m.TryNext(ctx) + } + + return DoneBy[R](r2) +} + +type filter[T any] struct { + inner TryNextor[T] + filterOutIf func(T) bool +} + +func (f filter[T]) TryNext(ctx context.Context) IterResult[T] { + for { + r := f.inner.TryNext(ctx) + if r.Err != nil || r.Finished || !f.filterOutIf(r.Item) { + return r + } + } +} + +type take[T any] struct { + n uint + inner TryNextor[T] +} + +func (t *take[T]) TryNext(ctx context.Context) IterResult[T] { + if t.n == 0 { + return Done[T]() + } + + t.n-- + return t.inner.TryNext(ctx) +} + +type join[T any] struct { + inner TryNextor[TryNextor[T]] + + current TryNextor[T] +} + +type pureMap[T, R any] struct { + inner TryNextor[T] + + mapper func(T) R +} + +func (p pureMap[T, R]) TryNext(ctx context.Context) IterResult[R] { + r := p.inner.TryNext(ctx) + + if r.FinishedOrError() { + return DoneBy[R](r) + } + return Emit(p.mapper(r.Item)) +} + +func (j *join[T]) TryNext(ctx context.Context) IterResult[T] { + r := j.current.TryNext(ctx) + if r.Err != nil { + j.inner = empty[TryNextor[T]]{} + return r + } + if !r.Finished { + return r + } + + nr := j.inner.TryNext(ctx) + if nr.FinishedOrError() { + return DoneBy[T](nr) + } + j.current = nr.Item + return j.TryNext(ctx) +} diff --git a/br/pkg/utils/iter/combinators.go b/br/pkg/utils/iter/combinators.go new file mode 100644 index 0000000000000..e852add07d7a4 --- /dev/null +++ b/br/pkg/utils/iter/combinators.go @@ -0,0 +1,94 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package iter + +import ( + "context" + + "github.com/pingcap/tidb/br/pkg/utils" +) + +// TransformConfig is the config for the combinator "transform". +type TransformConfig func(*chunkMappingCfg) + +func WithConcurrency(n uint) TransformConfig { + return func(c *chunkMappingCfg) { + c.quota = utils.NewWorkerPool(n, "transforming") + } +} + +func WithChunkSize(n uint) TransformConfig { + return func(c *chunkMappingCfg) { + c.chunkSize = n + } +} + +// Transform returns an iterator that performs an impure procedure for each element, +// then emitting the result of that procedure. +// The execution of that procedure can be paralleled with the config `WithConcurrency`. +// You may also need to config the `WithChunkSize`, because the concurrent execution is only available intra-batch. +func Transform[T, R any](it TryNextor[T], with func(context.Context, T) (R, error), cs ...TransformConfig) TryNextor[R] { + r := &chunkMapping[T, R]{ + inner: it, + mapper: with, + chunkMappingCfg: chunkMappingCfg{ + chunkSize: 1, + }, + } + for _, c := range cs { + c(&r.chunkMappingCfg) + } + if r.quota == nil { + r.quota = utils.NewWorkerPool(r.chunkSize, "max-concurrency") + } + if r.quota.Limit() > int(r.chunkSize) { + r.chunkSize = uint(r.quota.Limit()) + } + return r +} + +// FilterOut returns an iterator that yields all elements the original iterator +// generated and DOESN'T satisfies the predicate. +func FilterOut[T any](it TryNextor[T], f func(T) bool) TryNextor[T] { + return filter[T]{ + inner: it, + filterOutIf: f, + } +} + +// TakeFirst takes the first n elements of the iterator. +func TakeFirst[T any](inner TryNextor[T], n uint) TryNextor[T] { + return &take[T]{ + n: n, + inner: inner, + } +} + +// FlapMap applies the mapper over every elements the origin iterator generates, +// then flatten them. +func FlatMap[T, R any](it TryNextor[T], mapper func(T) TryNextor[R]) TryNextor[R] { + return &join[R]{ + inner: pureMap[T, TryNextor[R]]{ + inner: it, + mapper: mapper, + }, + current: empty[R]{}, + } +} + +// Map applies the mapper over every elements the origin iterator yields. +func Map[T, R any](it TryNextor[T], mapper func(T) R) TryNextor[R] { + return pureMap[T, R]{ + inner: it, + mapper: mapper, + } +} + +// ConcatAll concatenates all elements yields by the iterators. +// In another word, it 'chains' all the input iterators. +func ConcatAll[T any](items ...TryNextor[T]) TryNextor[T] { + return &join[T]{ + inner: FromSlice(items), + current: empty[T]{}, + } +} diff --git a/br/pkg/utils/iter/iter.go b/br/pkg/utils/iter/iter.go new file mode 100644 index 0000000000000..069b37c4f369e --- /dev/null +++ b/br/pkg/utils/iter/iter.go @@ -0,0 +1,111 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package iter + +import ( + "context" + "fmt" +) + +// IterResult is the result of try to advancing an impure iterator. +// Generally it is a "sum type", which only one field would be filled. +// You can create it via `Done`, `Emit` and `Throw`. +type IterResult[T any] struct { + Item T + Err error + Finished bool +} + +func (r IterResult[T]) String() string { + if r.Err != nil { + return fmt.Sprintf("IterResult.Throw(%s)", r.Err) + } + if r.Finished { + return "IterResult.Done()" + } + return fmt.Sprintf("IterResult.Emit(%v)", r.Item) +} + +// TryNextor is the general interface for "impure" iterators: +// which may trigger some error or block the caller when advancing. +type TryNextor[T any] interface { + TryNext(ctx context.Context) IterResult[T] +} + +func (r IterResult[T]) FinishedOrError() bool { + return r.Err != nil || r.Finished +} + +// DoneBy creates a finished or error IterResult by its argument. +func DoneBy[T, O any](r IterResult[O]) IterResult[T] { + return IterResult[T]{ + Err: r.Err, + Finished: r.Finished, + } +} + +// Done creates an IterResult which indices the iteration has finished. +func Done[T any]() IterResult[T] { + return IterResult[T]{ + Finished: true, + } +} + +// Emit creates an IterResult which contains normal data. +func Emit[T any](t T) IterResult[T] { + return IterResult[T]{ + Item: t, + } +} + +// Throw creates an IterResult which contains the err. +func Throw[T any](err error) IterResult[T] { + return IterResult[T]{ + Err: err, + } +} + +// CollectMany collects the first n items of the iterator. +// When the iterator contains less data than N, it emits as many items as it can and won't set `Finished`. +func CollectMany[T any](ctx context.Context, it TryNextor[T], n uint) IterResult[[]T] { + return CollectAll(ctx, TakeFirst(it, n)) +} + +// CollectAll fully consumes the iterator, collecting all items the iterator emitted. +// When the iterator has been finished, it emits empty slice and won't set `Finished`. +func CollectAll[T any](ctx context.Context, it TryNextor[T]) IterResult[[]T] { + r := IterResult[[]T]{} + + for ir := it.TryNext(ctx); !ir.Finished; ir = it.TryNext(ctx) { + if ir.Err != nil { + return DoneBy[[]T](ir) + } + r.Item = append(r.Item, ir.Item) + } + return r +} + +type tap[T any] struct { + inner TryNextor[T] + + tapper func(T) +} + +func (t tap[T]) TryNext(ctx context.Context) IterResult[T] { + n := t.inner.TryNext(ctx) + if n.FinishedOrError() { + return n + } + + t.tapper(n.Item) + return Emit(n.Item) +} + +// Tap adds a hook into the iterator, it would execute the function +// anytime the iterator emits an item. +func Tap[T any](i TryNextor[T], with func(T)) TryNextor[T] { + return tap[T]{ + inner: i, + tapper: with, + } +} diff --git a/br/pkg/utils/iter/source.go b/br/pkg/utils/iter/source.go new file mode 100644 index 0000000000000..f2ea2fd8fb173 --- /dev/null +++ b/br/pkg/utils/iter/source.go @@ -0,0 +1,28 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package iter + +import ( + "golang.org/x/exp/constraints" +) + +// FromSlice creates an iterator from a slice, the iterator would +func FromSlice[T any](s []T) TryNextor[T] { + sa := fromSlice[T](s) + return &sa +} + +// OfRange creates an iterator that yields elements in the integer range. +func OfRange[T constraints.Integer](begin, end T) TryNextor[T] { + return &ofRange[T]{ + end: end, + endExclusive: true, + + current: begin, + } +} + +// Fail creates an iterator always fail. +func Fail[T any](err error) TryNextor[T] { + return failure[T]{error: err} +} diff --git a/br/pkg/utils/iter/source_types.go b/br/pkg/utils/iter/source_types.go new file mode 100644 index 0000000000000..41e9810de5286 --- /dev/null +++ b/br/pkg/utils/iter/source_types.go @@ -0,0 +1,52 @@ +// Copyright 2022 PingCAP, Inc. Licensed under Apache-2.0. + +package iter + +import ( + "context" + + "golang.org/x/exp/constraints" +) + +type fromSlice[T any] []T + +func (s *fromSlice[T]) TryNext(ctx context.Context) IterResult[T] { + if s == nil || len(*s) == 0 { + return Done[T]() + } + + var item T + item, *s = (*s)[0], (*s)[1:] + return Emit(item) +} + +type ofRange[T constraints.Integer] struct { + end T + endExclusive bool + + current T +} + +func (r *ofRange[T]) TryNext(ctx context.Context) IterResult[T] { + if r.current > r.end || (r.current == r.end && r.endExclusive) { + return Done[T]() + } + + result := Emit(r.current) + r.current++ + return result +} + +type empty[T any] struct{} + +func (empty[T]) TryNext(ctx context.Context) IterResult[T] { + return Done[T]() +} + +type failure[T any] struct { + error +} + +func (f failure[T]) TryNext(ctx context.Context) IterResult[T] { + return Throw[T](f) +} diff --git a/br/pkg/utils/key.go b/br/pkg/utils/key.go index 062f4b5aac52d..62d194ca57a2e 100644 --- a/br/pkg/utils/key.go +++ b/br/pkg/utils/key.go @@ -163,7 +163,7 @@ func CloneSlice[T any](s []T) []T { // toClampIn: |_____| |____| |________________| // result: |_____| |_| |______________| // we are assuming the arguments are sorted by the start key and no overlaps. -// you can call CollapseRanges to get key ranges fits this requirements. +// you can call spans.Collapse to get key ranges fits this requirements. // Note: this algorithm is pretty like the `checkIntervalIsSubset`, can we get them together? func IntersectAll(s1 []kv.KeyRange, s2 []kv.KeyRange) []kv.KeyRange { currentClamping := 0 diff --git a/br/pkg/utils/main_test.go b/br/pkg/utils/main_test.go index b575947bf44f8..f1a0e7c1e39e5 100644 --- a/br/pkg/utils/main_test.go +++ b/br/pkg/utils/main_test.go @@ -24,6 +24,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } testsetup.SetupForCommonTest() diff --git a/br/pkg/version/BUILD.bazel b/br/pkg/version/BUILD.bazel index 8171081ae5df1..7a15014e378e6 100644 --- a/br/pkg/version/BUILD.bazel +++ b/br/pkg/version/BUILD.bazel @@ -10,7 +10,6 @@ go_library( "//br/pkg/logutil", "//br/pkg/utils", "//br/pkg/version/build", - "//sessionctx/variable", "//util/engine", "@com_github_coreos_go_semver//semver", "@com_github_pingcap_errors//:errors", @@ -29,7 +28,6 @@ go_test( flaky = True, deps = [ "//br/pkg/version/build", - "//sessionctx/variable", "@com_github_coreos_go_semver//semver", "@com_github_data_dog_go_sqlmock//:go-sqlmock", "@com_github_pingcap_kvproto//pkg/metapb", diff --git a/br/pkg/version/version.go b/br/pkg/version/version.go index ba3551f58b463..9cb974d48e13f 100644 --- a/br/pkg/version/version.go +++ b/br/pkg/version/version.go @@ -18,7 +18,6 @@ import ( "github.com/pingcap/tidb/br/pkg/logutil" "github.com/pingcap/tidb/br/pkg/utils" "github.com/pingcap/tidb/br/pkg/version/build" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/util/engine" pd "github.com/tikv/pd/client" "go.uber.org/zap" @@ -32,6 +31,10 @@ var ( compatibleTiFlashMajor4 = semver.New("4.0.0") versionHash = regexp.MustCompile("-[0-9]+-g[0-9a-f]{7,}") + + checkpointSupportError error = nil + // pitrSupportBatchKVFiles specifies whether TiKV-server supports batch PITR. + pitrSupportBatchKVFiles bool = false ) // NextMajorVersion returns the next major version. @@ -134,6 +137,12 @@ func CheckVersionForBRPiTR(s *metapb.Store, tikvVersion *semver.Version) error { return errors.Annotatef(berrors.ErrVersionMismatch, "TiKV node %s version %s is too low when use PiTR, please update tikv's version to at least v6.1.0(v6.2.0+ recommanded)", s.Address, tikvVersion) } + // If tikv version < 6.5, PITR do not support restoring batch kv files. + if tikvVersion.Major < 6 || (tikvVersion.Major == 6 && tikvVersion.Minor < 5) { + pitrSupportBatchKVFiles = false + } else { + pitrSupportBatchKVFiles = true + } // The versions of BR and TiKV should be the same when use BR 6.1.0 if BRVersion.Major == 6 && BRVersion.Minor == 1 { @@ -148,7 +157,6 @@ func CheckVersionForBRPiTR(s *metapb.Store, tikvVersion *semver.Version) error { s.Address, tikvVersion, build.ReleaseVersion) } } - return nil } @@ -157,9 +165,7 @@ func CheckVersionForDDL(s *metapb.Store, tikvVersion *semver.Version) error { // use tikvVersion instead of tidbVersion since br doesn't have mysql client to connect tidb. requireVersion := semver.New("6.2.0-alpha") if tikvVersion.Compare(*requireVersion) < 0 { - log.Info("detected the old version of tidb cluster. set enable concurrent ddl to false") - variable.EnableConcurrentDDL.Store(false) - return nil + return errors.Errorf("detected the old version of tidb cluster, require: >= 6.2.0, but got %s", tikvVersion.String()) } return nil } @@ -199,6 +205,14 @@ func CheckVersionForBR(s *metapb.Store, tikvVersion *semver.Version) error { } } + // reset the checkpoint support error + checkpointSupportError = nil + if tikvVersion.Major < 6 || (tikvVersion.Major == 6 && tikvVersion.Minor < 5) { + // checkpoint mode only support after v6.5.0 + checkpointSupportError = errors.Annotatef(berrors.ErrVersionMismatch, "TiKV node %s version %s is too low when use checkpoint, please update tikv's version to at least v6.5.0", + s.Address, tikvVersion) + } + // don't warn if we are the master build, which always have the version v4.0.0-beta.2-* if build.GitBranch != "master" && tikvVersion.Compare(*BRVersion) > 0 { log.Warn(fmt.Sprintf("BR version is outdated, please consider use version %s of BR", tikvVersion)) @@ -306,6 +320,14 @@ func FetchVersion(ctx context.Context, db utils.QueryExecutor) (string, error) { return versionInfo, nil } +func CheckCheckpointSupport() error { + return checkpointSupportError +} + +func CheckPITRSupportBatchKVFiles() bool { + return pitrSupportBatchKVFiles +} + type ServerType int const ( diff --git a/br/pkg/version/version_test.go b/br/pkg/version/version_test.go index f70a2074be0ec..927eeee119d5b 100644 --- a/br/pkg/version/version_test.go +++ b/br/pkg/version/version_test.go @@ -13,7 +13,6 @@ import ( "github.com/coreos/go-semver/semver" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/tidb/br/pkg/version/build" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/stretchr/testify/require" pd "github.com/tikv/pd/client" ) @@ -76,6 +75,15 @@ func TestCheckClusterVersion(t *testing.T) { require.Regexp(t, `^TiKV .* version mismatch when use PiTR v6.2.0\+, please `, err.Error()) } + { + // Default value of `pitrSupportBatchKVFiles` should be `false`. + build.ReleaseVersion = "v6.5.0" + mock.getAllStores = func() []*metapb.Store { + return []*metapb.Store{{Version: `v6.2.0`}} + } + require.Equal(t, CheckPITRSupportBatchKVFiles(), false) + } + { build.ReleaseVersion = "v6.2.0" mock.getAllStores = func() []*metapb.Store { @@ -83,6 +91,29 @@ func TestCheckClusterVersion(t *testing.T) { } err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBRPiTR) require.NoError(t, err) + require.Equal(t, CheckPITRSupportBatchKVFiles(), false) + } + + { + pitrSupportBatchKVFiles = true + build.ReleaseVersion = "v6.2.0" + mock.getAllStores = func() []*metapb.Store { + return []*metapb.Store{{Version: `v6.4.0`}} + } + err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBRPiTR) + require.NoError(t, err) + require.Equal(t, CheckPITRSupportBatchKVFiles(), false) + } + + { + pitrSupportBatchKVFiles = true + build.ReleaseVersion = "v6.2.0" + mock.getAllStores = func() []*metapb.Store { + return []*metapb.Store{{Version: `v6.5.0`}} + } + err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBRPiTR) + require.NoError(t, err) + require.Equal(t, CheckPITRSupportBatchKVFiles(), true) } { @@ -205,6 +236,29 @@ func TestCheckClusterVersion(t *testing.T) { } err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) require.NoError(t, err) + require.Error(t, CheckCheckpointSupport()) + } + + { + build.ReleaseVersion = "v6.0.0-rc.2" + mock.getAllStores = func() []*metapb.Store { + // TiKV v6.0.0-rc.1 with BR v6.0.0-rc.2 is ok + return []*metapb.Store{{Version: "v6.0.0-rc.1"}} + } + err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) + require.NoError(t, err) + require.Error(t, CheckCheckpointSupport()) + } + + { + build.ReleaseVersion = "v6.5.0-rc.2" + mock.getAllStores = func() []*metapb.Store { + // TiKV v6.5.0-rc.1 with BR v6.5.0-rc.2 is ok + return []*metapb.Store{{Version: "v6.5.0-rc.1"}} + } + err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) + require.NoError(t, err) + require.NoError(t, CheckCheckpointSupport()) } { @@ -266,50 +320,40 @@ func TestCheckClusterVersion(t *testing.T) { mock.getAllStores = func() []*metapb.Store { return []*metapb.Store{{Version: "v6.4.0"}} } - originVal := variable.EnableConcurrentDDL.Load() err := CheckClusterVersion(context.Background(), &mock, CheckVersionForDDL) require.NoError(t, err) - require.Equal(t, originVal, variable.EnableConcurrentDDL.Load()) } { mock.getAllStores = func() []*metapb.Store { return []*metapb.Store{{Version: "v6.2.0"}} } - originVal := variable.EnableConcurrentDDL.Load() err := CheckClusterVersion(context.Background(), &mock, CheckVersionForDDL) require.NoError(t, err) - require.Equal(t, originVal, variable.EnableConcurrentDDL.Load()) } { mock.getAllStores = func() []*metapb.Store { return []*metapb.Store{{Version: "v6.2.0-alpha"}} } - originVal := variable.EnableConcurrentDDL.Load() err := CheckClusterVersion(context.Background(), &mock, CheckVersionForDDL) require.NoError(t, err) - require.Equal(t, originVal, variable.EnableConcurrentDDL.Load()) } { mock.getAllStores = func() []*metapb.Store { return []*metapb.Store{{Version: "v6.1.0"}} } - variable.EnableConcurrentDDL.Store(true) err := CheckClusterVersion(context.Background(), &mock, CheckVersionForDDL) - require.NoError(t, err) - require.False(t, variable.EnableConcurrentDDL.Load()) + require.Error(t, err) } { mock.getAllStores = func() []*metapb.Store { return []*metapb.Store{{Version: "v5.4.0"}} } - variable.EnableConcurrentDDL.Store(true) err := CheckClusterVersion(context.Background(), &mock, CheckVersionForDDL) - require.NoError(t, err) - require.False(t, variable.EnableConcurrentDDL.Load()) + require.Error(t, err) } } diff --git a/br/tests/_utils/make_tiflash_config b/br/tests/_utils/make_tiflash_config index f759a990f6be9..6f0d41d800f78 100755 --- a/br/tests/_utils/make_tiflash_config +++ b/br/tests/_utils/make_tiflash_config @@ -12,8 +12,8 @@ key-path = "$TEST_DIR/certs/tiflash.key" [server] addr = "0.0.0.0:20170" advertise-addr = "127.0.0.1:20170" +status-addr = "127.0.0.1:20292" engine-addr = "127.0.0.1:3930" -status-addr = "$TIFLASH_STATUS" [storage] data-dir = "$TEST_DIR/tiflash/data" @@ -93,4 +93,4 @@ result_rows = 0 ca_path = "$TEST_DIR/certs/ca.pem" cert_path = "$TEST_DIR/certs/tiflash.pem" key_path = "$TEST_DIR/certs/tiflash.key" -EOF \ No newline at end of file +EOF diff --git a/br/tests/_utils/run_services b/br/tests/_utils/run_services index a7449cb229bf2..7e1917150b263 100644 --- a/br/tests/_utils/run_services +++ b/br/tests/_utils/run_services @@ -26,7 +26,6 @@ export TIDB_STATUS_ADDR="127.0.0.1:10080" export TIKV_ADDR="127.0.0.1:2016" export TIKV_STATUS_ADDR="127.0.0.1:2018" export TIKV_COUNT=3 -export TIFLASH_STATUS="127.0.0.1:17000" export TIFLASH_HTTP="127.0.0.1:8125" export TIKV_PIDS="${TEST_DIR:?}/tikv_pids.txt" diff --git a/br/tests/br_foreign_key/run.sh b/br/tests/br_foreign_key/run.sh new file mode 100644 index 0000000000000..eafd38a180d40 --- /dev/null +++ b/br/tests/br_foreign_key/run.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Copyright 2022 PingCAP, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu +DB="$TEST_NAME" + +run_sql "set @@global.foreign_key_checks=1;" +run_sql "set @@foreign_key_checks=1;" +run_sql "create schema $DB;" +run_sql "create table $DB.t1 (id int key);" +run_sql "create table $DB.t2 (id int key, a int, b int, foreign key fk_1 (a) references t1(id) ON UPDATE SET NULL ON DELETE SET NULL, foreign key fk_2 (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE);" +run_sql "insert into $DB.t1 values (1), (2), (3);" +run_sql "insert into $DB.t2 values (1, 1, 1), (2, 2, 2), (3, 3, 3);" +run_sql "update $DB.t1 set id=id+10 where id in (1, 3);" +run_sql "delete from $DB.t1 where id = 2;" + +echo "backup start..." +run_br backup db --db "$DB" -s "local://$TEST_DIR/$DB" --pd $PD_ADDR + +run_sql "drop schema $DB;" + +echo "restore start..." +run_br restore db --db $DB -s "local://$TEST_DIR/$DB" --pd $PD_ADDR + +set -x + +run_sql "select count(*) from $DB.t1;" +check_contains 'count(*): 2' + +run_sql "select count(*) from $DB.t2;" +check_contains 'count(*): 2' + +run_sql "select id, a, b from $DB.t2;" +check_contains 'id: 1' +check_contains 'id: 3' +check_contains 'a: NULL' +check_contains 'b: 11' +check_contains 'b: 13' + +run_sql "drop schema $DB" diff --git a/br/tests/br_full_cluster_restore/run.sh b/br/tests/br_full_cluster_restore/run.sh index e75b4d49fc914..14074e61f3825 100644 --- a/br/tests/br_full_cluster_restore/run.sh +++ b/br/tests/br_full_cluster_restore/run.sh @@ -55,7 +55,8 @@ restart_services # mock incompatible manually run_sql "alter table mysql.user add column xx int;" run_br restore full --with-sys-table --log-file $br_log_file -s "local://$backup_dir" > $res_file 2>&1 || true -check_contains "the target cluster is not compatible with the backup data" +run_sql "select count(*) from mysql.user" +check_contains "count(*): 6" echo "--> incompatible system table: less column on target cluster" restart_services diff --git a/br/tests/br_ttl/run.sh b/br/tests/br_ttl/run.sh new file mode 100644 index 0000000000000..cfb1a38c8281b --- /dev/null +++ b/br/tests/br_ttl/run.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# +# Copyright 2022 PingCAP, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu +DB="$TEST_NAME" + +PROGRESS_FILE="$TEST_DIR/progress_file" +BACKUPMETAV1_LOG="$TEST_DIR/backup.log" +BACKUPMETAV2_LOG="$TEST_DIR/backupv2.log" +RESTORE_LOG="$TEST_DIR/restore.log" +rm -rf $PROGRESS_FILE + +run_sql "create schema $DB;" +run_sql "create table $DB.ttl_test_tbl(id int primary key, t datetime) TTL=\`t\` + interval 1 day TTL_ENABLE='ON'" + +# backup db +echo "full backup meta v2 start..." +unset BR_LOG_TO_TERM +rm -f $BACKUPMETAV2_LOG +run_br backup full --log-file $BACKUPMETAV2_LOG -s "local://$TEST_DIR/${DB}v2" --pd $PD_ADDR --use-backupmeta-v2 + +echo "full backup meta v1 start..." +rm -f $BACKUPMETAV1_LOG +run_br backup full --log-file $BACKUPMETAV1_LOG -s "local://$TEST_DIR/$DB" --pd $PD_ADDR + +TTL_MARK='![ttl]' +CREATE_SQL_CONTAINS="/*T${TTL_MARK} TTL=\`t\` + INTERVAL 1 DAY */ /*T${TTL_MARK} TTL_ENABLE='OFF' */" + +# restore v2 +run_sql "DROP DATABASE $DB;" +echo "restore ttl table start v2..." +run_br restore db --db $DB -s "local://$TEST_DIR/${DB}v2" --pd $PD_ADDR +run_sql "show create table $DB.ttl_test_tbl;" +check_contains "$CREATE_SQL_CONTAINS" + +# restore v1 +run_sql "DROP DATABASE $DB;" +echo "restore ttl table start v1..." +run_br restore db --db $DB -s "local://$TEST_DIR/$DB" --pd $PD_ADDR +run_sql "show create table $DB.ttl_test_tbl;" +check_contains "$CREATE_SQL_CONTAINS" diff --git a/br/tests/lightning_check_partial_imported/config.toml b/br/tests/lightning_check_partial_imported/config.toml new file mode 100644 index 0000000000000..30cb6fe6b4eb3 --- /dev/null +++ b/br/tests/lightning_check_partial_imported/config.toml @@ -0,0 +1,5 @@ +[tikv-importer] +backend = "local" + +[mydumper.csv] +header = true diff --git a/br/tests/lightning_check_partial_imported/data/db01.tbl01-schema.sql b/br/tests/lightning_check_partial_imported/data/db01.tbl01-schema.sql new file mode 100644 index 0000000000000..b6832e95d95e3 --- /dev/null +++ b/br/tests/lightning_check_partial_imported/data/db01.tbl01-schema.sql @@ -0,0 +1,12 @@ +CREATE TABLE tbl01 ( + `id` INTEGER, + `val` VARCHAR(64), + `aaa` CHAR(66) DEFAULT NULL, + `bbb` CHAR(10) NOT NULL, + `ccc` CHAR(42) DEFAULT NULL, + `ddd` CHAR(42) DEFAULT NULL, + `eee` CHAR(66) DEFAULT NULL, + `fff` VARCHAR(128) DEFAULT NULL, + KEY `aaa` (`aaa`), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; diff --git a/br/tests/lightning_check_partial_imported/data/db01.tbl01.csv b/br/tests/lightning_check_partial_imported/data/db01.tbl01.csv new file mode 100644 index 0000000000000..108134af2ee72 --- /dev/null +++ b/br/tests/lightning_check_partial_imported/data/db01.tbl01.csv @@ -0,0 +1,6 @@ +id,val,aaa,bbb,ccc,ddd,eee,fff +1,"v01","a01","b01","c01","d01","e01","f01" +2,"v02","a02","b02","c02","d02","e02","f02" +3,"v03","a03","b03","c03","d03","e03","f03" +4,"v04","a04","b04","c04","d04","e04","f04" +5,"v05","a05","b05","c05","d05","e05","f05" diff --git a/br/tests/lightning_check_partial_imported/run.sh b/br/tests/lightning_check_partial_imported/run.sh new file mode 100755 index 0000000000000..00ed78a5013d1 --- /dev/null +++ b/br/tests/lightning_check_partial_imported/run.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# +# Copyright 2022 PingCAP, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +MYDIR=$(dirname "${BASH_SOURCE[0]}") +set -eux + +check_cluster_version 4 0 0 'local backend' || exit 0 + +export GO_FAILPOINTS="github.com/pingcap/tidb/br/pkg/lightning/restore/FailBeforeStartImportingIndexEngine=return" +set +e +if run_lightning; then + echo "The first import doesn't fail as expected" >&2 + exit 1 +fi +set -e + +data_records=$(tail -n +2 "${MYDIR}/data/db01.tbl01.csv" | wc -l | xargs echo ) +run_sql "SELECT COUNT(*) FROM db01.tbl01 USE INDEX();" +check_contains "${data_records}" + +export GO_FAILPOINTS="" +set +e +if run_lightning --check-requirements=1; then + echo "The pre-check doesn't find out the non-empty table problem" + exit 2 +fi +set -e + +run_sql "TRUNCATE TABLE db01.tbl01;" +run_lightning --check-requirements=1 +run_sql "SELECT COUNT(*) FROM db01.tbl01;" +check_contains "${data_records}" +run_sql "SELECT COUNT(*) FROM db01.tbl01 USE INDEX();" +check_contains "${data_records}" diff --git a/br/tests/lightning_checkpoint/run.sh b/br/tests/lightning_checkpoint/run.sh index 86551fd6246eb..5263dd90f1acf 100755 --- a/br/tests/lightning_checkpoint/run.sh +++ b/br/tests/lightning_checkpoint/run.sh @@ -79,6 +79,9 @@ for i in $(seq "$TABLE_COUNT"); do done set -e +# at the failure of last table, all data engines are imported so finished == total +grep "print lightning status" "$TEST_DIR/lightning.log" | grep -q "equal=true" + export GO_FAILPOINTS="$SLOWDOWN_FAILPOINTS" # After everything is done, there should be no longer new calls to ImportEngine # (and thus `kill_lightning_after_one_import` will spare this final check) diff --git a/br/tests/lightning_checkpoint_columns/run.sh b/br/tests/lightning_checkpoint_columns/run.sh index 401c75cfb9f64..5809d05a1b830 100755 --- a/br/tests/lightning_checkpoint_columns/run.sh +++ b/br/tests/lightning_checkpoint_columns/run.sh @@ -29,6 +29,8 @@ echo "INSERT INTO tbl (j, i) VALUES (3, 1),(4, 2);" > "$DBPATH/cp_tsr.tbl.sql" # Set the failpoint to kill the lightning instance as soon as one row is written PKG="github.com/pingcap/tidb/br/pkg/lightning/restore" export GO_FAILPOINTS="$PKG/SlowDownWriteRows=sleep(1000);$PKG/FailAfterWriteRows=panic;$PKG/SetMinDeliverBytes=return(1)" +# Check after 1 row is written in tidb backend, the finished progress is updated +export GO_FAILPOINTS="${GO_FAILPOINTS};github.com/pingcap/tidb/br/pkg/lightning/PrintStatus=return()" # Start importing the tables. run_sql 'DROP DATABASE IF EXISTS cp_tsr' @@ -40,11 +42,16 @@ set -e run_sql 'SELECT count(*) FROM `cp_tsr`.tbl' check_contains "count(*): 1" +# After FailAfterWriteRows, the finished bytes is 36 as the first row size +grep "PrintStatus Failpoint" "$TEST_DIR/lightning.log" | grep -q "finished=36" + # restart lightning from checkpoint, the second line should be written successfully -export GO_FAILPOINTS= +# also check after restart from checkpoint, final finished equals to total +export GO_FAILPOINTS="github.com/pingcap/tidb/br/pkg/lightning/PrintStatus=return()" set +e run_lightning -d "$DBPATH" --backend tidb --enable-checkpoint=1 2> /dev/null set -e run_sql 'SELECT j FROM `cp_tsr`.tbl WHERE i = 2;' check_contains "j: 4" +grep "PrintStatus Failpoint" "$TEST_DIR/lightning.log" | grep -q "equal=true" diff --git a/br/tests/lightning_compress/config.toml b/br/tests/lightning_compress/config.toml new file mode 100644 index 0000000000000..000018c5c41d4 --- /dev/null +++ b/br/tests/lightning_compress/config.toml @@ -0,0 +1,18 @@ +[mydumper.csv] +separator = ',' +delimiter = '"' +header = true +not-null = false +null = '\N' +backslash-escape = true +trim-last-separator = false + +[checkpoint] +enable = true +schema = "tidb_lightning_checkpoint_test" +driver = "mysql" +keep-after-success = true + +[tikv-importer] +send-kv-pairs=10 +region-split-size = 1024 diff --git a/br/tests/lightning_compress/data.gzip/compress-schema-create.sql.gz b/br/tests/lightning_compress/data.gzip/compress-schema-create.sql.gz new file mode 100644 index 0000000000000..6571d2a15b507 Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress-schema-create.sql.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.empty_strings-schema.sql.gz b/br/tests/lightning_compress/data.gzip/compress.empty_strings-schema.sql.gz new file mode 100644 index 0000000000000..542898561bab1 Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.empty_strings-schema.sql.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.empty_strings.000000000.csv.gz b/br/tests/lightning_compress/data.gzip/compress.empty_strings.000000000.csv.gz new file mode 100644 index 0000000000000..bfa13ed67b006 Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.empty_strings.000000000.csv.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.escapes-schema.sql.gz b/br/tests/lightning_compress/data.gzip/compress.escapes-schema.sql.gz new file mode 100644 index 0000000000000..bed4b7859ac92 Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.escapes-schema.sql.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.escapes.000000000.csv.gz b/br/tests/lightning_compress/data.gzip/compress.escapes.000000000.csv.gz new file mode 100644 index 0000000000000..37028e36d9de8 Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.escapes.000000000.csv.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.multi_rows-schema.sql.gz b/br/tests/lightning_compress/data.gzip/compress.multi_rows-schema.sql.gz new file mode 100644 index 0000000000000..328fed9cb3df8 Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.multi_rows-schema.sql.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.multi_rows.000000000.csv.gz b/br/tests/lightning_compress/data.gzip/compress.multi_rows.000000000.csv.gz new file mode 100644 index 0000000000000..c732af263d576 Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.multi_rows.000000000.csv.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.threads-schema.sql.gz b/br/tests/lightning_compress/data.gzip/compress.threads-schema.sql.gz new file mode 100644 index 0000000000000..1782675bfc7fe Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.threads-schema.sql.gz differ diff --git a/br/tests/lightning_compress/data.gzip/compress.threads.000000000.csv.gz b/br/tests/lightning_compress/data.gzip/compress.threads.000000000.csv.gz new file mode 100644 index 0000000000000..683eade1cdb9f Binary files /dev/null and b/br/tests/lightning_compress/data.gzip/compress.threads.000000000.csv.gz differ diff --git a/br/tests/lightning_compress/data.snappy/compress-schema-create.sql.snappy b/br/tests/lightning_compress/data.snappy/compress-schema-create.sql.snappy new file mode 100644 index 0000000000000..afa2211c77475 Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress-schema-create.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.empty_strings-schema.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.empty_strings-schema.sql.snappy new file mode 100644 index 0000000000000..cab30d082385a Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.empty_strings-schema.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.empty_strings.000000000.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.empty_strings.000000000.sql.snappy new file mode 100644 index 0000000000000..9c81e8f78f234 Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.empty_strings.000000000.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.escapes-schema.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.escapes-schema.sql.snappy new file mode 100644 index 0000000000000..9e27befa522a0 Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.escapes-schema.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.escapes.000000000.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.escapes.000000000.sql.snappy new file mode 100644 index 0000000000000..1380b47d9881e Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.escapes.000000000.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.multi_rows-schema.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.multi_rows-schema.sql.snappy new file mode 100644 index 0000000000000..5cc0365d1c65d Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.multi_rows-schema.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.multi_rows.000000000.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.multi_rows.000000000.sql.snappy new file mode 100644 index 0000000000000..7f5bf585e106c Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.multi_rows.000000000.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.threads-schema.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.threads-schema.sql.snappy new file mode 100644 index 0000000000000..b1c8b89565bfb Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.threads-schema.sql.snappy differ diff --git a/br/tests/lightning_compress/data.snappy/compress.threads.000000000.sql.snappy b/br/tests/lightning_compress/data.snappy/compress.threads.000000000.sql.snappy new file mode 100644 index 0000000000000..dc7c1ee8adc0b Binary files /dev/null and b/br/tests/lightning_compress/data.snappy/compress.threads.000000000.sql.snappy differ diff --git a/br/tests/lightning_compress/data.zstd/compress-schema-create.sql.zst b/br/tests/lightning_compress/data.zstd/compress-schema-create.sql.zst new file mode 100644 index 0000000000000..12bdbd710973e Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress-schema-create.sql.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.empty_strings-schema.sql.zst b/br/tests/lightning_compress/data.zstd/compress.empty_strings-schema.sql.zst new file mode 100644 index 0000000000000..f9b922954ff3d Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.empty_strings-schema.sql.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.empty_strings.000000000.csv.zst b/br/tests/lightning_compress/data.zstd/compress.empty_strings.000000000.csv.zst new file mode 100644 index 0000000000000..aa89918bb2cee Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.empty_strings.000000000.csv.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.escapes-schema.sql.zst b/br/tests/lightning_compress/data.zstd/compress.escapes-schema.sql.zst new file mode 100644 index 0000000000000..fa4b4e6b3497d Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.escapes-schema.sql.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.escapes.000000000.csv.zst b/br/tests/lightning_compress/data.zstd/compress.escapes.000000000.csv.zst new file mode 100644 index 0000000000000..40994e745bdf3 Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.escapes.000000000.csv.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.multi_rows-schema.sql.zst b/br/tests/lightning_compress/data.zstd/compress.multi_rows-schema.sql.zst new file mode 100644 index 0000000000000..d64a9a4a879d3 Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.multi_rows-schema.sql.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.multi_rows.000000000.csv.zst b/br/tests/lightning_compress/data.zstd/compress.multi_rows.000000000.csv.zst new file mode 100644 index 0000000000000..4db1bea4c69f9 Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.multi_rows.000000000.csv.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.threads-schema.sql.zst b/br/tests/lightning_compress/data.zstd/compress.threads-schema.sql.zst new file mode 100644 index 0000000000000..3a41c8de4816c Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.threads-schema.sql.zst differ diff --git a/br/tests/lightning_compress/data.zstd/compress.threads.000000000.csv.zst b/br/tests/lightning_compress/data.zstd/compress.threads.000000000.csv.zst new file mode 100644 index 0000000000000..13eef0ba83011 Binary files /dev/null and b/br/tests/lightning_compress/data.zstd/compress.threads.000000000.csv.zst differ diff --git a/br/tests/lightning_compress/run.sh b/br/tests/lightning_compress/run.sh new file mode 100755 index 0000000000000..bf48b09b2cccd --- /dev/null +++ b/br/tests/lightning_compress/run.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +set -eu + +for BACKEND in tidb local; do + for compress in gzip snappy zstd; do + if [ "$BACKEND" = 'local' ]; then + check_cluster_version 4 0 0 'local backend' || continue + fi + + # Set minDeliverBytes to a small enough number to only write only 1 row each time + # Set the failpoint to kill the lightning instance as soon as one row is written + PKG="github.com/pingcap/tidb/br/pkg/lightning/restore" + export GO_FAILPOINTS="$PKG/SlowDownWriteRows=sleep(1000);$PKG/FailAfterWriteRows=panic;$PKG/SetMinDeliverBytes=return(1)" + + # Start importing the tables. + run_sql 'DROP DATABASE IF EXISTS compress' + run_sql 'DROP DATABASE IF EXISTS tidb_lightning_checkpoint_test' + set +e + run_lightning --backend $BACKEND -d "tests/$TEST_NAME/data.$compress" --enable-checkpoint=1 2> /dev/null + set -e + + # restart lightning from checkpoint, the second line should be written successfully + export GO_FAILPOINTS= + set +e + run_lightning --backend $BACKEND -d "tests/$TEST_NAME/data.$compress" --enable-checkpoint=1 2> /dev/null + set -e + + run_sql 'SELECT count(*), sum(PROCESSLIST_TIME), sum(THREAD_OS_ID), count(PROCESSLIST_STATE) FROM compress.threads' + check_contains 'count(*): 43' + check_contains 'sum(PROCESSLIST_TIME): 322253' + check_contains 'sum(THREAD_OS_ID): 303775702' + check_contains 'count(PROCESSLIST_STATE): 3' + + run_sql 'SELECT count(*) FROM compress.threads WHERE PROCESSLIST_TIME IS NOT NULL' + check_contains 'count(*): 12' + + run_sql 'SELECT count(*) FROM compress.multi_rows WHERE a="aaaaaaaaaa"' + check_contains 'count(*): 100000' + + run_sql 'SELECT hex(t), j, hex(b) FROM compress.escapes WHERE i = 1' + check_contains 'hex(t): 5C' + check_contains 'j: {"?": []}' + check_contains 'hex(b): FFFFFFFF' + + run_sql 'SELECT hex(t), j, hex(b) FROM compress.escapes WHERE i = 2' + check_contains 'hex(t): 22' + check_contains 'j: "\n\n\n"' + check_contains 'hex(b): 0D0A0D0A' + + run_sql 'SELECT hex(t), j, hex(b) FROM compress.escapes WHERE i = 3' + check_contains 'hex(t): 0A' + check_contains 'j: [",,,"]' + check_contains 'hex(b): 5C2C5C2C' + + run_sql 'SELECT id FROM compress.empty_strings WHERE a = """"' + check_contains 'id: 3' + run_sql 'SELECT id FROM compress.empty_strings WHERE b <> ""' + check_not_contains 'id:' + done +done diff --git a/br/tests/lightning_csv/errData/db-schema-create.sql b/br/tests/lightning_csv/errData/db-schema-create.sql new file mode 100755 index 0000000000000..6adfeca7f7dab --- /dev/null +++ b/br/tests/lightning_csv/errData/db-schema-create.sql @@ -0,0 +1 @@ +create database if not exists db; diff --git a/br/tests/lightning_csv/errData/db.test-schema.sql b/br/tests/lightning_csv/errData/db.test-schema.sql new file mode 100755 index 0000000000000..955632c7761b2 --- /dev/null +++ b/br/tests/lightning_csv/errData/db.test-schema.sql @@ -0,0 +1 @@ +create table test(a int primary key, b int, c int, d int); diff --git a/br/tests/lightning_csv/errData/db.test.1.csv b/br/tests/lightning_csv/errData/db.test.1.csv new file mode 100755 index 0000000000000..2e8450c25786e --- /dev/null +++ b/br/tests/lightning_csv/errData/db.test.1.csv @@ -0,0 +1,3 @@ +1,2,3,4 +2,10,4,5 +1111,",7,8 diff --git a/br/tests/lightning_csv/run.sh b/br/tests/lightning_csv/run.sh index 83c4917b4b76c..682bc55b08e26 100755 --- a/br/tests/lightning_csv/run.sh +++ b/br/tests/lightning_csv/run.sh @@ -41,3 +41,11 @@ for BACKEND in tidb local; do check_not_contains 'id:' done + +set +e +run_lightning --backend local -d "tests/$TEST_NAME/errData" --log-file "$TEST_DIR/lightning-err.log" 2>/dev/null +set -e +# err content presented +grep ",7,8" "$TEST_DIR/lightning-err.log" +# pos should not set to end +grep "[\"syntax error\"] [pos=22]" "$TEST_DIR/lightning-err.log" \ No newline at end of file diff --git a/br/tests/lightning_exotic_filenames/data/xfn.etn-schema.sql b/br/tests/lightning_exotic_filenames/data/xfn.etn-schema.sql index e2d94bbdf8f32..d004fa92e0b64 100644 --- a/br/tests/lightning_exotic_filenames/data/xfn.etn-schema.sql +++ b/br/tests/lightning_exotic_filenames/data/xfn.etn-schema.sql @@ -1 +1 @@ -create table `exotic``table````name` (a varchar(6) primary key, b int unique auto_increment) auto_increment=80000; \ No newline at end of file +create table `exotic``table````name` (a varchar(6) primary key /*T![clustered_index] NONCLUSTERED */, b int unique auto_increment) auto_increment=80000; diff --git a/br/tests/lightning_exotic_filenames/data/zwk.zwb-schema.sql b/br/tests/lightning_exotic_filenames/data/zwk.zwb-schema.sql index 449584777c299..d9fae1aad0373 100644 --- a/br/tests/lightning_exotic_filenames/data/zwk.zwb-schema.sql +++ b/br/tests/lightning_exotic_filenames/data/zwk.zwb-schema.sql @@ -1 +1 @@ -create table 中文表(a int primary key); +create table 中文表(a int primary key /*T![clustered_index] NONCLUSTERED */); diff --git a/br/tests/lightning_extend_routes/config.toml b/br/tests/lightning_extend_routes/config.toml new file mode 100644 index 0000000000000..2010453870113 --- /dev/null +++ b/br/tests/lightning_extend_routes/config.toml @@ -0,0 +1,25 @@ +[tikv-importer] +sorted-kv-dir = "/tmp/tidb-lightning/sorted-kv-dir" + +[mydumper] +source-id = "mysql-01" + +# the complicated routing rules should be tested in tidb-tools repo already +# here we're just verifying the basic things do work. +[[routes]] +schema-pattern = "routes_a*" +table-pattern = "t*" +target-schema = "routes_b" +target-table = "u" + +[routes.extract-table] +table-regexp = "t(.*)" +target-column = "c_table" + +[routes.extract-schema] +schema-regexp = "routes_a(.*)" +target-column = "c_schema" + +[routes.extract-source] +source-regexp = "mysql-(.*)" +target-column = "c_source" diff --git a/br/tests/lightning_extend_routes/data/routes_a0-schema-create.sql b/br/tests/lightning_extend_routes/data/routes_a0-schema-create.sql new file mode 100644 index 0000000000000..13ae4918b6098 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a0-schema-create.sql @@ -0,0 +1 @@ +create database routes_a0; diff --git a/br/tests/lightning_extend_routes/data/routes_a0.t0-schema.sql b/br/tests/lightning_extend_routes/data/routes_a0.t0-schema.sql new file mode 100644 index 0000000000000..0df8bb24c5ac0 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a0.t0-schema.sql @@ -0,0 +1 @@ +create table t0 (x real primary key); diff --git a/br/tests/lightning_extend_routes/data/routes_a0.t0.1.sql b/br/tests/lightning_extend_routes/data/routes_a0.t0.1.sql new file mode 100644 index 0000000000000..e6fe0676be1c7 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a0.t0.1.sql @@ -0,0 +1 @@ +insert into t0 values (1.0); \ No newline at end of file diff --git a/br/tests/lightning_extend_routes/data/routes_a0.t0.2.sql b/br/tests/lightning_extend_routes/data/routes_a0.t0.2.sql new file mode 100644 index 0000000000000..c5ebd7ac4e224 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a0.t0.2.sql @@ -0,0 +1 @@ +insert into t0 values (6.0); \ No newline at end of file diff --git a/br/tests/lightning_extend_routes/data/routes_a0.t1-schema.sql b/br/tests/lightning_extend_routes/data/routes_a0.t1-schema.sql new file mode 100644 index 0000000000000..640043cdd0405 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a0.t1-schema.sql @@ -0,0 +1 @@ +create table t1 (x real primary key); diff --git a/br/tests/lightning_extend_routes/data/routes_a0.t1.1.sql b/br/tests/lightning_extend_routes/data/routes_a0.t1.1.sql new file mode 100644 index 0000000000000..ca471aa6698ff --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a0.t1.1.sql @@ -0,0 +1 @@ +insert into t1 (x) values (36.0); diff --git a/br/tests/lightning_extend_routes/data/routes_a1-schema-create.sql b/br/tests/lightning_extend_routes/data/routes_a1-schema-create.sql new file mode 100644 index 0000000000000..7f76665e1fed8 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a1-schema-create.sql @@ -0,0 +1 @@ +create database routes_a1; diff --git a/br/tests/lightning_extend_routes/data/routes_a1.s1-schema.sql b/br/tests/lightning_extend_routes/data/routes_a1.s1-schema.sql new file mode 100644 index 0000000000000..9f6be476718e9 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a1.s1-schema.sql @@ -0,0 +1 @@ +create table s1 (x real primary key); \ No newline at end of file diff --git a/br/tests/lightning_extend_routes/data/routes_a1.s1.sql b/br/tests/lightning_extend_routes/data/routes_a1.s1.sql new file mode 100644 index 0000000000000..51826fc361836 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a1.s1.sql @@ -0,0 +1 @@ +insert into s1 values (1296.0); \ No newline at end of file diff --git a/br/tests/lightning_extend_routes/data/routes_a1.t2-schema.sql b/br/tests/lightning_extend_routes/data/routes_a1.t2-schema.sql new file mode 100644 index 0000000000000..f07b1f26737a3 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a1.t2-schema.sql @@ -0,0 +1 @@ +create table t2 (x real primary key); \ No newline at end of file diff --git a/br/tests/lightning_extend_routes/data/routes_a1.t2.sql b/br/tests/lightning_extend_routes/data/routes_a1.t2.sql new file mode 100644 index 0000000000000..48f0da53eb7f5 --- /dev/null +++ b/br/tests/lightning_extend_routes/data/routes_a1.t2.sql @@ -0,0 +1 @@ +insert into t2 values (216.0); \ No newline at end of file diff --git a/br/tests/lightning_extend_routes/run.sh b/br/tests/lightning_extend_routes/run.sh new file mode 100755 index 0000000000000..1d7daa71a49e1 --- /dev/null +++ b/br/tests/lightning_extend_routes/run.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Basic check for whether routing rules work + +set -eux + +for BACKEND in tidb local; do + run_sql 'DROP DATABASE IF EXISTS routes_a0;' + run_sql 'DROP DATABASE IF EXISTS routes_a1;' + run_sql 'DROP DATABASE IF EXISTS routes_b;' + + run_sql 'CREATE DATABASE routes_b;' + run_sql 'CREATE TABLE routes_b.u (x real primary key, c_source varchar(11) not null, c_schema varchar(11) not null, c_table varchar(11) not null);' + + run_lightning --config "tests/$TEST_NAME/config.toml" --backend $BACKEND + echo Import using $BACKEND finished + + run_sql 'SELECT count(1), sum(x) FROM routes_b.u;' + check_contains 'count(1): 4' + check_contains 'sum(x): 259' + + run_sql 'SELECT count(1), sum(x) FROM routes_a1.s1;' + check_contains 'count(1): 1' + check_contains 'sum(x): 1296' + + run_sql 'SELECT count(1) FROM routes_b.u where c_table = "0";' + check_contains 'count(1): 2' + run_sql 'SELECT count(1) FROM routes_b.u where c_table = "1";' + check_contains 'count(1): 1' + run_sql 'SELECT count(1) FROM routes_b.u where c_table = "2";' + check_contains 'count(1): 1' + run_sql 'SELECT count(1) FROM routes_b.u where c_schema = "0";' + check_contains 'count(1): 3' + run_sql 'SELECT count(1) FROM routes_b.u where c_schema = "1";' + check_contains 'count(1): 1' + run_sql 'SELECT count(1) FROM routes_b.u where c_source = "01";' + check_contains 'count(1): 4' + + run_sql 'SHOW TABLES IN routes_a1;' + check_not_contains 'Tables_in_routes_a1: t2' +done diff --git a/br/tests/lightning_fail_fast/run.sh b/br/tests/lightning_fail_fast/run.sh index a1723b3e2cffd..5f8efb8b44712 100755 --- a/br/tests/lightning_fail_fast/run.sh +++ b/br/tests/lightning_fail_fast/run.sh @@ -25,7 +25,7 @@ for CFG in chunk engine; do ! run_lightning --backend tidb --enable-checkpoint=0 --log-file "$TEST_DIR/lightning-tidb.log" --config "tests/$TEST_NAME/$CFG.toml" [ $? -eq 0 ] - tail -n 10 $TEST_DIR/lightning-tidb.log | grep "ERROR" | tail -n 1 | grep -Fq "Error 1062: Duplicate entry '1-1' for key 'uq'" + tail -n 10 $TEST_DIR/lightning-tidb.log | grep "ERROR" | tail -n 1 | grep -Fq "Error 1062 (23000): Duplicate entry '1-1' for key 'tb.uq'" ! grep -Fq "restore file completed" $TEST_DIR/lightning-tidb.log [ $? -eq 0 ] diff --git a/br/tests/lightning_foreign_key/config.toml b/br/tests/lightning_foreign_key/config.toml new file mode 100644 index 0000000000000..3c85a830bfa22 --- /dev/null +++ b/br/tests/lightning_foreign_key/config.toml @@ -0,0 +1,3 @@ +[tikv-importer] +# Set on-duplicate=error to force using insert statement to write data. +on-duplicate = "error" diff --git a/br/tests/lightning_foreign_key/data/fk.child-schema.sql b/br/tests/lightning_foreign_key/data/fk.child-schema.sql new file mode 100644 index 0000000000000..18c361bf4c2e0 --- /dev/null +++ b/br/tests/lightning_foreign_key/data/fk.child-schema.sql @@ -0,0 +1 @@ +create table child (id int key, pid int, constraint fk_1 foreign key (pid) references parent(id)); diff --git a/br/tests/lightning_foreign_key/data/fk.child.sql b/br/tests/lightning_foreign_key/data/fk.child.sql new file mode 100644 index 0000000000000..12e531eb96a34 --- /dev/null +++ b/br/tests/lightning_foreign_key/data/fk.child.sql @@ -0,0 +1 @@ +insert into child values (1,1),(2,2),(3,3),(4,4); diff --git a/br/tests/lightning_foreign_key/data/fk.parent-schema.sql b/br/tests/lightning_foreign_key/data/fk.parent-schema.sql new file mode 100644 index 0000000000000..8ae8af2de6a2e --- /dev/null +++ b/br/tests/lightning_foreign_key/data/fk.parent-schema.sql @@ -0,0 +1 @@ +create table parent(id int key, a int); diff --git a/br/tests/lightning_foreign_key/data/fk.parent.sql b/br/tests/lightning_foreign_key/data/fk.parent.sql new file mode 100644 index 0000000000000..7a31a9f18db0f --- /dev/null +++ b/br/tests/lightning_foreign_key/data/fk.parent.sql @@ -0,0 +1 @@ +insert into parent values (1,1),(2,2),(3,3),(4,4); diff --git a/br/tests/lightning_foreign_key/data/fk.t-schema.sql b/br/tests/lightning_foreign_key/data/fk.t-schema.sql new file mode 100644 index 0000000000000..98f00b9cadca8 --- /dev/null +++ b/br/tests/lightning_foreign_key/data/fk.t-schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE `t` +( + `a` bigint(20) NOT NULL, + `b` bigint(20) DEFAULT NULL, + PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */, + KEY `fk_1` (`b`), + CONSTRAINT `fk_1` FOREIGN KEY (`b`) REFERENCES `test`.`t2` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; diff --git a/br/tests/lightning_foreign_key/data/fk.t.csv b/br/tests/lightning_foreign_key/data/fk.t.csv new file mode 100644 index 0000000000000..cd0368580a4c8 --- /dev/null +++ b/br/tests/lightning_foreign_key/data/fk.t.csv @@ -0,0 +1,6 @@ +a,b +1,1 +2,2 +3,3 +4,4 +5,5 diff --git a/br/tests/lightning_foreign_key/run.sh b/br/tests/lightning_foreign_key/run.sh new file mode 100755 index 0000000000000..1c045b61f43be --- /dev/null +++ b/br/tests/lightning_foreign_key/run.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# +# Copyright 2022 PingCAP, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu + +run_sql 'DROP DATABASE IF EXISTS fk;' +run_sql 'CREATE DATABASE IF NOT EXISTS fk;' +# Create existing tables that import data will reference. +run_sql 'CREATE TABLE fk.t2 (a BIGINT PRIMARY KEY);' + +for BACKEND in tidb local; do + run_sql 'DROP TABLE IF EXISTS fk.t, fk.parent, fk.child;' + + run_lightning --backend $BACKEND + run_sql 'SELECT GROUP_CONCAT(a) FROM fk.t ORDER BY a;' + check_contains '1,2,3,4,5' + + run_sql 'SELECT count(1), sum(a) FROM fk.parent;' + check_contains 'count(1): 4' + check_contains 'sum(a): 10' + + run_sql 'SELECT count(1), sum(pid) FROM fk.child;' + check_contains 'count(1): 4' + check_contains 'sum(pid): 10' +done diff --git a/br/tests/lightning_ignore_columns/config.toml b/br/tests/lightning_ignore_columns/config.toml new file mode 100644 index 0000000000000..081814e3bc2fd --- /dev/null +++ b/br/tests/lightning_ignore_columns/config.toml @@ -0,0 +1,27 @@ +[mydumper] +source-id = "mysql-01" + +[[mydumper.ignore-columns]] +db = "routes_b" +table = "u" +columns = ["b", "c"] + +# the complicated routing rules should be tested in tidb-tools repo already +# here we're just verifying the basic things do work. +[[routes]] +schema-pattern = "routes_a*" +table-pattern = "t*" +target-schema = "routes_b" +target-table = "u" + +[routes.extract-table] +table-regexp = "t(.*)" +target-column = "c_table" + +[routes.extract-schema] +schema-regexp = "routes_a(.*)" +target-column = "c_schema" + +[routes.extract-source] +source-regexp = "mysql-(.*)" +target-column = "c_source" diff --git a/br/tests/lightning_ignore_columns/data/routes_a0-schema-create.sql b/br/tests/lightning_ignore_columns/data/routes_a0-schema-create.sql new file mode 100644 index 0000000000000..13ae4918b6098 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a0-schema-create.sql @@ -0,0 +1 @@ +create database routes_a0; diff --git a/br/tests/lightning_ignore_columns/data/routes_a0.t0-schema.sql b/br/tests/lightning_ignore_columns/data/routes_a0.t0-schema.sql new file mode 100644 index 0000000000000..721808e895288 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a0.t0-schema.sql @@ -0,0 +1 @@ +create table t0 (a int primary key, b int, c int); diff --git a/br/tests/lightning_ignore_columns/data/routes_a0.t0.1.sql b/br/tests/lightning_ignore_columns/data/routes_a0.t0.1.sql new file mode 100644 index 0000000000000..8423d6272c5f5 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a0.t0.1.sql @@ -0,0 +1 @@ +insert into t0 values (1,1,1); diff --git a/br/tests/lightning_ignore_columns/data/routes_a0.t0.2.sql b/br/tests/lightning_ignore_columns/data/routes_a0.t0.2.sql new file mode 100644 index 0000000000000..6ece03887605b --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a0.t0.2.sql @@ -0,0 +1 @@ +insert into t0 values (2,2,2); diff --git a/br/tests/lightning_ignore_columns/data/routes_a0.t1-schema.sql b/br/tests/lightning_ignore_columns/data/routes_a0.t1-schema.sql new file mode 100644 index 0000000000000..2f5757afe3f3d --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a0.t1-schema.sql @@ -0,0 +1 @@ +create table t1 (a int primary key, b int, c int); diff --git a/br/tests/lightning_ignore_columns/data/routes_a0.t1.1.sql b/br/tests/lightning_ignore_columns/data/routes_a0.t1.1.sql new file mode 100644 index 0000000000000..6e0c62bf6a774 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a0.t1.1.sql @@ -0,0 +1 @@ +insert into t1 (a,b,c) values (3,3,3); diff --git a/br/tests/lightning_ignore_columns/data/routes_a1-schema-create.sql b/br/tests/lightning_ignore_columns/data/routes_a1-schema-create.sql new file mode 100644 index 0000000000000..7f76665e1fed8 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a1-schema-create.sql @@ -0,0 +1 @@ +create database routes_a1; diff --git a/br/tests/lightning_ignore_columns/data/routes_a1.s1-schema.sql b/br/tests/lightning_ignore_columns/data/routes_a1.s1-schema.sql new file mode 100644 index 0000000000000..c4e55cac7a713 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a1.s1-schema.sql @@ -0,0 +1 @@ +create table s1 (a int primary key, b int, c int); diff --git a/br/tests/lightning_ignore_columns/data/routes_a1.s1.sql b/br/tests/lightning_ignore_columns/data/routes_a1.s1.sql new file mode 100644 index 0000000000000..9f0a0a8e98e77 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a1.s1.sql @@ -0,0 +1 @@ +insert into s1 values (4,4,4); diff --git a/br/tests/lightning_ignore_columns/data/routes_a1.t2-schema.sql b/br/tests/lightning_ignore_columns/data/routes_a1.t2-schema.sql new file mode 100644 index 0000000000000..cfa986fec7f95 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a1.t2-schema.sql @@ -0,0 +1 @@ +create table t2 (a int primary key, b int, c int); diff --git a/br/tests/lightning_ignore_columns/data/routes_a1.t2.sql b/br/tests/lightning_ignore_columns/data/routes_a1.t2.sql new file mode 100644 index 0000000000000..1087175aef150 --- /dev/null +++ b/br/tests/lightning_ignore_columns/data/routes_a1.t2.sql @@ -0,0 +1 @@ +insert into t2 values (5,5,5); diff --git a/br/tests/lightning_ignore_columns/run.sh b/br/tests/lightning_ignore_columns/run.sh new file mode 100755 index 0000000000000..f11d216567512 --- /dev/null +++ b/br/tests/lightning_ignore_columns/run.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# Basic check for whether routing rules work + +set -eux + +for BACKEND in tidb local; do + run_sql 'DROP DATABASE IF EXISTS routes_a0;' + run_sql 'DROP DATABASE IF EXISTS routes_a1;' + run_sql 'DROP DATABASE IF EXISTS routes_b;' + + run_sql 'CREATE DATABASE routes_b;' + run_sql 'CREATE TABLE routes_b.u (a int primary key, b int, c int, c_source varchar(11), c_schema varchar(11) not null, c_table varchar(11) not null);' + + run_lightning --config "tests/$TEST_NAME/config.toml" --backend $BACKEND + echo Import using $BACKEND finished + + run_sql 'SELECT count(1), sum(a), sum(b), sum(c) FROM routes_b.u;' + check_contains 'count(1): 4' + check_contains 'sum(a): 11' + check_contains 'sum(b): NULL' + check_contains 'sum(c): NULL' + + run_sql 'SELECT count(1), sum(a), sum(b), sum(c) FROM routes_a1.s1;' + check_contains 'count(1): 1' + check_contains 'sum(a): 4' + check_contains 'sum(b): 4' + check_contains 'sum(c): 4' + + run_sql 'SELECT count(1) FROM routes_b.u where c_table = "0";' + check_contains 'count(1): 2' + run_sql 'SELECT count(1) FROM routes_b.u where c_table = "1";' + check_contains 'count(1): 1' + run_sql 'SELECT count(1) FROM routes_b.u where c_table = "2";' + check_contains 'count(1): 1' + run_sql 'SELECT count(1) FROM routes_b.u where c_schema = "0";' + check_contains 'count(1): 3' + run_sql 'SELECT count(1) FROM routes_b.u where c_schema = "1";' + check_contains 'count(1): 1' + run_sql 'SELECT count(1) FROM routes_b.u where c_source = "01";' + check_contains 'count(1): 4' + + run_sql 'SHOW TABLES IN routes_a1;' + check_not_contains 'Tables_in_routes_a1: t2' +done diff --git a/br/tests/lightning_record_network/config.toml b/br/tests/lightning_record_network/config.toml new file mode 100644 index 0000000000000..2de41a1f43dab --- /dev/null +++ b/br/tests/lightning_record_network/config.toml @@ -0,0 +1,2 @@ +[tikv-importer] +backend = 'tidb' diff --git a/br/tests/lightning_record_network/data/db-schema-create.sql b/br/tests/lightning_record_network/data/db-schema-create.sql new file mode 100644 index 0000000000000..c88b0e3150e76 --- /dev/null +++ b/br/tests/lightning_record_network/data/db-schema-create.sql @@ -0,0 +1 @@ +create database db; \ No newline at end of file diff --git a/br/tests/lightning_record_network/data/db.test-schema.sql b/br/tests/lightning_record_network/data/db.test-schema.sql new file mode 100644 index 0000000000000..7bee5f9ad639c --- /dev/null +++ b/br/tests/lightning_record_network/data/db.test-schema.sql @@ -0,0 +1 @@ +create table test ( id int primary key, a int, b int ); \ No newline at end of file diff --git a/br/tests/lightning_record_network/data/db.test.1.sql b/br/tests/lightning_record_network/data/db.test.1.sql new file mode 100644 index 0000000000000..3748d5fa91e80 --- /dev/null +++ b/br/tests/lightning_record_network/data/db.test.1.sql @@ -0,0 +1,21 @@ +insert into db.test values +(1,1,1), +(2,1,1), +(3,1,1), +(4,1,1), +(5,1,1), +(6,1,1), +(7,1,1), +(8,1,1), +(9,1,1), +(10,1,1), +(11,1,1), +(12,1,1), +(13,1,1), +(14,1,1), +(15,1,1), +(16,1,1), +(17,1,1), +(18,1,1), +(19,1,1), +(20,1,1); \ No newline at end of file diff --git a/br/tests/lightning_record_network/run.sh b/br/tests/lightning_record_network/run.sh new file mode 100644 index 0000000000000..e31f9d151d76a --- /dev/null +++ b/br/tests/lightning_record_network/run.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Copyright 2022 PingCAP, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euE + +export GO_FAILPOINTS="github.com/pingcap/tidb/br/pkg/lightning/SetIOTotalBytes=return(1)" +run_lightning + +grep 'IOTotal' "$TEST_DIR/lightning.log" | grep -v 'IOTotalBytes=0' diff --git a/br/tests/lightning_shard_rowid/data/shard_rowid.shr-schema.sql b/br/tests/lightning_shard_rowid/data/shard_rowid.shr-schema.sql index 312b13c1c1118..d544b7fdb84c1 100644 --- a/br/tests/lightning_shard_rowid/data/shard_rowid.shr-schema.sql +++ b/br/tests/lightning_shard_rowid/data/shard_rowid.shr-schema.sql @@ -3,5 +3,5 @@ CREATE TABLE `test` ( `s1` char(10) NOT NULL, `s2` char(10) NOT NULL, `s3` char(10) DEFAULT NULL, - PRIMARY KEY (`s1`,`s2`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin/*!90000 SHARD_ROW_ID_BITS=3 PRE_SPLIT_REGIONS=3 */; \ No newline at end of file + PRIMARY KEY (`s1`,`s2`) /*T![clustered_index] NONCLUSTERED */ +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin/*!90000 SHARD_ROW_ID_BITS=3 PRE_SPLIT_REGIONS=3 */; diff --git a/br/tests/lightning_tidb_rowid/data/rowid.non_pk-schema.sql b/br/tests/lightning_tidb_rowid/data/rowid.non_pk-schema.sql index 5b5757644b6dd..52ee2729417a3 100644 --- a/br/tests/lightning_tidb_rowid/data/rowid.non_pk-schema.sql +++ b/br/tests/lightning_tidb_rowid/data/rowid.non_pk-schema.sql @@ -1 +1 @@ -create table non_pk (pk varchar(6) primary key); +create table non_pk (pk varchar(6) primary key /*T![clustered_index] NONCLUSTERED */); diff --git a/br/tests/lightning_tidb_rowid/data/rowid.non_pk_auto_inc-schema.sql b/br/tests/lightning_tidb_rowid/data/rowid.non_pk_auto_inc-schema.sql index a71be02c9e8f1..97aa81838b1bc 100644 --- a/br/tests/lightning_tidb_rowid/data/rowid.non_pk_auto_inc-schema.sql +++ b/br/tests/lightning_tidb_rowid/data/rowid.non_pk_auto_inc-schema.sql @@ -4,6 +4,6 @@ CREATE TABLE `non_pk_auto_inc` ( `pk` char(36) NOT NULL, `id` int(11) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`pk`), + PRIMARY KEY (`pk`) /*T![clustered_index] NONCLUSTERED */, UNIQUE KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; diff --git a/br/tests/lightning_ttl/config.toml b/br/tests/lightning_ttl/config.toml new file mode 100644 index 0000000000000..d2152b47c922a --- /dev/null +++ b/br/tests/lightning_ttl/config.toml @@ -0,0 +1,2 @@ +[tikv-importer] +backend = 'local' diff --git a/br/tests/lightning_ttl/data/ttldb-schema-create.sql b/br/tests/lightning_ttl/data/ttldb-schema-create.sql new file mode 100644 index 0000000000000..46609f11e6635 --- /dev/null +++ b/br/tests/lightning_ttl/data/ttldb-schema-create.sql @@ -0,0 +1 @@ +CREATE DATABASE `ttldb`; diff --git a/br/tests/lightning_ttl/data/ttldb.t1-schema.sql b/br/tests/lightning_ttl/data/ttldb.t1-schema.sql new file mode 100644 index 0000000000000..7531d7f18ae01 --- /dev/null +++ b/br/tests/lightning_ttl/data/ttldb.t1-schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE `t1` ( + `id` int(11) PRIMARY KEY, + `t` datetime +) TTL = `t` + INTERVAL 1 DAY TTL_ENABLE = 'ON'; diff --git a/br/tests/lightning_ttl/run.sh b/br/tests/lightning_ttl/run.sh new file mode 100644 index 0000000000000..4a1d9ffc04d57 --- /dev/null +++ b/br/tests/lightning_ttl/run.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# +# Copyright 2022 PingCAP, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu + +run_sql 'drop database if exists ttldb;' +run_lightning + +TTL_MARK='![ttl]' +CREATE_SQL_CONTAINS="/*T${TTL_MARK} TTL=\`t\` + INTERVAL 1 DAY */ /*T${TTL_MARK} TTL_ENABLE='OFF' */" + +run_sql 'show create table ttldb.t1' +check_contains "$CREATE_SQL_CONTAINS" diff --git a/build/BUILD.bazel b/build/BUILD.bazel index a90a76bf3bf81..23cf263d525e3 100644 --- a/build/BUILD.bazel +++ b/build/BUILD.bazel @@ -124,7 +124,6 @@ nogo( "//build/linter/bodyclose:bodyclose", "//build/linter/durationcheck:durationcheck", "//build/linter/exportloopref:exportloopref", - "//build/linter/filepermission:filepermission", "//build/linter/forcetypeassert:forcetypeassert", "//build/linter/gofmt:gofmt", "//build/linter/gci:gci", @@ -140,6 +139,7 @@ nogo( ] + staticcheck_analyzers(STATICHECK_ANALYZERS) + select({ "//build:with_nogo": [ + "//build/linter/filepermission:filepermission", "//build/linter/allrevive:allrevive", "//build/linter/errcheck:errcheck", "//build/linter/revive:revive", diff --git a/build/linter/revive/analyzer.go b/build/linter/revive/analyzer.go index 19d44a95558e7..a3d269aad48e9 100644 --- a/build/linter/revive/analyzer.go +++ b/build/linter/revive/analyzer.go @@ -50,21 +50,11 @@ var defaultRules = []lint.Rule{ &rule.VarDeclarationsRule{}, //&rule.PackageCommentsRule{}, &rule.DotImportsRule{}, - &rule.BlankImportsRule{}, &rule.ExportedRule{}, &rule.VarNamingRule{}, - &rule.IndentErrorFlowRule{}, - &rule.RangeRule{}, - &rule.ErrorfRule{}, - &rule.ErrorNamingRule{}, - &rule.ErrorStringsRule{}, - &rule.ReceiverNamingRule{}, &rule.IncrementDecrementRule{}, - &rule.ErrorReturnRule{}, //&rule.UnexportedReturnRule{}, - &rule.TimeNamingRule{}, &rule.ContextKeysType{}, - &rule.ContextAsArgumentRule{}, } var allRules = append([]lint.Rule{ @@ -72,52 +62,31 @@ var allRules = append([]lint.Rule{ //&rule.CyclomaticRule{}, //&rule.FileHeaderRule{}, &rule.EmptyBlockRule{}, - &rule.SuperfluousElseRule{}, //&rule.ConfusingNamingRule{}, - &rule.GetReturnRule{}, - &rule.ModifiesParamRule{}, &rule.ConfusingResultsRule{}, //&rule.DeepExitRule{}, &rule.UnusedParamRule{}, - &rule.UnreachableCodeRule{}, //&rule.AddConstantRule{}, //&rule.FlagParamRule{}, &rule.UnnecessaryStmtRule{}, //&rule.StructTagRule{}, //&rule.ModifiesValRecRule{}, - &rule.ConstantLogicalExprRule{}, - &rule.BoolLiteralRule{}, //&rule.RedefinesBuiltinIDRule{}, - &rule.ImportsBlacklistRule{}, //&rule.FunctionResultsLimitRule{}, //&rule.MaxPublicStructsRule{}, - &rule.RangeValInClosureRule{}, - &rule.RangeValAddress{}, - &rule.WaitGroupByValueRule{}, - &rule.AtomicRule{}, - &rule.EmptyLinesRule{}, //&rule.LineLengthLimitRule{}, &rule.CallToGCRule{}, - &rule.DuplicatedImportsRule{}, //&rule.ImportShadowingRule{}, //&rule.BareReturnRule{}, &rule.UnusedReceiverRule{}, //&rule.UnhandledErrorRule{}, //&rule.CognitiveComplexityRule{}, - &rule.StringOfIntRule{}, - &rule.StringFormatRule{}, //&rule.EarlyReturnRule{}, - &rule.UnconditionalRecursionRule{}, - &rule.IdenticalBranchesRule{}, - &rule.DeferRule{}, &rule.UnexportedNamingRule{}, //&rule.FunctionLength{}, //&rule.NestedStructs{}, - &rule.IfReturnRule{}, &rule.UselessBreak{}, - &rule.TimeEqualRule{}, //&rule.BannedCharsRule{}, - &rule.OptimizeOperandsOrderRule{}, }, defaultRules...) func run(pass *analysis.Pass) (any, error) { diff --git a/build/nogo_config.json b/build/nogo_config.json index 2a5fe64ba3e49..97a1a1feed50e 100644 --- a/build/nogo_config.json +++ b/build/nogo_config.json @@ -198,22 +198,23 @@ ".*_generated\\.go$": "ignore generated code" }, "only_files": { - "util/gctuner": "util/gctuner", - "br/pkg/lightning/mydump/": "br/pkg/lightning/mydump/", - "br/pkg/lightning/restore/opts": "br/pkg/lightning/restore/opts", - "executor/aggregate.go": "executor/aggregate.go", - "types/json_binary_functions.go": "types/json_binary_functions.go", - "types/json_binary_test.go": "types/json_binary_test.go", - "ddl/backfilling.go": "ddl/backfilling.go", - "ddl/column.go": "ddl/column.go", - "ddl/index.go": "ddl/index.go", - "ddl/ingest/": "ddl/ingest/", - "util/cgroup": "util/cgroup code", - "server/conn.go": "server/conn.go", - "server/conn_stmt.go": "server/conn_stmt.go", - "server/conn_test.go": "server/conn_test.go", - "planner/core/plan.go": "planner/core/plan.go", - "errno/": "only table code" + "util/gctuner": "only for util/gctuner", + "br/pkg/lightning/mydump/": "only for br/pkg/lightning/mydump/", + "br/pkg/lightning/restore/opts": "only for br/pkg/lightning/restore/opts", + "executor/aggregate.go": "only for executor/aggregate.go", + "types/json_binary_functions.go": "only for types/json_binary_functions.go", + "types/json_binary_test.go": "only for types/json_binary_test.go", + "ddl/backfilling.go": "only for ddl/backfilling.go", + "ddl/column.go": "only for ddl/column.go", + "ddl/index.go": "only for ddl/index.go", + "ddl/ingest/": "only for ddl/ingest/", + "util/cgroup": "only for util/cgroup code", + "server/conn.go": "only for server/conn.go", + "server/conn_stmt.go": "only for server/conn_stmt.go", + "server/conn_test.go": "only for server/conn_test.go", + "planner/core/plan.go": "only for planner/core/plan.go", + "errno/": "only for errno/", + "extension/": "extension code" } }, "gofmt": { @@ -228,6 +229,7 @@ }, "gci": { "exclude_files": { + "external/": "no need to vet third party code", "/external/": "no need to vet third party code", ".*_generated\\.go$": "ignore generated code", "/cgo/": "ignore cgo code", @@ -316,7 +318,6 @@ "nilness": { "exclude_files": { "/external/": "no need to vet third party code", - "planner/core/physical_plan_test.go": "please fix it", ".*_generated\\.go$": "ignore generated code", "/cgo/": "ignore cgo" } @@ -332,7 +333,8 @@ "kv/": "kv code", "util/memory": "util/memory", "ddl/": "ddl", - "planner/": "planner" + "planner/": "planner", + "extension/": "extension code" } }, "pkgfact": { @@ -363,6 +365,8 @@ "ddl/backfilling.go": "ddl/backfilling.go", "ddl/column.go": "ddl/column.go", "ddl/index.go": "ddl/index.go", + "ddl/ttl.go": "ddl/ttl.go", + "ddl/ttl_test.go": "ddl/ttl_test.go", "ddl/ingest/": "ddl/ingest/", "expression/builtin_cast.go": "expression/builtin_cast code", "server/conn.go": "server/conn.go", @@ -399,7 +403,10 @@ "planner/core/util.go": "planner/core/util.go", "util/": "util code", "parser/": "parser code", - "meta/": "parser code" + "meta/": "parser code", + "extension/": "extension code", + "resourcemanager/": "resourcemanager code", + "keyspace": "keyspace code" } }, "shift": { @@ -742,22 +749,27 @@ "exclude_files": { "/build/": "no need to linter code", "/external/": "no need to vet third party code", - ".*_generated\\.go$": "ignore generated code" + ".*_generated\\.go$": "ignore generated code", + ".*_test\\.go$": "ignore test code" }, "only_files": { "util/gctuner": "util/gctuner", + "util/cgroup": "util/cgroup code", + "util/watcher": "util/watcher", + "br/pkg/lightning/restore/": "br/pkg/lightning/restore/", "br/pkg/lightning/mydump/": "br/pkg/lightning/mydump/", - "br/pkg/lightning/restore/opts": "br/pkg/lightning/restore/opts", "executor/aggregate.go": "executor/aggregate.go", "types/json_binary_functions.go": "types/json_binary_functions.go", "types/json_binary_test.go": "types/json_binary_test.go", "ddl/": "enable to ddl", - "util/cgroup": "util/cgroup code", "expression/builtin_cast.go": "enable expression/builtin_cast.go", "planner/core/plan.go": "planner/core/plan.go", "server/conn.go": "server/conn.go", "server/conn_stmt.go": "server/conn_stmt.go", - "server/conn_test.go": "server/conn_test.go" + "server/conn_test.go": "server/conn_test.go", + "extension/": "extension code", + "resourcemanager/": "resourcemanager code", + "keyspace/": "keyspace code" } }, "SA2000": { diff --git a/build/patches/io_etcd_go_etcd_raft_v3.patch b/build/patches/io_etcd_go_etcd_raft_v3.patch deleted file mode 100644 index 11c777b38f4de..0000000000000 --- a/build/patches/io_etcd_go_etcd_raft_v3.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff -urN a/raftpb/BUILD.bazel b/raftpb/BUILD.bazel ---- a/raftpb/BUILD.bazel 1969-12-31 19:00:00.000000000 -0500 -+++ b/raftpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -1,4 +1,5 @@ - load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+load("@rules_proto//proto:defs.bzl", "proto_library") - - go_library( - name = "raftpb", -@@ -28,3 +29,12 @@ - srcs = ["confstate_test.go"], - embed = [":raftpb"], - ) -+ -+# keep -+proto_library( -+ name = "raftpb_proto", -+ srcs = ["raft.proto"], -+ deps = ["@com_github_gogo_protobuf//gogoproto:gogo_proto"], -+ import_prefix = "etcd/raft/v3/", -+ visibility = ["//visibility:public"], -+) diff --git a/ci.md b/ci.md index 8b5abfd8fefd3..f7ebabd7a1331 100644 --- a/ci.md +++ b/ci.md @@ -2,30 +2,24 @@ ## Guide -1. ci pipeline will be triggered when your comment on pull request matched command. -2. "**Only triggered by command**". What does that mean? - * Yes, this ci will be triggered only when your comment on pr matched command. - * No, this ci will be triggered by every new commit on current pr, comment matched command also trigger ci pipeline. +ci pipeline will be triggered when your comment on pull request matched command. But we have some task that will be triggered manually. ## Commands -| ci pipeline | Commands | Only triggered by command | -| ---------------------------------------- | ------------------------------------------------------------ | ------------------------- | -| tidb_ghpr_build | /run-build
/run-all-tests
/merge | No | -| tidb_ghpr_check | /run-check_dev
/run-all-tests
/merge | No | -| tidb_ghpr_check_2 | /run-check_dev_2
/run-all-tests
/merge | No | -| tidb_ghpr_coverage | /run-coverage | Yes | -| tidb_ghpr_build_arm64 | /run-build-arm64 | Yes | -| tidb_ghpr_common_test | /run-common-test
/run-integration-tests | Yes | -| tidb_ghpr_integration_br_test | /run-integration-br-test
/run-integration-tests | Yes | -| tidb_ghpr_integration_campatibility_test | /run-integration-compatibility-test
/run-integration-tests | Yes | -| tidb_ghpr_integration_common_test | /run-integration-common-test
/run-integration-tests | Yes | -| tidb_ghpr_integration_copr_test | /run-integration-copr-test
/run-integration-tests | Yes | -| tidb_ghpr_integration_ddl_test | /run-integration-ddl-test
/run-integration-tests | Yes | -| tidb_ghpr_monitor_test | /run-monitor-test | Yes | -| tidb_ghpr_mybatis | /run-mybatis-test
/run-integration-tests | Yes | -| tidb_ghpr_sqllogic_test_1 | /run-sqllogic-test
/run-integration-tests | Yes | -| tidb_ghpr_sqllogic_test_2 | /run-sqllogic-test
/run-integration-tests | Yes | -| tidb_ghpr_tics_test | /run-tics-test
/run-integration-tests | Yes | -| tidb_ghpr_unit_test | /run-unit-test
/run-all-tests
/merge | Yes | +| ci pipeline | Commands | +| ---------------------------------------- |-----------------------------------------------------------------| +| tidb_ghpr_coverage | /run-coverage | +| tidb_ghpr_build_arm64 | /run-build-arm64 comment=true | +| tidb_ghpr_common_test | /run-common-test
/run-integration-tests | +| tidb_ghpr_integration_br_test | /run-integration-br-test
/run-integration-tests | +| tidb_ghpr_integration_campatibility_test | /run-integration-compatibility-test
/run-integration-tests | +| tidb_ghpr_integration_common_test | /run-integration-common-test
/run-integration-tests | +| tidb_ghpr_integration_copr_test | /run-integration-copr-test
/run-integration-tests | +| tidb_ghpr_integration_ddl_test | /run-integration-ddl-test
/run-integration-tests | +| tidb_ghpr_monitor_test | /run-monitor-test | +| tidb_ghpr_mybatis | /run-mybatis-test
/run-integration-tests | +| tidb_ghpr_sqllogic_test_1 | /run-sqllogic-test
/run-integration-tests | +| tidb_ghpr_sqllogic_test_2 | /run-sqllogic-test
/run-integration-tests | +| tidb_ghpr_tics_test | /run-tics-test
/run-integration-tests | +| tidb_ghpr_unit_test | /run-unit-test
/run-all-tests
/merge | diff --git a/cmd/benchkv/main.go b/cmd/benchkv/main.go index 73a388bebbfe5..2b7cf5c9e9abb 100644 --- a/cmd/benchkv/main.go +++ b/cmd/benchkv/main.go @@ -14,7 +14,6 @@ package main -// #nosec G108 import ( "context" "flag" diff --git a/cmd/benchraw/main.go b/cmd/benchraw/main.go index 80f1a1d2289bc..c042d59e9f180 100644 --- a/cmd/benchraw/main.go +++ b/cmd/benchraw/main.go @@ -14,7 +14,6 @@ package main -// #nosec G108 import ( "context" "flag" diff --git a/cmd/ddltest/BUILD.bazel b/cmd/ddltest/BUILD.bazel index 344d46dac3cad..39ac3c9bdb7b4 100644 --- a/cmd/ddltest/BUILD.bazel +++ b/cmd/ddltest/BUILD.bazel @@ -11,6 +11,7 @@ go_test( "random_test.go", ], flaky = True, + race = "on", deps = [ "//config", "//domain", diff --git a/cmd/ddltest/index_test.go b/cmd/ddltest/index_test.go index 7d3206197eba4..dbd96aa62aa39 100644 --- a/cmd/ddltest/index_test.go +++ b/cmd/ddltest/index_test.go @@ -18,11 +18,13 @@ import ( goctx "context" "fmt" "math" + "os" "sync" "sync/atomic" "testing" "time" + "github.com/pingcap/log" "github.com/pingcap/tidb/store/gcworker" "github.com/pingcap/tidb/table" "github.com/stretchr/testify/require" @@ -48,6 +50,11 @@ func (s *ddlSuite) checkDropIndex(t *testing.T, tableName string) { // TestIndex operations on table test_index (c int, c1 bigint, c2 double, c3 varchar(256), primary key(c)). func TestIndex(t *testing.T) { + err := os.Setenv("tidb_manager_ttl", fmt.Sprintf("%d", *lease+5)) + if err != nil { + log.Fatal("set tidb_manager_ttl failed") + } + s := createDDLSuite(t) defer s.teardown(t) diff --git a/cmd/ddltest/main_test.go b/cmd/ddltest/main_test.go index 6016cb9c8d12a..d0ca25b750a14 100644 --- a/cmd/ddltest/main_test.go +++ b/cmd/ddltest/main_test.go @@ -34,12 +34,14 @@ func TestMain(m *testing.M) { } opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), goleak.IgnoreTopFunction("net/http.(*persistConn).writeLoop"), goleak.IgnoreTopFunction("github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher.func1"), goleak.IgnoreTopFunction("database/sql.(*DB).connectionOpener"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/v3.waitRetryBackoff"), } goleak.VerifyTestMain(m, opts...) } diff --git a/cmd/explaintest/BUILD.bazel b/cmd/explaintest/BUILD.bazel index babd3c0d00ed6..106574214f047 100644 --- a/cmd/explaintest/BUILD.bazel +++ b/cmd/explaintest/BUILD.bazel @@ -28,7 +28,6 @@ go_test( name = "explaintest_test", timeout = "short", srcs = ["main_test.go"], - data = ["//tidb-server:tidb-server-raw"], embed = [":explaintest_lib"], flaky = True, ) diff --git a/cmd/explaintest/main.go b/cmd/explaintest/main.go index 32f88dc30a6bc..d5f7f0c98b0a1 100644 --- a/cmd/explaintest/main.go +++ b/cmd/explaintest/main.go @@ -724,6 +724,7 @@ func main() { "set @@tidb_window_concurrency=4", "set @@tidb_projection_concurrency=4", "set @@tidb_distsql_scan_concurrency=15", + "set @@tidb_enable_clustered_index='int_only';", "set @@global.tidb_enable_clustered_index=0;", "set @@global.tidb_mem_quota_query=34359738368", "set @@tidb_mem_quota_query=34359738368", diff --git a/cmd/explaintest/r/access_path_selection.result b/cmd/explaintest/r/access_path_selection.result index bbf5dcb8627a2..cafdc72269eed 100644 --- a/cmd/explaintest/r/access_path_selection.result +++ b/cmd/explaintest/r/access_path_selection.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE TABLE `access_path_selection` ( `a` int, `b` int, diff --git a/cmd/explaintest/r/agg_predicate_pushdown.result b/cmd/explaintest/r/agg_predicate_pushdown.result index 52d0c115aec4b..1e2bedfa2fe34 100644 --- a/cmd/explaintest/r/agg_predicate_pushdown.result +++ b/cmd/explaintest/r/agg_predicate_pushdown.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop database if exists agg_predicate_pushdown; create database agg_predicate_pushdown; create table t(a int, b int, c int); diff --git a/cmd/explaintest/r/black_list.result b/cmd/explaintest/r/black_list.result index 96879cfd47379..f62979b567ee9 100644 --- a/cmd/explaintest/r/black_list.result +++ b/cmd/explaintest/r/black_list.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t (a int); diff --git a/cmd/explaintest/r/clustered_index.result b/cmd/explaintest/r/clustered_index.result index 5412b0c50cfb7..bd1824d07edb3 100644 --- a/cmd/explaintest/r/clustered_index.result +++ b/cmd/explaintest/r/clustered_index.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set @@tidb_enable_outer_join_reorder=true; drop database if exists with_cluster_index; create database with_cluster_index; diff --git a/cmd/explaintest/r/collation_agg_func_disabled.result b/cmd/explaintest/r/collation_agg_func_disabled.result index d2503250f063f..b5075b3c82f83 100644 --- a/cmd/explaintest/r/collation_agg_func_disabled.result +++ b/cmd/explaintest/r/collation_agg_func_disabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_agg_func; use collation_agg_func; create table t(id int, value varchar(20) charset utf8mb4 collate utf8mb4_general_ci, value1 varchar(20) charset utf8mb4 collate utf8mb4_bin); @@ -132,13 +133,13 @@ approx_count_distinct(value collate utf8mb4_bin, value1) create table tt(a char(10), b enum('a', 'B', 'c'), c set('a', 'B', 'c'), d json) collate utf8mb4_general_ci; insert into tt values ("a", "a", "a", JSON_OBJECT("a", "a")); insert into tt values ("A", "A", "A", JSON_OBJECT("A", "A")); -Error 1265: Data truncated for column 'b' at row 1 +Error 1265 (01000): Data truncated for column 'b' at row 1 insert into tt values ("b", "b", "b", JSON_OBJECT("b", "b")); -Error 1265: Data truncated for column 'b' at row 1 +Error 1265 (01000): Data truncated for column 'b' at row 1 insert into tt values ("B", "B", "B", JSON_OBJECT("B", "B")); insert into tt values ("c", "c", "c", JSON_OBJECT("c", "c")); insert into tt values ("C", "C", "C", JSON_OBJECT("C", "C")); -Error 1265: Data truncated for column 'b' at row 1 +Error 1265 (01000): Data truncated for column 'b' at row 1 split table tt by (0), (1), (2), (3), (4), (5); desc format='brief' select min(a) from tt; id estRows task access object operator info @@ -209,9 +210,9 @@ select min(b) from tt; min(b) B desc format='brief' select min(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select min(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select max(b) from tt; id estRows task access object operator info StreamAgg 1.00 root funcs:max(Column#8)->Column#6 @@ -222,9 +223,9 @@ select max(b) from tt; max(b) c desc format='brief' select max(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select max(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select min(c) from tt; id estRows task access object operator info HashAgg 1.00 root funcs:min(collation_agg_func.tt.c)->Column#6 @@ -234,9 +235,9 @@ select min(c) from tt; min(c) B desc format='brief' select min(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select min(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select max(c) from tt; id estRows task access object operator info HashAgg 1.00 root funcs:max(collation_agg_func.tt.c)->Column#6 @@ -246,9 +247,9 @@ select max(c) from tt; max(c) c desc format='brief' select max(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select max(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select min(d) from tt; id estRows task access object operator info StreamAgg 1.00 root funcs:min(collation_agg_func.tt.d)->Column#6 diff --git a/cmd/explaintest/r/collation_agg_func_enabled.result b/cmd/explaintest/r/collation_agg_func_enabled.result index 35c21a1ec469a..5b587ff02d279 100644 --- a/cmd/explaintest/r/collation_agg_func_enabled.result +++ b/cmd/explaintest/r/collation_agg_func_enabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_agg_func; use collation_agg_func; create table t(id int, value varchar(20) charset utf8mb4 collate utf8mb4_general_ci, value1 varchar(20) charset utf8mb4 collate utf8mb4_bin); @@ -206,9 +207,9 @@ select min(b) from tt; min(b) a desc format='brief' select min(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select min(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select max(b) from tt; id estRows task access object operator info StreamAgg 1.00 root funcs:max(Column#8)->Column#6 @@ -219,9 +220,9 @@ select max(b) from tt; max(b) c desc format='brief' select max(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select max(b collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select min(c) from tt; id estRows task access object operator info HashAgg 1.00 root funcs:min(collation_agg_func.tt.c)->Column#6 @@ -231,9 +232,9 @@ select min(c) from tt; min(c) a desc format='brief' select min(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select min(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select max(c) from tt; id estRows task access object operator info HashAgg 1.00 root funcs:max(collation_agg_func.tt.c)->Column#6 @@ -243,9 +244,9 @@ select max(c) from tt; max(c) c desc format='brief' select max(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' select max(c collate utf8mb4_bin) from tt; -Error 1235: This version of TiDB doesn't yet support 'use collate clause for enum or set' +Error 1235 (42000): This version of TiDB doesn't yet support 'use collate clause for enum or set' desc format='brief' select min(d) from tt; id estRows task access object operator info StreamAgg 1.00 root funcs:min(collation_agg_func.tt.d)->Column#6 diff --git a/cmd/explaintest/r/collation_check_use_collation_disabled.result b/cmd/explaintest/r/collation_check_use_collation_disabled.result index 06af2890faa8f..2c0bd306f445b 100644 --- a/cmd/explaintest/r/collation_check_use_collation_disabled.result +++ b/cmd/explaintest/r/collation_check_use_collation_disabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_check_use_collation; use collation_check_use_collation; CREATE TABLE `t` ( @@ -31,7 +32,7 @@ drop table if exists t; create table t(a enum('a', 'b') charset utf8mb4 collate utf8mb4_general_ci, b varchar(20)); insert into t values ("b", "c"); insert into t values ("B", "b"); -Error 1265: Data truncated for column 'a' at row 1 +Error 1265 (01000): Data truncated for column 'a' at row 1 select * from t where 'B' collate utf8mb4_general_ci in (a); a b select * from t where 'B' collate utf8mb4_bin in (a); @@ -81,7 +82,7 @@ drop table if exists t; create table t(a set('a', 'b') charset utf8mb4 collate utf8mb4_general_ci, b varchar(20)); insert into t values ("b", "c"); insert into t values ("B", "b"); -Error 1265: Data truncated for column 'a' at row 1 +Error 1265 (01000): Data truncated for column 'a' at row 1 select * from t where 'B' collate utf8mb4_general_ci in (a); a b select * from t where 'B' collate utf8mb4_bin in (a); diff --git a/cmd/explaintest/r/collation_check_use_collation_enabled.result b/cmd/explaintest/r/collation_check_use_collation_enabled.result index 5bf70a6a73a09..838c6beba6535 100644 --- a/cmd/explaintest/r/collation_check_use_collation_enabled.result +++ b/cmd/explaintest/r/collation_check_use_collation_enabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_check_use_collation; use collation_check_use_collation; CREATE TABLE `t` ( diff --git a/cmd/explaintest/r/collation_misc_disabled.result b/cmd/explaintest/r/collation_misc_disabled.result index a9ee8ac04631f..a66f63ead2db9 100644 --- a/cmd/explaintest/r/collation_misc_disabled.result +++ b/cmd/explaintest/r/collation_misc_disabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_misc; use collation_misc; create table t1(a varchar(20) charset utf8); @@ -14,7 +15,7 @@ select * from t; a t_value alter table t modify column a varchar(20) charset utf8; -Error 8200: Unsupported modify charset from latin1 to utf8 +Error 8200 (HY000): Unsupported modify charset from latin1 to utf8 drop table t; create table t(a varchar(20) charset latin1); insert into t values ("t_value"); @@ -37,13 +38,13 @@ drop table t; create table t(a varchar(20) charset latin1); insert into t values ("t_value"); alter table t modify column a varchar(20) charset utf8 collate utf8_bin; -Error 8200: Unsupported modify charset from latin1 to utf8 +Error 8200 (HY000): Unsupported modify charset from latin1 to utf8 alter table t modify column a varchar(20) charset utf8mb4 collate utf8bin; [ddl:1273]Unknown collation: 'utf8bin' alter table t collate LATIN1_GENERAL_CI charset utf8 collate utf8_bin; -Error 1302: Conflicting declarations: 'CHARACTER SET latin1' and 'CHARACTER SET utf8' +Error 1302 (HY000): Conflicting declarations: 'CHARACTER SET latin1' and 'CHARACTER SET utf8' alter table t collate LATIN1_GENERAL_CI collate UTF8MB4_UNICODE_ci collate utf8_bin; -Error 1253: COLLATION 'utf8mb4_unicode_ci' is not valid for CHARACTER SET 'latin1' +Error 1253 (42000): COLLATION 'utf8mb4_unicode_ci' is not valid for CHARACTER SET 'latin1' drop table t; create table t(a varchar(20) charset latin1); insert into t values ("t_value"); diff --git a/cmd/explaintest/r/collation_misc_enabled.result b/cmd/explaintest/r/collation_misc_enabled.result index 38161ba4ca6a6..a088ddb0b2c9d 100644 --- a/cmd/explaintest/r/collation_misc_enabled.result +++ b/cmd/explaintest/r/collation_misc_enabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_misc; use collation_misc; create table t1(a varchar(20) charset utf8); @@ -14,7 +15,7 @@ select * from t; a t_value alter table t modify column a varchar(20) charset utf8; -Error 8200: Unsupported modify charset from latin1 to utf8 +Error 8200 (HY000): Unsupported modify charset from latin1 to utf8 drop table t; create table t(a varchar(20) charset latin1); insert into t values ("t_value"); @@ -37,13 +38,13 @@ drop table t; create table t(a varchar(20) charset latin1); insert into t values ("t_value"); alter table t modify column a varchar(20) charset utf8 collate utf8_bin; -Error 8200: Unsupported modify charset from latin1 to utf8 +Error 8200 (HY000): Unsupported modify charset from latin1 to utf8 alter table t modify column a varchar(20) charset utf8mb4 collate utf8bin; [ddl:1273]Unknown collation: 'utf8bin' alter table t collate LATIN1_GENERAL_CI charset utf8 collate utf8_bin; -Error 1273: Unsupported collation when new collation is enabled: 'latin1_general_ci' +Error 1273 (HY000): Unsupported collation when new collation is enabled: 'latin1_general_ci' alter table t collate LATIN1_GENERAL_CI collate UTF8MB4_UNICODE_ci collate utf8_bin; -Error 1273: Unsupported collation when new collation is enabled: 'latin1_general_ci' +Error 1273 (HY000): Unsupported collation when new collation is enabled: 'latin1_general_ci' drop table t; create table t(a varchar(20) charset latin1); insert into t values ("t_value"); @@ -55,7 +56,7 @@ a t_value create database if not exists cd_test_utf8 CHARACTER SET utf8 COLLATE utf8_bin; create database if not exists cd_test_latin1 CHARACTER SET latin1 COLLATE latin1_swedish_ci; -Error 1273: Unsupported collation when new collation is enabled: 'latin1_swedish_ci' +Error 1273 (HY000): Unsupported collation when new collation is enabled: 'latin1_swedish_ci' use cd_test_utf8; select @@character_set_database; @@character_set_database @@ -64,7 +65,7 @@ select @@collation_database; @@collation_database utf8_bin use cd_test_latin1; -Error 1049: Unknown database 'cd_test_latin1' +Error 1049 (42000): Unknown database 'cd_test_latin1' select @@character_set_database; @@character_set_database utf8 @@ -72,7 +73,7 @@ select @@collation_database; @@collation_database utf8_bin create database if not exists test_db CHARACTER SET latin1 COLLATE latin1_swedish_ci; -Error 1273: Unsupported collation when new collation is enabled: 'latin1_swedish_ci' +Error 1273 (HY000): Unsupported collation when new collation is enabled: 'latin1_swedish_ci' with cte as (select cast('2010-09-09' as date) a union select '2010-09-09 ') select count(*) from cte; count(*) 1 diff --git a/cmd/explaintest/r/collation_pointget_disabled.result b/cmd/explaintest/r/collation_pointget_disabled.result index 96b2a7aa58ca5..db7b0a9ab630f 100644 --- a/cmd/explaintest/r/collation_pointget_disabled.result +++ b/cmd/explaintest/r/collation_pointget_disabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_point_get; use collation_point_get; drop table if exists t; @@ -110,15 +111,15 @@ select *, a, b from t tmp where tmp.a = "aa"; a b a b aa bb aa bb select a from t where xxxxx.a = "aa"; -Error 1054: Unknown column 'xxxxx.a' in 'where clause' +Error 1054 (42S22): Unknown column 'xxxxx.a' in 'where clause' select xxxxx.a from t where a = "aa"; -Error 1054: Unknown column 'xxxxx.a' in 'field list' +Error 1054 (42S22): Unknown column 'xxxxx.a' in 'field list' select a from t tmp where t.a = "aa"; -Error 1054: Unknown column 't.a' in 'where clause' +Error 1054 (42S22): Unknown column 't.a' in 'where clause' select t.a from t tmp where a = "aa"; -Error 1054: Unknown column 't.a' in 'field list' +Error 1054 (42S22): Unknown column 't.a' in 'field list' select t.* from t tmp where a = "aa"; -Error 1051: Unknown table 't' +Error 1051 (42S02): Unknown table 't' drop table if exists t; create table t(a char(4) primary key, b char(4)); insert into t values("aa", "bb"); diff --git a/cmd/explaintest/r/collation_pointget_enabled.result b/cmd/explaintest/r/collation_pointget_enabled.result index c5bcd58c15ba2..7c404177ce587 100644 --- a/cmd/explaintest/r/collation_pointget_enabled.result +++ b/cmd/explaintest/r/collation_pointget_enabled.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; create database collation_point_get; use collation_point_get; drop table if exists t; @@ -123,15 +124,15 @@ select *, a, b from t tmp where tmp.a = "aa"; a b a b aa bb aa bb select a from t where xxxxx.a = "aa"; -Error 1054: Unknown column 'xxxxx.a' in 'where clause' +Error 1054 (42S22): Unknown column 'xxxxx.a' in 'where clause' select xxxxx.a from t where a = "aa"; -Error 1054: Unknown column 'xxxxx.a' in 'field list' +Error 1054 (42S22): Unknown column 'xxxxx.a' in 'field list' select a from t tmp where t.a = "aa"; -Error 1054: Unknown column 't.a' in 'where clause' +Error 1054 (42S22): Unknown column 't.a' in 'where clause' select t.a from t tmp where a = "aa"; -Error 1054: Unknown column 't.a' in 'field list' +Error 1054 (42S22): Unknown column 't.a' in 'field list' select t.* from t tmp where a = "aa"; -Error 1051: Unknown table 't' +Error 1051 (42S02): Unknown table 't' drop table if exists t; create table t(a char(4) primary key, b char(4)); insert into t values("aa", "bb"); diff --git a/cmd/explaintest/r/common_collation.result b/cmd/explaintest/r/common_collation.result index 235ce7fce3d0d..d686c5008bbd9 100644 --- a/cmd/explaintest/r/common_collation.result +++ b/cmd/explaintest/r/common_collation.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; create table t(a char(10) collate utf8mb4_unicode_ci, b char(10) collate utf8mb4_general_ci); insert into t values ('啊', '撒旦'); diff --git a/cmd/explaintest/r/cte.result b/cmd/explaintest/r/cte.result index cf427c05a181c..6f277815bb566 100644 --- a/cmd/explaintest/r/cte.result +++ b/cmd/explaintest/r/cte.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists tbl_0; create table tbl_0(a int); @@ -90,7 +91,7 @@ c1 c2 1 1 1 2 with recursive tbl_0 (col_943,col_944,col_945,col_946,col_947) AS ( with recursive tbl_0 (col_948,col_949,col_950,col_951,col_952) AS ( select 1, 2,3,4,5 UNION ALL select col_948 + 1,col_949 + 1,col_950 + 1,col_951 + 1,col_952 + 1 from tbl_0 where col_948 < 5 ) select col_948,col_949,col_951,col_950,col_952 from tbl_0 UNION ALL select col_943 + 1,col_944 + 1,col_945 + 1,col_946 + 1,col_947 + 1 from tbl_0 where col_943 < 5 ) select * from tbl_0; -Error 1054: Unknown column 'col_943' in 'where clause' +Error 1054 (42S22): Unknown column 'col_943' in 'where clause' with recursive cte1 (c1, c2) as (select 1, '1' union select concat(c1, 1), c2 + 1 from cte1 where c1 < 100) select * from cte1; c1 c2 1 1 @@ -282,15 +283,15 @@ union all select 3, 0 from qn ) select * from qn; -Error 1222: The used SELECT statements have a different number of columns +Error 1222 (21000): The used SELECT statements have a different number of columns with recursive cte1 as (select 1 union all (select 1 from cte1 limit 10)) select * from cte1; -Error 1235: This version of TiDB doesn't yet support 'ORDER BY / LIMIT / SELECT DISTINCT in recursive query block of Common Table Expression' +Error 1235 (42000): This version of TiDB doesn't yet support 'ORDER BY / LIMIT / SELECT DISTINCT in recursive query block of Common Table Expression' with recursive qn as (select 123 as a union all select null from qn where a is not null) select * from qn; a 123 NULL with recursive q (b) as (select 1, 1 union all select 1, 1 from q) select b from q; -Error 1353: In definition of view, derived table or common table expression, SELECT list and column names list have different column counts +Error 1353 (HY000): In definition of view, derived table or common table expression, SELECT list and column names list have different column counts drop table if exists t1; create table t1(a int); insert into t1 values(1); @@ -355,7 +356,7 @@ drop table if exists t1; create table t1(c1 bigint unsigned); insert into t1 values(0); with recursive cte1 as (select c1 - 1 c1 from t1 union all select c1 - 1 c1 from cte1 where c1 != 0) select * from cte1 dt1, cte1 dt2; -Error 1690: BIGINT UNSIGNED value is out of range in '(test.t1.c1 - 1)' +Error 1690 (22003): BIGINT UNSIGNED value is out of range in '(test.t1.c1 - 1)' drop table if exists t; create table t(a int, b int, key (b)); desc with cte as (select * from t) select * from cte; @@ -594,11 +595,11 @@ Projection_16 10000.00 root test.t1.c1, test.t1.c2 └─Apply_18 10000.00 root CARTESIAN inner join, other cond:or(and(gt(test.t1.c1, Column#11), if(ne(Column#12, 0), NULL, 1)), or(eq(Column#13, 0), if(isnull(test.t1.c1), NULL, 0))) ├─TableReader_20(Build) 10000.00 root data:TableFullScan_19 │ └─TableFullScan_19 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─StreamAgg_35(Probe) 1.00 root funcs:max(Column#19)->Column#11, funcs:sum(Column#20)->Column#12, funcs:count(Column#21)->Column#13 - └─TableReader_36 1.00 root data:StreamAgg_24 - └─StreamAgg_24 1.00 cop[tikv] funcs:max(test.t2.c1)->Column#19, funcs:sum(isnull(test.t2.c1))->Column#20, funcs:count(1)->Column#21 - └─Selection_34 10.00 cop[tikv] eq(test.t2.c2, test.t1.c2) - └─TableFullScan_33 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo + └─StreamAgg_35(Probe) 10000.00 root funcs:max(Column#19)->Column#11, funcs:sum(Column#20)->Column#12, funcs:count(Column#21)->Column#13 + └─TableReader_36 10000.00 root data:StreamAgg_24 + └─StreamAgg_24 10000.00 cop[tikv] funcs:max(test.t2.c1)->Column#19, funcs:sum(isnull(test.t2.c1))->Column#20, funcs:count(1)->Column#21 + └─Selection_34 100000.00 cop[tikv] eq(test.t2.c2, test.t1.c2) + └─TableFullScan_33 100000000.00 cop[tikv] table:t2 keep order:false, stats:pseudo select * from t1 where c1 > all(with cte1 as (select c1 from t2 where t2.c2 = t1.c2) select c1 from cte1); c1 c2 2 1 @@ -624,9 +625,9 @@ Projection_26 10000.00 root test.t1.c1, test.t1.c2 └─Apply_28 10000.00 root CARTESIAN inner join, other cond:or(and(gt(test.t1.c1, Column#14), if(ne(Column#15, 0), NULL, 1)), or(eq(Column#16, 0), if(isnull(test.t1.c1), NULL, 0))) ├─TableReader_30(Build) 10000.00 root data:TableFullScan_29 │ └─TableFullScan_29 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─HashAgg_31(Probe) 1.00 root funcs:max(Column#19)->Column#14, funcs:sum(Column#20)->Column#15, funcs:count(1)->Column#16 - └─Projection_35 20.00 root test.t2.c1, cast(isnull(test.t2.c1), decimal(20,0) BINARY)->Column#20 - └─CTEFullScan_33 20.00 root CTE:cte1 data:CTE_0 + └─HashAgg_31(Probe) 10000.00 root funcs:max(Column#19)->Column#14, funcs:sum(Column#20)->Column#15, funcs:count(1)->Column#16 + └─Projection_35 200000.00 root test.t2.c1, cast(isnull(test.t2.c1), decimal(20,0) BINARY)->Column#20 + └─CTEFullScan_33 200000.00 root CTE:cte1 data:CTE_0 CTE_0 20.00 root Recursive CTE, limit(offset:0, count:1) ├─Projection_19(Seed Part) 10.00 root test.t2.c1 │ └─TableReader_22 10.00 root data:Selection_21 @@ -643,7 +644,7 @@ id estRows task access object operator info Apply_25 10000.00 root CARTESIAN semi join ├─TableReader_27(Build) 10000.00 root data:TableFullScan_26 │ └─TableFullScan_26 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo -└─CTEFullScan_28(Probe) 20.00 root CTE:cte1 data:CTE_0 +└─CTEFullScan_28(Probe) 200000.00 root CTE:cte1 data:CTE_0 CTE_0 20.00 root Recursive CTE, limit(offset:0, count:10) ├─Projection_17(Seed Part) 10.00 root test.t2.c1 │ └─TableReader_20 10.00 root data:Selection_19 @@ -662,9 +663,9 @@ Projection_24 10000.00 root test.t1.c1, test.t1.c2 └─Apply_26 10000.00 root CARTESIAN inner join, other cond:or(and(gt(test.t1.c1, Column#18), if(ne(Column#19, 0), NULL, 1)), or(eq(Column#20, 0), if(isnull(test.t1.c1), NULL, 0))) ├─TableReader_28(Build) 10000.00 root data:TableFullScan_27 │ └─TableFullScan_27 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─HashAgg_29(Probe) 1.00 root funcs:max(Column#23)->Column#18, funcs:sum(Column#24)->Column#19, funcs:count(1)->Column#20 - └─Projection_33 18000.00 root test.t2.c1, cast(isnull(test.t2.c1), decimal(20,0) BINARY)->Column#24 - └─CTEFullScan_31 18000.00 root CTE:cte1 data:CTE_0 + └─HashAgg_29(Probe) 10000.00 root funcs:max(Column#23)->Column#18, funcs:sum(Column#24)->Column#19, funcs:count(1)->Column#20 + └─Projection_33 180000000.00 root test.t2.c1, cast(isnull(test.t2.c1), decimal(20,0) BINARY)->Column#24 + └─CTEFullScan_31 180000000.00 root CTE:cte1 data:CTE_0 CTE_0 18000.00 root Recursive CTE ├─TableReader_19(Seed Part) 10000.00 root data:TableFullScan_18 │ └─TableFullScan_18 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo @@ -678,7 +679,7 @@ id estRows task access object operator info Apply_23 10000.00 root CARTESIAN semi join ├─TableReader_25(Build) 10000.00 root data:TableFullScan_24 │ └─TableFullScan_24 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo -└─CTEFullScan_26(Probe) 18000.00 root CTE:cte1 data:CTE_0 +└─CTEFullScan_26(Probe) 180000000.00 root CTE:cte1 data:CTE_0 CTE_0 18000.00 root Recursive CTE ├─TableReader_17(Seed Part) 10000.00 root data:TableFullScan_16 │ └─TableFullScan_16 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo diff --git a/cmd/explaintest/r/explain-non-select-stmt.result b/cmd/explaintest/r/explain-non-select-stmt.result index 025733884b0b8..d5e18f7d85cf3 100644 --- a/cmd/explaintest/r/explain-non-select-stmt.result +++ b/cmd/explaintest/r/explain-non-select-stmt.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t(a bigint, b bigint); diff --git a/cmd/explaintest/r/explain.result b/cmd/explaintest/r/explain.result index 2556051099efc..78f7d289eb39d 100644 --- a/cmd/explaintest/r/explain.result +++ b/cmd/explaintest/r/explain.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; create table t (id int, c1 timestamp); show columns from t; diff --git a/cmd/explaintest/r/explain_complex.result b/cmd/explaintest/r/explain_complex.result index b68393c99fcfe..d8e1f186a4028 100644 --- a/cmd/explaintest/r/explain_complex.result +++ b/cmd/explaintest/r/explain_complex.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE TABLE `dt` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT , `aid` varchar(32) NOT NULL, @@ -138,9 +139,9 @@ Projection 0.00 root test.st.id, test.dd.id, test.st.aid, test.st.cm, test.dd.d │ └─Selection(Probe) 0.00 cop[tikv] eq(test.st.bm, 0), eq(test.st.dit, "mac"), eq(test.st.pt, "ios"), not(isnull(test.st.dic)) │ └─TableRowIDScan 3333.33 cop[tikv] table:gad keep order:false, stats:pseudo └─IndexLookUp(Probe) 0.00 root - ├─IndexRangeScan(Build) 10000.00 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:false, stats:pseudo + ├─IndexRangeScan(Build) 0.03 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:false, stats:pseudo └─Selection(Probe) 0.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "ios"), gt(test.dd.t, 1477971479), not(isnull(test.dd.mac)), not(isnull(test.dd.t)) - └─TableRowIDScan 10000.00 cop[tikv] table:sdk keep order:false, stats:pseudo + └─TableRowIDScan 0.03 cop[tikv] table:sdk keep order:false, stats:pseudo explain format = 'brief' SELECT cm, p1, p2, p3, p4, p5, p6_md5, p7_md5, count(1) as click_pv, count(DISTINCT ip) as click_ip FROM st WHERE (t between 1478188800 and 1478275200) and aid='cn.sbkcq' and pt='android' GROUP BY cm, p1, p2, p3, p4, p5, p6_md5, p7_md5; id estRows task access object operator info Projection 1.00 root test.st.cm, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, Column#20, Column#21 @@ -157,11 +158,11 @@ Projection 0.01 root test.dt.id, test.dt.aid, test.dt.pt, test.dt.dic, test.dt. ├─TableReader(Build) 3.33 root data:Selection │ └─Selection 3.33 cop[tikv] eq(test.rr.pt, "ios"), gt(test.rr.t, 1478185592) │ └─TableFullScan 10000.00 cop[tikv] table:rr keep order:false, stats:pseudo - └─IndexLookUp(Probe) 0.00 root - ├─Selection(Build) 1.00 cop[tikv] not(isnull(test.dt.dic)) - │ └─IndexRangeScan 1.00 cop[tikv] table:dt, index:aid(aid, dic) range: decided by [eq(test.dt.aid, test.rr.aid) eq(test.dt.dic, test.rr.dic)], keep order:false, stats:pseudo - └─Selection(Probe) 0.00 cop[tikv] eq(test.dt.bm, 0), eq(test.dt.pt, "ios"), gt(test.dt.t, 1478185592) - └─TableRowIDScan 1.00 cop[tikv] table:dt keep order:false, stats:pseudo + └─IndexLookUp(Probe) 0.01 root + ├─Selection(Build) 3.33 cop[tikv] not(isnull(test.dt.dic)) + │ └─IndexRangeScan 3.33 cop[tikv] table:dt, index:aid(aid, dic) range: decided by [eq(test.dt.aid, test.rr.aid) eq(test.dt.dic, test.rr.dic)], keep order:false, stats:pseudo + └─Selection(Probe) 0.01 cop[tikv] eq(test.dt.bm, 0), eq(test.dt.pt, "ios"), gt(test.dt.t, 1478185592) + └─TableRowIDScan 3.33 cop[tikv] table:dt keep order:false, stats:pseudo explain format = 'brief' select pc,cr,count(DISTINCT uid) as pay_users,count(oid) as pay_times,sum(am) as am from pp where ps=2 and ppt>=1478188800 and ppt<1478275200 and pi in ('510017','520017') and uid in ('18089709','18090780') group by pc,cr; id estRows task access object operator info Projection 1.00 root test.pp.pc, test.pp.cr, Column#22, Column#23, Column#24 @@ -242,6 +243,7 @@ created_on datetime DEFAULT NULL, updated_on datetime DEFAULT NULL, UNIQUE KEY org_employee_position_pk (hotel_id,user_id,position_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +set tidb_cost_model_version=2; explain format = 'brief' SELECT d.id, d.ctx, d.name, d.left_value, d.right_value, d.depth, d.leader_id, d.status, d.created_on, d.updated_on FROM org_department AS d LEFT JOIN org_position AS p ON p.department_id = d.id AND p.status = 1000 LEFT JOIN org_employee_position AS ep ON ep.position_id = p.id AND ep.status = 1000 WHERE (d.ctx = 1 AND (ep.user_id = 62 OR d.id = 20 OR d.id = 20) AND d.status = 1000) GROUP BY d.id ORDER BY d.left_value; id estRows task access object operator info Sort 1.00 root test.org_department.left_value @@ -253,14 +255,15 @@ Sort 1.00 root test.org_department.left_value │ │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:d, index:org_department_ctx_index(ctx) range:[1,1], keep order:false, stats:pseudo │ │ └─Selection(Probe) 0.01 cop[tikv] eq(test.org_department.status, 1000) │ │ └─TableRowIDScan 10.00 cop[tikv] table:d keep order:false, stats:pseudo - │ └─IndexLookUp(Probe) 1.25 root - │ ├─Selection(Build) 1250.00 cop[tikv] not(isnull(test.org_position.department_id)) - │ │ └─IndexRangeScan 1251.25 cop[tikv] table:p, index:org_position_department_id_index(department_id) range: decided by [eq(test.org_position.department_id, test.org_department.id)], keep order:false, stats:pseudo - │ └─Selection(Probe) 1.25 cop[tikv] eq(test.org_position.status, 1000) - │ └─TableRowIDScan 1250.00 cop[tikv] table:p keep order:false, stats:pseudo + │ └─IndexLookUp(Probe) 0.01 root + │ ├─Selection(Build) 12.50 cop[tikv] not(isnull(test.org_position.department_id)) + │ │ └─IndexRangeScan 12.51 cop[tikv] table:p, index:org_position_department_id_index(department_id) range: decided by [eq(test.org_position.department_id, test.org_department.id)], keep order:false, stats:pseudo + │ └─Selection(Probe) 0.01 cop[tikv] eq(test.org_position.status, 1000) + │ └─TableRowIDScan 12.50 cop[tikv] table:p keep order:false, stats:pseudo └─TableReader(Probe) 9.99 root data:Selection └─Selection 9.99 cop[tikv] eq(test.org_employee_position.status, 1000), not(isnull(test.org_employee_position.position_id)) └─TableFullScan 10000.00 cop[tikv] table:ep keep order:false, stats:pseudo +set tidb_cost_model_version=1; create table test.Tab_A (id int primary key,bid int,cid int,name varchar(20),type varchar(20),num int,amt decimal(11,2)); create table test.Tab_B (id int primary key,name varchar(20)); create table test.Tab_C (id int primary key,name varchar(20),amt decimal(11,2)); @@ -278,10 +281,10 @@ Projection_8 15.62 root test.tab_a.name, test.tab_b.name, test.tab_a.amt, test. │ ├─TableReader_33(Build) 10.00 root data:Selection_32 │ │ └─Selection_32 10.00 cop[tikv] eq(test.tab_a.num, 112) │ │ └─TableFullScan_31 10000.00 cop[tikv] table:Tab_A keep order:false, stats:pseudo - │ └─TableReader_21(Probe) 1.00 root data:TableRangeScan_20 - │ └─TableRangeScan_20 1.00 cop[tikv] table:Tab_B range: decided by [test.tab_a.bid], keep order:false, stats:pseudo - └─TableReader_10(Probe) 1.00 root data:TableRangeScan_9 - └─TableRangeScan_9 1.00 cop[tikv] table:Tab_C range: decided by [test.tab_a.cid], keep order:false, stats:pseudo + │ └─TableReader_21(Probe) 10.00 root data:TableRangeScan_20 + │ └─TableRangeScan_20 10.00 cop[tikv] table:Tab_B range: decided by [test.tab_a.bid], keep order:false, stats:pseudo + └─TableReader_10(Probe) 12.50 root data:TableRangeScan_9 + └─TableRangeScan_9 12.50 cop[tikv] table:Tab_C range: decided by [test.tab_a.cid], keep order:false, stats:pseudo select Tab_A.name AAA,Tab_B.name BBB,Tab_A.amt Aamt, Tab_C.amt Bamt,IFNULL(Tab_C.amt, 0) FROM Tab_A left join Tab_B on Tab_A.bid=Tab_B.id left join Tab_C on Tab_A.cid=Tab_C.id and Tab_A.type='01' where Tab_A.num=112; AAA BBB Aamt Bamt IFNULL(Tab_C.amt, 0) A01 B01 111.00 22.00 22.00 diff --git a/cmd/explaintest/r/explain_complex_stats.result b/cmd/explaintest/r/explain_complex_stats.result index ed7021dbbfba2..d6d753a7ef6bb 100644 --- a/cmd/explaintest/r/explain_complex_stats.result +++ b/cmd/explaintest/r/explain_complex_stats.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists dt; CREATE TABLE dt ( id int(11) unsigned NOT NULL, @@ -143,10 +144,10 @@ Projection 170.34 root test.st.id, test.dd.id, test.st.aid, test.st.cm, test.dd ├─TableReader(Build) 170.34 root data:Selection │ └─Selection 170.34 cop[tikv] eq(test.st.bm, 0), eq(test.st.dit, "mac"), eq(test.st.pt, "ios"), gt(test.st.t, 1477971479), not(isnull(test.st.dic)) │ └─TableFullScan 1999.00 cop[tikv] table:gad keep order:false - └─IndexLookUp(Probe) 1.00 root - ├─IndexRangeScan(Build) 3.93 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:false - └─Selection(Probe) 1.00 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "ios"), gt(test.dd.t, 1477971479), not(isnull(test.dd.mac)), not(isnull(test.dd.t)) - └─TableRowIDScan 3.93 cop[tikv] table:sdk keep order:false + └─IndexLookUp(Probe) 170.34 root + ├─IndexRangeScan(Build) 669.25 cop[tikv] table:sdk, index:aid(aid, dic) range: decided by [eq(test.dd.aid, test.st.aid)], keep order:false + └─Selection(Probe) 170.34 cop[tikv] eq(test.dd.bm, 0), eq(test.dd.pt, "ios"), gt(test.dd.t, 1477971479), not(isnull(test.dd.mac)), not(isnull(test.dd.t)) + └─TableRowIDScan 669.25 cop[tikv] table:sdk keep order:false explain format = 'brief' SELECT cm, p1, p2, p3, p4, p5, p6_md5, p7_md5, count(1) as click_pv, count(DISTINCT ip) as click_ip FROM st WHERE (t between 1478188800 and 1478275200) and aid='cn.sbkcq' and pt='android' GROUP BY cm, p1, p2, p3, p4, p5, p6_md5, p7_md5; id estRows task access object operator info Projection 39.28 root test.st.cm, test.st.p1, test.st.p2, test.st.p3, test.st.p4, test.st.p5, test.st.p6_md5, test.st.p7_md5, Column#20, Column#21 @@ -163,10 +164,10 @@ Projection 428.32 root test.dt.id, test.dt.aid, test.dt.pt, test.dt.dic, test.d ├─TableReader(Build) 428.32 root data:Selection │ └─Selection 428.32 cop[tikv] eq(test.dt.bm, 0), eq(test.dt.pt, "ios"), gt(test.dt.t, 1478185592), not(isnull(test.dt.dic)) │ └─TableFullScan 2000.00 cop[tikv] table:dt keep order:false - └─IndexLookUp(Probe) 1.00 root - ├─IndexRangeScan(Build) 1.00 cop[tikv] table:rr, index:PRIMARY(aid, dic) range: decided by [eq(test.rr.aid, test.dt.aid) eq(test.rr.dic, test.dt.dic)], keep order:false - └─Selection(Probe) 1.00 cop[tikv] eq(test.rr.pt, "ios"), gt(test.rr.t, 1478185592) - └─TableRowIDScan 1.00 cop[tikv] table:rr keep order:false + └─IndexLookUp(Probe) 428.32 root + ├─IndexRangeScan(Build) 428.32 cop[tikv] table:rr, index:PRIMARY(aid, dic) range: decided by [eq(test.rr.aid, test.dt.aid) eq(test.rr.dic, test.dt.dic)], keep order:false + └─Selection(Probe) 428.32 cop[tikv] eq(test.rr.pt, "ios"), gt(test.rr.t, 1478185592) + └─TableRowIDScan 428.32 cop[tikv] table:rr keep order:false explain format = 'brief' select pc,cr,count(DISTINCT uid) as pay_users,count(oid) as pay_times,sum(am) as am from pp where ps=2 and ppt>=1478188800 and ppt<1478275200 and pi in ('510017','520017') and uid in ('18089709','18090780') group by pc,cr; id estRows task access object operator info Projection 207.02 root test.pp.pc, test.pp.cr, Column#22, Column#23, Column#24 diff --git a/cmd/explaintest/r/explain_cte.result b/cmd/explaintest/r/explain_cte.result index 1d0653c4a4490..7d8b328fb4c50 100644 --- a/cmd/explaintest/r/explain_cte.result +++ b/cmd/explaintest/r/explain_cte.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2; create table t1 (c1 int primary key, c2 int, index c2 (c2)); @@ -113,8 +114,8 @@ id estRows task access object operator info Apply_24 10000.00 root CARTESIAN semi join ├─TableReader_26(Build) 10000.00 root data:TableFullScan_25 │ └─TableFullScan_25 10000.00 cop[tikv] table:dt keep order:false, stats:pseudo -└─Selection_29(Probe) 1.44 root eq(Column#8, 1) - └─CTEFullScan_30 1.80 root CTE:qn data:CTE_0 +└─Selection_29(Probe) 14400.00 root eq(Column#8, 1) + └─CTEFullScan_30 18000.00 root CTE:qn data:CTE_0 CTE_0 1.80 root Recursive CTE ├─Projection_17(Seed Part) 1.00 root plus(mul(test.t1.c1, 0), 1)->Column#4 │ └─TableDual_18 1.00 root rows:1 @@ -417,9 +418,9 @@ CTE_0 50.00 root Non-Recursive CTE │ │ └─TableReader(Probe) 9980.01 root data:Selection │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.store_sales.ss_customer_sk)), not(isnull(test.store_sales.ss_sold_date_sk)) │ │ └─TableFullScan 10000.00 cop[tikv] table:store_sales keep order:false, stats:pseudo - │ └─IndexLookUp(Probe) 1.00 root - │ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:customer, index:PRIMARY(c_customer_sk) range: decided by [eq(test.customer.c_customer_sk, test.store_sales.ss_customer_sk)], keep order:false, stats:pseudo - │ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:customer keep order:false, stats:pseudo + │ └─IndexLookUp(Probe) 25.00 root + │ ├─IndexRangeScan(Build) 25.00 cop[tikv] table:customer, index:PRIMARY(c_customer_sk) range: decided by [eq(test.customer.c_customer_sk, test.store_sales.ss_customer_sk)], keep order:false, stats:pseudo + │ └─TableRowIDScan(Probe) 25.00 cop[tikv] table:customer keep order:false, stats:pseudo └─Projection 25.00 root test.customer.c_customer_id, test.customer.c_first_name, test.customer.c_last_name, test.customer.c_preferred_cust_flag, test.customer.c_birth_country, test.customer.c_login, test.customer.c_email_address, test.date_dim.d_year, Column#158, w->Column#169 └─Selection 25.00 root or(0, or(and(1, and(eq(test.date_dim.d_year, 2001), gt(Column#158, 0))), and(1, eq(test.date_dim.d_year, 2002)))) └─HashAgg 31.25 root group by:Column#250, Column#251, Column#252, Column#253, Column#254, Column#255, Column#256, Column#257, funcs:sum(Column#241)->Column#158, funcs:firstrow(Column#242)->test.customer.c_customer_id, funcs:firstrow(Column#243)->test.customer.c_first_name, funcs:firstrow(Column#244)->test.customer.c_last_name, funcs:firstrow(Column#245)->test.customer.c_preferred_cust_flag, funcs:firstrow(Column#246)->test.customer.c_birth_country, funcs:firstrow(Column#247)->test.customer.c_login, funcs:firstrow(Column#248)->test.customer.c_email_address, funcs:firstrow(Column#249)->test.date_dim.d_year @@ -433,9 +434,9 @@ CTE_0 50.00 root Non-Recursive CTE │ └─TableReader(Probe) 9980.01 root data:Selection │ └─Selection 9980.01 cop[tikv] not(isnull(test.web_sales.ws_bill_customer_sk)), not(isnull(test.web_sales.ws_sold_date_sk)) │ └─TableFullScan 10000.00 cop[tikv] table:web_sales keep order:false, stats:pseudo - └─IndexLookUp(Probe) 1.00 root - ├─IndexRangeScan(Build) 1.00 cop[tikv] table:customer, index:PRIMARY(c_customer_sk) range: decided by [eq(test.customer.c_customer_sk, test.web_sales.ws_bill_customer_sk)], keep order:false, stats:pseudo - └─TableRowIDScan(Probe) 1.00 cop[tikv] table:customer keep order:false, stats:pseudo + └─IndexLookUp(Probe) 25.00 root + ├─IndexRangeScan(Build) 25.00 cop[tikv] table:customer, index:PRIMARY(c_customer_sk) range: decided by [eq(test.customer.c_customer_sk, test.web_sales.ws_bill_customer_sk)], keep order:false, stats:pseudo + └─TableRowIDScan(Probe) 25.00 cop[tikv] table:customer keep order:false, stats:pseudo drop table if exists t1; create table t1 (id int, bench_type varchar(10),version varchar(10),tps int(20)); insert into t1 (id,bench_type,version,tps) values (1,'sysbench','5.4.0',1111111); diff --git a/cmd/explaintest/r/explain_easy.result b/cmd/explaintest/r/explain_easy.result index b1fd300e9705f..6e367f1f1a0dc 100644 --- a/cmd/explaintest/r/explain_easy.result +++ b/cmd/explaintest/r/explain_easy.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2, t3, t4; create table t1 (c1 int primary key, c2 int, c3 int, index c2 (c2)); @@ -131,12 +132,12 @@ Projection 10000.00 root eq(test.t1.c2, test.t2.c2)->Column#11 └─Apply 10000.00 root CARTESIAN left outer join ├─TableReader(Build) 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─Limit(Probe) 1.00 root offset:0, count:1 - └─Projection 1.00 root test.t2.c1, test.t2.c2 - └─IndexLookUp 1.00 root - ├─Limit(Build) 1.00 cop[tikv] offset:0, count:1 - │ └─IndexRangeScan 1.00 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:true, stats:pseudo - └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false, stats:pseudo + └─Limit(Probe) 10000.00 root offset:0, count:1 + └─Projection 10000.00 root test.t2.c1, test.t2.c2 + └─IndexLookUp 10000.00 root + ├─Limit(Build) 10000.00 cop[tikv] offset:0, count:1 + │ └─IndexRangeScan 10000.00 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:true, stats:pseudo + └─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo explain format = 'brief' select * from t1 order by c1 desc limit 1; id estRows task access object operator info Limit 1.00 root offset:0, count:1 @@ -324,38 +325,38 @@ Projection 10000.00 root Column#17 └─Apply 10000.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#16) ├─TableReader(Build) 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo - └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#16 - └─MergeJoin 12.50 root inner join, left key:test.t.a, right key:test.t.a - ├─TableReader(Build) 1.00 root data:TableRangeScan - │ └─TableRangeScan 1.00 cop[tikv] table:t1 range: decided by [eq(test.t.a, test.t.a)], keep order:true, stats:pseudo - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:s range: decided by [eq(test.t.a, test.t.a)], keep order:true, stats:pseudo + └─StreamAgg(Probe) 10000.00 root funcs:count(1)->Column#16 + └─MergeJoin 125000.00 root inner join, left key:test.t.a, right key:test.t.a + ├─TableReader(Build) 10000.00 root data:TableRangeScan + │ └─TableRangeScan 10000.00 cop[tikv] table:t1 range: decided by [eq(test.t.a, test.t.a)], keep order:true, stats:pseudo + └─TableReader(Probe) 10000.00 root data:TableRangeScan + └─TableRangeScan 10000.00 cop[tikv] table:s range: decided by [eq(test.t.a, test.t.a)], keep order:true, stats:pseudo explain format = 'brief' select t.c in (select count(*) from t s use index(idx), t t1 where s.b = t.a and s.a = t1.a) from t; id estRows task access object operator info Projection 10000.00 root Column#17 └─Apply 10000.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#16) ├─TableReader(Build) 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo - └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#16 - └─IndexJoin 12.50 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a) - ├─IndexReader(Build) 10.00 root index:IndexRangeScan - │ └─IndexRangeScan 10.00 cop[tikv] table:s, index:idx(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:t1 range: decided by [test.t.a], keep order:false, stats:pseudo + └─StreamAgg(Probe) 10000.00 root funcs:count(1)->Column#16 + └─IndexJoin 125000.00 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a) + ├─IndexReader(Build) 100000.00 root index:IndexRangeScan + │ └─IndexRangeScan 100000.00 cop[tikv] table:s, index:idx(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo + └─TableReader(Probe) 100000.00 root data:TableRangeScan + └─TableRangeScan 100000.00 cop[tikv] table:t1 range: decided by [test.t.a], keep order:false, stats:pseudo explain format = 'brief' select t.c in (select count(*) from t s use index(idx), t t1 where s.b = t.a and s.c = t1.a) from t; id estRows task access object operator info Projection 10000.00 root Column#17 └─Apply 10000.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#16) ├─TableReader(Build) 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo - └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#16 - └─IndexJoin 12.49 root inner join, inner:TableReader, outer key:test.t.c, inner key:test.t.a, equal cond:eq(test.t.c, test.t.a) - ├─IndexLookUp(Build) 9.99 root - │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:s, index:idx(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo - │ └─Selection(Probe) 9.99 cop[tikv] not(isnull(test.t.c)) - │ └─TableRowIDScan 10.00 cop[tikv] table:s keep order:false, stats:pseudo - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:t1 range: decided by [test.t.c], keep order:false, stats:pseudo + └─StreamAgg(Probe) 10000.00 root funcs:count(1)->Column#16 + └─IndexJoin 124875.00 root inner join, inner:TableReader, outer key:test.t.c, inner key:test.t.a, equal cond:eq(test.t.c, test.t.a) + ├─IndexLookUp(Build) 99900.00 root + │ ├─IndexRangeScan(Build) 100000.00 cop[tikv] table:s, index:idx(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo + │ └─Selection(Probe) 99900.00 cop[tikv] not(isnull(test.t.c)) + │ └─TableRowIDScan 100000.00 cop[tikv] table:s keep order:false, stats:pseudo + └─TableReader(Probe) 99900.00 root data:TableRangeScan + └─TableRangeScan 99900.00 cop[tikv] table:t1 range: decided by [test.t.c], keep order:false, stats:pseudo insert into t values(1, 1, 1), (2, 2 ,2), (3, 3, 3), (4, 3, 4),(5,3,5); analyze table t; explain format = 'brief' select t.c in (select count(*) from t s, t t1 where s.b = t.a and s.b = 3 and s.a = t1.a) from t; @@ -364,42 +365,42 @@ Projection 5.00 root Column#17 └─Apply 5.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#16) ├─TableReader(Build) 5.00 root data:TableFullScan │ └─TableFullScan 5.00 cop[tikv] table:t keep order:false - └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#16 - └─MergeJoin 2.40 root inner join, left key:test.t.a, right key:test.t.a - ├─TableReader(Build) 4.00 root data:Selection - │ └─Selection 4.00 cop[tikv] eq(3, test.t.a) - │ └─TableFullScan 5.00 cop[tikv] table:t1 keep order:true - └─IndexReader(Probe) 2.40 root index:Selection - └─Selection 2.40 cop[tikv] eq(3, test.t.a) - └─IndexRangeScan 3.00 cop[tikv] table:s, index:idx(b) range:[3,3], keep order:true + └─StreamAgg(Probe) 5.00 root funcs:count(1)->Column#16 + └─MergeJoin 12.00 root inner join, left key:test.t.a, right key:test.t.a + ├─TableReader(Build) 20.00 root data:Selection + │ └─Selection 20.00 cop[tikv] eq(3, test.t.a) + │ └─TableFullScan 25.00 cop[tikv] table:t1 keep order:true + └─IndexReader(Probe) 12.00 root index:Selection + └─Selection 12.00 cop[tikv] eq(3, test.t.a) + └─IndexRangeScan 15.00 cop[tikv] table:s, index:idx(b) range:[3,3], keep order:true explain format = 'brief' select t.c in (select count(*) from t s left join t t1 on s.a = t1.a where 3 = t.a and s.b = 3) from t; id estRows task access object operator info Projection 5.00 root Column#17 └─Apply 5.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#16) ├─TableReader(Build) 5.00 root data:TableFullScan │ └─TableFullScan 5.00 cop[tikv] table:t keep order:false - └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#16 - └─MergeJoin 2.40 root left outer join, left key:test.t.a, right key:test.t.a - ├─TableReader(Build) 4.00 root data:Selection - │ └─Selection 4.00 cop[tikv] eq(3, test.t.a) - │ └─TableFullScan 5.00 cop[tikv] table:t1 keep order:true - └─IndexReader(Probe) 2.40 root index:Selection - └─Selection 2.40 cop[tikv] eq(3, test.t.a) - └─IndexRangeScan 3.00 cop[tikv] table:s, index:idx(b) range:[3,3], keep order:true + └─StreamAgg(Probe) 5.00 root funcs:count(1)->Column#16 + └─MergeJoin 12.00 root left outer join, left key:test.t.a, right key:test.t.a + ├─TableReader(Build) 20.00 root data:Selection + │ └─Selection 20.00 cop[tikv] eq(3, test.t.a) + │ └─TableFullScan 25.00 cop[tikv] table:t1 keep order:true + └─IndexReader(Probe) 12.00 root index:Selection + └─Selection 12.00 cop[tikv] eq(3, test.t.a) + └─IndexRangeScan 15.00 cop[tikv] table:s, index:idx(b) range:[3,3], keep order:true explain format = 'brief' select t.c in (select count(*) from t s right join t t1 on s.a = t1.a where 3 = t.a and t1.b = 3) from t; id estRows task access object operator info Projection 5.00 root Column#17 └─Apply 5.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#16) ├─TableReader(Build) 5.00 root data:TableFullScan │ └─TableFullScan 5.00 cop[tikv] table:t keep order:false - └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#16 - └─MergeJoin 2.40 root right outer join, left key:test.t.a, right key:test.t.a - ├─TableReader(Build) 4.00 root data:Selection - │ └─Selection 4.00 cop[tikv] eq(3, test.t.a) - │ └─TableFullScan 5.00 cop[tikv] table:s keep order:true - └─IndexReader(Probe) 2.40 root index:Selection - └─Selection 2.40 cop[tikv] eq(3, test.t.a) - └─IndexRangeScan 3.00 cop[tikv] table:t1, index:idx(b) range:[3,3], keep order:true + └─StreamAgg(Probe) 5.00 root funcs:count(1)->Column#16 + └─MergeJoin 12.00 root right outer join, left key:test.t.a, right key:test.t.a + ├─TableReader(Build) 20.00 root data:Selection + │ └─Selection 20.00 cop[tikv] eq(3, test.t.a) + │ └─TableFullScan 25.00 cop[tikv] table:s keep order:true + └─IndexReader(Probe) 12.00 root index:Selection + └─Selection 12.00 cop[tikv] eq(3, test.t.a) + └─IndexRangeScan 15.00 cop[tikv] table:t1, index:idx(b) range:[3,3], keep order:true drop table if exists t; create table t(a int unsigned not null); explain format = 'brief' select t.a = '123455' from t; @@ -525,8 +526,8 @@ StreamAgg 1.00 root funcs:count(1)->Column#22 │ └─TableReader 0.01 root data:Selection │ └─Selection 0.01 cop[tikv] eq(test.test01.period, 1), ge(test.test01.stat_date, 20191202), gt(cast(test.test01.registration_num, bigint(20) BINARY), 0), le(test.test01.stat_date, 20191202) │ └─TableFullScan 10000.00 cop[tikv] table:test01 keep order:false, stats:pseudo - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:b range: decided by [Column#16], keep order:false, stats:pseudo + └─TableReader(Probe) 2.00 root data:TableRangeScan + └─TableRangeScan 2.00 cop[tikv] table:b range: decided by [Column#16], keep order:false, stats:pseudo drop table if exists t; create table t(a int, nb int not null, nc int not null); explain format = 'brief' select ifnull(a, 0) from t; @@ -601,16 +602,16 @@ Projection 10000.00 root Column#22 └─Apply 10000.00 root left outer semi join, equal:[eq(test.t.nc, Column#21)] ├─TableReader(Build) 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo - └─HashAgg(Probe) 1.00 root funcs:count(Column#23)->Column#21 - └─HashJoin 9.99 root inner join, equal:[eq(test.t.a, test.t.a)] - ├─HashAgg(Build) 7.99 root group by:test.t.a, funcs:count(Column#24)->Column#23, funcs:firstrow(test.t.a)->test.t.a - │ └─TableReader 7.99 root data:HashAgg - │ └─HashAgg 7.99 cop[tikv] group by:test.t.a, funcs:count(1)->Column#24 - │ └─Selection 9.99 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) - │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─TableReader(Probe) 9.99 root data:Selection - └─Selection 9.99 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) - └─TableFullScan 10000.00 cop[tikv] table:s keep order:false, stats:pseudo + └─HashAgg(Probe) 10000.00 root funcs:count(Column#23)->Column#21 + └─HashJoin 99900.00 root inner join, equal:[eq(test.t.a, test.t.a)] + ├─HashAgg(Build) 79920.00 root group by:test.t.a, funcs:count(Column#24)->Column#23, funcs:firstrow(test.t.a)->test.t.a + │ └─TableReader 79920.00 root data:HashAgg + │ └─HashAgg 79920.00 cop[tikv] group by:test.t.a, funcs:count(1)->Column#24 + │ └─Selection 99900.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) + │ └─TableFullScan 100000000.00 cop[tikv] table:t1 keep order:false, stats:pseudo + └─TableReader(Probe) 99900.00 root data:Selection + └─Selection 99900.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) + └─TableFullScan 100000000.00 cop[tikv] table:s keep order:false, stats:pseudo explain format = 'brief' select * from t ta left outer join t tb on ta.nb = tb.nb and ta.a > 1 where ifnull(tb.a, 1) or tb.a is null; id estRows task access object operator info Selection 10000.00 root or(ifnull(test.t.a, 1), isnull(test.t.a)) @@ -635,16 +636,16 @@ Projection 10000.00 root Column#22 ├─Projection(Build) 10000.00 root test.t.a, ifnull(test.t.a, 1)->Column#23 │ └─TableReader 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo - └─HashAgg(Probe) 1.00 root funcs:count(Column#25)->Column#21 - └─HashJoin 9.99 root inner join, equal:[eq(test.t.a, test.t.a)] - ├─HashAgg(Build) 7.99 root group by:test.t.a, funcs:count(Column#26)->Column#25, funcs:firstrow(test.t.a)->test.t.a - │ └─TableReader 7.99 root data:HashAgg - │ └─HashAgg 7.99 cop[tikv] group by:test.t.a, funcs:count(1)->Column#26 - │ └─Selection 9.99 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) - │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─TableReader(Probe) 9.99 root data:Selection - └─Selection 9.99 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) - └─TableFullScan 10000.00 cop[tikv] table:s keep order:false, stats:pseudo + └─HashAgg(Probe) 10000.00 root funcs:count(Column#25)->Column#21 + └─HashJoin 99900.00 root inner join, equal:[eq(test.t.a, test.t.a)] + ├─HashAgg(Build) 79920.00 root group by:test.t.a, funcs:count(Column#26)->Column#25, funcs:firstrow(test.t.a)->test.t.a + │ └─TableReader 79920.00 root data:HashAgg + │ └─HashAgg 79920.00 cop[tikv] group by:test.t.a, funcs:count(1)->Column#26 + │ └─Selection 99900.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) + │ └─TableFullScan 100000000.00 cop[tikv] table:t1 keep order:false, stats:pseudo + └─TableReader(Probe) 99900.00 root data:Selection + └─Selection 99900.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a)) + └─TableFullScan 100000000.00 cop[tikv] table:s keep order:false, stats:pseudo drop table if exists t; create table t(a int); explain format = 'brief' select * from t where _tidb_rowid = 0; diff --git a/cmd/explaintest/r/explain_easy_stats.result b/cmd/explaintest/r/explain_easy_stats.result index c385377d512ff..d4bf4c9026156 100644 --- a/cmd/explaintest/r/explain_easy_stats.result +++ b/cmd/explaintest/r/explain_easy_stats.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2, t3; create table t1 (c1 int primary key, c2 int, c3 int, index c2 (c2)); @@ -107,11 +108,11 @@ Projection 1999.00 root eq(test.t1.c2, test.t2.c2)->Column#11 └─Apply 1999.00 root CARTESIAN left outer join ├─TableReader(Build) 1999.00 root data:TableFullScan │ └─TableFullScan 1999.00 cop[tikv] table:t1 keep order:false - └─TopN(Probe) 1.00 root test.t2.c1, offset:0, count:1 - └─IndexLookUp 1.00 root - ├─TopN(Build) 1.00 cop[tikv] test.t2.c1, offset:0, count:1 - │ └─IndexRangeScan 2.48 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:false - └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false + └─TopN(Probe) 1999.00 root test.t2.c1, offset:0, count:1 + └─IndexLookUp 1999.00 root + ├─TopN(Build) 1999.00 cop[tikv] test.t2.c1, offset:0, count:1 + │ └─IndexRangeScan 4960.02 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:false + └─TableRowIDScan(Probe) 1999.00 cop[tikv] table:t2 keep order:false explain format = 'brief' select * from t1 order by c1 desc limit 1; id estRows task access object operator info Limit 1.00 root offset:0, count:1 diff --git a/cmd/explaintest/r/explain_foreign_key.result b/cmd/explaintest/r/explain_foreign_key.result new file mode 100644 index 0000000000000..2e92440278a49 --- /dev/null +++ b/cmd/explaintest/r/explain_foreign_key.result @@ -0,0 +1,167 @@ +set @@foreign_key_checks=1; +use test; +drop table if exists t1,t2; +create table t1 (id int key); +create table t2 (id int key, foreign key fk(id) references t1(id) ON UPDATE CASCADE ON DELETE CASCADE); +create table t3 (id int, unique index idx(id)); +create table t4 (id int, index idx_id(id),foreign key fk(id) references t3(id)); +create table t5 (id int key, id2 int, id3 int, unique index idx2(id2), index idx3(id3)); +create table t6 (id int, id2 int, id3 int, index idx_id(id), index idx_id2(id2), foreign key fk_1 (id) references t5(id) ON UPDATE CASCADE ON DELETE CASCADE, foreign key fk_2 (id2) references t5(id2) ON UPDATE CASCADE, foreign key fk_3 (id3) references t5(id3) ON DELETE CASCADE); +explain format = 'brief' insert into t2 values (1); +id estRows task access object operator info +Insert N/A root N/A +└─Foreign_Key_Check 0.00 root table:t1 foreign_key:fk, check_exist +explain format = 'brief' update t2 set id=id+1 where id = 1; +id estRows task access object operator info +Update N/A root N/A +├─Point_Get 1.00 root table:t2 handle:1, lock +└─Foreign_Key_Check 0.00 root table:t1 foreign_key:fk, check_exist +explain format = 'brief' delete from t1 where id > 1; +id estRows task access object operator info +Delete N/A root N/A +├─SelectLock 3333.33 root for update 0 +│ └─TableReader 3333.33 root data:TableRangeScan +│ └─TableRangeScan 3333.33 cop[tikv] table:t1 range:(1,+inf], keep order:false, stats:pseudo +└─Foreign_Key_Cascade 0.00 root table:t2 foreign_key:fk, on_delete:CASCADE +explain format = 'brief' update t1 set id=id+1 where id = 1; +id estRows task access object operator info +Update N/A root N/A +├─Point_Get 1.00 root table:t1 handle:1, lock +└─Foreign_Key_Cascade 0.00 root table:t2 foreign_key:fk, on_update:CASCADE +explain format = 'brief' insert into t1 values (1); +id estRows task access object operator info +Insert N/A root N/A +explain format = 'brief' insert into t1 values (1) on duplicate key update id = 100; +id estRows task access object operator info +Insert N/A root N/A +└─Foreign_Key_Cascade 0.00 root table:t2 foreign_key:fk, on_update:CASCADE +explain format = 'brief' insert into t4 values (1); +id estRows task access object operator info +Insert N/A root N/A +└─Foreign_Key_Check 0.00 root table:t3, index:idx foreign_key:fk, check_exist +explain format = 'brief' update t4 set id=id+1 where id = 1; +id estRows task access object operator info +Update N/A root N/A +├─SelectLock 10.00 root for update 0 +│ └─IndexReader 10.00 root index:IndexRangeScan +│ └─IndexRangeScan 10.00 cop[tikv] table:t4, index:idx_id(id) range:[1,1], keep order:false, stats:pseudo +└─Foreign_Key_Check 0.00 root table:t3, index:idx foreign_key:fk, check_exist +explain format = 'brief' delete from t3 where id > 1; +id estRows task access object operator info +Delete N/A root N/A +├─SelectLock 3333.33 root for update 0 +│ └─IndexReader 3333.33 root index:IndexRangeScan +│ └─IndexRangeScan 3333.33 cop[tikv] table:t3, index:idx(id) range:(1,+inf], keep order:false, stats:pseudo +└─Foreign_Key_Check 0.00 root table:t4, index:idx_id foreign_key:fk, check_not_exist +explain format = 'brief' update t3 set id=id+1 where id = 1; +id estRows task access object operator info +Update N/A root N/A +├─Point_Get 1.00 root table:t3, index:idx(id) lock +└─Foreign_Key_Check 0.00 root table:t4, index:idx_id foreign_key:fk, check_not_exist +explain format = 'brief' insert into t3 values (1); +id estRows task access object operator info +Insert N/A root N/A +explain format = 'brief' insert into t3 values (1) on duplicate key update id = 100; +id estRows task access object operator info +Insert N/A root N/A +└─Foreign_Key_Check 0.00 root table:t4, index:idx_id foreign_key:fk, check_not_exist +explain format = 'brief' insert into t6 values (1,1,1); +id estRows task access object operator info +Insert N/A root N/A +├─Foreign_Key_Check 0.00 root table:t5 foreign_key:fk_1, check_exist +├─Foreign_Key_Check 0.00 root table:t5, index:idx2 foreign_key:fk_2, check_exist +└─Foreign_Key_Check 0.00 root table:t5, index:idx3 foreign_key:fk_3, check_exist +explain format = 'brief' update t6 set id=id+1, id3=id2+1 where id = 1; +id estRows task access object operator info +Update N/A root N/A +├─SelectLock 10.00 root for update 0 +│ └─IndexLookUp 10.00 root +│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t6, index:idx_id(id) range:[1,1], keep order:false, stats:pseudo +│ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t6 keep order:false, stats:pseudo +├─Foreign_Key_Check 0.00 root table:t5 foreign_key:fk_1, check_exist +└─Foreign_Key_Check 0.00 root table:t5, index:idx3 foreign_key:fk_3, check_exist +explain format = 'brief' delete from t5 where id > 1; +id estRows task access object operator info +Delete N/A root N/A +├─SelectLock 3333.33 root for update 0 +│ └─TableReader 3333.33 root data:TableRangeScan +│ └─TableRangeScan 3333.33 cop[tikv] table:t5 range:(1,+inf], keep order:false, stats:pseudo +├─Foreign_Key_Check 0.00 root table:t6, index:idx_id2 foreign_key:fk_2, check_not_exist +├─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id foreign_key:fk_1, on_delete:CASCADE +└─Foreign_Key_Cascade 0.00 root table:t6, index:fk_3 foreign_key:fk_3, on_delete:CASCADE +explain format = 'brief' update t5 set id=id+1, id2=id2+1 where id = 1; +id estRows task access object operator info +Update N/A root N/A +├─Point_Get 1.00 root table:t5 handle:1, lock +├─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id foreign_key:fk_1, on_update:CASCADE +└─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id2 foreign_key:fk_2, on_update:CASCADE +explain format = 'brief' update t5 set id=id+1, id2=id2+1, id3=id3+1 where id = 1; +id estRows task access object operator info +Update N/A root N/A +├─Point_Get 1.00 root table:t5 handle:1, lock +├─Foreign_Key_Check 0.00 root table:t6, index:fk_3 foreign_key:fk_3, check_not_exist +├─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id foreign_key:fk_1, on_update:CASCADE +└─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id2 foreign_key:fk_2, on_update:CASCADE +explain format = 'brief' insert into t5 values (1,1,1); +id estRows task access object operator info +Insert N/A root N/A +explain format = 'brief' insert into t5 values (1,1,1) on duplicate key update id = 100, id3=100; +id estRows task access object operator info +Insert N/A root N/A +├─Foreign_Key_Check 0.00 root table:t6, index:fk_3 foreign_key:fk_3, check_not_exist +└─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id foreign_key:fk_1, on_update:CASCADE +explain format = 'brief' insert into t5 values (1,1,1) on duplicate key update id = 100, id2=100, id3=100; +id estRows task access object operator info +Insert N/A root N/A +├─Foreign_Key_Check 0.00 root table:t6, index:fk_3 foreign_key:fk_3, check_not_exist +├─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id foreign_key:fk_1, on_update:CASCADE +└─Foreign_Key_Cascade 0.00 root table:t6, index:idx_id2 foreign_key:fk_2, on_update:CASCADE +drop table if exists t1,t2,t3,t4,t5,t6; +drop table if exists t_1,t_2,t_3,t_4; +create table t_1 (id int key); +create table t_2 (id int key); +create table t_3 (id int key, id2 int, foreign key fk_1(id) references t_1(id), foreign key fk_2(id2) references t_1(id), foreign key fk_3(id) references t_2(id) ON UPDATE CASCADE ON DELETE CASCADE); +create table t_4 (id int key, id2 int, foreign key fk_1(id) references t_2(id), foreign key fk_2(id2) references t_1(id), foreign key fk_3(id) references t_1(id) ON UPDATE CASCADE ON DELETE CASCADE); +explain format = 'brief' update t_1,t_2 set t_1.id=2,t_2.id=2 where t_1.id=t_2.id and t_1.id=1; +id estRows task access object operator info +Update N/A root N/A +├─HashJoin 1.00 root CARTESIAN inner join +│ ├─Point_Get(Build) 1.00 root table:t_2 handle:1 +│ └─Point_Get(Probe) 1.00 root table:t_1 handle:1 +├─Foreign_Key_Check 0.00 root table:t_3 foreign_key:fk_1, check_not_exist +├─Foreign_Key_Check 0.00 root table:t_3, index:fk_2 foreign_key:fk_2, check_not_exist +├─Foreign_Key_Check 0.00 root table:t_4, index:fk_2 foreign_key:fk_2, check_not_exist +├─Foreign_Key_Check 0.00 root table:t_4 foreign_key:fk_1, check_not_exist +├─Foreign_Key_Cascade 0.00 root table:t_4 foreign_key:fk_3, on_update:CASCADE +└─Foreign_Key_Cascade 0.00 root table:t_3 foreign_key:fk_3, on_update:CASCADE +explain format = 'brief' delete t_1,t_2 from t_1 join t_2 where t_1.id=t_2.id and t_1.id > 0; +id estRows task access object operator info +Delete N/A root N/A +├─MergeJoin 4166.67 root inner join, left key:test.t_1.id, right key:test.t_2.id +│ ├─TableReader(Build) 3333.33 root data:TableRangeScan +│ │ └─TableRangeScan 3333.33 cop[tikv] table:t_2 range:(0,+inf], keep order:true, stats:pseudo +│ └─TableReader(Probe) 3333.33 root data:TableRangeScan +│ └─TableRangeScan 3333.33 cop[tikv] table:t_1 range:(0,+inf], keep order:true, stats:pseudo +├─Foreign_Key_Check 0.00 root table:t_3 foreign_key:fk_1, check_not_exist +├─Foreign_Key_Check 0.00 root table:t_3, index:fk_2 foreign_key:fk_2, check_not_exist +├─Foreign_Key_Check 0.00 root table:t_4, index:fk_2 foreign_key:fk_2, check_not_exist +├─Foreign_Key_Check 0.00 root table:t_4 foreign_key:fk_1, check_not_exist +├─Foreign_Key_Cascade 0.00 root table:t_4 foreign_key:fk_3, on_delete:CASCADE +└─Foreign_Key_Cascade 0.00 root table:t_3 foreign_key:fk_3, on_delete:CASCADE +set @@foreign_key_checks=0; +explain format = 'brief' update t_1,t_2 set t_1.id=2,t_2.id=2 where t_1.id=t_2.id and t_1.id=1; +id estRows task access object operator info +Update N/A root N/A +└─HashJoin 1.00 root CARTESIAN inner join + ├─Point_Get(Build) 1.00 root table:t_2 handle:1 + └─Point_Get(Probe) 1.00 root table:t_1 handle:1 +explain format = 'brief' delete t_1,t_2 from t_1 join t_2 where t_1.id=t_2.id and t_1.id > 0; +id estRows task access object operator info +Delete N/A root N/A +└─MergeJoin 4166.67 root inner join, left key:test.t_1.id, right key:test.t_2.id + ├─TableReader(Build) 3333.33 root data:TableRangeScan + │ └─TableRangeScan 3333.33 cop[tikv] table:t_2 range:(0,+inf], keep order:true, stats:pseudo + └─TableReader(Probe) 3333.33 root data:TableRangeScan + └─TableRangeScan 3333.33 cop[tikv] table:t_1 range:(0,+inf], keep order:true, stats:pseudo +drop table if exists t_1,t_2,t_3,t_4; +set @@foreign_key_checks=0; diff --git a/cmd/explaintest/r/explain_generate_column_substitute.result b/cmd/explaintest/r/explain_generate_column_substitute.result index 83422a318e619..9afb09538c3b5 100644 --- a/cmd/explaintest/r/explain_generate_column_substitute.result +++ b/cmd/explaintest/r/explain_generate_column_substitute.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set names utf8mb4; use test; drop table if exists t; diff --git a/cmd/explaintest/r/explain_indexmerge.result b/cmd/explaintest/r/explain_indexmerge.result index 40e0cb4a1159d..46ba855e6c2a8 100644 --- a/cmd/explaintest/r/explain_indexmerge.result +++ b/cmd/explaintest/r/explain_indexmerge.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; create table t (a int primary key, b int, c int, d int, e int, f int); create index tb on t (b); @@ -6,33 +7,33 @@ create index td on t (d); load stats 's/explain_indexmerge_stats_t.json'; explain format = 'brief' select * from t where a < 50 or b < 50; id estRows task access object operator info -IndexMerge 98.00 root +IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where (a < 50 or b < 50) and f > 100; id estRows task access object operator info -IndexMerge 98.00 root +IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─Selection(Probe) 98.00 cop[tikv] gt(test.t.f, 100) └─TableRowIDScan 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where b < 50 or c < 50; id estRows task access object operator info -IndexMerge 98.00 root +IndexMerge 98.00 root type: union ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tc(c) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false set session tidb_enable_index_merge = on; explain format = 'brief' select * from t where a < 50 or b < 50; id estRows task access object operator info -IndexMerge 98.00 root +IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where (a < 50 or b < 50) and f > 100; id estRows task access object operator info -IndexMerge 98.00 root +IndexMerge 98.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false └─Selection(Probe) 98.00 cop[tikv] gt(test.t.f, 100) @@ -44,7 +45,7 @@ TableReader 4999999.00 root data:Selection └─TableFullScan 5000000.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where b < 50 or c < 50; id estRows task access object operator info -IndexMerge 98.00 root +IndexMerge 98.00 root type: union ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tc(c) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false @@ -55,14 +56,14 @@ TableReader 4999999.00 root data:Selection └─TableFullScan 5000000.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where a < 50 or b < 50 or c < 50; id estRows task access object operator info -IndexMerge 147.00 root +IndexMerge 147.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tc(c) range:[-inf,50), keep order:false └─TableRowIDScan(Probe) 147.00 cop[tikv] table:t keep order:false explain format = 'brief' select * from t where (b < 10000 or c < 10000) and (a < 10 or d < 10) and f < 10; id estRows task access object operator info -IndexMerge 0.00 root +IndexMerge 0.00 root type: union ├─TableRangeScan(Build) 9.00 cop[tikv] table:t range:[-inf,10), keep order:false ├─IndexRangeScan(Build) 9.00 cop[tikv] table:t, index:td(d) range:[-inf,10), keep order:false └─Selection(Probe) 0.00 cop[tikv] lt(test.t.f, 10), or(lt(test.t.b, 10000), lt(test.t.c, 10000)) @@ -103,20 +104,20 @@ label = "cop" set session tidb_enable_index_merge = off; explain format = 'brief' select /*+ use_index_merge(t, primary, tb, tc) */ * from t where a <= 500000 or b <= 1000000 or c <= 3000000; id estRows task access object operator info -IndexMerge 3560000.00 root +IndexMerge 3560000.00 root type: union ├─TableRangeScan(Build) 500000.00 cop[tikv] table:t range:[-inf,500000], keep order:false ├─IndexRangeScan(Build) 1000000.00 cop[tikv] table:t, index:tb(b) range:[-inf,1000000], keep order:false ├─IndexRangeScan(Build) 3000000.00 cop[tikv] table:t, index:tc(c) range:[-inf,3000000], keep order:false └─TableRowIDScan(Probe) 3560000.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ use_index_merge(t, tb, tc) */ * from t where b < 50 or c < 5000000; id estRows task access object operator info -IndexMerge 4999999.00 root +IndexMerge 4999999.00 root type: union ├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 4999999.00 cop[tikv] table:t, index:tc(c) range:[-inf,5000000), keep order:false └─TableRowIDScan(Probe) 4999999.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ use_index_merge(t, tb, tc) */ * from t where (b < 10000 or c < 10000) and (a < 10 or d < 10) and f < 10; id estRows task access object operator info -IndexMerge 0.00 root +IndexMerge 0.00 root type: union ├─IndexRangeScan(Build) 9999.00 cop[tikv] table:t, index:tb(b) range:[-inf,10000), keep order:false ├─IndexRangeScan(Build) 9999.00 cop[tikv] table:t, index:tc(c) range:[-inf,10000), keep order:false └─Selection(Probe) 0.00 cop[tikv] lt(test.t.f, 10), or(lt(test.t.a, 10), lt(test.t.d, 10)) @@ -133,7 +134,7 @@ TableReader 4999999.00 root data:Selection └─TableFullScan 5000000.00 cop[tikv] table:t keep order:false explain format = 'brief' select /*+ use_index_merge(t, primary, tb) */ * from t where a < 50 or b < 5000000; id estRows task access object operator info -IndexMerge 4999999.00 root +IndexMerge 4999999.00 root type: union ├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false ├─IndexRangeScan(Build) 4999999.00 cop[tikv] table:t, index:tb(b) range:[-inf,5000000), keep order:false └─TableRowIDScan(Probe) 4999999.00 cop[tikv] table:t keep order:false @@ -150,7 +151,7 @@ KEY `aid_c2` (`aid`,`c2`) ); desc select /*+ USE_INDEX_MERGE(t, aid_c1, aid_c2) */ * from t where (aid = 1 and c1='aaa') or (aid = 2 and c2='bbb'); id estRows task access object operator info -IndexMerge_8 8.08 root +IndexMerge_8 8.08 root type: union ├─IndexRangeScan_5(Build) 0.10 cop[tikv] table:t, index:aid_c1(aid, c1) range:[1 "aaa",1 "aaa"], keep order:false, stats:pseudo ├─IndexRangeScan_6(Build) 0.10 cop[tikv] table:t, index:aid_c2(aid, c2) range:[2 "bbb",2 "bbb"], keep order:false, stats:pseudo └─TableRowIDScan_7(Probe) 8.08 cop[tikv] table:t keep order:false, stats:pseudo diff --git a/cmd/explaintest/r/explain_join_stats.result b/cmd/explaintest/r/explain_join_stats.result index 15e68179c5085..e92f633b37f7f 100644 --- a/cmd/explaintest/r/explain_join_stats.result +++ b/cmd/explaintest/r/explain_join_stats.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists e, lo; create table e(a int, b int, key idx_a(a), key idx_b(b)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; @@ -20,8 +21,8 @@ StreamAgg 1.00 root funcs:count(1)->Column#5 └─IndexJoin 19977.00 root inner join, inner:IndexLookUp, outer key:test.lo.a, inner key:test.e.a, equal cond:eq(test.lo.a, test.e.a) ├─TableReader(Build) 250.00 root data:TableFullScan │ └─TableFullScan 250.00 cop[tikv] table:lo keep order:false - └─IndexLookUp(Probe) 79.91 root - ├─Selection(Build) 4080.00 cop[tikv] not(isnull(test.e.a)) - │ └─IndexRangeScan 4080.00 cop[tikv] table:e, index:idx_a(a) range: decided by [eq(test.e.a, test.lo.a)], keep order:false - └─Selection(Probe) 79.91 cop[tikv] eq(test.e.b, 22336) - └─TableRowIDScan 4080.00 cop[tikv] table:e keep order:false + └─IndexLookUp(Probe) 19977.00 root + ├─Selection(Build) 1020000.00 cop[tikv] not(isnull(test.e.a)) + │ └─IndexRangeScan 1020000.00 cop[tikv] table:e, index:idx_a(a) range: decided by [eq(test.e.a, test.lo.a)], keep order:false + └─Selection(Probe) 19977.00 cop[tikv] eq(test.e.b, 22336) + └─TableRowIDScan 1020000.00 cop[tikv] table:e keep order:false diff --git a/cmd/explaintest/r/explain_shard_index.result b/cmd/explaintest/r/explain_shard_index.result index 79276d331286c..a81e8e32d496b 100644 --- a/cmd/explaintest/r/explain_shard_index.result +++ b/cmd/explaintest/r/explain_shard_index.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists test3, test5; create table test3(id int primary key clustered, a int, b int, unique key uk_expr((tidb_shard(a)),a)); diff --git a/cmd/explaintest/r/explain_stats.result b/cmd/explaintest/r/explain_stats.result index 34d7d2d719e7a..441150c11ffd0 100644 --- a/cmd/explaintest/r/explain_stats.result +++ b/cmd/explaintest/r/explain_stats.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; create table t (id int, c1 timestamp); load stats 's/explain_stats_t.json'; diff --git a/cmd/explaintest/r/explain_union_scan.result b/cmd/explaintest/r/explain_union_scan.result index 1ef48623efd4a..8ddc407829520 100644 --- a/cmd/explaintest/r/explain_union_scan.result +++ b/cmd/explaintest/r/explain_union_scan.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists city; CREATE TABLE `city` ( `id` varchar(70) NOT NULL, @@ -19,11 +20,11 @@ Limit 10.00 root offset:0, count:10 │ ├─UnionScan(Build) 10.00 root │ │ └─TableReader 10.00 root data:TableFullScan │ │ └─TableFullScan 10.00 cop[tikv] table:t2 keep order:false - │ └─UnionScan(Probe) 1.00 root gt(test.city.province_id, 1), lt(test.city.province_id, 100) - │ └─IndexLookUp 1.00 root - │ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, index:PRIMARY(id) range: decided by [eq(test.city.id, test.city.id)], keep order:false - │ └─Selection(Probe) 1.00 cop[tikv] gt(test.city.province_id, 1), lt(test.city.province_id, 100) - │ └─TableRowIDScan 1.00 cop[tikv] table:t1 keep order:false + │ └─UnionScan(Probe) 10.00 root gt(test.city.province_id, 1), lt(test.city.province_id, 100) + │ └─IndexLookUp 10.00 root + │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:PRIMARY(id) range: decided by [eq(test.city.id, test.city.id)], keep order:false + │ └─Selection(Probe) 10.00 cop[tikv] gt(test.city.province_id, 1), lt(test.city.province_id, 100) + │ └─TableRowIDScan 10.00 cop[tikv] table:t1 keep order:false └─UnionScan(Probe) 536284.00 root gt(test.city.province_id, 1), lt(test.city.province_id, 100), not(isnull(test.city.province_id)) └─TableReader 536284.00 root data:Selection └─Selection 536284.00 cop[tikv] gt(test.city.province_id, 1), lt(test.city.province_id, 100), not(isnull(test.city.province_id)) diff --git a/cmd/explaintest/r/generated_columns.result b/cmd/explaintest/r/generated_columns.result index 59311e829ad41..d0334b401415d 100644 --- a/cmd/explaintest/r/generated_columns.result +++ b/cmd/explaintest/r/generated_columns.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; DROP TABLE IF EXISTS person; CREATE TABLE person ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, diff --git a/cmd/explaintest/r/imdbload.result b/cmd/explaintest/r/imdbload.result index c3ee5badab7e6..066dc14b155ae 100644 --- a/cmd/explaintest/r/imdbload.result +++ b/cmd/explaintest/r/imdbload.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE DATABASE IF NOT EXISTS `imdbload`; USE `imdbload`; CREATE TABLE `kind_type` ( @@ -286,7 +287,7 @@ IndexLookUp_7 1005030.94 root └─TableRowIDScan_6(Probe) 1005030.94 cop[tikv] table:char_name keep order:false trace plan target = 'estimation' select * from char_name where ((imdb_index = 'I') and (surname_pcode < 'E436')) or ((imdb_index = 'L') and (surname_pcode < 'E436')); CE_trace -[{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'I'))","row_count":0},{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'L'))","row_count":0},{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index = 'I') and (surname_pcode < 'E436')) or ((imdb_index = 'L') and (surname_pcode < 'E436'))","row_count":0},{"table_name":"char_name","type":"Index Stats-Range","expr":"((surname_pcode < 'E436'))","row_count":1005030},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`or`(`and`(`eq`(imdbload.char_name.imdb_index, 'I'), `lt`(imdbload.char_name.surname_pcode, 'E436')), `and`(`eq`(imdbload.char_name.imdb_index, 'L'), `lt`(imdbload.char_name.surname_pcode, 'E436')))","row_count":804024}] +[{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'I'))","row_count":0},{"table_name":"char_name","type":"Column Stats-Point","expr":"((imdb_index = 'L'))","row_count":0},{"table_name":"char_name","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":4314864},{"table_name":"char_name","type":"Column Stats-Range","expr":"((surname_pcode < 'E436'))","row_count":1005030},{"table_name":"char_name","type":"Index Stats-Range","expr":"((imdb_index = 'I') and (surname_pcode < 'E436')) or ((imdb_index = 'L') and (surname_pcode < 'E436'))","row_count":0},{"table_name":"char_name","type":"Index Stats-Range","expr":"((surname_pcode < 'E436'))","row_count":1005030},{"table_name":"char_name","type":"Table Stats-Expression-CNF","expr":"`or`(`and`(`eq`(imdbload.char_name.imdb_index, 'I'), `lt`(imdbload.char_name.surname_pcode, 'E436')), `and`(`eq`(imdbload.char_name.imdb_index, 'L'), `lt`(imdbload.char_name.surname_pcode, 'E436')))","row_count":804024}] explain select * from char_name where ((imdb_index = 'V') and (surname_pcode < 'L3416')); id estRows task access object operator info @@ -356,7 +357,7 @@ IndexLookUp_11 901.00 root └─TableRowIDScan_9 901.00 cop[tikv] table:keyword keep order:false trace plan target = 'estimation' select * from keyword where ((phonetic_code = 'R1652') and (keyword > 'ecg-monitor' and keyword < 'killers')); CE_trace -[{"table_name":"keyword","type":"Column Stats-Point","expr":"((phonetic_code = 'R1652'))","row_count":23480},{"table_name":"keyword","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":236627},{"table_name":"keyword","type":"Column Stats-Range","expr":"((keyword > 'ecg-monitor' and keyword < 'killers'))","row_count":44075},{"table_name":"keyword","type":"Index Stats-Point","expr":"((phonetic_code = 'R1652'))","row_count":23480},{"table_name":"keyword","type":"Index Stats-Range","expr":"((keyword > 'ecg-monitor' and keyword < 'killers'))","row_count":44036},{"table_name":"keyword","type":"Index Stats-Range","expr":"((keyword >= 'ecg-m' and keyword <= 'kille'))","row_count":44036},{"table_name":"keyword","type":"Index Stats-Range","expr":"((phonetic_code = 'R1652') and (keyword > 'ecg-monitor' and keyword < 'killers'))","row_count":901},{"table_name":"keyword","type":"Table Stats-Expression-CNF","expr":"`and`(`eq`(imdbload.keyword.phonetic_code, 'R1652'), `and`(`gt`(imdbload.keyword.keyword, 'ecg-monitor'), `lt`(imdbload.keyword.keyword, 'killers')))","row_count":901}] +[{"table_name":"keyword","type":"Column Stats-Point","expr":"((phonetic_code = 'R1652'))","row_count":23480},{"table_name":"keyword","type":"Column Stats-Range","expr":"((id >= -9223372036854775808 and id <= 9223372036854775807))","row_count":236627},{"table_name":"keyword","type":"Column Stats-Range","expr":"((keyword > 'ecg-monitor' and keyword < 'killers'))","row_count":44075},{"table_name":"keyword","type":"Index Stats-Point","expr":"((phonetic_code = 'R1652'))","row_count":23480},{"table_name":"keyword","type":"Index Stats-Range","expr":"((keyword >= 'ecg-m' and keyword <= 'kille'))","row_count":44036},{"table_name":"keyword","type":"Index Stats-Range","expr":"((phonetic_code = 'R1652') and (keyword > 'ecg-monitor' and keyword < 'killers'))","row_count":901},{"table_name":"keyword","type":"Table Stats-Expression-CNF","expr":"`and`(`eq`(imdbload.keyword.phonetic_code, 'R1652'), `and`(`gt`(imdbload.keyword.keyword, 'ecg-monitor'), `lt`(imdbload.keyword.keyword, 'killers')))","row_count":901}] explain select * from cast_info where (nr_order is null) and (person_role_id = 2) and (note >= '(key set pa: Florida'); id estRows task access object operator info diff --git a/cmd/explaintest/r/index_join.result b/cmd/explaintest/r/index_join.result index 771c95ad5e8b1..413a726601f97 100644 --- a/cmd/explaintest/r/index_join.result +++ b/cmd/explaintest/r/index_join.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2; create table t1(a bigint, b bigint, index idx(a)); @@ -36,8 +37,8 @@ id estRows task access object operator info IndexJoin 8000.00 root semi join, inner:IndexReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a) ├─TableReader(Build) 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo -└─IndexReader(Probe) 1.25 root index:IndexRangeScan - └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo +└─IndexReader(Probe) 12500.00 root index:IndexRangeScan + └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo show warnings; Level Code Message set @@tidb_opt_insubq_to_join_and_agg=1; @@ -50,6 +51,6 @@ IndexJoin 10000.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inn ├─StreamAgg(Build) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a │ └─IndexReader 10000.00 root index:IndexFullScan │ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo -└─IndexLookUp(Probe) 1.25 root - ├─IndexRangeScan(Build) 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo - └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo +└─IndexLookUp(Probe) 10000.00 root + ├─IndexRangeScan(Build) 10000.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo + └─TableRowIDScan(Probe) 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo diff --git a/cmd/explaintest/r/index_merge.result b/cmd/explaintest/r/index_merge.result index 3f2f26fd99e07..6b44c6122987e 100644 --- a/cmd/explaintest/r/index_merge.result +++ b/cmd/explaintest/r/index_merge.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; ///// SUBQUERY drop table if exists t1; create table t1(c1 int, c2 int, c3 int, key(c1), key(c2)); @@ -14,7 +15,7 @@ Sort_8 4433.77 root test.t1.c1 └─HashJoin_12 5542.21 root CARTESIAN left outer semi join, other cond:eq(test.t1.c3, test.t1.c3) ├─TableReader_18(Build) 10000.00 root data:TableFullScan_17 │ └─TableFullScan_17 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─IndexMerge_16(Probe) 5542.21 root + └─IndexMerge_16(Probe) 5542.21 root type: union ├─IndexRangeScan_13(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_14(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_15(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -34,7 +35,7 @@ Sort_8 4433.77 root test.t1.c1 └─HashJoin_12 5542.21 root CARTESIAN anti left outer semi join, other cond:eq(test.t1.c3, test.t1.c3) ├─TableReader_18(Build) 10000.00 root data:TableFullScan_17 │ └─TableFullScan_17 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─IndexMerge_16(Probe) 5542.21 root + └─IndexMerge_16(Probe) 5542.21 root type: union ├─IndexRangeScan_13(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_14(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_15(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -49,7 +50,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = (select max(c3) from t1) order by 1; id estRows task access object operator info Sort_33 3325.55 root test.t1.c1 -└─IndexMerge_40 1843.09 root +└─IndexMerge_40 1843.09 root type: union ├─IndexRangeScan_36(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_37(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_39(Probe) 1843.09 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), eq(test.t1.c3, 5))) @@ -70,7 +71,7 @@ Sort_9 4433.77 root test.t1.c1 └─HashJoin_22 5542.21 root left outer semi join, equal:[eq(test.t1.c1, test.t2.c1)] ├─IndexReader_30(Build) 10000.00 root index:IndexFullScan_29 │ └─IndexFullScan_29 10000.00 cop[tikv] table:t2, index:c1(c1) keep order:false, stats:pseudo - └─IndexMerge_26(Probe) 5542.21 root + └─IndexMerge_26(Probe) 5542.21 root type: union ├─IndexRangeScan_23(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_24(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_25(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -90,7 +91,7 @@ Sort_9 4433.77 root test.t1.c1 └─HashJoin_22 5542.21 root anti left outer semi join, equal:[eq(test.t1.c1, test.t2.c1)] ├─IndexReader_30(Build) 10000.00 root index:IndexFullScan_29 │ └─IndexFullScan_29 10000.00 cop[tikv] table:t2, index:c1(c1) keep order:false, stats:pseudo - └─IndexMerge_26(Probe) 5542.21 root + └─IndexMerge_26(Probe) 5542.21 root type: union ├─IndexRangeScan_23(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_24(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_25(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -105,7 +106,7 @@ c1 c2 c3 explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 = (select count(1) from t2) order by 1; id estRows task access object operator info Sort_38 3325.55 root test.t1.c1 -└─IndexMerge_45 1843.09 root +└─IndexMerge_45 1843.09 root type: union ├─IndexRangeScan_41(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_42(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_44(Probe) 1843.09 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), eq(test.t1.c3, 5))) @@ -127,7 +128,7 @@ Sort_11 5098.44 root test.t1.c1 │ └─IndexReader_44 1.00 root index:StreamAgg_27 │ └─StreamAgg_27 1.00 cop[tikv] funcs:count(1)->Column#25 │ └─IndexFullScan_41 10000.00 cop[tikv] table:t2, index:c1(c1) keep order:false, stats:pseudo - └─IndexMerge_21(Probe) 2825.66 root + └─IndexMerge_21(Probe) 2825.66 root type: union ├─IndexRangeScan_17(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_18(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_20(Probe) 2825.66 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), if(isnull(test.t1.c3), NULL, 1))) @@ -149,7 +150,7 @@ Sort_11 5098.44 root test.t1.c1 │ └─IndexReader_44 1.00 root index:StreamAgg_27 │ └─StreamAgg_27 1.00 cop[tikv] funcs:count(1)->Column#25 │ └─IndexFullScan_41 10000.00 cop[tikv] table:t2, index:c1(c1) keep order:false, stats:pseudo - └─IndexMerge_21(Probe) 2825.66 root + └─IndexMerge_21(Probe) 2825.66 root type: union ├─IndexRangeScan_17(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_18(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_20(Probe) 2825.66 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), if(isnull(test.t1.c3), NULL, 1))) @@ -171,7 +172,7 @@ Sort_11 5542.21 root test.t1.c1 │ └─IndexReader_43 1.00 root index:StreamAgg_26 │ └─StreamAgg_26 1.00 cop[tikv] funcs:count(1)->Column#25 │ └─IndexFullScan_40 10000.00 cop[tikv] table:t2, index:c1(c1) keep order:false, stats:pseudo - └─IndexMerge_20(Probe) 5542.21 root + └─IndexMerge_20(Probe) 5542.21 root type: union ├─IndexRangeScan_17(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_18(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_19(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -193,7 +194,7 @@ Sort_39 5542.21 root test.t1.c1 │ └─IndexReader_71 1.00 root index:StreamAgg_54 │ └─StreamAgg_54 1.00 cop[tikv] funcs:count(1)->Column#38 │ └─IndexFullScan_68 10000.00 cop[tikv] table:t2, index:c1(c1) keep order:false, stats:pseudo - └─IndexMerge_48(Probe) 5542.21 root + └─IndexMerge_48(Probe) 5542.21 root type: union ├─IndexRangeScan_45(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_46(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_47(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -219,7 +220,7 @@ Sort_14 4433.77 root test.t1.c1 │ └─TableReader_51(Probe) 9990.00 root data:Selection_50 │ └─Selection_50 9990.00 cop[tikv] not(isnull(test.t2.c2)) │ └─TableFullScan_49 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo - └─IndexMerge_22(Probe) 5542.21 root + └─IndexMerge_22(Probe) 5542.21 root type: union ├─IndexRangeScan_19(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_20(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_21(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -238,7 +239,7 @@ explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and id estRows task access object operator info Sort_5 4060.74 root test.t1.c1 └─Selection_12 2250.55 root or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) - └─IndexMerge_11 5542.21 root + └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_10(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -253,7 +254,7 @@ explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and id estRows task access object operator info Sort_5 5098.44 root test.t1.c1 └─Selection_12 2825.66 root or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), eq(test.t1.c3, plus(test.t1.c1, test.t1.c2)))) - └─IndexMerge_11 5542.21 root + └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_10(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -268,7 +269,7 @@ explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and id estRows task access object operator info Sort_5 5098.44 root test.t1.c1 └─Selection_12 2825.66 root or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), istrue_with_null(cast(substring(cast(test.t1.c3, var_string(20)), test.t1.c2), double BINARY)))) - └─IndexMerge_11 5542.21 root + └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_10(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -283,7 +284,7 @@ explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and id estRows task access object operator info Sort_5 4800.37 root test.t1.c1 └─Selection_12 2660.47 root or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), test.t1.c3)) - └─IndexMerge_11 5542.21 root + └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_10(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -303,7 +304,7 @@ explain select * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root test.t1.c1 └─Selection_12 2250.55 root or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) - └─IndexMerge_11 5542.21 root + └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_10(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -337,7 +338,7 @@ insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5); explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root test.t1.c1 -└─IndexMerge_12 2250.55 root +└─IndexMerge_12 2250.55 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 2250.55 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) @@ -367,7 +368,7 @@ alter table t1 add index c1(c1); explain select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10 order by 1; id estRows task access object operator info Sort_5 4060.74 root test.t1.c1 -└─IndexMerge_12 2250.55 root +└─IndexMerge_12 2250.55 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 2250.55 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) @@ -390,7 +391,7 @@ Delete_11 N/A root N/A └─SelectLock_17 4056.68 root for update 0 └─HashJoin_33 4056.68 root inner join, equal:[eq(test.t1.c1, test.t1.c1)] ├─HashAgg_36(Build) 3245.34 root group by:test.t1.c1, funcs:firstrow(test.t1.c1)->test.t1.c1 - │ └─IndexMerge_41 2248.30 root + │ └─IndexMerge_41 2248.30 root type: union │ ├─IndexRangeScan_37(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo │ ├─IndexRangeScan_38(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo │ └─Selection_40(Probe) 2248.30 cop[tikv] not(isnull(test.t1.c1)), or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) @@ -408,7 +409,7 @@ Update_10 N/A root N/A └─SelectLock_14 4056.68 root for update 0 └─HashJoin_30 4056.68 root inner join, equal:[eq(test.t1.c1, test.t1.c1)] ├─HashAgg_33(Build) 3245.34 root group by:test.t1.c1, funcs:firstrow(test.t1.c1)->test.t1.c1 - │ └─IndexMerge_38 2248.30 root + │ └─IndexMerge_38 2248.30 root type: union │ ├─IndexRangeScan_34(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo │ ├─IndexRangeScan_35(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo │ └─Selection_37(Probe) 2248.30 cop[tikv] not(isnull(test.t1.c1)), or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) @@ -425,7 +426,7 @@ id estRows task access object operator info Sort_6 4060.74 root test.t1.c1 └─Projection_8 4060.74 root test.t1.c1, test.t1.c2, test.t1.c3 └─SelectLock_9 4060.74 root for update 0 - └─IndexMerge_14 2250.55 root + └─IndexMerge_14 2250.55 root type: union ├─IndexRangeScan_10(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_11(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_13(Probe) 2250.55 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) @@ -454,9 +455,9 @@ c1 c2 c3 ///// MEMORY Table explain select count(c1) from (select /*+ use_index_merge(t_alias), stream_agg() */ count(1) c1 from information_schema.statements_summary where sum_latency >= 0 or max_latency >= 0 order by 1) dt; id estRows task access object operator info -StreamAgg_10 1.00 root funcs:count(Column#93)->Column#94 -└─Sort_11 1.00 root Column#93 - └─StreamAgg_14 1.00 root funcs:count(1)->Column#93 +StreamAgg_10 1.00 root funcs:count(Column#96)->Column#97 +└─Sort_11 1.00 root Column#96 + └─StreamAgg_14 1.00 root funcs:count(1)->Column#96 └─MemTableScan_18 10000.00 root table:STATEMENTS_SUMMARY show warnings; Level Code Message @@ -470,7 +471,7 @@ insert into t1 values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5); explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10 order by 1 limit 1 offset 2; id estRows task access object operator info TopN_10 1.00 root test.t1.c1, offset:2, count:1 -└─IndexMerge_19 1841.86 root +└─IndexMerge_19 1841.86 root type: union ├─IndexRangeScan_15(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_16(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_18(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) @@ -484,7 +485,7 @@ id estRows task access object operator info Sort_6 1473.49 root Column#5 └─HashAgg_11 1473.49 root group by:Column#10, funcs:sum(Column#9)->Column#5 └─Projection_18 1841.86 root cast(test.t1.c1, decimal(10,0) BINARY)->Column#9, test.t1.c1 - └─IndexMerge_16 1841.86 root + └─IndexMerge_16 1841.86 root type: union ├─IndexRangeScan_12(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_13(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_15(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) @@ -506,16 +507,16 @@ Sort_12 1841.86 root test.t1.c1 └─Projection_14 1841.86 root test.t1.c1, test.t1.c2, test.t1.c3 └─Apply_16 1841.86 root inner join, equal:[eq(Column#10, Column#9)] ├─Projection_17(Build) 1841.86 root test.t1.c1, test.t1.c2, test.t1.c3, cast(test.t1.c1, decimal(10,0) BINARY)->Column#10 - │ └─IndexMerge_22 1841.86 root + │ └─IndexMerge_22 1841.86 root type: union │ ├─IndexRangeScan_18(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo │ ├─IndexRangeScan_19(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,-1), keep order:false, stats:pseudo │ └─Selection_21(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) │ └─TableRowIDScan_20 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo - └─MaxOneRow_23(Probe) 1.00 root - └─StreamAgg_35 2.00 root group by:test.t2.c1, funcs:avg(Column#17, Column#18)->Column#9 - └─IndexReader_36 2.00 root index:StreamAgg_27 - └─StreamAgg_27 2.00 cop[tikv] group by:test.t2.c1, funcs:count(test.t2.c1)->Column#17, funcs:sum(test.t2.c1)->Column#18 - └─IndexRangeScan_34 2.50 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:true, stats:pseudo + └─MaxOneRow_23(Probe) 1841.86 root + └─StreamAgg_35 3683.72 root group by:test.t2.c1, funcs:avg(Column#17, Column#18)->Column#9 + └─IndexReader_36 3683.72 root index:StreamAgg_27 + └─StreamAgg_27 3683.72 cop[tikv] group by:test.t2.c1, funcs:count(test.t2.c1)->Column#17, funcs:sum(test.t2.c1)->Column#18 + └─IndexRangeScan_34 4604.65 cop[tikv] table:t2, index:c1(c1) range: decided by [eq(test.t1.c1, test.t2.c1)], keep order:true, stats:pseudo select /*+ use_index_merge(t1) */ * from t1 where t1.c1 = (select avg(t2.c1) from t2 where t1.c1 = t2.c1 group by t2.c1) and (c1 < 10 or c2 < -1) and c3 < 10 order by 1; c1 c2 c3 1 1 1 @@ -529,19 +530,19 @@ Sort_16 1841.86 root test.t1.c1 └─Projection_18 1841.86 root test.t1.c1, test.t1.c2, test.t1.c3 └─Apply_20 1841.86 root inner join, equal:[eq(Column#11, Column#9)] ├─Projection_21(Build) 1841.86 root test.t1.c1, test.t1.c2, test.t1.c3, cast(test.t1.c1, decimal(10,0) BINARY)->Column#11 - │ └─IndexMerge_26 1841.86 root + │ └─IndexMerge_26 1841.86 root type: union │ ├─IndexRangeScan_22(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo │ ├─IndexRangeScan_23(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,-1), keep order:false, stats:pseudo │ └─Selection_25(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10) │ └─TableRowIDScan_24 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo - └─TopN_29(Probe) 1.00 root test.t2.c1, offset:2, count:1 - └─HashAgg_36 2660.44 root group by:Column#21, funcs:avg(Column#19)->Column#9, funcs:firstrow(Column#20)->test.t2.c1 - └─Projection_48 3325.55 root cast(test.t2.c1, decimal(10,0) BINARY)->Column#19, test.t2.c1, test.t2.c1 - └─IndexMerge_41 3325.55 root - ├─Selection_38(Build) 3.32 cop[tikv] eq(test.t1.c1, test.t2.c1) - │ └─IndexRangeScan_37 3323.33 cop[tikv] table:t2, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo - ├─IndexRangeScan_39(Build) 3323.33 cop[tikv] table:t2, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo - └─TableRowIDScan_40(Probe) 3325.55 cop[tikv] table:t2 keep order:false, stats:pseudo + └─TopN_29(Probe) 1841.86 root test.t2.c1, offset:2, count:1 + └─HashAgg_36 4900166.23 root group by:Column#21, funcs:avg(Column#19)->Column#9, funcs:firstrow(Column#20)->test.t2.c1 + └─Projection_48 6125207.79 root cast(test.t2.c1, decimal(10,0) BINARY)->Column#19, test.t2.c1, test.t2.c1 + └─IndexMerge_41 6125207.79 root type: union + ├─Selection_38(Build) 6121.12 cop[tikv] eq(test.t1.c1, test.t2.c1) + │ └─IndexRangeScan_37 6121120.92 cop[tikv] table:t2, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo + ├─IndexRangeScan_39(Build) 6121120.92 cop[tikv] table:t2, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo + └─TableRowIDScan_40(Probe) 6125207.79 cop[tikv] table:t2 keep order:false, stats:pseudo select /*+ use_index_merge(t1) */ * from t1 where t1.c1 = (select /*+ use_index_merge(t2) */ avg(t2.c1) from t2 where t1.c1 = t2.c1 and t2.c1 < 10 or t2.c2 < 10 group by t2.c1 order by c1 limit 1 offset 2) and (c1 < 10 or c2 < -1) and c3 < 10 order by 1; c1 c2 c3 3 3 3 @@ -552,7 +553,7 @@ insert into t1 values(1, 1, 1, 1, 1), (2, 2, 2, 2, 2), (3, 3, 3, 3, 3), (4, 4, 4 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and (c3 < 10 or c4 < 10) order by 1; id estRows task access object operator info Sort_5 3071.61 root test.t1.c1 -└─IndexMerge_12 3071.61 root +└─IndexMerge_12 3071.61 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 3071.61 cop[tikv] or(lt(test.t1.c3, 10), lt(test.t1.c4, 10)) @@ -567,7 +568,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 and c2 < 10) or (c3 < 10 and c4 < 10) order by 1; id estRows task access object operator info Sort_5 2086.93 root test.t1.c1 -└─IndexMerge_12 1156.62 root +└─IndexMerge_12 1156.62 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c3(c3) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 1156.62 cop[tikv] or(and(lt(test.t1.c1, 10), lt(test.t1.c2, 10)), and(lt(test.t1.c3, 10), lt(test.t1.c4, 10))) @@ -582,7 +583,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 and c2 < 10) or (c3 < 10 and c4 < 10) and c5 < 10 order by 1; id estRows task access object operator info Sort_5 1430.96 root test.t1.c1 -└─IndexMerge_12 793.07 root +└─IndexMerge_12 793.07 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c3(c3) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 793.07 cop[tikv] or(and(lt(test.t1.c1, 10), lt(test.t1.c2, 10)), and(lt(test.t1.c3, 10), and(lt(test.t1.c4, 10), lt(test.t1.c5, 10)))) @@ -597,7 +598,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where ((c1 < 10 and c4 < 10) or c2 < 10) and (c3 < 10 or c5 < 10) order by 1; id estRows task access object operator info Sort_5 2250.55 root test.t1.c1 -└─IndexMerge_12 1247.30 root +└─IndexMerge_12 1247.30 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 1247.30 cop[tikv] or(and(lt(test.t1.c1, 10), lt(test.t1.c4, 10)), lt(test.t1.c2, 10)), or(lt(test.t1.c3, 10), lt(test.t1.c5, 10)) @@ -627,7 +628,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (((c1 < 10 or c3 < 10) and c1 < 10) or c2 < 10) and (c3 < 10 or c5 < 10) order by 1; id estRows task access object operator info Sort_5 2523.42 root test.t1.c1 -└─IndexMerge_12 1398.53 root +└─IndexMerge_12 1398.53 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 1398.53 cop[tikv] or(and(or(lt(test.t1.c1, 10), lt(test.t1.c3, 10)), lt(test.t1.c1, 10)), lt(test.t1.c2, 10)), or(lt(test.t1.c3, 10), lt(test.t1.c5, 10)) @@ -644,7 +645,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and coalesce(c1, c2, c4) = 1 order by 1; id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 -└─IndexMerge_12 4433.77 root +└─IndexMerge_12 4433.77 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 4433.77 cop[tikv] eq(coalesce(test.t1.c1, test.t1.c2, test.t1.c4), 1) @@ -656,7 +657,7 @@ explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) a id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 └─Selection_12 4433.77 root eq(greatest(test.t1.c1, test.t1.c2, test.t1.c4), 1) - └─IndexMerge_11 5542.21 root + └─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_10(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -667,7 +668,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and abs(c1) = 1 order by 1; id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 -└─IndexMerge_12 4433.77 root +└─IndexMerge_12 4433.77 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 4433.77 cop[tikv] eq(abs(test.t1.c1), 1) @@ -678,7 +679,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and pi() order by 1; id estRows task access object operator info Sort_5 5542.21 root test.t1.c1 -└─IndexMerge_11 5542.21 root +└─IndexMerge_11 5542.21 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_10(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -692,7 +693,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and ceil(c1) order by 1; id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 -└─IndexMerge_12 4433.77 root +└─IndexMerge_12 4433.77 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 4433.77 cop[tikv] ceil(test.t1.c1) @@ -708,7 +709,7 @@ explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) a id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 └─Selection_8 4433.77 root eq(truncate(test.t1.c1, 1), 1) - └─IndexMerge_12 5542.21 root + └─IndexMerge_12 5542.21 root type: union ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_10(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_11(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -724,7 +725,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and substring(c3, 1, 1) = '1' order by 1; id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 -└─IndexMerge_12 4433.77 root +└─IndexMerge_12 4433.77 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 4433.77 cop[tikv] eq(substring(cast(test.t1.c3, var_string(20)), 1, 1), "1") @@ -736,7 +737,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and ifnull(c1, c2) order by 1; id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 -└─IndexMerge_12 4433.77 root +└─IndexMerge_12 4433.77 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 4433.77 cop[tikv] ifnull(test.t1.c1, test.t1.c2) @@ -751,7 +752,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and if(c1, c2, c3) order by 1; id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 -└─IndexMerge_12 4433.77 root +└─IndexMerge_12 4433.77 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 4433.77 cop[tikv] if(test.t1.c1, test.t1.c2, test.t1.c3) @@ -766,7 +767,7 @@ c1 c2 c3 c4 c5 explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and (c1 between 1 and 2) order by 1; id estRows task access object operator info Sort_5 138.56 root test.t1.c1 -└─IndexMerge_12 138.56 root +└─IndexMerge_12 138.56 root type: union ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_11(Probe) 138.56 cop[tikv] ge(test.t1.c1, 1), le(test.t1.c1, 2) @@ -781,7 +782,7 @@ explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) a id estRows task access object operator info Sort_5 4433.77 root test.t1.c1 └─Selection_8 4433.77 root eq(length(substring(cast(sqrt(cast(test.t1.c3, double BINARY)), var_string(5)), getvar("a"), 1)), char_length(cast(if(test.t1.c1, test.t1.c2, test.t1.c3), var_string(20)))) - └─IndexMerge_12 5542.21 root + └─IndexMerge_12 5542.21 root type: union ├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_10(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─TableRowIDScan_11(Probe) 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo @@ -799,7 +800,7 @@ insert into t1 values(1, 1, 1, 1, 1), (2, 2, 2, 2, 2), (3, 3, 3, 3, 3), (4, 4, 4 explain with cte1 as (select /*+ use_index_merge(t1) */ * from t1 where c1 < 10 or c2 < 10 and c3 < 10) select * from cte1 order by 1; id estRows task access object operator info Sort_10 4060.74 root test.t1.c1 -└─IndexMerge_17 2250.55 root +└─IndexMerge_17 2250.55 root type: union ├─IndexRangeScan_13(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo ├─IndexRangeScan_14(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo └─Selection_16(Probe) 2250.55 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) @@ -817,7 +818,7 @@ Sort_23 7309.33 root test.t1.c1 └─CTEFullScan_26 7309.33 root CTE:cte1 data:CTE_0 CTE_0 7309.33 root Recursive CTE ├─Projection_14(Seed Part) 4060.74 root test.t1.c1 -│ └─IndexMerge_19 2250.55 root +│ └─IndexMerge_19 2250.55 root type: union │ ├─IndexRangeScan_15(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo │ ├─IndexRangeScan_16(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo │ └─Selection_18(Probe) 2250.55 cop[tikv] or(lt(test.t1.c1, 10), and(lt(test.t1.c2, 10), lt(test.t1.c3, 10))) diff --git a/cmd/explaintest/r/naaj.result b/cmd/explaintest/r/naaj.result index bc5bda03fbbc3..e46a16a489333 100644 --- a/cmd/explaintest/r/naaj.result +++ b/cmd/explaintest/r/naaj.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; set @@session.tidb_enable_null_aware_anti_join=1; select "***************************************************** PART 1 *****************************************************************" as name; diff --git a/cmd/explaintest/r/new_character_set.result b/cmd/explaintest/r/new_character_set.result index 18b0f44662025..52a761d6a6da6 100644 --- a/cmd/explaintest/r/new_character_set.result +++ b/cmd/explaintest/r/new_character_set.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; set names utf8mb4; create table t (a varchar(255) charset utf8mb4); diff --git a/cmd/explaintest/r/new_character_set_builtin.result b/cmd/explaintest/r/new_character_set_builtin.result index 96f903a13ee1b..77c9400e3128a 100644 --- a/cmd/explaintest/r/new_character_set_builtin.result +++ b/cmd/explaintest/r/new_character_set_builtin.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set names utf8mb4; set @@sql_mode = ''; drop table if exists t; @@ -398,17 +399,17 @@ a like 0xe4b880 b like 0xd2bb 1 1 1 1 select a = 0xb6fe from t; -Error 3854: Cannot convert string '\xB6\xFE' from binary to utf8mb4 +Error 3854 (HY000): Cannot convert string '\xB6\xFE' from binary to utf8mb4 select b = 0xe4ba8c from t; -Error 3854: Cannot convert string '\xE4\xBA\x8C' from binary to gbk +Error 3854 (HY000): Cannot convert string '\xE4\xBA\x8C' from binary to gbk select concat(a, 0xb6fe) from t; -Error 3854: Cannot convert string '\xB6\xFE' from binary to utf8mb4 +Error 3854 (HY000): Cannot convert string '\xB6\xFE' from binary to utf8mb4 select concat(b, 0xe4ba8c) from t; -Error 3854: Cannot convert string '\xE4\xBA\x8C' from binary to gbk +Error 3854 (HY000): Cannot convert string '\xE4\xBA\x8C' from binary to gbk select concat(convert('a' using gbk), 0x3fff) from t; -Error 3854: Cannot convert string '?\xFF' from binary to gbk +Error 3854 (HY000): Cannot convert string '?\xFF' from binary to gbk select concat(convert('a' using gbk), 0x3fffffffffffffff) from t; -Error 3854: Cannot convert string '?\xFF\xFF\xFF\xFF\xFF...' from binary to gbk +Error 3854 (HY000): Cannot convert string '?\xFF\xFF\xFF\xFF\xFF...' from binary to gbk set @@tidb_enable_vectorized_expression = false; select hex(concat(a, c)), hex(concat(b, c)) from t; hex(concat(a, c)) hex(concat(b, c)) @@ -501,13 +502,13 @@ a like 0xe4b880 b like 0xd2bb 1 1 1 1 select a = 0xb6fe from t; -Error 3854: Cannot convert string '\xB6\xFE' from binary to utf8mb4 +Error 3854 (HY000): Cannot convert string '\xB6\xFE' from binary to utf8mb4 select b = 0xe4ba8c from t; -Error 3854: Cannot convert string '\xE4\xBA\x8C' from binary to gbk +Error 3854 (HY000): Cannot convert string '\xE4\xBA\x8C' from binary to gbk select concat(a, 0xb6fe) from t; -Error 3854: Cannot convert string '\xB6\xFE' from binary to utf8mb4 +Error 3854 (HY000): Cannot convert string '\xB6\xFE' from binary to utf8mb4 select concat(b, 0xe4ba8c) from t; -Error 3854: Cannot convert string '\xE4\xBA\x8C' from binary to gbk +Error 3854 (HY000): Cannot convert string '\xE4\xBA\x8C' from binary to gbk drop table if exists t; create table t (a char(20) charset utf8mb4, b char(20) charset gbk, c binary(20)); insert into t values ('一二三', '一二三', '一二三'); diff --git a/cmd/explaintest/r/new_character_set_invalid.result b/cmd/explaintest/r/new_character_set_invalid.result index bb9ae4aa6db2b..e0c749d81ab15 100644 --- a/cmd/explaintest/r/new_character_set_invalid.result +++ b/cmd/explaintest/r/new_character_set_invalid.result @@ -1,13 +1,14 @@ +set tidb_cost_model_version=1; set @@sql_mode = 'strict_trans_tables'; drop table if exists t; create table t (a varchar(255) charset gbk, b varchar(255) charset ascii, c varchar(255) charset utf8); insert into t values ('中文', 'asdf', '字符集'); insert into t values ('À', 'ø', '😂'); -Error 1366: Incorrect string value '\xC3\x80' for column 'a' +Error 1366 (HY000): Incorrect string value '\xC3\x80' for column 'a' insert into t values ('中文À中文', 'asdføfdsa', '字符集😂字符集'); -Error 1366: Incorrect string value '\xC3\x80' for column 'a' +Error 1366 (HY000): Incorrect string value '\xC3\x80' for column 'a' insert into t values (0x4040ffff, 0x4040ffff, 0x4040ffff); -Error 1366: Incorrect string value '\xFF\xFF' for column 'a' +Error 1366 (HY000): Incorrect string value '\xFF\xFF' for column 'a' select * from t; a b c 中文 asdf 字符集 diff --git a/cmd/explaintest/r/select.result b/cmd/explaintest/r/select.result index 9577b28e47c35..70101f0218ca8 100644 --- a/cmd/explaintest/r/select.result +++ b/cmd/explaintest/r/select.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set @@tidb_enable_outer_join_reorder=true; DROP TABLE IF EXISTS t; CREATE TABLE t ( @@ -95,9 +96,9 @@ SELECT * from t a left join t2 b on a.c1 = b.c1; c1 c2 c3 c1 c2 1 2 3 1 2 SELECT * from (SELECT 1, 1) as a; -Error 1060: Duplicate column name '1' +Error 1060 (42S21): Duplicate column name '1' SELECT * from (SELECT * FROM t, t2) as a; -Error 1060: Duplicate column name 'c1' +Error 1060 (42S21): Duplicate column name 'c1' DROP TABLE IF EXISTS t; CREATE TABLE t (c1 INT, c2 INT); INSERT INTO t VALUES (1, 2), (1, 1), (1, 3); @@ -655,5 +656,5 @@ drop table if exists t3; create table t3(a char(10), primary key (a)); insert into t3 values ('a'); select * from t3 where a > 0x80; -Error 1105: Cannot convert string '\x80' from binary to utf8mb4 +Error 1105 (HY000): Cannot convert string '\x80' from binary to utf8mb4 set @@tidb_enable_outer_join_reorder=false; diff --git a/cmd/explaintest/r/show.result b/cmd/explaintest/r/show.result index 6dfbf77c4af44..e434f794cb313 100644 --- a/cmd/explaintest/r/show.result +++ b/cmd/explaintest/r/show.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; show tables like '%xx'; Tables_in_test (%xx) show databases like '%xx'; diff --git a/cmd/explaintest/r/subquery.result b/cmd/explaintest/r/subquery.result index cfb170dabf0cd..0cf9302f425c0 100644 --- a/cmd/explaintest/r/subquery.result +++ b/cmd/explaintest/r/subquery.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t1; drop table if exists t2; create table t1(a bigint, b bigint); @@ -21,12 +22,12 @@ Projection 5.00 root Column#22 └─Apply 5.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#21) ├─TableReader(Build) 5.00 root data:TableFullScan │ └─TableFullScan 5.00 cop[tikv] table:t keep order:false - └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#21 - └─IndexJoin 0.22 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a) - ├─IndexReader(Build) 0.45 root index:IndexRangeScan - │ └─IndexRangeScan 0.45 cop[tikv] table:s, index:idx(b, c, d) range: decided by [eq(test.t.b, 1) eq(test.t.c, 1) eq(test.t.d, test.t.a)], keep order:false - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:t1 range: decided by [test.t.a], keep order:false + └─StreamAgg(Probe) 5.00 root funcs:count(1)->Column#21 + └─IndexJoin 1.12 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a) + ├─IndexReader(Build) 2.24 root index:IndexRangeScan + │ └─IndexRangeScan 2.24 cop[tikv] table:s, index:idx(b, c, d) range: decided by [eq(test.t.b, 1) eq(test.t.c, 1) eq(test.t.d, test.t.a)], keep order:false + └─TableReader(Probe) 2.24 root data:TableRangeScan + └─TableRangeScan 2.24 cop[tikv] table:t1 range: decided by [test.t.a], keep order:false drop table if exists t; create table t(a int, b int, c int); explain format = 'brief' select a from t t1 where t1.a = (select max(t2.a) from t t2 where t1.b=t2.b and t1.c=t2.b); @@ -58,10 +59,10 @@ id estRows task access object operator info Apply 10000.00 root CARTESIAN anti semi join, other cond:eq(test.stu.name, Column#8) ├─TableReader(Build) 10000.00 root data:TableFullScan │ └─TableFullScan 10000.00 cop[tikv] table:stu keep order:false, stats:pseudo -└─Projection(Probe) 10.00 root guo->Column#8 - └─TableReader 10.00 root data:Selection - └─Selection 10.00 cop[tikv] eq(test.exam.stu_id, test.stu.id) - └─TableFullScan 10000.00 cop[tikv] table:exam keep order:false, stats:pseudo +└─Projection(Probe) 100000.00 root guo->Column#8 + └─TableReader 100000.00 root data:Selection + └─Selection 100000.00 cop[tikv] eq(test.exam.stu_id, test.stu.id) + └─TableFullScan 100000000.00 cop[tikv] table:exam keep order:false, stats:pseudo select * from stu where stu.name not in (select 'guo' from exam where exam.stu_id = stu.id); id name set names utf8mb4; diff --git a/cmd/explaintest/r/topn_push_down.result b/cmd/explaintest/r/topn_push_down.result index f45d88ea56a5c..5317f0161aded 100644 --- a/cmd/explaintest/r/topn_push_down.result +++ b/cmd/explaintest/r/topn_push_down.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE TABLE `tr` ( `id` bigint(20) NOT NULL, `biz_date` date NOT NULL, @@ -176,13 +177,13 @@ Limit 0.00 root offset:0, count:5 │ │ │ └─IndexRangeScan 10.00 cop[tikv] table:tr, index:idx_shop_identy_trade_status_business_type(shop_identy, trade_status, business_type, trade_pay_status, trade_type, delivery_type, source, biz_date) range:[810094178,810094178], keep order:false, stats:pseudo │ │ └─Selection(Probe) 0.00 cop[tikv] eq(test.tr.brand_identy, 32314), eq(test.tr.domain_type, 2) │ │ └─TableRowIDScan 0.00 cop[tikv] table:tr keep order:false, stats:pseudo - │ └─IndexLookUp(Probe) 1.25 root - │ ├─IndexRangeScan(Build) 50.00 cop[tikv] table:te, index:idx_trade_id(trade_id) range: decided by [eq(test.te.trade_id, test.tr.id)], keep order:false, stats:pseudo - │ └─Selection(Probe) 1.25 cop[tikv] ge(test.te.expect_time, 2018-04-23 00:00:00.000000), le(test.te.expect_time, 2018-04-23 23:59:59.000000) - │ └─TableRowIDScan 50.00 cop[tikv] table:te keep order:false, stats:pseudo - └─IndexReader(Probe) 1.25 root index:Selection - └─Selection 1.25 cop[tikv] not(isnull(test.p.relate_id)) - └─IndexRangeScan 1.25 cop[tikv] table:p, index:payment_relate_id(relate_id) range: decided by [eq(test.p.relate_id, test.tr.id)], keep order:false, stats:pseudo + │ └─IndexLookUp(Probe) 0.00 root + │ ├─IndexRangeScan(Build) 0.00 cop[tikv] table:te, index:idx_trade_id(trade_id) range: decided by [eq(test.te.trade_id, test.tr.id)], keep order:false, stats:pseudo + │ └─Selection(Probe) 0.00 cop[tikv] ge(test.te.expect_time, 2018-04-23 00:00:00.000000), le(test.te.expect_time, 2018-04-23 23:59:59.000000) + │ └─TableRowIDScan 0.00 cop[tikv] table:te keep order:false, stats:pseudo + └─IndexReader(Probe) 0.00 root index:Selection + └─Selection 0.00 cop[tikv] not(isnull(test.p.relate_id)) + └─IndexRangeScan 0.00 cop[tikv] table:p, index:payment_relate_id(relate_id) range: decided by [eq(test.p.relate_id, test.tr.id)], keep order:false, stats:pseudo desc select 1 as a from dual order by a limit 1; id estRows task access object operator info Projection_6 1.00 root 1->Column#1 @@ -197,24 +198,24 @@ Apply_15 9990.00 root semi join, equal:[eq(test.t1.a, test.t2.a)] ├─TableReader_18(Build) 9990.00 root data:Selection_17 │ └─Selection_17 9990.00 cop[tikv] not(isnull(test.t1.a)) │ └─TableFullScan_16 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo -└─Selection_19(Probe) 0.80 root not(isnull(test.t2.a)) - └─Limit_20 1.00 root offset:0, count:1 - └─TableReader_25 1.00 root data:Limit_24 - └─Limit_24 1.00 cop[tikv] offset:0, count:1 - └─Selection_23 1.00 cop[tikv] gt(test.t2.b, test.t1.b) - └─TableFullScan_22 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo +└─Selection_19(Probe) 7992.00 root not(isnull(test.t2.a)) + └─Limit_20 9990.00 root offset:0, count:1 + └─TableReader_25 9990.00 root data:Limit_24 + └─Limit_24 9990.00 cop[tikv] offset:0, count:1 + └─Selection_23 9990.00 cop[tikv] gt(test.t2.b, test.t1.b) + └─TableFullScan_22 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo desc select * from t1 where t1.a in (select a from (select t2.a as a, t1.b as b from t2 where t2.b > t1.b) x order by b limit 1); id estRows task access object operator info Apply_17 9990.00 root semi join, equal:[eq(test.t1.a, test.t2.a)] ├─TableReader_20(Build) 9990.00 root data:Selection_19 │ └─Selection_19 9990.00 cop[tikv] not(isnull(test.t1.a)) │ └─TableFullScan_18 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo -└─Selection_21(Probe) 0.80 root not(isnull(test.t2.a)) - └─Limit_23 1.00 root offset:0, count:1 - └─TableReader_28 1.00 root data:Limit_27 - └─Limit_27 1.00 cop[tikv] offset:0, count:1 - └─Selection_26 1.00 cop[tikv] gt(test.t2.b, test.t1.b) - └─TableFullScan_25 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo +└─Selection_21(Probe) 7992.00 root not(isnull(test.t2.a)) + └─Limit_23 9990.00 root offset:0, count:1 + └─TableReader_28 9990.00 root data:Limit_27 + └─Limit_27 9990.00 cop[tikv] offset:0, count:1 + └─Selection_26 9990.00 cop[tikv] gt(test.t2.b, test.t1.b) + └─TableFullScan_25 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo drop table if exists t; create table t(a int not null, index idx(a)); explain format = 'brief' select /*+ TIDB_INLJ(t2) */ * from t t1 join t t2 on t1.a = t2.a limit 5; @@ -223,8 +224,8 @@ Limit 5.00 root offset:0, count:5 └─IndexJoin 5.00 root inner join, inner:IndexReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a) ├─TableReader(Build) 4.00 root data:TableFullScan │ └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─IndexReader(Probe) 1.25 root index:IndexRangeScan - └─IndexRangeScan 1.25 cop[tikv] table:t2, index:idx(a) range: decided by [eq(test.t.a, test.t.a)], keep order:false, stats:pseudo + └─IndexReader(Probe) 5.00 root index:IndexRangeScan + └─IndexRangeScan 5.00 cop[tikv] table:t2, index:idx(a) range: decided by [eq(test.t.a, test.t.a)], keep order:false, stats:pseudo explain format = 'brief' select /*+ TIDB_INLJ(t2) */ * from t t1 left join t t2 on t1.a = t2.a where t2.a is null limit 5; id estRows task access object operator info Limit 5.00 root offset:0, count:5 @@ -232,8 +233,8 @@ Limit 5.00 root offset:0, count:5 └─IndexJoin 5.00 root left outer join, inner:IndexReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a) ├─TableReader(Build) 4.00 root data:TableFullScan │ └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false, stats:pseudo - └─IndexReader(Probe) 1.25 root index:IndexRangeScan - └─IndexRangeScan 1.25 cop[tikv] table:t2, index:idx(a) range: decided by [eq(test.t.a, test.t.a)], keep order:false, stats:pseudo + └─IndexReader(Probe) 5.00 root index:IndexRangeScan + └─IndexRangeScan 5.00 cop[tikv] table:t2, index:idx(a) range: decided by [eq(test.t.a, test.t.a)], keep order:false, stats:pseudo explain format = 'brief' select /*+ TIDB_SMJ(t1, t2) */ * from t t1 join t t2 on t1.a = t2.a limit 5; id estRows task access object operator info Limit 5.00 root offset:0, count:5 diff --git a/cmd/explaintest/r/topn_pushdown.result b/cmd/explaintest/r/topn_pushdown.result index 1b0be3c8e2190..e765953c727b3 100644 --- a/cmd/explaintest/r/topn_pushdown.result +++ b/cmd/explaintest/r/topn_pushdown.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; explain format = 'brief' select * from ((select 4 as a) union all (select 33 as a)) tmp order by a desc limit 1; id estRows task access object operator info TopN 1.00 root Column#3:desc, offset:0, count:1 diff --git a/cmd/explaintest/r/tpch.result b/cmd/explaintest/r/tpch.result index f1100126e8812..a2fc266a653d7 100644 --- a/cmd/explaintest/r/tpch.result +++ b/cmd/explaintest/r/tpch.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE DATABASE IF NOT EXISTS TPCH; USE TPCH; CREATE TABLE IF NOT EXISTS nation ( N_NATIONKEY INTEGER NOT NULL, @@ -26,16 +27,13 @@ S_NATIONKEY INTEGER NOT NULL, S_PHONE CHAR(15) NOT NULL, S_ACCTBAL DECIMAL(15,2) NOT NULL, S_COMMENT VARCHAR(101) NOT NULL, -PRIMARY KEY (S_SUPPKEY), -CONSTRAINT FOREIGN KEY SUPPLIER_FK1 (S_NATIONKEY) references nation(N_NATIONKEY)); +PRIMARY KEY (S_SUPPKEY)); CREATE TABLE IF NOT EXISTS partsupp ( PS_PARTKEY INTEGER NOT NULL, PS_SUPPKEY INTEGER NOT NULL, PS_AVAILQTY INTEGER NOT NULL, PS_SUPPLYCOST DECIMAL(15,2) NOT NULL, PS_COMMENT VARCHAR(199) NOT NULL, -PRIMARY KEY (PS_PARTKEY,PS_SUPPKEY), -CONSTRAINT FOREIGN KEY PARTSUPP_FK1 (PS_SUPPKEY) references supplier(S_SUPPKEY), -CONSTRAINT FOREIGN KEY PARTSUPP_FK2 (PS_PARTKEY) references part(P_PARTKEY)); +PRIMARY KEY (PS_PARTKEY,PS_SUPPKEY)); CREATE TABLE IF NOT EXISTS customer ( C_CUSTKEY INTEGER NOT NULL, C_NAME VARCHAR(25) NOT NULL, C_ADDRESS VARCHAR(40) NOT NULL, @@ -44,8 +42,7 @@ C_PHONE CHAR(15) NOT NULL, C_ACCTBAL DECIMAL(15,2) NOT NULL, C_MKTSEGMENT CHAR(10) NOT NULL, C_COMMENT VARCHAR(117) NOT NULL, -PRIMARY KEY (C_CUSTKEY), -CONSTRAINT FOREIGN KEY CUSTOMER_FK1 (C_NATIONKEY) references nation(N_NATIONKEY)); +PRIMARY KEY (C_CUSTKEY)); CREATE TABLE IF NOT EXISTS orders ( O_ORDERKEY INTEGER NOT NULL, O_CUSTKEY INTEGER NOT NULL, O_ORDERSTATUS CHAR(1) NOT NULL, @@ -55,8 +52,7 @@ O_ORDERPRIORITY CHAR(15) NOT NULL, O_CLERK CHAR(15) NOT NULL, O_SHIPPRIORITY INTEGER NOT NULL, O_COMMENT VARCHAR(79) NOT NULL, -PRIMARY KEY (O_ORDERKEY), -CONSTRAINT FOREIGN KEY ORDERS_FK1 (O_CUSTKEY) references customer(C_CUSTKEY)); +PRIMARY KEY (O_ORDERKEY)); CREATE TABLE IF NOT EXISTS lineitem ( L_ORDERKEY INTEGER NOT NULL, L_PARTKEY INTEGER NOT NULL, L_SUPPKEY INTEGER NOT NULL, @@ -73,9 +69,7 @@ L_RECEIPTDATE DATE NOT NULL, L_SHIPINSTRUCT CHAR(25) NOT NULL, L_SHIPMODE CHAR(10) NOT NULL, L_COMMENT VARCHAR(44) NOT NULL, -PRIMARY KEY (L_ORDERKEY,L_LINENUMBER), -CONSTRAINT FOREIGN KEY LINEITEM_FK1 (L_ORDERKEY) references orders(O_ORDERKEY), -CONSTRAINT FOREIGN KEY LINEITEM_FK2 (L_PARTKEY,L_SUPPKEY) references partsupp(PS_PARTKEY, PS_SUPPKEY)); +PRIMARY KEY (L_ORDERKEY,L_LINENUMBER)); load stats 's/tpch_stats/nation.json'; load stats 's/tpch_stats/region.json'; load stats 's/tpch_stats/part.json'; @@ -262,10 +256,10 @@ Projection 10.00 root tpch.lineitem.l_orderkey, Column#35, tpch.orders.o_orderd │ └─TableReader(Probe) 36870000.00 root data:Selection │ └─Selection 36870000.00 cop[tikv] lt(tpch.orders.o_orderdate, 1995-03-13 00:00:00.000000) │ └─TableFullScan 75000000.00 cop[tikv] table:orders keep order:false - └─IndexLookUp(Probe) 4.05 root - ├─IndexRangeScan(Build) 7.45 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false - └─Selection(Probe) 4.05 cop[tikv] gt(tpch.lineitem.l_shipdate, 1995-03-13 00:00:00.000000) - └─TableRowIDScan 7.45 cop[tikv] table:lineitem keep order:false + └─IndexLookUp(Probe) 91515927.49 root + ├─IndexRangeScan(Build) 168388203.74 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false + └─Selection(Probe) 91515927.49 cop[tikv] gt(tpch.lineitem.l_shipdate, 1995-03-13 00:00:00.000000) + └─TableRowIDScan 168388203.74 cop[tikv] table:lineitem keep order:false /* Q4 Order Priority Checking Query This query determines how well the order priority system is working and gives an assessment of customer satisfaction. @@ -303,10 +297,10 @@ Sort 1.00 root tpch.orders.o_orderpriority ├─TableReader(Build) 2925937.50 root data:Selection │ └─Selection 2925937.50 cop[tikv] ge(tpch.orders.o_orderdate, 1995-01-01 00:00:00.000000), lt(tpch.orders.o_orderdate, 1995-04-01 00:00:00.000000) │ └─TableFullScan 75000000.00 cop[tikv] table:orders keep order:false - └─IndexLookUp(Probe) 4.05 root - ├─IndexRangeScan(Build) 5.06 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false - └─Selection(Probe) 4.05 cop[tikv] lt(tpch.lineitem.l_commitdate, tpch.lineitem.l_receiptdate) - └─TableRowIDScan 5.06 cop[tikv] table:lineitem keep order:false + └─IndexLookUp(Probe) 11851908.75 root + ├─IndexRangeScan(Build) 14814885.94 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false + └─Selection(Probe) 11851908.75 cop[tikv] lt(tpch.lineitem.l_commitdate, tpch.lineitem.l_receiptdate) + └─TableRowIDScan 14814885.94 cop[tikv] table:lineitem keep order:false /* Q5 Local Supplier Volume Query This query lists the revenue volume done through local suppliers. @@ -469,8 +463,8 @@ Sort 769.96 root tpch.nation.n_name, tpch.nation.n_name, Column#50 │ └─TableReader(Probe) 91446230.29 root data:Selection │ └─Selection 91446230.29 cop[tikv] ge(tpch.lineitem.l_shipdate, 1995-01-01 00:00:00.000000), le(tpch.lineitem.l_shipdate, 1996-12-31 00:00:00.000000) │ └─TableFullScan 300005811.00 cop[tikv] table:lineitem keep order:false - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:orders range: decided by [tpch.lineitem.l_orderkey], keep order:false + └─TableReader(Probe) 24465505.20 root data:TableRangeScan + └─TableRangeScan 24465505.20 cop[tikv] table:orders range: decided by [tpch.lineitem.l_orderkey], keep order:false /* Q8 National Market Share Query This query determines how the market share of a given nation within a given region has changed over two years for @@ -548,9 +542,9 @@ Sort 719.02 root Column#62 │ └─TableReader(Probe) 22413367.93 root data:Selection │ └─Selection 22413367.93 cop[tikv] ge(tpch.orders.o_orderdate, 1995-01-01 00:00:00.000000), le(tpch.orders.o_orderdate, 1996-12-31 00:00:00.000000) │ └─TableFullScan 75000000.00 cop[tikv] table:orders keep order:false - └─IndexLookUp(Probe) 4.05 root - ├─IndexRangeScan(Build) 4.05 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false - └─TableRowIDScan(Probe) 4.05 cop[tikv] table:lineitem keep order:false + └─IndexLookUp(Probe) 90788402.51 root + ├─IndexRangeScan(Build) 90788402.51 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false + └─TableRowIDScan(Probe) 90788402.51 cop[tikv] table:lineitem keep order:false /* Q9 Product Type Profit Measure Query This query determines how much profit is made on a given line of parts, broken out by supplier nation and year. @@ -677,10 +671,10 @@ Projection 20.00 root tpch.customer.c_custkey, tpch.customer.c_name, Column#39, │ │ └─TableFullScan 25.00 cop[tikv] table:nation keep order:false │ └─TableReader(Probe) 7500000.00 root data:TableFullScan │ └─TableFullScan 7500000.00 cop[tikv] table:customer keep order:false - └─IndexLookUp(Probe) 4.05 root - ├─IndexRangeScan(Build) 16.44 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false - └─Selection(Probe) 4.05 cop[tikv] eq(tpch.lineitem.l_returnflag, "R") - └─TableRowIDScan 16.44 cop[tikv] table:lineitem keep order:false + └─IndexLookUp(Probe) 12222016.17 root + ├─IndexRangeScan(Build) 49605980.10 cop[tikv] table:lineitem, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)], keep order:false + └─Selection(Probe) 12222016.17 cop[tikv] eq(tpch.lineitem.l_returnflag, "R") + └─TableRowIDScan 49605980.10 cop[tikv] table:lineitem keep order:false /* Q11 Important Stock Identification Query This query finds the most important subset of suppliers' stock in a given nation. @@ -780,8 +774,8 @@ Sort 1.00 root tpch.lineitem.l_shipmode ├─TableReader(Build) 10023369.01 root data:Selection │ └─Selection 10023369.01 cop[tikv] ge(tpch.lineitem.l_receiptdate, 1997-01-01 00:00:00.000000), in(tpch.lineitem.l_shipmode, "RAIL", "FOB"), lt(tpch.lineitem.l_commitdate, tpch.lineitem.l_receiptdate), lt(tpch.lineitem.l_receiptdate, 1998-01-01 00:00:00.000000), lt(tpch.lineitem.l_shipdate, tpch.lineitem.l_commitdate) │ └─TableFullScan 300005811.00 cop[tikv] table:lineitem keep order:false - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:orders range: decided by [tpch.lineitem.l_orderkey], keep order:false + └─TableReader(Probe) 10023369.01 root data:TableRangeScan + └─TableRangeScan 10023369.01 cop[tikv] table:orders range: decided by [tpch.lineitem.l_orderkey], keep order:false /* Q13 Customer Distribution Query This query seeks relationships between customers and the size of their orders. @@ -851,8 +845,8 @@ Projection 1.00 root div(mul(100.00, Column#27), Column#28)->Column#29 ├─TableReader(Build) 4121984.49 root data:Selection │ └─Selection 4121984.49 cop[tikv] ge(tpch.lineitem.l_shipdate, 1996-12-01 00:00:00.000000), lt(tpch.lineitem.l_shipdate, 1997-01-01 00:00:00.000000) │ └─TableFullScan 300005811.00 cop[tikv] table:lineitem keep order:false - └─TableReader(Probe) 1.00 root data:TableRangeScan - └─TableRangeScan 1.00 cop[tikv] table:part range: decided by [tpch.lineitem.l_partkey], keep order:false + └─TableReader(Probe) 4121984.49 root data:TableRangeScan + └─TableRangeScan 4121984.49 cop[tikv] table:part range: decided by [tpch.lineitem.l_partkey], keep order:false /* Q15 Top Supplier Query This query determines the top supplier so it can be rewarded, given more business, or identified for special recognition. @@ -945,8 +939,8 @@ Sort 14.41 root Column#23:desc, tpch.part.p_brand, tpch.part.p_type, tpch.part. ├─TableReader(Build) 1200618.43 root data:Selection │ └─Selection 1200618.43 cop[tikv] in(tpch.part.p_size, 48, 19, 12, 4, 41, 7, 21, 39), ne(tpch.part.p_brand, "Brand#34"), not(like(tpch.part.p_type, "LARGE BRUSHED%", 92)) │ └─TableFullScan 10000000.00 cop[tikv] table:part keep order:false - └─IndexReader(Probe) 4.02 root index:IndexRangeScan - └─IndexRangeScan 4.02 cop[tikv] table:partsupp, index:PRIMARY(PS_PARTKEY, PS_SUPPKEY) range: decided by [eq(tpch.partsupp.ps_partkey, tpch.part.p_partkey)], keep order:false + └─IndexReader(Probe) 4829985.30 root index:IndexRangeScan + └─IndexRangeScan 4829985.30 cop[tikv] table:partsupp, index:PRIMARY(PS_PARTKEY, PS_SUPPKEY) range: decided by [eq(tpch.partsupp.ps_partkey, tpch.part.p_partkey)], keep order:false /* Q17 Small-Quantity-Order Revenue Query This query determines how much average yearly revenue would be lost if orders were no longer filled for small @@ -1167,9 +1161,9 @@ Sort 20000.00 root tpch.supplier.s_name │ ├─TableReader(Build) 80007.93 root data:Selection │ │ └─Selection 80007.93 cop[tikv] like(tpch.part.p_name, "green%", 92) │ │ └─TableFullScan 10000000.00 cop[tikv] table:part keep order:false - │ └─IndexLookUp(Probe) 4.02 root - │ ├─IndexRangeScan(Build) 4.02 cop[tikv] table:partsupp, index:PRIMARY(PS_PARTKEY, PS_SUPPKEY) range: decided by [eq(tpch.partsupp.ps_partkey, tpch.part.p_partkey)], keep order:false - │ └─TableRowIDScan(Probe) 4.02 cop[tikv] table:partsupp keep order:false + │ └─IndexLookUp(Probe) 321865.05 root + │ ├─IndexRangeScan(Build) 321865.05 cop[tikv] table:partsupp, index:PRIMARY(PS_PARTKEY, PS_SUPPKEY) range: decided by [eq(tpch.partsupp.ps_partkey, tpch.part.p_partkey)], keep order:false + │ └─TableRowIDScan(Probe) 321865.05 cop[tikv] table:partsupp keep order:false └─TableReader(Probe) 44189356.65 root data:Selection └─Selection 44189356.65 cop[tikv] ge(tpch.lineitem.l_shipdate, 1993-01-01 00:00:00.000000), lt(tpch.lineitem.l_shipdate, 1994-01-01 00:00:00.000000) └─TableFullScan 300005811.00 cop[tikv] table:lineitem keep order:false @@ -1238,16 +1232,16 @@ Projection 100.00 root tpch.supplier.s_name, Column#72 │ │ │ └─TableReader(Probe) 240004648.80 root data:Selection │ │ │ └─Selection 240004648.80 cop[tikv] gt(tpch.lineitem.l_receiptdate, tpch.lineitem.l_commitdate) │ │ │ └─TableFullScan 300005811.00 cop[tikv] table:l1 keep order:false - │ │ └─TableReader(Probe) 0.49 root data:Selection - │ │ └─Selection 0.49 cop[tikv] eq(tpch.orders.o_orderstatus, "F") - │ │ └─TableRangeScan 1.00 cop[tikv] table:orders range: decided by [tpch.lineitem.l_orderkey], keep order:false - │ └─IndexLookUp(Probe) 4.05 root - │ ├─IndexRangeScan(Build) 4.05 cop[tikv] table:l2, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.lineitem.l_orderkey)], keep order:false - │ └─TableRowIDScan(Probe) 4.05 cop[tikv] table:l2 keep order:false - └─IndexLookUp(Probe) 4.05 root - ├─IndexRangeScan(Build) 5.06 cop[tikv] table:l3, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.lineitem.l_orderkey)], keep order:false - └─Selection(Probe) 4.05 cop[tikv] gt(tpch.lineitem.l_receiptdate, tpch.lineitem.l_commitdate) - └─TableRowIDScan 5.06 cop[tikv] table:l3 keep order:false + │ │ └─TableReader(Probe) 5956106.20 root data:Selection + │ │ └─Selection 5956106.20 cop[tikv] eq(tpch.orders.o_orderstatus, "F") + │ │ └─TableRangeScan 12232752.60 cop[tikv] table:orders range: decided by [tpch.lineitem.l_orderkey], keep order:false + │ └─IndexLookUp(Probe) 49550432.16 root + │ ├─IndexRangeScan(Build) 49550432.16 cop[tikv] table:l2, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.lineitem.l_orderkey)], keep order:false + │ └─TableRowIDScan(Probe) 49550432.16 cop[tikv] table:l2 keep order:false + └─IndexLookUp(Probe) 39640345.73 root + ├─IndexRangeScan(Build) 49550432.16 cop[tikv] table:l3, index:PRIMARY(L_ORDERKEY, L_LINENUMBER) range: decided by [eq(tpch.lineitem.l_orderkey, tpch.lineitem.l_orderkey)], keep order:false + └─Selection(Probe) 39640345.73 cop[tikv] gt(tpch.lineitem.l_receiptdate, tpch.lineitem.l_commitdate) + └─TableRowIDScan 49550432.16 cop[tikv] table:l3 keep order:false /* Q22 Global Sales Opportunity Query The Global Sales Opportunity Query identifies geographies where there are customers who may be likely to make a diff --git a/cmd/explaintest/r/vitess_hash.result b/cmd/explaintest/r/vitess_hash.result index a6beca77cbe4e..aca512f469ee5 100644 --- a/cmd/explaintest/r/vitess_hash.result +++ b/cmd/explaintest/r/vitess_hash.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t( diff --git a/cmd/explaintest/r/window_function.result b/cmd/explaintest/r/window_function.result index b29d1e5d3fba7..2f7102f68d8c0 100644 --- a/cmd/explaintest/r/window_function.result +++ b/cmd/explaintest/r/window_function.result @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t (a int, b int, c timestamp, index idx(a)); diff --git a/cmd/explaintest/t/access_path_selection.test b/cmd/explaintest/t/access_path_selection.test index 26b68ff3609d8..59e2d255944a8 100644 --- a/cmd/explaintest/t/access_path_selection.test +++ b/cmd/explaintest/t/access_path_selection.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE TABLE `access_path_selection` ( `a` int, `b` int, diff --git a/cmd/explaintest/t/agg_predicate_pushdown.test b/cmd/explaintest/t/agg_predicate_pushdown.test index 0779fe9744030..752489eda4715 100644 --- a/cmd/explaintest/t/agg_predicate_pushdown.test +++ b/cmd/explaintest/t/agg_predicate_pushdown.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop database if exists agg_predicate_pushdown; create database agg_predicate_pushdown; diff --git a/cmd/explaintest/t/black_list.test b/cmd/explaintest/t/black_list.test index 6fcc8559cc0a0..cea82e7c3c4b1 100644 --- a/cmd/explaintest/t/black_list.test +++ b/cmd/explaintest/t/black_list.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t (a int); diff --git a/cmd/explaintest/t/clustered_index.test b/cmd/explaintest/t/clustered_index.test index 606a768f5b8d4..f809cf12104c0 100644 --- a/cmd/explaintest/t/clustered_index.test +++ b/cmd/explaintest/t/clustered_index.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set @@tidb_enable_outer_join_reorder=true; drop database if exists with_cluster_index; create database with_cluster_index; diff --git a/cmd/explaintest/t/collation_agg_func.test b/cmd/explaintest/t/collation_agg_func.test index 7a39729786404..c198dd1c9c708 100644 --- a/cmd/explaintest/t/collation_agg_func.test +++ b/cmd/explaintest/t/collation_agg_func.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; # These tests test the aggregate function's behavior according to collation. # The result of min/max of enum/set is wrong, please fix them soon. diff --git a/cmd/explaintest/t/collation_check_use_collation.test b/cmd/explaintest/t/collation_check_use_collation.test index ebaa37588d153..62fbea05ae628 100644 --- a/cmd/explaintest/t/collation_check_use_collation.test +++ b/cmd/explaintest/t/collation_check_use_collation.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; # These tests check that the used collation is correct. # prepare database diff --git a/cmd/explaintest/t/collation_misc.test b/cmd/explaintest/t/collation_misc.test index d46d3a27aa8b1..433cd2f7a9051 100644 --- a/cmd/explaintest/t/collation_misc.test +++ b/cmd/explaintest/t/collation_misc.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; # prepare database create database collation_misc; use collation_misc; diff --git a/cmd/explaintest/t/collation_pointget.test b/cmd/explaintest/t/collation_pointget.test index ea4cdca6f05c9..0cb02e2d6f2b2 100644 --- a/cmd/explaintest/t/collation_pointget.test +++ b/cmd/explaintest/t/collation_pointget.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; # prepare database create database collation_point_get; use collation_point_get; diff --git a/cmd/explaintest/t/common_collation.test b/cmd/explaintest/t/common_collation.test index 8f19d9d1a3e27..184e7246ca0da 100644 --- a/cmd/explaintest/t/common_collation.test +++ b/cmd/explaintest/t/common_collation.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; --disable_warnings drop table if exists t; --enable_warnings diff --git a/cmd/explaintest/t/cte.test b/cmd/explaintest/t/cte.test index c2441f288fa2a..860317681a210 100644 --- a/cmd/explaintest/t/cte.test +++ b/cmd/explaintest/t/cte.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; # case 1 drop table if exists tbl_0; diff --git a/cmd/explaintest/t/explain-non-select-stmt.test b/cmd/explaintest/t/explain-non-select-stmt.test index 474958c84e07c..05149a8cdb6a2 100644 --- a/cmd/explaintest/t/explain-non-select-stmt.test +++ b/cmd/explaintest/t/explain-non-select-stmt.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t(a bigint, b bigint); diff --git a/cmd/explaintest/t/explain.test b/cmd/explaintest/t/explain.test index 401fdf18aaaaf..ed679d54c199f 100644 --- a/cmd/explaintest/t/explain.test +++ b/cmd/explaintest/t/explain.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; create table t (id int, c1 timestamp); show columns from t; diff --git a/cmd/explaintest/t/explain_complex.test b/cmd/explaintest/t/explain_complex.test index 39a2baa357f1a..187ec571857d8 100644 --- a/cmd/explaintest/t/explain_complex.test +++ b/cmd/explaintest/t/explain_complex.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE TABLE `dt` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT , `aid` varchar(32) NOT NULL, @@ -173,7 +174,9 @@ CREATE TABLE org_position ( UNIQUE KEY org_employee_position_pk (hotel_id,user_id,position_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +set tidb_cost_model_version=2; explain format = 'brief' SELECT d.id, d.ctx, d.name, d.left_value, d.right_value, d.depth, d.leader_id, d.status, d.created_on, d.updated_on FROM org_department AS d LEFT JOIN org_position AS p ON p.department_id = d.id AND p.status = 1000 LEFT JOIN org_employee_position AS ep ON ep.position_id = p.id AND ep.status = 1000 WHERE (d.ctx = 1 AND (ep.user_id = 62 OR d.id = 20 OR d.id = 20) AND d.status = 1000) GROUP BY d.id ORDER BY d.left_value; +set tidb_cost_model_version=1; create table test.Tab_A (id int primary key,bid int,cid int,name varchar(20),type varchar(20),num int,amt decimal(11,2)); create table test.Tab_B (id int primary key,name varchar(20)); diff --git a/cmd/explaintest/t/explain_complex_stats.test b/cmd/explaintest/t/explain_complex_stats.test index cd5dc4bfce31b..4b4b6a9917c8c 100644 --- a/cmd/explaintest/t/explain_complex_stats.test +++ b/cmd/explaintest/t/explain_complex_stats.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists dt; CREATE TABLE dt ( id int(11) unsigned NOT NULL, diff --git a/cmd/explaintest/t/explain_cte.test b/cmd/explaintest/t/explain_cte.test index c97643115d880..1fdb897251736 100644 --- a/cmd/explaintest/t/explain_cte.test +++ b/cmd/explaintest/t/explain_cte.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2; create table t1 (c1 int primary key, c2 int, index c2 (c2)); diff --git a/cmd/explaintest/t/explain_easy.test b/cmd/explaintest/t/explain_easy.test index b03e30f5e2af7..f2b711831873b 100644 --- a/cmd/explaintest/t/explain_easy.test +++ b/cmd/explaintest/t/explain_easy.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2, t3, t4; create table t1 (c1 int primary key, c2 int, c3 int, index c2 (c2)); diff --git a/cmd/explaintest/t/explain_easy_stats.test b/cmd/explaintest/t/explain_easy_stats.test index cad15dc2db0b5..878db00ca3d4f 100644 --- a/cmd/explaintest/t/explain_easy_stats.test +++ b/cmd/explaintest/t/explain_easy_stats.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2, t3; create table t1 (c1 int primary key, c2 int, c3 int, index c2 (c2)); diff --git a/cmd/explaintest/t/explain_foreign_key.test b/cmd/explaintest/t/explain_foreign_key.test new file mode 100644 index 0000000000000..ec222d020a5ab --- /dev/null +++ b/cmd/explaintest/t/explain_foreign_key.test @@ -0,0 +1,45 @@ +set @@foreign_key_checks=1; +use test; +drop table if exists t1,t2; +create table t1 (id int key); +create table t2 (id int key, foreign key fk(id) references t1(id) ON UPDATE CASCADE ON DELETE CASCADE); +create table t3 (id int, unique index idx(id)); +create table t4 (id int, index idx_id(id),foreign key fk(id) references t3(id)); +create table t5 (id int key, id2 int, id3 int, unique index idx2(id2), index idx3(id3)); +create table t6 (id int, id2 int, id3 int, index idx_id(id), index idx_id2(id2), foreign key fk_1 (id) references t5(id) ON UPDATE CASCADE ON DELETE CASCADE, foreign key fk_2 (id2) references t5(id2) ON UPDATE CASCADE, foreign key fk_3 (id3) references t5(id3) ON DELETE CASCADE); + +explain format = 'brief' insert into t2 values (1); +explain format = 'brief' update t2 set id=id+1 where id = 1; +explain format = 'brief' delete from t1 where id > 1; +explain format = 'brief' update t1 set id=id+1 where id = 1; +explain format = 'brief' insert into t1 values (1); +explain format = 'brief' insert into t1 values (1) on duplicate key update id = 100; +explain format = 'brief' insert into t4 values (1); +explain format = 'brief' update t4 set id=id+1 where id = 1; +explain format = 'brief' delete from t3 where id > 1; +explain format = 'brief' update t3 set id=id+1 where id = 1; +explain format = 'brief' insert into t3 values (1); +explain format = 'brief' insert into t3 values (1) on duplicate key update id = 100; +explain format = 'brief' insert into t6 values (1,1,1); +explain format = 'brief' update t6 set id=id+1, id3=id2+1 where id = 1; +explain format = 'brief' delete from t5 where id > 1; +explain format = 'brief' update t5 set id=id+1, id2=id2+1 where id = 1; +explain format = 'brief' update t5 set id=id+1, id2=id2+1, id3=id3+1 where id = 1; +explain format = 'brief' insert into t5 values (1,1,1); +explain format = 'brief' insert into t5 values (1,1,1) on duplicate key update id = 100, id3=100; +explain format = 'brief' insert into t5 values (1,1,1) on duplicate key update id = 100, id2=100, id3=100; +drop table if exists t1,t2,t3,t4,t5,t6; + +drop table if exists t_1,t_2,t_3,t_4; +create table t_1 (id int key); +create table t_2 (id int key); +create table t_3 (id int key, id2 int, foreign key fk_1(id) references t_1(id), foreign key fk_2(id2) references t_1(id), foreign key fk_3(id) references t_2(id) ON UPDATE CASCADE ON DELETE CASCADE); +create table t_4 (id int key, id2 int, foreign key fk_1(id) references t_2(id), foreign key fk_2(id2) references t_1(id), foreign key fk_3(id) references t_1(id) ON UPDATE CASCADE ON DELETE CASCADE); + +explain format = 'brief' update t_1,t_2 set t_1.id=2,t_2.id=2 where t_1.id=t_2.id and t_1.id=1; +explain format = 'brief' delete t_1,t_2 from t_1 join t_2 where t_1.id=t_2.id and t_1.id > 0; +set @@foreign_key_checks=0; +explain format = 'brief' update t_1,t_2 set t_1.id=2,t_2.id=2 where t_1.id=t_2.id and t_1.id=1; +explain format = 'brief' delete t_1,t_2 from t_1 join t_2 where t_1.id=t_2.id and t_1.id > 0; +drop table if exists t_1,t_2,t_3,t_4; +set @@foreign_key_checks=0; diff --git a/cmd/explaintest/t/explain_generate_column_substitute.test b/cmd/explaintest/t/explain_generate_column_substitute.test index 527e404c9d17b..13ccab9fe42c6 100644 --- a/cmd/explaintest/t/explain_generate_column_substitute.test +++ b/cmd/explaintest/t/explain_generate_column_substitute.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set names utf8mb4; use test; drop table if exists t; diff --git a/cmd/explaintest/t/explain_indexmerge.test b/cmd/explaintest/t/explain_indexmerge.test index c58602f81a40b..be9d21c63e4bd 100644 --- a/cmd/explaintest/t/explain_indexmerge.test +++ b/cmd/explaintest/t/explain_indexmerge.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; create table t (a int primary key, b int, c int, d int, e int, f int); create index tb on t (b); diff --git a/cmd/explaintest/t/explain_join_stats.test b/cmd/explaintest/t/explain_join_stats.test index 39092af0cbfe3..52de049e6374c 100644 --- a/cmd/explaintest/t/explain_join_stats.test +++ b/cmd/explaintest/t/explain_join_stats.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists e, lo; create table e(a int, b int, key idx_a(a), key idx_b(b)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; diff --git a/cmd/explaintest/t/explain_shard_index.test b/cmd/explaintest/t/explain_shard_index.test index 4264ecfa47796..04e2bc8302746 100644 --- a/cmd/explaintest/t/explain_shard_index.test +++ b/cmd/explaintest/t/explain_shard_index.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists test3, test5; create table test3(id int primary key clustered, a int, b int, unique key uk_expr((tidb_shard(a)),a)); diff --git a/cmd/explaintest/t/explain_stats.test b/cmd/explaintest/t/explain_stats.test index e45d36bb36def..413b47e3dae39 100644 --- a/cmd/explaintest/t/explain_stats.test +++ b/cmd/explaintest/t/explain_stats.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t; create table t (id int, c1 timestamp); load stats 's/explain_stats_t.json'; diff --git a/cmd/explaintest/t/explain_union_scan.test b/cmd/explaintest/t/explain_union_scan.test index 6e904ad3c7a89..f85cd7132e833 100644 --- a/cmd/explaintest/t/explain_union_scan.test +++ b/cmd/explaintest/t/explain_union_scan.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists city; CREATE TABLE `city` ( diff --git a/cmd/explaintest/t/generated_columns.test b/cmd/explaintest/t/generated_columns.test index 48570e8ccbffb..3616a23be455c 100644 --- a/cmd/explaintest/t/generated_columns.test +++ b/cmd/explaintest/t/generated_columns.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; -- Tests of using stored generated column as index and partition column. -- Most of the cases are ported from other tests to make sure generated columns behaves the same. diff --git a/cmd/explaintest/t/imdbload.test b/cmd/explaintest/t/imdbload.test index df73903e0bb93..49b527dea5f4e 100644 --- a/cmd/explaintest/t/imdbload.test +++ b/cmd/explaintest/t/imdbload.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE DATABASE IF NOT EXISTS `imdbload`; USE `imdbload`; -- The table schema is converted from imdb dataset using IMDbPY diff --git a/cmd/explaintest/t/index_join.test b/cmd/explaintest/t/index_join.test index f766b1e899e29..c185d2b90ba72 100644 --- a/cmd/explaintest/t/index_join.test +++ b/cmd/explaintest/t/index_join.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t1, t2; create table t1(a bigint, b bigint, index idx(a)); diff --git a/cmd/explaintest/t/index_merge.test b/cmd/explaintest/t/index_merge.test index e89af1b613c27..07b552e2c823d 100644 --- a/cmd/explaintest/t/index_merge.test +++ b/cmd/explaintest/t/index_merge.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; --echo ///// SUBQUERY drop table if exists t1; create table t1(c1 int, c2 int, c3 int, key(c1), key(c2)); diff --git a/cmd/explaintest/t/naaj.test b/cmd/explaintest/t/naaj.test index eedada4c29202..69e1a4a3e7f6c 100644 --- a/cmd/explaintest/t/naaj.test +++ b/cmd/explaintest/t/naaj.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; # naaj.test file is for null-aware anti join use test; set @@session.tidb_enable_null_aware_anti_join=1; diff --git a/cmd/explaintest/t/new_character_set.test b/cmd/explaintest/t/new_character_set.test index 7de21592b89de..c466a66dfd178 100644 --- a/cmd/explaintest/t/new_character_set.test +++ b/cmd/explaintest/t/new_character_set.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; -- @@character_set_results = 'gbk', TiDB transforms row value into GBK charset. drop table if exists t; set names utf8mb4; diff --git a/cmd/explaintest/t/new_character_set_builtin.test b/cmd/explaintest/t/new_character_set_builtin.test index 93f160832ce01..8b16ebd53f50e 100644 --- a/cmd/explaintest/t/new_character_set_builtin.test +++ b/cmd/explaintest/t/new_character_set_builtin.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set names utf8mb4; set @@sql_mode = ''; -- test for builtin function hex(), length(), ascii(), octet_length() diff --git a/cmd/explaintest/t/new_character_set_invalid.test b/cmd/explaintest/t/new_character_set_invalid.test index 369f72362cfc7..58df2d0499f9e 100644 --- a/cmd/explaintest/t/new_character_set_invalid.test +++ b/cmd/explaintest/t/new_character_set_invalid.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set @@sql_mode = 'strict_trans_tables'; drop table if exists t; create table t (a varchar(255) charset gbk, b varchar(255) charset ascii, c varchar(255) charset utf8); diff --git a/cmd/explaintest/t/select.test b/cmd/explaintest/t/select.test index 907066ffff4f4..bf3e729c87225 100644 --- a/cmd/explaintest/t/select.test +++ b/cmd/explaintest/t/select.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; set @@tidb_enable_outer_join_reorder=true; DROP TABLE IF EXISTS t; diff --git a/cmd/explaintest/t/show.test b/cmd/explaintest/t/show.test index b90131d18f861..3727c1604a6f7 100644 --- a/cmd/explaintest/t/show.test +++ b/cmd/explaintest/t/show.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; # test show output field name show tables like '%xx'; show databases like '%xx'; diff --git a/cmd/explaintest/t/subquery.test b/cmd/explaintest/t/subquery.test index 5127c0e4260fa..b759cfbe52507 100644 --- a/cmd/explaintest/t/subquery.test +++ b/cmd/explaintest/t/subquery.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; drop table if exists t1; drop table if exists t2; create table t1(a bigint, b bigint); diff --git a/cmd/explaintest/t/topn_push_down.test b/cmd/explaintest/t/topn_push_down.test index baec87a061c00..3a44bbec8fb6b 100644 --- a/cmd/explaintest/t/topn_push_down.test +++ b/cmd/explaintest/t/topn_push_down.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; CREATE TABLE `tr` ( `id` bigint(20) NOT NULL, `biz_date` date NOT NULL, diff --git a/cmd/explaintest/t/topn_pushdown.test b/cmd/explaintest/t/topn_pushdown.test index 590c409c47d75..7089159adb1bd 100644 --- a/cmd/explaintest/t/topn_pushdown.test +++ b/cmd/explaintest/t/topn_pushdown.test @@ -1 +1,2 @@ +set tidb_cost_model_version=1; explain format = 'brief' select * from ((select 4 as a) union all (select 33 as a)) tmp order by a desc limit 1; diff --git a/cmd/explaintest/t/tpch.test b/cmd/explaintest/t/tpch.test index 4b195ac6c7373..fbf20e25637f4 100644 --- a/cmd/explaintest/t/tpch.test +++ b/cmd/explaintest/t/tpch.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; -- http://www.tpc.org/tpc_documents_current_versions/pdf/tpc-h_v2.17.1.pdf CREATE DATABASE IF NOT EXISTS TPCH; USE TPCH; @@ -30,17 +31,14 @@ CREATE TABLE IF NOT EXISTS supplier ( S_SUPPKEY INTEGER NOT NULL, S_PHONE CHAR(15) NOT NULL, S_ACCTBAL DECIMAL(15,2) NOT NULL, S_COMMENT VARCHAR(101) NOT NULL, - PRIMARY KEY (S_SUPPKEY), - CONSTRAINT FOREIGN KEY SUPPLIER_FK1 (S_NATIONKEY) references nation(N_NATIONKEY)); + PRIMARY KEY (S_SUPPKEY)); CREATE TABLE IF NOT EXISTS partsupp ( PS_PARTKEY INTEGER NOT NULL, PS_SUPPKEY INTEGER NOT NULL, PS_AVAILQTY INTEGER NOT NULL, PS_SUPPLYCOST DECIMAL(15,2) NOT NULL, PS_COMMENT VARCHAR(199) NOT NULL, - PRIMARY KEY (PS_PARTKEY,PS_SUPPKEY), - CONSTRAINT FOREIGN KEY PARTSUPP_FK1 (PS_SUPPKEY) references supplier(S_SUPPKEY), - CONSTRAINT FOREIGN KEY PARTSUPP_FK2 (PS_PARTKEY) references part(P_PARTKEY)); + PRIMARY KEY (PS_PARTKEY,PS_SUPPKEY)); CREATE TABLE IF NOT EXISTS customer ( C_CUSTKEY INTEGER NOT NULL, C_NAME VARCHAR(25) NOT NULL, @@ -50,8 +48,7 @@ CREATE TABLE IF NOT EXISTS customer ( C_CUSTKEY INTEGER NOT NULL, C_ACCTBAL DECIMAL(15,2) NOT NULL, C_MKTSEGMENT CHAR(10) NOT NULL, C_COMMENT VARCHAR(117) NOT NULL, - PRIMARY KEY (C_CUSTKEY), - CONSTRAINT FOREIGN KEY CUSTOMER_FK1 (C_NATIONKEY) references nation(N_NATIONKEY)); + PRIMARY KEY (C_CUSTKEY)); CREATE TABLE IF NOT EXISTS orders ( O_ORDERKEY INTEGER NOT NULL, O_CUSTKEY INTEGER NOT NULL, @@ -62,8 +59,7 @@ CREATE TABLE IF NOT EXISTS orders ( O_ORDERKEY INTEGER NOT NULL, O_CLERK CHAR(15) NOT NULL, O_SHIPPRIORITY INTEGER NOT NULL, O_COMMENT VARCHAR(79) NOT NULL, - PRIMARY KEY (O_ORDERKEY), - CONSTRAINT FOREIGN KEY ORDERS_FK1 (O_CUSTKEY) references customer(C_CUSTKEY)); + PRIMARY KEY (O_ORDERKEY)); CREATE TABLE IF NOT EXISTS lineitem ( L_ORDERKEY INTEGER NOT NULL, L_PARTKEY INTEGER NOT NULL, @@ -81,9 +77,7 @@ CREATE TABLE IF NOT EXISTS lineitem ( L_ORDERKEY INTEGER NOT NULL, L_SHIPINSTRUCT CHAR(25) NOT NULL, L_SHIPMODE CHAR(10) NOT NULL, L_COMMENT VARCHAR(44) NOT NULL, - PRIMARY KEY (L_ORDERKEY,L_LINENUMBER), - CONSTRAINT FOREIGN KEY LINEITEM_FK1 (L_ORDERKEY) references orders(O_ORDERKEY), - CONSTRAINT FOREIGN KEY LINEITEM_FK2 (L_PARTKEY,L_SUPPKEY) references partsupp(PS_PARTKEY, PS_SUPPKEY)); + PRIMARY KEY (L_ORDERKEY,L_LINENUMBER)); -- load stats. load stats 's/tpch_stats/nation.json'; load stats 's/tpch_stats/region.json'; diff --git a/cmd/explaintest/t/vitess_hash.test b/cmd/explaintest/t/vitess_hash.test index 6fd221a44019d..791eb7ccc9f6a 100644 --- a/cmd/explaintest/t/vitess_hash.test +++ b/cmd/explaintest/t/vitess_hash.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t( diff --git a/cmd/explaintest/t/window_function.test b/cmd/explaintest/t/window_function.test index 5bd5951653f73..4640bb8e1ebbe 100644 --- a/cmd/explaintest/t/window_function.test +++ b/cmd/explaintest/t/window_function.test @@ -1,3 +1,4 @@ +set tidb_cost_model_version=1; use test; drop table if exists t; create table t (a int, b int, c timestamp, index idx(a)); diff --git a/cmd/importer/db.go b/cmd/importer/db.go index 8b0d7353b9adf..b8ecf83abfc4b 100644 --- a/cmd/importer/db.go +++ b/cmd/importer/db.go @@ -22,7 +22,7 @@ import ( "strconv" "strings" - _ "github.com/go-sql-driver/mysql" + mysql2 "github.com/go-sql-driver/mysql" "github.com/pingcap/errors" "github.com/pingcap/log" "github.com/pingcap/tidb/parser/mysql" @@ -318,13 +318,18 @@ func execSQL(db *sql.DB, sql string) error { } func createDB(cfg DBConfig) (*sql.DB, error) { - dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.Name) - db, err := sql.Open("mysql", dbDSN) + driverCfg := mysql2.NewConfig() + driverCfg.User = cfg.User + driverCfg.Passwd = cfg.Password + driverCfg.Net = "tcp" + driverCfg.Addr = cfg.Host + ":" + strconv.Itoa(cfg.Port) + driverCfg.DBName = cfg.Name + + c, err := mysql2.NewConnector(driverCfg) if err != nil { return nil, errors.Trace(err) } - - return db, nil + return sql.OpenDB(c), nil } func closeDB(db *sql.DB) error { diff --git a/cmd/pluginpkg/pluginpkg b/cmd/pluginpkg/pluginpkg new file mode 100755 index 0000000000000..9da90a4758831 Binary files /dev/null and b/cmd/pluginpkg/pluginpkg differ diff --git a/config/config.go b/config/config.go index 78fa8417a72bc..9030c4ac388f8 100644 --- a/config/config.go +++ b/config/config.go @@ -46,10 +46,13 @@ import ( // Config number limitations const ( MaxLogFileSize = 4096 // MB + // MaxTxnEntrySize is the max value of TxnEntrySizeLimit. + MaxTxnEntrySizeLimit = 120 * 1024 * 1024 // 120MB // DefTxnEntrySizeLimit is the default value of TxnEntrySizeLimit. DefTxnEntrySizeLimit = 6 * 1024 * 1024 // DefTxnTotalSizeLimit is the default value of TxnTxnTotalSizeLimit. - DefTxnTotalSizeLimit = 100 * 1024 * 1024 + DefTxnTotalSizeLimit = 100 * 1024 * 1024 + SuperLargeTxnSize uint64 = 100 * 1024 * 1024 * 1024 * 1024 // 100T, we expect a txn can never be this large // DefMaxIndexLength is the maximum index length(in bytes). This value is consistent with MySQL. DefMaxIndexLength = 3072 // DefMaxOfMaxIndexLength is the maximum index length(in bytes) for TiDB v3.0.7 and previous version. @@ -86,6 +89,10 @@ const ( DefMemoryUsageAlarmRatio = 0.8 // DefTempDir is the default temporary directory path for TiDB. DefTempDir = "/tmp/tidb" + // DefAuthTokenRefreshInterval is the default time interval to refresh tidb auth token. + DefAuthTokenRefreshInterval = time.Hour + // EnvVarKeyspaceName is the system env name for keyspace name. + EnvVarKeyspaceName = "KEYSPACE_NAME" ) // Valid config maps @@ -180,6 +187,7 @@ type Config struct { VersionComment string `toml:"version-comment" json:"version-comment"` TiDBEdition string `toml:"tidb-edition" json:"tidb-edition"` TiDBReleaseVersion string `toml:"tidb-release-version" json:"tidb-release-version"` + KeyspaceName string `toml:"keyspace-name" json:"keyspace-name"` Log Log `toml:"log" json:"log"` Instance Instance `toml:"instance" json:"instance"` Security Security `toml:"security" json:"security"` @@ -258,6 +266,9 @@ type Config struct { // EnableGlobalKill indicates whether to enable global kill. TrxSummary TrxSummary `toml:"transaction-summary" json:"transaction-summary"` EnableGlobalKill bool `toml:"enable-global-kill" json:"enable-global-kill"` + // InitializeSQLFile is a file that will be executed after first bootstrap only. + // It can be used to set GLOBAL system variable values + InitializeSQLFile string `toml:"initialize-sql-file" json:"initialize-sql-file"` // The following items are deprecated. We need to keep them here temporarily // to support the upgrade process. They can be removed in future. @@ -276,6 +287,13 @@ type Config struct { Plugin Plugin `toml:"plugin" json:"plugin"` MaxServerConnections uint32 `toml:"max-server-connections" json:"max-server-connections"` RunDDL bool `toml:"run-ddl" json:"run-ddl"` + DisaggregatedTiFlash bool `toml:"disaggregated-tiflash" json:"disaggregated-tiflash"` + // TiDBMaxReuseChunk indicates max cached chunk num + TiDBMaxReuseChunk uint32 `toml:"tidb-max-reuse-chunk" json:"tidb-max-reuse-chunk"` + // TiDBMaxReuseColumn indicates max cached column num + TiDBMaxReuseColumn uint32 `toml:"tidb-max-reuse-column" json:"tidb-max-reuse-column"` + // TiDBEnableExitCheck indicates whether exit-checking in domain for background process + TiDBEnableExitCheck bool `toml:"tidb-enable-exit-check" json:"tidb-enable-exit-check"` } // UpdateTempStoragePath is to update the `TempStoragePath` if port/statusPort was changed @@ -534,6 +552,9 @@ type Security struct { ClusterSSLCert string `toml:"cluster-ssl-cert" json:"cluster-ssl-cert"` ClusterSSLKey string `toml:"cluster-ssl-key" json:"cluster-ssl-key"` ClusterVerifyCN []string `toml:"cluster-verify-cn" json:"cluster-verify-cn"` + // Used for auth plugin `tidb_session_token`. + SessionTokenSigningCert string `toml:"session-token-signing-cert" json:"session-token-signing-cert"` + SessionTokenSigningKey string `toml:"session-token-signing-key" json:"session-token-signing-key"` // If set to "plaintext", the spilled files will not be encrypted. SpilledFileEncryptionMethod string `toml:"spilled-file-encryption-method" json:"spilled-file-encryption-method"` // EnableSEM prevents SUPER users from having full access. @@ -543,6 +564,12 @@ type Security struct { MinTLSVersion string `toml:"tls-version" json:"tls-version"` RSAKeySize int `toml:"rsa-key-size" json:"rsa-key-size"` SecureBootstrap bool `toml:"secure-bootstrap" json:"secure-bootstrap"` + // The path of the JWKS for tidb_auth_token authentication + AuthTokenJWKS string `toml:"auth-token-jwks" json:"auth-token-jwks"` + // The refresh time interval of JWKS + AuthTokenRefreshInterval string `toml:"auth-token-refresh-interval" json:"auth-token-refresh-interval"` + // Disconnect directly when the password is expired + DisconnectOnExpiredPassword bool `toml:"disconnect-on-expired-password" json:"disconnect-on-expired-password"` } // The ErrConfigValidationFailed error is used so that external callers can do a type assertion @@ -640,14 +667,17 @@ type Performance struct { ProjectionPushDown bool `toml:"projection-push-down" json:"projection-push-down"` MaxTxnTTL uint64 `toml:"max-txn-ttl" json:"max-txn-ttl"` // Deprecated - MemProfileInterval string `toml:"-" json:"-"` - IndexUsageSyncLease string `toml:"index-usage-sync-lease" json:"index-usage-sync-lease"` - PlanReplayerGCLease string `toml:"plan-replayer-gc-lease" json:"plan-replayer-gc-lease"` - GOGC int `toml:"gogc" json:"gogc"` - EnforceMPP bool `toml:"enforce-mpp" json:"enforce-mpp"` - StatsLoadConcurrency uint `toml:"stats-load-concurrency" json:"stats-load-concurrency"` - StatsLoadQueueSize uint `toml:"stats-load-queue-size" json:"stats-load-queue-size"` - EnableStatsCacheMemQuota bool `toml:"enable-stats-cache-mem-quota" json:"enable-stats-cache-mem-quota"` + MemProfileInterval string `toml:"-" json:"-"` + + IndexUsageSyncLease string `toml:"index-usage-sync-lease" json:"index-usage-sync-lease"` + PlanReplayerGCLease string `toml:"plan-replayer-gc-lease" json:"plan-replayer-gc-lease"` + GOGC int `toml:"gogc" json:"gogc"` + EnforceMPP bool `toml:"enforce-mpp" json:"enforce-mpp"` + StatsLoadConcurrency uint `toml:"stats-load-concurrency" json:"stats-load-concurrency"` + StatsLoadQueueSize uint `toml:"stats-load-queue-size" json:"stats-load-queue-size"` + AnalyzePartitionConcurrencyQuota uint `toml:"analyze-partition-concurrency-quota" json:"analyze-partition-concurrency-quota"` + PlanReplayerDumpWorkerConcurrency uint `toml:"plan-replayer-dump-worker-concurrency" json:"plan-replayer-dump-worker-concurrency"` + EnableStatsCacheMemQuota bool `toml:"enable-stats-cache-mem-quota" json:"enable-stats-cache-mem-quota"` // The following items are deprecated. We need to keep them here temporarily // to support the upgrade process. They can be removed in future. @@ -736,6 +766,8 @@ type PessimisticTxn struct { DeadlockHistoryCollectRetryable bool `toml:"deadlock-history-collect-retryable" json:"deadlock-history-collect-retryable"` // PessimisticAutoCommit represents if true it means the auto-commit transactions will be in pessimistic mode. PessimisticAutoCommit AtomicBool `toml:"pessimistic-auto-commit" json:"pessimistic-auto-commit"` + // ConstraintCheckInPlacePessimistic is the default value for the session variable `tidb_constraint_check_in_place_pessimistic` + ConstraintCheckInPlacePessimistic bool `toml:"constraint-check-in-place-pessimistic" json:"constraint-check-in-place-pessimistic"` } // TrxSummary is the config for transaction summary collecting. @@ -757,10 +789,11 @@ func (config *TrxSummary) Valid() error { // DefaultPessimisticTxn returns the default configuration for PessimisticTxn func DefaultPessimisticTxn() PessimisticTxn { return PessimisticTxn{ - MaxRetryCount: 256, - DeadlockHistoryCapacity: 10, - DeadlockHistoryCollectRetryable: false, - PessimisticAutoCommit: *NewAtomicBool(false), + MaxRetryCount: 256, + DeadlockHistoryCapacity: 10, + DeadlockHistoryCollectRetryable: false, + PessimisticAutoCommit: *NewAtomicBool(false), + ConstraintCheckInPlacePessimistic: true, } } @@ -902,15 +935,17 @@ var defaultConf = Config{ CommitterConcurrency: defTiKVCfg.CommitterConcurrency, MaxTxnTTL: defTiKVCfg.MaxTxnTTL, // 1hour // TODO: set indexUsageSyncLease to 60s. - IndexUsageSyncLease: "0s", - GOGC: 100, - EnforceMPP: false, - PlanReplayerGCLease: "10m", - StatsLoadConcurrency: 5, - StatsLoadQueueSize: 1000, - EnableStatsCacheMemQuota: false, - RunAutoAnalyze: true, - EnableLoadFMSketch: false, + IndexUsageSyncLease: "0s", + GOGC: 100, + EnforceMPP: false, + PlanReplayerGCLease: "10m", + StatsLoadConcurrency: 5, + StatsLoadQueueSize: 1000, + AnalyzePartitionConcurrencyQuota: 16, + PlanReplayerDumpWorkerConcurrency: 1, + EnableStatsCacheMemQuota: false, + RunAutoAnalyze: true, + EnableLoadFMSketch: false, }, ProxyProtocol: ProxyProtocol{ Networks: "", @@ -953,6 +988,9 @@ var defaultConf = Config{ EnableSEM: false, AutoTLS: false, RSAKeySize: 4096, + AuthTokenJWKS: "", + AuthTokenRefreshInterval: DefAuthTokenRefreshInterval.String(), + DisconnectOnExpiredPassword: true, }, DeprecateIntegerDisplayWidth: false, EnableEnumLengthLimit: true, @@ -961,6 +999,10 @@ var defaultConf = Config{ NewCollationsEnabledOnFirstBootstrap: true, EnableGlobalKill: true, TrxSummary: DefaultTrxSummary(), + DisaggregatedTiFlash: false, + TiDBMaxReuseChunk: 64, + TiDBMaxReuseColumn: 256, + TiDBEnableExitCheck: false, } var ( @@ -1020,7 +1062,7 @@ var removedConfig = map[string]struct{}{ "log.query-log-max-len": {}, "performance.committer-concurrency": {}, "experimental.enable-global-kill": {}, - "performance.run-auto-analyze": {}, //use tidb_enable_auto_analyze + "performance.run-auto-analyze": {}, // use tidb_enable_auto_analyze // use tidb_enable_prepared_plan_cache, tidb_prepared_plan_cache_size and tidb_prepared_plan_cache_memory_guard_ratio "prepared-plan-cache.enabled": {}, "prepared-plan-cache.capacity": {}, @@ -1423,3 +1465,9 @@ func ContainHiddenConfig(s string) bool { } return false } + +// GetGlobalKeyspaceName is used to get global keyspace name +// from config file or command line. +func GetGlobalKeyspaceName() string { + return GetGlobalConfig().KeyspaceName +} diff --git a/config/config_test.go b/config/config_test.go index 50e3227de049c..4bd0911661e11 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -730,6 +730,8 @@ enable-enum-length-limit = false stores-refresh-interval = 30 enable-forwarding = true enable-global-kill = true +tidb-max-reuse-chunk = 10 +tidb-max-reuse-column = 20 [performance] txn-total-size-limit=2000 tcp-no-delay = false @@ -798,6 +800,8 @@ max_connections = 200 require.True(t, conf.RepairMode) require.Equal(t, uint64(16), conf.TiKVClient.ResolveLockLiteThreshold) require.Equal(t, uint32(200), conf.Instance.MaxConnections) + require.Equal(t, uint32(10), conf.TiDBMaxReuseChunk) + require.Equal(t, uint32(20), conf.TiDBMaxReuseColumn) require.Equal(t, []string{"tiflash"}, conf.IsolationRead.Engines) require.Equal(t, 3080, conf.MaxIndexLength) require.Equal(t, 70, conf.IndexLimit) @@ -1284,3 +1288,18 @@ func TestStatsLoadLimit(t *testing.T) { checkQueueSizeValid(DefMaxOfStatsLoadQueueSizeLimit, true) checkQueueSizeValid(DefMaxOfStatsLoadQueueSizeLimit+1, false) } + +func TestGetGlobalKeyspaceName(t *testing.T) { + conf := NewConfig() + require.Empty(t, conf.KeyspaceName) + + UpdateGlobal(func(conf *Config) { + conf.KeyspaceName = "test" + }) + + require.Equal(t, "test", GetGlobalKeyspaceName()) + + UpdateGlobal(func(conf *Config) { + conf.KeyspaceName = "" + }) +} diff --git a/config/main_test.go b/config/main_test.go index 363fd39d78304..3458dc358ad86 100644 --- a/config/main_test.go +++ b/config/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/ddl/BUILD.bazel b/ddl/BUILD.bazel index 3ccb33749d004..b3ba9639cb7f0 100644 --- a/ddl/BUILD.bazel +++ b/ddl/BUILD.bazel @@ -27,6 +27,7 @@ go_library( "foreign_key.go", "generated_column.go", "index.go", + "index_cop.go", "index_merge_tmp.go", "job_table.go", "mock.go", @@ -35,6 +36,7 @@ go_library( "partition.go", "placement_policy.go", "reorg.go", + "resource_group.go", "rollingback.go", "sanity_check.go", "schema.go", @@ -44,17 +46,20 @@ go_library( "stat.go", "table.go", "table_lock.go", + "ttl.go", ], importpath = "github.com/pingcap/tidb/ddl", visibility = [ ":ddl_friend", ], deps = [ + "//br/pkg/lightning/common", "//br/pkg/utils", "//config", "//ddl/ingest", "//ddl/label", "//ddl/placement", + "//ddl/resourcegroup", "//ddl/syncer", "//ddl/util", "//distsql", @@ -75,6 +80,7 @@ go_library( "//parser/opcode", "//parser/terror", "//parser/types", + "//privilege", "//sessionctx", "//sessionctx/binloginfo", "//sessionctx/stmtctx", @@ -99,6 +105,7 @@ go_library( "//util/domainutil", "//util/filter", "//util/gcutil", + "//util/generic", "//util/hack", "//util/logutil", "//util/mathutil", @@ -117,6 +124,7 @@ go_library( "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_kvproto//pkg/errorpb", "@com_github_pingcap_kvproto//pkg/kvrpcpb", "@com_github_pingcap_kvproto//pkg/metapb", "@com_github_pingcap_log//:log", @@ -140,6 +148,7 @@ go_test( timeout = "moderate", srcs = [ "attributes_sql_test.go", + "backfilling_test.go", "callback_test.go", "cancel_test.go", "cluster_test.go", @@ -160,13 +169,13 @@ go_test( "ddl_api_test.go", "ddl_error_test.go", "ddl_test.go", - "ddl_tiflash_test.go", "ddl_worker_test.go", "ddl_workerpool_test.go", "export_test.go", "fail_test.go", "foreign_key_test.go", "index_change_test.go", + "index_cop_test.go", "index_merge_tmp_test.go", "index_modify_test.go", "integration_test.go", @@ -174,6 +183,7 @@ go_test( "main_test.go", "modify_column_test.go", "multi_schema_change_test.go", + "mv_index_test.go", "options_test.go", "partition_test.go", "placement_policy_ddl_test.go", @@ -181,6 +191,7 @@ go_test( "placement_sql_test.go", "primary_key_handle_test.go", "repair_table_test.go", + "resource_group_test.go", "restart_test.go", "rollingback_test.go", "schema_test.go", @@ -191,14 +202,17 @@ go_test( "table_split_test.go", "table_test.go", "tiflash_replica_test.go", + "ttl_test.go", ], embed = [":ddl"], flaky = True, shard_count = 50, deps = [ + "//autoid_service", "//config", "//ddl/ingest", "//ddl/placement", + "//ddl/resourcegroup", "//ddl/schematracker", "//ddl/testutil", "//ddl/util", @@ -219,6 +233,7 @@ go_test( "//parser/terror", "//parser/types", "//planner/core", + "//server", "//session", "//sessionctx", "//sessionctx/stmtctx", @@ -227,7 +242,6 @@ go_test( "//store/gcworker", "//store/helper", "//store/mockstore", - "//store/mockstore/unistore", "//table", "//table/tables", "//tablecodec", @@ -243,20 +257,21 @@ go_test( "//util/domainutil", "//util/gcutil", "//util/logutil", + "//util/mathutil", "//util/mock", "//util/sem", "//util/sqlexec", "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", - "@com_github_pingcap_kvproto//pkg/metapb", "@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//require", "@com_github_tikv_client_go_v2//oracle", "@com_github_tikv_client_go_v2//testutils", "@com_github_tikv_client_go_v2//tikv", + "@com_github_tikv_client_go_v2//util", "@io_etcd_go_etcd_client_v3//:client", - "@io_etcd_go_etcd_tests_v3//integration", + "@org_golang_google_grpc//:grpc", "@org_golang_x_exp//slices", "@org_uber_go_atomic//:atomic", "@org_uber_go_goleak//:goleak", diff --git a/ddl/attributes_sql_test.go b/ddl/attributes_sql_test.go index de00a63a7a661..95f881e6fb3fe 100644 --- a/ddl/attributes_sql_test.go +++ b/ddl/attributes_sql_test.go @@ -28,6 +28,7 @@ import ( "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/util/gcutil" "github.com/stretchr/testify/require" + tikvutil "github.com/tikv/client-go/v2/util" ) // MockGC is used to make GC work in the test environment. @@ -44,9 +45,8 @@ func MockGC(tk *testkit.TestKit) (string, string, string, func()) { // disable emulator GC. // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. util.EmulatorGCDisable() - gcTimeFormat := "20060102-15:04:05 -0700 MST" - timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(gcTimeFormat) - timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(gcTimeFormat) + timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(tikvutil.GCTimeFormat) + timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(tikvutil.GCTimeFormat) safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') ON DUPLICATE KEY UPDATE variable_value = '%[1]s'` diff --git a/ddl/backfilling.go b/ddl/backfilling.go index 0736cbb58215f..51d156ebf91e3 100644 --- a/ddl/backfilling.go +++ b/ddl/backfilling.go @@ -15,7 +15,6 @@ package ddl import ( - "bytes" "context" "encoding/hex" "fmt" @@ -32,6 +31,7 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" @@ -39,35 +39,118 @@ import ( "github.com/pingcap/tidb/store/driver/backoff" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/tablecodec" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mathutil" decoder "github.com/pingcap/tidb/util/rowDecoder" "github.com/pingcap/tidb/util/timeutil" "github.com/pingcap/tidb/util/topsql" + "github.com/tikv/client-go/v2/oracle" "github.com/tikv/client-go/v2/tikv" "go.uber.org/zap" ) -type backfillWorkerType byte +type backfillerType byte const ( - typeAddIndexWorker backfillWorkerType = 0 - typeUpdateColumnWorker backfillWorkerType = 1 - typeCleanUpIndexWorker backfillWorkerType = 2 - typeAddIndexMergeTmpWorker backfillWorkerType = 3 + typeAddIndexWorker backfillerType = 0 + typeUpdateColumnWorker backfillerType = 1 + typeCleanUpIndexWorker backfillerType = 2 + typeAddIndexMergeTmpWorker backfillerType = 3 + typeReorgPartitionWorker backfillerType = 4 + + // InstanceLease is the instance lease. + InstanceLease = 1 * time.Minute + updateInstanceLease = 25 * time.Second + genTaskBatch = 4096 + minGenTaskBatch = 1024 + minDistTaskCnt = 16 + retrySQLTimes = 3 + retrySQLInterval = 500 * time.Millisecond ) +func (bT backfillerType) String() string { + switch bT { + case typeAddIndexWorker: + return "add index" + case typeUpdateColumnWorker: + return "update column" + case typeCleanUpIndexWorker: + return "clean up index" + case typeAddIndexMergeTmpWorker: + return "merge temporary index" + case typeReorgPartitionWorker: + return "reorganize partition" + default: + return "unknown" + } +} + +// BackfillJob is for a tidb_ddl_backfill table's record. +type BackfillJob struct { + ID int64 + JobID int64 + EleID int64 + EleKey []byte + Tp backfillerType + State model.JobState + StoreID int64 + InstanceID string + InstanceLease types.Time + // range info + CurrKey []byte + StartKey []byte + EndKey []byte + + StartTS uint64 + FinishTS uint64 + RowCount int64 + Meta *model.BackfillMeta +} + +// AbbrStr returns the BackfillJob's info without the Meta info. +func (bj *BackfillJob) AbbrStr() string { + return fmt.Sprintf("ID:%d, JobID:%d, EleID:%d, Type:%s, State:%s, InstanceID:%s, InstanceLease:%s", + bj.ID, bj.JobID, bj.EleID, bj.Tp, bj.State, bj.InstanceID, bj.InstanceLease) +} + +// GetOracleTimeWithStartTS returns the current time with txn's startTS. +func GetOracleTimeWithStartTS(se *session) (time.Time, error) { + txn, err := se.Txn(true) + if err != nil { + return time.Time{}, err + } + return oracle.GetTimeFromTS(txn.StartTS()).UTC(), nil +} + +// GetOracleTime returns the current time from TS. +func GetOracleTime(store kv.Storage) (time.Time, error) { + currentVer, err := store.CurrentVersion(kv.GlobalTxnScope) + if err != nil { + return time.Time{}, errors.Trace(err) + } + return oracle.GetTimeFromTS(currentVer.Ver).UTC(), nil +} + +// GetLeaseGoTime returns a types.Time by adding a lease. +func GetLeaseGoTime(currTime time.Time, lease time.Duration) types.Time { + leaseTime := currTime.Add(lease) + return types.NewTime(types.FromGoTime(leaseTime.In(time.UTC)), mysql.TypeTimestamp, types.MaxFsp) +} + // By now the DDL jobs that need backfilling include: // 1: add-index // 2: modify-column-type // 3: clean-up global index +// 4: reorganize partition // // They all have a write reorganization state to back fill data into the rows existed. // Backfilling is time consuming, to accelerate this process, TiDB has built some sub // workers to do this in the DDL owner node. // -// DDL owner thread +// DDL owner thread (also see comments before runReorgJob func) // ^ // | (reorgCtx.doneCh) // | @@ -110,27 +193,39 @@ const ( // Instead, it is divided into batches, each time a kv transaction completes the backfilling // of a partial batch. -func (bWT backfillWorkerType) String() string { - switch bWT { - case typeAddIndexWorker: - return "add index" - case typeUpdateColumnWorker: - return "update column" - case typeCleanUpIndexWorker: - return "clean up index" - case typeAddIndexMergeTmpWorker: - return "merge temporary index" - default: - return "unknown" +type backfillCtx struct { + *ddlCtx + reorgTp model.ReorgType + sessCtx sessionctx.Context + schemaName string + table table.Table + batchCnt int +} + +func newBackfillCtx(ctx *ddlCtx, sessCtx sessionctx.Context, reorgTp model.ReorgType, + schemaName string, tbl table.Table) *backfillCtx { + return &backfillCtx{ + ddlCtx: ctx, + sessCtx: sessCtx, + reorgTp: reorgTp, + schemaName: schemaName, + table: tbl, + batchCnt: int(variable.GetDDLReorgBatchSize()), } } type backfiller interface { BackfillDataInTxn(handleRange reorgBackfillTask) (taskCtx backfillTaskContext, errInTxn error) AddMetricInfo(float64) + GetTask() (*BackfillJob, error) + UpdateTask(bfJob *BackfillJob) error + FinishTask(bfJob *BackfillJob) error + GetCtx() *backfillCtx + String() string } type backfillResult struct { + taskID int addedCount int scanCount int nextKey kv.Key @@ -149,17 +244,40 @@ type backfillTaskContext struct { } type reorgBackfillTask struct { + bfJob *BackfillJob + physicalTable table.PhysicalTable + + // TODO: Remove the following fields after remove the function of run. + id int physicalTableID int64 startKey kv.Key endKey kv.Key endInclude bool + jobID int64 + sqlQuery string + priority int +} + +func (r *reorgBackfillTask) getJobID() int64 { + jobID := r.jobID + if r.bfJob != nil { + jobID = r.bfJob.JobID + } + return jobID +} + +func (r *reorgBackfillTask) excludedEndKey() kv.Key { + if r.endInclude { + return r.endKey.Next() + } + return r.endKey } func (r *reorgBackfillTask) String() string { physicalID := strconv.FormatInt(r.physicalTableID, 10) - startKey := tryDecodeToHandleString(r.startKey) - endKey := tryDecodeToHandleString(r.endKey) - rangeStr := "physicalTableID_" + physicalID + "_" + "[" + startKey + "," + endKey + startKey := hex.EncodeToString(r.startKey) + endKey := hex.EncodeToString(r.endKey) + rangeStr := "taskID_" + strconv.Itoa(r.id) + "_physicalTableID_" + physicalID + "_" + "[" + startKey + "," + endKey if r.endInclude { return rangeStr + "]" } @@ -174,37 +292,53 @@ func mergeBackfillCtxToResult(taskCtx *backfillTaskContext, result *backfillResu } type backfillWorker struct { - id int - reorgInfo *reorgInfo - batchCnt int - sessCtx sessionctx.Context - taskCh chan *reorgBackfillTask - resultCh chan *backfillResult - table table.Table - closed bool - priority int - tp backfillWorkerType -} - -func newBackfillWorker(sessCtx sessionctx.Context, id int, t table.PhysicalTable, - reorgInfo *reorgInfo, tp backfillWorkerType) *backfillWorker { + id int + backfiller + taskCh chan *reorgBackfillTask + resultCh chan *backfillResult + ctx context.Context + cancel func() +} + +func newBackfillWorker(ctx context.Context, id int, bf backfiller) *backfillWorker { + bfCtx, cancel := context.WithCancel(ctx) return &backfillWorker{ - id: id, - table: t, - reorgInfo: reorgInfo, - batchCnt: int(variable.GetDDLReorgBatchSize()), - sessCtx: sessCtx, - taskCh: make(chan *reorgBackfillTask, 1), - resultCh: make(chan *backfillResult, 1), - priority: reorgInfo.Job.Priority, - tp: tp, + backfiller: bf, + id: id, + taskCh: make(chan *reorgBackfillTask, 1), + resultCh: make(chan *backfillResult, 1), + ctx: bfCtx, + cancel: cancel, } } +func (w *backfillWorker) updateLease(execID string, bfJob *BackfillJob, nextKey kv.Key) error { + leaseTime, err := GetOracleTime(w.GetCtx().store) + if err != nil { + return err + } + bfJob.CurrKey = nextKey + bfJob.InstanceID = execID + bfJob.InstanceLease = GetLeaseGoTime(leaseTime, InstanceLease) + return w.backfiller.UpdateTask(bfJob) +} + +func (w *backfillWorker) finishJob(bfJob *BackfillJob) error { + bfJob.State = model.JobStateDone + return w.backfiller.FinishTask(bfJob) +} + +func (w *backfillWorker) String() string { + if w.backfiller == nil { + return fmt.Sprintf("worker %d", w.id) + } + return fmt.Sprintf("worker %d, tp %s", w.id, w.backfiller.String()) +} + func (w *backfillWorker) Close() { - if !w.closed { - w.closed = true - close(w.taskCh) + if w.cancel != nil { + w.cancel() + w.cancel = nil } } @@ -214,25 +348,31 @@ func closeBackfillWorkers(workers []*backfillWorker) { } } +// ResultCounterForTest is used for test. +var ResultCounterForTest *atomic.Int32 + // handleBackfillTask backfills range [task.startHandle, task.endHandle) handle's index to table. func (w *backfillWorker) handleBackfillTask(d *ddlCtx, task *reorgBackfillTask, bf backfiller) *backfillResult { handleRange := *task result := &backfillResult{ + taskID: task.id, err: nil, addedCount: 0, nextKey: handleRange.startKey, } + batchStartTime := time.Now() lastLogCount := 0 lastLogTime := time.Now() startTime := lastLogTime - rc := d.getReorgCtx(w.reorgInfo.Job) + jobID := task.getJobID() + rc := d.getReorgCtx(jobID) for { // Give job chance to be canceled, if we not check it here, // if there is panic in bf.BackfillDataInTxn we will never cancel the job. // Because reorgRecordTask may run a long time, // we should check whether this ddl job is still runnable. - err := d.isReorgRunnable(w.reorgInfo.Job) + err := d.isReorgRunnable(jobID) if err != nil { result.err = err return result @@ -258,13 +398,11 @@ func (w *backfillWorker) handleBackfillTask(d *ddlCtx, task *reorgBackfillTask, rc.increaseRowCount(int64(taskCtx.addedCount)) rc.mergeWarnings(taskCtx.warnings, taskCtx.warningsCount) - if num := result.scanCount - lastLogCount; num >= 30000 { + if num := result.scanCount - lastLogCount; num >= 90000 { lastLogCount = result.scanCount logutil.BgLogger().Info("[ddl] backfill worker back fill index", - zap.Int("workerID", w.id), - zap.Int("addedCount", result.addedCount), - zap.Int("scanCount", result.scanCount), - zap.String("nextHandle", tryDecodeToHandleString(taskCtx.nextKey)), + zap.Int("addedCount", result.addedCount), zap.Int("scanCount", result.scanCount), + zap.String("next key", hex.EncodeToString(taskCtx.nextKey)), zap.Float64("speed(rows/s)", float64(num)/time.Since(lastLogTime).Seconds())) lastLogTime = time.Now() } @@ -273,37 +411,59 @@ func (w *backfillWorker) handleBackfillTask(d *ddlCtx, task *reorgBackfillTask, if taskCtx.done { break } + + if task.bfJob != nil { + // TODO: Adjust the updating lease frequency by batch processing time carefully. + if time.Since(batchStartTime) < updateInstanceLease { + continue + } + batchStartTime = time.Now() + if err := w.updateLease(w.GetCtx().uuid, task.bfJob, result.nextKey); err != nil { + logutil.BgLogger().Info("[ddl] backfill worker handle task, update lease failed", zap.Stringer("worker", w), + zap.Stringer("task", task), zap.String("backfill job", task.bfJob.AbbrStr()), zap.Error(err)) + result.err = err + return result + } + } } logutil.BgLogger().Info("[ddl] backfill worker finish task", - zap.Stringer("type", w.tp), - zap.Int("workerID", w.id), - zap.String("task", task.String()), - zap.Int("addedCount", result.addedCount), - zap.Int("scanCount", result.scanCount), - zap.String("nextHandle", tryDecodeToHandleString(result.nextKey)), - zap.String("takeTime", time.Since(startTime).String())) + zap.Stringer("worker", w), + zap.Stringer("task", task), + zap.Int("added count", result.addedCount), + zap.Int("scan count", result.scanCount), + zap.String("next key", hex.EncodeToString(result.nextKey)), + zap.String("take time", time.Since(startTime).String())) + if ResultCounterForTest != nil && result.err == nil { + ResultCounterForTest.Add(1) + } return result } func (w *backfillWorker) run(d *ddlCtx, bf backfiller, job *model.Job) { - logutil.BgLogger().Info("[ddl] backfill worker start", - zap.Stringer("type", w.tp), - zap.Int("workerID", w.id)) - defer func() { - w.resultCh <- &backfillResult{err: dbterror.ErrReorgPanic} - }() - defer util.Recover(metrics.LabelDDL, "backfillWorker.run", nil, false) + logutil.BgLogger().Info("[ddl] backfill worker start", zap.Stringer("worker", w)) + var curTaskID int + defer util.Recover(metrics.LabelDDL, "backfillWorker.run", func() { + w.resultCh <- &backfillResult{taskID: curTaskID, err: dbterror.ErrReorgPanic} + }, false) for { + if util.HasCancelled(w.ctx) { + logutil.BgLogger().Info("[ddl] backfill worker exit on context done", + zap.Stringer("worker", w), zap.Int("workerID", w.id)) + return + } task, more := <-w.taskCh if !more { - break + logutil.BgLogger().Info("[ddl] backfill worker exit", + zap.Stringer("worker", w), zap.Int("workerID", w.id)) + return } - d.setDDLLabelForTopSQL(job) + curTaskID = task.id + d.setDDLLabelForTopSQL(job.ID, job.Query) logutil.BgLogger().Debug("[ddl] backfill worker got task", zap.Int("workerID", w.id), zap.String("task", task.String())) failpoint.Inject("mockBackfillRunErr", func() { if w.id == 0 { - result := &backfillResult{addedCount: 0, nextKey: nil, err: errors.Errorf("mock backfill error")} + result := &backfillResult{taskID: task.id, addedCount: 0, nextKey: nil, err: errors.Errorf("mock backfill error")} w.resultCh <- result failpoint.Continue() } @@ -318,14 +478,16 @@ func (w *backfillWorker) run(d *ddlCtx, bf backfiller, job *model.Job) { time.Sleep(100 * time.Millisecond) }) - // Dynamic change batch size. - w.batchCnt = int(variable.GetDDLReorgBatchSize()) + // Change the batch size dynamically. + w.GetCtx().batchCnt = int(variable.GetDDLReorgBatchSize()) result := w.handleBackfillTask(d, task, bf) w.resultCh <- result + if result.err != nil { + logutil.BgLogger().Info("[ddl] backfill worker exit on error", + zap.Stringer("worker", w), zap.Int("workerID", w.id), zap.Error(result.err)) + return + } } - logutil.BgLogger().Info("[ddl] backfill worker exit", - zap.Stringer("type", w.tp), - zap.Int("workerID", w.id)) } // splitTableRanges uses PD region's key ranges to split the backfilling table key range space, @@ -334,8 +496,8 @@ func (w *backfillWorker) run(d *ddlCtx, bf backfiller, job *model.Job) { func splitTableRanges(t table.PhysicalTable, store kv.Storage, startKey, endKey kv.Key) ([]kv.KeyRange, error) { logutil.BgLogger().Info("[ddl] split table range from PD", zap.Int64("physicalTableID", t.GetPhysicalID()), - zap.String("startHandle", tryDecodeToHandleString(startKey)), - zap.String("endHandle", tryDecodeToHandleString(endKey))) + zap.String("start key", hex.EncodeToString(startKey)), + zap.String("end key", hex.EncodeToString(endKey))) kvRange := kv.KeyRange{StartKey: startKey, EndKey: endKey} s, ok := store.(tikv.Storage) if !ok { @@ -357,119 +519,113 @@ func splitTableRanges(t table.PhysicalTable, store kv.Storage, startKey, endKey return ranges, nil } -func waitTaskResults(workers []*backfillWorker, taskCnt int, - totalAddedCount *int64, startKey kv.Key) (kv.Key, int64, error) { +func waitTaskResults(scheduler *backfillScheduler, batchTasks []*reorgBackfillTask, + totalAddedCount *int64) (kv.Key, int64, error) { var ( - addedCount int64 - nextKey = startKey firstErr error + addedCount int64 ) - for i := 0; i < taskCnt; i++ { - worker := workers[i] - result := <-worker.resultCh - if firstErr == nil && result.err != nil { - firstErr = result.err - // We should wait all working workers exits, any way. - continue - } - + keeper := newDoneTaskKeeper(batchTasks[0].startKey) + taskSize := len(batchTasks) + for i := 0; i < taskSize; i++ { + result := <-scheduler.resultCh if result.err != nil { - logutil.BgLogger().Warn("[ddl] backfill worker failed", zap.Int("workerID", worker.id), + if firstErr == nil { + firstErr = result.err + } + logutil.BgLogger().Warn("[ddl] backfill worker failed", + zap.String("result next key", hex.EncodeToString(result.nextKey)), zap.Error(result.err)) + // Drain tasks. + cnt := drainTasks(scheduler.taskCh) + // We need to wait all the tasks to finish before closing it + // to prevent send on closed channel error. + taskSize -= cnt + continue } - - if firstErr == nil { - *totalAddedCount += int64(result.addedCount) - addedCount += int64(result.addedCount) - nextKey = result.nextKey + *totalAddedCount += int64(result.addedCount) + addedCount += int64(result.addedCount) + keeper.updateNextKey(result.taskID, result.nextKey) + if i%scheduler.workerSize()*4 == 0 { + // We try to adjust the worker size regularly to reduce + // the overhead of loading the DDL related global variables. + err := scheduler.adjustWorkerSize() + if err != nil { + logutil.BgLogger().Warn("[ddl] cannot adjust backfill worker size", zap.Error(err)) + } } } + return keeper.nextKey, addedCount, errors.Trace(firstErr) +} - return nextKey, addedCount, errors.Trace(firstErr) +func drainTasks(taskCh chan *reorgBackfillTask) int { + cnt := 0 + for len(taskCh) > 0 { + <-taskCh + cnt++ + } + return cnt } // sendTasksAndWait sends tasks to workers, and waits for all the running workers to return results, // there are taskCnt running workers. -func (dc *ddlCtx) sendTasksAndWait(sessPool *sessionPool, reorgInfo *reorgInfo, totalAddedCount *int64, workers []*backfillWorker, batchTasks []*reorgBackfillTask) error { - for i, task := range batchTasks { - workers[i].taskCh <- task +func (dc *ddlCtx) sendTasksAndWait(scheduler *backfillScheduler, totalAddedCount *int64, + batchTasks []*reorgBackfillTask) error { + reorgInfo := scheduler.reorgInfo + for _, task := range batchTasks { + if scheduler.copReqSenderPool != nil { + scheduler.copReqSenderPool.sendTask(task) + } + scheduler.taskCh <- task } startKey := batchTasks[0].startKey - taskCnt := len(batchTasks) startTime := time.Now() - nextKey, taskAddedCount, err := waitTaskResults(workers, taskCnt, totalAddedCount, startKey) + nextKey, taskAddedCount, err := waitTaskResults(scheduler, batchTasks, totalAddedCount) elapsedTime := time.Since(startTime) if err == nil { - err = dc.isReorgRunnable(reorgInfo.Job) + err = dc.isReorgRunnable(reorgInfo.Job.ID) } + // Update the reorg handle that has been processed. + err1 := reorgInfo.UpdateReorgMeta(nextKey, scheduler.sessPool) + if err != nil { - // Update the reorg handle that has been processed. - err1 := reorgInfo.UpdateReorgMeta(nextKey, sessPool) metrics.BatchAddIdxHistogram.WithLabelValues(metrics.LblError).Observe(elapsedTime.Seconds()) logutil.BgLogger().Warn("[ddl] backfill worker handle batch tasks failed", - zap.Stringer("type", workers[0].tp), - zap.ByteString("elementType", reorgInfo.currElement.TypeKey), - zap.Int64("elementID", reorgInfo.currElement.ID), - zap.Int64("totalAddedCount", *totalAddedCount), - zap.String("startHandle", tryDecodeToHandleString(startKey)), - zap.String("nextHandle", tryDecodeToHandleString(nextKey)), - zap.Int64("batchAddedCount", taskAddedCount), - zap.String("taskFailedError", err.Error()), - zap.String("takeTime", elapsedTime.String()), + + zap.Int64("total added count", *totalAddedCount), + zap.String("start key", hex.EncodeToString(startKey)), + zap.String("next key", hex.EncodeToString(nextKey)), + zap.Int64("batch added count", taskAddedCount), + zap.String("task failed error", err.Error()), + zap.String("take time", elapsedTime.String()), zap.NamedError("updateHandleError", err1)) + failpoint.Inject("MockGetIndexRecordErr", func() { + // Make sure this job didn't failed because by the "Write conflict" error. + if dbterror.ErrNotOwner.Equal(err) { + time.Sleep(50 * time.Millisecond) + } + }) return errors.Trace(err) } - // nextHandle will be updated periodically in runReorgJob, so no need to update it here. - dc.getReorgCtx(reorgInfo.Job).setNextKey(nextKey) + dc.getReorgCtx(reorgInfo.Job.ID).setNextKey(nextKey) metrics.BatchAddIdxHistogram.WithLabelValues(metrics.LblOK).Observe(elapsedTime.Seconds()) logutil.BgLogger().Info("[ddl] backfill workers successfully processed batch", - zap.Stringer("type", workers[0].tp), - zap.ByteString("elementType", reorgInfo.currElement.TypeKey), - zap.Int64("elementID", reorgInfo.currElement.ID), - zap.Int64("totalAddedCount", *totalAddedCount), - zap.String("startHandle", tryDecodeToHandleString(startKey)), - zap.String("nextHandle", tryDecodeToHandleString(nextKey)), - zap.Int64("batchAddedCount", taskAddedCount), - zap.String("takeTime", elapsedTime.String())) + zap.Stringer("element", reorgInfo.currElement), + zap.Int64("total added count", *totalAddedCount), + zap.String("start key", hex.EncodeToString(startKey)), + zap.String("next key", hex.EncodeToString(nextKey)), + zap.Int64("batch added count", taskAddedCount), + zap.String("take time", elapsedTime.String()), + zap.NamedError("updateHandleError", err1)) return nil } -func tryDecodeToHandleString(key kv.Key) string { - defer func() { - if r := recover(); r != nil { - logutil.BgLogger().Warn("tryDecodeToHandleString panic", - zap.Any("recover()", r), - zap.Binary("key", key)) - } - }() - handle, err := tablecodec.DecodeRowKey(key) - if err != nil { - recordPrefixIdx := bytes.Index(key, []byte("_r")) - if recordPrefixIdx == -1 { - return fmt.Sprintf("key: %x", key) - } - handleBytes := key[recordPrefixIdx+2:] - terminatedWithZero := len(handleBytes) > 0 && handleBytes[len(handleBytes)-1] == 0 - if terminatedWithZero { - handle, err := tablecodec.DecodeRowKey(key[:len(key)-1]) - if err == nil { - return handle.String() + ".next" - } - } - return fmt.Sprintf("%x", handleBytes) - } - return handle.String() -} - -// handleRangeTasks sends tasks to workers, and returns remaining kvRanges that is not handled. -func (dc *ddlCtx) handleRangeTasks(sessPool *sessionPool, t table.Table, workers []*backfillWorker, reorgInfo *reorgInfo, - totalAddedCount *int64, kvRanges []kv.KeyRange) ([]kv.KeyRange, error) { - batchTasks := make([]*reorgBackfillTask, 0, len(workers)) +func getBatchTasks(t table.PhysicalTable, reorgInfo *reorgInfo, kvRanges []kv.KeyRange, batch int) []*reorgBackfillTask { + batchTasks := make([]*reorgBackfillTask, 0, batch) physicalTableID := reorgInfo.PhysicalTableID - var prefix kv.Key if reorgInfo.mergingTmpIdx { prefix = t.IndexPrefix() @@ -477,36 +633,55 @@ func (dc *ddlCtx) handleRangeTasks(sessPool *sessionPool, t table.Table, workers prefix = t.RecordPrefix() } // Build reorg tasks. + job := reorgInfo.Job + jobCtx := reorgInfo.d.jobContext(reorgInfo.Job.ID) for i, keyRange := range kvRanges { + startKey := keyRange.StartKey endKey := keyRange.EndKey - endK, err := getRangeEndKey(reorgInfo.d.jobContext(reorgInfo.Job), workers[0].sessCtx.GetStore(), workers[0].priority, prefix, keyRange.StartKey, endKey) + endK, err := getRangeEndKey(jobCtx, reorgInfo.d.store, job.Priority, prefix, keyRange.StartKey, endKey) if err != nil { - logutil.BgLogger().Info("[ddl] send range task to workers, get reverse key failed", zap.Error(err)) + logutil.BgLogger().Info("[ddl] get backfill range task, get reverse key failed", zap.Error(err)) } else { - logutil.BgLogger().Info("[ddl] send range task to workers, change end key", + logutil.BgLogger().Info("[ddl] get backfill range task, change end key", zap.String("end key", hex.EncodeToString(endKey)), zap.String("current end key", hex.EncodeToString(endK))) endKey = endK } + if len(startKey) == 0 { + startKey = prefix + } + if len(endKey) == 0 { + endKey = prefix.PrefixNext() + } task := &reorgBackfillTask{ + id: i, + jobID: reorgInfo.Job.ID, physicalTableID: physicalTableID, - startKey: keyRange.StartKey, + physicalTable: t, + priority: reorgInfo.Priority, + startKey: startKey, endKey: endKey, // If the boundaries overlap, we should ignore the preceding endKey. endInclude: endK.Cmp(keyRange.EndKey) != 0 || i == len(kvRanges)-1} batchTasks = append(batchTasks, task) - if len(batchTasks) >= len(workers) { + if len(batchTasks) >= batch { break } } + return batchTasks +} +// handleRangeTasks sends tasks to workers, and returns remaining kvRanges that is not handled. +func (dc *ddlCtx) handleRangeTasks(scheduler *backfillScheduler, t table.PhysicalTable, + totalAddedCount *int64, kvRanges []kv.KeyRange) ([]kv.KeyRange, error) { + batchTasks := getBatchTasks(t, scheduler.reorgInfo, kvRanges, backfillTaskChanSize) if len(batchTasks) == 0 { return nil, nil } // Wait tasks finish. - err := dc.sendTasksAndWait(sessPool, reorgInfo, totalAddedCount, workers, batchTasks) + err := dc.sendTasksAndWait(scheduler, totalAddedCount, batchTasks) if err != nil { return nil, errors.Trace(err) } @@ -524,7 +699,7 @@ var ( // TestCheckWorkerNumCh use for test adjust backfill worker. TestCheckWorkerNumCh = make(chan *sync.WaitGroup) // TestCheckWorkerNumber use for test adjust backfill worker. - TestCheckWorkerNumber = int32(16) + TestCheckWorkerNumber = int32(1) // TestCheckReorgTimeout is used to mock timeout when reorg data. TestCheckReorgTimeout = int32(0) ) @@ -539,8 +714,7 @@ func loadDDLReorgVars(ctx context.Context, sessPool *sessionPool) error { return ddlutil.LoadDDLReorgVars(ctx, sCtx) } -func makeupDecodeColMap(sessCtx sessionctx.Context, t table.Table) (map[int64]decoder.Column, error) { - dbName := model.NewCIStr(sessCtx.GetSessionVars().CurrentDB) +func makeupDecodeColMap(sessCtx sessionctx.Context, dbName model.CIStr, t table.Table) (map[int64]decoder.Column, error) { writableColInfos := make([]*model.ColumnInfo, 0, len(t.WritableCols())) for _, col := range t.WritableCols() { writableColInfos = append(writableColInfos, col.ColumnInfo) @@ -569,6 +743,198 @@ func setSessCtxLocation(sctx sessionctx.Context, info *reorgInfo) error { return nil } +type backfillScheduler struct { + ctx context.Context + reorgInfo *reorgInfo + sessPool *sessionPool + tp backfillerType + tbl table.PhysicalTable + decodeColMap map[int64]decoder.Column + jobCtx *JobContext + + workers []*backfillWorker + maxSize int + + taskCh chan *reorgBackfillTask + resultCh chan *backfillResult + + copReqSenderPool *copReqSenderPool // for add index in ingest way. +} + +const backfillTaskChanSize = 1024 + +func newBackfillScheduler(ctx context.Context, info *reorgInfo, sessPool *sessionPool, + tp backfillerType, tbl table.PhysicalTable, decColMap map[int64]decoder.Column, + jobCtx *JobContext) *backfillScheduler { + return &backfillScheduler{ + ctx: ctx, + reorgInfo: info, + sessPool: sessPool, + tp: tp, + tbl: tbl, + decodeColMap: decColMap, + jobCtx: jobCtx, + workers: make([]*backfillWorker, 0, variable.GetDDLReorgWorkerCounter()), + taskCh: make(chan *reorgBackfillTask, backfillTaskChanSize), + resultCh: make(chan *backfillResult, backfillTaskChanSize), + } +} + +func (b *backfillScheduler) newSessCtx() (sessionctx.Context, error) { + reorgInfo := b.reorgInfo + sessCtx := newContext(reorgInfo.d.store) + sessCtx.GetSessionVars().StmtCtx.IsDDLJobInQueue = true + // Set the row encode format version. + rowFormat := variable.GetDDLReorgRowFormat() + sessCtx.GetSessionVars().RowEncoder.Enable = rowFormat != variable.DefTiDBRowFormatV1 + // Simulate the sql mode environment in the worker sessionCtx. + sqlMode := reorgInfo.ReorgMeta.SQLMode + sessCtx.GetSessionVars().SQLMode = sqlMode + if err := setSessCtxLocation(sessCtx, reorgInfo); err != nil { + return nil, errors.Trace(err) + } + sessCtx.GetSessionVars().StmtCtx.BadNullAsWarning = !sqlMode.HasStrictMode() + sessCtx.GetSessionVars().StmtCtx.TruncateAsWarning = !sqlMode.HasStrictMode() + sessCtx.GetSessionVars().StmtCtx.OverflowAsWarning = !sqlMode.HasStrictMode() + sessCtx.GetSessionVars().StmtCtx.AllowInvalidDate = sqlMode.HasAllowInvalidDatesMode() + sessCtx.GetSessionVars().StmtCtx.DividedByZeroAsWarning = !sqlMode.HasStrictMode() + sessCtx.GetSessionVars().StmtCtx.IgnoreZeroInDate = !sqlMode.HasStrictMode() || sqlMode.HasAllowInvalidDatesMode() + sessCtx.GetSessionVars().StmtCtx.NoZeroDate = sqlMode.HasStrictMode() + return sessCtx, nil +} + +func (b *backfillScheduler) setMaxWorkerSize(maxSize int) { + b.maxSize = maxSize +} + +func (b *backfillScheduler) workerSize() int { + return len(b.workers) +} + +func (b *backfillScheduler) adjustWorkerSize() error { + b.initCopReqSenderPool() + reorgInfo := b.reorgInfo + job := reorgInfo.Job + jc := b.jobCtx + if err := loadDDLReorgVars(b.ctx, b.sessPool); err != nil { + logutil.BgLogger().Error("[ddl] load DDL reorganization variable failed", zap.Error(err)) + } + workerCnt := int(variable.GetDDLReorgWorkerCounter()) + if b.copReqSenderPool != nil { + workerCnt = mathutil.Min(workerCnt/2+1, b.maxSize) + } else { + workerCnt = mathutil.Min(workerCnt, b.maxSize) + } + // Increase the worker. + for i := len(b.workers); i < workerCnt; i++ { + sessCtx, err := b.newSessCtx() + if err != nil { + return err + } + var ( + runner *backfillWorker + worker backfiller + ) + switch b.tp { + case typeAddIndexWorker: + backfillCtx := newBackfillCtx(reorgInfo.d, sessCtx, reorgInfo.ReorgMeta.ReorgTp, job.SchemaName, b.tbl) + idxWorker, err := newAddIndexWorker(b.decodeColMap, i, b.tbl, backfillCtx, + jc, job.ID, reorgInfo.currElement.ID, reorgInfo.currElement.TypeKey) + if err != nil { + if b.canSkipError(err) { + continue + } + return err + } + idxWorker.copReqSenderPool = b.copReqSenderPool + runner = newBackfillWorker(jc.ddlJobCtx, i, idxWorker) + worker = idxWorker + case typeAddIndexMergeTmpWorker: + backfillCtx := newBackfillCtx(reorgInfo.d, sessCtx, reorgInfo.ReorgMeta.ReorgTp, job.SchemaName, b.tbl) + tmpIdxWorker := newMergeTempIndexWorker(backfillCtx, i, b.tbl, reorgInfo.currElement.ID, jc) + runner = newBackfillWorker(jc.ddlJobCtx, i, tmpIdxWorker) + worker = tmpIdxWorker + case typeUpdateColumnWorker: + // Setting InCreateOrAlterStmt tells the difference between SELECT casting and ALTER COLUMN casting. + sessCtx.GetSessionVars().StmtCtx.InCreateOrAlterStmt = true + updateWorker := newUpdateColumnWorker(sessCtx, b.tbl, b.decodeColMap, reorgInfo, jc) + runner = newBackfillWorker(jc.ddlJobCtx, i, updateWorker) + worker = updateWorker + case typeCleanUpIndexWorker: + idxWorker := newCleanUpIndexWorker(sessCtx, b.tbl, b.decodeColMap, reorgInfo, jc) + runner = newBackfillWorker(jc.ddlJobCtx, i, idxWorker) + worker = idxWorker + case typeReorgPartitionWorker: + partWorker, err := newReorgPartitionWorker(sessCtx, b.tbl, b.decodeColMap, reorgInfo, jc) + if err != nil { + return err + } + runner = newBackfillWorker(jc.ddlJobCtx, i, partWorker) + worker = partWorker + default: + return errors.New("unknown backfill type") + } + runner.taskCh = b.taskCh + runner.resultCh = b.resultCh + b.workers = append(b.workers, runner) + go runner.run(reorgInfo.d, worker, job) + } + // Decrease the worker. + if len(b.workers) > workerCnt { + workers := b.workers[workerCnt:] + b.workers = b.workers[:workerCnt] + closeBackfillWorkers(workers) + } + if b.copReqSenderPool != nil { + b.copReqSenderPool.adjustSize(len(b.workers)) + } + return injectCheckBackfillWorkerNum(len(b.workers), b.tp == typeAddIndexMergeTmpWorker) +} + +func (b *backfillScheduler) initCopReqSenderPool() { + if b.tp != typeAddIndexWorker || b.reorgInfo.Job.ReorgMeta.ReorgTp != model.ReorgTypeLitMerge || + b.copReqSenderPool != nil || len(b.workers) > 0 { + return + } + indexInfo := model.FindIndexInfoByID(b.tbl.Meta().Indices, b.reorgInfo.currElement.ID) + if indexInfo == nil { + logutil.BgLogger().Warn("[ddl-ingest] cannot init cop request sender", + zap.Int64("table ID", b.tbl.Meta().ID), zap.Int64("index ID", b.reorgInfo.currElement.ID)) + return + } + sessCtx, err := b.newSessCtx() + if err != nil { + logutil.BgLogger().Warn("[ddl-ingest] cannot init cop request sender", zap.Error(err)) + return + } + copCtx, err := newCopContext(b.tbl.Meta(), indexInfo, sessCtx) + if err != nil { + logutil.BgLogger().Warn("[ddl-ingest] cannot init cop request sender", zap.Error(err)) + return + } + b.copReqSenderPool = newCopReqSenderPool(b.ctx, copCtx, sessCtx.GetStore()) +} + +func (b *backfillScheduler) canSkipError(err error) bool { + if len(b.workers) > 0 { + // The error can be skipped because the rest workers can handle the tasks. + return true + } + logutil.BgLogger().Warn("[ddl] create add index backfill worker failed", + zap.Int("current worker count", len(b.workers)), + zap.Int64("job ID", b.reorgInfo.ID), zap.Error(err)) + return false +} + +func (b *backfillScheduler) Close() { + if b.copReqSenderPool != nil { + b.copReqSenderPool.close() + } + closeBackfillWorkers(b.workers) + close(b.taskCh) + close(b.resultCh) +} + // writePhysicalTableRecord handles the "add index" or "modify/change column" reorganization state for a non-partitioned table or a partition. // For a partitioned table, it should be handled partition by partition. // @@ -584,18 +950,18 @@ func setSessCtxLocation(sctx sessionctx.Context, info *reorgInfo) error { // // The above operations are completed in a transaction. // Finally, update the concurrent processing of the total number of rows, and store the completed handle value. -func (dc *ddlCtx) writePhysicalTableRecord(sessPool *sessionPool, t table.PhysicalTable, bfWorkerType backfillWorkerType, reorgInfo *reorgInfo) error { +func (dc *ddlCtx) writePhysicalTableRecord(sessPool *sessionPool, t table.PhysicalTable, bfWorkerType backfillerType, reorgInfo *reorgInfo) error { job := reorgInfo.Job totalAddedCount := job.GetRowCount() startKey, endKey := reorgInfo.StartKey, reorgInfo.EndKey sessCtx := newContext(reorgInfo.d.store) - decodeColMap, err := makeupDecodeColMap(sessCtx, t) + decodeColMap, err := makeupDecodeColMap(sessCtx, reorgInfo.dbInfo.Name, t) if err != nil { return errors.Trace(err) } - if err := dc.isReorgRunnable(reorgInfo.Job); err != nil { + if err := dc.isReorgRunnable(reorgInfo.Job.ID); err != nil { return errors.Trace(err) } if startKey == nil && endKey == nil { @@ -609,133 +975,396 @@ func (dc *ddlCtx) writePhysicalTableRecord(sessPool *sessionPool, t table.Physic } }) - // variable.ddlReorgWorkerCounter can be modified by system variable "tidb_ddl_reorg_worker_cnt". - workerCnt := variable.GetDDLReorgWorkerCounter() - backfillWorkers := make([]*backfillWorker, 0, workerCnt) - defer func() { - closeBackfillWorkers(backfillWorkers) - }() - jc := dc.jobContext(job) + jc := dc.jobContext(job.ID) + scheduler := newBackfillScheduler(dc.ctx, reorgInfo, sessPool, bfWorkerType, t, decodeColMap, jc) + defer scheduler.Close() + + var ingestBeCtx *ingest.BackendContext + if bfWorkerType == typeAddIndexWorker && job.ReorgMeta.ReorgTp == model.ReorgTypeLitMerge { + if bc, ok := ingest.LitBackCtxMgr.Load(job.ID); ok { + ingestBeCtx = bc + } else { + return errors.New(ingest.LitErrGetBackendFail) + } + } for { kvRanges, err := splitTableRanges(t, reorgInfo.d.store, startKey, endKey) if err != nil { return errors.Trace(err) } + scheduler.setMaxWorkerSize(len(kvRanges)) - // For dynamic adjust backfill worker number. - if err := loadDDLReorgVars(dc.ctx, sessPool); err != nil { - logutil.BgLogger().Error("[ddl] load DDL reorganization variable failed", zap.Error(err)) - } - workerCnt = variable.GetDDLReorgWorkerCounter() - rowFormat := variable.GetDDLReorgRowFormat() - // If only have 1 range, we can only start 1 worker. - if len(kvRanges) < int(workerCnt) { - workerCnt = int32(len(kvRanges)) - } - // Enlarge the worker size. - for i := len(backfillWorkers); i < int(workerCnt); i++ { - sessCtx := newContext(reorgInfo.d.store) - sessCtx.GetSessionVars().StmtCtx.IsDDLJobInQueue = true - // Set the row encode format version. - sessCtx.GetSessionVars().RowEncoder.Enable = rowFormat != variable.DefTiDBRowFormatV1 - // Simulate the sql mode environment in the worker sessionCtx. - sqlMode := reorgInfo.ReorgMeta.SQLMode - sessCtx.GetSessionVars().SQLMode = sqlMode - if err := setSessCtxLocation(sessCtx, reorgInfo); err != nil { - return errors.Trace(err) - } - - sessCtx.GetSessionVars().StmtCtx.BadNullAsWarning = !sqlMode.HasStrictMode() - sessCtx.GetSessionVars().StmtCtx.TruncateAsWarning = !sqlMode.HasStrictMode() - sessCtx.GetSessionVars().StmtCtx.OverflowAsWarning = !sqlMode.HasStrictMode() - sessCtx.GetSessionVars().StmtCtx.AllowInvalidDate = sqlMode.HasAllowInvalidDatesMode() - sessCtx.GetSessionVars().StmtCtx.DividedByZeroAsWarning = !sqlMode.HasStrictMode() - sessCtx.GetSessionVars().StmtCtx.IgnoreZeroInDate = !sqlMode.HasStrictMode() || sqlMode.HasAllowInvalidDatesMode() - sessCtx.GetSessionVars().StmtCtx.NoZeroDate = sqlMode.HasStrictMode() - - switch bfWorkerType { - case typeAddIndexWorker: - idxWorker, err := newAddIndexWorker(sessCtx, i, t, decodeColMap, reorgInfo, jc, job) - if err != nil { - return errors.Trace(err) - } - backfillWorkers = append(backfillWorkers, idxWorker.backfillWorker) - go idxWorker.backfillWorker.run(reorgInfo.d, idxWorker, job) - case typeAddIndexMergeTmpWorker: - tmpIdxWorker := newMergeTempIndexWorker(sessCtx, i, t, reorgInfo, jc) - backfillWorkers = append(backfillWorkers, tmpIdxWorker.backfillWorker) - go tmpIdxWorker.backfillWorker.run(reorgInfo.d, tmpIdxWorker, job) - case typeUpdateColumnWorker: - // Setting InCreateOrAlterStmt tells the difference between SELECT casting and ALTER COLUMN casting. - sessCtx.GetSessionVars().StmtCtx.InCreateOrAlterStmt = true - updateWorker := newUpdateColumnWorker(sessCtx, i, t, decodeColMap, reorgInfo, jc) - backfillWorkers = append(backfillWorkers, updateWorker.backfillWorker) - go updateWorker.backfillWorker.run(reorgInfo.d, updateWorker, job) - case typeCleanUpIndexWorker: - idxWorker := newCleanUpIndexWorker(sessCtx, i, t, decodeColMap, reorgInfo, jc) - backfillWorkers = append(backfillWorkers, idxWorker.backfillWorker) - go idxWorker.backfillWorker.run(reorgInfo.d, idxWorker, job) - default: - return errors.New("unknow backfill type") - } + err = scheduler.adjustWorkerSize() + if err != nil { + return errors.Trace(err) } - // Shrink the worker size. - if len(backfillWorkers) > int(workerCnt) { - workers := backfillWorkers[workerCnt:] - backfillWorkers = backfillWorkers[:workerCnt] - closeBackfillWorkers(workers) - } - - failpoint.Inject("checkBackfillWorkerNum", func(val failpoint.Value) { - //nolint:forcetypeassert - if val.(bool) { - num := int(atomic.LoadInt32(&TestCheckWorkerNumber)) - if num != 0 { - if num > len(kvRanges) { - if len(backfillWorkers) != len(kvRanges) { - failpoint.Return(errors.Errorf("check backfill worker num error, len kv ranges is: %v, check backfill worker num is: %v, actual record num is: %v", len(kvRanges), num, len(backfillWorkers))) - } - } else if num != len(backfillWorkers) { - failpoint.Return(errors.Errorf("check backfill worker num error, len kv ranges is: %v, check backfill worker num is: %v, actual record num is: %v", len(kvRanges), num, len(backfillWorkers))) - } - var wg sync.WaitGroup - wg.Add(1) - TestCheckWorkerNumCh <- &wg - wg.Wait() - } - } - }) logutil.BgLogger().Info("[ddl] start backfill workers to reorg record", zap.Stringer("type", bfWorkerType), - zap.Int("workerCnt", len(backfillWorkers)), + zap.Int("workerCnt", scheduler.workerSize()), zap.Int("regionCnt", len(kvRanges)), zap.String("startKey", hex.EncodeToString(startKey)), zap.String("endKey", hex.EncodeToString(endKey))) - if bfWorkerType == typeAddIndexWorker && job.ReorgMeta.ReorgTp == model.ReorgTypeLitMerge { - if bc, ok := ingest.LitBackCtxMgr.Load(job.ID); ok { - err := bc.Flush(reorgInfo.currElement.ID) - if err != nil { - return errors.Trace(err) + + if ingestBeCtx != nil { + err := ingestBeCtx.Flush(reorgInfo.currElement.ID) + if err != nil { + return errors.Trace(err) + } + } + remains, err := dc.handleRangeTasks(scheduler, t, &totalAddedCount, kvRanges) + if err != nil { + return errors.Trace(err) + } + + if len(remains) == 0 { + if ingestBeCtx != nil { + ingestBeCtx.EngMgr.ResetWorkers(ingestBeCtx, job.ID, reorgInfo.currElement.ID) + } + break + } + startKey = remains[0].StartKey + } + return nil +} + +func injectCheckBackfillWorkerNum(curWorkerSize int, isMergeWorker bool) error { + if isMergeWorker { + return nil + } + failpoint.Inject("checkBackfillWorkerNum", func(val failpoint.Value) { + //nolint:forcetypeassert + if val.(bool) { + num := int(atomic.LoadInt32(&TestCheckWorkerNumber)) + if num != 0 { + if num != curWorkerSize { + failpoint.Return(errors.Errorf("expected backfill worker num: %v, actual record num: %v", num, curWorkerSize)) } - } else { - return errors.New(ingest.LitErrGetBackendFail) + var wg sync.WaitGroup + wg.Add(1) + TestCheckWorkerNumCh <- &wg + wg.Wait() } } - remains, err := dc.handleRangeTasks(sessPool, t, backfillWorkers, reorgInfo, &totalAddedCount, kvRanges) + }) + return nil +} + +func addBatchBackfillJobs(sess *session, bfWorkerType backfillerType, reorgInfo *reorgInfo, notDistTask bool, + batchTasks []*reorgBackfillTask, bJobs []*BackfillJob, isUnique bool, id *int64) error { + bJobs = bJobs[:0] + instanceID := "" + if notDistTask { + instanceID = reorgInfo.d.uuid + } + // TODO: Adjust the number of ranges(region) for each task. + for _, task := range batchTasks { + bm := &model.BackfillMeta{ + PhysicalTableID: reorgInfo.PhysicalTableID, + IsUnique: isUnique, + EndInclude: task.endInclude, + ReorgTp: reorgInfo.Job.ReorgMeta.ReorgTp, + SQLMode: reorgInfo.ReorgMeta.SQLMode, + Location: reorgInfo.ReorgMeta.Location, + JobMeta: &model.JobMeta{ + SchemaID: reorgInfo.Job.SchemaID, + TableID: reorgInfo.Job.TableID, + Query: reorgInfo.Job.Query, + }, + } + bj := &BackfillJob{ + ID: *id, + JobID: reorgInfo.Job.ID, + EleID: reorgInfo.currElement.ID, + EleKey: reorgInfo.currElement.TypeKey, + Tp: bfWorkerType, + State: model.JobStateNone, + InstanceID: instanceID, + CurrKey: task.startKey, + StartKey: task.startKey, + EndKey: task.endKey, + Meta: bm, + } + *id++ + bJobs = append(bJobs, bj) + } + if err := AddBackfillJobs(sess, bJobs); err != nil { + return errors.Trace(err) + } + return nil +} + +func (*ddlCtx) splitTableToBackfillJobs(sess *session, reorgInfo *reorgInfo, pTbl table.PhysicalTable, isUnique bool, + bfWorkerType backfillerType, startKey kv.Key, currBackfillJobID int64) error { + endKey := reorgInfo.EndKey + isFirstOps := true + bJobs := make([]*BackfillJob, 0, genTaskBatch) + for { + kvRanges, err := splitTableRanges(pTbl, reorgInfo.d.store, startKey, endKey) if err != nil { return errors.Trace(err) } + batchTasks := getBatchTasks(pTbl, reorgInfo, kvRanges, genTaskBatch) + if len(batchTasks) == 0 { + break + } + notNeedDistProcess := isFirstOps && (len(kvRanges) < minDistTaskCnt) + if err = addBatchBackfillJobs(sess, bfWorkerType, reorgInfo, notNeedDistProcess, batchTasks, bJobs, isUnique, &currBackfillJobID); err != nil { + return errors.Trace(err) + } + isFirstOps = false + + remains := kvRanges[len(batchTasks):] + // TODO: After adding backfillCh do asyncNotify(dc.backfillJobCh). + logutil.BgLogger().Info("[ddl] split backfill jobs to the backfill table", + zap.Int("batchTasksCnt", len(batchTasks)), + zap.Int("totalRegionCnt", len(kvRanges)), + zap.Int("remainRegionCnt", len(remains)), + zap.String("startHandle", hex.EncodeToString(startKey)), + zap.String("endHandle", hex.EncodeToString(endKey))) if len(remains) == 0 { break } + + for { + bJobCnt, err := checkBackfillJobCount(sess, reorgInfo.Job.ID, reorgInfo.currElement.ID, reorgInfo.currElement.TypeKey) + if err != nil { + return errors.Trace(err) + } + if bJobCnt < minGenTaskBatch { + break + } + time.Sleep(retrySQLInterval) + } startKey = remains[0].StartKey } return nil } +func (dc *ddlCtx) controlWritePhysicalTableRecord(sess *session, t table.PhysicalTable, bfWorkerType backfillerType, reorgInfo *reorgInfo) error { + startKey, endKey := reorgInfo.StartKey, reorgInfo.EndKey + if startKey == nil && endKey == nil { + return nil + } + + if err := dc.isReorgRunnable(reorgInfo.Job.ID); err != nil { + return errors.Trace(err) + } + + currBackfillJobID := int64(1) + err := checkAndHandleInterruptedBackfillJobs(sess, reorgInfo.Job.ID, reorgInfo.currElement.ID, reorgInfo.currElement.TypeKey) + if err != nil { + return errors.Trace(err) + } + maxBfJob, err := GetMaxBackfillJob(sess, reorgInfo.Job.ID, reorgInfo.currElement.ID, reorgInfo.currElement.TypeKey) + if err != nil { + return errors.Trace(err) + } + if maxBfJob != nil { + startKey = maxBfJob.EndKey + currBackfillJobID = maxBfJob.ID + 1 + } + + var isUnique bool + if bfWorkerType == typeAddIndexWorker { + idxInfo := model.FindIndexInfoByID(t.Meta().Indices, reorgInfo.currElement.ID) + isUnique = idxInfo.Unique + } + err = dc.splitTableToBackfillJobs(sess, reorgInfo, t, isUnique, bfWorkerType, startKey, currBackfillJobID) + if err != nil { + return errors.Trace(err) + } + + var backfillJobFinished bool + jobID := reorgInfo.Job.ID + ticker := time.NewTicker(300 * time.Millisecond) + defer ticker.Stop() + for { + if err := dc.isReorgRunnable(reorgInfo.Job.ID); err != nil { + return errors.Trace(err) + } + + select { + case <-ticker.C: + if !backfillJobFinished { + err := checkAndHandleInterruptedBackfillJobs(sess, jobID, reorgInfo.currElement.ID, reorgInfo.currElement.TypeKey) + if err != nil { + logutil.BgLogger().Warn("[ddl] finish interrupted backfill jobs", zap.Int64("job ID", jobID), zap.Error(err)) + return errors.Trace(err) + } + + bfJob, err := getBackfillJobWithRetry(sess, BackfillTable, jobID, reorgInfo.currElement.ID, reorgInfo.currElement.TypeKey, false) + if err != nil { + logutil.BgLogger().Info("[ddl] getBackfillJobWithRetry failed", zap.Int64("job ID", jobID), zap.Error(err)) + return errors.Trace(err) + } + if bfJob == nil { + backfillJobFinished = true + logutil.BgLogger().Info("[ddl] finish backfill jobs", zap.Int64("job ID", jobID)) + } + } + if backfillJobFinished { + // TODO: Consider whether these backfill jobs are always out of sync. + isSynced, err := checkJobIsSynced(sess, jobID) + if err != nil { + logutil.BgLogger().Warn("[ddl] checkJobIsSynced failed", zap.Int64("job ID", jobID), zap.Error(err)) + return errors.Trace(err) + } + if isSynced { + logutil.BgLogger().Info("[ddl] sync backfill jobs", zap.Int64("job ID", jobID)) + return nil + } + } + case <-dc.ctx.Done(): + return dc.ctx.Err() + } + } +} + +func checkJobIsSynced(sess *session, jobID int64) (bool, error) { + var err error + var unsyncedInstanceIDs []string + for i := 0; i < retrySQLTimes; i++ { + unsyncedInstanceIDs, err = getUnsyncedInstanceIDs(sess, jobID, "check_backfill_history_job_sync") + if err == nil && len(unsyncedInstanceIDs) == 0 { + return true, nil + } + + logutil.BgLogger().Info("[ddl] checkJobIsSynced failed", + zap.Strings("unsyncedInstanceIDs", unsyncedInstanceIDs), zap.Int("tryTimes", i), zap.Error(err)) + time.Sleep(retrySQLInterval) + } + + return false, errors.Trace(err) +} + +func checkAndHandleInterruptedBackfillJobs(sess *session, jobID, currEleID int64, currEleKey []byte) (err error) { + var bJobs []*BackfillJob + for i := 0; i < retrySQLTimes; i++ { + bJobs, err = GetInterruptedBackfillJobsForOneEle(sess, jobID, currEleID, currEleKey) + if err == nil { + break + } + logutil.BgLogger().Info("[ddl] getInterruptedBackfillJobsForOneEle failed", zap.Error(err)) + time.Sleep(retrySQLInterval) + } + if err != nil { + return errors.Trace(err) + } + if len(bJobs) == 0 { + return nil + } + + for i := 0; i < retrySQLTimes; i++ { + err = MoveBackfillJobsToHistoryTable(sess, bJobs[0]) + if err == nil { + return errors.Errorf(bJobs[0].Meta.ErrMsg) + } + logutil.BgLogger().Info("[ddl] MoveBackfillJobsToHistoryTable failed", zap.Error(err)) + time.Sleep(retrySQLInterval) + } + return errors.Trace(err) +} + +func checkBackfillJobCount(sess *session, jobID, currEleID int64, currEleKey []byte) (backfillJobCnt int, err error) { + err = checkAndHandleInterruptedBackfillJobs(sess, jobID, currEleID, currEleKey) + if err != nil { + return 0, errors.Trace(err) + } + + backfillJobCnt, err = GetBackfillJobCount(sess, BackfillTable, fmt.Sprintf("ddl_job_id = %d and ele_id = %d and ele_key = '%s'", + jobID, currEleID, currEleKey), "check_backfill_job_count") + if err != nil { + return 0, errors.Trace(err) + } + + return backfillJobCnt, nil +} + +func getBackfillJobWithRetry(sess *session, tableName string, jobID, currEleID int64, currEleKey []byte, isDesc bool) (*BackfillJob, error) { + var err error + var bJobs []*BackfillJob + descStr := "" + if isDesc { + descStr = "order by id desc" + } + for i := 0; i < retrySQLTimes; i++ { + bJobs, err = GetBackfillJobs(sess, tableName, fmt.Sprintf("ddl_job_id = %d and ele_id = %d and ele_key = '%s' %s limit 1", + jobID, currEleID, currEleKey, descStr), "check_backfill_job_state") + if err != nil { + logutil.BgLogger().Warn("[ddl] GetBackfillJobs failed", zap.Error(err)) + continue + } + + if len(bJobs) != 0 { + return bJobs[0], nil + } + break + } + return nil, errors.Trace(err) +} + +// GetMaxBackfillJob gets the max backfill job in BackfillTable and BackfillHistoryTable. +func GetMaxBackfillJob(sess *session, jobID, currEleID int64, currEleKey []byte) (*BackfillJob, error) { + bfJob, err := getBackfillJobWithRetry(sess, BackfillTable, jobID, currEleID, currEleKey, true) + if err != nil { + return nil, errors.Trace(err) + } + hJob, err := getBackfillJobWithRetry(sess, BackfillHistoryTable, jobID, currEleID, currEleKey, true) + if err != nil { + return nil, errors.Trace(err) + } + + if bfJob == nil { + return hJob, nil + } + if hJob == nil { + return bfJob, nil + } + if bfJob.ID > hJob.ID { + return bfJob, nil + } + return hJob, nil +} + +// MoveBackfillJobsToHistoryTable moves backfill table jobs to the backfill history table. +func MoveBackfillJobsToHistoryTable(sctx sessionctx.Context, bfJob *BackfillJob) error { + s, ok := sctx.(*session) + if !ok { + return errors.Errorf("sess ctx:%#v convert session failed", sctx) + } + + return s.runInTxn(func(se *session) error { + // TODO: Consider batch by batch update backfill jobs and insert backfill history jobs. + bJobs, err := GetBackfillJobs(se, BackfillTable, fmt.Sprintf("ddl_job_id = %d and ele_id = %d and ele_key = '%s'", + bfJob.JobID, bfJob.EleID, bfJob.EleKey), "update_backfill_job") + if err != nil { + return errors.Trace(err) + } + if len(bJobs) == 0 { + return nil + } + + txn, err := se.txn() + if err != nil { + return errors.Trace(err) + } + startTS := txn.StartTS() + err = RemoveBackfillJob(se, true, bJobs[0]) + if err == nil { + for _, bj := range bJobs { + bj.State = model.JobStateCancelled + bj.FinishTS = startTS + } + err = AddBackfillHistoryJob(se, bJobs) + } + logutil.BgLogger().Info("[ddl] move backfill jobs to history table", zap.Int("job count", len(bJobs))) + return errors.Trace(err) + }) +} + // recordIterFunc is used for low-level record iteration. type recordIterFunc func(h kv.Handle, rowKey kv.Key, rawRecord []byte) (more bool, err error) @@ -847,3 +1476,36 @@ func logSlowOperations(elapsed time.Duration, slowMsg string, threshold uint32) logutil.BgLogger().Info("[ddl] slow operations", zap.Duration("takeTimes", elapsed), zap.String("msg", slowMsg)) } } + +// doneTaskKeeper keeps the done tasks and update the latest next key. +type doneTaskKeeper struct { + doneTaskNextKey map[int]kv.Key + current int + nextKey kv.Key +} + +func newDoneTaskKeeper(start kv.Key) *doneTaskKeeper { + return &doneTaskKeeper{ + doneTaskNextKey: make(map[int]kv.Key), + current: 0, + nextKey: start, + } +} + +func (n *doneTaskKeeper) updateNextKey(doneTaskID int, next kv.Key) { + if doneTaskID == n.current { + n.current++ + n.nextKey = next + for { + if nKey, ok := n.doneTaskNextKey[n.current]; ok { + delete(n.doneTaskNextKey, n.current) + n.current++ + n.nextKey = nKey + } else { + break + } + } + return + } + n.doneTaskNextKey[doneTaskID] = next +} diff --git a/ddl/backfilling_test.go b/ddl/backfilling_test.go new file mode 100644 index 0000000000000..167b809dd4487 --- /dev/null +++ b/ddl/backfilling_test.go @@ -0,0 +1,45 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl + +import ( + "bytes" + "testing" + + "github.com/pingcap/tidb/kv" + "github.com/stretchr/testify/require" +) + +func TestDoneTaskKeeper(t *testing.T) { + n := newDoneTaskKeeper(kv.Key("a")) + n.updateNextKey(0, kv.Key("b")) + n.updateNextKey(1, kv.Key("c")) + require.True(t, bytes.Equal(n.nextKey, kv.Key("c"))) + require.Len(t, n.doneTaskNextKey, 0) + + n.updateNextKey(4, kv.Key("f")) + require.True(t, bytes.Equal(n.nextKey, kv.Key("c"))) + require.Len(t, n.doneTaskNextKey, 1) + n.updateNextKey(3, kv.Key("e")) + n.updateNextKey(5, kv.Key("g")) + require.True(t, bytes.Equal(n.nextKey, kv.Key("c"))) + require.Len(t, n.doneTaskNextKey, 3) + n.updateNextKey(2, kv.Key("d")) + require.True(t, bytes.Equal(n.nextKey, kv.Key("g"))) + require.Len(t, n.doneTaskNextKey, 0) + + n.updateNextKey(6, kv.Key("h")) + require.True(t, bytes.Equal(n.nextKey, kv.Key("h"))) +} diff --git a/ddl/callback.go b/ddl/callback.go index 84b22cdfed944..b6160d150e717 100644 --- a/ddl/callback.go +++ b/ddl/callback.go @@ -48,7 +48,7 @@ type Callback interface { // OnChanged is called after a ddl statement is finished. OnChanged(err error) error // OnSchemaStateChanged is called after a schema state is changed. - OnSchemaStateChanged() + OnSchemaStateChanged(schemaVer int64) // OnJobRunBefore is called before running job. OnJobRunBefore(job *model.Job) // OnJobUpdated is called after the running job is updated. @@ -71,7 +71,7 @@ func (*BaseCallback) OnChanged(err error) error { } // OnSchemaStateChanged implements Callback interface. -func (*BaseCallback) OnSchemaStateChanged() { +func (*BaseCallback) OnSchemaStateChanged(schemaVer int64) { // Nothing to do. } @@ -129,7 +129,7 @@ func (c *DefaultCallback) OnChanged(err error) error { } // OnSchemaStateChanged overrides the ddl Callback interface. -func (c *DefaultCallback) OnSchemaStateChanged() { +func (c *DefaultCallback) OnSchemaStateChanged(schemaVer int64) { err := c.do.Reload() if err != nil { logutil.BgLogger().Error("domain callback failed on schema state changed", zap.Error(err)) @@ -166,7 +166,7 @@ func (c *ctcCallback) OnChanged(err error) error { } // OnSchemaStateChanged overrides the ddl Callback interface. -func (c *ctcCallback) OnSchemaStateChanged() { +func (c *ctcCallback) OnSchemaStateChanged(retVer int64) { err := c.do.Reload() if err != nil { logutil.BgLogger().Error("domain callback failed on schema state changed", zap.Error(err)) diff --git a/ddl/callback_test.go b/ddl/callback_test.go index 4e7199dbef8ca..5a97e8212689e 100644 --- a/ddl/callback_test.go +++ b/ddl/callback_test.go @@ -48,13 +48,14 @@ type TestDDLCallback struct { // domain to reload schema before your ddl stepping into the next state change. Do DomainReloader - onJobRunBefore func(*model.Job) - OnJobRunBeforeExported func(*model.Job) - onJobUpdated func(*model.Job) - OnJobUpdatedExported atomic.Pointer[func(*model.Job)] - onWatched func(ctx context.Context) - OnGetJobBeforeExported func(string) - OnGetJobAfterExported func(string, *model.Job) + onJobRunBefore func(*model.Job) + OnJobRunBeforeExported func(*model.Job) + onJobUpdated func(*model.Job) + OnJobUpdatedExported atomic.Pointer[func(*model.Job)] + onWatched func(ctx context.Context) + OnGetJobBeforeExported func(string) + OnGetJobAfterExported func(string, *model.Job) + OnJobSchemaStateChanged func(int64) } // OnChanged mock the same behavior with the main DDL hook. @@ -73,12 +74,17 @@ func (tc *TestDDLCallback) OnChanged(err error) error { } // OnSchemaStateChanged mock the same behavior with the main ddl hook. -func (tc *TestDDLCallback) OnSchemaStateChanged() { +func (tc *TestDDLCallback) OnSchemaStateChanged(schemaVer int64) { if tc.Do != nil { if err := tc.Do.Reload(); err != nil { logutil.BgLogger().Warn("reload failed on schema state changed", zap.Error(err)) } } + + if tc.OnJobSchemaStateChanged != nil { + tc.OnJobSchemaStateChanged(schemaVer) + return + } } // OnJobRunBefore is used to run the user customized logic of `onJobRunBefore` first. diff --git a/ddl/cancel_test.go b/ddl/cancel_test.go index b7d3ad93ec6c0..3a5c461ad8461 100644 --- a/ddl/cancel_test.go +++ b/ddl/cancel_test.go @@ -149,8 +149,8 @@ var allTestCase = []testCancelJob{ {"alter table t modify column c11 char(10)", true, model.StateWriteReorganization, true, true, nil}, {"alter table t modify column c11 char(10)", false, model.StatePublic, false, true, nil}, // Add foreign key. - {"alter table t add constraint fk foreign key a(c1) references t_ref(c1)", true, model.StateNone, true, false, []string{"create table t_ref (c1 int, c2 int, c3 int, c11 tinyint);"}}, - {"alter table t add constraint fk foreign key a(c1) references t_ref(c1)", false, model.StatePublic, false, true, nil}, + {"alter table t add constraint fk foreign key a(c1) references t_ref(c1)", true, model.StateNone, true, false, []string{"create table t_ref (c1 int key, c2 int, c3 int, c11 tinyint);"}}, + {"alter table t add constraint fk foreign key a(c1) references t_ref(c1)", false, model.StatePublic, false, true, []string{"insert into t_ref (c1) select c1 from t;"}}, // Drop foreign key. {"alter table t drop foreign key fk", true, model.StatePublic, true, false, nil}, {"alter table t drop foreign key fk", false, model.StateNone, false, true, nil}, @@ -244,7 +244,7 @@ func TestCancel(t *testing.T) { partition p4 values less than (7096) );`) tk.MustExec(`create table t ( - c1 int, c2 int, c3 int, c11 tinyint + c1 int, c2 int, c3 int, c11 tinyint, index fk_c1(c1) );`) // Prepare data. diff --git a/ddl/cluster.go b/ddl/cluster.go index a6f80991ca0c9..74ac8c05ca098 100644 --- a/ddl/cluster.go +++ b/ddl/cluster.go @@ -17,11 +17,14 @@ package ddl import ( "bytes" "context" + "encoding/hex" + "fmt" "strings" "time" "github.com/pingcap/errors" "github.com/pingcap/failpoint" + "github.com/pingcap/kvproto/pkg/errorpb" "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/domain/infosync" @@ -37,30 +40,35 @@ import ( "github.com/pingcap/tidb/util/filter" "github.com/pingcap/tidb/util/gcutil" "github.com/pingcap/tidb/util/logutil" - tikverr "github.com/tikv/client-go/v2/error" tikvstore "github.com/tikv/client-go/v2/kv" "github.com/tikv/client-go/v2/oracle" "github.com/tikv/client-go/v2/tikv" "github.com/tikv/client-go/v2/tikvrpc" "github.com/tikv/client-go/v2/txnkv/rangetask" + "go.uber.org/atomic" "go.uber.org/zap" "golang.org/x/exp/slices" ) var pdScheduleKey = []string{ - "hot-region-schedule-limit", - "leader-schedule-limit", "merge-schedule-limit", - "region-schedule-limit", - "replica-schedule-limit", } const ( - flashbackMaxBackoff = 300000 // 300s - flashbackTimeout = 30 * time.Second // 30s + flashbackMaxBackoff = 1800000 // 1800s + flashbackTimeout = 3 * time.Minute // 3min +) - readOnlyArgsOffset = 2 - gcEnabledArgsOffset = 3 +const ( + pdScheduleArgsOffset = 1 + iota + gcEnabledOffset + autoAnalyzeOffset + readOnlyOffset + totalLockedRegionsOffset + startTSOffset + commitTSOffset + ttlJobEnableOffSet + keyRangesOffset ) func closePDSchedule() error { @@ -80,7 +88,7 @@ func savePDSchedule(job *model.Job) error { for _, key := range pdScheduleKey { saveValue[key] = retValue[key] } - job.Args[1] = &saveValue + job.Args[pdScheduleArgsOffset] = &saveValue return nil } @@ -117,8 +125,32 @@ func ValidateFlashbackTS(ctx context.Context, sctx sessionctx.Context, flashBack return gcutil.ValidateSnapshotWithGCSafePoint(flashBackTS, gcSafePoint) } -func setTiDBSuperReadOnly(sess sessionctx.Context, value string) error { - return sess.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBSuperReadOnly, value) +func getTiDBTTLJobEnable(sess sessionctx.Context) (string, error) { + val, err := sess.GetSessionVars().GlobalVarsAccessor.GetGlobalSysVar(variable.TiDBTTLJobEnable) + if err != nil { + return "", errors.Trace(err) + } + return val, nil +} + +func setTiDBTTLJobEnable(ctx context.Context, sess sessionctx.Context, value string) error { + return sess.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(ctx, variable.TiDBTTLJobEnable, value) +} + +func setTiDBEnableAutoAnalyze(ctx context.Context, sess sessionctx.Context, value string) error { + return sess.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(ctx, variable.TiDBEnableAutoAnalyze, value) +} + +func getTiDBEnableAutoAnalyze(sess sessionctx.Context) (string, error) { + val, err := sess.GetSessionVars().GlobalVarsAccessor.GetGlobalSysVar(variable.TiDBEnableAutoAnalyze) + if err != nil { + return "", errors.Trace(err) + } + return val, nil +} + +func setTiDBSuperReadOnly(ctx context.Context, sess sessionctx.Context, value string) error { + return sess.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(ctx, variable.TiDBSuperReadOnly, value) } func getTiDBSuperReadOnly(sess sessionctx.Context) (string, error) { @@ -129,13 +161,35 @@ func getTiDBSuperReadOnly(sess sessionctx.Context) (string, error) { return val, nil } +func isFlashbackSupportedDDLAction(action model.ActionType) bool { + switch action { + case model.ActionSetTiFlashReplica, model.ActionUpdateTiFlashReplicaStatus, model.ActionAlterPlacementPolicy, + model.ActionAlterTablePlacement, model.ActionAlterTablePartitionPlacement, model.ActionCreatePlacementPolicy, + model.ActionDropPlacementPolicy, model.ActionModifySchemaDefaultPlacement: + return false + default: + return true + } +} + +func checkSystemSchemaID(t *meta.Meta, schemaID int64, flashbackTSString string) error { + if schemaID <= 0 { + return nil + } + DBInfo, err := t.GetDatabase(schemaID) + if err != nil || DBInfo == nil { + return errors.Trace(err) + } + if filter.IsSystemSchema(DBInfo.Name.L) { + return errors.Errorf("Detected modified system table during [%s, now), can't do flashback", flashbackTSString) + } + return nil +} + func checkAndSetFlashbackClusterInfo(sess sessionctx.Context, d *ddlCtx, t *meta.Meta, job *model.Job, flashbackTS uint64) (err error) { if err = ValidateFlashbackTS(d.ctx, sess, flashbackTS); err != nil { return err } - if err = CheckFlashbackHistoryTSRange(t, flashbackTS); err != nil { - return err - } if err = gcutil.DisableGC(sess); err != nil { return err @@ -143,7 +197,13 @@ func checkAndSetFlashbackClusterInfo(sess sessionctx.Context, d *ddlCtx, t *meta if err = closePDSchedule(); err != nil { return err } - if err = setTiDBSuperReadOnly(sess, variable.On); err != nil { + if err = setTiDBEnableAutoAnalyze(d.ctx, sess, variable.Off); err != nil { + return err + } + if err = setTiDBSuperReadOnly(d.ctx, sess, variable.On); err != nil { + return err + } + if err = setTiDBTTLJobEnable(d.ctx, sess, variable.Off); err != nil { return err } @@ -152,13 +212,55 @@ func checkAndSetFlashbackClusterInfo(sess sessionctx.Context, d *ddlCtx, t *meta return errors.Trace(err) } - flashbackSchemaVersion, err := meta.NewSnapshotMeta(d.store.GetSnapshot(kv.NewVersion(flashbackTS))).GetSchemaVersion() + flashbackSnapshotMeta := meta.NewSnapshotMeta(d.store.GetSnapshot(kv.NewVersion(flashbackTS))) + flashbackSchemaVersion, err := flashbackSnapshotMeta.GetSchemaVersion() + if err != nil { + return errors.Trace(err) + } + + flashbackTSString := oracle.GetTimeFromTS(flashbackTS).String() + + // Check if there is an upgrade during [flashbackTS, now) + sql := fmt.Sprintf("select VARIABLE_VALUE from mysql.tidb as of timestamp '%s' where VARIABLE_NAME='tidb_server_version'", flashbackTSString) + rows, err := newSession(sess).execute(d.ctx, sql, "check_tidb_server_version") + if err != nil || len(rows) == 0 { + return errors.Errorf("Get history `tidb_server_version` failed, can't do flashback") + } + sql = fmt.Sprintf("select 1 from mysql.tidb where VARIABLE_NAME='tidb_server_version' and VARIABLE_VALUE=%s", rows[0].GetString(0)) + rows, err = newSession(sess).execute(d.ctx, sql, "check_tidb_server_version") if err != nil { return errors.Trace(err) } - // If flashbackSchemaVersion not same as nowSchemaVersion, we've done ddl during [flashbackTs, now). - if flashbackSchemaVersion != nowSchemaVersion { - return errors.Errorf("schema version not same, have done ddl during [flashbackTS, now)") + if len(rows) == 0 { + return errors.Errorf("Detected TiDB upgrade during [%s, now), can't do flashback", flashbackTSString) + } + + // Check is there a DDL task at flashbackTS. + sql = fmt.Sprintf("select count(*) from mysql.%s as of timestamp '%s'", JobTable, flashbackTSString) + rows, err = newSession(sess).execute(d.ctx, sql, "check_history_job") + if err != nil || len(rows) == 0 { + return errors.Errorf("Get history ddl jobs failed, can't do flashback") + } + if rows[0].GetInt64(0) != 0 { + return errors.Errorf("Detected another DDL job at %s, can't do flashback", flashbackTSString) + } + + // If flashbackSchemaVersion not same as nowSchemaVersion, we should check all schema diffs during [flashbackTs, now). + for i := flashbackSchemaVersion + 1; i <= nowSchemaVersion; i++ { + diff, err := t.GetSchemaDiff(i) + if err != nil { + return errors.Trace(err) + } + if diff == nil { + continue + } + if !isFlashbackSupportedDDLAction(diff.Type) { + return errors.Errorf("Detected unsupported DDL job type(%s) during [%s, now), can't do flashback", diff.Type.String(), flashbackTSString) + } + err = checkSystemSchemaID(flashbackSnapshotMeta, diff.SchemaID, flashbackTSString) + if err != nil { + return errors.Trace(err) + } } jobs, err := GetAllDDLJobs(sess, t) @@ -179,97 +281,113 @@ func checkAndSetFlashbackClusterInfo(sess sessionctx.Context, d *ddlCtx, t *meta return nil } -type flashbackID struct { - id int64 - excluded bool +func addToSlice(schema string, tableName string, tableID int64, flashbackIDs []int64) []int64 { + if filter.IsSystemSchema(schema) && !strings.HasPrefix(tableName, "stats_") && tableName != "gc_delete_range" { + flashbackIDs = append(flashbackIDs, tableID) + } + return flashbackIDs } -func addToSlice(schema string, tableName string, tableID int64, flashbackIDs []flashbackID) []flashbackID { - var excluded bool - if filter.IsSystemSchema(schema) && !strings.HasPrefix(tableName, "stats_") { - excluded = true +// GetTableDataKeyRanges get keyRanges by `flashbackIDs`. +// This func will return all flashback table data key ranges. +func GetTableDataKeyRanges(nonFlashbackTableIDs []int64) []kv.KeyRange { + var keyRanges []kv.KeyRange + + nonFlashbackTableIDs = append(nonFlashbackTableIDs, -1) + + slices.SortFunc(nonFlashbackTableIDs, func(a, b int64) bool { + return a < b + }) + + for i := 1; i < len(nonFlashbackTableIDs); i++ { + keyRanges = append(keyRanges, kv.KeyRange{ + StartKey: tablecodec.EncodeTablePrefix(nonFlashbackTableIDs[i-1] + 1), + EndKey: tablecodec.EncodeTablePrefix(nonFlashbackTableIDs[i]), + }) } - flashbackIDs = append(flashbackIDs, flashbackID{ - id: tableID, - excluded: excluded, + + // Add all other key ranges. + keyRanges = append(keyRanges, kv.KeyRange{ + StartKey: tablecodec.EncodeTablePrefix(nonFlashbackTableIDs[len(nonFlashbackTableIDs)-1] + 1), + EndKey: tablecodec.EncodeTablePrefix(meta.MaxGlobalID), }) - return flashbackIDs + + return keyRanges } -// GetFlashbackKeyRanges make keyRanges efficiently for flashback cluster when many tables in cluster, +// GetFlashbackKeyRanges get keyRanges for flashback cluster. +// It contains all non system table key ranges and meta data key ranges. // The time complexity is O(nlogn). -func GetFlashbackKeyRanges(sess sessionctx.Context, startKey kv.Key) ([]kv.KeyRange, error) { +func GetFlashbackKeyRanges(sess sessionctx.Context, flashbackTS uint64) ([]kv.KeyRange, error) { schemas := sess.GetDomainInfoSchema().(infoschema.InfoSchema).AllSchemas() // The semantic of keyRanges(output). - var keyRanges []kv.KeyRange + keyRanges := make([]kv.KeyRange, 0) - var flashbackIDs []flashbackID - for _, db := range schemas { - for _, table := range db.Tables { - if !table.IsBaseTable() || table.ID > meta.MaxGlobalID { - continue - } - flashbackIDs = addToSlice(db.Name.L, table.Name.L, table.ID, flashbackIDs) - if table.Partition != nil { - for _, partition := range table.Partition.Definitions { - flashbackIDs = addToSlice(db.Name.L, table.Name.L, partition.ID, flashbackIDs) - } - } - } + // get snapshot schema IDs. + flashbackSnapshotMeta := meta.NewSnapshotMeta(sess.GetStore().GetSnapshot(kv.NewVersion(flashbackTS))) + snapshotSchemas, err := flashbackSnapshotMeta.ListDatabases() + if err != nil { + return nil, errors.Trace(err) } - slices.SortFunc(flashbackIDs, func(a, b flashbackID) bool { - return a.id < b.id - }) - - lastExcludeIdx := -1 - for i, id := range flashbackIDs { - if id.excluded { - // Found a range [lastExcludeIdx, i) needs to be added. - if i > lastExcludeIdx+1 { - keyRanges = append(keyRanges, kv.KeyRange{ - StartKey: tablecodec.EncodeTablePrefix(flashbackIDs[lastExcludeIdx+1].id), - EndKey: tablecodec.EncodeTablePrefix(flashbackIDs[i-1].id + 1), - }) - } - lastExcludeIdx = i + schemaIDs := make(map[int64]struct{}) + for _, schema := range schemas { + if !filter.IsSystemSchema(schema.Name.L) { + schemaIDs[schema.ID] = struct{}{} + } + } + for _, schema := range snapshotSchemas { + if !filter.IsSystemSchema(schema.Name.L) { + schemaIDs[schema.ID] = struct{}{} } } - // The last part needs to be added. - if lastExcludeIdx < len(flashbackIDs)-1 { + // The meta data key ranges. + for schemaID := range schemaIDs { + metaStartKey := tablecodec.EncodeMetaKeyPrefix(meta.DBkey(schemaID)) + metaEndKey := tablecodec.EncodeMetaKeyPrefix(meta.DBkey(schemaID + 1)) keyRanges = append(keyRanges, kv.KeyRange{ - StartKey: tablecodec.EncodeTablePrefix(flashbackIDs[lastExcludeIdx+1].id), - EndKey: tablecodec.EncodeTablePrefix(flashbackIDs[len(flashbackIDs)-1].id + 1), + StartKey: metaStartKey, + EndKey: metaEndKey, }) } - for i, ranges := range keyRanges { - // startKey smaller than ranges.StartKey, ranges begin with [ranges.StartKey, ranges.EndKey) - if ranges.StartKey.Cmp(startKey) > 0 { - keyRanges = keyRanges[i:] - break - } - // startKey in [ranges.StartKey, ranges.EndKey), ranges begin with [startKey, ranges.EndKey) - if ranges.StartKey.Cmp(startKey) <= 0 && ranges.EndKey.Cmp(startKey) > 0 { - keyRanges = keyRanges[i:] - keyRanges[0].StartKey = startKey - break + startKey := tablecodec.EncodeMetaKeyPrefix([]byte("DBs")) + keyRanges = append(keyRanges, kv.KeyRange{ + StartKey: startKey, + EndKey: startKey.PrefixNext(), + }) + + var nonFlashbackTableIDs []int64 + for _, db := range schemas { + for _, table := range db.Tables { + if !table.IsBaseTable() || table.ID > meta.MaxGlobalID { + continue + } + nonFlashbackTableIDs = addToSlice(db.Name.L, table.Name.L, table.ID, nonFlashbackTableIDs) + if table.Partition != nil { + for _, partition := range table.Partition.Definitions { + nonFlashbackTableIDs = addToSlice(db.Name.L, table.Name.L, partition.ID, nonFlashbackTableIDs) + } + } } } - return keyRanges, nil + return append(keyRanges, GetTableDataKeyRanges(nonFlashbackTableIDs)...), nil } -func sendFlashbackToVersionRPC( +// SendPrepareFlashbackToVersionRPC prepares regions for flashback, the purpose is to put region into flashback state which region stop write +// Function also be called by BR for volume snapshot backup and restore +func SendPrepareFlashbackToVersionRPC( ctx context.Context, s tikv.Storage, - version uint64, + flashbackTS, startTS uint64, r tikvstore.KeyRange, ) (rangetask.TaskStat, error) { startKey, rangeEndKey := r.StartKey, r.EndKey var taskStat rangetask.TaskStat + bo := tikv.NewBackoffer(ctx, flashbackMaxBackoff) for { select { case <-ctx.Done(): @@ -281,7 +399,6 @@ func sendFlashbackToVersionRPC( break } - bo := tikv.NewBackoffer(ctx, flashbackMaxBackoff) loc, err := s.GetRegionCache().LocateKey(bo, startKey) if err != nil { return taskStat, err @@ -289,15 +406,19 @@ func sendFlashbackToVersionRPC( endKey := loc.EndKey isLast := len(endKey) == 0 || (len(rangeEndKey) > 0 && bytes.Compare(endKey, rangeEndKey) >= 0) - // If it is the last region + // If it is the last region. if isLast { endKey = rangeEndKey } - req := tikvrpc.NewRequest(tikvrpc.CmdFlashbackToVersion, &kvrpcpb.FlashbackToVersionRequest{ - Version: version, + logutil.BgLogger().Info("[ddl] send prepare flashback request", zap.Uint64("region_id", loc.Region.GetID()), + zap.String("start_key", hex.EncodeToString(startKey)), zap.String("end_key", hex.EncodeToString(endKey))) + + req := tikvrpc.NewRequest(tikvrpc.CmdPrepareFlashbackToVersion, &kvrpcpb.PrepareFlashbackToVersionRequest{ StartKey: startKey, EndKey: endKey, + StartTs: startTS, + Version: flashbackTS, }) resp, err := s.SendReq(bo, req, loc.Region, flashbackTimeout) @@ -308,6 +429,14 @@ func sendFlashbackToVersionRPC( if err != nil { return taskStat, err } + failpoint.Inject("mockPrepareMeetsEpochNotMatch", func(val failpoint.Value) { + if val.(bool) && bo.ErrorsNum() == 0 { + regionErr = &errorpb.Error{ + Message: "stale epoch", + EpochNotMatch: &errorpb.EpochNotMatch{}, + } + } + }) if regionErr != nil { err = bo.Backoff(tikv.BoRegionMiss(), errors.New(regionErr.String())) if err != nil { @@ -316,16 +445,117 @@ func sendFlashbackToVersionRPC( continue } if resp.Resp == nil { - return taskStat, errors.WithStack(tikverr.ErrBodyMissing) + logutil.BgLogger().Warn("prepare flashback miss resp body", zap.Uint64("region_id", loc.Region.GetID())) + err = bo.Backoff(tikv.BoTiKVRPC(), errors.New("prepare flashback rpc miss resp body")) + if err != nil { + return taskStat, err + } + continue + } + prepareFlashbackToVersionResp := resp.Resp.(*kvrpcpb.PrepareFlashbackToVersionResponse) + if err := prepareFlashbackToVersionResp.GetError(); err != "" { + boErr := bo.Backoff(tikv.BoTiKVRPC(), errors.New(err)) + if boErr != nil { + return taskStat, boErr + } + continue + } + taskStat.CompletedRegions++ + if isLast { + break + } + bo = tikv.NewBackoffer(ctx, flashbackMaxBackoff) + startKey = endKey + } + return taskStat, nil +} + +// SendFlashbackToVersionRPC flashback the MVCC key to the version +// Function also be called by BR for volume snapshot backup and restore +func SendFlashbackToVersionRPC( + ctx context.Context, + s tikv.Storage, + version uint64, + startTS, commitTS uint64, + r tikvstore.KeyRange, +) (rangetask.TaskStat, error) { + startKey, rangeEndKey := r.StartKey, r.EndKey + var taskStat rangetask.TaskStat + bo := tikv.NewBackoffer(ctx, flashbackMaxBackoff) + for { + select { + case <-ctx.Done(): + return taskStat, errors.WithStack(ctx.Err()) + default: + } + + if len(rangeEndKey) > 0 && bytes.Compare(startKey, rangeEndKey) >= 0 { + break + } + + loc, err := s.GetRegionCache().LocateKey(bo, startKey) + if err != nil { + return taskStat, err + } + + endKey := loc.EndKey + isLast := len(endKey) == 0 || (len(rangeEndKey) > 0 && bytes.Compare(endKey, rangeEndKey) >= 0) + // If it is the last region. + if isLast { + endKey = rangeEndKey } - flashbackToVersionResp := resp.Resp.(*kvrpcpb.FlashbackToVersionResponse) - if err := flashbackToVersionResp.GetError(); err != "" { - return taskStat, errors.Errorf("unexpected flashback to version err: %v", err) + + logutil.BgLogger().Info("[ddl] send flashback request", zap.Uint64("region_id", loc.Region.GetID()), + zap.String("start_key", hex.EncodeToString(startKey)), zap.String("end_key", hex.EncodeToString(endKey))) + + req := tikvrpc.NewRequest(tikvrpc.CmdFlashbackToVersion, &kvrpcpb.FlashbackToVersionRequest{ + Version: version, + StartKey: startKey, + EndKey: endKey, + StartTs: startTS, + CommitTs: commitTS, + }) + + resp, err := s.SendReq(bo, req, loc.Region, flashbackTimeout) + if err != nil { + logutil.BgLogger().Warn("send request meets error", zap.Uint64("region_id", loc.Region.GetID()), zap.Error(err)) + if err.Error() != fmt.Sprintf("region %d is not prepared for the flashback", loc.Region.GetID()) { + return taskStat, err + } + } else { + regionErr, err := resp.GetRegionError() + if err != nil { + return taskStat, err + } + if regionErr != nil { + err = bo.Backoff(tikv.BoRegionMiss(), errors.New(regionErr.String())) + if err != nil { + return taskStat, err + } + continue + } + if resp.Resp == nil { + logutil.BgLogger().Warn("flashback miss resp body", zap.Uint64("region_id", loc.Region.GetID())) + err = bo.Backoff(tikv.BoTiKVRPC(), errors.New("flashback rpc miss resp body")) + if err != nil { + return taskStat, err + } + continue + } + flashbackToVersionResp := resp.Resp.(*kvrpcpb.FlashbackToVersionResponse) + if respErr := flashbackToVersionResp.GetError(); respErr != "" { + boErr := bo.Backoff(tikv.BoTiKVRPC(), errors.New(respErr)) + if boErr != nil { + return taskStat, boErr + } + continue + } } taskStat.CompletedRegions++ if isLast { break } + bo = tikv.NewBackoffer(ctx, flashbackMaxBackoff) startKey = endKey } return taskStat, nil @@ -334,23 +564,36 @@ func sendFlashbackToVersionRPC( func flashbackToVersion( ctx context.Context, d *ddlCtx, - version uint64, + handler rangetask.TaskHandler, startKey []byte, endKey []byte, ) (err error) { return rangetask.NewRangeTaskRunner( "flashback-to-version-runner", d.store.(tikv.Storage), int(variable.GetDDLFlashbackConcurrency()), - func(ctx context.Context, r tikvstore.KeyRange) (rangetask.TaskStat, error) { - return sendFlashbackToVersionRPC(ctx, d.store.(tikv.Storage), version, r) - }, + handler, ).RunOnRange(ctx, startKey, endKey) } -// A Flashback has 3 different stages. +func splitRegionsByKeyRanges(d *ddlCtx, keyRanges []kv.KeyRange) { + if s, ok := d.store.(kv.SplittableStore); ok { + for _, keys := range keyRanges { + for { + // tableID is useless when scatter == false + _, err := s.SplitRegions(d.ctx, [][]byte{keys.StartKey, keys.EndKey}, false, nil) + if err == nil { + break + } + } + } + } +} + +// A Flashback has 4 different stages. // 1. before lock flashbackClusterJobID, check clusterJobID and lock it. // 2. before flashback start, check timestamp, disable GC and close PD schedule. -// 3. before flashback done, get key ranges, send flashback RPC. +// 3. phase 1, get key ranges, lock all regions. +// 4. phase 2, send flashback RPC, do flashback jobs. func (w *worker) onFlashbackCluster(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, err error) { inFlashbackTest := false failpoint.Inject("mockFlashbackTest", func(val failpoint.Value) { @@ -364,15 +607,19 @@ func (w *worker) onFlashbackCluster(d *ddlCtx, t *meta.Meta, job *model.Job) (ve return ver, errors.Errorf("Not support flashback cluster in non-TiKV env") } - var flashbackTS uint64 + var flashbackTS, lockedRegions, startTS, commitTS uint64 var pdScheduleValue map[string]interface{} - var readOnlyValue string + var autoAnalyzeValue, readOnlyValue, ttlJobEnableValue string var gcEnabledValue bool - if err := job.DecodeArgs(&flashbackTS, &pdScheduleValue, &readOnlyValue, &gcEnabledValue); err != nil { + var keyRanges []kv.KeyRange + if err := job.DecodeArgs(&flashbackTS, &pdScheduleValue, &gcEnabledValue, &autoAnalyzeValue, &readOnlyValue, &lockedRegions, &startTS, &commitTS, &ttlJobEnableValue, &keyRanges); err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } + var totalRegions, completedRegions atomic.Uint64 + totalRegions.Store(lockedRegions) + sess, err := w.sessPool.get() if err != nil { job.State = model.JobStateCancelled @@ -381,39 +628,90 @@ func (w *worker) onFlashbackCluster(d *ddlCtx, t *meta.Meta, job *model.Job) (ve defer w.sessPool.put(sess) switch job.SchemaState { - // Stage 1, check and set FlashbackClusterJobID, and save the PD schedule. + // Stage 1, check and set FlashbackClusterJobID, and update job args. case model.StateNone: if err = savePDSchedule(job); err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } + gcEnableValue, err := gcutil.CheckGCEnable(sess) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + job.Args[gcEnabledOffset] = &gcEnableValue + autoAnalyzeValue, err = getTiDBEnableAutoAnalyze(sess) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + job.Args[autoAnalyzeOffset] = &autoAnalyzeValue readOnlyValue, err = getTiDBSuperReadOnly(sess) if err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } - job.Args[readOnlyArgsOffset] = &readOnlyValue - gcEnableValue, err := gcutil.CheckGCEnable(sess) + job.Args[readOnlyOffset] = &readOnlyValue + ttlJobEnableValue, err = getTiDBTTLJobEnable(sess) if err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } - job.Args[gcEnabledArgsOffset] = &gcEnableValue - job.SchemaState = model.StateWriteOnly + job.Args[ttlJobEnableOffSet] = &ttlJobEnableValue + job.SchemaState = model.StateDeleteOnly return ver, nil // Stage 2, check flashbackTS, close GC and PD schedule. - case model.StateWriteOnly: + case model.StateDeleteOnly: if err = checkAndSetFlashbackClusterInfo(sess, d, t, job, flashbackTS); err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } - // A hack way to make global variables are synchronized to all TiDB. - // TiKV will block read/write requests during flashback cluster. - // So it's not very dangerous when sync failed. - time.Sleep(1 * time.Second) - job.SchemaState = model.StateWriteReorganization + // We should get startTS here to avoid lost startTS when TiDB crashed during send prepare flashback RPC. + startTS, err = d.store.GetOracle().GetTimestamp(d.ctx, &oracle.Option{TxnScope: oracle.GlobalTxnScope}) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + job.Args[startTSOffset] = startTS + keyRanges, err = GetFlashbackKeyRanges(sess, flashbackTS) + if err != nil { + return ver, errors.Trace(err) + } + job.Args[keyRangesOffset] = keyRanges + job.SchemaState = model.StateWriteOnly return ver, nil - // Stage 3, get key ranges. + // Stage 3, get key ranges and get locks. + case model.StateWriteOnly: + // TODO: Support flashback in unistore. + if inFlashbackTest { + job.SchemaState = model.StateWriteReorganization + return updateSchemaVersion(d, t, job) + } + // Split region by keyRanges, make sure no unrelated key ranges be locked. + splitRegionsByKeyRanges(d, keyRanges) + totalRegions.Store(0) + for _, r := range keyRanges { + if err = flashbackToVersion(d.ctx, d, + func(ctx context.Context, r tikvstore.KeyRange) (rangetask.TaskStat, error) { + stats, err := SendPrepareFlashbackToVersionRPC(ctx, d.store.(tikv.Storage), flashbackTS, startTS, r) + totalRegions.Add(uint64(stats.CompletedRegions)) + return stats, err + }, r.StartKey, r.EndKey); err != nil { + logutil.BgLogger().Warn("[ddl] Get error when do flashback", zap.Error(err)) + return ver, err + } + } + job.Args[totalLockedRegionsOffset] = totalRegions.Load() + + // We should get commitTS here to avoid lost commitTS when TiDB crashed during send flashback RPC. + commitTS, err = d.store.GetOracle().GetTimestamp(d.ctx, &oracle.Option{TxnScope: oracle.GlobalTxnScope}) + if err != nil { + return ver, errors.Trace(err) + } + job.Args[commitTSOffset] = commitTS + job.SchemaState = model.StateWriteReorganization + return updateSchemaVersion(d, t, job) + // Stage 4, get key ranges and send flashback RPC. case model.StateWriteReorganization: // TODO: Support flashback in unistore. if inFlashbackTest { @@ -423,22 +721,27 @@ func (w *worker) onFlashbackCluster(d *ddlCtx, t *meta.Meta, job *model.Job) (ve return ver, nil } - keyRanges, err := GetFlashbackKeyRanges(sess, tablecodec.EncodeTablePrefix(0)) - if err != nil { - return ver, errors.Trace(err) - } - - for _, ranges := range keyRanges { - if err = flashbackToVersion(context.Background(), d, flashbackTS, ranges.StartKey, ranges.EndKey); err != nil { + for _, r := range keyRanges { + if err = flashbackToVersion(d.ctx, d, + func(ctx context.Context, r tikvstore.KeyRange) (rangetask.TaskStat, error) { + // Use same startTS as prepare phase to simulate 1PC txn. + stats, err := SendFlashbackToVersionRPC(ctx, d.store.(tikv.Storage), flashbackTS, startTS, commitTS, r) + completedRegions.Add(uint64(stats.CompletedRegions)) + logutil.BgLogger().Info("[ddl] flashback cluster stats", + zap.Uint64("complete regions", completedRegions.Load()), + zap.Uint64("total regions", totalRegions.Load()), + zap.Error(err)) + return stats, err + }, r.StartKey, r.EndKey); err != nil { logutil.BgLogger().Warn("[ddl] Get error when do flashback", zap.Error(err)) - return ver, err + return ver, errors.Trace(err) } } asyncNotifyEvent(d, &util.Event{Tp: model.ActionFlashbackCluster}) job.State = model.JobStateDone job.SchemaState = model.StatePublic - return ver, nil + return updateSchemaVersion(d, t, job) } return ver, nil } @@ -449,12 +752,12 @@ func finishFlashbackCluster(w *worker, job *model.Job) error { return nil } - var flashbackTS uint64 + var flashbackTS, lockedRegions, startTS, commitTS uint64 var pdScheduleValue map[string]interface{} - var readOnlyValue string + var autoAnalyzeValue, readOnlyValue, ttlJobEnableValue string var gcEnabled bool - if err := job.DecodeArgs(&flashbackTS, &pdScheduleValue, &readOnlyValue, &gcEnabled); err != nil { + if err := job.DecodeArgs(&flashbackTS, &pdScheduleValue, &gcEnabled, &autoAnalyzeValue, &readOnlyValue, &lockedRegions, &startTS, &commitTS, &ttlJobEnableValue); err != nil { return errors.Trace(err) } sess, err := w.sessPool.get() @@ -464,28 +767,26 @@ func finishFlashbackCluster(w *worker, job *model.Job) error { defer w.sessPool.put(sess) err = kv.RunInNewTxn(w.ctx, w.store, true, func(ctx context.Context, txn kv.Transaction) error { - t := meta.NewMeta(txn) if err = recoverPDSchedule(pdScheduleValue); err != nil { return err } - if err = setTiDBSuperReadOnly(sess, readOnlyValue); err != nil { - return err - } if gcEnabled { if err = gcutil.EnableGC(sess); err != nil { return err } } - if job.IsDone() || job.IsSynced() { - gcSafePoint, err := gcutil.GetGCSafePoint(sess) - if err != nil { - return err - } - if err = UpdateFlashbackHistoryTSRanges(t, flashbackTS, t.StartTS, gcSafePoint); err != nil { + if err = setTiDBSuperReadOnly(w.ctx, sess, readOnlyValue); err != nil { + return err + } + + if job.IsCancelled() { + // only restore `tidb_ttl_job_enable` when flashback failed + if err = setTiDBTTLJobEnable(w.ctx, sess, ttlJobEnableValue); err != nil { return err } } - return nil + + return setTiDBEnableAutoAnalyze(w.ctx, sess, autoAnalyzeValue) }) if err != nil { return err @@ -493,56 +794,3 @@ func finishFlashbackCluster(w *worker, job *model.Job) error { return nil } - -// CheckFlashbackHistoryTSRange checks flashbackTS overlapped with history time ranges or not. -func CheckFlashbackHistoryTSRange(m *meta.Meta, flashbackTS uint64) error { - tsRanges, err := m.GetFlashbackHistoryTSRange() - if err != nil { - return err - } - for _, tsRange := range tsRanges { - if tsRange.StartTS <= flashbackTS && flashbackTS <= tsRange.EndTS { - return errors.Errorf("FlashbackTs overlapped, old range: [%s, %s], flashbackTS: %s", - oracle.GetTimeFromTS(tsRange.StartTS), oracle.GetTimeFromTS(tsRange.EndTS), oracle.GetTimeFromTS(flashbackTS)) - } - } - return nil -} - -// UpdateFlashbackHistoryTSRanges insert [startTS, endTS] into FlashbackHistoryTSRange. -func UpdateFlashbackHistoryTSRanges(m *meta.Meta, startTS uint64, endTS uint64, gcSafePoint uint64) error { - tsRanges, err := m.GetFlashbackHistoryTSRange() - if err != nil { - return err - } - if len(tsRanges) != 0 && tsRanges[len(tsRanges)-1].EndTS >= endTS { - // It's impossible, endTS should always greater than all TS in history TS ranges. - return errors.Errorf("Maybe TSO fallback, last flashback endTS: %d, now: %d", tsRanges[len(tsRanges)-1].EndTS, endTS) - } - - newTsRange := make([]meta.TSRange, 0, len(tsRanges)) - - for _, tsRange := range tsRanges { - if tsRange.EndTS < gcSafePoint { - continue - } - if startTS > tsRange.EndTS { - // tsRange.StartTS < tsRange.EndTS < startTS. - // We should keep tsRange in slices. - newTsRange = append(newTsRange, tsRange) - } else if startTS < tsRange.StartTS { - // startTS < tsRange.StartTS < tsRange.EndTS. - // The remained ts ranges are useless, [startTS, endTS] will cover them, so break. - break - } else { - // tsRange.StartTS < startTS < tsRange.EndTS. - // It's impossible reach here, we checked it before start flashback cluster. - return errors.Errorf("It's an unreachable branch, flashbackTS (%d) in old ts range: [%d, %d]", - startTS, tsRange.StartTS, tsRange.EndTS) - } - } - - // Store the new tsRange. - newTsRange = append(newTsRange, meta.TSRange{StartTS: startTS, EndTS: endTS}) - return m.SetFlashbackHistoryTSRange(newTsRange) -} diff --git a/ddl/cluster_test.go b/ddl/cluster_test.go index 92ffd4391d384..e2a4302e044ce 100644 --- a/ddl/cluster_test.go +++ b/ddl/cluster_test.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/parser/model" - "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/testkit" @@ -36,80 +35,32 @@ import ( "github.com/tikv/client-go/v2/oracle" ) -func TestGetFlashbackKeyRanges(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - se, err := session.CreateSession4Test(store) - require.NoError(t, err) - - kvRanges, err := ddl.GetFlashbackKeyRanges(se, tablecodec.EncodeTablePrefix(0)) - require.NoError(t, err) - // The results are 6 key ranges - // 0: (stats_meta,stats_histograms,stats_buckets) - // 1: (stats_feedback) - // 2: (stats_top_n) - // 3: (stats_extended) - // 4: (stats_fm_sketch) - // 5: (stats_history, stats_meta_history) - require.Len(t, kvRanges, 6) - // tableID for mysql.stats_meta is 20 - require.Equal(t, kvRanges[0].StartKey, tablecodec.EncodeTablePrefix(20)) - // tableID for mysql.stats_feedback is 30 - require.Equal(t, kvRanges[1].StartKey, tablecodec.EncodeTablePrefix(30)) - // tableID for mysql.stats_meta_history is 62 - require.Equal(t, kvRanges[5].EndKey, tablecodec.EncodeTablePrefix(62+1)) - - // The original table ID for range is [60, 63) - // startKey is 61, so return [61, 63) - kvRanges, err = ddl.GetFlashbackKeyRanges(se, tablecodec.EncodeTablePrefix(61)) - require.NoError(t, err) - require.Len(t, kvRanges, 1) - require.Equal(t, kvRanges[0].StartKey, tablecodec.EncodeTablePrefix(61)) - - // The original ranges are [48, 49), [60, 63) - // startKey is 59, so return [60, 63) - kvRanges, err = ddl.GetFlashbackKeyRanges(se, tablecodec.EncodeTablePrefix(59)) - require.NoError(t, err) - require.Len(t, kvRanges, 1) - require.Equal(t, kvRanges[0].StartKey, tablecodec.EncodeTablePrefix(60)) - - tk.MustExec("use test") - tk.MustExec("CREATE TABLE employees (" + - " id INT NOT NULL," + - " store_id INT NOT NULL" + - ") PARTITION BY RANGE (store_id) (" + - " PARTITION p0 VALUES LESS THAN (6)," + - " PARTITION p1 VALUES LESS THAN (11)," + - " PARTITION p2 VALUES LESS THAN (16)," + - " PARTITION p3 VALUES LESS THAN (21)" + - ");") - kvRanges, err = ddl.GetFlashbackKeyRanges(se, tablecodec.EncodeTablePrefix(63)) - require.NoError(t, err) - // start from table ID is 63, so only 1 kv range. - require.Len(t, kvRanges, 1) - // 1 tableID and 4 partitions. - require.Equal(t, tablecodec.DecodeTableID(kvRanges[0].EndKey)-tablecodec.DecodeTableID(kvRanges[0].StartKey), int64(5)) - - tk.MustExec("truncate table mysql.analyze_jobs") - - // truncate all `stats_` tables, make table ID consecutive. - tk.MustExec("truncate table mysql.stats_meta") - tk.MustExec("truncate table mysql.stats_histograms") - tk.MustExec("truncate table mysql.stats_buckets") - tk.MustExec("truncate table mysql.stats_feedback") - tk.MustExec("truncate table mysql.stats_top_n") - tk.MustExec("truncate table mysql.stats_extended") - tk.MustExec("truncate table mysql.stats_fm_sketch") - tk.MustExec("truncate table mysql.stats_history") - tk.MustExec("truncate table mysql.stats_meta_history") - kvRanges, err = ddl.GetFlashbackKeyRanges(se, tablecodec.EncodeTablePrefix(0)) - require.NoError(t, err) - require.Len(t, kvRanges, 2) - - tk.MustExec("truncate table test.employees") - kvRanges, err = ddl.GetFlashbackKeyRanges(se, tablecodec.EncodeTablePrefix(0)) - require.NoError(t, err) - require.Len(t, kvRanges, 1) +func TestGetTableDataKeyRanges(t *testing.T) { + // case 1, empty flashbackIDs + keyRanges := ddl.GetTableDataKeyRanges([]int64{}) + require.Len(t, keyRanges, 1) + require.Equal(t, keyRanges[0].StartKey, tablecodec.EncodeTablePrefix(0)) + require.Equal(t, keyRanges[0].EndKey, tablecodec.EncodeTablePrefix(meta.MaxGlobalID)) + + // case 2, insert a execluded table ID + keyRanges = ddl.GetTableDataKeyRanges([]int64{3}) + require.Len(t, keyRanges, 2) + require.Equal(t, keyRanges[0].StartKey, tablecodec.EncodeTablePrefix(0)) + require.Equal(t, keyRanges[0].EndKey, tablecodec.EncodeTablePrefix(3)) + require.Equal(t, keyRanges[1].StartKey, tablecodec.EncodeTablePrefix(4)) + require.Equal(t, keyRanges[1].EndKey, tablecodec.EncodeTablePrefix(meta.MaxGlobalID)) + + // case 3, insert some execluded table ID + keyRanges = ddl.GetTableDataKeyRanges([]int64{3, 5, 9}) + require.Len(t, keyRanges, 4) + require.Equal(t, keyRanges[0].StartKey, tablecodec.EncodeTablePrefix(0)) + require.Equal(t, keyRanges[0].EndKey, tablecodec.EncodeTablePrefix(3)) + require.Equal(t, keyRanges[1].StartKey, tablecodec.EncodeTablePrefix(4)) + require.Equal(t, keyRanges[1].EndKey, tablecodec.EncodeTablePrefix(5)) + require.Equal(t, keyRanges[2].StartKey, tablecodec.EncodeTablePrefix(6)) + require.Equal(t, keyRanges[2].EndKey, tablecodec.EncodeTablePrefix(9)) + require.Equal(t, keyRanges[3].StartKey, tablecodec.EncodeTablePrefix(10)) + require.Equal(t, keyRanges[3].EndKey, tablecodec.EncodeTablePrefix(meta.MaxGlobalID)) } func TestFlashbackCloseAndResetPDSchedule(t *testing.T) { @@ -125,7 +76,7 @@ func TestFlashbackCloseAndResetPDSchedule(t *testing.T) { fmt.Sprintf("return(%v)", injectSafeTS))) oldValue := map[string]interface{}{ - "hot-region-schedule-limit": 1, + "merge-schedule-limit": 1, } require.NoError(t, infosync.SetPDScheduleConfig(context.Background(), oldValue)) @@ -139,7 +90,7 @@ func TestFlashbackCloseAndResetPDSchedule(t *testing.T) { if job.SchemaState == model.StateWriteReorganization { closeValue, err := infosync.GetPDScheduleConfig(context.Background()) assert.NoError(t, err) - assert.Equal(t, closeValue["hot-region-schedule-limit"], 0) + assert.Equal(t, closeValue["merge-schedule-limit"], 0) // cancel flashback job job.State = model.JobStateCancelled job.Error = dbterror.ErrCancelledDDLJob @@ -147,6 +98,7 @@ func TestFlashbackCloseAndResetPDSchedule(t *testing.T) { } dom.DDL().SetHook(hook) + time.Sleep(10 * time.Millisecond) ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) require.NoError(t, err) @@ -155,7 +107,7 @@ func TestFlashbackCloseAndResetPDSchedule(t *testing.T) { finishValue, err := infosync.GetPDScheduleConfig(context.Background()) require.NoError(t, err) - require.EqualValues(t, finishValue["hot-region-schedule-limit"], 1) + require.EqualValues(t, finishValue["merge-schedule-limit"], 1) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockFlashbackTest")) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) @@ -169,6 +121,7 @@ func TestAddDDLDuringFlashback(t *testing.T) { tk.MustExec("use test") tk.MustExec("create table t(a int)") + time.Sleep(10 * time.Millisecond) ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) require.NoError(t, err) @@ -186,7 +139,7 @@ func TestAddDDLDuringFlashback(t *testing.T) { hook := &ddl.TestDDLCallback{Do: dom} hook.OnJobRunBeforeExported = func(job *model.Job) { assert.Equal(t, model.ActionFlashbackCluster, job.Type) - if job.SchemaState == model.StateWriteReorganization { + if job.SchemaState == model.StateWriteOnly { _, err := tk.Exec("alter table t add column b int") assert.ErrorContains(t, err, "Can't add ddl job, have flashback cluster job") } @@ -207,6 +160,7 @@ func TestGlobalVariablesOnFlashback(t *testing.T) { tk.MustExec("use test") tk.MustExec("create table t(a int)") + time.Sleep(10 * time.Millisecond) ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) require.NoError(t, err) @@ -225,30 +179,42 @@ func TestGlobalVariablesOnFlashback(t *testing.T) { hook.OnJobRunBeforeExported = func(job *model.Job) { assert.Equal(t, model.ActionFlashbackCluster, job.Type) if job.SchemaState == model.StateWriteReorganization { - rs, err := tk.Exec("show variables like 'tidb_super_read_only'") + rs, err := tk.Exec("show variables like 'tidb_gc_enable'") + assert.NoError(t, err) + assert.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) + rs, err = tk.Exec("show variables like 'tidb_enable_auto_analyze'") + assert.NoError(t, err) + assert.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) + rs, err = tk.Exec("show variables like 'tidb_super_read_only'") assert.NoError(t, err) assert.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.On) - rs, err = tk.Exec("show variables like 'tidb_gc_enable'") + rs, err = tk.Exec("show variables like 'tidb_ttl_job_enable'") assert.NoError(t, err) assert.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) } } dom.DDL().SetHook(hook) - // first try with `tidb_gc_enable` = on and `tidb_super_read_only` = off + // first try with `tidb_gc_enable` = on and `tidb_super_read_only` = off and `tidb_ttl_job_enable` = on tk.MustExec("set global tidb_gc_enable = on") tk.MustExec("set global tidb_super_read_only = off") + tk.MustExec("set global tidb_ttl_job_enable = on") tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + rs, err := tk.Exec("show variables like 'tidb_super_read_only'") require.NoError(t, err) require.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) rs, err = tk.Exec("show variables like 'tidb_gc_enable'") require.NoError(t, err) require.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.On) + rs, err = tk.Exec("show variables like 'tidb_ttl_job_enable'") + require.NoError(t, err) + require.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) - // second try with `tidb_gc_enable` = off and `tidb_super_read_only` = on + // second try with `tidb_gc_enable` = off and `tidb_super_read_only` = on and `tidb_ttl_job_enable` = off tk.MustExec("set global tidb_gc_enable = off") tk.MustExec("set global tidb_super_read_only = on") + tk.MustExec("set global tidb_ttl_job_enable = off") ts, err = tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) require.NoError(t, err) @@ -259,6 +225,9 @@ func TestGlobalVariablesOnFlashback(t *testing.T) { rs, err = tk.Exec("show variables like 'tidb_gc_enable'") require.NoError(t, err) require.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) + rs, err = tk.Exec("show variables like 'tidb_ttl_job_enable'") + assert.NoError(t, err) + assert.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) dom.DDL().SetHook(originHook) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockFlashbackTest")) @@ -270,6 +239,8 @@ func TestCancelFlashbackCluster(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) originHook := dom.DDL().GetHook() tk := testkit.NewTestKit(t, store) + + time.Sleep(10 * time.Millisecond) ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) require.NoError(t, err) @@ -284,17 +255,18 @@ func TestCancelFlashbackCluster(t *testing.T) { defer resetGC() tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) - // Try canceled on StateWriteOnly, cancel success - tk.MustExec("set global tidb_super_read_only = off") + // Try canceled on StateDeleteOnly, cancel success hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { - return job.SchemaState == model.StateWriteOnly + return job.SchemaState == model.StateDeleteOnly }) dom.DDL().SetHook(hook) + tk.MustExec("set global tidb_ttl_job_enable = on") tk.MustGetErrCode(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts)), errno.ErrCancelledDDLJob) hook.MustCancelDone(t) - rs, err := tk.Exec("show variables like 'tidb_super_read_only'") - require.NoError(t, err) - require.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) + + rs, err := tk.Exec("show variables like 'tidb_ttl_job_enable'") + assert.NoError(t, err) + assert.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.On) // Try canceled on StateWriteReorganization, cancel failed hook = newCancelJobHook(t, store, dom, func(job *model.Job) bool { @@ -304,66 +276,13 @@ func TestCancelFlashbackCluster(t *testing.T) { tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) hook.MustCancelFailed(t) + rs, err = tk.Exec("show variables like 'tidb_ttl_job_enable'") + assert.NoError(t, err) + assert.Equal(t, tk.ResultSetToResult(rs, "").Rows()[0][1], variable.Off) + dom.DDL().SetHook(originHook) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockFlashbackTest")) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) } - -func TestFlashbackTimeRange(t *testing.T) { - store := testkit.CreateMockStore(t) - - se, err := session.CreateSession4Test(store) - require.NoError(t, err) - txn, err := se.GetStore().Begin() - require.NoError(t, err) - - m := meta.NewMeta(txn) - flashbackTime := oracle.GetTimeFromTS(m.StartTS).Add(-10 * time.Minute) - - // No flashback history, shouldn't return err. - require.NoError(t, ddl.CheckFlashbackHistoryTSRange(m, oracle.GoTimeToTS(flashbackTime))) - - // Insert a time range to flashback history ts ranges. - require.NoError(t, ddl.UpdateFlashbackHistoryTSRanges(m, oracle.GoTimeToTS(flashbackTime), m.StartTS, 0)) - - historyTS, err := m.GetFlashbackHistoryTSRange() - require.NoError(t, err) - require.Len(t, historyTS, 1) - require.NoError(t, txn.Commit(context.Background())) - - se, err = session.CreateSession4Test(store) - require.NoError(t, err) - txn, err = se.GetStore().Begin() - require.NoError(t, err) - - m = meta.NewMeta(txn) - require.NoError(t, err) - // Flashback history time range is [m.StartTS - 10min, m.StartTS] - require.Error(t, ddl.CheckFlashbackHistoryTSRange(m, oracle.GoTimeToTS(flashbackTime.Add(5*time.Minute)))) - - // Check add insert a new time range - require.NoError(t, ddl.CheckFlashbackHistoryTSRange(m, oracle.GoTimeToTS(flashbackTime.Add(-5*time.Minute)))) - require.NoError(t, ddl.UpdateFlashbackHistoryTSRanges(m, oracle.GoTimeToTS(flashbackTime.Add(-5*time.Minute)), m.StartTS, 0)) - - historyTS, err = m.GetFlashbackHistoryTSRange() - require.NoError(t, err) - // history time range still equals to 1, because overlapped - require.Len(t, historyTS, 1) - - require.NoError(t, ddl.UpdateFlashbackHistoryTSRanges(m, oracle.GoTimeToTS(flashbackTime.Add(15*time.Minute)), oracle.GoTimeToTS(flashbackTime.Add(20*time.Minute)), 0)) - historyTS, err = m.GetFlashbackHistoryTSRange() - require.NoError(t, err) - require.Len(t, historyTS, 2) - - // GCSafePoint updated will clean some history TS ranges - require.NoError(t, ddl.UpdateFlashbackHistoryTSRanges(m, - oracle.GoTimeToTS(flashbackTime.Add(25*time.Minute)), - oracle.GoTimeToTS(flashbackTime.Add(30*time.Minute)), - oracle.GoTimeToTS(flashbackTime.Add(22*time.Minute)))) - historyTS, err = m.GetFlashbackHistoryTSRange() - require.NoError(t, err) - require.Len(t, historyTS, 1) - require.NoError(t, txn.Commit(context.Background())) -} diff --git a/ddl/column.go b/ddl/column.go index 6beba60a35d5c..5f60972100739 100644 --- a/ddl/column.go +++ b/ddl/column.go @@ -17,6 +17,7 @@ package ddl import ( "bytes" "context" + "encoding/hex" "fmt" "math/bits" "strings" @@ -341,6 +342,9 @@ func checkDropColumn(d *ddlCtx, t *meta.Meta, job *model.Job) (*model.TableInfo, if err = checkDropColumnWithForeignKeyConstraintInOwner(d, t, job, tblInfo, colName.L); err != nil { return nil, nil, nil, false, errors.Trace(err) } + if err = checkDropColumnWithTTLConfig(tblInfo, colName.L); err != nil { + return nil, nil, nil, false, errors.Trace(err) + } idxInfos := listIndicesWithColumn(colName.L, tblInfo.Indices) return tblInfo, colInfo, idxInfos, false, nil } @@ -548,6 +552,10 @@ func (w *worker) onModifyColumn(d *ddlCtx, t *meta.Meta, job *model.Job) (ver in job.State = model.JobStateCancelled return ver, errors.Trace(err) } + if tblInfo.Partition != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs("table is partition table")) + } changingCol := modifyInfo.changingCol if changingCol == nil { @@ -802,8 +810,18 @@ func doReorgWorkForModifyColumnMultiSchema(w *worker, d *ddlCtx, t *meta.Meta, j func doReorgWorkForModifyColumn(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job, tbl table.Table, oldCol, changingCol *model.ColumnInfo, changingIdxs []*model.IndexInfo) (done bool, ver int64, err error) { job.ReorgMeta.ReorgTp = model.ReorgTypeTxn - rh := newReorgHandler(t, w.sess, w.concurrentDDL) - reorgInfo, err := getReorgInfo(d.jobContext(job), d, rh, job, tbl, BuildElements(changingCol, changingIdxs), false) + sctx, err1 := w.sessPool.get() + if err1 != nil { + err = errors.Trace(err1) + return + } + defer w.sessPool.put(sctx) + rh := newReorgHandler(newSession(sctx)) + dbInfo, err := t.GetDatabase(job.SchemaID) + if err != nil { + return false, ver, errors.Trace(err) + } + reorgInfo, err := getReorgInfo(d.jobContext(job.ID), d, rh, job, dbInfo, tbl, BuildElements(changingCol, changingIdxs), false) if err != nil || reorgInfo.first { // If we run reorg firstly, we should update the job snapshot version // and then run the reorg next time. @@ -830,7 +848,7 @@ func doReorgWorkForModifyColumn(w *worker, d *ddlCtx, t *meta.Meta, job *model.J // If timeout, we should return, check for the owner and re-wait job done. return false, ver, nil } - if kv.IsTxnRetryableError(err) { + if kv.IsTxnRetryableError(err) || dbterror.ErrNotOwner.Equal(err) { return false, ver, errors.Trace(err) } if err1 := rh.RemoveDDLReorgHandle(job, reorgInfo.elements); err1 != nil { @@ -857,6 +875,9 @@ func adjustTableInfoAfterModifyColumnWithData(tblInfo *model.TableInfo, pos *ast indexesToRemove := filterIndexesToRemove(changingIdxs, newName, tblInfo) replaceOldIndexes(tblInfo, indexesToRemove) } + if tblInfo.TTLInfo != nil { + updateTTLInfoWhenModifyColumn(tblInfo, oldCol.Name, changingCol.Name) + } // Move the new column to a correct offset. destOffset, err := LocateOffsetToMove(changingCol.Offset, pos, tblInfo) if err != nil { @@ -931,6 +952,17 @@ func updateFKInfoWhenModifyColumn(tblInfo *model.TableInfo, oldCol, newCol model } } +func updateTTLInfoWhenModifyColumn(tblInfo *model.TableInfo, oldCol, newCol model.CIStr) { + if oldCol.L == newCol.L { + return + } + if tblInfo.TTLInfo != nil { + if tblInfo.TTLInfo.ColumnName.L == oldCol.L { + tblInfo.TTLInfo.ColumnName = newCol + } + } +} + // filterIndexesToRemove filters out the indexes that can be removed. func filterIndexesToRemove(changingIdxs []*model.IndexInfo, colName model.CIStr, tblInfo *model.TableInfo) []*model.IndexInfo { indexesToRemove := make([]*model.IndexInfo, 0, len(changingIdxs)) @@ -1020,9 +1052,35 @@ func BuildElements(changingCol *model.ColumnInfo, changingIdxs []*model.IndexInf return elements } -func (w *worker) updatePhysicalTableRow(t table.PhysicalTable, reorgInfo *reorgInfo) error { +func (w *worker) updatePhysicalTableRow(t table.Table, reorgInfo *reorgInfo) error { logutil.BgLogger().Info("[ddl] start to update table row", zap.String("job", reorgInfo.Job.String()), zap.String("reorgInfo", reorgInfo.String())) - return w.writePhysicalTableRecord(w.sessPool, t, typeUpdateColumnWorker, reorgInfo) + if tbl, ok := t.(table.PartitionedTable); ok { + done := false + for !done { + p := tbl.GetPartition(reorgInfo.PhysicalTableID) + if p == nil { + return dbterror.ErrCancelledDDLJob.GenWithStack("Can not find partition id %d for table %d", reorgInfo.PhysicalTableID, t.Meta().ID) + } + workType := typeReorgPartitionWorker + if reorgInfo.Job.Type != model.ActionReorganizePartition { + workType = typeUpdateColumnWorker + panic("FIXME: See https://github.com/pingcap/tidb/issues/39915") + } + err := w.writePhysicalTableRecord(w.sessPool, p, workType, reorgInfo) + if err != nil { + return err + } + done, err = w.updateReorgInfo(tbl, reorgInfo) + if err != nil { + return errors.Trace(err) + } + } + return nil + } + if tbl, ok := t.(table.PhysicalTable); ok { + return w.writePhysicalTableRecord(w.sessPool, tbl, typeUpdateColumnWorker, reorgInfo) + } + return dbterror.ErrCancelledDDLJob.GenWithStack("internal error for phys tbl id: %d tbl id: %d", reorgInfo.PhysicalTableID, t.Meta().ID) } // TestReorgGoroutineRunning is only used in test to indicate the reorg goroutine has been started. @@ -1037,7 +1095,7 @@ func (w *worker) updateCurrentElement(t table.Table, reorgInfo *reorgInfo) error TestReorgGoroutineRunning <- a for { time.Sleep(30 * time.Millisecond) - if w.getReorgCtx(reorgInfo.Job).isReorgCanceled() { + if w.getReorgCtx(reorgInfo.Job.ID).isReorgCanceled() { // Job is cancelled. So it can't be done. failpoint.Return(dbterror.ErrCancelledDDLJob) } @@ -1053,13 +1111,17 @@ func (w *worker) updateCurrentElement(t table.Table, reorgInfo *reorgInfo) error } } + if _, ok := t.(table.PartitionedTable); ok { + // TODO: Remove this + panic("FIXME: this got reverted and needs to be back!") + } // Get the original start handle and end handle. currentVer, err := getValidCurrentVersion(reorgInfo.d.store) if err != nil { return errors.Trace(err) } //nolint:forcetypeassert - originalStartHandle, originalEndHandle, err := getTableRange(reorgInfo.d.jobContext(reorgInfo.Job), reorgInfo.d, t.(table.PhysicalTable), currentVer.Ver, reorgInfo.Job.Priority) + originalStartHandle, originalEndHandle, err := getTableRange(reorgInfo.d.jobContext(reorgInfo.Job.ID), reorgInfo.d, t.(table.PhysicalTable), currentVer.Ver, reorgInfo.Job.Priority) if err != nil { return errors.Trace(err) } @@ -1082,21 +1144,22 @@ func (w *worker) updateCurrentElement(t table.Table, reorgInfo *reorgInfo) error // Then the handle range of the rest elements' is [originalStartHandle, originalEndHandle]. if i == startElementOffsetToResetHandle+1 { reorgInfo.StartKey, reorgInfo.EndKey = originalStartHandle, originalEndHandle + w.getReorgCtx(reorgInfo.Job.ID).setNextKey(reorgInfo.StartKey) } // Update the element in the reorgCtx to keep the atomic access for daemon-worker. - w.getReorgCtx(reorgInfo.Job).setCurrentElement(reorgInfo.elements[i+1]) + w.getReorgCtx(reorgInfo.Job.ID).setCurrentElement(reorgInfo.elements[i+1]) // Update the element in the reorgInfo for updating the reorg meta below. reorgInfo.currElement = reorgInfo.elements[i+1] // Write the reorg info to store so the whole reorganize process can recover from panic. err := reorgInfo.UpdateReorgMeta(reorgInfo.StartKey, w.sessPool) logutil.BgLogger().Info("[ddl] update column and indexes", - zap.Int64("jobID", reorgInfo.Job.ID), - zap.ByteString("elementType", reorgInfo.currElement.TypeKey), - zap.Int64("elementID", reorgInfo.currElement.ID), - zap.String("startHandle", tryDecodeToHandleString(reorgInfo.StartKey)), - zap.String("endHandle", tryDecodeToHandleString(reorgInfo.EndKey))) + zap.Int64("job ID", reorgInfo.Job.ID), + zap.ByteString("element type", reorgInfo.currElement.TypeKey), + zap.Int64("element ID", reorgInfo.currElement.ID), + zap.String("start key", hex.EncodeToString(reorgInfo.StartKey)), + zap.String("end key", hex.EncodeToString(reorgInfo.EndKey))) if err != nil { return errors.Trace(err) } @@ -1109,7 +1172,7 @@ func (w *worker) updateCurrentElement(t table.Table, reorgInfo *reorgInfo) error } type updateColumnWorker struct { - *backfillWorker + *backfillCtx oldColInfo *model.ColumnInfo newColInfo *model.ColumnInfo metricCounter prometheus.Counter @@ -1121,11 +1184,10 @@ type updateColumnWorker struct { rowMap map[int64]types.Datum // For SQL Mode and warnings. - sqlMode mysql.SQLMode jobContext *JobContext } -func newUpdateColumnWorker(sessCtx sessionctx.Context, id int, t table.PhysicalTable, decodeColMap map[int64]decoder.Column, reorgInfo *reorgInfo, jc *JobContext) *updateColumnWorker { +func newUpdateColumnWorker(sessCtx sessionctx.Context, t table.PhysicalTable, decodeColMap map[int64]decoder.Column, reorgInfo *reorgInfo, jc *JobContext) *updateColumnWorker { if !bytes.Equal(reorgInfo.currElement.TypeKey, meta.ColumnElementKey) { logutil.BgLogger().Error("Element type for updateColumnWorker incorrect", zap.String("jobQuery", reorgInfo.Query), zap.String("reorgInfo", reorgInfo.String())) @@ -1141,14 +1203,13 @@ func newUpdateColumnWorker(sessCtx sessionctx.Context, id int, t table.PhysicalT } rowDecoder := decoder.NewRowDecoder(t, t.WritableCols(), decodeColMap) return &updateColumnWorker{ - backfillWorker: newBackfillWorker(sessCtx, id, t, reorgInfo, typeUpdateColumnWorker), - oldColInfo: oldCol, - newColInfo: newCol, - metricCounter: metrics.BackfillTotalCounter.WithLabelValues(metrics.GenerateReorgLabel("update_col_rate", reorgInfo.SchemaName, t.Meta().Name.String())), - rowDecoder: rowDecoder, - rowMap: make(map[int64]types.Datum, len(decodeColMap)), - sqlMode: reorgInfo.ReorgMeta.SQLMode, - jobContext: jc, + backfillCtx: newBackfillCtx(reorgInfo.d, sessCtx, reorgInfo.ReorgMeta.ReorgTp, reorgInfo.SchemaName, t), + oldColInfo: oldCol, + newColInfo: newCol, + metricCounter: metrics.BackfillTotalCounter.WithLabelValues(metrics.GenerateReorgLabel("update_col_rate", reorgInfo.SchemaName, t.Meta().Name.String())), + rowDecoder: rowDecoder, + rowMap: make(map[int64]types.Datum, len(decodeColMap)), + jobContext: jc, } } @@ -1156,14 +1217,34 @@ func (w *updateColumnWorker) AddMetricInfo(cnt float64) { w.metricCounter.Add(cnt) } +func (*updateColumnWorker) String() string { + return typeUpdateColumnWorker.String() +} + +func (*updateColumnWorker) GetTask() (*BackfillJob, error) { + panic("[ddl] update column worker GetTask function doesn't implement") +} + +func (*updateColumnWorker) UpdateTask(*BackfillJob) error { + panic("[ddl] update column worker UpdateTask function doesn't implement") +} + +func (*updateColumnWorker) FinishTask(*BackfillJob) error { + panic("[ddl] update column worker FinishTask function doesn't implement") +} + +func (w *updateColumnWorker) GetCtx() *backfillCtx { + return w.backfillCtx +} + type rowRecord struct { key []byte // It's used to lock a record. Record it to reduce the encoding time. vals []byte // It's the record. warning *terror.Error // It's used to record the cast warning of a record. } -// getNextKey gets next handle of entry that we are going to process. -func (*updateColumnWorker) getNextKey(taskRange reorgBackfillTask, +// getNextHandleKey gets next handle of entry that we are going to process. +func getNextHandleKey(taskRange reorgBackfillTask, taskDone bool, lastAccessedHandle kv.Key) (nextHandle kv.Key) { if !taskDone { // The task is not done. So we need to pick the last processed entry's handle and add one. @@ -1181,8 +1262,8 @@ func (w *updateColumnWorker) fetchRowColVals(txn kv.Transaction, taskRange reorg taskDone := false var lastAccessedHandle kv.Key oprStartTime := startTime - err := iterateSnapshotKeys(w.reorgInfo.d.jobContext(w.reorgInfo.Job), w.sessCtx.GetStore(), w.priority, w.table.RecordPrefix(), txn.StartTS(), taskRange.startKey, taskRange.endKey, - func(handle kv.Handle, recordKey kv.Key, rawRow []byte) (bool, error) { + err := iterateSnapshotKeys(w.GetCtx().jobContext(taskRange.getJobID()), w.sessCtx.GetStore(), taskRange.priority, taskRange.physicalTable.RecordPrefix(), + txn.StartTS(), taskRange.startKey, taskRange.endKey, func(handle kv.Handle, recordKey kv.Key, rawRow []byte) (bool, error) { oprEndTime := time.Now() logSlowOperations(oprEndTime.Sub(oprStartTime), "iterateSnapshotKeys in updateColumnWorker fetchRowColVals", 0) oprStartTime = oprEndTime @@ -1213,7 +1294,7 @@ func (w *updateColumnWorker) fetchRowColVals(txn kv.Transaction, taskRange reorg } logutil.BgLogger().Debug("[ddl] txn fetches handle info", zap.Uint64("txnStartTS", txn.StartTS()), zap.String("taskRange", taskRange.String()), zap.Duration("takeTime", time.Since(startTime))) - return w.rowRecords, w.getNextKey(taskRange, taskDone, lastAccessedHandle), taskDone, errors.Trace(err) + return w.rowRecords, getNextHandleKey(taskRange, taskDone, lastAccessedHandle), taskDone, errors.Trace(err) } func (w *updateColumnWorker) getRowRecord(handle kv.Handle, recordKey []byte, rawRow []byte) error { @@ -1250,8 +1331,8 @@ func (w *updateColumnWorker) getRowRecord(handle kv.Handle, recordKey []byte, ra if err != nil { return w.reformatErrors(err) } - if w.sessCtx.GetSessionVars().StmtCtx.GetWarnings() != nil && len(w.sessCtx.GetSessionVars().StmtCtx.GetWarnings()) != 0 { - warn := w.sessCtx.GetSessionVars().StmtCtx.GetWarnings() + warn := w.sessCtx.GetSessionVars().StmtCtx.GetWarnings() + if len(warn) != 0 { //nolint:forcetypeassert recordWarning = errors.Cause(w.reformatErrors(warn[0].Err)).(*terror.Error) } @@ -1323,8 +1404,8 @@ func (w *updateColumnWorker) BackfillDataInTxn(handleRange reorgBackfillTask) (t errInTxn = kv.RunInNewTxn(ctx, w.sessCtx.GetStore(), true, func(ctx context.Context, txn kv.Transaction) error { taskCtx.addedCount = 0 taskCtx.scanCount = 0 - txn.SetOption(kv.Priority, w.priority) - if tagger := w.reorgInfo.d.getResourceGroupTaggerForTopSQL(w.reorgInfo.Job); tagger != nil { + txn.SetOption(kv.Priority, handleRange.priority) + if tagger := w.GetCtx().getResourceGroupTaggerForTopSQL(handleRange.getJobID()); tagger != nil { txn.SetOption(kv.ResourceGroupTagger, tagger) } @@ -1335,8 +1416,9 @@ func (w *updateColumnWorker) BackfillDataInTxn(handleRange reorgBackfillTask) (t taskCtx.nextKey = nextKey taskCtx.done = taskDone - warningsMap := make(map[errors.ErrorID]*terror.Error, len(rowRecords)) - warningsCountMap := make(map[errors.ErrorID]int64, len(rowRecords)) + // Optimize for few warnings! + warningsMap := make(map[errors.ErrorID]*terror.Error, 2) + warningsCountMap := make(map[errors.ErrorID]int64, 2) for _, rowRecord := range rowRecords { taskCtx.scanCount++ @@ -1449,6 +1531,7 @@ func adjustTableInfoAfterModifyColumn( tblInfo.MoveColumnInfo(oldCol.Offset, destOffset) updateNewIdxColsNameOffset(tblInfo.Indices, oldCol.Name, newCol) updateFKInfoWhenModifyColumn(tblInfo, oldCol.Name, newCol.Name) + updateTTLInfoWhenModifyColumn(tblInfo, oldCol.Name, newCol.Name) return nil } @@ -1500,7 +1583,7 @@ func checkAndApplyAutoRandomBits(d *ddlCtx, m *meta.Meta, dbInfo *model.DBInfo, return nil } idAcc := m.GetAutoIDAccessors(dbInfo.ID, tblInfo.ID) - err := checkNewAutoRandomBits(idAcc, oldCol, newCol, newAutoRandBits, tblInfo.AutoRandomRangeBits, tblInfo.Version) + err := checkNewAutoRandomBits(idAcc, oldCol, newCol, newAutoRandBits, tblInfo.AutoRandomRangeBits, tblInfo.SepAutoInc()) if err != nil { return err } @@ -1509,13 +1592,17 @@ func checkAndApplyAutoRandomBits(d *ddlCtx, m *meta.Meta, dbInfo *model.DBInfo, // checkNewAutoRandomBits checks whether the new auto_random bits number can cause overflow. func checkNewAutoRandomBits(idAccessors meta.AutoIDAccessors, oldCol *model.ColumnInfo, - newCol *model.ColumnInfo, newShardBits, newRangeBits uint64, tblVer uint16) error { + newCol *model.ColumnInfo, newShardBits, newRangeBits uint64, sepAutoInc bool) error { shardFmt := autoid.NewShardIDFormat(&newCol.FieldType, newShardBits, newRangeBits) idAcc := idAccessors.RandomID() convertedFromAutoInc := mysql.HasAutoIncrementFlag(oldCol.GetFlag()) if convertedFromAutoInc { - idAcc = idAccessors.IncrementID(tblVer) + if sepAutoInc { + idAcc = idAccessors.IncrementID(model.TableInfoVersion5) + } else { + idAcc = idAccessors.RowID() + } } // Generate a new auto ID first to prevent concurrent update in DML. _, err := idAcc.Inc(1) @@ -1626,6 +1713,15 @@ func updateColumnDefaultValue(d *ddlCtx, t *meta.Meta, job *model.Job, newCol *m job.State = model.JobStateCancelled return ver, infoschema.ErrColumnNotExists.GenWithStackByArgs(newCol.Name, tblInfo.Name) } + + if hasDefaultValue, _, err := checkColumnDefaultValue(newContext(d.store), table.ToColumn(oldCol.Clone()), newCol.DefaultValue); err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } else if !hasDefaultValue { + job.State = model.JobStateCancelled + return ver, dbterror.ErrInvalidDefaultValue.GenWithStackByArgs(newCol.Name) + } + // The newCol's offset may be the value of the old schema version, so we can't use newCol directly. oldCol.DefaultValue = newCol.DefaultValue oldCol.DefaultValueBit = newCol.DefaultValueBit diff --git a/ddl/column_change_test.go b/ddl/column_change_test.go index 4528564d2f231..be393dd488668 100644 --- a/ddl/column_change_test.go +++ b/ddl/column_change_test.go @@ -437,3 +437,36 @@ func testNewContext(store kv.Storage) sessionctx.Context { ctx.Store = store return ctx } + +func TestIssue40150(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("CREATE TABLE t40150 (a int) PARTITION BY HASH (a) PARTITIONS 2") + tk.MustContainErrMsg(`alter table t40150 rename column a to c`, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") +} + +func TestIssue40135(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk1 := testkit.NewTestKit(t, store) + tk1.MustExec("use test") + + tk.MustExec("CREATE TABLE t40135 ( a tinyint DEFAULT NULL, b varchar(32) DEFAULT 'md') PARTITION BY HASH (a) PARTITIONS 2") + one := true + hook := &ddl.TestDDLCallback{Do: dom} + var checkErr error + hook.OnJobRunBeforeExported = func(job *model.Job) { + if one { + one = false + _, checkErr = tk1.Exec("alter table t40135 change column a aNew SMALLINT NULL DEFAULT '-14996'") + } + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t40135 modify column a MEDIUMINT NULL DEFAULT '6243108' FIRST") + + require.ErrorContains(t, checkErr, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") +} diff --git a/ddl/column_modify_test.go b/ddl/column_modify_test.go index f933182737d05..a8bb6e669a68f 100644 --- a/ddl/column_modify_test.go +++ b/ddl/column_modify_test.go @@ -289,8 +289,7 @@ func TestDropColumn(t *testing.T) { tk.MustExec("drop table if exists t1") tk.MustExec("create table t1 (a int,b int) partition by hash(a) partitions 4;") err := tk.ExecToErr("alter table t1 drop column a") - // TODO: refine the error message to compatible with MySQL - require.EqualError(t, err, "[planner:1054]Unknown column 'a' in 'expression'") + require.EqualError(t, err, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") } func TestChangeColumn(t *testing.T) { @@ -689,7 +688,7 @@ func TestTransactionWithWriteOnlyColumn(t *testing.T) { dom.DDL().SetHook(hook) done := make(chan error, 1) // test transaction on add column. - go backgroundExec(store, "alter table t1 add column c int not null", done) + go backgroundExec(store, "test", "alter table t1 add column c int not null", done) err := <-done require.NoError(t, err) require.NoError(t, checkErr) @@ -697,7 +696,7 @@ func TestTransactionWithWriteOnlyColumn(t *testing.T) { tk.MustExec("delete from t1") // test transaction on drop column. - go backgroundExec(store, "alter table t1 drop column c", done) + go backgroundExec(store, "test", "alter table t1 drop column c", done) err = <-done require.NoError(t, err) require.NoError(t, checkErr) @@ -1030,77 +1029,3 @@ func TestColumnTypeChangeGenUniqueChangingName(t *testing.T) { tk.MustExec("drop table if exists t") } - -func TestWriteReorgForColumnTypeChangeOnAmendTxn(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, columnModifyLease) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk.MustExec("set global tidb_enable_amend_pessimistic_txn = ON") - defer tk.MustExec("set global tidb_enable_amend_pessimistic_txn = OFF") - - d := dom.DDL() - testInsertOnModifyColumn := func(sql string, startColState, commitColState model.SchemaState, retStrs []string, retErr error) { - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t1") - tk.MustExec("create table t1 (c1 int, c2 int, c3 int, unique key(c1))") - tk.MustExec("insert into t1 values (20, 20, 20);") - - var checkErr error - tk1 := testkit.NewTestKit(t, store) - defer func() { - if tk1.Session() != nil { - tk1.Session().Close() - } - }() - hook := &ddl.TestDDLCallback{Do: dom} - times := 0 - hook.OnJobRunBeforeExported = func(job *model.Job) { - if job.Type != model.ActionModifyColumn || checkErr != nil || job.SchemaState != startColState { - return - } - - tk1.MustExec("use test") - tk1.MustExec("begin pessimistic;") - tk1.MustExec("insert into t1 values(101, 102, 103)") - } - onJobUpdatedExportedFunc := func(job *model.Job) { - if job.Type != model.ActionModifyColumn || checkErr != nil || job.SchemaState != commitColState { - return - } - if times == 0 { - _, checkErr = tk1.Exec("commit;") - } - times++ - } - hook.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) - d.SetHook(hook) - - tk.MustExec(sql) - if retErr == nil { - require.NoError(t, checkErr) - } else { - require.Error(t, checkErr) - require.Contains(t, checkErr.Error(), retErr.Error()) - } - tk.MustQuery("select * from t1").Check(testkit.Rows(retStrs...)) - tk.MustExec("admin check table t1") - } - - // Testing it needs reorg data. - ddlStatement := "alter table t1 change column c2 cc smallint;" - testInsertOnModifyColumn(ddlStatement, model.StateNone, model.StateWriteReorganization, []string{"20 20 20"}, domain.ErrInfoSchemaChanged) - testInsertOnModifyColumn(ddlStatement, model.StateDeleteOnly, model.StateWriteReorganization, []string{"20 20 20"}, domain.ErrInfoSchemaChanged) - testInsertOnModifyColumn(ddlStatement, model.StateWriteOnly, model.StateWriteReorganization, []string{"20 20 20"}, domain.ErrInfoSchemaChanged) - testInsertOnModifyColumn(ddlStatement, model.StateNone, model.StatePublic, []string{"20 20 20"}, domain.ErrInfoSchemaChanged) - testInsertOnModifyColumn(ddlStatement, model.StateDeleteOnly, model.StatePublic, []string{"20 20 20"}, domain.ErrInfoSchemaChanged) - testInsertOnModifyColumn(ddlStatement, model.StateWriteOnly, model.StatePublic, []string{"20 20 20"}, domain.ErrInfoSchemaChanged) - - // Testing it needs not reorg data. This case only have two states: none, public. - ddlStatement = "alter table t1 change column c2 cc bigint;" - testInsertOnModifyColumn(ddlStatement, model.StateNone, model.StateWriteReorganization, []string{"20 20 20"}, nil) - testInsertOnModifyColumn(ddlStatement, model.StateWriteOnly, model.StateWriteReorganization, []string{"20 20 20"}, nil) - testInsertOnModifyColumn(ddlStatement, model.StateNone, model.StatePublic, []string{"20 20 20", "101 102 103"}, nil) - testInsertOnModifyColumn(ddlStatement, model.StateWriteOnly, model.StatePublic, []string{"20 20 20"}, nil) -} diff --git a/ddl/column_test.go b/ddl/column_test.go index cae9a27318dec..e6c48b1121595 100644 --- a/ddl/column_test.go +++ b/ddl/column_test.go @@ -959,3 +959,65 @@ func TestGetDefaultValueOfColumn(t *testing.T) { tk.MustQuery("select * from t1").Check(testkit.RowsWithSep("|", ""+ "1962-03-03 1962-03-03 00:00:00 12:23:23 2020-10-13 2020-03-27")) } + +func TestIssue39080(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("CREATE TABLE t1(id INTEGER PRIMARY KEY, authorId INTEGER AUTO_INCREMENT UNIQUE)") + + tk.MustQuery("show create table t1").Check(testkit.RowsWithSep("|", ""+ + "t1 CREATE TABLE `t1` (\n"+ + " `id` int(11) NOT NULL,\n"+ + " `authorId` int(11) NOT NULL AUTO_INCREMENT,\n"+ + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n"+ + " UNIQUE KEY `authorId` (`authorId`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + //Do not affect the specified name + tk.MustExec("CREATE TABLE `t2`( `id` INTEGER PRIMARY KEY, `authorId` int(11) AUTO_INCREMENT, UNIQUE KEY `authorIdx` (`authorId`))") + + tk.MustQuery("show create table t2").Check(testkit.RowsWithSep("|", ""+ + "t2 CREATE TABLE `t2` (\n"+ + " `id` int(11) NOT NULL,\n"+ + " `authorId` int(11) NOT NULL AUTO_INCREMENT,\n"+ + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n"+ + " UNIQUE KEY `authorIdx` (`authorId`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) +} + +func TestWriteDataWriteOnlyMode(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, dbTestLease) + + tk := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2.MustExec("use test") + tk.MustExec("CREATE TABLE t (`col1` bigint(20) DEFAULT 1,`col2` float,UNIQUE KEY `key1` (`col1`))") + + originalCallback := dom.DDL().GetHook() + defer dom.DDL().SetHook(originalCallback) + + hook := &ddl.TestDDLCallback{Do: dom} + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.SchemaState != model.StateWriteOnly { + return + } + tk2.MustExec("insert ignore into t values (1, 2)") + tk2.MustExec("insert ignore into t values (2, 2)") + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t change column `col1` `col1` varchar(20)") + + hook = &ddl.TestDDLCallback{Do: dom} + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.SchemaState != model.StateWriteOnly { + return + } + tk2.MustExec("insert ignore into t values (1)") + tk2.MustExec("insert ignore into t values (2)") + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t drop column `col1`") + dom.DDL().SetHook(originalCallback) +} diff --git a/ddl/column_type_change_test.go b/ddl/column_type_change_test.go index ae0adda97b99b..308a815773ce9 100644 --- a/ddl/column_type_change_test.go +++ b/ddl/column_type_change_test.go @@ -1812,8 +1812,7 @@ func TestChangingAttributeOfColumnWithFK(t *testing.T) { tk.MustExec("use test") prepare := func() { - tk.MustExec("drop table if exists users") - tk.MustExec("drop table if exists orders") + tk.MustExec("drop table if exists users, orders") tk.MustExec("CREATE TABLE users (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, doc JSON);") tk.MustExec("CREATE TABLE orders (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, doc JSON, FOREIGN KEY fk_user_id (user_id) REFERENCES users(id));") } @@ -1946,7 +1945,7 @@ func TestChangeIntToBitWillPanicInBackfillIndexes(t *testing.T) { " KEY `idx3` (`a`,`b`),\n" + " KEY `idx4` (`a`,`b`,`c`)\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - tk.MustQuery("select * from t").Check(testkit.Rows("\x13 1 1.00", "\x11 2 2.00")) + tk.MustQuery("select * from t").Sort().Check(testkit.Rows("\x11 2 2.00", "\x13 1 1.00")) } // Close issue #24584 @@ -2422,3 +2421,18 @@ func TestColumnTypeChangeTimestampToInt(t *testing.T) { tk.MustExec("alter table t add index idx1(id, c1);") tk.MustExec("admin check table t") } + +func TestFixDDLTxnWillConflictWithReorgTxn(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("create table t (a int)") + tk.MustExec("set global tidb_ddl_enable_fast_reorg = OFF") + tk.MustExec("alter table t add index(a)") + tk.MustExec("set @@sql_mode=''") + tk.MustExec("insert into t values(128),(129)") + tk.MustExec("alter table t modify column a tinyint") + + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1690 2 warnings with this error code, first warning: constant 128 overflows tinyint")) +} diff --git a/ddl/concurrentddltest/switch_test.go b/ddl/concurrentddltest/switch_test.go deleted file mode 100644 index 5d77dcb8f7359..0000000000000 --- a/ddl/concurrentddltest/switch_test.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2022 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package concurrentddltest - -import ( - "context" - "fmt" - "math/rand" - "testing" - "time" - - "github.com/pingcap/tidb/kv" - "github.com/pingcap/tidb/meta" - "github.com/pingcap/tidb/testkit" - "github.com/pingcap/tidb/util" - "github.com/stretchr/testify/require" - "go.uber.org/atomic" -) - -func TestConcurrentDDLSwitch(t *testing.T) { - store := testkit.CreateMockStore(t) - - type table struct { - columnIdx int - indexIdx int - } - - var tables []*table - tblCount := 20 - for i := 0; i < tblCount; i++ { - tables = append(tables, &table{1, 0}) - } - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk.MustExec("set @@global.tidb_ddl_reorg_worker_cnt=1") - tk.MustExec("set @@global.tidb_ddl_reorg_batch_size=32") - - for i := range tables { - tk.MustExec(fmt.Sprintf("create table t%d (col0 int)", i)) - for j := 0; j < 1000; j++ { - tk.MustExec(fmt.Sprintf("insert into t%d values (%d)", i, j)) - } - } - - ddls := make([]string, 0, tblCount) - ddlCount := 100 - for i := 0; i < ddlCount; i++ { - tblIdx := rand.Intn(tblCount) - if rand.Intn(2) == 0 { - ddls = append(ddls, fmt.Sprintf("alter table t%d add index idx%d (col0)", tblIdx, tables[tblIdx].indexIdx)) - tables[tblIdx].indexIdx++ - } else { - ddls = append(ddls, fmt.Sprintf("alter table t%d add column col%d int", tblIdx, tables[tblIdx].columnIdx)) - tables[tblIdx].columnIdx++ - } - } - - c := atomic.NewInt32(0) - ch := make(chan struct{}) - go func() { - var wg util.WaitGroupWrapper - for i := range ddls { - wg.Add(1) - go func(idx int) { - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec(ddls[idx]) - c.Add(1) - wg.Done() - }(i) - } - wg.Wait() - ch <- struct{}{} - }() - - ticker := time.NewTicker(time.Second) - count := 0 - done := false - for !done { - select { - case <-ch: - done = true - case <-ticker.C: - var b bool - var err error - err = kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, false, func(ctx context.Context, txn kv.Transaction) error { - b, err = meta.NewMeta(txn).IsConcurrentDDL() - return err - }) - require.NoError(t, err) - rs, err := testkit.NewTestKit(t, store).Exec(fmt.Sprintf("set @@global.tidb_enable_concurrent_ddl=%t", !b)) - if rs != nil { - require.NoError(t, rs.Close()) - } - if err == nil { - count++ - if b { - tk := testkit.NewTestKit(t, store) - tk.MustQuery("select count(*) from mysql.tidb_ddl_job").Check(testkit.Rows("0")) - tk.MustQuery("select count(*) from mysql.tidb_ddl_reorg").Check(testkit.Rows("0")) - } - } - } - } - - require.Equal(t, int32(ddlCount), c.Load()) - require.Greater(t, count, 0) - - tk = testkit.NewTestKit(t, store) - tk.MustExec("use test") - for i, tbl := range tables { - tk.MustQuery(fmt.Sprintf("select count(*) from information_schema.columns where TABLE_SCHEMA = 'test' and TABLE_NAME = 't%d'", i)).Check(testkit.Rows(fmt.Sprintf("%d", tbl.columnIdx))) - tk.MustExec(fmt.Sprintf("admin check table t%d", i)) - for j := 0; j < tbl.indexIdx; j++ { - tk.MustExec(fmt.Sprintf("admin check index t%d idx%d", i, j)) - } - } -} diff --git a/ddl/constant.go b/ddl/constant.go index bf4d69fb8fd33..3fe6bf4a04ee6 100644 --- a/ddl/constant.go +++ b/ddl/constant.go @@ -25,6 +25,10 @@ const ( ReorgTable = "tidb_ddl_reorg" // HistoryTable stores the history DDL jobs. HistoryTable = "tidb_ddl_history" + // BackfillTable stores the information of backfill jobs. + BackfillTable = "tidb_ddl_backfill" + // BackfillHistoryTable stores the information of history backfill jobs. + BackfillHistoryTable = "tidb_ddl_backfill_history" // JobTableID is the table ID of `tidb_ddl_job`. JobTableID = meta.MaxInt48 - 1 @@ -34,6 +38,10 @@ const ( HistoryTableID = meta.MaxInt48 - 3 // MDLTableID is the table ID of `tidb_mdl_info`. MDLTableID = meta.MaxInt48 - 4 + // BackfillTableID is the table ID of `tidb_ddl_backfill`. + BackfillTableID = meta.MaxInt48 - 5 + // BackfillHistoryTableID is the table ID of `tidb_ddl_backfill_history`. + BackfillHistoryTableID = meta.MaxInt48 - 6 // JobTableSQL is the CREATE TABLE SQL of `tidb_ddl_job`. JobTableSQL = "create table " + JobTable + "(job_id bigint not null, reorg int, schema_ids text(65535), table_ids text(65535), job_meta longblob, type int, processing int, primary key(job_id))" @@ -41,4 +49,42 @@ const ( ReorgTableSQL = "create table " + ReorgTable + "(job_id bigint not null, ele_id bigint, ele_type blob, start_key blob, end_key blob, physical_id bigint, reorg_meta longblob, unique key(job_id, ele_id, ele_type(20)))" // HistoryTableSQL is the CREATE TABLE SQL of `tidb_ddl_history`. HistoryTableSQL = "create table " + HistoryTable + "(job_id bigint not null, job_meta longblob, db_name char(64), table_name char(64), schema_ids text(65535), table_ids text(65535), create_time datetime, primary key(job_id))" + // BackfillTableSQL is the CREATE TABLE SQL of `tidb_ddl_backfill`. + BackfillTableSQL = "create table " + BackfillTable + `( + id bigint not null, + ddl_job_id bigint not null, + ele_id bigint not null, + ele_key blob, + store_id bigint, + type int, + exec_id blob default null, + exec_lease Time, + state int, + curr_key blob, + start_key blob, + end_key blob, + start_ts bigint, + finish_ts bigint, + row_count bigint, + backfill_meta longblob, + unique key(ddl_job_id, ele_id, ele_key(20), id))` + // BackfillHistoryTableSQL is the CREATE TABLE SQL of `tidb_ddl_backfill_history`. + BackfillHistoryTableSQL = "create table " + BackfillHistoryTable + `( + id bigint not null, + ddl_job_id bigint not null, + ele_id bigint not null, + ele_key blob, + store_id bigint, + type int, + exec_id blob default null, + exec_lease Time, + state int, + curr_key blob, + start_key blob, + end_key blob, + start_ts bigint, + finish_ts bigint, + row_count bigint, + backfill_meta longblob, + unique key(ddl_job_id, ele_id, ele_key(20), id))` ) diff --git a/ddl/db_cache_test.go b/ddl/db_cache_test.go index 6506f24e4ef0d..012ac09ac7375 100644 --- a/ddl/db_cache_test.go +++ b/ddl/db_cache_test.go @@ -232,7 +232,14 @@ func TestCacheTableSizeLimit(t *testing.T) { } time.Sleep(50 * time.Millisecond) } - require.True(t, cached) + + // require.True(t, cached) + if !cached { + // cached should be true, but it depends on the hardward. + // If the CI environment is too slow, 200 iteration would not be enough, + // check the result makes this test unstable, so skip the following. + return + } // Forbit the insert once the table size limit is detected. tk.MustGetErrCode("insert into cache_t2 select * from tmp;", errno.ErrOptOnCacheTable) diff --git a/ddl/db_change_test.go b/ddl/db_change_test.go index d865c970e7f42..da49688ccc608 100644 --- a/ddl/db_change_test.go +++ b/ddl/db_change_test.go @@ -1712,6 +1712,14 @@ func TestCreateExpressionIndex(t *testing.T) { require.NoError(t, checkErr) tk.MustExec("admin check table t") tk.MustQuery("select * from t order by a, b").Check(testkit.Rows("0 9", "0 11", "0 11", "1 7", "2 7", "5 7", "8 8", "10 10", "10 10")) + + // https://github.com/pingcap/tidb/issues/39784 + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(name varchar(20))") + tk.MustExec("insert into t values ('Abc'), ('Bcd'), ('abc')") + tk.MustExec("create index idx on test.t((lower(test.t.name)))") + tk.MustExec("admin check table t") } func TestCreateUniqueExpressionIndex(t *testing.T) { @@ -1738,8 +1746,6 @@ func TestCreateUniqueExpressionIndex(t *testing.T) { if checkErr != nil { return } - err := originalCallback.OnChanged(nil) - require.NoError(t, err) switch job.SchemaState { case model.StateDeleteOnly: for _, sql := range stateDeleteOnlySQLs { diff --git a/ddl/db_foreign_key_test.go b/ddl/db_foreign_key_test.go index dc60b53112291..f45db3934d89a 100644 --- a/ddl/db_foreign_key_test.go +++ b/ddl/db_foreign_key_test.go @@ -26,8 +26,7 @@ func TestDuplicateForeignKey(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("drop table if exists t1") + tk.MustExec("drop table if exists t, t1") // Foreign table. tk.MustExec("create table t(id int key)") // Create target table with duplicate fk. @@ -38,8 +37,7 @@ func TestDuplicateForeignKey(t *testing.T) { // Alter target table with duplicate fk. tk.MustGetErrCode("alter table t1 add CONSTRAINT `fk_aaa` FOREIGN KEY (`id_fk`) REFERENCES `t` (`id`)", mysql.ErrFkDupName) tk.MustGetErrCode("alter table t1 add CONSTRAINT `fk_aAa` FOREIGN KEY (`id_fk`) REFERENCES `t` (`id`)", mysql.ErrFkDupName) - tk.MustExec("drop table if exists t") - tk.MustExec("drop table if exists t1") + tk.MustExec("drop table if exists t, t1") } func TestTemporaryTableForeignKey(t *testing.T) { diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index 7c53b2495917d..a893f15899f41 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -26,6 +26,7 @@ import ( "time" "github.com/pingcap/errors" + _ "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/ddl/schematracker" @@ -1214,14 +1215,14 @@ func TestBitDefaultValue(t *testing.T) { );`) } -func backgroundExec(s kv.Storage, sql string, done chan error) { +func backgroundExec(s kv.Storage, schema, sql string, done chan error) { se, err := session.CreateSession4Test(s) if err != nil { done <- errors.Trace(err) return } defer se.Close() - _, err = se.Execute(context.Background(), "use test") + _, err = se.Execute(context.Background(), "use "+schema) if err != nil { done <- errors.Trace(err) return @@ -2373,11 +2374,49 @@ func TestSqlFunctionsInGeneratedColumns(t *testing.T) { tk.MustExec("create table t (a int, b int as ((a)))") } +func TestSchemaNameAndTableNameInGeneratedExpr(t *testing.T) { + store := testkit.CreateMockStore(t, mockstore.WithDDLChecker()) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("create database if not exists test") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + + tk.MustExec("create table t(a int, b int as (lower(test.t.a)))") + tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" + + " `a` int(11) DEFAULT NULL,\n" + + " `b` int(11) GENERATED ALWAYS AS (lower(`a`)) VIRTUAL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + tk.MustExec("drop table t") + tk.MustExec("create table t(a int)") + tk.MustExec("alter table t add column b int as (lower(test.t.a))") + tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" + + " `a` int(11) DEFAULT NULL,\n" + + " `b` int(11) GENERATED ALWAYS AS (lower(`a`)) VIRTUAL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + tk.MustGetErrCode("alter table t add index idx((lower(test.t1.a)))", errno.ErrBadField) + + tk.MustExec("drop table t") + tk.MustGetErrCode("create table t(a int, b int as (lower(test1.t.a)))", errno.ErrWrongDBName) + + tk.MustExec("create table t(a int)") + tk.MustGetErrCode("alter table t add column b int as (lower(test.t1.a))", errno.ErrWrongTableName) + + tk.MustExec("alter table t add column c int") + tk.MustGetErrCode("alter table t modify column c int as (test.t1.a + 1) stored", errno.ErrWrongTableName) + + tk.MustExec("alter table t add column d int as (lower(test.T.a))") + tk.MustExec("alter table t add column e int as (lower(Test.t.a))") +} + func TestParserIssue284(t *testing.T) { store := testkit.CreateMockStore(t, mockstore.WithDDLChecker()) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set @@foreign_key_checks=0") tk.MustExec("create table test.t_parser_issue_284(c1 int not null primary key)") _, err := tk.Exec("create table test.t_parser_issue_284_2(id int not null primary key, c1 int not null, constraint foreign key (c1) references t_parser_issue_284(c1))") require.NoError(t, err) @@ -2894,17 +2933,23 @@ func TestAutoIncrementTableOption(t *testing.T) { tk.MustExec("create database test_auto_inc_table_opt;") tk.MustExec("use test_auto_inc_table_opt;") - // Empty auto_inc allocator should not cause error. - tk.MustExec("create table t (a bigint primary key clustered) auto_increment = 10;") - tk.MustExec("alter table t auto_increment = 10;") - tk.MustExec("alter table t auto_increment = 12345678901234567890;") - - // Rebase the auto_inc allocator to a large integer should work. - tk.MustExec("drop table t;") - tk.MustExec("create table t (a bigint unsigned auto_increment, unique key idx(a));") - tk.MustExec("alter table t auto_increment = 12345678901234567890;") - tk.MustExec("insert into t values ();") - tk.MustQuery("select * from t;").Check(testkit.Rows("12345678901234567890")) + for _, str := range []string{"", " AUTO_ID_CACHE 1"} { + // Empty auto_inc allocator should not cause error. + tk.MustExec("create table t (a bigint primary key clustered) auto_increment = 10" + str) + tk.MustExec("alter table t auto_increment = 10;") + tk.MustExec("alter table t auto_increment = 12345678901234567890;") + tk.MustExec("drop table t;") + + // Rebase the auto_inc allocator to a large integer should work. + tk.MustExec("create table t (a bigint unsigned auto_increment, unique key idx(a))" + str) + // Set auto_inc to negative is not supported + err := tk.ExecToErr("alter table t auto_increment = -1;") + require.Error(t, err) + tk.MustExec("alter table t auto_increment = 12345678901234567890;") + tk.MustExec("insert into t values ();") + tk.MustQuery("select * from t;").Check(testkit.Rows("12345678901234567890")) + tk.MustExec("drop table t;") + } } func TestAutoIncrementForce(t *testing.T) { @@ -2919,8 +2964,9 @@ func TestAutoIncrementForce(t *testing.T) { require.NoError(t, err) return gid } + // Rebase _tidb_row_id. - tk.MustExec("create table t (a int);") + tk.MustExec("create table t (a int)") tk.MustExec("alter table t force auto_increment = 2;") tk.MustExec("insert into t values (1),(2);") tk.MustQuery("select a, _tidb_rowid from t;").Check(testkit.Rows("1 2", "2 3")) @@ -2930,12 +2976,12 @@ func TestAutoIncrementForce(t *testing.T) { require.Equal(t, uint64(1), getNextGlobalID()) // inserting new rows can overwrite the existing data. tk.MustExec("insert into t values (3);") - require.Equal(t, "[kv:1062]Duplicate entry '2' for key 'PRIMARY'", tk.ExecToErr("insert into t values (3);").Error()) + require.Equal(t, "[kv:1062]Duplicate entry '2' for key 't.PRIMARY'", tk.ExecToErr("insert into t values (3);").Error()) tk.MustQuery("select a, _tidb_rowid from t;").Check(testkit.Rows("3 1", "1 2", "2 3")) + tk.MustExec("drop table if exists t;") // Rebase auto_increment. - tk.MustExec("drop table if exists t;") - tk.MustExec("create table t (a int primary key auto_increment, b int);") + tk.MustExec("create table t (a int primary key auto_increment, b int)") tk.MustExec("insert into t values (1, 1);") tk.MustExec("insert into t values (100000000, 1);") tk.MustExec("delete from t where a = 100000000;") @@ -2946,10 +2992,10 @@ func TestAutoIncrementForce(t *testing.T) { require.Equal(t, uint64(2), getNextGlobalID()) tk.MustExec("insert into t(b) values (2);") tk.MustQuery("select a, b from t;").Check(testkit.Rows("1 1", "2 2")) + tk.MustExec("drop table if exists t;") // Rebase auto_random. - tk.MustExec("drop table if exists t;") - tk.MustExec("create table t (a bigint primary key auto_random(5));") + tk.MustExec("create table t (a bigint primary key auto_random(5))") tk.MustExec("insert into t values ();") tk.MustExec("set @@allow_auto_random_explicit_insert = true") tk.MustExec("insert into t values (100000000);") @@ -2961,14 +3007,15 @@ func TestAutoIncrementForce(t *testing.T) { require.Equal(t, uint64(2), getNextGlobalID()) tk.MustExec("insert into t values ();") tk.MustQuery("select (a & 3) from t order by 1;").Check(testkit.Rows("1", "2")) + tk.MustExec("drop table if exists t;") // Change next global ID. - tk.MustExec("drop table if exists t;") - tk.MustExec("create table t (a bigint primary key auto_increment);") + tk.MustExec("create table t (a bigint primary key auto_increment)") tk.MustExec("insert into t values (1);") bases := []uint64{1, 65535, 10, math.MaxUint64, math.MaxInt64 + 1, 1, math.MaxUint64, math.MaxInt64, 2} lastBase := fmt.Sprintf("%d", bases[len(bases)-1]) for _, b := range bases { + fmt.Println("execute alter table force increment to ==", b) tk.MustExec(fmt.Sprintf("alter table t force auto_increment = %d;", b)) require.Equal(t, b, getNextGlobalID()) } @@ -2976,7 +3023,7 @@ func TestAutoIncrementForce(t *testing.T) { tk.MustQuery("select a from t;").Check(testkit.Rows("1", lastBase)) // Force alter unsigned int auto_increment column. tk.MustExec("drop table if exists t;") - tk.MustExec("create table t (a bigint unsigned primary key auto_increment);") + tk.MustExec("create table t (a bigint unsigned primary key auto_increment)") for _, b := range bases { tk.MustExec(fmt.Sprintf("alter table t force auto_increment = %d;", b)) require.Equal(t, b, getNextGlobalID()) @@ -2984,10 +3031,10 @@ func TestAutoIncrementForce(t *testing.T) { tk.MustQuery("select a from t;").Check(testkit.Rows(fmt.Sprintf("%d", b))) tk.MustExec("delete from t;") } + tk.MustExec("drop table if exists t;") // Force alter with @@auto_increment_increment and @@auto_increment_offset. - tk.MustExec("drop table if exists t;") - tk.MustExec("create table t(a int key auto_increment);") + tk.MustExec("create table t(a int key auto_increment)") tk.MustExec("set @@auto_increment_offset=2;") tk.MustExec("set @@auto_increment_increment = 11;") tk.MustExec("insert into t values (500);") @@ -3015,6 +3062,135 @@ func TestAutoIncrementForce(t *testing.T) { tk.MustExec("drop table t") } +func TestAutoIncrementForceAutoIDCache(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists auto_inc_force;") + tk.MustExec("create database auto_inc_force;") + tk.MustExec("use auto_inc_force;") + getNextGlobalID := func() uint64 { + gidStr := tk.MustQuery("show table t next_row_id").Rows()[0][3] + gid, err := strconv.ParseUint(gidStr.(string), 10, 64) + require.NoError(t, err) + return gid + } + + // When AUTO_ID_CACHE is 1, row id and auto increment id use separate allocator, so the behaviour differs. + // "Alter table t force auto_increment" has no effect on row id. + tk.MustExec("create table t (a int) AUTO_ID_CACHE 1") + tk.MustExec("alter table t force auto_increment = 2;") + tk.MustExec("insert into t values (1),(2);") + tk.MustQuery("select a, _tidb_rowid from t;").Check(testkit.Rows("1 1", "2 2")) + // Cannot set next global ID to 0. + tk.MustExec("alter table t force auto_increment = 0;") + tk.MustExec("alter table t force auto_increment = 1;") + tk.MustQuery("show table t next_row_id").Check(testkit.Rows( + "auto_inc_force t _tidb_rowid 5001 _TIDB_ROWID", + )) + + // inserting new rows can overwrite the existing data. + tk.MustExec("insert into t values (3);") + tk.MustExec("insert into t values (3);") + tk.MustQuery("select a, _tidb_rowid from t;").Check(testkit.Rows("1 1", "2 2", "3 5001", "3 5002")) + tk.MustExec("drop table if exists t;") + + // Rebase auto_increment. + tk.MustExec("create table t (a int primary key auto_increment, b int) AUTO_ID_CACHE 1") + tk.MustExec("insert into t values (1, 1);") + tk.MustExec("insert into t values (100000000, 1);") + tk.MustExec("delete from t where a = 100000000;") + tk.MustQuery("show table t next_row_id").Check(testkit.Rows( + "auto_inc_force t a 1 _TIDB_ROWID", + "auto_inc_force t a 100000001 AUTO_INCREMENT", + )) + // Cannot set next global ID to 0. + tk.MustGetErrCode("alter table t /*T![force_inc] force */ auto_increment = 0;", errno.ErrAutoincReadFailed) + tk.MustExec("alter table t /*T![force_inc] force */ auto_increment = 2;") + tk.MustQuery("show table t next_row_id").Check(testkit.Rows( + "auto_inc_force t a 1 _TIDB_ROWID", + "auto_inc_force t a 2 AUTO_INCREMENT", + )) + + tk.MustExec("insert into t(b) values (2);") + tk.MustQuery("select a, b from t;").Check(testkit.Rows("1 1", "2 2")) + tk.MustExec("drop table if exists t;") + + // Rebase auto_random. + tk.MustExec("create table t (a bigint primary key auto_random(5)) AUTO_ID_CACHE 1") + tk.MustExec("insert into t values ();") + tk.MustExec("set @@allow_auto_random_explicit_insert = true") + tk.MustExec("insert into t values (100000000);") + tk.MustExec("delete from t where a = 100000000;") + require.Greater(t, getNextGlobalID(), uint64(100000000)) + // Cannot set next global ID to 0. + tk.MustGetErrCode("alter table t force auto_random_base = 0;", errno.ErrAutoincReadFailed) + tk.MustExec("alter table t force auto_random_base = 2;") + require.Equal(t, uint64(2), getNextGlobalID()) + tk.MustExec("insert into t values ();") + tk.MustQuery("select (a & 3) from t order by 1;").Check(testkit.Rows("1", "2")) + tk.MustExec("drop table if exists t;") + + // Change next global ID. + tk.MustExec("create table t (a bigint primary key auto_increment) AUTO_ID_CACHE 1") + tk.MustExec("insert into t values (1);") + bases := []uint64{1, 65535, 10, math.MaxUint64, math.MaxInt64 + 1, 1, math.MaxUint64, math.MaxInt64, 2} + lastBase := fmt.Sprintf("%d", bases[len(bases)-1]) + for _, b := range bases { + fmt.Println("execute alter table force increment to ==", b) + tk.MustExec(fmt.Sprintf("alter table t force auto_increment = %d;", b)) + tk.MustQuery("show table t next_row_id").Check(testkit.Rows( + "auto_inc_force t a 1 _TIDB_ROWID", + fmt.Sprintf("auto_inc_force t a %d AUTO_INCREMENT", b), + )) + } + tk.MustExec("insert into t values ();") + tk.MustQuery("select a from t;").Check(testkit.Rows("1", lastBase)) + // Force alter unsigned int auto_increment column. + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (a bigint unsigned primary key auto_increment) AUTO_ID_CACHE 1") + for _, b := range bases { + tk.MustExec(fmt.Sprintf("alter table t force auto_increment = %d;", b)) + tk.MustQuery("show table t next_row_id").Check(testkit.Rows( + "auto_inc_force t a 1 _TIDB_ROWID", + fmt.Sprintf("auto_inc_force t a %d AUTO_INCREMENT", b), + )) + tk.MustExec("insert into t values ();") + tk.MustQuery("select a from t;").Check(testkit.Rows(fmt.Sprintf("%d", b))) + tk.MustExec("delete from t;") + } + tk.MustExec("drop table if exists t;") + + // Force alter with @@auto_increment_increment and @@auto_increment_offset. + tk.MustExec("create table t(a int key auto_increment) AUTO_ID_CACHE 1") + tk.MustExec("set @@auto_increment_offset=2;") + tk.MustExec("set @@auto_increment_increment = 11;") + tk.MustExec("insert into t values (500);") + tk.MustExec("alter table t force auto_increment=100;") + tk.MustExec("insert into t values (), ();") + tk.MustQuery("select * from t;").Check(testkit.Rows("101", "112", "500")) + tk.MustQuery("select * from t order by a;").Check(testkit.Rows("101", "112", "500")) + tk.MustExec("drop table if exists t;") + + // Check for warning in case we can't set the auto_increment to the desired value + tk.MustExec("create table t(a int primary key auto_increment) AUTO_ID_CACHE 1") + tk.MustExec("insert into t values (200)") + tk.MustQuery("show create table t").Check(testkit.Rows( + "t CREATE TABLE `t` (\n" + + " `a` int(11) NOT NULL AUTO_INCREMENT,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![auto_id_cache] AUTO_ID_CACHE=1 */")) + tk.MustExec("alter table t auto_increment=100;") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 Can't reset AUTO_INCREMENT to 100 without FORCE option, using 201 instead")) + tk.MustExec("insert into t values ()") + tk.MustQuery("select * from t").Check(testkit.Rows("200", "211")) + tk.MustQuery("show create table t").Check(testkit.Rows( + "t CREATE TABLE `t` (\n" + + " `a` int(11) NOT NULL AUTO_INCREMENT,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![auto_id_cache] AUTO_ID_CACHE=1 */")) + tk.MustExec("drop table t") +} + func TestIssue20490(t *testing.T) { store := testkit.CreateMockStore(t, mockstore.WithDDLChecker()) @@ -3144,7 +3320,7 @@ func TestDuplicateErrorMessage(t *testing.T) { fields[i] = strings.Replace(val, "'", "", -1) } tk.MustGetErrMsg("alter table t add unique index t_idx(id1,"+index+")", - fmt.Sprintf("[kv:1062]Duplicate entry '1-%s' for key 't_idx'", strings.Join(fields, "-"))) + fmt.Sprintf("[kv:1062]Duplicate entry '1-%s' for key 't.t_idx'", strings.Join(fields, "-"))) } } restoreConfig() @@ -4135,3 +4311,78 @@ func TestRegexpFunctionsGeneratedColumn(t *testing.T) { tk.MustExec("drop table if exists reg_like") } + +func TestReorgPartitionRangeFailure(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`create schema reorgfail`) + tk.MustExec("use reorgfail") + + tk.MustExec("CREATE TABLE t (id int, d varchar(255)) partition by range (id) (partition p0 values less than (1000000), partition p1 values less than (2000000), partition p2 values less than (3000000))") + tk.MustContainErrMsg(`ALTER TABLE t REORGANIZE PARTITION p0,p2 INTO (PARTITION p0 VALUES LESS THAN (1000000))`, "[ddl:8200]Unsupported REORGANIZE PARTITION of RANGE; not adjacent partitions") + tk.MustContainErrMsg(`ALTER TABLE t REORGANIZE PARTITION p0,p2 INTO (PARTITION p0 VALUES LESS THAN (4000000))`, "[ddl:8200]Unsupported REORGANIZE PARTITION of RANGE; not adjacent partitions") +} + +func TestReorgPartitionDocs(t *testing.T) { + // To test what is added as partition management in the docs + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`create schema reorgdocs`) + tk.MustExec("use reorgdocs") + tk.MustExec(`CREATE TABLE members ( + id int, + fname varchar(255), + lname varchar(255), + dob date, + data json +) +PARTITION BY RANGE (YEAR(dob)) ( + PARTITION pBefore1950 VALUES LESS THAN (1950), + PARTITION p1950 VALUES LESS THAN (1960), + PARTITION p1960 VALUES LESS THAN (1970), + PARTITION p1970 VALUES LESS THAN (1980), + PARTITION p1980 VALUES LESS THAN (1990), + PARTITION p1990 VALUES LESS THAN (2000))`) + tk.MustExec(`CREATE TABLE member_level ( + id int, + level int, + achievements json +) +PARTITION BY LIST (level) ( + PARTITION l1 VALUES IN (1), + PARTITION l2 VALUES IN (2), + PARTITION l3 VALUES IN (3), + PARTITION l4 VALUES IN (4), + PARTITION l5 VALUES IN (5));`) + tk.MustExec(`ALTER TABLE members DROP PARTITION p1990`) + tk.MustExec(`ALTER TABLE member_level DROP PARTITION l5`) + tk.MustExec(`ALTER TABLE members TRUNCATE PARTITION p1980`) + tk.MustExec(`ALTER TABLE member_level TRUNCATE PARTITION l4`) + tk.MustExec("ALTER TABLE members ADD PARTITION (PARTITION `p1990to2010` VALUES LESS THAN (2010))") + tk.MustExec(`ALTER TABLE member_level ADD PARTITION (PARTITION l5_6 VALUES IN (5,6))`) + tk.MustContainErrMsg(`ALTER TABLE members ADD PARTITION (PARTITION p1990 VALUES LESS THAN (2000))`, "[ddl:1493]VALUES LESS THAN value must be strictly increasing for each partition") + tk.MustExec(`ALTER TABLE members REORGANIZE PARTITION p1990to2010 INTO +(PARTITION p1990 VALUES LESS THAN (2000), + PARTITION p2000 VALUES LESS THAN (2010), + PARTITION p2010 VALUES LESS THAN (2020), + PARTITION p2020 VALUES LESS THAN (2030), + PARTITION pMax VALUES LESS THAN (MAXVALUE))`) + tk.MustExec(`ALTER TABLE member_level REORGANIZE PARTITION l5_6 INTO +(PARTITION l5 VALUES IN (5), + PARTITION l6 VALUES IN (6))`) + tk.MustExec(`ALTER TABLE members REORGANIZE PARTITION pBefore1950,p1950 INTO (PARTITION pBefore1960 VALUES LESS THAN (1960))`) + tk.MustExec(`ALTER TABLE member_level REORGANIZE PARTITION l1,l2 INTO (PARTITION l1_2 VALUES IN (1,2))`) + tk.MustExec(`ALTER TABLE members REORGANIZE PARTITION pBefore1960,p1960,p1970,p1980,p1990,p2000,p2010,p2020,pMax INTO +(PARTITION p1800 VALUES LESS THAN (1900), + PARTITION p1900 VALUES LESS THAN (2000), + PARTITION p2000 VALUES LESS THAN (2100))`) + tk.MustExec(`ALTER TABLE member_level REORGANIZE PARTITION l1_2,l3,l4,l5,l6 INTO +(PARTITION lOdd VALUES IN (1,3,5), + PARTITION lEven VALUES IN (2,4,6))`) + tk.MustContainErrMsg(`ALTER TABLE members REORGANIZE PARTITION p1800,p2000 INTO (PARTITION p2000 VALUES LESS THAN (2100))`, "[ddl:8200]Unsupported REORGANIZE PARTITION of RANGE; not adjacent partitions") + tk.MustExec(`INSERT INTO members VALUES (313, "John", "Doe", "2022-11-22", NULL)`) + tk.MustExec(`ALTER TABLE members REORGANIZE PARTITION p2000 INTO (PARTITION p2000 VALUES LESS THAN (2050))`) + tk.MustContainErrMsg(`ALTER TABLE members REORGANIZE PARTITION p2000 INTO (PARTITION p2000 VALUES LESS THAN (2020))`, "[table:1526]Table has no partition for value 2022") + tk.MustExec(`INSERT INTO member_level (id, level) values (313, 6)`) + tk.MustContainErrMsg(`ALTER TABLE member_level REORGANIZE PARTITION lEven INTO (PARTITION lEven VALUES IN (2,4))`, "[table:1526]Table has no partition for value 6") +} diff --git a/ddl/db_partition_test.go b/ddl/db_partition_test.go index ff75ba2f41b10..9b39d309aeb19 100644 --- a/ddl/db_partition_test.go +++ b/ddl/db_partition_test.go @@ -20,6 +20,7 @@ import ( "fmt" "math/rand" "strings" + "sync" "sync/atomic" "testing" "time" @@ -49,10 +50,96 @@ import ( "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mathutil" "github.com/stretchr/testify/require" "go.uber.org/zap" ) +type allTableData struct { + keys [][]byte + vals [][]byte + tp []string +} + +// TODO: Create a more generic function that gets all accessible table ids +// from all schemas, and checks the full key space so that there are no +// keys for non-existing table IDs. Also figure out how to wait for deleteRange +// Checks that there are no accessible data after an existing table +// assumes that tableIDs are only increasing. +// To be used during failure testing of ALTER, to make sure cleanup is done. +func noNewTablesAfter(t *testing.T, ctx sessionctx.Context, tbl table.Table) { + require.NoError(t, sessiontxn.NewTxn(context.Background(), ctx)) + txn, err := ctx.Txn(true) + require.NoError(t, err) + defer func() { + err := txn.Rollback() + require.NoError(t, err) + }() + // Get max tableID (if partitioned) + tblID := tbl.Meta().ID + if pt := tbl.GetPartitionedTable(); pt != nil { + defs := pt.Meta().Partition.Definitions + { + for i := range defs { + tblID = mathutil.Max[int64](tblID, defs[i].ID) + } + } + } + prefix := tablecodec.EncodeTablePrefix(tblID + 1) + it, err := txn.Iter(prefix, nil) + require.NoError(t, err) + if it.Valid() { + foundTblID := tablecodec.DecodeTableID(it.Key()) + // There are internal table ids starting from MaxInt48 -1 and allocating decreasing ids + // Allow 0xFF of them, See JobTableID, ReorgTableID, HistoryTableID, MDLTableID + require.False(t, it.Key()[0] == 't' && foundTblID < 0xFFFFFFFFFF00, "Found table data after highest physical Table ID %d < %d", tblID, foundTblID) + } +} + +func getAllDataForPhysicalTable(t *testing.T, ctx sessionctx.Context, physTable table.PhysicalTable) allTableData { + require.NoError(t, sessiontxn.NewTxn(context.Background(), ctx)) + txn, err := ctx.Txn(true) + require.NoError(t, err) + defer func() { + err := txn.Rollback() + require.NoError(t, err) + }() + + all := allTableData{ + keys: make([][]byte, 0), + vals: make([][]byte, 0), + tp: make([]string, 0), + } + pid := physTable.GetPhysicalID() + prefix := tablecodec.EncodeTablePrefix(pid) + it, err := txn.Iter(prefix, nil) + require.NoError(t, err) + for it.Valid() { + if !it.Key().HasPrefix(prefix) { + break + } + all.keys = append(all.keys, it.Key()) + all.vals = append(all.vals, it.Value()) + if tablecodec.IsRecordKey(it.Key()) { + all.tp = append(all.tp, "Record") + tblID, kv, _ := tablecodec.DecodeRecordKey(it.Key()) + require.Equal(t, pid, tblID) + vals, _ := tablecodec.DecodeValuesBytesToStrings(it.Value()) + logutil.BgLogger().Info("Record", + zap.Int64("pid", tblID), + zap.Stringer("key", kv), + zap.Strings("values", vals)) + } else if tablecodec.IsIndexKey(it.Key()) { + all.tp = append(all.tp, "Index") + } else { + all.tp = append(all.tp, "Other") + } + err = it.Next() + require.NoError(t, err) + } + return all +} + func checkGlobalIndexCleanUpDone(t *testing.T, ctx sessionctx.Context, tblInfo *model.TableInfo, idxInfo *model.IndexInfo, pid int64) int { require.NoError(t, sessiontxn.NewTxn(context.Background(), ctx)) txn, err := ctx.Txn(true) @@ -383,7 +470,14 @@ func TestCreateTableWithHashPartition(t *testing.T) { ) PARTITION BY HASH(store_id) PARTITIONS 102400000000;`, errno.ErrTooManyPartitions) tk.MustExec("CREATE TABLE t_linear (a int, b varchar(128)) PARTITION BY LINEAR HASH(a) PARTITIONS 4") - tk.MustGetErrCode("select * from t_linear partition (p0)", errno.ErrPartitionClauseOnNonpartitioned) + tk.MustQuery(`show warnings`).Check(testkit.Rows("Warning 8200 LINEAR HASH is not supported, using non-linear HASH instead")) + tk.MustQuery(`show create table t_linear`).Check(testkit.Rows("" + + "t_linear CREATE TABLE `t_linear` (\n" + + " `a` int(11) DEFAULT NULL,\n" + + " `b` varchar(128) DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY HASH (`a`) PARTITIONS 4")) + tk.MustQuery("select * from t_linear partition (p0)").Check(testkit.Rows()) tk.MustExec(`CREATE TABLE t_sub (a int, b varchar(128)) PARTITION BY RANGE( a ) SUBPARTITION BY HASH( a ) SUBPARTITIONS 2 ( @@ -1402,7 +1496,7 @@ func TestAlterTableDropPartitionByList(t *testing.T) { );`) tk.MustExec(`insert into t values (1),(3),(5),(null)`) tk.MustExec(`alter table t drop partition p1`) - tk.MustQuery("select * from t").Sort().Check(testkit.Rows("1", "5", "")) + tk.MustQuery("select * from t order by id").Check(testkit.Rows("", "1", "5")) ctx := tk.Session() is := domain.GetDomain(ctx).InfoSchema() tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) @@ -2239,14 +2333,6 @@ func TestExchangePartitionTableCompatiable(t *testing.T) { "alter table pt8 exchange partition p0 with table nt8;", dbterror.ErrTablesDifferentMetadata, }, - { - // foreign key test - // Partition table doesn't support to add foreign keys in mysql - "create table pt9 (id int not null primary key auto_increment,t_id int not null) partition by hash(id) partitions 1;", - "create table nt9 (id int not null primary key auto_increment, t_id int not null,foreign key fk_id (t_id) references pt5(id));", - "alter table pt9 exchange partition p0 with table nt9;", - dbterror.ErrPartitionExchangeForeignKey, - }, { // Generated column (virtual) "create table pt10 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname,' ')) virtual) partition by hash(id) partitions 1;", @@ -3336,9 +3422,6 @@ func TestPartitionErrorCode(t *testing.T) { );`) tk.MustGetDBError("alter table t_part coalesce partition 4;", dbterror.ErrCoalesceOnlyOnHashPartition) - tk.MustGetErrCode(`alter table t_part reorganize partition p0, p1 into ( - partition p0 values less than (1980));`, errno.ErrUnsupportedDDLOperation) - tk.MustGetErrCode("alter table t_part check partition p0, p1;", errno.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t_part optimize partition p0,p1;", errno.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t_part rebuild partition p0,p1;", errno.ErrUnsupportedDDLOperation) @@ -3750,9 +3833,9 @@ func TestTruncatePartitionMultipleTimes(t *testing.T) { } hook.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) done1 := make(chan error, 1) - go backgroundExec(store, "alter table test.t truncate partition p0;", done1) + go backgroundExec(store, "test", "alter table test.t truncate partition p0;", done1) done2 := make(chan error, 1) - go backgroundExec(store, "alter table test.t truncate partition p0;", done2) + go backgroundExec(store, "test", "alter table test.t truncate partition p0;", done2) <-done1 <-done2 require.LessOrEqual(t, errCount, int32(1)) @@ -4061,7 +4144,7 @@ func TestCreateAndAlterIntervalPartition(t *testing.T) { tk.MustQuery("select count(*) from ipt").Check(testkit.Rows("27")) - tk.MustExec("create table idpt (id date primary key, val varchar(255), key (val)) partition by range COLUMNS (id) INTERVAL (1 week) FIRST PARTITION LESS THAN ('2022-02-01') LAST PARTITION LESS THAN ('2022-03-29') NULL PARTITION MAXVALUE PARTITION") + tk.MustExec("create table idpt (id date primary key nonclustered, val varchar(255), key (val)) partition by range COLUMNS (id) INTERVAL (1 week) FIRST PARTITION LESS THAN ('2022-02-01') LAST PARTITION LESS THAN ('2022-03-29') NULL PARTITION MAXVALUE PARTITION") tk.MustQuery("SHOW CREATE TABLE idpt").Check(testkit.Rows( "idpt CREATE TABLE `idpt` (\n" + " `id` date NOT NULL,\n" + @@ -4087,7 +4170,7 @@ func TestCreateAndAlterIntervalPartition(t *testing.T) { // if using a month with 31 days. // But managing partitions with the day-part of 29, 30 or 31 will be troublesome, since once the FIRST is not 31 // both the ALTER TABLE t FIRST PARTITION and MERGE FIRST PARTITION will have issues - tk.MustExec("create table t (id date primary key, val varchar(255), key (val)) partition by range COLUMNS (id) INTERVAL (1 MONTH) FIRST PARTITION LESS THAN ('2022-01-31') LAST PARTITION LESS THAN ('2022-05-31')") + tk.MustExec("create table t (id date primary key nonclustered, val varchar(255), key (val)) partition by range COLUMNS (id) INTERVAL (1 MONTH) FIRST PARTITION LESS THAN ('2022-01-31') LAST PARTITION LESS THAN ('2022-05-31')") tk.MustQuery("show create table t").Check(testkit.Rows( "t CREATE TABLE `t` (\n" + " `id` date NOT NULL,\n" + @@ -4528,3 +4611,809 @@ func TestPartitionTableWithAnsiQuotes(t *testing.T) { ` PARTITION "p4" VALUES LESS THAN ('\\''\t\n','\\''\t\n'),` + "\n" + ` PARTITION "pMax" VALUES LESS THAN (MAXVALUE,MAXVALUE))`)) } + +func TestIssue40135Ver2(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk1 := testkit.NewTestKit(t, store) + tk1.MustExec("use test") + + tk3 := testkit.NewTestKit(t, store) + tk3.MustExec("use test") + + tk.MustExec("CREATE TABLE t40135 ( a int DEFAULT NULL, b varchar(32) DEFAULT 'md', index(a)) PARTITION BY HASH (a) PARTITIONS 6") + tk.MustExec("insert into t40135 values (1, 'md'), (2, 'ma'), (3, 'md'), (4, 'ma'), (5, 'md'), (6, 'ma')") + one := true + hook := &ddl.TestDDLCallback{Do: dom} + var checkErr error + var wg sync.WaitGroup + wg.Add(1) + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.SchemaState == model.StateDeleteOnly { + tk3.MustExec("delete from t40135 where a = 1") + } + if one { + one = false + go func() { + _, checkErr = tk1.Exec("alter table t40135 modify column a int NULL") + wg.Done() + }() + } + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t40135 modify column a bigint NULL DEFAULT '6243108' FIRST") + wg.Wait() + require.ErrorContains(t, checkErr, "[ddl:8200]Unsupported modify column: table is partition table") + tk.MustExec("admin check table t40135") +} + +func TestReorganizeRangePartition(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("create database ReorgPartition") + tk.MustExec("use ReorgPartition") + tk.MustExec(`create table t (a int unsigned PRIMARY KEY, b varchar(255), c int, key (b), key (c,b)) partition by range (a) ` + + `(partition p0 values less than (10),` + + ` partition p1 values less than (20),` + + ` partition pMax values less than (MAXVALUE))`) + tk.MustExec(`insert into t values (1,"1",1), (12,"12",21),(23,"23",32),(34,"34",43),(45,"45",54),(56,"56",65)`) + tk.MustQuery(`select * from t where c < 40`).Sort().Check(testkit.Rows(""+ + "1 1 1", + "12 12 21", + "23 23 32")) + tk.MustExec(`alter table t reorganize partition pMax into (partition p2 values less than (30), partition pMax values less than (MAXVALUE))`) + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `p2` VALUES LESS THAN (30),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows(""+ + "1 1 1", + "12 12 21", + "23 23 32", + "34 34 43", + "45 45 54", + "56 56 65")) + tk.MustQuery(`select * from t partition (p0)`).Sort().Check(testkit.Rows("" + + "1 1 1")) + tk.MustQuery(`select * from t partition (p1)`).Sort().Check(testkit.Rows("" + + "12 12 21")) + tk.MustQuery(`select * from t partition (p2)`).Sort().Check(testkit.Rows("" + + "23 23 32")) + tk.MustQuery(`select * from t partition (pMax)`).Sort().Check(testkit.Rows(""+ + "34 34 43", + "45 45 54", + "56 56 65")) + tk.MustQuery(`select * from t where b > "1"`).Sort().Check(testkit.Rows(""+ + "12 12 21", + "23 23 32", + "34 34 43", + "45 45 54", + "56 56 65")) + tk.MustQuery(`select * from t where c < 40`).Sort().Check(testkit.Rows(""+ + "1 1 1", + "12 12 21", + "23 23 32")) + tk.MustExec(`alter table t reorganize partition p2,pMax into (partition p2 values less than (35),partition p3 values less than (47), partition pMax values less than (MAXVALUE))`) + tk.MustExec(`admin check table t`) + tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows(""+ + "1 1 1", + "12 12 21", + "23 23 32", + "34 34 43", + "45 45 54", + "56 56 65")) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `p2` VALUES LESS THAN (35),\n" + + " PARTITION `p3` VALUES LESS THAN (47),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + tk.MustQuery(`select * from t partition (p0)`).Sort().Check(testkit.Rows("" + + "1 1 1")) + tk.MustQuery(`select * from t partition (p1)`).Sort().Check(testkit.Rows("" + + "12 12 21")) + tk.MustQuery(`select * from t partition (p2)`).Sort().Check(testkit.Rows(""+ + "23 23 32", + "34 34 43")) + tk.MustQuery(`select * from t partition (p3)`).Sort().Check(testkit.Rows("" + + "45 45 54")) + tk.MustQuery(`select * from t partition (pMax)`).Sort().Check(testkit.Rows("" + + "56 56 65")) + tk.MustExec(`alter table t reorganize partition p0,p1 into (partition p1 values less than (20))`) + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `p2` VALUES LESS THAN (35),\n" + + " PARTITION `p3` VALUES LESS THAN (47),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows(""+ + "1 1 1", + "12 12 21", + "23 23 32", + "34 34 43", + "45 45 54", + "56 56 65")) + tk.MustExec(`alter table t drop index b`) + tk.MustExec(`alter table t drop index c`) + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `p2` VALUES LESS THAN (35),\n" + + " PARTITION `p3` VALUES LESS THAN (47),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + tk.MustExec(`create table t2 (a int unsigned not null, b varchar(255), c int, key (b), key (c,b)) partition by range (a) ` + + "(PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `p2` VALUES LESS THAN (35),\n" + + " PARTITION `p3` VALUES LESS THAN (47),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))") + tk.MustExec(`insert into t2 select * from t`) + // Not allowed to change the start range! + tk.MustGetErrCode(`alter table t2 reorganize partition p2 into (partition p2a values less than (20), partition p2b values less than (36))`, + mysql.ErrRangeNotIncreasing) + // Not allowed to change the end range! + tk.MustGetErrCode(`alter table t2 reorganize partition p2 into (partition p2a values less than (30), partition p2b values less than (36))`, mysql.ErrRangeNotIncreasing) + tk.MustGetErrCode(`alter table t2 reorganize partition p2 into (partition p2a values less than (30), partition p2b values less than (34))`, mysql.ErrRangeNotIncreasing) + // Also not allowed to change from MAXVALUE to something else IF there are values in the removed range! + tk.MustContainErrMsg(`alter table t2 reorganize partition pMax into (partition p2b values less than (50))`, "[table:1526]Table has no partition for value 56") + tk.MustQuery(`show create table t2`).Check(testkit.Rows("" + + "t2 CREATE TABLE `t2` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `p2` VALUES LESS THAN (35),\n" + + " PARTITION `p3` VALUES LESS THAN (47),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + // But allowed to change from MAXVALUE if no existing values is outside the new range! + tk.MustExec(`alter table t2 reorganize partition pMax into (partition p4 values less than (90))`) + tk.MustExec(`admin check table t2`) + tk.MustQuery(`show create table t2`).Check(testkit.Rows("" + + "t2 CREATE TABLE `t2` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `p2` VALUES LESS THAN (35),\n" + + " PARTITION `p3` VALUES LESS THAN (47),\n" + + " PARTITION `p4` VALUES LESS THAN (90))")) +} + +func TestReorganizeListPartition(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("create database ReorgListPartition") + tk.MustExec("use ReorgListPartition") + tk.MustExec(`create table t (a int, b varchar(55), c int) partition by list (a)` + + ` (partition p1 values in (12,23,51,14), partition p2 values in (24,63), partition p3 values in (45))`) + tk.MustExec(`insert into t values (12,"12",21), (24,"24",42),(51,"51",15),(23,"23",32),(63,"63",36),(45,"45",54)`) + tk.MustExec(`alter table t reorganize partition p1 into (partition p0 values in (12,51,13), partition p1 values in (23))`) + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(11) DEFAULT NULL,\n" + + " `b` varchar(55) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY LIST (`a`)\n" + + "(PARTITION `p0` VALUES IN (12,51,13),\n" + + " PARTITION `p1` VALUES IN (23),\n" + + " PARTITION `p2` VALUES IN (24,63),\n" + + " PARTITION `p3` VALUES IN (45))")) + tk.MustExec(`alter table t add primary key (a), add key (b), add key (c,b)`) + + // Note: MySQL cannot reorganize two non-consecutive list partitions :) + // ERROR 1519 (HY000): When reorganizing a set of partitions they must be in consecutive order + tk.MustExec(`alter table t reorganize partition p1, p3 into (partition pa values in (45,23,15))`) + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(11) NOT NULL,\n" + + " `b` varchar(55) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] NONCLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY LIST (`a`)\n" + + "(PARTITION `p0` VALUES IN (12,51,13),\n" + + " PARTITION `pa` VALUES IN (45,23,15),\n" + + " PARTITION `p2` VALUES IN (24,63))")) + tk.MustGetErrCode(`alter table t modify a varchar(20)`, errno.ErrUnsupportedDDLOperation) +} + +func TestAlterModifyPartitionColTruncateWarning(t *testing.T) { + t.Skip("waiting for supporting Modify Partition Column again") + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + schemaName := "truncWarn" + tk.MustExec("create database " + schemaName) + tk.MustExec("use " + schemaName) + tk.MustExec(`set sql_mode = default`) + tk.MustExec(`create table t (a varchar(255)) partition by range columns (a) (partition p1 values less than ("0"), partition p2 values less than ("zzzz"))`) + tk.MustExec(`insert into t values ("123456"),(" 654321")`) + tk.MustContainErrMsg(`alter table t modify a varchar(5)`, "[types:1265]Data truncated for column 'a', value is '") + tk.MustExec(`set sql_mode = ''`) + tk.MustExec(`alter table t modify a varchar(5)`) + // Fix the duplicate warning, see https://github.com/pingcap/tidb/issues/38699 + tk.MustQuery(`show warnings`).Check(testkit.Rows(""+ + "Warning 1265 Data truncated for column 'a', value is ' 654321'", + "Warning 1265 Data truncated for column 'a', value is ' 654321'")) + tk.MustExec(`admin check table t`) +} + +func TestAlterModifyColumnOnPartitionedTableRename(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + schemaName := "modColPartRename" + tk.MustExec("create database " + schemaName) + tk.MustExec("use " + schemaName) + tk.MustExec(`create table t (a int, b char) partition by range (a) (partition p0 values less than (10))`) + tk.MustContainErrMsg(`alter table t change a c int`, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") + tk.MustExec(`drop table t`) + tk.MustExec(`create table t (a char, b char) partition by range columns (a) (partition p0 values less than ('z'))`) + tk.MustContainErrMsg(`alter table t change a c char`, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") + tk.MustExec(`drop table t`) + tk.MustExec(`create table t (a int, b char) partition by list (a) (partition p0 values in (10))`) + tk.MustContainErrMsg(`alter table t change a c int`, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") + tk.MustExec(`drop table t`) + tk.MustExec(`create table t (a char, b char) partition by list columns (a) (partition p0 values in ('z'))`) + tk.MustContainErrMsg(`alter table t change a c char`, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") + tk.MustExec(`drop table t`) + tk.MustExec(`create table t (a int, b char) partition by hash (a) partitions 3`) + tk.MustContainErrMsg(`alter table t change a c int`, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") +} + +func TestDropPartitionKeyColumn(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("create database DropPartitionKeyColumn") + defer tk.MustExec("drop database DropPartitionKeyColumn") + tk.MustExec("use DropPartitionKeyColumn") + + tk.MustExec("create table t1 (a tinyint, b char) partition by range (a) ( partition p0 values less than (10) )") + err := tk.ExecToErr("alter table t1 drop column a") + require.Error(t, err) + require.Equal(t, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed", err.Error()) + tk.MustExec("alter table t1 drop column b") + + tk.MustExec("create table t2 (a tinyint, b char) partition by range (a-1) ( partition p0 values less than (10) )") + err = tk.ExecToErr("alter table t2 drop column a") + require.Error(t, err) + require.Equal(t, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed", err.Error()) + tk.MustExec("alter table t2 drop column b") + + tk.MustExec("create table t3 (a tinyint, b char) partition by hash(a) partitions 4;") + err = tk.ExecToErr("alter table t3 drop column a") + require.Error(t, err) + require.Equal(t, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed", err.Error()) + tk.MustExec("alter table t3 drop column b") + + tk.MustExec("create table t4 (a char, b char) partition by list columns (a) ( partition p0 values in ('0'), partition p1 values in ('a'), partition p2 values in ('b'));") + err = tk.ExecToErr("alter table t4 drop column a") + require.Error(t, err) + require.Equal(t, "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed", err.Error()) + tk.MustExec("alter table t4 drop column b") +} + +type TestReorgDDLCallback struct { + *ddl.TestDDLCallback + syncChan chan bool +} + +func (tc *TestReorgDDLCallback) OnChanged(err error) error { + err = tc.TestDDLCallback.OnChanged(err) + <-tc.syncChan + // We want to wait here + <-tc.syncChan + return err +} + +func TestReorgPartitionConcurrent(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + schemaName := "ReorgPartConcurrent" + tk.MustExec("create database " + schemaName) + tk.MustExec("use " + schemaName) + tk.MustExec(`create table t (a int unsigned PRIMARY KEY, b varchar(255), c int, key (b), key (c,b))` + + ` partition by range (a) ` + + `(partition p0 values less than (10),` + + ` partition p1 values less than (20),` + + ` partition pMax values less than (MAXVALUE))`) + tk.MustExec(`insert into t values (1,"1",1), (10,"10",10),(23,"23",32),(34,"34",43),(45,"45",54),(56,"56",65)`) + dom := domain.GetDomain(tk.Session()) + originHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originHook) + syncOnChanged := make(chan bool) + defer close(syncOnChanged) + hook := &TestReorgDDLCallback{TestDDLCallback: &ddl.TestDDLCallback{Do: dom}, syncChan: syncOnChanged} + dom.DDL().SetHook(hook) + + wait := make(chan bool) + defer close(wait) + + currState := model.StateNone + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.Type == model.ActionReorganizePartition && + (job.SchemaState == model.StateDeleteOnly || + job.SchemaState == model.StateWriteOnly || + job.SchemaState == model.StateWriteReorganization || + job.SchemaState == model.StateDeleteReorganization) && + currState != job.SchemaState { + currState = job.SchemaState + <-wait + <-wait + } + } + alterErr := make(chan error, 1) + go backgroundExec(store, schemaName, "alter table t reorganize partition p1 into (partition p1a values less than (15), partition p1b values less than (20))", alterErr) + + wait <- true + // StateDeleteOnly + deleteOnlyInfoSchema := sessiontxn.GetTxnManager(tk.Session()).GetTxnInfoSchema() + wait <- true + + // StateWriteOnly + wait <- true + tk.MustExec(`insert into t values (11, "11", 11),(12,"12",21)`) + tk.MustExec(`admin check table t`) + writeOnlyInfoSchema := sessiontxn.GetTxnManager(tk.Session()).GetTxnInfoSchema() + require.Equal(t, int64(1), writeOnlyInfoSchema.SchemaMetaVersion()-deleteOnlyInfoSchema.SchemaMetaVersion()) + deleteOnlyTbl, err := deleteOnlyInfoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + writeOnlyTbl, err := writeOnlyInfoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + writeOnlyParts := writeOnlyTbl.Meta().Partition + writeOnlyTbl.Meta().Partition = deleteOnlyTbl.Meta().Partition + // If not DeleteOnly is working, then this would show up when reorg is done + tk.MustExec(`delete from t where a = 11`) + tk.MustExec(`update t set b = "12b", c = 12 where a = 12`) + tk.MustExec(`admin check table t`) + writeOnlyTbl.Meta().Partition = writeOnlyParts + tk.MustExec(`admin check table t`) + wait <- true + + // StateWriteReorganization + wait <- true + tk.MustExec(`insert into t values (14, "14", 14),(15, "15",15)`) + writeReorgInfoSchema := sessiontxn.GetTxnManager(tk.Session()).GetTxnInfoSchema() + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + wait <- true + + // StateDeleteReorganization + wait <- true + tk.MustQuery(`select * from t where c between 10 and 22`).Sort().Check(testkit.Rows(""+ + "10 10 10", + "12 12b 12", + "14 14 14", + "15 15 15")) + deleteReorgInfoSchema := sessiontxn.GetTxnManager(tk.Session()).GetTxnInfoSchema() + require.Equal(t, int64(1), deleteReorgInfoSchema.SchemaMetaVersion()-writeReorgInfoSchema.SchemaMetaVersion()) + tk.MustExec(`insert into t values (16, "16", 16)`) + oldTbl, err := writeReorgInfoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + partDef := oldTbl.Meta().Partition.Definitions[1] + require.Equal(t, "p1", partDef.Name.O) + rows := getNumRowsFromPartitionDefs(t, tk, oldTbl, oldTbl.Meta().Partition.Definitions[1:2]) + require.Equal(t, 5, rows) + currTbl, err := deleteReorgInfoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + currPart := currTbl.Meta().Partition + currTbl.Meta().Partition = oldTbl.Meta().Partition + tk.MustQuery(`select * from t where b = "16"`).Sort().Check(testkit.Rows("16 16 16")) + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + tk.MustQuery(`select * from t partition (p1)`).Sort().Check(testkit.Rows(""+ + "10 10 10", + "12 12b 12", + "14 14 14", + "15 15 15", + "16 16 16")) + currTbl.Meta().Partition = currPart + wait <- true + syncOnChanged <- true + // This reads the new schema (Schema update completed) + tk.MustQuery(`select * from t where c between 10 and 22`).Sort().Check(testkit.Rows(""+ + "10 10 10", + "12 12b 12", + "14 14 14", + "15 15 15", + "16 16 16")) + tk.MustExec(`admin check table t`) + newInfoSchema := sessiontxn.GetTxnManager(tk.Session()).GetTxnInfoSchema() + require.Equal(t, int64(1), newInfoSchema.SchemaMetaVersion()-deleteReorgInfoSchema.SchemaMetaVersion()) + oldTbl, err = deleteReorgInfoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + partDef = oldTbl.Meta().Partition.Definitions[1] + require.Equal(t, "p1a", partDef.Name.O) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1a` VALUES LESS THAN (15),\n" + + " PARTITION `p1b` VALUES LESS THAN (20),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + newTbl, err := deleteReorgInfoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + newPart := newTbl.Meta().Partition + newTbl.Meta().Partition = oldTbl.Meta().Partition + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1a` VALUES LESS THAN (15),\n" + + " PARTITION `p1b` VALUES LESS THAN (20),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + tk.MustExec(`admin check table t`) + newTbl.Meta().Partition = newPart + syncOnChanged <- true + require.NoError(t, <-alterErr) +} + +func TestReorgPartitionFailConcurrent(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + schemaName := "ReorgPartFailConcurrent" + tk.MustExec("create database " + schemaName) + tk.MustExec("use " + schemaName) + tk.MustExec(`create table t (a int unsigned PRIMARY KEY, b varchar(255), c int, key (b), key (c,b))` + + ` partition by range (a) ` + + `(partition p0 values less than (10),` + + ` partition p1 values less than (20),` + + ` partition pMax values less than (MAXVALUE))`) + tk.MustExec(`insert into t values (1,"1",1), (12,"12",21),(23,"23",32),(34,"34",43),(45,"45",54),(56,"56",65)`) + dom := domain.GetDomain(tk.Session()) + originHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originHook) + hook := &ddl.TestDDLCallback{Do: dom} + dom.DDL().SetHook(hook) + + wait := make(chan bool) + defer close(wait) + + // Test insert of duplicate key during copy phase + injected := false + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.Type == model.ActionReorganizePartition && job.SchemaState == model.StateWriteReorganization && !injected { + injected = true + <-wait + <-wait + } + } + alterErr := make(chan error, 1) + go backgroundExec(store, schemaName, "alter table t reorganize partition p1 into (partition p1a values less than (15), partition p1b values less than (20))", alterErr) + wait <- true + tk.MustExec(`insert into t values (14, "14", 14),(15, "15",15)`) + tk.MustGetErrCode(`insert into t values (11, "11", 11),(12,"duplicate PK 💥", 13)`, mysql.ErrDupEntry) + tk.MustExec(`admin check table t`) + wait <- true + require.NoError(t, <-alterErr) + tk.MustQuery(`select * from t where c between 10 and 22`).Sort().Check(testkit.Rows(""+ + "12 12 21", + "14 14 14", + "15 15 15")) + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1a` VALUES LESS THAN (15),\n" + + " PARTITION `p1b` VALUES LESS THAN (20),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + + // Test reorg of duplicate key + prevState := model.StateNone + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.Type == model.ActionReorganizePartition && + job.SchemaState == model.StateWriteReorganization && + job.SnapshotVer == 0 && + prevState != job.SchemaState { + prevState = job.SchemaState + <-wait + <-wait + } + if job.Type == model.ActionReorganizePartition && + job.SchemaState == model.StateDeleteReorganization && + prevState != job.SchemaState { + prevState = job.SchemaState + <-wait + <-wait + } + } + go backgroundExec(store, schemaName, "alter table t reorganize partition p1a,p1b into (partition p1a values less than (14), partition p1b values less than (17), partition p1c values less than (20))", alterErr) + wait <- true + infoSchema := sessiontxn.GetTxnManager(tk.Session()).GetTxnInfoSchema() + tbl, err := infoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + require.Equal(t, 0, getNumRowsFromPartitionDefs(t, tk, tbl, tbl.Meta().Partition.AddingDefinitions)) + tk.MustExec(`delete from t where a = 14`) + tk.MustExec(`insert into t values (13, "13", 31),(14,"14b",14),(16, "16",16)`) + tk.MustExec(`admin check table t`) + wait <- true + wait <- true + tbl, err = infoSchema.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + require.Equal(t, 5, getNumRowsFromPartitionDefs(t, tk, tbl, tbl.Meta().Partition.AddingDefinitions)) + tk.MustExec(`delete from t where a = 15`) + tk.MustExec(`insert into t values (11, "11", 11),(15,"15b",15),(17, "17",17)`) + tk.MustExec(`admin check table t`) + wait <- true + require.NoError(t, <-alterErr) + + tk.MustExec(`admin check table t`) + tk.MustQuery(`select * from t where a between 10 and 22`).Sort().Check(testkit.Rows(""+ + "11 11 11", + "12 12 21", + "13 13 31", + "14 14b 14", + "15 15b 15", + "16 16 16", + "17 17 17")) + tk.MustQuery(`select * from t where c between 10 and 22`).Sort().Check(testkit.Rows(""+ + "11 11 11", + "12 12 21", + "14 14b 14", + "15 15b 15", + "16 16 16", + "17 17 17")) + tk.MustQuery(`select * from t where b between "10" and "22"`).Sort().Check(testkit.Rows(""+ + "11 11 11", + "12 12 21", + "13 13 31", + "14 14b 14", + "15 15b 15", + "16 16 16", + "17 17 17")) +} + +func getNumRowsFromPartitionDefs(t *testing.T, tk *testkit.TestKit, tbl table.Table, defs []model.PartitionDefinition) int { + ctx := tk.Session() + pt := tbl.GetPartitionedTable() + require.NotNil(t, pt) + cnt := 0 + for _, def := range defs { + data := getAllDataForPhysicalTable(t, ctx, pt.GetPartition(def.ID)) + require.True(t, len(data.keys) == len(data.vals)) + require.True(t, len(data.keys) == len(data.tp)) + for _, s := range data.tp { + if s == "Record" { + cnt++ + } + } + } + return cnt +} + +func TestReorgPartitionFailInject(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + schemaName := "ReorgPartFailInjectConcurrent" + tk.MustExec("create database " + schemaName) + tk.MustExec("use " + schemaName) + tk.MustExec(`create table t (a int unsigned PRIMARY KEY, b varchar(255), c int, key (b), key (c,b))` + + ` partition by range (a) ` + + `(partition p0 values less than (10),` + + ` partition p1 values less than (20),` + + ` partition pMax values less than (MAXVALUE))`) + tk.MustExec(`insert into t values (1,"1",1), (12,"12",21),(23,"23",32),(34,"34",43),(45,"45",54),(56,"56",65)`) + + dom := domain.GetDomain(tk.Session()) + originHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originHook) + hook := &ddl.TestDDLCallback{Do: dom} + dom.DDL().SetHook(hook) + + wait := make(chan bool) + defer close(wait) + + injected := false + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.Type == model.ActionReorganizePartition && job.SchemaState == model.StateWriteReorganization && !injected { + injected = true + <-wait + <-wait + } + } + alterErr := make(chan error, 1) + go backgroundExec(store, schemaName, "alter table t reorganize partition p1 into (partition p1a values less than (15), partition p1b values less than (20))", alterErr) + wait <- true + tk.MustExec(`insert into t values (14, "14", 14),(15, "15",15)`) + tk.MustGetErrCode(`insert into t values (11, "11", 11),(12,"duplicate PK 💥", 13)`, mysql.ErrDupEntry) + tk.MustExec(`admin check table t`) + wait <- true + require.NoError(t, <-alterErr) + tk.MustExec(`admin check table t`) + tk.MustQuery(`select * from t where c between 10 and 22`).Sort().Check(testkit.Rows(""+ + "12 12 21", + "14 14 14", + "15 15 15")) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1a` VALUES LESS THAN (15),\n" + + " PARTITION `p1b` VALUES LESS THAN (20),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) +} + +func TestReorgPartitionRollback(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + schemaName := "ReorgPartRollback" + tk.MustExec("create database " + schemaName) + tk.MustExec("use " + schemaName) + tk.MustExec(`create table t (a int unsigned PRIMARY KEY, b varchar(255), c int, key (b), key (c,b))` + + ` partition by range (a) ` + + `(partition p0 values less than (10),` + + ` partition p1 values less than (20),` + + ` partition pMax values less than (MAXVALUE))`) + tk.MustExec(`insert into t values (1,"1",1), (12,"12",21),(23,"23",32),(34,"34",43),(45,"45",54),(56,"56",65)`) + // TODO: Check that there are no additional placement rules, + // bundles, or ranges with non-completed tableIDs + // (partitions used during reorg, but was dropped) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/mockUpdateVersionAndTableInfoErr", `return(true)`)) + tk.MustExecToErr("alter table t reorganize partition p1 into (partition p1a values less than (15), partition p1b values less than (20))") + tk.MustExec(`admin check table t`) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockUpdateVersionAndTableInfoErr")) + ctx := tk.Session() + is := domain.GetDomain(ctx).InfoSchema() + tbl, err := is.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + noNewTablesAfter(t, ctx, tbl) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/reorgPartitionAfterDataCopy", `return(true)`)) + defer func() { + err := failpoint.Disable("github.com/pingcap/tidb/ddl/reorgPartitionAfterDataCopy") + require.NoError(t, err) + }() + tk.MustExecToErr("alter table t reorganize partition p1 into (partition p1a values less than (15), partition p1b values less than (20))") + tk.MustExec(`admin check table t`) + tk.MustQuery(`show create table t`).Check(testkit.Rows("" + + "t CREATE TABLE `t` (\n" + + " `a` int(10) unsigned NOT NULL,\n" + + " `b` varchar(255) DEFAULT NULL,\n" + + " `c` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " KEY `c` (`c`,`b`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (10),\n" + + " PARTITION `p1` VALUES LESS THAN (20),\n" + + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE))")) + + // WASHERE: How to test these? + //tk.MustQuery(`select * from mysql.gc_delete_range_done`).Sort().Check(testkit.Rows()) + //time.Sleep(1 * time.Second) + //tk.MustQuery(`select * from mysql.gc_delete_range`).Sort().Check(testkit.Rows()) + + tbl, err = is.TableByName(model.NewCIStr(schemaName), model.NewCIStr("t")) + require.NoError(t, err) + noNewTablesAfter(t, ctx, tbl) +} + +func TestReorgPartitionData(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + schemaName := "ReorgPartData" + tk.MustExec("create database " + schemaName) + tk.MustExec("use " + schemaName) + tk.MustExec(`SET @@session.sql_mode = default`) + tk.MustExec(`create table t (a int PRIMARY KEY AUTO_INCREMENT, b varchar(255), c int, d datetime, key (b), key (c,b)) partition by range (a) (partition p1 values less than (0), partition p1M values less than (1000000))`) + tk.MustContainErrMsg(`insert into t values (0, "Zero value!", 0, '2022-02-30')`, "[table:1292]Incorrect datetime value: '2022-02-30' for column 'd' at row 1") + tk.MustExec(`SET @@session.sql_mode = 'ALLOW_INVALID_DATES,NO_AUTO_VALUE_ON_ZERO'`) + tk.MustExec(`insert into t values (0, "Zero value!", 0, '2022-02-30')`) + tk.MustQuery(`show warnings`).Check(testkit.Rows()) + tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows("0 Zero value! 0 2022-02-30 00:00:00")) + tk.MustExec(`SET @@session.sql_mode = default`) + tk.MustExec(`alter table t reorganize partition p1M into (partition p0 values less than (1), partition p2M values less than (2000000))`) + tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows("0 Zero value! 0 2022-02-30 00:00:00")) + tk.MustExec(`admin check table t`) +} + +// TODO Test with/without PK, indexes, UK, virtual, virtual stored columns + +// How to test rollback? +// Create new table +// insert some data +// start reorganize partition +// pause and get the AddingPartition IDs for later use +// continue reorganize partition and fail or crash in points of interests +// check if there are any data to be read from the AddingPartition IDs +// check if the table structure is correct. diff --git a/ddl/db_table_test.go b/ddl/db_table_test.go index 730e3bb941848..33fe6f4337055 100644 --- a/ddl/db_table_test.go +++ b/ddl/db_table_test.go @@ -18,6 +18,7 @@ import ( "bytes" "context" "fmt" + "strconv" "strings" "testing" "time" @@ -30,6 +31,7 @@ import ( "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/terror" @@ -49,7 +51,7 @@ func TestTableForeignKey(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk.MustExec("create table t1 (a int, b int);") + tk.MustExec("create table t1 (a int, b int, index(a), index(b));") // test create table with foreign key. failSQL := "create table t2 (c int, foreign key (a) references t1(a));" tk.MustGetErrCode(failSQL, errno.ErrKeyColumnDoesNotExits) @@ -207,7 +209,7 @@ func TestTransactionOnAddDropColumn(t *testing.T) { dom.DDL().SetHook(hook) done := make(chan error, 1) // test transaction on add column. - go backgroundExec(store, "alter table t1 add column c int not null after a", done) + go backgroundExec(store, "test", "alter table t1 add column c int not null after a", done) err := <-done require.NoError(t, err) require.Nil(t, checkErr) @@ -215,7 +217,7 @@ func TestTransactionOnAddDropColumn(t *testing.T) { tk.MustExec("delete from t1") // test transaction on drop column. - go backgroundExec(store, "alter table t1 drop column c", done) + go backgroundExec(store, "test", "alter table t1 drop column c", done) err = <-done require.NoError(t, err) require.Nil(t, checkErr) @@ -380,6 +382,49 @@ func TestAlterTableWithValidation(t *testing.T) { tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|8200|ALTER TABLE WITHOUT VALIDATION is currently unsupported")) } +func TestCreateTableWithInfo(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.Session().SetValue(sessionctx.QueryString, "skip") + + d := dom.DDL() + require.NotNil(t, d) + info := []*model.TableInfo{{ + ID: 42, + Name: model.NewCIStr("t"), + }} + + require.NoError(t, d.BatchCreateTableWithInfo(tk.Session(), model.NewCIStr("test"), info, ddl.OnExistError, ddl.AllocTableIDIf(func(ti *model.TableInfo) bool { + return false + }))) + tk.MustQuery("select tidb_table_id from information_schema.tables where table_name = 't'").Check(testkit.Rows("42")) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnOthers) + + var id int64 + err := kv.RunInNewTxn(ctx, store, true, func(_ context.Context, txn kv.Transaction) error { + m := meta.NewMeta(txn) + var err error + id, err = m.GenGlobalID() + return err + }) + + require.NoError(t, err) + info = []*model.TableInfo{{ + ID: 42, + Name: model.NewCIStr("tt"), + }} + tk.Session().SetValue(sessionctx.QueryString, "skip") + require.NoError(t, d.BatchCreateTableWithInfo(tk.Session(), model.NewCIStr("test"), info, ddl.OnExistError, ddl.AllocTableIDIf(func(ti *model.TableInfo) bool { + return true + }))) + idGen, ok := tk.MustQuery("select tidb_table_id from information_schema.tables where table_name = 'tt'").Rows()[0][0].(string) + require.True(t, ok) + idGenNum, err := strconv.ParseInt(idGen, 10, 64) + require.NoError(t, err) + require.Greater(t, idGenNum, id) +} + func TestBatchCreateTable(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) @@ -826,8 +871,7 @@ func TestDDLWithInvalidTableInfo(t *testing.T) { tk.MustExec("create table t (a bigint, b int, c int generated always as (b+1)) partition by hash(a) partitions 4;") // Test drop partition column. - // TODO: refine the error message to compatible with MySQL - tk.MustGetErrMsg("alter table t drop column a;", "[planner:1054]Unknown column 'a' in 'expression'") + tk.MustGetErrMsg("alter table t drop column a;", "[ddl:3855]Column 'a' has a partitioning function dependency and cannot be dropped or renamed") // Test modify column with invalid expression. tk.MustGetErrMsg("alter table t modify column c int GENERATED ALWAYS AS ((case when (a = 0) then 0when (a > 0) then (b / a) end));", "[parser:1064]You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 97 near \"then (b / a) end));\" ") // Test add column with invalid expression. @@ -854,7 +898,7 @@ func TestAddColumn2(t *testing.T) { dom.DDL().SetHook(hook) done := make(chan error, 1) // test transaction on add column. - go backgroundExec(store, "alter table t1 add column c int not null", done) + go backgroundExec(store, "test", "alter table t1 add column c int not null", done) err := <-done require.NoError(t, err) @@ -873,7 +917,7 @@ func TestAddColumn2(t *testing.T) { require.NoError(t, err) _, err = writeOnlyTable.AddRecord(tk.Session(), types.MakeDatums(oldRow[0].GetInt64(), 2, oldRow[2].GetInt64()), table.IsUpdate) require.NoError(t, err) - tk.Session().StmtCommit() + tk.Session().StmtCommit(ctx) err = tk.Session().CommitTxn(ctx) require.NoError(t, err) @@ -895,7 +939,7 @@ func TestAddColumn2(t *testing.T) { } dom.DDL().SetHook(hook) - go backgroundExec(store, "alter table t2 add column b int not null default 3", done) + go backgroundExec(store, "test", "alter table t2 add column b int not null default 3", done) err = <-done require.NoError(t, err) re.Check(testkit.Rows("1 2")) diff --git a/ddl/db_test.go b/ddl/db_test.go index f0e7c6809a12e..f9d5ef000ba24 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -20,6 +20,7 @@ import ( "math" "strconv" "strings" + "sync" "testing" "time" @@ -40,7 +41,6 @@ import ( "github.com/pingcap/tidb/parser/terror" parsertypes "github.com/pingcap/tidb/parser/types" "github.com/pingcap/tidb/planner/core" - "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/store/mockstore" @@ -54,7 +54,6 @@ import ( "github.com/stretchr/testify/require" "github.com/tikv/client-go/v2/oracle" "github.com/tikv/client-go/v2/tikv" - "golang.org/x/exp/slices" ) const ( @@ -237,7 +236,7 @@ func TestJsonUnmarshalErrWhenPanicInCancellingPath(t *testing.T) { tk.MustExec("create table test_add_index_after_add_col(a int, b int not null default '0');") tk.MustExec("insert into test_add_index_after_add_col values(1, 2),(2,2);") tk.MustExec("alter table test_add_index_after_add_col add column c int not null default '0';") - tk.MustGetErrMsg("alter table test_add_index_after_add_col add unique index cc(c);", "[kv:1062]Duplicate entry '0' for key 'cc'") + tk.MustGetErrMsg("alter table test_add_index_after_add_col add unique index cc(c);", "[kv:1062]Duplicate entry '0' for key 'test_add_index_after_add_col.cc'") } func TestIssue22819(t *testing.T) { @@ -282,7 +281,7 @@ func TestIssue22307(t *testing.T) { dom.DDL().SetHook(hook) done := make(chan error, 1) // test transaction on add column. - go backgroundExec(store, "alter table t drop column b;", done) + go backgroundExec(store, "test", "alter table t drop column b;", done) err := <-done require.NoError(t, err) require.EqualError(t, checkErr1, "[planner:1054]Unknown column 'b' in 'where clause'") @@ -619,10 +618,7 @@ func TestAddExpressionIndexRollback(t *testing.T) { // Check whether the reorg information is cleaned up. err := sessiontxn.NewTxn(context.Background(), ctx) require.NoError(t, err) - txn, err := ctx.Txn(true) - require.NoError(t, err) - m := meta.NewMeta(txn) - element, start, end, physicalID, err := ddl.NewReorgHandlerForTest(m, testkit.NewTestKit(t, store).Session()).GetDDLReorgHandle(currJob) + element, start, end, physicalID, err := ddl.NewReorgHandlerForTest(testkit.NewTestKit(t, store).Session()).GetDDLReorgHandle(currJob) require.True(t, meta.ErrDDLReorgElementNotExist.Equal(err)) require.Nil(t, element) require.Nil(t, start) @@ -898,11 +894,11 @@ func TestAutoIncrementIDOnTemporaryTable(t *testing.T) { tk.MustExec("drop table if exists global_temp_auto_id") tk.MustExec("create global temporary table global_temp_auto_id(id int primary key auto_increment) on commit delete rows") tk.MustExec("begin") - tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 1 AUTO_INCREMENT")) + tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 1 _TIDB_ROWID")) tk.MustExec("insert into global_temp_auto_id value(null)") tk.MustQuery("select @@last_insert_id").Check(testkit.Rows("1")) tk.MustQuery("select id from global_temp_auto_id").Check(testkit.Rows("1")) - tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 2 AUTO_INCREMENT")) + tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 2 _TIDB_ROWID")) tk.MustExec("commit") tk.MustExec("drop table global_temp_auto_id") @@ -914,12 +910,12 @@ func TestAutoIncrementIDOnTemporaryTable(t *testing.T) { " `id` int(11) NOT NULL AUTO_INCREMENT,\n" + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=100 ON COMMIT DELETE ROWS")) - tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 100 AUTO_INCREMENT")) + tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 100 _TIDB_ROWID")) tk.MustExec("begin") tk.MustExec("insert into global_temp_auto_id value(null)") tk.MustQuery("select @@last_insert_id").Check(testkit.Rows("100")) tk.MustQuery("select id from global_temp_auto_id").Check(testkit.Rows("100")) - tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 101 AUTO_INCREMENT")) + tk.MustQuery("show table global_temp_auto_id next_row_id").Check(testkit.Rows("test global_temp_auto_id id 101 _TIDB_ROWID")) tk.MustExec("commit") } tk.MustExec("drop table global_temp_auto_id") @@ -980,201 +976,6 @@ func TestDDLJobErrorCount(t *testing.T) { require.True(t, kv.ErrEntryTooLarge.Equal(historyJob.Error)) } -func TestCommitTxnWithIndexChange(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, dbTestLease) - // Prepare work. - tk := testkit.NewTestKit(t, store) - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk.MustExec("use test") - tk.MustExec("create table t1 (c1 int primary key, c2 int, c3 int, index ok2(c2))") - tk.MustExec("insert t1 values (1, 10, 100), (2, 20, 200)") - tk.MustExec("alter table t1 add index k2(c2)") - tk.MustExec("alter table t1 drop index k2") - tk.MustExec("alter table t1 add index k2(c2)") - tk.MustExec("alter table t1 drop index k2") - tk2 := testkit.NewTestKit(t, store) - tk2.MustExec("use test") - - // tkSQLs are the sql statements for the pessimistic transaction. - // tk2DDL are the ddl statements executed before the pessimistic transaction. - // idxDDL is the DDL statement executed between pessimistic transaction begin and commit. - // failCommit means the pessimistic transaction commit should fail not. - type caseUnit struct { - tkSQLs []string - tk2DDL []string - idxDDL string - checkSQLs []string - rowsExps [][]string - failCommit bool - stateEnd model.SchemaState - } - - cases := []caseUnit{ - // Test secondary index - {[]string{"insert into t1 values(3, 30, 300)", - "insert into t2 values(11, 11, 11)"}, - []string{"alter table t1 add index k2(c2)", - "alter table t1 drop index k2", - "alter table t1 add index kk2(c2, c1)", - "alter table t1 add index k2(c2)", - "alter table t1 drop index k2"}, - "alter table t1 add index k2(c2)", - []string{"select c3, c2 from t1 use index(k2) where c2 = 20", - "select c3, c2 from t1 use index(k2) where c2 = 10", - "select * from t1", - "select * from t2 where c1 = 11"}, - [][]string{{"200 20"}, - {"100 10"}, - {"1 10 100", "2 20 200", "3 30 300"}, - {"11 11 11"}}, - false, - model.StateNone}, - // Test secondary index - {[]string{"insert into t2 values(5, 50, 500)", - "insert into t2 values(11, 11, 11)", - "delete from t2 where c2 = 11", - "update t2 set c2 = 110 where c1 = 11"}, - // "update t2 set c1 = 10 where c3 = 100"}, - []string{"alter table t1 add index k2(c2)", - "alter table t1 drop index k2", - "alter table t1 add index kk2(c2, c1)", - "alter table t1 add index k2(c2)", - "alter table t1 drop index k2"}, - "alter table t1 add index k2(c2)", - []string{"select c3, c2 from t1 use index(k2) where c2 = 20", - "select c3, c2 from t1 use index(k2) where c2 = 10", - "select * from t1", - "select * from t2 where c1 = 11", - "select * from t2 where c3 = 100"}, - [][]string{{"200 20"}, - {"100 10"}, - {"1 10 100", "2 20 200"}, - {}, - {"1 10 100"}}, - false, - model.StateNone}, - // Test unique index - {[]string{"insert into t1 values(3, 30, 300)", - "insert into t1 values(4, 40, 400)", - "insert into t2 values(11, 11, 11)", - "insert into t2 values(12, 12, 11)"}, - []string{"alter table t1 add unique index uk3(c3)", - "alter table t1 drop index uk3", - "alter table t2 add unique index ukc1c3(c1, c3)", - "alter table t2 add unique index ukc3(c3)", - "alter table t2 drop index ukc1c3", - "alter table t2 drop index ukc3", - "alter table t2 add index kc3(c3)"}, - "alter table t1 add unique index uk3(c3)", - []string{"select c3, c2 from t1 use index(uk3) where c3 = 200", - "select c3, c2 from t1 use index(uk3) where c3 = 300", - "select c3, c2 from t1 use index(uk3) where c3 = 400", - "select * from t1", - "select * from t2"}, - [][]string{{"200 20"}, - {"300 30"}, - {"400 40"}, - {"1 10 100", "2 20 200", "3 30 300", "4 40 400"}, - {"1 10 100", "2 20 200", "11 11 11", "12 12 11"}}, - false, model.StateNone}, - // Test unique index fail to commit, this case needs the new index could be inserted - {[]string{"insert into t1 values(3, 30, 300)", - "insert into t1 values(4, 40, 300)", - "insert into t2 values(11, 11, 11)", - "insert into t2 values(12, 11, 12)"}, - //[]string{"alter table t1 add unique index uk3(c3)", "alter table t1 drop index uk3"}, - []string{}, - "alter table t1 add unique index uk3(c3)", - []string{"select c3, c2 from t1 use index(uk3) where c3 = 200", - "select c3, c2 from t1 use index(uk3) where c3 = 300", - "select c3, c2 from t1 where c1 = 4", - "select * from t1", - "select * from t2"}, - [][]string{{"200 20"}, - {}, - {}, - {"1 10 100", "2 20 200"}, - {"1 10 100", "2 20 200"}}, - true, - model.StateWriteOnly}, - } - tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200")) - - // Test add index state change - do := dom.DDL() - startStates := []model.SchemaState{model.StateNone, model.StateDeleteOnly} - for _, startState := range startStates { - endStatMap := session.ConstOpAddIndex[startState] - var endStates []model.SchemaState - for st := range endStatMap { - endStates = append(endStates, st) - } - slices.Sort(endStates) - for _, endState := range endStates { - for _, curCase := range cases { - if endState < curCase.stateEnd { - break - } - tk2.MustExec("drop table if exists t1") - tk2.MustExec("drop table if exists t2") - tk2.MustExec("create table t1 (c1 int primary key, c2 int, c3 int, index ok2(c2))") - tk2.MustExec("create table t2 (c1 int primary key, c2 int, c3 int, index ok2(c2))") - tk2.MustExec("insert t1 values (1, 10, 100), (2, 20, 200)") - tk2.MustExec("insert t2 values (1, 10, 100), (2, 20, 200)") - tk2.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200")) - tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200")) - tk.MustQuery("select * from t2;").Check(testkit.Rows("1 10 100", "2 20 200")) - - for _, DDLSQL := range curCase.tk2DDL { - tk2.MustExec(DDLSQL) - } - hook := &ddl.TestDDLCallback{Do: dom} - prepared := false - committed := false - hook.OnJobRunBeforeExported = func(job *model.Job) { - if job.SchemaState == startState { - if !prepared { - tk.MustExec("begin pessimistic") - for _, tkSQL := range curCase.tkSQLs { - tk.MustExec(tkSQL) - } - prepared = true - } - } - } - onJobUpdatedExportedFunc := func(job *model.Job) { - if job.SchemaState == endState { - if !committed { - if curCase.failCommit { - err := tk.ExecToErr("commit") - require.Error(t, err) - } else { - tk.MustExec("commit") - } - } - committed = true - } - } - hook.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) - originalCallback := do.GetHook() - do.SetHook(hook) - tk2.MustExec(curCase.idxDDL) - do.SetHook(originalCallback) - tk2.MustExec("admin check table t1") - for i, checkSQL := range curCase.checkSQLs { - if len(curCase.rowsExps[i]) > 0 { - tk2.MustQuery(checkSQL).Check(testkit.Rows(curCase.rowsExps[i]...)) - } else { - tk2.MustQuery(checkSQL).Check(nil) - } - } - } - } - } - tk.MustExec("admin check table t1") -} - // TestAddIndexFailOnCaseWhenCanExit is used to close #19325. func TestAddIndexFailOnCaseWhenCanExit(t *testing.T) { require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/MockCaseWhenParseFailure", `return(true)`)) @@ -1378,54 +1179,6 @@ func TestTxnSavepointWithDDL(t *testing.T) { tk.MustExec("admin check table t1, t2") } -func TestAmendTxnSavepointWithDDL(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomainWithSchemaLease(t, dbTestLease) - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("use test;") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk2.MustExec("use test;") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - - prepareFn := func() { - tk.MustExec("drop table if exists t1, t2") - tk.MustExec("create table t1 (c1 int primary key, c2 int)") - tk.MustExec("create table t2 (c1 int primary key, c2 int)") - } - - prepareFn() - tk.MustExec("truncate table t1") - tk.MustExec("begin pessimistic") - tk.MustExec("savepoint s1") - tk.MustExec("insert t1 values (1, 11)") - tk.MustExec("savepoint s2") - tk.MustExec("insert t2 values (1, 11)") - tk.MustExec("rollback to s2") - tk2.MustExec("alter table t1 add index idx2(c2)") - tk2.MustExec("alter table t2 add index idx2(c2)") - tk.MustExec("commit") - tk.MustQuery("select * from t1").Check(testkit.Rows("1 11")) - tk.MustQuery("select * from t2").Check(testkit.Rows()) - tk.MustExec("admin check table t1, t2") - - prepareFn() - tk.MustExec("truncate table t1") - tk.MustExec("begin pessimistic") - tk.MustExec("savepoint s1") - tk.MustExec("insert t1 values (1, 11)") - tk.MustExec("savepoint s2") - tk.MustExec("insert t2 values (1, 11)") - tk.MustExec("savepoint s3") - tk.MustExec("insert t2 values (2, 22)") - tk.MustExec("rollback to s3") - tk2.MustExec("alter table t1 add index idx2(c2)") - tk2.MustExec("alter table t2 add index idx2(c2)") - tk.MustExec("commit") - tk.MustQuery("select * from t1").Check(testkit.Rows("1 11")) - tk.MustQuery("select * from t2").Check(testkit.Rows("1 11")) - tk.MustExec("admin check table t1, t2") -} - func TestSnapshotVersion(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, dbTestLease) @@ -1582,13 +1335,11 @@ func TestLogAndShowSlowLog(t *testing.T) { } func TestReportingMinStartTimestamp(t *testing.T) { - _, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, dbTestLease) + store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, dbTestLease) + tk := testkit.NewTestKit(t, store) + se := tk.Session() infoSyncer := dom.InfoSyncer() - sm := &testkit.MockSessionManager{ - PS: make([]*util.ProcessInfo, 0), - } - infoSyncer.SetSessionManager(sm) beforeTS := oracle.GoTimeToTS(time.Now()) infoSyncer.ReportMinStartTS(dom.Store()) afterTS := oracle.GoTimeToTS(time.Now()) @@ -1597,13 +1348,21 @@ func TestReportingMinStartTimestamp(t *testing.T) { now := time.Now() validTS := oracle.GoTimeToLowerLimitStartTS(now.Add(time.Minute), tikv.MaxTxnTimeUse) lowerLimit := oracle.GoTimeToLowerLimitStartTS(now, tikv.MaxTxnTimeUse) + sm := se.GetSessionManager().(*testkit.MockSessionManager) sm.PS = []*util.ProcessInfo{ - {CurTxnStartTS: 0}, - {CurTxnStartTS: math.MaxUint64}, - {CurTxnStartTS: lowerLimit}, - {CurTxnStartTS: validTS}, + {CurTxnStartTS: 0, ProtectedTSList: &se.GetSessionVars().ProtectedTSList}, + {CurTxnStartTS: math.MaxUint64, ProtectedTSList: &se.GetSessionVars().ProtectedTSList}, + {CurTxnStartTS: lowerLimit, ProtectedTSList: &se.GetSessionVars().ProtectedTSList}, + {CurTxnStartTS: validTS, ProtectedTSList: &se.GetSessionVars().ProtectedTSList}, } - infoSyncer.SetSessionManager(sm) + infoSyncer.ReportMinStartTS(dom.Store()) + require.Equal(t, validTS, infoSyncer.GetMinStartTS()) + + unhold := se.GetSessionVars().ProtectedTSList.HoldTS(validTS - 1) + infoSyncer.ReportMinStartTS(dom.Store()) + require.Equal(t, validTS-1, infoSyncer.GetMinStartTS()) + + unhold() infoSyncer.ReportMinStartTS(dom.Store()) require.Equal(t, validTS, infoSyncer.GetMinStartTS()) } @@ -1736,3 +1495,131 @@ func TestTiDBDownBeforeUpdateGlobalVersion(t *testing.T) { require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockDownBeforeUpdateGlobalVersion")) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/checkDownBeforeUpdateGlobalVersion")) } + +func TestDDLBlockedCreateView(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int)") + + hook := &ddl.TestDDLCallback{Do: dom} + first := true + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.SchemaState != model.StateWriteOnly { + return + } + if !first { + return + } + first = false + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec("create view v as select * from t") + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t modify column a char(10)") +} + +func TestHashPartitionAddColumn(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int, b int) partition by hash(a) partitions 4") + + hook := &ddl.TestDDLCallback{Do: dom} + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.SchemaState != model.StateWriteOnly { + return + } + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec("delete from t") + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t add column c int") +} + +func TestSetInvalidDefaultValueAfterModifyColumn(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int, b int)") + + var wg sync.WaitGroup + var checkErr error + one := false + hook := &ddl.TestDDLCallback{Do: dom} + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.SchemaState != model.StateDeleteOnly { + return + } + if !one { + one = true + } else { + return + } + wg.Add(1) + go func() { + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + _, checkErr = tk2.Exec("alter table t alter column a set default 1") + wg.Done() + }() + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t modify column a text(100)") + wg.Wait() + require.EqualError(t, checkErr, "[ddl:1101]BLOB/TEXT/JSON column 'a' can't have a default value") +} + +func TestMDLTruncateTable(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk3 := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int);") + tk.MustExec("begin") + tk.MustExec("select * from t for update") + + var wg sync.WaitGroup + + hook := &ddl.TestDDLCallback{Do: dom} + wg.Add(2) + var timetk2 time.Time + var timetk3 time.Time + + one := false + f := func(job *model.Job) { + if !one { + one = true + } else { + return + } + go func() { + tk3.MustExec("truncate table test.t") + timetk3 = time.Now() + wg.Done() + }() + } + + hook.OnJobUpdatedExported.Store(&f) + dom.DDL().SetHook(hook) + + go func() { + tk2.MustExec("truncate table test.t") + timetk2 = time.Now() + wg.Done() + }() + + time.Sleep(2 * time.Second) + timeMain := time.Now() + tk.MustExec("commit") + wg.Wait() + require.True(t, timetk2.After(timeMain)) + require.True(t, timetk3.After(timeMain)) +} diff --git a/ddl/ddl.go b/ddl/ddl.go index 0fac4e23ec0b9..2e6e753e31fdf 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -85,11 +85,62 @@ const ( reorgWorkerCnt = 10 generalWorkerCnt = 1 + + // checkFlagIndexInJobArgs is the recoverCheckFlag index used in RecoverTable/RecoverSchema job arg list. + checkFlagIndexInJobArgs = 1 +) + +const ( + // The recoverCheckFlag is used to judge the gc work status when RecoverTable/RecoverSchema. + recoverCheckFlagNone int64 = iota + recoverCheckFlagEnableGC + recoverCheckFlagDisableGC ) // OnExist specifies what to do when a new object has a name collision. type OnExist uint8 +// AllocTableIDIf specifies whether to retain the old table ID. +// If this returns "false", then we would assume the table ID has been +// allocated before calling `CreateTableWithInfo` family. +type AllocTableIDIf func(*model.TableInfo) bool + +// CreateTableWithInfoConfig is the configuration of `CreateTableWithInfo`. +type CreateTableWithInfoConfig struct { + OnExist OnExist + ShouldAllocTableID AllocTableIDIf +} + +// CreateTableWithInfoConfigurier is the "diff" which can be applied to the +// CreateTableWithInfoConfig, currently implementations are "OnExist" and "AllocTableIDIf". +type CreateTableWithInfoConfigurier interface { + // Apply the change over the config. + Apply(*CreateTableWithInfoConfig) +} + +// GetCreateTableWithInfoConfig applies the series of configurier from default config +// and returns the final config. +func GetCreateTableWithInfoConfig(cs []CreateTableWithInfoConfigurier) CreateTableWithInfoConfig { + config := CreateTableWithInfoConfig{} + for _, c := range cs { + c.Apply(&config) + } + if config.ShouldAllocTableID == nil { + config.ShouldAllocTableID = func(*model.TableInfo) bool { return true } + } + return config +} + +// Apply implements Configurier. +func (o OnExist) Apply(c *CreateTableWithInfoConfig) { + c.OnExist = o +} + +// Apply implements Configurier. +func (a AllocTableIDIf) Apply(c *CreateTableWithInfoConfig) { + c.ShouldAllocTableID = a +} + const ( // OnExistError throws an error on name collision. OnExistError OnExist = iota @@ -119,6 +170,7 @@ type DDL interface { CreateView(ctx sessionctx.Context, stmt *ast.CreateViewStmt) error DropTable(ctx sessionctx.Context, stmt *ast.DropTableStmt) (err error) RecoverTable(ctx sessionctx.Context, recoverInfo *RecoverInfo) (err error) + RecoverSchema(ctx sessionctx.Context, recoverSchemaInfo *RecoverSchemaInfo) error DropView(ctx sessionctx.Context, stmt *ast.DropTableStmt) (err error) CreateIndex(ctx sessionctx.Context, stmt *ast.CreateIndexStmt) error DropIndex(ctx sessionctx.Context, stmt *ast.DropIndexStmt) error @@ -136,6 +188,9 @@ type DDL interface { CreatePlacementPolicy(ctx sessionctx.Context, stmt *ast.CreatePlacementPolicyStmt) error DropPlacementPolicy(ctx sessionctx.Context, stmt *ast.DropPlacementPolicyStmt) error AlterPlacementPolicy(ctx sessionctx.Context, stmt *ast.AlterPlacementPolicyStmt) error + CreateResourceGroup(ctx sessionctx.Context, stmt *ast.CreateResourceGroupStmt) error + AlterResourceGroup(ctx sessionctx.Context, stmt *ast.AlterResourceGroupStmt) error + DropResourceGroup(ctx sessionctx.Context, stmt *ast.DropResourceGroupStmt) error FlashbackCluster(ctx sessionctx.Context, flashbackTS uint64) error // CreateSchemaWithInfo creates a database (schema) given its database info. @@ -155,13 +210,13 @@ type DDL interface { ctx sessionctx.Context, schema model.CIStr, info *model.TableInfo, - onExist OnExist) error + cs ...CreateTableWithInfoConfigurier) error // BatchCreateTableWithInfo is like CreateTableWithInfo, but can handle multiple tables. BatchCreateTableWithInfo(ctx sessionctx.Context, schema model.CIStr, info []*model.TableInfo, - onExist OnExist) error + cs ...CreateTableWithInfoConfigurier) error // CreatePlacementPolicyWithInfo creates a placement policy // @@ -200,10 +255,6 @@ type DDL interface { GetInfoSchemaWithInterceptor(ctx sessionctx.Context) infoschema.InfoSchema // DoDDLJob does the DDL job, it's exported for test. DoDDLJob(ctx sessionctx.Context, job *model.Job) error - // MoveJobFromQueue2Table move existing DDLs from queue to table. - MoveJobFromQueue2Table(bool) error - // MoveJobFromTable2Queue move existing DDLs from table to queue. - MoveJobFromTable2Queue() error } type limitJobTask struct { @@ -218,7 +269,6 @@ type ddl struct { limitJobCh chan *limitJobTask *ddlCtx - workers map[workerType]*worker sessPool *sessionPool delRangeMgr delRangeManager enableTiFlashPoll *atomicutil.Bool @@ -370,15 +420,15 @@ func (dc *ddlCtx) isOwner() bool { return isOwner } -func (dc *ddlCtx) setDDLLabelForTopSQL(job *model.Job) { +func (dc *ddlCtx) setDDLLabelForTopSQL(jobID int64, jobQuery string) { dc.jobCtx.Lock() defer dc.jobCtx.Unlock() - ctx, exists := dc.jobCtx.jobCtxMap[job.ID] + ctx, exists := dc.jobCtx.jobCtxMap[jobID] if !exists { ctx = NewJobContext() - dc.jobCtx.jobCtxMap[job.ID] = ctx + dc.jobCtx.jobCtxMap[jobID] = ctx } - ctx.setDDLLabelForTopSQL(job) + ctx.setDDLLabelForTopSQL(jobQuery) } func (dc *ddlCtx) setDDLSourceForDiagnosis(job *model.Job) { @@ -387,15 +437,15 @@ func (dc *ddlCtx) setDDLSourceForDiagnosis(job *model.Job) { ctx, exists := dc.jobCtx.jobCtxMap[job.ID] if !exists { ctx = NewJobContext() - ctx.setDDLLabelForDiagnosis(job) dc.jobCtx.jobCtxMap[job.ID] = ctx } + ctx.setDDLLabelForDiagnosis(job) } -func (dc *ddlCtx) getResourceGroupTaggerForTopSQL(job *model.Job) tikvrpc.ResourceGroupTagger { +func (dc *ddlCtx) getResourceGroupTaggerForTopSQL(jobID int64) tikvrpc.ResourceGroupTagger { dc.jobCtx.Lock() defer dc.jobCtx.Unlock() - ctx, exists := dc.jobCtx.jobCtxMap[job.ID] + ctx, exists := dc.jobCtx.jobCtxMap[jobID] if !exists { return nil } @@ -408,19 +458,19 @@ func (dc *ddlCtx) removeJobCtx(job *model.Job) { delete(dc.jobCtx.jobCtxMap, job.ID) } -func (dc *ddlCtx) jobContext(job *model.Job) *JobContext { +func (dc *ddlCtx) jobContext(jobID int64) *JobContext { dc.jobCtx.RLock() defer dc.jobCtx.RUnlock() - if jobContext, exists := dc.jobCtx.jobCtxMap[job.ID]; exists { + if jobContext, exists := dc.jobCtx.jobCtxMap[jobID]; exists { return jobContext } return NewJobContext() } -func (dc *ddlCtx) getReorgCtx(job *model.Job) *reorgCtx { +func (dc *ddlCtx) getReorgCtx(jobID int64) *reorgCtx { dc.reorgCtx.RLock() defer dc.reorgCtx.RUnlock() - return dc.reorgCtx.reorgCtxMap[job.ID] + return dc.reorgCtx.reorgCtxMap[jobID] } func (dc *ddlCtx) newReorgCtx(r *reorgInfo) *reorgCtx { @@ -445,7 +495,7 @@ func (dc *ddlCtx) removeReorgCtx(job *model.Job) { } func (dc *ddlCtx) notifyReorgCancel(job *model.Job) { - rc := dc.getReorgCtx(job) + rc := dc.getReorgCtx(job.ID) if rc == nil { return } @@ -572,7 +622,6 @@ func newDDL(ctx context.Context, options ...Option) *ddl { // Register functions for enable/disable ddl when changing system variable `tidb_enable_ddl`. variable.EnableDDL = d.EnableDDL variable.DisableDDL = d.DisableDDL - variable.SwitchConcurrentDDL = d.SwitchConcurrentDDL variable.SwitchMDL = d.SwitchMDL return d @@ -604,7 +653,7 @@ func (d *ddl) newDeleteRangeManager(mock bool) delRangeManager { func (d *ddl) prepareWorkers4ConcurrencyDDL() { workerFactory := func(tp workerType) func() (pools.Resource, error) { return func() (pools.Resource, error) { - wk := newWorker(d.ctx, tp, d.sessPool, d.delRangeMgr, d.ddlCtx, true) + wk := newWorker(d.ctx, tp, d.sessPool, d.delRangeMgr, d.ddlCtx) sessForJob, err := d.sessPool.get() if err != nil { return nil, err @@ -627,23 +676,6 @@ func (d *ddl) prepareWorkers4ConcurrencyDDL() { d.wg.Run(d.startDispatchLoop) } -func (d *ddl) prepareWorkers4legacyDDL() { - d.workers = make(map[workerType]*worker, 2) - d.workers[generalWorker] = newWorker(d.ctx, generalWorker, d.sessPool, d.delRangeMgr, d.ddlCtx, false) - d.workers[addIdxWorker] = newWorker(d.ctx, addIdxWorker, d.sessPool, d.delRangeMgr, d.ddlCtx, false) - for _, worker := range d.workers { - worker.wg.Add(1) - w := worker - go w.start(d.ddlCtx) - - metrics.DDLCounter.WithLabelValues(fmt.Sprintf("%s_%s", metrics.CreateDDL, worker.String())).Inc() - - // When the start function is called, we will send a fake job to let worker - // checks owner firstly and try to find whether a job exists and run. - asyncNotify(worker.ddlJobCh) - } -} - // Start implements DDL.Start interface. func (d *ddl) Start(ctxPool *pools.ResourcePool) error { logutil.BgLogger().Info("[ddl] start DDL", zap.String("ID", d.uuid), zap.Bool("runWorker", config.GetGlobalConfig().Instance.TiDBEnableDDL.Load())) @@ -661,7 +693,6 @@ func (d *ddl) Start(ctxPool *pools.ResourcePool) error { d.delRangeMgr = d.newDeleteRangeManager(ctxPool == nil) d.prepareWorkers4ConcurrencyDDL() - d.prepareWorkers4legacyDDL() if config.TableLockEnabled() { d.wg.Add(1) @@ -747,9 +778,6 @@ func (d *ddl) close() { d.generalDDLWorkerPool.close() } - for _, worker := range d.workers { - worker.Close() - } // d.delRangeMgr using sessions from d.sessPool. // Put it before d.sessPool.close to reduce the time spent by d.sessPool.close. if d.delRangeMgr != nil { @@ -855,7 +883,8 @@ func getIntervalFromPolicy(policy []time.Duration, i int) (time.Duration, bool) func getJobCheckInterval(job *model.Job, i int) (time.Duration, bool) { switch job.Type { - case model.ActionAddIndex, model.ActionAddPrimaryKey, model.ActionModifyColumn: + case model.ActionAddIndex, model.ActionAddPrimaryKey, model.ActionModifyColumn, + model.ActionReorganizePartition: return getIntervalFromPolicy(slowDDLIntervalPolicy, i) case model.ActionCreateTable, model.ActionCreateSchema: return getIntervalFromPolicy(fastDDLIntervalPolicy, i) @@ -869,24 +898,10 @@ func (d *ddl) asyncNotifyWorker(job *model.Job) { if !config.GetGlobalConfig().Instance.TiDBEnableDDL.Load() { return } - if variable.EnableConcurrentDDL.Load() { - if d.isOwner() { - asyncNotify(d.ddlJobCh) - } else { - d.asyncNotifyByEtcd(addingDDLJobConcurrent, job) - } + if d.isOwner() { + asyncNotify(d.ddlJobCh) } else { - var worker *worker - if job.MayNeedReorg() { - worker = d.workers[addIdxWorker] - } else { - worker = d.workers[generalWorker] - } - if d.ownerManager.IsOwner() { - asyncNotify(worker.ddlJobCh) - } else { - d.asyncNotifyByEtcd(worker.addingDDLJobKey, job) - } + d.asyncNotifyByEtcd(addingDDLJobConcurrent, job) } } @@ -927,7 +942,6 @@ func (d *ddl) DoDDLJob(ctx sessionctx.Context, job *model.Job) error { // Instead, we merge all the jobs into one pending job. return appendToSubJobs(mci, job) } - // Get a global job ID and put the DDL job in the queue. setDDLJobQuery(ctx, job) task := &limitJobTask{job, make(chan error)} @@ -1004,7 +1018,7 @@ func (d *ddl) DoDDLJob(ctx sessionctx.Context, job *model.Job) error { continue } sessVars.StmtCtx.DDLJobID = 0 // Avoid repeat. - errs, err := CancelJobs(se, d.store, []int64{jobID}) + errs, err := CancelJobs(se, []int64{jobID}) d.sessPool.put(se) if len(errs) > 0 { logutil.BgLogger().Warn("error canceling DDL job", zap.Error(errs[0])) @@ -1042,8 +1056,13 @@ func (d *ddl) DoDDLJob(ctx sessionctx.Context, job *model.Job) error { logutil.BgLogger().Info("[ddl] DDL warnings doesn't match the warnings count", zap.Int64("jobID", jobID)) } else { for key, warning := range historyJob.ReorgMeta.Warnings { - for j := int64(0); j < historyJob.ReorgMeta.WarningsCount[key]; j++ { + keyCount := historyJob.ReorgMeta.WarningsCount[key] + if keyCount == 1 { ctx.GetSessionVars().StmtCtx.AppendWarning(warning) + } else { + newMsg := fmt.Sprintf("%d warnings with this error code, first warning: "+warning.GetMsg(), keyCount) + newWarning := dbterror.ClassTypes.Synthesize(terror.ErrCode(warning.Code()), newMsg) + ctx.GetSessionVars().StmtCtx.AppendWarning(newWarning) } } } @@ -1126,52 +1145,33 @@ func (d *ddl) startCleanDeadTableLock() { } } -// SwitchConcurrentDDL changes the DDL to concurrent DDL if toConcurrentDDL is true, otherwise, queue based DDL. -func (d *ddl) SwitchConcurrentDDL(toConcurrentDDL bool) error { - if !d.isOwner() { - return kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), d.store, true, func(ctx context.Context, txn kv.Transaction) error { - isConcurrentDDL, err := meta.NewMeta(txn).IsConcurrentDDL() - if err != nil { - return err - } - if isConcurrentDDL != toConcurrentDDL { - return errors.New("please set it on the DDL owner node") - } - return nil - }) - } - +// SwitchMDL enables MDL or disable DDL. +func (d *ddl) SwitchMDL(enable bool) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() - d.waiting.Store(true) - defer d.waiting.Store(false) - if err := d.wait4Switch(ctx); err != nil { - return err - } - var err error - if toConcurrentDDL { - err = d.MoveJobFromQueue2Table(false) - } else { - err = d.MoveJobFromTable2Queue() - } - if err == nil { - variable.EnableConcurrentDDL.Store(toConcurrentDDL) + if enable { + sql := fmt.Sprintf("UPDATE HIGH_PRIORITY %[1]s.%[2]s SET VARIABLE_VALUE = %[4]d WHERE VARIABLE_NAME = '%[3]s'", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBEnableMDL, 0) + sess, err := d.sessPool.get() + if err != nil { + logutil.BgLogger().Warn("[ddl] get session failed", zap.Error(err)) + return nil + } + defer d.sessPool.put(sess) + se := newSession(sess) + _, err = se.execute(ctx, sql, "disableMDL") + if err != nil { + logutil.BgLogger().Warn("[ddl] disable MDL failed", zap.Error(err)) + } + return nil } - logutil.BgLogger().Info("[ddl] SwitchConcurrentDDL", zap.Bool("toConcurrentDDL", toConcurrentDDL), zap.Error(err)) - return err -} -// SwitchMDL enables MDL or disable DDL. -func (d *ddl) SwitchMDL(enable bool) error { isEnableBefore := variable.EnableMDL.Load() if isEnableBefore == enable { return nil } - ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) - defer cancel() - // Check if there is any DDL running. // This check can not cover every corner cases, so users need to guarantee that there is no DDL running by themselves. sess, err := d.sessPool.get() @@ -1189,25 +1189,23 @@ func (d *ddl) SwitchMDL(enable bool) error { } variable.EnableMDL.Store(enable) - logutil.BgLogger().Info("[ddl] switch metadata lock feature", zap.Bool("enable", enable), zap.Error(err)) - return nil -} - -func (d *ddl) wait4Switch(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - default: + err = kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), d.store, true, func(ctx context.Context, txn kv.Transaction) error { + m := meta.NewMeta(txn) + oldEnable, _, err := m.GetMetadataLock() + if err != nil { + return err } - d.runningJobs.RLock() - if len(d.runningJobs.ids) == 0 { - d.runningJobs.RUnlock() - return nil + if oldEnable != enable { + err = m.SetMetadataLock(enable) } - d.runningJobs.RUnlock() - time.Sleep(time.Second * 1) + return err + }) + if err != nil { + logutil.BgLogger().Warn("[ddl] switch metadata lock feature", zap.Bool("enable", enable), zap.Error(err)) + return err } + logutil.BgLogger().Info("[ddl] switch metadata lock feature", zap.Bool("enable", enable)) + return nil } // RecoverInfo contains information needed by DDL.RecoverTable. @@ -1221,10 +1219,25 @@ type RecoverInfo struct { OldTableName string } +// RecoverSchemaInfo contains information needed by DDL.RecoverSchema. +type RecoverSchemaInfo struct { + *model.DBInfo + RecoverTabsInfo []*RecoverInfo + DropJobID int64 + SnapshotTS uint64 + OldSchemaName model.CIStr +} + // delayForAsyncCommit sleeps `SafeWindow + AllowedClockDrift` before a DDL job finishes. // It should be called before any DDL that could break data consistency. // This provides a safe window for async commit and 1PC to commit with an old schema. func delayForAsyncCommit() { + if variable.EnableMDL.Load() { + // If metadata lock is enabled. The transaction of DDL must begin after prewrite of the async commit transaction, + // then the commit ts of DDL must be greater than the async commit transaction. In this case, the corresponding schema of the async commit transaction + // is correct. But if metadata lock is disabled, we can't ensure that the corresponding schema of the async commit transaction isn't change. + return + } cfg := config.GetGlobalConfig().TiKVClient.AsyncCommit duration := cfg.SafeWindow + cfg.AllowedClockDrift logutil.BgLogger().Info("sleep before DDL finishes to make async commit and 1PC safe", @@ -1309,13 +1322,8 @@ func GetDDLInfo(s sessionctx.Context) (*Info, error) { } t := meta.NewMeta(txn) info.Jobs = make([]*model.Job, 0, 2) - enable := variable.EnableConcurrentDDL.Load() var generalJob, reorgJob *model.Job - if enable { - generalJob, reorgJob, err = get2JobsFromTable(sess) - } else { - generalJob, reorgJob, err = get2JobsFromQueue(t) - } + generalJob, reorgJob, err = get2JobsFromTable(sess) if err != nil { return nil, errors.Trace(err) } @@ -1336,7 +1344,7 @@ func GetDDLInfo(s sessionctx.Context) (*Info, error) { return info, nil } - _, info.ReorgHandle, _, _, err = newReorgHandler(t, sess, enable).GetDDLReorgHandle(reorgJob) + _, info.ReorgHandle, _, _, err = newReorgHandler(sess).GetDDLReorgHandle(reorgJob) if err != nil { if meta.ErrDDLReorgElementNotExist.Equal(err) { return info, nil @@ -1347,19 +1355,6 @@ func GetDDLInfo(s sessionctx.Context) (*Info, error) { return info, nil } -func get2JobsFromQueue(t *meta.Meta) (*model.Job, *model.Job, error) { - generalJob, err := t.GetDDLJobByIdx(0) - if err != nil { - return nil, nil, errors.Trace(err) - } - reorgJob, err := t.GetDDLJobByIdx(0, meta.AddIndexJobListKey) - if err != nil { - return nil, nil, errors.Trace(err) - } - - return generalJob, reorgJob, nil -} - func get2JobsFromTable(sess *session) (*model.Job, *model.Job, error) { var generalJob, reorgJob *model.Job jobs, err := getJobsBySQL(sess, JobTable, "not reorg order by job_id limit 1") @@ -1381,82 +1376,8 @@ func get2JobsFromTable(sess *session) (*model.Job, *model.Job, error) { } // CancelJobs cancels the DDL jobs. -func CancelJobs(se sessionctx.Context, store kv.Storage, ids []int64) (errs []error, err error) { - if variable.EnableConcurrentDDL.Load() { - return cancelConcurrencyJobs(se, ids) - } - - err = kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, true, func(ctx context.Context, txn kv.Transaction) error { - errs, err = cancelLegacyJobs(txn, ids) - return err - }) - return -} - -func cancelLegacyJobs(txn kv.Transaction, ids []int64) ([]error, error) { - if len(ids) == 0 { - return nil, nil - } - - errs := make([]error, len(ids)) - t := meta.NewMeta(txn) - generalJobs, err := getDDLJobsInQueue(t, meta.DefaultJobListKey) - if err != nil { - return nil, errors.Trace(err) - } - addIdxJobs, err := getDDLJobsInQueue(t, meta.AddIndexJobListKey) - if err != nil { - return nil, errors.Trace(err) - } - jobs := append(generalJobs, addIdxJobs...) - jobsMap := make(map[int64]int) - for i, id := range ids { - jobsMap[id] = i - } - for j, job := range jobs { - i, ok := jobsMap[job.ID] - if !ok { - logutil.BgLogger().Debug("the job that needs to be canceled isn't equal to current job", - zap.Int64("need to canceled job ID", job.ID), - zap.Int64("current job ID", job.ID)) - continue - } - delete(jobsMap, job.ID) - // These states can't be cancelled. - if job.IsDone() || job.IsSynced() { - errs[i] = dbterror.ErrCancelFinishedDDLJob.GenWithStackByArgs(job.ID) - continue - } - // If the state is rolling back, it means the work is cleaning the data after cancelling the job. - if job.IsCancelled() || job.IsRollingback() || job.IsRollbackDone() { - continue - } - if !job.IsRollbackable() { - errs[i] = dbterror.ErrCannotCancelDDLJob.GenWithStackByArgs(job.ID) - continue - } - - job.State = model.JobStateCancelling - // Make sure RawArgs isn't overwritten. - err := json.Unmarshal(job.RawArgs, &job.Args) - if err != nil { - errs[i] = errors.Trace(err) - continue - } - if j >= len(generalJobs) { - offset := int64(j - len(generalJobs)) - err = t.UpdateDDLJob(offset, job, true, meta.AddIndexJobListKey) - } else { - err = t.UpdateDDLJob(int64(j), job, true) - } - if err != nil { - errs[i] = errors.Trace(err) - } - } - for id, i := range jobsMap { - errs[i] = dbterror.ErrDDLJobNotFound.GenWithStackByArgs(id) - } - return errs, nil +func CancelJobs(se sessionctx.Context, ids []int64) (errs []error, err error) { + return cancelConcurrencyJobs(se, ids) } // cancelConcurrencyJobs cancels the DDL jobs that are in the concurrent state. @@ -1535,45 +1456,9 @@ func cancelConcurrencyJobs(se sessionctx.Context, ids []int64) ([]error, error) return errs, nil } -func getDDLJobsInQueue(t *meta.Meta, jobListKey meta.JobListKeyType) ([]*model.Job, error) { - cnt, err := t.DDLJobQueueLen(jobListKey) - if err != nil { - return nil, errors.Trace(err) - } - jobs := make([]*model.Job, cnt) - for i := range jobs { - jobs[i], err = t.GetDDLJobByIdx(int64(i), jobListKey) - if err != nil { - return nil, errors.Trace(err) - } - } - return jobs, nil -} - // GetAllDDLJobs get all DDL jobs and sorts jobs by job.ID. func GetAllDDLJobs(sess sessionctx.Context, t *meta.Meta) ([]*model.Job, error) { - if variable.EnableConcurrentDDL.Load() { - return getJobsBySQL(newSession(sess), JobTable, "1 order by job_id") - } - - return getDDLJobs(t) -} - -// getDDLJobs get all DDL jobs and sorts jobs by job.ID. -func getDDLJobs(t *meta.Meta) ([]*model.Job, error) { - generalJobs, err := getDDLJobsInQueue(t, meta.DefaultJobListKey) - if err != nil { - return nil, errors.Trace(err) - } - addIdxJobs, err := getDDLJobsInQueue(t, meta.AddIndexJobListKey) - if err != nil { - return nil, errors.Trace(err) - } - jobs := append(generalJobs, addIdxJobs...) - slices.SortFunc(jobs, func(i, j *model.Job) bool { - return i.ID < j.ID - }) - return jobs, nil + return getJobsBySQL(newSession(sess), JobTable, "1 order by job_id") } // MaxHistoryJobs is exported for testing. @@ -1653,7 +1538,7 @@ func (s *session) begin() error { } func (s *session) commit() error { - s.StmtCommit() + s.StmtCommit(context.Background()) return s.CommitTxn(context.Background()) } @@ -1662,12 +1547,12 @@ func (s *session) txn() (kv.Transaction, error) { } func (s *session) rollback() { - s.StmtRollback() + s.StmtRollback(context.Background(), false) s.RollbackTxn(context.Background()) } func (s *session) reset() { - s.StmtRollback() + s.StmtRollback(context.Background(), false) } func (s *session) execute(ctx context.Context, query string, label string) ([]chunk.Row, error) { @@ -1676,7 +1561,11 @@ func (s *session) execute(ctx context.Context, query string, label string) ([]ch defer func() { metrics.DDLJobTableDuration.WithLabelValues(label + "-" + metrics.RetLabel(err)).Observe(time.Since(startTime).Seconds()) }() - rs, err := s.Context.(sqlexec.SQLExecutor).ExecuteInternal(kv.WithInternalSourceType(ctx, kv.InternalTxnDDL), query) + + if ctx.Value(kv.RequestSourceKey) == nil { + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnDDL) + } + rs, err := s.Context.(sqlexec.SQLExecutor).ExecuteInternal(ctx, query) if err != nil { return nil, errors.Trace(err) } @@ -1696,6 +1585,19 @@ func (s *session) session() sessionctx.Context { return s.Context } +func (s *session) runInTxn(f func(*session) error) (err error) { + err = s.begin() + if err != nil { + return err + } + err = f(s) + if err != nil { + s.rollback() + return + } + return errors.Trace(s.commit()) +} + // GetAllHistoryDDLJobs get all the done DDL jobs. func GetAllHistoryDDLJobs(m *meta.Meta) ([]*model.Job, error) { iterator, err := GetLastHistoryDDLJobsIterator(m) @@ -1759,19 +1661,11 @@ func GetHistoryJobByID(sess sessionctx.Context, id int64) (*model.Job, error) { return job, errors.Trace(err) } -// AddHistoryDDLJobForTest used for test. -func AddHistoryDDLJobForTest(sess sessionctx.Context, t *meta.Meta, job *model.Job, updateRawArgs bool) error { - return AddHistoryDDLJob(newSession(sess), t, job, updateRawArgs, variable.EnableConcurrentDDL.Load()) -} - // AddHistoryDDLJob record the history job. -func AddHistoryDDLJob(sess *session, t *meta.Meta, job *model.Job, updateRawArgs bool, concurrentDDL bool) error { - if concurrentDDL { - // only add history job into table if it is concurrent DDL. - err := addHistoryDDLJob2Table(sess, job, updateRawArgs) - if err != nil { - logutil.BgLogger().Info("[ddl] failed to add DDL job to history table", zap.Error(err)) - } +func AddHistoryDDLJob(sess *session, t *meta.Meta, job *model.Job, updateRawArgs bool) error { + err := addHistoryDDLJob2Table(sess, job, updateRawArgs) + if err != nil { + logutil.BgLogger().Info("[ddl] failed to add DDL job to history table", zap.Error(err)) } // we always add history DDL job to job list at this moment. return t.AddHistoryDDLJob(job, updateRawArgs) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 153567e2c9fe1..7774f87ce5f6c 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -33,11 +33,13 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl/label" + "github.com/pingcap/tidb/ddl/resourcegroup" ddlutil "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta/autoid" + "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/format" @@ -45,6 +47,7 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" field_types "github.com/pingcap/tidb/parser/types" + "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" @@ -81,6 +84,7 @@ const ( // When setting the placement policy with "PLACEMENT POLICY `default`", // it means to remove placement policy from the specified object. defaultPlacementPolicyName = "default" + defaultResourceGroupName = "default" tiflashCheckPendingTablesWaitTime = 3000 * time.Millisecond // Once tiflashCheckPendingTablesLimit is reached, we trigger a limiter detection. tiflashCheckPendingTablesLimit = 100 @@ -94,11 +98,11 @@ func (d *ddl) CreateSchema(ctx sessionctx.Context, stmt *ast.CreateDatabaseStmt) // If no charset and/or collation is specified use collation_server and character_set_server charsetOpt := ast.CharsetOpt{} if sessionVars.GlobalVarsAccessor != nil { - charsetOpt.Col, err = sessionVars.GetSessionOrGlobalSystemVar(variable.CollationServer) + charsetOpt.Col, err = sessionVars.GetSessionOrGlobalSystemVar(context.Background(), variable.CollationServer) if err != nil { return err } - charsetOpt.Chs, err = sessionVars.GetSessionOrGlobalSystemVar(variable.CharacterSetServer) + charsetOpt.Chs, err = sessionVars.GetSessionOrGlobalSystemVar(context.Background(), variable.CharacterSetServer) if err != nil { return err } @@ -633,6 +637,18 @@ func (d *ddl) DropSchema(ctx sessionctx.Context, stmt *ast.DropDatabaseStmt) (er return nil } +func (d *ddl) RecoverSchema(ctx sessionctx.Context, recoverSchemaInfo *RecoverSchemaInfo) error { + recoverSchemaInfo.State = model.StateNone + job := &model.Job{ + Type: model.ActionRecoverSchema, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{recoverSchemaInfo, recoverCheckFlagNone}, + } + err := d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) + return errors.Trace(err) +} + func checkTooLongSchema(schema model.CIStr) error { if utf8.RuneCountInString(schema.L) > mysql.MaxDatabaseNameLength { return dbterror.ErrTooLongIdent.GenWithStackByArgs(schema) @@ -654,6 +670,20 @@ func checkTooLongIndex(index model.CIStr) error { return nil } +func checkTooLongColumn(col model.CIStr) error { + if utf8.RuneCountInString(col.L) > mysql.MaxColumnNameLength { + return dbterror.ErrTooLongIdent.GenWithStackByArgs(col) + } + return nil +} + +func checkTooLongForeignKey(fk model.CIStr) error { + if utf8.RuneCountInString(fk.L) > mysql.MaxForeignKeyIdentifierLen { + return dbterror.ErrTooLongIdent.GenWithStackByArgs(fk) + } + return nil +} + func setColumnFlagWithConstraint(colMap map[string]*table.Column, v *ast.Constraint) { switch v.Tp { case ast.ConstraintPrimaryKey: @@ -1055,7 +1085,7 @@ func columnDefToCol(ctx sessionctx.Context, offset int, colDef *ast.ColumnDef, o var sb strings.Builder restoreFlags := format.RestoreStringSingleQuotes | format.RestoreKeyWordLowercase | format.RestoreNameBackQuotes | - format.RestoreSpacesAroundBinaryOperation + format.RestoreSpacesAroundBinaryOperation | format.RestoreWithoutSchemaName | format.RestoreWithoutTableName restoreCtx := format.NewRestoreCtx(restoreFlags, &sb) for _, v := range colDef.Options { @@ -1115,7 +1145,10 @@ func columnDefToCol(ctx sessionctx.Context, offset int, colDef *ast.ColumnDef, o } col.GeneratedExprString = sb.String() col.GeneratedStored = v.Stored - _, dependColNames := findDependedColumnNames(colDef) + _, dependColNames, err := findDependedColumnNames(model.NewCIStr(""), model.NewCIStr(""), colDef) + if err != nil { + return nil, nil, errors.Trace(err) + } col.Dependences = dependColNames case ast.ColumnOptionCollate: if field_types.HasCharset(colDef.Tp) { @@ -1138,7 +1171,7 @@ func columnDefToCol(ctx sessionctx.Context, offset int, colDef *ast.ColumnDef, o // getFuncCallDefaultValue gets the default column value of function-call expression. func getFuncCallDefaultValue(col *table.Column, option *ast.ColumnOption, expr *ast.FuncCallExpr) (interface{}, bool, error) { switch expr.FnName.L { - case ast.CurrentTimestamp: + case ast.CurrentTimestamp, ast.CurrentDate: tp, fsp := col.FieldType.GetType(), col.FieldType.GetDecimal() if tp == mysql.TypeTimestamp || tp == mysql.TypeDatetime { defaultFsp := 0 @@ -1191,7 +1224,7 @@ func getDefaultValue(ctx sessionctx.Context, col *table.Column, option *ast.Colu // If the function call is ast.CurrentTimestamp, it needs to be continuously processed. } - if tp == mysql.TypeTimestamp || tp == mysql.TypeDatetime { + if tp == mysql.TypeTimestamp || tp == mysql.TypeDatetime || tp == mysql.TypeDate { vd, err := expression.GetTimeValue(ctx, option.Expr, tp, fsp) value := vd.GetValue() if err != nil { @@ -1518,10 +1551,23 @@ func containsColumnOption(colDef *ast.ColumnDef, opTp ast.ColumnOptionType) bool // IsAutoRandomColumnID returns true if the given column ID belongs to an auto_random column. func IsAutoRandomColumnID(tblInfo *model.TableInfo, colID int64) bool { - return tblInfo.PKIsHandle && tblInfo.ContainsAutoRandomBits() && tblInfo.GetPkColInfo().ID == colID + if !tblInfo.ContainsAutoRandomBits() { + return false + } + if tblInfo.PKIsHandle { + return tblInfo.GetPkColInfo().ID == colID + } else if tblInfo.IsCommonHandle { + pk := tables.FindPrimaryIndex(tblInfo) + if pk == nil { + return false + } + offset := pk.Columns[0].Offset + return tblInfo.Columns[offset].ID == colID + } + return false } -func checkGeneratedColumn(ctx sessionctx.Context, colDefs []*ast.ColumnDef) error { +func checkGeneratedColumn(ctx sessionctx.Context, schemaName model.CIStr, tableName model.CIStr, colDefs []*ast.ColumnDef) error { var colName2Generation = make(map[string]columnGenerationInDDL, len(colDefs)) var exists bool var autoIncrementColumn string @@ -1536,7 +1582,10 @@ func checkGeneratedColumn(ctx sessionctx.Context, colDefs []*ast.ColumnDef) erro if containsColumnOption(colDef, ast.ColumnOptionAutoIncrement) { exists, autoIncrementColumn = true, colDef.Name.Name.L } - generated, depCols := findDependedColumnNames(colDef) + generated, depCols, err := findDependedColumnNames(schemaName, tableName, colDef) + if err != nil { + return errors.Trace(err) + } if !generated { colName2Generation[colDef.Name.Name.L] = columnGenerationInDDL{ position: i, @@ -1571,11 +1620,10 @@ func checkGeneratedColumn(ctx sessionctx.Context, colDefs []*ast.ColumnDef) erro return nil } -func checkTooLongColumn(cols []*model.ColumnInfo) error { +func checkTooLongColumns(cols []*model.ColumnInfo) error { for _, col := range cols { - colName := col.Name.O - if utf8.RuneCountInString(colName) > mysql.MaxColumnNameLength { - return dbterror.ErrTooLongIdent.GenWithStackByArgs(colName) + if err := checkTooLongColumn(col.Name); err != nil { + return err } } return nil @@ -1654,7 +1702,7 @@ func setEmptyConstraintName(namesMap map[string]bool, constr *ast.Constraint) { } } if colName == "" { - colName = constr.Keys[0].Column.Name.L + colName = constr.Keys[0].Column.Name.O } constrName := colName i := 2 @@ -1717,17 +1765,31 @@ func checkInvisibleIndexOnPK(tblInfo *model.TableInfo) error { } func setTableAutoRandomBits(ctx sessionctx.Context, tbInfo *model.TableInfo, colDefs []*ast.ColumnDef) error { - pkColName := tbInfo.GetPkName() for _, col := range colDefs { if containsColumnOption(col, ast.ColumnOptionAutoRandom) { if col.Tp.GetType() != mysql.TypeLonglong { return dbterror.ErrInvalidAutoRandom.GenWithStackByArgs( fmt.Sprintf(autoid.AutoRandomOnNonBigIntColumn, types.TypeStr(col.Tp.GetType()))) } - if !tbInfo.PKIsHandle || col.Name.Name.L != pkColName.L { - errMsg := fmt.Sprintf(autoid.AutoRandomPKisNotHandleErrMsg, col.Name.Name.O) - return dbterror.ErrInvalidAutoRandom.GenWithStackByArgs(errMsg) + switch { + case tbInfo.PKIsHandle: + if tbInfo.GetPkName().L != col.Name.Name.L { + errMsg := fmt.Sprintf(autoid.AutoRandomMustFirstColumnInPK, col.Name.Name.O) + return dbterror.ErrInvalidAutoRandom.GenWithStackByArgs(errMsg) + } + case tbInfo.IsCommonHandle: + pk := tables.FindPrimaryIndex(tbInfo) + if pk == nil { + return dbterror.ErrInvalidAutoRandom.GenWithStackByArgs(autoid.AutoRandomNoClusteredPKErrMsg) + } + if col.Name.Name.L != pk.Columns[0].Name.L { + errMsg := fmt.Sprintf(autoid.AutoRandomMustFirstColumnInPK, col.Name.Name.O) + return dbterror.ErrInvalidAutoRandom.GenWithStackByArgs(errMsg) + } + default: + return dbterror.ErrInvalidAutoRandom.GenWithStackByArgs(autoid.AutoRandomNoClusteredPKErrMsg) } + if containsColumnOption(col, ast.ColumnOptionAutoIncrement) { return dbterror.ErrInvalidAutoRandom.GenWithStackByArgs(autoid.AutoRandomIncompatibleWithAutoIncErrMsg) } @@ -1927,7 +1989,7 @@ func addIndexForForeignKey(ctx sessionctx.Context, tbInfo *model.TableInfo) erro if handleCol != nil && len(fk.Cols) == 1 && handleCol.Name.L == fk.Cols[0].L { continue } - if model.FindIndexByColumns(tbInfo, fk.Cols...) != nil { + if model.FindIndexByColumns(tbInfo, tbInfo.Indices, fk.Cols...) != nil { continue } idxName := fk.Name @@ -2008,7 +2070,7 @@ func checkTableInfoValidExtra(tbInfo *model.TableInfo) error { if err := checkDuplicateColumn(tbInfo.Columns); err != nil { return err } - if err := checkTooLongColumn(tbInfo.Columns); err != nil { + if err := checkTooLongColumns(tbInfo.Columns); err != nil { return err } if err := checkTooManyColumns(tbInfo.Columns); err != nil { @@ -2041,7 +2103,7 @@ func CheckTableInfoValidWithStmt(ctx sessionctx.Context, tbInfo *model.TableInfo func checkTableInfoValidWithStmt(ctx sessionctx.Context, tbInfo *model.TableInfo, s *ast.CreateTableStmt) (err error) { // All of these rely on the AST structure of expressions, which were // lost in the model (got serialized into strings). - if err := checkGeneratedColumn(ctx, s.Cols); err != nil { + if err := checkGeneratedColumn(ctx, s.Table.Schema, tbInfo.Name, s.Cols); err != nil { return errors.Trace(err) } @@ -2062,6 +2124,11 @@ func checkTableInfoValidWithStmt(ctx sessionctx.Context, tbInfo *model.TableInfo } } } + if tbInfo.TTLInfo != nil { + if err := checkTTLInfoValid(ctx, s.Table.Schema, tbInfo); err != nil { + return errors.Trace(err) + } + } return nil } @@ -2094,7 +2161,7 @@ func checkPartitionDefinitionConstraints(ctx sessionctx.Context, tbInfo *model.T // checkTableInfoValid uses to check table info valid. This is used to validate table info. func checkTableInfoValid(tblInfo *model.TableInfo) error { - _, err := tables.TableFromMeta(nil, tblInfo) + _, err := tables.TableFromMeta(autoid.NewAllocators(false), tblInfo) if err != nil { return err } @@ -2140,6 +2207,10 @@ func BuildTableInfoWithLike(ctx sessionctx.Context, ident ast.Ident, referTblInf copy(pi.Definitions, referTblInfo.Partition.Definitions) tblInfo.Partition = &pi } + + if referTblInfo.TTLInfo != nil { + tblInfo.TTLInfo = referTblInfo.TTLInfo.Clone() + } return &tblInfo, nil } @@ -2431,7 +2502,13 @@ func (d *ddl) createTableWithInfoPost( // Default tableAutoIncID base is 0. // If the first ID is expected to greater than 1, we need to do rebase. newEnd := tbInfo.AutoIncID - 1 - if err = d.handleAutoIncID(tbInfo, schemaID, newEnd, autoid.RowIDAllocType); err != nil { + var allocType autoid.AllocatorType + if tbInfo.SepAutoInc() { + allocType = autoid.AutoIncrementType + } else { + allocType = autoid.RowIDAllocType + } + if err = d.handleAutoIncID(tbInfo, schemaID, newEnd, allocType); err != nil { return errors.Trace(err) } } @@ -2448,9 +2525,11 @@ func (d *ddl) CreateTableWithInfo( ctx sessionctx.Context, dbName model.CIStr, tbInfo *model.TableInfo, - onExist OnExist, + cs ...CreateTableWithInfoConfigurier, ) (err error) { - job, err := d.createTableWithInfoJob(ctx, dbName, tbInfo, onExist, false) + c := GetCreateTableWithInfoConfig(cs) + + job, err := d.createTableWithInfoJob(ctx, dbName, tbInfo, c.OnExist, !c.ShouldAllocTableID(tbInfo)) if err != nil { return err } @@ -2461,7 +2540,7 @@ func (d *ddl) CreateTableWithInfo( err = d.DoDDLJob(ctx, job) if err != nil { // table exists, but if_not_exists flags is true, so we ignore this error. - if onExist == OnExistIgnore && infoschema.ErrTableExists.Equal(err) { + if c.OnExist == OnExistIgnore && infoschema.ErrTableExists.Equal(err) { ctx.GetSessionVars().StmtCtx.AppendNote(err) err = nil } @@ -2476,7 +2555,10 @@ func (d *ddl) CreateTableWithInfo( func (d *ddl) BatchCreateTableWithInfo(ctx sessionctx.Context, dbName model.CIStr, infos []*model.TableInfo, - onExist OnExist) error { + cs ...CreateTableWithInfoConfigurier, +) error { + c := GetCreateTableWithInfoConfig(cs) + jobs := &model.Job{ BinlogInfo: &model.HistoryInfo{}, } @@ -2491,7 +2573,7 @@ func (d *ddl) BatchCreateTableWithInfo(ctx sessionctx.Context, for _, info := range infos { if _, ok := duplication[info.Name.L]; ok { err = infoschema.ErrTableExists.FastGenByArgs("can not batch create tables with same name") - if onExist == OnExistIgnore && infoschema.ErrTableExists.Equal(err) { + if c.OnExist == OnExistIgnore && infoschema.ErrTableExists.Equal(err) { ctx.GetSessionVars().StmtCtx.AppendNote(err) err = nil } @@ -2515,15 +2597,17 @@ func (d *ddl) BatchCreateTableWithInfo(ctx sessionctx.Context, } for _, info := range infos { - info.ID, genIDs = genIDs[0], genIDs[1:] + if c.ShouldAllocTableID(info) { + info.ID, genIDs = genIDs[0], genIDs[1:] - if parts := info.GetPartitionInfo(); parts != nil { - for i := range parts.Definitions { - parts.Definitions[i].ID, genIDs = genIDs[0], genIDs[1:] + if parts := info.GetPartitionInfo(); parts != nil { + for i := range parts.Definitions { + parts.Definitions[i].ID, genIDs = genIDs[0], genIDs[1:] + } } } - job, err := d.createTableWithInfoJob(ctx, dbName, info, onExist, true) + job, err := d.createTableWithInfoJob(ctx, dbName, info, c.OnExist, true) if err != nil { return errors.Trace(err) } @@ -2555,7 +2639,7 @@ func (d *ddl) BatchCreateTableWithInfo(ctx sessionctx.Context, err = d.DoDDLJob(ctx, jobs) if err != nil { // table exists, but if_not_exists flags is true, so we ignore this error. - if onExist == OnExistIgnore && infoschema.ErrTableExists.Equal(err) { + if c.OnExist == OnExistIgnore && infoschema.ErrTableExists.Equal(err) { ctx.GetSessionVars().StmtCtx.AppendNote(err) err = nil } @@ -2629,7 +2713,7 @@ func (d *ddl) preSplitAndScatter(ctx sessionctx.Context, tbInfo *model.TableInfo preSplit func() scatterRegion bool ) - val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBScatterRegion) + val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBScatterRegion) if err != nil { logutil.BgLogger().Warn("[ddl] won't scatter region", zap.Error(err)) } else { @@ -2649,6 +2733,14 @@ func (d *ddl) preSplitAndScatter(ctx sessionctx.Context, tbInfo *model.TableInfo func (d *ddl) FlashbackCluster(ctx sessionctx.Context, flashbackTS uint64) error { logutil.BgLogger().Info("[ddl] get flashback cluster job", zap.String("flashbackTS", oracle.GetTimeFromTS(flashbackTS).String())) + nowTS, err := ctx.GetStore().GetOracle().GetTimestamp(d.ctx, &oracle.Option{}) + if err != nil { + return errors.Trace(err) + } + gap := time.Until(oracle.GetTimeFromTS(nowTS)).Abs() + if gap > 1*time.Second { + ctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("Gap between local time and PD TSO is %s, please check PD/system time", gap)) + } job := &model.Job{ Type: model.ActionFlashbackCluster, BinlogInfo: &model.HistoryInfo{}, @@ -2656,10 +2748,16 @@ func (d *ddl) FlashbackCluster(ctx sessionctx.Context, flashbackTS uint64) error Args: []interface{}{ flashbackTS, map[string]interface{}{}, - variable.On, /* tidb_super_read_only */ - true /* tidb_gc_enable */}, + true, /* tidb_gc_enable */ + variable.On, /* tidb_enable_auto_analyze */ + variable.Off, /* tidb_super_read_only */ + 0, /* totalRegions */ + 0, /* startTS */ + 0, /* commitTS */ + variable.On, /* tidb_ttl_job_enable */ + []kv.KeyRange{} /* flashback key_ranges */}, } - err := d.DoDDLJob(ctx, job) + err = d.DoDDLJob(ctx, job) err = d.callHookOnChanged(job, err) return errors.Trace(err) } @@ -2688,9 +2786,7 @@ func (d *ddl) RecoverTable(ctx sessionctx.Context, recoverInfo *RecoverInfo) (er Type: model.ActionRecoverTable, BinlogInfo: &model.HistoryInfo{}, - Args: []interface{}{tbInfo, recoverInfo.AutoIDs.RowID, recoverInfo.DropJobID, - recoverInfo.SnapshotTS, recoverTableCheckFlagNone, recoverInfo.AutoIDs.RandomID, - recoverInfo.OldSchemaName, recoverInfo.OldTableName}, + Args: []interface{}{recoverInfo, recoverCheckFlagNone}, } err = d.DoDDLJob(ctx, job) err = d.callHookOnChanged(job, err) @@ -2772,23 +2868,30 @@ func checkPartitionByList(ctx sessionctx.Context, tbInfo *model.TableInfo) error return checkListPartitionValue(ctx, tbInfo) } +func isColTypeAllowedAsPartitioningCol(fieldType types.FieldType) bool { + // The permitted data types are shown in the following list: + // All integer types + // DATE and DATETIME + // CHAR, VARCHAR, BINARY, and VARBINARY + // See https://dev.mysql.com/doc/mysql-partitioning-excerpt/5.7/en/partitioning-columns.html + // Note that also TIME is allowed in MySQL. Also see https://bugs.mysql.com/bug.php?id=84362 + switch fieldType.GetType() { + case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: + case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeDuration: + case mysql.TypeVarchar, mysql.TypeString: + default: + return false + } + return true +} + func checkColumnsPartitionType(tbInfo *model.TableInfo) error { for _, col := range tbInfo.Partition.Columns { colInfo := tbInfo.FindPublicColumnByName(col.L) if colInfo == nil { return errors.Trace(dbterror.ErrFieldNotFoundPart) } - // The permitted data types are shown in the following list: - // All integer types - // DATE and DATETIME - // CHAR, VARCHAR, BINARY, and VARBINARY - // See https://dev.mysql.com/doc/mysql-partitioning-excerpt/5.7/en/partitioning-columns.html - // Note that also TIME is allowed in MySQL. Also see https://bugs.mysql.com/bug.php?id=84362 - switch colInfo.FieldType.GetType() { - case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: - case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeDuration: - case mysql.TypeVarchar, mysql.TypeString: - default: + if !isColTypeAllowedAsPartitioningCol(colInfo.FieldType) { return dbterror.ErrNotAllowedTypeInPartition.GenWithStackByArgs(col.O) } } @@ -2930,8 +3033,29 @@ func SetDirectPlacementOpt(placementSettings *model.PlacementSettings, placement return nil } +// SetDirectResourceGroupUnit tries to set the ResourceGroupSettings. +func SetDirectResourceGroupUnit(resourceGroupSettings *model.ResourceGroupSettings, typ ast.ResourceUnitType, stringVal string, uintVal uint64) error { + switch typ { + case ast.ResourceRRURate: + resourceGroupSettings.RRURate = uintVal + case ast.ResourceWRURate: + resourceGroupSettings.WRURate = uintVal + case ast.ResourceUnitCPU: + resourceGroupSettings.CPULimiter = stringVal + case ast.ResourceUnitIOReadBandwidth: + resourceGroupSettings.IOReadBandwidth = stringVal + case ast.ResourceUnitIOWriteBandwidth: + resourceGroupSettings.IOWriteBandwidth = stringVal + default: + return errors.Trace(errors.New("unknown resource unit type")) + } + return nil +} + // handleTableOptions updates tableInfo according to table options. func handleTableOptions(options []*ast.TableOption, tbInfo *model.TableInfo) error { + var ttlOptionsHandled bool + for _, op := range options { switch op.Tp { case ast.TableOptionAutoIncrement: @@ -2968,6 +3092,28 @@ func handleTableOptions(options []*ast.TableOption, tbInfo *model.TableInfo) err tbInfo.PlacementPolicyRef = &model.PolicyRefInfo{ Name: model.NewCIStr(op.StrValue), } + case ast.TableOptionTTL, ast.TableOptionTTLEnable, ast.TableOptionTTLJobInterval: + if ttlOptionsHandled { + continue + } + + ttlInfo, ttlEnable, ttlJobInterval, err := getTTLInfoInOptions(options) + if err != nil { + return err + } + // It's impossible that `ttlInfo` and `ttlEnable` are all nil, because we have met this option. + // After exclude the situation `ttlInfo == nil && ttlEnable != nil`, we could say `ttlInfo != nil` + if ttlInfo == nil { + if ttlEnable != nil { + return errors.Trace(dbterror.ErrSetTTLOptionForNonTTLTable.FastGenByArgs("TTL_ENABLE")) + } + if ttlJobInterval != nil { + return errors.Trace(dbterror.ErrSetTTLOptionForNonTTLTable.FastGenByArgs("TTL_JOB_INTERVAL")) + } + } + + tbInfo.TTLInfo = ttlInfo + ttlOptionsHandled = true } } shardingBits := shardingBits(tbInfo) @@ -3153,12 +3299,21 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast return dbterror.ErrOptOnCacheTable.GenWithStackByArgs("Alter Table") } } + // set name for anonymous foreign key. + maxForeignKeyID := tb.Meta().MaxForeignKeyID + for _, spec := range validSpecs { + if spec.Tp == ast.AlterTableAddConstraint && spec.Constraint.Tp == ast.ConstraintForeignKey && spec.Constraint.Name == "" { + maxForeignKeyID++ + spec.Constraint.Name = fmt.Sprintf("fk_%d", maxForeignKeyID) + } + } if len(validSpecs) > 1 { sctx.GetSessionVars().StmtCtx.MultiSchemaInfo = model.NewMultiSchemaInfo() } for _, spec := range validSpecs { var handledCharsetOrCollate bool + var ttlOptionsHandled bool switch spec.Tp { case ast.AlterTableAddColumns: err = d.AddColumn(sctx, ident, spec) @@ -3167,7 +3322,7 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast case ast.AlterTableCoalescePartitions: err = d.CoalescePartitions(sctx, ident, spec) case ast.AlterTableReorganizePartition: - err = errors.Trace(dbterror.ErrUnsupportedReorganizePartition) + err = d.ReorganizePartitions(sctx, ident, spec) case ast.AlterTableReorganizeFirstPartition: err = dbterror.ErrGeneralUnsupportedDDL.GenWithStackByArgs("MERGE FIRST PARTITION") case ast.AlterTableReorganizeLastPartition: @@ -3264,7 +3419,7 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast } err = d.ShardRowID(sctx, ident, opt.UintValue) case ast.TableOptionAutoIncrement: - err = d.RebaseAutoID(sctx, ident, int64(opt.UintValue), autoid.RowIDAllocType, opt.BoolValue) + err = d.RebaseAutoID(sctx, ident, int64(opt.UintValue), autoid.AutoIncrementType, opt.BoolValue) case ast.TableOptionAutoIdCache: if opt.UintValue > uint64(math.MaxInt64) { // TODO: Refine this error. @@ -3295,6 +3450,21 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast Name: model.NewCIStr(opt.StrValue), } case ast.TableOptionEngine: + case ast.TableOptionTTL, ast.TableOptionTTLEnable, ast.TableOptionTTLJobInterval: + var ttlInfo *model.TTLInfo + var ttlEnable *bool + var ttlJobInterval *string + + if ttlOptionsHandled { + continue + } + ttlInfo, ttlEnable, ttlJobInterval, err = getTTLInfoInOptions(spec.Options) + if err != nil { + return err + } + err = d.AlterTableTTLInfoOrEnable(sctx, ident, ttlInfo, ttlEnable, ttlJobInterval) + + ttlOptionsHandled = true default: err = dbterror.ErrUnsupportedAlterTableOption } @@ -3338,6 +3508,9 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast case ast.AlterTableDisableKeys, ast.AlterTableEnableKeys: // Nothing to do now, see https://github.com/pingcap/tidb/issues/1051 // MyISAM specific + case ast.AlterTableRemoveTTL: + // the parser makes sure we have only one `ast.AlterTableRemoveTTL` in an alter statement + err = d.AlterTableRemoveTTL(sctx, ident) default: err = errors.Trace(dbterror.ErrUnsupportedAlterTableSpec) } @@ -3378,6 +3551,10 @@ func (d *ddl) RebaseAutoID(ctx sessionctx.Context, ident ast.Ident, newBase int6 actionType = model.ActionRebaseAutoRandomBase case autoid.RowIDAllocType: actionType = model.ActionRebaseAutoID + case autoid.AutoIncrementType: + actionType = model.ActionRebaseAutoID + default: + panic(fmt.Sprintf("unimplemented rebase autoid type %s", tp)) } if !force { @@ -3531,7 +3708,10 @@ func CreateNewColumn(ctx sessionctx.Context, ti ast.Ident, schema *model.DBInfo, return nil, dbterror.ErrUnsupportedOnGeneratedColumn.GenWithStackByArgs("Adding generated stored column through ALTER TABLE") } - _, dependColNames := findDependedColumnNames(specNewColumn) + _, dependColNames, err := findDependedColumnNames(schema.Name, t.Meta().Name, specNewColumn) + if err != nil { + return nil, errors.Trace(err) + } if !ctx.GetSessionVars().EnableAutoIncrementInGenerated { if err := checkAutoIncrementRef(specNewColumn.Name.Name.L, dependColNames, t.Meta()); err != nil { return nil, errors.Trace(err) @@ -3718,6 +3898,181 @@ func (d *ddl) AddTablePartitions(ctx sessionctx.Context, ident ast.Ident, spec * return errors.Trace(err) } +// getReorganizedDefinitions return the definitions as they would look like after the REORGANIZE PARTITION is done. +func getReorganizedDefinitions(pi *model.PartitionInfo, firstPartIdx, lastPartIdx int, idMap map[int]struct{}) []model.PartitionDefinition { + tmpDefs := make([]model.PartitionDefinition, 0, len(pi.Definitions)+len(pi.AddingDefinitions)-len(idMap)) + if pi.Type == model.PartitionTypeList { + replaced := false + for i := range pi.Definitions { + if _, ok := idMap[i]; ok { + if !replaced { + tmpDefs = append(tmpDefs, pi.AddingDefinitions...) + replaced = true + } + continue + } + tmpDefs = append(tmpDefs, pi.Definitions[i]) + } + if !replaced { + // For safety, for future non-partitioned table -> partitioned + tmpDefs = append(tmpDefs, pi.AddingDefinitions...) + } + return tmpDefs + } + // Range + tmpDefs = append(tmpDefs, pi.Definitions[:firstPartIdx]...) + tmpDefs = append(tmpDefs, pi.AddingDefinitions...) + if len(pi.Definitions) > (lastPartIdx + 1) { + tmpDefs = append(tmpDefs, pi.Definitions[lastPartIdx+1:]...) + } + return tmpDefs +} + +func getReplacedPartitionIDs(names []model.CIStr, pi *model.PartitionInfo) (int, int, map[int]struct{}, error) { + idMap := make(map[int]struct{}) + var firstPartIdx, lastPartIdx = -1, -1 + for _, name := range names { + partIdx := pi.FindPartitionDefinitionByName(name.L) + if partIdx == -1 { + return 0, 0, nil, errors.Trace(dbterror.ErrWrongPartitionName) + } + if _, ok := idMap[partIdx]; ok { + return 0, 0, nil, errors.Trace(dbterror.ErrSameNamePartition) + } + idMap[partIdx] = struct{}{} + if firstPartIdx == -1 { + firstPartIdx = partIdx + } else { + firstPartIdx = mathutil.Min[int](firstPartIdx, partIdx) + } + if lastPartIdx == -1 { + lastPartIdx = partIdx + } else { + lastPartIdx = mathutil.Max[int](lastPartIdx, partIdx) + } + } + if pi.Type == model.PartitionTypeRange { + if len(idMap) != (lastPartIdx - firstPartIdx + 1) { + return 0, 0, nil, errors.Trace(dbterror.ErrGeneralUnsupportedDDL.GenWithStackByArgs( + "REORGANIZE PARTITION of RANGE; not adjacent partitions")) + } + } + + return firstPartIdx, lastPartIdx, idMap, nil +} + +// ReorganizePartitions reorganize one set of partitions to a new set of partitions. +func (d *ddl) ReorganizePartitions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { + schema, t, err := d.getSchemaAndTableByIdent(ctx, ident) + if err != nil { + return errors.Trace(infoschema.ErrTableNotExists.FastGenByArgs(ident.Schema, ident.Name)) + } + + meta := t.Meta() + pi := meta.GetPartitionInfo() + if pi == nil { + return dbterror.ErrPartitionMgmtOnNonpartitioned + } + switch pi.Type { + case model.PartitionTypeRange, model.PartitionTypeList: + default: + return errors.Trace(dbterror.ErrUnsupportedReorganizePartition) + } + firstPartIdx, lastPartIdx, idMap, err := getReplacedPartitionIDs(spec.PartitionNames, pi) + if err != nil { + return errors.Trace(err) + } + partInfo, err := BuildAddedPartitionInfo(ctx, meta, spec) + if err != nil { + return errors.Trace(err) + } + if err = d.assignPartitionIDs(partInfo.Definitions); err != nil { + return errors.Trace(err) + } + if err = checkReorgPartitionDefs(ctx, meta, partInfo, firstPartIdx, lastPartIdx, idMap); err != nil { + return errors.Trace(err) + } + if err = handlePartitionPlacement(ctx, partInfo); err != nil { + return errors.Trace(err) + } + + tzName, tzOffset := ddlutil.GetTimeZone(ctx) + job := &model.Job{ + SchemaID: schema.ID, + TableID: meta.ID, + SchemaName: schema.Name.L, + TableName: t.Meta().Name.L, + Type: model.ActionReorganizePartition, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{spec.PartitionNames, partInfo}, + ReorgMeta: &model.DDLReorgMeta{ + SQLMode: ctx.GetSessionVars().SQLMode, + Warnings: make(map[errors.ErrorID]*terror.Error), + WarningsCount: make(map[errors.ErrorID]int64), + Location: &model.TimeZoneLocation{Name: tzName, Offset: tzOffset}, + }, + } + + // No preSplitAndScatter here, it will be done by the worker in onReorganizePartition instead. + err = d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) + return errors.Trace(err) +} + +func checkReorgPartitionDefs(ctx sessionctx.Context, tblInfo *model.TableInfo, partInfo *model.PartitionInfo, firstPartIdx, lastPartIdx int, idMap map[int]struct{}) error { + // partInfo contains only the new added partition, we have to combine it with the + // old partitions to check all partitions is strictly increasing. + pi := tblInfo.Partition + clonedMeta := tblInfo.Clone() + clonedMeta.Partition.AddingDefinitions = partInfo.Definitions + clonedMeta.Partition.Definitions = getReorganizedDefinitions(clonedMeta.Partition, firstPartIdx, lastPartIdx, idMap) + if err := checkPartitionDefinitionConstraints(ctx, clonedMeta); err != nil { + return errors.Trace(err) + } + if pi.Type == model.PartitionTypeRange { + if lastPartIdx == len(pi.Definitions)-1 { + // Last partition dropped, OK to change the end range + // Also includes MAXVALUE + return nil + } + // Check if the replaced end range is the same as before + lastAddingPartition := partInfo.Definitions[len(partInfo.Definitions)-1] + lastOldPartition := pi.Definitions[lastPartIdx] + if len(pi.Columns) > 0 { + newGtOld, err := checkTwoRangeColumns(ctx, &lastAddingPartition, &lastOldPartition, pi, tblInfo) + if err != nil { + return errors.Trace(err) + } + if newGtOld { + return errors.Trace(dbterror.ErrRangeNotIncreasing) + } + oldGtNew, err := checkTwoRangeColumns(ctx, &lastOldPartition, &lastAddingPartition, pi, tblInfo) + if err != nil { + return errors.Trace(err) + } + if oldGtNew { + return errors.Trace(dbterror.ErrRangeNotIncreasing) + } + return nil + } + + isUnsigned := isPartExprUnsigned(tblInfo) + currentRangeValue, _, err := getRangeValue(ctx, pi.Definitions[lastPartIdx].LessThan[0], isUnsigned) + if err != nil { + return errors.Trace(err) + } + newRangeValue, _, err := getRangeValue(ctx, partInfo.Definitions[len(partInfo.Definitions)-1].LessThan[0], isUnsigned) + if err != nil { + return errors.Trace(err) + } + + if currentRangeValue != newRangeValue { + return errors.Trace(dbterror.ErrRangeNotIncreasing) + } + } + return nil +} + // CoalescePartitions coalesce partitions can be used with a table that is partitioned by hash or key to reduce the number of partitions by number. func (d *ddl) CoalescePartitions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { is := d.infoCache.GetLatest() @@ -4165,11 +4520,19 @@ func checkIsDroppableColumn(ctx sessionctx.Context, is infoschema.InfoSchema, sc if err = isDroppableColumn(tblInfo, colName); err != nil { return false, errors.Trace(err) } + if err = checkDropColumnWithPartitionConstraint(t, colName); err != nil { + return false, errors.Trace(err) + } // Check the column with foreign key. err = checkDropColumnWithForeignKeyConstraint(is, schema.Name.L, tblInfo, colName.L) if err != nil { return false, errors.Trace(err) } + // Check the column with TTL config + err = checkDropColumnWithTTLConfig(tblInfo, colName.L) + if err != nil { + return false, errors.Trace(err) + } // We don't support dropping column with PK handle covered now. if col.IsPKHandleColumn(tblInfo) { return false, dbterror.ErrUnsupportedPKHandle @@ -4180,6 +4543,24 @@ func checkIsDroppableColumn(ctx sessionctx.Context, is infoschema.InfoSchema, sc return true, nil } +// checkDropColumnWithPartitionConstraint is used to check the partition constraint of the drop column. +func checkDropColumnWithPartitionConstraint(t table.Table, colName model.CIStr) error { + if t.Meta().Partition == nil { + return nil + } + pt, ok := t.(table.PartitionedTable) + if !ok { + // Should never happen! + return errors.Trace(dbterror.ErrDependentByPartitionFunctional.GenWithStackByArgs(colName.L)) + } + for _, name := range pt.GetPartitionColumnNames() { + if strings.EqualFold(name.L, colName.L) { + return errors.Trace(dbterror.ErrDependentByPartitionFunctional.GenWithStackByArgs(colName.L)) + } + } + return nil +} + func checkVisibleColumnCnt(t table.Table, addCnt, dropCnt int) error { tblInfo := t.Meta() visibleColumCnt := 0 @@ -4318,7 +4699,7 @@ func setColumnComment(ctx sessionctx.Context, col *table.Column, option *ast.Col func processColumnOptions(ctx sessionctx.Context, col *table.Column, options []*ast.ColumnOption) error { var sb strings.Builder restoreFlags := format.RestoreStringSingleQuotes | format.RestoreKeyWordLowercase | format.RestoreNameBackQuotes | - format.RestoreSpacesAroundBinaryOperation + format.RestoreSpacesAroundBinaryOperation | format.RestoreWithoutSchemaName | format.RestoreWithoutSchemaName restoreCtx := format.NewRestoreCtx(restoreFlags, &sb) var hasDefaultValue, setOnUpdateNow bool @@ -4548,6 +4929,94 @@ func GetModifiableColumnJob( } } + // Check that the column change does not affect the partitioning column + // It must keep the same type, int [unsigned], [var]char, date[time] + if t.Meta().Partition != nil { + pt, ok := t.(table.PartitionedTable) + if !ok { + // Should never happen! + return nil, dbterror.ErrNotAllowedTypeInPartition.GenWithStackByArgs(newCol.Name.O) + } + isPartitioningColumn := false + for _, name := range pt.GetPartitionColumnNames() { + if strings.EqualFold(name.L, col.Name.L) { + isPartitioningColumn = true + break + } + } + if isPartitioningColumn { + // TODO: update the partitioning columns with new names if column is renamed + // Would be an extension from MySQL which does not support it. + if col.Name.L != newCol.Name.L { + return nil, dbterror.ErrDependentByPartitionFunctional.GenWithStackByArgs(col.Name.L) + } + if !isColTypeAllowedAsPartitioningCol(newCol.FieldType) { + return nil, dbterror.ErrNotAllowedTypeInPartition.GenWithStackByArgs(newCol.Name.O) + } + pi := pt.Meta().GetPartitionInfo() + if len(pi.Columns) == 0 { + // non COLUMNS partitioning, only checks INTs, not their actual range + // There are many edge cases, like when truncating SQL Mode is allowed + // which will change the partitioning expression value resulting in a + // different partition. Better be safe and not allow decreasing of length. + // TODO: Should we allow it in strict mode? Wait for a use case / request. + if newCol.FieldType.GetFlen() < col.FieldType.GetFlen() { + return nil, dbterror.ErrUnsupportedModifyCollation.GenWithStack("Unsupported modify column, decreasing length of int may result in truncation and change of partition") + } + } + // Basically only allow changes of the length/decimals for the column + // Note that enum is not allowed, so elems are not checked + // TODO: support partition by ENUM + if newCol.FieldType.EvalType() != col.FieldType.EvalType() || + newCol.FieldType.GetFlag() != col.FieldType.GetFlag() || + newCol.FieldType.GetCollate() != col.FieldType.GetCollate() || + newCol.FieldType.GetCharset() != col.FieldType.GetCharset() { + return nil, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs("can't change the partitioning column, since it would require reorganize all partitions") + } + // Generate a new PartitionInfo and validate it together with the new column definition + // Checks if all partition definition values are compatible. + // Similar to what buildRangePartitionDefinitions would do in terms of checks. + + tblInfo := pt.Meta() + newTblInfo := *tblInfo + // Replace col with newCol and see if we can generate a new SHOW CREATE TABLE + // and reparse it and build new partition definitions (which will do additional + // checks columns vs partition definition values + newCols := make([]*model.ColumnInfo, 0, len(newTblInfo.Columns)) + for _, c := range newTblInfo.Columns { + if c.ID == col.ID { + newCols = append(newCols, newCol.ColumnInfo) + continue + } + newCols = append(newCols, c) + } + newTblInfo.Columns = newCols + + var buf bytes.Buffer + AppendPartitionInfo(tblInfo.GetPartitionInfo(), &buf, mysql.ModeNone) + // The parser supports ALTER TABLE ... PARTITION BY ... even if the ddl code does not yet :) + // Ignoring warnings + stmt, _, err := parser.New().ParseSQL("ALTER TABLE t " + buf.String()) + if err != nil { + // Should never happen! + return nil, dbterror.ErrUnsupportedModifyColumn.GenWithStack("cannot parse generated PartitionInfo") + } + at, ok := stmt[0].(*ast.AlterTableStmt) + if !ok || len(at.Specs) != 1 || at.Specs[0].Partition == nil { + return nil, dbterror.ErrUnsupportedModifyColumn.GenWithStack("cannot parse generated PartitionInfo") + } + pAst := at.Specs[0].Partition + sv := sctx.GetSessionVars().StmtCtx + oldTruncAsWarn, oldIgnoreTrunc := sv.TruncateAsWarning, sv.IgnoreTruncate + sv.TruncateAsWarning, sv.IgnoreTruncate = false, false + _, err = buildPartitionDefinitionsInfo(sctx, pAst.Definitions, &newTblInfo) + sv.TruncateAsWarning, sv.IgnoreTruncate = oldTruncAsWarn, oldIgnoreTrunc + if err != nil { + return nil, dbterror.ErrUnsupportedModifyColumn.GenWithStack("New column does not match partition definitions: %s", err.Error()) + } + } + } + // We don't support modifying column from not_auto_increment to auto_increment. if !mysql.HasAutoIncrementFlag(col.GetFlag()) && mysql.HasAutoIncrementFlag(newCol.GetFlag()) { return nil, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs("can't set auto_increment") @@ -4572,10 +5041,17 @@ func GetModifiableColumnJob( } // As same with MySQL, we don't support modifying the stored status for generated columns. - if err = checkModifyGeneratedColumn(sctx, t, col, newCol, specNewColumn, spec.Position); err != nil { + if err = checkModifyGeneratedColumn(sctx, schema.Name, t, col, newCol, specNewColumn, spec.Position); err != nil { return nil, errors.Trace(err) } + if t.Meta().TTLInfo != nil { + // the column referenced by TTL should be a time type + if t.Meta().TTLInfo.ColumnName.L == originalColName.L && !types.IsTypeTime(newCol.ColumnInfo.FieldType.GetType()) { + return nil, errors.Trace(dbterror.ErrUnsupportedColumnInTTLConfig.GenWithStackByArgs(newCol.ColumnInfo.Name.O)) + } + } + var newAutoRandBits uint64 if newAutoRandBits, err = checkAutoRandom(t.Meta(), col, specNewColumn); err != nil { return nil, errors.Trace(err) @@ -4683,9 +5159,26 @@ func checkIndexInModifiableColumns(columns []*model.ColumnInfo, idxColumns []*mo return nil } +func isClusteredPKColumn(col *table.Column, tblInfo *model.TableInfo) bool { + switch { + case tblInfo.PKIsHandle: + return mysql.HasPriKeyFlag(col.GetFlag()) + case tblInfo.IsCommonHandle: + pk := tables.FindPrimaryIndex(tblInfo) + for _, c := range pk.Columns { + if c.Name.L == col.Name.L { + return true + } + } + return false + default: + return false + } +} + func checkAutoRandom(tableInfo *model.TableInfo, originCol *table.Column, specNewColumn *ast.ColumnDef) (uint64, error) { var oldShardBits, oldRangeBits uint64 - if originCol.IsPKHandleColumn(tableInfo) { + if isClusteredPKColumn(originCol, tableInfo) { oldShardBits = tableInfo.AutoRandomBits oldRangeBits = tableInfo.AutoRandomRangeBits } @@ -4831,6 +5324,11 @@ func (d *ddl) RenameColumn(ctx sessionctx.Context, ident ast.Ident, spec *ast.Al } } + err = checkDropColumnWithPartitionConstraint(tbl, oldColName) + if err != nil { + return errors.Trace(err) + } + tzName, tzOffset := ddlutil.GetTimeZone(ctx) newCol := oldCol.Clone() @@ -4980,6 +5478,11 @@ func (d *ddl) AlterTableAutoIDCache(ctx sessionctx.Context, ident ast.Ident, new if err != nil { return errors.Trace(err) } + tbInfo := tb.Meta() + if (newCache == 1 && tbInfo.AutoIdCache != 1) || + (newCache != 1 && tbInfo.AutoIdCache == 1) { + return fmt.Errorf("Can't Alter AUTO_ID_CACHE between 1 and non-1, the underlying implementation is different") + } job := &model.Job{ SchemaID: schema.ID, @@ -5097,6 +5600,96 @@ func (d *ddl) AlterTableSetTiFlashReplica(ctx sessionctx.Context, ident ast.Iden return errors.Trace(err) } +// AlterTableTTLInfoOrEnable submit ddl job to change table info according to the ttlInfo, or ttlEnable +// at least one of the `ttlInfo`, `ttlEnable` or `ttlCronJobSchedule` should be not nil. +// When `ttlInfo` is nil, and `ttlEnable` is not, it will use the original `.TTLInfo` in the table info and modify the +// `.Enable`. If the `.TTLInfo` in the table info is empty, this function will return an error. +// When `ttlInfo` is nil, and `ttlCronJobSchedule` is not, it will use the original `.TTLInfo` in the table info and modify the +// `.JobInterval`. If the `.TTLInfo` in the table info is empty, this function will return an error. +// When `ttlInfo` is not nil, it simply submits the job with the `ttlInfo` and ignore the `ttlEnable`. +func (d *ddl) AlterTableTTLInfoOrEnable(ctx sessionctx.Context, ident ast.Ident, ttlInfo *model.TTLInfo, ttlEnable *bool, ttlCronJobSchedule *string) error { + is := d.infoCache.GetLatest() + schema, ok := is.SchemaByName(ident.Schema) + if !ok { + return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(ident.Schema) + } + + tb, err := is.TableByName(ident.Schema, ident.Name) + if err != nil { + return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ident.Schema, ident.Name)) + } + + tblInfo := tb.Meta().Clone() + tableID := tblInfo.ID + tableName := tblInfo.Name.L + + var job *model.Job + if ttlInfo != nil { + tblInfo.TTLInfo = ttlInfo + err = checkTTLInfoValid(ctx, ident.Schema, tblInfo) + if err != nil { + return err + } + } else { + if tblInfo.TTLInfo == nil { + if ttlEnable != nil { + return errors.Trace(dbterror.ErrSetTTLOptionForNonTTLTable.FastGenByArgs("TTL_ENABLE")) + } + if ttlCronJobSchedule != nil { + return errors.Trace(dbterror.ErrSetTTLOptionForNonTTLTable.FastGenByArgs("TTL_JOB_INTERVAL")) + } + } + } + + job = &model.Job{ + SchemaID: schema.ID, + TableID: tableID, + SchemaName: schema.Name.L, + TableName: tableName, + Type: model.ActionAlterTTLInfo, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{ttlInfo, ttlEnable, ttlCronJobSchedule}, + } + + err = d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) + return errors.Trace(err) +} + +func (d *ddl) AlterTableRemoveTTL(ctx sessionctx.Context, ident ast.Ident) error { + is := d.infoCache.GetLatest() + + schema, ok := is.SchemaByName(ident.Schema) + if !ok { + return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(ident.Schema) + } + + tb, err := is.TableByName(ident.Schema, ident.Name) + if err != nil { + return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ident.Schema, ident.Name)) + } + + tblInfo := tb.Meta().Clone() + tableID := tblInfo.ID + tableName := tblInfo.Name.L + + if tblInfo.TTLInfo != nil { + job := &model.Job{ + SchemaID: schema.ID, + TableID: tableID, + SchemaName: schema.Name.L, + TableName: tableName, + Type: model.ActionAlterTTLRemove, + BinlogInfo: &model.HistoryInfo{}, + } + err = d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) + return errors.Trace(err) + } + + return nil +} + func isTableTiFlashSupported(schema *model.DBInfo, tb table.Table) error { // Memory tables and system tables are not supported by TiFlash if util.IsMemOrSysDB(schema.Name.L) { @@ -5822,7 +6415,7 @@ func (d *ddl) CreatePrimaryKey(ctx sessionctx.Context, ti ast.Ident, indexName m // After DDL job is put to the queue, and if the check fail, TiDB will run the DDL cancel logic. // The recover step causes DDL wait a few seconds, makes the unit test painfully slow. // For same reason, decide whether index is global here. - indexColumns, err := buildIndexColumns(ctx, tblInfo.Columns, indexPartSpecifications) + indexColumns, _, err := buildIndexColumns(ctx, tblInfo.Columns, indexPartSpecifications) if err != nil { return errors.Trace(err) } @@ -5925,14 +6518,14 @@ func BuildHiddenColumnInfo(ctx sessionctx.Context, indexPartSpecifications []*as var sb strings.Builder restoreFlags := format.RestoreStringSingleQuotes | format.RestoreKeyWordLowercase | format.RestoreNameBackQuotes | - format.RestoreSpacesAroundBinaryOperation + format.RestoreSpacesAroundBinaryOperation | format.RestoreWithoutSchemaName | format.RestoreWithoutTableName restoreCtx := format.NewRestoreCtx(restoreFlags, &sb) sb.Reset() err := idxPart.Expr.Restore(restoreCtx) if err != nil { return nil, errors.Trace(err) } - expr, err := expression.RewriteSimpleExprWithTableInfo(ctx, tblInfo, idxPart.Expr) + expr, err := expression.RewriteSimpleExprWithTableInfo(ctx, tblInfo, idxPart.Expr, true) if err != nil { // TODO: refine the error message. return nil, err @@ -6047,7 +6640,7 @@ func (d *ddl) createIndex(ctx sessionctx.Context, ti ast.Ident, keyType ast.Inde // After DDL job is put to the queue, and if the check fail, TiDB will run the DDL cancel logic. // The recover step causes DDL wait a few seconds, makes the unit test painfully slow. // For same reason, decide whether index is global here. - indexColumns, err := buildIndexColumns(ctx, finalColumns, indexPartSpecifications) + indexColumns, _, err := buildIndexColumns(ctx, finalColumns, indexPartSpecifications) if err != nil { return errors.Trace(err) } @@ -6105,6 +6698,15 @@ func buildFKInfo(ctx sessionctx.Context, fkName model.CIStr, keys []*ast.IndexPa if len(keys) != len(refer.IndexPartSpecifications) { return nil, infoschema.ErrForeignKeyNotMatch.GenWithStackByArgs(fkName, "Key reference and table reference don't match") } + if err := checkTooLongForeignKey(fkName); err != nil { + return nil, err + } + if err := checkTooLongSchema(refer.Table.Schema); err != nil { + return nil, err + } + if err := checkTooLongTable(refer.Table.Name); err != nil { + return nil, err + } // all base columns of stored generated columns baseCols := make(map[string]struct{}) @@ -6176,6 +6778,9 @@ func buildFKInfo(ctx sessionctx.Context, fkName model.CIStr, keys []*ast.IndexPa fkInfo.RefCols = make([]model.CIStr, len(refer.IndexPartSpecifications)) for i, key := range refer.IndexPartSpecifications { + if err := checkTooLongColumn(key.Column.Name); err != nil { + return nil, err + } fkInfo.RefCols[i] = key.Column.Name } @@ -6216,6 +6821,24 @@ func (d *ddl) CreateForeignKey(ctx sessionctx.Context, ti ast.Ident, fkName mode if err != nil { return err } + if model.FindIndexByColumns(t.Meta(), t.Meta().Indices, fkInfo.Cols...) == nil { + // Need to auto create index for fk cols + if ctx.GetSessionVars().StmtCtx.MultiSchemaInfo == nil { + ctx.GetSessionVars().StmtCtx.MultiSchemaInfo = model.NewMultiSchemaInfo() + } + indexPartSpecifications := make([]*ast.IndexPartSpecification, 0, len(fkInfo.Cols)) + for _, col := range fkInfo.Cols { + indexPartSpecifications = append(indexPartSpecifications, &ast.IndexPartSpecification{ + Column: &ast.ColumnName{Name: col}, + Length: types.UnspecifiedLength, // Index prefixes on foreign key columns are not supported. + }) + } + indexOption := &ast.IndexOption{} + err = d.createIndex(ctx, ti, ast.IndexKeyTypeNone, fkInfo.Name, indexPartSpecifications, indexOption, false) + if err != nil { + return err + } + } job := &model.Job{ SchemaID: schema.ID, @@ -6347,10 +6970,7 @@ func CheckIsDropPrimaryKey(indexName model.CIStr, indexInfo *model.IndexInfo, t if indexInfo == nil && !t.Meta().PKIsHandle { return isPK, dbterror.ErrCantDropFieldOrKey.GenWithStackByArgs("PRIMARY") } - if t.Meta().PKIsHandle { - return isPK, dbterror.ErrUnsupportedModifyPrimaryKey.GenWithStack("Unsupported drop primary key when the table's pkIsHandle is true") - } - if t.Meta().IsCommonHandle { + if t.Meta().IsCommonHandle || t.Meta().PKIsHandle { return isPK, dbterror.ErrUnsupportedModifyPrimaryKey.GenWithStack("Unsupported drop primary key when the table is using clustered index") } } @@ -7161,6 +7781,135 @@ func checkIgnorePlacementDDL(ctx sessionctx.Context) bool { return false } +// CreateResourceGroup implements the DDL interface, creates a resource group. +func (d *ddl) CreateResourceGroup(ctx sessionctx.Context, stmt *ast.CreateResourceGroupStmt) (err error) { + groupInfo := &model.ResourceGroupInfo{ResourceGroupSettings: &model.ResourceGroupSettings{}} + groupName := stmt.ResourceGroupName + groupInfo.Name = groupName + for _, opt := range stmt.ResourceGroupOptionList { + err := SetDirectResourceGroupUnit(groupInfo.ResourceGroupSettings, opt.Tp, opt.StrValue, opt.UintValue) + if err != nil { + return err + } + } + if !stmt.IfNotExists { + if _, ok := d.GetInfoSchemaWithInterceptor(ctx).ResourceGroupByName(groupName); ok { + return infoschema.ErrResourceGroupExists.GenWithStackByArgs(groupName) + } + } + + if groupName.L == defaultResourceGroupName { + return errors.Trace(infoschema.ErrReservedSyntax.GenWithStackByArgs(groupName)) + } + + if err := d.checkResourceGroupValidation(groupInfo); err != nil { + return err + } + + logutil.BgLogger().Debug("create resource group", zap.String("name", groupName.O), zap.Stringer("resource group settings", groupInfo.ResourceGroupSettings)) + groupIDs, err := d.genGlobalIDs(1) + if err != nil { + return err + } + groupInfo.ID = groupIDs[0] + + job := &model.Job{ + SchemaName: groupName.L, + Type: model.ActionCreateResourceGroup, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{groupInfo, false}, + } + err = d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) + return err +} + +func (d *ddl) checkResourceGroupValidation(groupInfo *model.ResourceGroupInfo) error { + _, err := resourcegroup.NewGroupFromOptions(groupInfo.Name.L, groupInfo.ResourceGroupSettings) + return err +} + +// DropResourceGroup implements the DDL interface. +func (d *ddl) DropResourceGroup(ctx sessionctx.Context, stmt *ast.DropResourceGroupStmt) (err error) { + groupName := stmt.ResourceGroupName + is := d.GetInfoSchemaWithInterceptor(ctx) + // Check group existence. + group, ok := is.ResourceGroupByName(groupName) + if !ok { + err = infoschema.ErrResourceGroupNotExists.GenWithStackByArgs(groupName) + if stmt.IfExists { + ctx.GetSessionVars().StmtCtx.AppendNote(err) + return nil + } + return err + } + + // check to see if some user has dependency on the group + checker := privilege.GetPrivilegeManager(ctx) + if checker == nil { + return errors.New("miss privilege checker") + } + user, matched := checker.MatchUserResourceGroupName(groupName.L) + if matched { + err = errors.Errorf("user [%s] depends on the resource group to drop", user) + return err + } + + job := &model.Job{ + SchemaID: group.ID, + SchemaName: group.Name.L, + Type: model.ActionDropResourceGroup, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{groupName}, + } + err = d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) + return err +} + +func buildResourceGroup(oldGroup *model.ResourceGroupInfo, options []*ast.ResourceGroupOption) (*model.ResourceGroupInfo, error) { + groupInfo := &model.ResourceGroupInfo{Name: oldGroup.Name, ID: oldGroup.ID, ResourceGroupSettings: &model.ResourceGroupSettings{}} + for _, opt := range options { + err := SetDirectResourceGroupUnit(groupInfo.ResourceGroupSettings, opt.Tp, opt.StrValue, opt.UintValue) + if err != nil { + return nil, err + } + } + return groupInfo, nil +} + +// AlterResourceGroup implements the DDL interface. +func (d *ddl) AlterResourceGroup(ctx sessionctx.Context, stmt *ast.AlterResourceGroupStmt) (err error) { + groupName := stmt.ResourceGroupName + is := d.GetInfoSchemaWithInterceptor(ctx) + // Check group existence. + group, ok := is.ResourceGroupByName(groupName) + if !ok { + return infoschema.ErrResourceGroupNotExists.GenWithStackByArgs(groupName) + } + newGroupInfo, err := buildResourceGroup(group, stmt.ResourceGroupOptionList) + if err != nil { + return errors.Trace(err) + } + + if err := d.checkResourceGroupValidation(newGroupInfo); err != nil { + return err + } + + logutil.BgLogger().Debug("alter resource group", zap.String("name", groupName.L), zap.Stringer("new resource group settings", newGroupInfo.ResourceGroupSettings)) + + job := &model.Job{ + SchemaID: newGroupInfo.ID, + SchemaName: newGroupInfo.Name.L, + Type: model.ActionAlterResourceGroup, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{newGroupInfo}, + } + err = d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) + return err +} + func (d *ddl) CreatePlacementPolicy(ctx sessionctx.Context, stmt *ast.CreatePlacementPolicyStmt) (err error) { if checkIgnorePlacementDDL(ctx) { return nil diff --git a/ddl/ddl_api_test.go b/ddl/ddl_api_test.go index f4010015f5456..9f36cc95f806c 100644 --- a/ddl/ddl_api_test.go +++ b/ddl/ddl_api_test.go @@ -115,73 +115,6 @@ func TestGetDDLJobsIsSort(t *testing.T) { require.NoError(t, err) } -func TestGetHistoryDDLJobs(t *testing.T) { - store := testkit.CreateMockStore(t) - - // delete the internal DDL record. - err := kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, false, func(ctx context.Context, txn kv.Transaction) error { - return meta.NewMeta(txn).ClearAllHistoryJob() - }) - require.NoError(t, err) - testkit.NewTestKit(t, store).MustExec("delete from mysql.tidb_ddl_history") - - tk := testkit.NewTestKit(t, store) - sess := tk.Session() - tk.MustExec("begin") - - txn, err := sess.Txn(true) - require.NoError(t, err) - - m := meta.NewMeta(txn) - cnt := 11 - jobs := make([]*model.Job, cnt) - for i := 0; i < cnt; i++ { - jobs[i] = &model.Job{ - ID: int64(i), - SchemaID: 1, - Type: model.ActionCreateTable, - } - err = ddl.AddHistoryDDLJobForTest(sess, m, jobs[i], true) - require.NoError(t, err) - - historyJobs, err := ddl.GetLastNHistoryDDLJobs(m, ddl.DefNumHistoryJobs) - require.NoError(t, err) - - if i+1 > ddl.MaxHistoryJobs { - require.Len(t, historyJobs, ddl.MaxHistoryJobs) - } else { - require.Len(t, historyJobs, i+1) - } - } - - delta := cnt - ddl.MaxHistoryJobs - historyJobs, err := ddl.GetLastNHistoryDDLJobs(m, ddl.DefNumHistoryJobs) - require.NoError(t, err) - require.Len(t, historyJobs, ddl.MaxHistoryJobs) - - l := len(historyJobs) - 1 - for i, job := range historyJobs { - require.Equal(t, jobs[delta+l-i].ID, job.ID) - require.Equal(t, int64(1), job.SchemaID) - require.Equal(t, model.ActionCreateTable, job.Type) - } - - var historyJobs2 []*model.Job - err = ddl.IterHistoryDDLJobs(txn, func(jobs []*model.Job) (b bool, e error) { - for _, job := range jobs { - historyJobs2 = append(historyJobs2, job) - if len(historyJobs2) == ddl.DefNumHistoryJobs { - return true, nil - } - } - return false, nil - }) - require.NoError(t, err) - require.Equal(t, historyJobs, historyJobs2) - - tk.MustExec("rollback") -} - func TestIsJobRollbackable(t *testing.T) { cases := []struct { tp model.ActionType diff --git a/ddl/ddl_test.go b/ddl/ddl_test.go index 9760608674c6f..6b210d2445c26 100644 --- a/ddl/ddl_test.go +++ b/ddl/ddl_test.go @@ -19,7 +19,6 @@ import ( "testing" "time" - "github.com/pingcap/failpoint" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" @@ -56,6 +55,9 @@ func (d *ddl) SetInterceptor(i Interceptor) { // JobNeedGCForTest is only used for test. var JobNeedGCForTest = jobNeedGC +// NewSession is only used for test. +var NewSession = newSession + // GetMaxRowID is used for test. func GetMaxRowID(store kv.Storage, priority int, t table.Table, startHandle, endHandle kv.Key) (kv.Key, error) { return getRangeEndKey(NewJobContext(), store, priority, t.RecordPrefix(), startHandle, endHandle) @@ -268,109 +270,6 @@ func TestBuildJobDependence(t *testing.T) { require.NoError(t, err) } -func TestNotifyDDLJob(t *testing.T) { - store := createMockStore(t) - defer func() { - require.NoError(t, store.Close()) - }() - - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/NoDDLDispatchLoop", `return(true)`)) - defer require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/NoDDLDispatchLoop")) - - getFirstNotificationAfterStartDDL := func(d *ddl) { - select { - case <-d.workers[addIdxWorker].ddlJobCh: - default: - // The notification may be received by the worker. - } - select { - case <-d.workers[generalWorker].ddlJobCh: - default: - // The notification may be received by the worker. - } - - select { - case <-d.ddlJobCh: - default: - } - } - - d, err := testNewDDLAndStart( - context.Background(), - WithStore(store), - WithLease(testLease), - ) - require.NoError(t, err) - defer func() { - require.NoError(t, d.Stop()) - }() - getFirstNotificationAfterStartDDL(d) - // Ensure that the notification is not handled in workers `start` function. - d.cancel() - for _, worker := range d.workers { - worker.Close() - } - - job := &model.Job{ - SchemaID: 1, - TableID: 2, - Type: model.ActionCreateTable, - BinlogInfo: &model.HistoryInfo{}, - Args: []interface{}{}, - } - // Test the notification mechanism of the owner and the server receiving the DDL request on the same TiDB. - // This DDL request is a general DDL job. - d.asyncNotifyWorker(job) - select { - case <-d.workers[generalWorker].ddlJobCh: - case <-d.ddlJobCh: - default: - require.FailNow(t, "do not get the general job notification") - } - // Test the notification mechanism of the owner and the server receiving the DDL request on the same TiDB. - // This DDL request is a add index DDL job. - job.Type = model.ActionAddIndex - d.asyncNotifyWorker(job) - select { - case <-d.workers[addIdxWorker].ddlJobCh: - case <-d.ddlJobCh: - default: - require.FailNow(t, "do not get the add index job notification") - } - - // Test the notification mechanism that the owner and the server receiving the DDL request are not on the same TiDB. - // And the etcd client is nil. - d1, err := testNewDDLAndStart( - context.Background(), - WithStore(store), - WithLease(testLease), - ) - require.NoError(t, err) - defer func() { - require.NoError(t, d1.Stop()) - }() - getFirstNotificationAfterStartDDL(d1) - // Ensure that the notification is not handled by worker's "start". - d1.cancel() - for _, worker := range d1.workers { - worker.Close() - } - d1.ownerManager.RetireOwner() - d1.asyncNotifyWorker(job) - job.Type = model.ActionCreateTable - d1.asyncNotifyWorker(job) - require.False(t, d1.OwnerManager().IsOwner()) - select { - case <-d1.workers[addIdxWorker].ddlJobCh: - require.FailNow(t, "should not get the add index job notification") - case <-d1.workers[generalWorker].ddlJobCh: - require.FailNow(t, "should not get the general job notification") - case <-d1.ddlJobCh: - require.FailNow(t, "should not get the job notification") - default: - } -} - func TestError(t *testing.T) { kvErrs := []*terror.Error{ dbterror.ErrDDLJobNotFound, diff --git a/ddl/ddl_tiflash_api.go b/ddl/ddl_tiflash_api.go index 6c818be465de9..4b8fca2a91c0f 100644 --- a/ddl/ddl_tiflash_api.go +++ b/ddl/ddl_tiflash_api.go @@ -29,21 +29,14 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" - "github.com/pingcap/tidb/ddl/placement" ddlutil "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/infoschema" - "github.com/pingcap/tidb/kv" - "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/parser/model" - "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/store/helper" "github.com/pingcap/tidb/table" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" - "github.com/pingcap/tidb/util/gcutil" "github.com/pingcap/tidb/util/logutil" atomicutil "go.uber.org/atomic" "go.uber.org/zap" @@ -51,12 +44,13 @@ import ( // TiFlashReplicaStatus records status for each TiFlash replica. type TiFlashReplicaStatus struct { - ID int64 - Count uint64 - LocationLabels []string - Available bool - HighPriority bool - IsPartition bool + ID int64 + Count uint64 + LocationLabels []string + Available bool + LogicalTableAvailable bool + HighPriority bool + IsPartition bool } // TiFlashTick is type for backoff threshold. @@ -117,7 +111,6 @@ func NewPollTiFlashBackoffContext(MinThreshold, MaxThreshold TiFlashTick, Capaci type TiFlashManagementContext struct { TiFlashStores map[int64]helper.StoreStat PollCounter uint64 - ProgressCache map[int64]string Backoff *PollTiFlashBackoffContext // tables waiting for updating progress after become available. UpdatingProgressTables *list.List @@ -212,7 +205,6 @@ func NewTiFlashManagementContext() (*TiFlashManagementContext, error) { return &TiFlashManagementContext{ PollCounter: 0, TiFlashStores: make(map[int64]helper.StoreStat), - ProgressCache: make(map[int64]string), Backoff: c, UpdatingProgressTables: list.New(), }, nil @@ -235,8 +227,6 @@ var ( PollTiFlashBackoffRate TiFlashTick = 1.5 // RefreshProgressMaxTableCount is the max count of table to refresh progress after available each poll. RefreshProgressMaxTableCount uint64 = 1000 - // PollCleanProgressCacheInterval is the inteval (PollTiFlashInterval * PollCleanProgressCacheInterval) of cleaning progress cache to avoid data race when ddl owner switchover - PollCleanProgressCacheInterval uint64 = 300 ) func getTiflashHTTPAddr(host string, statusAddr string) (string, error) { @@ -288,16 +278,16 @@ func LoadTiFlashReplicaInfo(tblInfo *model.TableInfo, tableList *[]TiFlashReplic for _, p := range pi.Definitions { logutil.BgLogger().Debug(fmt.Sprintf("Table %v has partition %v\n", tblInfo.ID, p.ID)) *tableList = append(*tableList, TiFlashReplicaStatus{p.ID, - tblInfo.TiFlashReplica.Count, tblInfo.TiFlashReplica.LocationLabels, tblInfo.TiFlashReplica.IsPartitionAvailable(p.ID), false, true}) + tblInfo.TiFlashReplica.Count, tblInfo.TiFlashReplica.LocationLabels, tblInfo.TiFlashReplica.IsPartitionAvailable(p.ID), tblInfo.TiFlashReplica.Available, false, true}) } // partitions that in adding mid-state for _, p := range pi.AddingDefinitions { logutil.BgLogger().Debug(fmt.Sprintf("Table %v has partition adding %v\n", tblInfo.ID, p.ID)) - *tableList = append(*tableList, TiFlashReplicaStatus{p.ID, tblInfo.TiFlashReplica.Count, tblInfo.TiFlashReplica.LocationLabels, tblInfo.TiFlashReplica.IsPartitionAvailable(p.ID), true, true}) + *tableList = append(*tableList, TiFlashReplicaStatus{p.ID, tblInfo.TiFlashReplica.Count, tblInfo.TiFlashReplica.LocationLabels, tblInfo.TiFlashReplica.IsPartitionAvailable(p.ID), tblInfo.TiFlashReplica.Available, true, true}) } } else { logutil.BgLogger().Debug(fmt.Sprintf("Table %v has no partition\n", tblInfo.ID)) - *tableList = append(*tableList, TiFlashReplicaStatus{tblInfo.ID, tblInfo.TiFlashReplica.Count, tblInfo.TiFlashReplica.LocationLabels, tblInfo.TiFlashReplica.Available, false, false}) + *tableList = append(*tableList, TiFlashReplicaStatus{tblInfo.ID, tblInfo.TiFlashReplica.Count, tblInfo.TiFlashReplica.LocationLabels, tblInfo.TiFlashReplica.Available, tblInfo.TiFlashReplica.Available, false, false}) } } @@ -360,51 +350,6 @@ func updateTiFlashStores(pollTiFlashContext *TiFlashManagementContext) error { return nil } -func getTiFlashPeerWithoutLagCount(pollTiFlashContext *TiFlashManagementContext, tableID int64) (int, error) { - // storeIDs -> regionID, PD will not create two peer on the same store - var flashPeerCount int - for _, store := range pollTiFlashContext.TiFlashStores { - regionReplica := make(map[int64]int) - err := helper.CollectTiFlashStatus(store.Store.StatusAddress, tableID, ®ionReplica) - if err != nil { - logutil.BgLogger().Error("Fail to get peer status from TiFlash.", - zap.Int64("tableID", tableID)) - return 0, err - } - flashPeerCount += len(regionReplica) - } - return flashPeerCount, nil -} - -// getTiFlashTableSyncProgress return truncated string to avoid float64 comparison. -func getTiFlashTableSyncProgress(pollTiFlashContext *TiFlashManagementContext, tableID int64, replicaCount uint64) (string, error) { - var stats helper.PDRegionStats - if err := infosync.GetTiFlashPDRegionRecordStats(context.Background(), tableID, &stats); err != nil { - logutil.BgLogger().Error("Fail to get region stats from PD.", - zap.Int64("tableID", tableID)) - return "0", errors.Trace(err) - } - regionCount := stats.Count - - tiflashPeerCount, err := getTiFlashPeerWithoutLagCount(pollTiFlashContext, tableID) - if err != nil { - logutil.BgLogger().Error("Fail to get peer count from TiFlash.", - zap.Int64("tableID", tableID)) - return "0", errors.Trace(err) - } - progress := float64(tiflashPeerCount) / float64(regionCount*int(replicaCount)) - if progress > 1 { // when pd do balance - logutil.BgLogger().Debug("TiFlash peer count > pd peer count, maybe doing balance.", - zap.Int64("tableID", tableID), zap.Int("tiflashPeerCount", tiflashPeerCount), zap.Int("regionCount", regionCount), zap.Uint64("replicaCount", replicaCount)) - progress = 1 - } - if progress < 1 { - logutil.BgLogger().Debug("TiFlash replica progress < 1.", - zap.Int64("tableID", tableID), zap.Int("tiflashPeerCount", tiflashPeerCount), zap.Int("regionCount", regionCount), zap.Uint64("replicaCount", replicaCount)) - } - return types.TruncateFloatToString(progress, 2), nil -} - func pollAvailableTableProgress(schemas infoschema.InfoSchema, ctx sessionctx.Context, pollTiFlashContext *TiFlashManagementContext) { pollMaxCount := RefreshProgressMaxTableCount failpoint.Inject("PollAvailableTableProgressMaxCount", func(val failpoint.Value) { @@ -446,7 +391,7 @@ func pollAvailableTableProgress(schemas infoschema.InfoSchema, ctx sessionctx.Co element = element.Next() continue } - progress, err := getTiFlashTableSyncProgress(pollTiFlashContext, availableTableID.ID, tableInfo.TiFlashReplica.Count) + progress, err := infosync.CalculateTiFlashProgress(availableTableID.ID, tableInfo.TiFlashReplica.Count, pollTiFlashContext.TiFlashStores) if err != nil { logutil.BgLogger().Error("get tiflash sync progress failed", zap.Error(err), @@ -455,21 +400,19 @@ func pollAvailableTableProgress(schemas infoschema.InfoSchema, ctx sessionctx.Co ) continue } - if pollTiFlashContext.ProgressCache[availableTableID.ID] != progress { - err = infosync.UpdateTiFlashTableSyncProgress(context.Background(), availableTableID.ID, progress) - if err != nil { - logutil.BgLogger().Error("updating TiFlash replica process failed", - zap.Error(err), - zap.Int64("tableID or partitionID", availableTableID.ID), - zap.Bool("IsPartition", availableTableID.IsPartition), - zap.String("progress", progress), - ) - continue - } - pollTiFlashContext.ProgressCache[availableTableID.ID] = progress + err = infosync.UpdateTiFlashProgressCache(availableTableID.ID, progress) + if err != nil { + logutil.BgLogger().Error("update tiflash sync progress cache failed", + zap.Error(err), + zap.Int64("tableID", availableTableID.ID), + zap.Bool("IsPartition", availableTableID.IsPartition), + zap.Float64("progress", progress), + ) + continue } + next := element.Next() pollTiFlashContext.UpdatingProgressTables.Remove(element) - element = element.Next() + element = next } } @@ -481,14 +424,6 @@ func (d *ddl) refreshTiFlashTicker(ctx sessionctx.Context, pollTiFlashContext *T return err } } - - failpoint.Inject("PollTiFlashReplicaStatusCleanProgressCache", func() { - pollTiFlashContext.PollCounter = PollCleanProgressCacheInterval - }) - // 10min clean progress cache to avoid data race - if pollTiFlashContext.PollCounter > 0 && pollTiFlashContext.PollCounter%PollCleanProgressCacheInterval == 0 { - pollTiFlashContext.ProgressCache = make(map[int64]string) - } pollTiFlashContext.PollCounter++ // Start to process every table. @@ -510,6 +445,21 @@ func (d *ddl) refreshTiFlashTicker(ctx sessionctx.Context, pollTiFlashContext *T } } + failpoint.Inject("waitForAddPartition", func(val failpoint.Value) { + for _, phyTable := range tableList { + is := d.infoCache.GetLatest() + _, ok := is.TableByID(phyTable.ID) + if !ok { + tb, _, _ := is.FindTableByPartitionID(phyTable.ID) + if tb == nil { + logutil.BgLogger().Info("[ddl] waitForAddPartition") + sleepSecond := val.(int) + time.Sleep(time.Duration(sleepSecond) * time.Second) + } + } + } + }) + needPushPending := false if pollTiFlashContext.UpdatingProgressTables.Len() == 0 { needPushPending = true @@ -523,14 +473,14 @@ func (d *ddl) refreshTiFlashTicker(ctx sessionctx.Context, pollTiFlashContext *T available = val.(bool) }) // We only check unavailable tables here, so doesn't include blocked add partition case. - if !available { + if !available && !tb.LogicalTableAvailable { enabled, inqueue, _ := pollTiFlashContext.Backoff.Tick(tb.ID) if inqueue && !enabled { logutil.BgLogger().Info("Escape checking available status due to backoff", zap.Int64("tableId", tb.ID)) continue } - progress, err := getTiFlashTableSyncProgress(pollTiFlashContext, tb.ID, tb.Count) + progress, err := infosync.CalculateTiFlashProgress(tb.ID, tb.Count, pollTiFlashContext.TiFlashStores) if err != nil { logutil.BgLogger().Error("get tiflash sync progress failed", zap.Error(err), @@ -538,29 +488,28 @@ func (d *ddl) refreshTiFlashTicker(ctx sessionctx.Context, pollTiFlashContext *T ) continue } - if pollTiFlashContext.ProgressCache[tb.ID] != progress { - err = infosync.UpdateTiFlashTableSyncProgress(context.Background(), tb.ID, progress) - if err != nil { - logutil.BgLogger().Error("updating TiFlash replica process failed", - zap.Error(err), - zap.Int64("tableID", tb.ID), - zap.String("progress", progress), - ) - continue - } - pollTiFlashContext.ProgressCache[tb.ID] = progress + + err = infosync.UpdateTiFlashProgressCache(tb.ID, progress) + if err != nil { + logutil.BgLogger().Error("get tiflash sync progress from cache failed", + zap.Error(err), + zap.Int64("tableID", tb.ID), + zap.Bool("IsPartition", tb.IsPartition), + zap.Float64("progress", progress), + ) + continue } - avail := progress[0] == '1' + avail := progress == 1 failpoint.Inject("PollTiFlashReplicaStatusReplaceCurAvailableValue", func(val failpoint.Value) { avail = val.(bool) }) if !avail { - logutil.BgLogger().Info("Tiflash replica is not available", zap.Int64("tableID", tb.ID), zap.String("progress", progress)) + logutil.BgLogger().Info("Tiflash replica is not available", zap.Int64("tableID", tb.ID), zap.Float64("progress", progress)) pollTiFlashContext.Backoff.Put(tb.ID) } else { - logutil.BgLogger().Info("Tiflash replica is available", zap.Int64("tableID", tb.ID), zap.String("progress", progress)) + logutil.BgLogger().Info("Tiflash replica is available", zap.Int64("tableID", tb.ID), zap.Float64("progress", progress)) pollTiFlashContext.Backoff.Remove(tb.ID) } failpoint.Inject("skipUpdateTableReplicaInfoInLoop", func() { @@ -585,110 +534,6 @@ func (d *ddl) refreshTiFlashTicker(ctx sessionctx.Context, pollTiFlashContext *T return nil } -func getDropOrTruncateTableTiflash(ctx sessionctx.Context, currentSchema infoschema.InfoSchema, tikvHelper *helper.Helper, replicaInfos *[]TiFlashReplicaStatus) error { - store := tikvHelper.Store.(kv.Storage) - - txn, err := store.Begin() - if err != nil { - return errors.Trace(err) - } - gcSafePoint, err := gcutil.GetGCSafePoint(ctx) - if err != nil { - return err - } - uniqueIDMap := make(map[int64]struct{}) - handleJobAndTableInfo := func(job *model.Job, tblInfo *model.TableInfo) (bool, error) { - // Avoid duplicate table ID info. - if _, ok := currentSchema.TableByID(tblInfo.ID); ok { - return false, nil - } - if _, ok := uniqueIDMap[tblInfo.ID]; ok { - return false, nil - } - uniqueIDMap[tblInfo.ID] = struct{}{} - LoadTiFlashReplicaInfo(tblInfo, replicaInfos) - return false, nil - } - fn := func(jobs []*model.Job) (bool, error) { - getTable := func(StartTS uint64, SchemaID int64, TableID int64) (*model.TableInfo, error) { - snapMeta := meta.NewSnapshotMeta(store.GetSnapshot(kv.NewVersion(StartTS))) - if err != nil { - return nil, err - } - tbl, err := snapMeta.GetTable(SchemaID, TableID) - return tbl, err - } - return GetDropOrTruncateTableInfoFromJobsByStore(jobs, gcSafePoint, getTable, handleJobAndTableInfo) - } - - err = IterAllDDLJobs(ctx, txn, fn) - if err != nil { - if terror.ErrorEqual(variable.ErrSnapshotTooOld, err) { - // The err indicate that current ddl job and remain DDL jobs was been deleted by GC, - // just ignore the error and return directly. - return nil - } - return err - } - return nil -} - -// HandlePlacementRuleRoutine fetch all rules from pd, remove all obsolete rules. -// It handles rare situation, when we fail to alter pd rules. -func HandlePlacementRuleRoutine(ctx sessionctx.Context, d *ddl, tableList []TiFlashReplicaStatus) error { - c := context.Background() - tikvStore, ok := ctx.GetStore().(helper.Storage) - if !ok { - return errors.New("Can not get Helper") - } - tikvHelper := &helper.Helper{ - Store: tikvStore, - RegionCache: tikvStore.GetRegionCache(), - } - - allRulesArr, err := infosync.GetTiFlashGroupRules(c, "tiflash") - if err != nil { - return errors.Trace(err) - } - allRules := make(map[string]placement.TiFlashRule) - for _, r := range allRulesArr { - allRules[r.ID] = r - } - - start := time.Now() - originLen := len(tableList) - currentSchema := d.GetInfoSchemaWithInterceptor(ctx) - if err := getDropOrTruncateTableTiflash(ctx, currentSchema, tikvHelper, &tableList); err != nil { - // may fail when no `tikv_gc_safe_point` available, should return in order to remove valid pd rules. - logutil.BgLogger().Error("getDropOrTruncateTableTiflash returns error", zap.Error(err)) - return errors.Trace(err) - } - elapsed := time.Since(start) - logutil.BgLogger().Info("getDropOrTruncateTableTiflash cost", zap.Duration("time", elapsed), zap.Int("updated", len(tableList)-originLen)) - for _, tb := range tableList { - // For every region in each table, if it has one replica, we reckon it ready. - ruleID := fmt.Sprintf("table-%v-r", tb.ID) - if _, ok := allRules[ruleID]; !ok { - // Mostly because of a previous failure of setting pd rule. - logutil.BgLogger().Warn(fmt.Sprintf("Table %v exists, but there are no rule for it", tb.ID)) - newRule := infosync.MakeNewRule(tb.ID, tb.Count, tb.LocationLabels) - _ = infosync.SetTiFlashPlacementRule(context.Background(), *newRule) - } - // For every existing table, we do not remove their rules. - delete(allRules, ruleID) - } - - // Remove rules of non-existing table - for _, v := range allRules { - logutil.BgLogger().Info("Remove TiFlash rule", zap.String("id", v.ID)) - if err := infosync.DeleteTiFlashPlacementRule(c, "tiflash", v.ID); err != nil { - logutil.BgLogger().Warn("delete TiFlash pd rule failed", zap.Error(err), zap.String("ruleID", v.ID)) - } - } - - return nil -} - func (d *ddl) PollTiFlashRoutine() { pollTiflashContext, err := NewTiFlashManagementContext() if err != nil { @@ -736,7 +581,7 @@ func (d *ddl) PollTiFlashRoutine() { } } } else { - pollTiflashContext.ProgressCache = make(map[int64]string) + infosync.CleanTiFlashProgressCache() } d.sessPool.put(sctx) } else { diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index 2e9d66b3149f2..789b291ba8452 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -40,6 +40,7 @@ import ( tidbutil "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/resourcegrouptag" "github.com/pingcap/tidb/util/topsql" topsqlstate "github.com/pingcap/tidb/util/topsql/state" @@ -97,8 +98,6 @@ type worker struct { logCtx context.Context lockSeqNum bool - concurrentDDL bool - *ddlCtx } @@ -119,11 +118,11 @@ func NewJobContext() *JobContext { cacheSQL: "", cacheNormalizedSQL: "", cacheDigest: nil, - tp: "unknown", + tp: "", } } -func newWorker(ctx context.Context, tp workerType, sessPool *sessionPool, delRangeMgr delRangeManager, dCtx *ddlCtx, concurrentDDL bool) *worker { +func newWorker(ctx context.Context, tp workerType, sessPool *sessionPool, delRangeMgr delRangeManager, dCtx *ddlCtx) *worker { worker := &worker{ id: ddlWorkerID.Add(1), tp: tp, @@ -132,7 +131,6 @@ func newWorker(ctx context.Context, tp workerType, sessPool *sessionPool, delRan ddlCtx: dCtx, sessPool: sessPool, delRangeManager: delRangeMgr, - concurrentDDL: concurrentDDL, } worker.addingDDLJobKey = addingDDLJobPrefix + worker.typeStr() worker.logCtx = logutil.WithKeyValue(context.Background(), "worker", worker.String()) @@ -165,59 +163,6 @@ func (w *worker) Close() { logutil.Logger(w.logCtx).Info("[ddl] DDL worker closed", zap.Duration("take time", time.Since(startTime))) } -// start is used for async online schema changing, it will try to become the owner firstly, -// then wait or pull the job queue to handle a schema change job. -func (w *worker) start(d *ddlCtx) { - logutil.Logger(w.logCtx).Info("[ddl] start DDL worker") - defer w.wg.Done() - defer tidbutil.Recover( - metrics.LabelDDLWorker, - fmt.Sprintf("DDL ID %s, %s start", d.uuid, w), - nil, true, - ) - - // We use 4 * lease time to check owner's timeout, so here, we will update owner's status - // every 2 * lease time. If lease is 0, we will use default 1s. - // But we use etcd to speed up, normally it takes less than 1s now, so we use 1s as the max value. - checkTime := chooseLeaseTime(2*d.lease, 1*time.Second) - - ticker := time.NewTicker(checkTime) - defer ticker.Stop() - var notifyDDLJobByEtcdCh clientv3.WatchChan - if d.etcdCli != nil { - notifyDDLJobByEtcdCh = d.etcdCli.Watch(context.Background(), w.addingDDLJobKey) - } - - rewatchCnt := 0 - for { - ok := true - select { - case <-ticker.C: - logutil.Logger(w.logCtx).Debug("[ddl] wait to check DDL status again", zap.Duration("interval", checkTime)) - case <-w.ddlJobCh: - case _, ok = <-notifyDDLJobByEtcdCh: - case <-w.ctx.Done(): - return - } - - if !ok { - logutil.Logger(w.logCtx).Warn("[ddl] start worker watch channel closed", zap.String("watch key", w.addingDDLJobKey)) - notifyDDLJobByEtcdCh = d.etcdCli.Watch(context.Background(), w.addingDDLJobKey) - rewatchCnt++ - if rewatchCnt > 10 { - time.Sleep(time.Duration(rewatchCnt) * time.Second) - } - continue - } - - rewatchCnt = 0 - err := w.handleDDLJobQueue(d) - if err != nil { - logutil.Logger(w.logCtx).Warn("[ddl] handle DDL job failed", zap.Error(err)) - } - } -} - func (d *ddl) asyncNotifyByEtcd(addingDDLJobKey string, job *model.Job) { if d.etcdCli == nil { return @@ -239,37 +184,6 @@ func asyncNotify(ch chan struct{}) { } } -// buildJobDependence sets the curjob's dependency-ID. -// The dependency-job's ID must less than the current job's ID, and we need the largest one in the list. -func buildJobDependence(t *meta.Meta, curJob *model.Job) error { - // Jobs in the same queue are ordered. If we want to find a job's dependency-job, we need to look for - // it from the other queue. So if the job is "ActionAddIndex" job, we need find its dependency-job from DefaultJobList. - jobListKey := meta.DefaultJobListKey - if !curJob.MayNeedReorg() { - jobListKey = meta.AddIndexJobListKey - } - jobs, err := t.GetAllDDLJobsInQueue(jobListKey) - if err != nil { - return errors.Trace(err) - } - - for _, job := range jobs { - if curJob.ID < job.ID { - continue - } - isDependent, err := curJob.IsDependentOn(job) - if err != nil { - return errors.Trace(err) - } - if isDependent { - logutil.BgLogger().Info("[ddl] current DDL job depends on other job", zap.String("currentJob", curJob.String()), zap.String("dependentJob", job.String())) - curJob.DependencyID = job.ID - break - } - } - return nil -} - func (d *ddl) limitDDLJobs() { defer tidbutil.Recover(metrics.LabelDDL, "limitDDLJobs", nil, true) @@ -295,7 +209,7 @@ func (d *ddl) addBatchDDLJobs(tasks []*limitJobTask) { startTime := time.Now() var err error // DDLForce2Queue is a flag to tell DDL worker to always push the job to the DDL queue. - toTable := variable.EnableConcurrentDDL.Load() && !variable.DDLForce2Queue.Load() + toTable := !variable.DDLForce2Queue.Load() if toTable { err = d.addBatchDDLJobs2Table(tasks) } else { @@ -315,6 +229,37 @@ func (d *ddl) addBatchDDLJobs(tasks []*limitJobTask) { } } +// buildJobDependence sets the curjob's dependency-ID. +// The dependency-job's ID must less than the current job's ID, and we need the largest one in the list. +func buildJobDependence(t *meta.Meta, curJob *model.Job) error { + // Jobs in the same queue are ordered. If we want to find a job's dependency-job, we need to look for + // it from the other queue. So if the job is "ActionAddIndex" job, we need find its dependency-job from DefaultJobList. + jobListKey := meta.DefaultJobListKey + if !curJob.MayNeedReorg() { + jobListKey = meta.AddIndexJobListKey + } + jobs, err := t.GetAllDDLJobsInQueue(jobListKey) + if err != nil { + return errors.Trace(err) + } + + for _, job := range jobs { + if curJob.ID < job.ID { + continue + } + isDependent, err := curJob.IsDependentOn(job) + if err != nil { + return errors.Trace(err) + } + if isDependent { + logutil.BgLogger().Info("[ddl] current DDL job depends on other job", zap.String("currentJob", curJob.String()), zap.String("dependentJob", job.String())) + curJob.DependencyID = job.ID + break + } + } + return nil +} + func (d *ddl) addBatchDDLJobs2Queue(tasks []*limitJobTask) error { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL) return kv.RunInNewTxn(ctx, d.store, true, func(ctx context.Context, txn kv.Transaction) error { @@ -425,6 +370,7 @@ func (d *ddl) addBatchDDLJobs2Table(tasks []*limitJobTask) error { jobTasks[i] = job injectModifyJobArgFailPoint(job) } + sess.SetDiskFullOpt(kvrpcpb.DiskFullOpt_AllowedOnAlmostFull) err = insertDDLJobs2Table(newSession(sess), true, jobTasks...) } @@ -443,13 +389,6 @@ func injectFailPointForGetJob(job *model.Job) { }) } -// getFirstDDLJob gets the first DDL job form DDL queue. -func (w *worker) getFirstDDLJob(t *meta.Meta) (*model.Job, error) { - job, err := t.GetDDLJobByIdx(0) - injectFailPointForGetJob(job) - return job, errors.Trace(err) -} - // handleUpdateJobError handles the too large DDL job. func (w *worker) handleUpdateJobError(t *meta.Meta, job *model.Job, err error) error { if err == nil { @@ -470,7 +409,7 @@ func (w *worker) handleUpdateJobError(t *meta.Meta, job *model.Job, err error) e // updateDDLJob updates the DDL job information. // Every time we enter another state except final state, we must call this function. -func (w *worker) updateDDLJob(t *meta.Meta, job *model.Job, meetErr bool) error { +func (w *worker) updateDDLJob(job *model.Job, meetErr bool) error { failpoint.Inject("mockErrEntrySizeTooLarge", func(val failpoint.Value) { if val.(bool) { failpoint.Return(kv.ErrEntryTooLarge) @@ -481,13 +420,7 @@ func (w *worker) updateDDLJob(t *meta.Meta, job *model.Job, meetErr bool) error logutil.Logger(w.logCtx).Info("[ddl] meet something wrong before update DDL job, shouldn't update raw args", zap.String("job", job.String())) } - var err error - if w.concurrentDDL { - err = updateDDLJob2Table(w.sess, job, updateRawArgs) - } else { - err = t.UpdateDDLJob(0, job, updateRawArgs) - } - return errors.Trace(err) + return errors.Trace(updateDDLJob2Table(w.sess, job, updateRawArgs)) } // registerMDLInfo registers metadata lock info. @@ -512,7 +445,7 @@ func (w *worker) registerMDLInfo(job *model.Job, ver int64) error { } // cleanMDLInfo cleans metadata lock info. -func cleanMDLInfo(pool *sessionPool, jobID int64) { +func cleanMDLInfo(pool *sessionPool, jobID int64, ec *clientv3.Client) { if !variable.EnableMDL.Load() { return } @@ -525,19 +458,30 @@ func cleanMDLInfo(pool *sessionPool, jobID int64) { if err != nil { logutil.BgLogger().Warn("unexpected error when clean mdl info", zap.Error(err)) } + if ec != nil { + path := fmt.Sprintf("%s/%d/", util.DDLAllSchemaVersionsByJob, jobID) + _, err = ec.Delete(context.Background(), path, clientv3.WithPrefix()) + if err != nil { + logutil.BgLogger().Warn("[ddl] delete versions failed", zap.Any("job id", jobID), zap.Error(err)) + } + } } // checkMDLInfo checks if metadata lock info exists. It means the schema is locked by some TiDBs if exists. -func checkMDLInfo(jobID int64, pool *sessionPool) (bool, error) { - sql := fmt.Sprintf("select * from mysql.tidb_mdl_info where job_id = %d", jobID) +func checkMDLInfo(jobID int64, pool *sessionPool) (bool, int64, error) { + sql := fmt.Sprintf("select version from mysql.tidb_mdl_info where job_id = %d", jobID) sctx, _ := pool.get() defer pool.put(sctx) sess := newSession(sctx) rows, err := sess.execute(context.Background(), sql, "check-mdl-info") if err != nil { - return false, err + return false, 0, err } - return len(rows) > 0, nil + if len(rows) == 0 { + return false, 0, nil + } + ver := rows[0].GetInt64(0) + return true, ver, nil } func needUpdateRawArgs(job *model.Job, meetErr bool) bool { @@ -571,7 +515,8 @@ func jobNeedGC(job *model.Job) bool { switch job.Type { case model.ActionDropSchema, model.ActionDropTable, model.ActionTruncateTable, model.ActionDropIndex, model.ActionDropPrimaryKey, model.ActionDropTablePartition, model.ActionTruncateTablePartition, model.ActionDropColumn, model.ActionModifyColumn, - model.ActionAddIndex, model.ActionAddPrimaryKey: + model.ActionAddIndex, model.ActionAddPrimaryKey, + model.ActionReorganizePartition: return true case model.ActionMultiSchemaChange: for _, sub := range job.MultiSchemaInfo.SubJobs { @@ -607,6 +552,8 @@ func (w *worker) finishDDLJob(t *meta.Meta, job *model.Job) (err error) { err = finishRecoverTable(w, job) case model.ActionFlashbackCluster: err = finishFlashbackCluster(w, job) + case model.ActionRecoverSchema: + err = finishRecoverSchema(w, job) case model.ActionCreateTables: if job.IsCancelled() { // it may be too large that it can not be added to the history queue, too @@ -617,11 +564,7 @@ func (w *worker) finishDDLJob(t *meta.Meta, job *model.Job) (err error) { if err != nil { return errors.Trace(err) } - if w.concurrentDDL { - err = w.deleteDDLJob(job) - } else { - _, err = t.DeQueueDDLJob() - } + err = w.deleteDDLJob(job) if err != nil { return errors.Trace(err) } @@ -636,7 +579,7 @@ func (w *worker) finishDDLJob(t *meta.Meta, job *model.Job) (err error) { } w.writeDDLSeqNum(job) w.removeJobCtx(job) - err = AddHistoryDDLJob(w.sess, t, job, updateRawArgs, w.concurrentDDL) + err = AddHistoryDDLJob(w.sess, t, job, updateRawArgs) return errors.Trace(err) } @@ -648,14 +591,33 @@ func (w *worker) writeDDLSeqNum(job *model.Job) { } func finishRecoverTable(w *worker, job *model.Job) error { - tbInfo := &model.TableInfo{} - var autoIncID, autoRandID, dropJobID, recoverTableCheckFlag int64 - var snapshotTS uint64 - err := job.DecodeArgs(tbInfo, &autoIncID, &dropJobID, &snapshotTS, &recoverTableCheckFlag, &autoRandID) + var ( + recoverInfo *RecoverInfo + recoverTableCheckFlag int64 + ) + err := job.DecodeArgs(&recoverInfo, &recoverTableCheckFlag) if err != nil { return errors.Trace(err) } - if recoverTableCheckFlag == recoverTableCheckFlagEnableGC { + if recoverTableCheckFlag == recoverCheckFlagEnableGC { + err = enableGC(w) + if err != nil { + return errors.Trace(err) + } + } + return nil +} + +func finishRecoverSchema(w *worker, job *model.Job) error { + var ( + recoverSchemaInfo *RecoverSchemaInfo + recoverSchemaCheckFlag int64 + ) + err := job.DecodeArgs(&recoverSchemaInfo, &recoverSchemaCheckFlag) + if err != nil { + return errors.Trace(err) + } + if recoverSchemaCheckFlag == recoverCheckFlagEnableGC { err = enableGC(w) if err != nil { return errors.Trace(err) @@ -681,21 +643,14 @@ func isDependencyJobDone(t *meta.Meta, job *model.Job) (bool, error) { return true, nil } -func newMetaWithQueueTp(txn kv.Transaction, tp workerType) *meta.Meta { - if tp == addIdxWorker { - return meta.NewMeta(txn, meta.AddIndexJobListKey) - } - return meta.NewMeta(txn) -} - -func (w *JobContext) setDDLLabelForTopSQL(job *model.Job) { - if !topsqlstate.TopSQLEnabled() || job == nil { +func (w *JobContext) setDDLLabelForTopSQL(jobQuery string) { + if !topsqlstate.TopSQLEnabled() || jobQuery == "" { return } - if job.Query != w.cacheSQL || w.cacheDigest == nil { - w.cacheNormalizedSQL, w.cacheDigest = parser.NormalizeDigest(job.Query) - w.cacheSQL = job.Query + if jobQuery != w.cacheSQL || w.cacheDigest == nil { + w.cacheNormalizedSQL, w.cacheDigest = parser.NormalizeDigest(jobQuery) + w.cacheSQL = jobQuery w.ddlJobCtx = topsql.AttachAndRegisterSQLInfo(context.Background(), w.cacheNormalizedSQL, w.cacheDigest, false) } else { topsql.AttachAndRegisterSQLInfo(w.ddlJobCtx, w.cacheNormalizedSQL, w.cacheDigest, false) @@ -715,9 +670,10 @@ func (w *worker) unlockSeqNum(err error) { // DDLBackfillers contains the DDL need backfill step. var DDLBackfillers = map[model.ActionType]string{ - model.ActionAddIndex: "add_index", - model.ActionModifyColumn: "modify_column", - model.ActionDropIndex: "drop_index", + model.ActionAddIndex: "add_index", + model.ActionModifyColumn: "modify_column", + model.ActionDropIndex: "drop_index", + model.ActionReorganizePartition: "reorganize_partition", } func getDDLRequestSource(job *model.Job) string { @@ -728,6 +684,9 @@ func getDDLRequestSource(job *model.Job) string { } func (w *JobContext) setDDLLabelForDiagnosis(job *model.Job) { + if w.tp != "" { + return + } w.tp = getDDLRequestSource(job) w.ddlJobCtx = kv.WithInternalSourceType(w.ddlJobCtx, w.ddlJobSourceType()) } @@ -743,6 +702,7 @@ func (w *worker) HandleJobDone(d *ddlCtx, job *model.Job, t *meta.Meta) error { if err != nil { return err } + CleanupDDLReorgHandles(job, w.sess) asyncNotify(d.ddlJobDoneCh) return nil } @@ -761,7 +721,7 @@ func (w *worker) HandleDDLJobTable(d *ddlCtx, job *model.Job) (int64, error) { if err != nil { return 0, err } - if !variable.EnableConcurrentDDL.Load() || d.waiting.Load() { + if d.waiting.Load() { w.sess.rollback() return 0, nil } @@ -779,10 +739,10 @@ func (w *worker) HandleDDLJobTable(d *ddlCtx, job *model.Job) (int64, error) { if w.tp == addIdxWorker && job.IsRunning() { txn.SetDiskFullOpt(kvrpcpb.DiskFullOpt_NotAllowedOnFull) } - w.setDDLLabelForTopSQL(job) + w.setDDLLabelForTopSQL(job.ID, job.Query) w.setDDLSourceForDiagnosis(job) - jobContext := w.jobContext(job) - if tagger := w.getResourceGroupTaggerForTopSQL(job); tagger != nil { + jobContext := w.jobContext(job.ID) + if tagger := w.getResourceGroupTaggerForTopSQL(job.ID); tagger != nil { txn.SetOption(kv.ResourceGroupTagger, tagger) } t := meta.NewMeta(txn) @@ -831,7 +791,7 @@ func (w *worker) HandleDDLJobTable(d *ddlCtx, job *model.Job) (int64, error) { d.unlockSchemaVersion(job.ID) return 0, err } - err = w.updateDDLJob(t, job, runJobErr != nil) + err = w.updateDDLJob(job, runJobErr != nil) if err = w.handleUpdateJobError(t, job, err); err != nil { w.sess.rollback() d.unlockSchemaVersion(job.ID) @@ -875,152 +835,6 @@ func (w *JobContext) ddlJobSourceType() string { return w.tp } -// handleDDLJobQueue handles DDL jobs in DDL Job queue. -func (w *worker) handleDDLJobQueue(d *ddlCtx) error { - once := true - waitDependencyJobCnt := 0 - for { - if isChanClosed(w.ctx.Done()) { - return nil - } - - var ( - job *model.Job - schemaVer int64 - runJobErr error - ) - waitTime := 2 * d.lease - ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL) - err := kv.RunInNewTxn(ctx, d.store, false, func(ctx context.Context, txn kv.Transaction) error { - d.runningJobs.Lock() - // We are not owner, return and retry checking later. - if !d.isOwner() || variable.EnableConcurrentDDL.Load() || d.waiting.Load() { - d.runningJobs.Unlock() - return nil - } - - var err error - t := newMetaWithQueueTp(txn, w.tp) - - // We become the owner. Get the first job and run it. - job, err = w.getFirstDDLJob(t) - if job == nil || err != nil { - d.runningJobs.Unlock() - return errors.Trace(err) - } - d.runningJobs.ids[job.ID] = struct{}{} - d.runningJobs.Unlock() - - defer d.deleteRunningDDLJobMap(job.ID) - - // only general ddls allowed to be executed when TiKV is disk full. - if w.tp == addIdxWorker && job.IsRunning() { - txn.SetDiskFullOpt(kvrpcpb.DiskFullOpt_NotAllowedOnFull) - } - - w.setDDLLabelForTopSQL(job) - w.setDDLSourceForDiagnosis(job) - jobContext := w.jobContext(job) - if tagger := w.getResourceGroupTaggerForTopSQL(job); tagger != nil { - txn.SetOption(kv.ResourceGroupTagger, tagger) - } - if isDone, err1 := isDependencyJobDone(t, job); err1 != nil || !isDone { - return errors.Trace(err1) - } - - if once { - err = waitSchemaSynced(d, job, waitTime) - if err == nil { - once = false - } - return err - } - - if job.IsDone() || job.IsRollbackDone() { - if !job.IsRollbackDone() { - job.State = model.JobStateSynced - } - err = w.finishDDLJob(t, job) - return errors.Trace(err) - } - - d.mu.RLock() - d.mu.hook.OnJobRunBefore(job) - d.mu.RUnlock() - - // set request source type to DDL type - txn.SetOption(kv.RequestSourceType, jobContext.ddlJobSourceType()) - // If running job meets error, we will save this error in job Error - // and retry later if the job is not cancelled. - schemaVer, runJobErr = w.runDDLJob(d, t, job) - if job.IsCancelled() { - txn.Reset() - err = w.finishDDLJob(t, job) - return errors.Trace(err) - } - if runJobErr != nil && !job.IsRollingback() && !job.IsRollbackDone() { - // If the running job meets an error - // and the job state is rolling back, it means that we have already handled this error. - // Some DDL jobs (such as adding indexes) may need to update the table info and the schema version, - // then shouldn't discard the KV modification. - // And the job state is rollback done, it means the job was already finished, also shouldn't discard too. - // Otherwise, we should discard the KV modification when running job. - txn.Reset() - // If error happens after updateSchemaVersion(), then the schemaVer is updated. - // Result in the retry duration is up to 2 * lease. - schemaVer = 0 - } - err = w.updateDDLJob(t, job, runJobErr != nil) - if err = w.handleUpdateJobError(t, job, err); err != nil { - return errors.Trace(err) - } - writeBinlog(d.binlogCli, txn, job) - return nil - }) - - if runJobErr != nil { - // wait a while to retry again. If we don't wait here, DDL will retry this job immediately, - // which may act like a deadlock. - logutil.Logger(w.logCtx).Info("[ddl] run DDL job failed, sleeps a while then retries it.", - zap.Duration("waitTime", GetWaitTimeWhenErrorOccurred()), zap.Error(runJobErr)) - time.Sleep(GetWaitTimeWhenErrorOccurred()) - } - if job != nil { - d.unlockSchemaVersion(job.ID) - } - - if err != nil { - w.unlockSeqNum(err) - return errors.Trace(err) - } else if job == nil { - // No job now, return and retry getting later. - return nil - } - w.unlockSeqNum(err) - w.waitDependencyJobFinished(job, &waitDependencyJobCnt) - - // Here means the job enters another state (delete only, write only, public, etc...) or is cancelled. - // If the job is done or still running or rolling back, we will wait 2 * lease time to guarantee other servers to update - // the newest schema. - waitSchemaChanged(context.Background(), d, waitTime, schemaVer, job) - - if RunInGoTest { - // d.mu.hook is initialed from domain / test callback, which will force the owner host update schema diff synchronously. - d.mu.RLock() - d.mu.hook.OnSchemaStateChanged() - d.mu.RUnlock() - } - - d.mu.RLock() - d.mu.hook.OnJobUpdated(job) - d.mu.RUnlock() - - if job.IsSynced() || job.IsCancelled() || job.IsRollbackDone() { - asyncNotify(d.ddlJobDoneCh) - } - } -} - func skipWriteBinlog(job *model.Job) bool { switch job.Type { // ActionUpdateTiFlashReplicaStatus is a TiDB internal DDL, @@ -1168,6 +982,8 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = onModifySchemaCharsetAndCollate(d, t, job) case model.ActionDropSchema: ver, err = onDropSchema(d, t, job) + case model.ActionRecoverSchema: + ver, err = w.onRecoverSchema(d, t, job) case model.ActionModifySchemaDefaultPlacement: ver, err = onModifySchemaDefaultPlacement(d, t, job) case model.ActionCreateTable: @@ -1209,7 +1025,7 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, case model.ActionTruncateTable: ver, err = onTruncateTable(d, t, job) case model.ActionRebaseAutoID: - ver, err = onRebaseRowIDType(d, t, job) + ver, err = onRebaseAutoIncrementIDType(d, t, job) case model.ActionRebaseAutoRandomBase: ver, err = onRebaseAutoRandomType(d, t, job) case model.ActionRenameTable: @@ -1256,6 +1072,12 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = onAlterTablePartitionPlacement(d, t, job) case model.ActionAlterTablePlacement: ver, err = onAlterTablePlacement(d, t, job) + case model.ActionCreateResourceGroup: + ver, err = onCreateResourceGroup(d, t, job) + case model.ActionAlterResourceGroup: + ver, err = onAlterResourceGroup(d, t, job) + case model.ActionDropResourceGroup: + ver, err = onDropResourceGroup(d, t, job) case model.ActionAlterCacheTable: ver, err = onAlterCacheTable(d, t, job) case model.ActionAlterNoCacheTable: @@ -1264,6 +1086,12 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = w.onFlashbackCluster(d, t, job) case model.ActionMultiSchemaChange: ver, err = onMultiSchemaChange(w, d, t, job) + case model.ActionReorganizePartition: + ver, err = w.onReorganizePartition(d, t, job) + case model.ActionAlterTTLInfo: + ver, err = onTTLInfoChange(d, t, job) + case model.ActionAlterTTLRemove: + ver, err = onTTLInfoRemove(d, t, job) default: // Invalid job, cancel it. job.State = model.JobStateCancelled @@ -1342,6 +1170,32 @@ func waitSchemaChanged(ctx context.Context, d *ddlCtx, waitTime time.Duration, l zap.String("job", job.String())) } +// waitSchemaSyncedForMDL likes waitSchemaSynced, but it waits for getting the metadata lock of the latest version of this DDL. +func waitSchemaSyncedForMDL(d *ddlCtx, job *model.Job, latestSchemaVersion int64) error { + failpoint.Inject("checkDownBeforeUpdateGlobalVersion", func(val failpoint.Value) { + if val.(bool) { + if mockDDLErrOnce > 0 && mockDDLErrOnce != latestSchemaVersion { + panic("check down before update global version failed") + } else { + mockDDLErrOnce = -1 + } + } + }) + + timeStart := time.Now() + // OwnerCheckAllVersions returns only when all TiDB schemas are synced(exclude the isolated TiDB). + err := d.schemaSyncer.OwnerCheckAllVersions(context.Background(), job.ID, latestSchemaVersion) + if err != nil { + logutil.Logger(d.ctx).Info("[ddl] wait latest schema version encounter error", zap.Int64("ver", latestSchemaVersion), zap.Error(err)) + return err + } + logutil.Logger(d.ctx).Info("[ddl] wait latest schema version changed(get the metadata lock if tidb_enable_metadata_lock is true)", + zap.Int64("ver", latestSchemaVersion), + zap.Duration("take time", time.Since(timeStart)), + zap.String("job", job.String())) + return nil +} + // waitSchemaSynced handles the following situation: // If the job enters a new state, and the worker crashs when it's in the process of waiting for 2 * lease time, // Then the worker restarts quickly, we may run the job immediately again, @@ -1507,6 +1361,22 @@ func updateSchemaVersion(d *ddlCtx, t *meta.Meta, job *model.Job, multiInfos ... diff.AffectedOpts = buildPlacementAffects(oldIDs, oldIDs) } } + case model.ActionReorganizePartition: + diff.TableID = job.TableID + if len(job.CtxVars) > 0 { + if droppedIDs, ok := job.CtxVars[0].([]int64); ok { + if addedIDs, ok := job.CtxVars[1].([]int64); ok { + // to use AffectedOpts we need both new and old to have the same length + maxParts := mathutil.Max[int](len(droppedIDs), len(addedIDs)) + // Also initialize them to 0! + oldIDs := make([]int64, maxParts) + copy(oldIDs, droppedIDs) + newIDs := make([]int64, maxParts) + copy(newIDs, addedIDs) + diff.AffectedOpts = buildPlacementAffects(oldIDs, newIDs) + } + } + } case model.ActionCreateTable: diff.TableID = job.TableID if len(job.Args) > 0 { @@ -1520,6 +1390,32 @@ func updateSchemaVersion(d *ddlCtx, t *meta.Meta, job *model.Job, multiInfos ... diff.OldTableID = job.TableID } } + case model.ActionRecoverSchema: + var ( + recoverSchemaInfo *RecoverSchemaInfo + recoverSchemaCheckFlag int64 + ) + err = job.DecodeArgs(&recoverSchemaInfo, &recoverSchemaCheckFlag) + if err != nil { + return 0, errors.Trace(err) + } + // Reserved recoverSchemaCheckFlag value for gc work judgment. + job.Args[checkFlagIndexInJobArgs] = recoverSchemaCheckFlag + recoverTabsInfo := recoverSchemaInfo.RecoverTabsInfo + diff.AffectedOpts = make([]*model.AffectedOption, len(recoverTabsInfo)) + for i := range recoverTabsInfo { + diff.AffectedOpts[i] = &model.AffectedOption{ + SchemaID: job.SchemaID, + OldSchemaID: job.SchemaID, + TableID: recoverTabsInfo[i].TableInfo.ID, + OldTableID: recoverTabsInfo[i].TableInfo.ID, + } + } + case model.ActionFlashbackCluster: + diff.TableID = -1 + if job.SchemaState == model.StatePublic { + diff.RegenerateSchemaMap = true + } default: diff.TableID = job.TableID } diff --git a/ddl/ddl_workerpool_test.go b/ddl/ddl_workerpool_test.go index 39a3a6b1452d0..123d05abb1d86 100644 --- a/ddl/ddl_workerpool_test.go +++ b/ddl/ddl_workerpool_test.go @@ -15,17 +15,17 @@ package ddl import ( + "context" "testing" "github.com/ngaut/pools" - "github.com/pingcap/tidb/parser/model" "github.com/stretchr/testify/require" ) func TestDDLWorkerPool(t *testing.T) { f := func() func() (pools.Resource, error) { return func() (pools.Resource, error) { - wk := newWorker(nil, addIdxWorker, nil, nil, nil, true) + wk := newWorker(nil, addIdxWorker, nil, nil, nil) return wk, nil } } @@ -35,10 +35,9 @@ func TestDDLWorkerPool(t *testing.T) { } func TestBackfillWorkerPool(t *testing.T) { - reorgInfo := &reorgInfo{Job: &model.Job{ID: 1}} f := func() func() (pools.Resource, error) { return func() (pools.Resource, error) { - wk := newBackfillWorker(nil, 1, nil, reorgInfo, typeAddIndexWorker) + wk := newBackfillWorker(context.Background(), 1, nil) return wk, nil } } diff --git a/ddl/delete_range.go b/ddl/delete_range.go index 669ff286ea9dd..bba8aff7e2f99 100644 --- a/ddl/delete_range.go +++ b/ddl/delete_range.go @@ -307,9 +307,13 @@ func insertJobIntoDeleteRangeTable(ctx context.Context, sctx sessionctx.Context, endKey := tablecodec.EncodeTablePrefix(tableID + 1) elemID := ea.allocForPhysicalID(tableID) return doInsert(ctx, s, job.ID, elemID, startKey, endKey, now, fmt.Sprintf("table ID is %d", tableID)) - case model.ActionDropTablePartition, model.ActionTruncateTablePartition: + case model.ActionDropTablePartition, model.ActionTruncateTablePartition, model.ActionReorganizePartition: var physicalTableIDs []int64 - if err := job.DecodeArgs(&physicalTableIDs); err != nil { + // partInfo is not used, but is set in ReorgPartition. + // Better to have an additional argument in job.DecodeArgs since it is ignored, + // instead of having one to few, which will remove the data from the job arguments... + var partInfo model.PartitionInfo + if err := job.DecodeArgs(&physicalTableIDs, &partInfo); err != nil { return errors.Trace(err) } for _, physicalTableID := range physicalTableIDs { diff --git a/ddl/export_test.go b/ddl/export_test.go index 708b3474515c5..3ea26fb04290c 100644 --- a/ddl/export_test.go +++ b/ddl/export_test.go @@ -14,6 +14,42 @@ package ddl +import ( + "context" + + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/types" +) + func SetBatchInsertDeleteRangeSize(i int) { batchInsertDeleteRangeSize = i } + +var NewCopContext4Test = newCopContext + +func FetchRowsFromCop4Test(copCtx *copContext, startKey, endKey kv.Key, store kv.Storage, + batchSize int) ([]*indexRecord, bool, error) { + variable.SetDDLReorgBatchSize(int32(batchSize)) + task := &reorgBackfillTask{ + id: 1, + startKey: startKey, + endKey: endKey, + } + pool := newCopReqSenderPool(context.Background(), copCtx, store) + pool.adjustSize(1) + pool.tasksCh <- task + idxRec, _, _, done, err := pool.fetchRowColValsFromCop(*task) + pool.close() + return idxRec, done, err +} + +type IndexRecord4Test = *indexRecord + +func (i IndexRecord4Test) GetHandle() kv.Handle { + return i.handle +} + +func (i IndexRecord4Test) GetIndexValues() []types.Datum { + return i.vals +} diff --git a/ddl/failtest/fail_db_test.go b/ddl/failtest/fail_db_test.go index e4d8ea7e58342..4a938e5fd2ad4 100644 --- a/ddl/failtest/fail_db_test.go +++ b/ddl/failtest/fail_db_test.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "math/rand" + "strings" "sync/atomic" "testing" "time" @@ -534,6 +535,34 @@ func TestModifyColumn(t *testing.T) { tk.MustExec("drop table t, t1, t2, t3, t4, t5") } +func TestIssue38699(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + //Test multi records + tk.MustExec("USE test") + tk.MustExec("set sql_mode=''") + tk.MustExec("DROP TABLE IF EXISTS t;") + tk.MustExec("CREATE TABLE t (a int)") + tk.MustExec("insert into t values (1000000000), (2000000)") + tk.MustExec("alter table t modify a tinyint") + result := tk.MustQuery("show warnings") + require.Len(t, result.Rows(), 1) + result.CheckWithFunc(testkit.Rows("Warning 1690 2 warnings with this error code"), func(actual []string, expected []interface{}) bool { + //Check if it starts with x warning(s) + return strings.EqualFold(actual[0], expected[0].(string)) && strings.EqualFold(actual[1], expected[1].(string)) && strings.HasPrefix(actual[2], expected[2].(string)) + }) + + //Test single record + tk.MustExec("DROP TABLE IF EXISTS t;") + tk.MustExec("CREATE TABLE t (a int)") + tk.MustExec("insert into t values (1000000000)") + tk.MustExec("alter table t modify a tinyint") + result = tk.MustQuery("show warnings") + require.Len(t, result.Rows(), 1) + result.Check(testkit.Rows("Warning 1690 constant 1000000000 overflows tinyint")) +} + func TestPartitionAddPanic(t *testing.T) { s := createFailDBSuite(t) tk := testkit.NewTestKit(t, s.store) diff --git a/ddl/failtest/main_test.go b/ddl/failtest/main_test.go index 90097bae51e71..c136cb0fa6b94 100644 --- a/ddl/failtest/main_test.go +++ b/ddl/failtest/main_test.go @@ -36,6 +36,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } diff --git a/ddl/fktest/BUILD.bazel b/ddl/fktest/BUILD.bazel new file mode 100644 index 0000000000000..a2452785fcaa8 --- /dev/null +++ b/ddl/fktest/BUILD.bazel @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "fktest_test", + srcs = [ + "foreign_key_test.go", + "main_test.go", + ], + flaky = True, + shard_count = 4, + deps = [ + "//config", + "//ddl", + "//domain", + "//infoschema", + "//meta", + "//meta/autoid", + "//parser/auth", + "//parser/model", + "//planner/core", + "//sessiontxn", + "//testkit", + "//testkit/testsetup", + "//util/dbterror", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//tikv", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/ddl/fktest/foreign_key_test.go b/ddl/fktest/foreign_key_test.go new file mode 100644 index 0000000000000..489e125dc8a3c --- /dev/null +++ b/ddl/fktest/foreign_key_test.go @@ -0,0 +1,1837 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl_test + +import ( + "bytes" + "context" + "fmt" + "sync" + "testing" + "time" + + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/meta" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/model" + plannercore "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/sessiontxn" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/util/dbterror" + "github.com/stretchr/testify/require" +) + +func TestCreateTableWithForeignKeyMetaInfo(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int,b int as (a) virtual);") + tk.MustExec("create database test2") + tk.MustExec("use test2") + tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id) ON UPDATE RESTRICT ON DELETE CASCADE)") + tb1Info := getTableInfo(t, dom, "test", "t1") + tb2Info := getTableInfo(t, dom, "test2", "t2") + require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test", "t1"))) + require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) + require.Equal(t, 0, len(tb1Info.ForeignKeys)) + tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("t2"), + ChildFKName: model.NewCIStr("fk_b"), + }, *tb1ReferredFKs[0]) + tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t2") + require.Equal(t, 0, len(tb2ReferredFKs)) + require.Equal(t, 1, len(tb2Info.ForeignKeys)) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_b"), + RefSchema: model.NewCIStr("test"), + RefTable: model.NewCIStr("t1"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("b")}, + OnDelete: 2, + OnUpdate: 1, + State: model.StatePublic, + Version: 1, + }, *tb2Info.ForeignKeys[0]) + // Auto create index for foreign key usage. + require.Equal(t, 1, len(tb2Info.Indices)) + require.Equal(t, "fk_b", tb2Info.Indices[0].Name.L) + require.Equal(t, "`test2`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT", tb2Info.ForeignKeys[0].String("test2", "t2")) + + tk.MustExec("create table t3 (id int, b int, index idx_b(b), foreign key fk_b(b) references t2(id) ON UPDATE SET NULL ON DELETE NO ACTION)") + tb2Info = getTableInfo(t, dom, "test2", "t2") + tb3Info := getTableInfo(t, dom, "test2", "t3") + require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) + require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t3"))) + require.Equal(t, 1, len(tb2Info.ForeignKeys)) + tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test2", "t2") + require.Equal(t, 1, len(tb2ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("t3"), + ChildFKName: model.NewCIStr("fk_b"), + }, *tb2ReferredFKs[0]) + tb3ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t3") + require.Equal(t, 0, len(tb3ReferredFKs)) + require.Equal(t, 1, len(tb3Info.ForeignKeys)) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_b"), + RefSchema: model.NewCIStr("test2"), + RefTable: model.NewCIStr("t2"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("b")}, + OnDelete: 4, + OnUpdate: 3, + State: model.StatePublic, + Version: 1, + }, *tb3Info.ForeignKeys[0]) + require.Equal(t, 1, len(tb3Info.Indices)) + require.Equal(t, "idx_b", tb3Info.Indices[0].Name.L) + require.Equal(t, "`test2`.`t3`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `t2` (`id`) ON DELETE NO ACTION ON UPDATE SET NULL", tb3Info.ForeignKeys[0].String("test2", "t3")) + + tk.MustExec("create table t5 (id int key, a int, b int, foreign key (a) references t5(id));") + tb5Info := getTableInfo(t, dom, "test2", "t5") + require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t5"))) + require.Equal(t, 1, len(tb5Info.ForeignKeys)) + tb5ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t5") + require.Equal(t, 1, len(tb5ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("t5"), + ChildFKName: model.NewCIStr("fk_1"), + }, *tb5ReferredFKs[0]) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_1"), + RefSchema: model.NewCIStr("test2"), + RefTable: model.NewCIStr("t5"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("a")}, + State: model.StatePublic, + Version: 1, + }, *tb5Info.ForeignKeys[0]) + require.Equal(t, 1, len(tb5Info.Indices)) + require.Equal(t, "fk_1", tb5Info.Indices[0].Name.L) + require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test", "t1"))) + require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) + require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t3"))) + require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t5"))) + + tk.MustExec("set @@global.tidb_enable_foreign_key=0") + tk.MustExec("drop database test2") + require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) + require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t3"))) + require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t5"))) +} + +func TestCreateTableWithForeignKeyMetaInfo2(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("create database test2") + tk.MustExec("set @@foreign_key_checks=0") + tk.MustExec("use test2") + tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id) ON UPDATE RESTRICT ON DELETE CASCADE)") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int, b int as (a) virtual);") + tb1Info := getTableInfo(t, dom, "test", "t1") + tb2Info := getTableInfo(t, dom, "test2", "t2") + require.Equal(t, 0, len(tb1Info.ForeignKeys)) + tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("t2"), + ChildFKName: model.NewCIStr("fk_b"), + }, *tb1ReferredFKs[0]) + tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t2") + require.Equal(t, 0, len(tb2ReferredFKs)) + require.Equal(t, 1, len(tb2Info.ForeignKeys)) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_b"), + RefSchema: model.NewCIStr("test"), + RefTable: model.NewCIStr("t1"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("b")}, + OnDelete: 2, + OnUpdate: 1, + State: model.StatePublic, + Version: 1, + }, *tb2Info.ForeignKeys[0]) + // Auto create index for foreign key usage. + require.Equal(t, 1, len(tb2Info.Indices)) + require.Equal(t, "fk_b", tb2Info.Indices[0].Name.L) + require.Equal(t, "`test2`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT", tb2Info.ForeignKeys[0].String("test2", "t2")) + + tk.MustExec("create table t3 (id int key, a int, foreign key fk_a(a) references test.t1(id) ON DELETE CASCADE ON UPDATE RESTRICT, foreign key fk_a2(a) references test2.t2(id))") + tb1Info = getTableInfo(t, dom, "test", "t1") + tb3Info := getTableInfo(t, dom, "test", "t3") + require.Equal(t, 0, len(tb1Info.ForeignKeys)) + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 2, len(tb1ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test"), + ChildTable: model.NewCIStr("t3"), + ChildFKName: model.NewCIStr("fk_a"), + }, *tb1ReferredFKs[0]) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("t2"), + ChildFKName: model.NewCIStr("fk_b"), + }, *tb1ReferredFKs[1]) + tb3ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t3") + require.Equal(t, 0, len(tb3ReferredFKs)) + require.Equal(t, 2, len(tb3Info.ForeignKeys)) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_a"), + RefSchema: model.NewCIStr("test"), + RefTable: model.NewCIStr("t1"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("a")}, + OnDelete: 2, + OnUpdate: 1, + State: model.StatePublic, + Version: 1, + }, *tb3Info.ForeignKeys[0]) + require.Equal(t, model.FKInfo{ + ID: 2, + Name: model.NewCIStr("fk_a2"), + RefSchema: model.NewCIStr("test2"), + RefTable: model.NewCIStr("t2"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("a")}, + State: model.StatePublic, + Version: 1, + }, *tb3Info.ForeignKeys[1]) + // Auto create index for foreign key usage. + require.Equal(t, 1, len(tb3Info.Indices)) + require.Equal(t, "fk_a", tb3Info.Indices[0].Name.L) + require.Equal(t, "`test`.`t3`, CONSTRAINT `fk_a` FOREIGN KEY (`a`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT", tb3Info.ForeignKeys[0].String("test", "t3")) + require.Equal(t, "`test`.`t3`, CONSTRAINT `fk_a2` FOREIGN KEY (`a`) REFERENCES `test2`.`t2` (`id`)", tb3Info.ForeignKeys[1].String("test", "t3")) + + tk.MustExec("set @@foreign_key_checks=0") + tk.MustExec("drop table test2.t2") + tb1Info = getTableInfo(t, dom, "test", "t1") + tb3Info = getTableInfo(t, dom, "test", "t3") + require.Equal(t, 0, len(tb1Info.ForeignKeys)) + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test"), + ChildTable: model.NewCIStr("t3"), + ChildFKName: model.NewCIStr("fk_a"), + }, *tb1ReferredFKs[0]) + tb3ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t3") + require.Equal(t, 0, len(tb3ReferredFKs)) + require.Equal(t, 2, len(tb3Info.ForeignKeys)) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_a"), + RefSchema: model.NewCIStr("test"), + RefTable: model.NewCIStr("t1"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("a")}, + OnDelete: 2, + OnUpdate: 1, + State: model.StatePublic, + Version: 1, + }, *tb3Info.ForeignKeys[0]) + require.Equal(t, model.FKInfo{ + ID: 2, + Name: model.NewCIStr("fk_a2"), + RefSchema: model.NewCIStr("test2"), + RefTable: model.NewCIStr("t2"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("a")}, + State: model.StatePublic, + Version: 1, + }, *tb3Info.ForeignKeys[1]) +} + +func TestCreateTableWithForeignKeyMetaInfo3(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int, b int as (a) virtual);") + tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id))") + tk.MustExec("create table t3 (id int key, b int, foreign key fk_b(b) references test.t1(id))") + tk.MustExec("create table t4 (id int key, b int, foreign key fk_b(b) references test.t1(id))") + tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + tk.MustExec("drop table t3") + tk.MustExec("create table t5 (id int key, b int, foreign key fk_b(b) references test.t1(id))") + require.Equal(t, 3, len(tb1ReferredFKs)) + require.Equal(t, "t2", tb1ReferredFKs[0].ChildTable.L) + require.Equal(t, "t3", tb1ReferredFKs[1].ChildTable.L) + require.Equal(t, "t4", tb1ReferredFKs[2].ChildTable.L) +} + +func TestCreateTableWithForeignKeyPrivilegeCheck(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("create user 'u1'@'%' identified by '';") + tk.MustExec("grant create on *.* to 'u1'@'%';") + tk.MustExec("create table t1 (id int key);") + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost", CurrentUser: true, AuthUsername: "u1", AuthHostname: "%"}, nil, []byte("012345678901234567890")) + err := tk2.ExecToErr("create table t2 (a int, foreign key fk(a) references t1(id));") + require.Error(t, err) + require.Equal(t, "[planner:1142]REFERENCES command denied to user 'u1'@'%' for table 't1'", err.Error()) + + tk.MustExec("grant references on test.t1 to 'u1'@'%';") + tk2.MustExec("create table t2 (a int, foreign key fk(a) references t1(id));") + tk2.MustExec("create table t3 (id int key)") + err = tk2.ExecToErr("create table t4 (a int, foreign key fk(a) references t1(id), foreign key (a) references t3(id));") + require.Error(t, err) + require.Equal(t, "[planner:1142]REFERENCES command denied to user 'u1'@'%' for table 't3'", err.Error()) + + tk.MustExec("grant references on test.t3 to 'u1'@'%';") + tk2.MustExec("create table t4 (a int, foreign key fk(a) references t1(id), foreign key (a) references t3(id));") +} + +func TestAlterTableWithForeignKeyPrivilegeCheck(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create user 'u1'@'%' identified by '';") + tk.MustExec("grant create,alter on *.* to 'u1'@'%';") + tk.MustExec("create table t1 (id int key);") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost", CurrentUser: true, AuthUsername: "u1", AuthHostname: "%"}, nil, []byte("012345678901234567890")) + tk2.MustExec("create table t2 (a int)") + err := tk2.ExecToErr("alter table t2 add foreign key (a) references t1 (id) on update cascade") + require.Error(t, err) + require.Equal(t, "[planner:1142]REFERENCES command denied to user 'u1'@'%' for table 't1'", err.Error()) + tk.MustExec("grant references on test.t1 to 'u1'@'%';") + tk2.MustExec("alter table t2 add foreign key (a) references t1 (id) on update cascade") +} + +func TestRenameTableWithForeignKeyMetaInfo(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("create database test2") + tk.MustExec("create database test3") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))") + tk.MustExec("rename table test.t1 to test2.t2") + // check the schema diff + diff := getLatestSchemaDiff(t, tk) + require.Equal(t, model.ActionRenameTable, diff.Type) + require.Equal(t, 0, len(diff.AffectedOpts)) + tk.MustQuery("show create table test2.t2").Check(testkit.Rows("t2 CREATE TABLE `t2` (\n" + + " `id` int(11) NOT NULL,\n" + + " `a` int(11) DEFAULT NULL,\n" + + " `b` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `fk` (`a`),\n" + + " CONSTRAINT `fk` FOREIGN KEY (`a`) REFERENCES `test2`.`t2` (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + tblInfo := getTableInfo(t, dom, "test2", "t2") + tbReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t2") + require.Equal(t, 1, len(tblInfo.ForeignKeys)) + require.Equal(t, 1, len(tbReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("t2"), + ChildFKName: model.NewCIStr("fk"), + }, *tbReferredFKs[0]) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk"), + RefSchema: model.NewCIStr("test2"), + RefTable: model.NewCIStr("t2"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("a")}, + State: model.StatePublic, + Version: 1, + }, *tblInfo.ForeignKeys[0]) + + tk.MustExec("drop table test2.t2") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int, b int as (a) virtual);") + tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id))") + tk.MustExec("use test2") + tk.MustExec("rename table test.t2 to test2.tt2") + // check the schema diff + diff = getLatestSchemaDiff(t, tk) + require.Equal(t, model.ActionRenameTable, diff.Type) + require.Equal(t, 0, len(diff.AffectedOpts)) + tb1Info := getTableInfo(t, dom, "test", "t1") + tb2Info := getTableInfo(t, dom, "test2", "tt2") + require.Equal(t, 0, len(tb1Info.ForeignKeys)) + tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("tt2"), + ChildFKName: model.NewCIStr("fk_b"), + }, *tb1ReferredFKs[0]) + tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "tt2") + require.Equal(t, 0, len(tb2ReferredFKs)) + require.Equal(t, 1, len(tb2Info.ForeignKeys)) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_b"), + RefSchema: model.NewCIStr("test"), + RefTable: model.NewCIStr("t1"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("b")}, + State: model.StatePublic, + Version: 1, + }, *tb2Info.ForeignKeys[0]) + // Auto create index for foreign key usage. + require.Equal(t, 1, len(tb2Info.Indices)) + require.Equal(t, "fk_b", tb2Info.Indices[0].Name.L) + require.Equal(t, "`test2`.`tt2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`id`)", tb2Info.ForeignKeys[0].String("test2", "tt2")) + + tk.MustExec("rename table test.t1 to test3.tt1") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test3", "tt1") + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) + // check the schema diff + diff = getLatestSchemaDiff(t, tk) + require.Equal(t, model.ActionRenameTable, diff.Type) + require.Equal(t, 1, len(diff.AffectedOpts)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("tt2"), + ChildFKName: model.NewCIStr("fk_b"), + }, *tb1ReferredFKs[0]) + tbl2Info := getTableInfo(t, dom, "test2", "tt2") + tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test2", "tt2") + require.Equal(t, 0, len(tb2ReferredFKs)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys)) + require.Equal(t, model.FKInfo{ + ID: 1, + Name: model.NewCIStr("fk_b"), + RefSchema: model.NewCIStr("test3"), + RefTable: model.NewCIStr("tt1"), + RefCols: []model.CIStr{model.NewCIStr("id")}, + Cols: []model.CIStr{model.NewCIStr("b")}, + State: model.StatePublic, + Version: 1, + }, *tbl2Info.ForeignKeys[0]) + tk.MustQuery("show create table test2.tt2").Check(testkit.Rows("tt2 CREATE TABLE `tt2` (\n" + + " `id` int(11) NOT NULL,\n" + + " `b` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `fk_b` (`b`),\n" + + " CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test3`.`tt1` (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) +} + +func TestCreateTableWithForeignKeyDML(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int);") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1)") + tk.MustExec("update t1 set a = 2 where id = 1") + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id))") + + tk.MustExec("commit") +} + +func TestCreateTableWithForeignKeyError(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("use test") + + cases := []struct { + prepare []string + refer string + create string + err string + }{ + { + refer: "create table t1 (id int, a int, b int);", + create: "create table t2 (a int, b int, foreign key fk_b(b) references T_unknown(b));", + err: "[schema:1824]Failed to open the referenced table 'T_unknown'", + }, + { + refer: "create table t1 (id int, a int, b int);", + create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(c_unknown));", + err: "[schema:3734]Failed to add the foreign key constraint. Missing column 'c_unknown' for constraint 'fk_b' in the referenced table 't1'", + }, + { + refer: "create table t1 (id int key, a int, b int);", + create: "create table t2 (a int, b int, foreign key fk(c_unknown) references t1(id));", + err: "[ddl:1072]Key column 'c_unknown' doesn't exist in table", + }, + { + refer: "create table t1 (id int, a int, b int);", + create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", + }, + { + refer: "create table t1 (id int, a int, b int not null, index(b));", + create: "create table t2 (a int, b int not null, foreign key fk_b(b) references t1(b) on update set null);", + err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", + }, + { + refer: "create table t1 (id int, a int, b int not null, index(b));", + create: "create table t2 (a int, b int not null, foreign key fk_b(b) references t1(b) on delete set null);", + err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", + }, + { + refer: "create table t1 (id int key, a int, b int as (a) virtual, index(b));", + create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", + err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", + }, + { + refer: "create table t1 (id int key, a int, b int, index(b));", + create: "create table t2 (a int, b int as (a) virtual, foreign key fk_b(b) references t1(b));", + err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", + }, + { + refer: "create table t1 (id int key, a int);", + create: "create table t2 (a int, b varchar(10), foreign key fk(b) references t1(id));", + err: "[ddl:3780]Referencing column 'b' and referenced column 'id' in foreign key constraint 'fk' are incompatible.", + }, + { + refer: "create table t1 (id int key, a int not null, index(a));", + create: "create table t2 (a int, b int unsigned, foreign key fk_b(b) references t1(a));", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + refer: "create table t1 (id int key, a bigint, index(a));", + create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(a));", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + refer: "create table t1 (id int key, a varchar(10) charset utf8, index(a));", + create: "create table t2 (a int, b varchar(10) charset utf8mb4, foreign key fk_b(b) references t1(a));", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + refer: "create table t1 (id int key, a varchar(10) collate utf8_bin, index(a));", + create: "create table t2 (a int, b varchar(10) collate utf8mb4_bin, foreign key fk_b(b) references t1(a));", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + refer: "create table t1 (id int key, a varchar(10));", + create: "create table t2 (a int, b varchar(10), foreign key fk_b(b) references t1(a));", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", + }, + { + refer: "create table t1 (id int key, a varchar(10), index (a(5)));", + create: "create table t2 (a int, b varchar(10), foreign key fk_b(b) references t1(a));", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", + }, + { + refer: "create table t1 (id int key, a int, index(a));", + create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(id, a));", + err: "[schema:1239]Incorrect foreign key definition for 'fk_b': Key reference and table reference don't match", + }, + { + create: "create table t2 (a int key, foreign key (a) references t2(a));", + err: "[schema:1215]Cannot add foreign key constraint", + }, + { + create: "create table t2 (a int, b int, index(a,b), index(b,a), foreign key (a,b) references t2(a,b));", + err: "[schema:1215]Cannot add foreign key constraint", + }, + { + create: "create table t2 (a int, b int, index(a,b), foreign key (a,b) references t2(b,a));", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_1' in the referenced table 't2'", + }, + { + prepare: []string{ + "set @@foreign_key_checks=0;", + "create table t2 (a int, b int, index(a), foreign key (a) references t1(id));", + }, + create: "create table t1 (id int, a int);", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_1' in the referenced table 't1'", + }, + { + prepare: []string{ + "set @@foreign_key_checks=0;", + "create table t2 (a int, b int, index(a), foreign key (a) references t1(id));", + }, + create: "create table t1 (id bigint key, a int);", + err: "[ddl:3780]Referencing column 'a' and referenced column 'id' in foreign key constraint 'fk_1' are incompatible.", + }, + { + // foreign key is not support in temporary table. + refer: "create temporary table t1 (id int key, b int, index(b))", + create: "create table t2 (a int, b int, foreign key fk(b) references t1(b))", + err: "[schema:1824]Failed to open the referenced table 't1'", + }, + { + // foreign key is not support in temporary table. + refer: "create global temporary table t1 (id int key, b int, index(b)) on commit delete rows", + create: "create table t2 (a int, b int, foreign key fk(b) references t1(b))", + err: "[schema:1215]Cannot add foreign key constraint", + }, + { + // foreign key is not support in temporary table. + refer: "create table t1 (id int key, b int, index(b))", + create: "create temporary table t2 (a int, b int, foreign key fk(b) references t1(b))", + err: "[schema:1215]Cannot add foreign key constraint", + }, + { + // foreign key is not support in temporary table. + refer: "create table t1 (id int key, b int, index(b))", + create: "create global temporary table t2 (a int, b int, foreign key fk(b) references t1(b)) on commit delete rows", + err: "[schema:1215]Cannot add foreign key constraint", + }, + { + create: "create table t1 (a int, foreign key ``(a) references t1(a));", + err: "[ddl:1280]Incorrect index name ''", + }, + { + create: "create table t1 (a int, constraint `` foreign key (a) references t1(a));", + err: "[ddl:1280]Incorrect index name ''", + }, + { + create: "create table t1 (a int, constraint `fk` foreign key (a,a) references t1(a, b));", + err: "[schema:1060]Duplicate column name 'a'", + }, + { + refer: "create table t1(a int, b int, index(a,b));", + create: "create table t2 (a int, b int, foreign key (a,b) references t1(a,a));", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_1' in the referenced table 't1'", + }, + { + refer: "create table t1 (id int key, b int, index(b))", + create: "create table t2 (a int, b int, index fk_1(a), foreign key (b) references t1(b));", + err: "[ddl:1061]duplicate key name fk_1", + }, + { + refer: "create table t1 (id int key);", + create: "create table t2 (id int key, foreign key name5678901234567890123456789012345678901234567890123456789012345(id) references t1(id));", + err: "[ddl:1059]Identifier name 'name5678901234567890123456789012345678901234567890123456789012345' is too long", + }, + { + refer: "create table t1 (id int key);", + create: "create table t2 (id int key, constraint name5678901234567890123456789012345678901234567890123456789012345 foreign key (id) references t1(id));", + err: "[ddl:1059]Identifier name 'name5678901234567890123456789012345678901234567890123456789012345' is too long", + }, + { + create: "create table t2 (id int key, constraint fk foreign key (id) references name5678901234567890123456789012345678901234567890123456789012345.t1(id));", + err: "[ddl:1059]Identifier name 'name5678901234567890123456789012345678901234567890123456789012345' is too long", + }, + { + prepare: []string{ + "set @@foreign_key_checks=0;", + }, + create: "create table t2 (id int key, constraint fk foreign key (id) references name5678901234567890123456789012345678901234567890123456789012345(id));", + err: "[ddl:1059]Identifier name 'name5678901234567890123456789012345678901234567890123456789012345' is too long", + }, + { + prepare: []string{ + "set @@foreign_key_checks=0;", + }, + create: "create table t2 (id int key, constraint fk foreign key (id) references t1(name5678901234567890123456789012345678901234567890123456789012345));", + err: "[ddl:1059]Identifier name 'name5678901234567890123456789012345678901234567890123456789012345' is too long", + }, + // Test foreign key with temporary table + { + refer: "create temporary table t1 (id int key);", + create: "create table t2 (id int key, constraint fk foreign key (id) references t1(id));", + err: "[schema:1824]Failed to open the referenced table 't1'", + }, + { + refer: "create table t1 (id int key);", + create: "create temporary table t2 (id int key, constraint fk foreign key (id) references t1(id));", + err: "[schema:1215]Cannot add foreign key constraint", + }, + // Test foreign key with partition table + { + refer: "create table t1 (id int key) partition by hash(id) partitions 3;", + create: "create table t2 (id int key, constraint fk foreign key (id) references t1(id));", + err: "[schema:1506]Foreign key clause is not yet supported in conjunction with partitioning", + }, + { + refer: "create table t1 (id int key);", + create: "create table t2 (id int key, constraint fk foreign key (id) references t1(id)) partition by hash(id) partitions 3;", + err: "[schema:1506]Foreign key clause is not yet supported in conjunction with partitioning", + }, + } + for _, ca := range cases { + tk.MustExec("drop table if exists t2") + tk.MustExec("drop table if exists t1") + tk.MustExec("set @@foreign_key_checks=1") + for _, sql := range ca.prepare { + tk.MustExec(sql) + } + if ca.refer != "" { + tk.MustExec(ca.refer) + } + err := tk.ExecToErr(ca.create) + require.Error(t, err, ca.create) + require.Equal(t, ca.err, err.Error(), ca.create) + } + + passCases := [][]string{ + { + "create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))", + }, + { + "create table t1 (id int key, b int not null, index(b))", + "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", + }, + { + "create table t1 (id int key, a varchar(10), index(a));", + "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", + }, + { + "create table t1 (id int key, a decimal(10,5), index(a));", + "create table t2 (a int, b decimal(20, 10), foreign key fk_b(b) references t1(a));", + }, + { + "create table t1 (id int key, a varchar(10), index (a(10)));", + "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", + }, + { + "set @@foreign_key_checks=0;", + "create table t2 (a int, b int, foreign key fk_b(b) references t_unknown(b));", + "set @@foreign_key_checks=1;", + }, + { + "create table t2 (a int, b int, index(a,b), index(b,a), foreign key (a,b) references t2(b,a));", + }, + { + "create table t1 (a int key, b int, index(b))", + "create table t2 (a int, b int, foreign key (a) references t1(a), foreign key (b) references t1(b));", + }, + { + "create table t1 (id int key);", + "create table t2 (id int key, foreign key name567890123456789012345678901234567890123456789012345678901234(id) references t1(id));", + }, + } + for _, ca := range passCases { + tk.MustExec("drop table if exists t2") + tk.MustExec("drop table if exists t1") + for _, sql := range ca { + tk.MustExec(sql) + } + } +} + +func TestModifyColumnWithForeignKey(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + + tk.MustExec("create table t1 (id int key, b varchar(10), index(b));") + tk.MustExec("create table t2 (a varchar(10), constraint fk foreign key (a) references t1(b));") + tk.MustExec("insert into t1 values (1, '123456789');") + tk.MustExec("insert into t2 values ('123456789');") + tk.MustGetErrMsg("alter table t1 modify column b varchar(5);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") + tk.MustGetErrMsg("alter table t1 modify column b bigint;", "[ddl:3780]Referencing column 'a' and referenced column 'b' in foreign key constraint 'fk' are incompatible.") + tk.MustExec("alter table t1 modify column b varchar(20);") + tk.MustGetErrMsg("alter table t1 modify column b varchar(10);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") + tk.MustExec("alter table t2 modify column a varchar(20);") + tk.MustExec("alter table t2 modify column a varchar(21);") + tk.MustGetErrMsg("alter table t2 modify column a varchar(5);", "[ddl:1832]Cannot change column 'a': used in a foreign key constraint 'fk'") + tk.MustGetErrMsg("alter table t2 modify column a bigint;", "[ddl:3780]Referencing column 'a' and referenced column 'b' in foreign key constraint 'fk' are incompatible.") + + tk.MustExec("drop table t2") + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id int key, b decimal(10, 5), index(b));") + tk.MustExec("create table t2 (a decimal(10, 5), constraint fk foreign key (a) references t1(b));") + tk.MustExec("insert into t1 values (1, 12345.67891);") + tk.MustExec("insert into t2 values (12345.67891);") + tk.MustGetErrMsg("alter table t1 modify column b decimal(10, 6);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") + tk.MustGetErrMsg("alter table t1 modify column b decimal(10, 3);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") + tk.MustGetErrMsg("alter table t1 modify column b decimal(5, 2);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") + tk.MustGetErrMsg("alter table t1 modify column b decimal(20, 10);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") + tk.MustGetErrMsg("alter table t2 modify column a decimal(30, 15);", "[ddl:1832]Cannot change column 'a': used in a foreign key constraint 'fk'") + tk.MustGetErrMsg("alter table t2 modify column a decimal(5, 2);", "[ddl:1832]Cannot change column 'a': used in a foreign key constraint 'fk'") +} + +func TestDropChildTableForeignKeyMetaInfo(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int, b int, CONSTRAINT fk foreign key (a) references t1(id))") + tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + tk.MustExec("drop table t1") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 0, len(tb1ReferredFKs)) + + tk.MustExec("create table t1 (id int key, b int, index(b))") + tk.MustExec("create table t2 (a int, b int, foreign key fk (a) references t1(b));") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + tk.MustExec("drop table t2") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 0, len(tb1ReferredFKs)) +} + +func TestDropForeignKeyMetaInfo(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int, b int, CONSTRAINT fk foreign key (a) references t1(id))") + tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + tk.MustExec("alter table t1 drop foreign key fk") + tbl1Info := getTableInfo(t, dom, "test", "t1") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 0, len(tbl1Info.ForeignKeys)) + require.Equal(t, 0, len(tb1ReferredFKs)) + + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id int key, b int, index(b))") + tk.MustExec("create table t2 (a int, b int, foreign key fk (a) references t1(b));") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + tk.MustExec("alter table t2 drop foreign key fk") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 0, len(tb1ReferredFKs)) + tbl2Info := getTableInfo(t, dom, "test", "t2") + require.Equal(t, 0, len(tbl2Info.ForeignKeys)) +} + +func TestTruncateOrDropTableWithForeignKeyReferred(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("use test") + + cases := []struct { + prepares []string + tbl string + truncateErr string + dropErr string + }{ + { + prepares: []string{ + "create table t1 (id int key, b int not null, index(b))", + "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", + }, + tbl: "t1", + truncateErr: "[ddl:1701]Cannot truncate a table referenced in a foreign key constraint (`test`.`t2` CONSTRAINT `fk_b`)", + dropErr: "[ddl:3730]Cannot drop table 't1' referenced by a foreign key constraint 'fk_b' on table 't2'.", + }, + { + prepares: []string{ + "create table t1 (id int key, a varchar(10), index(a));", + "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", + }, + tbl: "t1", + truncateErr: "[ddl:1701]Cannot truncate a table referenced in a foreign key constraint (`test`.`t2` CONSTRAINT `fk_b`)", + dropErr: "[ddl:3730]Cannot drop table 't1' referenced by a foreign key constraint 'fk_b' on table 't2'.", + }, + { + prepares: []string{ + "create table t1 (id int key, a varchar(10), index (a(10)));", + "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", + }, + tbl: "t1", + truncateErr: "[ddl:1701]Cannot truncate a table referenced in a foreign key constraint (`test`.`t2` CONSTRAINT `fk_b`)", + dropErr: "[ddl:3730]Cannot drop table 't1' referenced by a foreign key constraint 'fk_b' on table 't2'.", + }, + } + + for _, ca := range cases { + tk.MustExec("drop table if exists t2") + tk.MustExec("drop table if exists t1") + for _, sql := range ca.prepares { + tk.MustExec(sql) + } + truncateSQL := fmt.Sprintf("truncate table %v", ca.tbl) + tk.MustExec("set @@foreign_key_checks=1;") + err := tk.ExecToErr(truncateSQL) + require.Error(t, err) + require.Equal(t, ca.truncateErr, err.Error()) + dropSQL := fmt.Sprintf("drop table %v", ca.tbl) + err = tk.ExecToErr(dropSQL) + require.Error(t, err) + require.Equal(t, ca.dropErr, err.Error()) + + tk.MustExec("set @@foreign_key_checks=0;") + tk.MustExec(truncateSQL) + } + passCases := [][]string{ + { + "create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))", + "truncate table t1", + "drop table t1", + }, + { + "create table t1 (id int key, a varchar(10), index (a(10)));", + "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", + "drop table t1, t2", + }, + { + "set @@foreign_key_checks=0;", + "create table t1 (id int key, a varchar(10), index (a(10)));", + "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", + "truncate table t1", + "drop table t1", + }, + } + for _, ca := range passCases { + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("set @@foreign_key_checks=1;") + for _, sql := range ca { + tk.MustExec(sql) + } + } +} + +func TestDropTableWithForeignKeyReferred(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + + tk.MustExec("create table t1 (id int key, b int, index(b));") + tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references t1(id));") + tk.MustExec("create table t3 (id int key, b int, foreign key fk_b(b) references t2(id));") + err := tk.ExecToErr("drop table if exists t1,t2;") + require.Error(t, err) + require.Equal(t, "[ddl:3730]Cannot drop table 't2' referenced by a foreign key constraint 'fk_b' on table 't3'.", err.Error()) + tk.MustQuery("show tables").Check(testkit.Rows("t1", "t2", "t3")) +} + +func TestDropIndexNeededInForeignKey(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + cases := []struct { + prepares []string + drops []string + err string + }{ + { + prepares: []string{ + "create table t1 (id int key, b int, index idx (b))", + "create table t2 (a int, b int, index idx (b), foreign key fk_b(b) references t1(b));", + }, + drops: []string{ + "alter table t1 drop index idx", + "alter table t2 drop index idx", + }, + err: "[ddl:1553]Cannot drop index 'idx': needed in a foreign key constraint", + }, + { + prepares: []string{ + "create table t1 (id int, b int, index idx (id, b))", + "create table t2 (a int, b int, index idx (b, a), foreign key fk_b(b) references t1(id));", + }, + drops: []string{ + "alter table t1 drop index idx", + "alter table t2 drop index idx", + }, + err: "[ddl:1553]Cannot drop index 'idx': needed in a foreign key constraint", + }, + } + + for _, ca := range cases { + tk.MustExec("drop table if exists t2") + tk.MustExec("drop table if exists t1") + for _, sql := range ca.prepares { + tk.MustExec(sql) + } + for _, drop := range ca.drops { + // even disable foreign key check, still can't drop the index used by foreign key. + tk.MustExec("set @@foreign_key_checks=0;") + err := tk.ExecToErr(drop) + require.Error(t, err) + require.Equal(t, ca.err, err.Error()) + tk.MustExec("set @@foreign_key_checks=1;") + err = tk.ExecToErr(drop) + require.Error(t, err) + require.Equal(t, ca.err, err.Error()) + } + } + passCases := [][]string{ + { + "create table t1 (id int key, b int, index idxb (b))", + "create table t2 (a int, b int key, index idxa (a),index idxb (b), foreign key fk_b(b) references t1(id));", + "alter table t1 drop index idxb", + "alter table t2 drop index idxa", + "alter table t2 drop index idxb", + }, + { + "create table t1 (id int key, b int, index idxb (b), unique index idx(b, id))", + "create table t2 (a int, b int key, index idx (b, a),index idxb (b), index idxab(a, b), foreign key fk_b(b) references t1(b));", + "alter table t1 drop index idxb", + "alter table t1 add index idxb (b)", + "alter table t1 drop index idx", + "alter table t2 drop index idx", + "alter table t2 add index idx (b, a)", + "alter table t2 drop index idxb", + "alter table t2 drop index idxab", + }, + } + tk.MustExec("set @@foreign_key_checks=1;") + for _, ca := range passCases { + tk.MustExec("drop table if exists t2") + tk.MustExec("drop table if exists t1") + for _, sql := range ca { + tk.MustExec(sql) + } + } +} + +func getTableInfo(t *testing.T, dom *domain.Domain, db, tb string) *model.TableInfo { + err := dom.Reload() + require.NoError(t, err) + is := dom.InfoSchema() + tbl, err := is.TableByName(model.NewCIStr(db), model.NewCIStr(tb)) + require.NoError(t, err) + _, exist := is.TableByID(tbl.Meta().ID) + require.True(t, exist) + return tbl.Meta() +} + +func getTableInfoReferredForeignKeys(t *testing.T, dom *domain.Domain, db, tb string) []*model.ReferredFKInfo { + err := dom.Reload() + require.NoError(t, err) + return dom.InfoSchema().GetTableReferredForeignKeys(db, tb) +} + +func TestDropColumnWithForeignKey(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + + tk.MustExec("create table t1 (id int key, a int, b int, index(b), CONSTRAINT fk foreign key (a) references t1(b))") + tk.MustGetErrMsg("alter table t1 drop column a;", "[ddl:1828]Cannot drop column 'a': needed in a foreign key constraint 'fk'") + tk.MustGetErrMsg("alter table t1 drop column b;", "[ddl:1829]Cannot drop column 'b': needed in a foreign key constraint 'fk' of table 't1'") + + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id int key, b int, index(b));") + tk.MustExec("create table t2 (a int, b int, constraint fk foreign key (a) references t1(b));") + tk.MustGetErrMsg("alter table t1 drop column b;", "[ddl:1829]Cannot drop column 'b': needed in a foreign key constraint 'fk' of table 't2'") + tk.MustGetErrMsg("alter table t2 drop column a;", "[ddl:1828]Cannot drop column 'a': needed in a foreign key constraint 'fk'") +} + +func TestRenameColumnWithForeignKeyMetaInfo(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + + tk.MustExec("create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))") + tk.MustExec("alter table t1 change id kid int") + tk.MustExec("alter table t1 rename column a to aa") + tbl1Info := getTableInfo(t, dom, "test", "t1") + tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tbl1Info.ForeignKeys)) + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, "kid", tb1ReferredFKs[0].Cols[0].L) + require.Equal(t, "kid", tbl1Info.ForeignKeys[0].RefCols[0].L) + require.Equal(t, "aa", tbl1Info.ForeignKeys[0].Cols[0].L) + + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id int key, b int, index(b))") + tk.MustExec("create table t2 (a int, b int, foreign key fk(a) references t1(b));") + tk.MustExec("alter table t2 change a aa int") + tbl1Info = getTableInfo(t, dom, "test", "t1") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) + require.Equal(t, "b", tb1ReferredFKs[0].Cols[0].L) + tbl2Info := getTableInfo(t, dom, "test", "t2") + tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t2") + require.Equal(t, 0, len(tb2ReferredFKs)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].Cols)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].RefCols)) + require.Equal(t, "aa", tbl2Info.ForeignKeys[0].Cols[0].L) + require.Equal(t, "b", tbl2Info.ForeignKeys[0].RefCols[0].L) + + tk.MustExec("alter table t1 change id kid int") + tk.MustExec("alter table t1 change b bb int") + tbl1Info = getTableInfo(t, dom, "test", "t1") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 1, len(tb1ReferredFKs)) + require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) + require.Equal(t, "bb", tb1ReferredFKs[0].Cols[0].L) + tbl2Info = getTableInfo(t, dom, "test", "t2") + tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t2") + require.Equal(t, 0, len(tb2ReferredFKs)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].Cols)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].RefCols)) + require.Equal(t, "aa", tbl2Info.ForeignKeys[0].Cols[0].L) + require.Equal(t, "bb", tbl2Info.ForeignKeys[0].RefCols[0].L) + + tk.MustExec("drop table t1, t2") + tk.MustExec("create table t1 (id int key, b int, index(b))") + tk.MustExec("create table t2 (a int, b int, foreign key (a) references t1(b), foreign key (b) references t1(b));") + tk.MustExec("alter table t1 change b bb int") + tbl1Info = getTableInfo(t, dom, "test", "t1") + tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") + require.Equal(t, 2, len(tb1ReferredFKs)) + require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) + require.Equal(t, 1, len(tb1ReferredFKs[1].Cols)) + require.Equal(t, "bb", tb1ReferredFKs[0].Cols[0].L) + require.Equal(t, "bb", tb1ReferredFKs[1].Cols[0].L) + tbl2Info = getTableInfo(t, dom, "test", "t2") + tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t2") + require.Equal(t, 0, len(tb2ReferredFKs)) + require.Equal(t, 2, len(tbl2Info.ForeignKeys)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].Cols)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].RefCols)) + require.Equal(t, "a", tbl2Info.ForeignKeys[0].Cols[0].L) + require.Equal(t, "bb", tbl2Info.ForeignKeys[0].RefCols[0].L) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[1].Cols)) + require.Equal(t, 1, len(tbl2Info.ForeignKeys[1].RefCols)) + require.Equal(t, "b", tbl2Info.ForeignKeys[1].Cols[0].L) + require.Equal(t, "bb", tbl2Info.ForeignKeys[1].RefCols[0].L) + tk.MustExec("alter table t2 rename column a to aa") + tk.MustExec("alter table t2 change b bb int") + tk.MustQuery("show create table t2"). + Check(testkit.Rows("t2 CREATE TABLE `t2` (\n" + + " `aa` int(11) DEFAULT NULL,\n" + + " `bb` int(11) DEFAULT NULL,\n" + + " KEY `fk_1` (`aa`),\n KEY `fk_2` (`bb`),\n" + + " CONSTRAINT `fk_1` FOREIGN KEY (`aa`) REFERENCES `test`.`t1` (`bb`),\n" + + " CONSTRAINT `fk_2` FOREIGN KEY (`bb`) REFERENCES `test`.`t1` (`bb`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) +} + +func TestDropDatabaseWithForeignKeyReferred(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + + tk.MustExec("create table t1 (id int key, b int, index(b));") + tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references t1(id));") + tk.MustExec("create database test2") + tk.MustExec("create table test2.t3 (id int key, b int, foreign key fk_b(b) references test.t2(id));") + err := tk.ExecToErr("drop database test;") + require.Error(t, err) + require.Equal(t, "[ddl:3730]Cannot drop table 't2' referenced by a foreign key constraint 'fk_b' on table 't3'.", err.Error()) + tk.MustExec("set @@foreign_key_checks=0;") + tk.MustExec("drop database test") + + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("create database test") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, b int, index(b));") + tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references t1(id));") + err = tk.ExecToErr("drop database test;") + require.Error(t, err) + require.Equal(t, "[ddl:3730]Cannot drop table 't2' referenced by a foreign key constraint 'fk_b' on table 't3'.", err.Error()) + tk.MustExec("drop table test2.t3") + tk.MustExec("drop database test") +} + +func TestAddForeignKey(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, b int);") + tk.MustExec("create table t2 (id int key, b int);") + tk.MustExec("alter table t2 add index(b)") + tk.MustExec("alter table t2 add foreign key (b) references t1(id);") + tbl2Info := getTableInfo(t, dom, "test", "t2") + require.Equal(t, int64(1), tbl2Info.MaxForeignKeyID) + tk.MustGetDBError("alter table t2 add foreign key (b) references t1(b);", infoschema.ErrForeignKeyNoIndexInParent) + tk.MustExec("alter table t1 add index(b)") + tk.MustExec("alter table t2 add foreign key (b) references t1(b);") + tk.MustGetDBError("alter table t2 add foreign key (b) references t2(b);", infoschema.ErrCannotAddForeign) + // Test auto-create index when create foreign key constraint. + tk.MustExec("drop table if exists t1,t2") + tk.MustExec("create table t1 (id int key, b int, index(b));") + tk.MustExec("create table t2 (id int key, b int);") + tk.MustExec("alter table t2 add constraint fk foreign key (b) references t1(b);") + tbl2Info = getTableInfo(t, dom, "test", "t2") + require.Equal(t, 1, len(tbl2Info.Indices)) + require.Equal(t, "fk", tbl2Info.Indices[0].Name.L) + require.Equal(t, model.StatePublic, tbl2Info.Indices[0].State) + tk.MustQuery("select b from t2 use index(fk)").Check(testkit.Rows()) + res := tk.MustQuery("explain select b from t2 use index(fk)") + plan := bytes.NewBuffer(nil) + rows := res.Rows() + for _, row := range rows { + for _, c := range row { + plan.WriteString(c.(string)) + plan.WriteString(" ") + } + } + require.Regexp(t, ".*IndexReader.*index:fk.*", plan.String()) + + // Test add multiple foreign key constraint in one statement. + tk.MustExec("alter table t2 add column c int, add column d int, add column e int;") + tk.MustExec("alter table t2 add index idx_c(c, d, e)") + tk.MustExec("alter table t2 add constraint fk_c foreign key (c) references t1(b), " + + "add constraint fk_d foreign key (d) references t1(b)," + + "add constraint fk_e foreign key (e) references t1(b)") + tbl2Info = getTableInfo(t, dom, "test", "t2") + require.Equal(t, 4, len(tbl2Info.Indices)) + names := []string{"fk", "idx_c", "fk_d", "fk_e"} + for i, idx := range tbl2Info.Indices { + require.Equal(t, names[i], idx.Name.L) + require.Equal(t, model.StatePublic, idx.State) + } + names = []string{"fk", "fk_c", "fk_d", "fk_e"} + for i, fkInfo := range tbl2Info.ForeignKeys { + require.Equal(t, names[i], fkInfo.Name.L) + require.Equal(t, model.StatePublic, fkInfo.State) + } + tk.MustGetDBError("insert into t2 (id, b) values (1,1)", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("insert into t2 (id, c) values (1,1)", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("insert into t2 (id, d) values (1,1)", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("insert into t2 (id, e) values (1,1)", plannercore.ErrNoReferencedRow2) + + // Test add multiple foreign key constraint in one statement but failed. + tk.MustExec("alter table t2 drop foreign key fk") + tk.MustExec("alter table t2 drop foreign key fk_c") + tk.MustExec("alter table t2 drop foreign key fk_d") + tk.MustExec("alter table t2 drop foreign key fk_e") + tk.MustGetDBError("alter table t2 add constraint fk_c foreign key (c) references t1(b), "+ + "add constraint fk_d foreign key (d) references t1(b),"+ + "add constraint fk_e foreign key (e) references t1(unknown_col)", infoschema.ErrForeignKeyNoColumnInParent) + tbl2Info = getTableInfo(t, dom, "test", "t2") + require.Equal(t, 0, len(tbl2Info.ForeignKeys)) + tk.MustGetDBError("alter table t2 drop index idx_c, add constraint fk_c foreign key (c) references t1(b)", dbterror.ErrDropIndexNeededInForeignKey) + + // Test circular dependency add foreign key failed. + tk.MustExec("drop table if exists t1,t2") + tk.MustExec("create table t1 (id int key,a int, index(a));") + tk.MustExec("create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE);") + tk.MustExec("insert into t1 values (1,1);") + err := tk.ExecToErr("ALTER TABLE t1 ADD foreign key fk(a) references t2(id) ON DELETE CASCADE;") + require.Error(t, err) + require.Equal(t, "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `fk` FOREIGN KEY (`a`) REFERENCES `t2` (`id`) ON DELETE CASCADE)", err.Error()) + tbl1Info := getTableInfo(t, dom, "test", "t1") + require.Equal(t, 0, len(tbl1Info.ForeignKeys)) + referredFKs := dom.InfoSchema().GetTableReferredForeignKeys("test", "t2") + require.Equal(t, 0, len(referredFKs)) + tk.MustQuery("show create table t1").Check(testkit.Rows("t1 CREATE TABLE `t1` (\n" + + " `id` int(11) NOT NULL,\n" + + " `a` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `a` (`a`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + // Test add foreign key with auto-create index failed. + tk.MustExec("drop table if exists t1,t2") + tk.MustExec("create table t1 (id int key,a int);") + tk.MustExec("create table t2 (id int key);") + tk.MustExec("insert into t1 values (1,1);") + err = tk.ExecToErr("ALTER TABLE t1 ADD foreign key fk(a) references t2(id) ON DELETE CASCADE;") + require.Error(t, err) + require.Equal(t, "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `fk` FOREIGN KEY (`a`) REFERENCES `t2` (`id`) ON DELETE CASCADE)", err.Error()) + tbl1Info = getTableInfo(t, dom, "test", "t1") + require.Equal(t, 0, len(tbl1Info.ForeignKeys)) + referredFKs = dom.InfoSchema().GetTableReferredForeignKeys("test", "t2") + require.Equal(t, 0, len(referredFKs)) + tk.MustQuery("show create table t1").Check(testkit.Rows("t1 CREATE TABLE `t1` (\n" + + " `id` int(11) NOT NULL,\n" + + " `a` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) +} + +func TestAlterTableAddForeignKeyError(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + cases := []struct { + prepares []string + alter string + err string + }{ + { + prepares: []string{ + "create table t1 (id int, a int, b int);", + "create table t2 (a int, b int);", + }, + alter: "alter table t2 add foreign key fk(b) references t_unknown(id)", + err: "[schema:1824]Failed to open the referenced table 't_unknown'", + }, + { + prepares: []string{ + "create table t1 (id int, a int, b int);", + "create table t2 (a int, b int);", + }, + alter: "alter table t2 add foreign key fk(b) references t1(c_unknown)", + err: "[schema:3734]Failed to add the foreign key constraint. Missing column 'c_unknown' for constraint 'fk' in the referenced table 't1'", + }, + { + prepares: []string{ + "create table t1 (id int, a int, b int);", + "create table t2 (a int, b int);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(b)", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", + }, + { + prepares: []string{ + "create table t1 (id int, a int, b int not null, index(b));", + "create table t2 (a int, b int not null);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(b) on update set null", + err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", + }, + { + prepares: []string{ + "create table t1 (id int, a int, b int not null, index(b));", + "create table t2 (a int, b int not null);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(b) on delete set null", + err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", + }, + { + prepares: []string{ + "create table t1 (id int key, a int, b int as (a) virtual, index(b));", + "create table t2 (a int, b int);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(b)", + err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", + }, + { + prepares: []string{ + "create table t1 (id int key, a int, b int, index(b));", + "create table t2 (a int, b int as (a) virtual);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(b)", + err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", + }, + { + prepares: []string{ + "create table t1 (id int key, a int);", + "create table t2 (a int, b varchar(10));", + }, + alter: "alter table t2 add foreign key fk(b) references t1(id)", + err: "[ddl:3780]Referencing column 'b' and referenced column 'id' in foreign key constraint 'fk' are incompatible.", + }, + { + prepares: []string{ + "create table t1 (id int key, a int not null, index(a));", + "create table t2 (a int, b int unsigned);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(a)", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + prepares: []string{ + "create table t1 (id int key, a bigint, index(a));", + "create table t2 (a int, b int);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(a)", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + prepares: []string{ + "create table t1 (id int key, a varchar(10) charset utf8, index(a));", + "create table t2 (a int, b varchar(10) charset utf8mb4);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(a)", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + prepares: []string{ + "create table t1 (id int key, a varchar(10) collate utf8_bin, index(a));", + "create table t2 (a int, b varchar(10) collate utf8mb4_bin);", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(a)", + err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", + }, + { + prepares: []string{ + "create table t1 (id int key, a varchar(10));", + "create table t2 (a int, b varchar(10));", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(a)", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", + }, + { + prepares: []string{ + "create table t1 (id int key, a varchar(10), index (a(5)));", + "create table t2 (a int, b varchar(10));", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(a)", + err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", + }, + { + prepares: []string{ + "create table t1 (id int key, a int)", + "create table t2 (id int, b int, index(b))", + "insert into t2 values (1,1)", + }, + alter: "alter table t2 add foreign key fk_b(b) references t1(id)", + err: "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `t1` (`id`))", + }, + { + prepares: []string{ + "create table t1 (id int, a int, b int, index(a,b))", + "create table t2 (id int, a int, b int, index(a,b))", + "insert into t2 values (1, 1, null), (2, null, 1), (3, null, null), (4, 1, 1)", + }, + alter: "alter table t2 add foreign key fk_b(a, b) references t1(a, b)", + err: "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`a`, `b`) REFERENCES `t1` (`a`, `b`))", + }, + { + prepares: []string{ + "create table t1 (id int key);", + "create table t2 (a int, b int unique);", + }, + alter: "alter table t2 add foreign key name5678901234567890123456789012345678901234567890123456789012345(b) references t1(id)", + err: "[ddl:1059]Identifier name 'name5678901234567890123456789012345678901234567890123456789012345' is too long", + }, + { + prepares: []string{ + "create table t1 (id int key);", + "create table t2 (a int, b int unique);", + }, + alter: "alter table t2 add constraint name5678901234567890123456789012345678901234567890123456789012345 foreign key (b) references t1(id)", + err: "[ddl:1059]Identifier name 'name5678901234567890123456789012345678901234567890123456789012345' is too long", + }, + // Test foreign key with temporary table. + { + prepares: []string{ + "create temporary table t1 (id int key);", + "create table t2 (a int, b int unique);", + }, + alter: "alter table t2 add constraint fk foreign key (b) references t1(id)", + err: "[schema:1824]Failed to open the referenced table 't1'", + }, + { + prepares: []string{ + "create table t1 (id int key);", + "create temporary table t2 (a int, b int unique);", + }, + alter: "alter table t2 add constraint fk foreign key (b) references t1(id)", + err: "[ddl:8200]TiDB doesn't support ALTER TABLE for local temporary table", + }, + // Test foreign key with partition table + { + prepares: []string{ + "create table t1 (id int key) partition by hash(id) partitions 3;", + "create table t2 (id int key);", + }, + alter: "alter table t2 add constraint fk foreign key (id) references t1(id)", + err: "[schema:1506]Foreign key clause is not yet supported in conjunction with partitioning", + }, + { + prepares: []string{ + "create table t1 (id int key);", + "create table t2 (id int key) partition by hash(id) partitions 3;;", + }, + alter: "alter table t2 add constraint fk foreign key (id) references t1(id)", + err: "[schema:1506]Foreign key clause is not yet supported in conjunction with partitioning", + }, + } + for i, ca := range cases { + tk.MustExec("drop table if exists t2") + tk.MustExec("drop table if exists t1") + for _, sql := range ca.prepares { + tk.MustExec(sql) + } + err := tk.ExecToErr(ca.alter) + require.Error(t, err, fmt.Sprintf("%v, %v", i, ca.err)) + require.Equal(t, ca.err, err.Error()) + } + + passCases := [][]string{ + { + "create table t1 (id int key, a int, b int, index(a))", + "alter table t1 add foreign key fk(a) references t1(id)", + }, + { + "create table t1 (id int key, b int not null, index(b))", + "create table t2 (a int, b int, index(b));", + "alter table t2 add foreign key fk_b(b) references t1(b)", + }, + { + "create table t1 (id int key, a varchar(10), index(a));", + "create table t2 (a int, b varchar(20), index(b));", + "alter table t2 add foreign key fk_b(b) references t1(a)", + }, + { + "create table t1 (id int key, a decimal(10,5), index(a));", + "create table t2 (a int, b decimal(20, 10), index(b));", + "alter table t2 add foreign key fk_b(b) references t1(a)", + }, + { + "create table t1 (id int key, a varchar(10), index (a(10)));", + "create table t2 (a int, b varchar(20), index(b));", + "alter table t2 add foreign key fk_b(b) references t1(a)", + }, + { + "create table t1 (id int key, a int)", + "create table t2 (id int, b int, index(b))", + "insert into t2 values (1, null)", + "alter table t2 add foreign key fk_b(b) references t1(id)", + }, + { + "create table t1 (id int, a int, b int, index(a,b))", + "create table t2 (id int, a int, b int, index(a,b))", + "insert into t2 values (1, 1, null), (2, null, 1), (3, null, null)", + "alter table t2 add foreign key fk_b(a, b) references t1(a, b)", + }, + { + "set @@foreign_key_checks=0;", + "create table t1 (id int, a int, b int, index(a,b))", + "create table t2 (id int, a int, b int, index(a,b))", + "insert into t2 values (1, 1, 1)", + "alter table t2 add foreign key fk_b(a, b) references t1(a, b)", + "set @@foreign_key_checks=1;", + }, + { + "set @@foreign_key_checks=0;", + "create table t2 (a int, b int, index(b));", + "alter table t2 add foreign key fk_b(b) references t_unknown(a)", + "set @@foreign_key_checks=1;", + }, + { + "create table t1 (id int key);", + "create table t2 (a int, b int unique);", + "alter table t2 add foreign key name567890123456789012345678901234567890123456789012345678901234(b) references t1(id)", + }, + } + for _, ca := range passCases { + tk.MustExec("drop table if exists t2") + tk.MustExec("drop table if exists t1") + for _, sql := range ca { + tk.MustExec(sql) + } + } +} + +func TestRenameTablesWithForeignKey(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=0;") + tk.MustExec("create database test1") + tk.MustExec("create database test2") + tk.MustExec("use test") + tk.MustExec("create table t0 (id int key, b int);") + tk.MustExec("create table t1 (id int key, b int, index(b), foreign key fk(b) references t2(id));") + tk.MustExec("create table t2 (id int key, b int, index(b), foreign key fk(b) references t1(id));") + tk.MustExec("rename table test.t1 to test1.tt1, test.t2 to test2.tt2, test.t0 to test.tt0") + + // check the schema diff + diff := getLatestSchemaDiff(t, tk) + require.Equal(t, model.ActionRenameTables, diff.Type) + require.Equal(t, 3, len(diff.AffectedOpts)) + + // check referred foreign key information. + t1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") + t2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t2") + require.Equal(t, 0, len(t1ReferredFKs)) + require.Equal(t, 0, len(t2ReferredFKs)) + tt1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test1", "tt1") + tt2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "tt2") + require.Equal(t, 1, len(tt1ReferredFKs)) + require.Equal(t, 1, len(tt2ReferredFKs)) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test2"), + ChildTable: model.NewCIStr("tt2"), + ChildFKName: model.NewCIStr("fk"), + }, *tt1ReferredFKs[0]) + require.Equal(t, model.ReferredFKInfo{ + Cols: []model.CIStr{model.NewCIStr("id")}, + ChildSchema: model.NewCIStr("test1"), + ChildTable: model.NewCIStr("tt1"), + ChildFKName: model.NewCIStr("fk"), + }, *tt2ReferredFKs[0]) + + // check show create table information + tk.MustQuery("show create table test1.tt1").Check(testkit.Rows("tt1 CREATE TABLE `tt1` (\n" + + " `id` int(11) NOT NULL,\n" + + " `b` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `test2`.`tt2` (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + tk.MustQuery("show create table test2.tt2").Check(testkit.Rows("tt2 CREATE TABLE `tt2` (\n" + + " `id` int(11) NOT NULL,\n" + + " `b` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `b` (`b`),\n" + + " CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `test1`.`tt1` (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) +} + +func getLatestSchemaDiff(t *testing.T, tk *testkit.TestKit) *model.SchemaDiff { + ctx := tk.Session() + err := sessiontxn.NewTxn(context.Background(), ctx) + require.NoError(t, err) + txn, err := ctx.Txn(true) + require.NoError(t, err) + m := meta.NewMeta(txn) + ver, err := m.GetSchemaVersion() + require.NoError(t, err) + diff, err := m.GetSchemaDiff(ver) + require.NoError(t, err) + return diff +} + +func TestMultiSchemaAddForeignKey(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key);") + tk.MustExec("create table t2 (a int, b int);") + tk.MustExec("alter table t2 add foreign key (a) references t1(id), add foreign key (b) references t1(id)") + tk.MustExec("alter table t2 add column c int, add column d int") + tk.MustExec("alter table t2 add foreign key (c) references t1(id), add foreign key (d) references t1(id), add index(c), add index(d)") + tk.MustExec("drop table t2") + tk.MustExec("create table t2 (a int, b int, index idx1(a), index idx2(b));") + tk.MustGetErrMsg("alter table t2 drop index idx1, drop index idx2, add foreign key (a) references t1(id), add foreign key (b) references t1(id)", + "[ddl:1553]Cannot drop index 'idx1': needed in a foreign key constraint") + tk.MustExec("alter table t2 drop index idx1, drop index idx2") + tk.MustExec("alter table t2 add foreign key (a) references t1(id), add foreign key (b) references t1(id)") + tk.MustQuery("show create table t2").Check(testkit.Rows("t2 CREATE TABLE `t2` (\n" + + " `a` int(11) DEFAULT NULL,\n" + + " `b` int(11) DEFAULT NULL,\n" + + " KEY `fk_1` (`a`),\n" + + " KEY `fk_2` (`b`),\n" + + " CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`id`),\n" + + " CONSTRAINT `fk_2` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + tk.MustExec("drop table t2") + tk.MustExec("create table t2 (a int, b int, index idx0(a,b), index idx1(a), index idx2(b));") + tk.MustExec("alter table t2 drop index idx1, add foreign key (a) references t1(id), add foreign key (b) references t1(id)") +} + +func TestAddForeignKeyInBigTable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + tk.MustExec("create table employee (id bigint auto_increment key, pid bigint)") + tk.MustExec("insert into employee (id) values (1),(2),(3),(4),(5),(6),(7),(8)") + for i := 0; i < 14; i++ { + tk.MustExec("insert into employee (pid) select pid from employee") + } + tk.MustExec("update employee set pid=id-1 where id>1") + start := time.Now() + tk.MustExec("alter table employee add foreign key fk_1(pid) references employee(id)") + require.Less(t, time.Since(start), time.Minute) +} + +func TestForeignKeyWithCacheTable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + // Test foreign key refer cache table. + tk.MustExec("create table t1 (id int key);") + tk.MustExec("insert into t1 values (1),(2),(3),(4)") + tk.MustExec("alter table t1 cache;") + tk.MustExec("create table t2 (b int);") + tk.MustExec("alter table t2 add constraint fk foreign key (b) references t1(id) on delete cascade on update cascade") + tk.MustExec("insert into t2 values (1),(2),(3),(4)") + tk.MustGetDBError("insert into t2 values (5)", plannercore.ErrNoReferencedRow2) + tk.MustExec("update t1 set id = id+10 where id=1") + tk.MustExec("delete from t1 where id<10") + tk.MustQuery("select * from t1").Check(testkit.Rows("11")) + tk.MustQuery("select * from t2").Check(testkit.Rows("11")) + tk.MustExec("alter table t1 nocache;") + tk.MustExec("drop table t1,t2;") + + // Test add foreign key on cache table. + tk.MustExec("create table t1 (id int key);") + tk.MustExec("create table t2 (b int);") + tk.MustExec("alter table t2 add constraint fk foreign key (b) references t1(id) on delete cascade on update cascade") + tk.MustExec("alter table t2 cache;") + tk.MustExec("insert into t1 values (1),(2),(3),(4)") + tk.MustExec("insert into t2 values (1),(2),(3),(4)") + tk.MustGetDBError("insert into t2 values (5)", plannercore.ErrNoReferencedRow2) + tk.MustExec("update t1 set id = id+10 where id=1") + tk.MustExec("delete from t1 where id<10") + tk.MustQuery("select * from t1").Check(testkit.Rows("11")) + tk.MustQuery("select * from t2").Check(testkit.Rows("11")) + tk.MustExec("alter table t2 nocache;") + tk.MustExec("drop table t1,t2;") +} + +func TestForeignKeyAndConcurrentDDL(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + // Test foreign key refer cache table. + tk.MustExec("create table t1 (a int, b int, c int, index(a), index(b), index(c));") + tk.MustExec("create table t2 (a int, b int, c int, index(a), index(b), index(c));") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("set @@foreign_key_checks=1;") + tk2.MustExec("use test") + passCases := []struct { + prepare []string + ddl1 string + ddl2 string + }{ + { + ddl1: "alter table t2 add constraint fk_1 foreign key (a) references t1(a)", + ddl2: "alter table t2 add constraint fk_2 foreign key (b) references t1(b)", + }, + { + ddl1: "alter table t2 drop foreign key fk_1", + ddl2: "alter table t2 drop foreign key fk_2", + }, + { + prepare: []string{ + "alter table t2 drop index a", + }, + ddl1: "alter table t2 add index(a)", + ddl2: "alter table t2 add constraint fk_1 foreign key (a) references t1(a)", + }, + { + ddl1: "alter table t2 drop index c", + ddl2: "alter table t2 add constraint fk_2 foreign key (b) references t1(b)", + }, + } + for _, ca := range passCases { + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + tk.MustExec(ca.ddl1) + }() + go func() { + defer wg.Done() + tk2.MustExec(ca.ddl2) + }() + wg.Wait() + } + errorCases := []struct { + prepare []string + ddl1 string + err1 string + ddl2 string + err2 string + }{ + { + ddl1: "alter table t2 add constraint fk foreign key (a) references t1(a)", + err1: "[ddl:1826]Duplicate foreign key constraint name 'fk'", + ddl2: "alter table t2 add constraint fk foreign key (b) references t1(b)", + err2: "[ddl:1826]Duplicate foreign key constraint name 'fk'", + }, + { + prepare: []string{ + "alter table t2 add constraint fk_1 foreign key (a) references t1(a)", + }, + ddl1: "alter table t2 drop foreign key fk_1", + err1: "[schema:1091]Can't DROP 'fk_1'; check that column/key exists", + ddl2: "alter table t2 drop foreign key fk_1", + err2: "[schema:1091]Can't DROP 'fk_1'; check that column/key exists", + }, + { + ddl1: "alter table t2 drop index a", + err1: "[ddl:1553]Cannot drop index 'a': needed in a foreign key constraint", + ddl2: "alter table t2 add constraint fk_1 foreign key (a) references t1(a)", + err2: "[ddl:-1]Failed to add the foreign key constraint. Missing index for 'fk_1' foreign key columns in the table 't2'", + }, + } + tk.MustExec("drop table t1,t2") + tk.MustExec("create table t1 (a int, b int, c int, index(a), index(b), index(c));") + tk.MustExec("create table t2 (a int, b int, c int, index(a), index(b), index(c));") + for i, ca := range errorCases { + for _, sql := range ca.prepare { + tk.MustExec(sql) + } + var wg sync.WaitGroup + var err1, err2 error + wg.Add(2) + go func() { + defer wg.Done() + err1 = tk.ExecToErr(ca.ddl1) + }() + go func() { + defer wg.Done() + err2 = tk2.ExecToErr(ca.ddl2) + }() + wg.Wait() + if (err1 == nil && err2 == nil) || (err1 != nil && err2 != nil) { + require.Failf(t, "both ddl1 and ddl2 execute success, but expect 1 error", fmt.Sprintf("idx: %v, err1: %v, err2: %v", i, err1, err2)) + } + if err1 != nil { + require.Equal(t, ca.err1, err1.Error()) + } + if err2 != nil { + require.Equal(t, ca.err2, err2.Error()) + } + } +} + +func TestForeignKeyAndRenameIndex(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, b int, index idx1(b));") + tk.MustExec("create table t2 (id int key, b int, constraint fk foreign key (b) references t1(b));") + tk.MustExec("insert into t1 values (1,1),(2,2)") + tk.MustExec("insert into t2 values (1,1),(2,2)") + tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("delete from t1 where id=1", plannercore.ErrRowIsReferenced2) + tk.MustExec("alter table t1 rename index idx1 to idx2") + tk.MustExec("alter table t2 rename index fk to idx") + tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("delete from t1 where id=1", plannercore.ErrRowIsReferenced2) + tk.MustExec("alter table t2 drop foreign key fk") + tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete cascade on update cascade") + tk.MustExec("alter table t1 rename index idx2 to idx3") + tk.MustExec("alter table t2 rename index idx to idx0") + tk.MustExec("delete from t1 where id=1") + tk.MustQuery("select * from t1").Check(testkit.Rows("2 2")) + tk.MustQuery("select * from t2").Check(testkit.Rows("2 2")) + tk.MustExec("admin check table t1,t2") +} diff --git a/ddl/fktest/main_test.go b/ddl/fktest/main_test.go new file mode 100644 index 0000000000000..36f34049a9d03 --- /dev/null +++ b/ddl/fktest/main_test.go @@ -0,0 +1,56 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl_test + +import ( + "testing" + "time" + + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/ddl" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/meta/autoid" + "github.com/pingcap/tidb/testkit/testsetup" + "github.com/tikv/client-go/v2/tikv" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + testsetup.SetupForCommonTest() + tikv.EnableFailpoints() + + domain.SchemaOutOfDateRetryInterval.Store(50 * time.Millisecond) + domain.SchemaOutOfDateRetryTimes.Store(50) + + autoid.SetStep(5000) + ddl.RunInGoTest = true + + config.UpdateGlobal(func(conf *config.Config) { + conf.Instance.SlowThreshold = 10000 + conf.TiKVClient.AsyncCommit.SafeWindow = 0 + conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 + conf.Experimental.AllowsExpressionIndex = true + }) + + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + } + + goleak.VerifyTestMain(m, opts...) +} diff --git a/ddl/foreign_key.go b/ddl/foreign_key.go index b91c2ef18406c..1a06719cb404b 100644 --- a/ddl/foreign_key.go +++ b/ddl/foreign_key.go @@ -44,29 +44,50 @@ func (w *worker) onCreateForeignKey(d *ddlCtx, t *meta.Meta, job *model.Job) (ve job.State = model.JobStateCancelled return ver, errors.Trace(err) } - err = checkAddForeignKeyValidInOwner(w, d, t, job, job.SchemaName, tblInfo, &fkInfo, fkCheck) - if err != nil { - return ver, err + if job.IsRollingback() { + return dropForeignKey(d, t, job, tblInfo, fkInfo.Name) } - fkInfo.ID = allocateFKIndexID(tblInfo) - tblInfo.ForeignKeys = append(tblInfo.ForeignKeys, &fkInfo) - - originalState := fkInfo.State - switch fkInfo.State { + switch job.SchemaState { case model.StateNone: - // We just support record the foreign key, so we just make it public. - // none -> public - fkInfo.State = model.StatePublic - ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, originalState != fkInfo.State) + err = checkAddForeignKeyValidInOwner(d, t, job.SchemaName, tblInfo, &fkInfo, fkCheck) + if err != nil { + job.State = model.JobStateCancelled + return ver, err + } + fkInfo.State = model.StateWriteOnly + fkInfo.ID = allocateFKIndexID(tblInfo) + tblInfo.ForeignKeys = append(tblInfo.ForeignKeys, &fkInfo) + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + job.SchemaState = model.StateWriteOnly + return ver, nil + case model.StateWriteOnly: + err = checkForeignKeyConstrain(w, job.SchemaName, tblInfo.Name.L, &fkInfo, fkCheck) + if err != nil { + job.State = model.JobStateRollingback + return ver, err + } + tblInfo.ForeignKeys[len(tblInfo.ForeignKeys)-1].State = model.StateWriteReorganization + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + job.SchemaState = model.StateWriteReorganization + case model.StateWriteReorganization: + tblInfo.ForeignKeys[len(tblInfo.ForeignKeys)-1].State = model.StatePublic + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) if err != nil { return ver, errors.Trace(err) } // Finish this job. + job.SchemaState = model.StatePublic job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo) - return ver, nil default: return ver, dbterror.ErrInvalidDDLState.GenWithStack("foreign key", fkInfo.State) } + return ver, nil } func onDropForeignKey(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { @@ -76,29 +97,27 @@ func onDropForeignKey(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ err return ver, errors.Trace(err) } - var ( - fkName model.CIStr - found bool - fkInfo model.FKInfo - ) + var fkName model.CIStr err = job.DecodeArgs(&fkName) if err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } + return dropForeignKey(d, t, job, tblInfo, fkName) +} +func dropForeignKey(d *ddlCtx, t *meta.Meta, job *model.Job, tblInfo *model.TableInfo, fkName model.CIStr) (ver int64, err error) { + var fkInfo *model.FKInfo for _, fk := range tblInfo.ForeignKeys { if fk.Name.L == fkName.L { - found = true - fkInfo = *fk + fkInfo = fk + break } } - - if !found { + if fkInfo == nil { job.State = model.JobStateCancelled return ver, infoschema.ErrForeignKeyNotExists.GenWithStackByArgs(fkName) } - nfks := tblInfo.ForeignKeys[:0] for _, fk := range tblInfo.ForeignKeys { if fk.Name.L != fkName.L { @@ -106,24 +125,18 @@ func onDropForeignKey(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ err } } tblInfo.ForeignKeys = nfks - - originalState := fkInfo.State - switch fkInfo.State { - case model.StatePublic: - // We just support record the foreign key, so we just make it none. - // public -> none - fkInfo.State = model.StateNone - ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, originalState != fkInfo.State) - if err != nil { - return ver, errors.Trace(err) - } - // Finish this job. + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + // Finish this job. + if job.IsRollingback() { + job.FinishTableJob(model.JobStateRollbackDone, model.StateNone, ver, tblInfo) + } else { job.FinishTableJob(model.JobStateDone, model.StateNone, ver, tblInfo) - job.SchemaState = fkInfo.State - return ver, nil - default: - return ver, dbterror.ErrInvalidDDLState.GenWithStackByArgs("foreign key", fkInfo.State) } + job.SchemaState = model.StateNone + return ver, err } func allocateFKIndexID(tblInfo *model.TableInfo) int64 { @@ -250,6 +263,12 @@ func checkTableForeignKey(referTblInfo, tblInfo *model.TableInfo, fkInfo *model. if referTblInfo.TempTableType != model.TempTableNone || tblInfo.TempTableType != model.TempTableNone { return infoschema.ErrCannotAddForeign } + if referTblInfo.TTLInfo != nil { + return dbterror.ErrUnsupportedTTLReferencedByFK + } + if referTblInfo.GetPartitionInfo() != nil || tblInfo.GetPartitionInfo() != nil { + return infoschema.ErrForeignKeyOnPartitioned + } // check refer columns in parent table. for i := range fkInfo.RefCols { @@ -275,7 +294,7 @@ func checkTableForeignKey(referTblInfo, tblInfo *model.TableInfo, fkInfo *model. } } // check refer columns should have index. - if model.FindIndexByColumns(referTblInfo, fkInfo.RefCols...) == nil { + if model.FindIndexByColumns(referTblInfo, referTblInfo.Indices, fkInfo.RefCols...) == nil { return infoschema.ErrForeignKeyNoIndexInParent.GenWithStackByArgs(fkInfo.Name, fkInfo.RefTable) } return nil @@ -618,21 +637,10 @@ func checkAddForeignKeyValid(is infoschema.InfoSchema, schema string, tbInfo *mo if err != nil { return err } - if len(fk.Cols) == 1 && tbInfo.PKIsHandle { - pkCol := tbInfo.GetPkColInfo() - if pkCol != nil && pkCol.Name.L == fk.Cols[0].L { - return nil - } - } - // check foreign key columns should have index. - // TODO(crazycs520): we can remove this check after TiDB support auto create index if needed when add foreign key. - if model.FindIndexByColumns(tbInfo, fk.Cols...) == nil { - return errors.Errorf("Failed to add the foreign key constraint. Missing index for '%s' foreign key columns in the table '%s'", fk.Name, tbInfo.Name) - } return nil } -func checkAddForeignKeyValidInOwner(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job, schema string, tbInfo *model.TableInfo, fk *model.FKInfo, fkCheck bool) error { +func checkAddForeignKeyValidInOwner(d *ddlCtx, t *meta.Meta, schema string, tbInfo *model.TableInfo, fk *model.FKInfo, fkCheck bool) error { err := checkFKDupName(tbInfo, fk.Name) if err != nil { return err @@ -646,15 +654,17 @@ func checkAddForeignKeyValidInOwner(w *worker, d *ddlCtx, t *meta.Meta, job *mod } err = checkAddForeignKeyValid(is, schema, tbInfo, fk, fkCheck) if err != nil { - job.State = model.JobStateCancelled return errors.Trace(err) } - // TODO(crazycs520): fix me. we need to do multi-schema change when add foreign key constraint. - // Since after this check, DML can write data which break the foreign key constraint. - err = checkForeignKeyConstrain(w, schema, tbInfo.Name.L, fk, fkCheck) - if err != nil { - job.State = model.JobStateCancelled - return errors.Trace(err) + // check foreign key columns should have index. + if len(fk.Cols) == 1 && tbInfo.PKIsHandle { + pkCol := tbInfo.GetPkColInfo() + if pkCol != nil && pkCol.Name.L == fk.Cols[0].L { + return nil + } + } + if model.FindIndexByColumns(tbInfo, tbInfo.Indices, fk.Cols...) == nil { + return errors.Errorf("Failed to add the foreign key constraint. Missing index for '%s' foreign key columns in the table '%s'", fk.Name, tbInfo.Name) } return nil } @@ -667,7 +677,12 @@ func checkForeignKeyConstrain(w *worker, schema, table string, fkInfo *model.FKI if err != nil { return errors.Trace(err) } - defer w.sessPool.put(sctx) + originValue := sctx.GetSessionVars().OptimizerEnableNAAJ + sctx.GetSessionVars().OptimizerEnableNAAJ = true + defer func() { + sctx.GetSessionVars().OptimizerEnableNAAJ = originValue + w.sessPool.put(sctx) + }() var buf strings.Builder buf.WriteString("select 1 from %n.%n where ") @@ -702,7 +717,7 @@ func checkForeignKeyConstrain(w *worker, schema, table string, fkInfo *model.FKI } buf.WriteString(" from %n.%n ) limit 1") paramsList = append(paramsList, fkInfo.RefSchema.L, fkInfo.RefTable.L) - rows, _, err := sctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(w.ctx, nil, buf.String(), paramsList...) + rows, _, err := sctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(w.ctx, []sqlexec.OptionFuncAlias{sqlexec.ExecOptionUseCurSession}, buf.String(), paramsList...) if err != nil { return errors.Trace(err) } diff --git a/ddl/foreign_key_test.go b/ddl/foreign_key_test.go index cf22a487cd65b..627c924b21871 100644 --- a/ddl/foreign_key_test.go +++ b/ddl/foreign_key_test.go @@ -16,7 +16,6 @@ package ddl_test import ( "context" - "fmt" "strings" "sync" "testing" @@ -24,15 +23,12 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/ddl" - "github.com/pingcap/tidb/domain" - "github.com/pingcap/tidb/infoschema" - "github.com/pingcap/tidb/meta" - "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" ) @@ -112,7 +108,17 @@ func TestForeignKey(t *testing.T) { testCreateSchema(t, testkit.NewTestKit(t, store).Session(), dom.DDL(), dbInfo) tblInfo, err := testTableInfo(store, "t", 3) require.NoError(t, err) - + tblInfo.Indices = append(tblInfo.Indices, &model.IndexInfo{ + ID: 1, + Name: model.NewCIStr("idx_fk"), + Table: model.NewCIStr("t"), + Columns: []*model.IndexColumn{{ + Name: model.NewCIStr("c1"), + Offset: 0, + Length: types.UnspecifiedLength, + }}, + State: model.StatePublic, + }) testCreateTable(t, testkit.NewTestKit(t, store).Session(), d, dbInfo, tblInfo) // fix data race @@ -201,821 +207,6 @@ func TestForeignKey(t *testing.T) { require.NoError(t, err) } -func TestCreateTableWithForeignKeyMetaInfo(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int,b int as (a) virtual);") - tk.MustExec("create database test2") - tk.MustExec("use test2") - tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id) ON UPDATE RESTRICT ON DELETE CASCADE)") - tb1Info := getTableInfo(t, dom, "test", "t1") - tb2Info := getTableInfo(t, dom, "test2", "t2") - require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test", "t1"))) - require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) - require.Equal(t, 0, len(tb1Info.ForeignKeys)) - tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("t2"), - ChildFKName: model.NewCIStr("fk_b"), - }, *tb1ReferredFKs[0]) - tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t2") - require.Equal(t, 0, len(tb2ReferredFKs)) - require.Equal(t, 1, len(tb2Info.ForeignKeys)) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_b"), - RefSchema: model.NewCIStr("test"), - RefTable: model.NewCIStr("t1"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("b")}, - OnDelete: 2, - OnUpdate: 1, - State: model.StatePublic, - Version: 1, - }, *tb2Info.ForeignKeys[0]) - // Auto create index for foreign key usage. - require.Equal(t, 1, len(tb2Info.Indices)) - require.Equal(t, "fk_b", tb2Info.Indices[0].Name.L) - require.Equal(t, "`test2`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT", tb2Info.ForeignKeys[0].String("test2", "t2")) - - tk.MustExec("create table t3 (id int, b int, index idx_b(b), foreign key fk_b(b) references t2(id) ON UPDATE SET NULL ON DELETE NO ACTION)") - tb2Info = getTableInfo(t, dom, "test2", "t2") - tb3Info := getTableInfo(t, dom, "test2", "t3") - require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) - require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t3"))) - require.Equal(t, 1, len(tb2Info.ForeignKeys)) - tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test2", "t2") - require.Equal(t, 1, len(tb2ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("t3"), - ChildFKName: model.NewCIStr("fk_b"), - }, *tb2ReferredFKs[0]) - tb3ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t3") - require.Equal(t, 0, len(tb3ReferredFKs)) - require.Equal(t, 1, len(tb3Info.ForeignKeys)) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_b"), - RefSchema: model.NewCIStr("test2"), - RefTable: model.NewCIStr("t2"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("b")}, - OnDelete: 4, - OnUpdate: 3, - State: model.StatePublic, - Version: 1, - }, *tb3Info.ForeignKeys[0]) - require.Equal(t, 1, len(tb3Info.Indices)) - require.Equal(t, "idx_b", tb3Info.Indices[0].Name.L) - require.Equal(t, "`test2`.`t3`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `t2` (`id`) ON DELETE NO ACTION ON UPDATE SET NULL", tb3Info.ForeignKeys[0].String("test2", "t3")) - - tk.MustExec("create table t5 (id int key, a int, b int, foreign key (a) references t5(id));") - tb5Info := getTableInfo(t, dom, "test2", "t5") - require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t5"))) - require.Equal(t, 1, len(tb5Info.ForeignKeys)) - tb5ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t5") - require.Equal(t, 1, len(tb5ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("t5"), - ChildFKName: model.NewCIStr("fk_1"), - }, *tb5ReferredFKs[0]) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_1"), - RefSchema: model.NewCIStr("test2"), - RefTable: model.NewCIStr("t5"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("a")}, - State: model.StatePublic, - Version: 1, - }, *tb5Info.ForeignKeys[0]) - require.Equal(t, 1, len(tb5Info.Indices)) - require.Equal(t, "fk_1", tb5Info.Indices[0].Name.L) - require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test", "t1"))) - require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) - require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t3"))) - require.Equal(t, 1, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t5"))) - - tk.MustExec("set @@global.tidb_enable_foreign_key=0") - tk.MustExec("drop database test2") - require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t2"))) - require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t3"))) - require.Equal(t, 0, len(dom.InfoSchema().GetTableReferredForeignKeys("test2", "t5"))) -} - -func TestCreateTableWithForeignKeyMetaInfo2(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("create database test2") - tk.MustExec("set @@foreign_key_checks=0") - tk.MustExec("use test2") - tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id) ON UPDATE RESTRICT ON DELETE CASCADE)") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int, b int as (a) virtual);") - tb1Info := getTableInfo(t, dom, "test", "t1") - tb2Info := getTableInfo(t, dom, "test2", "t2") - require.Equal(t, 0, len(tb1Info.ForeignKeys)) - tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("t2"), - ChildFKName: model.NewCIStr("fk_b"), - }, *tb1ReferredFKs[0]) - tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t2") - require.Equal(t, 0, len(tb2ReferredFKs)) - require.Equal(t, 1, len(tb2Info.ForeignKeys)) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_b"), - RefSchema: model.NewCIStr("test"), - RefTable: model.NewCIStr("t1"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("b")}, - OnDelete: 2, - OnUpdate: 1, - State: model.StatePublic, - Version: 1, - }, *tb2Info.ForeignKeys[0]) - // Auto create index for foreign key usage. - require.Equal(t, 1, len(tb2Info.Indices)) - require.Equal(t, "fk_b", tb2Info.Indices[0].Name.L) - require.Equal(t, "`test2`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT", tb2Info.ForeignKeys[0].String("test2", "t2")) - - tk.MustExec("create table t3 (id int key, a int, foreign key fk_a(a) references test.t1(id) ON DELETE CASCADE ON UPDATE RESTRICT, foreign key fk_a2(a) references test2.t2(id))") - tb1Info = getTableInfo(t, dom, "test", "t1") - tb3Info := getTableInfo(t, dom, "test", "t3") - require.Equal(t, 0, len(tb1Info.ForeignKeys)) - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 2, len(tb1ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test"), - ChildTable: model.NewCIStr("t3"), - ChildFKName: model.NewCIStr("fk_a"), - }, *tb1ReferredFKs[0]) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("t2"), - ChildFKName: model.NewCIStr("fk_b"), - }, *tb1ReferredFKs[1]) - tb3ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t3") - require.Equal(t, 0, len(tb3ReferredFKs)) - require.Equal(t, 2, len(tb3Info.ForeignKeys)) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_a"), - RefSchema: model.NewCIStr("test"), - RefTable: model.NewCIStr("t1"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("a")}, - OnDelete: 2, - OnUpdate: 1, - State: model.StatePublic, - Version: 1, - }, *tb3Info.ForeignKeys[0]) - require.Equal(t, model.FKInfo{ - ID: 2, - Name: model.NewCIStr("fk_a2"), - RefSchema: model.NewCIStr("test2"), - RefTable: model.NewCIStr("t2"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("a")}, - State: model.StatePublic, - Version: 1, - }, *tb3Info.ForeignKeys[1]) - // Auto create index for foreign key usage. - require.Equal(t, 1, len(tb3Info.Indices)) - require.Equal(t, "fk_a", tb3Info.Indices[0].Name.L) - require.Equal(t, "`test`.`t3`, CONSTRAINT `fk_a` FOREIGN KEY (`a`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT", tb3Info.ForeignKeys[0].String("test", "t3")) - require.Equal(t, "`test`.`t3`, CONSTRAINT `fk_a2` FOREIGN KEY (`a`) REFERENCES `test2`.`t2` (`id`)", tb3Info.ForeignKeys[1].String("test", "t3")) - - tk.MustExec("set @@foreign_key_checks=0") - tk.MustExec("drop table test2.t2") - tb1Info = getTableInfo(t, dom, "test", "t1") - tb3Info = getTableInfo(t, dom, "test", "t3") - require.Equal(t, 0, len(tb1Info.ForeignKeys)) - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test"), - ChildTable: model.NewCIStr("t3"), - ChildFKName: model.NewCIStr("fk_a"), - }, *tb1ReferredFKs[0]) - tb3ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t3") - require.Equal(t, 0, len(tb3ReferredFKs)) - require.Equal(t, 2, len(tb3Info.ForeignKeys)) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_a"), - RefSchema: model.NewCIStr("test"), - RefTable: model.NewCIStr("t1"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("a")}, - OnDelete: 2, - OnUpdate: 1, - State: model.StatePublic, - Version: 1, - }, *tb3Info.ForeignKeys[0]) - require.Equal(t, model.FKInfo{ - ID: 2, - Name: model.NewCIStr("fk_a2"), - RefSchema: model.NewCIStr("test2"), - RefTable: model.NewCIStr("t2"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("a")}, - State: model.StatePublic, - Version: 1, - }, *tb3Info.ForeignKeys[1]) -} - -func TestCreateTableWithForeignKeyMetaInfo3(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int, b int as (a) virtual);") - tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id))") - tk.MustExec("create table t3 (id int key, b int, foreign key fk_b(b) references test.t1(id))") - tk.MustExec("create table t4 (id int key, b int, foreign key fk_b(b) references test.t1(id))") - tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - tk.MustExec("drop table t3") - tk.MustExec("create table t5 (id int key, b int, foreign key fk_b(b) references test.t1(id))") - require.Equal(t, 3, len(tb1ReferredFKs)) - require.Equal(t, "t2", tb1ReferredFKs[0].ChildTable.L) - require.Equal(t, "t3", tb1ReferredFKs[1].ChildTable.L) - require.Equal(t, "t4", tb1ReferredFKs[2].ChildTable.L) -} - -func TestCreateTableWithForeignKeyPrivilegeCheck(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - - tk.MustExec("create user 'u1'@'%' identified by '';") - tk.MustExec("grant create on *.* to 'u1'@'%';") - tk.MustExec("create table t1 (id int key);") - - tk2 := testkit.NewTestKit(t, store) - tk2.MustExec("use test") - tk2.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost", CurrentUser: true, AuthUsername: "u1", AuthHostname: "%"}, nil, []byte("012345678901234567890")) - err := tk2.ExecToErr("create table t2 (a int, foreign key fk(a) references t1(id));") - require.Error(t, err) - require.Equal(t, "[planner:1142]REFERENCES command denied to user 'u1'@'%' for table 't1'", err.Error()) - - tk.MustExec("grant references on test.t1 to 'u1'@'%';") - tk2.MustExec("create table t2 (a int, foreign key fk(a) references t1(id));") - tk2.MustExec("create table t3 (id int key)") - err = tk2.ExecToErr("create table t4 (a int, foreign key fk(a) references t1(id), foreign key (a) references t3(id));") - require.Error(t, err) - require.Equal(t, "[planner:1142]REFERENCES command denied to user 'u1'@'%' for table 't3'", err.Error()) - - tk.MustExec("grant references on test.t3 to 'u1'@'%';") - tk2.MustExec("create table t4 (a int, foreign key fk(a) references t1(id), foreign key (a) references t3(id));") -} - -func TestRenameTableWithForeignKeyMetaInfo(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("create database test2") - tk.MustExec("create database test3") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))") - tk.MustExec("rename table test.t1 to test2.t2") - // check the schema diff - diff := getLatestSchemaDiff(t, tk) - require.Equal(t, model.ActionRenameTable, diff.Type) - require.Equal(t, 0, len(diff.AffectedOpts)) - tk.MustQuery("show create table test2.t2").Check(testkit.Rows("t2 CREATE TABLE `t2` (\n" + - " `id` int(11) NOT NULL,\n" + - " `a` int(11) DEFAULT NULL,\n" + - " `b` int(11) DEFAULT NULL,\n" + - " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + - " KEY `fk` (`a`),\n" + - " CONSTRAINT `fk` FOREIGN KEY (`a`) REFERENCES `test2`.`t2` (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - tblInfo := getTableInfo(t, dom, "test2", "t2") - tbReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "t2") - require.Equal(t, 1, len(tblInfo.ForeignKeys)) - require.Equal(t, 1, len(tbReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("t2"), - ChildFKName: model.NewCIStr("fk"), - }, *tbReferredFKs[0]) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk"), - RefSchema: model.NewCIStr("test2"), - RefTable: model.NewCIStr("t2"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("a")}, - State: model.StatePublic, - Version: 1, - }, *tblInfo.ForeignKeys[0]) - - tk.MustExec("drop table test2.t2") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int, b int as (a) virtual);") - tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id))") - tk.MustExec("use test2") - tk.MustExec("rename table test.t2 to test2.tt2") - // check the schema diff - diff = getLatestSchemaDiff(t, tk) - require.Equal(t, model.ActionRenameTable, diff.Type) - require.Equal(t, 0, len(diff.AffectedOpts)) - tb1Info := getTableInfo(t, dom, "test", "t1") - tb2Info := getTableInfo(t, dom, "test2", "tt2") - require.Equal(t, 0, len(tb1Info.ForeignKeys)) - tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("tt2"), - ChildFKName: model.NewCIStr("fk_b"), - }, *tb1ReferredFKs[0]) - tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "tt2") - require.Equal(t, 0, len(tb2ReferredFKs)) - require.Equal(t, 1, len(tb2Info.ForeignKeys)) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_b"), - RefSchema: model.NewCIStr("test"), - RefTable: model.NewCIStr("t1"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("b")}, - State: model.StatePublic, - Version: 1, - }, *tb2Info.ForeignKeys[0]) - // Auto create index for foreign key usage. - require.Equal(t, 1, len(tb2Info.Indices)) - require.Equal(t, "fk_b", tb2Info.Indices[0].Name.L) - require.Equal(t, "`test2`.`tt2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`id`)", tb2Info.ForeignKeys[0].String("test2", "tt2")) - - tk.MustExec("rename table test.t1 to test3.tt1") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test3", "tt1") - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) - // check the schema diff - diff = getLatestSchemaDiff(t, tk) - require.Equal(t, model.ActionRenameTable, diff.Type) - require.Equal(t, 1, len(diff.AffectedOpts)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("tt2"), - ChildFKName: model.NewCIStr("fk_b"), - }, *tb1ReferredFKs[0]) - tbl2Info := getTableInfo(t, dom, "test2", "tt2") - tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test2", "tt2") - require.Equal(t, 0, len(tb2ReferredFKs)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys)) - require.Equal(t, model.FKInfo{ - ID: 1, - Name: model.NewCIStr("fk_b"), - RefSchema: model.NewCIStr("test3"), - RefTable: model.NewCIStr("tt1"), - RefCols: []model.CIStr{model.NewCIStr("id")}, - Cols: []model.CIStr{model.NewCIStr("b")}, - State: model.StatePublic, - Version: 1, - }, *tbl2Info.ForeignKeys[0]) - tk.MustQuery("show create table test2.tt2").Check(testkit.Rows("tt2 CREATE TABLE `tt2` (\n" + - " `id` int(11) NOT NULL,\n" + - " `b` int(11) DEFAULT NULL,\n" + - " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + - " KEY `fk_b` (`b`),\n" + - " CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `test3`.`tt1` (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) -} - -func TestCreateTableWithForeignKeyDML(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int);") - tk.MustExec("begin") - tk.MustExec("insert into t1 values (1, 1)") - tk.MustExec("update t1 set a = 2 where id = 1") - - tk2 := testkit.NewTestKit(t, store) - tk2.MustExec("use test") - tk2.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references test.t1(id))") - - tk.MustExec("commit") -} - -func TestCreateTableWithForeignKeyError(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("use test") - - cases := []struct { - prepare []string - refer string - create string - err string - }{ - { - refer: "create table t1 (id int, a int, b int);", - create: "create table t2 (a int, b int, foreign key fk_b(b) references T_unknown(b));", - err: "[schema:1824]Failed to open the referenced table 'T_unknown'", - }, - { - refer: "create table t1 (id int, a int, b int);", - create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(c_unknown));", - err: "[schema:3734]Failed to add the foreign key constraint. Missing column 'c_unknown' for constraint 'fk_b' in the referenced table 't1'", - }, - { - refer: "create table t1 (id int key, a int, b int);", - create: "create table t2 (a int, b int, foreign key fk(c_unknown) references t1(id));", - err: "[ddl:1072]Key column 'c_unknown' doesn't exist in table", - }, - { - refer: "create table t1 (id int, a int, b int);", - create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", - }, - { - refer: "create table t1 (id int, a int, b int not null, index(b));", - create: "create table t2 (a int, b int not null, foreign key fk_b(b) references t1(b) on update set null);", - err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", - }, - { - refer: "create table t1 (id int, a int, b int not null, index(b));", - create: "create table t2 (a int, b int not null, foreign key fk_b(b) references t1(b) on delete set null);", - err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", - }, - { - refer: "create table t1 (id int key, a int, b int as (a) virtual, index(b));", - create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", - err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", - }, - { - refer: "create table t1 (id int key, a int, b int, index(b));", - create: "create table t2 (a int, b int as (a) virtual, foreign key fk_b(b) references t1(b));", - err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", - }, - { - refer: "create table t1 (id int key, a int);", - create: "create table t2 (a int, b varchar(10), foreign key fk(b) references t1(id));", - err: "[ddl:3780]Referencing column 'b' and referenced column 'id' in foreign key constraint 'fk' are incompatible.", - }, - { - refer: "create table t1 (id int key, a int not null, index(a));", - create: "create table t2 (a int, b int unsigned, foreign key fk_b(b) references t1(a));", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - refer: "create table t1 (id int key, a bigint, index(a));", - create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(a));", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - refer: "create table t1 (id int key, a varchar(10) charset utf8, index(a));", - create: "create table t2 (a int, b varchar(10) charset utf8mb4, foreign key fk_b(b) references t1(a));", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - refer: "create table t1 (id int key, a varchar(10) collate utf8_bin, index(a));", - create: "create table t2 (a int, b varchar(10) collate utf8mb4_bin, foreign key fk_b(b) references t1(a));", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - refer: "create table t1 (id int key, a varchar(10));", - create: "create table t2 (a int, b varchar(10), foreign key fk_b(b) references t1(a));", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", - }, - { - refer: "create table t1 (id int key, a varchar(10), index (a(5)));", - create: "create table t2 (a int, b varchar(10), foreign key fk_b(b) references t1(a));", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", - }, - { - refer: "create table t1 (id int key, a int, index(a));", - create: "create table t2 (a int, b int, foreign key fk_b(b) references t1(id, a));", - err: "[schema:1239]Incorrect foreign key definition for 'fk_b': Key reference and table reference don't match", - }, - { - create: "create table t2 (a int key, foreign key (a) references t2(a));", - err: "[schema:1215]Cannot add foreign key constraint", - }, - { - create: "create table t2 (a int, b int, index(a,b), index(b,a), foreign key (a,b) references t2(a,b));", - err: "[schema:1215]Cannot add foreign key constraint", - }, - { - create: "create table t2 (a int, b int, index(a,b), foreign key (a,b) references t2(b,a));", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_1' in the referenced table 't2'", - }, - { - prepare: []string{ - "set @@foreign_key_checks=0;", - "create table t2 (a int, b int, index(a), foreign key (a) references t1(id));", - }, - create: "create table t1 (id int, a int);", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_1' in the referenced table 't1'", - }, - { - prepare: []string{ - "set @@foreign_key_checks=0;", - "create table t2 (a int, b int, index(a), foreign key (a) references t1(id));", - }, - create: "create table t1 (id bigint key, a int);", - err: "[ddl:3780]Referencing column 'a' and referenced column 'id' in foreign key constraint 'fk_1' are incompatible.", - }, - { - // foreign key is not support in temporary table. - refer: "create temporary table t1 (id int key, b int, index(b))", - create: "create table t2 (a int, b int, foreign key fk(b) references t1(b))", - err: "[schema:1824]Failed to open the referenced table 't1'", - }, - { - // foreign key is not support in temporary table. - refer: "create global temporary table t1 (id int key, b int, index(b)) on commit delete rows", - create: "create table t2 (a int, b int, foreign key fk(b) references t1(b))", - err: "[schema:1215]Cannot add foreign key constraint", - }, - { - // foreign key is not support in temporary table. - refer: "create table t1 (id int key, b int, index(b))", - create: "create temporary table t2 (a int, b int, foreign key fk(b) references t1(b))", - err: "[schema:1215]Cannot add foreign key constraint", - }, - { - // foreign key is not support in temporary table. - refer: "create table t1 (id int key, b int, index(b))", - create: "create global temporary table t2 (a int, b int, foreign key fk(b) references t1(b)) on commit delete rows", - err: "[schema:1215]Cannot add foreign key constraint", - }, - { - create: "create table t1 (a int, foreign key ``(a) references t1(a));", - err: "[ddl:1280]Incorrect index name ''", - }, - { - create: "create table t1 (a int, constraint `` foreign key (a) references t1(a));", - err: "[ddl:1280]Incorrect index name ''", - }, - { - create: "create table t1 (a int, constraint `fk` foreign key (a,a) references t1(a, b));", - err: "[schema:1060]Duplicate column name 'a'", - }, - { - refer: "create table t1(a int, b int, index(a,b));", - create: "create table t2 (a int, b int, foreign key (a,b) references t1(a,a));", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_1' in the referenced table 't1'", - }, - { - refer: "create table t1 (id int key, b int, index(b))", - create: "create table t2 (a int, b int, index fk_1(a), foreign key (b) references t1(b));", - err: "[ddl:1061]duplicate key name fk_1", - }, - } - for _, ca := range cases { - tk.MustExec("drop table if exists t2") - tk.MustExec("drop table if exists t1") - tk.MustExec("set @@foreign_key_checks=1") - for _, sql := range ca.prepare { - tk.MustExec(sql) - } - if ca.refer != "" { - tk.MustExec(ca.refer) - } - err := tk.ExecToErr(ca.create) - require.Error(t, err, ca.create) - require.Equal(t, ca.err, err.Error(), ca.create) - } - - passCases := [][]string{ - { - "create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))", - }, - { - "create table t1 (id int key, b int not null, index(b))", - "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", - }, - { - "create table t1 (id int key, a varchar(10), index(a));", - "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", - }, - { - "create table t1 (id int key, a decimal(10,5), index(a));", - "create table t2 (a int, b decimal(20, 10), foreign key fk_b(b) references t1(a));", - }, - { - "create table t1 (id int key, a varchar(10), index (a(10)));", - "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", - }, - { - "set @@foreign_key_checks=0;", - "create table t2 (a int, b int, foreign key fk_b(b) references t_unknown(b));", - "set @@foreign_key_checks=1;", - }, - { - "create table t2 (a int, b int, index(a,b), index(b,a), foreign key (a,b) references t2(b,a));", - }, - { - "create table t1 (a int key, b int, index(b))", - "create table t2 (a int, b int, foreign key (a) references t1(a), foreign key (b) references t1(b));", - }, - } - for _, ca := range passCases { - tk.MustExec("drop table if exists t2") - tk.MustExec("drop table if exists t1") - for _, sql := range ca { - tk.MustExec(sql) - } - } -} - -func TestModifyColumnWithForeignKey(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1;") - tk.MustExec("use test") - - tk.MustExec("create table t1 (id int key, b varchar(10), index(b));") - tk.MustExec("create table t2 (a varchar(10), constraint fk foreign key (a) references t1(b));") - tk.MustExec("insert into t1 values (1, '123456789');") - tk.MustExec("insert into t2 values ('123456789');") - tk.MustGetErrMsg("alter table t1 modify column b varchar(5);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") - tk.MustGetErrMsg("alter table t1 modify column b bigint;", "[ddl:3780]Referencing column 'a' and referenced column 'b' in foreign key constraint 'fk' are incompatible.") - tk.MustExec("alter table t1 modify column b varchar(20);") - tk.MustGetErrMsg("alter table t1 modify column b varchar(10);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") - tk.MustExec("alter table t2 modify column a varchar(20);") - tk.MustExec("alter table t2 modify column a varchar(21);") - tk.MustGetErrMsg("alter table t2 modify column a varchar(5);", "[ddl:1832]Cannot change column 'a': used in a foreign key constraint 'fk'") - tk.MustGetErrMsg("alter table t2 modify column a bigint;", "[ddl:3780]Referencing column 'a' and referenced column 'b' in foreign key constraint 'fk' are incompatible.") - - tk.MustExec("drop table t2") - tk.MustExec("drop table t1") - tk.MustExec("create table t1 (id int key, b decimal(10, 5), index(b));") - tk.MustExec("create table t2 (a decimal(10, 5), constraint fk foreign key (a) references t1(b));") - tk.MustExec("insert into t1 values (1, 12345.67891);") - tk.MustExec("insert into t2 values (12345.67891);") - tk.MustGetErrMsg("alter table t1 modify column b decimal(10, 6);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") - tk.MustGetErrMsg("alter table t1 modify column b decimal(10, 3);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") - tk.MustGetErrMsg("alter table t1 modify column b decimal(5, 2);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") - tk.MustGetErrMsg("alter table t1 modify column b decimal(20, 10);", "[ddl:1833]Cannot change column 'b': used in a foreign key constraint 'fk' of table 'test.t2'") - tk.MustGetErrMsg("alter table t2 modify column a decimal(30, 15);", "[ddl:1832]Cannot change column 'a': used in a foreign key constraint 'fk'") - tk.MustGetErrMsg("alter table t2 modify column a decimal(5, 2);", "[ddl:1832]Cannot change column 'a': used in a foreign key constraint 'fk'") -} - -func TestDropChildTableForeignKeyMetaInfo(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int, b int, CONSTRAINT fk foreign key (a) references t1(id))") - tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - tk.MustExec("drop table t1") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 0, len(tb1ReferredFKs)) - - tk.MustExec("create table t1 (id int key, b int, index(b))") - tk.MustExec("create table t2 (a int, b int, foreign key fk (a) references t1(b));") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - tk.MustExec("drop table t2") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 0, len(tb1ReferredFKs)) -} - -func TestDropForeignKeyMetaInfo(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int, b int, CONSTRAINT fk foreign key (a) references t1(id))") - tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - tk.MustExec("alter table t1 drop foreign key fk") - tbl1Info := getTableInfo(t, dom, "test", "t1") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 0, len(tbl1Info.ForeignKeys)) - require.Equal(t, 0, len(tb1ReferredFKs)) - - tk.MustExec("drop table t1") - tk.MustExec("create table t1 (id int key, b int, index(b))") - tk.MustExec("create table t2 (a int, b int, foreign key fk (a) references t1(b));") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - tk.MustExec("alter table t2 drop foreign key fk") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 0, len(tb1ReferredFKs)) - tbl2Info := getTableInfo(t, dom, "test", "t2") - require.Equal(t, 0, len(tbl2Info.ForeignKeys)) -} - -func TestTruncateOrDropTableWithForeignKeyReferred(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("use test") - - cases := []struct { - prepares []string - tbl string - truncateErr string - dropErr string - }{ - { - prepares: []string{ - "create table t1 (id int key, b int not null, index(b))", - "create table t2 (a int, b int, foreign key fk_b(b) references t1(b));", - }, - tbl: "t1", - truncateErr: "[ddl:1701]Cannot truncate a table referenced in a foreign key constraint (`test`.`t2` CONSTRAINT `fk_b`)", - dropErr: "[ddl:3730]Cannot drop table 't1' referenced by a foreign key constraint 'fk_b' on table 't2'.", - }, - { - prepares: []string{ - "create table t1 (id int key, a varchar(10), index(a));", - "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", - }, - tbl: "t1", - truncateErr: "[ddl:1701]Cannot truncate a table referenced in a foreign key constraint (`test`.`t2` CONSTRAINT `fk_b`)", - dropErr: "[ddl:3730]Cannot drop table 't1' referenced by a foreign key constraint 'fk_b' on table 't2'.", - }, - { - prepares: []string{ - "create table t1 (id int key, a varchar(10), index (a(10)));", - "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", - }, - tbl: "t1", - truncateErr: "[ddl:1701]Cannot truncate a table referenced in a foreign key constraint (`test`.`t2` CONSTRAINT `fk_b`)", - dropErr: "[ddl:3730]Cannot drop table 't1' referenced by a foreign key constraint 'fk_b' on table 't2'.", - }, - } - - for _, ca := range cases { - tk.MustExec("drop table if exists t2") - tk.MustExec("drop table if exists t1") - for _, sql := range ca.prepares { - tk.MustExec(sql) - } - truncateSQL := fmt.Sprintf("truncate table %v", ca.tbl) - tk.MustExec("set @@foreign_key_checks=1;") - err := tk.ExecToErr(truncateSQL) - require.Error(t, err) - require.Equal(t, ca.truncateErr, err.Error()) - dropSQL := fmt.Sprintf("drop table %v", ca.tbl) - err = tk.ExecToErr(dropSQL) - require.Error(t, err) - require.Equal(t, ca.dropErr, err.Error()) - - tk.MustExec("set @@foreign_key_checks=0;") - tk.MustExec(truncateSQL) - } - passCases := [][]string{ - { - "create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))", - "truncate table t1", - "drop table t1", - }, - { - "create table t1 (id int key, a varchar(10), index (a(10)));", - "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", - "drop table t1, t2", - }, - { - "set @@foreign_key_checks=0;", - "create table t1 (id int key, a varchar(10), index (a(10)));", - "create table t2 (a int, b varchar(20), foreign key fk_b(b) references t1(a));", - "truncate table t1", - "drop table t1", - }, - } - for _, ca := range passCases { - tk.MustExec("drop table if exists t1, t2") - tk.MustExec("set @@foreign_key_checks=1;") - for _, sql := range ca { - tk.MustExec(sql) - } - } -} - func TestTruncateOrDropTableWithForeignKeyReferred2(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) d := dom.DDL() @@ -1073,106 +264,6 @@ func TestTruncateOrDropTableWithForeignKeyReferred2(t *testing.T) { require.Equal(t, "[ddl:1701]Cannot truncate a table referenced in a foreign key constraint (`test`.`t2` CONSTRAINT `fk`)", dropErr.Error()) } -func TestDropTableWithForeignKeyReferred(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1;") - tk.MustExec("use test") - - tk.MustExec("create table t1 (id int key, b int, index(b));") - tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references t1(id));") - tk.MustExec("create table t3 (id int key, b int, foreign key fk_b(b) references t2(id));") - err := tk.ExecToErr("drop table if exists t1,t2;") - require.Error(t, err) - require.Equal(t, "[ddl:3730]Cannot drop table 't2' referenced by a foreign key constraint 'fk_b' on table 't3'.", err.Error()) - tk.MustQuery("show tables").Check(testkit.Rows("t1", "t2", "t3")) -} - -func TestDropIndexNeededInForeignKey(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - - cases := []struct { - prepares []string - drops []string - err string - }{ - { - prepares: []string{ - "create table t1 (id int key, b int, index idx (b))", - "create table t2 (a int, b int, index idx (b), foreign key fk_b(b) references t1(b));", - }, - drops: []string{ - "alter table t1 drop index idx", - "alter table t2 drop index idx", - }, - err: "[ddl:1553]Cannot drop index 'idx': needed in a foreign key constraint", - }, - { - prepares: []string{ - "create table t1 (id int, b int, index idx (id, b))", - "create table t2 (a int, b int, index idx (b, a), foreign key fk_b(b) references t1(id));", - }, - drops: []string{ - "alter table t1 drop index idx", - "alter table t2 drop index idx", - }, - err: "[ddl:1553]Cannot drop index 'idx': needed in a foreign key constraint", - }, - } - - for _, ca := range cases { - tk.MustExec("drop table if exists t2") - tk.MustExec("drop table if exists t1") - for _, sql := range ca.prepares { - tk.MustExec(sql) - } - for _, drop := range ca.drops { - // even disable foreign key check, still can't drop the index used by foreign key. - tk.MustExec("set @@foreign_key_checks=0;") - err := tk.ExecToErr(drop) - require.Error(t, err) - require.Equal(t, ca.err, err.Error()) - tk.MustExec("set @@foreign_key_checks=1;") - err = tk.ExecToErr(drop) - require.Error(t, err) - require.Equal(t, ca.err, err.Error()) - } - } - passCases := [][]string{ - { - "create table t1 (id int key, b int, index idxb (b))", - "create table t2 (a int, b int key, index idxa (a),index idxb (b), foreign key fk_b(b) references t1(id));", - "alter table t1 drop index idxb", - "alter table t2 drop index idxa", - "alter table t2 drop index idxb", - }, - { - "create table t1 (id int key, b int, index idxb (b), unique index idx(b, id))", - "create table t2 (a int, b int key, index idx (b, a),index idxb (b), index idxab(a, b), foreign key fk_b(b) references t1(b));", - "alter table t1 drop index idxb", - "alter table t1 add index idxb (b)", - "alter table t1 drop index idx", - "alter table t2 drop index idx", - "alter table t2 add index idx (b, a)", - "alter table t2 drop index idxb", - "alter table t2 drop index idxab", - }, - } - tk.MustExec("set @@foreign_key_checks=1;") - for _, ca := range passCases { - tk.MustExec("drop table if exists t2") - tk.MustExec("drop table if exists t1") - for _, sql := range ca { - tk.MustExec(sql) - } - } -} - func TestDropIndexNeededInForeignKey2(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) d := dom.DDL() @@ -1212,157 +303,6 @@ func TestDropIndexNeededInForeignKey2(t *testing.T) { require.Equal(t, "[ddl:1553]Cannot drop index 'idx2': needed in a foreign key constraint", dropErr.Error()) } -func getTableInfo(t *testing.T, dom *domain.Domain, db, tb string) *model.TableInfo { - err := dom.Reload() - require.NoError(t, err) - is := dom.InfoSchema() - tbl, err := is.TableByName(model.NewCIStr(db), model.NewCIStr(tb)) - require.NoError(t, err) - _, exist := is.TableByID(tbl.Meta().ID) - require.True(t, exist) - return tbl.Meta() -} - -func getTableInfoReferredForeignKeys(t *testing.T, dom *domain.Domain, db, tb string) []*model.ReferredFKInfo { - err := dom.Reload() - require.NoError(t, err) - return dom.InfoSchema().GetTableReferredForeignKeys(db, tb) -} - -func TestDropColumnWithForeignKey(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1;") - tk.MustExec("use test") - - tk.MustExec("create table t1 (id int key, a int, b int, index(b), CONSTRAINT fk foreign key (a) references t1(b))") - tk.MustGetErrMsg("alter table t1 drop column a;", "[ddl:1828]Cannot drop column 'a': needed in a foreign key constraint 'fk'") - tk.MustGetErrMsg("alter table t1 drop column b;", "[ddl:1829]Cannot drop column 'b': needed in a foreign key constraint 'fk' of table 't1'") - - tk.MustExec("drop table t1") - tk.MustExec("create table t1 (id int key, b int, index(b));") - tk.MustExec("create table t2 (a int, b int, constraint fk foreign key (a) references t1(b));") - tk.MustGetErrMsg("alter table t1 drop column b;", "[ddl:1829]Cannot drop column 'b': needed in a foreign key constraint 'fk' of table 't2'") - tk.MustGetErrMsg("alter table t2 drop column a;", "[ddl:1828]Cannot drop column 'a': needed in a foreign key constraint 'fk'") -} - -func TestRenameColumnWithForeignKeyMetaInfo(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1;") - tk.MustExec("use test") - - tk.MustExec("create table t1 (id int key, a int, b int, foreign key fk(a) references t1(id))") - tk.MustExec("alter table t1 change id kid int") - tk.MustExec("alter table t1 rename column a to aa") - tbl1Info := getTableInfo(t, dom, "test", "t1") - tb1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tbl1Info.ForeignKeys)) - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, "kid", tb1ReferredFKs[0].Cols[0].L) - require.Equal(t, "kid", tbl1Info.ForeignKeys[0].RefCols[0].L) - require.Equal(t, "aa", tbl1Info.ForeignKeys[0].Cols[0].L) - - tk.MustExec("drop table t1") - tk.MustExec("create table t1 (id int key, b int, index(b))") - tk.MustExec("create table t2 (a int, b int, foreign key fk(a) references t1(b));") - tk.MustExec("alter table t2 change a aa int") - tbl1Info = getTableInfo(t, dom, "test", "t1") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) - require.Equal(t, "b", tb1ReferredFKs[0].Cols[0].L) - tbl2Info := getTableInfo(t, dom, "test", "t2") - tb2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t2") - require.Equal(t, 0, len(tb2ReferredFKs)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].Cols)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].RefCols)) - require.Equal(t, "aa", tbl2Info.ForeignKeys[0].Cols[0].L) - require.Equal(t, "b", tbl2Info.ForeignKeys[0].RefCols[0].L) - - tk.MustExec("alter table t1 change id kid int") - tk.MustExec("alter table t1 change b bb int") - tbl1Info = getTableInfo(t, dom, "test", "t1") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 1, len(tb1ReferredFKs)) - require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) - require.Equal(t, "bb", tb1ReferredFKs[0].Cols[0].L) - tbl2Info = getTableInfo(t, dom, "test", "t2") - tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t2") - require.Equal(t, 0, len(tb2ReferredFKs)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].Cols)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].RefCols)) - require.Equal(t, "aa", tbl2Info.ForeignKeys[0].Cols[0].L) - require.Equal(t, "bb", tbl2Info.ForeignKeys[0].RefCols[0].L) - - tk.MustExec("drop table t1, t2") - tk.MustExec("create table t1 (id int key, b int, index(b))") - tk.MustExec("create table t2 (a int, b int, foreign key (a) references t1(b), foreign key (b) references t1(b));") - tk.MustExec("alter table t1 change b bb int") - tbl1Info = getTableInfo(t, dom, "test", "t1") - tb1ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t1") - require.Equal(t, 2, len(tb1ReferredFKs)) - require.Equal(t, 1, len(tb1ReferredFKs[0].Cols)) - require.Equal(t, 1, len(tb1ReferredFKs[1].Cols)) - require.Equal(t, "bb", tb1ReferredFKs[0].Cols[0].L) - require.Equal(t, "bb", tb1ReferredFKs[1].Cols[0].L) - tbl2Info = getTableInfo(t, dom, "test", "t2") - tb2ReferredFKs = getTableInfoReferredForeignKeys(t, dom, "test", "t2") - require.Equal(t, 0, len(tb2ReferredFKs)) - require.Equal(t, 2, len(tbl2Info.ForeignKeys)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].Cols)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[0].RefCols)) - require.Equal(t, "a", tbl2Info.ForeignKeys[0].Cols[0].L) - require.Equal(t, "bb", tbl2Info.ForeignKeys[0].RefCols[0].L) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[1].Cols)) - require.Equal(t, 1, len(tbl2Info.ForeignKeys[1].RefCols)) - require.Equal(t, "b", tbl2Info.ForeignKeys[1].Cols[0].L) - require.Equal(t, "bb", tbl2Info.ForeignKeys[1].RefCols[0].L) - tk.MustExec("alter table t2 rename column a to aa") - tk.MustExec("alter table t2 change b bb int") - tk.MustQuery("show create table t2"). - Check(testkit.Rows("t2 CREATE TABLE `t2` (\n" + - " `aa` int(11) DEFAULT NULL,\n" + - " `bb` int(11) DEFAULT NULL,\n" + - " KEY `fk_1` (`aa`),\n KEY `fk_2` (`bb`),\n" + - " CONSTRAINT `fk_1` FOREIGN KEY (`aa`) REFERENCES `test`.`t1` (`bb`),\n" + - " CONSTRAINT `fk_2` FOREIGN KEY (`bb`) REFERENCES `test`.`t1` (`bb`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) -} - -func TestDropDatabaseWithForeignKeyReferred(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1;") - tk.MustExec("use test") - - tk.MustExec("create table t1 (id int key, b int, index(b));") - tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references t1(id));") - tk.MustExec("create database test2") - tk.MustExec("create table test2.t3 (id int key, b int, foreign key fk_b(b) references test.t2(id));") - err := tk.ExecToErr("drop database test;") - require.Error(t, err) - require.Equal(t, "[ddl:3730]Cannot drop table 't2' referenced by a foreign key constraint 'fk_b' on table 't3'.", err.Error()) - tk.MustExec("set @@foreign_key_checks=0;") - tk.MustExec("drop database test") - - tk.MustExec("set @@foreign_key_checks=1;") - tk.MustExec("create database test") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, b int, index(b));") - tk.MustExec("create table t2 (id int key, b int, foreign key fk_b(b) references t1(id));") - err = tk.ExecToErr("drop database test;") - require.Error(t, err) - require.Equal(t, "[ddl:3730]Cannot drop table 't2' referenced by a foreign key constraint 'fk_b' on table 't3'.", err.Error()) - tk.MustExec("drop table test2.t3") - tk.MustExec("drop database test") -} - func TestDropDatabaseWithForeignKeyReferred2(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) d := dom.DDL() @@ -1407,27 +347,6 @@ func TestDropDatabaseWithForeignKeyReferred2(t *testing.T) { tk.MustExec("drop database test") } -func TestAddForeignKey(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1;") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, b int);") - tk.MustExec("create table t2 (id int key, b int);") - err := tk.ExecToErr("alter table t2 add foreign key (b) references t1(id);") - require.Error(t, err) - require.Equal(t, "Failed to add the foreign key constraint. Missing index for 'fk_1' foreign key columns in the table 't2'", err.Error()) - tk.MustExec("alter table t2 add index(b)") - tk.MustExec("alter table t2 add foreign key (b) references t1(id);") - tbl2Info := getTableInfo(t, dom, "test", "t2") - require.Equal(t, int64(1), tbl2Info.MaxForeignKeyID) - tk.MustGetDBError("alter table t2 add foreign key (b) references t1(b);", infoschema.ErrForeignKeyNoIndexInParent) - tk.MustExec("alter table t1 add index(b)") - tk.MustExec("alter table t2 add foreign key (b) references t1(b);") - tk.MustGetDBError("alter table t2 add foreign key (b) references t2(b);", infoschema.ErrCannotAddForeign) -} - func TestAddForeignKey2(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) d := dom.DDL() @@ -1464,287 +383,49 @@ func TestAddForeignKey2(t *testing.T) { require.Equal(t, "[ddl:-1]Failed to add the foreign key constraint. Missing index for 'fk_1' foreign key columns in the table 't2'", addErr.Error()) } -func TestAlterTableAddForeignKeyError(t *testing.T) { - store, _ := testkit.CreateMockStoreAndDomain(t) +func TestAddForeignKey3(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) + d := dom.DDL() tk := testkit.NewTestKit(t, store) tk.MustExec("set @@global.tidb_enable_foreign_key=1") tk.MustExec("set @@foreign_key_checks=1;") tk.MustExec("use test") - cases := []struct { - prepares []string - alter string - err string - }{ - { - prepares: []string{ - "create table t1 (id int, a int, b int);", - "create table t2 (a int, b int);", - }, - alter: "alter table t2 add foreign key fk(b) references t_unknown(id)", - err: "[schema:1824]Failed to open the referenced table 't_unknown'", - }, - { - prepares: []string{ - "create table t1 (id int, a int, b int);", - "create table t2 (a int, b int);", - }, - alter: "alter table t2 add foreign key fk(b) references t1(c_unknown)", - err: "[schema:3734]Failed to add the foreign key constraint. Missing column 'c_unknown' for constraint 'fk' in the referenced table 't1'", - }, - { - prepares: []string{ - "create table t1 (id int, a int, b int);", - "create table t2 (a int, b int);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(b)", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", - }, - { - prepares: []string{ - "create table t1 (id int, a int, b int not null, index(b));", - "create table t2 (a int, b int not null);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(b) on update set null", - err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", - }, - { - prepares: []string{ - "create table t1 (id int, a int, b int not null, index(b));", - "create table t2 (a int, b int not null);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(b) on delete set null", - err: "[schema:1830]Column 'b' cannot be NOT NULL: needed in a foreign key constraint 'fk_b' SET NULL", - }, - { - prepares: []string{ - "create table t1 (id int key, a int, b int as (a) virtual, index(b));", - "create table t2 (a int, b int);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(b)", - err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", - }, - { - prepares: []string{ - "create table t1 (id int key, a int, b int, index(b));", - "create table t2 (a int, b int as (a) virtual);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(b)", - err: "[schema:3733]Foreign key 'fk_b' uses virtual column 'b' which is not supported.", - }, - { - prepares: []string{ - "create table t1 (id int key, a int);", - "create table t2 (a int, b varchar(10));", - }, - alter: "alter table t2 add foreign key fk(b) references t1(id)", - err: "[ddl:3780]Referencing column 'b' and referenced column 'id' in foreign key constraint 'fk' are incompatible.", - }, - { - prepares: []string{ - "create table t1 (id int key, a int not null, index(a));", - "create table t2 (a int, b int unsigned);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(a)", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - prepares: []string{ - "create table t1 (id int key, a bigint, index(a));", - "create table t2 (a int, b int);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(a)", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - prepares: []string{ - "create table t1 (id int key, a varchar(10) charset utf8, index(a));", - "create table t2 (a int, b varchar(10) charset utf8mb4);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(a)", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - prepares: []string{ - "create table t1 (id int key, a varchar(10) collate utf8_bin, index(a));", - "create table t2 (a int, b varchar(10) collate utf8mb4_bin);", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(a)", - err: "[ddl:3780]Referencing column 'b' and referenced column 'a' in foreign key constraint 'fk_b' are incompatible.", - }, - { - prepares: []string{ - "create table t1 (id int key, a varchar(10));", - "create table t2 (a int, b varchar(10));", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(a)", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", - }, - { - prepares: []string{ - "create table t1 (id int key, a varchar(10), index (a(5)));", - "create table t2 (a int, b varchar(10));", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(a)", - err: "[schema:1822]Failed to add the foreign key constraint. Missing index for constraint 'fk_b' in the referenced table 't1'", - }, - { - prepares: []string{ - "create table t1 (id int key, a int)", - "create table t2 (id int, b int, index(b))", - "insert into t2 values (1,1)", - }, - alter: "alter table t2 add foreign key fk_b(b) references t1(id)", - err: "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`b`) REFERENCES `t1` (`id`))", - }, - { - prepares: []string{ - "create table t1 (id int, a int, b int, index(a,b))", - "create table t2 (id int, a int, b int, index(a,b))", - "insert into t2 values (1, 1, null), (2, null, 1), (3, null, null), (4, 1, 1)", - }, - alter: "alter table t2 add foreign key fk_b(a, b) references t1(a, b)", - err: "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_b` FOREIGN KEY (`a`, `b`) REFERENCES `t1` (`a`, `b`))", - }, - } - for i, ca := range cases { - tk.MustExec("drop table if exists t2") - tk.MustExec("drop table if exists t1") - for _, sql := range ca.prepares { - tk.MustExec(sql) + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec("set @@foreign_key_checks=1;") + tk.MustExec("create table t1 (id int key, b int, index(b));") + tk.MustExec("create table t2 (id int, b int, index(id), index(b));") + tk.MustExec("insert into t1 values (1, 1), (2, 2), (3, 3)") + tk.MustExec("insert into t2 values (1, 1), (2, 2), (3, 3)") + + var insertErrs []error + var deleteErrs []error + tc := &ddl.TestDDLCallback{} + tc.OnJobRunBeforeExported = func(job *model.Job) { + if job.Type != model.ActionAddForeignKey { + return + } + if job.SchemaState == model.StateWriteOnly || job.SchemaState == model.StateWriteReorganization { + err := tk2.ExecToErr("insert into t2 values (10, 10)") + insertErrs = append(insertErrs, err) + err = tk2.ExecToErr("delete from t1 where id = 1") + deleteErrs = append(deleteErrs, err) } - err := tk.ExecToErr(ca.alter) - require.Error(t, err, fmt.Sprintf("%v, %v", i, ca.err)) - require.Equal(t, ca.err, err.Error()) } + originalHook := d.GetHook() + defer d.SetHook(originalHook) + d.SetHook(tc) - passCases := [][]string{ - { - "create table t1 (id int key, a int, b int, index(a))", - "alter table t1 add foreign key fk(a) references t1(id)", - }, - { - "create table t1 (id int key, b int not null, index(b))", - "create table t2 (a int, b int, index(b));", - "alter table t2 add foreign key fk_b(b) references t1(b)", - }, - { - "create table t1 (id int key, a varchar(10), index(a));", - "create table t2 (a int, b varchar(20), index(b));", - "alter table t2 add foreign key fk_b(b) references t1(a)", - }, - { - "create table t1 (id int key, a decimal(10,5), index(a));", - "create table t2 (a int, b decimal(20, 10), index(b));", - "alter table t2 add foreign key fk_b(b) references t1(a)", - }, - { - "create table t1 (id int key, a varchar(10), index (a(10)));", - "create table t2 (a int, b varchar(20), index(b));", - "alter table t2 add foreign key fk_b(b) references t1(a)", - }, - { - "create table t1 (id int key, a int)", - "create table t2 (id int, b int, index(b))", - "insert into t2 values (1, null)", - "alter table t2 add foreign key fk_b(b) references t1(id)", - }, - { - "create table t1 (id int, a int, b int, index(a,b))", - "create table t2 (id int, a int, b int, index(a,b))", - "insert into t2 values (1, 1, null), (2, null, 1), (3, null, null)", - "alter table t2 add foreign key fk_b(a, b) references t1(a, b)", - }, - { - "set @@foreign_key_checks=0;", - "create table t1 (id int, a int, b int, index(a,b))", - "create table t2 (id int, a int, b int, index(a,b))", - "insert into t2 values (1, 1, 1)", - "alter table t2 add foreign key fk_b(a, b) references t1(a, b)", - "set @@foreign_key_checks=1;", - }, - { - "set @@foreign_key_checks=0;", - "create table t2 (a int, b int, index(b));", - "alter table t2 add foreign key fk_b(b) references t_unknown(a)", - "set @@foreign_key_checks=1;", - }, + tk.MustExec("alter table t2 add foreign key (id) references t1(id) on delete cascade") + require.Equal(t, 2, len(insertErrs)) + for _, err := range insertErrs { + require.Error(t, err) + require.Equal(t, "[planner:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE)", err.Error()) } - for _, ca := range passCases { - tk.MustExec("drop table if exists t2") - tk.MustExec("drop table if exists t1") - for _, sql := range ca { - tk.MustExec(sql) - } + for _, err := range deleteErrs { + require.Error(t, err) + require.Equal(t, "[planner:1451]Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE)", err.Error()) } -} - -func TestRenameTablesWithForeignKey(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=0;") - tk.MustExec("create database test1") - tk.MustExec("create database test2") - tk.MustExec("use test") - tk.MustExec("create table t0 (id int key, b int);") - tk.MustExec("create table t1 (id int key, b int, index(b), foreign key fk(b) references t2(id));") - tk.MustExec("create table t2 (id int key, b int, index(b), foreign key fk(b) references t1(id));") - tk.MustExec("rename table test.t1 to test1.tt1, test.t2 to test2.tt2, test.t0 to test.tt0") - - // check the schema diff - diff := getLatestSchemaDiff(t, tk) - require.Equal(t, model.ActionRenameTables, diff.Type) - require.Equal(t, 3, len(diff.AffectedOpts)) - - // check referred foreign key information. - t1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t1") - t2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test", "t2") - require.Equal(t, 0, len(t1ReferredFKs)) - require.Equal(t, 0, len(t2ReferredFKs)) - tt1ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test1", "tt1") - tt2ReferredFKs := getTableInfoReferredForeignKeys(t, dom, "test2", "tt2") - require.Equal(t, 1, len(tt1ReferredFKs)) - require.Equal(t, 1, len(tt2ReferredFKs)) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test2"), - ChildTable: model.NewCIStr("tt2"), - ChildFKName: model.NewCIStr("fk"), - }, *tt1ReferredFKs[0]) - require.Equal(t, model.ReferredFKInfo{ - Cols: []model.CIStr{model.NewCIStr("id")}, - ChildSchema: model.NewCIStr("test1"), - ChildTable: model.NewCIStr("tt1"), - ChildFKName: model.NewCIStr("fk"), - }, *tt2ReferredFKs[0]) - - // check show create table information - tk.MustQuery("show create table test1.tt1").Check(testkit.Rows("tt1 CREATE TABLE `tt1` (\n" + - " `id` int(11) NOT NULL,\n" + - " `b` int(11) DEFAULT NULL,\n" + - " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + - " KEY `b` (`b`),\n" + - " CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `test2`.`tt2` (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - tk.MustQuery("show create table test2.tt2").Check(testkit.Rows("tt2 CREATE TABLE `tt2` (\n" + - " `id` int(11) NOT NULL,\n" + - " `b` int(11) DEFAULT NULL,\n" + - " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + - " KEY `b` (`b`),\n" + - " CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `test1`.`tt1` (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) -} - -func getLatestSchemaDiff(t *testing.T, tk *testkit.TestKit) *model.SchemaDiff { - ctx := tk.Session() - err := sessiontxn.NewTxn(context.Background(), ctx) - require.NoError(t, err) - txn, err := ctx.Txn(true) - require.NoError(t, err) - m := meta.NewMeta(txn) - ver, err := m.GetSchemaVersion() - require.NoError(t, err) - diff, err := m.GetSchemaDiff(ver) - require.NoError(t, err) - return diff + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1 1", "2 2", "3 3")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 1", "2 2", "3 3")) } diff --git a/ddl/generated_column.go b/ddl/generated_column.go index 2f4ceee8b60a9..0e877a3e63eb3 100644 --- a/ddl/generated_column.go +++ b/ddl/generated_column.go @@ -122,13 +122,19 @@ func findPositionRelativeColumn(cols []*table.Column, pos *ast.ColumnPosition) ( // findDependedColumnNames returns a set of string, which indicates // the names of the columns that are depended by colDef. -func findDependedColumnNames(colDef *ast.ColumnDef) (generated bool, colsMap map[string]struct{}) { +func findDependedColumnNames(schemaName model.CIStr, tableName model.CIStr, colDef *ast.ColumnDef) (generated bool, colsMap map[string]struct{}, err error) { colsMap = make(map[string]struct{}) for _, option := range colDef.Options { if option.Tp == ast.ColumnOptionGenerated { generated = true colNames := FindColumnNamesInExpr(option.Expr) for _, depCol := range colNames { + if depCol.Schema.L != "" && schemaName.L != "" && depCol.Schema.L != schemaName.L { + return false, nil, dbterror.ErrWrongDBName.GenWithStackByArgs(depCol.Schema.O) + } + if depCol.Table.L != "" && tableName.L != "" && depCol.Table.L != tableName.L { + return false, nil, dbterror.ErrWrongTableName.GenWithStackByArgs(depCol.Table.O) + } colsMap[depCol.Name.L] = struct{}{} } break @@ -192,7 +198,7 @@ func (c *generatedColumnChecker) Leave(inNode ast.Node) (node ast.Node, ok bool) // 3. check if the modified expr contains non-deterministic functions // 4. check whether new column refers to any auto-increment columns. // 5. check if the new column is indexed or stored -func checkModifyGeneratedColumn(sctx sessionctx.Context, tbl table.Table, oldCol, newCol *table.Column, newColDef *ast.ColumnDef, pos *ast.ColumnPosition) error { +func checkModifyGeneratedColumn(sctx sessionctx.Context, schemaName model.CIStr, tbl table.Table, oldCol, newCol *table.Column, newColDef *ast.ColumnDef, pos *ast.ColumnPosition) error { // rule 1. oldColIsStored := !oldCol.IsGenerated() || oldCol.GeneratedStored newColIsStored := !newCol.IsGenerated() || newCol.GeneratedStored @@ -252,7 +258,10 @@ func checkModifyGeneratedColumn(sctx sessionctx.Context, tbl table.Table, oldCol } // rule 4. - _, dependColNames := findDependedColumnNames(newColDef) + _, dependColNames, err := findDependedColumnNames(schemaName, tbl.Meta().Name, newColDef) + if err != nil { + return errors.Trace(err) + } if !sctx.GetSessionVars().EnableAutoIncrementInGenerated { if err := checkAutoIncrementRef(newColDef.Name.Name.L, dependColNames, tbl.Meta()); err != nil { return errors.Trace(err) @@ -268,12 +277,14 @@ func checkModifyGeneratedColumn(sctx sessionctx.Context, tbl table.Table, oldCol } type illegalFunctionChecker struct { - hasIllegalFunc bool - hasAggFunc bool - hasRowVal bool // hasRowVal checks whether the functional index refers to a row value - hasWindowFunc bool - hasNotGAFunc4ExprIdx bool - otherErr error + hasIllegalFunc bool + hasAggFunc bool + hasRowVal bool // hasRowVal checks whether the functional index refers to a row value + hasWindowFunc bool + hasNotGAFunc4ExprIdx bool + hasCastArrayFunc bool + disallowCastArrayFunc bool + otherErr error } func (c *illegalFunctionChecker) Enter(inNode ast.Node) (outNode ast.Node, skipChildren bool) { @@ -308,7 +319,16 @@ func (c *illegalFunctionChecker) Enter(inNode ast.Node) (outNode ast.Node, skipC case *ast.WindowFuncExpr: c.hasWindowFunc = true return inNode, true + case *ast.FuncCastExpr: + c.hasCastArrayFunc = c.hasCastArrayFunc || node.Tp.IsArray() + if c.disallowCastArrayFunc && node.Tp.IsArray() { + c.otherErr = expression.ErrNotSupportedYet.GenWithStackByArgs("Use of CAST( .. AS .. ARRAY) outside of functional index in CREATE(non-SELECT)/ALTER TABLE or in general expressions") + return inNode, true + } + case *ast.ParenthesesExpr: + return inNode, false } + c.disallowCastArrayFunc = true return inNode, false } @@ -355,6 +375,9 @@ func checkIllegalFn4Generated(name string, genType int, expr ast.ExprNode) error if genType == typeIndex && c.hasNotGAFunc4ExprIdx && !config.GetGlobalConfig().Experimental.AllowsExpressionIndex { return dbterror.ErrUnsupportedExpressionIndex } + if genType == typeColumn && c.hasCastArrayFunc { + return expression.ErrNotSupportedYet.GenWithStackByArgs("Use of CAST( .. AS .. ARRAY) outside of functional index in CREATE(non-SELECT)/ALTER TABLE or in general expressions") + } return nil } diff --git a/ddl/index.go b/ddl/index.go index 914e5e8ff48a3..f634f23bd3f05 100644 --- a/ddl/index.go +++ b/ddl/index.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/kvrpcpb" + "github.com/pingcap/tidb/br/pkg/lightning/common" "github.com/pingcap/tidb/br/pkg/utils" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl/ingest" @@ -38,12 +39,15 @@ import ( "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" decoder "github.com/pingcap/tidb/util/rowDecoder" @@ -63,26 +67,33 @@ var ( telemetryAddIndexIngestUsage = metrics.TelemetryAddIndexIngestCnt ) -func buildIndexColumns(ctx sessionctx.Context, columns []*model.ColumnInfo, indexPartSpecifications []*ast.IndexPartSpecification) ([]*model.IndexColumn, error) { +func buildIndexColumns(ctx sessionctx.Context, columns []*model.ColumnInfo, indexPartSpecifications []*ast.IndexPartSpecification) ([]*model.IndexColumn, bool, error) { // Build offsets. idxParts := make([]*model.IndexColumn, 0, len(indexPartSpecifications)) var col *model.ColumnInfo + var mvIndex bool maxIndexLength := config.GetGlobalConfig().MaxIndexLength // The sum of length of all index columns. sumLength := 0 for _, ip := range indexPartSpecifications { col = model.FindColumnInfo(columns, ip.Column.Name.L) if col == nil { - return nil, dbterror.ErrKeyColumnDoesNotExits.GenWithStack("column does not exist: %s", ip.Column.Name) + return nil, false, dbterror.ErrKeyColumnDoesNotExits.GenWithStack("column does not exist: %s", ip.Column.Name) } if err := checkIndexColumn(ctx, col, ip.Length); err != nil { - return nil, err + return nil, false, err + } + if col.FieldType.IsArray() { + if mvIndex { + return nil, false, dbterror.ErrNotSupportedYet.GenWithStackByArgs("more than one multi-valued key part per index") + } + mvIndex = true } indexColLen := ip.Length indexColumnLength, err := getIndexColumnLength(col, ip.Length) if err != nil { - return nil, err + return nil, false, err } sumLength += indexColumnLength @@ -91,12 +102,12 @@ func buildIndexColumns(ctx sessionctx.Context, columns []*model.ColumnInfo, inde // The multiple column index and the unique index in which the length sum exceeds the maximum size // will return an error instead produce a warning. if ctx == nil || ctx.GetSessionVars().StrictSQLMode || mysql.HasUniKeyFlag(col.GetFlag()) || len(indexPartSpecifications) > 1 { - return nil, dbterror.ErrTooLongKey.GenWithStackByArgs(maxIndexLength) + return nil, false, dbterror.ErrTooLongKey.GenWithStackByArgs(maxIndexLength) } // truncate index length and produce warning message in non-restrict sql mode. colLenPerUint, err := getIndexColumnLength(col, 1) if err != nil { - return nil, err + return nil, false, err } indexColLen = maxIndexLength / colLenPerUint // produce warning message @@ -110,7 +121,7 @@ func buildIndexColumns(ctx sessionctx.Context, columns []*model.ColumnInfo, inde }) } - return idxParts, nil + return idxParts, mvIndex, nil } // CheckPKOnGeneratedColumn checks the specification of PK is valid. @@ -153,7 +164,7 @@ func checkIndexColumn(ctx sessionctx.Context, col *model.ColumnInfo, indexColumn } // JSON column cannot index. - if col.FieldType.GetType() == mysql.TypeJSON { + if col.FieldType.GetType() == mysql.TypeJSON && !col.FieldType.IsArray() { if col.Hidden { return dbterror.ErrFunctionalIndexOnJSONOrGeometryFunction } @@ -262,7 +273,7 @@ func BuildIndexInfo( return nil, errors.Trace(err) } - idxColumns, err := buildIndexColumns(ctx, allTableColumns, indexPartSpecifications) + idxColumns, mvIndex, err := buildIndexColumns(ctx, allTableColumns, indexPartSpecifications) if err != nil { return nil, errors.Trace(err) } @@ -275,6 +286,7 @@ func BuildIndexInfo( Primary: isPrimary, Unique: isUnique, Global: isGlobal, + MVIndex: mvIndex, } if indexOption != nil { @@ -676,6 +688,9 @@ func (w *worker) onCreateIndex(d *ddlCtx, t *meta.Meta, job *model.Job, isPK boo job.Args = []interface{}{indexInfo.ID, false /*if exists*/, getPartitionIDs(tbl.Meta())} // Finish this job. job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo) + if job.ReorgMeta.ReorgTp == model.ReorgTypeLitMerge { + ingest.LitBackCtxMgr.Unregister(job.ID) + } default: err = dbterror.ErrInvalidDDLState.GenWithStackByArgs("index", tblInfo.State) } @@ -691,15 +706,18 @@ func pickBackfillType(w *worker, job *model.Job) model.ReorgType { return job.ReorgMeta.ReorgTp } if IsEnableFastReorg() { - canUseIngest := canUseIngest(w) - if ingest.LitInitialized && canUseIngest { - job.ReorgMeta.ReorgTp = model.ReorgTypeLitMerge - return model.ReorgTypeLitMerge + var useIngest bool + if ingest.LitInitialized { + useIngest = canUseIngest(w) + if useIngest { + job.ReorgMeta.ReorgTp = model.ReorgTypeLitMerge + return model.ReorgTypeLitMerge + } } // The lightning environment is unavailable, but we can still use the txn-merge backfill. logutil.BgLogger().Info("[ddl] fallback to txn-merge backfill process", zap.Bool("lightning env initialized", ingest.LitInitialized), - zap.Bool("can use ingest", canUseIngest)) + zap.Bool("can use ingest", useIngest)) job.ReorgMeta.ReorgTp = model.ReorgTypeTxnMerge return model.ReorgTypeTxnMerge } @@ -709,6 +727,13 @@ func pickBackfillType(w *worker, job *model.Job) model.ReorgType { // canUseIngest indicates whether it can use ingest way to backfill index. func canUseIngest(w *worker) bool { + // We only allow one task to use ingest at the same time, in order to limit the CPU usage. + activeJobIDs := ingest.LitBackCtxMgr.Keys() + if len(activeJobIDs) > 0 { + logutil.BgLogger().Info("[ddl-ingest] ingest backfill is already in use by another DDL job", + zap.Int64("job ID", activeJobIDs[0])) + return false + } ctx, err := w.sessPool.get() if err != nil { return false @@ -749,12 +774,15 @@ func IngestJobsNotExisted(ctx sessionctx.Context) bool { } // tryFallbackToTxnMerge changes the reorg type to txn-merge if the lightning backfill meets something wrong. -func tryFallbackToTxnMerge(job *model.Job, err error) { +func tryFallbackToTxnMerge(job *model.Job, err error) error { if job.State != model.JobStateRollingback { logutil.BgLogger().Info("[ddl] fallback to txn-merge backfill process", zap.Error(err)) job.ReorgMeta.ReorgTp = model.ReorgTypeTxnMerge job.SnapshotVer = 0 + job.RowCount = 0 + return nil } + return err } func doReorgWorkForCreateIndexMultiSchema(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job, @@ -778,8 +806,10 @@ func doReorgWorkForCreateIndex(w *worker, d *ddlCtx, t *meta.Meta, job *model.Jo } switch indexInfo.BackfillState { case model.BackfillStateRunning: - logutil.BgLogger().Info("[ddl] index backfill state running", zap.Int64("job ID", job.ID), - zap.String("table", tbl.Meta().Name.O), zap.String("index", indexInfo.Name.O)) + logutil.BgLogger().Info("[ddl] index backfill state running", + zap.Int64("job ID", job.ID), zap.String("table", tbl.Meta().Name.O), + zap.Bool("ingest mode", bfProcess == model.ReorgTypeLitMerge), + zap.String("index", indexInfo.Name.O)) switch bfProcess { case model.ReorgTypeLitMerge: bc, ok := ingest.LitBackCtxMgr.Load(job.ID) @@ -789,17 +819,18 @@ func doReorgWorkForCreateIndex(w *worker, d *ddlCtx, t *meta.Meta, job *model.Jo if !ok && job.SnapshotVer != 0 { // The owner is crashed or changed, we need to restart the backfill. job.SnapshotVer = 0 + job.RowCount = 0 return false, ver, nil } bc, err = ingest.LitBackCtxMgr.Register(w.ctx, indexInfo.Unique, job.ID, job.ReorgMeta.SQLMode) if err != nil { - tryFallbackToTxnMerge(job, err) + err = tryFallbackToTxnMerge(job, err) return false, ver, errors.Trace(err) } done, ver, err = runReorgJobAndHandleErr(w, d, t, job, tbl, indexInfo, false) if err != nil { ingest.LitBackCtxMgr.Unregister(job.ID) - tryFallbackToTxnMerge(job, err) + err = tryFallbackToTxnMerge(job, err) return false, ver, errors.Trace(err) } if !done { @@ -807,12 +838,15 @@ func doReorgWorkForCreateIndex(w *worker, d *ddlCtx, t *meta.Meta, job *model.Jo } err = bc.FinishImport(indexInfo.ID, indexInfo.Unique, tbl) if err != nil { - if kv.ErrKeyExists.Equal(err) { + if kv.ErrKeyExists.Equal(err) || common.ErrFoundDuplicateKeys.Equal(err) { logutil.BgLogger().Warn("[ddl] import index duplicate key, convert job to rollback", zap.String("job", job.String()), zap.Error(err)) + if common.ErrFoundDuplicateKeys.Equal(err) { + err = convertToKeyExistsErr(err, indexInfo, tbl.Meta()) + } ver, err = convertAddIdxJob2RollbackJob(d, t, job, tbl.Meta(), indexInfo, err) } else { logutil.BgLogger().Warn("[ddl] lightning import error", zap.Error(err)) - tryFallbackToTxnMerge(job, err) + err = tryFallbackToTxnMerge(job, err) } ingest.LitBackCtxMgr.Unregister(job.ID) return false, ver, errors.Trace(err) @@ -843,17 +877,44 @@ func doReorgWorkForCreateIndex(w *worker, d *ddlCtx, t *meta.Meta, job *model.Jo return false, ver, err } indexInfo.BackfillState = model.BackfillStateInapplicable // Prevent double-write on this index. - return true, ver, nil + ver, err = updateVersionAndTableInfo(d, t, job, tbl.Meta(), true) + return true, ver, err default: return false, 0, dbterror.ErrInvalidDDLState.GenWithStackByArgs("backfill", indexInfo.BackfillState) } } +func convertToKeyExistsErr(originErr error, idxInfo *model.IndexInfo, tblInfo *model.TableInfo) error { + tErr, ok := errors.Cause(originErr).(*terror.Error) + if !ok { + return originErr + } + if len(tErr.Args()) != 2 { + return originErr + } + key, keyIsByte := tErr.Args()[0].([]byte) + value, valIsByte := tErr.Args()[1].([]byte) + if !keyIsByte || !valIsByte { + return originErr + } + return genKeyExistsErr(key, value, idxInfo, tblInfo) +} + func runReorgJobAndHandleErr(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job, tbl table.Table, indexInfo *model.IndexInfo, mergingTmpIdx bool) (done bool, ver int64, err error) { elements := []*meta.Element{{ID: indexInfo.ID, TypeKey: meta.IndexElementKey}} - rh := newReorgHandler(t, w.sess, w.concurrentDDL) - reorgInfo, err := getReorgInfo(d.jobContext(job), d, rh, job, tbl, elements, mergingTmpIdx) + sctx, err1 := w.sessPool.get() + if err1 != nil { + err = err1 + return + } + defer w.sessPool.put(sctx) + rh := newReorgHandler(newSession(sctx)) + dbInfo, err := t.GetDatabase(job.SchemaID) + if err != nil { + return false, ver, errors.Trace(err) + } + reorgInfo, err := getReorgInfo(d.jobContext(job.ID), d, rh, job, dbInfo, tbl, elements, mergingTmpIdx) if err != nil || reorgInfo.first { // If we run reorg firstly, we should update the job snapshot version // and then run the reorg next time. @@ -949,6 +1010,9 @@ func onDropIndex(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { // Finish this job. if job.IsRollingback() { job.FinishTableJob(model.JobStateRollbackDone, model.StateNone, ver, tblInfo) + if job.ReorgMeta.ReorgTp == model.ReorgTypeLitMerge { + ingest.LitBackCtxMgr.Unregister(job.ID) + } job.Args[0] = indexInfo.ID } else { // the partition ids were append by convertAddIdxJob2RollbackJob, it is weird, but for the compatibility, @@ -1155,9 +1219,10 @@ type indexRecord struct { } type baseIndexWorker struct { - *backfillWorker + *backfillCtx indexes []table.Index + tp backfillerType metricCounter prometheus.Counter // The following attributes are used to reduce memory allocation. @@ -1166,43 +1231,43 @@ type baseIndexWorker struct { rowMap map[int64]types.Datum rowDecoder *decoder.RowDecoder - sqlMode mysql.SQLMode jobContext *JobContext } type addIndexWorker struct { baseIndexWorker - index table.Index - writerCtx *ingest.WriterContext + index table.Index + writerCtx *ingest.WriterContext + copReqSenderPool *copReqSenderPool // The following attributes are used to reduce memory allocation. idxKeyBufs [][]byte batchCheckKeys []kv.Key + batchCheckValues [][]byte distinctCheckFlags []bool } -func newAddIndexWorker(sessCtx sessionctx.Context, id int, t table.PhysicalTable, decodeColMap map[int64]decoder.Column, - reorgInfo *reorgInfo, jc *JobContext, job *model.Job) (*addIndexWorker, error) { - if !bytes.Equal(reorgInfo.currElement.TypeKey, meta.IndexElementKey) { - logutil.BgLogger().Error("Element type for addIndexWorker incorrect", zap.String("jobQuery", reorgInfo.Query), - zap.String("reorgInfo", reorgInfo.String())) - return nil, errors.Errorf("element type is not index, typeKey: %v", reorgInfo.currElement.TypeKey) +func newAddIndexWorker(decodeColMap map[int64]decoder.Column, id int, t table.PhysicalTable, bfCtx *backfillCtx, jc *JobContext, jobID, eleID int64, eleTypeKey []byte) (*addIndexWorker, error) { + if !bytes.Equal(eleTypeKey, meta.IndexElementKey) { + logutil.BgLogger().Error("Element type for addIndexWorker incorrect", zap.String("jobQuery", jc.cacheSQL), + zap.Int64("job ID", jobID), zap.ByteString("element type", eleTypeKey), zap.Int64("element ID", eleID)) + return nil, errors.Errorf("element type is not index, typeKey: %v", eleTypeKey) } - indexInfo := model.FindIndexInfoByID(t.Meta().Indices, reorgInfo.currElement.ID) + indexInfo := model.FindIndexInfoByID(t.Meta().Indices, eleID) index := tables.NewIndex(t.GetPhysicalID(), t.Meta(), indexInfo) rowDecoder := decoder.NewRowDecoder(t, t.WritableCols(), decodeColMap) var lwCtx *ingest.WriterContext - if job.ReorgMeta.ReorgTp == model.ReorgTypeLitMerge { - bc, ok := ingest.LitBackCtxMgr.Load(job.ID) + if bfCtx.reorgTp == model.ReorgTypeLitMerge { + bc, ok := ingest.LitBackCtxMgr.Load(jobID) if !ok { return nil, errors.Trace(errors.New(ingest.LitErrGetBackendFail)) } - ei, err := bc.EngMgr.Register(bc, job, reorgInfo.currElement.ID) + ei, err := bc.EngMgr.Register(bc, jobID, eleID, bfCtx.schemaName, t.Meta().Name.O) if err != nil { - return nil, errors.Trace(errors.New(ingest.LitErrCreateEngineFail)) + return nil, errors.Trace(err) } - lwCtx, err = ei.NewWriterCtx(id) + lwCtx, err = ei.NewWriterCtx(id, indexInfo.Unique) if err != nil { return nil, err } @@ -1210,14 +1275,13 @@ func newAddIndexWorker(sessCtx sessionctx.Context, id int, t table.PhysicalTable return &addIndexWorker{ baseIndexWorker: baseIndexWorker{ - backfillWorker: newBackfillWorker(sessCtx, id, t, reorgInfo, typeAddIndexWorker), - indexes: []table.Index{index}, - rowDecoder: rowDecoder, - defaultVals: make([]types.Datum, len(t.WritableCols())), - rowMap: make(map[int64]types.Datum, len(decodeColMap)), - metricCounter: metrics.BackfillTotalCounter.WithLabelValues(metrics.GenerateReorgLabel("add_idx_rate", reorgInfo.SchemaName, t.Meta().Name.String())), - sqlMode: reorgInfo.ReorgMeta.SQLMode, - jobContext: jc, + backfillCtx: bfCtx, + indexes: []table.Index{index}, + rowDecoder: rowDecoder, + defaultVals: make([]types.Datum, len(t.WritableCols())), + rowMap: make(map[int64]types.Datum, len(decodeColMap)), + metricCounter: metrics.BackfillTotalCounter.WithLabelValues(metrics.GenerateReorgLabel("add_idx_rate", bfCtx.schemaName, t.Meta().Name.String())), + jobContext: jc, }, index: index, writerCtx: lwCtx, @@ -1228,6 +1292,59 @@ func (w *baseIndexWorker) AddMetricInfo(cnt float64) { w.metricCounter.Add(cnt) } +func (*baseIndexWorker) GetTask() (*BackfillJob, error) { + return nil, nil +} + +func (w *baseIndexWorker) String() string { + return w.tp.String() +} + +func (w *baseIndexWorker) UpdateTask(bfJob *BackfillJob) error { + s := newSession(w.backfillCtx.sessCtx) + + return s.runInTxn(func(se *session) error { + jobs, err := GetBackfillJobs(se, BackfillTable, fmt.Sprintf("ddl_job_id = %d and ele_id = %d and ele_key = '%s' and id = %d", + bfJob.JobID, bfJob.EleID, bfJob.EleKey, bfJob.ID), "update_backfill_task") + if err != nil { + return err + } + if len(jobs) == 0 { + return dbterror.ErrDDLJobNotFound.FastGen("get zero backfill job") + } + if jobs[0].InstanceID != bfJob.InstanceID { + return dbterror.ErrDDLJobNotFound.FastGenByArgs(fmt.Sprintf("get a backfill job %v, want instance ID %s", jobs[0], bfJob.InstanceID)) + } + + currTime, err := GetOracleTimeWithStartTS(se) + if err != nil { + return err + } + bfJob.InstanceLease = GetLeaseGoTime(currTime, InstanceLease) + return updateBackfillJob(se, BackfillTable, bfJob, "update_backfill_task") + }) +} + +func (w *baseIndexWorker) FinishTask(bfJob *BackfillJob) error { + s := newSession(w.backfillCtx.sessCtx) + return s.runInTxn(func(se *session) error { + txn, err := se.txn() + if err != nil { + return errors.Trace(err) + } + bfJob.FinishTS = txn.StartTS() + err = RemoveBackfillJob(se, false, bfJob) + if err != nil { + return err + } + return AddBackfillHistoryJob(se, []*BackfillJob{bfJob}) + }) +} + +func (w *baseIndexWorker) GetCtx() *backfillCtx { + return w.backfillCtx +} + // mockNotOwnerErrOnce uses to make sure `notOwnerErr` only mock error once. var mockNotOwnerErrOnce uint32 @@ -1241,7 +1358,7 @@ func (w *baseIndexWorker) getIndexRecord(idxInfo *model.IndexInfo, handle kv.Han failpoint.Return(nil, errors.Trace(dbterror.ErrCantDecodeRecord.GenWithStackByArgs("index", errors.New("mock can't decode record error")))) case "modifyColumnNotOwnerErr": - if idxInfo.Name.O == "_Idx$_idx" && handle.IntValue() == 7168 && atomic.CompareAndSwapUint32(&mockNotOwnerErrOnce, 0, 1) { + if idxInfo.Name.O == "_Idx$_idx_0" && handle.IntValue() == 7168 && atomic.CompareAndSwapUint32(&mockNotOwnerErrOnce, 0, 1) { failpoint.Return(nil, errors.Trace(dbterror.ErrNotOwner)) } case "addIdxNotOwnerErr": @@ -1270,7 +1387,7 @@ func (w *baseIndexWorker) getIndexRecord(idxInfo *model.IndexInfo, handle kv.Han idxVal[j] = idxColumnVal } - rsData := tables.TryGetHandleRestoredDataWrapper(w.table, nil, w.rowMap, idxInfo) + rsData := tables.TryGetHandleRestoredDataWrapper(w.table.Meta(), nil, w.rowMap, idxInfo) idxRecord := &indexRecord{handle: handle, key: recordKey, vals: idxVal, rsData: rsData} return idxRecord, nil } @@ -1289,7 +1406,10 @@ func (w *baseIndexWorker) getNextKey(taskRange reorgBackfillTask, taskDone bool) recordKey := tablecodec.EncodeRecordKey(w.table.RecordPrefix(), lastHandle) return recordKey.Next() } - return taskRange.endKey.Next() + if taskRange.endInclude { + return taskRange.endKey.Next() + } + return taskRange.endKey } func (w *baseIndexWorker) updateRowDecoder(handle kv.Handle, rawRecord []byte) error { @@ -1315,8 +1435,9 @@ func (w *baseIndexWorker) fetchRowColVals(txn kv.Transaction, taskRange reorgBac // taskDone means that the reorged handle is out of taskRange.endHandle. taskDone := false oprStartTime := startTime - err := iterateSnapshotKeys(w.reorgInfo.d.jobContext(w.reorgInfo.Job), w.sessCtx.GetStore(), w.priority, w.table.RecordPrefix(), txn.StartTS(), taskRange.startKey, taskRange.endKey, - func(handle kv.Handle, recordKey kv.Key, rawRow []byte) (bool, error) { + jobID := taskRange.getJobID() + err := iterateSnapshotKeys(w.GetCtx().jobContext(jobID), w.sessCtx.GetStore(), taskRange.priority, taskRange.physicalTable.RecordPrefix(), txn.StartTS(), + taskRange.startKey, taskRange.endKey, func(handle kv.Handle, recordKey kv.Key, rawRow []byte) (bool, error) { oprEndTime := time.Now() logSlowOperations(oprEndTime.Sub(oprStartTime), "iterateSnapshotKeys in baseIndexWorker fetchRowColVals", 0) oprStartTime = oprEndTime @@ -1369,6 +1490,7 @@ func (w *addIndexWorker) initBatchCheckBufs(batchCount int) { } w.batchCheckKeys = w.batchCheckKeys[:0] + w.batchCheckValues = w.batchCheckValues[:0] w.distinctCheckFlags = w.distinctCheckFlags[:0] } @@ -1384,22 +1506,34 @@ func (w *addIndexWorker) checkHandleExists(key kv.Key, value []byte, handle kv.H if hasBeenBackFilled { return nil } + return genKeyExistsErr(key, value, idxInfo, tblInfo) +} + +func genKeyExistsErr(key, value []byte, idxInfo *model.IndexInfo, tblInfo *model.TableInfo) error { + idxColLen := len(idxInfo.Columns) + indexName := fmt.Sprintf("%s.%s", tblInfo.Name.String(), idxInfo.Name.String()) colInfos := tables.BuildRowcodecColInfoForIndexColumns(idxInfo, tblInfo) values, err := tablecodec.DecodeIndexKV(key, value, idxColLen, tablecodec.HandleNotNeeded, colInfos) if err != nil { - return err + logutil.BgLogger().Warn("decode index key value failed", zap.String("index", indexName), + zap.String("key", hex.EncodeToString(key)), zap.String("value", hex.EncodeToString(value)), zap.Error(err)) + return kv.ErrKeyExists.FastGenByArgs(key, indexName) } - indexName := w.index.Meta().Name.String() valueStr := make([]string, 0, idxColLen) for i, val := range values[:idxColLen] { d, err := tablecodec.DecodeColumnValue(val, colInfos[i].Ft, time.Local) if err != nil { - return kv.ErrKeyExists.FastGenByArgs(key.String(), indexName) + logutil.BgLogger().Warn("decode column value failed", zap.String("index", indexName), + zap.String("key", hex.EncodeToString(key)), zap.String("value", hex.EncodeToString(value)), zap.Error(err)) + return kv.ErrKeyExists.FastGenByArgs(key, indexName) } str, err := d.ToString() if err != nil { str = string(val) } + if types.IsBinaryStr(colInfos[i].Ft) || types.IsTypeBit(colInfos[i].Ft) { + str = util.FmtNonASCIIPrintableCharToHex(str) + } valueStr = append(valueStr, str) } return kv.ErrKeyExists.FastGenByArgs(strings.Join(valueStr, "-"), indexName) @@ -1415,16 +1549,28 @@ func (w *addIndexWorker) batchCheckUniqueKey(txn kv.Transaction, idxRecords []*i w.initBatchCheckBufs(len(idxRecords)) stmtCtx := w.sessCtx.GetSessionVars().StmtCtx + cnt := 0 for i, record := range idxRecords { - idxKey, distinct, err := w.index.GenIndexKey(stmtCtx, record.vals, record.handle, w.idxKeyBufs[i]) - if err != nil { - return errors.Trace(err) + iter := w.index.GenIndexKVIter(stmtCtx, record.vals, record.handle, idxRecords[i].rsData) + for iter.Valid() { + var buf []byte + if cnt < len(w.idxKeyBufs) { + buf = w.idxKeyBufs[cnt] + } + key, val, distinct, err := iter.Next(buf) + if err != nil { + return errors.Trace(err) + } + if cnt < len(w.idxKeyBufs) { + w.idxKeyBufs[cnt] = key + } else { + w.idxKeyBufs = append(w.idxKeyBufs, key) + } + cnt++ + w.batchCheckKeys = append(w.batchCheckKeys, key) + w.batchCheckValues = append(w.batchCheckValues, val) + w.distinctCheckFlags = append(w.distinctCheckFlags, distinct) } - // save the buffer to reduce memory allocations. - w.idxKeyBufs[i] = idxKey - - w.batchCheckKeys = append(w.batchCheckKeys, idxKey) - w.distinctCheckFlags = append(w.distinctCheckFlags, distinct) } batchVals, err := txn.BatchGet(context.Background(), w.batchCheckKeys) @@ -1446,12 +1592,7 @@ func (w *addIndexWorker) batchCheckUniqueKey(txn kv.Transaction, idxRecords []*i } else if w.distinctCheckFlags[i] { // The keys in w.batchCheckKeys also maybe duplicate, // so we need to backfill the not found key into `batchVals` map. - needRsData := tables.NeedRestoredData(w.index.Meta().Columns, w.table.Meta().Columns) - val, err := tablecodec.GenIndexValuePortal(stmtCtx, w.table.Meta(), w.index.Meta(), needRsData, w.distinctCheckFlags[i], false, idxRecords[i].vals, idxRecords[i].handle, 0, idxRecords[i].rsData) - if err != nil { - return errors.Trace(err) - } - batchVals[string(key)] = val + batchVals[string(key)] = w.batchCheckValues[i] } } // Constrains is already checked. @@ -1473,16 +1614,28 @@ func (w *addIndexWorker) BackfillDataInTxn(handleRange reorgBackfillTask) (taskC needMergeTmpIdx := w.index.Meta().BackfillState != model.BackfillStateInapplicable oprStartTime := time.Now() + jobID := handleRange.getJobID() ctx := kv.WithInternalSourceType(context.Background(), w.jobContext.ddlJobSourceType()) - errInTxn = kv.RunInNewTxn(ctx, w.sessCtx.GetStore(), true, func(ctx context.Context, txn kv.Transaction) error { + errInTxn = kv.RunInNewTxn(ctx, w.sessCtx.GetStore(), true, func(ctx context.Context, txn kv.Transaction) (err error) { taskCtx.addedCount = 0 taskCtx.scanCount = 0 - txn.SetOption(kv.Priority, w.priority) - if tagger := w.reorgInfo.d.getResourceGroupTaggerForTopSQL(w.reorgInfo.Job); tagger != nil { + txn.SetOption(kv.Priority, handleRange.priority) + if tagger := w.GetCtx().getResourceGroupTaggerForTopSQL(jobID); tagger != nil { txn.SetOption(kv.ResourceGroupTagger, tagger) } - idxRecords, nextKey, taskDone, err := w.fetchRowColVals(txn, handleRange) + var ( + idxRecords []*indexRecord + copChunk *chunk.Chunk // only used by the coprocessor request sender. + nextKey kv.Key + taskDone bool + ) + if w.copReqSenderPool != nil { + idxRecords, copChunk, nextKey, taskDone, err = w.copReqSenderPool.fetchRowColValsFromCop(handleRange) + defer w.copReqSenderPool.recycleIdxRecordsAndChunk(idxRecords, copChunk) + } else { + idxRecords, nextKey, taskDone, err = w.fetchRowColVals(txn, handleRange) + } if err != nil { return errors.Trace(err) } @@ -1527,19 +1680,18 @@ func (w *addIndexWorker) BackfillDataInTxn(handleRange reorgBackfillTask) (taskC } else { // The lightning environment is ready. vars := w.sessCtx.GetSessionVars() sCtx, writeBufs := vars.StmtCtx, vars.GetWriteStmtBufs() - key, distinct, err := w.index.GenIndexKey(sCtx, idxRecord.vals, idxRecord.handle, writeBufs.IndexKeyBuf) - if err != nil { - return errors.Trace(err) - } - idxVal, err := w.index.GenIndexValue(sCtx, distinct, idxRecord.vals, idxRecord.handle, idxRecord.rsData) - if err != nil { - return errors.Trace(err) - } - err = w.writerCtx.WriteRow(key, idxVal) - if err != nil { - return errors.Trace(err) + iter := w.index.GenIndexKVIter(sCtx, idxRecord.vals, idxRecord.handle, idxRecord.rsData) + for iter.Valid() { + key, idxVal, _, err := iter.Next(writeBufs.IndexKeyBuf) + if err != nil { + return errors.Trace(err) + } + err = w.writerCtx.WriteRow(key, idxVal) + if err != nil { + return errors.Trace(err) + } + writeBufs.IndexKeyBuf = key } - writeBufs.IndexKeyBuf = key } taskCtx.addedCount++ } @@ -1547,10 +1699,18 @@ func (w *addIndexWorker) BackfillDataInTxn(handleRange reorgBackfillTask) (taskC return nil }) logSlowOperations(time.Since(oprStartTime), "AddIndexBackfillDataInTxn", 3000) - + failpoint.Inject("mockDMLExecution", func(val failpoint.Value) { + //nolint:forcetypeassert + if val.(bool) && MockDMLExecution != nil { + MockDMLExecution() + } + }) return } +// MockDMLExecution is only used for test. +var MockDMLExecution func() + func (w *worker) addPhysicalTableIndex(t table.PhysicalTable, reorgInfo *reorgInfo) error { if reorgInfo.mergingTmpIdx { logutil.BgLogger().Info("[ddl] start to merge temp index", zap.String("job", reorgInfo.Job.String()), zap.String("reorgInfo", reorgInfo.String())) @@ -1581,7 +1741,18 @@ func (w *worker) addTableIndex(t table.Table, reorgInfo *reorgInfo) error { } } else { //nolint:forcetypeassert - err = w.addPhysicalTableIndex(t.(table.PhysicalTable), reorgInfo) + phyTbl := t.(table.PhysicalTable) + // TODO: Support typeAddIndexMergeTmpWorker and partitionTable. + isDistReorg := variable.DDLEnableDistributeReorg.Load() + if isDistReorg && !reorgInfo.mergingTmpIdx { + sCtx, err := w.sessPool.get() + if err != nil { + return errors.Trace(err) + } + defer w.sessPool.put(sCtx) + return w.controlWritePhysicalTableRecord(newSession(sCtx), phyTbl, typeAddIndexWorker, reorgInfo) + } + err = w.addPhysicalTableIndex(phyTbl, reorgInfo) } return errors.Trace(err) } @@ -1595,7 +1766,16 @@ func (w *worker) updateReorgInfo(t table.PartitionedTable, reorg *reorgInfo) (bo return true, nil } - pid, err := findNextPartitionID(reorg.PhysicalTableID, pi.Definitions) + // During data copying, copy data from partitions to be dropped + nextPartitionDefs := pi.DroppingDefinitions + if bytes.Equal(reorg.currElement.TypeKey, meta.IndexElementKey) { + // During index re-creation, process data from partitions to be added + nextPartitionDefs = pi.AddingDefinitions + } + if nextPartitionDefs == nil { + nextPartitionDefs = pi.Definitions + } + pid, err := findNextPartitionID(reorg.PhysicalTableID, nextPartitionDefs) if err != nil { // Fatal error, should not run here. logutil.BgLogger().Error("[ddl] find next partition ID failed", zap.Reflect("table", t), zap.Error(err)) @@ -1624,7 +1804,7 @@ func (w *worker) updateReorgInfo(t table.PartitionedTable, reorg *reorgInfo) (bo if err != nil { return false, errors.Trace(err) } - start, end, err := getTableRange(reorg.d.jobContext(reorg.Job), reorg.d, t.GetPartition(pid), currentVer.Ver, reorg.Job.Priority) + start, end, err := getTableRange(reorg.d.jobContext(reorg.Job.ID), reorg.d, t.GetPartition(pid), currentVer.Ver, reorg.Job.Priority) if err != nil { return false, errors.Trace(err) } @@ -1695,7 +1875,7 @@ type cleanUpIndexWorker struct { baseIndexWorker } -func newCleanUpIndexWorker(sessCtx sessionctx.Context, id int, t table.PhysicalTable, decodeColMap map[int64]decoder.Column, reorgInfo *reorgInfo, jc *JobContext) *cleanUpIndexWorker { +func newCleanUpIndexWorker(sessCtx sessionctx.Context, t table.PhysicalTable, decodeColMap map[int64]decoder.Column, reorgInfo *reorgInfo, jc *JobContext) *cleanUpIndexWorker { indexes := make([]table.Index, 0, len(t.Indices())) rowDecoder := decoder.NewRowDecoder(t, t.WritableCols(), decodeColMap) for _, index := range t.Indices() { @@ -1705,14 +1885,13 @@ func newCleanUpIndexWorker(sessCtx sessionctx.Context, id int, t table.PhysicalT } return &cleanUpIndexWorker{ baseIndexWorker: baseIndexWorker{ - backfillWorker: newBackfillWorker(sessCtx, id, t, reorgInfo, typeCleanUpIndexWorker), - indexes: indexes, - rowDecoder: rowDecoder, - defaultVals: make([]types.Datum, len(t.WritableCols())), - rowMap: make(map[int64]types.Datum, len(decodeColMap)), - metricCounter: metrics.BackfillTotalCounter.WithLabelValues(metrics.GenerateReorgLabel("cleanup_idx_rate", reorgInfo.SchemaName, t.Meta().Name.String())), - sqlMode: reorgInfo.ReorgMeta.SQLMode, - jobContext: jc, + backfillCtx: newBackfillCtx(reorgInfo.d, sessCtx, reorgInfo.ReorgMeta.ReorgTp, reorgInfo.SchemaName, t), + indexes: indexes, + rowDecoder: rowDecoder, + defaultVals: make([]types.Datum, len(t.WritableCols())), + rowMap: make(map[int64]types.Datum, len(decodeColMap)), + metricCounter: metrics.BackfillTotalCounter.WithLabelValues(metrics.GenerateReorgLabel("cleanup_idx_rate", reorgInfo.SchemaName, t.Meta().Name.String())), + jobContext: jc, }, } } @@ -1730,8 +1909,8 @@ func (w *cleanUpIndexWorker) BackfillDataInTxn(handleRange reorgBackfillTask) (t errInTxn = kv.RunInNewTxn(ctx, w.sessCtx.GetStore(), true, func(ctx context.Context, txn kv.Transaction) error { taskCtx.addedCount = 0 taskCtx.scanCount = 0 - txn.SetOption(kv.Priority, w.priority) - if tagger := w.reorgInfo.d.getResourceGroupTaggerForTopSQL(w.reorgInfo.Job); tagger != nil { + txn.SetOption(kv.Priority, handleRange.priority) + if tagger := w.GetCtx().getResourceGroupTaggerForTopSQL(handleRange.getJobID()); tagger != nil { txn.SetOption(kv.ResourceGroupTagger, tagger) } @@ -1814,7 +1993,7 @@ func (w *worker) updateReorgInfoForPartitions(t table.PartitionedTable, reorg *r if err != nil { return false, errors.Trace(err) } - start, end, err := getTableRange(reorg.d.jobContext(reorg.Job), reorg.d, t.GetPartition(pid), currentVer.Ver, reorg.Job.Priority) + start, end, err := getTableRange(reorg.d.jobContext(reorg.Job.ID), reorg.d, t.GetPartition(pid), currentVer.Ver, reorg.Job.Priority) if err != nil { return false, errors.Trace(err) } @@ -1822,10 +2001,10 @@ func (w *worker) updateReorgInfoForPartitions(t table.PartitionedTable, reorg *r // Write the reorg info to store so the whole reorganize process can recover from panic. err = reorg.UpdateReorgMeta(reorg.StartKey, w.sessPool) - logutil.BgLogger().Info("[ddl] job update reorgInfo", zap.Int64("jobID", reorg.Job.ID), - zap.ByteString("elementType", reorg.currElement.TypeKey), zap.Int64("elementID", reorg.currElement.ID), - zap.Int64("partitionTableID", pid), zap.String("startHandle", tryDecodeToHandleString(start)), - zap.String("endHandle", tryDecodeToHandleString(end)), zap.Error(err)) + logutil.BgLogger().Info("[ddl] job update reorg info", zap.Int64("jobID", reorg.Job.ID), + zap.Stringer("element", reorg.currElement), + zap.Int64("partition table ID", pid), zap.String("start key", hex.EncodeToString(start)), + zap.String("end key", hex.EncodeToString(end)), zap.Error(err)) return false, errors.Trace(err) } diff --git a/ddl/index_change_test.go b/ddl/index_change_test.go index b5d2c9d6ce983..f9dcc99154dc5 100644 --- a/ddl/index_change_test.go +++ b/ddl/index_change_test.go @@ -219,6 +219,7 @@ func checkAddWriteOnlyForAddIndex(ctx sessionctx.Context, delOnlyTbl, writeOnlyT } func checkAddPublicForAddIndex(ctx sessionctx.Context, writeTbl, publicTbl table.Table) error { + var err1 error // WriteOnlyTable: insert t values (6, 6) err := sessiontxn.NewTxn(context.Background(), ctx) if err != nil { @@ -229,7 +230,11 @@ func checkAddPublicForAddIndex(ctx sessionctx.Context, writeTbl, publicTbl table return errors.Trace(err) } err = checkIndexExists(ctx, publicTbl, 6, 6, true) - if err != nil { + if ddl.IsEnableFastReorg() { + // Need check temp index also. + err1 = checkIndexExists(ctx, writeTbl, 6, 6, true) + } + if err != nil && err1 != nil { return errors.Trace(err) } // PublicTable: insert t values (7, 7) @@ -248,10 +253,18 @@ func checkAddPublicForAddIndex(ctx sessionctx.Context, writeTbl, publicTbl table return errors.Trace(err) } err = checkIndexExists(ctx, publicTbl, 5, 7, true) - if err != nil { + if ddl.IsEnableFastReorg() { + // Need check temp index also. + err1 = checkIndexExists(ctx, writeTbl, 5, 7, true) + } + if err != nil && err1 != nil { return errors.Trace(err) } - err = checkIndexExists(ctx, publicTbl, 7, 7, false) + if ddl.IsEnableFastReorg() { + err = checkIndexExists(ctx, writeTbl, 7, 7, false) + } else { + err = checkIndexExists(ctx, publicTbl, 7, 7, false) + } if err != nil { return errors.Trace(err) } @@ -281,7 +294,11 @@ func checkAddPublicForAddIndex(ctx sessionctx.Context, writeTbl, publicTbl table idxVal := row[1].GetInt64() handle := row[0].GetInt64() err = checkIndexExists(ctx, publicTbl, idxVal, handle, true) - if err != nil { + if ddl.IsEnableFastReorg() { + // Need check temp index also. + err1 = checkIndexExists(ctx, writeTbl, idxVal, handle, true) + } + if err != nil && err1 != nil { return errors.Trace(err) } } diff --git a/ddl/index_cop.go b/ddl/index_cop.go new file mode 100644 index 0000000000000..fab097727139b --- /dev/null +++ b/ddl/index_cop.go @@ -0,0 +1,546 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl + +import ( + "context" + "sync" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/distsql" + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/table" + "github.com/pingcap/tidb/table/tables" + "github.com/pingcap/tidb/tablecodec" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/collate" + "github.com/pingcap/tidb/util/dbterror" + "github.com/pingcap/tidb/util/generic" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/timeutil" + "github.com/pingcap/tipb/go-tipb" + "go.uber.org/zap" +) + +// copReadBatchSize is the batch size of coprocessor read. +// It multiplies the tidb_ddl_reorg_batch_size by 10 to avoid +// sending too many cop requests for the same handle range. +func copReadBatchSize() int { + return 10 * int(variable.GetDDLReorgBatchSize()) +} + +// copReadChunkPoolSize is the size of chunk pool, which +// represents the max concurrent ongoing coprocessor requests. +// It multiplies the tidb_ddl_reorg_worker_cnt by 10. +func copReadChunkPoolSize() int { + return 10 * int(variable.GetDDLReorgWorkerCounter()) +} + +func (c *copReqSenderPool) fetchRowColValsFromCop(handleRange reorgBackfillTask) ([]*indexRecord, *chunk.Chunk, kv.Key, bool, error) { + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() + for { + select { + case rs, ok := <-c.resultsCh: + if !ok { + logutil.BgLogger().Info("[ddl-ingest] cop-response channel is closed", + zap.Int("id", handleRange.id), zap.String("task", handleRange.String())) + return nil, nil, handleRange.endKey, true, nil + } + if rs.err != nil { + return nil, nil, handleRange.startKey, false, rs.err + } + if rs.done { + logutil.BgLogger().Info("[ddl-ingest] finish a cop-request task", + zap.Int("id", rs.id), zap.Int("total", rs.total)) + c.results.Store(rs.id, struct{}{}) + } + if _, found := c.results.Load(handleRange.id); found { + logutil.BgLogger().Info("[ddl-ingest] task is found in results", + zap.Int("id", handleRange.id), zap.String("task", handleRange.String())) + c.results.Delete(handleRange.id) + return rs.records, rs.chunk, handleRange.endKey, true, nil + } + return rs.records, rs.chunk, handleRange.startKey, false, nil + case <-ticker.C: + logutil.BgLogger().Info("[ddl-ingest] cop-request result channel is empty", + zap.Int("id", handleRange.id)) + if _, found := c.results.Load(handleRange.id); found { + c.results.Delete(handleRange.id) + return nil, nil, handleRange.endKey, true, nil + } + } + } +} + +type copReqSenderPool struct { + tasksCh chan *reorgBackfillTask + resultsCh chan idxRecResult + results generic.SyncMap[int, struct{}] + + ctx context.Context + copCtx *copContext + store kv.Storage + + senders []*copReqSender + wg sync.WaitGroup + + idxBufPool chan []*indexRecord + srcChkPool chan *chunk.Chunk +} + +type copReqSender struct { + senderPool *copReqSenderPool + + ctx context.Context + cancel context.CancelFunc +} + +func (c *copReqSender) run() { + p := c.senderPool + defer p.wg.Done() + var curTaskID int + defer util.Recover(metrics.LabelDDL, "copReqSender.run", func() { + p.resultsCh <- idxRecResult{id: curTaskID, err: dbterror.ErrReorgPanic} + }, false) + for { + if util.HasCancelled(c.ctx) { + return + } + task, ok := <-p.tasksCh + if !ok { + return + } + curTaskID = task.id + logutil.BgLogger().Info("[ddl-ingest] start a cop-request task", + zap.Int("id", task.id), zap.String("task", task.String())) + ver, err := p.store.CurrentVersion(kv.GlobalTxnScope) + if err != nil { + p.resultsCh <- idxRecResult{id: task.id, err: err} + return + } + rs, err := p.copCtx.buildTableScan(p.ctx, ver.Ver, task.startKey, task.excludedEndKey()) + if err != nil { + p.resultsCh <- idxRecResult{id: task.id, err: err} + return + } + failpoint.Inject("MockCopSenderPanic", func(val failpoint.Value) { + if val.(bool) { + panic("mock panic") + } + }) + var done bool + var total int + for !done { + idxRec, srcChk := p.getIndexRecordsAndChunks() + idxRec, done, err = p.copCtx.fetchTableScanResult(p.ctx, rs, srcChk, idxRec) + if err != nil { + p.resultsCh <- idxRecResult{id: task.id, err: err} + p.recycleIdxRecordsAndChunk(idxRec, srcChk) + terror.Call(rs.Close) + return + } + total += len(idxRec) + p.resultsCh <- idxRecResult{id: task.id, records: idxRec, chunk: srcChk, done: done, total: total} + } + terror.Call(rs.Close) + } +} + +func newCopReqSenderPool(ctx context.Context, copCtx *copContext, store kv.Storage) *copReqSenderPool { + poolSize := copReadChunkPoolSize() + idxBufPool := make(chan []*indexRecord, poolSize) + srcChkPool := make(chan *chunk.Chunk, poolSize) + for i := 0; i < poolSize; i++ { + idxBufPool <- make([]*indexRecord, 0, copReadBatchSize()) + srcChkPool <- chunk.NewChunkWithCapacity(copCtx.fieldTps, copReadBatchSize()) + } + return &copReqSenderPool{ + tasksCh: make(chan *reorgBackfillTask, backfillTaskChanSize), + resultsCh: make(chan idxRecResult, backfillTaskChanSize), + results: generic.NewSyncMap[int, struct{}](10), + ctx: ctx, + copCtx: copCtx, + store: store, + senders: make([]*copReqSender, 0, variable.GetDDLReorgWorkerCounter()), + wg: sync.WaitGroup{}, + idxBufPool: idxBufPool, + srcChkPool: srcChkPool, + } +} + +func (c *copReqSenderPool) sendTask(task *reorgBackfillTask) { + c.tasksCh <- task +} + +func (c *copReqSenderPool) adjustSize(n int) { + // Add some senders. + for i := len(c.senders); i < n; i++ { + ctx, cancel := context.WithCancel(c.ctx) + c.senders = append(c.senders, &copReqSender{ + senderPool: c, + ctx: ctx, + cancel: cancel, + }) + c.wg.Add(1) + go c.senders[i].run() + } + // Remove some senders. + if n < len(c.senders) { + for i := n; i < len(c.senders); i++ { + c.senders[i].cancel() + } + c.senders = c.senders[:n] + } +} + +func (c *copReqSenderPool) close() { + logutil.BgLogger().Info("[ddl-ingest] close cop-request sender pool", zap.Int("results not handled", len(c.results.Keys()))) + close(c.tasksCh) + for _, w := range c.senders { + w.cancel() + } + cleanupWg := util.WaitGroupWrapper{} + cleanupWg.Run(c.drainResults) + // Wait for all cop-req senders to exit. + c.wg.Wait() + close(c.resultsCh) + cleanupWg.Wait() + close(c.idxBufPool) + close(c.srcChkPool) +} + +func (c *copReqSenderPool) drainResults() { + // Consume the rest results because the writers are inactive anymore. + for rs := range c.resultsCh { + c.recycleIdxRecordsAndChunk(rs.records, rs.chunk) + } +} + +func (c *copReqSenderPool) getIndexRecordsAndChunks() ([]*indexRecord, *chunk.Chunk) { + ir := <-c.idxBufPool + chk := <-c.srcChkPool + newCap := copReadBatchSize() + if chk.Capacity() != newCap { + chk = chunk.NewChunkWithCapacity(c.copCtx.fieldTps, newCap) + } + chk.Reset() + return ir[:0], chk +} + +// recycleIdxRecordsAndChunk puts the index record slice and the chunk back to the pool for reuse. +func (c *copReqSenderPool) recycleIdxRecordsAndChunk(idxRecs []*indexRecord, chk *chunk.Chunk) { + if idxRecs == nil || chk == nil { + return + } + c.idxBufPool <- idxRecs + c.srcChkPool <- chk +} + +// copContext contains the information that is needed when building a coprocessor request. +// It is unchanged after initialization. +type copContext struct { + tblInfo *model.TableInfo + idxInfo *model.IndexInfo + pkInfo *model.IndexInfo + colInfos []*model.ColumnInfo + fieldTps []*types.FieldType + sessCtx sessionctx.Context + + expColInfos []*expression.Column + idxColOutputOffsets []int + handleOutputOffsets []int + virtualColOffsets []int + virtualColFieldTps []*types.FieldType +} + +func newCopContext(tblInfo *model.TableInfo, idxInfo *model.IndexInfo, sessCtx sessionctx.Context) (*copContext, error) { + var err error + usedColumnIDs := make(map[int64]struct{}, len(idxInfo.Columns)) + usedColumnIDs, err = fillUsedColumns(usedColumnIDs, idxInfo, tblInfo) + var handleIDs []int64 + if err != nil { + return nil, err + } + var primaryIdx *model.IndexInfo + if tblInfo.PKIsHandle { + pkCol := tblInfo.GetPkColInfo() + usedColumnIDs[pkCol.ID] = struct{}{} + handleIDs = []int64{pkCol.ID} + } else if tblInfo.IsCommonHandle { + primaryIdx = tables.FindPrimaryIndex(tblInfo) + handleIDs = make([]int64, 0, len(primaryIdx.Columns)) + for _, pkCol := range primaryIdx.Columns { + col := tblInfo.Columns[pkCol.Offset] + handleIDs = append(handleIDs, col.ID) + } + usedColumnIDs, err = fillUsedColumns(usedColumnIDs, primaryIdx, tblInfo) + if err != nil { + return nil, err + } + } + + // Only collect the columns that are used by the index. + colInfos := make([]*model.ColumnInfo, 0, len(idxInfo.Columns)) + fieldTps := make([]*types.FieldType, 0, len(idxInfo.Columns)) + for i := range tblInfo.Columns { + col := tblInfo.Columns[i] + if _, found := usedColumnIDs[col.ID]; found { + colInfos = append(colInfos, col) + fieldTps = append(fieldTps, &col.FieldType) + } + } + + // Append the extra handle column when _tidb_rowid is used. + if !tblInfo.HasClusteredIndex() { + extra := model.NewExtraHandleColInfo() + colInfos = append(colInfos, extra) + fieldTps = append(fieldTps, &extra.FieldType) + handleIDs = []int64{extra.ID} + } + + expColInfos, _, err := expression.ColumnInfos2ColumnsAndNames(sessCtx, + model.CIStr{} /* unused */, tblInfo.Name, colInfos, tblInfo) + if err != nil { + return nil, err + } + idxOffsets := resolveIndicesForIndex(expColInfos, idxInfo, tblInfo) + hdColOffsets := resolveIndicesForHandle(expColInfos, handleIDs) + vColOffsets, vColFts := collectVirtualColumnOffsetsAndTypes(expColInfos) + + copCtx := &copContext{ + tblInfo: tblInfo, + idxInfo: idxInfo, + pkInfo: primaryIdx, + colInfos: colInfos, + fieldTps: fieldTps, + sessCtx: sessCtx, + + expColInfos: expColInfos, + idxColOutputOffsets: idxOffsets, + handleOutputOffsets: hdColOffsets, + virtualColOffsets: vColOffsets, + virtualColFieldTps: vColFts, + } + return copCtx, nil +} + +func fillUsedColumns(usedCols map[int64]struct{}, idxInfo *model.IndexInfo, tblInfo *model.TableInfo) (map[int64]struct{}, error) { + colsToChecks := make([]*model.ColumnInfo, 0, len(idxInfo.Columns)) + for _, idxCol := range idxInfo.Columns { + colsToChecks = append(colsToChecks, tblInfo.Columns[idxCol.Offset]) + } + for len(colsToChecks) > 0 { + next := colsToChecks[0] + colsToChecks = colsToChecks[1:] + usedCols[next.ID] = struct{}{} + for depColName := range next.Dependences { + // Expand the virtual generated columns. + depCol := model.FindColumnInfo(tblInfo.Columns, depColName) + if depCol == nil { + return nil, errors.Trace(errors.Errorf("dependent column %s not found", depColName)) + } + if _, ok := usedCols[depCol.ID]; !ok { + colsToChecks = append(colsToChecks, depCol) + } + } + } + return usedCols, nil +} + +func resolveIndicesForIndex(outputCols []*expression.Column, idxInfo *model.IndexInfo, tblInfo *model.TableInfo) []int { + offsets := make([]int, 0, len(idxInfo.Columns)) + for _, idxCol := range idxInfo.Columns { + hid := tblInfo.Columns[idxCol.Offset].ID + for j, col := range outputCols { + if col.ID == hid { + offsets = append(offsets, j) + break + } + } + } + return offsets +} + +func resolveIndicesForHandle(cols []*expression.Column, handleIDs []int64) []int { + offsets := make([]int, 0, len(handleIDs)) + for _, hid := range handleIDs { + for j, col := range cols { + if col.ID == hid { + offsets = append(offsets, j) + break + } + } + } + return offsets +} + +func collectVirtualColumnOffsetsAndTypes(cols []*expression.Column) ([]int, []*types.FieldType) { + var offsets []int + var fts []*types.FieldType + for i, col := range cols { + if col.VirtualExpr != nil { + offsets = append(offsets, i) + fts = append(fts, col.GetType()) + } + } + return offsets, fts +} + +func (c *copContext) buildTableScan(ctx context.Context, startTS uint64, start, end kv.Key) (distsql.SelectResult, error) { + dagPB, err := buildDAGPB(c.sessCtx, c.tblInfo, c.colInfos) + if err != nil { + return nil, err + } + + var builder distsql.RequestBuilder + kvReq, err := builder. + SetDAGRequest(dagPB). + SetStartTS(startTS). + SetKeyRanges([]kv.KeyRange{{StartKey: start, EndKey: end}}). + SetKeepOrder(true). + SetFromSessionVars(c.sessCtx.GetSessionVars()). + SetFromInfoSchema(c.sessCtx.GetDomainInfoSchema()). + SetConcurrency(1). + Build() + if err != nil { + return nil, err + } + return distsql.Select(ctx, c.sessCtx, kvReq, c.fieldTps, statistics.NewQueryFeedback(0, nil, 0, false)) +} + +func (c *copContext) fetchTableScanResult(ctx context.Context, result distsql.SelectResult, + chk *chunk.Chunk, buf []*indexRecord) ([]*indexRecord, bool, error) { + sctx := c.sessCtx.GetSessionVars().StmtCtx + err := result.Next(ctx, chk) + if err != nil { + return nil, false, errors.Trace(err) + } + if chk.NumRows() == 0 { + return buf, true, nil + } + iter := chunk.NewIterator4Chunk(chk) + err = table.FillVirtualColumnValue(c.virtualColFieldTps, c.virtualColOffsets, c.expColInfos, c.colInfos, c.sessCtx, chk) + if err != nil { + return nil, false, errors.Trace(err) + } + for row := iter.Begin(); row != iter.End(); row = iter.Next() { + idxDt := extractDatumByOffsets(row, c.idxColOutputOffsets, c.expColInfos) + hdDt := extractDatumByOffsets(row, c.handleOutputOffsets, c.expColInfos) + handle, err := buildHandle(hdDt, c.tblInfo, c.pkInfo, sctx) + if err != nil { + return nil, false, errors.Trace(err) + } + rsData := getRestoreData(c.tblInfo, c.idxInfo, c.pkInfo, hdDt) + buf = append(buf, &indexRecord{handle: handle, key: nil, vals: idxDt, rsData: rsData, skip: false}) + } + return buf, false, nil +} + +func getRestoreData(tblInfo *model.TableInfo, targetIdx, pkIdx *model.IndexInfo, handleDts []types.Datum) []types.Datum { + if !collate.NewCollationEnabled() || !tblInfo.IsCommonHandle || tblInfo.CommonHandleVersion == 0 { + return nil + } + if pkIdx == nil { + return nil + } + for i, pkIdxCol := range pkIdx.Columns { + pkCol := tblInfo.Columns[pkIdxCol.Offset] + if !types.NeedRestoredData(&pkCol.FieldType) { + // Since the handle data cannot be null, we can use SetNull to + // indicate that this column does not need to be restored. + handleDts[i].SetNull() + continue + } + tables.TryTruncateRestoredData(&handleDts[i], pkCol, pkIdxCol, targetIdx) + tables.ConvertDatumToTailSpaceCount(&handleDts[i], pkCol) + } + dtToRestored := handleDts[:0] + for _, handleDt := range handleDts { + if !handleDt.IsNull() { + dtToRestored = append(dtToRestored, handleDt) + } + } + return dtToRestored +} + +func buildDAGPB(sCtx sessionctx.Context, tblInfo *model.TableInfo, colInfos []*model.ColumnInfo) (*tipb.DAGRequest, error) { + dagReq := &tipb.DAGRequest{} + dagReq.TimeZoneName, dagReq.TimeZoneOffset = timeutil.Zone(sCtx.GetSessionVars().Location()) + sc := sCtx.GetSessionVars().StmtCtx + dagReq.Flags = sc.PushDownFlags() + for i := range colInfos { + dagReq.OutputOffsets = append(dagReq.OutputOffsets, uint32(i)) + } + execPB, err := constructTableScanPB(sCtx, tblInfo, colInfos) + if err != nil { + return nil, err + } + dagReq.Executors = append(dagReq.Executors, execPB) + distsql.SetEncodeType(sCtx, dagReq) + return dagReq, nil +} + +func constructTableScanPB(sCtx sessionctx.Context, tblInfo *model.TableInfo, colInfos []*model.ColumnInfo) (*tipb.Executor, error) { + tblScan := tables.BuildTableScanFromInfos(tblInfo, colInfos) + tblScan.TableId = tblInfo.ID + err := tables.SetPBColumnsDefaultValue(sCtx, tblScan.Columns, colInfos) + return &tipb.Executor{Tp: tipb.ExecType_TypeTableScan, TblScan: tblScan}, err +} + +func extractDatumByOffsets(row chunk.Row, offsets []int, expCols []*expression.Column) []types.Datum { + datumBuf := make([]types.Datum, 0, len(offsets)) + for _, offset := range offsets { + c := expCols[offset] + rowDt := row.GetDatum(offset, c.GetType()) + datumBuf = append(datumBuf, rowDt) + } + return datumBuf +} + +func buildHandle(pkDts []types.Datum, tblInfo *model.TableInfo, + pkInfo *model.IndexInfo, stmtCtx *stmtctx.StatementContext) (kv.Handle, error) { + if tblInfo.IsCommonHandle { + tablecodec.TruncateIndexValues(tblInfo, pkInfo, pkDts) + handleBytes, err := codec.EncodeKey(stmtCtx, nil, pkDts...) + if err != nil { + return nil, err + } + return kv.NewCommonHandle(handleBytes) + } + return kv.IntHandle(pkDts[0].GetInt64()), nil +} + +type idxRecResult struct { + id int + records []*indexRecord + chunk *chunk.Chunk + err error + done bool + total int +} diff --git a/ddl/index_cop_test.go b/ddl/index_cop_test.go new file mode 100644 index 0000000000000..38bced0b6678d --- /dev/null +++ b/ddl/index_cop_test.go @@ -0,0 +1,101 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl_test + +import ( + "fmt" + "strconv" + "testing" + + "github.com/pingcap/tidb/ddl" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" + "github.com/stretchr/testify/require" +) + +func TestAddIndexFetchRowsFromCoprocessor(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + testFetchRows := func(db, tb, idx string) ([]kv.Handle, [][]types.Datum) { + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(tb)) + require.NoError(t, err) + tblInfo := tbl.Meta() + idxInfo := tblInfo.FindIndexByName(idx) + copCtx, err := ddl.NewCopContext4Test(tblInfo, idxInfo, tk.Session()) + require.NoError(t, err) + startKey := tbl.RecordPrefix() + endKey := startKey.PrefixNext() + txn, err := store.Begin() + require.NoError(t, err) + idxRec, done, err := ddl.FetchRowsFromCop4Test(copCtx, startKey, endKey, store, 10) + require.NoError(t, err) + require.False(t, done) + require.NoError(t, txn.Rollback()) + + handles := make([]kv.Handle, 0, len(idxRec)) + values := make([][]types.Datum, 0, len(idxRec)) + for _, rec := range idxRec { + handles = append(handles, rec.GetHandle()) + values = append(values, rec.GetIndexValues()) + } + return handles, values + } + + // Test nonclustered primary key table. + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (a bigint, b int, index idx (b));") + for i := 0; i < 8; i++ { + tk.MustExec("insert into t values (?, ?)", i, i) + } + hds, vals := testFetchRows("test", "t", "idx") + require.Len(t, hds, 8) + for i := 0; i < 8; i++ { + require.Equal(t, hds[i].IntValue(), int64(i+1)) + require.Len(t, vals[i], 1) + require.Equal(t, vals[i][0].GetInt64(), int64(i)) + } + + // Test clustered primary key table(pk_is_handle). + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (a bigint primary key, b int, index idx (b));") + for i := 0; i < 8; i++ { + tk.MustExec("insert into t values (?, ?)", i, i) + } + hds, vals = testFetchRows("test", "t", "idx") + require.Len(t, hds, 8) + for i := 0; i < 8; i++ { + require.Equal(t, hds[i].IntValue(), int64(i)) + require.Len(t, vals[i], 1) + require.Equal(t, vals[i][0].GetInt64(), int64(i)) + } + + // Test clustered primary key table(common_handle). + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (a varchar(10), b int, c char(10), primary key (a, c) clustered, index idx (b));") + for i := 0; i < 8; i++ { + tk.MustExec("insert into t values (?, ?, ?)", strconv.Itoa(i), i, strconv.Itoa(i)) + } + hds, vals = testFetchRows("test", "t", "idx") + require.Len(t, hds, 8) + for i := 0; i < 8; i++ { + require.Equal(t, hds[i].String(), fmt.Sprintf("{%d, %d}", i, i)) + require.Len(t, vals[i], 1) + require.Equal(t, vals[i][0].GetInt64(), int64(i)) + } +} diff --git a/ddl/index_merge_tmp.go b/ddl/index_merge_tmp.go index 9159b47c47951..302bb6a50a620 100644 --- a/ddl/index_merge_tmp.go +++ b/ddl/index_merge_tmp.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" - "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/table/tables" @@ -49,16 +48,12 @@ func (w *mergeIndexWorker) batchCheckTemporaryUniqueKey(txn kv.Transaction, idxR return errors.Trace(err) } - // 1. unique-key/primary-key is duplicate and the handle is equal, skip it. - // 2. unique-key/primary-key is duplicate and the handle is not equal, return duplicate error. - // 3. non-unique-key is duplicate, skip it. for i, key := range w.originIdxKeys { if val, found := batchVals[string(key)]; found { - if idxRecords[i].distinct && !bytes.Equal(val, idxRecords[i].vals) { - return kv.ErrKeyExists - } - if !idxRecords[i].delete { - idxRecords[i].skip = true + // Found a value in the original index key. + err := checkTempIndexKey(txn, idxRecords[i], val, w.table) + if err != nil { + return errors.Trace(err) } } else if idxRecords[i].distinct { // The keys in w.batchCheckKeys also maybe duplicate, @@ -69,6 +64,48 @@ func (w *mergeIndexWorker) batchCheckTemporaryUniqueKey(txn kv.Transaction, idxR return nil } +func checkTempIndexKey(txn kv.Transaction, tmpRec *temporaryIndexRecord, originIdxVal []byte, tblInfo table.Table) error { + if !tmpRec.delete { + if tmpRec.distinct && !bytes.Equal(originIdxVal, tmpRec.vals) { + return kv.ErrKeyExists + } + // The key has been found in the original index, skip merging it. + tmpRec.skip = true + return nil + } + // Delete operation. + distinct := tablecodec.IndexKVIsUnique(originIdxVal) + if !distinct { + // For non-distinct key, it is consist of a null value and the handle. + // Same as the non-unique indexes, replay the delete operation on non-distinct keys. + return nil + } + // For distinct index key values, prevent deleting an unexpected index KV in original index. + hdInVal, err := tablecodec.DecodeHandleInUniqueIndexValue(originIdxVal, tblInfo.Meta().IsCommonHandle) + if err != nil { + return errors.Trace(err) + } + if !tmpRec.handle.Equal(hdInVal) { + // The inequality means multiple modifications happened in the same key. + // We use the handle in origin index value to check if the row exists. + rowKey := tablecodec.EncodeRecordKey(tblInfo.RecordPrefix(), hdInVal) + _, err := txn.Get(context.Background(), rowKey) + if err != nil { + if kv.IsErrNotFound(err) { + // The row is deleted, so we can merge the delete operation to the origin index. + tmpRec.skip = false + return nil + } + // Unexpected errors. + return errors.Trace(err) + } + // Don't delete the index key if the row exists. + tmpRec.skip = true + return nil + } + return nil +} + // temporaryIndexRecord is the record information of an index. type temporaryIndexRecord struct { vals []byte @@ -76,10 +113,12 @@ type temporaryIndexRecord struct { delete bool unique bool distinct bool + handle kv.Handle + rowKey kv.Key } type mergeIndexWorker struct { - *backfillWorker + *backfillCtx index table.Index @@ -89,15 +128,15 @@ type mergeIndexWorker struct { jobContext *JobContext } -func newMergeTempIndexWorker(sessCtx sessionctx.Context, id int, t table.PhysicalTable, reorgInfo *reorgInfo, jc *JobContext) *mergeIndexWorker { - indexInfo := model.FindIndexInfoByID(t.Meta().Indices, reorgInfo.currElement.ID) +func newMergeTempIndexWorker(bfCtx *backfillCtx, id int, t table.PhysicalTable, eleID int64, jc *JobContext) *mergeIndexWorker { + indexInfo := model.FindIndexInfoByID(t.Meta().Indices, eleID) index := tables.NewIndex(t.GetPhysicalID(), t.Meta(), indexInfo) return &mergeIndexWorker{ - backfillWorker: newBackfillWorker(sessCtx, id, t, reorgInfo, typeAddIndexMergeTmpWorker), - index: index, - jobContext: jc, + backfillCtx: bfCtx, + index: index, + jobContext: jc, } } @@ -108,8 +147,8 @@ func (w *mergeIndexWorker) BackfillDataInTxn(taskRange reorgBackfillTask) (taskC errInTxn = kv.RunInNewTxn(ctx, w.sessCtx.GetStore(), true, func(ctx context.Context, txn kv.Transaction) error { taskCtx.addedCount = 0 taskCtx.scanCount = 0 - txn.SetOption(kv.Priority, w.priority) - if tagger := w.reorgInfo.d.getResourceGroupTaggerForTopSQL(w.reorgInfo.Job); tagger != nil { + txn.SetOption(kv.Priority, taskRange.priority) + if tagger := w.GetCtx().getResourceGroupTaggerForTopSQL(taskRange.getJobID()); tagger != nil { txn.SetOption(kv.ResourceGroupTagger, tagger) } @@ -133,6 +172,15 @@ func (w *mergeIndexWorker) BackfillDataInTxn(taskRange reorgBackfillTask) (taskC if idxRecord.skip { continue } + + // Lock the corresponding row keys so that it doesn't modify the index KVs + // that are changing by a pessimistic transaction. + rowKey := tablecodec.EncodeRecordKey(w.table.RecordPrefix(), idxRecord.handle) + err := txn.LockKeys(context.Background(), new(kv.LockCtx), rowKey) + if err != nil { + return errors.Trace(err) + } + if idxRecord.delete { if idxRecord.unique { err = txn.GetMemBuffer().DeleteWithFlags(w.originIdxKeys[i], kv.SetNeedLocked) @@ -149,11 +197,32 @@ func (w *mergeIndexWorker) BackfillDataInTxn(taskRange reorgBackfillTask) (taskC } return nil }) + logSlowOperations(time.Since(oprStartTime), "AddIndexMergeDataInTxn", 3000) return } -func (w *mergeIndexWorker) AddMetricInfo(cnt float64) { +func (*mergeIndexWorker) AddMetricInfo(float64) { +} + +func (*mergeIndexWorker) String() string { + return typeAddIndexMergeTmpWorker.String() +} + +func (*mergeIndexWorker) GetTask() (*BackfillJob, error) { + panic("[ddl] merge index worker GetTask function doesn't implement") +} + +func (*mergeIndexWorker) UpdateTask(*BackfillJob) error { + panic("[ddl] merge index worker UpdateTask function doesn't implement") +} + +func (*mergeIndexWorker) FinishTask(*BackfillJob) error { + panic("[ddl] merge index worker FinishTask function doesn't implement") +} + +func (w *mergeIndexWorker) GetCtx() *backfillCtx { + return w.backfillCtx } func (w *mergeIndexWorker) fetchTempIndexVals(txn kv.Transaction, taskRange reorgBackfillTask) ([]*temporaryIndexRecord, kv.Key, bool, error) { @@ -166,7 +235,8 @@ func (w *mergeIndexWorker) fetchTempIndexVals(txn kv.Transaction, taskRange reor oprStartTime := startTime idxPrefix := w.table.IndexPrefix() var lastKey kv.Key - err := iterateSnapshotKeys(w.reorgInfo.d.jobContext(w.reorgInfo.Job), w.sessCtx.GetStore(), w.priority, idxPrefix, txn.StartTS(), + isCommonHandle := w.table.Meta().IsCommonHandle + err := iterateSnapshotKeys(w.GetCtx().jobContext(taskRange.getJobID()), w.sessCtx.GetStore(), taskRange.priority, idxPrefix, txn.StartTS(), taskRange.startKey, taskRange.endKey, func(_ kv.Handle, indexKey kv.Key, rawValue []byte) (more bool, err error) { oprEndTime := time.Now() logSlowOperations(oprEndTime.Sub(oprStartTime), "iterate temporary index in merge process", 0) @@ -182,20 +252,21 @@ func (w *mergeIndexWorker) fetchTempIndexVals(txn kv.Transaction, taskRange reor return false, nil } - isDelete := false - unique := false - length := len(rawValue) - keyVer := rawValue[length-1] - if keyVer == tables.TempIndexKeyTypeMerge { - // The kv is written in the merging state. It has been written to the origin index, we can skip it. + originVal, handle, isDelete, unique, keyVer := tablecodec.DecodeTempIndexValue(rawValue, isCommonHandle) + if keyVer == tables.TempIndexKeyTypeMerge || keyVer == tables.TempIndexKeyTypeDelete { + // For 'm' version kvs, they are double-written. + // For 'd' version kvs, they are written in the delete-only state and can be dropped safely. return true, nil } - rawValue = rawValue[:length-1] - if bytes.Equal(rawValue, tables.DeleteMarker) { - isDelete = true - } else if bytes.Equal(rawValue, tables.DeleteMarkerUnique) { - isDelete = true - unique = true + + if handle == nil { + // If the handle is not found in the value of the temp index, it means + // 1) This is not a deletion marker, the handle is in the key or the origin value. + // 2) This is a deletion marker, but the handle is in the key of temp index. + handle, err = tablecodec.DecodeIndexHandle(indexKey, originVal, len(w.index.Meta().Columns)) + if err != nil { + return false, err + } } originIdxKey := make([]byte, len(indexKey)) @@ -203,13 +274,14 @@ func (w *mergeIndexWorker) fetchTempIndexVals(txn kv.Transaction, taskRange reor tablecodec.TempIndexKey2IndexKey(w.index.Meta().ID, originIdxKey) idxRecord := &temporaryIndexRecord{ + handle: handle, delete: isDelete, unique: unique, skip: false, } if !isDelete { - idxRecord.vals = rawValue - idxRecord.distinct = tablecodec.IndexKVIsUnique(rawValue) + idxRecord.vals = originVal + idxRecord.distinct = tablecodec.IndexKVIsUnique(originVal) } w.tmpIdxRecords = append(w.tmpIdxRecords, idxRecord) w.originIdxKeys = append(w.originIdxKeys, originIdxKey) diff --git a/ddl/index_merge_tmp_test.go b/ddl/index_merge_tmp_test.go index eb0a935690068..b637a55d2925f 100644 --- a/ddl/index_merge_tmp_test.go +++ b/ddl/index_merge_tmp_test.go @@ -16,7 +16,9 @@ package ddl_test import ( "testing" + "time" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/ddl/ingest" "github.com/pingcap/tidb/domain" @@ -174,6 +176,73 @@ func TestAddIndexMergeVersionIndexValue(t *testing.T) { require.Equal(t, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, iter.Value()) } +func TestAddIndexMergeIndexUntouchedValue(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk.MustExec(`create table t ( + id int not null auto_increment, + k int not null default '0', + c char(120) not null default '', + pad char(60) not null default '', + primary key (id) clustered, + key k_1(k));`) + tk.MustExec("insert into t values (1, 1, 'a', 'a')") + // Force onCreateIndex use the txn-merge process. + ingest.LitInitialized = false + tk.MustExec("set @@global.tidb_ddl_enable_fast_reorg = 1;") + + var checkErrs []error + var runInsert bool + var runUpdate bool + originHook := dom.DDL().GetHook() + callback := &ddl.TestDDLCallback{ + Do: dom, + } + onJobUpdatedExportedFunc := func(job *model.Job) { + if job.Type != model.ActionAddIndex || job.SchemaState != model.StateWriteReorganization { + return + } + idx := findIdxInfo(dom, "test", "t", "idx") + if idx == nil { + return + } + if !runInsert { + if idx.BackfillState != model.BackfillStateRunning || job.SnapshotVer == 0 { + return + } + runInsert = true + _, err := tk2.Exec("insert into t values (100, 1, 'a', 'a');") + checkErrs = append(checkErrs, err) + } + if !runUpdate { + if idx.BackfillState != model.BackfillStateReadyToMerge { + return + } + runUpdate = true + _, err := tk2.Exec("begin;") + checkErrs = append(checkErrs, err) + _, err = tk2.Exec("update t set k=k+1 where id = 100;") + checkErrs = append(checkErrs, err) + _, err = tk2.Exec("commit;") + checkErrs = append(checkErrs, err) + } + } + callback.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) + dom.DDL().SetHook(callback) + tk.MustExec("alter table t add index idx(c);") + dom.DDL().SetHook(originHook) + require.True(t, runUpdate) + for _, err := range checkErrs { + require.NoError(t, err) + } + tk.MustExec("admin check table t;") + tk.MustQuery("select * from t use index (idx);").Check(testkit.Rows("1 1 a a", "100 2 a a")) + tk.MustQuery("select * from t ignore index (idx);").Check(testkit.Rows("1 1 a a", "100 2 a a")) +} + func findIdxInfo(dom *domain.Domain, dbName, tbName, idxName string) *model.IndexInfo { tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(dbName), model.NewCIStr(tbName)) if err != nil { @@ -183,13 +252,282 @@ func findIdxInfo(dom *domain.Domain, dbName, tbName, idxName string) *model.Inde return tbl.Meta().FindIndexByName(idxName) } -func TestPessimisticAmendIncompatibleWithFastReorg(t *testing.T) { +// TestCreateUniqueIndexKeyExist this case will test below things: +// Create one unique index idx((a*b+1)); +// insert (0, 6) and delete it; +// insert (0, 9), it should be successful; +// Should check temp key exist and skip deleted mark +// The error returned below: +// Error: Received unexpected error: +// +// [kv:1062]Duplicate entry '1' for key 't.idx' +func TestCreateUniqueIndexKeyExist(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int default 0, b int default 0)") + tk.MustExec("insert into t values (1, 1), (2, 2), (3, 3), (4, 4)") + + tk1 := testkit.NewTestKit(t, store) + tk1.MustExec("use test") + + stateDeleteOnlySQLs := []string{"insert into t values (5, 5)", "begin pessimistic;", "insert into t select * from t", "rollback", "insert into t set b = 6", "update t set b = 7 where a = 1", "delete from t where b = 4"} + + // If waitReorg timeout, the worker may enter writeReorg more than 2 times. + reorgTime := 0 + d := dom.DDL() + originalCallback := d.GetHook() + defer d.SetHook(originalCallback) + callback := &ddl.TestDDLCallback{} + onJobUpdatedExportedFunc := func(job *model.Job) { + if t.Failed() { + return + } + var err error + switch job.SchemaState { + case model.StateDeleteOnly: + for _, sql := range stateDeleteOnlySQLs { + _, err = tk1.Exec(sql) + assert.NoError(t, err) + } + // (1, 7), (2, 2), (3, 3), (5, 5), (0, 6) + case model.StateWriteOnly: + _, err = tk1.Exec("insert into t values (8, 8)") + assert.NoError(t, err) + _, err = tk1.Exec("update t set b = 7 where a = 2") + assert.NoError(t, err) + _, err = tk1.Exec("delete from t where b = 3") + assert.NoError(t, err) + // (1, 7), (2, 7), (5, 5), (0, 6), (8, 8) + case model.StateWriteReorganization: + if reorgTime < 1 { + reorgTime++ + } else { + return + } + _, err = tk1.Exec("insert into t values (10, 10)") + assert.NoError(t, err) + _, err = tk1.Exec("delete from t where b = 6") + assert.NoError(t, err) + _, err = tk1.Exec("insert into t set b = 9") + assert.NoError(t, err) + _, err = tk1.Exec("update t set b = 7 where a = 5") + assert.NoError(t, err) + // (1, 7), (2, 7), (5, 7), (8, 8), (10, 10), (0, 9) + } + } + callback.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) + d.SetHook(callback) + tk.MustExec("alter table t add unique index idx((a*b+1))") + tk.MustExec("admin check table t") + tk.MustQuery("select * from t order by a, b").Check(testkit.Rows("0 9", "1 7", "2 7", "5 7", "8 8", "10 10")) +} + +func TestAddIndexMergeIndexUpdateOnDeleteOnly(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk.MustExec(`CREATE TABLE t (a DATE NULL DEFAULT '1619-01-18', b BOOL NULL DEFAULT '0') CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_bin';`) + tk.MustExec(`INSERT INTO t SET b = '1';`) + + updateSQLs := []string{ + "UPDATE t SET a = '9432-05-10', b = '0';", + "UPDATE t SET a = '9432-05-10', b = '1';", + } + + // Force onCreateIndex use the txn-merge process. + ingest.LitInitialized = false + tk.MustExec("set @@global.tidb_ddl_enable_fast_reorg = 1;") + tk.MustExec("set @@global.tidb_enable_mutation_checker = 1;") + tk.MustExec("set @@global.tidb_txn_assertion_level = 'STRICT';") + + var checkErrs []error + originHook := dom.DDL().GetHook() + callback := &ddl.TestDDLCallback{ + Do: dom, + } + onJobUpdatedBefore := func(job *model.Job) { + if job.SchemaState == model.StateDeleteOnly { + for _, sql := range updateSQLs { + _, err := tk2.Exec(sql) + if err != nil { + checkErrs = append(checkErrs, err) + } + } + } + } + callback.OnJobUpdatedExported.Store(&onJobUpdatedBefore) + dom.DDL().SetHook(callback) + tk.MustExec("alter table t add index idx(b);") + dom.DDL().SetHook(originHook) + for _, err := range checkErrs { + require.NoError(t, err) + } + tk.MustExec("admin check table t;") +} + +func TestAddIndexMergeDeleteUniqueOnWriteOnly(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int default 0, b int default 0);") + tk.MustExec("insert into t values (1, 1), (2, 2), (3, 3), (4, 4);") + + tk1 := testkit.NewTestKit(t, store) + tk1.MustExec("use test") + + d := dom.DDL() + originalCallback := d.GetHook() + defer d.SetHook(originalCallback) + callback := &ddl.TestDDLCallback{} + onJobUpdatedExportedFunc := func(job *model.Job) { + if t.Failed() { + return + } + var err error + switch job.SchemaState { + case model.StateDeleteOnly: + _, err = tk1.Exec("insert into t values (5, 5);") + assert.NoError(t, err) + case model.StateWriteOnly: + _, err = tk1.Exec("insert into t values (5, 7);") + assert.NoError(t, err) + _, err = tk1.Exec("delete from t where b = 7;") + assert.NoError(t, err) + } + } + callback.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) + d.SetHook(callback) + tk.MustExec("alter table t add unique index idx(a);") + tk.MustExec("admin check table t;") +} + +func TestAddIndexMergeDeleteNullUnique(t *testing.T) { store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk.MustExec("set global tidb_ddl_enable_fast_reorg = 1;") - tk.MustExec("set global tidb_ddl_enable_fast_reorg = 1;") + tk.MustExec("create table t(id int primary key, a int default 0);") + tk.MustExec("insert into t values (1, 1), (2, null);") + + tk1 := testkit.NewTestKit(t, store) + tk1.MustExec("use test") + + ddl.MockDMLExecution = func() { + _, err := tk1.Exec("delete from t where id = 2;") + assert.NoError(t, err) + } + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/mockDMLExecution", "1*return(true)->return(false)")) + tk.MustExec("alter table t add unique index idx(a);") + tk.MustQuery("select count(1) from t;").Check(testkit.Rows("1")) + tk.MustExec("admin check table t;") + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockDMLExecution")) +} - tk.MustGetErrMsg("set @@tidb_enable_amend_pessimistic_txn = 1;", - "amend pessimistic transactions is not compatible with tidb_ddl_enable_fast_reorg") +func TestAddIndexMergeDoubleDelete(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int primary key, a int default 0);") + + tk1 := testkit.NewTestKit(t, store) + tk1.MustExec("use test") + + d := dom.DDL() + originalCallback := d.GetHook() + defer d.SetHook(originalCallback) + callback := &ddl.TestDDLCallback{} + onJobUpdatedExportedFunc := func(job *model.Job) { + if t.Failed() { + return + } + switch job.SchemaState { + case model.StateWriteOnly: + _, err := tk1.Exec("insert into t values (1, 1);") + assert.NoError(t, err) + } + } + callback.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) + d.SetHook(callback) + + ddl.MockDMLExecution = func() { + _, err := tk1.Exec("delete from t where id = 1;") + assert.NoError(t, err) + _, err = tk1.Exec("insert into t values (2, 1);") + assert.NoError(t, err) + _, err = tk1.Exec("delete from t where id = 2;") + assert.NoError(t, err) + } + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/mockDMLExecution", "1*return(true)->return(false)")) + tk.MustExec("alter table t add unique index idx(a);") + tk.MustQuery("select count(1) from t;").Check(testkit.Rows("0")) + tk.MustExec("admin check table t;") + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockDMLExecution")) +} + +func TestAddIndexMergeConflictWithPessimistic(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk.MustExec(`CREATE TABLE t (id int primary key, a int);`) + tk.MustExec(`INSERT INTO t VALUES (1, 1);`) + + // Force onCreateIndex use the txn-merge process. + ingest.LitInitialized = false + tk.MustExec("set @@global.tidb_ddl_enable_fast_reorg = 1;") + tk.MustExec("set @@global.tidb_enable_metadata_lock = 0;") + + originHook := dom.DDL().GetHook() + callback := &ddl.TestDDLCallback{Do: dom} + + runPessimisticTxn := false + callback.OnJobRunBeforeExported = func(job *model.Job) { + if t.Failed() { + return + } + if job.SchemaState == model.StateWriteOnly { + // Write a record to the temp index. + _, err := tk2.Exec("update t set a = 2 where id = 1;") + assert.NoError(t, err) + } + if !runPessimisticTxn && job.SchemaState == model.StateWriteReorganization { + idx := findIdxInfo(dom, "test", "t", "idx") + if idx == nil { + return + } + if idx.BackfillState != model.BackfillStateReadyToMerge { + return + } + runPessimisticTxn = true + _, err := tk2.Exec("begin pessimistic;") + assert.NoError(t, err) + _, err = tk2.Exec("update t set a = 3 where id = 1;") + assert.NoError(t, err) + } + } + dom.DDL().SetHook(callback) + afterCommit := make(chan struct{}, 1) + go func() { + tk.MustExec("alter table t add index idx(a);") + afterCommit <- struct{}{} + }() + timer := time.NewTimer(300 * time.Millisecond) + select { + case <-timer.C: + break + case <-afterCommit: + require.Fail(t, "should be blocked by the pessimistic txn") + } + tk2.MustExec("rollback;") + <-afterCommit + dom.DDL().SetHook(originHook) + tk.MustExec("admin check table t;") + tk.MustQuery("select * from t;").Check(testkit.Rows("1 2")) } diff --git a/ddl/index_modify_test.go b/ddl/index_modify_test.go index 7aff7ac81b2f3..2caf54c31c157 100644 --- a/ddl/index_modify_test.go +++ b/ddl/index_modify_test.go @@ -374,7 +374,7 @@ func TestAddIndexForGeneratedColumn(t *testing.T) { func TestAddPrimaryKeyRollback1(t *testing.T) { idxName := "PRIMARY" addIdxSQL := "alter table t1 add primary key c3_index (c3);" - errMsg := "[kv:1062]Duplicate entry '" + strconv.Itoa(defaultBatchSize*2-10) + "' for key 'PRIMARY'" + errMsg := "[kv:1062]Duplicate entry '" + strconv.Itoa(defaultBatchSize*2-10) + "' for key 't1.PRIMARY'" testAddIndexRollback(t, idxName, addIdxSQL, errMsg, false) } @@ -389,7 +389,7 @@ func TestAddPrimaryKeyRollback2(t *testing.T) { func TestAddUniqueIndexRollback(t *testing.T) { idxName := "c3_index" addIdxSQL := "create unique index c3_index on t1 (c3)" - errMsg := "[kv:1062]Duplicate entry '" + strconv.Itoa(defaultBatchSize*2-10) + "' for key 'c3_index'" + errMsg := "[kv:1062]Duplicate entry '" + strconv.Itoa(defaultBatchSize*2-10) + "' for key 't1.c3_index'" testAddIndexRollback(t, idxName, addIdxSQL, errMsg, false) } @@ -416,7 +416,7 @@ func testAddIndexRollback(t *testing.T, idxName, addIdxSQL, errMsg string, hasNu } done := make(chan error, 1) - go backgroundExec(store, addIdxSQL, done) + go backgroundExec(store, "test", addIdxSQL, done) times := 0 ticker := time.NewTicker(indexModifyLease / 2) @@ -816,7 +816,7 @@ func TestDropIndexes(t *testing.T) { store := testkit.CreateMockStoreWithSchemaLease(t, indexModifyLease, mockstore.WithDDLChecker()) // drop multiple indexes - createSQL := "create table test_drop_indexes (id int, c1 int, c2 int, primary key(id), key i1(c1), key i2(c2));" + createSQL := "create table test_drop_indexes (id int, c1 int, c2 int, primary key(id) nonclustered, key i1(c1), key i2(c2));" dropIdxSQL := "alter table test_drop_indexes drop index i1, drop index i2;" idxNames := []string{"i1", "i2"} testDropIndexes(t, store, createSQL, dropIdxSQL, idxNames) @@ -826,7 +826,7 @@ func TestDropIndexes(t *testing.T) { idxNames = []string{"primary", "i1"} testDropIndexes(t, store, createSQL, dropIdxSQL, idxNames) - createSQL = "create table test_drop_indexes (uuid varchar(32), c1 int, c2 int, primary key(uuid), unique key i1(c1), key i2(c2));" + createSQL = "create table test_drop_indexes (uuid varchar(32), c1 int, c2 int, primary key(uuid) nonclustered, unique key i1(c1), key i2(c2));" dropIdxSQL = "alter table test_drop_indexes drop primary key, drop index i1, drop index i2;" idxNames = []string{"primary", "i1", "i2"} testDropIndexes(t, store, createSQL, dropIdxSQL, idxNames) @@ -1067,3 +1067,20 @@ func TestAddIndexWithDupIndex(t *testing.T) { err = tk.ExecToErr("alter table test_add_index_with_dup add index idx (a)") require.ErrorIs(t, err, errors.Cause(err2)) } + +func TestAddIndexUniqueFailOnDuplicate(t *testing.T) { + ddl.ResultCounterForTest = &atomic.Int32{} + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (a bigint primary key clustered, b int);") + tk.MustExec("set @@global.tidb_ddl_reorg_worker_cnt = 1;") + for i := 1; i <= 12; i++ { + tk.MustExec("insert into t values (?, ?)", i, i) + } + tk.MustExec("insert into t values (0, 1);") // Insert a duplicate key. + tk.MustQuery("split table t by (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);").Check(testkit.Rows("13 1")) + tk.MustGetErrCode("alter table t add unique index idx (b);", errno.ErrDupEntry) + require.Less(t, int(ddl.ResultCounterForTest.Load()), 6) + ddl.ResultCounterForTest = nil +} diff --git a/ddl/ingest/BUILD.bazel b/ddl/ingest/BUILD.bazel index 3fd286e450b25..962ae4da35637 100644 --- a/ddl/ingest/BUILD.bazel +++ b/ddl/ingest/BUILD.bazel @@ -33,13 +33,13 @@ go_library( "//sessionctx/variable", "//table", "//util", + "//util/dbterror", "//util/generic", "//util/logutil", "//util/mathutil", "//util/size", "@com_github_google_uuid//:uuid", "@com_github_pingcap_errors//:errors", - "@com_github_pkg_errors//:errors", "@org_uber_go_zap//:zap", ], ) diff --git a/ddl/ingest/backend.go b/ddl/ingest/backend.go index 63034f0be3a22..26344359dd6b9 100644 --- a/ddl/ingest/backend.go +++ b/ddl/ingest/backend.go @@ -17,13 +17,13 @@ package ingest import ( "context" - "github.com/pingcap/errors" "github.com/pingcap/tidb/br/pkg/lightning/backend" "github.com/pingcap/tidb/br/pkg/lightning/backend/kv" "github.com/pingcap/tidb/br/pkg/lightning/config" tikv "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/table" + "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" "go.uber.org/zap" ) @@ -45,7 +45,7 @@ type BackendContext struct { func (bc *BackendContext) FinishImport(indexID int64, unique bool, tbl table.Table) error { ei, exist := bc.EngMgr.Load(indexID) if !exist { - return errors.New(LitErrGetEngineFail) + return dbterror.ErrIngestFailed.FastGenByArgs("ingest engine not found") } err := ei.ImportAndClean() @@ -63,7 +63,7 @@ func (bc *BackendContext) FinishImport(indexID int64, unique bool, tbl table.Tab if err != nil { logutil.BgLogger().Error(LitInfoRemoteDupCheck, zap.Error(err), zap.String("table", tbl.Meta().Name.O), zap.Int64("index ID", indexID)) - return errors.New(LitInfoRemoteDupCheck) + return err } else if hasDupe { logutil.BgLogger().Error(LitErrRemoteDupExistErr, zap.String("table", tbl.Meta().Name.O), zap.Int64("index ID", indexID)) @@ -80,7 +80,7 @@ func (bc *BackendContext) Flush(indexID int64) error { ei, exist := bc.EngMgr.Load(indexID) if !exist { logutil.BgLogger().Error(LitErrGetEngineFail, zap.Int64("index ID", indexID)) - return errors.New(LitErrGetEngineFail) + return dbterror.ErrIngestFailed.FastGenByArgs("ingest engine not found") } err := bc.diskRoot.UpdateUsageAndQuota() diff --git a/ddl/ingest/config.go b/ddl/ingest/config.go index 3a96e8ae5201b..7fd251a361939 100644 --- a/ddl/ingest/config.go +++ b/ddl/ingest/config.go @@ -16,6 +16,7 @@ package ingest import ( "path/filepath" + "sync/atomic" "github.com/pingcap/tidb/br/pkg/lightning/backend" "github.com/pingcap/tidb/br/pkg/lightning/checkpoints" @@ -26,12 +27,18 @@ import ( "go.uber.org/zap" ) +// ImporterRangeConcurrencyForTest is only used for test. +var ImporterRangeConcurrencyForTest *atomic.Int32 + func generateLightningConfig(memRoot MemRoot, jobID int64, unique bool) (*config.Config, error) { tidbCfg := tidbconf.GetGlobalConfig() cfg := config.NewConfig() cfg.TikvImporter.Backend = config.BackendLocal // Each backend will build a single dir in lightning dir. cfg.TikvImporter.SortedKVDir = filepath.Join(LitSortPath, encodeBackendTag(jobID)) + if ImporterRangeConcurrencyForTest != nil { + cfg.TikvImporter.RangeConcurrency = int(ImporterRangeConcurrencyForTest.Load()) + } _, err := cfg.AdjustCommon() if err != nil { logutil.BgLogger().Warn(LitWarnConfigError, zap.Error(err)) @@ -40,7 +47,7 @@ func generateLightningConfig(memRoot MemRoot, jobID int64, unique bool) (*config adjustImportMemory(memRoot, cfg) cfg.Checkpoint.Enable = true if unique { - cfg.TikvImporter.DuplicateResolution = config.DupeResAlgRecord + cfg.TikvImporter.DuplicateResolution = config.DupeResAlgErr } else { cfg.TikvImporter.DuplicateResolution = config.DupeResAlgNone } diff --git a/ddl/ingest/disk_root.go b/ddl/ingest/disk_root.go index c1c98f3fe681a..445115333edd1 100644 --- a/ddl/ingest/disk_root.go +++ b/ddl/ingest/disk_root.go @@ -15,7 +15,6 @@ package ingest import ( - "github.com/pingcap/errors" lcom "github.com/pingcap/tidb/br/pkg/lightning/common" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/util/logutil" @@ -64,7 +63,7 @@ func (d *diskRootImpl) UpdateUsageAndQuota() error { sz, err := lcom.GetStorageSize(d.path) if err != nil { logutil.BgLogger().Error(LitErrGetStorageQuota, zap.Error(err)) - return errors.New(LitErrGetStorageQuota) + return err } d.maxQuota = mathutil.Min(variable.DDLDiskQuota.Load(), uint64(capacityThreshold*float64(sz.Capacity))) return nil diff --git a/ddl/ingest/engine.go b/ddl/ingest/engine.go index d875d78e346d0..0c9409bf7657e 100644 --- a/ddl/ingest/engine.go +++ b/ddl/ingest/engine.go @@ -17,6 +17,7 @@ package ingest import ( "context" "strconv" + "sync/atomic" "github.com/google/uuid" "github.com/pingcap/tidb/br/pkg/lightning/backend" @@ -25,7 +26,6 @@ import ( "github.com/pingcap/tidb/br/pkg/lightning/config" "github.com/pingcap/tidb/util/generic" "github.com/pingcap/tidb/util/logutil" - "github.com/pkg/errors" "go.uber.org/zap" ) @@ -42,6 +42,7 @@ type engineInfo struct { writerCache generic.SyncMap[int, *backend.LocalEngineWriter] memRoot MemRoot diskRoot DiskRoot + rowSeq atomic.Int64 } // NewEngineInfo create a new EngineInfo struct. @@ -83,6 +84,11 @@ func (ei *engineInfo) Clean() { zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID)) } ei.openedEngine = nil + err = ei.closeWriters() + if err != nil { + logutil.BgLogger().Error(LitErrCloseWriterErr, zap.Error(err), + zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID)) + } // Here the local intermediate files will be removed. err = closedEngine.Cleanup(ei.ctx) if err != nil { @@ -99,11 +105,17 @@ func (ei *engineInfo) ImportAndClean() error { if err1 != nil { logutil.BgLogger().Error(LitErrCloseEngineErr, zap.Error(err1), zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID)) - return errors.New(LitErrCloseEngineErr) + return err1 } ei.openedEngine = nil + err := ei.closeWriters() + if err != nil { + logutil.BgLogger().Error(LitErrCloseWriterErr, zap.Error(err), + zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID)) + return err + } - err := ei.diskRoot.UpdateUsageAndQuota() + err = ei.diskRoot.UpdateUsageAndQuota() if err != nil { logutil.BgLogger().Error(LitErrUpdateDiskStats, zap.Error(err), zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID)) @@ -118,7 +130,7 @@ func (ei *engineInfo) ImportAndClean() error { if err != nil { logutil.BgLogger().Error(LitErrIngestDataErr, zap.Error(err), zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID)) - return errors.New(LitErrIngestDataErr) + return err } // Clean up the engine local workspace. @@ -126,7 +138,7 @@ func (ei *engineInfo) ImportAndClean() error { if err != nil { logutil.BgLogger().Error(LitErrCloseEngineErr, zap.Error(err), zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID)) - return errors.New(LitErrCloseEngineErr) + return err } return nil } @@ -134,17 +146,18 @@ func (ei *engineInfo) ImportAndClean() error { // WriterContext is used to keep a lightning local writer for each backfill worker. type WriterContext struct { ctx context.Context + rowSeq func() int64 lWrite *backend.LocalEngineWriter } -func (ei *engineInfo) NewWriterCtx(id int) (*WriterContext, error) { +func (ei *engineInfo) NewWriterCtx(id int, unique bool) (*WriterContext, error) { ei.memRoot.RefreshConsumption() ok := ei.memRoot.CheckConsume(StructSizeWriterCtx) if !ok { return nil, genEngineAllocMemFailedErr(ei.memRoot, ei.jobID, ei.indexID) } - wCtx, err := ei.newWriterContext(id) + wCtx, err := ei.newWriterContext(id, unique) if err != nil { logutil.BgLogger().Error(LitErrCreateContextFail, zap.Error(err), zap.Int64("job ID", ei.jobID), zap.Int64("index ID", ei.indexID), @@ -165,7 +178,7 @@ func (ei *engineInfo) NewWriterCtx(id int) (*WriterContext, error) { // If local writer not exist, then create new one and store it into engine info writer cache. // note: operate ei.writeCache map is not thread safe please make sure there is sync mechanism to // make sure the safe. -func (ei *engineInfo) newWriterContext(workerID int) (*WriterContext, error) { +func (ei *engineInfo) newWriterContext(workerID int, unique bool) (*WriterContext, error) { lWrite, exist := ei.writerCache.Load(workerID) if !exist { var err error @@ -176,10 +189,32 @@ func (ei *engineInfo) newWriterContext(workerID int) (*WriterContext, error) { // Cache the local writer. ei.writerCache.Store(workerID, lWrite) } - return &WriterContext{ + wc := &WriterContext{ ctx: ei.ctx, lWrite: lWrite, - }, nil + } + if unique { + wc.rowSeq = func() int64 { + return ei.rowSeq.Add(1) + } + } + return wc, nil +} + +func (ei *engineInfo) closeWriters() error { + var firstErr error + for wid := range ei.writerCache.Keys() { + if w, ok := ei.writerCache.Load(wid); ok { + _, err := w.Close(ei.ctx) + if err != nil { + if firstErr == nil { + firstErr = err + } + } + } + ei.writerCache.Delete(wid) + } + return firstErr } // WriteRow Write one row into local writer buffer. @@ -187,6 +222,9 @@ func (wCtx *WriterContext) WriteRow(key, idxVal []byte) error { kvs := make([]common.KvPair, 1) kvs[0].Key = key kvs[0].Val = idxVal + if wCtx.rowSeq != nil { + kvs[0].RowID = wCtx.rowSeq() + } row := kv.MakeRowsFromKvPairs(kvs) return wCtx.lWrite.WriteRows(wCtx.ctx, nil, row) } diff --git a/ddl/ingest/engine_mgr.go b/ddl/ingest/engine_mgr.go index 44ecff9941932..f9b006ec9e369 100644 --- a/ddl/ingest/engine_mgr.go +++ b/ddl/ingest/engine_mgr.go @@ -18,7 +18,7 @@ import ( "fmt" "github.com/pingcap/errors" - "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/generic" "github.com/pingcap/tidb/util/logutil" "go.uber.org/zap" @@ -37,7 +37,7 @@ func (m *engineManager) init(memRoot MemRoot, diskRoot DiskRoot) { } // Register create a new engineInfo and register it to the engineManager. -func (m *engineManager) Register(bc *BackendContext, job *model.Job, indexID int64) (*engineInfo, error) { +func (m *engineManager) Register(bc *BackendContext, jobID, indexID int64, schemaName, tableName string) (*engineInfo, error) { // Calculate lightning concurrency degree and set memory usage // and pre-allocate memory usage for worker. m.MemRoot.RefreshConsumption() @@ -55,29 +55,31 @@ func (m *engineManager) Register(bc *BackendContext, job *model.Job, indexID int return nil, genEngineAllocMemFailedErr(m.MemRoot, bc.jobID, indexID) } - cfg := generateLocalEngineConfig(job.ID, job.SchemaName, job.TableName) - openedEn, err := bc.backend.OpenEngine(bc.ctx, cfg, job.TableName, int32(indexID)) + cfg := generateLocalEngineConfig(jobID, schemaName, tableName) + openedEn, err := bc.backend.OpenEngine(bc.ctx, cfg, tableName, int32(indexID)) if err != nil { - return nil, errors.New(LitErrCreateEngineFail) + logutil.BgLogger().Warn(LitErrCreateEngineFail, zap.Int64("job ID", jobID), + zap.Int64("index ID", indexID), zap.Error(err)) + return nil, errors.Trace(err) } id := openedEn.GetEngineUUID() - en = NewEngineInfo(bc.ctx, job.ID, indexID, cfg, openedEn, id, 1, m.MemRoot, m.DiskRoot) + en = NewEngineInfo(bc.ctx, jobID, indexID, cfg, openedEn, id, 1, m.MemRoot, m.DiskRoot) m.Store(indexID, en) m.MemRoot.Consume(StructSizeEngineInfo) - m.MemRoot.ConsumeWithTag(encodeEngineTag(job.ID, indexID), engineCacheSize) + m.MemRoot.ConsumeWithTag(encodeEngineTag(jobID, indexID), engineCacheSize) info = LitInfoOpenEngine } else { if en.writerCount+1 > bc.cfg.TikvImporter.RangeConcurrency { - logutil.BgLogger().Warn(LitErrExceedConcurrency, zap.Int64("job ID", job.ID), + logutil.BgLogger().Warn(LitErrExceedConcurrency, zap.Int64("job ID", jobID), zap.Int64("index ID", indexID), zap.Int("concurrency", bc.cfg.TikvImporter.RangeConcurrency)) - return nil, errors.New(LitErrExceedConcurrency) + return nil, dbterror.ErrIngestFailed.FastGenByArgs("concurrency quota exceeded") } en.writerCount++ info = LitInfoAddWriter } - m.MemRoot.ConsumeWithTag(encodeEngineTag(job.ID, indexID), int64(bc.cfg.TikvImporter.LocalWriterMemCacheSize)) - logutil.BgLogger().Info(info, zap.Int64("job ID", job.ID), + m.MemRoot.ConsumeWithTag(encodeEngineTag(jobID, indexID), int64(bc.cfg.TikvImporter.LocalWriterMemCacheSize)) + logutil.BgLogger().Info(info, zap.Int64("job ID", jobID), zap.Int64("index ID", indexID), zap.Int64("current memory usage", m.MemRoot.CurrentUsage()), zap.Int64("memory limitation", m.MemRoot.MaxMemoryQuota()), @@ -99,6 +101,20 @@ func (m *engineManager) Unregister(jobID, indexID int64) { m.MemRoot.Release(StructSizeEngineInfo) } +// ResetWorkers reset the writer count of the engineInfo because +// the goroutines of backfill workers have been terminated. +func (m *engineManager) ResetWorkers(bc *BackendContext, jobID, indexID int64) { + ei, exist := m.Load(indexID) + if !exist { + return + } + m.MemRoot.Release(StructSizeWriterCtx * int64(ei.writerCount)) + m.MemRoot.ReleaseWithTag(encodeEngineTag(jobID, indexID)) + engineCacheSize := int64(bc.cfg.TikvImporter.EngineMemCacheSize) + m.MemRoot.ConsumeWithTag(encodeEngineTag(jobID, indexID), engineCacheSize) + ei.writerCount = 0 +} + // UnregisterAll delete all engineInfo from the engineManager. func (m *engineManager) UnregisterAll(jobID int64) { for _, idxID := range m.Keys() { diff --git a/ddl/ingest/env.go b/ddl/ingest/env.go index 185f873b820a4..864cc61ae4e02 100644 --- a/ddl/ingest/env.go +++ b/ddl/ingest/env.go @@ -47,6 +47,14 @@ const maxMemoryQuota = 2 * size.GB // InitGlobalLightningEnv initialize Lightning backfill environment. func InitGlobalLightningEnv() { log.SetAppLogger(logutil.BgLogger()) + globalCfg := config.GetGlobalConfig() + if globalCfg.Store != "tikv" { + logutil.BgLogger().Warn(LitWarnEnvInitFail, + zap.String("storage limitation", "only support TiKV storage"), + zap.String("current storage", globalCfg.Store), + zap.Bool("lightning is initialized", LitInitialized)) + return + } sPath, err := genLightningDataDir() if err != nil { logutil.BgLogger().Warn(LitWarnEnvInitFail, zap.Error(err), @@ -102,8 +110,5 @@ func genLightningDataDir() (string, error) { return sortPath, nil } -// GenRLimitForTest is only used for test. -var GenRLimitForTest = util.GenRLimit() - // GenLightningDataDirForTest is only used for test. var GenLightningDataDirForTest = genLightningDataDir diff --git a/ddl/ingest/mem_root.go b/ddl/ingest/mem_root.go index a36d934c0abcd..522e5ddc1f7cc 100644 --- a/ddl/ingest/mem_root.go +++ b/ddl/ingest/mem_root.go @@ -122,7 +122,7 @@ func (m *memRootImpl) ConsumeWithTag(tag string, size int64) { m.structSize[tag] = size } -// TestConsume implements MemRoot. +// CheckConsume implements MemRoot. func (m *memRootImpl) CheckConsume(size int64) bool { m.mu.RLock() defer m.mu.RUnlock() diff --git a/ddl/ingest/message.go b/ddl/ingest/message.go index 3858d40ec4e0a..4996aab49a415 100644 --- a/ddl/ingest/message.go +++ b/ddl/ingest/message.go @@ -15,7 +15,7 @@ package ingest import ( - "github.com/pingcap/errors" + "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" "go.uber.org/zap" ) @@ -23,28 +23,26 @@ import ( // Message const text const ( LitErrAllocMemFail string = "[ddl-ingest] allocate memory failed" - LitErrOutMaxMem string = "[ddl-ingest] memory used up for lightning add index" - LitErrCreateDirFail string = "[ddl-ingest] create lightning sort path error" - LitErrStatDirFail string = "[ddl-ingest] stat lightning sort path error" - LitErrDeleteDirFail string = "[ddl-ingest] delete lightning sort path error" - LitErrCreateBackendFail string = "[ddl-ingest] build lightning backend failed, will use kernel index reorg method to backfill the index" - LitErrGetBackendFail string = "[ddl-ingest]: Can not get cached backend" - LitErrCreateEngineFail string = "[ddl-ingest] build lightning engine failed, will use kernel index reorg method to backfill the index" - LitErrCreateContextFail string = "[ddl-ingest] build lightning worker context failed, will use kernel index reorg method to backfill the index" - LitErrGetEngineFail string = "[ddl-ingest] can not get cached engine info" + LitErrCreateDirFail string = "[ddl-ingest] create ingest sort path error" + LitErrStatDirFail string = "[ddl-ingest] stat ingest sort path error" + LitErrDeleteDirFail string = "[ddl-ingest] delete ingest sort path error" + LitErrCreateBackendFail string = "[ddl-ingest] build ingest backend failed" + LitErrGetBackendFail string = "[ddl-ingest] cannot get ingest backend" + LitErrCreateEngineFail string = "[ddl-ingest] build ingest engine failed" + LitErrCreateContextFail string = "[ddl-ingest] build ingest writer context failed" + LitErrGetEngineFail string = "[ddl-ingest] can not get ingest engine info" LitErrGetStorageQuota string = "[ddl-ingest] get storage quota error" LitErrCloseEngineErr string = "[ddl-ingest] close engine error" LitErrCleanEngineErr string = "[ddl-ingest] clean engine error" LitErrFlushEngineErr string = "[ddl-ingest] flush engine data err" LitErrIngestDataErr string = "[ddl-ingest] ingest data into storage error" LitErrRemoteDupExistErr string = "[ddl-ingest] remote duplicate index key exist" - LitErrExceedConcurrency string = "[ddl-ingest] the concurrency is greater than lightning limit(tikv-importer.range-concurrency)" + LitErrExceedConcurrency string = "[ddl-ingest] the concurrency is greater than ingest limit" LitErrUpdateDiskStats string = "[ddl-ingest] update disk usage error" LitWarnEnvInitFail string = "[ddl-ingest] initialize environment failed" LitWarnConfigError string = "[ddl-ingest] build config for backend failed" - LitWarnGenMemLimit string = "[ddl-ingest] generate memory max limitation" - LitInfoEnvInitSucc string = "[ddl-ingest] init global lightning backend environment finished" - LitInfoSortDir string = "[ddl-ingest] the lightning sorted dir" + LitInfoEnvInitSucc string = "[ddl-ingest] init global ingest backend environment finished" + LitInfoSortDir string = "[ddl-ingest] the ingest sorted directory" LitInfoCreateBackend string = "[ddl-ingest] create one backend for an DDL job" LitInfoCloseBackend string = "[ddl-ingest] close one backend for DDL job" LitInfoOpenEngine string = "[ddl-ingest] open an engine for index reorg task" @@ -53,17 +51,17 @@ const ( LitInfoCloseEngine string = "[ddl-ingest] flush all writer and get closed engine" LitInfoRemoteDupCheck string = "[ddl-ingest] start remote duplicate checking" LitInfoStartImport string = "[ddl-ingest] start to import data" - LitInfoSetMemLimit string = "[ddl-ingest] set max memory limitation" - LitInfoChgMemSetting string = "[ddl-ingest] change memory setting for lightning" - LitInfoInitMemSetting string = "[ddl-ingest] initial memory setting for lightning" + LitInfoChgMemSetting string = "[ddl-ingest] change memory setting for ingest" + LitInfoInitMemSetting string = "[ddl-ingest] initial memory setting for ingest" LitInfoUnsafeImport string = "[ddl-ingest] do a partial import data into the storage" + LitErrCloseWriterErr string = "[ddl-ingest] close writer error" ) func genBackendAllocMemFailedErr(memRoot MemRoot, jobID int64) error { logutil.BgLogger().Warn(LitErrAllocMemFail, zap.Int64("job ID", jobID), zap.Int64("current memory usage", memRoot.CurrentUsage()), zap.Int64("max memory quota", memRoot.MaxMemoryQuota())) - return errors.New(LitErrOutMaxMem) + return dbterror.ErrIngestFailed.FastGenByArgs("memory used up") } func genEngineAllocMemFailedErr(memRoot MemRoot, jobID, idxID int64) error { @@ -71,5 +69,5 @@ func genEngineAllocMemFailedErr(memRoot MemRoot, jobID, idxID int64) error { zap.Int64("index ID", idxID), zap.Int64("current memory usage", memRoot.CurrentUsage()), zap.Int64("max memory quota", memRoot.MaxMemoryQuota())) - return errors.New(LitErrOutMaxMem) + return dbterror.ErrIngestFailed.FastGenByArgs("memory used up") } diff --git a/ddl/job_table.go b/ddl/job_table.go index 83585ca040704..782abcc8b5765 100644 --- a/ddl/job_table.go +++ b/ddl/job_table.go @@ -31,6 +31,7 @@ import ( "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" clientv3 "go.etcd.io/etcd/client/v3" "go.uber.org/zap" @@ -67,7 +68,7 @@ func (dc *ddlCtx) excludeJobIDs() string { } const ( - getJobSQL = "select job_meta, processing from mysql.tidb_ddl_job where job_id in (select min(job_id) from mysql.tidb_ddl_job group by schema_ids, table_ids) and %s reorg %s order by processing desc, job_id" + getJobSQL = "select job_meta, processing from mysql.tidb_ddl_job where job_id in (select min(job_id) from mysql.tidb_ddl_job group by schema_ids, table_ids, processing) and %s reorg %s order by processing desc, job_id" ) type jobType int @@ -173,7 +174,7 @@ func (d *ddl) startDispatchLoop() { if isChanClosed(d.ctx.Done()) { return } - if !variable.EnableConcurrentDDL.Load() || !d.isOwner() || d.waiting.Load() { + if !d.isOwner() || d.waiting.Load() { d.once.Store(true) time.Sleep(time.Second) continue @@ -236,7 +237,7 @@ func (d *ddl) delivery2worker(wk *worker, pool *workerPool, job *model.Job) { // check if this ddl job is synced to all servers. if !d.isSynced(job) || d.once.Load() { if variable.EnableMDL.Load() { - exist, err := checkMDLInfo(job.ID, d.sessPool) + exist, version, err := checkMDLInfo(job.ID, d.sessPool) if err != nil { logutil.BgLogger().Warn("[ddl] check MDL info failed", zap.Error(err), zap.String("job", job.String())) // Release the worker resource. @@ -245,14 +246,12 @@ func (d *ddl) delivery2worker(wk *worker, pool *workerPool, job *model.Job) { } else if exist { // Release the worker resource. pool.put(wk) - err = waitSchemaSynced(d.ddlCtx, job, 2*d.lease) + err = waitSchemaSyncedForMDL(d.ddlCtx, job, version) if err != nil { - logutil.BgLogger().Warn("[ddl] wait ddl job sync failed", zap.Error(err), zap.String("job", job.String())) - time.Sleep(time.Second) return } d.once.Store(false) - cleanMDLInfo(d.sessPool, job.ID) + cleanMDLInfo(d.sessPool, job.ID, d.etcdCli) // Don't have a worker now. return } @@ -287,13 +286,13 @@ func (d *ddl) delivery2worker(wk *worker, pool *workerPool, job *model.Job) { // If the job is done or still running or rolling back, we will wait 2 * lease time to guarantee other servers to update // the newest schema. waitSchemaChanged(context.Background(), d.ddlCtx, d.lease*2, schemaVer, job) - cleanMDLInfo(d.sessPool, job.ID) + cleanMDLInfo(d.sessPool, job.ID, d.etcdCli) d.synced(job) if RunInGoTest { // d.mu.hook is initialed from domain / test callback, which will force the owner host update schema diff synchronously. d.mu.RLock() - d.mu.hook.OnSchemaStateChanged() + d.mu.hook.OnSchemaStateChanged(schemaVer) d.mu.RUnlock() } @@ -371,6 +370,8 @@ func job2UniqueIDs(job *model.Job, schema bool) string { } slices.Sort(s) return strings.Join(s, ",") + case model.ActionTruncateTable: + return strconv.FormatInt(job.TableID, 10) + "," + strconv.FormatInt(job.Args[0].(int64), 10) } if schema { return strconv.FormatInt(job.SchemaID, 10) @@ -397,7 +398,8 @@ func updateDDLJob2Table(sctx *session, job *model.Job, updateRawArgs bool) error // getDDLReorgHandle gets DDL reorg handle. func getDDLReorgHandle(sess *session, job *model.Job) (element *meta.Element, startKey, endKey kv.Key, physicalTableID int64, err error) { sql := fmt.Sprintf("select ele_id, ele_type, start_key, end_key, physical_id from mysql.tidb_ddl_reorg where job_id = %d", job.ID) - rows, err := sess.execute(context.Background(), sql, "get_handle") + ctx := kv.WithInternalSourceType(context.Background(), getDDLRequestSource(job)) + rows, err := sess.execute(ctx, sql, "get_handle") if err != nil { return nil, nil, nil, 0, err } @@ -430,15 +432,8 @@ func getDDLReorgHandle(sess *session, job *model.Job) (element *meta.Element, st return } -// updateDDLReorgStartHandle update the startKey of the handle. -func updateDDLReorgStartHandle(sess *session, job *model.Job, element *meta.Element, startKey kv.Key) error { - sql := fmt.Sprintf("update mysql.tidb_ddl_reorg set ele_id = %d, ele_type = %s, start_key = %s where job_id = %d", - element.ID, wrapKey2String(element.TypeKey), wrapKey2String(startKey), job.ID) - _, err := sess.execute(context.Background(), sql, "update_start_handle") - return err -} - // updateDDLReorgHandle update startKey, endKey physicalTableID and element of the handle. +// Caller should wrap this in a separate transaction, to avoid conflicts. func updateDDLReorgHandle(sess *session, jobID int64, startKey kv.Key, endKey kv.Key, physicalTableID int64, element *meta.Element) error { sql := fmt.Sprintf("update mysql.tidb_ddl_reorg set ele_id = %d, ele_type = %s, start_key = %s, end_key = %s, physical_id = %d where job_id = %d", element.ID, wrapKey2String(element.TypeKey), wrapKey2String(startKey), wrapKey2String(endKey), physicalTableID, jobID) @@ -447,28 +442,48 @@ func updateDDLReorgHandle(sess *session, jobID int64, startKey kv.Key, endKey kv } // initDDLReorgHandle initializes the handle for ddl reorg. -func initDDLReorgHandle(sess *session, jobID int64, startKey kv.Key, endKey kv.Key, physicalTableID int64, element *meta.Element) error { - sql := fmt.Sprintf("insert into mysql.tidb_ddl_reorg(job_id, ele_id, ele_type, start_key, end_key, physical_id) values (%d, %d, %s, %s, %s, %d)", +func initDDLReorgHandle(s *session, jobID int64, startKey kv.Key, endKey kv.Key, physicalTableID int64, element *meta.Element) error { + del := fmt.Sprintf("delete from mysql.tidb_ddl_reorg where job_id = %d", jobID) + ins := fmt.Sprintf("insert into mysql.tidb_ddl_reorg(job_id, ele_id, ele_type, start_key, end_key, physical_id) values (%d, %d, %s, %s, %s, %d)", jobID, element.ID, wrapKey2String(element.TypeKey), wrapKey2String(startKey), wrapKey2String(endKey), physicalTableID) - _, err := sess.execute(context.Background(), sql, "update_handle") - return err + return s.runInTxn(func(se *session) error { + _, err := se.execute(context.Background(), del, "init_handle") + if err != nil { + logutil.BgLogger().Info("initDDLReorgHandle failed to delete", zap.Int64("jobID", jobID), zap.Error(err)) + } + _, err = se.execute(context.Background(), ins, "init_handle") + return err + }) } // deleteDDLReorgHandle deletes the handle for ddl reorg. -func removeDDLReorgHandle(sess *session, job *model.Job, elements []*meta.Element) error { +func removeDDLReorgHandle(s *session, job *model.Job, elements []*meta.Element) error { if len(elements) == 0 { return nil } sql := fmt.Sprintf("delete from mysql.tidb_ddl_reorg where job_id = %d", job.ID) - _, err := sess.execute(context.Background(), sql, "remove_handle") - return err + return s.runInTxn(func(se *session) error { + _, err := se.execute(context.Background(), sql, "remove_handle") + return err + }) } // removeReorgElement removes the element from ddl reorg, it is the same with removeDDLReorgHandle, only used in failpoint -func removeReorgElement(sess *session, job *model.Job) error { +func removeReorgElement(s *session, job *model.Job) error { sql := fmt.Sprintf("delete from mysql.tidb_ddl_reorg where job_id = %d", job.ID) - _, err := sess.execute(context.Background(), sql, "remove_handle") - return err + return s.runInTxn(func(se *session) error { + _, err := se.execute(context.Background(), sql, "remove_handle") + return err + }) +} + +// cleanDDLReorgHandles removes handles that are no longer needed. +func cleanDDLReorgHandles(s *session, job *model.Job) error { + sql := "delete from mysql.tidb_ddl_reorg where job_id = " + strconv.FormatInt(job.ID, 10) + return s.runInTxn(func(se *session) error { + _, err := se.execute(context.Background(), sql, "clean_handle") + return err + }) } func wrapKey2String(key []byte) string { @@ -496,134 +511,243 @@ func getJobsBySQL(sess *session, tbl, condition string) ([]*model.Job, error) { return jobs, nil } -// MoveJobFromQueue2Table move existing DDLs in queue to table. -func (d *ddl) MoveJobFromQueue2Table(inBootstrap bool) error { - sess, err := d.sessPool.get() - if err != nil { - return err - } - defer d.sessPool.put(sess) - return runInTxn(newSession(sess), func(se *session) error { - txn, err := se.txn() +func generateInsertBackfillJobSQL(tableName string, backfillJobs []*BackfillJob) (string, error) { + sqlPrefix := fmt.Sprintf("insert into mysql.%s(id, ddl_job_id, ele_id, ele_key, store_id, type, exec_id, exec_lease, state, curr_key, start_key, end_key, start_ts, finish_ts, row_count, backfill_meta) values", tableName) + var sql string + for i, bj := range backfillJobs { + mateByte, err := bj.Meta.Encode() if err != nil { - return errors.Trace(err) - } - t := meta.NewMeta(txn) - isConcurrentDDL, err := t.IsConcurrentDDL() - if !inBootstrap && (isConcurrentDDL || err != nil) { - return errors.Trace(err) - } - systemDBID, err := t.GetSystemDBID() - if err != nil { - return errors.Trace(err) - } - for _, tp := range []workerType{addIdxWorker, generalWorker} { - t := newMetaWithQueueTp(txn, tp) - jobs, err := t.GetAllDDLJobsInQueue() - if err != nil { - return errors.Trace(err) - } - for _, job := range jobs { - // In bootstrap, we can ignore the internal DDL. - if inBootstrap && job.SchemaID == systemDBID { - continue - } - err = insertDDLJobs2Table(se, false, job) - if err != nil { - return errors.Trace(err) - } - if tp == generalWorker { - // General job do not have reorg info. - continue - } - element, start, end, pid, err := t.GetDDLReorgHandle(job) - if meta.ErrDDLReorgElementNotExist.Equal(err) { - continue - } - if err != nil { - return errors.Trace(err) - } - err = initDDLReorgHandle(se, job.ID, start, end, pid, element) - if err != nil { - return errors.Trace(err) - } - } + return "", errors.Trace(err) } - if err = t.ClearALLDDLJob(); err != nil { - return errors.Trace(err) - } - if err = t.ClearAllDDLReorgHandle(); err != nil { - return errors.Trace(err) + if i == 0 { + sql = sqlPrefix + fmt.Sprintf("(%d, %d, %d, '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', %d, %d, %d, '%s')", + bj.ID, bj.JobID, bj.EleID, bj.EleKey, bj.StoreID, bj.Tp, bj.InstanceID, bj.InstanceLease, bj.State, + bj.CurrKey, bj.StartKey, bj.EndKey, bj.StartTS, bj.FinishTS, bj.RowCount, mateByte) + continue } - return t.SetConcurrentDDL(true) - }) + sql += fmt.Sprintf(", (%d, %d, %d, '%s', %d, %d, '%s', '%s', %d, '%s', '%s', '%s', %d, %d, %d, '%s')", + bj.ID, bj.JobID, bj.EleID, bj.EleKey, bj.StoreID, bj.Tp, bj.InstanceID, bj.InstanceLease, bj.State, + bj.CurrKey, bj.StartKey, bj.EndKey, bj.StartTS, bj.FinishTS, bj.RowCount, mateByte) + } + return sql, nil } -// MoveJobFromTable2Queue move existing DDLs in table to queue. -func (d *ddl) MoveJobFromTable2Queue() error { - sess, err := d.sessPool.get() +// AddBackfillHistoryJob adds the backfill jobs to the tidb_ddl_backfill_history table. +func AddBackfillHistoryJob(sess *session, backfillJobs []*BackfillJob) error { + label := fmt.Sprintf("add_%s_job", BackfillHistoryTable) + sql, err := generateInsertBackfillJobSQL(BackfillHistoryTable, backfillJobs) if err != nil { return err } - defer d.sessPool.put(sess) - return runInTxn(newSession(sess), func(se *session) error { + _, err = sess.execute(context.Background(), sql, label) + return errors.Trace(err) +} + +// AddBackfillJobs adds the backfill jobs to the tidb_ddl_backfill table. +func AddBackfillJobs(s *session, backfillJobs []*BackfillJob) error { + label := fmt.Sprintf("add_%s_job", BackfillTable) + // Do runInTxn to get StartTS. + return s.runInTxn(func(se *session) error { txn, err := se.txn() if err != nil { return errors.Trace(err) } - t := meta.NewMeta(txn) - isConcurrentDDL, err := t.IsConcurrentDDL() - if !isConcurrentDDL || err != nil { - return errors.Trace(err) + startTS := txn.StartTS() + for _, bj := range backfillJobs { + bj.StartTS = startTS } - jobs, err := getJobsBySQL(se, "tidb_ddl_job", "1 order by job_id") + + sql, err := generateInsertBackfillJobSQL(BackfillTable, backfillJobs) if err != nil { - return errors.Trace(err) + return err } + _, err = se.execute(context.Background(), sql, label) + return errors.Trace(err) + }) +} - for _, job := range jobs { - jobListKey := meta.DefaultJobListKey - if job.MayNeedReorg() { - jobListKey = meta.AddIndexJobListKey - } - if err := t.EnQueueDDLJobNoUpdate(job, jobListKey); err != nil { - return errors.Trace(err) - } +// GetBackfillJobsForOneEle batch gets the backfill jobs in the tblName table that contains only one element. +func GetBackfillJobsForOneEle(s *session, batch int, excludedJobIDs []int64, lease time.Duration) ([]*BackfillJob, error) { + eJobIDsBuilder := strings.Builder{} + for i, id := range excludedJobIDs { + if i == 0 { + eJobIDsBuilder.WriteString(" and ddl_job_id not in (") + } + eJobIDsBuilder.WriteString(strconv.Itoa(int(id))) + if i == len(excludedJobIDs)-1 { + eJobIDsBuilder.WriteString(")") + } else { + eJobIDsBuilder.WriteString(", ") } + } - reorgHandle, err := se.execute(context.Background(), "select job_id, start_key, end_key, physical_id, ele_id, ele_type from mysql.tidb_ddl_reorg", "get_handle") + var err error + var bJobs []*BackfillJob + err = s.runInTxn(func(se *session) error { + currTime, err := GetOracleTimeWithStartTS(se) if err != nil { - return errors.Trace(err) + return err } - for _, row := range reorgHandle { - if err := t.UpdateDDLReorgHandle(row.GetInt64(0), row.GetBytes(1), row.GetBytes(2), row.GetInt64(3), &meta.Element{ID: row.GetInt64(4), TypeKey: row.GetBytes(5)}); err != nil { - return errors.Trace(err) - } + + bJobs, err = GetBackfillJobs(se, BackfillTable, + fmt.Sprintf("(exec_ID = '' or exec_lease < '%v') %s order by ddl_job_id, ele_key, ele_id limit %d", + currTime.Add(-lease), eJobIDsBuilder.String(), batch), "get_backfill_job") + return err + }) + if err != nil || len(bJobs) == 0 { + return nil, err + } + + validLen := 1 + firstJobID, firstEleID, firstEleKey := bJobs[0].JobID, bJobs[0].EleID, bJobs[0].EleKey + for i := 1; i < len(bJobs); i++ { + if bJobs[i].JobID != firstJobID || bJobs[i].EleID != firstEleID || !bytes.Equal(bJobs[i].EleKey, firstEleKey) { + break } + validLen++ + } + + return bJobs[:validLen], nil +} - // clean up these 2 tables. - _, err = se.execute(context.Background(), "delete from mysql.tidb_ddl_job", "delete_old_ddl") +// GetAndMarkBackfillJobsForOneEle batch gets the backfill jobs in the tblName table that contains only one element, +// and update these jobs with instance ID and lease. +func GetAndMarkBackfillJobsForOneEle(s *session, batch int, jobID int64, uuid string, lease time.Duration) ([]*BackfillJob, error) { + var validLen int + var bJobs []*BackfillJob + err := s.runInTxn(func(se *session) error { + currTime, err := GetOracleTimeWithStartTS(se) if err != nil { - return errors.Trace(err) + return err } - _, err = se.execute(context.Background(), "delete from mysql.tidb_ddl_reorg", "delete_old_reorg") + + bJobs, err = GetBackfillJobs(se, BackfillTable, + fmt.Sprintf("(exec_ID = '' or exec_lease < '%v') and ddl_job_id = %d order by ddl_job_id, ele_key, ele_id limit %d", + currTime.Add(-lease), jobID, batch), "get_mark_backfill_job") if err != nil { - return errors.Trace(err) + return err + } + if len(bJobs) == 0 { + return dbterror.ErrDDLJobNotFound.FastGen("get zero backfill job") + } + + validLen = 0 + firstJobID, firstEleID, firstEleKey := bJobs[0].JobID, bJobs[0].EleID, bJobs[0].EleKey + for i := 0; i < len(bJobs); i++ { + if bJobs[i].JobID != firstJobID || bJobs[i].EleID != firstEleID || !bytes.Equal(bJobs[i].EleKey, firstEleKey) { + break + } + validLen++ + + bJobs[i].InstanceID = uuid + bJobs[i].InstanceLease = GetLeaseGoTime(currTime, lease) + // TODO: batch update + if err = updateBackfillJob(se, BackfillTable, bJobs[i], "get_mark_backfill_job"); err != nil { + return err + } } - return t.SetConcurrentDDL(false) + return nil }) + if validLen == 0 { + return nil, err + } + + return bJobs[:validLen], err } -func runInTxn(se *session, f func(*session) error) (err error) { - err = se.begin() +// GetInterruptedBackfillJobsForOneEle gets the interrupted backfill jobs in the tblName table that contains only one element. +func GetInterruptedBackfillJobsForOneEle(sess *session, jobID, eleID int64, eleKey []byte) ([]*BackfillJob, error) { + bJobs, err := GetBackfillJobs(sess, BackfillTable, fmt.Sprintf("ddl_job_id = %d and ele_id = %d and ele_key = '%s' and (state = %d or state = %d)", + jobID, eleID, eleKey, model.JobStateRollingback, model.JobStateCancelling), "get_interrupt_backfill_job") + if err != nil || len(bJobs) == 0 { + return nil, err + } + return bJobs, nil +} + +// GetBackfillJobCount gets the number of rows in the tblName table according to condition. +func GetBackfillJobCount(sess *session, tblName, condition string, label string) (int, error) { + rows, err := sess.execute(context.Background(), fmt.Sprintf("select count(1) from mysql.%s where %s", tblName, condition), label) if err != nil { - return err + return 0, errors.Trace(err) } - err = f(se) + if len(rows) == 0 { + return 0, dbterror.ErrDDLJobNotFound.FastGenByArgs(fmt.Sprintf("get wrong result cnt:%d", len(rows))) + } + + return int(rows[0].GetInt64(0)), nil +} + +func getUnsyncedInstanceIDs(sess *session, jobID int64, label string) ([]string, error) { + sql := fmt.Sprintf("select sum(state = %d) as tmp, exec_id from mysql.tidb_ddl_backfill_history where ddl_job_id = %d group by exec_id having tmp = 0;", + model.JobStateSynced, jobID) + rows, err := sess.execute(context.Background(), sql, label) if err != nil { - se.rollback() - return + return nil, errors.Trace(err) + } + InstanceIDs := make([]string, 0, len(rows)) + for _, row := range rows { + InstanceID := row.GetString(1) + InstanceIDs = append(InstanceIDs, InstanceID) + } + return InstanceIDs, nil +} + +// GetBackfillJobs gets the backfill jobs in the tblName table according to condition. +func GetBackfillJobs(sess *session, tblName, condition string, label string) ([]*BackfillJob, error) { + rows, err := sess.execute(context.Background(), fmt.Sprintf("select * from mysql.%s where %s", tblName, condition), label) + if err != nil { + return nil, errors.Trace(err) } - return errors.Trace(se.commit()) + bJobs := make([]*BackfillJob, 0, len(rows)) + for _, row := range rows { + bfJob := BackfillJob{ + ID: row.GetInt64(0), + JobID: row.GetInt64(1), + EleID: row.GetInt64(2), + EleKey: row.GetBytes(3), + StoreID: row.GetInt64(4), + Tp: backfillerType(row.GetInt64(5)), + InstanceID: row.GetString(6), + InstanceLease: row.GetTime(7), + State: model.JobState(row.GetInt64(8)), + CurrKey: row.GetBytes(9), + StartKey: row.GetBytes(10), + EndKey: row.GetBytes(11), + StartTS: row.GetUint64(12), + FinishTS: row.GetUint64(13), + RowCount: row.GetInt64(14), + } + bfJob.Meta = &model.BackfillMeta{} + err = bfJob.Meta.Decode(row.GetBytes(15)) + if err != nil { + return nil, errors.Trace(err) + } + bJobs = append(bJobs, &bfJob) + } + return bJobs, nil +} + +// RemoveBackfillJob removes the backfill jobs from the tidb_ddl_backfill table. +// If isOneEle is true, removes all jobs with backfillJob's ddl_job_id, ele_id and ele_key. Otherwise, removes the backfillJob. +func RemoveBackfillJob(sess *session, isOneEle bool, backfillJob *BackfillJob) error { + sql := fmt.Sprintf("delete from mysql.tidb_ddl_backfill where ddl_job_id = %d and ele_id = %d and ele_key = '%s'", + backfillJob.JobID, backfillJob.EleID, backfillJob.EleKey) + if !isOneEle { + sql += fmt.Sprintf(" and id = %d", backfillJob.ID) + } + _, err := sess.execute(context.Background(), sql, "remove_backfill_job") + return err +} + +func updateBackfillJob(sess *session, tableName string, backfillJob *BackfillJob, label string) error { + mate, err := backfillJob.Meta.Encode() + if err != nil { + return err + } + sql := fmt.Sprintf("update mysql.%s set exec_id = '%s', exec_lease = '%s', state = %d, backfill_meta = '%s' where ddl_job_id = %d and ele_id = %d and ele_key = '%s' and id = %d", + tableName, backfillJob.InstanceID, backfillJob.InstanceLease, backfillJob.State, mate, backfillJob.JobID, backfillJob.EleID, backfillJob.EleKey, backfillJob.ID) + _, err = sess.execute(context.Background(), sql, label) + return err } diff --git a/ddl/job_table_test.go b/ddl/job_table_test.go index 8f9e59ae31084..d869dcecc2c0e 100644 --- a/ddl/job_table_test.go +++ b/ddl/job_table_test.go @@ -15,16 +15,22 @@ package ddl_test import ( + "context" + "fmt" "sync" "testing" "time" "github.com/pingcap/failpoint" "github.com/pingcap/tidb/ddl" + "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/parser/model" - "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/dbterror" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" ) @@ -33,9 +39,6 @@ import ( // This test checks the chosen job records to see if there are wrong scheduling, if job A and job B cannot run concurrently, // then the all the record of job A must before or after job B, no cross record between these 2 jobs should be in between. func TestDDLScheduling(t *testing.T) { - if !variable.EnableConcurrentDDL.Load() { - t.Skipf("test requires concurrent ddl") - } store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) @@ -177,3 +180,363 @@ func check(t *testing.T, record []int64, ids ...int64) { } } } + +func makeAddIdxBackfillJobs(schemaID, tblID, jobID, eleID int64, cnt int, query string) []*ddl.BackfillJob { + bJobs := make([]*ddl.BackfillJob, 0, cnt) + for i := 0; i < cnt; i++ { + sKey := []byte(fmt.Sprintf("%d", i)) + eKey := []byte(fmt.Sprintf("%d", i+1)) + bm := &model.BackfillMeta{ + EndInclude: true, + JobMeta: &model.JobMeta{ + SchemaID: schemaID, + TableID: tblID, + Query: query, + }, + } + bj := &ddl.BackfillJob{ + ID: int64(i), + JobID: jobID, + EleID: eleID, + EleKey: meta.IndexElementKey, + State: model.JobStateNone, + CurrKey: sKey, + StartKey: sKey, + EndKey: eKey, + Meta: bm, + } + bJobs = append(bJobs, bj) + } + return bJobs +} + +func equalBackfillJob(t *testing.T, a, b *ddl.BackfillJob, lessTime types.Time) { + require.Equal(t, a.ID, b.ID) + require.Equal(t, a.JobID, b.JobID) + require.Equal(t, a.EleID, b.EleID) + require.Equal(t, a.EleKey, b.EleKey) + require.Equal(t, a.StoreID, b.StoreID) + require.Equal(t, a.InstanceID, b.InstanceID) + require.GreaterOrEqual(t, b.InstanceLease.Compare(lessTime), 0) + require.Equal(t, a.State, b.State) + require.Equal(t, a.Meta, b.Meta) +} + +func getIdxConditionStr(jobID, eleID int64) string { + return fmt.Sprintf("ddl_job_id = %d and ele_id = %d and ele_key = '%s'", + jobID, eleID, meta.IndexElementKey) +} + +func readInTxn(se sessionctx.Context, f func(sessionctx.Context)) (err error) { + err = sessiontxn.NewTxn(context.Background(), se) + if err != nil { + return err + } + f(se) + se.RollbackTxn(context.Background()) + return nil +} + +func TestSimpleExecBackfillJobs(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + d := dom.DDL() + se := ddl.NewSession(tk.Session()) + + jobID1 := int64(1) + jobID2 := int64(2) + eleID1 := int64(11) + eleID2 := int64(22) + eleID3 := int64(33) + uuid := d.GetID() + eleKey := meta.IndexElementKey + instanceLease := ddl.InstanceLease + // test no backfill job + bJobs, err := ddl.GetBackfillJobsForOneEle(se, 1, []int64{jobID1, jobID2}, instanceLease) + require.NoError(t, err) + require.Nil(t, bJobs) + bJobs, err = ddl.GetAndMarkBackfillJobsForOneEle(se, 1, jobID1, uuid, instanceLease) + require.EqualError(t, err, dbterror.ErrDDLJobNotFound.FastGen("get zero backfill job").Error()) + require.Nil(t, bJobs) + allCnt, err := ddl.GetBackfillJobCount(se, ddl.BackfillTable, fmt.Sprintf("ddl_job_id = %d and ele_id = %d and ele_key = '%s'", + jobID1, eleID2, meta.IndexElementKey), "check_backfill_job_count") + require.NoError(t, err) + require.Equal(t, allCnt, 0) + // Test some backfill jobs, add backfill jobs to the table. + cnt := 2 + bjTestCases := make([]*ddl.BackfillJob, 0, cnt*3) + bJobs1 := makeAddIdxBackfillJobs(1, 2, jobID1, eleID1, cnt, "alter table add index idx(a)") + bJobs2 := makeAddIdxBackfillJobs(1, 2, jobID2, eleID2, cnt, "alter table add index idx(b)") + bJobs3 := makeAddIdxBackfillJobs(1, 2, jobID2, eleID3, cnt, "alter table add index idx(c)") + bjTestCases = append(bjTestCases, bJobs1...) + bjTestCases = append(bjTestCases, bJobs2...) + bjTestCases = append(bjTestCases, bJobs3...) + err = ddl.AddBackfillJobs(se, bjTestCases) + // ID jobID eleID InstanceID + // ------------------------------------- + // 0 jobID1 eleID1 uuid + // 1 jobID1 eleID1 "" + // 0 jobID2 eleID2 "" + // 1 jobID2 eleID2 "" + // 0 jobID2 eleID3 "" + // 1 jobID2 eleID3 "" + require.NoError(t, err) + // test get some backfill jobs + bJobs, err = ddl.GetBackfillJobsForOneEle(se, 1, []int64{jobID2 - 1, jobID2 + 1}, instanceLease) + require.NoError(t, err) + require.Len(t, bJobs, 1) + expectJob := bjTestCases[2] + if expectJob.ID != bJobs[0].ID { + expectJob = bjTestCases[3] + } + require.Equal(t, expectJob, bJobs[0]) + previousTime, err := ddl.GetOracleTimeWithStartTS(se) + require.EqualError(t, err, "[kv:8024]invalid transaction") + readInTxn(se, func(sessionctx.Context) { + previousTime, err = ddl.GetOracleTimeWithStartTS(se) + require.NoError(t, err) + }) + + bJobs, err = ddl.GetAndMarkBackfillJobsForOneEle(se, 1, jobID2, uuid, instanceLease) + require.NoError(t, err) + require.Len(t, bJobs, 1) + expectJob = bjTestCases[2] + if expectJob.ID != bJobs[0].ID { + expectJob = bjTestCases[3] + } + expectJob.InstanceID = uuid + equalBackfillJob(t, expectJob, bJobs[0], ddl.GetLeaseGoTime(previousTime, instanceLease)) + var currTime time.Time + readInTxn(se, func(sessionctx.Context) { + currTime, err = ddl.GetOracleTimeWithStartTS(se) + require.NoError(t, err) + }) + currGoTime := ddl.GetLeaseGoTime(currTime, instanceLease) + require.GreaterOrEqual(t, currGoTime.Compare(bJobs[0].InstanceLease), 0) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID2, eleID2), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, cnt) + + // remove a backfill job + err = ddl.RemoveBackfillJob(se, false, bJobs1[0]) + // ID jobID eleID + // ------------------------ + // 1 jobID1 eleID1 + // 0 jobID2 eleID2 + // 1 jobID2 eleID2 + // 0 jobID2 eleID3 + // 1 jobID2 eleID3 + require.NoError(t, err) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID1, eleID1), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 1) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID2, eleID2), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, cnt) + // remove all backfill jobs + err = ddl.RemoveBackfillJob(se, true, bJobs2[0]) + // ID jobID eleID + // ------------------------ + // 1 jobID1 eleID1 + // 0 jobID2 eleID3 + // 1 jobID2 eleID3 + require.NoError(t, err) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID1, eleID1), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 1) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID2, eleID2), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 0) + // clean backfill job + err = ddl.RemoveBackfillJob(se, true, bJobs1[1]) + require.NoError(t, err) + err = ddl.RemoveBackfillJob(se, true, bJobs3[0]) + require.NoError(t, err) + // ID jobID eleID + // ------------------------ + + // test history backfill jobs + err = ddl.AddBackfillHistoryJob(se, []*ddl.BackfillJob{bJobs2[0]}) + require.NoError(t, err) + // ID jobID eleID + // ------------------------ + // 0 jobID2 eleID2 + readInTxn(se, func(sessionctx.Context) { + currTime, err = ddl.GetOracleTimeWithStartTS(se) + require.NoError(t, err) + }) + condition := fmt.Sprintf("exec_ID = '' or exec_lease < '%v' and ddl_job_id = %d order by ddl_job_id", currTime.Add(-instanceLease), jobID2) + bJobs, err = ddl.GetBackfillJobs(se, ddl.BackfillHistoryTable, condition, "test_get_bj") + require.NoError(t, err) + require.Len(t, bJobs, 1) + require.Equal(t, bJobs[0].FinishTS, uint64(0)) + + // test GetMaxBackfillJob and GetInterruptedBackfillJobsForOneEle + bjob, err := ddl.GetMaxBackfillJob(se, bJobs3[0].JobID, bJobs3[0].EleID, eleKey) + require.NoError(t, err) + require.Nil(t, bjob) + bJobs, err = ddl.GetInterruptedBackfillJobsForOneEle(se, jobID1, eleID1, eleKey) + require.NoError(t, err) + require.Nil(t, bJobs) + err = ddl.AddBackfillJobs(se, bjTestCases) + require.NoError(t, err) + // ID jobID eleID + // ------------------------ + // 0 jobID1 eleID1 + // 1 jobID1 eleID1 + // 0 jobID2 eleID2 + // 1 jobID2 eleID2 + // 0 jobID2 eleID3 + // 1 jobID2 eleID3 + bjob, err = ddl.GetMaxBackfillJob(se, jobID2, eleID2, eleKey) + require.NoError(t, err) + require.Equal(t, bJobs2[1], bjob) + bJobs, err = ddl.GetInterruptedBackfillJobsForOneEle(se, jobID1, eleID1, eleKey) + require.NoError(t, err) + require.Nil(t, bJobs) + bJobs1[0].State = model.JobStateRollingback + bJobs1[0].ID = 2 + bJobs1[0].InstanceID = uuid + bJobs1[1].State = model.JobStateCancelling + bJobs1[1].ID = 3 + bJobs1[1].Meta.ErrMsg = "errMsg" + err = ddl.AddBackfillJobs(se, bJobs1) + require.NoError(t, err) + // ID jobID eleID state + // -------------------------------- + // 0 jobID1 eleID1 JobStateNone + // 1 jobID1 eleID1 JobStateNone + // 0 jobID2 eleID2 JobStateNone + // 1 jobID2 eleID2 JobStateNone + // 0 jobID2 eleID3 JobStateNone + // 1 jobID2 eleID3 JobStateNone + // 2 jobID1 eleID1 JobStateRollingback + // 3 jobID1 eleID1 JobStateCancelling + bjob, err = ddl.GetMaxBackfillJob(se, jobID1, eleID1, eleKey) + require.NoError(t, err) + require.Equal(t, bJobs1[1], bjob) + bJobs, err = ddl.GetInterruptedBackfillJobsForOneEle(se, jobID1, eleID1, eleKey) + require.NoError(t, err) + require.Len(t, bJobs, 2) + equalBackfillJob(t, bJobs1[0], bJobs[0], types.ZeroTime) + equalBackfillJob(t, bJobs1[1], bJobs[1], types.ZeroTime) + // test the BackfillJob's AbbrStr + require.Equal(t, fmt.Sprintf("ID:2, JobID:1, EleID:11, Type:add index, State:rollingback, InstanceID:%s, InstanceLease:0000-00-00 00:00:00", uuid), bJobs1[0].AbbrStr()) + require.Equal(t, "ID:3, JobID:1, EleID:11, Type:add index, State:cancelling, InstanceID:, InstanceLease:0000-00-00 00:00:00", bJobs1[1].AbbrStr()) + require.Equal(t, "ID:0, JobID:2, EleID:33, Type:add index, State:none, InstanceID:, InstanceLease:0000-00-00 00:00:00", bJobs3[0].AbbrStr()) + require.Equal(t, "ID:1, JobID:2, EleID:33, Type:add index, State:none, InstanceID:, InstanceLease:0000-00-00 00:00:00", bJobs3[1].AbbrStr()) + + bJobs1[0].State = model.JobStateNone + bJobs1[0].ID = 5 + bJobs1[1].State = model.JobStateNone + bJobs1[1].ID = 4 + err = ddl.AddBackfillHistoryJob(se, bJobs1) + // BackfillTable + // ID jobID eleID state + // -------------------------------- + // 0 jobID1 eleID1 JobStateNone + // 1 jobID1 eleID1 JobStateNone + // 0 jobID2 eleID2 JobStateNone + // 1 jobID2 eleID2 JobStateNone + // 0 jobID2 eleID3 JobStateNone + // 1 jobID2 eleID3 JobStateNone + // 2 jobID1 eleID1 JobStateRollingback + // 3 jobID1 eleID1 JobStateCancelling + // + // BackfillHistoryTable + // ID jobID eleID state + // -------------------------------- + // 5 jobID1 eleID1 JobStateNone + // 4 jobID1 eleID1 JobStateNone + bjob, err = ddl.GetMaxBackfillJob(se, jobID1, eleID1, eleKey) + require.NoError(t, err) + require.Equal(t, bJobs1[0], bjob) + bJobs1[0].ID = 6 + bJobs1[1].ID = 7 + err = ddl.AddBackfillJobs(se, bJobs1) + // BackfillTable + // ID jobID eleID state + // -------------------------------- + // 0 jobID1 eleID1 JobStateNone + // 1 jobID1 eleID1 JobStateNone + // 0 jobID2 eleID2 JobStateNone + // 1 jobID2 eleID2 JobStateNone + // 0 jobID2 eleID3 JobStateNone + // 1 jobID2 eleID3 JobStateNone + // 2 jobID1 eleID1 JobStateRollingback + // 3 jobID1 eleID1 JobStateCancelling + // 6 jobID1 eleID1 JobStateNone + // 7 jobID1 eleID1 JobStateNone + // + // BackfillHistoryTable + // ID jobID eleID state + // -------------------------------- + // 5 jobID1 eleID1 JobStateNone + // 4 jobID1 eleID1 JobStateNone + bjob, err = ddl.GetMaxBackfillJob(se, jobID1, eleID1, eleKey) + require.NoError(t, err) + require.Equal(t, bJobs1[1], bjob) + + // test MoveBackfillJobsToHistoryTable + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID2, eleID3), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 2) + err = ddl.MoveBackfillJobsToHistoryTable(se, bJobs3[0]) + require.NoError(t, err) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID2, eleID3), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 0) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillHistoryTable, getIdxConditionStr(jobID2, eleID3), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 2) + // BackfillTable + // ID jobID eleID state + // -------------------------------- + // 0 jobID1 eleID1 JobStateNone + // 1 jobID1 eleID1 JobStateNone + // 0 jobID2 eleID2 JobStateNone + // 1 jobID2 eleID2 JobStateNone + // 2 jobID1 eleID1 JobStateRollingback + // 3 jobID1 eleID1 JobStateCancelling + // 6 jobID1 eleID1 JobStateNone + // 7 jobID1 eleID1 JobStateNone + // + // BackfillHistoryTable + // ID jobID eleID state + // -------------------------------- + // 5 jobID1 eleID1 JobStateNone + // 4 jobID1 eleID1 JobStateNone + // 0 jobID2 eleID3 JobStateNone + // 1 jobID2 eleID3 JobStateNone + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID1, eleID1), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 6) + err = ddl.MoveBackfillJobsToHistoryTable(se, bJobs1[0]) + require.NoError(t, err) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillTable, getIdxConditionStr(jobID1, eleID1), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 0) + allCnt, err = ddl.GetBackfillJobCount(se, ddl.BackfillHistoryTable, getIdxConditionStr(jobID1, eleID1), "test_get_bj") + require.NoError(t, err) + require.Equal(t, allCnt, 8) + // BackfillTable + // ID jobID eleID state + // -------------------------------- + // 0 jobID2 eleID2 JobStateNone + // 1 jobID2 eleID2 JobStateNone + // + // BackfillHistoryTable + // ID jobID eleID state + // -------------------------------- + // 5 jobID1 eleID1 JobStateNone + // 4 jobID1 eleID1 JobStateNone + // 0 jobID2 eleID3 JobStateNone + // 1 jobID2 eleID3 JobStateNone + // 0 jobID1 eleID1 JobStateNone + // 1 jobID1 eleID1 JobStateNone + // 2 jobID1 eleID1 JobStateRollingback + // 3 jobID1 eleID1 JobStateCancelling + // 6 jobID1 eleID1 JobStateNone + // 7 jobID1 eleID1 JobStateNone +} diff --git a/ddl/label/main_test.go b/ddl/label/main_test.go index b077fcc255bcc..559584b77f407 100644 --- a/ddl/label/main_test.go +++ b/ddl/label/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/ddl/main_test.go b/ddl/main_test.go index 91558d1e44e27..6a8642ae34380 100644 --- a/ddl/main_test.go +++ b/ddl/main_test.go @@ -60,8 +60,12 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), + goleak.IgnoreTopFunction("net/http.(*persistConn).writeLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/ddl/metadatalocktest/main_test.go b/ddl/metadatalocktest/main_test.go index 62dbb9a626287..4a52dad904905 100644 --- a/ddl/metadatalocktest/main_test.go +++ b/ddl/metadatalocktest/main_test.go @@ -36,6 +36,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/ddl/metadatalocktest/mdl_test.go b/ddl/metadatalocktest/mdl_test.go index d91bee7010013..d7c05fa334508 100644 --- a/ddl/metadatalocktest/mdl_test.go +++ b/ddl/metadatalocktest/mdl_test.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !featuretag - package metadatalocktest import ( @@ -257,6 +255,47 @@ func TestMDLBasicBatchPointGet(t *testing.T) { require.Less(t, ts1, ts2) } +func TestMDLAddForeignKey(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + sv := server.CreateMockServer(t, store) + + sv.SetDomain(dom) + dom.InfoSyncer().SetSessionManager(sv) + defer sv.Close() + + conn1 := server.CreateMockConn(t, sv) + tk := testkit.NewTestKitWithSession(t, store, conn1.Context().Session) + conn2 := server.CreateMockConn(t, sv) + tkDDL := testkit.NewTestKitWithSession(t, store, conn2.Context().Session) + tk.MustExec("use test") + tk.MustExec("set global tidb_enable_metadata_lock=1") + tk.MustExec("create table t1(id int key);") + tk.MustExec("create table t2(id int key);") + + tk.MustExec("begin") + tk.MustExec("insert into t2 values(1);") + + var wg sync.WaitGroup + var ddlErr error + wg.Add(1) + var ts2 time.Time + go func() { + defer wg.Done() + ddlErr = tkDDL.ExecToErr("alter table test.t2 add foreign key (id) references t1(id)") + ts2 = time.Now() + }() + + time.Sleep(2 * time.Second) + + ts1 := time.Now() + tk.MustExec("commit") + + wg.Wait() + require.Error(t, ddlErr) + require.Equal(t, "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))", ddlErr.Error()) + require.Less(t, ts1, ts2) +} + func TestMDLRRUpdateSchema(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) sv := server.CreateMockServer(t, store) @@ -292,7 +331,7 @@ func TestMDLRRUpdateSchema(t *testing.T) { // Modify column(reorg). tk.MustExec("begin") tkDDL.MustExec("alter table test.t modify column a char(10);") - tk.MustGetErrCode("select * from t", mysql.ErrSchemaChanged) + tk.MustGetErrCode("select * from t", mysql.ErrInfoSchemaChanged) tk.MustExec("commit") tk.MustQuery("select * from t").Check(testkit.Rows("1 ")) @@ -1105,3 +1144,16 @@ func TestMDLRenameTable(t *testing.T) { tk.MustGetErrCode("select * from test2.t1;", mysql.ErrNoSuchTable) tk.MustExec("commit") } + +func TestMDLPrepareFail(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int);") + _, _, _, err := tk.Session().PrepareStmt("select b from t") + require.Error(t, err) + + tk2.MustExec("alter table test.t add column c int") +} diff --git a/ddl/modify_column_test.go b/ddl/modify_column_test.go index 10a9835bc8215..6eb8e633be007 100644 --- a/ddl/modify_column_test.go +++ b/ddl/modify_column_test.go @@ -17,6 +17,7 @@ package ddl_test import ( "context" "fmt" + "strconv" "sync" "testing" "time" @@ -50,6 +51,11 @@ func batchInsert(tk *testkit.TestKit, tbl string, start, end int) { func TestModifyColumnReorgInfo(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) + originalTimeout := ddl.ReorgWaitTimeout + ddl.ReorgWaitTimeout = 10 * time.Millisecond + defer func() { + ddl.ReorgWaitTimeout = originalTimeout + }() tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t1") @@ -112,14 +118,18 @@ func TestModifyColumnReorgInfo(t *testing.T) { require.NoError(t, checkErr) // Check whether the reorg information is cleaned up when executing "modify column" failed. checkReorgHandle := func(gotElements, expectedElements []*meta.Element) { + require.Equal(t, len(expectedElements), len(gotElements)) for i, e := range gotElements { require.Equal(t, expectedElements[i], e) } + // check the consistency of the tables. + currJobID := strconv.FormatInt(currJob.ID, 10) + tk.MustQuery("select job_id, reorg, schema_ids, table_ids, type, processing from mysql.tidb_ddl_job where job_id = " + currJobID).Check(testkit.Rows()) + tk.MustQuery("select job_id from mysql.tidb_ddl_history where job_id = " + currJobID).Check(testkit.Rows(currJobID)) + tk.MustQuery("select job_id, ele_id, ele_type, physical_id from mysql.tidb_ddl_reorg where job_id = " + currJobID).Check(testkit.Rows()) require.NoError(t, sessiontxn.NewTxn(context.Background(), ctx)) - txn, err := ctx.Txn(true) - require.NoError(t, err) - m := meta.NewMeta(txn) - e, start, end, physicalID, err := ddl.NewReorgHandlerForTest(m, testkit.NewTestKit(t, store).Session()).GetDDLReorgHandle(currJob) + e, start, end, physicalID, err := ddl.NewReorgHandlerForTest(testkit.NewTestKit(t, store).Session()).GetDDLReorgHandle(currJob) + require.Error(t, err, "Error not ErrDDLReorgElementNotExists, found orphan row in tidb_ddl_reorg for job.ID %d: e: '%s', physicalID: %d, start: 0x%x end: 0x%x", currJob.ID, e, physicalID, start, end) require.True(t, meta.ErrDDLReorgElementNotExist.Equal(err)) require.Nil(t, e) require.Nil(t, start) @@ -813,10 +823,7 @@ func TestModifyColumnTypeWithWarnings(t *testing.T) { // 111.22 will be truncated the fraction .22 as .2 with truncated warning for each row. tk.MustExec("alter table t modify column a decimal(4,1)") // there should 4 rows of warnings corresponding to the origin rows. - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 Truncated incorrect DECIMAL value: '111.22'", - "Warning 1292 Truncated incorrect DECIMAL value: '111.22'", - "Warning 1292 Truncated incorrect DECIMAL value: '111.22'", - "Warning 1292 Truncated incorrect DECIMAL value: '111.22'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 4 warnings with this error code, first warning: Truncated incorrect DECIMAL value: '111.22'")) // Test the strict warnings is treated as errors under the strict mode. tk.MustExec("drop table if exists t") @@ -829,15 +836,13 @@ func TestModifyColumnTypeWithWarnings(t *testing.T) { // Test the strict warnings is treated as warnings under the non-strict mode. tk.MustExec("set @@sql_mode=\"\"") tk.MustExec("alter table t modify column a decimal(3,1)") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1690 DECIMAL value is out of range in '(3, 1)'", - "Warning 1690 DECIMAL value is out of range in '(3, 1)'", - "Warning 1690 DECIMAL value is out of range in '(3, 1)'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1690 3 warnings with this error code, first warning: DECIMAL value is out of range in '(3, 1)'")) } // TestModifyColumnTypeWhenInterception is to test modifying column type with warnings intercepted by // reorg timeout, not owner error and so on. func TestModifyColumnTypeWhenInterception(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) + store, _ := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -858,42 +863,10 @@ func TestModifyColumnTypeWhenInterception(t *testing.T) { // Make the regions scale like: [1, 1024), [1024, 2048), [2048, 3072), [3072, 4096] tk.MustQuery("split table t between(0) and (4096) regions 4") - d := dom.DDL() - hook := &ddl.TestDDLCallback{} - var checkMiddleWarningCount bool - var checkMiddleAddedCount bool - // Since the `DefTiDBDDLReorgWorkerCount` is 4, every worker will be assigned with one region - // for the first time. Here we mock the insert failure/reorg timeout in region [2048, 3072) - // which will lead next handle be set to 2048 and partial warnings be stored into ddl job. - // Since the existence of reorg batch size, only the last reorg batch [2816, 3072) of kv - // range [2048, 3072) fail to commit, the rest of them all committed successfully. So the - // addedCount and warnings count in the job are all equal to `4096 - reorg batch size`. - // In the next round of this ddl job, the last reorg batch will be finished. - var middleWarningsCount = int64(defaultBatchSize*4 - defaultReorgBatchSize) - onJobUpdatedExportedFunc := func(job *model.Job) { - if job.SchemaState == model.StateWriteReorganization || job.SnapshotVer != 0 { - if len(job.ReorgMeta.WarningsCount) == len(job.ReorgMeta.Warnings) { - for _, v := range job.ReorgMeta.WarningsCount { - if v == middleWarningsCount { - checkMiddleWarningCount = true - } - } - } - if job.RowCount == middleWarningsCount { - checkMiddleAddedCount = true - } - } - } - hook.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) - d.SetHook(hook) require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/MockReorgTimeoutInOneRegion", `return(true)`)) defer func() { require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/MockReorgTimeoutInOneRegion")) }() tk.MustExec("alter table t modify column b decimal(3,1)") - require.True(t, checkMiddleWarningCount) - require.True(t, checkMiddleAddedCount) - - res := tk.MustQuery("show warnings") - require.Len(t, res.Rows(), count) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 4096 warnings with this error code, first warning: Truncated incorrect DECIMAL value: '11.22'")) } diff --git a/ddl/multi_schema_change.go b/ddl/multi_schema_change.go index 894b926ba512e..19c355ebfa8da 100644 --- a/ddl/multi_schema_change.go +++ b/ddl/multi_schema_change.go @@ -118,11 +118,13 @@ func onMultiSchemaChange(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job) (ve proxyJob := sub.ToProxyJob(job) if schemaVersionGenerated { proxyJob.MultiSchemaInfo.SkipVersion = true - } else { + } + proxyJobVer, err := w.runDDLJob(d, t, &proxyJob) + if !schemaVersionGenerated && proxyJobVer != 0 { schemaVersionGenerated = true + ver = proxyJobVer } - ver, err = w.runDDLJob(d, t, &proxyJob) - sub.FromProxyJob(&proxyJob, ver) + sub.FromProxyJob(&proxyJob, proxyJobVer) if err != nil || proxyJob.Error != nil { for j := i - 1; j >= 0; j-- { job.MultiSchemaInfo.SubJobs[j] = &subJobs[j] @@ -188,6 +190,10 @@ func appendToSubJobs(m *model.MultiSchemaInfo, job *model.Job) error { if err != nil { return err } + var reorgTp model.ReorgType + if job.ReorgMeta != nil { + reorgTp = job.ReorgMeta.ReorgTp + } m.SubJobs = append(m.SubJobs, &model.SubJob{ Type: job.Type, Args: job.Args, @@ -196,6 +202,7 @@ func appendToSubJobs(m *model.MultiSchemaInfo, job *model.Job) error { SnapshotVer: job.SnapshotVer, Revertible: true, CtxVars: job.CtxVars, + ReorgTp: reorgTp, }) return nil } @@ -257,6 +264,12 @@ func fillMultiSchemaInfo(info *model.MultiSchemaInfo, job *model.Job) (err error idxName := job.Args[0].(model.CIStr) info.AlterIndexes = append(info.AlterIndexes, idxName) case model.ActionRebaseAutoID, model.ActionModifyTableComment, model.ActionModifyTableCharsetAndCollate: + case model.ActionAddForeignKey: + fkInfo := job.Args[0].(*model.FKInfo) + info.AddForeignKeys = append(info.AddForeignKeys, model.AddForeignKeyInfo{ + Name: fkInfo.Name, + Cols: fkInfo.Cols, + }) default: return dbterror.ErrRunMultiSchemaChanges.FastGenByArgs(job.Type.String()) } @@ -318,6 +331,32 @@ func checkOperateSameColAndIdx(info *model.MultiSchemaInfo) error { return checkIndexes(info.AlterIndexes, true) } +func checkOperateDropIndexUseByForeignKey(info *model.MultiSchemaInfo, t table.Table) error { + var remainIndexes, droppingIndexes []*model.IndexInfo + tbInfo := t.Meta() + for _, idx := range tbInfo.Indices { + dropping := false + for _, name := range info.DropIndexes { + if name.L == idx.Name.L { + dropping = true + break + } + } + if dropping { + droppingIndexes = append(droppingIndexes, idx) + } else { + remainIndexes = append(remainIndexes, idx) + } + } + + for _, fk := range info.AddForeignKeys { + if droppingIdx := model.FindIndexByColumns(tbInfo, droppingIndexes, fk.Cols...); droppingIdx != nil && model.FindIndexByColumns(tbInfo, remainIndexes, fk.Cols...) == nil { + return dbterror.ErrDropIndexNeededInForeignKey.GenWithStackByArgs(droppingIdx.Name) + } + } + return nil +} + func checkMultiSchemaInfo(info *model.MultiSchemaInfo, t table.Table) error { err := checkOperateSameColAndIdx(info) if err != nil { @@ -329,6 +368,11 @@ func checkMultiSchemaInfo(info *model.MultiSchemaInfo, t table.Table) error { return err } + err = checkOperateDropIndexUseByForeignKey(info, t) + if err != nil { + return err + } + return checkAddColumnTooManyColumns(len(t.Cols()) + len(info.AddColumns) - len(info.DropColumns)) } @@ -373,8 +417,8 @@ func finishMultiSchemaJob(job *model.Job, t *meta.Meta) (ver int64, err error) { } tblInfo, err := t.GetTable(job.SchemaID, job.TableID) if err != nil { - return ver, err + return 0, err } job.FinishTableJob(model.JobStateDone, model.StateNone, ver, tblInfo) - return ver, err + return 0, err } diff --git a/ddl/multi_schema_change_test.go b/ddl/multi_schema_change_test.go index d2e62d20d736d..d9facec4642cf 100644 --- a/ddl/multi_schema_change_test.go +++ b/ddl/multi_schema_change_test.go @@ -141,6 +141,9 @@ func TestMultiSchemaChangeAddColumnsCancelled(t *testing.T) { tk.MustExec("insert into t values (1);") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'c' is in write-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 3) return job.MultiSchemaInfo.SubJobs[1].SchemaState == model.StateWriteReorganization }) @@ -221,6 +224,9 @@ func TestMultiSchemaChangeDropColumnsCancelled(t *testing.T) { tk.MustExec("insert into t values ();") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'a' is in delete-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 3) return job.MultiSchemaInfo.SubJobs[1].SchemaState == model.StateDeleteReorganization }) @@ -236,6 +242,9 @@ func TestMultiSchemaChangeDropColumnsCancelled(t *testing.T) { tk.MustExec("insert into t values ();") hook = newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'a' is in public. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 3) return job.MultiSchemaInfo.SubJobs[1].SchemaState == model.StatePublic }) @@ -258,6 +267,9 @@ func TestMultiSchemaChangeDropIndexedColumnsCancelled(t *testing.T) { tk.MustExec("insert into t values ();") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'a' is in delete-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 3) return job.MultiSchemaInfo.SubJobs[1].SchemaState == model.StateDeleteReorganization }) @@ -358,6 +370,9 @@ func TestMultiSchemaChangeRenameColumns(t *testing.T) { tk.MustExec("insert into t values ()") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'c' is in write-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 2) return job.MultiSchemaInfo.SubJobs[0].SchemaState == model.StateWriteReorganization }) @@ -427,6 +442,9 @@ func TestMultiSchemaChangeAlterColumns(t *testing.T) { tk.MustExec("create table t (a int default 1, b int default 2)") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'a' is in write-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 2) return job.MultiSchemaInfo.SubJobs[0].SchemaState == model.StateWriteReorganization }) @@ -496,6 +514,9 @@ func TestMultiSchemaChangeChangeColumns(t *testing.T) { tk.MustExec("insert into t values ()") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'c' is in write-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 2) return job.MultiSchemaInfo.SubJobs[0].SchemaState == model.StateWriteReorganization }) @@ -555,6 +576,9 @@ func TestMultiSchemaChangeAddIndexesCancelled(t *testing.T) { tk.MustExec("insert into t values (1, 2, 3);") cancelHook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel the job when index 't2' is in write-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 4) return job.MultiSchemaInfo.SubJobs[2].SchemaState == model.StateWriteReorganization }) @@ -574,6 +598,9 @@ func TestMultiSchemaChangeAddIndexesCancelled(t *testing.T) { tk.MustExec("insert into t values (1, 2, 3);") cancelHook = newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel the job when index 't1' is in public. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 4) return job.MultiSchemaInfo.SubJobs[1].SchemaState == model.StatePublic }) @@ -623,6 +650,9 @@ func TestMultiSchemaChangeDropIndexesCancelled(t *testing.T) { // Test for cancelling the job in a middle state. tk.MustExec("create table t (a int, b int, index(a), unique index(b), index idx(a, b));") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 3) return job.MultiSchemaInfo.SubJobs[1].SchemaState == model.StateDeleteOnly }) @@ -638,6 +668,9 @@ func TestMultiSchemaChangeDropIndexesCancelled(t *testing.T) { tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a int, b int, index(a), unique index(b), index idx(a, b));") hook = newCancelJobHook(t, store, dom, func(job *model.Job) bool { + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 3) return job.MultiSchemaInfo.SubJobs[1].SchemaState == model.StatePublic }) @@ -686,8 +719,8 @@ func TestMultiSchemaChangeAddDropIndexes(t *testing.T) { tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a int, b int, c int, index (a), index(b), index(c));") tk.MustExec("insert into t values (1, 2, 3);") - tk.MustExec("alter table t add index aa(a), drop index a, add index cc(c), drop index b, drop index c, add index bb(b);") - tk.MustQuery("select * from t use index(aa, bb, cc);").Check(testkit.Rows("1 2 3")) + tk.MustExec("alter table t add index xa(a), drop index a, add index xc(c), drop index b, drop index c, add index xb(b);") + tk.MustQuery("select * from t use index(xa, xb, xc);").Check(testkit.Rows("1 2 3")) tk.MustGetErrCode("select * from t use index(a);", errno.ErrKeyDoesNotExist) tk.MustGetErrCode("select * from t use index(b);", errno.ErrKeyDoesNotExist) tk.MustGetErrCode("select * from t use index(c);", errno.ErrKeyDoesNotExist) @@ -733,6 +766,9 @@ func TestMultiSchemaChangeRenameIndexes(t *testing.T) { tk.MustExec("insert into t values ()") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { // Cancel job when the column 'c' is in write-reorg. + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 2) return job.MultiSchemaInfo.SubJobs[0].SchemaState == model.StateWriteReorganization }) @@ -881,6 +917,9 @@ func TestMultiSchemaChangeModifyColumnsCancelled(t *testing.T) { tk.MustExec("create table t (a int, b int, c int, index i1(a), unique index i2(b), index i3(a, b));") tk.MustExec("insert into t values (1, 2, 3);") hook := newCancelJobHook(t, store, dom, func(job *model.Job) bool { + if job.Type != model.ActionMultiSchemaChange { + return false + } assertMultiSchema(t, job, 3) return job.MultiSchemaInfo.SubJobs[2].SchemaState == model.StateWriteReorganization }) @@ -975,6 +1014,7 @@ func TestMultiSchemaChangeMixCancelled(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") + tk.MustExec("set global tidb_ddl_enable_fast_reorg = 0;") tk.MustExec("create table t (a int, b int, c int, index i1(c), index i2(c));") tk.MustExec("insert into t values (1, 2, 3);") @@ -1012,7 +1052,7 @@ func TestMultiSchemaChangeAdminShowDDLJobs(t *testing.T) { assert.Equal(t, len(rows), 4) assert.Equal(t, rows[1][1], "test") assert.Equal(t, rows[1][2], "t") - assert.Equal(t, rows[1][3], "add index /* subjob */") + assert.Equal(t, rows[1][3], "add index /* subjob */ /* txn-merge */") assert.Equal(t, rows[1][4], "delete only") assert.Equal(t, rows[1][len(rows[1])-1], "running") @@ -1137,10 +1177,48 @@ func TestMultiSchemaChangeUnsupportedType(t *testing.T) { tk.MustExec("use test;") tk.MustExec("create table t (a int, b int);") - tk.MustGetErrMsg("alter table t add column c int, auto_id_cache = 1;", + tk.MustGetErrMsg("alter table t add column c int, auto_id_cache = 10;", "[ddl:8200]Unsupported multi schema change for modify auto id cache") } +func TestMultiSchemaChangeSchemaVersion(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test;") + tk.MustExec("create table t(a int, b int, c int, d int)") + tk.MustExec("insert into t values (1,2,3,4)") + + schemaVerMap := map[int64]struct{}{} + + originHook := dom.DDL().GetHook() + hook := &ddl.TestDDLCallback{Do: dom} + hook.OnJobSchemaStateChanged = func(schemaVer int64) { + if schemaVer != 0 { + // No same return schemaVer during multi-schema change + _, ok := schemaVerMap[schemaVer] + assert.False(t, ok) + schemaVerMap[schemaVer] = struct{}{} + } + } + dom.DDL().SetHook(hook) + tk.MustExec("alter table t drop column b, drop column c") + tk.MustExec("alter table t add column b int, add column c int") + tk.MustExec("alter table t add index k(b), add column e int") + tk.MustExec("alter table t alter index k invisible, drop column e") + dom.DDL().SetHook(originHook) +} + +func TestMultiSchemaChangeAddIndexChangeColumn(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test;") + tk.MustExec("CREATE TABLE t (a SMALLINT DEFAULT '30219', b TIME NULL DEFAULT '02:45:06', PRIMARY KEY (a));") + tk.MustExec("ALTER TABLE t ADD unique INDEX idx4 (b), change column a e MEDIUMINT DEFAULT '5280454' FIRST;") + tk.MustExec("insert ignore into t (e) values (5586359),(501788),(-5961048),(220083),(-4917129),(-7267211),(7750448);") + tk.MustQuery("select * from t;").Check(testkit.Rows("5586359 02:45:06")) + tk.MustExec("admin check table t;") +} + func TestMultiSchemaChangeMixedWithUpdate(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) @@ -1196,7 +1274,7 @@ func (c *cancelOnceHook) OnJobUpdated(job *model.Job) { return } c.triggered = true - errs, err := ddl.CancelJobs(c.s, c.store, []int64{job.ID}) + errs, err := ddl.CancelJobs(c.s, []int64{job.ID}) if errs[0] != nil { c.cancelErr = errs[0] return @@ -1235,7 +1313,6 @@ func putTheSameDDLJobTwice(t *testing.T, fn func()) { } func assertMultiSchema(t *testing.T, job *model.Job, subJobLen int) { - assert.Equal(t, model.ActionMultiSchemaChange, job.Type, job) assert.NotNil(t, job.MultiSchemaInfo, job) assert.Len(t, job.MultiSchemaInfo.SubJobs, subJobLen, job) } diff --git a/ddl/mv_index_test.go b/ddl/mv_index_test.go new file mode 100644 index 0000000000000..964211ad76740 --- /dev/null +++ b/ddl/mv_index_test.go @@ -0,0 +1,71 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/pingcap/tidb/ddl" + "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/testkit" +) + +func TestMultiValuedIndexOnlineDDL(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (pk int primary key, a json) partition by hash(pk) partitions 32;") + var sb strings.Builder + sb.WriteString("insert into t values ") + for i := 0; i < 100; i++ { + sb.WriteString(fmt.Sprintf("(%d, '[%d, %d, %d]')", i, i+1, i+2, i+3)) + if i != 99 { + sb.WriteString(",") + } + } + tk.MustExec(sb.String()) + + internalTK := testkit.NewTestKit(t, store) + internalTK.MustExec("use test") + + hook := &ddl.TestDDLCallback{Do: dom} + n := 100 + hook.OnJobRunBeforeExported = func(job *model.Job) { + internalTK.MustExec(fmt.Sprintf("insert into t values (%d, '[%d, %d, %d]')", n, n, n+1, n+2)) + internalTK.MustExec(fmt.Sprintf("delete from t where pk = %d", n-4)) + internalTK.MustExec(fmt.Sprintf("update t set a = '[%d, %d, %d]' where pk = %d", n-3, n-2, n+1000, n-3)) + n++ + } + o := dom.DDL().GetHook() + dom.DDL().SetHook(hook) + + tk.MustExec("alter table t add index idx((cast(a as signed array)))") + tk.MustExec("admin check table t") + dom.DDL().SetHook(o) + + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (pk int primary key, a json);") + tk.MustExec("insert into t values (1, '[1,2,3]');") + tk.MustExec("insert into t values (2, '[2,3,4]');") + tk.MustExec("insert into t values (3, '[3,4,5]');") + tk.MustExec("insert into t values (4, '[-4,5,6]');") + tk.MustGetErrCode("alter table t add unique index idx((cast(a as signed array)));", errno.ErrDupEntry) + tk.MustGetErrMsg("alter table t add index idx((cast(a as unsigned array)));", "[ddl:8202]Cannot decode index value, because [types:1690]constant -4 overflows bigint") +} diff --git a/ddl/partition.go b/ddl/partition.go index b2fa6293dfd86..dcd5a2e50a056 100644 --- a/ddl/partition.go +++ b/ddl/partition.go @@ -34,6 +34,7 @@ import ( "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser" @@ -42,8 +43,10 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/opcode" + "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/table" + "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" driver "github.com/pingcap/tidb/types/parser_driver" @@ -55,9 +58,11 @@ import ( "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/mock" + decoder "github.com/pingcap/tidb/util/rowDecoder" "github.com/pingcap/tidb/util/slice" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/stringutil" + "github.com/prometheus/client_golang/prometheus" "github.com/tikv/client-go/v2/tikv" "go.uber.org/zap" ) @@ -161,7 +166,7 @@ func (w *worker) onAddTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) (v for _, p := range tblInfo.Partition.AddingDefinitions { ids = append(ids, p.ID) } - if err := alterTableLabelRule(job.SchemaName, tblInfo, ids); err != nil { + if _, err := alterTableLabelRule(job.SchemaName, tblInfo, ids); err != nil { job.State = model.JobStateCancelled return ver, err } @@ -170,6 +175,10 @@ func (w *worker) onAddTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) (v job.SchemaState = model.StateReplicaOnly case model.StateReplicaOnly: // replica only -> public + failpoint.Inject("sleepBeforeReplicaOnly", func(val failpoint.Value) { + sleepSecond := val.(int) + time.Sleep(time.Duration(sleepSecond) * time.Second) + }) // Here need do some tiflash replica complement check. // TODO: If a table is with no TiFlashReplica or it is not available, the replica-only state can be eliminated. if tblInfo.TiFlashReplica != nil && tblInfo.TiFlashReplica.Available { @@ -177,8 +186,7 @@ func (w *worker) onAddTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) (v // be finished. Otherwise the query to this partition will be blocked. needRetry, err := checkPartitionReplica(tblInfo.TiFlashReplica.Count, addingDefinitions, d) if err != nil { - ver, err = convertAddTablePartitionJob2RollbackJob(d, t, job, err, tblInfo) - return ver, err + return convertAddTablePartitionJob2RollbackJob(d, t, job, err, tblInfo) } if needRetry { // The new added partition hasn't been replicated. @@ -193,6 +201,15 @@ func (w *worker) onAddTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) (v if tblInfo.TiFlashReplica != nil && tblInfo.TiFlashReplica.Available { for _, d := range partInfo.Definitions { tblInfo.TiFlashReplica.AvailablePartitionIDs = append(tblInfo.TiFlashReplica.AvailablePartitionIDs, d.ID) + err = infosync.UpdateTiFlashProgressCache(d.ID, 1) + if err != nil { + // just print log, progress will be updated in `refreshTiFlashTicker` + logutil.BgLogger().Error("update tiflash sync progress cache failed", + zap.Error(err), + zap.Int64("tableID", tblInfo.ID), + zap.Int64("partitionID", d.ID), + ) + } } } // For normal and replica finished table, move the `addingDefinitions` into `Definitions`. @@ -213,14 +230,16 @@ func (w *worker) onAddTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) (v return ver, errors.Trace(err) } -func alterTableLabelRule(schemaName string, meta *model.TableInfo, ids []int64) error { +// alterTableLabelRule updates Label Rules if they exists +// returns true if changed. +func alterTableLabelRule(schemaName string, meta *model.TableInfo, ids []int64) (bool, error) { tableRuleID := fmt.Sprintf(label.TableIDFormat, label.IDPrefix, schemaName, meta.Name.L) oldRule, err := infosync.GetLabelRules(context.TODO(), []string{tableRuleID}) if err != nil { - return errors.Trace(err) + return false, errors.Trace(err) } if len(oldRule) == 0 { - return nil + return false, nil } r, ok := oldRule[tableRuleID] @@ -228,10 +247,11 @@ func alterTableLabelRule(schemaName string, meta *model.TableInfo, ids []int64) rule := r.Reset(schemaName, meta.Name.L, "", ids...) err = infosync.PutLabelRule(context.TODO(), rule) if err != nil { - return errors.Wrapf(err, "failed to notify PD label rule") + return false, errors.Wrapf(err, "failed to notify PD label rule") } + return true, nil } - return nil + return false, nil } func alterTablePartitionBundles(t *meta.Meta, tblInfo *model.TableInfo, addingDefinitions []model.PartitionDefinition) ([]*placement.Bundle, error) { @@ -425,8 +445,11 @@ func buildTablePartitionInfo(ctx sessionctx.Context, s *ast.PartitionOptions, tb } case model.PartitionTypeHash: // Partition by hash is enabled by default. - // Note that linear hash is not enabled. - if !s.Linear && s.Sub == nil { + // Note that linear hash is simply ignored, and creates non-linear hash. + if s.Linear { + ctx.GetSessionVars().StmtCtx.AppendWarning(dbterror.ErrUnsupportedCreatePartition.GenWithStack("LINEAR HASH is not supported, using non-linear HASH instead")) + } + if s.Sub == nil { enable = true } case model.PartitionTypeList: @@ -779,6 +802,9 @@ func generatePartitionDefinitionsFromInterval(ctx sessionctx.Context, partOption } if len(tbInfo.Partition.Columns) > 0 { colTypes := collectColumnsType(tbInfo) + if len(colTypes) != len(tbInfo.Partition.Columns) { + return dbterror.ErrWrongPartitionName.GenWithStack("partition column name cannot be found") + } if _, err := checkAndGetColumnsTypeAndValuesMatch(ctx, colTypes, first.Exprs); err != nil { return err } @@ -1078,6 +1104,9 @@ func buildListPartitionDefinitions(ctx sessionctx.Context, defs []*ast.Partition definitions := make([]model.PartitionDefinition, 0, len(defs)) exprChecker := newPartitionExprChecker(ctx, nil, checkPartitionExprAllowed) colTypes := collectColumnsType(tbInfo) + if len(colTypes) != len(tbInfo.Partition.Columns) { + return nil, dbterror.ErrWrongPartitionName.GenWithStack("partition column name cannot be found") + } for _, def := range defs { if err := def.Clause.Validate(model.PartitionTypeList, len(tbInfo.Partition.Columns)); err != nil { return nil, err @@ -1136,7 +1165,11 @@ func collectColumnsType(tbInfo *model.TableInfo) []types.FieldType { if len(tbInfo.Partition.Columns) > 0 { colTypes := make([]types.FieldType, 0, len(tbInfo.Partition.Columns)) for _, col := range tbInfo.Partition.Columns { - colTypes = append(colTypes, findColumnByName(col.L, tbInfo).FieldType) + c := findColumnByName(col.L, tbInfo) + if c == nil { + return nil + } + colTypes = append(colTypes, c.FieldType) } return colTypes @@ -1149,6 +1182,9 @@ func buildRangePartitionDefinitions(ctx sessionctx.Context, defs []*ast.Partitio definitions := make([]model.PartitionDefinition, 0, len(defs)) exprChecker := newPartitionExprChecker(ctx, nil, checkPartitionExprAllowed) colTypes := collectColumnsType(tbInfo) + if len(colTypes) != len(tbInfo.Partition.Columns) { + return nil, dbterror.ErrWrongPartitionName.GenWithStack("partition column name cannot be found") + } for _, def := range defs { if err := def.Clause.Validate(model.PartitionTypeRange, len(tbInfo.Partition.Columns)); err != nil { return nil, err @@ -1278,6 +1314,28 @@ func checkAddPartitionNameUnique(tbInfo *model.TableInfo, pi *model.PartitionInf return nil } +func checkReorgPartitionNames(p *model.PartitionInfo, droppedNames []model.CIStr, pi *model.PartitionInfo) error { + partNames := make(map[string]struct{}) + oldDefs := p.Definitions + for _, oldDef := range oldDefs { + partNames[oldDef.Name.L] = struct{}{} + } + for _, delName := range droppedNames { + if _, ok := partNames[delName.L]; !ok { + return dbterror.ErrSameNamePartition.GenWithStackByArgs(delName) + } + delete(partNames, delName.L) + } + newDefs := pi.Definitions + for _, newDef := range newDefs { + if _, ok := partNames[newDef.Name.L]; ok { + return dbterror.ErrSameNamePartition.GenWithStackByArgs(newDef.Name) + } + partNames[newDef.Name.L] = struct{}{} + } + return nil +} + func checkAndOverridePartitionID(newTableInfo, oldTableInfo *model.TableInfo) error { // If any old partitionInfo has lost, that means the partition ID lost too, so did the data, repair failed. if newTableInfo.Partition == nil { @@ -1346,7 +1404,7 @@ func checkPartitionFuncType(ctx sessionctx.Context, expr ast.ExprNode, tblInfo * return nil } - e, err := expression.RewriteSimpleExprWithTableInfo(ctx, tblInfo, expr) + e, err := expression.RewriteSimpleExprWithTableInfo(ctx, tblInfo, expr, false) if err != nil { return errors.Trace(err) } @@ -1647,7 +1705,7 @@ func (w *worker) onDropTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) ( if err != nil { return ver, errors.Trace(err) } - if job.Type == model.ActionAddTablePartition { + if job.Type == model.ActionAddTablePartition || job.Type == model.ActionReorganizePartition { // It is rollbacked from adding table partition, just remove addingDefinitions from tableInfo. physicalTableIDs, pNames, rollbackBundles := rollbackAddingPartitionInfo(tblInfo) err = infosync.PutRuleBundlesWithDefaultRetry(context.TODO(), rollbackBundles) @@ -1661,7 +1719,7 @@ func (w *worker) onDropTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) ( return ver, errors.Wrapf(err, "failed to notify PD the label rules") } - if err := alterTableLabelRule(job.SchemaName, tblInfo, getIDs([]*model.TableInfo{tblInfo})); err != nil { + if _, err := alterTableLabelRule(job.SchemaName, tblInfo, getIDs([]*model.TableInfo{tblInfo})); err != nil { job.State = model.JobStateCancelled return ver, err } @@ -1694,7 +1752,7 @@ func (w *worker) onDropTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) ( return ver, errors.Wrapf(err, "failed to notify PD the label rules") } - if err := alterTableLabelRule(job.SchemaName, tblInfo, getIDs([]*model.TableInfo{tblInfo})); err != nil { + if _, err := alterTableLabelRule(job.SchemaName, tblInfo, getIDs([]*model.TableInfo{tblInfo})); err != nil { job.State = model.JobStateCancelled return ver, err } @@ -1714,6 +1772,10 @@ func (w *worker) onDropTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) ( if err != nil { return ver, errors.Trace(err) } + dbInfo, err := t.GetDatabase(job.SchemaID) + if err != nil { + return ver, errors.Trace(err) + } // If table has global indexes, we need reorg to clean up them. if pt, ok := tbl.(table.PartitionedTable); ok && hasGlobalIndex(tblInfo) { // Build elements for compatible with modify column type. elements will not be used when reorganizing. @@ -1723,8 +1785,13 @@ func (w *worker) onDropTablePartition(d *ddlCtx, t *meta.Meta, job *model.Job) ( elements = append(elements, &meta.Element{ID: idxInfo.ID, TypeKey: meta.IndexElementKey}) } } - rh := newReorgHandler(t, w.sess, w.concurrentDDL) - reorgInfo, err := getReorgInfoFromPartitions(d.jobContext(job), d, rh, job, tbl, physicalTableIDs, elements) + sctx, err1 := w.sessPool.get() + if err1 != nil { + return ver, err1 + } + defer w.sessPool.put(sctx) + rh := newReorgHandler(newSession(sctx)) + reorgInfo, err := getReorgInfoFromPartitions(d.jobContext(job.ID), d, rh, job, dbInfo, pt, physicalTableIDs, elements) if err != nil || reorgInfo.first { // If we run reorg firstly, we should update the job snapshot version @@ -2048,7 +2115,7 @@ func (w *worker) onExchangeTablePartition(d *ddlCtx, t *meta.Meta, job *model.Jo failpoint.Return(ver, err) } sess := newSession(se) - _, err = sess.execute(context.Background(), "insert into test.pt values (40000000)", "exchange_partition_test") + _, err = sess.execute(context.Background(), "insert ignore into test.pt values (40000000)", "exchange_partition_test") if err != nil { failpoint.Return(ver, err) } @@ -2121,6 +2188,674 @@ func (w *worker) onExchangeTablePartition(d *ddlCtx, t *meta.Meta, job *model.Jo return ver, nil } +func checkReorgPartition(t *meta.Meta, job *model.Job) (*model.TableInfo, []model.CIStr, *model.PartitionInfo, []model.PartitionDefinition, []model.PartitionDefinition, error) { + schemaID := job.SchemaID + tblInfo, err := GetTableInfoAndCancelFaultJob(t, job, schemaID) + if err != nil { + return nil, nil, nil, nil, nil, errors.Trace(err) + } + partInfo := &model.PartitionInfo{} + var partNames []model.CIStr + err = job.DecodeArgs(&partNames, &partInfo) + if err != nil { + job.State = model.JobStateCancelled + return nil, nil, nil, nil, nil, errors.Trace(err) + } + addingDefs := tblInfo.Partition.AddingDefinitions + droppingDefs := tblInfo.Partition.DroppingDefinitions + if len(addingDefs) == 0 { + addingDefs = []model.PartitionDefinition{} + } + if len(droppingDefs) == 0 { + droppingDefs = []model.PartitionDefinition{} + } + return tblInfo, partNames, partInfo, droppingDefs, addingDefs, nil +} + +func (w *worker) onReorganizePartition(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { + // Handle the rolling back job + if job.IsRollingback() { + ver, err := w.onDropTablePartition(d, t, job) + if err != nil { + return ver, errors.Trace(err) + } + return ver, nil + } + + tblInfo, partNamesCIStr, partInfo, _, addingDefinitions, err := checkReorgPartition(t, job) + if err != nil { + return ver, err + } + partNames := make([]string, len(partNamesCIStr)) + for i := range partNamesCIStr { + partNames[i] = partNamesCIStr[i].L + } + + // In order to skip maintaining the state check in partitionDefinition, TiDB use dropping/addingDefinition instead of state field. + // So here using `job.SchemaState` to judge what the stage of this job is. + originalState := job.SchemaState + switch job.SchemaState { + case model.StateNone: + // job.SchemaState == model.StateNone means the job is in the initial state of reorg partition. + // Here should use partInfo from job directly and do some check action. + // In case there was a race for queueing different schema changes on the same + // table and the checks was not done on the current schema version. + // The partInfo may have been checked against an older schema version for example. + // If the check is done here, it does not need to be repeated, since no other + // DDL on the same table can be run concurrently. + err = checkAddPartitionTooManyPartitions(uint64(len(tblInfo.Partition.Definitions) + + len(partInfo.Definitions) - + len(partNames))) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + + err = checkReorgPartitionNames(tblInfo.Partition, partNamesCIStr, partInfo) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + + // Re-check that the dropped/added partitions are compatible with current definition + firstPartIdx, lastPartIdx, idMap, err := getReplacedPartitionIDs(partNamesCIStr, tblInfo.Partition) + if err != nil { + job.State = model.JobStateCancelled + return ver, err + } + sctx := w.sess.Context + if err = checkReorgPartitionDefs(sctx, tblInfo, partInfo, firstPartIdx, lastPartIdx, idMap); err != nil { + job.State = model.JobStateCancelled + return ver, err + } + + // move the adding definition into tableInfo. + updateAddingPartitionInfo(partInfo, tblInfo) + orgDefs := tblInfo.Partition.Definitions + _ = updateDroppingPartitionInfo(tblInfo, partNames) + // Reset original partitions, and keep DroppedDefinitions + tblInfo.Partition.Definitions = orgDefs + + // modify placement settings + for _, def := range tblInfo.Partition.AddingDefinitions { + if _, err = checkPlacementPolicyRefValidAndCanNonValidJob(t, job, def.PlacementPolicyRef); err != nil { + // job.State = model.JobStateCancelled may be set depending on error in function above. + return ver, errors.Trace(err) + } + } + + // From now on we cannot just cancel the DDL, we must roll back if changesMade! + changesMade := false + if tblInfo.TiFlashReplica != nil { + // Must set placement rule, and make sure it succeeds. + if err := infosync.ConfigureTiFlashPDForPartitions(true, &tblInfo.Partition.AddingDefinitions, tblInfo.TiFlashReplica.Count, &tblInfo.TiFlashReplica.LocationLabels, tblInfo.ID); err != nil { + logutil.BgLogger().Error("ConfigureTiFlashPDForPartitions fails", zap.Error(err)) + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + changesMade = true + // In the next step, StateDeleteOnly, wait to verify the TiFlash replicas are OK + } + + bundles, err := alterTablePartitionBundles(t, tblInfo, tblInfo.Partition.AddingDefinitions) + if err != nil { + if !changesMade { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + return convertAddTablePartitionJob2RollbackJob(d, t, job, err, tblInfo) + } + + if len(bundles) > 0 { + if err = infosync.PutRuleBundlesWithDefaultRetry(context.TODO(), bundles); err != nil { + if !changesMade { + job.State = model.JobStateCancelled + return ver, errors.Wrapf(err, "failed to notify PD the placement rules") + } + return convertAddTablePartitionJob2RollbackJob(d, t, job, err, tblInfo) + } + changesMade = true + } + + ids := getIDs([]*model.TableInfo{tblInfo}) + for _, p := range tblInfo.Partition.AddingDefinitions { + ids = append(ids, p.ID) + } + changed, err := alterTableLabelRule(job.SchemaName, tblInfo, ids) + changesMade = changesMade || changed + if err != nil { + if !changesMade { + job.State = model.JobStateCancelled + return ver, err + } + return convertAddTablePartitionJob2RollbackJob(d, t, job, err, tblInfo) + } + + // Doing the preSplitAndScatter here, since all checks are completed, + // and we will soon start writing to the new partitions. + if s, ok := d.store.(kv.SplittableStore); ok && s != nil { + // partInfo only contains the AddingPartitions + splitPartitionTableRegion(w.sess.Context, s, tblInfo, partInfo, true) + } + + // TODO: test... + // Assume we cannot have more than MaxUint64 rows, set the progress to 1/10 of that. + metrics.GetBackfillProgressByLabel(metrics.LblReorgPartition, job.SchemaName, tblInfo.Name.String()).Set(0.1 / float64(math.MaxUint64)) + job.SchemaState = model.StateDeleteOnly + tblInfo.Partition.DDLState = model.StateDeleteOnly + ver, err = updateVersionAndTableInfoWithCheck(d, t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + + // Is really both StateDeleteOnly AND StateWriteOnly needed? + // If transaction A in WriteOnly inserts row 1 (into both new and old partition set) + // and then transaction B in DeleteOnly deletes that row (in both new and old) + // does really transaction B need to do the delete in the new partition? + // Yes, otherwise it would still be there when the WriteReorg happens, + // and WriteReorg would only copy existing rows to the new table, so unless it is + // deleted it would result in a ghost row! + // What about update then? + // Updates also need to be handled for new partitions in DeleteOnly, + // since it would not be overwritten during Reorganize phase. + // BUT if the update results in adding in one partition and deleting in another, + // THEN only the delete must happen in the new partition set, not the insert! + case model.StateDeleteOnly: + // This state is to confirm all servers can not see the new partitions when reorg is running, + // so that all deletes will be done in both old and new partitions when in either DeleteOnly + // or WriteOnly state. + // Also using the state for checking that the optional TiFlash replica is available, making it + // in a state without (much) data and easy to retry without side effects. + + // Reason for having it here, is to make it easy for retry, and better to make sure it is in-sync + // as early as possible, to avoid a long wait after the data copying. + if tblInfo.TiFlashReplica != nil && tblInfo.TiFlashReplica.Available { + // For available state, the new added partition should wait its replica to + // be finished, otherwise the query to this partition will be blocked. + count := tblInfo.TiFlashReplica.Count + needRetry, err := checkPartitionReplica(count, addingDefinitions, d) + if err != nil { + // need to rollback, since we tried to register the new + // partitions before! + return convertAddTablePartitionJob2RollbackJob(d, t, job, err, tblInfo) + } + if needRetry { + // The new added partition hasn't been replicated. + // Do nothing to the job this time, wait next worker round. + time.Sleep(tiflashCheckTiDBHTTPAPIHalfInterval) + // Set the error here which will lead this job exit when it's retry times beyond the limitation. + return ver, errors.Errorf("[ddl] add partition wait for tiflash replica to complete") + } + + // When TiFlash Replica is ready, we must move them into `AvailablePartitionIDs`. + // Since onUpdateFlashReplicaStatus cannot see the partitions yet (not public) + for _, d := range addingDefinitions { + tblInfo.TiFlashReplica.AvailablePartitionIDs = append(tblInfo.TiFlashReplica.AvailablePartitionIDs, d.ID) + } + } + + job.SchemaState = model.StateWriteOnly + tblInfo.Partition.DDLState = model.StateWriteOnly + metrics.GetBackfillProgressByLabel(metrics.LblReorgPartition, job.SchemaName, tblInfo.Name.String()).Set(0.2 / float64(math.MaxUint64)) + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, originalState != job.SchemaState) + case model.StateWriteOnly: + // Insert this state to confirm all servers can see the new partitions when reorg is running, + // so that new data will be updated in both old and new partitions when reorganizing. + job.SnapshotVer = 0 + job.SchemaState = model.StateWriteReorganization + tblInfo.Partition.DDLState = model.StateWriteReorganization + metrics.GetBackfillProgressByLabel(metrics.LblReorgPartition, job.SchemaName, tblInfo.Name.String()).Set(0.3 / float64(math.MaxUint64)) + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, originalState != job.SchemaState) + case model.StateWriteReorganization: + physicalTableIDs := getPartitionIDsFromDefinitions(tblInfo.Partition.DroppingDefinitions) + tbl, err2 := getTable(d.store, job.SchemaID, tblInfo) + if err2 != nil { + return ver, errors.Trace(err2) + } + // TODO: If table has global indexes, we need reorg to clean up them. + // and then add the new partition ids back... + if _, ok := tbl.(table.PartitionedTable); ok && hasGlobalIndex(tblInfo) { + err = errors.Trace(dbterror.ErrCancelledDDLJob.GenWithStack("global indexes is not supported yet for reorganize partition")) + return convertAddTablePartitionJob2RollbackJob(d, t, job, err, tblInfo) + } + var done bool + done, ver, err = doPartitionReorgWork(w, d, t, job, tbl, physicalTableIDs) + + if !done { + return ver, err + } + + firstPartIdx, lastPartIdx, idMap, err2 := getReplacedPartitionIDs(partNamesCIStr, tblInfo.Partition) + failpoint.Inject("reorgPartWriteReorgReplacedPartIDsFail", func(val failpoint.Value) { + if val.(bool) { + err2 = errors.New("Injected error by reorgPartWriteReorgReplacedPartIDsFail") + } + }) + if err2 != nil { + return ver, err2 + } + newDefs := getReorganizedDefinitions(tblInfo.Partition, firstPartIdx, lastPartIdx, idMap) + + // From now on, use the new definitions, but keep the Adding and Dropping for double write + tblInfo.Partition.Definitions = newDefs + tblInfo.Partition.Num = uint64(len(newDefs)) + + // TODO: How do we handle the table schema change for Adding and Dropping Definitions? + + // Now all the data copying is done, but we cannot simply remove the droppingDefinitions + // since they are a part of the normal Definitions that other nodes with + // the current schema version. So we need to double write for one more schema version + job.SchemaState = model.StateDeleteReorganization + tblInfo.Partition.DDLState = model.StateDeleteReorganization + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, originalState != job.SchemaState) + + case model.StateDeleteReorganization: + // Drop the droppingDefinitions and finish the DDL + // This state is needed for the case where client A sees the schema + // with version of StateWriteReorg and would not see updates of + // client B that writes to the new partitions, previously + // addingDefinitions, since it would not double write to + // the droppingDefinitions during this time + // By adding StateDeleteReorg state, client B will write to both + // the new (previously addingDefinitions) AND droppingDefinitions + // TODO: Make sure the dropLabelRules are done both if successful (droppingDefinitions) or if rollback (addingDefinitions) + // TODO: Make sure stats is handled (eventually dropped for old partitions, and added for new?) + // Hmm, maybe we should actually update the stats here as well? + // Can we collect the stats while doing the reorg? + + // Register the droppingDefinitions ids for rangeDelete + // and the addingDefinitions for handling in the updateSchemaVersion + physicalTableIDs := getPartitionIDsFromDefinitions(tblInfo.Partition.DroppingDefinitions) + newIDs := getPartitionIDsFromDefinitions(partInfo.Definitions) + job.CtxVars = []interface{}{physicalTableIDs, newIDs} + definitionsToDrop := tblInfo.Partition.DroppingDefinitions + tblInfo.Partition.DroppingDefinitions = nil + tblInfo.Partition.AddingDefinitions = nil + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) + failpoint.Inject("reorgPartWriteReorgSchemaVersionUpdateFail", func(val failpoint.Value) { + if val.(bool) { + err = errors.New("Injected error by reorgPartWriteReorgSchemaVersionUpdateFail") + } + }) + if err != nil { + return ver, errors.Trace(err) + } + job.SchemaState = model.StateNone + tblInfo.Partition.DDLState = model.StateNone + job.FinishTableJob(model.JobStateDone, model.StateNone, ver, tblInfo) + // How to handle this? + // Seems to only trigger asynchronous update of statistics. + // Should it actually be synchronous? + asyncNotifyEvent(d, &util.Event{Tp: model.ActionReorganizePartition, TableInfo: tblInfo, PartInfo: &model.PartitionInfo{Definitions: definitionsToDrop}}) + // A background job will be created to delete old partition data. + job.Args = []interface{}{physicalTableIDs} + + default: + err = dbterror.ErrInvalidDDLState.GenWithStackByArgs("partition", job.SchemaState) + } + + return ver, errors.Trace(err) +} + +func doPartitionReorgWork(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job, tbl table.Table, physTblIDs []int64) (done bool, ver int64, err error) { + job.ReorgMeta.ReorgTp = model.ReorgTypeTxn + sctx, err1 := w.sessPool.get() + if err1 != nil { + return done, ver, err1 + } + defer w.sessPool.put(sctx) + rh := newReorgHandler(newSession(sctx)) + elements := BuildElements(tbl.Meta().Columns[0], tbl.Meta().Indices) + partTbl, ok := tbl.(table.PartitionedTable) + if !ok { + return false, ver, dbterror.ErrUnsupportedReorganizePartition.GenWithStackByArgs() + } + dbInfo, err := t.GetDatabase(job.SchemaID) + if err != nil { + return false, ver, errors.Trace(err) + } + reorgInfo, err := getReorgInfoFromPartitions(d.jobContext(job.ID), d, rh, job, dbInfo, partTbl, physTblIDs, elements) + err = w.runReorgJob(rh, reorgInfo, tbl.Meta(), d.lease, func() (reorgErr error) { + defer tidbutil.Recover(metrics.LabelDDL, "doPartitionReorgWork", + func() { + reorgErr = dbterror.ErrCancelledDDLJob.GenWithStack("reorganize partition for table `%v` panic", tbl.Meta().Name) + }, false) + return w.reorgPartitionDataAndIndex(tbl, reorgInfo) + }) + if err != nil { + if dbterror.ErrWaitReorgTimeout.Equal(err) { + // If timeout, we should return, check for the owner and re-wait job done. + return false, ver, nil + } + if kv.IsTxnRetryableError(err) { + return false, ver, errors.Trace(err) + } + // TODO: Create tests for this! + if err1 := rh.RemoveDDLReorgHandle(job, reorgInfo.elements); err1 != nil { + logutil.BgLogger().Warn("[ddl] reorg partition job failed, RemoveDDLReorgHandle failed, can't convert job to rollback", + zap.String("job", job.String()), zap.Error(err1)) + } + logutil.BgLogger().Warn("[ddl] reorg partition job failed, convert job to rollback", zap.String("job", job.String()), zap.Error(err)) + ver, err = convertAddTablePartitionJob2RollbackJob(d, t, job, err, tbl.Meta()) + return false, ver, errors.Trace(err) + } + return true, ver, err +} + +type reorgPartitionWorker struct { + *backfillCtx + metricCounter prometheus.Counter + + // Static allocated to limit memory allocations + rowRecords []*rowRecord + rowDecoder *decoder.RowDecoder + rowMap map[int64]types.Datum + writeColOffsetMap map[int64]int + maxOffset int + reorgedTbl table.PartitionedTable + + // SQL MODE should be ignored for reorganize partition? + // TODO: Test with zero date? and NULL timestamp? + // Test with generated/virtual stored columns. + // Can indexes be affected? + + jobContext *JobContext +} + +func newReorgPartitionWorker(sessCtx sessionctx.Context, t table.PhysicalTable, decodeColMap map[int64]decoder.Column, reorgInfo *reorgInfo, jc *JobContext) (*reorgPartitionWorker, error) { + reorgedTbl, err := tables.GetReorganizedPartitionedTable(t) + if err != nil { + return nil, errors.Trace(err) + } + pt := t.GetPartitionedTable() + if pt == nil { + return nil, dbterror.ErrUnsupportedReorganizePartition.GenWithStackByArgs() + } + partColIDs := pt.GetPartitionColumnIDs() + writeColOffsetMap := make(map[int64]int, len(partColIDs)) + maxOffset := 0 + for _, col := range pt.Cols() { + found := false + for _, id := range partColIDs { + if col.ID == id { + found = true + break + } + } + if !found { + continue + } + writeColOffsetMap[col.ID] = col.Offset + maxOffset = mathutil.Max[int](maxOffset, col.Offset) + } + return &reorgPartitionWorker{ + backfillCtx: newBackfillCtx(reorgInfo.d, sessCtx, reorgInfo.ReorgMeta.ReorgTp, reorgInfo.SchemaName, t), + metricCounter: metrics.BackfillTotalCounter.WithLabelValues(metrics.GenerateReorgLabel("reorg_partition_rate", reorgInfo.SchemaName, t.Meta().Name.String())), + rowDecoder: decoder.NewRowDecoder(t, t.WritableCols(), decodeColMap), + rowMap: make(map[int64]types.Datum, len(decodeColMap)), + jobContext: jc, + writeColOffsetMap: writeColOffsetMap, + maxOffset: maxOffset, + reorgedTbl: reorgedTbl, + }, nil +} + +func (w *reorgPartitionWorker) BackfillDataInTxn(handleRange reorgBackfillTask) (taskCtx backfillTaskContext, errInTxn error) { + oprStartTime := time.Now() + ctx := kv.WithInternalSourceType(context.Background(), w.jobContext.ddlJobSourceType()) + errInTxn = kv.RunInNewTxn(ctx, w.sessCtx.GetStore(), true, func(ctx context.Context, txn kv.Transaction) error { + taskCtx.addedCount = 0 + taskCtx.scanCount = 0 + txn.SetOption(kv.Priority, handleRange.priority) + if tagger := w.GetCtx().getResourceGroupTaggerForTopSQL(handleRange.getJobID()); tagger != nil { + txn.SetOption(kv.ResourceGroupTagger, tagger) + } + + rowRecords, nextKey, taskDone, err := w.fetchRowColVals(txn, handleRange) + if err != nil { + return errors.Trace(err) + } + taskCtx.nextKey = nextKey + taskCtx.done = taskDone + + warningsMap := make(map[errors.ErrorID]*terror.Error) + warningsCountMap := make(map[errors.ErrorID]int64) + for _, prr := range rowRecords { + taskCtx.scanCount++ + + err = txn.Set(prr.key, prr.vals) + if err != nil { + return errors.Trace(err) + } + taskCtx.addedCount++ + if prr.warning != nil { + if _, ok := warningsCountMap[prr.warning.ID()]; ok { + warningsCountMap[prr.warning.ID()]++ + } else { + warningsCountMap[prr.warning.ID()] = 1 + warningsMap[prr.warning.ID()] = prr.warning + } + } + // TODO: Future optimization: also write the indexes here? + // What if the transaction limit is just enough for a single row, without index? + // Hmm, how could that be in the first place? + // For now, implement the batch-txn w.addTableIndex, + // since it already exists and is in use + } + + // Collect the warnings. + taskCtx.warnings, taskCtx.warningsCount = warningsMap, warningsCountMap + + // also add the index entries here? And make sure they are not added somewhere else + + return nil + }) + logSlowOperations(time.Since(oprStartTime), "BackfillDataInTxn", 3000) + + return +} + +func (w *reorgPartitionWorker) fetchRowColVals(txn kv.Transaction, taskRange reorgBackfillTask) ([]*rowRecord, kv.Key, bool, error) { + w.rowRecords = w.rowRecords[:0] + startTime := time.Now() + + // taskDone means that the added handle is out of taskRange.endHandle. + taskDone := false + sysTZ := w.sessCtx.GetSessionVars().StmtCtx.TimeZone + + tmpRow := make([]types.Datum, w.maxOffset+1) + var lastAccessedHandle kv.Key + oprStartTime := startTime + err := iterateSnapshotKeys(w.GetCtx().jobContext(taskRange.getJobID()), w.sessCtx.GetStore(), taskRange.priority, w.table.RecordPrefix(), txn.StartTS(), taskRange.startKey, taskRange.endKey, + func(handle kv.Handle, recordKey kv.Key, rawRow []byte) (bool, error) { + oprEndTime := time.Now() + logSlowOperations(oprEndTime.Sub(oprStartTime), "iterateSnapshotKeys in reorgPartitionWorker fetchRowColVals", 0) + oprStartTime = oprEndTime + + if taskRange.endInclude { + taskDone = recordKey.Cmp(taskRange.endKey) > 0 + } else { + taskDone = recordKey.Cmp(taskRange.endKey) >= 0 + } + + if taskDone || len(w.rowRecords) >= w.batchCnt { + return false, nil + } + + _, err := w.rowDecoder.DecodeTheExistedColumnMap(w.sessCtx, handle, rawRow, sysTZ, w.rowMap) + if err != nil { + return false, errors.Trace(err) + } + + // Set the partitioning columns and calculate which partition to write to + for colID, offset := range w.writeColOffsetMap { + if d, ok := w.rowMap[colID]; ok { + tmpRow[offset] = d + } else { + return false, dbterror.ErrUnsupportedReorganizePartition.GenWithStackByArgs() + } + } + p, err := w.reorgedTbl.GetPartitionByRow(w.sessCtx, tmpRow) + if err != nil { + return false, errors.Trace(err) + } + pid := p.GetPhysicalID() + newKey := tablecodec.EncodeTablePrefix(pid) + newKey = append(newKey, recordKey[len(newKey):]...) + w.rowRecords = append(w.rowRecords, &rowRecord{ + key: newKey, vals: rawRow, + }) + + w.cleanRowMap() + lastAccessedHandle = recordKey + if recordKey.Cmp(taskRange.endKey) == 0 { + taskDone = true + return false, nil + } + return true, nil + }) + + if len(w.rowRecords) == 0 { + taskDone = true + } + + logutil.BgLogger().Debug("[ddl] txn fetches handle info", zap.Uint64("txnStartTS", txn.StartTS()), zap.String("taskRange", taskRange.String()), zap.Duration("takeTime", time.Since(startTime))) + return w.rowRecords, getNextHandleKey(taskRange, taskDone, lastAccessedHandle), taskDone, errors.Trace(err) +} + +func (w *reorgPartitionWorker) cleanRowMap() { + for id := range w.rowMap { + delete(w.rowMap, id) + } +} + +func (w *reorgPartitionWorker) AddMetricInfo(cnt float64) { + w.metricCounter.Add(cnt) +} + +func (w *reorgPartitionWorker) String() string { + return typeReorgPartitionWorker.String() +} + +func (w *reorgPartitionWorker) GetTask() (*BackfillJob, error) { + panic("[ddl] partition reorg worker does not implement GetTask function") +} + +func (w *reorgPartitionWorker) UpdateTask(*BackfillJob) error { + panic("[ddl] partition reorg worker does not implement UpdateTask function") +} + +func (w *reorgPartitionWorker) FinishTask(*BackfillJob) error { + panic("[ddl] partition reorg worker does not implement FinishTask function") +} + +func (w *reorgPartitionWorker) GetCtx() *backfillCtx { + return w.backfillCtx +} + +func (w *worker) reorgPartitionDataAndIndex(t table.Table, reorgInfo *reorgInfo) error { + // First copy all table data to the new partitions + // from each of the DroppingDefinitions partitions. + // Then create all indexes on the AddingDefinitions partitions + // for each new index, one partition at a time. + + // Copy the data from the DroppingDefinitions to the AddingDefinitions + if bytes.Equal(reorgInfo.currElement.TypeKey, meta.ColumnElementKey) { + err := w.updatePhysicalTableRow(t, reorgInfo) + if err != nil { + return errors.Trace(err) + } + } + + failpoint.Inject("reorgPartitionAfterDataCopy", func(val failpoint.Value) { + //nolint:forcetypeassert + if val.(bool) { + panic("panic test in reorgPartitionAfterDataCopy") + } + }) + + // Rewrite this to do all indexes at once in addTableIndex + // instead of calling it once per index (meaning reading the table multiple times) + // But for now, try to understand how it works... + firstNewPartitionID := t.Meta().Partition.AddingDefinitions[0].ID + startElementOffset := 0 + //startElementOffsetToResetHandle := -1 + // This backfill job starts with backfilling index data, whose index ID is currElement.ID. + if !bytes.Equal(reorgInfo.currElement.TypeKey, meta.IndexElementKey) { + // First run, have not yet started backfilling index data + // Restart with the first new partition. + // TODO: handle remove partitioning + reorgInfo.PhysicalTableID = firstNewPartitionID + } else { + // The job was interrupted and has been restarted, + // reset and start from where it was done + for i, element := range reorgInfo.elements[1:] { + if reorgInfo.currElement.ID == element.ID { + startElementOffset = i + //startElementOffsetToResetHandle = i + break + } + } + } + + for i := startElementOffset; i < len(reorgInfo.elements[1:]); i++ { + // Now build the indexes in the new partitions + var physTbl table.PhysicalTable + if tbl, ok := t.(table.PartitionedTable); ok { + physTbl = tbl.GetPartition(reorgInfo.PhysicalTableID) + } else if tbl, ok := t.(table.PhysicalTable); ok { + // This may be used when partitioning a non-partitioned table + physTbl = tbl + } + // Get the original start handle and end handle. + currentVer, err := getValidCurrentVersion(reorgInfo.d.store) + if err != nil { + return errors.Trace(err) + } + // TODO: Can we improve this in case of a crash? + // like where the regInfo PhysicalTableID and element is the same, + // and the tableid in the key-prefix regInfo.StartKey and regInfo.EndKey matches with PhysicalTableID + // do not change the reorgInfo start/end key + startHandle, endHandle, err := getTableRange(reorgInfo.d.jobContext(reorgInfo.Job.ID), reorgInfo.d, physTbl, currentVer.Ver, reorgInfo.Job.Priority) + if err != nil { + return errors.Trace(err) + } + + // Always (re)start with the full PhysicalTable range + reorgInfo.StartKey, reorgInfo.EndKey = startHandle, endHandle + + // Update the element in the reorgCtx to keep the atomic access for daemon-worker. + w.getReorgCtx(reorgInfo.Job.ID).setCurrentElement(reorgInfo.elements[i+1]) + + // Update the element in the reorgInfo for updating the reorg meta below. + reorgInfo.currElement = reorgInfo.elements[i+1] + // Write the reorg info to store so the whole reorganize process can recover from panic. + err = reorgInfo.UpdateReorgMeta(reorgInfo.StartKey, w.sessPool) + logutil.BgLogger().Info("[ddl] update column and indexes", + zap.Int64("jobID", reorgInfo.Job.ID), + zap.ByteString("elementType", reorgInfo.currElement.TypeKey), + zap.Int64("elementID", reorgInfo.currElement.ID), + zap.Int64("partitionTableId", physTbl.GetPhysicalID()), + zap.String("startHandle", hex.EncodeToString(reorgInfo.StartKey)), + zap.String("endHandle", hex.EncodeToString(reorgInfo.EndKey))) + if err != nil { + return errors.Trace(err) + } + err = w.addTableIndex(t, reorgInfo) + if err != nil { + return errors.Trace(err) + } + reorgInfo.PhysicalTableID = firstNewPartitionID + } + failpoint.Inject("reorgPartitionAfterIndex", func(val failpoint.Value) { + //nolint:forcetypeassert + if val.(bool) { + panic("panic test in reorgPartitionAfterIndex") + } + }) + return nil +} + func bundlesForExchangeTablePartition(t *meta.Meta, job *model.Job, pt *model.TableInfo, newPar *model.PartitionDefinition, nt *model.TableInfo) ([]*placement.Bundle, error) { bundles := make([]*placement.Bundle, 0, 3) @@ -2804,6 +3539,54 @@ func hexIfNonPrint(s string) string { return "0x" + hex.EncodeToString([]byte(driver.UnwrapFromSingleQuotes(s))) } +// AppendPartitionInfo is used in SHOW CREATE TABLE as well as generation the SQL syntax +// for the PartitionInfo during validation of various DDL commands +func AppendPartitionInfo(partitionInfo *model.PartitionInfo, buf *bytes.Buffer, sqlMode mysql.SQLMode) { + if partitionInfo == nil { + return + } + // Since MySQL 5.1/5.5 is very old and TiDB aims for 5.7/8.0 compatibility, we will not + // include the /*!50100 or /*!50500 comments for TiDB. + // This also solves the issue with comments within comments that would happen for + // PLACEMENT POLICY options. + if partitionInfo.Type == model.PartitionTypeHash { + defaultPartitionDefinitions := true + for i, def := range partitionInfo.Definitions { + if def.Name.O != fmt.Sprintf("p%d", i) { + defaultPartitionDefinitions = false + break + } + if len(def.Comment) > 0 || def.PlacementPolicyRef != nil { + defaultPartitionDefinitions = false + break + } + } + + if defaultPartitionDefinitions { + fmt.Fprintf(buf, "\nPARTITION BY HASH (%s) PARTITIONS %d", partitionInfo.Expr, partitionInfo.Num) + return + } + } + // this if statement takes care of lists/range columns case + if len(partitionInfo.Columns) > 0 { + // partitionInfo.Type == model.PartitionTypeRange || partitionInfo.Type == model.PartitionTypeList + // Notice that MySQL uses two spaces between LIST and COLUMNS... + fmt.Fprintf(buf, "\nPARTITION BY %s COLUMNS(", partitionInfo.Type.String()) + for i, col := range partitionInfo.Columns { + buf.WriteString(stringutil.Escape(col.O, sqlMode)) + if i < len(partitionInfo.Columns)-1 { + buf.WriteString(",") + } + } + buf.WriteString(")\n(") + } else { + fmt.Fprintf(buf, "\nPARTITION BY %s (%s)\n(", partitionInfo.Type.String(), partitionInfo.Expr) + } + + AppendPartitionDefs(partitionInfo, buf, sqlMode) + buf.WriteString(")") +} + // AppendPartitionDefs generates a list of partition definitions needed for SHOW CREATE TABLE (in executor/show.go) // as well as needed for generating the ADD PARTITION query for INTERVAL partitioning of ALTER TABLE t LAST PARTITION // and generating the CREATE TABLE query from CREATE TABLE ... INTERVAL diff --git a/ddl/placement/common.go b/ddl/placement/common.go index cd02622dd0562..7c77ead97e30e 100644 --- a/ddl/placement/common.go +++ b/ddl/placement/common.go @@ -54,4 +54,8 @@ const ( // EngineLabelTiKV is the label value used in some tests. And possibly TiKV will // set the engine label with a value of EngineLabelTiKV. EngineLabelTiKV = "tikv" + + // EngineLabelTiFlashCompute is for disaggregated tiflash mode, + // it's the lable of tiflash_compute nodes. + EngineLabelTiFlashCompute = "tiflash_compute" ) diff --git a/ddl/placement_policy_ddl_test.go b/ddl/placement_policy_ddl_test.go index f5d1392018c84..0c0793e711d8e 100644 --- a/ddl/placement_policy_ddl_test.go +++ b/ddl/placement_policy_ddl_test.go @@ -121,6 +121,7 @@ func TestPlacementPolicyInUse(t *testing.T) { builder, err := infoschema.NewBuilder(store, nil).InitWithDBInfos( []*model.DBInfo{db1, db2, dbP}, []*model.PolicyInfo{p1, p2, p3, p4, p5}, + nil, 1, ) require.NoError(t, err) diff --git a/ddl/placement_sql_test.go b/ddl/placement_sql_test.go index 5daca69feabec..b9af2af16e19d 100644 --- a/ddl/placement_sql_test.go +++ b/ddl/placement_sql_test.go @@ -588,7 +588,7 @@ func checkTiflashReplicaSet(t *testing.T, do *domain.Domain, db, tb string, cnt return } - CheckPlacementRule(infosync.GetMockTiFlash(), *infosync.MakeNewRule(tbl.Meta().ID, 1, nil)) + infosync.GetMockTiFlash().CheckPlacementRule(*infosync.MakeNewRule(tbl.Meta().ID, 1, nil)) require.NotNil(t, tiflashReplica) require.Equal(t, cnt, tiflashReplica.Count) } diff --git a/ddl/reorg.go b/ddl/reorg.go index 2c7508d24b38f..1fd3373536768 100644 --- a/ddl/reorg.go +++ b/ddl/reorg.go @@ -18,6 +18,7 @@ import ( "encoding/hex" "fmt" "strconv" + "strings" "sync" "sync/atomic" "time" @@ -34,7 +35,6 @@ import ( "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/table/tables" @@ -142,11 +142,9 @@ func (rc *reorgCtx) increaseRowCount(count int64) { atomic.AddInt64(&rc.rowCount, count) } -func (rc *reorgCtx) getRowCountAndKey() (int64, kv.Key, *meta.Element) { +func (rc *reorgCtx) getRowCount() int64 { row := atomic.LoadInt64(&rc.rowCount) - h, _ := (rc.doneKey.Load()).(nullableKey) - element, _ := (rc.element.Load()).(*meta.Element) - return row, h.key, element + return row } // runReorgJob is used as a portal to do the reorganization work. @@ -154,6 +152,7 @@ func (rc *reorgCtx) getRowCountAndKey() (int64, kv.Key, *meta.Element) { // 1: add index // 2: alter column type // 3: clean global index +// 4: reorganize partitions /* ddl goroutine >---------+ ^ | @@ -197,7 +196,7 @@ func (w *worker) runReorgJob(rh *reorgHandler, reorgInfo *reorgInfo, tblInfo *mo } } - rc := w.getReorgCtx(job) + rc := w.getReorgCtx(job.ID) if rc == nil { // This job is cancelling, we should return ErrCancelledDDLJob directly. // Q: Is there any possibility that the job is cancelling and has no reorgCtx? @@ -233,8 +232,13 @@ func (w *worker) runReorgJob(rh *reorgHandler, reorgInfo *reorgInfo, tblInfo *mo d.removeReorgCtx(job) return dbterror.ErrCancelledDDLJob } - rowCount, _, _ := rc.getRowCountAndKey() - logutil.BgLogger().Info("[ddl] run reorg job done", zap.Int64("handled rows", rowCount)) + rowCount := rc.getRowCount() + if err != nil { + logutil.BgLogger().Warn("[ddl] run reorg job done", zap.Int64("handled rows", rowCount), zap.Error(err)) + } else { + logutil.BgLogger().Info("[ddl] run reorg job done", zap.Int64("handled rows", rowCount)) + } + job.SetRowCount(rowCount) // Update a job's warnings. @@ -248,17 +252,13 @@ func (w *worker) runReorgJob(rh *reorgHandler, reorgInfo *reorgInfo, tblInfo *mo } updateBackfillProgress(w, reorgInfo, tblInfo, 0) - if err1 := rh.RemoveDDLReorgHandle(job, reorgInfo.elements); err1 != nil { - logutil.BgLogger().Warn("[ddl] run reorg job done, removeDDLReorgHandle failed", zap.Error(err1)) - return errors.Trace(err1) - } case <-w.ctx.Done(): logutil.BgLogger().Info("[ddl] run reorg job quit") d.removeReorgCtx(job) // We return dbterror.ErrWaitReorgTimeout here too, so that outer loop will break. return dbterror.ErrWaitReorgTimeout case <-time.After(waitTimeout): - rowCount, doneKey, currentElement := rc.getRowCountAndKey() + rowCount := rc.getRowCount() job.SetRowCount(rowCount) updateBackfillProgress(w, reorgInfo, tblInfo, rowCount) @@ -267,18 +267,9 @@ func (w *worker) runReorgJob(rh *reorgHandler, reorgInfo *reorgInfo, tblInfo *mo rc.resetWarnings() - // Update a reorgInfo's handle. - // Since daemon-worker is triggered by timer to store the info half-way. - // you should keep these infos is read-only (like job) / atomic (like doneKey & element) / concurrent safe. - err := rh.UpdateDDLReorgStartHandle(job, currentElement, doneKey) - logutil.BgLogger().Info("[ddl] run reorg job wait timeout", - zap.Duration("waitTime", waitTimeout), - zap.ByteString("elementType", currentElement.TypeKey), - zap.Int64("elementID", currentElement.ID), - zap.Int64("totalAddedRowCount", rowCount), - zap.String("doneKey", tryDecodeToHandleString(doneKey)), - zap.Error(err)) + zap.Duration("wait time", waitTimeout), + zap.Int64("total added row count", rowCount)) // If timeout, we will return, check the owner and retry to wait job done again. return dbterror.ErrWaitReorgTimeout } @@ -286,7 +277,7 @@ func (w *worker) runReorgJob(rh *reorgHandler, reorgInfo *reorgInfo, tblInfo *mo } func (w *worker) mergeWarningsIntoJob(job *model.Job) { - rc := w.getReorgCtx(job) + rc := w.getReorgCtx(job.ID) rc.mu.Lock() defer rc.mu.Unlock() partWarnings := rc.mu.warnings @@ -310,6 +301,10 @@ func updateBackfillProgress(w *worker, reorgInfo *reorgInfo, tblInfo *model.Tabl if progress > 1 { progress = 1 } + logutil.BgLogger().Debug("[ddl] update progress", + zap.Float64("progress", progress), + zap.Int64("addedRowCount", addedRowCount), + zap.Int64("totalCount", totalCount)) } switch reorgInfo.Type { case model.ActionAddIndex, model.ActionAddPrimaryKey: @@ -322,6 +317,8 @@ func updateBackfillProgress(w *worker, reorgInfo *reorgInfo, tblInfo *model.Tabl metrics.GetBackfillProgressByLabel(label, reorgInfo.SchemaName, tblInfo.Name.String()).Set(progress * 100) case model.ActionModifyColumn: metrics.GetBackfillProgressByLabel(metrics.LblModifyColumn, reorgInfo.SchemaName, tblInfo.Name.String()).Set(progress * 100) + case model.ActionReorganizePartition: + metrics.GetBackfillProgressByLabel(metrics.LblReorgPartition, reorgInfo.SchemaName, tblInfo.Name.String()).Set(progress * 100) } } @@ -338,8 +335,20 @@ func getTableTotalCount(w *worker, tblInfo *model.TableInfo) int64 { if !ok { return statistics.PseudoRowCount } - sql := "select table_rows from information_schema.tables where tidb_table_id=%?;" - rows, _, err := executor.ExecRestrictedSQL(w.ctx, nil, sql, tblInfo.ID) + var rows []chunk.Row + if tblInfo.Partition != nil && len(tblInfo.Partition.DroppingDefinitions) > 0 { + // if Reorganize Partition, only select number of rows from the selected partitions! + defs := tblInfo.Partition.DroppingDefinitions + partIDs := make([]string, 0, len(defs)) + for _, def := range defs { + partIDs = append(partIDs, strconv.FormatInt(def.ID, 10)) + } + sql := "select sum(table_rows) from information_schema.partitions where tidb_partition_id in (%?);" + rows, _, err = executor.ExecRestrictedSQL(w.ctx, nil, sql, strings.Join(partIDs, ",")) + } else { + sql := "select table_rows from information_schema.tables where tidb_table_id=%?;" + rows, _, err = executor.ExecRestrictedSQL(w.ctx, nil, sql, tblInfo.ID) + } if err != nil { return statistics.PseudoRowCount } @@ -349,13 +358,13 @@ func getTableTotalCount(w *worker, tblInfo *model.TableInfo) int64 { return rows[0].GetInt64(0) } -func (dc *ddlCtx) isReorgRunnable(job *model.Job) error { +func (dc *ddlCtx) isReorgRunnable(jobID int64) error { if isChanClosed(dc.ctx.Done()) { // Worker is closed. So it can't do the reorganization. return dbterror.ErrInvalidWorker.GenWithStack("worker is closed") } - if dc.getReorgCtx(job).isReorgCanceled() { + if dc.getReorgCtx(jobID).isReorgCanceled() { // Job is cancelled. So it can't be done. return dbterror.ErrCancelledDDLJob } @@ -381,6 +390,7 @@ type reorgInfo struct { // PhysicalTableID is used to trace the current partition we are handling. // If the table is not partitioned, PhysicalTableID would be TableID. PhysicalTableID int64 + dbInfo *model.DBInfo elements []*meta.Element currElement *meta.Element } @@ -559,10 +569,12 @@ func getTableRange(ctx *JobContext, d *ddlCtx, tbl table.PhysicalTable, snapshot endHandleKey = tablecodec.EncodeRecordKey(tbl.RecordPrefix(), maxHandle) } if isEmptyTable || endHandleKey.Cmp(startHandleKey) < 0 { - logutil.BgLogger().Info("[ddl] get table range, endHandle < startHandle", zap.String("table", fmt.Sprintf("%v", tbl.Meta())), + logutil.BgLogger().Info("[ddl] get noop table range", + zap.String("table", fmt.Sprintf("%v", tbl.Meta())), zap.Int64("table/partition ID", tbl.GetPhysicalID()), - zap.String("endHandle", tryDecodeToHandleString(endHandleKey)), - zap.String("startHandle", tryDecodeToHandleString(startHandleKey))) + zap.String("start key", hex.EncodeToString(startHandleKey)), + zap.String("end key", hex.EncodeToString(endHandleKey)), + zap.Bool("is empty table", isEmptyTable)) endHandleKey = startHandleKey } return @@ -578,7 +590,7 @@ func getValidCurrentVersion(store kv.Storage) (ver kv.Version, err error) { return ver, nil } -func getReorgInfo(ctx *JobContext, d *ddlCtx, rh *reorgHandler, job *model.Job, +func getReorgInfo(ctx *JobContext, d *ddlCtx, rh *reorgHandler, job *model.Job, dbInfo *model.DBInfo, tbl table.Table, elements []*meta.Element, mergingTmpIdx bool) (*reorgInfo, error) { var ( element *meta.Element @@ -634,10 +646,6 @@ func getReorgInfo(ctx *JobContext, d *ddlCtx, rh *reorgHandler, job *model.Job, failpoint.Inject("errorUpdateReorgHandle", func() (*reorgInfo, error) { return &info, errors.New("occur an error when update reorg handle") }) - err = rh.RemoveDDLReorgHandle(job, elements) - if err != nil { - return &info, errors.Trace(err) - } err = rh.InitDDLReorgHandle(job, start, end, pid, elements[0]) if err != nil { return &info, errors.Trace(err) @@ -665,7 +673,7 @@ func getReorgInfo(ctx *JobContext, d *ddlCtx, rh *reorgHandler, job *model.Job, // We'll try to remove it in the next major TiDB version. if meta.ErrDDLReorgElementNotExist.Equal(err) { job.SnapshotVer = 0 - logutil.BgLogger().Warn("[ddl] get reorg info, the element does not exist", zap.String("job", job.String()), zap.Bool("enableConcurrentDDL", rh.enableConcurrentDDL)) + logutil.BgLogger().Warn("[ddl] get reorg info, the element does not exist", zap.String("job", job.String())) } return &info, errors.Trace(err) } @@ -678,11 +686,12 @@ func getReorgInfo(ctx *JobContext, d *ddlCtx, rh *reorgHandler, job *model.Job, info.currElement = element info.elements = elements info.mergingTmpIdx = mergingTmpIdx + info.dbInfo = dbInfo return &info, nil } -func getReorgInfoFromPartitions(ctx *JobContext, d *ddlCtx, rh *reorgHandler, job *model.Job, tbl table.Table, partitionIDs []int64, elements []*meta.Element) (*reorgInfo, error) { +func getReorgInfoFromPartitions(ctx *JobContext, d *ddlCtx, rh *reorgHandler, job *model.Job, dbInfo *model.DBInfo, tbl table.PartitionedTable, partitionIDs []int64, elements []*meta.Element) (*reorgInfo, error) { var ( element *meta.Element start kv.Key @@ -700,15 +709,16 @@ func getReorgInfoFromPartitions(ctx *JobContext, d *ddlCtx, rh *reorgHandler, jo return nil, errors.Trace(err) } pid = partitionIDs[0] - tb := tbl.(table.PartitionedTable).GetPartition(pid) - start, end, err = getTableRange(ctx, d, tb, ver.Ver, job.Priority) + physTbl := tbl.GetPartition(pid) + + start, end, err = getTableRange(ctx, d, physTbl, ver.Ver, job.Priority) if err != nil { return nil, errors.Trace(err) } logutil.BgLogger().Info("[ddl] job get table range", - zap.Int64("jobID", job.ID), zap.Int64("physicalTableID", pid), - zap.String("startHandle", tryDecodeToHandleString(start)), - zap.String("endHandle", tryDecodeToHandleString(end))) + zap.Int64("job ID", job.ID), zap.Int64("physical table ID", pid), + zap.String("start key", hex.EncodeToString(start)), + zap.String("end key", hex.EncodeToString(end))) err = rh.InitDDLReorgHandle(job, start, end, pid, elements[0]) if err != nil { @@ -738,32 +748,30 @@ func getReorgInfoFromPartitions(ctx *JobContext, d *ddlCtx, rh *reorgHandler, jo info.PhysicalTableID = pid info.currElement = element info.elements = elements + info.dbInfo = dbInfo return &info, nil } +// UpdateReorgMeta creates a new transaction and updates tidb_ddl_reorg table, +// so the reorg can restart in case of issues. func (r *reorgInfo) UpdateReorgMeta(startKey kv.Key, pool *sessionPool) (err error) { if startKey == nil && r.EndKey == nil { return nil } - se, err := pool.get() + sctx, err := pool.get() if err != nil { return } - defer pool.put(se) + defer pool.put(sctx) - sess := newSession(se) + sess := newSession(sctx) err = sess.begin() if err != nil { return } - txn, err := sess.txn() - if err != nil { - sess.rollback() - return err - } - rh := newReorgHandler(meta.NewMeta(txn), sess, variable.EnableConcurrentDDL.Load()) - err = rh.UpdateDDLReorgHandle(r.Job, startKey, r.EndKey, r.PhysicalTableID, r.currElement) + rh := newReorgHandler(sess) + err = updateDDLReorgHandle(rh.s, r.Job.ID, startKey, r.EndKey, r.PhysicalTableID, r.currElement) err1 := sess.commit() if err == nil { err = err1 @@ -773,65 +781,48 @@ func (r *reorgInfo) UpdateReorgMeta(startKey kv.Key, pool *sessionPool) (err err // reorgHandler is used to handle the reorg information duration reorganization DDL job. type reorgHandler struct { - m *meta.Meta s *session - - enableConcurrentDDL bool } // NewReorgHandlerForTest creates a new reorgHandler, only used in test. -func NewReorgHandlerForTest(t *meta.Meta, sess sessionctx.Context) *reorgHandler { - return newReorgHandler(t, newSession(sess), variable.EnableConcurrentDDL.Load()) -} - -func newReorgHandler(t *meta.Meta, sess *session, enableConcurrentDDL bool) *reorgHandler { - return &reorgHandler{m: t, s: sess, enableConcurrentDDL: enableConcurrentDDL} -} - -// UpdateDDLReorgStartHandle saves the job reorganization latest processed element and start handle for later resuming. -func (r *reorgHandler) UpdateDDLReorgStartHandle(job *model.Job, element *meta.Element, startKey kv.Key) error { - if r.enableConcurrentDDL { - return updateDDLReorgStartHandle(r.s, job, element, startKey) - } - return r.m.UpdateDDLReorgStartHandle(job, element, startKey) +func NewReorgHandlerForTest(sess sessionctx.Context) *reorgHandler { + return newReorgHandler(newSession(sess)) } -// UpdateDDLReorgHandle saves the job reorganization latest processed information for later resuming. -func (r *reorgHandler) UpdateDDLReorgHandle(job *model.Job, startKey, endKey kv.Key, physicalTableID int64, element *meta.Element) error { - if r.enableConcurrentDDL { - return updateDDLReorgHandle(r.s, job.ID, startKey, endKey, physicalTableID, element) - } - return r.m.UpdateDDLReorgHandle(job.ID, startKey, endKey, physicalTableID, element) +func newReorgHandler(sess *session) *reorgHandler { + return &reorgHandler{s: sess} } // InitDDLReorgHandle initializes the job reorganization information. func (r *reorgHandler) InitDDLReorgHandle(job *model.Job, startKey, endKey kv.Key, physicalTableID int64, element *meta.Element) error { - if r.enableConcurrentDDL { - return initDDLReorgHandle(r.s, job.ID, startKey, endKey, physicalTableID, element) - } - return r.m.UpdateDDLReorgHandle(job.ID, startKey, endKey, physicalTableID, element) + return initDDLReorgHandle(r.s, job.ID, startKey, endKey, physicalTableID, element) } // RemoveReorgElementFailPoint removes the element of the reorganization information. func (r *reorgHandler) RemoveReorgElementFailPoint(job *model.Job) error { - if r.enableConcurrentDDL { - return removeReorgElement(r.s, job) - } - return r.m.RemoveReorgElement(job) + return removeReorgElement(r.s, job) } // RemoveDDLReorgHandle removes the job reorganization related handles. func (r *reorgHandler) RemoveDDLReorgHandle(job *model.Job, elements []*meta.Element) error { - if r.enableConcurrentDDL { - return removeDDLReorgHandle(r.s, job, elements) + return removeDDLReorgHandle(r.s, job, elements) +} + +// CleanupDDLReorgHandles removes the job reorganization related handles. +func CleanupDDLReorgHandles(job *model.Job, s *session) { + if job != nil && !job.IsFinished() && !job.IsSynced() { + // Job is given, but it is neither finished nor synced; do nothing + return + } + + err := cleanDDLReorgHandles(s, job) + if err != nil { + // ignore error, cleanup is not that critical + logutil.BgLogger().Warn("Failed removing the DDL reorg entry in tidb_ddl_reorg", zap.String("job", job.String()), zap.Error(err)) } - return r.m.RemoveDDLReorgHandle(job, elements) } // GetDDLReorgHandle gets the latest processed DDL reorganize position. func (r *reorgHandler) GetDDLReorgHandle(job *model.Job) (element *meta.Element, startKey, endKey kv.Key, physicalTableID int64, err error) { - if r.enableConcurrentDDL { - return getDDLReorgHandle(r.s, job) - } - return r.m.GetDDLReorgHandle(job) + return getDDLReorgHandle(r.s, job) } diff --git a/ddl/resource_group.go b/ddl/resource_group.go new file mode 100644 index 0000000000000..3d397dd14160c --- /dev/null +++ b/ddl/resource_group.go @@ -0,0 +1,157 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl + +import ( + "context" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/ddl/resourcegroup" + "github.com/pingcap/tidb/domain/infosync" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/meta" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/util/dbterror" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" +) + +func onCreateResourceGroup(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { + groupInfo := &model.ResourceGroupInfo{} + if err := job.DecodeArgs(groupInfo); err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + groupInfo.State = model.StateNone + + // check if resource group value is valid and convert to proto format. + protoGroup, err := resourcegroup.NewGroupFromOptions(groupInfo.Name.L, groupInfo.ResourceGroupSettings) + if err != nil { + logutil.BgLogger().Warn("convert to resource group failed", zap.Error(err)) + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + + switch groupInfo.State { + case model.StateNone: + // none -> public + groupInfo.State = model.StatePublic + err := t.CreateResourceGroup(groupInfo) + if err != nil { + return ver, errors.Trace(err) + } + err = infosync.CreateResourceGroup(context.TODO(), protoGroup) + if err != nil { + logutil.BgLogger().Warn("create resource group failed", zap.Error(err)) + return ver, errors.Trace(err) + } + job.SchemaID = groupInfo.ID + ver, err = updateSchemaVersion(d, t, job) + if err != nil { + return ver, errors.Trace(err) + } + // Finish this job. + job.FinishDBJob(model.JobStateDone, model.StatePublic, ver, nil) + return ver, nil + default: + return ver, dbterror.ErrInvalidDDLState.GenWithStackByArgs("resource_group", groupInfo.State) + } +} + +func onAlterResourceGroup(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { + alterGroupInfo := &model.ResourceGroupInfo{} + if err := job.DecodeArgs(alterGroupInfo); err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + // check if resource group value is valid and convert to proto format. + protoGroup, err := resourcegroup.NewGroupFromOptions(alterGroupInfo.Name.L, alterGroupInfo.ResourceGroupSettings) + if err != nil { + logutil.BgLogger().Warn("convert to resource group failed", zap.Error(err)) + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + + oldGroup, err := checkResourceGroupExist(t, job, alterGroupInfo.ID) + if err != nil { + return ver, errors.Trace(err) + } + + newGroup := *oldGroup + newGroup.ResourceGroupSettings = alterGroupInfo.ResourceGroupSettings + + // TODO: check the group validation + err = t.UpdateResourceGroup(&newGroup) + if err != nil { + return ver, errors.Trace(err) + } + + err = infosync.ModifyResourceGroup(context.TODO(), protoGroup) + if err != nil { + logutil.BgLogger().Warn("update resource group failed", zap.Error(err)) + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + + ver, err = updateSchemaVersion(d, t, job) + if err != nil { + return ver, errors.Trace(err) + } + // Finish this job. + job.FinishDBJob(model.JobStateDone, model.StatePublic, ver, nil) + return ver, nil +} + +func checkResourceGroupExist(t *meta.Meta, job *model.Job, groupID int64) (*model.ResourceGroupInfo, error) { + groupInfo, err := t.GetResourceGroup(groupID) + if err == nil { + return groupInfo, nil + } + if infoschema.ErrResourceGroupNotExists.Equal(err) { + job.State = model.JobStateCancelled + } + return nil, err +} + +func onDropResourceGroup(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { + groupInfo, err := checkResourceGroupExist(t, job, job.SchemaID) + if err != nil { + return ver, errors.Trace(err) + } + // TODO: check the resource group not in use. + switch groupInfo.State { + case model.StatePublic: + // public -> none + // resource group not influence the correctness of the data, so we can directly remove it. + groupInfo.State = model.StateNone + err = t.DropResourceGroup(groupInfo.ID) + if err != nil { + return ver, errors.Trace(err) + } + err = infosync.DeleteResourceGroup(context.TODO(), groupInfo.Name.L) + if err != nil { + return ver, errors.Trace(err) + } + ver, err = updateSchemaVersion(d, t, job) + if err != nil { + return ver, errors.Trace(err) + } + // Finish this job. + job.FinishDBJob(model.JobStateDone, model.StateNone, ver, nil) + default: + err = dbterror.ErrInvalidDDLState.GenWithStackByArgs("resource_group", groupInfo.State) + } + return ver, errors.Trace(err) +} diff --git a/ddl/resource_group_test.go b/ddl/resource_group_test.go new file mode 100644 index 0000000000000..789e81f99f0fb --- /dev/null +++ b/ddl/resource_group_test.go @@ -0,0 +1,176 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl_test + +import ( + "context" + "strconv" + "testing" + + "github.com/pingcap/tidb/ddl" + "github.com/pingcap/tidb/ddl/resourcegroup" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/domain/infosync" + mysql "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" +) + +func TestResourceGroupBasic(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + re := require.New(t) + + hook := &ddl.TestDDLCallback{Do: dom} + var groupID int64 + onJobUpdatedExportedFunc := func(job *model.Job) { + // job.SchemaID will be assigned when the group is created. + if (job.SchemaName == "x" || job.SchemaName == "y") && job.Type == model.ActionCreateResourceGroup && job.SchemaID != 0 { + groupID = job.SchemaID + return + } + } + hook.OnJobUpdatedExported.Store(&onJobUpdatedExportedFunc) + dom.DDL().SetHook(hook) + + tk.MustExec("set global tidb_enable_resource_control = 'off'") + tk.MustGetErrCode("create user usr1 resource group rg1", mysql.ErrResourceGroupSupportDisabled) + tk.MustExec("create user usr1") + tk.MustGetErrCode("alter user usr1 resource group rg1", mysql.ErrResourceGroupSupportDisabled) + tk.MustGetErrCode("create resource group x "+ + "RRU_PER_SEC=1000 "+ + "WRU_PER_SEC=2000", mysql.ErrResourceGroupSupportDisabled) + + tk.MustExec("set global tidb_enable_resource_control = 'on'") + + tk.MustExec("create resource group x " + + "RRU_PER_SEC=1000 " + + "WRU_PER_SEC=2000") + checkFunc := func(groupInfo *model.ResourceGroupInfo) { + require.Equal(t, true, groupInfo.ID != 0) + require.Equal(t, "x", groupInfo.Name.L) + require.Equal(t, groupID, groupInfo.ID) + require.Equal(t, uint64(1000), groupInfo.RRURate) + require.Equal(t, uint64(2000), groupInfo.WRURate) + } + // Check the group is correctly reloaded in the information schema. + g := testResourceGroupNameFromIS(t, tk.Session(), "x") + checkFunc(g) + + tk.MustExec("set global tidb_enable_resource_control = DEFAULT") + tk.MustGetErrCode("alter resource group x "+ + "RRU_PER_SEC=2000 "+ + "WRU_PER_SEC=3000", mysql.ErrResourceGroupSupportDisabled) + tk.MustGetErrCode("drop resource group x ", mysql.ErrResourceGroupSupportDisabled) + + tk.MustExec("set global tidb_enable_resource_control = 'on'") + + tk.MustGetErrCode("create resource group x "+ + "RRU_PER_SEC=1000 "+ + "WRU_PER_SEC=2000", mysql.ErrResourceGroupExists) + + tk.MustExec("alter resource group x " + + "RRU_PER_SEC=2000 " + + "WRU_PER_SEC=3000") + g = testResourceGroupNameFromIS(t, tk.Session(), "x") + re.Equal(uint64(2000), g.RRURate) + re.Equal(uint64(3000), g.WRURate) + + tk.MustQuery("select * from information_schema.resource_groups where group_name = 'x'").Check(testkit.Rows(strconv.FormatInt(g.ID, 10) + " x 2000 3000")) + + tk.MustExec("drop resource group x") + g = testResourceGroupNameFromIS(t, tk.Session(), "x") + re.Nil(g) + + tk.MustExec("create resource group y " + + "CPU='4000m' " + + "IO_READ_BANDWIDTH='1G' " + + "IO_WRITE_BANDWIDTH='300M'") + checkFunc = func(groupInfo *model.ResourceGroupInfo) { + require.Equal(t, true, groupInfo.ID != 0) + require.Equal(t, "y", groupInfo.Name.L) + require.Equal(t, groupID, groupInfo.ID) + require.Equal(t, "4000m", groupInfo.CPULimiter) + require.Equal(t, "1G", groupInfo.IOReadBandwidth) + require.Equal(t, "300M", groupInfo.IOWriteBandwidth) + } + g = testResourceGroupNameFromIS(t, tk.Session(), "y") + checkFunc(g) + tk.MustExec("alter resource group y " + + "CPU='8000m' " + + "IO_READ_BANDWIDTH='10G' " + + "IO_WRITE_BANDWIDTH='3000M'") + checkFunc = func(groupInfo *model.ResourceGroupInfo) { + require.Equal(t, true, groupInfo.ID != 0) + require.Equal(t, "y", groupInfo.Name.L) + require.Equal(t, groupID, groupInfo.ID) + require.Equal(t, "8000m", groupInfo.CPULimiter) + require.Equal(t, "10G", groupInfo.IOReadBandwidth) + require.Equal(t, "3000M", groupInfo.IOWriteBandwidth) + } + g = testResourceGroupNameFromIS(t, tk.Session(), "y") + checkFunc(g) + tk.MustExec("drop resource group y") + g = testResourceGroupNameFromIS(t, tk.Session(), "y") + re.Nil(g) + tk.MustContainErrMsg("create resource group x RRU_PER_SEC=1000, CPU='8000m';", resourcegroup.ErrInvalidResourceGroupDuplicatedMode.Error()) + groups, err := infosync.GetAllResourceGroups(context.TODO()) + require.Equal(t, 0, len(groups)) + require.NoError(t, err) + + // Check information schema table information_schema.resource_groups + tk.MustExec("create resource group x " + + "RRU_PER_SEC=1000 " + + "WRU_PER_SEC=2000") + g1 := testResourceGroupNameFromIS(t, tk.Session(), "x") + tk.MustQuery("select * from information_schema.resource_groups where group_name = 'x'").Check(testkit.Rows(strconv.FormatInt(g1.ID, 10) + " x 1000 2000")) + tk.MustQuery("show create resource group x").Check(testkit.Rows("x CREATE RESOURCE GROUP `x` RRU_PER_SEC=1000 WRU_PER_SEC=2000")) + + tk.MustExec("create resource group y " + + "RRU_PER_SEC=2000 " + + "WRU_PER_SEC=3000") + g2 := testResourceGroupNameFromIS(t, tk.Session(), "y") + tk.MustQuery("select * from information_schema.resource_groups where group_name = 'y'").Check(testkit.Rows(strconv.FormatInt(g2.ID, 10) + " y 2000 3000")) + tk.MustQuery("show create resource group y").Check(testkit.Rows("y CREATE RESOURCE GROUP `y` RRU_PER_SEC=2000 WRU_PER_SEC=3000")) + + tk.MustExec("alter resource group y " + + "RRU_PER_SEC=4000 " + + "WRU_PER_SEC=2000") + + g2 = testResourceGroupNameFromIS(t, tk.Session(), "y") + tk.MustQuery("select * from information_schema.resource_groups where group_name = 'y'").Check(testkit.Rows(strconv.FormatInt(g2.ID, 10) + " y 4000 2000")) + tk.MustQuery("show create resource group y").Check(testkit.Rows("y CREATE RESOURCE GROUP `y` RRU_PER_SEC=4000 WRU_PER_SEC=2000")) + + tk.MustQuery("select count(*) from information_schema.resource_groups").Check(testkit.Rows("2")) + tk.MustGetErrCode("create user usr_fail resource group nil_group", mysql.ErrResourceGroupNotExists) + tk.MustExec("create user user2") + tk.MustGetErrCode("alter user user2 resource group nil_group", mysql.ErrResourceGroupNotExists) + + tk.MustExec("create resource group do_not_delete_rg rru_per_sec=100 wru_per_sec=200") + tk.MustExec("create user usr3 resource group do_not_delete_rg") + tk.MustContainErrMsg("drop resource group do_not_delete_rg", "user [usr3] depends on the resource group to drop") +} + +func testResourceGroupNameFromIS(t *testing.T, ctx sessionctx.Context, name string) *model.ResourceGroupInfo { + dom := domain.GetDomain(ctx) + // Make sure the table schema is the new schema. + err := dom.Reload() + require.NoError(t, err) + g, _ := dom.InfoSchema().ResourceGroupByName(model.NewCIStr(name)) + return g +} diff --git a/ddl/resourcegroup/BUILD.bazel b/ddl/resourcegroup/BUILD.bazel new file mode 100644 index 0000000000000..45bfe6465637f --- /dev/null +++ b/ddl/resourcegroup/BUILD.bazel @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "resourcegroup", + srcs = [ + "errors.go", + "group.go", + ], + importpath = "github.com/pingcap/tidb/ddl/resourcegroup", + visibility = ["//visibility:public"], + deps = [ + "//parser/model", + "@com_github_pingcap_errors//:errors", + "@com_github_pingcap_kvproto//pkg/resource_manager", + "@io_k8s_apimachinery//pkg/api/resource", + ], +) + +go_test( + name = "resourcegroup_test", + srcs = ["group_test.go"], + embed = [":resourcegroup"], + deps = [ + "//parser/model", + "@com_github_pingcap_kvproto//pkg/resource_manager", + "@com_github_stretchr_testify//require", + ], +) diff --git a/ddl/resourcegroup/errors.go b/ddl/resourcegroup/errors.go new file mode 100644 index 0000000000000..0893f59876f6d --- /dev/null +++ b/ddl/resourcegroup/errors.go @@ -0,0 +1,32 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resourcegroup + +import ( + "github.com/pingcap/errors" +) + +var ( + // ErrInvalidGroupSettings is from group.go. + ErrInvalidGroupSettings = errors.New("invalid group settings") + // ErrTooLongResourceGroupName is from group.go. + ErrTooLongResourceGroupName = errors.New("resource group name too long") + // ErrInvalidResourceGroupFormat is from group.go. + ErrInvalidResourceGroupFormat = errors.New("group settings with invalid format") + // ErrInvalidResourceGroupDuplicatedMode is from group.go. + ErrInvalidResourceGroupDuplicatedMode = errors.New("cannot set RU mode and Raw mode options at the same time") + // ErrUnknownResourceGroupMode is from group.go. + ErrUnknownResourceGroupMode = errors.New("unknown resource group mode") +) diff --git a/ddl/resourcegroup/group.go b/ddl/resourcegroup/group.go new file mode 100644 index 0000000000000..f52094aee2e5f --- /dev/null +++ b/ddl/resourcegroup/group.go @@ -0,0 +1,105 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resourcegroup + +import ( + "github.com/pingcap/errors" + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" + "github.com/pingcap/tidb/parser/model" + "k8s.io/apimachinery/pkg/api/resource" +) + +const maxGroupNameLength = 32 + +// NewGroupFromOptions creates a new resource group from the given options. +func NewGroupFromOptions(groupName string, options *model.ResourceGroupSettings) (*rmpb.ResourceGroup, error) { + if options == nil { + return nil, ErrInvalidGroupSettings + } + if len(groupName) > maxGroupNameLength { + return nil, ErrTooLongResourceGroupName + } + group := &rmpb.ResourceGroup{ + Name: groupName, + } + var isRUMode bool + if options.RRURate > 0 || options.WRURate > 0 { + isRUMode = true + group.Mode = rmpb.GroupMode_RUMode + group.RUSettings = &rmpb.GroupRequestUnitSettings{ + RRU: &rmpb.TokenBucket{ + Settings: &rmpb.TokenLimitSettings{ + FillRate: options.RRURate, + }, + }, + WRU: &rmpb.TokenBucket{ + Settings: &rmpb.TokenLimitSettings{ + FillRate: options.WRURate, + }, + }, + } + } + if len(options.CPULimiter) > 0 || len(options.IOReadBandwidth) > 0 || len(options.IOWriteBandwidth) > 0 { + if isRUMode { + return nil, ErrInvalidResourceGroupDuplicatedMode + } + parseF := func(s string, scale resource.Scale) (uint64, error) { + if len(s) == 0 { + return 0, nil + } + q, err := resource.ParseQuantity(s) + if err != nil { + return 0, err + } + return uint64(q.ScaledValue(scale)), nil + } + cpuRate, err := parseF(options.CPULimiter, resource.Milli) + if err != nil { + return nil, errors.Annotate(ErrInvalidResourceGroupFormat, err.Error()) + } + ioReadRate, err := parseF(options.IOReadBandwidth, resource.Scale(0)) + if err != nil { + return nil, errors.Annotate(ErrInvalidResourceGroupFormat, err.Error()) + } + ioWriteRate, err := parseF(options.IOWriteBandwidth, resource.Scale(0)) + if err != nil { + return nil, errors.Annotate(ErrInvalidResourceGroupFormat, err.Error()) + } + + group.Mode = rmpb.GroupMode_RawMode + group.RawResourceSettings = &rmpb.GroupRawResourceSettings{ + Cpu: &rmpb.TokenBucket{ + Settings: &rmpb.TokenLimitSettings{ + FillRate: cpuRate, + }, + }, + IoRead: &rmpb.TokenBucket{ + Settings: &rmpb.TokenLimitSettings{ + FillRate: ioReadRate, + }, + }, + IoWrite: &rmpb.TokenBucket{ + Settings: &rmpb.TokenLimitSettings{ + FillRate: ioWriteRate, + }, + }, + } + return group, nil + } + if isRUMode { + return group, nil + } + return nil, ErrUnknownResourceGroupMode +} diff --git a/ddl/resourcegroup/group_test.go b/ddl/resourcegroup/group_test.go new file mode 100644 index 0000000000000..09ca2f4f04fb2 --- /dev/null +++ b/ddl/resourcegroup/group_test.go @@ -0,0 +1,197 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resourcegroup + +import ( + "fmt" + "testing" + + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" + "github.com/pingcap/tidb/parser/model" + "github.com/stretchr/testify/require" +) + +func TestNewResourceGroupFromOptions(t *testing.T) { + type TestCase struct { + name string + groupName string + input *model.ResourceGroupSettings + output *rmpb.ResourceGroup + err error + } + var tests []TestCase + groupName := "test" + tests = append(tests, TestCase{ + name: "empty 1", + input: &model.ResourceGroupSettings{}, + err: ErrUnknownResourceGroupMode, + }) + + tests = append(tests, TestCase{ + name: "empty 2", + input: nil, + err: ErrInvalidGroupSettings, + }) + + tests = append(tests, TestCase{ + name: "normal case: ru case 1", + input: &model.ResourceGroupSettings{ + RRURate: 2000, + WRURate: 20000, + }, + output: &rmpb.ResourceGroup{ + Name: groupName, + Mode: rmpb.GroupMode_RUMode, + RUSettings: &rmpb.GroupRequestUnitSettings{ + RRU: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 2000}}, + WRU: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 20000}}, + }, + }, + }) + + tests = append(tests, TestCase{ + name: "normal case: ru case 2", + input: &model.ResourceGroupSettings{ + RRURate: 5000, + }, + output: &rmpb.ResourceGroup{ + Name: groupName, + Mode: rmpb.GroupMode_RUMode, + RUSettings: &rmpb.GroupRequestUnitSettings{ + RRU: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 5000}}, + WRU: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 0}}, + }, + }, + }) + + tests = append(tests, TestCase{ + name: "normal case: ru case 3", + input: &model.ResourceGroupSettings{ + WRURate: 15000, + }, + output: &rmpb.ResourceGroup{ + Name: groupName, + Mode: rmpb.GroupMode_RUMode, + RUSettings: &rmpb.GroupRequestUnitSettings{ + RRU: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 0}}, + WRU: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 15000}}, + }, + }, + }) + + tests = append(tests, TestCase{ + name: "normal case: native case 1", + input: &model.ResourceGroupSettings{ + CPULimiter: "8000m", + IOReadBandwidth: "3000M", + IOWriteBandwidth: "1500M", + }, + output: &rmpb.ResourceGroup{ + Name: groupName, + Mode: rmpb.GroupMode_RawMode, + RawResourceSettings: &rmpb.GroupRawResourceSettings{ + Cpu: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 8000}}, + IoRead: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 3000000000}}, + IoWrite: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 1500000000}}, + }, + }, + }) + + tests = append(tests, TestCase{ + name: "normal case: native case 2", + input: &model.ResourceGroupSettings{ + CPULimiter: "8", + IOReadBandwidth: "3000Mi", + IOWriteBandwidth: "3000Mi", + }, + output: &rmpb.ResourceGroup{ + Name: groupName, + Mode: rmpb.GroupMode_RawMode, + RawResourceSettings: &rmpb.GroupRawResourceSettings{ + Cpu: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 8000}}, + IoRead: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 3145728000}}, + IoWrite: &rmpb.TokenBucket{Settings: &rmpb.TokenLimitSettings{FillRate: 3145728000}}, + }, + }, + }) + + tests = append(tests, TestCase{ + name: "error case: native case 1", + input: &model.ResourceGroupSettings{ + CPULimiter: "8", + IOReadBandwidth: "3000MB/s", + IOWriteBandwidth: "3000Mi", + }, + err: ErrInvalidResourceGroupFormat, + }) + + tests = append(tests, TestCase{ + name: "error case: native case 2", + input: &model.ResourceGroupSettings{ + CPULimiter: "8c", + IOReadBandwidth: "3000Mi", + IOWriteBandwidth: "3000Mi", + }, + err: ErrInvalidResourceGroupFormat, + }) + + tests = append(tests, TestCase{ + name: "error case: native case 3", + input: &model.ResourceGroupSettings{ + CPULimiter: "8", + IOReadBandwidth: "3000G", + IOWriteBandwidth: "3000MB", + }, + err: ErrInvalidResourceGroupFormat, + }) + + tests = append(tests, TestCase{ + name: "error case: duplicated mode", + input: &model.ResourceGroupSettings{ + CPULimiter: "8", + IOReadBandwidth: "3000Mi", + IOWriteBandwidth: "3000Mi", + RRURate: 1000, + }, + err: ErrInvalidResourceGroupDuplicatedMode, + }) + + tests = append(tests, TestCase{ + name: "error case: duplicated mode", + groupName: "test_group_too_looooooooooooooooooooooooooooooooooooooooooooooooong", + input: &model.ResourceGroupSettings{ + CPULimiter: "8", + IOReadBandwidth: "3000Mi", + IOWriteBandwidth: "3000Mi", + RRURate: 1000, + }, + err: ErrTooLongResourceGroupName, + }) + + for _, test := range tests { + name := groupName + if len(test.groupName) > 0 { + name = test.groupName + } + group, err := NewGroupFromOptions(name, test.input) + comment := fmt.Sprintf("[%s]\nerr1 %s\nerr2 %s", test.name, err, test.err) + if test.err != nil { + require.ErrorIs(t, err, test.err, comment) + } else { + require.NoError(t, err, comment) + require.Equal(t, test.output, group) + } + } +} diff --git a/ddl/restart_test.go b/ddl/restart_test.go index 450624f7dfe97..fa4e21b5f1c05 100644 --- a/ddl/restart_test.go +++ b/ddl/restart_test.go @@ -141,7 +141,7 @@ func TestStat(t *testing.T) { SchemaID: dbInfo.ID, Type: model.ActionDropSchema, BinlogInfo: &model.HistoryInfo{}, - Args: []interface{}{dbInfo.Name}, + Args: []interface{}{true}, } done := make(chan error, 1) diff --git a/ddl/rollingback.go b/ddl/rollingback.go index 4fd30d4c9d84a..c6f75442479b6 100644 --- a/ddl/rollingback.go +++ b/ddl/rollingback.go @@ -388,7 +388,8 @@ func convertJob2RollbackJob(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job) model.ActionModifyTableCharsetAndCollate, model.ActionTruncateTablePartition, model.ActionModifySchemaCharsetAndCollate, model.ActionRepairTable, model.ActionModifyTableAutoIdCache, model.ActionAlterIndexVisibility, - model.ActionExchangeTablePartition, model.ActionModifySchemaDefaultPlacement: + model.ActionExchangeTablePartition, model.ActionModifySchemaDefaultPlacement, + model.ActionRecoverSchema: ver, err = cancelOnlyNotHandledJob(job, model.StateNone) case model.ActionMultiSchemaChange: err = rollingBackMultiSchemaChange(job) diff --git a/ddl/sanity_check.go b/ddl/sanity_check.go index e005eee6a9856..093a8f9fb604f 100644 --- a/ddl/sanity_check.go +++ b/ddl/sanity_check.go @@ -98,7 +98,8 @@ func expectedDeleteRangeCnt(ctx delRangeCntCtx, job *model.Job) (int, error) { return 0, errors.Trace(err) } return mathutil.Max(len(physicalTableIDs), 1), nil - case model.ActionDropTablePartition, model.ActionTruncateTablePartition: + case model.ActionDropTablePartition, model.ActionTruncateTablePartition, + model.ActionReorganizePartition: var physicalTableIDs []int64 if err := job.DecodeArgs(&physicalTableIDs); err != nil { return 0, errors.Trace(err) diff --git a/ddl/schema.go b/ddl/schema.go index e8502189b6ca2..e9cb1e6579635 100644 --- a/ddl/schema.go +++ b/ddl/schema.go @@ -253,6 +253,95 @@ func onDropSchema(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) return ver, errors.Trace(err) } +func (w *worker) onRecoverSchema(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { + var ( + recoverSchemaInfo *RecoverSchemaInfo + recoverSchemaCheckFlag int64 + ) + if err := job.DecodeArgs(&recoverSchemaInfo, &recoverSchemaCheckFlag); err != nil { + // Invalid arguments, cancel this job. + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + schemaInfo := recoverSchemaInfo.DBInfo + // check GC and safe point + gcEnable, err := checkGCEnable(w) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + switch schemaInfo.State { + case model.StateNone: + // none -> write only + // check GC enable and update flag. + if gcEnable { + job.Args[checkFlagIndexInJobArgs] = recoverCheckFlagEnableGC + } else { + job.Args[checkFlagIndexInJobArgs] = recoverCheckFlagDisableGC + } + // Clear all placement when recover + for _, recoverTabInfo := range recoverSchemaInfo.RecoverTabsInfo { + err = clearTablePlacementAndBundles(recoverTabInfo.TableInfo) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Wrapf(err, "failed to notify PD the placement rules") + } + } + schemaInfo.State = model.StateWriteOnly + job.SchemaState = model.StateWriteOnly + case model.StateWriteOnly: + // write only -> public + // do recover schema and tables. + if gcEnable { + err = disableGC(w) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Errorf("disable gc failed, try again later. err: %v", err) + } + } + dbInfo := schemaInfo.Clone() + dbInfo.State = model.StatePublic + err = t.CreateDatabase(dbInfo) + if err != nil { + return ver, errors.Trace(err) + } + // check GC safe point + err = checkSafePoint(w, recoverSchemaInfo.SnapshotTS) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + for _, recoverInfo := range recoverSchemaInfo.RecoverTabsInfo { + if recoverInfo.TableInfo.TTLInfo != nil { + // force disable TTL job schedule for recovered table + recoverInfo.TableInfo.TTLInfo.Enable = false + } + ver, err = w.recoverTable(t, job, recoverInfo) + if err != nil { + return ver, errors.Trace(err) + } + } + schemaInfo.State = model.StatePublic + for _, recoverInfo := range recoverSchemaInfo.RecoverTabsInfo { + recoverInfo.TableInfo.State = model.StatePublic + recoverInfo.TableInfo.UpdateTS = t.StartTS + } + // use to update InfoSchema + job.SchemaID = schemaInfo.ID + ver, err = updateSchemaVersion(d, t, job) + if err != nil { + return ver, errors.Trace(err) + } + // Finish this job. + job.FinishDBJob(model.JobStateDone, model.StatePublic, ver, schemaInfo) + return ver, nil + default: + // We can't enter here. + return ver, errors.Errorf("invalid db state %v", schemaInfo.State) + } + return ver, errors.Trace(err) +} + func checkSchemaExistAndCancelNotExistJob(t *meta.Meta, job *model.Job) (*model.DBInfo, error) { dbInfo, err := t.GetDatabase(job.SchemaID) if err != nil { diff --git a/ddl/schema_test.go b/ddl/schema_test.go index 70206ed2f179f..3be4fb4e4d278 100644 --- a/ddl/schema_test.go +++ b/ddl/schema_test.go @@ -163,13 +163,13 @@ func testDropSchema(t *testing.T, ctx sessionctx.Context, d ddl.DDL, dbInfo *mod return job, ver } -func isDDLJobDone(test *testing.T, t *meta.Meta) bool { - job, err := t.GetDDLJobByIdx(0) - require.NoError(test, err) - if job == nil { +func isDDLJobDone(test *testing.T, t *meta.Meta, store kv.Storage) bool { + tk := testkit.NewTestKit(test, store) + rows := tk.MustQuery("select * from mysql.tidb_ddl_job").Rows() + + if len(rows) == 0 { return true } - time.Sleep(testLease) return false } @@ -185,7 +185,7 @@ func testCheckSchemaState(test *testing.T, store kv.Storage, dbInfo *model.DBInf require.NoError(test, err) if state == model.StateNone { - isDropped = isDDLJobDone(test, t) + isDropped = isDDLJobDone(test, t, store) if !isDropped { return nil } diff --git a/ddl/schematracker/checker.go b/ddl/schematracker/checker.go index a2a5c8f5a4402..ec6a7892996c9 100644 --- a/ddl/schematracker/checker.go +++ b/ddl/schematracker/checker.go @@ -17,6 +17,7 @@ package schematracker import ( "bytes" "context" + "crypto/tls" "fmt" "strings" "time" @@ -210,6 +211,11 @@ func (d Checker) DropSchema(ctx sessionctx.Context, stmt *ast.DropDatabaseStmt) return nil } +// RecoverSchema implements the DDL interface. +func (d Checker) RecoverSchema(ctx sessionctx.Context, recoverSchemaInfo *ddl.RecoverSchemaInfo) (err error) { + return nil +} + // CreateTable implements the DDL interface. func (d Checker) CreateTable(ctx sessionctx.Context, stmt *ast.CreateTableStmt) error { err := d.realDDL.CreateTable(ctx, stmt) @@ -427,6 +433,22 @@ func (d Checker) AlterPlacementPolicy(ctx sessionctx.Context, stmt *ast.AlterPla panic("implement me") } +// CreateResourceGroup implements the DDL interface. +// ResourceGroup do not affect the transaction. +func (d Checker) CreateResourceGroup(ctx sessionctx.Context, stmt *ast.CreateResourceGroupStmt) error { + return nil +} + +// DropResourceGroup implements the DDL interface. +func (d Checker) DropResourceGroup(ctx sessionctx.Context, stmt *ast.DropResourceGroupStmt) error { + return nil +} + +// AlterResourceGroup implements the DDL interface. +func (d Checker) AlterResourceGroup(ctx sessionctx.Context, stmt *ast.AlterResourceGroupStmt) error { + return nil +} + // CreateSchemaWithInfo implements the DDL interface. func (d Checker) CreateSchemaWithInfo(ctx sessionctx.Context, info *model.DBInfo, onExist ddl.OnExist) error { err := d.realDDL.CreateSchemaWithInfo(ctx, info, onExist) @@ -443,13 +465,13 @@ func (d Checker) CreateSchemaWithInfo(ctx sessionctx.Context, info *model.DBInfo } // CreateTableWithInfo implements the DDL interface. -func (d Checker) CreateTableWithInfo(ctx sessionctx.Context, schema model.CIStr, info *model.TableInfo, onExist ddl.OnExist) error { +func (d Checker) CreateTableWithInfo(ctx sessionctx.Context, schema model.CIStr, info *model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { //TODO implement me panic("implement me") } // BatchCreateTableWithInfo implements the DDL interface. -func (d Checker) BatchCreateTableWithInfo(ctx sessionctx.Context, schema model.CIStr, info []*model.TableInfo, onExist ddl.OnExist) error { +func (d Checker) BatchCreateTableWithInfo(ctx sessionctx.Context, schema model.CIStr, info []*model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { //TODO implement me panic("implement me") } @@ -535,28 +557,40 @@ func (d Checker) DoDDLJob(ctx sessionctx.Context, job *model.Job) error { return d.realDDL.DoDDLJob(ctx, job) } -// MoveJobFromQueue2Table implements the DDL interface. -func (d Checker) MoveJobFromQueue2Table(bool) error { - panic("implement me") -} - -// MoveJobFromTable2Queue implements the DDL interface. -func (d Checker) MoveJobFromTable2Queue() error { - panic("implement me") -} - // StorageDDLInjector wraps kv.Storage to inject checker to domain's DDL in bootstrap time. type StorageDDLInjector struct { kv.Storage + kv.EtcdBackend Injector func(ddl.DDL) *Checker } +var _ kv.EtcdBackend = StorageDDLInjector{} + +// EtcdAddrs implements the kv.EtcdBackend interface. +func (s StorageDDLInjector) EtcdAddrs() ([]string, error) { + return s.EtcdBackend.EtcdAddrs() +} + +// TLSConfig implements the kv.EtcdBackend interface. +func (s StorageDDLInjector) TLSConfig() *tls.Config { + return s.EtcdBackend.TLSConfig() +} + +// StartGCWorker implements the kv.EtcdBackend interface. +func (s StorageDDLInjector) StartGCWorker() error { + return s.EtcdBackend.StartGCWorker() +} + // NewStorageDDLInjector creates a new StorageDDLInjector to inject Checker. func NewStorageDDLInjector(s kv.Storage) kv.Storage { - return StorageDDLInjector{ + ret := StorageDDLInjector{ Storage: s, Injector: NewChecker, } + if ebd, ok := s.(kv.EtcdBackend); ok { + ret.EtcdBackend = ebd + } + return ret } // UnwrapStorage unwraps StorageDDLInjector for one level. diff --git a/ddl/schematracker/dm_tracker.go b/ddl/schematracker/dm_tracker.go index 1ef078805fe6c..c6bdd892fcff2 100644 --- a/ddl/schematracker/dm_tracker.go +++ b/ddl/schematracker/dm_tracker.go @@ -49,6 +49,9 @@ var _ ddl.DDL = SchemaTracker{} // SchemaTracker is used to track schema changes by DM. It implements DDL interface and by applying DDL, it updates the // table structure to keep tracked with upstream changes. +// It embeds an InfoStore which stores DBInfo and TableInfo. The DBInfo and TableInfo can be treated as immutable, so +// after reading them by SchemaByName or TableByName, later modifications made by SchemaTracker will not change them. +// SchemaTracker is not thread-safe. type SchemaTracker struct { *InfoStore } @@ -108,16 +111,22 @@ func (d SchemaTracker) CreateSchemaWithInfo(ctx sessionctx.Context, dbInfo *mode } // AlterSchema implements the DDL interface. -func (d SchemaTracker) AlterSchema(ctx sessionctx.Context, stmt *ast.AlterDatabaseStmt) error { +func (d SchemaTracker) AlterSchema(ctx sessionctx.Context, stmt *ast.AlterDatabaseStmt) (err error) { dbInfo := d.SchemaByName(stmt.Name) if dbInfo == nil { return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(stmt.Name.O) } + dbInfo = dbInfo.Clone() + defer func() { + if err == nil { + d.PutSchema(dbInfo) + } + }() + // Resolve target charset and collation from options. var ( toCharset, toCollate string - err error ) for _, val := range stmt.Options { @@ -173,9 +182,15 @@ func (d SchemaTracker) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStm return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(ident.Schema) } // suppress ErrTooLongKey + strictSQLModeBackup := ctx.GetSessionVars().StrictSQLMode ctx.GetSessionVars().StrictSQLMode = false // support drop PK + enableClusteredIndexBackup := ctx.GetSessionVars().EnableClusteredIndex ctx.GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeOff + defer func() { + ctx.GetSessionVars().StrictSQLMode = strictSQLModeBackup + ctx.GetSessionVars().EnableClusteredIndex = enableClusteredIndexBackup + }() var ( referTbl *model.TableInfo @@ -220,8 +235,10 @@ func (d SchemaTracker) CreateTableWithInfo( ctx sessionctx.Context, dbName model.CIStr, info *model.TableInfo, - onExist ddl.OnExist, + cs ...ddl.CreateTableWithInfoConfigurier, ) error { + c := ddl.GetCreateTableWithInfoConfig(cs) + schema := d.SchemaByName(dbName) if schema == nil { return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(dbName) @@ -229,7 +246,7 @@ func (d SchemaTracker) CreateTableWithInfo( oldTable, _ := d.TableByName(dbName, info.Name) if oldTable != nil { - switch onExist { + switch c.OnExist { case ddl.OnExistIgnore: return nil case ddl.OnExistReplace: @@ -311,6 +328,11 @@ func (d SchemaTracker) FlashbackCluster(ctx sessionctx.Context, flashbackTS uint return nil } +// RecoverSchema implements the DDL interface, which is no-op in DM's case. +func (d SchemaTracker) RecoverSchema(ctx sessionctx.Context, recoverSchemaInfo *ddl.RecoverSchemaInfo) (err error) { + return nil +} + // DropView implements the DDL interface. func (d SchemaTracker) DropView(ctx sessionctx.Context, stmt *ast.DropTableStmt) (err error) { notExistTables := make([]string, 0, len(stmt.Tables)) @@ -347,6 +369,13 @@ func (d SchemaTracker) CreateIndex(ctx sessionctx.Context, stmt *ast.CreateIndex stmt.IndexPartSpecifications, stmt.IndexOption, stmt.IfNotExists) } +func (d SchemaTracker) putTableIfNoError(err error, dbName model.CIStr, tbInfo *model.TableInfo) { + if err != nil { + return + } + _ = d.PutTable(dbName, tbInfo) +} + // createIndex is shared by CreateIndex and AlterTable. func (d SchemaTracker) createIndex( ctx sessionctx.Context, @@ -356,12 +385,15 @@ func (d SchemaTracker) createIndex( indexPartSpecifications []*ast.IndexPartSpecification, indexOption *ast.IndexOption, ifNotExists bool, -) error { +) (err error) { unique := keyType == ast.IndexKeyTypeUnique - tblInfo, err := d.TableByName(ti.Schema, ti.Name) + tblInfo, err := d.TableClonedByName(ti.Schema, ti.Name) if err != nil { return err } + + defer d.putTableIfNoError(err, ti.Schema, tblInfo) + t := tables.MockTableFromMeta(tblInfo) // Deal with anonymous index. @@ -425,12 +457,14 @@ func (d SchemaTracker) DropIndex(ctx sessionctx.Context, stmt *ast.DropIndexStmt } // dropIndex is shared by DropIndex and AlterTable. -func (d SchemaTracker) dropIndex(ctx sessionctx.Context, ti ast.Ident, indexName model.CIStr, ifExists bool) error { - tblInfo, err := d.TableByName(ti.Schema, ti.Name) +func (d SchemaTracker) dropIndex(ctx sessionctx.Context, ti ast.Ident, indexName model.CIStr, ifExists bool) (err error) { + tblInfo, err := d.TableClonedByName(ti.Schema, ti.Name) if err != nil { return infoschema.ErrTableNotExists.GenWithStackByArgs(ti.Schema, ti.Name) } + defer d.putTableIfNoError(err, ti.Schema, tblInfo) + indexInfo := tblInfo.FindIndexByName(indexName.L) if indexInfo == nil { if ifExists { @@ -457,16 +491,19 @@ func (d SchemaTracker) dropIndex(ctx sessionctx.Context, ti ast.Ident, indexName } // addColumn is used by AlterTable. -func (d SchemaTracker) addColumn(ctx sessionctx.Context, ti ast.Ident, spec *ast.AlterTableSpec) error { +func (d SchemaTracker) addColumn(ctx sessionctx.Context, ti ast.Ident, spec *ast.AlterTableSpec) (err error) { specNewColumn := spec.NewColumns[0] schema := d.SchemaByName(ti.Schema) if schema == nil { return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(ti.Schema) } - tblInfo, err := d.TableByName(ti.Schema, ti.Name) + tblInfo, err := d.TableClonedByName(ti.Schema, ti.Name) if err != nil { return err } + + defer d.putTableIfNoError(err, ti.Schema, tblInfo) + t := tables.MockTableFromMeta(tblInfo) colName := specNewColumn.Name.Name.O @@ -497,12 +534,14 @@ func (d SchemaTracker) addColumn(ctx sessionctx.Context, ti ast.Ident, spec *ast } // dropColumn is used by AlterTable. -func (d *SchemaTracker) dropColumn(ctx sessionctx.Context, ti ast.Ident, spec *ast.AlterTableSpec) error { - tblInfo, err := d.TableByName(ti.Schema, ti.Name) +func (d *SchemaTracker) dropColumn(ctx sessionctx.Context, ti ast.Ident, spec *ast.AlterTableSpec) (err error) { + tblInfo, err := d.TableClonedByName(ti.Schema, ti.Name) if err != nil { return err } + defer d.putTableIfNoError(err, ti.Schema, tblInfo) + colName := spec.OldColumnName.Name colInfo := tblInfo.FindPublicColumnByName(colName.L) if colInfo == nil { @@ -539,14 +578,17 @@ func (d *SchemaTracker) dropColumn(ctx sessionctx.Context, ti ast.Ident, spec *a } // renameColumn is used by AlterTable. -func (d SchemaTracker) renameColumn(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { +func (d SchemaTracker) renameColumn(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) (err error) { oldColName := spec.OldColumnName.Name newColName := spec.NewColumnName.Name - tblInfo, err := d.TableByName(ident.Schema, ident.Name) + tblInfo, err := d.TableClonedByName(ident.Schema, ident.Name) if err != nil { return err } + + defer d.putTableIfNoError(err, ident.Schema, tblInfo) + tbl := tables.MockTableFromMeta(tblInfo) oldCol := table.FindCol(tbl.VisibleCols(), oldColName.L) @@ -588,12 +630,15 @@ func (d SchemaTracker) renameColumn(ctx sessionctx.Context, ident ast.Ident, spe } // alterColumn is used by AlterTable. -func (d SchemaTracker) alterColumn(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { +func (d SchemaTracker) alterColumn(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) (err error) { specNewColumn := spec.NewColumns[0] - tblInfo, err := d.TableByName(ident.Schema, ident.Name) + tblInfo, err := d.TableClonedByName(ident.Schema, ident.Name) if err != nil { return err } + + defer d.putTableIfNoError(err, ident.Schema, tblInfo) + t := tables.MockTableFromMeta(tblInfo) colName := specNewColumn.Name.Name @@ -657,11 +702,14 @@ func (d SchemaTracker) handleModifyColumn( ident ast.Ident, originalColName model.CIStr, spec *ast.AlterTableSpec, -) error { - tblInfo, err := d.TableByName(ident.Schema, ident.Name) +) (err error) { + tblInfo, err := d.TableClonedByName(ident.Schema, ident.Name) if err != nil { return err } + + defer d.putTableIfNoError(err, ident.Schema, tblInfo) + schema := d.SchemaByName(ident.Schema) t := tables.MockTableFromMeta(tblInfo) job, err := ddl.GetModifiableColumnJob(ctx, sctx, nil, ident, originalColName, schema, t, spec) @@ -707,11 +755,14 @@ func (d SchemaTracker) handleModifyColumn( } // renameIndex is used by AlterTable. -func (d SchemaTracker) renameIndex(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { - tblInfo, err := d.TableByName(ident.Schema, ident.Name) +func (d SchemaTracker) renameIndex(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) (err error) { + tblInfo, err := d.TableClonedByName(ident.Schema, ident.Name) if err != nil { return err } + + defer d.putTableIfNoError(err, ident.Schema, tblInfo) + duplicate, err := ddl.ValidateRenameIndex(spec.FromKey, spec.ToKey, tblInfo) if duplicate { return nil @@ -725,12 +776,14 @@ func (d SchemaTracker) renameIndex(ctx sessionctx.Context, ident ast.Ident, spec } // addTablePartitions is used by AlterTable. -func (d SchemaTracker) addTablePartitions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { - tblInfo, err := d.TableByName(ident.Schema, ident.Name) +func (d SchemaTracker) addTablePartitions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) (err error) { + tblInfo, err := d.TableClonedByName(ident.Schema, ident.Name) if err != nil { return errors.Trace(err) } + defer d.putTableIfNoError(err, ident.Schema, tblInfo) + pi := tblInfo.GetPartitionInfo() if pi == nil { return errors.Trace(dbterror.ErrPartitionMgmtOnNonpartitioned) @@ -745,12 +798,14 @@ func (d SchemaTracker) addTablePartitions(ctx sessionctx.Context, ident ast.Iden } // dropTablePartitions is used by AlterTable. -func (d SchemaTracker) dropTablePartition(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { - tblInfo, err := d.TableByName(ident.Schema, ident.Name) +func (d SchemaTracker) dropTablePartitions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) (err error) { + tblInfo, err := d.TableClonedByName(ident.Schema, ident.Name) if err != nil { return errors.Trace(err) } + defer d.putTableIfNoError(err, ident.Schema, tblInfo) + pi := tblInfo.GetPartitionInfo() if pi == nil { return errors.Trace(dbterror.ErrPartitionMgmtOnNonpartitioned) @@ -792,12 +847,14 @@ func (d SchemaTracker) createPrimaryKey( indexName model.CIStr, indexPartSpecifications []*ast.IndexPartSpecification, indexOption *ast.IndexOption, -) error { - tblInfo, err := d.TableByName(ti.Schema, ti.Name) +) (err error) { + tblInfo, err := d.TableClonedByName(ti.Schema, ti.Name) if err != nil { return errors.Trace(err) } + defer d.putTableIfNoError(err, ti.Schema, tblInfo) + indexName = model.NewCIStr(mysql.PrimaryKeyName) if indexInfo := tblInfo.FindIndexByName(indexName.L); indexInfo != nil || // If the table's PKIsHandle is true, it also means that this table has a primary key. @@ -881,7 +938,7 @@ func (d SchemaTracker) AlterTable(ctx context.Context, sctx sessionctx.Context, case ast.AlterTableRenameIndex: err = d.renameIndex(sctx, ident, spec) case ast.AlterTableDropPartition: - err = d.dropTablePartition(sctx, ident, spec) + err = d.dropTablePartitions(sctx, ident, spec) case ast.AlterTableAddConstraint: constr := spec.Constraint switch spec.Constraint.Tp { @@ -918,7 +975,9 @@ func (d SchemaTracker) AlterTable(ctx context.Context, sctx sessionctx.Context, case ast.TableOptionAutoIdCache: case ast.TableOptionAutoRandomBase: case ast.TableOptionComment: + tblInfo = tblInfo.Clone() tblInfo.Comment = opt.StrValue + _ = d.PutTable(ident.Schema, tblInfo) case ast.TableOptionCharset, ast.TableOptionCollate: // getCharsetAndCollateInTableOption will get the last charset and collate in the options, // so it should be handled only once. @@ -932,6 +991,7 @@ func (d SchemaTracker) AlterTable(ctx context.Context, sctx sessionctx.Context, } needsOverwriteCols := ddl.NeedToOverwriteColCharset(spec.Options) + tblInfo = tblInfo.Clone() if toCharset != "" { tblInfo.Charset = toCharset } @@ -950,6 +1010,7 @@ func (d SchemaTracker) AlterTable(ctx context.Context, sctx sessionctx.Context, } } } + _ = d.PutTable(ident.Schema, tblInfo) handledCharsetOrCollate = true case ast.TableOptionPlacementPolicy: @@ -963,11 +1024,13 @@ func (d SchemaTracker) AlterTable(ctx context.Context, sctx sessionctx.Context, } } case ast.AlterTableIndexInvisible: + tblInfo = tblInfo.Clone() idx := tblInfo.FindIndexByName(spec.IndexName.L) if idx == nil { return errors.Trace(infoschema.ErrKeyNotExists.GenWithStackByArgs(spec.IndexName.O, ident.Name)) } idx.Invisible = spec.Visibility == ast.IndexVisibilityInvisible + _ = d.PutTable(ident.Schema, tblInfo) case ast.AlterTablePartitionOptions, ast.AlterTableDropForeignKey, ast.AlterTableCoalescePartitions, @@ -1110,10 +1173,25 @@ func (SchemaTracker) AlterPlacementPolicy(ctx sessionctx.Context, stmt *ast.Alte return nil } +// CreateResourceGroup implements the DDL interface, it's no-op in DM's case. +func (SchemaTracker) CreateResourceGroup(_ sessionctx.Context, _ *ast.CreateResourceGroupStmt) error { + return nil +} + +// DropResourceGroup implements the DDL interface, it's no-op in DM's case. +func (SchemaTracker) DropResourceGroup(_ sessionctx.Context, _ *ast.DropResourceGroupStmt) error { + return nil +} + +// AlterResourceGroup implements the DDL interface, it's no-op in DM's case. +func (SchemaTracker) AlterResourceGroup(ctx sessionctx.Context, stmt *ast.AlterResourceGroupStmt) error { + return nil +} + // BatchCreateTableWithInfo implements the DDL interface, it will call CreateTableWithInfo for each table. -func (d SchemaTracker) BatchCreateTableWithInfo(ctx sessionctx.Context, schema model.CIStr, info []*model.TableInfo, onExist ddl.OnExist) error { +func (d SchemaTracker) BatchCreateTableWithInfo(ctx sessionctx.Context, schema model.CIStr, info []*model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { for _, tableInfo := range info { - if err := d.CreateTableWithInfo(ctx, schema, tableInfo, onExist); err != nil { + if err := d.CreateTableWithInfo(ctx, schema, tableInfo, cs...); err != nil { return err } } @@ -1193,13 +1271,3 @@ func (SchemaTracker) GetInfoSchemaWithInterceptor(ctx sessionctx.Context) infosc func (SchemaTracker) DoDDLJob(ctx sessionctx.Context, job *model.Job) error { return nil } - -// MoveJobFromQueue2Table implements the DDL interface, it's no-op in DM's case. -func (SchemaTracker) MoveJobFromQueue2Table(b bool) error { - panic("implement me") -} - -// MoveJobFromTable2Queue implements the DDL interface, it's no-op in DM's case. -func (SchemaTracker) MoveJobFromTable2Queue() error { - panic("implement me") -} diff --git a/ddl/schematracker/dm_tracker_test.go b/ddl/schematracker/dm_tracker_test.go index 8cfd34cde0590..01998d3dc0134 100644 --- a/ddl/schematracker/dm_tracker_test.go +++ b/ddl/schematracker/dm_tracker_test.go @@ -98,6 +98,12 @@ func execAlter(t *testing.T, tracker schematracker.SchemaTracker, sql string) { require.NoError(t, err) } +func mustTableByName(t *testing.T, tracker schematracker.SchemaTracker, schema, table string) *model.TableInfo { + tblInfo, err := tracker.TableByName(model.NewCIStr(schema), model.NewCIStr(table)) + require.NoError(t, err) + return tblInfo +} + func TestAlterPK(t *testing.T) { sql := "create table test.t (c1 int primary key, c2 blob);" @@ -105,20 +111,24 @@ func TestAlterPK(t *testing.T) { tracker.CreateTestDB() execCreate(t, tracker, sql) - tblInfo, err := tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo := mustTableByName(t, tracker, "test", "t") require.Equal(t, 1, len(tblInfo.Indices)) sql = "alter table test.t drop primary key;" execAlter(t, tracker, sql) + // TableInfo should be immutable. + require.Equal(t, 1, len(tblInfo.Indices)) + tblInfo = mustTableByName(t, tracker, "test", "t") require.Equal(t, 0, len(tblInfo.Indices)) sql = "alter table test.t add primary key(c1);" execAlter(t, tracker, sql) + tblInfo = mustTableByName(t, tracker, "test", "t") require.Equal(t, 1, len(tblInfo.Indices)) sql = "alter table test.t drop primary key;" execAlter(t, tracker, sql) + tblInfo = mustTableByName(t, tracker, "test", "t") require.Equal(t, 0, len(tblInfo.Indices)) } @@ -129,20 +139,22 @@ func TestDropColumn(t *testing.T) { tracker.CreateTestDB() execCreate(t, tracker, sql) - tblInfo, err := tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo := mustTableByName(t, tracker, "test", "t") require.Equal(t, 1, len(tblInfo.Indices)) sql = "alter table test.t drop column b" execAlter(t, tracker, sql) + tblInfo = mustTableByName(t, tracker, "test", "t") require.Equal(t, 0, len(tblInfo.Indices)) sql = "alter table test.t add index idx_2_col(a, c)" execAlter(t, tracker, sql) + tblInfo = mustTableByName(t, tracker, "test", "t") require.Equal(t, 1, len(tblInfo.Indices)) sql = "alter table test.t drop column c" execAlter(t, tracker, sql) + tblInfo = mustTableByName(t, tracker, "test", "t") require.Equal(t, 1, len(tblInfo.Indices)) require.Equal(t, 1, len(tblInfo.Columns)) } @@ -172,8 +184,7 @@ func TestIndexLength(t *testing.T) { tracker.CreateTestDB() execCreate(t, tracker, sql) - tblInfo, err := tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo := mustTableByName(t, tracker, "test", "t") expected := "CREATE TABLE `t` (\n" + " `a` text DEFAULT NULL,\n" + @@ -185,7 +196,7 @@ func TestIndexLength(t *testing.T) { ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin" checkShowCreateTable(t, tblInfo, expected) - err = tracker.DeleteTable(model.NewCIStr("test"), model.NewCIStr("t")) + err := tracker.DeleteTable(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) sql = "create table test.t(a text, b text charset ascii, c blob);" @@ -198,9 +209,7 @@ func TestIndexLength(t *testing.T) { sql = "alter table test.t add index (c(3072))" execAlter(t, tracker, sql) - tblInfo, err = tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) - + tblInfo = mustTableByName(t, tracker, "test", "t") checkShowCreateTable(t, tblInfo, expected) } @@ -225,8 +234,7 @@ func TestIssue5092(t *testing.T) { sql = "alter table test.t add column b2 int after b1, add column c2 int first" execAlter(t, tracker, sql) - tblInfo, err := tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo := mustTableByName(t, tracker, "test", "t") expected := "CREATE TABLE `t` (\n" + " `c2` int(11) DEFAULT NULL,\n" + @@ -303,8 +311,7 @@ func TestAddExpressionIndex(t *testing.T) { sql = "alter table test.t add index idx_multi((a+b),(a+1), b);" execAlter(t, tracker, sql) - tblInfo, err := tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo := mustTableByName(t, tracker, "test", "t") expected := "CREATE TABLE `t` (\n" + " `a` int(11) DEFAULT NULL,\n" + @@ -319,6 +326,8 @@ func TestAddExpressionIndex(t *testing.T) { sql = "alter table test.t drop index idx_multi;" execAlter(t, tracker, sql) + tblInfo = mustTableByName(t, tracker, "test", "t") + expected = "CREATE TABLE `t` (\n" + " `a` int(11) DEFAULT NULL,\n" + " `b` double DEFAULT NULL\n" + @@ -330,8 +339,7 @@ func TestAddExpressionIndex(t *testing.T) { sql = "alter table test.t2 add unique index ei_ab ((concat(a, b)));" execAlter(t, tracker, sql) - tblInfo, err = tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t2")) - require.NoError(t, err) + tblInfo = mustTableByName(t, tracker, "test", "t2") expected = "CREATE TABLE `t2` (\n" + " `a` varchar(10) DEFAULT NULL,\n" + @@ -343,6 +351,8 @@ func TestAddExpressionIndex(t *testing.T) { sql = "alter table test.t2 alter index ei_ab invisible;" execAlter(t, tracker, sql) + tblInfo = mustTableByName(t, tracker, "test", "t2") + expected = "CREATE TABLE `t2` (\n" + " `a` varchar(10) DEFAULT NULL,\n" + " `b` varchar(10) DEFAULT NULL,\n" + @@ -353,8 +363,7 @@ func TestAddExpressionIndex(t *testing.T) { sql = "create table test.t3(a int, key((a+1)), key((a+2)), key idx((a+3)), key((a+4)), UNIQUE KEY ((a * 2)));" execCreate(t, tracker, sql) - tblInfo, err = tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t3")) - require.NoError(t, err) + tblInfo = mustTableByName(t, tracker, "test", "t3") expected = "CREATE TABLE `t3` (\n" + " `a` int(11) DEFAULT NULL,\n" + @@ -381,8 +390,7 @@ func TestAddExpressionIndex(t *testing.T) { sql = "alter table test.t4 add index idx((a+c));" execAlter(t, tracker, sql) - tblInfo, err = tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t4")) - require.NoError(t, err) + tblInfo = mustTableByName(t, tracker, "test", "t4") expected = "CREATE TABLE `t4` (\n" + " `a` int(11) DEFAULT NULL,\n" + @@ -408,8 +416,7 @@ func TestAtomicMultiSchemaChange(t *testing.T) { sql = "alter table test.t add b int, add c int;" execAlter(t, tracker, sql) - tblInfo, err := tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo := mustTableByName(t, tracker, "test", "t") require.Len(t, tblInfo.Columns, 3) sql = "alter table test.t add d int, add a int;" @@ -422,11 +429,45 @@ func TestAtomicMultiSchemaChange(t *testing.T) { err = tracker.AlterTable(ctx, sctx, stmt.(*ast.AlterTableStmt)) require.True(t, infoschema.ErrColumnExists.Equal(err)) - tblInfo, err = tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo = mustTableByName(t, tracker, "test", "t") require.Len(t, tblInfo.Columns, 3) } +func TestImmutableTableInfo(t *testing.T) { + sql := "create table test.t (a varchar(20)) charset latin1;" + + tracker := schematracker.NewSchemaTracker(2) + tracker.CreateTestDB() + execCreate(t, tracker, sql) + + tblInfo := mustTableByName(t, tracker, "test", "t") + require.Equal(t, "", tblInfo.Comment) + + sql = "alter table test.t comment = '123';" + execAlter(t, tracker, sql) + require.Equal(t, "", tblInfo.Comment) + + tblInfo = mustTableByName(t, tracker, "test", "t") + require.Equal(t, "123", tblInfo.Comment) + + require.Equal(t, "latin1", tblInfo.Charset) + require.Equal(t, "latin1_bin", tblInfo.Collate) + require.Equal(t, "latin1", tblInfo.Columns[0].GetCharset()) + require.Equal(t, "latin1_bin", tblInfo.Columns[0].GetCollate()) + + sql = "alter table test.t convert to character set utf8mb4 collate utf8mb4_general_ci;" + execAlter(t, tracker, sql) + require.Equal(t, "latin1", tblInfo.Charset) + require.Equal(t, "latin1_bin", tblInfo.Collate) + require.Equal(t, "latin1", tblInfo.Columns[0].GetCharset()) + require.Equal(t, "latin1_bin", tblInfo.Columns[0].GetCollate()) + tblInfo = mustTableByName(t, tracker, "test", "t") + require.Equal(t, "utf8mb4", tblInfo.Charset) + require.Equal(t, "utf8mb4_general_ci", tblInfo.Collate) + require.Equal(t, "utf8mb4", tblInfo.Columns[0].GetCharset()) + require.Equal(t, "utf8mb4_general_ci", tblInfo.Columns[0].GetCollate()) +} + var _ sqlexec.RestrictedSQLExecutor = (*mockRestrictedSQLExecutor)(nil) type mockRestrictedSQLExecutor struct { @@ -462,7 +503,6 @@ func TestModifyFromNullToNotNull(t *testing.T) { err = tracker.AlterTable(ctx, executorCtx, stmt.(*ast.AlterTableStmt)) require.NoError(t, err) - tblInfo, err := tracker.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) + tblInfo := mustTableByName(t, tracker, "test", "t") require.Len(t, tblInfo.Columns, 2) } diff --git a/ddl/schematracker/info_store.go b/ddl/schematracker/info_store.go index 6c0739d960b3c..d6bb970591c8b 100644 --- a/ddl/schematracker/info_store.go +++ b/ddl/schematracker/info_store.go @@ -88,6 +88,15 @@ func (i *InfoStore) TableByName(schema, table model.CIStr) (*model.TableInfo, er return tbl, nil } +// TableClonedByName is like TableByName, plus it will clone the TableInfo. +func (i *InfoStore) TableClonedByName(schema, table model.CIStr) (*model.TableInfo, error) { + tbl, err := i.TableByName(schema, table) + if err != nil { + return nil, err + } + return tbl.Clone(), nil +} + // PutTable puts a TableInfo, it will overwrite the old one. If the schema doesn't exist, it will return ErrDatabaseNotExists. func (i *InfoStore) PutTable(schemaName model.CIStr, tblInfo *model.TableInfo) error { schemaKey := i.ciStr2Key(schemaName) diff --git a/ddl/sequence_test.go b/ddl/sequence_test.go index df58df12b0ebd..9b798c9f45eea 100644 --- a/ddl/sequence_test.go +++ b/ddl/sequence_test.go @@ -62,8 +62,7 @@ func TestCreateSequence(t *testing.T) { // test unsupported table option in sequence. tk.MustGetErrCode("create sequence seq CHARSET=utf8", mysql.ErrSequenceUnsupportedTableOption) - _, err := tk.Exec("create sequence seq comment=\"test\"") - require.NoError(t, err) + tk.MustExec("create sequence seq comment=\"test\"") sequenceTable := external.GetTableByName(t, tk, "test", "seq") diff --git a/ddl/serial_test.go b/ddl/serial_test.go index fc74d0400e0f6..970f60a95ff96 100644 --- a/ddl/serial_test.go +++ b/ddl/serial_test.go @@ -112,6 +112,7 @@ func TestCreateTableWithLike(t *testing.T) { tk.MustExec("use ctwl_db") tk.MustExec("create table tt(id int primary key)") tk.MustExec("create table t (c1 int not null auto_increment, c2 int, constraint cc foreign key (c2) references tt(id), primary key(c1)) auto_increment = 10") + tk.MustExec("set @@foreign_key_checks=0") tk.MustExec("insert into t set c2=1") tk.MustExec("create table t1 like ctwl_db.t") tk.MustExec("insert into t1 set c2=11") @@ -297,7 +298,7 @@ func TestCreateTableWithLikeAtTemporaryMode(t *testing.T) { // Test foreign key. tk.MustExec("drop table if exists test_foreign_key, t1") - tk.MustExec("create table t1 (a int, b int)") + tk.MustExec("create table t1 (a int, b int, index(b))") tk.MustExec("create table test_foreign_key (c int,d int,foreign key (d) references t1 (b))") defer tk.MustExec("drop table if exists test_foreign_key, t1") tk.MustExec("create global temporary table test_foreign_key_temp like test_foreign_key on commit delete rows") @@ -382,7 +383,7 @@ func TestCreateTableWithLikeAtTemporaryMode(t *testing.T) { defer tk.MustExec("drop table if exists partition_table, tmp_partition_table") tk.MustExec("drop table if exists foreign_key_table1, foreign_key_table2, foreign_key_tmp") - tk.MustExec("create table foreign_key_table1 (a int, b int)") + tk.MustExec("create table foreign_key_table1 (a int, b int, index(b))") tk.MustExec("create table foreign_key_table2 (c int,d int,foreign key (d) references foreign_key_table1 (b))") tk.MustExec("create temporary table foreign_key_tmp like foreign_key_table2") is = sessiontxn.GetTxnManager(tk.Session()).GetTxnInfoSchema() @@ -461,6 +462,70 @@ func TestCancelAddIndexPanic(t *testing.T) { require.Truef(t, strings.HasPrefix(errMsg, "[ddl:8214]Cancelled DDL job"), "%v", errMsg) } +func TestRecoverTableWithTTL(t *testing.T) { + store, _ := createMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("create database if not exists test_recover") + tk.MustExec("use test_recover") + defer func(originGC bool) { + if originGC { + util.EmulatorGCEnable() + } else { + util.EmulatorGCDisable() + } + }(util.IsEmulatorGCEnable()) + + // disable emulator GC. + // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. + util.EmulatorGCDisable() + gcTimeFormat := "20060102-15:04:05 -0700 MST" + safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') + ON DUPLICATE KEY + UPDATE variable_value = '%[1]s'` + tk.MustExec(fmt.Sprintf(safePointSQL, time.Now().Add(-time.Hour).Format(gcTimeFormat))) + getDDLJobID := func(table, tp string) int64 { + rs, err := tk.Exec("admin show ddl jobs") + require.NoError(t, err) + rows, err := session.GetRows4Test(context.Background(), tk.Session(), rs) + require.NoError(t, err) + for _, row := range rows { + if row.GetString(2) == table && row.GetString(3) == tp { + return row.GetInt64(0) + } + } + require.FailNowf(t, "can't find %s table of %s", tp, table) + return -1 + } + + // recover table + tk.MustExec("create table t_recover1 (t timestamp) TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("drop table t_recover1") + tk.MustExec("recover table t_recover1") + tk.MustQuery("show create table t_recover1").Check(testkit.Rows("t_recover1 CREATE TABLE `t_recover1` (\n `t` timestamp NULL DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`t` + INTERVAL 1 DAY */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + // recover table with job id + tk.MustExec("create table t_recover2 (t timestamp) TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("drop table t_recover2") + jobID := getDDLJobID("t_recover2", "drop table") + tk.MustExec(fmt.Sprintf("recover table BY JOB %d", jobID)) + tk.MustQuery("show create table t_recover2").Check(testkit.Rows("t_recover2 CREATE TABLE `t_recover2` (\n `t` timestamp NULL DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`t` + INTERVAL 1 DAY */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + // flashback table + tk.MustExec("create table t_recover3 (t timestamp) TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("drop table t_recover3") + tk.MustExec("flashback table t_recover3") + tk.MustQuery("show create table t_recover3").Check(testkit.Rows("t_recover3 CREATE TABLE `t_recover3` (\n `t` timestamp NULL DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`t` + INTERVAL 1 DAY */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + // flashback database + tk.MustExec("create database if not exists test_recover2") + tk.MustExec("create table test_recover2.t1 (t timestamp) TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("create table test_recover2.t2 (t timestamp) TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("drop database test_recover2") + tk.MustExec("flashback database test_recover2") + tk.MustQuery("show create table test_recover2.t1").Check(testkit.Rows("t1 CREATE TABLE `t1` (\n `t` timestamp NULL DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`t` + INTERVAL 1 DAY */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + tk.MustQuery("show create table test_recover2.t2").Check(testkit.Rows("t2 CREATE TABLE `t2` (\n `t` timestamp NULL DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`t` + INTERVAL 1 DAY */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) +} + func TestRecoverTableByJobID(t *testing.T) { store, _ := createMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) @@ -824,8 +889,11 @@ func TestAutoRandom(t *testing.T) { require.EqualError(t, err, dbterror.ErrInvalidAutoRandom.GenWithStackByArgs(fmt.Sprintf(errMsg, args...)).Error()) } - assertPKIsNotHandle := func(sql, errCol string) { - assertInvalidAutoRandomErr(sql, autoid.AutoRandomPKisNotHandleErrMsg, errCol) + assertNotFirstColPK := func(sql, errCol string) { + assertInvalidAutoRandomErr(sql, autoid.AutoRandomMustFirstColumnInPK, errCol) + } + assertNoClusteredPK := func(sql string) { + assertInvalidAutoRandomErr(sql, autoid.AutoRandomNoClusteredPKErrMsg) } assertAlterValue := func(sql string) { assertInvalidAutoRandomErr(sql, autoid.AutoRandomAlterErrMsg) @@ -868,36 +936,36 @@ func TestAutoRandom(t *testing.T) { tk.MustExec("drop table t") } - // Only bigint column can set auto_random + // Only bigint column can set auto_random. assertBigIntOnly("create table t (a char primary key auto_random(3), b int)", "char") assertBigIntOnly("create table t (a varchar(255) primary key auto_random(3), b int)", "varchar") assertBigIntOnly("create table t (a timestamp primary key auto_random(3), b int)", "timestamp") + assertBigIntOnly("create table t (a timestamp auto_random(3), b int, primary key (a, b) clustered)", "timestamp") - // PKIsHandle, but auto_random is defined on non-primary key. - assertPKIsNotHandle("create table t (a bigint auto_random (3) primary key, b bigint auto_random (3))", "b") - assertPKIsNotHandle("create table t (a bigint auto_random (3), b bigint auto_random(3), primary key(a))", "b") - assertPKIsNotHandle("create table t (a bigint auto_random (3), b bigint auto_random(3) primary key)", "a") + // Clustered, but auto_random is defined on non-primary key. + assertNotFirstColPK("create table t (a bigint auto_random (3) primary key, b bigint auto_random (3))", "b") + assertNotFirstColPK("create table t (a bigint auto_random (3), b bigint auto_random(3), primary key(a))", "b") + assertNotFirstColPK("create table t (a bigint auto_random (3), b bigint auto_random(3) primary key)", "a") + assertNotFirstColPK("create table t (a bigint auto_random, b bigint, primary key (b, a) clustered);", "a") - // PKIsNotHandle: no primary key. - assertPKIsNotHandle("create table t (a bigint auto_random(3), b int)", "a") - // PKIsNotHandle: primary key is not a single column. - assertPKIsNotHandle("create table t (a bigint auto_random(3), b bigint, primary key (a, b))", "a") - assertPKIsNotHandle("create table t (a bigint auto_random(3), b int, c char, primary key (a, c))", "a") + // No primary key. + assertNoClusteredPK("create table t (a bigint auto_random(3), b int)") - // PKIsNotHandle: nonclustered integer primary key. - assertPKIsNotHandle("create table t (a bigint auto_random(3) primary key nonclustered, b int)", "a") - assertPKIsNotHandle("create table t (a bigint auto_random(3) primary key nonclustered, b int)", "a") - assertPKIsNotHandle("create table t (a int, b bigint auto_random(3) primary key nonclustered)", "b") + // No clustered primary key. + assertNoClusteredPK("create table t (a bigint auto_random(3) primary key nonclustered, b int)") + assertNoClusteredPK("create table t (a int, b bigint auto_random(3) primary key nonclustered)") // Can not set auto_random along with auto_increment. assertWithAutoInc("create table t (a bigint auto_random(3) primary key auto_increment)") assertWithAutoInc("create table t (a bigint primary key auto_increment auto_random(3))") assertWithAutoInc("create table t (a bigint auto_increment primary key auto_random(3))") assertWithAutoInc("create table t (a bigint auto_random(3) auto_increment, primary key (a))") + assertWithAutoInc("create table t (a bigint auto_random(3) auto_increment, b int, primary key (a, b) clustered)") // Can not set auto_random along with default. assertDefault("create table t (a bigint auto_random primary key default 3)") assertDefault("create table t (a bigint auto_random(2) primary key default 5)") + assertDefault("create table t (a bigint auto_random(2) default 5, b int, primary key (a, b) clustered)") mustExecAndDrop("create table t (a bigint auto_random primary key)", func() { assertDefault("alter table t modify column a bigint auto_random default 3") assertDefault("alter table t alter column a set default 3") @@ -906,12 +974,14 @@ func TestAutoRandom(t *testing.T) { // Overflow data type max length. assertMaxOverflow("create table t (a bigint auto_random(64) primary key)", "a", 64) assertMaxOverflow("create table t (a bigint auto_random(16) primary key)", "a", 16) + assertMaxOverflow("create table t (a bigint auto_random(16), b int, primary key (a, b) clustered)", "a", 16) mustExecAndDrop("create table t (a bigint auto_random(5) primary key)", func() { assertMaxOverflow("alter table t modify a bigint auto_random(64)", "a", 64) assertMaxOverflow("alter table t modify a bigint auto_random(16)", "a", 16) }) assertNonPositive("create table t (a bigint auto_random(0) primary key)") + assertNonPositive("create table t (a bigint auto_random(0), b int, primary key (a, b) clustered)") tk.MustGetErrMsg("create table t (a bigint auto_random(-1) primary key)", `[parser:1064]You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 38 near "-1) primary key)" `) @@ -921,6 +991,8 @@ func TestAutoRandom(t *testing.T) { mustExecAndDrop("create table t (a bigint auto_random(15) primary key)") mustExecAndDrop("create table t (a bigint primary key auto_random(4))") mustExecAndDrop("create table t (a bigint auto_random(4), primary key (a))") + mustExecAndDrop("create table t (a bigint auto_random(3), b bigint, primary key (a, b) clustered)") + mustExecAndDrop("create table t (a bigint auto_random(3), b int, c char, primary key (a, c) clustered)") // Increase auto_random bits. mustExecAndDrop("create table t (a bigint auto_random(5) primary key)", func() { @@ -928,11 +1000,17 @@ func TestAutoRandom(t *testing.T) { tk.MustExec("alter table t modify a bigint auto_random(10)") tk.MustExec("alter table t modify a bigint auto_random(12)") }) + mustExecAndDrop("create table t (a bigint auto_random(5), b char(255), primary key (a, b) clustered)", func() { + tk.MustExec("alter table t modify a bigint auto_random(8)") + tk.MustExec("alter table t modify a bigint auto_random(10)") + tk.MustExec("alter table t modify a bigint auto_random(12)") + }) // Auto_random can occur multiple times like other column attributes. mustExecAndDrop("create table t (a bigint auto_random(3) auto_random(2) primary key)") mustExecAndDrop("create table t (a bigint, b bigint auto_random(3) primary key auto_random(2))") mustExecAndDrop("create table t (a bigint auto_random(1) auto_random(2) auto_random(3), primary key (a))") + mustExecAndDrop("create table t (a bigint auto_random(1) auto_random(2) auto_random(3), b int, primary key (a, b) clustered)") // Add/drop the auto_random attribute is not allowed. mustExecAndDrop("create table t (a bigint auto_random(3) primary key)", func() { @@ -943,6 +1021,10 @@ func TestAutoRandom(t *testing.T) { assertAlterValue("alter table t modify column c bigint") assertAlterValue("alter table t change column c d bigint") }) + mustExecAndDrop("create table t (a bigint, b char, c bigint auto_random(3), primary key(c, a) clustered)", func() { + assertAlterValue("alter table t modify column c bigint") + assertAlterValue("alter table t change column c d bigint") + }) mustExecAndDrop("create table t (a bigint primary key)", func() { assertOnlyChangeFromAutoIncPK("alter table t modify column a bigint auto_random(3)") }) @@ -970,6 +1052,9 @@ func TestAutoRandom(t *testing.T) { mustExecAndDrop("create table t (a bigint auto_random(10) primary key)", func() { assertDecreaseBitErr("alter table t modify column a bigint auto_random(1)") }) + mustExecAndDrop("create table t (a bigint auto_random(10), b int, primary key (a, b) clustered)", func() { + assertDecreaseBitErr("alter table t modify column a bigint auto_random(6)") + }) originStep := autoid.GetStep() autoid.SetStep(1) diff --git a/ddl/split_region.go b/ddl/split_region.go index 465e18ddc719d..ffbcb7439292d 100644 --- a/ddl/split_region.go +++ b/ddl/split_region.go @@ -31,7 +31,7 @@ import ( ) func splitPartitionTableRegion(ctx sessionctx.Context, store kv.SplittableStore, tbInfo *model.TableInfo, pi *model.PartitionInfo, scatter bool) { - // Max partition count is 4096, should we sample and just choose some of the partition to split? + // Max partition count is 8192, should we sample and just choose some partitions to split? regionIDs := make([]uint64, 0, len(pi.Definitions)) ctxWithTimeout, cancel := context.WithTimeout(context.Background(), ctx.GetSessionVars().GetSplitRegionTimeout()) defer cancel() @@ -42,11 +42,11 @@ func splitPartitionTableRegion(ctx sessionctx.Context, store kv.SplittableStore, } } else { for _, def := range pi.Definitions { - regionIDs = append(regionIDs, splitRecordRegion(ctxWithTimeout, store, def.ID, scatter)) + regionIDs = append(regionIDs, SplitRecordRegion(ctxWithTimeout, store, def.ID, scatter)) } } if scatter { - waitScatterRegionFinish(ctxWithTimeout, store, regionIDs...) + WaitScatterRegionFinish(ctxWithTimeout, store, regionIDs...) } } @@ -58,10 +58,10 @@ func splitTableRegion(ctx sessionctx.Context, store kv.SplittableStore, tbInfo * if shardingBits(tbInfo) > 0 && tbInfo.PreSplitRegions > 0 { regionIDs = preSplitPhysicalTableByShardRowID(ctxWithTimeout, store, tbInfo, tbInfo.ID, scatter) } else { - regionIDs = append(regionIDs, splitRecordRegion(ctxWithTimeout, store, tbInfo.ID, scatter)) + regionIDs = append(regionIDs, SplitRecordRegion(ctxWithTimeout, store, tbInfo.ID, scatter)) } if scatter { - waitScatterRegionFinish(ctxWithTimeout, store, regionIDs...) + WaitScatterRegionFinish(ctxWithTimeout, store, regionIDs...) } } @@ -117,7 +117,8 @@ func preSplitPhysicalTableByShardRowID(ctx context.Context, store kv.SplittableS return regionIDs } -func splitRecordRegion(ctx context.Context, store kv.SplittableStore, tableID int64, scatter bool) uint64 { +// SplitRecordRegion is to split region in store by table prefix. +func SplitRecordRegion(ctx context.Context, store kv.SplittableStore, tableID int64, scatter bool) uint64 { tableStartKey := tablecodec.GenTablePrefix(tableID) regionIDs, err := store.SplitRegions(ctx, [][]byte{tableStartKey}, scatter, &tableID) if err != nil { @@ -144,7 +145,8 @@ func splitIndexRegion(store kv.SplittableStore, tblInfo *model.TableInfo, scatte return regionIDs } -func waitScatterRegionFinish(ctx context.Context, store kv.SplittableStore, regionIDs ...uint64) { +// WaitScatterRegionFinish will block until all regions are scattered. +func WaitScatterRegionFinish(ctx context.Context, store kv.SplittableStore, regionIDs ...uint64) { for _, regionID := range regionIDs { err := store.WaitScatterRegionFinish(ctx, regionID, 0) if err != nil { diff --git a/ddl/stat.go b/ddl/stat.go index 24462f9bb141a..15be82d6719ae 100644 --- a/ddl/stat.go +++ b/ddl/stat.go @@ -15,6 +15,8 @@ package ddl import ( + "encoding/hex" + "github.com/pingcap/errors" "github.com/pingcap/tidb/sessionctx/variable" ) @@ -79,7 +81,7 @@ func (d *ddl) Stats(vars *variable.SessionVars) (map[string]interface{}, error) m[ddlJobSchemaID] = job.SchemaID m[ddlJobTableID] = job.TableID m[ddlJobSnapshotVer] = job.SnapshotVer - m[ddlJobReorgHandle] = tryDecodeToHandleString(ddlInfo.ReorgHandle) + m[ddlJobReorgHandle] = hex.EncodeToString(ddlInfo.ReorgHandle) m[ddlJobArgs] = job.Args return m, nil } diff --git a/ddl/stat_test.go b/ddl/stat_test.go index 67d64c7c6cfa5..4280c2254c40a 100644 --- a/ddl/stat_test.go +++ b/ddl/stat_test.go @@ -16,6 +16,7 @@ package ddl_test import ( "context" + "encoding/hex" "fmt" "strconv" "testing" @@ -24,15 +25,14 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/kv" - "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" + "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" @@ -42,13 +42,14 @@ func TestDDLStatsInfo(t *testing.T) { store, domain := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) d := domain.DDL() + tk := testkit.NewTestKit(t, store) + ctx := tk.Session() dbInfo, err := testSchemaInfo(store, "test_stat") require.NoError(t, err) - testCreateSchema(t, testkit.NewTestKit(t, store).Session(), d, dbInfo) + testCreateSchema(t, ctx, d, dbInfo) tblInfo, err := testTableInfo(store, "t", 2) require.NoError(t, err) - testCreateTable(t, testkit.NewTestKit(t, store).Session(), d, dbInfo, tblInfo) - ctx := testkit.NewTestKit(t, store).Session() + testCreateTable(t, ctx, d, dbInfo, tblInfo) err = sessiontxn.NewTxn(context.Background(), ctx) require.NoError(t, err) @@ -60,7 +61,7 @@ func TestDDLStatsInfo(t *testing.T) { require.NoError(t, err) _, err = m.AddRecord(ctx, types.MakeDatums(3, 3)) require.NoError(t, err) - ctx.StmtCommit() + ctx.StmtCommit(context.Background()) require.NoError(t, ctx.CommitTxn(context.Background())) job := buildCreateIdxJob(dbInfo, tblInfo, true, "idx", "c1") @@ -89,7 +90,11 @@ func TestDDLStatsInfo(t *testing.T) { varMap, err := d.Stats(nil) wg.Done() require.NoError(t, err) - require.Equal(t, "1", varMap[ddlJobReorgHandle]) + key, err := hex.DecodeString(varMap[ddlJobReorgHandle].(string)) + require.NoError(t, err) + _, h, err := tablecodec.DecodeRecordKey(key) + require.NoError(t, err) + require.Equal(t, h.IntValue(), int64(1)) } } } @@ -145,20 +150,13 @@ func TestGetDDLInfo(t *testing.T) { } func addDDLJobs(sess session.Session, txn kv.Transaction, job *model.Job) error { - if variable.EnableConcurrentDDL.Load() { - b, err := job.Encode(true) - if err != nil { - return err - } - _, err = sess.Execute(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), fmt.Sprintf("insert into mysql.tidb_ddl_job(job_id, reorg, schema_ids, table_ids, job_meta, type, processing) values (%d, %t, %s, %s, %s, %d, %t)", - job.ID, job.MayNeedReorg(), strconv.Quote(strconv.FormatInt(job.SchemaID, 10)), strconv.Quote(strconv.FormatInt(job.TableID, 10)), wrapKey2String(b), job.Type, false)) + b, err := job.Encode(true) + if err != nil { return err } - m := meta.NewMeta(txn) - if job.MayNeedReorg() { - return m.EnQueueDDLJob(job, meta.AddIndexJobListKey) - } - return m.EnQueueDDLJob(job) + _, err = sess.Execute(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), fmt.Sprintf("insert into mysql.tidb_ddl_job(job_id, reorg, schema_ids, table_ids, job_meta, type, processing) values (%d, %t, %s, %s, %s, %d, %t)", + job.ID, job.MayNeedReorg(), strconv.Quote(strconv.FormatInt(job.SchemaID, 10)), strconv.Quote(strconv.FormatInt(job.TableID, 10)), wrapKey2String(b), job.Type, false)) + return err } func wrapKey2String(key []byte) string { diff --git a/ddl/syncer/syncer.go b/ddl/syncer/syncer.go index b2285351f83ae..e28d3d4954ca0 100644 --- a/ddl/syncer/syncer.go +++ b/ddl/syncer/syncer.go @@ -262,7 +262,7 @@ func (s *schemaVersionSyncer) OwnerCheckAllVersions(ctx context.Context, jobID i // If MDL is enabled, updatedMap is used to check if all the servers report the least version. // updatedMap is initialed to record all the server in every loop. We delete a server from the map if it gets the metadata lock(the key version equal the given version. // updatedMap should be empty if all the servers get the metadata lock. - updatedMap := make(map[string]struct{}) + updatedMap := make(map[string]string) for { if util.IsContextDone(ctx) { // ctx is canceled or timeout. @@ -278,9 +278,23 @@ func (s *schemaVersionSyncer) OwnerCheckAllVersions(ctx context.Context, jobID i if err != nil { return err } - updatedMap = make(map[string]struct{}) + updatedMap = make(map[string]string) + instance2id := make(map[string]string) + + // Set updatedMap according to the serverInfos, and remove some invalid serverInfos. for _, info := range serverInfos { - updatedMap[info.ID] = struct{}{} + instance := fmt.Sprintf("%s:%d", info.IP, info.Port) + if id, ok := instance2id[instance]; ok { + if info.StartTimestamp > serverInfos[id].StartTimestamp { + // Replace it. + delete(updatedMap, id) + updatedMap[info.ID] = fmt.Sprintf("instance ip %s, port %d, id %s", info.IP, info.Port, info.ID) + instance2id[instance] = info.ID + } + } else { + updatedMap[info.ID] = fmt.Sprintf("instance ip %s, port %d, id %s", info.IP, info.Port, info.ID) + instance2id[instance] = info.ID + } } } @@ -315,6 +329,9 @@ func (s *schemaVersionSyncer) OwnerCheckAllVersions(ctx context.Context, jobID i } if len(updatedMap) > 0 { succ = false + for _, info := range updatedMap { + logutil.BgLogger().Info("[ddl] syncer check all versions, someone is not synced", zap.String("info", info), zap.Any("ddl id", jobID), zap.Any("ver", latestVer)) + } } } else { for _, kv := range resp.Kvs { @@ -337,17 +354,11 @@ func (s *schemaVersionSyncer) OwnerCheckAllVersions(ctx context.Context, jobID i notMatchVerCnt++ break } - updatedMap[string(kv.Key)] = struct{}{} + updatedMap[string(kv.Key)] = "" } } if succ { - if variable.EnableMDL.Load() { - _, err = s.etcdCli.Delete(ctx, path, clientv3.WithPrefix()) - if err != nil { - logutil.BgLogger().Warn("[ddl] syncer delete versions failed", zap.Any("job id", jobID), zap.Error(err)) - } - } return nil } time.Sleep(checkVersInterval) diff --git a/ddl/table.go b/ddl/table.go index 001f5e26702ee..e867bd832c102 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -301,6 +301,7 @@ func onCreateView(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) if oldTbInfoID > 0 && orReplace { err = t.DropTableOrView(schemaID, oldTbInfoID) if err != nil { + job.State = model.JobStateCancelled return ver, errors.Trace(err) } err = t.GetAutoIDAccessors(schemaID, oldTbInfoID).Del() @@ -372,7 +373,7 @@ func onDropTableOrView(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ er } } if tblInfo.TiFlashReplica != nil { - e := infosync.DeleteTiFlashTableSyncProgress(tblInfo.ID) + e := infosync.DeleteTiFlashTableSyncProgress(tblInfo) if e != nil { logutil.BgLogger().Error("DeleteTiFlashTableSyncProgress fails", zap.Error(e)) } @@ -391,25 +392,24 @@ func onDropTableOrView(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ er return ver, errors.Trace(err) } -const ( - recoverTableCheckFlagNone int64 = iota - recoverTableCheckFlagEnableGC - recoverTableCheckFlagDisableGC -) - func (w *worker) onRecoverTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, err error) { - schemaID := job.SchemaID - tblInfo := &model.TableInfo{} - var autoIncID, autoRandID, dropJobID, recoverTableCheckFlag int64 - var snapshotTS uint64 - var oldTableName, oldSchemaName string - const checkFlagIndexInJobArgs = 4 // The index of `recoverTableCheckFlag` in job arg list. - if err = job.DecodeArgs(tblInfo, &autoIncID, &dropJobID, &snapshotTS, &recoverTableCheckFlag, &autoRandID, &oldSchemaName, &oldTableName); err != nil { + var ( + recoverInfo *RecoverInfo + recoverTableCheckFlag int64 + ) + if err = job.DecodeArgs(&recoverInfo, &recoverTableCheckFlag); err != nil { // Invalid arguments, cancel this job. job.State = model.JobStateCancelled return ver, errors.Trace(err) } + schemaID := recoverInfo.SchemaID + tblInfo := recoverInfo.TableInfo + if tblInfo.TTLInfo != nil { + // force disable TTL job schedule for recovered table + tblInfo.TTLInfo.Enable = false + } + // check GC and safe point gcEnable, err := checkGCEnable(w) if err != nil { @@ -454,9 +454,9 @@ func (w *worker) onRecoverTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver in // none -> write only // check GC enable and update flag. if gcEnable { - job.Args[checkFlagIndexInJobArgs] = recoverTableCheckFlagEnableGC + job.Args[checkFlagIndexInJobArgs] = recoverCheckFlagEnableGC } else { - job.Args[checkFlagIndexInJobArgs] = recoverTableCheckFlagDisableGC + job.Args[checkFlagIndexInJobArgs] = recoverCheckFlagDisableGC } // Clear all placement when recover @@ -479,56 +479,22 @@ func (w *worker) onRecoverTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver in } } // check GC safe point - err = checkSafePoint(w, snapshotTS) + err = checkSafePoint(w, recoverInfo.SnapshotTS) if err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } - // Remove dropped table DDL job from gc_delete_range table. - var tids []int64 - if tblInfo.GetPartitionInfo() != nil { - tids = getPartitionIDs(tblInfo) - } else { - tids = []int64{tblInfo.ID} - } - - tableRuleID, partRuleIDs, oldRuleIDs, oldRules, err := getOldLabelRules(tblInfo, oldSchemaName, oldTableName) - if err != nil { - job.State = model.JobStateCancelled - return ver, errors.Wrapf(err, "failed to get old label rules from PD") - } - - err = w.delRangeManager.removeFromGCDeleteRange(w.ctx, dropJobID) + ver, err = w.recoverTable(t, job, recoverInfo) if err != nil { return ver, errors.Trace(err) } - tableInfo := tblInfo.Clone() tableInfo.State = model.StatePublic tableInfo.UpdateTS = t.StartTS - err = t.CreateTableAndSetAutoID(schemaID, tableInfo, autoIncID, autoRandID) - if err != nil { - return ver, errors.Trace(err) - } - - failpoint.Inject("mockRecoverTableCommitErr", func(val failpoint.Value) { - if val.(bool) && atomic.CompareAndSwapUint32(&mockRecoverTableCommitErrOnce, 0, 1) { - _ = failpoint.Enable(`tikvclient/mockCommitErrorOpt`, "return(true)") - } - }) - - err = updateLabelRules(job, tblInfo, oldRules, tableRuleID, partRuleIDs, oldRuleIDs, tblInfo.ID) - if err != nil { - job.State = model.JobStateCancelled - return ver, errors.Wrapf(err, "failed to update the label rule to PD") - } - - job.CtxVars = []interface{}{tids} ver, err = updateVersionAndTableInfo(d, t, job, tableInfo, true) if err != nil { return ver, errors.Trace(err) } - tblInfo.State = model.StatePublic tblInfo.UpdateTS = t.StartTS // Finish this job. @@ -539,6 +505,47 @@ func (w *worker) onRecoverTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver in return ver, nil } +func (w *worker) recoverTable(t *meta.Meta, job *model.Job, recoverInfo *RecoverInfo) (ver int64, err error) { + var tids []int64 + if recoverInfo.TableInfo.GetPartitionInfo() != nil { + tids = getPartitionIDs(recoverInfo.TableInfo) + tids = append(tids, recoverInfo.TableInfo.ID) + } else { + tids = []int64{recoverInfo.TableInfo.ID} + } + tableRuleID, partRuleIDs, oldRuleIDs, oldRules, err := getOldLabelRules(recoverInfo.TableInfo, recoverInfo.OldSchemaName, recoverInfo.OldTableName) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Wrapf(err, "failed to get old label rules from PD") + } + // Remove dropped table DDL job from gc_delete_range table. + err = w.delRangeManager.removeFromGCDeleteRange(w.ctx, recoverInfo.DropJobID) + if err != nil { + return ver, errors.Trace(err) + } + tableInfo := recoverInfo.TableInfo.Clone() + tableInfo.State = model.StatePublic + tableInfo.UpdateTS = t.StartTS + err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, tableInfo, recoverInfo.AutoIDs.RowID, recoverInfo.AutoIDs.RandomID) + if err != nil { + return ver, errors.Trace(err) + } + + failpoint.Inject("mockRecoverTableCommitErr", func(val failpoint.Value) { + if val.(bool) && atomic.CompareAndSwapUint32(&mockRecoverTableCommitErrOnce, 0, 1) { + err = failpoint.Enable(`tikvclient/mockCommitErrorOpt`, "return(true)") + } + }) + + err = updateLabelRules(job, recoverInfo.TableInfo, oldRules, tableRuleID, partRuleIDs, oldRuleIDs, recoverInfo.TableInfo.ID) + if err != nil { + job.State = model.JobStateCancelled + return ver, errors.Wrapf(err, "failed to update the label rule to PD") + } + job.CtxVars = []interface{}{tids} + return ver, nil +} + func clearTablePlacementAndBundles(tblInfo *model.TableInfo) error { var bundles []*placement.Bundle if tblInfo.PlacementPolicyRef != nil { @@ -708,6 +715,14 @@ func onTruncateTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ erro } }) + // Clear the TiFlash replica progress from ETCD. + if tblInfo.TiFlashReplica != nil { + e := infosync.DeleteTiFlashTableSyncProgress(tblInfo) + if e != nil { + logutil.BgLogger().Error("DeleteTiFlashTableSyncProgress fails", zap.Error(e)) + } + } + var oldPartitionIDs []int64 if tblInfo.GetPartitionInfo() != nil { oldPartitionIDs = getPartitionIDs(tblInfo) @@ -747,10 +762,6 @@ func onTruncateTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ erro // Clear the TiFlash replica available status. if tblInfo.TiFlashReplica != nil { - e := infosync.DeleteTiFlashTableSyncProgress(tblInfo.ID) - if e != nil { - logutil.BgLogger().Error("DeleteTiFlashTableSyncProgress fails", zap.Error(e)) - } // Set PD rules for TiFlash if pi := tblInfo.GetPartitionInfo(); pi != nil { if e := infosync.ConfigureTiFlashPDForPartitions(true, &pi.Definitions, tblInfo.TiFlashReplica.Count, &tblInfo.TiFlashReplica.LocationLabels, tblInfo.ID); e != nil { @@ -807,8 +818,8 @@ func onTruncateTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ erro return ver, nil } -func onRebaseRowIDType(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { - return onRebaseAutoID(d, d.store, t, job, autoid.RowIDAllocType) +func onRebaseAutoIncrementIDType(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { + return onRebaseAutoID(d, d.store, t, job, autoid.AutoIncrementType) } func onRebaseAutoRandomType(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) { @@ -857,7 +868,7 @@ func onRebaseAutoID(d *ddlCtx, store kv.Storage, t *meta.Meta, job *model.Job, t newBase = newBaseTemp } - if tp == autoid.RowIDAllocType { + if tp == autoid.AutoIncrementType { tblInfo.AutoIncID = newBase } else { tblInfo.AutoRandID = newBase @@ -1270,6 +1281,12 @@ func (w *worker) onSetTableFlashReplica(d *ddlCtx, t *meta.Meta, job *model.Job) Available: available, } } else { + if tblInfo.TiFlashReplica != nil { + err = infosync.DeleteTiFlashTableSyncProgress(tblInfo) + if err != nil { + logutil.BgLogger().Error("DeleteTiFlashTableSyncProgress fails", zap.Error(err)) + } + } tblInfo.TiFlashReplica = nil } @@ -1330,6 +1347,7 @@ func onUpdateFlashReplicaStatus(d *ddlCtx, t *meta.Meta, job *model.Job) (ver in newIDs = append(newIDs, tblInfo.TiFlashReplica.AvailablePartitionIDs[i+1:]...) tblInfo.TiFlashReplica.AvailablePartitionIDs = newIDs tblInfo.TiFlashReplica.Available = false + logutil.BgLogger().Info("TiFlash replica become unavailable", zap.Int64("tableID", tblInfo.ID), zap.Int64("partitionID", id)) break } } @@ -1339,6 +1357,9 @@ func onUpdateFlashReplicaStatus(d *ddlCtx, t *meta.Meta, job *model.Job) (ver in return ver, errors.Errorf("unknown physical ID %v in table %v", physicalID, tblInfo.Name.O) } + if tblInfo.TiFlashReplica.Available { + logutil.BgLogger().Info("TiFlash replica available", zap.Int64("tableID", tblInfo.ID)) + } ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) if err != nil { return ver, errors.Trace(err) diff --git a/ddl/table_modify_test.go b/ddl/table_modify_test.go index f4b273771fd46..590fea8ad973d 100644 --- a/ddl/table_modify_test.go +++ b/ddl/table_modify_test.go @@ -117,7 +117,6 @@ func TestLockTableReadOnly(t *testing.T) { tk1 := testkit.NewTestKit(t, store) tk2 := testkit.NewTestKit(t, store) tk1.MustExec("use test") - tk1.MustExec("set global tidb_enable_metadata_lock=0") tk2.MustExec("use test") tk1.MustExec("drop table if exists t1,t2") defer func() { @@ -162,17 +161,6 @@ func TestLockTableReadOnly(t *testing.T) { require.True(t, terror.ErrorEqual(tk2.ExecToErr("lock tables t1 write local"), infoschema.ErrTableLocked)) tk1.MustExec("admin cleanup table lock t1") tk2.MustExec("insert into t1 set a=1, b=2") - - tk1.MustExec("set tidb_enable_amend_pessimistic_txn = 1") - tk1.MustExec("begin pessimistic") - tk1.MustQuery("select * from t1 where a = 1").Check(testkit.Rows("1 2")) - tk2.MustExec("update t1 set b = 3") - tk2.MustExec("alter table t1 read only") - tk2.MustQuery("select * from t1 where a = 1").Check(testkit.Rows("1 3")) - tk1.MustQuery("select * from t1 where a = 1").Check(testkit.Rows("1 2")) - tk1.MustExec("update t1 set b = 4") - require.True(t, terror.ErrorEqual(tk1.ExecToErr("commit"), domain.ErrInfoSchemaChanged)) - tk2.MustExec("alter table t1 read write") } // TestConcurrentLockTables test concurrent lock/unlock tables. diff --git a/ddl/table_test.go b/ddl/table_test.go index a9320e01cc781..cf7fdbf1cd7af 100644 --- a/ddl/table_test.go +++ b/ddl/table_test.go @@ -24,7 +24,9 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/meta/autoid" + "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/table" @@ -158,7 +160,7 @@ func testGetTableWithError(store kv.Storage, schemaID, tableID int64) (table.Tab return nil, errors.New("table not found") } alloc := autoid.NewAllocator(store, schemaID, tblInfo.ID, false, autoid.RowIDAllocType) - tbl, err := table.TableFromMeta(autoid.NewAllocators(alloc), tblInfo) + tbl, err := table.TableFromMeta(autoid.NewAllocators(false, alloc), tblInfo) if err != nil { return nil, errors.Trace(err) } @@ -235,6 +237,79 @@ func TestTable(t *testing.T) { testDropSchema(t, testkit.NewTestKit(t, store).Session(), d, dbInfo) } +func TestCreateView(t *testing.T) { + store, domain := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) + + d := domain.DDL() + dbInfo, err := testSchemaInfo(store, "test_table") + require.NoError(t, err) + testCreateSchema(t, testkit.NewTestKit(t, store).Session(), domain.DDL(), dbInfo) + + ctx := testkit.NewTestKit(t, store).Session() + + tblInfo, err := testTableInfo(store, "t", 3) + require.NoError(t, err) + job := testCreateTable(t, ctx, d, dbInfo, tblInfo) + testCheckTableState(t, store, dbInfo, tblInfo, model.StatePublic) + testCheckJobDone(t, store, job.ID, true) + + // Create a view + newTblInfo0, err := testTableInfo(store, "v", 3) + require.NoError(t, err) + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionCreateView, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{newTblInfo0}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + err = d.DoDDLJob(ctx, job) + require.NoError(t, err) + + v := getSchemaVer(t, ctx) + tblInfo.State = model.StatePublic + checkHistoryJobArgs(t, ctx, job.ID, &historyJobArgs{ver: v, tbl: newTblInfo0}) + tblInfo.State = model.StateNone + testCheckTableState(t, store, dbInfo, tblInfo, model.StatePublic) + testCheckJobDone(t, store, job.ID, true) + + // Replace a view + newTblInfo1, err := testTableInfo(store, "v", 3) + require.NoError(t, err) + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionCreateView, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{newTblInfo1, true, newTblInfo0.ID}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + err = d.DoDDLJob(ctx, job) + require.NoError(t, err) + + v = getSchemaVer(t, ctx) + tblInfo.State = model.StatePublic + checkHistoryJobArgs(t, ctx, job.ID, &historyJobArgs{ver: v, tbl: newTblInfo1}) + tblInfo.State = model.StateNone + testCheckTableState(t, store, dbInfo, tblInfo, model.StatePublic) + testCheckJobDone(t, store, job.ID, true) + + // Replace a view with a non-existing table id + newTblInfo2, err := testTableInfo(store, "v", 3) + require.NoError(t, err) + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionCreateView, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{newTblInfo2, true, newTblInfo0.ID}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + err = d.DoDDLJob(ctx, job) + require.Error(t, err) +} + func checkTableCacheTest(t *testing.T, store kv.Storage, dbInfo *model.DBInfo, tblInfo *model.TableInfo) { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL) require.NoError(t, kv.RunInNewTxn(ctx, store, false, func(ctx context.Context, txn kv.Transaction) error { @@ -371,3 +446,82 @@ func TestCreateTables(t *testing.T) { testGetTable(t, domain, genIDs[1]) testGetTable(t, domain, genIDs[2]) } + +func TestAlterTTL(t *testing.T) { + store, domain := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) + + d := domain.DDL() + + dbInfo, err := testSchemaInfo(store, "test_table") + require.NoError(t, err) + testCreateSchema(t, testkit.NewTestKit(t, store).Session(), d, dbInfo) + + ctx := testkit.NewTestKit(t, store).Session() + + // initialize a table with ttlInfo + tableName := "t" + tblInfo, err := testTableInfo(store, tableName, 2) + require.NoError(t, err) + tblInfo.Columns[0].FieldType = *types.NewFieldType(mysql.TypeDatetime) + tblInfo.Columns[1].FieldType = *types.NewFieldType(mysql.TypeDatetime) + tblInfo.TTLInfo = &model.TTLInfo{ + ColumnName: tblInfo.Columns[0].Name, + IntervalExprStr: "5", + IntervalTimeUnit: int(ast.TimeUnitDay), + } + + // create table + job := testCreateTable(t, ctx, d, dbInfo, tblInfo) + testCheckTableState(t, store, dbInfo, tblInfo, model.StatePublic) + testCheckJobDone(t, store, job.ID, true) + + // submit ddl job to modify ttlInfo + tableInfoAfterAlterTTLInfo := tblInfo.Clone() + require.NoError(t, err) + tableInfoAfterAlterTTLInfo.TTLInfo = &model.TTLInfo{ + ColumnName: tblInfo.Columns[1].Name, + IntervalExprStr: "1", + IntervalTimeUnit: int(ast.TimeUnitYear), + } + + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionAlterTTLInfo, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{&model.TTLInfo{ + ColumnName: tblInfo.Columns[1].Name, + IntervalExprStr: "1", + IntervalTimeUnit: int(ast.TimeUnitYear), + }}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + require.NoError(t, d.DoDDLJob(ctx, job)) + + v := getSchemaVer(t, ctx) + checkHistoryJobArgs(t, ctx, job.ID, &historyJobArgs{ver: v, tbl: nil}) + + // assert the ddlInfo as expected + historyJob, err := ddl.GetHistoryJobByID(testkit.NewTestKit(t, store).Session(), job.ID) + require.NoError(t, err) + require.Equal(t, tableInfoAfterAlterTTLInfo.TTLInfo, historyJob.BinlogInfo.TableInfo.TTLInfo) + + // submit a ddl job to modify ttlEnabled + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionAlterTTLRemove, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{true}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + require.NoError(t, d.DoDDLJob(ctx, job)) + + v = getSchemaVer(t, ctx) + checkHistoryJobArgs(t, ctx, job.ID, &historyJobArgs{ver: v, tbl: nil}) + + // assert the ddlInfo as expected + historyJob, err = ddl.GetHistoryJobByID(testkit.NewTestKit(t, store).Session(), job.ID) + require.NoError(t, err) + require.Empty(t, historyJob.BinlogInfo.TableInfo.TTLInfo) +} diff --git a/ddl/tiflash_replica_test.go b/ddl/tiflash_replica_test.go index d43cc0947b24f..c66061ad64b3b 100644 --- a/ddl/tiflash_replica_test.go +++ b/ddl/tiflash_replica_test.go @@ -18,12 +18,14 @@ import ( "context" "fmt" "math" + "net" "strings" "sync" "testing" "time" "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/errno" @@ -31,10 +33,13 @@ import ( "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/server" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/external" + "github.com/pingcap/tidb/util" "github.com/stretchr/testify/require" + "google.golang.org/grpc" ) const tiflashReplicaLease = 600 * time.Millisecond @@ -138,6 +143,44 @@ func TestSetTableFlashReplica(t *testing.T) { tk.MustGetErrMsg("alter table t_flash set tiflash replica 2 location labels 'a','b';", "the tiflash replica count: 2 should be less than the total tiflash server count: 0") } +// setUpRPCService setup grpc server to handle cop request for test. +func setUpRPCService(t *testing.T, addr string, dom *domain.Domain, sm util.SessionManager) (*grpc.Server, string) { + lis, err := net.Listen("tcp", addr) + require.NoError(t, err) + srv := server.NewRPCServer(config.GetGlobalConfig(), dom, sm) + port := lis.Addr().(*net.TCPAddr).Port + addr = fmt.Sprintf("127.0.0.1:%d", port) + go func() { + err = srv.Serve(lis) + require.NoError(t, err) + }() + config.UpdateGlobal(func(conf *config.Config) { + conf.Status.StatusPort = uint(port) + }) + return srv, addr +} + +func TestInfoSchemaForTiFlashReplica(t *testing.T) { + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/infoschema/mockTiFlashStoreCount", `return(true)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/infoschema/mockTiFlashStoreCount")) + }() + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + rpcserver, _ := setUpRPCService(t, "127.0.0.1:0", domain.GetDomain(tk.Session()), nil) + defer rpcserver.Stop() + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (a int, b int, index idx(a))") + tk.MustExec("alter table t set tiflash replica 2 location labels 'a','b';") + tk.MustQuery("select TABLE_SCHEMA,TABLE_NAME,REPLICA_COUNT,LOCATION_LABELS,AVAILABLE,PROGRESS from information_schema.tiflash_replica").Check(testkit.Rows("test t 2 a,b 0 0")) + tbl, err := domain.GetDomain(tk.Session()).InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + tbl.Meta().TiFlashReplica.Available = true + tk.MustQuery("select TABLE_SCHEMA,TABLE_NAME,REPLICA_COUNT,LOCATION_LABELS,AVAILABLE,PROGRESS from information_schema.tiflash_replica").Check(testkit.Rows("test t 2 a,b 1 0")) +} + func TestSetTiFlashReplicaForTemporaryTable(t *testing.T) { // test for tiflash replica require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/infoschema/mockTiFlashStoreCount", `return(true)`)) @@ -146,8 +189,9 @@ func TestSetTiFlashReplicaForTemporaryTable(t *testing.T) { }() store := testkit.CreateMockStoreWithSchemaLease(t, tiflashReplicaLease) - tk := testkit.NewTestKit(t, store) + rpcserver, _ := setUpRPCService(t, "127.0.0.1:0", domain.GetDomain(tk.Session()), nil) + defer rpcserver.Stop() tk.MustExec("use test") tk.MustExec("create global temporary table temp(id int) on commit delete rows") tk.MustExec("create temporary table temp2(id int)") @@ -259,7 +303,7 @@ func TestCreateTableWithLike2(t *testing.T) { } onceChecker.Store(job.ID, true) - go backgroundExec(store, "create table t2 like t1", doneCh) + go backgroundExec(store, "test", "create table t2 like t1", doneCh) } } originalHook := dom.DDL().GetHook() diff --git a/ddl/tiflashtest/BUILD.bazel b/ddl/tiflashtest/BUILD.bazel new file mode 100644 index 0000000000000..2a803cf03c5af --- /dev/null +++ b/ddl/tiflashtest/BUILD.bazel @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "tiflashtest_test", + srcs = [ + "ddl_tiflash_test.go", + "main_test.go", + ], + flaky = True, + deps = [ + "//config", + "//ddl", + "//ddl/placement", + "//ddl/util", + "//domain", + "//domain/infosync", + "//kv", + "//parser/model", + "//session", + "//store/gcworker", + "//store/mockstore", + "//store/mockstore/unistore", + "//table", + "//testkit", + "//testkit/testsetup", + "//util", + "//util/logutil", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_kvproto//pkg/metapb", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//oracle", + "@com_github_tikv_client_go_v2//testutils", + "@org_uber_go_goleak//:goleak", + "@org_uber_go_zap//:zap", + ], +) diff --git a/ddl/ddl_tiflash_test.go b/ddl/tiflashtest/ddl_tiflash_test.go similarity index 83% rename from ddl/ddl_tiflash_test.go rename to ddl/tiflashtest/ddl_tiflash_test.go index ec1afd9300107..d1d0368138b18 100644 --- a/ddl/ddl_tiflash_test.go +++ b/ddl/tiflashtest/ddl_tiflash_test.go @@ -16,7 +16,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSES/QL-LICENSE file. -package ddl_test +package tiflashtest import ( "context" @@ -42,12 +42,11 @@ import ( "github.com/pingcap/tidb/store/mockstore/unistore" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/testkit" - "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/logutil" "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/oracle" "github.com/tikv/client-go/v2/testutils" - "go.etcd.io/etcd/tests/v3/integration" "go.uber.org/zap" ) @@ -128,10 +127,6 @@ func ChangeGCSafePoint(tk *testkit.TestKit, t time.Time, enable string, lifeTime tk.MustExec(s) } -func CheckPlacementRule(tiflash *infosync.MockTiFlash, rule placement.TiFlashRule) bool { - return tiflash.CheckPlacementRule(rule) -} - func (s *tiflashContext) CheckFlashback(tk *testkit.TestKit, t *testing.T) { // If table is dropped after tikv_gc_safe_point, it can be recovered ChangeGCSafePoint(tk, time.Now().Add(-time.Hour), "false", "10m0s") @@ -444,6 +439,44 @@ func TestTiFlashDropPartition(t *testing.T) { CheckTableAvailableWithTableName(s.dom, t, 1, []string{}, "test", "ddltiflash") } +func TestTiFlashFlashbackCluster(t *testing.T) { + s, teardown := createTiFlashContext(t) + defer teardown() + tk := testkit.NewTestKit(t, s.store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int)") + tk.MustExec("insert into t values (1), (2), (3)") + + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("alter table t set tiflash replica 1") + time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable) + CheckTableAvailableWithTableName(s.dom, t, 1, []string{}, "test", "t") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(10 * time.Second)) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/mockFlashbackTest", `return(true)`)) + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + + ChangeGCSafePoint(tk, time.Now().Add(-10*time.Second), "true", "10m0s") + defer func() { + ChangeGCSafePoint(tk, time.Now(), "true", "10m0s") + }() + + errorMsg := fmt.Sprintf("[ddl:-1]Detected unsupported DDL job type(%s) during [%s, now), can't do flashback", + model.ActionSetTiFlashReplica.String(), oracle.GetTimeFromTS(ts).String()) + tk.MustGetErrMsg(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts)), errorMsg) + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockFlashbackTest")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) +} + func CheckTableAvailableWithTableName(dom *domain.Domain, t *testing.T, count uint64, labels []string, db string, table string) { tb, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) require.NoError(t, err) @@ -526,7 +559,7 @@ func TestSetPlacementRuleNormal(t *testing.T) { tb, err := s.dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ddltiflash")) require.NoError(t, err) expectRule := infosync.MakeNewRule(tb.Meta().ID, 1, []string{"a", "b"}) - res := CheckPlacementRule(s.tiflash, *expectRule) + res := s.tiflash.CheckPlacementRule(*expectRule) require.True(t, res) // Set lastSafePoint to a timepoint in future, so all dropped table can be reckon as gc-ed. @@ -538,7 +571,7 @@ func TestSetPlacementRuleNormal(t *testing.T) { defer fCancelPD() tk.MustExec("drop table ddltiflash") expectRule = infosync.MakeNewRule(tb.Meta().ID, 1, []string{"a", "b"}) - res = CheckPlacementRule(s.tiflash, *expectRule) + res = s.tiflash.CheckPlacementRule(*expectRule) require.True(t, res) } @@ -582,7 +615,7 @@ func TestSetPlacementRuleWithGCWorker(t *testing.T) { require.NoError(t, err) expectRule := infosync.MakeNewRule(tb.Meta().ID, 1, []string{"a", "b"}) - res := CheckPlacementRule(s.tiflash, *expectRule) + res := s.tiflash.CheckPlacementRule(*expectRule) require.True(t, res) ChangeGCSafePoint(tk, time.Now().Add(-time.Hour), "true", "10m0s") @@ -592,7 +625,7 @@ func TestSetPlacementRuleWithGCWorker(t *testing.T) { // Wait GC time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable) - res = CheckPlacementRule(s.tiflash, *expectRule) + res = s.tiflash.CheckPlacementRule(*expectRule) require.False(t, res) } @@ -613,7 +646,7 @@ func TestSetPlacementRuleFail(t *testing.T) { require.NoError(t, err) expectRule := infosync.MakeNewRule(tb.Meta().ID, 1, []string{}) - res := CheckPlacementRule(s.tiflash, *expectRule) + res := s.tiflash.CheckPlacementRule(*expectRule) require.False(t, res) } @@ -956,13 +989,6 @@ func TestTiFlashProgress(t *testing.T) { defer teardown() tk := testkit.NewTestKit(t, s.store) - integration.BeforeTest(t, integration.WithoutGoLeakDetection()) - cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) - defer cluster.Terminate(t) - - save := infosync.GetEtcdClient() - defer infosync.SetEtcdClient(save) - infosync.SetEtcdClient(cluster.Client(0)) tk.MustExec("create database tiflash_d") tk.MustExec("create table tiflash_d.t(z int)") tk.MustExec("alter table tiflash_d.t set tiflash replica 1") @@ -970,34 +996,79 @@ func TestTiFlashProgress(t *testing.T) { require.NoError(t, err) require.NotNil(t, tb) mustExist := func(tid int64) { - pm, err := infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - _, ok := pm[tb.Meta().ID] - require.True(t, ok) + _, isExist := infosync.GetTiFlashProgressFromCache(tid) + require.True(t, isExist) } mustAbsent := func(tid int64) { - pm, err := infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - _, ok := pm[tb.Meta().ID] - require.False(t, ok) + _, isExist := infosync.GetTiFlashProgressFromCache(tid) + require.False(t, isExist) } - _ = infosync.UpdateTiFlashTableSyncProgress(context.TODO(), tb.Meta().ID, "5.0") + infosync.UpdateTiFlashProgressCache(tb.Meta().ID, 5.0) mustExist(tb.Meta().ID) - _ = infosync.DeleteTiFlashTableSyncProgress(tb.Meta().ID) + _ = infosync.DeleteTiFlashTableSyncProgress(tb.Meta()) mustAbsent(tb.Meta().ID) - _ = infosync.UpdateTiFlashTableSyncProgress(context.TODO(), tb.Meta().ID, "5.0") + infosync.UpdateTiFlashProgressCache(tb.Meta().ID, 5.0) tk.MustExec("truncate table tiflash_d.t") mustAbsent(tb.Meta().ID) tb, _ = s.dom.InfoSchema().TableByName(model.NewCIStr("tiflash_d"), model.NewCIStr("t")) - _ = infosync.UpdateTiFlashTableSyncProgress(context.TODO(), tb.Meta().ID, "5.0") + infosync.UpdateTiFlashProgressCache(tb.Meta().ID, 5.0) + tk.MustExec("alter table tiflash_d.t set tiflash replica 0") + mustAbsent(tb.Meta().ID) + tk.MustExec("alter table tiflash_d.t set tiflash replica 1") + + tb, _ = s.dom.InfoSchema().TableByName(model.NewCIStr("tiflash_d"), model.NewCIStr("t")) + infosync.UpdateTiFlashProgressCache(tb.Meta().ID, 5.0) tk.MustExec("drop table tiflash_d.t") mustAbsent(tb.Meta().ID) time.Sleep(100 * time.Millisecond) } +func TestTiFlashProgressForPartitionTable(t *testing.T) { + s, teardown := createTiFlashContext(t) + s.tiflash.NotAvailable = true + defer teardown() + tk := testkit.NewTestKit(t, s.store) + + tk.MustExec("create database tiflash_d") + tk.MustExec("create table tiflash_d.t(z int) PARTITION BY RANGE(z) (PARTITION p0 VALUES LESS THAN (10))") + tk.MustExec("alter table tiflash_d.t set tiflash replica 1") + tb, err := s.dom.InfoSchema().TableByName(model.NewCIStr("tiflash_d"), model.NewCIStr("t")) + require.NoError(t, err) + require.NotNil(t, tb) + mustExist := func(tid int64) { + _, isExist := infosync.GetTiFlashProgressFromCache(tid) + require.True(t, isExist) + } + mustAbsent := func(tid int64) { + _, isExist := infosync.GetTiFlashProgressFromCache(tid) + require.False(t, isExist) + } + time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable) + mustExist(tb.Meta().Partition.Definitions[0].ID) + _ = infosync.DeleteTiFlashTableSyncProgress(tb.Meta()) + mustAbsent(tb.Meta().Partition.Definitions[0].ID) + + infosync.UpdateTiFlashProgressCache(tb.Meta().Partition.Definitions[0].ID, 5.0) + tk.MustExec("truncate table tiflash_d.t") + mustAbsent(tb.Meta().Partition.Definitions[0].ID) + + tb, _ = s.dom.InfoSchema().TableByName(model.NewCIStr("tiflash_d"), model.NewCIStr("t")) + infosync.UpdateTiFlashProgressCache(tb.Meta().Partition.Definitions[0].ID, 5.0) + tk.MustExec("alter table tiflash_d.t set tiflash replica 0") + mustAbsent(tb.Meta().Partition.Definitions[0].ID) + tk.MustExec("alter table tiflash_d.t set tiflash replica 1") + + tb, _ = s.dom.InfoSchema().TableByName(model.NewCIStr("tiflash_d"), model.NewCIStr("t")) + infosync.UpdateTiFlashProgressCache(tb.Meta().Partition.Definitions[0].ID, 5.0) + tk.MustExec("drop table tiflash_d.t") + mustAbsent(tb.Meta().Partition.Definitions[0].ID) + + time.Sleep(100 * time.Millisecond) +} + func TestTiFlashGroupIndexWhenStartup(t *testing.T) { s, teardown := createTiFlashContext(t) tiflash := s.tiflash @@ -1022,14 +1093,6 @@ func TestTiFlashProgressAfterAvailable(t *testing.T) { defer teardown() tk := testkit.NewTestKit(t, s.store) - integration.BeforeTest(t, integration.WithoutGoLeakDetection()) - cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) - defer cluster.Terminate(t) - - save := infosync.GetEtcdClient() - defer infosync.SetEtcdClient(save) - infosync.SetEtcdClient(cluster.Client(0)) - tk.MustExec("use test") tk.MustExec("drop table if exists ddltiflash") tk.MustExec("create table ddltiflash(z int)") @@ -1043,19 +1106,15 @@ func TestTiFlashProgressAfterAvailable(t *testing.T) { // after available, progress should can be updated. s.tiflash.ResetSyncStatus(int(tb.Meta().ID), false) time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) - pm, err := infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok := pm[tb.Meta().ID] - require.True(t, ok) - require.Equal(t, types.TruncateFloatToString(progress, 2), "0") + progress, isExist := infosync.GetTiFlashProgressFromCache(tb.Meta().ID) + require.True(t, isExist) + require.True(t, progress == 0) s.tiflash.ResetSyncStatus(int(tb.Meta().ID), true) time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) - pm, err = infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok = pm[tb.Meta().ID] - require.True(t, ok) - require.Equal(t, types.TruncateFloatToString(progress, 2), "1") + progress, isExist = infosync.GetTiFlashProgressFromCache(tb.Meta().ID) + require.True(t, isExist) + require.True(t, progress == 1) } func TestTiFlashProgressAfterAvailableForPartitionTable(t *testing.T) { @@ -1063,14 +1122,6 @@ func TestTiFlashProgressAfterAvailableForPartitionTable(t *testing.T) { defer teardown() tk := testkit.NewTestKit(t, s.store) - integration.BeforeTest(t, integration.WithoutGoLeakDetection()) - cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) - defer cluster.Terminate(t) - - save := infosync.GetEtcdClient() - defer infosync.SetEtcdClient(save) - infosync.SetEtcdClient(cluster.Client(0)) - tk.MustExec("use test") tk.MustExec("drop table if exists ddltiflash") tk.MustExec("create table ddltiflash(z int) PARTITION BY RANGE(z) (PARTITION p0 VALUES LESS THAN (10))") @@ -1084,19 +1135,15 @@ func TestTiFlashProgressAfterAvailableForPartitionTable(t *testing.T) { // after available, progress should can be updated. s.tiflash.ResetSyncStatus(int(tb.Meta().Partition.Definitions[0].ID), false) time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) - pm, err := infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok := pm[tb.Meta().Partition.Definitions[0].ID] - require.True(t, ok) - require.Equal(t, types.TruncateFloatToString(progress, 2), "0") + progress, isExist := infosync.GetTiFlashProgressFromCache(tb.Meta().Partition.Definitions[0].ID) + require.True(t, isExist) + require.True(t, progress == 0) s.tiflash.ResetSyncStatus(int(tb.Meta().Partition.Definitions[0].ID), true) time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) - pm, err = infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok = pm[tb.Meta().Partition.Definitions[0].ID] - require.True(t, ok) - require.Equal(t, types.TruncateFloatToString(progress, 2), "1") + progress, isExist = infosync.GetTiFlashProgressFromCache(tb.Meta().Partition.Definitions[0].ID) + require.True(t, isExist) + require.True(t, progress == 1) } func TestTiFlashProgressCache(t *testing.T) { @@ -1104,14 +1151,6 @@ func TestTiFlashProgressCache(t *testing.T) { defer teardown() tk := testkit.NewTestKit(t, s.store) - integration.BeforeTest(t, integration.WithoutGoLeakDetection()) - cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) - defer cluster.Terminate(t) - - save := infosync.GetEtcdClient() - defer infosync.SetEtcdClient(save) - infosync.SetEtcdClient(cluster.Client(0)) - tk.MustExec("use test") tk.MustExec("drop table if exists ddltiflash") tk.MustExec("create table ddltiflash(z int)") @@ -1122,26 +1161,12 @@ func TestTiFlashProgressCache(t *testing.T) { tb, err := s.dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ddltiflash")) require.NoError(t, err) require.NotNil(t, tb) - err = infosync.UpdateTiFlashTableSyncProgress(context.TODO(), tb.Meta().ID, "0") - require.NoError(t, err) - // after available, progress cache should be 1, so it will not update progress. - time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) - pm, err := infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok := pm[tb.Meta().ID] - require.True(t, ok) - require.Equal(t, types.TruncateFloatToString(progress, 2), "0") - // clean progress cache, and it will update progress - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/PollTiFlashReplicaStatusCleanProgressCache", `return`)) - defer func() { - _ = failpoint.Disable("github.com/pingcap/tidb/ddl/PollTiFlashReplicaStatusCleanProgressCache") - }() + infosync.UpdateTiFlashProgressCache(tb.Meta().ID, 0) + // after available, it will still update progress cache. time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) - pm, err = infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok = pm[tb.Meta().ID] - require.True(t, ok) - require.Equal(t, types.TruncateFloatToString(progress, 2), "1") + progress, isExist := infosync.GetTiFlashProgressFromCache(tb.Meta().ID) + require.True(t, isExist) + require.True(t, progress == 1) } func TestTiFlashProgressAvailableList(t *testing.T) { @@ -1149,14 +1174,6 @@ func TestTiFlashProgressAvailableList(t *testing.T) { defer teardown() tk := testkit.NewTestKit(t, s.store) - integration.BeforeTest(t, integration.WithoutGoLeakDetection()) - cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) - defer cluster.Terminate(t) - - save := infosync.GetEtcdClient() - defer infosync.SetEtcdClient(save) - infosync.SetEtcdClient(cluster.Client(0)) - tableCount := 8 tableNames := make([]string, tableCount) tbls := make([]table.Table, tableCount) @@ -1190,10 +1207,8 @@ func TestTiFlashProgressAvailableList(t *testing.T) { // Not all table have updated progress UpdatedTableCount := 0 for i := 0; i < tableCount; i++ { - pm, err := infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok := pm[tbls[i].Meta().ID] - require.True(t, ok) + progress, isExist := infosync.GetTiFlashProgressFromCache(tbls[i].Meta().ID) + require.True(t, isExist) if progress == 0 { UpdatedTableCount++ } @@ -1206,10 +1221,8 @@ func TestTiFlashProgressAvailableList(t *testing.T) { // All table have updated progress UpdatedTableCount = 0 for i := 0; i < tableCount; i++ { - pm, err := infosync.GetTiFlashTableSyncProgress(context.TODO()) - require.NoError(t, err) - progress, ok := pm[tbls[i].Meta().ID] - require.True(t, ok) + progress, isExist := infosync.GetTiFlashProgressFromCache(tbls[i].Meta().ID) + require.True(t, isExist) if progress == 0 { UpdatedTableCount++ } @@ -1243,3 +1256,81 @@ func TestTiFlashAvailableAfterResetReplica(t *testing.T) { require.NotNil(t, tb) require.Nil(t, tb.Meta().TiFlashReplica) } + +func TestTiFlashPartitionNotAvailable(t *testing.T) { + s, teardown := createTiFlashContext(t) + defer teardown() + tk := testkit.NewTestKit(t, s.store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists ddltiflash") + tk.MustExec("create table ddltiflash(z int) PARTITION BY RANGE(z) (PARTITION p0 VALUES LESS THAN (10))") + + tb, err := s.dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ddltiflash")) + require.NoError(t, err) + require.NotNil(t, tb) + + tk.MustExec("alter table ddltiflash set tiflash replica 1") + s.tiflash.ResetSyncStatus(int(tb.Meta().Partition.Definitions[0].ID), false) + time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) + + tb, err = s.dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ddltiflash")) + require.NoError(t, err) + require.NotNil(t, tb) + replica := tb.Meta().TiFlashReplica + require.NotNil(t, replica) + require.False(t, replica.Available) + + s.tiflash.ResetSyncStatus(int(tb.Meta().Partition.Definitions[0].ID), true) + time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) + + tb, err = s.dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ddltiflash")) + require.NoError(t, err) + require.NotNil(t, tb) + replica = tb.Meta().TiFlashReplica + require.NotNil(t, replica) + require.True(t, replica.Available) + + s.tiflash.ResetSyncStatus(int(tb.Meta().Partition.Definitions[0].ID), false) + time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) + require.NoError(t, err) + require.NotNil(t, tb) + replica = tb.Meta().TiFlashReplica + require.NotNil(t, replica) + require.True(t, replica.Available) +} + +func TestTiFlashAvailableAfterAddPartition(t *testing.T) { + s, teardown := createTiFlashContext(t) + defer teardown() + tk := testkit.NewTestKit(t, s.store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists ddltiflash") + tk.MustExec("create table ddltiflash(z int) PARTITION BY RANGE(z) (PARTITION p0 VALUES LESS THAN (10))") + tk.MustExec("alter table ddltiflash set tiflash replica 1") + time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) + CheckTableAvailable(s.dom, t, 1, []string{}) + + tb, err := s.dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ddltiflash")) + require.NoError(t, err) + require.NotNil(t, tb) + + // still available after adding partition. + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/sleepBeforeReplicaOnly", `return(2)`)) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/waitForAddPartition", `return(3)`)) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/PollTiFlashReplicaStatusReplaceCurAvailableValue", `return(false)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/sleepBeforeReplicaOnly")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/waitForAddPartition")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/PollTiFlashReplicaStatusReplaceCurAvailableValue")) + }() + tk.MustExec("ALTER TABLE ddltiflash ADD PARTITION (PARTITION pn VALUES LESS THAN (20))") + time.Sleep(ddl.PollTiFlashInterval * RoundToBeAvailable * 3) + CheckTableAvailable(s.dom, t, 1, []string{}) + tb, err = s.dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ddltiflash")) + require.NoError(t, err) + pi := tb.Meta().GetPartitionInfo() + require.NotNil(t, pi) + require.Equal(t, len(pi.Definitions), 2) +} diff --git a/ddl/concurrentddltest/main_test.go b/ddl/tiflashtest/main_test.go similarity index 83% rename from ddl/concurrentddltest/main_test.go rename to ddl/tiflashtest/main_test.go index d6b52492ddb07..68063ce27071b 100644 --- a/ddl/concurrentddltest/main_test.go +++ b/ddl/tiflashtest/main_test.go @@ -12,7 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -package concurrentddltest +// Copyright 2013 The ql Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSES/QL-LICENSE file. + +package tiflashtest import ( "testing" @@ -36,6 +40,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/ddl/ttl.go b/ddl/ttl.go new file mode 100644 index 0000000000000..58011ee9e79f9 --- /dev/null +++ b/ddl/ttl.go @@ -0,0 +1,234 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl + +import ( + "fmt" + "strings" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/meta" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/format" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessiontxn" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/dbterror" +) + +func onTTLInfoRemove(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, err error) { + tblInfo, err := GetTableInfoAndCancelFaultJob(t, job, job.SchemaID) + if err != nil { + return ver, errors.Trace(err) + } + + tblInfo.TTLInfo = nil + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo) + return ver, nil +} + +func onTTLInfoChange(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, err error) { + // at least one for them is not nil + var ttlInfo *model.TTLInfo + var ttlInfoEnable *bool + var ttlInfoJobInterval *string + + if err := job.DecodeArgs(&ttlInfo, &ttlInfoEnable, &ttlInfoJobInterval); err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + + tblInfo, err := GetTableInfoAndCancelFaultJob(t, job, job.SchemaID) + if err != nil { + return ver, errors.Trace(err) + } + + if ttlInfo != nil { + // if the TTL_ENABLE is not set explicitly, use the original value + if ttlInfoEnable == nil && tblInfo.TTLInfo != nil { + ttlInfo.Enable = tblInfo.TTLInfo.Enable + } + if ttlInfoJobInterval == nil && tblInfo.TTLInfo != nil { + ttlInfo.JobInterval = tblInfo.TTLInfo.JobInterval + } + tblInfo.TTLInfo = ttlInfo + } + if ttlInfoEnable != nil { + if tblInfo.TTLInfo == nil { + return ver, errors.Trace(dbterror.ErrSetTTLOptionForNonTTLTable.FastGenByArgs("TTL_ENABLE")) + } + + tblInfo.TTLInfo.Enable = *ttlInfoEnable + } + if ttlInfoJobInterval != nil { + if tblInfo.TTLInfo == nil { + return ver, errors.Trace(dbterror.ErrSetTTLOptionForNonTTLTable.FastGenByArgs("TTL_JOB_INTERVAL")) + } + + tblInfo.TTLInfo.JobInterval = *ttlInfoJobInterval + } + + ver, err = updateVersionAndTableInfo(d, t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo) + return ver, nil +} + +func checkTTLInfoValid(ctx sessionctx.Context, schema model.CIStr, tblInfo *model.TableInfo) error { + if err := checkTTLIntervalExpr(ctx, tblInfo.TTLInfo); err != nil { + return err + } + + if err := checkTTLTableSuitable(ctx, schema, tblInfo); err != nil { + return err + } + + return checkTTLInfoColumnType(tblInfo) +} + +func checkTTLIntervalExpr(ctx sessionctx.Context, ttlInfo *model.TTLInfo) error { + // FIXME: use a better way to validate the interval expression in ttl + var nowAddIntervalExpr ast.ExprNode + + unit := ast.TimeUnitType(ttlInfo.IntervalTimeUnit) + expr := fmt.Sprintf("select NOW() + INTERVAL %s %s", ttlInfo.IntervalExprStr, unit.String()) + stmts, _, err := parser.New().ParseSQL(expr) + if err != nil { + // FIXME: the error information can be wrong, as it could indicate an unknown position to user. + return errors.Trace(err) + } + nowAddIntervalExpr = stmts[0].(*ast.SelectStmt).Fields.Fields[0].Expr + _, err = expression.EvalAstExpr(ctx, nowAddIntervalExpr) + return err +} + +func checkTTLInfoColumnType(tblInfo *model.TableInfo) error { + colInfo := findColumnByName(tblInfo.TTLInfo.ColumnName.L, tblInfo) + if colInfo == nil { + return dbterror.ErrBadField.GenWithStackByArgs(tblInfo.TTLInfo.ColumnName.O, "TTL config") + } + if !types.IsTypeTime(colInfo.FieldType.GetType()) { + return dbterror.ErrUnsupportedColumnInTTLConfig.GenWithStackByArgs(tblInfo.TTLInfo.ColumnName.O) + } + + return nil +} + +// checkTTLTableSuitable returns whether this table is suitable to be a TTL table +// A temporary table or a parent table referenced by a foreign key cannot be TTL table +func checkTTLTableSuitable(ctx sessionctx.Context, schema model.CIStr, tblInfo *model.TableInfo) error { + if tblInfo.TempTableType != model.TempTableNone { + return dbterror.ErrTempTableNotAllowedWithTTL + } + + if err := checkPrimaryKeyForTTLTable(tblInfo); err != nil { + return err + } + + // checks even when the foreign key check is not enabled, to keep safe + is := sessiontxn.GetTxnManager(ctx).GetTxnInfoSchema() + if referredFK := checkTableHasForeignKeyReferred(is, schema.L, tblInfo.Name.L, nil, true); referredFK != nil { + return dbterror.ErrUnsupportedTTLReferencedByFK + } + + return nil +} + +func checkDropColumnWithTTLConfig(tblInfo *model.TableInfo, colName string) error { + if tblInfo.TTLInfo != nil { + if tblInfo.TTLInfo.ColumnName.L == colName { + return dbterror.ErrTTLColumnCannotDrop.GenWithStackByArgs(colName) + } + } + + return nil +} + +// We should forbid creating a TTL table with clustered primary key that contains a column with type float/double. +// This is because currently we are using SQL to delete expired rows and when the primary key contains float/double column, +// it is hard to use condition `WHERE PK in (...)` to delete specified rows because some precision will be lost when comparing. +func checkPrimaryKeyForTTLTable(tblInfo *model.TableInfo) error { + if !tblInfo.IsCommonHandle { + // only check the primary keys when it is common handle + return nil + } + + pk := tblInfo.GetPrimaryKey() + if pk == nil { + return nil + } + + for _, colDef := range pk.Columns { + col := tblInfo.Columns[colDef.Offset] + switch col.GetType() { + case mysql.TypeFloat, mysql.TypeDouble: + return dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL + } + } + + return nil +} + +// getTTLInfoInOptions returns the aggregated ttlInfo, the ttlEnable, or an error. +// if TTL, TTL_ENABLE or TTL_JOB_INTERVAL is not set in the config, the corresponding return value will be nil. +// if both of TTL and TTL_ENABLE are set, the `ttlInfo.Enable` will be equal with `ttlEnable`. +// if both of TTL and TTL_JOB_INTERVAL are set, the `ttlInfo.JobInterval` will be equal with `ttlCronJobSchedule`. +func getTTLInfoInOptions(options []*ast.TableOption) (ttlInfo *model.TTLInfo, ttlEnable *bool, ttlCronJobSchedule *string, err error) { + for _, op := range options { + switch op.Tp { + case ast.TableOptionTTL: + var sb strings.Builder + restoreFlags := format.RestoreStringSingleQuotes | format.RestoreNameBackQuotes + restoreCtx := format.NewRestoreCtx(restoreFlags, &sb) + err := op.Value.Restore(restoreCtx) + if err != nil { + return nil, nil, nil, err + } + + intervalExpr := sb.String() + ttlInfo = &model.TTLInfo{ + ColumnName: op.ColumnName.Name, + IntervalExprStr: intervalExpr, + IntervalTimeUnit: int(op.TimeUnitValue.Unit), + Enable: true, + JobInterval: "1h", + } + case ast.TableOptionTTLEnable: + ttlEnable = &op.BoolValue + case ast.TableOptionTTLJobInterval: + ttlCronJobSchedule = &op.StrValue + } + } + + if ttlInfo != nil { + if ttlEnable != nil { + ttlInfo.Enable = *ttlEnable + } + if ttlCronJobSchedule != nil { + ttlInfo.JobInterval = *ttlCronJobSchedule + } + } + return ttlInfo, ttlEnable, ttlCronJobSchedule, nil +} diff --git a/ddl/ttl_test.go b/ddl/ttl_test.go new file mode 100644 index 0000000000000..fafc9e240a710 --- /dev/null +++ b/ddl/ttl_test.go @@ -0,0 +1,150 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ddl + +import ( + "testing" + + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/model" + "github.com/stretchr/testify/assert" +) + +func Test_getTTLInfoInOptions(t *testing.T) { + falseValue := false + trueValue := true + twentyFourHours := "24h" + + cases := []struct { + options []*ast.TableOption + ttlInfo *model.TTLInfo + ttlEnable *bool + ttlCronJobSchedule *string + err error + }{ + { + []*ast.TableOption{}, + nil, + nil, + nil, + nil, + }, + { + []*ast.TableOption{ + { + Tp: ast.TableOptionTTL, + ColumnName: &ast.ColumnName{Name: model.NewCIStr("test_column")}, + Value: ast.NewValueExpr(5, "", ""), + TimeUnitValue: &ast.TimeUnitExpr{Unit: ast.TimeUnitYear}, + }, + }, + &model.TTLInfo{ + ColumnName: model.NewCIStr("test_column"), + IntervalExprStr: "5", + IntervalTimeUnit: int(ast.TimeUnitYear), + Enable: true, + JobInterval: "1h", + }, + nil, + nil, + nil, + }, + { + []*ast.TableOption{ + { + Tp: ast.TableOptionTTLEnable, + BoolValue: false, + }, + { + Tp: ast.TableOptionTTL, + ColumnName: &ast.ColumnName{Name: model.NewCIStr("test_column")}, + Value: ast.NewValueExpr(5, "", ""), + TimeUnitValue: &ast.TimeUnitExpr{Unit: ast.TimeUnitYear}, + }, + }, + &model.TTLInfo{ + ColumnName: model.NewCIStr("test_column"), + IntervalExprStr: "5", + IntervalTimeUnit: int(ast.TimeUnitYear), + Enable: false, + JobInterval: "1h", + }, + &falseValue, + nil, + nil, + }, + { + []*ast.TableOption{ + { + Tp: ast.TableOptionTTLEnable, + BoolValue: false, + }, + { + Tp: ast.TableOptionTTL, + ColumnName: &ast.ColumnName{Name: model.NewCIStr("test_column")}, + Value: ast.NewValueExpr(5, "", ""), + TimeUnitValue: &ast.TimeUnitExpr{Unit: ast.TimeUnitYear}, + }, + { + Tp: ast.TableOptionTTLEnable, + BoolValue: true, + }, + }, + &model.TTLInfo{ + ColumnName: model.NewCIStr("test_column"), + IntervalExprStr: "5", + IntervalTimeUnit: int(ast.TimeUnitYear), + Enable: true, + JobInterval: "1h", + }, + &trueValue, + nil, + nil, + }, + { + []*ast.TableOption{ + { + Tp: ast.TableOptionTTL, + ColumnName: &ast.ColumnName{Name: model.NewCIStr("test_column")}, + Value: ast.NewValueExpr(5, "", ""), + TimeUnitValue: &ast.TimeUnitExpr{Unit: ast.TimeUnitYear}, + }, + { + Tp: ast.TableOptionTTLJobInterval, + StrValue: "24h", + }, + }, + &model.TTLInfo{ + ColumnName: model.NewCIStr("test_column"), + IntervalExprStr: "5", + IntervalTimeUnit: int(ast.TimeUnitYear), + Enable: true, + JobInterval: "24h", + }, + nil, + &twentyFourHours, + nil, + }, + } + + for _, c := range cases { + ttlInfo, ttlEnable, ttlCronJobSchedule, err := getTTLInfoInOptions(c.options) + + assert.Equal(t, c.ttlInfo, ttlInfo) + assert.Equal(t, c.ttlEnable, ttlEnable) + assert.Equal(t, c.ttlCronJobSchedule, ttlCronJobSchedule) + assert.Equal(t, c.err, err) + } +} diff --git a/ddl/util/main_test.go b/ddl/util/main_test.go index a28cdcb4b5bfc..ae8004db124ba 100644 --- a/ddl/util/main_test.go +++ b/ddl/util/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/distsql/distsql.go b/distsql/distsql.go index 19c2d6e3edea4..3c65205f3d331 100644 --- a/distsql/distsql.go +++ b/distsql/distsql.go @@ -38,11 +38,11 @@ import ( ) // DispatchMPPTasks dispatches all tasks and returns an iterator. -func DispatchMPPTasks(ctx context.Context, sctx sessionctx.Context, tasks []*kv.MPPDispatchRequest, fieldTypes []*types.FieldType, planIDs []int, rootID int, startTs uint64) (SelectResult, error) { +func DispatchMPPTasks(ctx context.Context, sctx sessionctx.Context, tasks []*kv.MPPDispatchRequest, fieldTypes []*types.FieldType, planIDs []int, rootID int, startTs uint64, mppQueryID kv.MPPQueryID) (SelectResult, error) { ctx = WithSQLKvExecCounterInterceptor(ctx, sctx.GetSessionVars().StmtCtx) _, allowTiFlashFallback := sctx.GetSessionVars().AllowFallbackToTiKV[kv.TiFlash] ctx = SetTiFlashMaxThreadsInContext(ctx, sctx) - resp := sctx.GetMPPClient().DispatchMPPTasks(ctx, sctx.GetSessionVars().KVVars, tasks, allowTiFlashFallback, startTs) + resp := sctx.GetMPPClient().DispatchMPPTasks(ctx, sctx.GetSessionVars().KVVars, tasks, allowTiFlashFallback, startTs, mppQueryID) if resp == nil { return nil, errors.New("client returns nil response") } @@ -88,7 +88,7 @@ func Select(ctx context.Context, sctx sessionctx.Context, kvReq *kv.Request, fie ctx = WithSQLKvExecCounterInterceptor(ctx, sctx.GetSessionVars().StmtCtx) option := &kv.ClientSendOption{ - SessionMemTracker: sctx.GetSessionVars().StmtCtx.MemTracker, + SessionMemTracker: sctx.GetSessionVars().MemTracker, EnabledRateLimitAction: enabledRateLimitAction, EventCb: eventCb, EnableCollectExecutionInfo: config.GetGlobalConfig().Instance.EnableCollectExecutionInfo.Load(), diff --git a/distsql/distsql_test.go b/distsql/distsql_test.go index 52aa62ba112fa..f3988ea5f7c4d 100644 --- a/distsql/distsql_test.go +++ b/distsql/distsql_test.go @@ -107,7 +107,8 @@ func TestSelectWithRuntimeStats(t *testing.T) { } func TestSelectResultRuntimeStats(t *testing.T) { - basic := &execdetails.BasicRuntimeStats{} + stmtStats := execdetails.NewRuntimeStatsColl(nil) + basic := stmtStats.GetBasicRuntimeStats(1) basic.Record(time.Second, 20) s1 := &selectResultRuntimeStats{ copRespTime: []time.Duration{time.Second, time.Millisecond}, @@ -120,8 +121,6 @@ func TestSelectResultRuntimeStats(t *testing.T) { } s2 := *s1 - stmtStats := execdetails.NewRuntimeStatsColl(nil) - stmtStats.RegisterStats(1, basic) stmtStats.RegisterStats(1, s1) stmtStats.RegisterStats(1, &s2) stats := stmtStats.GetRootStats(1) diff --git a/distsql/main_test.go b/distsql/main_test.go index 1d8765d866f59..10e6ed474ce70 100644 --- a/distsql/main_test.go +++ b/distsql/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/distsql/request_builder.go b/distsql/request_builder.go index aae83a0dd0053..439c6ecd8e7fe 100644 --- a/distsql/request_builder.go +++ b/distsql/request_builder.go @@ -20,7 +20,6 @@ import ( "sort" "sync/atomic" - "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/tidb/ddl/placement" @@ -71,6 +70,9 @@ func (builder *RequestBuilder) Build() (*kv.Request, error) { if err != nil { builder.err = err } + if builder.Request.KeyRanges == nil { + builder.Request.KeyRanges = kv.NewNonParitionedKeyRanges(nil) + } return &builder.Request, builder.err } @@ -86,7 +88,7 @@ func (builder *RequestBuilder) SetMemTracker(tracker *memory.Tracker) *RequestBu // br refers it, so have to keep it. func (builder *RequestBuilder) SetTableRanges(tid int64, tableRanges []*ranger.Range, fb *statistics.QueryFeedback) *RequestBuilder { if builder.err == nil { - builder.Request.KeyRanges = TableRangesToKVRanges(tid, tableRanges, fb) + builder.Request.KeyRanges = kv.NewNonParitionedKeyRanges(TableRangesToKVRanges(tid, tableRanges, fb)) } return builder } @@ -112,7 +114,9 @@ func (builder *RequestBuilder) SetIndexRangesForTables(sc *stmtctx.StatementCont // SetHandleRanges sets "KeyRanges" for "kv.Request" by converting table handle range // "ranges" to "KeyRanges" firstly. func (builder *RequestBuilder) SetHandleRanges(sc *stmtctx.StatementContext, tid int64, isCommonHandle bool, ranges []*ranger.Range, fb *statistics.QueryFeedback) *RequestBuilder { - return builder.SetHandleRangesForTables(sc, []int64{tid}, isCommonHandle, ranges, fb) + builder = builder.SetHandleRangesForTables(sc, []int64{tid}, isCommonHandle, ranges, fb) + builder.err = builder.Request.KeyRanges.SetToNonPartitioned() + return builder } // SetHandleRangesForTables sets "KeyRanges" for "kv.Request" by converting table handle range @@ -127,14 +131,16 @@ func (builder *RequestBuilder) SetHandleRangesForTables(sc *stmtctx.StatementCon // SetTableHandles sets "KeyRanges" for "kv.Request" by converting table handles // "handles" to "KeyRanges" firstly. func (builder *RequestBuilder) SetTableHandles(tid int64, handles []kv.Handle) *RequestBuilder { - builder.Request.KeyRanges = TableHandlesToKVRanges(tid, handles) + keyRanges, hints := TableHandlesToKVRanges(tid, handles) + builder.Request.KeyRanges = kv.NewNonParitionedKeyRangesWithHint(keyRanges, hints) return builder } // SetPartitionsAndHandles sets "KeyRanges" for "kv.Request" by converting ParitionHandles to KeyRanges. // handles in slice must be kv.PartitionHandle. func (builder *RequestBuilder) SetPartitionsAndHandles(handles []kv.Handle) *RequestBuilder { - builder.Request.KeyRanges = PartitionHandlesToKVRanges(handles) + keyRanges, hints := PartitionHandlesToKVRanges(handles) + builder.Request.KeyRanges = kv.NewNonParitionedKeyRangesWithHint(keyRanges, hints) return builder } @@ -183,10 +189,28 @@ func (builder *RequestBuilder) SetChecksumRequest(checksum *tipb.ChecksumRequest // SetKeyRanges sets "KeyRanges" for "kv.Request". func (builder *RequestBuilder) SetKeyRanges(keyRanges []kv.KeyRange) *RequestBuilder { + builder.Request.KeyRanges = kv.NewNonParitionedKeyRanges(keyRanges) + return builder +} + +// SetKeyRangesWithHints sets "KeyRanges" for "kv.Request" with row count hints. +func (builder *RequestBuilder) SetKeyRangesWithHints(keyRanges []kv.KeyRange, hints []int) *RequestBuilder { + builder.Request.KeyRanges = kv.NewNonParitionedKeyRangesWithHint(keyRanges, hints) + return builder +} + +// SetWrappedKeyRanges sets "KeyRanges" for "kv.Request". +func (builder *RequestBuilder) SetWrappedKeyRanges(keyRanges *kv.KeyRanges) *RequestBuilder { builder.Request.KeyRanges = keyRanges return builder } +// SetPartitionKeyRanges sets the "KeyRanges" for "kv.Request" on partitioned table cases. +func (builder *RequestBuilder) SetPartitionKeyRanges(keyRanges [][]kv.KeyRange) *RequestBuilder { + builder.Request.KeyRanges = kv.NewPartitionedKeyRanges(keyRanges) + return builder +} + // SetStartTS sets "StartTS" for "kv.Request". func (builder *RequestBuilder) SetStartTS(startTS uint64) *RequestBuilder { builder.Request.StartTs = startTS @@ -243,7 +267,8 @@ func (*RequestBuilder) getKVPriority(sv *variable.SessionVars) int { } // SetFromSessionVars sets the following fields for "kv.Request" from session variables: -// "Concurrency", "IsolationLevel", "NotFillCache", "TaskID", "Priority", "ReplicaRead", "ResourceGroupTagger". +// "Concurrency", "IsolationLevel", "NotFillCache", "TaskID", "Priority", "ReplicaRead", +// "ResourceGroupTagger", "ResourceGroupName" func (builder *RequestBuilder) SetFromSessionVars(sv *variable.SessionVars) *RequestBuilder { if builder.Request.Concurrency == 0 { // Concurrency may be set to 1 by SetDAGRequest @@ -270,6 +295,8 @@ func (builder *RequestBuilder) SetFromSessionVars(sv *variable.SessionVars) *Req } builder.RequestSource.RequestSourceInternal = sv.InRestrictedSQL builder.RequestSource.RequestSourceType = sv.RequestSourceType + builder.StoreBatchSize = sv.StoreBatchSize + builder.Request.ResourceGroupName = sv.ResourceGroupName return builder } @@ -312,19 +339,24 @@ func (builder *RequestBuilder) SetResourceGroupTagger(tagger tikvrpc.ResourceGro return builder } +// SetResourceGroupName sets the request resource group name. +func (builder *RequestBuilder) SetResourceGroupName(name string) *RequestBuilder { + builder.Request.ResourceGroupName = name + return builder +} + func (builder *RequestBuilder) verifyTxnScope() error { txnScope := builder.TxnScope if txnScope == "" || txnScope == kv.GlobalReplicaScope || builder.is == nil { return nil } visitPhysicalTableID := make(map[int64]struct{}) - for _, keyRange := range builder.Request.KeyRanges { - tableID := tablecodec.DecodeTableID(keyRange.StartKey) - if tableID > 0 { - visitPhysicalTableID[tableID] = struct{}{} - } else { - return errors.New("requestBuilder can't decode tableID from keyRange") - } + tids, err := tablecodec.VerifyTableIDForRanges(builder.Request.KeyRanges) + if err != nil { + return err + } + for _, tid := range tids { + visitPhysicalTableID[tid] = struct{}{} } for phyTableID := range visitPhysicalTableID { @@ -376,7 +408,7 @@ func (builder *RequestBuilder) SetClosestReplicaReadAdjuster(chkFn kv.CoprReques } // TableHandleRangesToKVRanges convert table handle ranges to "KeyRanges" for multiple tables. -func TableHandleRangesToKVRanges(sc *stmtctx.StatementContext, tid []int64, isCommonHandle bool, ranges []*ranger.Range, fb *statistics.QueryFeedback) ([]kv.KeyRange, error) { +func TableHandleRangesToKVRanges(sc *stmtctx.StatementContext, tid []int64, isCommonHandle bool, ranges []*ranger.Range, fb *statistics.QueryFeedback) (*kv.KeyRanges, error) { if !isCommonHandle { return tablesRangesToKVRanges(tid, ranges, fb), nil } @@ -387,14 +419,18 @@ func TableHandleRangesToKVRanges(sc *stmtctx.StatementContext, tid []int64, isCo // Note this function should not be exported, but currently // br refers to it, so have to keep it. func TableRangesToKVRanges(tid int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) []kv.KeyRange { - return tablesRangesToKVRanges([]int64{tid}, ranges, fb) + if len(ranges) == 0 { + return []kv.KeyRange{} + } + return tablesRangesToKVRanges([]int64{tid}, ranges, fb).FirstPartitionRange() } // tablesRangesToKVRanges converts table ranges to "KeyRange". -func tablesRangesToKVRanges(tids []int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) []kv.KeyRange { +func tablesRangesToKVRanges(tids []int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) *kv.KeyRanges { if fb == nil || fb.Hist == nil { return tableRangesToKVRangesWithoutSplit(tids, ranges) } + // The following codes are deprecated since the feedback is deprecated. krs := make([]kv.KeyRange, 0, len(ranges)) feedbackRanges := make([]*ranger.Range, 0, len(ranges)) for _, ran := range ranges { @@ -420,20 +456,23 @@ func tablesRangesToKVRanges(tids []int64, ranges []*ranger.Range, fb *statistics } } fb.StoreRanges(feedbackRanges) - return krs + return kv.NewNonParitionedKeyRanges(krs) } -func tableRangesToKVRangesWithoutSplit(tids []int64, ranges []*ranger.Range) []kv.KeyRange { - krs := make([]kv.KeyRange, 0, len(ranges)*len(tids)) +func tableRangesToKVRangesWithoutSplit(tids []int64, ranges []*ranger.Range) *kv.KeyRanges { + krs := make([][]kv.KeyRange, len(tids)) + for i := range krs { + krs[i] = make([]kv.KeyRange, 0, len(ranges)) + } for _, ran := range ranges { low, high := encodeHandleKey(ran) - for _, tid := range tids { + for i, tid := range tids { startKey := tablecodec.EncodeRowKey(tid, low) endKey := tablecodec.EncodeRowKey(tid, high) - krs = append(krs, kv.KeyRange{StartKey: startKey, EndKey: endKey}) + krs[i] = append(krs[i], kv.KeyRange{StartKey: startKey, EndKey: endKey}) } } - return krs + return kv.NewPartitionedKeyRanges(krs) } func encodeHandleKey(ran *ranger.Range) ([]byte, []byte) { @@ -515,8 +554,9 @@ func SplitRangesAcrossInt64Boundary(ranges []*ranger.Range, keepOrder bool, desc // TableHandlesToKVRanges converts sorted handle to kv ranges. // For continuous handles, we should merge them to a single key range. -func TableHandlesToKVRanges(tid int64, handles []kv.Handle) []kv.KeyRange { +func TableHandlesToKVRanges(tid int64, handles []kv.Handle) ([]kv.KeyRange, []int) { krs := make([]kv.KeyRange, 0, len(handles)) + hints := make([]int, 0, len(handles)) i := 0 for i < len(handles) { if commonHandle, ok := handles[i].(*kv.CommonHandle); ok { @@ -525,6 +565,7 @@ func TableHandlesToKVRanges(tid int64, handles []kv.Handle) []kv.KeyRange { EndKey: tablecodec.EncodeRowKey(tid, kv.Key(commonHandle.Encoded()).Next()), } krs = append(krs, ran) + hints = append(hints, 1) i++ continue } @@ -540,15 +581,17 @@ func TableHandlesToKVRanges(tid int64, handles []kv.Handle) []kv.KeyRange { startKey := tablecodec.EncodeRowKey(tid, low) endKey := tablecodec.EncodeRowKey(tid, high) krs = append(krs, kv.KeyRange{StartKey: startKey, EndKey: endKey}) + hints = append(hints, j-i) i = j } - return krs + return krs, hints } // PartitionHandlesToKVRanges convert ParitionHandles to kv ranges. // Handle in slices must be kv.PartitionHandle -func PartitionHandlesToKVRanges(handles []kv.Handle) []kv.KeyRange { +func PartitionHandlesToKVRanges(handles []kv.Handle) ([]kv.KeyRange, []int) { krs := make([]kv.KeyRange, 0, len(handles)) + hints := make([]int, 0, len(handles)) i := 0 for i < len(handles) { ph := handles[i].(kv.PartitionHandle) @@ -560,6 +603,7 @@ func PartitionHandlesToKVRanges(handles []kv.Handle) []kv.KeyRange { EndKey: tablecodec.EncodeRowKey(pid, append(commonHandle.Encoded(), 0)), } krs = append(krs, ran) + hints = append(hints, 1) i++ continue } @@ -578,33 +622,40 @@ func PartitionHandlesToKVRanges(handles []kv.Handle) []kv.KeyRange { startKey := tablecodec.EncodeRowKey(pid, low) endKey := tablecodec.EncodeRowKey(pid, high) krs = append(krs, kv.KeyRange{StartKey: startKey, EndKey: endKey}) + hints = append(hints, j-i) i = j } - return krs + return krs, hints } // IndexRangesToKVRanges converts index ranges to "KeyRange". -func IndexRangesToKVRanges(sc *stmtctx.StatementContext, tid, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) ([]kv.KeyRange, error) { +func IndexRangesToKVRanges(sc *stmtctx.StatementContext, tid, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) (*kv.KeyRanges, error) { return IndexRangesToKVRangesWithInterruptSignal(sc, tid, idxID, ranges, fb, nil, nil) } // IndexRangesToKVRangesWithInterruptSignal converts index ranges to "KeyRange". // The process can be interrupted by set `interruptSignal` to true. -func IndexRangesToKVRangesWithInterruptSignal(sc *stmtctx.StatementContext, tid, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback, memTracker *memory.Tracker, interruptSignal *atomic.Value) ([]kv.KeyRange, error) { - return indexRangesToKVRangesForTablesWithInterruptSignal(sc, []int64{tid}, idxID, ranges, fb, memTracker, interruptSignal) +func IndexRangesToKVRangesWithInterruptSignal(sc *stmtctx.StatementContext, tid, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback, memTracker *memory.Tracker, interruptSignal *atomic.Value) (*kv.KeyRanges, error) { + keyRanges, err := indexRangesToKVRangesForTablesWithInterruptSignal(sc, []int64{tid}, idxID, ranges, fb, memTracker, interruptSignal) + if err != nil { + return nil, err + } + err = keyRanges.SetToNonPartitioned() + return keyRanges, err } // IndexRangesToKVRangesForTables converts indexes ranges to "KeyRange". -func IndexRangesToKVRangesForTables(sc *stmtctx.StatementContext, tids []int64, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) ([]kv.KeyRange, error) { +func IndexRangesToKVRangesForTables(sc *stmtctx.StatementContext, tids []int64, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) (*kv.KeyRanges, error) { return indexRangesToKVRangesForTablesWithInterruptSignal(sc, tids, idxID, ranges, fb, nil, nil) } // IndexRangesToKVRangesForTablesWithInterruptSignal converts indexes ranges to "KeyRange". // The process can be interrupted by set `interruptSignal` to true. -func indexRangesToKVRangesForTablesWithInterruptSignal(sc *stmtctx.StatementContext, tids []int64, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback, memTracker *memory.Tracker, interruptSignal *atomic.Value) ([]kv.KeyRange, error) { +func indexRangesToKVRangesForTablesWithInterruptSignal(sc *stmtctx.StatementContext, tids []int64, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback, memTracker *memory.Tracker, interruptSignal *atomic.Value) (*kv.KeyRanges, error) { if fb == nil || fb.Hist == nil { return indexRangesToKVWithoutSplit(sc, tids, idxID, ranges, memTracker, interruptSignal) } + // The following code is non maintained since the feedback deprecated. feedbackRanges := make([]*ranger.Range, 0, len(ranges)) for _, ran := range ranges { low, high, err := EncodeIndexKey(sc, ran) @@ -639,11 +690,11 @@ func indexRangesToKVRangesForTablesWithInterruptSignal(sc *stmtctx.StatementCont } } fb.StoreRanges(feedbackRanges) - return krs, nil + return kv.NewNonParitionedKeyRanges(krs), nil } // CommonHandleRangesToKVRanges converts common handle ranges to "KeyRange". -func CommonHandleRangesToKVRanges(sc *stmtctx.StatementContext, tids []int64, ranges []*ranger.Range) ([]kv.KeyRange, error) { +func CommonHandleRangesToKVRanges(sc *stmtctx.StatementContext, tids []int64, ranges []*ranger.Range) (*kv.KeyRanges, error) { rans := make([]*ranger.Range, 0, len(ranges)) for _, ran := range ranges { low, high, err := EncodeIndexKey(sc, ran) @@ -653,20 +704,23 @@ func CommonHandleRangesToKVRanges(sc *stmtctx.StatementContext, tids []int64, ra rans = append(rans, &ranger.Range{LowVal: []types.Datum{types.NewBytesDatum(low)}, HighVal: []types.Datum{types.NewBytesDatum(high)}, LowExclude: false, HighExclude: true, Collators: collate.GetBinaryCollatorSlice(1)}) } - krs := make([]kv.KeyRange, 0, len(rans)) + krs := make([][]kv.KeyRange, len(tids)) + for i := range krs { + krs[i] = make([]kv.KeyRange, 0, len(ranges)) + } for _, ran := range rans { low, high := ran.LowVal[0].GetBytes(), ran.HighVal[0].GetBytes() if ran.LowExclude { low = kv.Key(low).PrefixNext() } ran.LowVal[0].SetBytes(low) - for _, tid := range tids { + for i, tid := range tids { startKey := tablecodec.EncodeRowKey(tid, low) endKey := tablecodec.EncodeRowKey(tid, high) - krs = append(krs, kv.KeyRange{StartKey: startKey, EndKey: endKey}) + krs[i] = append(krs[i], kv.KeyRange{StartKey: startKey, EndKey: endKey}) } } - return krs, nil + return kv.NewPartitionedKeyRanges(krs), nil } // VerifyTxnScope verify whether the txnScope and visited physical table break the leader rule's dcLocation. @@ -688,8 +742,12 @@ func VerifyTxnScope(txnScope string, physicalTableID int64, is infoschema.InfoSc return true } -func indexRangesToKVWithoutSplit(sc *stmtctx.StatementContext, tids []int64, idxID int64, ranges []*ranger.Range, memTracker *memory.Tracker, interruptSignal *atomic.Value) ([]kv.KeyRange, error) { - krs := make([]kv.KeyRange, 0, len(ranges)) +func indexRangesToKVWithoutSplit(sc *stmtctx.StatementContext, tids []int64, idxID int64, ranges []*ranger.Range, memTracker *memory.Tracker, interruptSignal *atomic.Value) (*kv.KeyRanges, error) { + krs := make([][]kv.KeyRange, len(tids)) + for i := range krs { + krs[i] = make([]kv.KeyRange, 0, len(ranges)) + } + const checkSignalStep = 8 var estimatedMemUsage int64 // encodeIndexKey and EncodeIndexSeekKey is time-consuming, thus we need to @@ -702,13 +760,13 @@ func indexRangesToKVWithoutSplit(sc *stmtctx.StatementContext, tids []int64, idx if i == 0 { estimatedMemUsage += int64(cap(low) + cap(high)) } - for _, tid := range tids { + for j, tid := range tids { startKey := tablecodec.EncodeIndexSeekKey(tid, idxID, low) endKey := tablecodec.EncodeIndexSeekKey(tid, idxID, high) if i == 0 { estimatedMemUsage += int64(cap(startKey)) + int64(cap(endKey)) } - krs = append(krs, kv.KeyRange{StartKey: startKey, EndKey: endKey}) + krs[j] = append(krs[j], kv.KeyRange{StartKey: startKey, EndKey: endKey}) } if i%checkSignalStep == 0 { if i == 0 && memTracker != nil { @@ -716,11 +774,11 @@ func indexRangesToKVWithoutSplit(sc *stmtctx.StatementContext, tids []int64, idx memTracker.Consume(estimatedMemUsage) } if interruptSignal != nil && interruptSignal.Load().(bool) { - return nil, nil + return kv.NewPartitionedKeyRanges(nil), nil } } } - return krs, nil + return kv.NewPartitionedKeyRanges(krs), nil } // EncodeIndexKey gets encoded keys containing low and high @@ -740,20 +798,5 @@ func EncodeIndexKey(sc *stmtctx.StatementContext, ran *ranger.Range) ([]byte, [] if !ran.HighExclude { high = kv.Key(high).PrefixNext() } - - var hasNull bool - for _, highVal := range ran.HighVal { - if highVal.IsNull() { - hasNull = true - break - } - } - - // NOTE: this is a hard-code operation to avoid wrong results when accessing unique index with NULL; - // Please see https://github.com/pingcap/tidb/issues/29650 for more details - if hasNull { - // Append 0 to make unique-key range [null, null] to be a scan rather than point-get. - high = kv.Key(high).Next() - } return low, high, nil } diff --git a/distsql/request_builder_test.go b/distsql/request_builder_test.go index 0a11b9e04512c..74bdf723216f1 100644 --- a/distsql/request_builder_test.go +++ b/distsql/request_builder_test.go @@ -61,10 +61,11 @@ func TestTableHandlesToKVRanges(t *testing.T) { // Build key ranges. expect := getExpectedRanges(1, hrs) - actual := TableHandlesToKVRanges(1, handles) + actual, hints := TableHandlesToKVRanges(1, handles) // Compare key ranges and expected key ranges. require.Equal(t, len(expect), len(actual)) + require.Equal(t, hints, []int{1, 4, 2, 1, 2}) for i := range actual { require.Equal(t, expect[i].StartKey, actual[i].StartKey) require.Equal(t, expect[i].EndKey, actual[i].EndKey) @@ -192,8 +193,8 @@ func TestIndexRangesToKVRanges(t *testing.T) { actual, err := IndexRangesToKVRanges(new(stmtctx.StatementContext), 12, 15, ranges, nil) require.NoError(t, err) - for i := range actual { - require.Equal(t, expect[i], actual[i]) + for i := range actual.FirstPartitionRange() { + require.Equal(t, expect[i], actual.FirstPartitionRange()[i]) } } @@ -242,7 +243,7 @@ func TestRequestBuilder1(t *testing.T) { Tp: 103, StartTs: 0x0, Data: []uint8{0x18, 0x0, 0x20, 0x0, 0x40, 0x0, 0x5a, 0x0}, - KeyRanges: []kv.KeyRange{ + KeyRanges: kv.NewNonParitionedKeyRanges([]kv.KeyRange{ { StartKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, EndKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3}, @@ -263,7 +264,7 @@ func TestRequestBuilder1(t *testing.T) { StartKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x23}, EndKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x23}, }, - }, + }), Cacheable: true, KeepOrder: false, Desc: false, @@ -325,7 +326,7 @@ func TestRequestBuilder2(t *testing.T) { Tp: 103, StartTs: 0x0, Data: []uint8{0x18, 0x0, 0x20, 0x0, 0x40, 0x0, 0x5a, 0x0}, - KeyRanges: []kv.KeyRange{ + KeyRanges: kv.NewNonParitionedKeyRanges([]kv.KeyRange{ { StartKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x69, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, EndKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x69, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3}, @@ -346,7 +347,7 @@ func TestRequestBuilder2(t *testing.T) { StartKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x69, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x23}, EndKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5f, 0x69, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x23}, }, - }, + }), Cacheable: true, KeepOrder: false, Desc: false, @@ -378,7 +379,7 @@ func TestRequestBuilder3(t *testing.T) { Tp: 103, StartTs: 0x0, Data: []uint8{0x18, 0x0, 0x20, 0x0, 0x40, 0x0, 0x5a, 0x0}, - KeyRanges: []kv.KeyRange{ + KeyRanges: kv.NewNonParitionedKeyRangesWithHint([]kv.KeyRange{ { StartKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, EndKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, @@ -395,7 +396,7 @@ func TestRequestBuilder3(t *testing.T) { StartKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64}, EndKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x5f, 0x72, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x65}, }, - }, + }, []int{1, 4, 2, 1}), Cacheable: true, KeepOrder: false, Desc: false, @@ -443,7 +444,7 @@ func TestRequestBuilder4(t *testing.T) { Tp: 103, StartTs: 0x0, Data: []uint8{0x18, 0x0, 0x20, 0x0, 0x40, 0x0, 0x5a, 0x0}, - KeyRanges: keyRanges, + KeyRanges: kv.NewNonParitionedKeyRanges(keyRanges), Cacheable: true, KeepOrder: false, Desc: false, @@ -490,7 +491,7 @@ func TestRequestBuilder5(t *testing.T) { Tp: 104, StartTs: 0x0, Data: []uint8{0x8, 0x0, 0x18, 0x0, 0x20, 0x0}, - KeyRanges: keyRanges, + KeyRanges: kv.NewNonParitionedKeyRanges(keyRanges), KeepOrder: true, Desc: false, Concurrency: 15, @@ -519,7 +520,7 @@ func TestRequestBuilder6(t *testing.T) { Tp: 105, StartTs: 0x0, Data: []uint8{0x10, 0x0, 0x18, 0x0}, - KeyRanges: keyRanges, + KeyRanges: kv.NewNonParitionedKeyRanges(keyRanges), KeepOrder: false, Desc: false, Concurrency: concurrency, @@ -556,6 +557,7 @@ func TestRequestBuilder7(t *testing.T) { Tp: 0, StartTs: 0x0, KeepOrder: false, + KeyRanges: kv.NewNonParitionedKeyRanges(nil), Desc: false, Concurrency: concurrency, IsolationLevel: 0, @@ -574,20 +576,23 @@ func TestRequestBuilder7(t *testing.T) { func TestRequestBuilder8(t *testing.T) { sv := variable.NewSessionVars(nil) + sv.ResourceGroupName = "test" actual, err := (&RequestBuilder{}). SetFromSessionVars(sv). Build() require.NoError(t, err) expect := &kv.Request{ - Tp: 0, - StartTs: 0x0, - Data: []uint8(nil), - Concurrency: variable.DefDistSQLScanConcurrency, - IsolationLevel: 0, - Priority: 0, - MemTracker: (*memory.Tracker)(nil), - SchemaVar: 0, - ReadReplicaScope: kv.GlobalReplicaScope, + Tp: 0, + StartTs: 0x0, + Data: []uint8(nil), + KeyRanges: kv.NewNonParitionedKeyRanges(nil), + Concurrency: variable.DefDistSQLScanConcurrency, + IsolationLevel: 0, + Priority: 0, + MemTracker: (*memory.Tracker)(nil), + SchemaVar: 0, + ReadReplicaScope: kv.GlobalReplicaScope, + ResourceGroupName: "test", } expect.Paging.MinPagingSize = paging.MinPagingSize expect.Paging.MaxPagingSize = paging.MaxPagingSize @@ -634,8 +639,8 @@ func TestIndexRangesToKVRangesWithFbs(t *testing.T) { EndKey: kv.Key{0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x69, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5}, }, } - for i := 0; i < len(actual); i++ { - require.Equal(t, expect[i], actual[i]) + for i := 0; i < len(actual.FirstPartitionRange()); i++ { + require.Equal(t, expect[i], actual.FirstPartitionRange()[i]) } } diff --git a/distsql/select_result.go b/distsql/select_result.go index 0e807b360d0ad..6d1f6308e4120 100644 --- a/distsql/select_result.go +++ b/distsql/select_result.go @@ -359,13 +359,11 @@ func (r *selectResult) updateCopRuntimeStats(ctx context.Context, copStats *copr } if r.stats == nil { - id := r.rootPlanID r.stats = &selectResultRuntimeStats{ backoffSleep: make(map[string]time.Duration), rpcStat: tikv.NewRegionRequestRuntimeStats(), distSQLConcurrency: r.distSQLConcurrency, } - r.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(id, r.stats) } r.stats.mergeCopRuntimeStats(copStats, respTime) @@ -456,6 +454,9 @@ func (r *selectResult) Close() error { if respSize > 0 { r.memConsume(-respSize) } + if r.stats != nil { + defer r.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(r.rootPlanID, r.stats) + } return r.resp.Close() } diff --git a/distsql/select_result_test.go b/distsql/select_result_test.go index c12892083d641..4ec56a286e5ab 100644 --- a/distsql/select_result_test.go +++ b/distsql/select_result_test.go @@ -34,7 +34,7 @@ func TestUpdateCopRuntimeStats(t *testing.T) { require.Nil(t, ctx.GetSessionVars().StmtCtx.RuntimeStatsColl) sr.rootPlanID = 1234 - sr.updateCopRuntimeStats(context.Background(), &copr.CopRuntimeStats{ExecDetails: execdetails.ExecDetails{CalleeAddress: "a"}}, 0) + sr.updateCopRuntimeStats(context.Background(), &copr.CopRuntimeStats{ExecDetails: execdetails.ExecDetails{DetailsNeedP90: execdetails.DetailsNeedP90{CalleeAddress: "a"}}}, 0) ctx.GetSessionVars().StmtCtx.RuntimeStatsColl = execdetails.NewRuntimeStatsColl(nil) i := uint64(1) @@ -46,13 +46,13 @@ func TestUpdateCopRuntimeStats(t *testing.T) { require.NotEqual(t, len(sr.copPlanIDs), len(sr.selectResp.GetExecutionSummaries())) - sr.updateCopRuntimeStats(context.Background(), &copr.CopRuntimeStats{ExecDetails: execdetails.ExecDetails{CalleeAddress: "callee"}}, 0) + sr.updateCopRuntimeStats(context.Background(), &copr.CopRuntimeStats{ExecDetails: execdetails.ExecDetails{DetailsNeedP90: execdetails.DetailsNeedP90{CalleeAddress: "callee"}}}, 0) require.False(t, ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.ExistsCopStats(1234)) sr.copPlanIDs = []int{sr.rootPlanID} require.NotNil(t, ctx.GetSessionVars().StmtCtx.RuntimeStatsColl) require.Equal(t, len(sr.copPlanIDs), len(sr.selectResp.GetExecutionSummaries())) - sr.updateCopRuntimeStats(context.Background(), &copr.CopRuntimeStats{ExecDetails: execdetails.ExecDetails{CalleeAddress: "callee"}}, 0) + sr.updateCopRuntimeStats(context.Background(), &copr.CopRuntimeStats{ExecDetails: execdetails.ExecDetails{DetailsNeedP90: execdetails.DetailsNeedP90{CalleeAddress: "callee"}}}, 0) require.Equal(t, "tikv_task:{time:1ns, loops:1}", ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.GetOrCreateCopStats(1234, "tikv").String()) } diff --git a/docs/design/2019-11-05-index-advisor.md b/docs/design/2019-11-05-index-advisor.md index 53abab5ba0d5a..5606d9bd9a942 100644 --- a/docs/design/2019-11-05-index-advisor.md +++ b/docs/design/2019-11-05-index-advisor.md @@ -57,7 +57,7 @@ for { Note that executing `Swap and Re-evaluate` algorithm is necessary as the `reduced_cost` sometimes is a joint effect of several indexes and it's hard to tell each index's independent contribution to the final `reduced_cost`. For example, assume there is an extremely slow query in input workload and the desired indexes for this query is `a` and `b`. However, the number of allowed recommended indexes for the whole workload is limited and for some reason, `a` ranks top `n` in the final score list while `b` is not. But there are chances that without `b`, `a` can no more optimize that extremely slow query. ---------------------------------------------- -### A quick exmaple for single-column index recommendation +### A quick example for single-column index recommendation **Workload**: diff --git a/docs/design/2020-01-24-collations.md b/docs/design/2020-01-24-collations.md index a222035745b83..d610514ed76d5 100644 --- a/docs/design/2020-01-24-collations.md +++ b/docs/design/2020-01-24-collations.md @@ -105,10 +105,10 @@ The interface is quite similar to the Go [collate package](https://godoc.org/gol ### Row Format -The encoding layout of TiDB has been described in our [previous article](https://pingcap.com/blog/2017-07-11-tidbinternal2/#map). The row format should be changed to make it memory comparable, this is important to the index lookup. Basic principle is that all keys encoded for strings should use the `sortKeys` result from `Key()`/`KeyFromString()` function. However, most of the `sortKeys` calculations are not reversible. +The encoding layout of TiDB has been described in our [previous article](https://docs.pingcap.com/tidb/stable/tidb-computing). The row format should be changed to make it memory comparable, this is important to the index lookup. Basic principle is that all keys encoded for strings should use the `sortKeys` result from `Key()`/`KeyFromString()` function. However, most of the `sortKeys` calculations are not reversible. * For table data, encodings stay unchanged. All strings are compared after decoding with the `Compare()` function. - * For table indices, we replace current `ColumnValue` with `sortKey` and encode the `ColumnValue` to the value,: + * For table indices, we replace current `ColumnValue` with `sortKey` and encode the `ColumnValue` to the value: - For unique indices: ``` Key: tablePrefix{tableID}_indexPrefixSep{indexID}_sortKey @@ -233,7 +233,7 @@ The following features of the general collation algorithm will be supported: * Tertiary Weight i.e. case * PAD / NOPAD -All of them are supported by `text/collate` package of Go, so it is possible to map Go collations to some of UCA-based collations in MySQL like `utf8mb4_unicode_ci`/`utf8mb4_0900_ai_ci`, if we ignore the differences between UCA versions: current `text/collate` uses UCA version `6.2.0` and it is not changable. However, the collations in MySQL are with different UCA versions marked in the names, for example, `utf8mb4_0900_ai_ci` uses version `9.0`. +All of them are supported by `text/collate` package of Go, so it is possible to map Go collations to some of UCA-based collations in MySQL like `utf8mb4_unicode_ci`/`utf8mb4_0900_ai_ci`, if we ignore the differences between UCA versions: current `text/collate` uses UCA version `6.2.0` and it is not changeable. However, the collations in MySQL are with different UCA versions marked in the names, for example, `utf8mb4_0900_ai_ci` uses version `9.0`. For non-standard UCA implementations in MySQL, i.e. the `utf8mb4_general_ci`. The implementation depends on our choice to the [Compatibility with MySQL](#compatibility-with-mysql) chapter, if a 100% compatibility of `utf8mb4_general_ci` is chosen, we need to implement it by our hands. diff --git a/docs/design/2020-08-04-global-index.md b/docs/design/2020-08-04-global-index.md index 80078688777b7..f5e2d89f932c4 100644 --- a/docs/design/2020-08-04-global-index.md +++ b/docs/design/2020-08-04-global-index.md @@ -183,7 +183,7 @@ In TiDB, operators in the partitioned table will be translated to UnionAll in th ## Compatibility -MySQL does not support global index, which means this feature may cause some compatibility issues. We add an option `enable_global_index` in `config.Config` to control it. The default value of this option is `false`, so TiDB will keep consistent with MySQL, unless the user open global index feature manually. +MySQL does not support global index, which means this feature may cause some compatibility issues. We add an option `enable-global-index` in `config.Config` to control it. The default value of this option is `false`, so TiDB will keep consistent with MySQL, unless the user open global index feature manually. ## Implementation diff --git a/docs/design/2022-06-06-Adding-Index-Acceleration.md b/docs/design/2022-06-07-adding-index-acceleration.md similarity index 100% rename from docs/design/2022-06-06-Adding-Index-Acceleration.md rename to docs/design/2022-06-07-adding-index-acceleration.md diff --git a/docs/design/2022-06-22-foreign-key.md b/docs/design/2022-06-22-foreign-key.md new file mode 100644 index 0000000000000..5c6b32d9474e0 --- /dev/null +++ b/docs/design/2022-06-22-foreign-key.md @@ -0,0 +1,708 @@ +# Foreign Key Design Doc + +- Author(s): [crazycs520](https://github.com/crazycs520) +- Tracking Issue: https://github.com/pingcap/tidb/issues/18209 + +## Abstract + +This proposes an implementation of supporting foreign key constraints. + +## DDL Technical Design + +### Table Information Changes +The table's foreign key information will be stored in `model.TableInfo`: + +```go +// TableInfo provides meta data describing a DB table. +type TableInfo struct { + ... + ForeignKeys []*FKInfo `json:"fk_info"` + // MaxFKIndexID uses to allocate foreign key ID. + MaxForeignKeyID int64 `json:"max_fk_id"` + ... +} + +// FKInfo provides meta data describing a foreign key constraint. +type FKInfo struct { + ID int64 `json:"id"` + Name CIStr `json:"fk_name"` + RefSchema CIStr `json:"ref_schema"` + RefTable CIStr `json:"ref_table"` + RefCols []CIStr `json:"ref_cols"` + Cols []CIStr `json:"cols"` + OnDelete int `json:"on_delete"` + OnUpdate int `json:"on_update"` + State SchemaState `json:"state"` + Version int `json:"version"` +} +``` + +Struct `FKInfo` uses for the child table to record the referenced parent table. Struct `FKInfo` has existed for a long time, I just added some fields. +- `Version`: uses to distinguish between old and new versions. The new version value is 1, the old version value is 0. + +Why `FKInfo` record the table/schema name instead of table/schema id? Because we may don't know the table/schema id when building `FKInfo`. Here is an example: + +```sql +>set @@foreign_key_checks=0; +Query OK, 0 rows affected +>create table t2 (a int key, foreign key fk(a) references t1(id)); +Query OK, 0 rows affected +>create table t1 (id int key); +Query OK, 0 rows affected +>set @@foreign_key_checks=1; +Query OK, 0 rows affected +>insert into t2 values (1); +(1452, 'Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`))') +``` + +As you can see, table `t2` refers to table `t1`, and when creating table `t2`, table `t1` still not be created, so we can't know the id of table `t1`. + +### Create Table with Foreign Key + +#### Build TableInfo + +When building `TableInfo`, an index for the foreign key columns is created automatically if there is no index covering the foreign key columns. Here is an example: + +```sql +mysql> create table t (id int key, a int, foreign key fk(a) references t(id)); +Query OK, 0 rows affected +mysql> show create table t\G +***************************[ 1. row ]*************************** +Table | t +Create Table | CREATE TABLE `t` ( + `id` int NOT NULL, + `a` int DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk` (`a`), + CONSTRAINT `t_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci +1 row in set +``` + +As you can see, the index `fk` is created automatically for the foreign key. + +#### Validate + +Create a table with foreign key, check the following conditions when a DDL job is built and the DDL owner received a DDL job(aka Double-Check): + +- whether the user has `REFERENCES` privilege to the foreign key references table. +- Corresponding columns in the foreign key and the referenced key must have similar data types. The size and sign of fixed precision types such as INTEGER and DECIMAL must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same. +- Supports foreign key references between one column and another within a table. (A column cannot have a foreign key reference to itself.) +- Indexes on foreign keys and referenced keys are required, because the foreign key check can be fast and do not require a table scan. +- Prefixed indexes on foreign key columns are not supported. Consequently, BLOB and TEXT columns cannot be included in a foreign key because indexes on those columns must always include a prefix length. +- Does not currently support foreign keys for the partition table. This includes both reference and child tables. +- A foreign key constraint cannot reference any virtual generated columns, but the stored generated columns are fine. + +#### Handle In DDL Owner + +When the DDL Owner handle create table job, the DDL owner needs to create a new table. + +At the same point in time, there may be two versions of the schema in the TiDB cluster, so we can't create a new table and +update all reference tables in one schema version, since this may break foreign key constraints, such as delete reference table +without foreign key constraint check in the child table. + +```sql +-- In TiDB-1 and Schema Version is 1 +insert into t_has_foreign_key values (1, 1); + +-- In TiDB-0 and Schema Version is 0 +delete from t_reference where id = 1; --Since doesn't know foreign key information in old version, so doesn't do foreign key constrain check. +``` + +So, when creating a table with foreign key, we need multi-schema version change: + +1. None -> Write Only: Create table with the state is `write-only`. +2. Write Only -> Public: Update the created table state to `public`. + +#### Maintain ReferredFKInfo + +Why need to maintain `ReferredFKInfo` in the reference table? When executing `UPDATE`/`DELETE` in the reference table, we need the `ReferredFKInfo` of the reference table to do a foreign key check/cascade. + +How to maintain `ReferredFKInfo` in the reference table? When we create table with foreign key, we didn't add `ReferredFKInfo` into the reference table, because the reference table may not have been created yet, +when `foreign_key_checks` variable value is `OFF`, the user can create a child table before the reference table. + +We decided to maintain `ReferredFKInfo` while TiDB loading schema. At first, `infoSchema` will record all table's `ReferredFKInfo`: + +```sql +// ReferredFKInfo provides the referred foreign key in the child table. +type ReferredFKInfo struct { + Cols []CIStr `json:"cols"` + ChildSchema CIStr `json:"child_schema"` + ChildTable CIStr `json:"child_table"` + ChildFKName CIStr `json:"child_fk"` +} +``` + +```go +type infoSchema struct { + // referredForeignKeyMap records all table's ReferredFKInfo. + // referredSchemaAndTableName => child SchemaAndTableAndForeignKeyName => *model.ReferredFKInfo + referredForeignKeyMap map[SchemaAndTableName]map[SchemaAndTableAndForeignKeyName]*model.ReferredFKInfo +} +``` + +Function `applyTableUpdate` uses `applyDropTable` to drop the old table, uses `applyCreateTable` to create the new table. + +In the function `applyDropTable`, we will delete the table's foreign key information from `infoSchema.referredForeignKeyMap`. + +In the function `applyCreateTable`, we will add the table's foreign key information into `infoSchema.referredForeignKeyMap` first, +then get the table's `ReferredFKInfo` by schema name and table name, then store the `ReferredFKInfo` into `TableInfo.ReferredForeignKeys`. + +Then `applyTableUpdate` will also need to reload the old/new table's referred table information, also uses `applyDropTable` to drop the old reference table, use `applyCreateTable` to create new reference table. + +That's all. + +### Alter Table Add Foreign Key + +Here is an example: + +```sql +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int); +alter table t2 add foreign key fk(a) references t1(id) ON DELETE CASCADE; +``` + +Just like create table, we should validate first, and return an error if the conditions for creating foreign keys are not met, and also need to double-check. + +When building `TableInfo`, we need to auto-create an index for foreign key columns if there are no index cover foreign key columns. +And this divides the problem into two cases: +- Case-1: No need to create an index automatically, and only add the foreign key constraint. +- Case-2: Need auto-create index for foreign key + +#### Case-1: Only add foreign key constrain + +The DDL owner handle adds foreign key constrain step is: + +1. None -> Write Only: add foreign key constraint which state is `write-only` into the table. +2. Write Only -> Write Reorg: check all rows in the table whether has related foreign key exists in the reference table, we can use the following SQL to check: + + ```sql + select 1 from t2 where t2.a is not null and t2.a not in (select id from t1) limit 1; + ``` + The expected result is `empty`, otherwise, an error is returned and cancels the DDL job. + +3. Write Reorg -> Public: update the foreign key constraint state to `public`. + +A problem is, How the DML treat the foreign key on delete/update cascade behaviour in which state is non-public? +Here is an example: + +```sql +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int, index(a)); +insert into t1 values (1,1); +insert into t2 values (1,1); +alter table t2 add constraint fk_1 foreign key (a) references t1(id) ON DELETE CASCADE; +``` + +The schema change of foreign key `fk_1` is from `None` -> `Write-Only` -> `Write-Reorg` -> `Public`。 +When the foreign key `fk_1` in `Write-Only` state, a DML request has come to be processed: + +```sql +delete from t1 where id = 1; +``` + +Then, TiDB shouldn't do cascade delete for foreign key `fk_1` in state `Write-Only`, since the `Add Foreign Key` DDL job maybe +failed in `Write-Reorg` state and rollback the DDL job. But it is hard to rollback the cascade deleted executed before. + +So, when executing DML with `non-public` foreign key, TiDB will do foreign key constraint check instead of foreign key cascade behaviour. + +#### Case-2: Auto-create index for foreign key and add foreign key constrain + +As TiDB support multi-schema change now, we create an `ActionMultiSchemaChange` job that contains the following 2 sub-ddl job. +- Add Index DDL job +- Add Foreign Key Constraint DDL job + +When TiDB adds foreign key DDL job meet error, TiDB will rollback the `ActionMultiSchemaChange` job and the 2 sub-ddl job will also be rollback. + +### Drop Table + +If `foreign_key_checks` is `ON`, then drop the table which has foreign key references will be rejected. + +```sql +> drop table t1; +(3730, "Cannot drop table 't1' referenced by a foreign key constraint 't2_ibfk_1' on table 't2'.") +``` + +### Drop Database + +If `foreign_key_checks` is `ON`, then drop the database which has foreign key references by another database will be rejected. + +```sql +> drop database test; +(3730, "Cannot drop table 't1' referenced by a foreign key constraint 't2_ibfk_1' on table 't2'.") +``` + +### Drop Index + +Drop index used by the foreign key will be rejected. + +```sql +> set @@foreign_key_checks=0; -- Even disable foreign_key_checks, you still can't drop the index used for foreign key constrain. +Query OK, 0 rows affected +> alter table t2 drop index fk; +(1553, "Cannot drop index 'fk': needed in a foreign key constraint") +``` + +### Rename Column + +Rename column which has foreign keys or references should also need to update the related child/parent table info. + +```sql +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); +rename table t1 to t11; +alter table t11 change column id id1 int; +show create table t2\G +***************************[ 1. row ]*************************** + Table | t2 +Create Table | CREATE TABLE `t2` ( + `id` int NOT NULL, + `a` int DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fk` (`a`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t11` (`id1`) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci +``` + +### Truncate Table + +A truncate table which has foreign keys or references should also need to update the related child/parent table info. + +### Modify Column + +Modify column which used by the foreign key will be rejected. + +```sql +> alter table t1 change column id id1 bigint; +(3780, "Referencing column 'a' and referenced column 'id1' in foreign key constraint 't2_ibfk_1' are incompatible.") +``` + +MySQL modify column problem: https://www.percona.com/blog/2019/06/04/ddl-queries-foreign-key-columns-MySQL-pxc/ + +What if the user really needs to modify column type, such as from `INT` to `BIGINT`. Maybe we can offer a variable such as `alter-foreign-keys-method=auto`, +then when the user modifies the column type, TiDB will auto-modify the related foreign key column's type. For easy implementation and to reduce risk, maybe only support modifying column type which doesn't need to reorg table row data. + +## DML Technical Design + +### DML On Child Table + +On Child Table Insert Or Update, need to Find FK column value that exist in the reference table: + +1. Get reference table info by table name. +2. Get the related fk index of the reference table. +3. tiny optimize, check fk column value exists in reference table cache(map[string(index_key)]struct). +3. Get related row in reference. +- Construct index key and then use snapshot `Iter` and `Seek` API to scan. If the index is unique and only contain + foreign key columns, use the snapshot `Get` API. + - `Iter` default scan batch size is 256, need to set 2 to avoid read unnecessary data. +4. compact column value to make sure exist. +5. If relate row exist in reference table, also need to add lock in the related row. +6. put column value into reference fk column value cache. + +#### Lock + +Let's see an example in MySQL first: + +prepare: +```sql +create table t1 (id int key,a int, b int, unique index(a, b, id)); +create table t2 (id int key,a int, b int, index (a,b,id), foreign key fk(a, b) references t1(a, b)); +insert into t1 values (-1, 1, 1); +``` + +Then, execute the following SQL in 2 sessions: + +| Session 1 | Session 2 | +| -------------------------------- | ------------------------------------------- | +| Begin; | | +| insert into t2 values (1, 1, 1); | | +| | delete from t1; -- Blocked by wait lock | +| Commit | | +| | ERROR: Cannot delete or update a parent row | + +So we need to add lock in the reference table when insert/update child table. + +##### In Pessimistic Transaction + +When TiDB add pessimistic locks, if related row exists in the reference table, also needs to add lock in the related row. + +##### In Optimistic Transaction + +Just like `SELECT FOR UPDATE` statement, need to use `doLockKeys` to lock the related row in the reference table. + +##### Issue + +TiDB currently only support `lock for update`(aka write-lock, such as `select for update`), and doesn't support `lock for share`(aka read-lock, such as `select for share`). + +So far we have to add `lock for update` in the reference table when insert/update child table, then the performance will be poor. After TiDB support `lock for share`, we should use `lock for share` instead. + +#### DML Load data + +Load data should also do foreign key check, but report a warning instead error: + +```sql +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); + +test> load data local infile 'data.csv' into table t2 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'; +Query OK, 0 rows affected +test> show warnings; ++---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Level | Code | Message | ++---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Warning | 1452 | Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`) ON DELETE CASCADE) | +| Warning | 1452 | Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`) ON DELETE CASCADE) | ++---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +``` + +`data.csv` is: +``` +1,1 +2,2 +``` + +### DML On reference Table + +On reference Table Delete Or Update: + +1. modify related child table row by referential action: +- `CASCADE`: update/delete related child table row. +- `SET NULL`: set related child row's foreign key columns value to NULL. +- `RESTRICT`, `NO ACTION`: If related row exist in child table, reject update/delete the reference table. +- `SET DEFAULT`: just like `RESTRICT`. + +modify related child table rows by the following step: +1. get child table info by name(in reference table info). +2. get the child table fk index's column info. +3. build update executor to update child table rows. + +### Issue need to be discussed + +#### Affect Row + +related article: https://www.percona.com/blog/hidden-cost-of-foreign-key-constraints-in-MySQL/ + +Here is a MySQL example: + +prepare: +```sql +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); +insert into t1 values (1, 1); +insert into t2 values (1, 1); +``` + +Then delete on reference table: +```sql +> delete from t1 where id=1; +Query OK, 1 row affected +``` + +As you can see, in the query result, the affected row is 1, but actually should be 2, since the related row in t2 is also been deleted. + +This is a MySQL behaviour, We can be compatible with it. + +#### DML Execution plan + +Here is a MySQL example: + +prepare: +```sql +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); +insert into t1 values (1, 1); +insert into t2 values (1, 1); +``` + +```sql +> explain delete from t1 where id = 1; ++----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ +| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | ++----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ +| 1 | DELETE | t1 | | range | PRIMARY | PRIMARY | 4 | const | 1 | 100.0 | Using where | ++----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ +``` + +From the plan, you can't see any information about the foreign key constraint which needs to delete the related row in child table `t2`. + +I think this is a MySQL issue, should we make TiDB plan better, at least when we meet some slow query, we can know maybe it is caused by modify related rows in the child table. + +Here is an example plan with foreign key: + +```sql +> explain delete from t1 where id = 1; ++-------------------------+---------+------+---------------+-----------------------------------+ +| id | estRows | task | access object | operator info | ++-------------------------+---------+------+---------------+-----------------------------------+ +| Delete_2 | N/A | root | | N/A | +| ├─Point_Get_1 | 1.00 | root | table:t1 | handle:1 | +| └─Foreign_Key_Cascade_3 | 0.00 | root | table:t2 | foreign_key:fk, on_delete:CASCADE | ++-------------------------+---------+------+---------------+-----------------------------------+ +``` + +And the `explain analyze` will show the foreign key cascade child plan: + +```sql +> explain analyze delete from t1 where id = 1; ++-------------------------+---------+---------+------+---------------+----------------------------------------------------------+-----------------------------------+-----------+------+ +| id | estRows | actRows | task | access object | execution info | operator info | memory | disk | ++-------------------------+---------+---------+------+---------------+----------------------------------------------------------+-----------------------------------+-----------+------+ +| Delete_2 | N/A | 0 | root | | time:109.5µs, loops:1 | N/A | 380 Bytes | N/A | +| ├─Point_Get_1 | 1.00 | 1 | root | table:t1 | time:62.7µs, loops:2, Get:{num_rpc:1, total_time:26.4µs} | handle:1 | N/A | N/A | +| └─Foreign_Key_Cascade_3 | 0.00 | 0 | root | table:t2 | total:322.1µs, foreign_keys:1 | foreign_key:fk, on_delete:CASCADE | N/A | N/A | +| └─Delete_7 | N/A | 0 | root | | time:23.5µs, loops:1 | N/A | 129 Bytes | N/A | +| └─Point_Get_9 | 1.00 | 1 | root | table:t2 | time:12.6µs, loops:2, Get:{num_rpc:1, total_time:4.21µs} | handle:1 | N/A | N/A | ++-------------------------+---------+---------+------+---------------+----------------------------------------------------------+-----------------------------------+-----------+------+ +``` + +##### CockroachDB DML Execution Plan + +```sql +CREATE TABLE customers_2 ( + id INT PRIMARY KEY +); +CREATE TABLE orders_2 ( + id INT PRIMARY KEY, + customer_id INT REFERENCES customers_2(id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO customers_2 VALUES (1), (2), (3); +INSERT INTO orders_2 VALUES (100,1), (101,2), (102,3), (103,1); +``` + +```sql +> explain analyze UPDATE customers_2 SET id = 23 WHERE id = 1; + info +-------------------------------------------------- + planning time: 494µs + execution time: 5ms + distribution: local + vectorized: true + rows read from KV: 6 (170 B) + cumulative time spent in KV: 978µs + maximum memory usage: 100 KiB + network usage: 0 B (0 messages) + regions: us-east1 + + • root + │ + ├── • update + │ │ nodes: n1 + │ │ regions: us-east1 + │ │ actual row count: 1 + │ │ table: customers_2 + │ │ set: id + │ │ + │ └── • buffer + │ │ label: buffer 1 + │ │ + │ └── • render + │ │ nodes: n1 + │ │ regions: us-east1 + │ │ actual row count: 1 + │ │ KV rows read: 1 + │ │ KV bytes read: 27 B + │ │ + │ └── • scan + │ nodes: n1 + │ regions: us-east1 + │ actual row count: 1 + │ KV rows read: 1 + │ KV bytes read: 27 B + │ missing stats + │ table: customers_2@primary + │ spans: [/1 - /1] + │ locking strength: for update + │ + └── • fk-cascade + fk: fk_customer_id_ref_customers_2 + input: buffer 1 +``` + +##### PostgreSQL DML Execution Plan + +```sql +postgres=# explain analyze UPDATE customers_2 SET id = 20 WHERE id = 23; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Update on customers_2 (cost=0.15..8.17 rows=1 width=10) (actual time=0.039..0.039 rows=0 loops=1) + -> Index Scan using customers_2_pkey on customers_2 (cost=0.15..8.17 rows=1 width=10) (actual time=0.016..0.016 rows=1 loops=1) + Index Cond: (id = 23) + Planning Time: 0.057 ms + Trigger for constraint orders_2_customer_id_fkey on customers_2: time=0.045 calls=1 + Trigger for constraint orders_2_customer_id_fkey on orders_2: time=0.023 calls=2 + Execution Time: 0.129 ms +``` + +## Compatibility + +Since the old version TiDB already support foreign key syntax, but doesn't support it, after upgrade TiDB to latest version, the foreign key created before won't take effect. Only foreign keys created in the new version actually take effect. + +You can use `SHOW CREATE TABLE` to see whethere a foreign key is take effect, the old version foreign key will have a comment `/* FOREIGN KEY INVALID */` to indicate it is invalid, the new version foreign key doesn't have this comment. + +```sql +> show create table t2\G + ***************************[ 1. row ]*************************** + Table | t2 +Create Table | CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */, + CONSTRAINT `fk` FOREIGN KEY (`id`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE /* FOREIGN KEY INVALID */ + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin +``` + +## Impact + +### Impact of data replication + +#### TiCDC + +When syncing table data to downstream TiDB, TiCDC should `set @@foreign_key_checks=0` in downstream TiDB. + +#### DM + +When doing full synchronization, DM should `set @@foreign_key_checks=0` in downstream TiDB. + +When doing incremental synchronization, DM should set `foreign_key_checks` session variable according to MySQL binlog. + +#### BR + +When restore data into TiDB, BR should `set @@foreign_key_checks=0` in TiDB. + +## Test Case + +Cascade modification test case: + +```sql +drop table if exists t3,t2,t1; +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); +create table t3 (id int key,a int, foreign key fk(a) references t2(id) ON DELETE CASCADE); +insert into t1 values (1,1); +insert into t2 values (2,1); +insert into t3 values (3,2); +delete from t1 where id = 1; -- both t1, t2, t3 rows are deleted. +``` + +Following is a MySQL test case about `SET DEFAULT`, as you can see, MySQL actualy doesn't support `SET DEFAULT`, the behaviour is just like `RESTRICT` + +```sql +MySQL>create table t1 (a int,b int, index(a,b)) ; +Query OK, 0 rows affected +Time: 0.022s +MySQL>create table t (a int, b int, foreign key fk_a(a) references test.t1(a) ON DELETE SET DEFAULT); +Query OK, 0 rows affected +Time: 0.019s +MySQL>insert into t1 values (1,1); +Query OK, 1 row affected +Time: 0.003s +MySQL>insert into t values (1,1); +Query OK, 1 row affected +Time: 0.006s +MySQL>delete from t1 where a=1; +(1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t`, CONSTRAINT `t_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))') +MySQL>select version(); ++-----------+ +| version() | ++-----------+ +| 8.0.29 | ++-----------+ +``` + +### Self-Referencing Tables + +For example, table `employee` has a column `manager_id` references to `employee.id`. + +```sql +create table employee (id int key,manager_id int, foreign key fk(manager_id) references employee(id) ON DELETE CASCADE); +insert into employee values (1,1); +insert into employee values (2,1); + +test> delete from employee where id=1; +Query OK, 1 row affected +test> select * from employee; ++----+---+ +| id | a | ++----+---+ +0 rows in set +``` + +A case of self-reference and cyclical dependencies: + +```sql +test> create table t (id int key,a int, foreign key fk_a(a) references t(id) ON DELETE CASCADE, foreign key fk_id(id) references t(a) ON DELETE CASCADE); +Query OK, 0 rows affected +Time: 0.045s +test> insert into t values (1,1); +(1452, 'Cannot add or update a child row: a foreign key constraint fails (`test`.`t`, CONSTRAINT `t_ibfk_2` FOREIGN KEY (`id`) REFERENCES `t` (`a`) ON DELETE CASCADE)') +``` + +### Cyclical Dependencies + +```sql +create table t1 (id int key,a int, index(a)); +create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); +insert into t1 values (1,1); +ALTER TABLE t1 ADD foreign key fk(a) references t2(id) ON DELETE CASCADE; +(1452, 'Cannot add or update a child row: a foreign key constraint fails (`test`.`#sql-298_8`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t2` (`id`) ON DELETE CASCADE)') +``` + +```sql +set @@foreign_key_checks=0; +create table t1 (id int key,a int, foreign key fk(a) references t2(id) ON DELETE CASCADE); +create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); +insert into t1 values (1, 2); +insert into t2 values (2, 1); +set @@foreign_key_checks=1; -- add test case without this. +delete from t1 where id=1; +test> select * from t2; ++----+---+ +| id | a | ++----+---+ +0 rows in set +Time: 0.004s +test> select * from t1; ++----+---+ +| id | a | ++----+---+ +0 rows in set +``` + +### Check order + +check order should check unique/primary key constrain first: + +```sql +test> create table t1 (id int key,a int, index(a)); +test> create table t2 (id int key,a int, foreign key fk(a) references t1(id) ON DELETE CASCADE); +test> insert into t1 values (1, 1); +test> insert into t2 values (1, 1); +test> insert into t2 values (1, 2); +(1062, "Duplicate entry '1' for key 't2.PRIMARY'") +test> insert ignore into t2 values (1, 2); +Query OK, 0 rows affected +``` + +### MATCH FULL or MATCH SIMPLE + +This definition is from [CRDB](https://www.cockroachlabs.com/docs/v22.1/foreign-key.html#match-composite-foreign-keys-with-match-simple-and-match-full). MySQL doesn't mention it, here is a MySQL test case: + +Here is an MySQL example: + +```sql +create table t1 (i int, a int,b int, index(a,b)) ; +create table t (a int, b int, foreign key fk_a(a,b) references test.t1(a,b)); + +test> insert into t values (null,1); +Query OK, 1 row affected +test> insert into t values (null,null); +Query OK, 1 row affected +test> insert into t values (1,null); +Query OK, 1 row affected +``` + +## reference + +- [MySQL FOREIGN KEY Constraints Document](https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html#foreign-key-adding) +- [3 Common Foreign Key Mistakes (And How to Avoid Them)](https://www.cockroachlabs.com/blog/common-foreign-key-mistakes/) +- [Hidden Cost of Foreign Key Constraints in MySQL](https://www.percona.com/blog/hidden-cost-of-foreign-key-constraints-in-MySQL/) +- [DDL Queries on Foreign Key Columns in MySQL/PXC](https://www.percona.com/blog/2019/06/04/ddl-queries-foreign-key-columns-mysql-pxc/) diff --git a/docs/design/2022-07-20-session-manager.md b/docs/design/2022-07-20-session-manager.md index 59d4d2b64feac..d50092180ac07 100644 --- a/docs/design/2022-07-20-session-manager.md +++ b/docs/design/2022-07-20-session-manager.md @@ -67,7 +67,7 @@ When the Session Manager migrates a session, it needs to authenticate with the n It's unsafe to save user passwords in the Session Manager, so we use a token-based authentication: -1. The administrator places a self-signed certificate on each TiDB server. The certificate and key paths are defined by global variables `tidb_auth_signing_cert` and `tidb_auth_signing_key`. The certificates on all the servers are the same so that a message encrypted by one server can be decrypted by another. +1. The administrator places a self-signed certificate on each TiDB server. The certificate and key paths are defined by configurations `security.session-token-signing-cert` and `security.session-token-signing-key`. The certificates on all the servers are the same so that a message encrypted by one server can be decrypted by another. 2. When the Session Manager is going to migrate a session from one TiDB instance to another, it queries the session token. The session token is composed by the username, token expiration time, and a signature. The signature is signed with the private key of the certificate. 3. The Session Manager then authenticates with the new TiDB server with a new auth-plugin. The session token acts as the password. The new server checks the username, token expiration time, and the signature. The signature should be verified by the public key. diff --git a/docs/design/2022-09-22-global-memory-control.md b/docs/design/2022-09-22-global-memory-control.md new file mode 100644 index 0000000000000..7eb3e04b307a2 --- /dev/null +++ b/docs/design/2022-09-22-global-memory-control.md @@ -0,0 +1,66 @@ +# Proposal: Global Memory Control + +* Authors: [wshwsh12](https://github.com/wshwsh12), [Xuhuaiyu](https://github.com/Xuhuaiyu) +* Tracking issue: [#37816](https://github.com/pingcap/tidb/issues/37816) + +## Abstract + +This proposes a design of how to control global memory of TiDB instance. + +## Background + +Currently, TiDB has a query-level memory control strategy `mem-quota-query`, which triggers Cancel when the memory usage of a single SQL exceeds `mem-quota-query`. However, there is currently no global memory control strategy. + +When TiDB has multiple SQLs whose memory usage does not exceed `mem-quota-query` or memory tracking inaccurate, it will lead to high memory usage or even OOM. + +Therefore, we need an observer to check whether the memory usage of the current system is normal. When there are some problems, try to control TiDB's memory no longer continue to grow, to reduce the risk of process crashes. + +## Goal + +- Control the TiDB execution memory within the system variable `tidb_server_memory_limit`. + +## Design + +New system variables: +- `tidb_server_memory_limit`: TiDB maintains the overall memory usage within `tidb_server_memory_limit` +- `tidb_server_memory_gc_trigger`: When TiDB memory usage reaches a certain percentage of `tidb_server_memory_limit`, try to take the initiative to trigger golang GC to release memory +- `tidb_server_memory_limit_sess_min_size`: The minimum memory of a session that can be killed by TiDB + +We need to implement the following three functions to control the memory usage of TiDB: +1. Kill the SQL with the most memory usage in the current system, when `HeapInuse` is larger than `tidb_server_memory_limit`. +2. Take the initiative to trigger `runtime.GC()`, when `HeapInuse` is large than `tidb_server_memory_limit`*`tidb_server_memory_limit_gc_trigger`. +3. Introduce some memory tables to observe the memory status of the current system. + +### Kill the SQL with the max memory usage + +New variables: + +1. Global variable `MemUsageTop1Tracker atomic.Pointer[Tracker]`: Indicates the Tracker with the largest memory usage. +2. The flag `NeedKill atomic.Bool` in the structure `Tracker`: Indicates whether the SQL for the current Tracker needs to be Killed. +3. `SessionID int64` in Structure Tracker: Indicates the Session ID corresponding to the current Tracker. + +Implements: + +#### How to get the current TiDB memory usage Top 1 +When `Tracker.Consume()` calling, check the following logic. If all are satisfied, update the `MemUsageTop1Tracker`. +1. Is it a Session-level Tracker? +2. Whether the flag `NeedKill` is false, to avoid cancel the current SQL twice +3. Whether the memory usage exceeds the threshold `tidb_server_memory_limit_sess_min_size`(default 128MB, can be dynamically adjusted), can be candidate of the `MemUsageTop1Tracker` +4. Is the memory usage of the current Tracker greater than the current `MemUsageTop1Tracker` + +#### How to Cancel the current top 1 memory usage and recycle memory in time +1. Create a goroutine that calls Golang's `ReadMemStat` interface in a 100 ms cycle. (Get the memory usage of the current TiDB instance) +2. If the `heapInuse` of the current instance is greater than `tidb_server_memory_limit`, set `MemUsageTop1Tracker`'s `NeedKill` flag. (Sends a Kill signal) +3. When the SQL call to `Tracker.Consume()`, check its own `NeedKill` flag. If it is true, trigger Panic and exit. (terminates the execution of SQL) +4. Get the `SessionID` from the tracker and continuously query its status, waiting for it to complete exited. When SQL successfully exited, explicitly trigger Golang GC to release memory. (Wait for SQL exited completely and release memory) + +### Take the initiative to trigger GC + +The inspiration for this design comes from uber-go-gc-tuner: +1. Use the Go1.19 `SetMemoryLimit` feature to set the soft limit to `tidb_server_memory_limit` * `tidb_server_memory_limit_gc_trigger` to ensure that GC can be triggered when reaching the certain threshold. +2. After each GC, check whether this GC is caused by memory limit. If it is caused by this, temporarily set memory limit to infinite, and then set it back to the specified threshold after 1 minute. In this way, the problem of frequent GC caused by `heapInUse` being larger than the soft limit can be avoided. + +### Introduce some memory tables + +Introduce `performance_schema.memory_usage` and `performance_schema.memory_usage_ops_history` to display the current system memory usage and historical operations. +This can be implemented by maintaining a set of global data, and reading and outputting directly from the global data when querying. diff --git a/docs/design/2022-09-28-flashback-to-timestamp.md b/docs/design/2022-09-28-flashback-to-timestamp.md new file mode 100644 index 0000000000000..d71ff39404179 --- /dev/null +++ b/docs/design/2022-09-28-flashback-to-timestamp.md @@ -0,0 +1,111 @@ +# Proposal: Flashback To Timestamp +- Author(s): [Defined2014](https://github.com/Defined2014) and [JmPotato](https://github.com/JmPotato) +- Last updated: 2022-12-19 +- Tracking Issues: https://github.com/pingcap/tidb/issues/37197 and https://github.com/tikv/tikv/issues/13303 + +## Abstract + +This proposal aims to support `Flashback To Timestamp` and describe what `Flashback To Timestamp` should look like and how to implement it. + +## Background + +Some users want to `Flashback table/database/cluster` to the specified timestamp when there is a problem with the data like deleted some important keys, updated wrong values etc. + +TiDB uses MVCC to store key-values, which means it can easily get historical data at any timestamp. Based on this feature, TiDB already supports `Flashback To Timestamp`, for example, users can read historical data and update it through Snapshot Read which is not only inelegant, but also inefficient. + +Therefore, we propose to use a series of new SQL syntaxes to support this feature, and push down the read-write operations to storage side. + +## Detailed Design + +### Implementation Overview + +In TiKV, a multi-version concurrency control (MVCC) mechanism is introduced to avoid the overhead of introducing locks when data is updated concurrently. Under this mechanism, when TiDB modified data, it doesn't directly operate on the original value, but writes a data with the latest timestamp to cover it. The GC Worker in the background of TiDB will periodically update `tikv_gc_safe_point` and delete the version older than this point. `Flashback To Timestamp` is developmented based on this feature of TiKV. In order to improve execution efficiency and reduce data transmission overhead, TiKV has added two RPC interfaces called `PrepareFlashbackToVersion` and `FlashbackToVersion`. The protobuf related change shown below: + +```protobuf +// Preparing the flashback for a region/key range will "lock" the region +// so that there is no any read, write or schedule operation could be proposed before +// the actual flashback operation. +message PrepareFlashbackToVersionRequest { + Context context = 1; + bytes start_key = 2; + bytes end_key = 3; +} + +message PrepareFlashbackToVersionResponse { + errorpb.Error region_error = 1; + string error = 2; +} + +// Flashback the region to a specific point with the given `version`, please +// make sure the region is "locked" by `PrepareFlashbackToVersionRequest` first, +// otherwise this request will fail. +message FlashbackToVersionRequest { + Context context = 1; + // The TS version which the data should flashback to. + uint64 version = 2; + bytes start_key = 3; + bytes end_key = 4; + // The `start_ts`` and `commit_ts` which the newly written MVCC version will use. + uint64 start_ts = 5; + uint64 commit_ts = 6; +} + +message FlashbackToVersionResponse { + errorpb.Error region_error = 1; + string error = 2; +} +``` + +Then a `Flashback To Timestamp` DDL job can be simply divided into the following steps + +* Save values of some global variables and PD schedule. Those values will be changed during `Flashback`. + +* Pre-checks. After all checks are passed, TiDB will disable GC and closed PD schedule for the cluster. The specific checks are as follows: + * The FlashbackTS is after `tikv_gc_safe_point`. + * The FlashbackTS is before the minimal store resolved timestamp. + * No DDL job was executing at FlashbackTS. + * No running related DDL jobs. + +* TiDB get flashback key ranges and splits them into separate regions to avoid locking unrelated key ranges. Then TiDB send `PrepareFlashbackToVersion` RPC requests to lock regions in TiKV. Once locked, no more read, write and scheduling operations are allowed for those regions. + +* After locked all relevant key ranges, the DDL owner will update schema version and synchronize it to other TiDBs. When other TiDB applies the `SchemaDiff` of type `Flashback To Timestamp`, it will disconnect all relevant links. + +* Send `FlashbackToVersion` RPC requests to all relevant key ranges with same `commit_ts`. Each region handles its own flashback progress independently. + * Read the old MVCC data and write it again with the given `commit_ts` to pretend it's a new transaction commit. + * Release the Raft proposing lock and resume the lease read. + +* TiDB checks whether all the requests returned successfully, and retries those failed requests with the same `commit_ts`. After all requests finished, the DDL owner update the schema version with new type named `ReloadSchemaMap`, so that all TiDB servers regenerate the schema map from TiKV. + +* After `Flashback To Timestamp` is finished, TiDB will restore all changed global variables and restart PD schedule. At the same time, notify `Stats Handle` to reload statistics from TiKV. + +### New Syntax Overview + +TiDB will support 3 new syntaxes as follows. + +1. Flashback whole cluster except some system tables to the specified timestamp. + +```sql +FLASHBACK CLUSTER TO TIMESTAMP '2022-07-05 08:00:00'; +``` + +2. Flashback some databases to the specified timestamp. + +```sql +FLASHBACK DATABASE [db] TO TIMESTAMP '2022-07-05 08:00:00'; +``` + +3. Flashback some tables to the specified timestamp. + +```sql +FLASHBACK TABLE [table1], [table2] TO TIMESTAMP '2022-08-10 08:00:00'; +``` + +### Limitations and future Work + +1. Compare with the other DDL jobs, `Flashback To Timestamp` job cannot be rollbacked after some regions failure and also needs to resend rpc to all regions when ddl owner crashed. In the future, we will improve those two issues with a new TiKV interface and new distributed processing ddl framework. + +### Alternative Solutions + +1. Read historical data via `As of timestamp` clause and write back with the lastest timestamp. But it's much slower than `Flashback To Timestamp`, the data needs to be read to TiDB first then written back to TiKV. + +2. Use `Reset To Version` interface to delete all historical version. After this operation, the user can't find the deleted version any more and this interface is incompatible with snapshot read. diff --git a/docs/design/2022-09-29-reorganize-partition.md b/docs/design/2022-09-29-reorganize-partition.md new file mode 100644 index 0000000000000..56e380826efa7 --- /dev/null +++ b/docs/design/2022-09-29-reorganize-partition.md @@ -0,0 +1,180 @@ +# TiDB Design Documents + +- Author(s): [Mattias Jonsson](http://github.com/mjonss) +- Discussion PR: https://github.com/pingcap/tidb/issues/38535 +- Tracking Issue: https://github.com/pingcap/tidb/issues/15000 + +## Table of Contents + +* [Introduction](#introduction) +* [Motivation or Background](#motivation-or-background) +* [Detailed Design](#detailed-design) + * [Schema change states for REORGANIZE PARTITION](#schema-change-states-for-reorganize-partition) + * [Error Handling](#error-handling) + * [Notes](#notes) +* [Test Design](#test-design) + * [Benchmark Tests](#benchmark-tests) +* [Impacts & Risks](#impacts--risks) + +## Introduction + +Support ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (partition pNew1 values...) + +## Motivation or Background + +TiDB is currently lacking the support of changing the partitions of a partitioned table, it only supports adding and dropping LIST/RANGE partitions. +Supporting REORGANIZE PARTITIONs will allow RANGE partitioned tables to have a MAXVALUE partition to catch all values and split it into new ranges. Similar with LIST partitions where one can split or merge different partitions. + +When this is implemented, it will also allow future PRs transforming a non-partitioned table into a partitioned table as well as remove partitioning and make a partitioned table a normal non-partitioned table, as well as COALESCE PARTITION and ADD PARTITION for HASH partitioned tables, which is different ALTER statements but can use the same implementation as REORGANIZE PARTITION + +The operation should be online, and must handle multiple partitions as well as large data sets. + +Possible usage scenarios: +- Full table copy + - merging all partitions to a single table (ALTER TABLE t REMOVE PARTITIONING) + - splitting data from many to many partitions, like change the number of HASH partitions + - splitting a table to many partitions (ALTER TABLE t PARTITION BY ...) +- Partial table copy (not full table/all partitions) + - split one or more partitions + - merge two or more partitions + +These different use cases can have different optimizations, but the generic form must still be solved: +- N partitions, where each partition has M indexes + +First implementation should be based on the merge-txn (row-by-row batch read, update record key with new Physical Table ID, write) transactional batches and then create the indexes in batches index by index, partition by partition. +Later we can implement the ingest (lightning way) optimization, since DDL module are on the way of evolution to do reorg tasks more efficiency. + +## Detailed Design + +There are two parts of the design: +- Schema change states throughout the operation +- Reorganization implementation, which will be handled in the StateWriteReorganization state. + +Where the schema change states will clarify which different steps that will be done in which schema state transitions. + +### Schema change states for REORGANIZE PARTITION + +Since this operation will: +- create new partitions +- copy data from dropped partitions to new partitions and create their indexes +- change the partition definitions +- drop existing partitions + +It will use all these schema change stages: + + // StateNone means this schema element is absent and can't be used. + StateNone SchemaState = iota + - Check if the table structure after the ALTER is valid + - Use the generate physical table ids to each new partition (that was generated already by the client sending the ALTER command). + - Update the meta data with the new partitions (AddingDefinitions) and which partitions to be dropped (DroppingDefinitions), so that new transactions can double write. + - Set placement rules + - Set TiFlash Replicas + - Set legacy Bundles (non-sql placement) + - Set the state to StateDeleteOnly + + // StateDeleteOnly means we can only delete items for this schema element (the new partition). + StateDeleteOnly + - Set the state to StateWriteOnly + + // StateWriteOnly means we can use any write operation on this schema element, + // but outer can't read the changed data. + StateWriteOnly + - Set the state to StateWriteReorganization + + // StateWriteReorganization means we are re-organizing whole data after write only state. + StateWriteReorganization + - Copy the data from the partitions to be dropped (one at a time) and insert it into the new partitions. This needs a new backfillWorker implementation. + - Recreate the indexes one by one for the new partitions (one partition at a time) (create an element for each index and reuse the addIndexWorker). (Note: this can be optimized in the futute, either with the new fast add index implementation, based on lightning. Or by either writing the index entries at the same time as the records, in the previous step, or if the partitioning columns are included in the index or handle) + - Replace the old partitions with the new partitions in the metadata when the data copying is done + - Set the state to StateDeleteReorganization + + // StateDeleteReorganization means we are re-organizing whole data after delete only state. + StateDeleteReorganization - we are using this state in a slightly different way than the comment above says. + This state is needed since we cannot directly move from StateWriteReorganization to StatePublic. + Imagine that the StateWriteReorganization is complete and we are updating the schema version, then if a transaction seeing the new schema version is writing to the new partitions, then those changes needs to be written to the old partitions as well, so new transactions in other nodes using the older schema version can still see the changes. + - Remove the notion of new partitions (AddingDefinitions) and which partitions to be dropped (DroppingDefinitions) and double writing will stop when it goes to StatePublic. + - Register the range delete of the old partition data (in finishJob / deleteRange). + - Set the state to StatePublic + + // StatePublic means this schema element is ok for all write and read operations. + StatePublic + - Table structure is now complete and the table is ready to use with its new partitioning scheme + - Note that there is a background job for the GCWorker to do in its deleteRange function. + +During the reorganization happens in the background the normal write path needs to check if there are any new partitions in the metadata and also check if the updated/deleted/inserted row would match a new partition, and if so, also do the same operation in the new partition, just like during adding index or modify column operations currently does. (To be implemented in `(*partitionedTable) AddRecord/UpdateRecord/RemoveRecord`) + +Example of why an extra state between StateWriteReorganize and StatePublic is needed: + +```sql +-- table: +CREATE TABLE t (a int) PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1,2,3,4,5), PARTITION p1 VALUES IN (6,7,8,9,10)); +-- during alter operation: +ALTER TABLE t REORGANIZE PARTITION p0 INTO (PARTITION p0a VALUES IN (1,2,3), PARTITION p0b VALUES IN (4,5)); +``` + +Partition within parentheses `(p0a [1] p0b [0])` is hidden or to be deleted by GC/DeleteRange. Values in the brackets after the partition `p0a [2]`. + +If we go directly from StateWriteReorganize to StatePublic, then clients one schema version behind will not see changes to the new partitions: + +| Data (TiKV/Unistore) | TiDB client 1 | TiDB client 2 | +| --------------------------------------- | ------------------------------------ | ------------------------------------------------------------ | +| p0 [] p1 [] StateWriteReorganize | | | +| p0 [] p1 [] (p0a [] p0b []) | | | +| (p0 []) p1 [] p0a [] p0b [] StatePublic | | | +| (p0 []) p1 [] p0a [2] p0b [] | StatePublic INSERT INTO T VALUES (2) | | +| (p0 []) p1 [] p0a [2] p0b [] | | StateWriteReorganize SELECT * FROM t => [] (only sees p0,p1) | + + +But if we add a state between StateWriteReorganize and StatePublic and double write to the old partitions during that state it works: + + +| Data (TiKV/Unistore) | TiDB client 1 | TiDB client 2 | +| ------------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------- | +| p0 [] p1 [] (p0a [] p0b []) StateWriteReorganize | | | +| (p0 []) p1 [] p0a [] p0b [] StateDeleteReorganize | | | +| (p0 [2]) p1 [] p0a [2] p0b [] | StateDeleteReorganize INSERT INTO T VALUES (2) | | +| (p0 [2]) p1 [] p0a [2] p0b [] | | StateWriteReorganize SELECT * FROM t => [2] (only sees p0,p1) | +| (p0 [2]) p1 [] p0a [2] p0b [] StatePublic | | | +| (p0 [2]) p1 [] p0a [2] p0b [4] | StatePublic INSERT INTO T VALUES (4) | | +| (p0 [2]) p1 [] p0a [2] p0b [4] | | StateDeleteReorganize SELECT * FROM t => [2,4] (sees p0a,p0b,p1) | + + +### Error handling + +If any non-retryable error occurs, we will call onDropTablePartition and adjust the logic in that function to also handle the roll back of reorganize partition, in a similar way as it does with model.ActionAddTablePartition. + +### Notes + +Note that parser support already exists. +There should be no issues with upgrading, and downgrade will not be supported during the DDL. + +Notes: +- statistics should be removed from the old partitions. +- statistics will not be generated for the new partitions (future optimization possible, to get statistics during the data copying?) +- the global statistics (table level) will remain the same, since the data has not changed. +- this DDL will be online, while MySQL is blocking on MDL. + +## Test Design + +Re-use tests from other DDLs like Modify column, but adjust them for Reorganize partition. +A separate test plan will be created and a test report will be written and signed off when the tests are completed. + +### Benchmark Tests + +Correctness and functionality is higher priority than performance. + +## Impacts & Risks + +Impacts: +- better usability of partitioned tables +- online alter in TiDB, where MySQL is blocking +- all affected data needs to be read (CPU/IO/Network load on TiDB/PD/TiKV), even multiple times in case of indexes. +- all data needs to be writted (duplicated, both row-data and indexes), including transaction logs (more disk space on TiKV, CPU/IO/Network load on TiDB/PD/TiKV and TiFlash if configured on the table). + +Risks: +- introduction of bugs + - in the DDL code + - in the write path (double writing the changes for transactions running during the DDL) +- out of disk space +- out of memory +- general resource usage, resulting in lower performance of the cluster diff --git a/docs/design/2022-11-22-view-hint.md b/docs/design/2022-11-22-view-hint.md new file mode 100644 index 0000000000000..b780208a13f45 --- /dev/null +++ b/docs/design/2022-11-22-view-hint.md @@ -0,0 +1,134 @@ +# View Hint Design Doc +- Author: Reminiscent +- Tracking Issue: https://github.com/pingcap/tidb/issues/37887 + +## Background +Hints that specify a table generally refer to tables in the DELETE, SELECT, or UPDATE query block in which the hint occurs, not to tables inside any views referenced by the statement. So we introduce the view hint to specify the table in view instead of embedding the hint in the view. + +In Oracle, there are three ways to use the global hint. (Node: the `{}` part is only used for explanation) +```SQL +CREATE OR REPLACE VIEW v AS +SELECT {SEL$2} * from e1 join (select {SEL$3} * from e3) e2 on e1.a = e2.a; + +SELECT {SEL$1} * FROM v; + +A. SELECT /*+ INDEX(v.e2.e3 idx) */ * FROM v; // /*+ INDEX(@SEL$1 v.e2.e3 idx) */ + +B. SELECT /*+ INDEX(@SEL$2 e2.e3 idx) */ * FROM v; + +C. SELECT /*+ INDEX(@SEL$3 e3 idx) */ * FROM v; +``` + +Compared with TiDB, Oracle has two differences: +1. Oracle can use `alias.table` to represent in subquery, such as e2.e3. Besides, TiDB can use `db.table` to represent a table. +2. The count for query block number treats view like a subquery, which means the select parts in view are counted. + +Based on the difference, there are some reasons why TiDB can not just use the grammar from Oracle: +1. Compatibility + 1. Grammar. + 1. We can not use the `alias.table` to represent in subquery, such as e2.e3. + 2. We can use `db.table` to represent a table. So if we want to use the `view.table` to represent a table in view, we should change the grammar or it will conflict with db.table. + 2. The count for the query block. + 1. Previously, the query block in view would not be counted. But now, if we take the view into consideration, it will change the origin count. For example, in the following part. The count of the query block for the `select a from t1` will be changed from `@SEL_2` to `@SEL_3`. So if we use the query block related hints for this part, it will be invalid or represent the content in the view. + +```SQL +CREATE OR REPLACE VIEW v AS +SELECT {SEL$2} * FROM t; + +SELECT {SEL$1} * FROM v JOIN (select {SEL$3} a from t1) t2 on v.a = t2.a; +``` + +So based on the above reasons, we should introduce another way to let hint take effect in the view. + +## Detailed Design +### How does origin hint framework work? +1. Parser: parse the sql text and get the basic information about the hint. Handle hint syntax error in this phase. +2. Optimizer: + 1. Divide and mark the query block. Besides, group the hints in the same query blocks. + 2. In the plan builder phase, when we try to build select. We will handle the hints in the current query block. Including doing some simple checks and building the hints structure which can be used by planner. + 3. When we build some logical operators, we will use the hints which belongs to the current query block. And tt will use the table in hint to match the table in the plan node. For example, when we build the `DataSource` operator, it will generate the possible access path based on the index hints. When we build the `Aggregation` operator, it will set the aggregation algorithm based on the agg hints. And for the `Join` operator, it will store the hint in the join node and use the hint information in the physical optimization phase. The warning about which table is not used in the hint will be recorded in this phase. + 4. Use the hint information in the physical optimization phase to determine which physical algorithm should be used. And if the hint can not take effect, it will report warning. For example, if the join can not use the index join, but we set the index join hint in the sql text. It will report related warnings. + +### View Hint Design +Based on the goal and current infrastructure for hint. I extend the current usage of the qb_name hint to a bigger scope to support the view hint. + +An example to show the usage of the current `qb_name` hint. +```SQL +select /*+ stream_agg(@qb) merge_join(t1@qb)*/ * from (select /*+ qb_name(qb) */ count(*) from t1 join t2 on t1.a = t2.a) tt; +``` +1. First, we define the name for some query blocks. +2. Then we can use the query block name to represent the query block. + +Based on the meaning of `qb_name` hint now, we can expand it to support the view. The basic idea is the same here. We define the query block name in the view first. And then we can use the query block name to represent the contents in the view. Now the grammar is expanded from +`qb_name(name)` in the query block which you want to rename +To +`qb_name(name, viewName@queryBlockNum . {viewName}@queryBlockNum . ...)` in the first query block to represent any query block. Besides, we will reset the count for query block in every view. It means, for every view, it always counts from 1 and it will not effect the outer part. +For example: +```SQL +create table t(a int, b int); +create table t1(a int, b int); +create table t2(a int, b int); + +create view v as select {@SEL_1}{5} t.a, t.b from t join (select {@SEL_2}{6} t1.a from t1 join t2 on t1.b=t2.b) tt on t.a = tt.a; + +create view v1 as select {@SEL_1}{3} t.a, t.b from t join (select {@SEL_2}{4} from t1 join v on t1.b=v.b) tt on t.a = tt.a; + +create view v2 as select {@SEL_1}{1} t.a, t.b from t join (select {@SEL_2}{2} t1.a from t1 join v1 join v3 on t1.b=v1.b) tt on t.a = tt.a; + +select {@SEL_1} * from v2; + +/* We can use the following part to represent the {1} - {6} */ +1: qb_name(v2_sel1, v2@sel_1 . @sel_1) +2: qb_name(v2_sel2, v2@sel_1 . @sel_2) +3: qb_name(v1_sel1, v2@sel_1 . v1@sel_2 . @sel_1) +4: qb_name(v1_sel2, v2@sel_1 . v1@sel_2 . @sel_2) +5: qb_name(v_sel1, v2@sel_1 . v1@sel_2 . v@sel_2 . @sel_1) +6: qb_name(v_sel2, v2@sel_1 . v1@sel_2 . v@sel_2 . @sel_2) +``` +Take the previous as example: +```SQL +CREATE OR REPLACE VIEW v AS +SELECT * from e1 join (select count(*) from e3) e2 on e1.a = e2.a; + + +/* In Oracle */ +A1. SELECT /*+ INDEX(v.e2.e3 idx) */ * FROM v; + +A2. SELECT /*+ INDEX(@SEL$1 v.e2.e3 idx) */ * FROM v; + +B. SELECT /*+ INDEX(@SEL$2 e2.e3 idx) */ * FROM v; + +C. SELECT /*+ INDEX(@SEL$3 e3 idx) */ * FROM v; + +/* In TiDB */ +SELECT /*+ qb_name(viewSub, v@sel_1 . @sel_2) use_index(e3@viewSub, idx) hash_agg(viewSub) */ * FROM v; +``` + +### Implementation +Parser part is easy to implement. Just to expand the origin `qb_name` hint grammar. The only problem maybe is how to express the nested view(use dot or blank or something else). + +For the planner part: +1. At the beginning of the optimization, we should handle the query block name hint for view and the other method hints for view. And group these hints based on the query block name. +2. When we try to build the data source from the view, we have to traverse all of the query blocks for views. Check whether the view name in hint can match the data source or not. If there are some hints that can match, we pass it to the `buildDataSourceFromView`. +3. When we try to build the view plan, we first handle the hints which are passed by the caller. Distinguish which hints belong to the current view and which belongs to the nested view. If the hint belongs to the current view, we transform the hint to the normal hint. If the hints belong to the nested view. Then we will do the same thing, like step2. + +Besides the planner part, we need support to show the query block for a sql to increase usability. The user can copy the result and use it in hint directly. + +### Support Scope +1. We can support almost all physical algorithm's hints. Like join hints/ agg hints/ index etc. +2. Do not support the leading hints which may be across the view. But we can support the leading hint in the same view. + +### Pros and Cons +Pros: +1. No compatibility problems. Just expand the usage of the existing hint. +2. It is easier to implement. It can use the origin hints' infrastructure as much as possible. +3. It can support almost all the hints which can take effect in the query block. Oracle can only support the join order, join method and access path hints. + +Cons: +1. It may not be easy to write the query block name hint for a view. +2. The user should define the query block name hint first. + +## Reference +[Oracle Global Hint](https://docs.oracle.com/cd/E18283_01/server.112/e16638/hintsref.htm#i27644) + + diff --git a/docs/logo_with_text.png b/docs/logo_with_text.png deleted file mode 100644 index 722bbf8f8c53a..0000000000000 Binary files a/docs/logo_with_text.png and /dev/null differ diff --git a/docs/tidb-architecture.png b/docs/tidb-architecture.png new file mode 100644 index 0000000000000..e3360c45258dd Binary files /dev/null and b/docs/tidb-architecture.png differ diff --git a/docs/tidb-logo-with-text.png b/docs/tidb-logo-with-text.png new file mode 100644 index 0000000000000..111465b9fc842 Binary files /dev/null and b/docs/tidb-logo-with-text.png differ diff --git a/domain/BUILD.bazel b/domain/BUILD.bazel index 1c4a433c79e86..859943b6c6672 100644 --- a/domain/BUILD.bazel +++ b/domain/BUILD.bazel @@ -6,8 +6,10 @@ go_library( "domain.go", "domain_sysvars.go", "domainctx.go", + "historical_stats.go", "optimize_trace.go", "plan_replayer.go", + "plan_replayer_dump.go", "schema_checker.go", "schema_validator.go", "sysvar_cache.go", @@ -30,10 +32,12 @@ go_library( "//errno", "//infoschema", "//infoschema/perfschema", + "//keyspace", "//kv", "//meta", "//metrics", "//owner", + "//parser", "//parser/ast", "//parser/model", "//parser/mysql", @@ -41,24 +45,34 @@ go_library( "//privilege/privileges", "//sessionctx", "//sessionctx/sessionstates", + "//sessionctx/stmtctx", "//sessionctx/variable", "//statistics/handle", "//telemetry", + "//ttl/ttlworker", "//types", "//util", + "//util/chunk", "//util/dbterror", "//util/domainutil", "//util/engine", + "//util/etcd", "//util/execdetails", "//util/expensivequery", "//util/logutil", + "//util/memory", "//util/memoryusagealarm", + "//util/printer", + "//util/replayer", "//util/servermemorylimit", "//util/sqlexec", + "//util/syncutil", + "@com_github_burntsushi_toml//:toml", "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_kvproto//pkg/metapb", + "@com_github_pingcap_kvproto//pkg/pdpb", "@com_github_pingcap_log//:log", "@com_github_stretchr_testify//require", "@com_github_tikv_client_go_v2//oracle", @@ -85,6 +99,7 @@ go_test( "domain_utils_test.go", "domainctx_test.go", "main_test.go", + "plan_replayer_handle_test.go", "plan_replayer_test.go", "schema_checker_test.go", "schema_validator_test.go", @@ -108,9 +123,11 @@ go_test( "//session", "//sessionctx/variable", "//store/mockstore", + "//testkit", "//testkit/testsetup", "//util", "//util/mock", + "//util/replayer", "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", diff --git a/domain/domain.go b/domain/domain.go index 61f19b22fa185..24f3dfb0547da 100644 --- a/domain/domain.go +++ b/domain/domain.go @@ -17,7 +17,9 @@ package domain import ( "context" "fmt" + "math" "math/rand" + "sort" "strconv" "strings" "sync" @@ -29,6 +31,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/kvproto/pkg/pdpb" "github.com/pingcap/log" "github.com/pingcap/tidb/bindinfo" "github.com/pingcap/tidb/br/pkg/streamhelper" @@ -43,6 +46,7 @@ import ( "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/infoschema/perfschema" + "github.com/pingcap/tidb/keyspace" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/metrics" @@ -57,16 +61,21 @@ import ( "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics/handle" "github.com/pingcap/tidb/telemetry" + "github.com/pingcap/tidb/ttl/ttlworker" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/domainutil" "github.com/pingcap/tidb/util/engine" + "github.com/pingcap/tidb/util/etcd" "github.com/pingcap/tidb/util/expensivequery" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/memoryusagealarm" + "github.com/pingcap/tidb/util/replayer" "github.com/pingcap/tidb/util/servermemorylimit" "github.com/pingcap/tidb/util/sqlexec" + "github.com/tikv/client-go/v2/tikv" "github.com/tikv/client-go/v2/txnkv/transaction" pd "github.com/tikv/pd/client" clientv3 "go.etcd.io/etcd/client/v3" @@ -108,13 +117,17 @@ type Domain struct { expensiveQueryHandle *expensivequery.Handle memoryUsageAlarmHandle *memoryusagealarm.Handle serverMemoryLimitHandle *servermemorylimit.Handle - wg util.WaitGroupWrapper - statsUpdating atomicutil.Int32 - cancel context.CancelFunc - indexUsageSyncLease time.Duration - dumpFileGcChecker *dumpFileGcChecker - expiredTimeStamp4PC types.Time - logBackupAdvancer *daemon.OwnerDaemon + // TODO: use Run for each process in future pr + wg *util.WaitGroupEnhancedWrapper + statsUpdating atomicutil.Int32 + cancel context.CancelFunc + indexUsageSyncLease time.Duration + dumpFileGcChecker *dumpFileGcChecker + planReplayerHandle *planReplayerHandle + expiredTimeStamp4PC types.Time + logBackupAdvancer *daemon.OwnerDaemon + historicalStatsWorker *HistoricalStatsWorker + ttlJobManager *ttlworker.JobManager serverID uint64 serverIDSession *concurrency.Session @@ -125,6 +138,11 @@ type Domain struct { sysProcesses SysProcesses mdlCheckTableInfo *mdlCheckTableInfo + + analyzeMu struct { + sync.Mutex + sctxs map[sessionctx.Context]bool + } } type mdlCheckTableInfo struct { @@ -174,6 +192,7 @@ func (do *Domain) loadInfoSchema(startTS uint64) (infoschema.InfoSchema, bool, i // 1. Not first time bootstrap loading, which needs a full load. // 2. It is newer than the current one, so it will be "the current one" after this function call. // 3. There are less 100 diffs. + // 4. No regenrated schema diff. startTime := time.Now() if currentSchemaVersion != 0 && neededSchemaVersion > currentSchemaVersion && neededSchemaVersion-currentSchemaVersion < 100 { is, relatedChanges, err := do.tryLoadSchemaDiffs(m, currentSchemaVersion, neededSchemaVersion) @@ -183,6 +202,7 @@ func (do *Domain) loadInfoSchema(startTS uint64) (infoschema.InfoSchema, bool, i zap.Int64("currentSchemaVersion", currentSchemaVersion), zap.Int64("neededSchemaVersion", neededSchemaVersion), zap.Duration("start time", time.Since(startTime)), + zap.Int64("gotSchemaVersion", is.SchemaMetaVersion()), zap.Int64s("phyTblIDs", relatedChanges.PhyTblIDS), zap.Uint64s("actionTypes", relatedChanges.ActionTypes)) return is, false, currentSchemaVersion, relatedChanges, nil @@ -201,7 +221,12 @@ func (do *Domain) loadInfoSchema(startTS uint64) (infoschema.InfoSchema, bool, i return nil, false, currentSchemaVersion, nil, err } - newISBuilder, err := infoschema.NewBuilder(do.Store(), do.sysFacHack).InitWithDBInfos(schemas, policies, neededSchemaVersion) + resourceGroups, err := do.fetchResourceGroups(m) + if err != nil { + return nil, false, currentSchemaVersion, nil, err + } + + newISBuilder, err := infoschema.NewBuilder(do.Store(), do.sysFacHack).InitWithDBInfos(schemas, policies, resourceGroups, neededSchemaVersion) if err != nil { return nil, false, currentSchemaVersion, nil, err } @@ -233,6 +258,14 @@ func (do *Domain) fetchPolicies(m *meta.Meta) ([]*model.PolicyInfo, error) { return allPolicies, nil } +func (do *Domain) fetchResourceGroups(m *meta.Meta) ([]*model.ResourceGroupInfo, error) { + allResourceGroups, err := m.ListResourceGroups() + if err != nil { + return nil, err + } + return allResourceGroups, nil +} + func (do *Domain) fetchAllSchemasWithTables(m *meta.Meta) ([]*model.DBInfo, error) { allSchemas, err := m.ListDatabases() if err != nil { @@ -333,12 +366,15 @@ func (do *Domain) tryLoadSchemaDiffs(m *meta.Meta, usedVersion, newVersion int64 if err != nil { return nil, nil, err } + if diff.RegenerateSchemaMap { + return nil, nil, errors.Errorf("Meets a schema diff with RegenerateSchemaMap flag") + } if canSkipSchemaCheckerDDL(diff.Type) { continue } phyTblIDs = append(phyTblIDs, IDs...) for i := 0; i < len(IDs); i++ { - actions = append(actions, uint64(1< 0 { - do.wg.Add(1) // Local store needs to get the change information for every DDL state in each session. - go do.loadSchemaInLoop(ctx, ddlLease) - } - do.wg.Run(do.mdlCheckLoop) - do.wg.Add(3) - go do.topNSlowQueryLoop() - go do.infoSyncerKeeper() - go do.globalConfigSyncerKeeper() + do.wg.Run(func() { + do.loadSchemaInLoop(ctx, ddlLease) + }, "loadSchemaInLoop") + } + do.wg.Run(do.mdlCheckLoop, "mdlCheckLoop") + do.wg.Run(do.topNSlowQueryLoop, "topNSlowQueryLoop") + do.wg.Run(do.infoSyncerKeeper, "infoSyncerKeeper") + do.wg.Run(do.globalConfigSyncerKeeper, "globalConfigSyncerKeeper") if !skipRegisterToDashboard { - do.wg.Add(1) - go do.topologySyncerKeeper() + do.wg.Run(do.topologySyncerKeeper, "topologySyncerKeeper") } if pdClient != nil { - do.wg.Add(1) - go do.closestReplicaReadCheckLoop(ctx, pdClient) + do.wg.Run(func() { + do.closestReplicaReadCheckLoop(ctx, pdClient) + }, "closestReplicaReadCheckLoop") } err = do.initLogBackup(ctx, pdClient) if err != nil { @@ -1051,6 +1084,11 @@ func (do *Domain) Init( return nil } +// SetOnClose used to set do.onClose func. +func (do *Domain) SetOnClose(onClose func()) { + do.onClose = onClose +} + func (do *Domain) initLogBackup(ctx context.Context, pdClient pd.Client) error { cfg := config.GetGlobalConfig() if pdClient == nil || do.etcdClient == nil { @@ -1067,7 +1105,7 @@ func (do *Domain) initLogBackup(ctx context.Context, pdClient pd.Client) error { if err != nil { return err } - do.wg.Run(loop) + do.wg.Run(loop, "logBackupAdvancer") return nil } @@ -1084,7 +1122,6 @@ func (do *Domain) closestReplicaReadCheckLoop(ctx context.Context, pdClient pd.C ticker := time.NewTicker(time.Minute) defer func() { ticker.Stop() - do.wg.Done() logutil.BgLogger().Info("closestReplicaReadCheckLoop exited.") }() for { @@ -1099,8 +1136,12 @@ func (do *Domain) closestReplicaReadCheckLoop(ctx context.Context, pdClient pd.C } } +// Periodically check and update the replica-read status when `tidb_replica_read` is set to "closest-adaptive" +// We disable "closest-adaptive" in following conditions to ensure the read traffic is evenly distributed across +// all AZs: +// - There are no TiKV servers in the AZ of this tidb instance +// - The AZ if this tidb contains more tidb than other AZ and this tidb's id is the bigger one. func (do *Domain) checkReplicaRead(ctx context.Context, pdClient pd.Client) error { - // fast path do.sysVarCache.RLock() replicaRead := do.sysVarCache.global[variable.TiDBReplicaRead] do.sysVarCache.RUnlock() @@ -1109,6 +1150,24 @@ func (do *Domain) checkReplicaRead(ctx context.Context, pdClient pd.Client) erro logutil.BgLogger().Debug("closest replica read is not enabled, skip check!", zap.String("mode", replicaRead)) return nil } + + serverInfo, err := infosync.GetServerInfo() + if err != nil { + return err + } + zone := "" + for k, v := range serverInfo.Labels { + if k == placement.DCLabelKey && v != "" { + zone = v + break + } + } + if zone == "" { + logutil.BgLogger().Debug("server contains no 'zone' label, disable closest replica read", zap.Any("labels", serverInfo.Labels)) + variable.SetEnableAdaptiveReplicaRead(false) + return nil + } + stores, err := pdClient.GetAllStores(ctx, pd.WithExcludeTombstone()) if err != nil { return err @@ -1128,32 +1187,48 @@ func (do *Domain) checkReplicaRead(ctx context.Context, pdClient pd.Client) erro } } - enabled := false - // if stores don't have zone labels or are distribued in 1 zone, just disable cloeset replica read. - if len(storeZones) > 1 { - enabled = true - servers, err := infosync.GetAllServerInfo(ctx) - if err != nil { - return err - } - for _, s := range servers { - if v, ok := s.Labels[placement.DCLabelKey]; ok && v != "" { - if _, ok := storeZones[v]; !ok { - enabled = false - break - } + // no stores in this AZ + if _, ok := storeZones[zone]; !ok { + variable.SetEnableAdaptiveReplicaRead(false) + return nil + } + + servers, err := infosync.GetAllServerInfo(ctx) + if err != nil { + return err + } + svrIdsInThisZone := make([]string, 0) + for _, s := range servers { + if v, ok := s.Labels[placement.DCLabelKey]; ok && v != "" { + if _, ok := storeZones[v]; ok { storeZones[v] += 1 - } - } - if enabled { - for _, count := range storeZones { - if count == 0 { - enabled = false - break + if v == zone { + svrIdsInThisZone = append(svrIdsInThisZone, s.ID) } } } } + enabledCount := math.MaxInt + for _, count := range storeZones { + if count < enabledCount { + enabledCount = count + } + } + // sort tidb in the same AZ by ID and disable the tidb with bigger ID + // because ID is unchangeable, so this is a simple and stable algorithm to select + // some instances across all tidb servers. + if enabledCount < len(svrIdsInThisZone) { + sort.Slice(svrIdsInThisZone, func(i, j int) bool { + return strings.Compare(svrIdsInThisZone[i], svrIdsInThisZone[j]) < 0 + }) + } + enabled := true + for _, s := range svrIdsInThisZone[enabledCount:] { + if s == serverInfo.ID { + enabled = false + break + } + } if variable.SetEnableAdaptiveReplicaRead(enabled) { logutil.BgLogger().Info("tidb server adaptive closest replica read is changed", zap.Bool("enable", enabled)) @@ -1268,10 +1343,8 @@ func (do *Domain) LoadPrivilegeLoop(sctx sessionctx.Context) error { duration = 10 * time.Minute } - do.wg.Add(1) - go func() { + do.wg.Run(func() { defer func() { - do.wg.Done() logutil.BgLogger().Info("loadPrivilegeInLoop exited.") util.Recover(metrics.LabelDomain, "loadPrivilegeInLoop", nil, false) }() @@ -1301,7 +1374,7 @@ func (do *Domain) LoadPrivilegeLoop(sctx sessionctx.Context) error { logutil.BgLogger().Error("load privilege failed", zap.Error(err)) } } - }() + }, "loadPrivilegeInLoop") return nil } @@ -1318,10 +1391,9 @@ func (do *Domain) LoadSysVarCacheLoop(ctx sessionctx.Context) error { if do.etcdClient != nil { watchCh = do.etcdClient.Watch(context.Background(), sysVarCacheKey) } - do.wg.Add(1) - go func() { + + do.wg.Run(func() { defer func() { - do.wg.Done() logutil.BgLogger().Info("LoadSysVarCacheLoop exited.") util.Recover(metrics.LabelDomain, "LoadSysVarCacheLoop", nil, false) }() @@ -1364,7 +1436,63 @@ func (do *Domain) LoadSysVarCacheLoop(ctx sessionctx.Context) error { logutil.BgLogger().Error("LoadSysVarCacheLoop failed", zap.Error(err)) } } - }() + }, "LoadSysVarCacheLoop") + return nil +} + +// WatchTiFlashComputeNodeChange create a routine to watch if the topology of tiflash_compute node is changed. +// TODO: tiflashComputeNodeKey is not put to etcd yet(finish this when AutoScaler is done) +// +// store cache will only be invalidated every n seconds. +func (do *Domain) WatchTiFlashComputeNodeChange() error { + var watchCh clientv3.WatchChan + if do.etcdClient != nil { + watchCh = do.etcdClient.Watch(context.Background(), tiflashComputeNodeKey) + } + duration := 10 * time.Second + do.wg.Run(func() { + defer func() { + logutil.BgLogger().Info("WatchTiFlashComputeNodeChange exit") + util.Recover(metrics.LabelDomain, "WatchTiFlashComputeNodeChange", nil, false) + }() + + var count int + var logCount int + for { + ok := true + var watched bool + select { + case <-do.exit: + return + case _, ok = <-watchCh: + watched = true + case <-time.After(duration): + } + if !ok { + logutil.BgLogger().Error("WatchTiFlashComputeNodeChange watch channel closed") + watchCh = do.etcdClient.Watch(context.Background(), tiflashComputeNodeKey) + count++ + if count > 10 { + time.Sleep(time.Duration(count) * time.Second) + } + continue + } + count = 0 + switch s := do.store.(type) { + case tikv.Storage: + logCount++ + s.GetRegionCache().InvalidateTiFlashComputeStores() + if logCount == 6 { + // Print log every 6*duration seconds. + logutil.BgLogger().Debug("tiflash_compute store cache invalied, will update next query", zap.Bool("watched", watched)) + logCount = 0 + } + default: + logutil.BgLogger().Debug("No need to watch tiflash_compute store cache for non-tikv store") + return + } + } + }, "WatchTiFlashComputeNodeChange") return nil } @@ -1399,10 +1527,8 @@ func (do *Domain) LoadBindInfoLoop(ctxForHandle sessionctx.Context, ctxForEvolve } func (do *Domain) globalBindHandleWorkerLoop(owner owner.Manager) { - do.wg.Add(1) - go func() { + do.wg.Run(func() { defer func() { - do.wg.Done() logutil.BgLogger().Info("globalBindHandleWorkerLoop exited.") util.Recover(metrics.LabelDomain, "globalBindHandleWorkerLoop", nil, false) }() @@ -1439,14 +1565,12 @@ func (do *Domain) globalBindHandleWorkerLoop(owner owner.Manager) { } } } - }() + }, "globalBindHandleWorkerLoop") } func (do *Domain) handleEvolvePlanTasksLoop(ctx sessionctx.Context, owner owner.Manager) { - do.wg.Add(1) - go func() { + do.wg.Run(func() { defer func() { - do.wg.Done() logutil.BgLogger().Info("handleEvolvePlanTasksLoop exited.") util.Recover(metrics.LabelDomain, "handleEvolvePlanTasksLoop", nil, false) }() @@ -1464,7 +1588,7 @@ func (do *Domain) handleEvolvePlanTasksLoop(ctx sessionctx.Context, owner owner. } } } - }() + }, "handleEvolvePlanTasksLoop") } // TelemetryReportLoop create a goroutine that reports usage data in a loop, it should be called only once @@ -1476,10 +1600,8 @@ func (do *Domain) TelemetryReportLoop(ctx sessionctx.Context) { logutil.BgLogger().Warn("Initial telemetry run failed", zap.Error(err)) } - do.wg.Add(1) - go func() { + do.wg.Run(func() { defer func() { - do.wg.Done() logutil.BgLogger().Info("TelemetryReportLoop exited.") util.Recover(metrics.LabelDomain, "TelemetryReportLoop", nil, false) }() @@ -1500,16 +1622,14 @@ func (do *Domain) TelemetryReportLoop(ctx sessionctx.Context) { } } } - }() + }, "TelemetryReportLoop") } // TelemetryRotateSubWindowLoop create a goroutine that rotates the telemetry window regularly. func (do *Domain) TelemetryRotateSubWindowLoop(ctx sessionctx.Context) { ctx.GetSessionVars().InRestrictedSQL = true - do.wg.Add(1) - go func() { + do.wg.Run(func() { defer func() { - do.wg.Done() logutil.BgLogger().Info("TelemetryRotateSubWindowLoop exited.") util.Recover(metrics.LabelDomain, "TelemetryRotateSubWindowLoop", nil, false) }() @@ -1521,19 +1641,124 @@ func (do *Domain) TelemetryRotateSubWindowLoop(ctx sessionctx.Context) { telemetry.RotateSubWindow() } } - }() + }, "TelemetryRotateSubWindowLoop") +} + +// SetupPlanReplayerHandle setup plan replayer handle +func (do *Domain) SetupPlanReplayerHandle(collectorSctx sessionctx.Context, workersSctxs []sessionctx.Context) { + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + do.planReplayerHandle = &planReplayerHandle{} + do.planReplayerHandle.planReplayerTaskCollectorHandle = &planReplayerTaskCollectorHandle{ + ctx: ctx, + sctx: collectorSctx, + } + taskCH := make(chan *PlanReplayerDumpTask, 16) + taskStatus := &planReplayerDumpTaskStatus{} + taskStatus.finishedTaskMu.finishedTask = map[replayer.PlanReplayerTaskKey]struct{}{} + taskStatus.runningTaskMu.runningTasks = map[replayer.PlanReplayerTaskKey]struct{}{} + + do.planReplayerHandle.planReplayerTaskDumpHandle = &planReplayerTaskDumpHandle{ + taskCH: taskCH, + status: taskStatus, + } + do.planReplayerHandle.planReplayerTaskDumpHandle.workers = make([]*planReplayerTaskDumpWorker, 0) + for i := 0; i < len(workersSctxs); i++ { + worker := &planReplayerTaskDumpWorker{ + ctx: ctx, + sctx: workersSctxs[i], + taskCH: taskCH, + status: taskStatus, + } + do.planReplayerHandle.planReplayerTaskDumpHandle.workers = append(do.planReplayerHandle.planReplayerTaskDumpHandle.workers, worker) + } +} + +// SetupHistoricalStatsWorker setups worker +func (do *Domain) SetupHistoricalStatsWorker(ctx sessionctx.Context) { + do.historicalStatsWorker = &HistoricalStatsWorker{ + tblCH: make(chan int64, 16), + sctx: ctx, + } +} + +// SetupDumpFileGCChecker setup sctx +func (do *Domain) SetupDumpFileGCChecker(ctx sessionctx.Context) { + do.dumpFileGcChecker.setupSctx(ctx) + do.dumpFileGcChecker.planReplayerTaskStatus = do.planReplayerHandle.status +} + +var planReplayerHandleLease atomic.Uint64 + +func init() { + planReplayerHandleLease.Store(uint64(10 * time.Second)) + enableDumpHistoricalStats.Store(true) +} + +// DisablePlanReplayerBackgroundJob4Test disable plan replayer handle for test +func DisablePlanReplayerBackgroundJob4Test() { + planReplayerHandleLease.Store(0) +} + +// DisableDumpHistoricalStats4Test disable historical dump worker for test +func DisableDumpHistoricalStats4Test() { + enableDumpHistoricalStats.Store(false) +} + +// StartPlanReplayerHandle start plan replayer handle job +func (do *Domain) StartPlanReplayerHandle() { + lease := planReplayerHandleLease.Load() + if lease < 1 { + return + } + do.wg.Run(func() { + logutil.BgLogger().Info("PlanReplayerTaskCollectHandle started") + tikcer := time.NewTicker(time.Duration(lease)) + defer func() { + tikcer.Stop() + util.Recover(metrics.LabelDomain, "PlanReplayerTaskCollectHandle", nil, false) + logutil.BgLogger().Info("PlanReplayerTaskCollectHandle exited.") + }() + for { + select { + case <-do.exit: + return + case <-tikcer.C: + err := do.planReplayerHandle.CollectPlanReplayerTask() + if err != nil { + logutil.BgLogger().Warn("plan replayer handle collect tasks failed", zap.Error(err)) + } + } + } + }, "PlanReplayerTaskCollectHandle") + + do.wg.Run(func() { + logutil.BgLogger().Info("PlanReplayerTaskDumpHandle started") + defer func() { + util.Recover(metrics.LabelDomain, "PlanReplayerTaskDumpHandle", nil, false) + logutil.BgLogger().Info("PlanReplayerTaskDumpHandle exited.") + }() + for _, worker := range do.planReplayerHandle.planReplayerTaskDumpHandle.workers { + go worker.run() + } + <-do.exit + do.planReplayerHandle.planReplayerTaskDumpHandle.Close() + }, "PlanReplayerTaskDumpHandle") +} + +// GetPlanReplayerHandle returns plan replayer handle +func (do *Domain) GetPlanReplayerHandle() *planReplayerHandle { + return do.planReplayerHandle } // DumpFileGcCheckerLoop creates a goroutine that handles `exit` and `gc`. func (do *Domain) DumpFileGcCheckerLoop() { - do.wg.Add(1) - go func() { + do.wg.Run(func() { + logutil.BgLogger().Info("dumpFileGcChecker started") gcTicker := time.NewTicker(do.dumpFileGcChecker.gcLease) defer func() { gcTicker.Stop() - do.wg.Done() - logutil.BgLogger().Info("dumpFileGcChecker exited.") util.Recover(metrics.LabelDomain, "dumpFileGcCheckerLoop", nil, false) + logutil.BgLogger().Info("dumpFileGcChecker exited.") }() for { select { @@ -1543,7 +1768,44 @@ func (do *Domain) DumpFileGcCheckerLoop() { do.dumpFileGcChecker.gcDumpFiles(time.Hour) } } - }() + }, "dumpFileGcChecker") +} + +// GetHistoricalStatsWorker gets historical workers +func (do *Domain) GetHistoricalStatsWorker() *HistoricalStatsWorker { + return do.historicalStatsWorker +} + +// EnableDumpHistoricalStats used to control whether enbale dump stats for unit test +var enableDumpHistoricalStats atomic.Bool + +// StartHistoricalStatsWorker start historical workers running +func (do *Domain) StartHistoricalStatsWorker() { + if !enableDumpHistoricalStats.Load() { + return + } + do.wg.Run(func() { + logutil.BgLogger().Info("HistoricalStatsWorker started") + defer func() { + util.Recover(metrics.LabelDomain, "HistoricalStatsWorkerLoop", nil, false) + logutil.BgLogger().Info("HistoricalStatsWorker exited.") + }() + for { + select { + case <-do.exit: + close(do.historicalStatsWorker.tblCH) + return + case tblID, ok := <-do.historicalStatsWorker.tblCH: + if !ok { + return + } + err := do.historicalStatsWorker.DumpHistoricalStats(tblID, do.StatsHandle()) + if err != nil { + logutil.BgLogger().Warn("dump historical stats failed", zap.Error(err), zap.Int64("tableID", tblID)) + } + } + } + }, "HistoricalStatsWorker") } // StatsHandle returns the statistic handle. @@ -1552,8 +1814,8 @@ func (do *Domain) StatsHandle() *handle.Handle { } // CreateStatsHandle is used only for test. -func (do *Domain) CreateStatsHandle(ctx sessionctx.Context) error { - h, err := handle.NewHandle(ctx, do.statsLease, do.sysSessionPool, &do.sysProcesses, do.ServerID) +func (do *Domain) CreateStatsHandle(ctx, initStatsCtx sessionctx.Context) error { + h, err := handle.NewHandle(ctx, initStatsCtx, do.statsLease, do.sysSessionPool, &do.sysProcesses, do.ServerID) if err != nil { return err } @@ -1575,9 +1837,49 @@ func (do *Domain) SetStatsUpdating(val bool) { } } +// ReleaseAnalyzeExec returned extra exec for Analyze +func (do *Domain) ReleaseAnalyzeExec(sctxs []sessionctx.Context) { + do.analyzeMu.Lock() + defer do.analyzeMu.Unlock() + for _, ctx := range sctxs { + do.analyzeMu.sctxs[ctx] = false + } +} + +// FetchAnalyzeExec get needed exec for analyze +func (do *Domain) FetchAnalyzeExec(need int) []sessionctx.Context { + if need < 1 { + return nil + } + count := 0 + r := make([]sessionctx.Context, 0) + do.analyzeMu.Lock() + defer do.analyzeMu.Unlock() + for sctx, used := range do.analyzeMu.sctxs { + if used { + continue + } + r = append(r, sctx) + do.analyzeMu.sctxs[sctx] = true + count++ + if count >= need { + break + } + } + return r +} + +// SetupAnalyzeExec setups exec for Analyze Executor +func (do *Domain) SetupAnalyzeExec(ctxs []sessionctx.Context) { + do.analyzeMu.sctxs = make(map[sessionctx.Context]bool) + for _, ctx := range ctxs { + do.analyzeMu.sctxs[ctx] = false + } +} + // LoadAndUpdateStatsLoop loads and updates stats info. -func (do *Domain) LoadAndUpdateStatsLoop(ctxs []sessionctx.Context) error { - if err := do.UpdateTableStatsLoop(ctxs[0]); err != nil { +func (do *Domain) LoadAndUpdateStatsLoop(ctxs []sessionctx.Context, initStatsCtx sessionctx.Context) error { + if err := do.UpdateTableStatsLoop(ctxs[0], initStatsCtx); err != nil { return err } do.StartLoadStatsSubWorkers(ctxs[1:]) @@ -1587,9 +1889,9 @@ func (do *Domain) LoadAndUpdateStatsLoop(ctxs []sessionctx.Context) error { // UpdateTableStatsLoop creates a goroutine loads stats info and updates stats info in a loop. // It will also start a goroutine to analyze tables automatically. // It should be called only once in BootstrapSession. -func (do *Domain) UpdateTableStatsLoop(ctx sessionctx.Context) error { +func (do *Domain) UpdateTableStatsLoop(ctx, initStatsCtx sessionctx.Context) error { ctx.GetSessionVars().InRestrictedSQL = true - statsHandle, err := handle.NewHandle(ctx, do.statsLease, do.sysSessionPool, &do.sysProcesses, do.ServerID) + statsHandle, err := handle.NewHandle(ctx, initStatsCtx, do.statsLease, do.sysSessionPool, &do.sysProcesses, do.ServerID) if err != nil { return err } @@ -1597,20 +1899,21 @@ func (do *Domain) UpdateTableStatsLoop(ctx sessionctx.Context) error { do.ddl.RegisterStatsHandle(statsHandle) // Negative stats lease indicates that it is in test, it does not need update. if do.statsLease >= 0 { - do.wg.Run(do.loadStatsWorker) + do.wg.Run(do.loadStatsWorker, "loadStatsWorker") } owner := do.newOwnerManager(handle.StatsPrompt, handle.StatsOwnerKey) if do.indexUsageSyncLease > 0 { - do.wg.Add(1) - go do.syncIndexUsageWorker(owner) + do.wg.Run(func() { + do.syncIndexUsageWorker(owner) + }, "syncIndexUsageWorker") } if do.statsLease <= 0 { return nil } do.SetStatsUpdating(true) - do.wg.Run(func() { do.updateStatsWorker(ctx, owner) }) - do.wg.Run(func() { do.autoAnalyzeWorker(owner) }) - do.wg.Run(func() { do.gcAnalyzeHistory(owner) }) + do.wg.Run(func() { do.updateStatsWorker(ctx, owner) }, "updateStatsWorker") + do.wg.Run(func() { do.autoAnalyzeWorker(owner) }, "autoAnalyzeWorker") + do.wg.Run(func() { do.gcAnalyzeHistory(owner) }, "gcAnalyzeHistory") return nil } @@ -1620,7 +1923,7 @@ func (do *Domain) StartLoadStatsSubWorkers(ctxList []sessionctx.Context) { for i, ctx := range ctxList { statsHandle.StatsLoad.SubCtxs[i] = ctx do.wg.Add(1) - go statsHandle.SubLoadWorker(ctx, do.exit, &do.wg) + go statsHandle.SubLoadWorker(ctx, do.exit, do.wg) } } @@ -1647,15 +1950,17 @@ func (do *Domain) loadStatsWorker() { lease = 3 * time.Second } loadTicker := time.NewTicker(lease) + updStatsHealthyTicker := time.NewTicker(20 * lease) defer func() { loadTicker.Stop() + updStatsHealthyTicker.Stop() logutil.BgLogger().Info("loadStatsWorker exited.") }() statsHandle := do.StatsHandle() t := time.Now() err := statsHandle.InitStats(do.InfoSchema()) if err != nil { - logutil.BgLogger().Debug("init stats info failed", zap.Error(err)) + logutil.BgLogger().Error("init stats info failed", zap.Duration("take time", time.Since(t)), zap.Error(err)) } else { logutil.BgLogger().Info("init stats info time", zap.Duration("take time", time.Since(t))) } @@ -1674,6 +1979,8 @@ func (do *Domain) loadStatsWorker() { if err != nil { logutil.BgLogger().Debug("load histograms failed", zap.Error(err)) } + case <-updStatsHealthyTicker.C: + statsHandle.UpdateStatsHealthyMetrics() case <-do.exit: return } @@ -1687,7 +1994,6 @@ func (do *Domain) syncIndexUsageWorker(owner owner.Manager) { handle := do.StatsHandle() defer func() { idxUsageSyncTicker.Stop() - do.wg.Done() logutil.BgLogger().Info("syncIndexUsageWorker exited.") }() for { @@ -1710,14 +2016,38 @@ func (do *Domain) syncIndexUsageWorker(owner owner.Manager) { } } +func (do *Domain) updateStatsWorkerExitPreprocessing(statsHandle *handle.Handle, owner owner.Manager) { + ch := make(chan struct{}, 1) + timeout, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + go func() { + logutil.BgLogger().Info("updateStatsWorker is going to exit, start to flush stats") + statsHandle.FlushStats() + logutil.BgLogger().Info("updateStatsWorker ready to release owner") + owner.Cancel() + ch <- struct{}{} + }() + select { + case <-ch: + logutil.BgLogger().Info("updateStatsWorker exit preprocessing finished") + return + case <-timeout.Done(): + logutil.BgLogger().Warn("updateStatsWorker exit preprocessing timeout, force exiting") + return + } +} + func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) { defer util.Recover(metrics.LabelDomain, "updateStatsWorker", nil, false) + logutil.BgLogger().Info("updateStatsWorker started.") lease := do.statsLease deltaUpdateTicker := time.NewTicker(20 * lease) gcStatsTicker := time.NewTicker(100 * lease) dumpFeedbackTicker := time.NewTicker(200 * lease) loadFeedbackTicker := time.NewTicker(5 * lease) + loadLockedTablesTicker := time.NewTicker(5 * lease) dumpColStatsUsageTicker := time.NewTicker(100 * lease) + readMemTricker := time.NewTicker(memory.ReadMemInterval) statsHandle := do.StatsHandle() defer func() { dumpColStatsUsageTicker.Stop() @@ -1725,20 +2055,21 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) dumpFeedbackTicker.Stop() gcStatsTicker.Stop() deltaUpdateTicker.Stop() + readMemTricker.Stop() do.SetStatsUpdating(false) + util.Recover(metrics.LabelDomain, "updateStatsWorker", nil, false) logutil.BgLogger().Info("updateStatsWorker exited.") }() for { select { case <-do.exit: - statsHandle.FlushStats() - owner.Cancel() + do.updateStatsWorkerExitPreprocessing(statsHandle, owner) return // This channel is sent only by ddl owner. case t := <-statsHandle.DDLEventCh(): err := statsHandle.HandleDDLEvent(t) if err != nil { - logutil.BgLogger().Debug("handle ddl event failed", zap.Error(err)) + logutil.BgLogger().Error("handle ddl event failed", zap.String("event", t.String()), zap.Error(err)) } case <-deltaUpdateTicker.C: err := statsHandle.DumpStatsDeltaToKV(handle.DumpDelta) @@ -1755,6 +2086,11 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) if err != nil { logutil.BgLogger().Debug("update stats using feedback failed", zap.Error(err)) } + case <-loadLockedTablesTicker.C: + err := statsHandle.LoadLockedTables() + if err != nil { + logutil.BgLogger().Debug("load locked table failed", zap.Error(err)) + } case <-dumpFeedbackTicker.C: err := statsHandle.DumpStatsFeedbackToKV() if err != nil { @@ -1773,6 +2109,9 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) if err != nil { logutil.BgLogger().Debug("dump column stats usage failed", zap.Error(err)) } + + case <-readMemTricker.C: + memory.ForceReadMemStats() } } } @@ -1839,8 +2178,9 @@ func (do *Domain) ServerMemoryLimitHandle() *servermemorylimit.Handle { } const ( - privilegeKey = "/tidb/privilege" - sysVarCacheKey = "/tidb/sysvars" + privilegeKey = "/tidb/privilege" + sysVarCacheKey = "/tidb/sysvars" + tiflashComputeNodeKey = "/tiflash/new_tiflash_compute_nodes" ) // NotifyUpdatePrivilege updates privilege key in etcd, TiDB client that watches @@ -1877,7 +2217,7 @@ func (do *Domain) NotifyUpdatePrivilege() error { // NotifyUpdateSysVarCache updates the sysvar cache key in etcd, which other TiDB // clients are subscribed to for updates. For the caller, the cache is also built // synchronously so that the effect is immediate. -func (do *Domain) NotifyUpdateSysVarCache() { +func (do *Domain) NotifyUpdateSysVarCache(updateLocal bool) { if do.etcdClient != nil { row := do.etcdClient.KV _, err := row.Put(context.Background(), sysVarCacheKey, "") @@ -1886,17 +2226,20 @@ func (do *Domain) NotifyUpdateSysVarCache() { } } // update locally - if err := do.rebuildSysVarCache(nil); err != nil { - logutil.BgLogger().Error("rebuilding sysvar cache failed", zap.Error(err)) + if updateLocal { + if err := do.rebuildSysVarCache(nil); err != nil { + logutil.BgLogger().Error("rebuilding sysvar cache failed", zap.Error(err)) + } } } // LoadSigningCertLoop loads the signing cert periodically to make sure it's fresh new. -func (do *Domain) LoadSigningCertLoop() { - do.wg.Add(1) - go func() { +func (do *Domain) LoadSigningCertLoop(signingCert, signingKey string) { + sessionstates.SetCertPath(signingCert) + sessionstates.SetKeyPath(signingKey) + + do.wg.Run(func() { defer func() { - do.wg.Done() logutil.BgLogger().Debug("loadSigningCertLoop exited.") util.Recover(metrics.LabelDomain, "LoadSigningCertLoop", nil, false) }() @@ -1908,7 +2251,7 @@ func (do *Domain) LoadSigningCertLoop() { return } } - }() + }, "loadSigningCertLoop") } // ServerID gets serverID. @@ -2144,6 +2487,32 @@ func (do *Domain) serverIDKeeper() { } } +// StartTTLJobManager creates and starts the ttl job manager +func (do *Domain) StartTTLJobManager() { + do.wg.Run(func() { + defer func() { + logutil.BgLogger().Info("ttlJobManager exited.") + }() + + ttlJobManager := ttlworker.NewJobManager(do.ddl.GetID(), do.sysSessionPool, do.store, do.etcdClient) + do.ttlJobManager = ttlJobManager + ttlJobManager.Start() + + <-do.exit + + ttlJobManager.Stop() + err := ttlJobManager.WaitStopped(context.Background(), 30*time.Second) + if err != nil { + logutil.BgLogger().Warn("fail to wait until the ttl job manager stop", zap.Error(err)) + } + }, "ttlJobManager") +} + +// TTLJobManager returns the ttl job manager on this domain +func (do *Domain) TTLJobManager() *ttlworker.JobManager { + return do.ttlJobManager +} + func init() { initByLDFlagsForGlobalKill() telemetry.GetDomainInfoSchema = func(ctx sessionctx.Context) infoschema.InfoSchema { diff --git a/domain/domain_sysvars.go b/domain/domain_sysvars.go index 19c02a9572934..6988cedcc9b52 100644 --- a/domain/domain_sysvars.go +++ b/domain/domain_sysvars.go @@ -15,6 +15,7 @@ package domain import ( + "context" "strconv" "time" @@ -33,6 +34,12 @@ func (do *Domain) initDomainSysVars() { variable.SetStatsCacheCapacity.Store(do.setStatsCacheCapacity) pdClientDynamicOptionFunc := do.setPDClientDynamicOption variable.SetPDClientDynamicOption.Store(&pdClientDynamicOptionFunc) + + variable.SetExternalTimestamp = do.setExternalTimestamp + variable.GetExternalTimestamp = do.getExternalTimestamp + + setGlobalResourceControlFunc := do.setGlobalResourceControl + variable.SetGlobalResourceControl.Store(&setGlobalResourceControlFunc) } // setStatsCacheCapacity sets statsCache cap @@ -63,6 +70,15 @@ func (do *Domain) setPDClientDynamicOption(name, sVal string) { } } +func (do *Domain) setGlobalResourceControl(enable bool) { + if enable { + variable.EnableGlobalResourceControlFunc() + } else { + variable.DisableGlobalResourceControlFunc() + } + logutil.BgLogger().Info("set resource control", zap.Bool("enable", enable)) +} + // updatePDClient is used to set the dynamic option into the PD client. func (do *Domain) updatePDClient(option pd.DynamicOption, val interface{}) error { store, ok := do.store.(interface{ GetPDClient() pd.Client }) @@ -75,3 +91,11 @@ func (do *Domain) updatePDClient(option pd.DynamicOption, val interface{}) error } return pdClient.UpdateOption(option, val) } + +func (do *Domain) setExternalTimestamp(ctx context.Context, ts uint64) error { + return do.store.GetOracle().SetExternalTimestamp(ctx, ts) +} + +func (do *Domain) getExternalTimestamp(ctx context.Context) (uint64, error) { + return do.store.GetOracle().GetExternalTimestamp(ctx) +} diff --git a/domain/domain_test.go b/domain/domain_test.go index 621f0fb2c431f..bd9287fe730ec 100644 --- a/domain/domain_test.go +++ b/domain/domain_test.go @@ -17,6 +17,8 @@ package domain import ( "context" "crypto/tls" + "encoding/json" + "fmt" "net" "runtime" "testing" @@ -66,7 +68,7 @@ func TestInfo(t *testing.T) { Storage: s, pdAddrs: []string{cluster.Members[0].GRPCURL()}} ddlLease := 80 * time.Millisecond - dom := NewDomain(mockStore, ddlLease, 0, 0, 0, mockFactory, nil) + dom := NewDomain(mockStore, ddlLease, 0, 0, 0, mockFactory) defer func() { dom.Close() err := s.Close() @@ -169,7 +171,7 @@ func TestStatWorkRecoverFromPanic(t *testing.T) { require.NoError(t, err) ddlLease := 80 * time.Millisecond - dom := NewDomain(store, ddlLease, 0, 0, 0, mockFactory, nil) + dom := NewDomain(store, ddlLease, 0, 0, 0, mockFactory) metrics.PanicCounter.Reset() // Since the stats lease is 0 now, so create a new ticker will panic. @@ -236,7 +238,7 @@ func TestClosestReplicaReadChecker(t *testing.T) { require.NoError(t, err) ddlLease := 80 * time.Millisecond - dom := NewDomain(store, ddlLease, 0, 0, 0, mockFactory, nil) + dom := NewDomain(store, ddlLease, 0, 0, 0, mockFactory) defer func() { dom.Close() require.Nil(t, store.Close()) @@ -247,7 +249,29 @@ func TestClosestReplicaReadChecker(t *testing.T) { } dom.sysVarCache.Unlock() - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/domain/infosync/mockGetAllServerInfo", `return("")`)) + makeFailpointRes := func(v interface{}) string { + bytes, err := json.Marshal(v) + require.NoError(t, err) + return fmt.Sprintf("return(`%s`)", string(bytes)) + } + + mockedAllServerInfos := map[string]*infosync.ServerInfo{ + "s1": { + ID: "s1", + Labels: map[string]string{ + "zone": "zone1", + }, + }, + "s2": { + ID: "s2", + Labels: map[string]string{ + "zone": "zone2", + }, + }, + } + + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/domain/infosync/mockGetAllServerInfo", makeFailpointRes(mockedAllServerInfos))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/domain/infosync/mockGetServerInfo", makeFailpointRes(mockedAllServerInfos["s2"]))) stores := []*metapb.Store{ { @@ -304,8 +328,77 @@ func TestClosestReplicaReadChecker(t *testing.T) { require.False(t, variable.IsAdaptiveReplicaReadEnabled()) } + // partial matches + mockedAllServerInfos = map[string]*infosync.ServerInfo{ + "s1": { + ID: "s1", + Labels: map[string]string{ + "zone": "zone1", + }, + }, + "s2": { + ID: "s2", + Labels: map[string]string{ + "zone": "zone2", + }, + }, + "s22": { + ID: "s22", + Labels: map[string]string{ + "zone": "zone2", + }, + }, + "s3": { + ID: "s3", + Labels: map[string]string{ + "zone": "zone3", + }, + }, + "s4": { + ID: "s4", + Labels: map[string]string{ + "zone": "zone4", + }, + }, + } + pdClient.stores = stores + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/domain/infosync/mockGetAllServerInfo", makeFailpointRes(mockedAllServerInfos))) + cases := []struct { + id string + matches bool + }{ + { + id: "s1", + matches: true, + }, + { + id: "s2", + matches: true, + }, + { + id: "s22", + matches: false, + }, + { + id: "s3", + matches: true, + }, + { + id: "s4", + matches: false, + }, + } + for _, c := range cases { + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/domain/infosync/mockGetServerInfo", makeFailpointRes(mockedAllServerInfos[c.id]))) + variable.SetEnableAdaptiveReplicaRead(!c.matches) + err = dom.checkReplicaRead(ctx, pdClient) + require.Nil(t, err) + require.Equal(t, c.matches, variable.IsAdaptiveReplicaReadEnabled()) + } + variable.SetEnableAdaptiveReplicaRead(true) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/domain/infosync/mockGetAllServerInfo")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/domain/infosync/mockGetServerInfo")) } type mockInfoPdClient struct { diff --git a/domain/globalconfigsync/globalconfig.go b/domain/globalconfigsync/globalconfig.go index 5bbb6a260e3c8..020e5dde8491c 100644 --- a/domain/globalconfigsync/globalconfig.go +++ b/domain/globalconfigsync/globalconfig.go @@ -1,4 +1,4 @@ -// Copyright 2021 PingCAP, Inc. +// Copyright 2023 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,6 +22,9 @@ import ( "go.uber.org/zap" ) +// GlobalConfigPath as Etcd prefix +const GlobalConfigPath = "/global/config/" + // GlobalConfigSyncer is used to sync pd global config. type GlobalConfigSyncer struct { pd pd.Client @@ -41,7 +44,7 @@ func (s *GlobalConfigSyncer) StoreGlobalConfig(ctx context.Context, item pd.Glob if s.pd == nil { return nil } - err := s.pd.StoreGlobalConfig(ctx, []pd.GlobalConfigItem{item}) + err := s.pd.StoreGlobalConfig(ctx, GlobalConfigPath, []pd.GlobalConfigItem{item}) if err != nil { return err } diff --git a/domain/globalconfigsync/globalconfig_test.go b/domain/globalconfigsync/globalconfig_test.go index a3cbd5e143a0b..455b79f2276b4 100644 --- a/domain/globalconfigsync/globalconfig_test.go +++ b/domain/globalconfigsync/globalconfig_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 PingCAP, Inc. +// Copyright 2023 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package globalconfigsync_test import ( "context" + "path" "runtime" "testing" "time" @@ -36,6 +37,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) @@ -57,11 +59,12 @@ func TestGlobalConfigSyncer(t *testing.T) { syncer.Notify(pd.GlobalConfigItem{Name: "a", Value: "b"}) err = syncer.StoreGlobalConfig(context.Background(), <-syncer.NotifyCh) require.NoError(t, err) - items, err := client.LoadGlobalConfig(context.Background(), []string{"a"}) + items, revision, err := client.LoadGlobalConfig(context.Background(), globalconfigsync.GlobalConfigPath) require.NoError(t, err) - require.Equal(t, len(items), 1) - require.Equal(t, items[0].Name, "/global/config/a") - require.Equal(t, items[0].Value, "b") + require.Equal(t, 1, len(items)) + require.Equal(t, path.Join(globalconfigsync.GlobalConfigPath, "a"), items[0].Name) + require.Equal(t, int64(0), revision) + require.Equal(t, "b", items[0].Value) } func TestStoreGlobalConfig(t *testing.T) { @@ -87,19 +90,23 @@ func TestStoreGlobalConfig(t *testing.T) { _, err = se.Execute(context.Background(), "set @@global.tidb_enable_top_sql=1;") require.NoError(t, err) + _, err = se.Execute(context.Background(), "set @@global.tidb_source_id=2;") + require.NoError(t, err) for i := 0; i < 20; i++ { time.Sleep(100 * time.Millisecond) client := store.(kv.StorageWithPD).GetPDClient() // enable top sql will be translated to enable_resource_metering - items, err := client.LoadGlobalConfig(context.Background(), []string{"enable_resource_metering"}) + items, _, err := client.LoadGlobalConfig(context.Background(), globalconfigsync.GlobalConfigPath) require.NoError(t, err) - if len(items) == 1 && items[0].Value == "" { + if len(items) == 2 && items[0].Value == "" { continue } - require.Len(t, items, 1) - require.Equal(t, items[0].Name, "/global/config/enable_resource_metering") + require.Len(t, items, 2) + require.Equal(t, items[0].Name, path.Join(globalconfigsync.GlobalConfigPath, "enable_resource_metering")) require.Equal(t, items[0].Value, "true") + require.Equal(t, items[1].Name, path.Join(globalconfigsync.GlobalConfigPath, "source_id")) + require.Equal(t, items[1].Value, "2") return } require.Fail(t, "timeout for waiting global config synced") diff --git a/domain/historical_stats.go b/domain/historical_stats.go new file mode 100644 index 0000000000000..07e82bafeb58c --- /dev/null +++ b/domain/historical_stats.go @@ -0,0 +1,86 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package domain + +import ( + "github.com/pingcap/errors" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/statistics/handle" +) + +var ( + generateHistoricalStatsSuccessCounter = metrics.HistoricalStatsCounter.WithLabelValues("generate", "success") + generateHistoricalStatsFailedCounter = metrics.HistoricalStatsCounter.WithLabelValues("generate", "fail") +) + +// HistoricalStatsWorker indicates for dump historical stats +type HistoricalStatsWorker struct { + tblCH chan int64 + sctx sessionctx.Context +} + +// SendTblToDumpHistoricalStats send tableID to worker to dump historical stats +func (w *HistoricalStatsWorker) SendTblToDumpHistoricalStats(tableID int64) { + w.tblCH <- tableID +} + +// DumpHistoricalStats dump stats by given tableID +func (w *HistoricalStatsWorker) DumpHistoricalStats(tableID int64, statsHandle *handle.Handle) error { + historicalStatsEnabled, err := statsHandle.CheckHistoricalStatsEnable() + if err != nil { + return errors.Errorf("check tidb_enable_historical_stats failed: %v", err) + } + if !historicalStatsEnabled { + return nil + } + sctx := w.sctx + is := GetDomain(sctx).InfoSchema() + isPartition := false + var tblInfo *model.TableInfo + tbl, existed := is.TableByID(tableID) + if !existed { + tbl, db, p := is.FindTableByPartitionID(tableID) + if tbl != nil && db != nil && p != nil { + isPartition = true + tblInfo = tbl.Meta() + } else { + return errors.Errorf("cannot get table by id %d", tableID) + } + } else { + tblInfo = tbl.Meta() + } + dbInfo, existed := is.SchemaByTable(tblInfo) + if !existed { + return errors.Errorf("cannot get DBInfo by TableID %d", tableID) + } + if _, err := statsHandle.RecordHistoricalStatsToStorage(dbInfo.Name.O, tblInfo, tableID, isPartition); err != nil { + generateHistoricalStatsFailedCounter.Inc() + return errors.Errorf("record table %s.%s's historical stats failed, err:%v", dbInfo.Name.O, tblInfo.Name.O, err) + } + generateHistoricalStatsSuccessCounter.Inc() + return nil +} + +// GetOneHistoricalStatsTable gets one tableID from channel, only used for test +func (w *HistoricalStatsWorker) GetOneHistoricalStatsTable() int64 { + select { + case tblID := <-w.tblCH: + return tblID + default: + return -1 + } +} diff --git a/domain/infosync/BUILD.bazel b/domain/infosync/BUILD.bazel index c0936390ff016..0952dfc300490 100644 --- a/domain/infosync/BUILD.bazel +++ b/domain/infosync/BUILD.bazel @@ -8,6 +8,7 @@ go_library( "label_manager.go", "placement_manager.go", "region.go", + "resource_group_manager.go", "schedule_manager.go", "tiflash_manager.go", ], @@ -41,6 +42,8 @@ go_library( "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_kvproto//pkg/metapb", + "@com_github_pingcap_kvproto//pkg/resource_manager", + "@com_github_pingcap_log//:log", "@com_github_tikv_client_go_v2//oracle", "@com_github_tikv_pd_client//:client", "@io_etcd_go_etcd_client_v3//:client", diff --git a/domain/infosync/info.go b/domain/infosync/info.go index fd29483c8b157..7732a831b057e 100644 --- a/domain/infosync/info.go +++ b/domain/infosync/info.go @@ -33,6 +33,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/metapb" + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl/label" "github.com/pingcap/tidb/ddl/placement" @@ -103,14 +104,15 @@ type InfoSyncer struct { mu sync.RWMutex util2.SessionManager } - session *concurrency.Session - topologySession *concurrency.Session - prometheusAddr string - modifyTime time.Time - labelRuleManager LabelRuleManager - placementManager PlacementManager - scheduleManager ScheduleManager - tiflashPlacementManager TiFlashPlacementManager + session *concurrency.Session + topologySession *concurrency.Session + prometheusAddr string + modifyTime time.Time + labelRuleManager LabelRuleManager + placementManager PlacementManager + scheduleManager ScheduleManager + tiflashReplicaManager TiFlashReplicaManager + resourceGroupManager ResourceGroupManager } // ServerInfo is server static information. @@ -192,7 +194,8 @@ func GlobalInfoSyncerInit(ctx context.Context, id string, serverIDGetter func() is.labelRuleManager = initLabelRuleManager(etcdCli) is.placementManager = initPlacementManager(etcdCli) is.scheduleManager = initScheduleManager(etcdCli) - is.tiflashPlacementManager = initTiFlashPlacementManager(etcdCli) + is.resourceGroupManager = initResourceGroupManager(etcdCli) + is.tiflashReplicaManager = initTiFlashReplicaManager(etcdCli) setGlobalInfoSyncer(is) return is, nil } @@ -237,13 +240,20 @@ func initPlacementManager(etcdCli *clientv3.Client) PlacementManager { return &PDPlacementManager{etcdCli: etcdCli} } -func initTiFlashPlacementManager(etcdCli *clientv3.Client) TiFlashPlacementManager { +func initResourceGroupManager(etcdCli *clientv3.Client) ResourceGroupManager { if etcdCli == nil { - m := mockTiFlashPlacementManager{} + return &mockResourceGroupManager{groups: make(map[string]*rmpb.ResourceGroup)} + } + return NewResourceManager(etcdCli) +} + +func initTiFlashReplicaManager(etcdCli *clientv3.Client) TiFlashReplicaManager { + if etcdCli == nil { + m := mockTiFlashReplicaManagerCtx{tiflashProgressCache: make(map[int64]float64)} return &m } - logutil.BgLogger().Warn("init TiFlashPlacementManager", zap.Strings("pd addrs", etcdCli.Endpoints())) - return &TiFlashPDPlacementManager{etcdCli: etcdCli} + logutil.BgLogger().Warn("init TiFlashReplicaManager", zap.Strings("pd addrs", etcdCli.Endpoints())) + return &TiFlashReplicaManagerCtx{etcdCli: etcdCli, tiflashProgressCache: make(map[int64]float64)} } func initScheduleManager(etcdCli *clientv3.Client) ScheduleManager { @@ -260,7 +270,7 @@ func GetMockTiFlash() *MockTiFlash { return nil } - m, ok := is.tiflashPlacementManager.(*mockTiFlashPlacementManager) + m, ok := is.tiflashReplicaManager.(*mockTiFlashReplicaManagerCtx) if ok { return m.tiflash } @@ -274,7 +284,7 @@ func SetMockTiFlash(tiflash *MockTiFlash) { return } - m, ok := is.tiflashPlacementManager.(*mockTiFlashPlacementManager) + m, ok := is.tiflashReplicaManager.(*mockTiFlashReplicaManagerCtx) if ok { m.SetMockTiFlash(tiflash) } @@ -282,6 +292,11 @@ func SetMockTiFlash(tiflash *MockTiFlash) { // GetServerInfo gets self server static information. func GetServerInfo() (*ServerInfo, error) { + failpoint.Inject("mockGetServerInfo", func(v failpoint.Value) { + var res ServerInfo + err := json.Unmarshal([]byte(v.(string)), &res) + failpoint.Return(&res, err) + }) is, err := getGlobalInfoSyncer() if err != nil { return nil, err @@ -316,20 +331,10 @@ func (is *InfoSyncer) getServerInfoByID(ctx context.Context, id string) (*Server // GetAllServerInfo gets all servers static information from etcd. func GetAllServerInfo(ctx context.Context) (map[string]*ServerInfo, error) { - failpoint.Inject("mockGetAllServerInfo", func() { - res := map[string]*ServerInfo{ - "fa598405-a08e-4e74-83ff-75c30b1daedc": { - Labels: map[string]string{ - "zone": "zone1", - }, - }, - "ad84dbbd-5a50-4742-a73c-4f674d41d4bd": { - Labels: map[string]string{ - "zone": "zone2", - }, - }, - } - failpoint.Return(res, nil) + failpoint.Inject("mockGetAllServerInfo", func(val failpoint.Value) { + res := make(map[string]*ServerInfo) + err := json.Unmarshal([]byte(val.(string)), &res) + failpoint.Return(res, err) }) is, err := getGlobalInfoSyncer() if err != nil { @@ -338,65 +343,58 @@ func GetAllServerInfo(ctx context.Context) (map[string]*ServerInfo, error) { return is.getAllServerInfo(ctx) } -// UpdateTiFlashTableSyncProgress is used to update the tiflash table replica sync progress. -func UpdateTiFlashTableSyncProgress(ctx context.Context, tid int64, progressString string) error { - is, err := getGlobalInfoSyncer() - if err != nil { - return err - } - if is.etcdCli == nil { - return nil - } - key := fmt.Sprintf("%s/%v", TiFlashTableSyncProgressPath, tid) - return util.PutKVToEtcd(ctx, is.etcdCli, keyOpDefaultRetryCnt, key, progressString) -} - // DeleteTiFlashTableSyncProgress is used to delete the tiflash table replica sync progress. -func DeleteTiFlashTableSyncProgress(tid int64) error { +func DeleteTiFlashTableSyncProgress(tableInfo *model.TableInfo) error { is, err := getGlobalInfoSyncer() if err != nil { return err } - if is.etcdCli == nil { - return nil + if pi := tableInfo.GetPartitionInfo(); pi != nil { + for _, p := range pi.Definitions { + is.tiflashReplicaManager.DeleteTiFlashProgressFromCache(p.ID) + } + } else { + is.tiflashReplicaManager.DeleteTiFlashProgressFromCache(tableInfo.ID) } - key := fmt.Sprintf("%s/%v", TiFlashTableSyncProgressPath, tid) - return util.DeleteKeyFromEtcd(key, is.etcdCli, keyOpDefaultRetryCnt, keyOpDefaultTimeout) + return nil } -// GetTiFlashTableSyncProgress uses to get all the tiflash table replica sync progress. -func GetTiFlashTableSyncProgress(ctx context.Context) (map[int64]float64, error) { +// MustGetTiFlashProgress gets tiflash replica progress from tiflashProgressCache, if cache not exist, it calculates progress from PD and TiFlash and inserts progress into cache. +func MustGetTiFlashProgress(tableID int64, replicaCount uint64, tiFlashStores *map[int64]helper.StoreStat) (float64, error) { is, err := getGlobalInfoSyncer() if err != nil { - return nil, err + return 0, err } - progressMap := make(map[int64]float64) - if is.etcdCli == nil { - return progressMap, nil + progressCache, isExist := is.tiflashReplicaManager.GetTiFlashProgressFromCache(tableID) + if isExist { + return progressCache, nil } - for i := 0; i < keyOpDefaultRetryCnt; i++ { - resp, err := is.etcdCli.Get(ctx, TiFlashTableSyncProgressPath+"/", clientv3.WithPrefix()) + if *tiFlashStores == nil { + // We need the up-to-date information about TiFlash stores. + // Since TiFlash Replica synchronize may happen immediately after new TiFlash stores are added. + tikvStats, err := is.tiflashReplicaManager.GetStoresStat(context.Background()) + // If MockTiFlash is not set, will issue a MockTiFlashError here. if err != nil { - logutil.BgLogger().Info("get tiflash table replica sync progress failed, continue checking.", zap.Error(err)) - continue + return 0, err } - for _, kv := range resp.Kvs { - tid, err := strconv.ParseInt(string(kv.Key[len(TiFlashTableSyncProgressPath)+1:]), 10, 64) - if err != nil { - logutil.BgLogger().Info("invalid tiflash table replica sync progress key.", zap.String("key", string(kv.Key))) - continue - } - progress, err := strconv.ParseFloat(string(kv.Value), 64) - if err != nil { - logutil.BgLogger().Info("invalid tiflash table replica sync progress value.", - zap.String("key", string(kv.Key)), zap.String("value", string(kv.Value))) - continue + stores := make(map[int64]helper.StoreStat) + for _, store := range tikvStats.Stores { + for _, l := range store.Store.Labels { + if l.Key == "engine" && l.Value == "tiflash" { + stores[store.Store.ID] = store + logutil.BgLogger().Debug("Found tiflash store", zap.Int64("id", store.Store.ID), zap.String("Address", store.Store.Address), zap.String("StatusAddress", store.Store.StatusAddress)) + } } - progressMap[tid] = progress } - break + *tiFlashStores = stores + logutil.BgLogger().Debug("updateTiFlashStores finished", zap.Int("TiFlash store count", len(*tiFlashStores))) } - return progressMap, nil + progress, err := is.tiflashReplicaManager.CalculateTiFlashProgress(tableID, replicaCount, *tiFlashStores) + if err != nil { + return 0, err + } + is.tiflashReplicaManager.UpdateTiFlashProgressCache(tableID, progress) + return progress, nil } func doRequest(ctx context.Context, apiName string, addrs []string, route, method string, body io.Reader) ([]byte, error) { @@ -515,7 +513,7 @@ func doRequestWithFailpoint(req *http.Request) (resp *http.Response, err error) return util2.InternalHTTPClient().Do(req) } -// GetAllRuleBundles is used to get all rule bundles from PD. It is used to load full rules from PD while fullload infoschema. +// GetAllRuleBundles is used to get all rule bundles from PD It is used to load full rules from PD while fullload infoschema. func GetAllRuleBundles(ctx context.Context) ([]*placement.Bundle, error) { is, err := getGlobalInfoSyncer() if err != nil { @@ -575,6 +573,53 @@ func PutRuleBundlesWithRetry(ctx context.Context, bundles []*placement.Bundle, m return } +// GetResourceGroup is used to get one specific resource group from resource manager. +func GetResourceGroup(ctx context.Context, name string) (*rmpb.ResourceGroup, error) { + is, err := getGlobalInfoSyncer() + if err != nil { + return nil, err + } + + return is.resourceGroupManager.GetResourceGroup(ctx, name) +} + +// GetAllResourceGroups is used to get all resource groups from resource manager. +func GetAllResourceGroups(ctx context.Context) ([]*rmpb.ResourceGroup, error) { + is, err := getGlobalInfoSyncer() + if err != nil { + return nil, err + } + + return is.resourceGroupManager.GetAllResourceGroups(ctx) +} + +// CreateResourceGroup is used to create one specific resource group to resource manager. +func CreateResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error { + is, err := getGlobalInfoSyncer() + if err != nil { + return err + } + return is.resourceGroupManager.CreateResourceGroup(ctx, group) +} + +// ModifyResourceGroup is used to modify one specific resource group to resource manager. +func ModifyResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error { + is, err := getGlobalInfoSyncer() + if err != nil { + return err + } + return is.resourceGroupManager.ModifyResourceGroup(ctx, group) +} + +// DeleteResourceGroup is used to delete one specific resource group from resource manager. +func DeleteResourceGroup(ctx context.Context, name string) error { + is, err := getGlobalInfoSyncer() + if err != nil { + return err + } + return is.resourceGroupManager.DeleteResourceGroup(ctx, name) +} + // PutRuleBundlesWithDefaultRetry will retry for default times func PutRuleBundlesWithDefaultRetry(ctx context.Context, bundles []*placement.Bundle) (err error) { return PutRuleBundlesWithRetry(ctx, bundles, SyncBundlesMaxRetry, RequestRetryInterval) @@ -701,8 +746,6 @@ func (is *InfoSyncer) ReportMinStartTS(store kv.Storage) { if sm == nil { return } - pl := sm.ShowProcessList() - innerSessionStartTSList := sm.GetInternalSessionStartTSList() // Calculate the lower limit of the start timestamp to avoid extremely old transaction delaying GC. currentVer, err := store.CurrentVersion(kv.GlobalTxnScope) @@ -716,18 +759,8 @@ func (is *InfoSyncer) ReportMinStartTS(store kv.Storage) { minStartTS := oracle.GoTimeToTS(now) logutil.BgLogger().Debug("ReportMinStartTS", zap.Uint64("initial minStartTS", minStartTS), zap.Uint64("StartTSLowerLimit", startTSLowerLimit)) - for _, info := range pl { - if info.CurTxnStartTS > startTSLowerLimit && info.CurTxnStartTS < minStartTS { - minStartTS = info.CurTxnStartTS - } - } - - for _, innerTS := range innerSessionStartTSList { - logutil.BgLogger().Debug("ReportMinStartTS", zap.Uint64("Internal Session Transaction StartTS", innerTS)) - kv.PrintLongTimeInternalTxn(now, innerTS, false) - if innerTS > startTSLowerLimit && innerTS < minStartTS { - minStartTS = innerTS - } + if ts := sm.GetMinStartTS(startTSLowerLimit); ts > startTSLowerLimit && ts < minStartTS { + minStartTS = ts } is.minStartTS = kv.GetMinInnerTxnStartTS(now, startTSLowerLimit, minStartTS) @@ -1045,6 +1078,44 @@ func GetLabelRules(ctx context.Context, ruleIDs []string) (map[string]*label.Rul return is.labelRuleManager.GetLabelRules(ctx, ruleIDs) } +// CalculateTiFlashProgress calculates TiFlash replica progress +func CalculateTiFlashProgress(tableID int64, replicaCount uint64, TiFlashStores map[int64]helper.StoreStat) (float64, error) { + is, err := getGlobalInfoSyncer() + if err != nil { + return 0, errors.Trace(err) + } + return is.tiflashReplicaManager.CalculateTiFlashProgress(tableID, replicaCount, TiFlashStores) +} + +// UpdateTiFlashProgressCache updates tiflashProgressCache +func UpdateTiFlashProgressCache(tableID int64, progress float64) error { + is, err := getGlobalInfoSyncer() + if err != nil { + return errors.Trace(err) + } + is.tiflashReplicaManager.UpdateTiFlashProgressCache(tableID, progress) + return nil +} + +// GetTiFlashProgressFromCache gets tiflash replica progress from tiflashProgressCache +func GetTiFlashProgressFromCache(tableID int64) (float64, bool) { + is, err := getGlobalInfoSyncer() + if err != nil { + logutil.BgLogger().Error("GetTiFlashProgressFromCache get info sync failed", zap.Int64("tableID", tableID), zap.Error(err)) + return 0, false + } + return is.tiflashReplicaManager.GetTiFlashProgressFromCache(tableID) +} + +// CleanTiFlashProgressCache clean progress cache +func CleanTiFlashProgressCache() { + is, err := getGlobalInfoSyncer() + if err != nil { + return + } + is.tiflashReplicaManager.CleanTiFlashProgressCache() +} + // SetTiFlashGroupConfig is a helper function to set tiflash rule group config func SetTiFlashGroupConfig(ctx context.Context) error { is, err := getGlobalInfoSyncer() @@ -1052,7 +1123,7 @@ func SetTiFlashGroupConfig(ctx context.Context) error { return errors.Trace(err) } logutil.BgLogger().Info("SetTiFlashGroupConfig") - return is.tiflashPlacementManager.SetTiFlashGroupConfig(ctx) + return is.tiflashReplicaManager.SetTiFlashGroupConfig(ctx) } // SetTiFlashPlacementRule is a helper function to set placement rule. @@ -1064,7 +1135,7 @@ func SetTiFlashPlacementRule(ctx context.Context, rule placement.TiFlashRule) er return errors.Trace(err) } logutil.BgLogger().Info("SetTiFlashPlacementRule", zap.String("ruleID", rule.ID)) - return is.tiflashPlacementManager.SetPlacementRule(ctx, rule) + return is.tiflashReplicaManager.SetPlacementRule(ctx, rule) } // DeleteTiFlashPlacementRule is to delete placement rule for certain group. @@ -1074,7 +1145,7 @@ func DeleteTiFlashPlacementRule(ctx context.Context, group string, ruleID string return errors.Trace(err) } logutil.BgLogger().Info("DeleteTiFlashPlacementRule", zap.String("ruleID", ruleID)) - return is.tiflashPlacementManager.DeletePlacementRule(ctx, group, ruleID) + return is.tiflashReplicaManager.DeletePlacementRule(ctx, group, ruleID) } // GetTiFlashGroupRules to get all placement rule in a certain group. @@ -1083,7 +1154,7 @@ func GetTiFlashGroupRules(ctx context.Context, group string) ([]placement.TiFlas if err != nil { return nil, errors.Trace(err) } - return is.tiflashPlacementManager.GetGroupRules(ctx, group) + return is.tiflashReplicaManager.GetGroupRules(ctx, group) } // PostTiFlashAccelerateSchedule sends `regions/accelerate-schedule` request. @@ -1093,16 +1164,16 @@ func PostTiFlashAccelerateSchedule(ctx context.Context, tableID int64) error { return errors.Trace(err) } logutil.BgLogger().Info("PostTiFlashAccelerateSchedule", zap.Int64("tableID", tableID)) - return is.tiflashPlacementManager.PostAccelerateSchedule(ctx, tableID) + return is.tiflashReplicaManager.PostAccelerateSchedule(ctx, tableID) } -// GetTiFlashPDRegionRecordStats is a helper function calling `/stats/region`. -func GetTiFlashPDRegionRecordStats(ctx context.Context, tableID int64, stats *helper.PDRegionStats) error { +// GetTiFlashRegionCountFromPD is a helper function calling `/stats/region`. +func GetTiFlashRegionCountFromPD(ctx context.Context, tableID int64, regionCount *int) error { is, err := getGlobalInfoSyncer() if err != nil { return errors.Trace(err) } - return is.tiflashPlacementManager.GetPDRegionRecordStats(ctx, tableID, stats) + return is.tiflashReplicaManager.GetRegionCountFromPD(ctx, tableID, regionCount) } // GetTiFlashStoresStat gets the TiKV store information by accessing PD's api. @@ -1111,7 +1182,7 @@ func GetTiFlashStoresStat(ctx context.Context) (*helper.StoresStat, error) { if err != nil { return nil, errors.Trace(err) } - return is.tiflashPlacementManager.GetStoresStat(ctx) + return is.tiflashReplicaManager.GetStoresStat(ctx) } // CloseTiFlashManager closes TiFlash manager. @@ -1120,7 +1191,7 @@ func CloseTiFlashManager(ctx context.Context) { if err != nil { return } - is.tiflashPlacementManager.Close(ctx) + is.tiflashReplicaManager.Close(ctx) } // ConfigureTiFlashPDForTable configures pd rule for unpartitioned tables. @@ -1132,7 +1203,7 @@ func ConfigureTiFlashPDForTable(id int64, count uint64, locationLabels *[]string ctx := context.Background() logutil.BgLogger().Info("ConfigureTiFlashPDForTable", zap.Int64("tableID", id), zap.Uint64("count", count)) ruleNew := MakeNewRule(id, count, *locationLabels) - if e := is.tiflashPlacementManager.SetPlacementRule(ctx, *ruleNew); e != nil { + if e := is.tiflashReplicaManager.SetPlacementRule(ctx, *ruleNew); e != nil { return errors.Trace(e) } return nil @@ -1148,11 +1219,11 @@ func ConfigureTiFlashPDForPartitions(accel bool, definitions *[]model.PartitionD for _, p := range *definitions { logutil.BgLogger().Info("ConfigureTiFlashPDForPartitions", zap.Int64("tableID", tableID), zap.Int64("partID", p.ID), zap.Bool("accel", accel), zap.Uint64("count", count)) ruleNew := MakeNewRule(p.ID, count, *locationLabels) - if e := is.tiflashPlacementManager.SetPlacementRule(ctx, *ruleNew); e != nil { + if e := is.tiflashReplicaManager.SetPlacementRule(ctx, *ruleNew); e != nil { return errors.Trace(e) } if accel { - e := is.tiflashPlacementManager.PostAccelerateSchedule(ctx, p.ID) + e := is.tiflashReplicaManager.PostAccelerateSchedule(ctx, p.ID) if e != nil { return errors.Trace(e) } diff --git a/domain/infosync/info_test.go b/domain/infosync/info_test.go index 1a043e8decf2d..90a30d8f1f161 100644 --- a/domain/infosync/info_test.go +++ b/domain/infosync/info_test.go @@ -40,6 +40,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/domain/infosync/resource_group_manager.go b/domain/infosync/resource_group_manager.go new file mode 100644 index 0000000000000..93c751fc04968 --- /dev/null +++ b/domain/infosync/resource_group_manager.go @@ -0,0 +1,144 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package infosync + +import ( + "context" + "sync" + + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" + "github.com/pingcap/log" + clientv3 "go.etcd.io/etcd/client/v3" + "go.uber.org/zap" +) + +// ResourceGroupManager manages resource group settings +type ResourceGroupManager interface { + // GetResourceGroup is used to get one specific rule bundle from ResourceGroup Manager. + GetResourceGroup(ctx context.Context, name string) (*rmpb.ResourceGroup, error) + // GetAllResourceGroups is used to get all rule bundles from ResourceGroup Manager. + GetAllResourceGroups(ctx context.Context) ([]*rmpb.ResourceGroup, error) + // PutResourceGroup is used to post specific rule bundles to ResourceGroup Manager. + CreateResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error + // ModifyResourceGroup is used to modify specific rule bundles to ResourceGroup Manager. + ModifyResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error + // DeleteResourceGroup is used to delete specific rule bundles to ResourceGroup Manager. + DeleteResourceGroup(ctx context.Context, name string) error +} + +// externalResourceGroupManager manages placement with resource manager. +// TODO: replace with resource manager client. +type externalResourceGroupManager struct { + etcdCli *clientv3.Client +} + +// NewResourceManager is used to create a new resource manager in client side. +func NewResourceManager(etcdCli *clientv3.Client) ResourceGroupManager { + return &externalResourceGroupManager{etcdCli: etcdCli} +} + +// GetResourceGroupClient is used to get resource group client. +func (m *externalResourceGroupManager) GetResourceGroupClient() rmpb.ResourceManagerClient { + conn := m.etcdCli.ActiveConnection() + return rmpb.NewResourceManagerClient(conn) +} + +// GetResourceGroup is used to get one specific rule bundle from ResourceGroup Manager. +func (m *externalResourceGroupManager) GetResourceGroup(ctx context.Context, name string) (*rmpb.ResourceGroup, error) { + group := &rmpb.GetResourceGroupRequest{ResourceGroupName: name} + resp, err := m.GetResourceGroupClient().GetResourceGroup(ctx, group) + if err != nil { + return nil, err + } + return resp.GetGroup(), nil +} + +// GetAllResourceGroups is used to get all resource group from ResourceGroup Manager. It is used to load full resource groups from PD while fullload infoschema. +func (m *externalResourceGroupManager) GetAllResourceGroups(ctx context.Context) ([]*rmpb.ResourceGroup, error) { + req := &rmpb.ListResourceGroupsRequest{} + resp, err := m.GetResourceGroupClient().ListResourceGroups(ctx, req) + if err != nil { + return nil, err + } + return resp.GetGroups(), nil +} + +// CreateResourceGroup is used to post specific resource group to ResourceGroup Manager. +func (m *externalResourceGroupManager) CreateResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error { + req := &rmpb.PutResourceGroupRequest{Group: group} + _, err := m.GetResourceGroupClient().AddResourceGroup(ctx, req) + return err +} + +// ModifyResourceGroup is used to modify specific resource group to ResourceGroup Manager. +func (m *externalResourceGroupManager) ModifyResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error { + req := &rmpb.PutResourceGroupRequest{Group: group} + _, err := m.GetResourceGroupClient().ModifyResourceGroup(ctx, req) + return err +} + +// DeleteResourceGroup is used to delete specific resource group to ResourceGroup Manager. +func (m *externalResourceGroupManager) DeleteResourceGroup(ctx context.Context, name string) error { + req := &rmpb.DeleteResourceGroupRequest{ResourceGroupName: name} + log.Info("delete resource group", zap.String("name", name)) + _, err := m.GetResourceGroupClient().DeleteResourceGroup(ctx, req) + return err +} + +type mockResourceGroupManager struct { + sync.Mutex + groups map[string]*rmpb.ResourceGroup +} + +func (m *mockResourceGroupManager) GetResourceGroup(ctx context.Context, name string) (*rmpb.ResourceGroup, error) { + m.Lock() + defer m.Unlock() + group, ok := m.groups[name] + if !ok { + return nil, nil + } + return group, nil +} + +func (m *mockResourceGroupManager) GetAllResourceGroups(ctx context.Context) ([]*rmpb.ResourceGroup, error) { + m.Lock() + defer m.Unlock() + groups := make([]*rmpb.ResourceGroup, 0, len(m.groups)) + for _, group := range m.groups { + groups = append(groups, group) + } + return groups, nil +} + +func (m *mockResourceGroupManager) CreateResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error { + m.Lock() + defer m.Unlock() + m.groups[group.Name] = group + return nil +} + +func (m *mockResourceGroupManager) ModifyResourceGroup(ctx context.Context, group *rmpb.ResourceGroup) error { + m.Lock() + defer m.Unlock() + m.groups[group.Name] = group + return nil +} + +func (m *mockResourceGroupManager) DeleteResourceGroup(ctx context.Context, name string) error { + m.Lock() + defer m.Unlock() + delete(m.groups, name) + return nil +} diff --git a/domain/infosync/tiflash_manager.go b/domain/infosync/tiflash_manager.go index 5b937f626cd00..4d01c64de002d 100644 --- a/domain/infosync/tiflash_manager.go +++ b/domain/infosync/tiflash_manager.go @@ -41,8 +41,8 @@ import ( "go.uber.org/zap" ) -// TiFlashPlacementManager manages placement settings for TiFlash. -type TiFlashPlacementManager interface { +// TiFlashReplicaManager manages placement settings and replica progress for TiFlash. +type TiFlashReplicaManager interface { // SetTiFlashGroupConfig sets the group index of the tiflash placement rule SetTiFlashGroupConfig(ctx context.Context) error // SetPlacementRule is a helper function to set placement rule. @@ -53,26 +53,122 @@ type TiFlashPlacementManager interface { GetGroupRules(ctx context.Context, group string) ([]placement.TiFlashRule, error) // PostAccelerateSchedule sends `regions/accelerate-schedule` request. PostAccelerateSchedule(ctx context.Context, tableID int64) error - // GetPDRegionRecordStats is a helper function calling `/stats/region`. - GetPDRegionRecordStats(ctx context.Context, tableID int64, stats *helper.PDRegionStats) error + // GetRegionCountFromPD is a helper function calling `/stats/region`. + GetRegionCountFromPD(ctx context.Context, tableID int64, regionCount *int) error // GetStoresStat gets the TiKV store information by accessing PD's api. GetStoresStat(ctx context.Context) (*helper.StoresStat, error) - // Close is to close TiFlashPlacementManager + // CalculateTiFlashProgress calculates TiFlash replica progress + CalculateTiFlashProgress(tableID int64, replicaCount uint64, TiFlashStores map[int64]helper.StoreStat) (float64, error) + // UpdateTiFlashProgressCache updates tiflashProgressCache + UpdateTiFlashProgressCache(tableID int64, progress float64) + // GetTiFlashProgressFromCache gets tiflash replica progress from tiflashProgressCache + GetTiFlashProgressFromCache(tableID int64) (float64, bool) + // DeleteTiFlashProgressFromCache delete tiflash replica progress from tiflashProgressCache + DeleteTiFlashProgressFromCache(tableID int64) + // CleanTiFlashProgressCache clean progress cache + CleanTiFlashProgressCache() + // Close is to close TiFlashReplicaManager Close(ctx context.Context) } -// TiFlashPDPlacementManager manages placement with pd for TiFlash. -type TiFlashPDPlacementManager struct { - etcdCli *clientv3.Client +// TiFlashReplicaManagerCtx manages placement with pd and replica progress for TiFlash. +type TiFlashReplicaManagerCtx struct { + etcdCli *clientv3.Client + sync.RWMutex // protect tiflashProgressCache + tiflashProgressCache map[int64]float64 } -// Close is called to close TiFlashPDPlacementManager. -func (m *TiFlashPDPlacementManager) Close(ctx context.Context) { +// Close is called to close TiFlashReplicaManagerCtx. +func (m *TiFlashReplicaManagerCtx) Close(ctx context.Context) { } +func getTiFlashPeerWithoutLagCount(tiFlashStores map[int64]helper.StoreStat, tableID int64) (int, error) { + // storeIDs -> regionID, PD will not create two peer on the same store + var flashPeerCount int + for _, store := range tiFlashStores { + regionReplica := make(map[int64]int) + err := helper.CollectTiFlashStatus(store.Store.StatusAddress, tableID, ®ionReplica) + if err != nil { + logutil.BgLogger().Error("Fail to get peer status from TiFlash.", + zap.Int64("tableID", tableID)) + return 0, err + } + flashPeerCount += len(regionReplica) + } + return flashPeerCount, nil +} + +// calculateTiFlashProgress calculates progress based on the region status from PD and TiFlash. +func calculateTiFlashProgress(tableID int64, replicaCount uint64, tiFlashStores map[int64]helper.StoreStat) (float64, error) { + var regionCount int + if err := GetTiFlashRegionCountFromPD(context.Background(), tableID, ®ionCount); err != nil { + logutil.BgLogger().Error("Fail to get regionCount from PD.", + zap.Int64("tableID", tableID)) + return 0, errors.Trace(err) + } + + if regionCount == 0 { + logutil.BgLogger().Warn("region count getting from PD is 0.", + zap.Int64("tableID", tableID)) + return 0, fmt.Errorf("region count getting from PD is 0") + } + + tiflashPeerCount, err := getTiFlashPeerWithoutLagCount(tiFlashStores, tableID) + if err != nil { + logutil.BgLogger().Error("Fail to get peer count from TiFlash.", + zap.Int64("tableID", tableID)) + return 0, errors.Trace(err) + } + progress := float64(tiflashPeerCount) / float64(regionCount*int(replicaCount)) + if progress > 1 { // when pd do balance + logutil.BgLogger().Debug("TiFlash peer count > pd peer count, maybe doing balance.", + zap.Int64("tableID", tableID), zap.Int("tiflashPeerCount", tiflashPeerCount), zap.Int("regionCount", regionCount), zap.Uint64("replicaCount", replicaCount)) + progress = 1 + } + if progress < 1 { + logutil.BgLogger().Debug("TiFlash replica progress < 1.", + zap.Int64("tableID", tableID), zap.Int("tiflashPeerCount", tiflashPeerCount), zap.Int("regionCount", regionCount), zap.Uint64("replicaCount", replicaCount)) + } + return progress, nil +} + +// CalculateTiFlashProgress calculates TiFlash replica progress. +func (m *TiFlashReplicaManagerCtx) CalculateTiFlashProgress(tableID int64, replicaCount uint64, tiFlashStores map[int64]helper.StoreStat) (float64, error) { + return calculateTiFlashProgress(tableID, replicaCount, tiFlashStores) +} + +// UpdateTiFlashProgressCache updates tiflashProgressCache +func (m *TiFlashReplicaManagerCtx) UpdateTiFlashProgressCache(tableID int64, progress float64) { + m.Lock() + defer m.Unlock() + m.tiflashProgressCache[tableID] = progress +} + +// GetTiFlashProgressFromCache gets tiflash replica progress from tiflashProgressCache +func (m *TiFlashReplicaManagerCtx) GetTiFlashProgressFromCache(tableID int64) (float64, bool) { + m.RLock() + defer m.RUnlock() + progress, ok := m.tiflashProgressCache[tableID] + return progress, ok +} + +// DeleteTiFlashProgressFromCache delete tiflash replica progress from tiflashProgressCache +func (m *TiFlashReplicaManagerCtx) DeleteTiFlashProgressFromCache(tableID int64) { + m.Lock() + defer m.Unlock() + delete(m.tiflashProgressCache, tableID) +} + +// CleanTiFlashProgressCache clean progress cache +func (m *TiFlashReplicaManagerCtx) CleanTiFlashProgressCache() { + m.Lock() + defer m.Unlock() + m.tiflashProgressCache = make(map[int64]float64) +} + // SetTiFlashGroupConfig sets the tiflash's rule group config -func (m *TiFlashPDPlacementManager) SetTiFlashGroupConfig(ctx context.Context) error { +func (m *TiFlashReplicaManagerCtx) SetTiFlashGroupConfig(ctx context.Context) error { res, err := doRequest(ctx, "GetRuleGroupConfig", m.etcdCli.Endpoints(), @@ -123,7 +219,7 @@ func (m *TiFlashPDPlacementManager) SetTiFlashGroupConfig(ctx context.Context) e } // SetPlacementRule is a helper function to set placement rule. -func (m *TiFlashPDPlacementManager) SetPlacementRule(ctx context.Context, rule placement.TiFlashRule) error { +func (m *TiFlashReplicaManagerCtx) SetPlacementRule(ctx context.Context, rule placement.TiFlashRule) error { if err := m.SetTiFlashGroupConfig(ctx); err != nil { return err } @@ -138,31 +234,31 @@ func (m *TiFlashPDPlacementManager) SetPlacementRule(ctx context.Context, rule p return errors.Trace(err) } if res == nil { - return fmt.Errorf("TiFlashPDPlacementManager returns error in SetPlacementRule") + return fmt.Errorf("TiFlashReplicaManagerCtx returns error in SetPlacementRule") } return nil } // DeletePlacementRule is to delete placement rule for certain group. -func (m *TiFlashPDPlacementManager) DeletePlacementRule(ctx context.Context, group string, ruleID string) error { +func (m *TiFlashReplicaManagerCtx) DeletePlacementRule(ctx context.Context, group string, ruleID string) error { res, err := doRequest(ctx, "DeletePlacementRule", m.etcdCli.Endpoints(), path.Join(pdapi.Config, "rule", group, ruleID), "DELETE", nil) if err != nil { return errors.Trace(err) } if res == nil { - return fmt.Errorf("TiFlashPDPlacementManager returns error in DeletePlacementRule") + return fmt.Errorf("TiFlashReplicaManagerCtx returns error in DeletePlacementRule") } return nil } // GetGroupRules to get all placement rule in a certain group. -func (m *TiFlashPDPlacementManager) GetGroupRules(ctx context.Context, group string) ([]placement.TiFlashRule, error) { +func (m *TiFlashReplicaManagerCtx) GetGroupRules(ctx context.Context, group string) ([]placement.TiFlashRule, error) { res, err := doRequest(ctx, "GetGroupRules", m.etcdCli.Endpoints(), path.Join(pdapi.Config, "rules", "group", group), "GET", nil) if err != nil { return nil, errors.Trace(err) } if res == nil { - return nil, fmt.Errorf("TiFlashPDPlacementManager returns error in GetGroupRules") + return nil, fmt.Errorf("TiFlashReplicaManagerCtx returns error in GetGroupRules") } var rules []placement.TiFlashRule @@ -175,7 +271,7 @@ func (m *TiFlashPDPlacementManager) GetGroupRules(ctx context.Context, group str } // PostAccelerateSchedule sends `regions/accelerate-schedule` request. -func (m *TiFlashPDPlacementManager) PostAccelerateSchedule(ctx context.Context, tableID int64) error { +func (m *TiFlashReplicaManagerCtx) PostAccelerateSchedule(ctx context.Context, tableID int64) error { startKey := tablecodec.GenTableRecordPrefix(tableID) endKey := tablecodec.EncodeTablePrefix(tableID + 1) startKey = codec.EncodeBytes([]byte{}, startKey) @@ -195,19 +291,19 @@ func (m *TiFlashPDPlacementManager) PostAccelerateSchedule(ctx context.Context, return errors.Trace(err) } if res == nil { - return fmt.Errorf("TiFlashPDPlacementManager returns error in PostAccelerateSchedule") + return fmt.Errorf("TiFlashReplicaManagerCtx returns error in PostAccelerateSchedule") } return nil } -// GetPDRegionRecordStats is a helper function calling `/stats/region`. -func (m *TiFlashPDPlacementManager) GetPDRegionRecordStats(ctx context.Context, tableID int64, stats *helper.PDRegionStats) error { +// GetRegionCountFromPD is a helper function calling `/stats/region`. +func (m *TiFlashReplicaManagerCtx) GetRegionCountFromPD(ctx context.Context, tableID int64, regionCount *int) error { startKey := tablecodec.GenTableRecordPrefix(tableID) endKey := tablecodec.EncodeTablePrefix(tableID + 1) startKey = codec.EncodeBytes([]byte{}, startKey) endKey = codec.EncodeBytes([]byte{}, endKey) - p := fmt.Sprintf("/pd/api/v1/stats/region?start_key=%s&end_key=%s", + p := fmt.Sprintf("/pd/api/v1/stats/region?start_key=%s&end_key=%s&count", url.QueryEscape(string(startKey)), url.QueryEscape(string(endKey))) res, err := doRequest(ctx, "GetPDRegionStats", m.etcdCli.Endpoints(), p, "GET", nil) @@ -215,25 +311,26 @@ func (m *TiFlashPDPlacementManager) GetPDRegionRecordStats(ctx context.Context, return errors.Trace(err) } if res == nil { - return fmt.Errorf("TiFlashPDPlacementManager returns error in GetPDRegionRecordStats") + return fmt.Errorf("TiFlashReplicaManagerCtx returns error in GetRegionCountFromPD") } - - err = json.Unmarshal(res, stats) + var stats helper.PDRegionStats + err = json.Unmarshal(res, &stats) if err != nil { return errors.Trace(err) } + *regionCount = stats.Count return nil } // GetStoresStat gets the TiKV store information by accessing PD's api. -func (m *TiFlashPDPlacementManager) GetStoresStat(ctx context.Context) (*helper.StoresStat, error) { +func (m *TiFlashReplicaManagerCtx) GetStoresStat(ctx context.Context) (*helper.StoresStat, error) { var storesStat helper.StoresStat res, err := doRequest(ctx, "GetStoresStat", m.etcdCli.Endpoints(), pdapi.Stores, "GET", nil) if err != nil { return nil, errors.Trace(err) } if res == nil { - return nil, fmt.Errorf("TiFlashPDPlacementManager returns error in GetStoresStat") + return nil, fmt.Errorf("TiFlashReplicaManagerCtx returns error in GetStoresStat") } err = json.Unmarshal(res, &storesStat) @@ -243,11 +340,12 @@ func (m *TiFlashPDPlacementManager) GetStoresStat(ctx context.Context) (*helper. return &storesStat, err } -type mockTiFlashPlacementManager struct { - sync.Mutex +type mockTiFlashReplicaManagerCtx struct { + sync.RWMutex // Set to nil if there is no need to set up a mock TiFlash server. // Otherwise use NewMockTiFlash to create one. - tiflash *MockTiFlash + tiflash *MockTiFlash + tiflashProgressCache map[int64]float64 } func makeBaseRule() placement.TiFlashRule { @@ -478,16 +576,11 @@ func (tiflash *MockTiFlash) HandlePostAccelerateSchedule(endKey string) error { return nil } -// HandleGetPDRegionRecordStats is mock function for GetPDRegionRecordStats. +// HandleGetPDRegionRecordStats is mock function for GetRegionCountFromPD. // It currently always returns 1 Region for convenience. func (tiflash *MockTiFlash) HandleGetPDRegionRecordStats(_ int64) helper.PDRegionStats { return helper.PDRegionStats{ - Count: 1, - EmptyCount: 1, - StorageSize: 1, - StorageKeys: 1, - StoreLeaderCount: map[uint64]int{1: 1}, - StorePeerCount: map[uint64]int{1: 1}, + Count: 1, } } @@ -654,15 +747,49 @@ func (tiflash *MockTiFlash) PdSwitch(enabled bool) { tiflash.PdEnabled = enabled } +// CalculateTiFlashProgress return truncated string to avoid float64 comparison. +func (m *mockTiFlashReplicaManagerCtx) CalculateTiFlashProgress(tableID int64, replicaCount uint64, tiFlashStores map[int64]helper.StoreStat) (float64, error) { + return calculateTiFlashProgress(tableID, replicaCount, tiFlashStores) +} + +// UpdateTiFlashProgressCache updates tiflashProgressCache +func (m *mockTiFlashReplicaManagerCtx) UpdateTiFlashProgressCache(tableID int64, progress float64) { + m.Lock() + defer m.Unlock() + m.tiflashProgressCache[tableID] = progress +} + +// GetTiFlashProgressFromCache gets tiflash replica progress from tiflashProgressCache +func (m *mockTiFlashReplicaManagerCtx) GetTiFlashProgressFromCache(tableID int64) (float64, bool) { + m.RLock() + defer m.RUnlock() + progress, ok := m.tiflashProgressCache[tableID] + return progress, ok +} + +// DeleteTiFlashProgressFromCache delete tiflash replica progress from tiflashProgressCache +func (m *mockTiFlashReplicaManagerCtx) DeleteTiFlashProgressFromCache(tableID int64) { + m.Lock() + defer m.Unlock() + delete(m.tiflashProgressCache, tableID) +} + +// CleanTiFlashProgressCache clean progress cache +func (m *mockTiFlashReplicaManagerCtx) CleanTiFlashProgressCache() { + m.Lock() + defer m.Unlock() + m.tiflashProgressCache = make(map[int64]float64) +} + // SetMockTiFlash is set a mock TiFlash server. -func (m *mockTiFlashPlacementManager) SetMockTiFlash(tiflash *MockTiFlash) { +func (m *mockTiFlashReplicaManagerCtx) SetMockTiFlash(tiflash *MockTiFlash) { m.Lock() defer m.Unlock() m.tiflash = tiflash } // SetTiFlashGroupConfig sets the tiflash's rule group config -func (m *mockTiFlashPlacementManager) SetTiFlashGroupConfig(_ context.Context) error { +func (m *mockTiFlashReplicaManagerCtx) SetTiFlashGroupConfig(_ context.Context) error { m.Lock() defer m.Unlock() if m.tiflash == nil { @@ -673,7 +800,7 @@ func (m *mockTiFlashPlacementManager) SetTiFlashGroupConfig(_ context.Context) e } // SetPlacementRule is a helper function to set placement rule. -func (m *mockTiFlashPlacementManager) SetPlacementRule(ctx context.Context, rule placement.TiFlashRule) error { +func (m *mockTiFlashReplicaManagerCtx) SetPlacementRule(ctx context.Context, rule placement.TiFlashRule) error { m.Lock() defer m.Unlock() if m.tiflash == nil { @@ -683,7 +810,7 @@ func (m *mockTiFlashPlacementManager) SetPlacementRule(ctx context.Context, rule } // DeletePlacementRule is to delete placement rule for certain group. -func (m *mockTiFlashPlacementManager) DeletePlacementRule(ctx context.Context, group string, ruleID string) error { +func (m *mockTiFlashReplicaManagerCtx) DeletePlacementRule(ctx context.Context, group string, ruleID string) error { m.Lock() defer m.Unlock() if m.tiflash == nil { @@ -695,7 +822,7 @@ func (m *mockTiFlashPlacementManager) DeletePlacementRule(ctx context.Context, g } // GetGroupRules to get all placement rule in a certain group. -func (m *mockTiFlashPlacementManager) GetGroupRules(ctx context.Context, group string) ([]placement.TiFlashRule, error) { +func (m *mockTiFlashReplicaManagerCtx) GetGroupRules(ctx context.Context, group string) ([]placement.TiFlashRule, error) { m.Lock() defer m.Unlock() if m.tiflash == nil { @@ -705,7 +832,7 @@ func (m *mockTiFlashPlacementManager) GetGroupRules(ctx context.Context, group s } // PostAccelerateSchedule sends `regions/accelerate-schedule` request. -func (m *mockTiFlashPlacementManager) PostAccelerateSchedule(ctx context.Context, tableID int64) error { +func (m *mockTiFlashReplicaManagerCtx) PostAccelerateSchedule(ctx context.Context, tableID int64) error { m.Lock() defer m.Unlock() if m.tiflash == nil { @@ -716,19 +843,20 @@ func (m *mockTiFlashPlacementManager) PostAccelerateSchedule(ctx context.Context return m.tiflash.HandlePostAccelerateSchedule(hex.EncodeToString(endKey)) } -// GetPDRegionRecordStats is a helper function calling `/stats/region`. -func (m *mockTiFlashPlacementManager) GetPDRegionRecordStats(ctx context.Context, tableID int64, stats *helper.PDRegionStats) error { +// GetRegionCountFromPD is a helper function calling `/stats/region`. +func (m *mockTiFlashReplicaManagerCtx) GetRegionCountFromPD(ctx context.Context, tableID int64, regionCount *int) error { m.Lock() defer m.Unlock() if m.tiflash == nil { return nil } - *stats = m.tiflash.HandleGetPDRegionRecordStats(tableID) + stats := m.tiflash.HandleGetPDRegionRecordStats(tableID) + *regionCount = stats.Count return nil } // GetStoresStat gets the TiKV store information by accessing PD's api. -func (m *mockTiFlashPlacementManager) GetStoresStat(ctx context.Context) (*helper.StoresStat, error) { +func (m *mockTiFlashReplicaManagerCtx) GetStoresStat(ctx context.Context) (*helper.StoresStat, error) { m.Lock() defer m.Unlock() if m.tiflash == nil { @@ -737,8 +865,8 @@ func (m *mockTiFlashPlacementManager) GetStoresStat(ctx context.Context) (*helpe return m.tiflash.HandleGetStoresStat(), nil } -// Close is called to close mockTiFlashPlacementManager. -func (m *mockTiFlashPlacementManager) Close(ctx context.Context) { +// Close is called to close mockTiFlashReplicaManager. +func (m *mockTiFlashReplicaManagerCtx) Close(ctx context.Context) { m.Lock() defer m.Unlock() if m.tiflash == nil { diff --git a/domain/main_test.go b/domain/main_test.go index 163fedbad111a..f236b8461fa12 100644 --- a/domain/main_test.go +++ b/domain/main_test.go @@ -27,6 +27,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/domain/plan_replayer.go b/domain/plan_replayer.go index b207f904a6608..0f72a1ac8a575 100644 --- a/domain/plan_replayer.go +++ b/domain/plan_replayer.go @@ -15,7 +15,8 @@ package domain import ( - "errors" + "context" + "fmt" "io/ioutil" "os" "path/filepath" @@ -24,7 +25,21 @@ import ( "sync" "time" + "github.com/pingcap/errors" + "github.com/pingcap/tidb/bindinfo" + "github.com/pingcap/tidb/domain/infosync" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/replayer" + "github.com/pingcap/tidb/util/sqlexec" "go.uber.org/zap" ) @@ -32,14 +47,14 @@ import ( // For now it is used by `plan replayer` and `trace plan` statement type dumpFileGcChecker struct { sync.Mutex - gcLease time.Duration - paths []string + gcLease time.Duration + paths []string + sctx sessionctx.Context + planReplayerTaskStatus *planReplayerDumpTaskStatus } -// GetPlanReplayerDirName returns plan replayer directory path. -// The path is related to the process id. -func GetPlanReplayerDirName() string { - return filepath.Join(os.TempDir(), "replayer", strconv.Itoa(os.Getpid())) +func parseType(s string) string { + return strings.Split(s, "_")[0] } func parseTime(s string) (time.Time, error) { @@ -66,6 +81,10 @@ func (p *dumpFileGcChecker) gcDumpFiles(t time.Duration) { } } +func (p *dumpFileGcChecker) setupSctx(sctx sessionctx.Context) { + p.sctx = sctx +} + func (p *dumpFileGcChecker) gcDumpFilesByPath(path string, t time.Duration) { files, err := ioutil.ReadDir(path) if err != nil { @@ -82,6 +101,7 @@ func (p *dumpFileGcChecker) gcDumpFilesByPath(path string, t time.Duration) { logutil.BgLogger().Error("[dumpFileGcChecker] parseTime failed", zap.Error(err), zap.String("filename", fileName)) continue } + isPlanReplayer := strings.Contains(fileName, "replayer") if !createTime.After(gcTime) { err := os.Remove(filepath.Join(path, f.Name())) if err != nil { @@ -89,6 +109,453 @@ func (p *dumpFileGcChecker) gcDumpFilesByPath(path string, t time.Duration) { continue } logutil.BgLogger().Info("dumpFileGcChecker successful", zap.String("filename", fileName)) + if isPlanReplayer && p.sctx != nil { + deletePlanReplayerStatus(context.Background(), p.sctx, fileName) + p.planReplayerTaskStatus.clearFinishedTask() + } + } + } +} + +func deletePlanReplayerStatus(ctx context.Context, sctx sessionctx.Context, token string) { + ctx1 := kv.WithInternalSourceType(ctx, kv.InternalTxnStats) + exec := sctx.(sqlexec.SQLExecutor) + _, err := exec.ExecuteInternal(ctx1, fmt.Sprintf("delete from mysql.plan_replayer_status where token = %v", token)) + if err != nil { + logutil.BgLogger().Warn("delete mysql.plan_replayer_status record failed", zap.String("token", token), zap.Error(err)) + } +} + +// insertPlanReplayerStatus insert mysql.plan_replayer_status record +func insertPlanReplayerStatus(ctx context.Context, sctx sessionctx.Context, records []PlanReplayerStatusRecord) { + ctx1 := kv.WithInternalSourceType(ctx, kv.InternalTxnStats) + var instance string + serverInfo, err := infosync.GetServerInfo() + if err != nil { + logutil.BgLogger().Error("failed to get server info", zap.Error(err)) + instance = "unknown" + } else { + instance = fmt.Sprintf("%s:%d", serverInfo.IP, serverInfo.Port) + } + for _, record := range records { + if len(record.FailedReason) > 0 { + insertPlanReplayerErrorStatusRecord(ctx1, sctx, instance, record) + } else { + insertPlanReplayerSuccessStatusRecord(ctx1, sctx, instance, record) + } + } +} + +func insertPlanReplayerErrorStatusRecord(ctx context.Context, sctx sessionctx.Context, instance string, record PlanReplayerStatusRecord) { + exec := sctx.(sqlexec.SQLExecutor) + _, err := exec.ExecuteInternal(ctx, fmt.Sprintf( + "insert into mysql.plan_replayer_status (sql_digest, plan_digest, origin_sql, fail_reason, instance) values ('%s','%s','%s','%s','%s')", + record.SQLDigest, record.PlanDigest, record.OriginSQL, record.FailedReason, instance)) + if err != nil { + logutil.BgLogger().Warn("insert mysql.plan_replayer_status record failed", + zap.Error(err)) + } +} + +func insertPlanReplayerSuccessStatusRecord(ctx context.Context, sctx sessionctx.Context, instance string, record PlanReplayerStatusRecord) { + exec := sctx.(sqlexec.SQLExecutor) + _, err := exec.ExecuteInternal(ctx, fmt.Sprintf( + "insert into mysql.plan_replayer_status (sql_digest, plan_digest, origin_sql, token, instance) values ('%s','%s','%s','%s','%s')", + record.SQLDigest, record.PlanDigest, record.OriginSQL, record.Token, instance)) + if err != nil { + logutil.BgLogger().Warn("insert mysql.plan_replayer_status record failed", + zap.Error(err)) + } +} + +var ( + planReplayerCaptureTaskSendCounter = metrics.PlanReplayerTaskCounter.WithLabelValues("capture", "send") + planReplayerCaptureTaskDiscardCounter = metrics.PlanReplayerTaskCounter.WithLabelValues("capture", "discard") + + planReplayerRegisterTaskGauge = metrics.PlanReplayerRegisterTaskGauge +) + +type planReplayerHandle struct { + *planReplayerTaskCollectorHandle + *planReplayerTaskDumpHandle +} + +// SendTask send dumpTask in background task handler +func (h *planReplayerHandle) SendTask(task *PlanReplayerDumpTask) bool { + select { + case h.planReplayerTaskDumpHandle.taskCH <- task: + // we directly remove the task key if we put task in channel successfully, if the task was failed to dump, + // the task handle will re-add the task in next loop + if !task.IsContinuesCapture { + h.planReplayerTaskCollectorHandle.removeTask(task.PlanReplayerTaskKey) + } + planReplayerCaptureTaskSendCounter.Inc() + return true + default: + planReplayerCaptureTaskDiscardCounter.Inc() + // directly discard the task if the task channel is full in order not to block the query process + logutil.BgLogger().Warn("discard one plan replayer dump task", + zap.String("sql-digest", task.SQLDigest), zap.String("plan-digest", task.PlanDigest)) + return false + } +} + +type planReplayerTaskCollectorHandle struct { + taskMu struct { + sync.RWMutex + tasks map[replayer.PlanReplayerTaskKey]struct{} + } + ctx context.Context + sctx sessionctx.Context +} + +// CollectPlanReplayerTask collects all unhandled plan replayer task +func (h *planReplayerTaskCollectorHandle) CollectPlanReplayerTask() error { + allKeys, err := h.collectAllPlanReplayerTask(h.ctx) + if err != nil { + return err + } + tasks := make([]replayer.PlanReplayerTaskKey, 0) + for _, key := range allKeys { + unhandled, err := checkUnHandledReplayerTask(h.ctx, h.sctx, key) + if err != nil { + logutil.BgLogger().Warn("[plan-replayer-task] collect plan replayer task failed", zap.Error(err)) + return err + } + if unhandled { + logutil.BgLogger().Debug("[plan-replayer-task] collect plan replayer task success", + zap.String("sql-digest", key.SQLDigest), + zap.String("plan-digest", key.PlanDigest)) + tasks = append(tasks, key) + } + } + h.setupTasks(tasks) + planReplayerRegisterTaskGauge.Set(float64(len(tasks))) + return nil +} + +// GetTasks get all tasks +func (h *planReplayerTaskCollectorHandle) GetTasks() []replayer.PlanReplayerTaskKey { + tasks := make([]replayer.PlanReplayerTaskKey, 0) + h.taskMu.RLock() + defer h.taskMu.RUnlock() + for taskKey := range h.taskMu.tasks { + tasks = append(tasks, taskKey) + } + return tasks +} + +func (h *planReplayerTaskCollectorHandle) setupTasks(tasks []replayer.PlanReplayerTaskKey) { + r := make(map[replayer.PlanReplayerTaskKey]struct{}) + for _, task := range tasks { + r[task] = struct{}{} + } + h.taskMu.Lock() + defer h.taskMu.Unlock() + h.taskMu.tasks = r +} + +func (h *planReplayerTaskCollectorHandle) removeTask(taskKey replayer.PlanReplayerTaskKey) { + h.taskMu.Lock() + defer h.taskMu.Unlock() + delete(h.taskMu.tasks, taskKey) +} + +func (h *planReplayerTaskCollectorHandle) collectAllPlanReplayerTask(ctx context.Context) ([]replayer.PlanReplayerTaskKey, error) { + exec := h.sctx.(sqlexec.SQLExecutor) + rs, err := exec.ExecuteInternal(ctx, "select sql_digest, plan_digest from mysql.plan_replayer_task") + if err != nil { + return nil, err + } + if rs == nil { + return nil, nil + } + var rows []chunk.Row + defer terror.Call(rs.Close) + if rows, err = sqlexec.DrainRecordSet(ctx, rs, 8); err != nil { + return nil, errors.Trace(err) + } + allKeys := make([]replayer.PlanReplayerTaskKey, 0, len(rows)) + for _, row := range rows { + sqlDigest, planDigest := row.GetString(0), row.GetString(1) + allKeys = append(allKeys, replayer.PlanReplayerTaskKey{ + SQLDigest: sqlDigest, + PlanDigest: planDigest, + }) + } + return allKeys, nil +} + +type planReplayerDumpTaskStatus struct { + // running task records the task running by all workers in order to avoid multi workers running the same task key + runningTaskMu struct { + sync.RWMutex + runningTasks map[replayer.PlanReplayerTaskKey]struct{} + } + + // finished task records the finished task in order to avoid running finished task key + finishedTaskMu struct { + sync.RWMutex + finishedTask map[replayer.PlanReplayerTaskKey]struct{} + } +} + +// GetRunningTaskStatusLen used for unit test +func (r *planReplayerDumpTaskStatus) GetRunningTaskStatusLen() int { + r.runningTaskMu.RLock() + defer r.runningTaskMu.RUnlock() + return len(r.runningTaskMu.runningTasks) +} + +// CleanFinishedTaskStatus clean then finished tasks, only used for unit test +func (r *planReplayerDumpTaskStatus) CleanFinishedTaskStatus() { + r.finishedTaskMu.Lock() + defer r.finishedTaskMu.Unlock() + r.finishedTaskMu.finishedTask = map[replayer.PlanReplayerTaskKey]struct{}{} +} + +// GetFinishedTaskStatusLen used for unit test +func (r *planReplayerDumpTaskStatus) GetFinishedTaskStatusLen() int { + r.finishedTaskMu.RLock() + defer r.finishedTaskMu.RUnlock() + return len(r.finishedTaskMu.finishedTask) +} + +func (r *planReplayerDumpTaskStatus) occupyRunningTaskKey(task *PlanReplayerDumpTask) bool { + r.runningTaskMu.Lock() + defer r.runningTaskMu.Unlock() + _, ok := r.runningTaskMu.runningTasks[task.PlanReplayerTaskKey] + if ok { + return false + } + r.runningTaskMu.runningTasks[task.PlanReplayerTaskKey] = struct{}{} + return true +} + +func (r *planReplayerDumpTaskStatus) releaseRunningTaskKey(task *PlanReplayerDumpTask) { + r.runningTaskMu.Lock() + defer r.runningTaskMu.Unlock() + delete(r.runningTaskMu.runningTasks, task.PlanReplayerTaskKey) +} + +func (r *planReplayerDumpTaskStatus) checkTaskKeyFinishedBefore(task *PlanReplayerDumpTask) bool { + r.finishedTaskMu.RLock() + defer r.finishedTaskMu.RUnlock() + _, ok := r.finishedTaskMu.finishedTask[task.PlanReplayerTaskKey] + return ok +} + +func (r *planReplayerDumpTaskStatus) setTaskFinished(task *PlanReplayerDumpTask) { + r.finishedTaskMu.Lock() + defer r.finishedTaskMu.Unlock() + r.finishedTaskMu.finishedTask[task.PlanReplayerTaskKey] = struct{}{} +} + +func (r *planReplayerDumpTaskStatus) clearFinishedTask() { + r.finishedTaskMu.Lock() + defer r.finishedTaskMu.Unlock() + r.finishedTaskMu.finishedTask = map[replayer.PlanReplayerTaskKey]struct{}{} +} + +type planReplayerTaskDumpWorker struct { + ctx context.Context + sctx sessionctx.Context + taskCH <-chan *PlanReplayerDumpTask + status *planReplayerDumpTaskStatus +} + +func (w *planReplayerTaskDumpWorker) run() { + logutil.BgLogger().Info("planReplayerTaskDumpWorker started.") + for task := range w.taskCH { + w.handleTask(task) + } + logutil.BgLogger().Info("planReplayerTaskDumpWorker exited.") +} + +func (w *planReplayerTaskDumpWorker) handleTask(task *PlanReplayerDumpTask) { + sqlDigest := task.SQLDigest + planDigest := task.PlanDigest + check := true + occupy := true + handleTask := true + defer func() { + logutil.BgLogger().Debug("[plan-replayer-capture] handle task", + zap.String("sql-digest", sqlDigest), + zap.String("plan-digest", planDigest), + zap.Bool("check", check), + zap.Bool("occupy", occupy), + zap.Bool("handle", handleTask)) + }() + if task.IsContinuesCapture { + if w.status.checkTaskKeyFinishedBefore(task) { + check = false + return } } + occupy = w.status.occupyRunningTaskKey(task) + if !occupy { + return + } + handleTask = w.HandleTask(task) + w.status.releaseRunningTaskKey(task) +} + +// HandleTask handled task +func (w *planReplayerTaskDumpWorker) HandleTask(task *PlanReplayerDumpTask) (success bool) { + defer func() { + if success && task.IsContinuesCapture { + w.status.setTaskFinished(task) + } + }() + taskKey := task.PlanReplayerTaskKey + unhandled, err := checkUnHandledReplayerTask(w.ctx, w.sctx, taskKey) + if err != nil { + logutil.BgLogger().Warn("[plan-replayer-capture] check task failed", + zap.String("sqlDigest", taskKey.SQLDigest), + zap.String("planDigest", taskKey.PlanDigest), + zap.Error(err)) + return false + } + // the task is processed, thus we directly skip it. + if !unhandled { + return true + } + + file, fileName, err := replayer.GeneratePlanReplayerFile(task.IsCapture, task.IsContinuesCapture, variable.EnableHistoricalStatsForCapture.Load()) + if err != nil { + logutil.BgLogger().Warn("[plan-replayer-capture] generate task file failed", + zap.String("sqlDigest", taskKey.SQLDigest), + zap.String("planDigest", taskKey.PlanDigest), + zap.Error(err)) + return false + } + task.Zf = file + task.FileName = fileName + task.EncodedPlan, _ = task.EncodePlan(task.SessionVars.StmtCtx, false) + if task.InExecute && len(task.NormalizedSQL) > 0 { + p := parser.New() + stmts, _, err := p.ParseSQL(task.NormalizedSQL) + if err != nil { + logutil.BgLogger().Warn("[plan-replayer-capture] parse normalized sql failed", + zap.String("sql", task.NormalizedSQL), + zap.String("sqlDigest", taskKey.SQLDigest), + zap.String("planDigest", taskKey.PlanDigest), + zap.Error(err)) + return false + } + task.ExecStmts = stmts + } + err = DumpPlanReplayerInfo(w.ctx, w.sctx, task) + if err != nil { + logutil.BgLogger().Warn("[plan-replayer-capture] dump task result failed", + zap.String("sqlDigest", taskKey.SQLDigest), + zap.String("planDigest", taskKey.PlanDigest), + zap.Error(err)) + return false + } + return true +} + +type planReplayerTaskDumpHandle struct { + taskCH chan *PlanReplayerDumpTask + status *planReplayerDumpTaskStatus + workers []*planReplayerTaskDumpWorker +} + +// GetTaskStatus used for test +func (h *planReplayerTaskDumpHandle) GetTaskStatus() *planReplayerDumpTaskStatus { + return h.status +} + +// GetWorker used for test +func (h *planReplayerTaskDumpHandle) GetWorker() *planReplayerTaskDumpWorker { + return h.workers[0] +} + +// Close make finished flag ture +func (h *planReplayerTaskDumpHandle) Close() { + close(h.taskCH) +} + +// DrainTask drain a task for unit test +func (h *planReplayerTaskDumpHandle) DrainTask() *PlanReplayerDumpTask { + return <-h.taskCH +} + +func checkUnHandledReplayerTask(ctx context.Context, sctx sessionctx.Context, task replayer.PlanReplayerTaskKey) (bool, error) { + exec := sctx.(sqlexec.SQLExecutor) + rs, err := exec.ExecuteInternal(ctx, fmt.Sprintf("select * from mysql.plan_replayer_status where sql_digest = '%v' and plan_digest = '%v' and fail_reason is null", task.SQLDigest, task.PlanDigest)) + if err != nil { + return false, err + } + if rs == nil { + return true, nil + } + var rows []chunk.Row + defer terror.Call(rs.Close) + if rows, err = sqlexec.DrainRecordSet(ctx, rs, 8); err != nil { + return false, errors.Trace(err) + } + if len(rows) > 0 { + return false, nil + } + return true, nil +} + +// CheckPlanReplayerTaskExists checks whether plan replayer capture task exists already +func CheckPlanReplayerTaskExists(ctx context.Context, sctx sessionctx.Context, sqlDigest, planDigest string) (bool, error) { + exec := sctx.(sqlexec.SQLExecutor) + rs, err := exec.ExecuteInternal(ctx, fmt.Sprintf("select * from mysql.plan_replayer_task where sql_digest = '%v' and plan_digest = '%v'", + sqlDigest, planDigest)) + if err != nil { + return false, err + } + if rs == nil { + return false, nil + } + var rows []chunk.Row + defer terror.Call(rs.Close) + if rows, err = sqlexec.DrainRecordSet(ctx, rs, 8); err != nil { + return false, errors.Trace(err) + } + if len(rows) > 0 { + return true, nil + } + return false, nil +} + +// PlanReplayerStatusRecord indicates record in mysql.plan_replayer_status +type PlanReplayerStatusRecord struct { + SQLDigest string + PlanDigest string + OriginSQL string + Token string + FailedReason string +} + +// PlanReplayerDumpTask wrap the params for plan replayer dump +type PlanReplayerDumpTask struct { + replayer.PlanReplayerTaskKey + + // tmp variables stored during the query + EncodePlan func(*stmtctx.StatementContext, bool) (string, string) + TblStats map[int64]interface{} + InExecute bool + NormalizedSQL string + + // variables used to dump the plan + StartTS uint64 + SessionBindings []*bindinfo.BindRecord + EncodedPlan string + SessionVars *variable.SessionVars + ExecStmts []ast.StmtNode + Analyze bool + + FileName string + Zf *os.File + + // IsCapture indicates whether the task is from capture + IsCapture bool + // IsContinuesCapture indicates whether the task is from continues capture + IsContinuesCapture bool } diff --git a/domain/plan_replayer_dump.go b/domain/plan_replayer_dump.go new file mode 100644 index 0000000000000..01ab473e16a90 --- /dev/null +++ b/domain/plan_replayer_dump.go @@ -0,0 +1,808 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package domain + +import ( + "archive/zip" + "context" + "encoding/json" + "fmt" + "io" + "strconv" + "strings" + + "github.com/BurntSushi/toml" + "github.com/pingcap/errors" + "github.com/pingcap/tidb/bindinfo" + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/statistics/handle" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/printer" + "github.com/pingcap/tidb/util/sqlexec" + "go.uber.org/zap" +) + +const ( + // PlanReplayerSQLMetaFile indicates sql meta path for plan replayer + PlanReplayerSQLMetaFile = "sql_meta.toml" + // PlanReplayerConfigFile indicates config file path for plan replayer + PlanReplayerConfigFile = "config.toml" + // PlanReplayerMetaFile meta file path for plan replayer + PlanReplayerMetaFile = "meta.txt" + // PlanReplayerVariablesFile indicates for session variables file path for plan replayer + PlanReplayerVariablesFile = "variables.toml" + // PlanReplayerTiFlashReplicasFile indicates for table tiflash replica file path for plan replayer + PlanReplayerTiFlashReplicasFile = "table_tiflash_replica.txt" + // PlanReplayerSessionBindingFile indicates session binding file path for plan replayer + PlanReplayerSessionBindingFile = "session_bindings.sql" + // PlanReplayerGlobalBindingFile indicates global binding file path for plan replayer + PlanReplayerGlobalBindingFile = "global_bindings.sql" + // PlanReplayerSchemaMetaFile indicates the schema meta + PlanReplayerSchemaMetaFile = "schema_meta.txt" +) + +const ( + // PlanReplayerSQLMetaStartTS indicates the startTS in plan replayer sql meta + PlanReplayerSQLMetaStartTS = "startTS" + // PlanReplayerTaskMetaIsCapture indicates whether this task is capture task + PlanReplayerTaskMetaIsCapture = "isCapture" + // PlanReplayerTaskMetaIsContinues indicates whether this task is continues task + PlanReplayerTaskMetaIsContinues = "isContinues" + // PlanReplayerTaskMetaSQLDigest indicates the sql digest of this task + PlanReplayerTaskMetaSQLDigest = "sqlDigest" + // PlanReplayerTaskMetaPlanDigest indicates the plan digest of this task + PlanReplayerTaskMetaPlanDigest = "planDigest" + // PlanReplayerTaskEnableHistoricalStats indicates whether the task is using historical stats + PlanReplayerTaskEnableHistoricalStats = "enableHistoricalStats" +) + +type tableNamePair struct { + DBName string + TableName string + IsView bool +} + +type tableNameExtractor struct { + ctx context.Context + executor sqlexec.RestrictedSQLExecutor + is infoschema.InfoSchema + curDB model.CIStr + names map[tableNamePair]struct{} + cteNames map[string]struct{} + err error +} + +func (tne *tableNameExtractor) Enter(in ast.Node) (ast.Node, bool) { + if _, ok := in.(*ast.TableName); ok { + return in, true + } + return in, false +} + +func (tne *tableNameExtractor) Leave(in ast.Node) (ast.Node, bool) { + if tne.err != nil { + return in, true + } + if t, ok := in.(*ast.TableName); ok { + isView, err := tne.handleIsView(t) + if err != nil { + tne.err = err + return in, true + } + tp := tableNamePair{DBName: t.Schema.L, TableName: t.Name.L, IsView: isView} + if tp.DBName == "" { + tp.DBName = tne.curDB.L + } + if _, ok := tne.names[tp]; !ok { + tne.names[tp] = struct{}{} + } + } else if s, ok := in.(*ast.SelectStmt); ok { + if s.With != nil && len(s.With.CTEs) > 0 { + for _, cte := range s.With.CTEs { + tne.cteNames[cte.Name.L] = struct{}{} + } + } + } + return in, true +} + +func (tne *tableNameExtractor) handleIsView(t *ast.TableName) (bool, error) { + schema := t.Schema + if schema.L == "" { + schema = tne.curDB + } + table := t.Name + isView := tne.is.TableIsView(schema, table) + if !isView { + return false, nil + } + viewTbl, err := tne.is.TableByName(schema, table) + if err != nil { + return false, err + } + sql := viewTbl.Meta().View.SelectStmt + node, err := tne.executor.ParseWithParams(tne.ctx, sql) + if err != nil { + return false, err + } + node.Accept(tne) + return true, nil +} + +var ( + planReplayerDumpTaskSuccess = metrics.PlanReplayerTaskCounter.WithLabelValues("dump", "success") + planReplayerDumpTaskFailed = metrics.PlanReplayerTaskCounter.WithLabelValues("dump", "fail") +) + +// DumpPlanReplayerInfo will dump the information about sqls. +// The files will be organized into the following format: +/* + |-sql_meta.toml + |-meta.txt + |-schema + | |-schema_meta.txt + | |-db1.table1.schema.txt + | |-db2.table2.schema.txt + | |-.... + |-view + | |-db1.view1.view.txt + | |-db2.view2.view.txt + | |-.... + |-stats + | |-stats1.json + | |-stats2.json + | |-.... + |-statsMem + | |-stats1.txt + | |-stats2.txt + | |-.... + |-config.toml + |-table_tiflash_replica.txt + |-variables.toml + |-bindings.sql + |-sql + | |-sql1.sql + | |-sql2.sql + | |-.... + |_explain + |-explain1.txt + |-explain2.txt + |-.... +*/ +func DumpPlanReplayerInfo(ctx context.Context, sctx sessionctx.Context, + task *PlanReplayerDumpTask) (err error) { + zf := task.Zf + fileName := task.FileName + sessionVars := task.SessionVars + execStmts := task.ExecStmts + zw := zip.NewWriter(zf) + var records []PlanReplayerStatusRecord + sqls := make([]string, 0) + for _, execStmt := range task.ExecStmts { + sqls = append(sqls, execStmt.Text()) + } + if task.IsCapture { + logutil.BgLogger().Info("[plan-replayer-dump] start to dump plan replayer result", + zap.String("sql-digest", task.SQLDigest), + zap.String("plan-digest", task.PlanDigest), + zap.Strings("sql", sqls), + zap.Bool("isContinues", task.IsContinuesCapture)) + } else { + logutil.BgLogger().Info("[plan-replayer-dump] start to dump plan replayer result", + zap.Strings("sqls", sqls)) + } + defer func() { + errMsg := "" + if err != nil { + if task.IsCapture { + logutil.BgLogger().Info("[plan-replayer-dump] dump file failed", + zap.String("sql-digest", task.SQLDigest), + zap.String("plan-digest", task.PlanDigest), + zap.Strings("sql", sqls), + zap.Bool("isContinues", task.IsContinuesCapture)) + } else { + logutil.BgLogger().Info("[plan-replayer-dump] start to dump plan replayer result", + zap.Strings("sqls", sqls)) + } + errMsg = err.Error() + planReplayerDumpTaskFailed.Inc() + } else { + planReplayerDumpTaskSuccess.Inc() + } + err1 := zw.Close() + if err1 != nil { + logutil.BgLogger().Error("[plan-replayer-dump] Closing zip writer failed", zap.Error(err), zap.String("filename", fileName)) + errMsg = errMsg + "," + err1.Error() + } + err2 := zf.Close() + if err2 != nil { + logutil.BgLogger().Error("[plan-replayer-dump] Closing zip file failed", zap.Error(err), zap.String("filename", fileName)) + errMsg = errMsg + "," + err2.Error() + } + if len(errMsg) > 0 { + for i, record := range records { + record.FailedReason = errMsg + records[i] = record + } + } + insertPlanReplayerStatus(ctx, sctx, records) + }() + // Dump SQLMeta + if err = dumpSQLMeta(zw, task); err != nil { + return err + } + + // Dump config + if err = dumpConfig(zw); err != nil { + return err + } + + // Dump meta + if err = dumpMeta(zw); err != nil { + return err + } + // Retrieve current DB + dbName := model.NewCIStr(sessionVars.CurrentDB) + do := GetDomain(sctx) + + // Retrieve all tables + pairs, err := extractTableNames(ctx, sctx, execStmts, dbName) + if err != nil { + return errors.AddStack(fmt.Errorf("plan replayer: invalid SQL text, err: %v", err)) + } + + // Dump Schema and View + if err = dumpSchemas(sctx, zw, pairs); err != nil { + return err + } + + // Dump tables tiflash replicas + if err = dumpTiFlashReplica(sctx, zw, pairs); err != nil { + return err + } + + // For capture task, we dump stats in storage only if EnableHistoricalStatsForCapture is disabled. + // For manual plan replayer dump command, we directly dump stats in storage + if !variable.EnableHistoricalStatsForCapture.Load() || !task.IsCapture { + // Dump stats + if err = dumpStats(zw, pairs, do); err != nil { + return err + } + } + + if err = dumpStatsMemStatus(zw, pairs, do); err != nil { + return err + } + + // Dump variables + if err = dumpVariables(sctx, sessionVars, zw); err != nil { + return err + } + + // Dump sql + if err = dumpSQLs(execStmts, zw); err != nil { + return err + } + + // Dump session bindings + if len(task.SessionBindings) > 0 { + if err = dumpSessionBindRecords(task.SessionBindings, zw); err != nil { + return err + } + } else { + if err = dumpSessionBindings(sctx, zw); err != nil { + return err + } + } + + // Dump global bindings + if err = dumpGlobalBindings(sctx, zw); err != nil { + return err + } + + if len(task.EncodedPlan) > 0 { + records = generateRecords(task) + return dumpEncodedPlan(sctx, zw, task.EncodedPlan) + } + // Dump explain + return dumpExplain(sctx, zw, task, &records) +} + +func generateRecords(task *PlanReplayerDumpTask) []PlanReplayerStatusRecord { + records := make([]PlanReplayerStatusRecord, 0) + if len(task.ExecStmts) > 0 { + for _, execStmt := range task.ExecStmts { + records = append(records, PlanReplayerStatusRecord{ + SQLDigest: task.SQLDigest, + PlanDigest: task.PlanDigest, + OriginSQL: execStmt.Text(), + Token: task.FileName, + }) + } + } + return records +} + +func dumpSQLMeta(zw *zip.Writer, task *PlanReplayerDumpTask) error { + cf, err := zw.Create(PlanReplayerSQLMetaFile) + if err != nil { + return errors.AddStack(err) + } + varMap := make(map[string]string) + varMap[PlanReplayerSQLMetaStartTS] = strconv.FormatUint(task.StartTS, 10) + varMap[PlanReplayerTaskMetaIsCapture] = strconv.FormatBool(task.IsCapture) + varMap[PlanReplayerTaskMetaIsContinues] = strconv.FormatBool(task.IsContinuesCapture) + varMap[PlanReplayerTaskMetaSQLDigest] = task.SQLDigest + varMap[PlanReplayerTaskMetaPlanDigest] = task.PlanDigest + varMap[PlanReplayerTaskEnableHistoricalStats] = strconv.FormatBool(variable.EnableHistoricalStatsForCapture.Load()) + if err := toml.NewEncoder(cf).Encode(varMap); err != nil { + return errors.AddStack(err) + } + return nil +} + +func dumpConfig(zw *zip.Writer) error { + cf, err := zw.Create(PlanReplayerConfigFile) + if err != nil { + return errors.AddStack(err) + } + if err := toml.NewEncoder(cf).Encode(config.GetGlobalConfig()); err != nil { + return errors.AddStack(err) + } + return nil +} + +func dumpMeta(zw *zip.Writer) error { + mt, err := zw.Create(PlanReplayerMetaFile) + if err != nil { + return errors.AddStack(err) + } + _, err = mt.Write([]byte(printer.GetTiDBInfo())) + if err != nil { + return errors.AddStack(err) + } + return nil +} + +func dumpTiFlashReplica(ctx sessionctx.Context, zw *zip.Writer, pairs map[tableNamePair]struct{}) error { + bf, err := zw.Create(PlanReplayerTiFlashReplicasFile) + if err != nil { + return errors.AddStack(err) + } + is := GetDomain(ctx).InfoSchema() + for pair := range pairs { + dbName := model.NewCIStr(pair.DBName) + tableName := model.NewCIStr(pair.TableName) + t, err := is.TableByName(dbName, tableName) + if err != nil { + logutil.BgLogger().Warn("failed to find table info", zap.Error(err), + zap.String("dbName", dbName.L), zap.String("tableName", tableName.L)) + continue + } + if t.Meta().TiFlashReplica != nil && t.Meta().TiFlashReplica.Count > 0 { + row := []string{ + pair.DBName, pair.TableName, strconv.FormatUint(t.Meta().TiFlashReplica.Count, 10), + } + fmt.Fprintf(bf, "%s\n", strings.Join(row, "\t")) + } + } + return nil +} + +func dumpSchemas(ctx sessionctx.Context, zw *zip.Writer, pairs map[tableNamePair]struct{}) error { + tables := make(map[tableNamePair]struct{}) + for pair := range pairs { + err := getShowCreateTable(pair, zw, ctx) + if err != nil { + return err + } + if !pair.IsView { + tables[pair] = struct{}{} + } + } + return dumpSchemaMeta(zw, tables) +} + +func dumpSchemaMeta(zw *zip.Writer, tables map[tableNamePair]struct{}) error { + zf, err := zw.Create(fmt.Sprintf("schema/%v", PlanReplayerSchemaMetaFile)) + if err != nil { + return err + } + for table := range tables { + _, err := fmt.Fprintf(zf, "%s;%s", table.DBName, table.TableName) + if err != nil { + return err + } + } + return nil +} + +func dumpStatsMemStatus(zw *zip.Writer, pairs map[tableNamePair]struct{}, do *Domain) error { + statsHandle := do.StatsHandle() + is := do.InfoSchema() + for pair := range pairs { + if pair.IsView { + continue + } + tbl, err := is.TableByName(model.NewCIStr(pair.DBName), model.NewCIStr(pair.TableName)) + if err != nil { + return err + } + tblStats := statsHandle.GetTableStats(tbl.Meta()) + if tblStats == nil { + continue + } + statsMemFw, err := zw.Create(fmt.Sprintf("statsMem/%v.%v.txt", pair.DBName, pair.TableName)) + if err != nil { + return errors.AddStack(err) + } + fmt.Fprintf(statsMemFw, "[INDEX]\n") + for _, indice := range tblStats.Indices { + fmt.Fprintf(statsMemFw, "%s\n", fmt.Sprintf("%s=%s", indice.Info.Name.String(), indice.StatusToString())) + } + fmt.Fprintf(statsMemFw, "[COLUMN]\n") + for _, col := range tblStats.Columns { + fmt.Fprintf(statsMemFw, "%s\n", fmt.Sprintf("%s=%s", col.Info.Name.String(), col.StatusToString())) + } + } + return nil +} + +func dumpStats(zw *zip.Writer, pairs map[tableNamePair]struct{}, do *Domain) error { + for pair := range pairs { + if pair.IsView { + continue + } + jsonTbl, err := getStatsForTable(do, pair) + if err != nil { + return err + } + statsFw, err := zw.Create(fmt.Sprintf("stats/%v.%v.json", pair.DBName, pair.TableName)) + if err != nil { + return errors.AddStack(err) + } + data, err := json.Marshal(jsonTbl) + if err != nil { + return errors.AddStack(err) + } + _, err = statsFw.Write(data) + if err != nil { + return errors.AddStack(err) + } + } + return nil +} + +func dumpSQLs(execStmts []ast.StmtNode, zw *zip.Writer) error { + for i, stmtExec := range execStmts { + zf, err := zw.Create(fmt.Sprintf("sql/sql%v.sql", i)) + if err != nil { + return err + } + _, err = zf.Write([]byte(stmtExec.Text())) + if err != nil { + return err + } + } + return nil +} + +func dumpVariables(sctx sessionctx.Context, sessionVars *variable.SessionVars, zw *zip.Writer) error { + varMap := make(map[string]string) + for _, v := range variable.GetSysVars() { + if v.IsNoop && !variable.EnableNoopVariables.Load() { + continue + } + if infoschema.SysVarHiddenForSem(sctx, v.Name) { + continue + } + value, err := sessionVars.GetSessionOrGlobalSystemVar(context.Background(), v.Name) + if err != nil { + return errors.Trace(err) + } + varMap[v.Name] = value + } + vf, err := zw.Create(PlanReplayerVariablesFile) + if err != nil { + return errors.AddStack(err) + } + if err := toml.NewEncoder(vf).Encode(varMap); err != nil { + return errors.AddStack(err) + } + return nil +} + +func dumpSessionBindRecords(records []*bindinfo.BindRecord, zw *zip.Writer) error { + sRows := make([][]string, 0) + for _, bindData := range records { + for _, hint := range bindData.Bindings { + sRows = append(sRows, []string{ + bindData.OriginalSQL, + hint.BindSQL, + bindData.Db, + hint.Status, + hint.CreateTime.String(), + hint.UpdateTime.String(), + hint.Charset, + hint.Collation, + hint.Source, + }) + } + } + bf, err := zw.Create(PlanReplayerSessionBindingFile) + if err != nil { + return errors.AddStack(err) + } + for _, row := range sRows { + fmt.Fprintf(bf, "%s\n", strings.Join(row, "\t")) + } + return nil +} + +func dumpSessionBindings(ctx sessionctx.Context, zw *zip.Writer) error { + recordSets, err := ctx.(sqlexec.SQLExecutor).Execute(context.Background(), "show bindings") + if err != nil { + return err + } + sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], true) + if err != nil { + return err + } + bf, err := zw.Create(PlanReplayerSessionBindingFile) + if err != nil { + return errors.AddStack(err) + } + for _, row := range sRows { + fmt.Fprintf(bf, "%s\n", strings.Join(row, "\t")) + } + if len(recordSets) > 0 { + if err := recordSets[0].Close(); err != nil { + return err + } + } + return nil +} + +func dumpGlobalBindings(ctx sessionctx.Context, zw *zip.Writer) error { + recordSets, err := ctx.(sqlexec.SQLExecutor).Execute(context.Background(), "show global bindings") + if err != nil { + return err + } + sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) + if err != nil { + return err + } + bf, err := zw.Create(PlanReplayerGlobalBindingFile) + if err != nil { + return errors.AddStack(err) + } + for _, row := range sRows { + fmt.Fprintf(bf, "%s\n", strings.Join(row, "\t")) + } + if len(recordSets) > 0 { + if err := recordSets[0].Close(); err != nil { + return err + } + } + return nil +} + +func dumpEncodedPlan(ctx sessionctx.Context, zw *zip.Writer, encodedPlan string) error { + var recordSets []sqlexec.RecordSet + var err error + recordSets, err = ctx.(sqlexec.SQLExecutor).Execute(context.Background(), fmt.Sprintf("select tidb_decode_plan('%s')", encodedPlan)) + if err != nil { + return err + } + sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) + if err != nil { + return err + } + fw, err := zw.Create("explain/sql.txt") + if err != nil { + return errors.AddStack(err) + } + for _, row := range sRows { + fmt.Fprintf(fw, "%s\n", strings.Join(row, "\t")) + } + if len(recordSets) > 0 { + if err := recordSets[0].Close(); err != nil { + return err + } + } + return nil +} + +func dumpExplain(ctx sessionctx.Context, zw *zip.Writer, task *PlanReplayerDumpTask, records *[]PlanReplayerStatusRecord) error { + for i, stmtExec := range task.ExecStmts { + sql := stmtExec.Text() + var recordSets []sqlexec.RecordSet + var err error + if task.Analyze { + // Explain analyze + recordSets, err = ctx.(sqlexec.SQLExecutor).Execute(context.Background(), fmt.Sprintf("explain analyze %s", sql)) + if err != nil { + return err + } + } else { + // Explain + recordSets, err = ctx.(sqlexec.SQLExecutor).Execute(context.Background(), fmt.Sprintf("explain %s", sql)) + if err != nil { + return err + } + } + sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) + if err != nil { + return err + } + fw, err := zw.Create(fmt.Sprintf("explain/sql%v.txt", i)) + if err != nil { + return errors.AddStack(err) + } + for _, row := range sRows { + fmt.Fprintf(fw, "%s\n", strings.Join(row, "\t")) + } + if len(recordSets) > 0 { + if err := recordSets[0].Close(); err != nil { + return err + } + } + *records = append(*records, PlanReplayerStatusRecord{ + OriginSQL: sql, + Token: task.FileName, + }) + } + return nil +} + +func extractTableNames(ctx context.Context, sctx sessionctx.Context, + ExecStmts []ast.StmtNode, curDB model.CIStr) (map[tableNamePair]struct{}, error) { + tableExtractor := &tableNameExtractor{ + ctx: ctx, + executor: sctx.(sqlexec.RestrictedSQLExecutor), + is: GetDomain(sctx).InfoSchema(), + curDB: curDB, + names: make(map[tableNamePair]struct{}), + cteNames: make(map[string]struct{}), + } + for _, execStmt := range ExecStmts { + execStmt.Accept(tableExtractor) + } + if tableExtractor.err != nil { + return nil, tableExtractor.err + } + r := make(map[tableNamePair]struct{}) + for tablePair := range tableExtractor.names { + if tablePair.IsView { + r[tablePair] = struct{}{} + continue + } + // remove cte in table names + _, ok := tableExtractor.cteNames[tablePair.TableName] + if !ok { + r[tablePair] = struct{}{} + } + } + return r, nil +} + +func getStatsForTable(do *Domain, pair tableNamePair) (*handle.JSONTable, error) { + is := do.InfoSchema() + h := do.StatsHandle() + tbl, err := is.TableByName(model.NewCIStr(pair.DBName), model.NewCIStr(pair.TableName)) + if err != nil { + return nil, err + } + return h.DumpStatsToJSON(pair.DBName, tbl.Meta(), nil, true) +} + +func getShowCreateTable(pair tableNamePair, zw *zip.Writer, ctx sessionctx.Context) error { + recordSets, err := ctx.(sqlexec.SQLExecutor).Execute(context.Background(), fmt.Sprintf("show create table `%v`.`%v`", pair.DBName, pair.TableName)) + if err != nil { + return err + } + sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) + if err != nil { + return err + } + var fw io.Writer + if pair.IsView { + fw, err = zw.Create(fmt.Sprintf("view/%v.%v.view.txt", pair.DBName, pair.TableName)) + if err != nil { + return errors.AddStack(err) + } + if len(sRows) == 0 || len(sRows[0]) != 4 { + return fmt.Errorf("plan replayer: get create view %v.%v failed", pair.DBName, pair.TableName) + } + } else { + fw, err = zw.Create(fmt.Sprintf("schema/%v.%v.schema.txt", pair.DBName, pair.TableName)) + if err != nil { + return errors.AddStack(err) + } + if len(sRows) == 0 || len(sRows[0]) != 2 { + return fmt.Errorf("plan replayer: get create table %v.%v failed", pair.DBName, pair.TableName) + } + } + fmt.Fprintf(fw, "create database if not exists `%v`; use `%v`;", pair.DBName, pair.DBName) + fmt.Fprintf(fw, "%s", sRows[0][1]) + if len(recordSets) > 0 { + if err := recordSets[0].Close(); err != nil { + return err + } + } + return nil +} + +func resultSetToStringSlice(ctx context.Context, rs sqlexec.RecordSet, emptyAsNil bool) ([][]string, error) { + rows, err := getRows(ctx, rs) + if err != nil { + return nil, err + } + err = rs.Close() + if err != nil { + return nil, err + } + sRows := make([][]string, len(rows)) + for i, row := range rows { + iRow := make([]string, row.Len()) + for j := 0; j < row.Len(); j++ { + if row.IsNull(j) { + iRow[j] = "" + } else { + d := row.GetDatum(j, &rs.Fields()[j].Column.FieldType) + iRow[j], err = d.ToString() + if err != nil { + return nil, err + } + if len(iRow[j]) < 1 && emptyAsNil { + iRow[j] = "" + } + } + } + sRows[i] = iRow + } + return sRows, nil +} + +func getRows(ctx context.Context, rs sqlexec.RecordSet) ([]chunk.Row, error) { + if rs == nil { + return nil, nil + } + var rows []chunk.Row + req := rs.NewChunk(nil) + // Must reuse `req` for imitating server.(*clientConn).writeChunks + for { + err := rs.Next(ctx, req) + if err != nil { + return nil, err + } + if req.NumRows() == 0 { + break + } + + iter := chunk.NewIterator4Chunk(req.CopyConstruct()) + for row := iter.Begin(); row != iter.End(); row = iter.Next() { + rows = append(rows, row) + } + } + return rows, nil +} diff --git a/domain/plan_replayer_handle_test.go b/domain/plan_replayer_handle_test.go new file mode 100644 index 0000000000000..cb5d0bd5126bb --- /dev/null +++ b/domain/plan_replayer_handle_test.go @@ -0,0 +1,121 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package domain_test + +import ( + "fmt" + "testing" + + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" +) + +func TestPlanReplayerHandleCollectTask(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + prHandle := dom.GetPlanReplayerHandle() + + // assert 1 task + tk.MustExec("delete from mysql.plan_replayer_task") + tk.MustExec("delete from mysql.plan_replayer_status") + tk.MustExec("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('123','123');") + err := prHandle.CollectPlanReplayerTask() + require.NoError(t, err) + require.Len(t, prHandle.GetTasks(), 1) + + // assert no task + tk.MustExec("delete from mysql.plan_replayer_task") + tk.MustExec("delete from mysql.plan_replayer_status") + err = prHandle.CollectPlanReplayerTask() + require.NoError(t, err) + require.Len(t, prHandle.GetTasks(), 0) + + // assert 1 unhandled task + tk.MustExec("delete from mysql.plan_replayer_task") + tk.MustExec("delete from mysql.plan_replayer_status") + tk.MustExec("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('123','123');") + tk.MustExec("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('345','345');") + tk.MustExec("insert into mysql.plan_replayer_status(sql_digest, plan_digest, token, instance) values ('123','123','123','123')") + err = prHandle.CollectPlanReplayerTask() + require.NoError(t, err) + require.Len(t, prHandle.GetTasks(), 1) + + // assert 2 unhandled task + tk.MustExec("delete from mysql.plan_replayer_task") + tk.MustExec("delete from mysql.plan_replayer_status") + tk.MustExec("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('123','123');") + tk.MustExec("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('345','345');") + tk.MustExec("insert into mysql.plan_replayer_status(sql_digest, plan_digest, fail_reason, instance) values ('123','123','123','123')") + err = prHandle.CollectPlanReplayerTask() + require.NoError(t, err) + require.Len(t, prHandle.GetTasks(), 2) +} + +func TestPlanReplayerHandleDumpTask(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + prHandle := dom.GetPlanReplayerHandle() + tk.MustExec("use test") + tk.MustExec("create table t(a int)") + tk.MustQuery("select * from t;") + _, d := tk.Session().GetSessionVars().StmtCtx.SQLDigest() + _, pd := tk.Session().GetSessionVars().StmtCtx.GetPlanDigest() + sqlDigest := d.String() + planDigest := pd.String() + + // register task + tk.MustExec("delete from mysql.plan_replayer_task") + tk.MustExec("delete from mysql.plan_replayer_status") + tk.MustExec(fmt.Sprintf("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('%v','%v');", sqlDigest, planDigest)) + err := prHandle.CollectPlanReplayerTask() + require.NoError(t, err) + require.Len(t, prHandle.GetTasks(), 1) + + tk.MustExec("SET @@tidb_enable_plan_replayer_capture = ON;") + + // capture task and dump + tk.MustQuery("select * from t;") + task := prHandle.DrainTask() + require.NotNil(t, task) + worker := prHandle.GetWorker() + success := worker.HandleTask(task) + require.True(t, success) + require.Equal(t, prHandle.GetTaskStatus().GetRunningTaskStatusLen(), 0) + // assert memory task consumed + require.Len(t, prHandle.GetTasks(), 0) + + // assert collect task again and no more memory task + err = prHandle.CollectPlanReplayerTask() + require.NoError(t, err) + require.Len(t, prHandle.GetTasks(), 0) + + // clean the task and register task + prHandle.GetTaskStatus().CleanFinishedTaskStatus() + tk.MustExec("delete from mysql.plan_replayer_task") + tk.MustExec("delete from mysql.plan_replayer_status") + tk.MustExec(fmt.Sprintf("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('%v','%v');", sqlDigest, "*")) + err = prHandle.CollectPlanReplayerTask() + require.NoError(t, err) + require.Len(t, prHandle.GetTasks(), 1) + tk.MustQuery("select * from t;") + task = prHandle.DrainTask() + require.NotNil(t, task) + worker = prHandle.GetWorker() + success = worker.HandleTask(task) + require.True(t, success) + require.Equal(t, prHandle.GetTaskStatus().GetRunningTaskStatusLen(), 0) + // assert capture * task still remained + require.Len(t, prHandle.GetTasks(), 1) +} diff --git a/domain/plan_replayer_test.go b/domain/plan_replayer_test.go index 7b44db9b8d239..5e0912b86e66c 100644 --- a/domain/plan_replayer_test.go +++ b/domain/plan_replayer_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "github.com/pingcap/tidb/util/replayer" "github.com/stretchr/testify/require" ) @@ -28,15 +29,15 @@ func TestPlanReplayerGC(t *testing.T) { startTime := time.Now() time := startTime.UnixNano() fileName := fmt.Sprintf("replayer_single_xxxxxx_%v.zip", time) - err := os.MkdirAll(GetPlanReplayerDirName(), os.ModePerm) + err := os.MkdirAll(replayer.GetPlanReplayerDirName(), os.ModePerm) require.NoError(t, err) - path := filepath.Join(GetPlanReplayerDirName(), fileName) + path := filepath.Join(replayer.GetPlanReplayerDirName(), fileName) zf, err := os.Create(path) require.NoError(t, err) zf.Close() handler := &dumpFileGcChecker{ - paths: []string{GetPlanReplayerDirName()}, + paths: []string{replayer.GetPlanReplayerDirName()}, } handler.gcDumpFiles(0) diff --git a/domain/schema_validator.go b/domain/schema_validator.go index 511553feafad8..592f558f0b27c 100644 --- a/domain/schema_validator.go +++ b/domain/schema_validator.go @@ -149,10 +149,12 @@ func (s *schemaValidator) Update(leaseGrantTS uint64, oldVer, currVer int64, cha actionTypes = change.ActionTypes } for idx, ac := range actionTypes { - // NOTE: ac is not an action type, it is (1 << action type). - if ac == 1<= 64, the value of left shift equals 0, and it will not impact amend txn + changedTblMap[tblID] |= 1 << item.relatedActions[i] affected = true } } @@ -195,22 +197,15 @@ func (s *schemaValidator) isRelatedTablesChanged(currVer int64, tableIDs []int64 } if len(changedTblMap) > 0 { tblIds := make([]int64, 0, len(changedTblMap)) - actionTypes := make([]uint64, 0, len(changedTblMap)) for id := range changedTblMap { tblIds = append(tblIds, id) } slices.Sort(tblIds) - for _, tblID := range tblIds { - actionTypes = append(actionTypes, changedTblMap[tblID]) - } - res.PhyTblIDS = tblIds - res.ActionTypes = actionTypes - res.Amendable = true logutil.BgLogger().Info("schema of tables in the transaction are changed", zap.Int64s("conflicted table IDs", tblIds), zap.Int64("transaction schema", currVer), zap.Int64s("schema versions that changed the tables", changedSchemaVers)) - return res, true + return true } - return res, false + return false } func (s *schemaValidator) findNewerDeltas(currVer int64) []deltaSchemaInfo { @@ -248,12 +243,8 @@ func (s *schemaValidator) Check(txnTS uint64, schemaVer int64, relatedPhysicalTa // When disabling MDL -> enabling MDL, the old transaction's needCheckSchema is true, we need to check it. // When enabling MDL -> disabling MDL, the old transaction's needCheckSchema is false, so still need to check it, and variable EnableMDL is false now. if needCheckSchema || !variable.EnableMDL.Load() { - relatedChanges, changed := s.isRelatedTablesChanged(schemaVer, relatedPhysicalTableIDs) + changed := s.isRelatedTablesChanged(schemaVer, relatedPhysicalTableIDs) if changed { - if relatedChanges.Amendable { - relatedChanges.LatestInfoSchema = s.latestInfoSchema - return &relatedChanges, ResultFail - } return nil, ResultFail } } diff --git a/domain/schema_validator_test.go b/domain/schema_validator_test.go index a18fbcb4a435a..ddcc57634ab60 100644 --- a/domain/schema_validator_test.go +++ b/domain/schema_validator_test.go @@ -61,7 +61,7 @@ func subTestSchemaValidatorGeneral(t *testing.T) { // Stop the validator, validator's items value is nil. validator.Stop() require.False(t, validator.IsStarted()) - _, isTablesChanged := validator.isRelatedTablesChanged(item.schemaVer, []int64{10}) + isTablesChanged := validator.isRelatedTablesChanged(item.schemaVer, []int64{10}) require.True(t, isTablesChanged) _, valid = validator.Check(item.leaseGrantTS, item.schemaVer, []int64{10}, true) require.Equal(t, ResultUnknown, valid) @@ -91,12 +91,12 @@ func subTestSchemaValidatorGeneral(t *testing.T) { validator.Update(ts, currVer, newItem.schemaVer, &transaction.RelatedSchemaChange{PhyTblIDS: []int64{1, 2, 3}, ActionTypes: []uint64{1, 2, 3}}) // Make sure the updated table IDs don't be covered with the same schema version. validator.Update(ts, newItem.schemaVer, newItem.schemaVer, nil) - _, isTablesChanged = validator.isRelatedTablesChanged(currVer, nil) + isTablesChanged = validator.isRelatedTablesChanged(currVer, nil) require.False(t, isTablesChanged) - _, isTablesChanged = validator.isRelatedTablesChanged(currVer, []int64{2}) + isTablesChanged = validator.isRelatedTablesChanged(currVer, []int64{2}) require.Truef(t, isTablesChanged, "currVer %d, newItem %v", currVer, newItem) // The current schema version is older than the oldest schema version. - _, isTablesChanged = validator.isRelatedTablesChanged(-1, nil) + isTablesChanged = validator.isRelatedTablesChanged(-1, nil) require.Truef(t, isTablesChanged, "currVer %d, newItem %v", currVer, newItem) // All schema versions is expired. @@ -214,10 +214,8 @@ func subTestEnqueueActionType(t *testing.T) { // Check the flag set by schema diff, note tableID = 3 has been set flag 0x3 in schema version 9, and flag 0x4 // in schema version 10, so the resActions for tableID = 3 should be 0x3 & 0x4 = 0x7. - relatedChanges, isTablesChanged := validator.isRelatedTablesChanged(5, []int64{1, 2, 3, 4}) + isTablesChanged := validator.isRelatedTablesChanged(5, []int64{1, 2, 3, 4}) require.True(t, isTablesChanged) - require.Equal(t, []int64{1, 2, 3, 4}, relatedChanges.PhyTblIDS) - require.Equal(t, []uint64{15, 2, 7, 4}, relatedChanges.ActionTypes) } type leaseGrantItem struct { diff --git a/domain/sysvar_cache.go b/domain/sysvar_cache.go index 238f8f867257c..1611231d42ad5 100644 --- a/domain/sysvar_cache.go +++ b/domain/sysvar_cache.go @@ -17,13 +17,13 @@ package domain import ( "context" "fmt" - "sync" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/sqlexec" + "github.com/pingcap/tidb/util/syncutil" "go.uber.org/zap" "golang.org/x/exp/maps" ) @@ -36,10 +36,10 @@ import ( // sysVarCache represents the cache of system variables broken up into session and global scope. type sysVarCache struct { - sync.RWMutex // protects global and session maps - global map[string]string - session map[string]string - rebuildLock sync.Mutex // protects concurrent rebuild + syncutil.RWMutex // protects global and session maps + global map[string]string + session map[string]string + rebuildLock syncutil.Mutex // protects concurrent rebuild } func (do *Domain) rebuildSysVarCacheIfNeeded() (err error) { @@ -144,7 +144,7 @@ func (do *Domain) rebuildSysVarCache(ctx sessionctx.Context) error { // This does not apply to INSTANCE scoped vars (HasGlobalScope() is false) if sv.SetGlobal != nil && !sv.SkipSysvarCache() { sVal = sv.ValidateWithRelaxedValidation(ctx.GetSessionVars(), sVal, variable.ScopeGlobal) - err = sv.SetGlobal(ctx.GetSessionVars(), sVal) + err = sv.SetGlobal(context.Background(), ctx.GetSessionVars(), sVal) if err != nil { logutil.BgLogger().Error(fmt.Sprintf("load global variable %s error", sv.Name), zap.Error(err)) } diff --git a/domain/test_helper.go b/domain/test_helper.go index e63e8dee7389b..e8c106c29d23b 100644 --- a/domain/test_helper.go +++ b/domain/test_helper.go @@ -26,7 +26,7 @@ import ( // MockInfoCacheAndLoadInfoSchema only used in unit tests. func (do *Domain) MockInfoCacheAndLoadInfoSchema(is infoschema.InfoSchema) { - do.infoCache = infoschema.NewCache(16) + do.infoCache.Reset(16) do.infoCache.Insert(is, 0) } diff --git a/dumpling/export/BUILD.bazel b/dumpling/export/BUILD.bazel index 35f1f9925d43d..cf4d938de6042 100644 --- a/dumpling/export/BUILD.bazel +++ b/dumpling/export/BUILD.bazel @@ -62,6 +62,7 @@ go_library( "@io_etcd_go_etcd_client_v3//:client", "@org_golang_x_exp//slices", "@org_golang_x_sync//errgroup", + "@org_uber_go_atomic//:atomic", "@org_uber_go_multierr//:multierr", "@org_uber_go_zap//:zap", ], @@ -102,6 +103,7 @@ go_test( "//util/filter", "//util/promutil", "//util/table-filter", + "@com_github_coreos_go_semver//semver", "@com_github_data_dog_go_sqlmock//:go-sqlmock", "@com_github_go_sql_driver_mysql//:mysql", "@com_github_pingcap_errors//:errors", diff --git a/dumpling/export/config.go b/dumpling/export/config.go index 980de0d8807f5..36af37b30e924 100644 --- a/dumpling/export/config.go +++ b/dumpling/export/config.go @@ -4,6 +4,7 @@ package export import ( "context" + "crypto/tls" "encoding/json" "fmt" "net" @@ -15,8 +16,8 @@ import ( "github.com/coreos/go-semver/semver" "github.com/docker/go-units" "github.com/go-sql-driver/mysql" - "github.com/google/uuid" "github.com/pingcap/errors" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/br/pkg/version" "github.com/pingcap/tidb/util" @@ -24,6 +25,7 @@ import ( filter "github.com/pingcap/tidb/util/table-filter" "github.com/prometheus/client_golang/prometheus" "github.com/spf13/pflag" + "go.uber.org/atomic" "go.uber.org/zap" ) @@ -102,7 +104,7 @@ type Config struct { User string Password string `json:"-"` Security struct { - DriveTLSName string `json:"-"` + TLS *tls.Config `json:"-"` CAPath string CertPath string KeyPath string @@ -143,6 +145,9 @@ type Config struct { PromFactory promutil.Factory `json:"-"` PromRegistry promutil.Registry `json:"-"` ExtStorage storage.ExternalStorage `json:"-"` + + IOTotalBytes *atomic.Uint64 + Net string } // ServerInfoUnknown is the unknown database type to dumpling @@ -202,20 +207,46 @@ func (conf *Config) String() string { return string(cfg) } -// GetDSN generates DSN from Config -func (conf *Config) GetDSN(db string) string { +// GetDriverConfig returns the MySQL driver config from Config. +func (conf *Config) GetDriverConfig(db string) *mysql.Config { + driverCfg := mysql.NewConfig() // maxAllowedPacket=0 can be used to automatically fetch the max_allowed_packet variable from server on every connection. // https://github.com/go-sql-driver/mysql#maxallowedpacket hostPort := net.JoinHostPort(conf.Host, strconv.Itoa(conf.Port)) - dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?collation=utf8mb4_general_ci&readTimeout=%s&writeTimeout=30s&interpolateParams=true&maxAllowedPacket=0", - conf.User, conf.Password, hostPort, db, conf.ReadTimeout) - if conf.Security.DriveTLSName != "" { - dsn += "&tls=" + conf.Security.DriveTLSName + driverCfg.User = conf.User + driverCfg.Passwd = conf.Password + driverCfg.Net = "tcp" + if conf.Net != "" { + driverCfg.Net = conf.Net + } + driverCfg.Addr = hostPort + driverCfg.DBName = db + driverCfg.Collation = "utf8mb4_general_ci" + driverCfg.ReadTimeout = conf.ReadTimeout + driverCfg.WriteTimeout = 30 * time.Second + driverCfg.InterpolateParams = true + driverCfg.MaxAllowedPacket = 0 + if conf.Security.TLS != nil { + driverCfg.TLS = conf.Security.TLS + } else { + // Use TLS first. + driverCfg.AllowFallbackToPlaintext = true + /* #nosec G402 */ + driverCfg.TLS = &tls.Config{ + InsecureSkipVerify: true, + MinVersion: tls.VersionTLS10, + NextProtos: []string{"h2", "http/1.1"}, // specify `h2` to let Go use HTTP/2. + } } if conf.AllowCleartextPasswords { - dsn += "&allowCleartextPasswords=1" + driverCfg.AllowCleartextPasswords = true } - return dsn + failpoint.Inject("SetWaitTimeout", func(val failpoint.Value) { + driverCfg.Params = map[string]string{ + "wait_timeout": strconv.Itoa(val.(int)), + } + }) + return driverCfg } func timestampDirName() string { @@ -273,7 +304,7 @@ func (*Config) DefineFlags(flags *pflag.FlagSet) { _ = flags.MarkHidden(flagReadTimeout) flags.Bool(flagTransactionalConsistency, true, "Only support transactional consistency") _ = flags.MarkHidden(flagTransactionalConsistency) - flags.StringP(flagCompress, "c", "", "Compress output file type, support 'gzip', 'no-compression' now") + flags.StringP(flagCompress, "c", "", "Compress output file type, support 'gzip', 'snappy', 'zstd', 'no-compression' now") } // ParseFromFlags parses dumpling's export.Config from flags @@ -578,6 +609,10 @@ func ParseCompressType(compressType string) (storage.CompressType, error) { return storage.NoCompression, nil case "gzip", "gz": return storage.Gzip, nil + case "snappy": + return storage.Snappy, nil + case "zstd", "zst": + return storage.Zstd, nil default: return storage.NoCompression, errors.Errorf("unknown compress type %s", compressType) } @@ -606,9 +641,9 @@ const ( // DefaultTableFilter is the default exclude table filter. It will exclude all system databases DefaultTableFilter = "!/^(mysql|sys|INFORMATION_SCHEMA|PERFORMANCE_SCHEMA|METRICS_SCHEMA|INSPECTION_SCHEMA)$/.*" - defaultDumpThreads = 128 - defaultDumpGCSafePointTTL = 5 * 60 - defaultEtcdDialTimeOut = 3 * time.Second + defaultTaskChannelCapacity = 128 + defaultDumpGCSafePointTTL = 5 * 60 + defaultEtcdDialTimeOut = 3 * time.Second // LooseCollationCompatible is used in DM, represents a collation setting for best compatibility. LooseCollationCompatible = "loose" @@ -634,7 +669,7 @@ func adjustConfig(conf *Config, fns ...func(*Config) error) error { return nil } -func registerTLSConfig(conf *Config) error { +func buildTLSConfig(conf *Config) error { tlsConfig, err := util.NewTLSConfig( util.WithCAPath(conf.Security.CAPath), util.WithCertAndKeyPath(conf.Security.CertPath, conf.Security.KeyPath), @@ -644,14 +679,8 @@ func registerTLSConfig(conf *Config) error { if err != nil { return errors.Trace(err) } - - if tlsConfig == nil { - return nil - } - - conf.Security.DriveTLSName = "dumpling" + uuid.NewString() - err = mysql.RegisterTLSConfig(conf.Security.DriveTLSName, tlsConfig) - return errors.Trace(err) + conf.Security.TLS = tlsConfig + return nil } func validateSpecifiedSQL(conf *Config) error { diff --git a/dumpling/export/conn.go b/dumpling/export/conn.go index c981febe19450..2e9674a18a41f 100644 --- a/dumpling/export/conn.go +++ b/dumpling/export/conn.go @@ -61,6 +61,7 @@ func (conn *BaseConn) QuerySQLWithColumns(tctx *tcontext.Context, columns []stri if retryTime > 1 && conn.rebuildConnFn != nil { conn.DBConn, err = conn.rebuildConnFn(conn.DBConn, false) if err != nil { + tctx.L().Warn("rebuild connection failed", zap.Error(err)) return } } diff --git a/dumpling/export/consistency.go b/dumpling/export/consistency.go index 187f5a9073ef4..b46259bc748b9 100644 --- a/dumpling/export/consistency.go +++ b/dumpling/export/consistency.go @@ -42,8 +42,9 @@ func NewConsistencyController(ctx context.Context, conf *Config, session *sql.DB }, nil case ConsistencyTypeLock: return &ConsistencyLockDumpingTables{ - conn: conn, - conf: conf, + conn: conn, + conf: conf, + emptyLockSQL: false, }, nil case ConsistencyTypeSnapshot: if conf.ServerInfo.ServerType != version.ServerTypeTiDB { @@ -118,8 +119,9 @@ func (c *ConsistencyFlushTableWithReadLock) PingContext(ctx context.Context) err // ConsistencyLockDumpingTables execute lock tables read on all tables before dump type ConsistencyLockDumpingTables struct { - conn *sql.Conn - conf *Config + conn *sql.Conn + conf *Config + emptyLockSQL bool } // Setup implements ConsistencyController.Setup @@ -135,7 +137,15 @@ func (c *ConsistencyLockDumpingTables) Setup(tctx *tcontext.Context) error { blockList := make(map[string]map[string]interface{}) return utils.WithRetry(tctx, func() error { lockTablesSQL := buildLockTablesSQL(c.conf.Tables, blockList) - _, err := c.conn.ExecContext(tctx, lockTablesSQL) + var err error + if len(lockTablesSQL) == 0 { + c.emptyLockSQL = true + // transfer to ConsistencyNone + _ = c.conn.Close() + c.conn = nil + } else { + _, err = c.conn.ExecContext(tctx, lockTablesSQL) + } if err == nil { if len(blockList) > 0 { filterTablesFunc(tctx, c.conf, func(db string, tbl string) bool { @@ -166,6 +176,9 @@ func (c *ConsistencyLockDumpingTables) TearDown(ctx context.Context) error { // PingContext implements ConsistencyController.PingContext func (c *ConsistencyLockDumpingTables) PingContext(ctx context.Context) error { + if c.emptyLockSQL { + return nil + } if c.conn == nil { return errors.New("consistency connection has already been closed") } diff --git a/dumpling/export/consistency_test.go b/dumpling/export/consistency_test.go index f93bac90a83a6..555338803d40d 100644 --- a/dumpling/export/consistency_test.go +++ b/dumpling/export/consistency_test.go @@ -107,6 +107,39 @@ func TestConsistencyLockControllerRetry(t *testing.T) { require.NoError(t, mock.ExpectationsWereMet()) } +func TestConsistencyLockControllerEmpty(t *testing.T) { + db, mock, err := sqlmock.New() + require.NoError(t, err) + defer func() { + _ = db.Close() + }() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + tctx := tcontext.Background().WithContext(ctx) + conf := defaultConfigForTest(t) + + conf.ServerInfo.ServerType = version.ServerTypeMySQL + conf.Consistency = ConsistencyTypeLock + conf.Tables = NewDatabaseTables(). + AppendTables("db1", []string{"t1"}, []uint64{1}). + AppendViews("db2", "t4") + mock.ExpectExec("LOCK TABLES `db1`.`t1` READ"). + WillReturnError(&mysql.MySQLError{Number: ErrNoSuchTable, Message: "Table 'db1.t1' doesn't exist"}) + ctrl, _ := NewConsistencyController(ctx, conf, db) + _, ok := ctrl.(*ConsistencyLockDumpingTables) + require.True(t, ok) + require.NoError(t, ctrl.Setup(tctx)) + require.NoError(t, ctrl.TearDown(tctx)) + + // should remove table db1.t1 in tables to dump + expectedDumpTables := NewDatabaseTables(). + AppendViews("db2", "t4") + expectedDumpTables["db1"] = make([]*TableInfo, 0) + require.Equal(t, expectedDumpTables, conf.Tables) + require.NoError(t, mock.ExpectationsWereMet()) +} + func TestResolveAutoConsistency(t *testing.T) { conf := defaultConfigForTest(t) cases := []struct { diff --git a/dumpling/export/dump.go b/dumpling/export/dump.go index 37825895a10de..b8e46f595c4e9 100644 --- a/dumpling/export/dump.go +++ b/dumpling/export/dump.go @@ -6,16 +6,20 @@ import ( "bytes" "context" "database/sql" + "database/sql/driver" "encoding/hex" "fmt" "math/big" + "net" "strconv" "strings" "sync/atomic" "time" + "github.com/coreos/go-semver/semver" // import mysql driver "github.com/go-sql-driver/mysql" + "github.com/google/uuid" "github.com/pingcap/errors" "github.com/pingcap/failpoint" pclog "github.com/pingcap/log" @@ -30,17 +34,23 @@ import ( "github.com/pingcap/tidb/parser/format" "github.com/pingcap/tidb/store/helper" "github.com/pingcap/tidb/tablecodec" + "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/codec" pd "github.com/tikv/pd/client" + gatomic "go.uber.org/atomic" "go.uber.org/zap" "golang.org/x/exp/slices" "golang.org/x/sync/errgroup" ) -var openDBFunc = sql.Open +var openDBFunc = openDB var errEmptyHandleVals = errors.New("empty handleVals for TiDB table") +// After TiDB v6.2.0 we always enable tidb_enable_paging by default. +// see https://docs.pingcap.com/zh/tidb/dev/system-variables#tidb_enable_paging-%E4%BB%8E-v540-%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5 +var enablePagingVersion = semver.New("6.2.0") + // Dumper is the dump progress structure type Dumper struct { tctx *tcontext.Context @@ -55,6 +65,8 @@ type Dumper struct { selectTiDBTableRegionFunc func(tctx *tcontext.Context, conn *BaseConn, meta TableMeta) (pkFields []string, pkVals [][]string, err error) totalTables int64 charsetAndDefaultCollationMap map[string]string + + speedRecorder *SpeedRecorder } // NewDumper returns a new Dumper @@ -78,6 +90,7 @@ func NewDumper(ctx context.Context, conf *Config) (*Dumper, error) { conf: conf, cancelCtx: cancelFn, selectTiDBTableRegionFunc: selectTiDBTableRegion, + speedRecorder: NewSpeedRecorder(), } var err error @@ -91,12 +104,23 @@ func NewDumper(ctx context.Context, conf *Config) (*Dumper, error) { }() err = adjustConfig(conf, - registerTLSConfig, + buildTLSConfig, validateSpecifiedSQL, adjustFileFormat) if err != nil { return nil, err } + failpoint.Inject("SetIOTotalBytes", func(_ failpoint.Value) { + d.conf.IOTotalBytes = gatomic.NewUint64(0) + d.conf.Net = uuid.New().String() + go func() { + for { + time.Sleep(10 * time.Millisecond) + d.tctx.L().Logger.Info("IOTotalBytes", zap.Uint64("IOTotalBytes", d.conf.IOTotalBytes.Load())) + } + }() + }) + err = runSteps(d, initLogger, createExternalStore, @@ -200,14 +224,13 @@ func (d *Dumper) Dump() (dumpErr error) { atomic.StoreInt64(&d.totalTables, int64(calculateTableCount(conf.Tables))) - rebuildConn := func(conn *sql.Conn, updateMeta bool) (*sql.Conn, error) { - // make sure that the lock connection is still alive - err1 := conCtrl.PingContext(tctx) - if err1 != nil { - return conn, errors.Trace(err1) - } - // give up the last broken connection - _ = conn.Close() + rebuildMetaConn := func(conn *sql.Conn, updateMeta bool) (*sql.Conn, error) { + _ = conn.Raw(func(dc interface{}) error { + // return an `ErrBadConn` to ensure close the connection, but do not put it back to the pool. + // if we choose to use `Close`, it will always put the connection back to the pool. + return driver.ErrBadConn + }) + newConn, err1 := createConnWithConsistency(tctx, pool, repeatableRead) if err1 != nil { return conn, errors.Trace(err1) @@ -223,11 +246,25 @@ func (d *Dumper) Dump() (dumpErr error) { return conn, nil } - taskChan := make(chan Task, defaultDumpThreads) - AddGauge(d.metrics.taskChannelCapacity, defaultDumpThreads) + rebuildConn := func(conn *sql.Conn, updateMeta bool) (*sql.Conn, error) { + // make sure that the lock connection is still alive + err1 := conCtrl.PingContext(tctx) + if err1 != nil { + return conn, errors.Trace(err1) + } + return rebuildMetaConn(conn, updateMeta) + } + + chanSize := defaultTaskChannelCapacity + failpoint.Inject("SmallDumpChanSize", func() { + chanSize = 1 + }) + taskIn, taskOut := infiniteChan[Task]() + // todo: refine metrics + AddGauge(d.metrics.taskChannelCapacity, float64(chanSize)) wg, writingCtx := errgroup.WithContext(tctx) writerCtx := tctx.WithContext(writingCtx) - writers, tearDownWriters, err := d.startWriters(writerCtx, wg, taskChan, rebuildConn) + writers, tearDownWriters, err := d.startWriters(writerCtx, wg, taskOut, rebuildConn) if err != nil { return err } @@ -272,16 +309,21 @@ func (d *Dumper) Dump() (dumpErr error) { fmt.Printf("tidb_mem_quota_query == %s\n", s) } }) - baseConn := newBaseConn(metaConn, canRebuildConn(conf.Consistency, conf.TransactionalConsistency), rebuildConn) + baseConn := newBaseConn(metaConn, true, rebuildMetaConn) if conf.SQL == "" { - if err = d.dumpDatabases(writerCtx, baseConn, taskChan); err != nil && !errors.ErrorEqual(err, context.Canceled) { + if err = d.dumpDatabases(writerCtx, baseConn, taskIn); err != nil && !errors.ErrorEqual(err, context.Canceled) { return err } } else { - d.dumpSQL(writerCtx, baseConn, taskChan) + d.dumpSQL(writerCtx, baseConn, taskIn) } - close(taskChan) + d.metrics.progressReady.Store(true) + close(taskIn) + failpoint.Inject("EnableLogProgress", func() { + time.Sleep(1 * time.Second) + tctx.L().Debug("progress ready, sleep 1s") + }) _ = baseConn.DBConn.Close() if err := wg.Wait(); err != nil { summary.CollectFailureUnit("dump table data", err) @@ -314,11 +356,16 @@ func (d *Dumper) startWriters(tctx *tcontext.Context, wg *errgroup.Group, taskCh // tctx.L().Debug("finished dumping table data", // zap.String("database", td.Meta.DatabaseName()), // zap.String("table", td.Meta.TableName())) + failpoint.Inject("EnableLogProgress", func() { + time.Sleep(1 * time.Second) + tctx.L().Debug("EnableLogProgress, sleep 1s") + }) } }) writer.setFinishTaskCallBack(func(task Task) { IncGauge(d.metrics.taskChannelCapacity) if td, ok := task.(*TaskTableData); ok { + d.metrics.completedChunks.Add(1) tctx.L().Debug("finish dumping table data task", zap.String("database", td.Meta.DatabaseName()), zap.String("table", td.Meta.TableName()), @@ -435,7 +482,6 @@ func (d *Dumper) dumpDatabases(tctx *tcontext.Context, metaConn *BaseConn, taskC } } } - return nil } @@ -608,6 +654,7 @@ func (d *Dumper) buildConcatTask(tctx *tcontext.Context, conn *BaseConn, meta Ta return } tableDataArr = append(tableDataArr, tableDataInst) + d.metrics.totalChunks.Dec() } for { select { @@ -634,7 +681,7 @@ func (d *Dumper) buildConcatTask(tctx *tcontext.Context, conn *BaseConn, meta Ta return nil, nil } } - return NewTaskTableData(meta, newMultiQueriesChunk(queries, colLen), 0, 1), nil + return d.newTaskTableData(meta, newMultiQueriesChunk(queries, colLen), 0, 1), nil } return nil, err case task := <-tableChan: @@ -646,7 +693,7 @@ func (d *Dumper) buildConcatTask(tctx *tcontext.Context, conn *BaseConn, meta Ta func (d *Dumper) dumpWholeTableDirectly(tctx *tcontext.Context, meta TableMeta, taskChan chan<- Task, partition, orderByClause string, currentChunk, totalChunks int) error { conf := d.conf tableIR := SelectAllFromTable(conf, meta, partition, orderByClause) - task := NewTaskTableData(meta, tableIR, currentChunk, totalChunks) + task := d.newTaskTableData(meta, tableIR, currentChunk, totalChunks) ctxDone := d.sendTaskToChan(tctx, task, taskChan) if ctxDone { return tctx.Err() @@ -759,7 +806,7 @@ func (d *Dumper) concurrentDumpTable(tctx *tcontext.Context, conn *BaseConn, met if len(nullValueCondition) > 0 { nullValueCondition = "" } - task := NewTaskTableData(meta, newTableData(query, selectLen, false), chunkIndex, int(totalChunks)) + task := d.newTaskTableData(meta, newTableData(query, selectLen, false), chunkIndex, int(totalChunks)) ctxDone := d.sendTaskToChan(tctx, task, taskChan) if ctxDone { return tctx.Err() @@ -887,7 +934,8 @@ func (d *Dumper) concurrentDumpTiDBPartitionTables(tctx *tcontext.Context, conn func (d *Dumper) sendConcurrentDumpTiDBTasks(tctx *tcontext.Context, meta TableMeta, taskChan chan<- Task, - handleColNames []string, handleVals [][]string, partition string, startChunkIdx, totalChunk int) error { + handleColNames []string, handleVals [][]string, partition string, + startChunkIdx, totalChunk int) error { db, tbl := meta.DatabaseName(), meta.TableName() if len(handleVals) == 0 { if partition == "" { @@ -903,7 +951,7 @@ func (d *Dumper) sendConcurrentDumpTiDBTasks(tctx *tcontext.Context, for i, w := range where { query := buildSelectQuery(db, tbl, selectField, partition, buildWhereCondition(conf, w), orderByClause) - task := NewTaskTableData(meta, newTableData(query, selectLen, false), i+startChunkIdx, totalChunk) + task := d.newTaskTableData(meta, newTableData(query, selectLen, false), i+startChunkIdx, totalChunk) ctxDone := d.sendTaskToChan(tctx, task, taskChan) if ctxDone { return tctx.Err() @@ -1171,9 +1219,7 @@ func dumpTableMeta(tctx *tcontext.Context, conf *Config, conn *BaseConn, db stri selectedField: selectField, selectedLen: selectLen, hasImplicitRowID: hasImplicitRowID, - specCmts: []string{ - "/*!40101 SET NAMES binary*/;", - }, + specCmts: getSpecialComments(conf.ServerInfo.ServerType), } if conf.NoSchemas { @@ -1211,7 +1257,7 @@ func (d *Dumper) dumpSQL(tctx *tcontext.Context, metaConn *BaseConn, taskChan ch conf := d.conf meta := &tableMeta{} data := newTableData(conf.SQL, 0, true) - task := NewTaskTableData(meta, data, 0, 1) + task := d.newTaskTableData(meta, data, 0, 1) c := detectEstimateRows(tctx, metaConn, fmt.Sprintf("EXPLAIN %s", conf.SQL), []string{"rows", "estRows", "count"}) AddCounter(d.metrics.estimateTotalRowsCounter, float64(c)) atomic.StoreInt64(&d.totalTables, int64(1)) @@ -1236,9 +1282,6 @@ func (d *Dumper) Close() error { if d.dbHandle != nil { return d.dbHandle.Close() } - if d.conf.Security.DriveTLSName != "" { - mysql.DeregisterTLSConfig(d.conf.Security.DriveTLSName) - } return nil } @@ -1305,12 +1348,28 @@ func startHTTPService(d *Dumper) error { // openSQLDB is an initialization step of Dumper. func openSQLDB(d *Dumper) error { + if d.conf.IOTotalBytes != nil { + mysql.RegisterDialContext(d.conf.Net, func(ctx context.Context, addr string) (net.Conn, error) { + dial := &net.Dialer{} + conn, err := dial.DialContext(ctx, "tcp", addr) + if err != nil { + return nil, err + } + tcpConn := conn.(*net.TCPConn) + // try https://github.com/go-sql-driver/mysql/blob/bcc459a906419e2890a50fc2c99ea6dd927a88f2/connector.go#L56-L64 + err = tcpConn.SetKeepAlive(true) + if err != nil { + d.tctx.L().Logger.Warn("fail to keep alive", zap.Error(err)) + } + return util.NewTCPConnWithIOCounter(tcpConn, d.conf.IOTotalBytes), nil + }) + } conf := d.conf - pool, err := sql.Open("mysql", conf.GetDSN("")) + c, err := mysql.NewConnector(conf.GetDriverConfig("")) if err != nil { return errors.Trace(err) } - d.dbHandle = pool + d.dbHandle = sql.OpenDB(c) return nil } @@ -1483,6 +1542,19 @@ func updateServiceSafePoint(tctx *tcontext.Context, pdClient pd.Client, ttl int6 } } +// setDefaultSessionParams is a step to set default params for session params. +func setDefaultSessionParams(si version.ServerInfo, sessionParams map[string]interface{}) { + defaultSessionParams := map[string]interface{}{} + if si.ServerType == version.ServerTypeTiDB && si.HasTiKV && si.ServerVersion.Compare(*enablePagingVersion) >= 0 { + defaultSessionParams["tidb_enable_paging"] = "ON" + } + for k, v := range defaultSessionParams { + if _, ok := sessionParams[k]; !ok { + sessionParams[k] = v + } + } +} + // setSessionParam is an initialization step of Dumper. func setSessionParam(d *Dumper) error { conf, pool := d.conf, d.dbHandle @@ -1507,12 +1579,20 @@ func setSessionParam(d *Dumper) error { } } } - if d.dbHandle, err = resetDBWithSessionParams(d.tctx, pool, conf.GetDSN(""), conf.SessionParams); err != nil { + if d.dbHandle, err = resetDBWithSessionParams(d.tctx, pool, conf.GetDriverConfig(""), conf.SessionParams); err != nil { return errors.Trace(err) } return nil } +func openDB(cfg *mysql.Config) (*sql.DB, error) { + c, err := mysql.NewConnector(cfg) + if err != nil { + return nil, errors.Trace(err) + } + return sql.OpenDB(c), nil +} + func (d *Dumper) renewSelectTableRegionFuncForLowerTiDB(tctx *tcontext.Context) error { conf := d.conf if !(conf.ServerInfo.ServerType == version.ServerTypeTiDB && conf.ServerInfo.ServerVersion != nil && conf.ServerInfo.HasTiKV && @@ -1529,7 +1609,7 @@ func (d *Dumper) renewSelectTableRegionFuncForLowerTiDB(tctx *tcontext.Context) d.selectTiDBTableRegionFunc = func(_ *tcontext.Context, _ *BaseConn, meta TableMeta) (pkFields []string, pkVals [][]string, err error) { return nil, nil, errors.Annotatef(errEmptyHandleVals, "table: `%s`.`%s`", escapeString(meta.DatabaseName()), escapeString(meta.TableName())) } - dbHandle, err := openDBFunc("mysql", conf.GetDSN("")) + dbHandle, err := openDBFunc(conf.GetDriverConfig("")) if err != nil { return errors.Trace(err) } @@ -1613,3 +1693,8 @@ func (d *Dumper) renewSelectTableRegionFuncForLowerTiDB(tctx *tcontext.Context) return nil } + +func (d *Dumper) newTaskTableData(meta TableMeta, data TableDataIR, currentChunk, totalChunks int) *TaskTableData { + d.metrics.totalChunks.Add(1) + return NewTaskTableData(meta, data, currentChunk, totalChunks) +} diff --git a/dumpling/export/dump_test.go b/dumpling/export/dump_test.go index 1f18e9e8aa19c..7d621857f3a85 100644 --- a/dumpling/export/dump_test.go +++ b/dumpling/export/dump_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/coreos/go-semver/semver" "github.com/pingcap/errors" "github.com/pingcap/tidb/br/pkg/version" tcontext "github.com/pingcap/tidb/dumpling/context" @@ -18,7 +19,7 @@ import ( "golang.org/x/sync/errgroup" ) -func TestDumpBlock(t *testing.T) { +func TestDumpExit(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) defer func() { @@ -56,7 +57,6 @@ func TestDumpBlock(t *testing.T) { }) writerCtx := tctx.WithContext(writingCtx) - // simulate taskChan is full taskChan := make(chan Task, 1) taskChan <- &TaskDatabaseMeta{} d.conf.Tables = DatabaseTables{}.AppendTable(database, nil) @@ -225,3 +225,67 @@ func TestUnregisterMetrics(t *testing.T) { // should not panic require.Error(t, err) } + +func TestSetDefaultSessionParams(t *testing.T) { + testCases := []struct { + si version.ServerInfo + sessionParams map[string]interface{} + expectedParams map[string]interface{} + }{ + { + si: version.ServerInfo{ + ServerType: version.ServerTypeTiDB, + HasTiKV: true, + ServerVersion: semver.New("6.1.0"), + }, + sessionParams: map[string]interface{}{ + "tidb_snapshot": "2020-01-01 00:00:00", + }, + expectedParams: map[string]interface{}{ + "tidb_snapshot": "2020-01-01 00:00:00", + }, + }, + { + si: version.ServerInfo{ + ServerType: version.ServerTypeTiDB, + HasTiKV: true, + ServerVersion: semver.New("6.2.0"), + }, + sessionParams: map[string]interface{}{ + "tidb_snapshot": "2020-01-01 00:00:00", + }, + expectedParams: map[string]interface{}{ + "tidb_enable_paging": "ON", + "tidb_snapshot": "2020-01-01 00:00:00", + }, + }, + { + si: version.ServerInfo{ + ServerType: version.ServerTypeTiDB, + HasTiKV: true, + ServerVersion: semver.New("6.2.0"), + }, + sessionParams: map[string]interface{}{ + "tidb_enable_paging": "OFF", + "tidb_snapshot": "2020-01-01 00:00:00", + }, + expectedParams: map[string]interface{}{ + "tidb_enable_paging": "OFF", + "tidb_snapshot": "2020-01-01 00:00:00", + }, + }, + { + si: version.ServerInfo{ + ServerType: version.ServerTypeMySQL, + ServerVersion: semver.New("8.0.32"), + }, + sessionParams: map[string]interface{}{}, + expectedParams: map[string]interface{}{}, + }, + } + + for _, testCase := range testCases { + setDefaultSessionParams(testCase.si, testCase.sessionParams) + require.Equal(t, testCase.expectedParams, testCase.sessionParams) + } +} diff --git a/dumpling/export/ir.go b/dumpling/export/ir.go index 4b98019605e9c..aa1b2070591ab 100644 --- a/dumpling/export/ir.go +++ b/dumpling/export/ir.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/pingcap/errors" + "github.com/pingcap/tidb/br/pkg/version" tcontext "github.com/pingcap/tidb/dumpling/context" ) @@ -85,7 +86,7 @@ type MetaIR interface { MetaSQL() string } -func setTableMetaFromRows(rows *sql.Rows) (TableMeta, error) { +func setTableMetaFromRows(serverType version.ServerType, rows *sql.Rows) (TableMeta, error) { tps, err := rows.ColumnTypes() if err != nil { return nil, errors.Trace(err) @@ -101,6 +102,6 @@ func setTableMetaFromRows(rows *sql.Rows) (TableMeta, error) { colTypes: tps, selectedField: strings.Join(nms, ","), selectedLen: len(nms), - specCmts: []string{"/*!40101 SET NAMES binary*/;"}, + specCmts: getSpecialComments(serverType), }, nil } diff --git a/dumpling/export/ir_impl.go b/dumpling/export/ir_impl.go index bca821f612623..d1efa75db3365 100644 --- a/dumpling/export/ir_impl.go +++ b/dumpling/export/ir_impl.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/pingcap/errors" + "github.com/pingcap/tidb/br/pkg/version" tcontext "github.com/pingcap/tidb/dumpling/context" "go.uber.org/zap" ) @@ -370,3 +371,22 @@ func (td *multiQueriesChunk) Close() error { func (*multiQueriesChunk) RawRows() *sql.Rows { return nil } + +var serverSpecialComments = map[version.ServerType][]string{ + version.ServerTypeMySQL: { + "/*!40014 SET FOREIGN_KEY_CHECKS=0*/;", + "/*!40101 SET NAMES binary*/;", + }, + version.ServerTypeTiDB: { + "/*!40014 SET FOREIGN_KEY_CHECKS=0*/;", + "/*!40101 SET NAMES binary*/;", + }, + version.ServerTypeMariaDB: { + "/*!40101 SET NAMES binary*/;", + "SET FOREIGN_KEY_CHECKS=0;", + }, +} + +func getSpecialComments(serverType version.ServerType) []string { + return serverSpecialComments[serverType] +} diff --git a/dumpling/export/main_test.go b/dumpling/export/main_test.go index d66fb40eee907..da19d470dc94f 100644 --- a/dumpling/export/main_test.go +++ b/dumpling/export/main_test.go @@ -49,6 +49,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/dumpling/export/metrics.go b/dumpling/export/metrics.go index 5546a614049c4..b4f9aa66ac4d1 100644 --- a/dumpling/export/metrics.go +++ b/dumpling/export/metrics.go @@ -8,6 +8,7 @@ import ( "github.com/pingcap/tidb/util/promutil" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" + "go.uber.org/atomic" ) type metrics struct { @@ -19,6 +20,10 @@ type metrics struct { receiveWriteChunkTimeHistogram *prometheus.HistogramVec errorCount *prometheus.CounterVec taskChannelCapacity *prometheus.GaugeVec + // todo: add these to metrics + totalChunks atomic.Int64 + completedChunks atomic.Int64 + progressReady atomic.Bool } func newMetrics(f promutil.Factory, constLabels prometheus.Labels) *metrics { diff --git a/dumpling/export/sql.go b/dumpling/export/sql.go index 83655df99e330..837bec568b9a7 100644 --- a/dumpling/export/sql.go +++ b/dumpling/export/sql.go @@ -10,7 +10,6 @@ import ( "fmt" "io" "math" - "net/url" "strconv" "strings" @@ -834,7 +833,7 @@ func isUnknownSystemVariableErr(err error) bool { // resetDBWithSessionParams will return a new sql.DB as a replacement for input `db` with new session parameters. // If returned error is nil, the input `db` will be closed. -func resetDBWithSessionParams(tctx *tcontext.Context, db *sql.DB, dsn string, params map[string]interface{}) (*sql.DB, error) { +func resetDBWithSessionParams(tctx *tcontext.Context, db *sql.DB, cfg *mysql.Config, params map[string]interface{}) (*sql.DB, error) { support := make(map[string]interface{}) for k, v := range params { var pv interface{} @@ -862,6 +861,10 @@ func resetDBWithSessionParams(tctx *tcontext.Context, db *sql.DB, dsn string, pa support[k] = pv } + if cfg.Params == nil { + cfg.Params = make(map[string]string) + } + for k, v := range support { var s string // Wrap string with quote to handle string with space. For example, '2020-10-20 13:41:40' @@ -871,19 +874,21 @@ func resetDBWithSessionParams(tctx *tcontext.Context, db *sql.DB, dsn string, pa } else { s = fmt.Sprintf("%v", v) } - dsn += fmt.Sprintf("&%s=%s", k, url.QueryEscape(s)) + cfg.Params[k] = s } db.Close() - newDB, err := sql.Open("mysql", dsn) - if err == nil { - // ping to make sure all session parameters are set correctly - err = newDB.PingContext(tctx) - if err != nil { - newDB.Close() - } + c, err := mysql.NewConnector(cfg) + if err != nil { + return nil, errors.Trace(err) + } + newDB := sql.OpenDB(c) + // ping to make sure all session parameters are set correctly + err = newDB.PingContext(tctx) + if err != nil { + newDB.Close() } - return newDB, errors.Trace(err) + return newDB, nil } func createConnWithConsistency(ctx context.Context, db *sql.DB, repeatableRead bool) (*sql.Conn, error) { diff --git a/dumpling/export/sql_test.go b/dumpling/export/sql_test.go index d98a8a3c76a64..5ae4c7278efa4 100644 --- a/dumpling/export/sql_test.go +++ b/dumpling/export/sql_test.go @@ -1308,6 +1308,8 @@ func buildMockNewRows(mock sqlmock.Sqlmock, columns []string, driverValues [][]d } func readRegionCsvDriverValues(t *testing.T) [][]driver.Value { + t.Helper() + csvFilename := "region_results.csv" file, err := os.Open(csvFilename) require.NoError(t, err) @@ -1345,7 +1347,7 @@ func TestBuildVersion3RegionQueries(t *testing.T) { defer func() { openDBFunc = oldOpenFunc }() - openDBFunc = func(_, _ string) (*sql.DB, error) { + openDBFunc = func(*mysql.Config) (*sql.DB, error) { return db, nil } diff --git a/dumpling/export/status.go b/dumpling/export/status.go index f8e189fd365d5..0a861f4c40677 100644 --- a/dumpling/export/status.go +++ b/dumpling/export/status.go @@ -4,10 +4,12 @@ package export import ( "fmt" + "sync" "sync/atomic" "time" "github.com/docker/go-units" + "github.com/pingcap/failpoint" tcontext "github.com/pingcap/tidb/dumpling/context" "go.uber.org/zap" ) @@ -16,6 +18,11 @@ const logProgressTick = 2 * time.Minute func (d *Dumper) runLogProgress(tctx *tcontext.Context) { logProgressTicker := time.NewTicker(logProgressTick) + failpoint.Inject("EnableLogProgress", func() { + logProgressTicker.Stop() + logProgressTicker = time.NewTicker(time.Duration(1) * time.Second) + tctx.L().Debug("EnableLogProgress") + }) lastCheckpoint := time.Now() lastBytes := float64(0) defer logProgressTicker.Stop() @@ -33,6 +40,8 @@ func (d *Dumper) runLogProgress(tctx *tcontext.Context) { zap.String("estimate total rows", fmt.Sprintf("%.0f", s.EstimateTotalRows)), zap.String("finished size", units.HumanSize(s.FinishedBytes)), zap.Float64("average speed(MiB/s)", (s.FinishedBytes-lastBytes)/(1048576e-9*nanoseconds)), + zap.Float64("recent speed bps", s.CurrentSpeedBPS), + zap.String("chunks progress", s.Progress), ) lastCheckpoint = time.Now() @@ -48,6 +57,8 @@ type DumpStatus struct { FinishedRows float64 EstimateTotalRows float64 TotalTables int64 + CurrentSpeedBPS float64 + Progress string } // GetStatus returns the status of dumping by reading metrics. @@ -58,6 +69,21 @@ func (d *Dumper) GetStatus() *DumpStatus { ret.FinishedBytes = ReadGauge(d.metrics.finishedSizeGauge) ret.FinishedRows = ReadGauge(d.metrics.finishedRowsGauge) ret.EstimateTotalRows = ReadCounter(d.metrics.estimateTotalRowsCounter) + ret.CurrentSpeedBPS = d.speedRecorder.GetSpeed(ret.FinishedBytes) + if d.metrics.progressReady.Load() { + // chunks will be zero when upstream has no data + if d.metrics.totalChunks.Load() == 0 { + ret.Progress = "100 %" + return ret + } + progress := float64(d.metrics.completedChunks.Load()) / float64(d.metrics.totalChunks.Load()) + if progress > 1 { + ret.Progress = "100 %" + d.L().Warn("completedChunks is greater than totalChunks", zap.Int64("completedChunks", d.metrics.completedChunks.Load()), zap.Int64("totalChunks", d.metrics.totalChunks.Load())) + } else { + ret.Progress = fmt.Sprintf("%5.2f %%", progress*100) + } + } return ret } @@ -72,3 +98,47 @@ func calculateTableCount(m DatabaseTables) int { } return cnt } + +// SpeedRecorder record the finished bytes and calculate its speed. +type SpeedRecorder struct { + mu sync.Mutex + lastFinished float64 + lastUpdateTime time.Time + speedBPS float64 +} + +// NewSpeedRecorder new a SpeedRecorder. +func NewSpeedRecorder() *SpeedRecorder { + return &SpeedRecorder{ + lastUpdateTime: time.Now(), + } +} + +// GetSpeed calculate status speed. +func (s *SpeedRecorder) GetSpeed(finished float64) float64 { + s.mu.Lock() + defer s.mu.Unlock() + + if finished <= s.lastFinished { + // for finished bytes does not get forwarded, use old speed to avoid + // display zero. We may find better strategy in future. + return s.speedBPS + } + + now := time.Now() + elapsed := now.Sub(s.lastUpdateTime).Seconds() + if elapsed == 0 { + // if time is short, return last speed + return s.speedBPS + } + currentSpeed := (finished - s.lastFinished) / elapsed + if currentSpeed == 0 { + currentSpeed = 1 + } + + s.lastFinished = finished + s.lastUpdateTime = now + s.speedBPS = currentSpeed + + return currentSpeed +} diff --git a/dumpling/export/status_test.go b/dumpling/export/status_test.go index 5d2b080ba82a1..7c340b06dcf83 100644 --- a/dumpling/export/status_test.go +++ b/dumpling/export/status_test.go @@ -3,14 +3,16 @@ package export import ( + "math" "testing" + "time" "github.com/stretchr/testify/require" ) func TestGetParameters(t *testing.T) { conf := defaultConfigForTest(t) - d := &Dumper{conf: conf} + d := &Dumper{conf: conf, speedRecorder: NewSpeedRecorder()} d.metrics = newMetrics(conf.PromFactory, nil) mid := d.GetStatus() @@ -30,3 +32,24 @@ func TestGetParameters(t *testing.T) { require.EqualValues(t, float64(30), mid.FinishedRows) require.EqualValues(t, float64(40), mid.EstimateTotalRows) } + +func TestSpeedRecorder(t *testing.T) { + testCases := []struct { + spentTime int64 + finished float64 + expected float64 + }{ + {spentTime: 1, finished: 100, expected: 100}, + {spentTime: 2, finished: 200, expected: 50}, + // already finished, will return last speed + {spentTime: 3, finished: 200, expected: 50}, + } + speedRecorder := NewSpeedRecorder() + for _, tc := range testCases { + time.Sleep(time.Duration(tc.spentTime) * time.Second) + recentSpeed := speedRecorder.GetSpeed(tc.finished) + if math.Abs(tc.expected-recentSpeed)/tc.expected > 0.1 { + require.FailNow(t, "speed is unexpected", "expected: %5.2f, recent: %5.2f", tc.expected, recentSpeed) + } + } +} diff --git a/dumpling/export/task.go b/dumpling/export/task.go index 36d88c3e3454c..760f5833df017 100644 --- a/dumpling/export/task.go +++ b/dumpling/export/task.go @@ -2,7 +2,9 @@ package export -import "fmt" +import ( + "fmt" +) // Task is a file dump task for dumpling, it could either be dumping database/table/view/policy metadata, table data type Task interface { diff --git a/dumpling/export/util.go b/dumpling/export/util.go index cad703f9f23f4..6c7443a1bee84 100644 --- a/dumpling/export/util.go +++ b/dumpling/export/util.go @@ -78,3 +78,44 @@ func string2Map(a, b []string) map[string]string { func needRepeatableRead(serverType version.ServerType, consistency string) bool { return consistency != ConsistencyTypeSnapshot || serverType != version.ServerTypeTiDB } + +func infiniteChan[T any]() (chan<- T, <-chan T) { + in, out := make(chan T), make(chan T) + + go func() { + var ( + q []T + e T + ok bool + ) + handleRead := func() bool { + if !ok { + for _, e = range q { + out <- e + } + close(out) + return true + } + q = append(q, e) + return false + } + for { + if len(q) > 0 { + select { + case e, ok = <-in: + if handleRead() { + return + } + case out <- q[0]: + q = q[1:] + } + } else { + e, ok = <-in + if handleRead() { + return + } + } + } + }() + return in, out +} diff --git a/dumpling/export/util_test.go b/dumpling/export/util_test.go index 1686a24902825..35de448432cd0 100644 --- a/dumpling/export/util_test.go +++ b/dumpling/export/util_test.go @@ -29,3 +29,17 @@ func TestRepeatableRead(t *testing.T) { require.True(t, rr == expectRepeatableRead, comment) } } + +func TestInfiniteChan(t *testing.T) { + in, out := infiniteChan[int]() + go func() { + for i := 0; i < 10000; i++ { + in <- i + } + }() + for i := 0; i < 10000; i++ { + j := <-out + require.Equal(t, i, j) + } + close(in) +} diff --git a/dumpling/export/writer.go b/dumpling/export/writer.go index 0ce7a006244b3..ae037041596ae 100644 --- a/dumpling/export/writer.go +++ b/dumpling/export/writer.go @@ -133,7 +133,7 @@ func (w *Writer) WritePolicyMeta(policy, createSQL string) error { if err != nil { return err } - return writeMetaToFile(tctx, "placement-policy", createSQL, w.extStorage, fileName+".sql", conf.CompressType) + return w.writeMetaToFile(tctx, "placement-policy", createSQL, fileName+".sql") } // WriteDatabaseMeta writes database meta to a file @@ -143,7 +143,7 @@ func (w *Writer) WriteDatabaseMeta(db, createSQL string) error { if err != nil { return err } - return writeMetaToFile(tctx, db, createSQL, w.extStorage, fileName+".sql", conf.CompressType) + return w.writeMetaToFile(tctx, db, createSQL, fileName+".sql") } // WriteTableMeta writes table meta to a file @@ -153,7 +153,7 @@ func (w *Writer) WriteTableMeta(db, table, createSQL string) error { if err != nil { return err } - return writeMetaToFile(tctx, db, createSQL, w.extStorage, fileName+".sql", conf.CompressType) + return w.writeMetaToFile(tctx, db, createSQL, fileName+".sql") } // WriteViewMeta writes view meta to a file @@ -167,11 +167,11 @@ func (w *Writer) WriteViewMeta(db, view, createTableSQL, createViewSQL string) e if err != nil { return err } - err = writeMetaToFile(tctx, db, createTableSQL, w.extStorage, fileNameTable+".sql", conf.CompressType) + err = w.writeMetaToFile(tctx, db, createTableSQL, fileNameTable+".sql") if err != nil { return err } - return writeMetaToFile(tctx, db, createViewSQL, w.extStorage, fileNameView+".sql", conf.CompressType) + return w.writeMetaToFile(tctx, db, createViewSQL, fileNameView+".sql") } // WriteSequenceMeta writes sequence meta to a file @@ -181,7 +181,7 @@ func (w *Writer) WriteSequenceMeta(db, sequence, createSQL string) error { if err != nil { return err } - return writeMetaToFile(tctx, db, createSQL, w.extStorage, fileName+".sql", conf.CompressType) + return w.writeMetaToFile(tctx, db, createSQL, fileName+".sql") } // WriteTableData writes table data to a file with retry @@ -209,13 +209,18 @@ func (w *Writer) WriteTableData(meta TableMeta, ir TableDataIR, currentChunk int } err = ir.Start(tctx, conn) if err != nil { + tctx.L().Warn("failed to start table chunk", zap.Error(err)) return } if conf.SQL != "" { - meta, err = setTableMetaFromRows(ir.RawRows()) + rows := ir.RawRows() + meta, err = setTableMetaFromRows(w.conf.ServerInfo.ServerType, rows) if err != nil { return err } + if err = rows.Err(); err != nil { + return errors.Trace(err) + } } defer func() { _ = ir.Close() @@ -269,19 +274,17 @@ func (w *Writer) tryToWriteTableData(tctx *tcontext.Context, meta TableMeta, ir return nil } -func writeMetaToFile(tctx *tcontext.Context, target, metaSQL string, s storage.ExternalStorage, path string, compressType storage.CompressType) error { - fileWriter, tearDown, err := buildFileWriter(tctx, s, path, compressType) +func (w *Writer) writeMetaToFile(tctx *tcontext.Context, target, metaSQL string, path string) error { + fileWriter, tearDown, err := buildFileWriter(tctx, w.extStorage, path, w.conf.CompressType) if err != nil { return errors.Trace(err) } defer tearDown(tctx) return WriteMeta(tctx, &metaData{ - target: target, - metaSQL: metaSQL, - specCmts: []string{ - "/*!40101 SET NAMES binary*/;", - }, + target: target, + metaSQL: metaSQL, + specCmts: getSpecialComments(w.conf.ServerInfo.ServerType), }, fileWriter) } diff --git a/dumpling/export/writer_test.go b/dumpling/export/writer_test.go index b5f54f3debcb9..4f07d25b7b224 100644 --- a/dumpling/export/writer_test.go +++ b/dumpling/export/writer_test.go @@ -5,13 +5,13 @@ package export import ( "context" "database/sql/driver" - "io/ioutil" "os" "path" "sync" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/pingcap/tidb/br/pkg/version" tcontext "github.com/pingcap/tidb/dumpling/context" "github.com/pingcap/tidb/util/promutil" "github.com/stretchr/testify/require" @@ -31,9 +31,9 @@ func TestWriteDatabaseMeta(t *testing.T) { _, err = os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) - require.Equal(t, "/*!40101 SET NAMES binary*/;\nCREATE DATABASE `test`;\n", string(bytes)) + require.Equal(t, "/*!40014 SET FOREIGN_KEY_CHECKS=0*/;\n/*!40101 SET NAMES binary*/;\nCREATE DATABASE `test`;\n", string(bytes)) } func TestWritePolicyMeta(t *testing.T) { @@ -50,9 +50,9 @@ func TestWritePolicyMeta(t *testing.T) { _, err = os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) - require.Equal(t, "/*!40101 SET NAMES binary*/;\ncreate placement policy `y` followers=2;\n", string(bytes)) + require.Equal(t, "/*!40014 SET FOREIGN_KEY_CHECKS=0*/;\n/*!40101 SET NAMES binary*/;\ncreate placement policy `y` followers=2;\n", string(bytes)) } func TestWriteTableMeta(t *testing.T) { @@ -68,9 +68,9 @@ func TestWriteTableMeta(t *testing.T) { p := path.Join(dir, "test.t-schema.sql") _, err = os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) - require.Equal(t, "/*!40101 SET NAMES binary*/;\nCREATE TABLE t (a INT);\n", string(bytes)) + require.Equal(t, "/*!40014 SET FOREIGN_KEY_CHECKS=0*/;\n/*!40101 SET NAMES binary*/;\nCREATE TABLE t (a INT);\n", string(bytes)) } func TestWriteViewMeta(t *testing.T) { @@ -80,7 +80,7 @@ func TestWriteViewMeta(t *testing.T) { writer := createTestWriter(config, t) - specCmt := "/*!40101 SET NAMES binary*/;\n" + specCmt := "/*!40014 SET FOREIGN_KEY_CHECKS=0*/;\n/*!40101 SET NAMES binary*/;\n" createTableSQL := "CREATE TABLE `v`(\n`a` int\n)ENGINE=MyISAM;\n" createViewSQL := "DROP TABLE IF EXISTS `v`;\nDROP VIEW IF EXISTS `v`;\nSET @PREV_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;\nSET @PREV_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;\nSET @PREV_COLLATION_CONNECTION=@@COLLATION_CONNECTION;\nSET character_set_client = utf8;\nSET character_set_results = utf8;\nSET collation_connection = utf8_general_ci;\nCREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` (`a`) AS SELECT `t`.`a` AS `a` FROM `test`.`t`;\nSET character_set_client = @PREV_CHARACTER_SET_CLIENT;\nSET character_set_results = @PREV_CHARACTER_SET_RESULTS;\nSET collation_connection = @PREV_COLLATION_CONNECTION;\n" err := writer.WriteViewMeta("test", "v", createTableSQL, createViewSQL) @@ -89,14 +89,14 @@ func TestWriteViewMeta(t *testing.T) { p := path.Join(dir, "test.v-schema.sql") _, err = os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) require.Equal(t, specCmt+createTableSQL, string(bytes)) p = path.Join(dir, "test.v-schema-view.sql") _, err = os.Stat(p) require.NoError(t, err) - bytes, err = ioutil.ReadFile(p) + bytes, err = os.ReadFile(p) require.NoError(t, err) require.Equal(t, specCmt+createViewSQL, string(bytes)) } @@ -126,7 +126,7 @@ func TestWriteTableData(t *testing.T) { p := path.Join(dir, "test.employee.000000000.sql") _, err = os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) expected := "/*!40101 SET NAMES binary*/;\n" + @@ -182,7 +182,7 @@ func TestWriteTableDataWithFileSize(t *testing.T) { p = path.Join(dir, p) _, err := os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) require.Equal(t, expected, string(bytes)) } @@ -232,7 +232,7 @@ func TestWriteTableDataWithFileSizeAndRows(t *testing.T) { p = path.Join(dir, p) _, err = os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) require.Equal(t, expected, string(bytes)) } @@ -281,7 +281,7 @@ func TestWriteTableDataWithStatementSize(t *testing.T) { p = path.Join(config.OutputDirPath, p) _, err = os.Stat(p) require.NoError(t, err) - bytes, err1 := ioutil.ReadFile(p) + bytes, err1 := os.ReadFile(p) require.NoError(t, err1) require.Equal(t, expected, string(bytes)) } @@ -297,7 +297,7 @@ func TestWriteTableDataWithStatementSize(t *testing.T) { require.NoError(t, err) err = os.RemoveAll(config.OutputDirPath) require.NoError(t, err) - config.OutputDirPath, err = ioutil.TempDir("", "dumpling") + config.OutputDirPath, err = os.MkdirTemp("", "dumpling") writer = createTestWriter(config, t) @@ -322,7 +322,7 @@ func TestWriteTableDataWithStatementSize(t *testing.T) { p = path.Join(config.OutputDirPath, p) _, err = os.Stat(p) require.NoError(t, err) - bytes, err := ioutil.ReadFile(p) + bytes, err := os.ReadFile(p) require.NoError(t, err) require.Equal(t, expected, string(bytes)) } @@ -331,6 +331,9 @@ func TestWriteTableDataWithStatementSize(t *testing.T) { var mu sync.Mutex func createTestWriter(conf *Config, t *testing.T) *Writer { + t.Helper() + conf.ServerInfo.ServerType = version.ServerTypeMySQL + mu.Lock() extStore, err := conf.createExternalStorage(context.Background()) mu.Unlock() diff --git a/dumpling/export/writer_util.go b/dumpling/export/writer_util.go index 978178c36c0f8..809f82e59c9b5 100644 --- a/dumpling/export/writer_util.go +++ b/dumpling/export/writer_util.go @@ -242,6 +242,7 @@ func WriteInsert( failpoint.Inject("ChaosBrokenWriterConn", func(_ failpoint.Value) { failpoint.Return(0, errors.New("connection is closed")) }) + failpoint.Inject("AtEveryRow", nil) fileRowIter.Next() shouldSwitch := wp.ShouldSwitchStatement() @@ -590,6 +591,10 @@ func compressFileSuffix(compressType storage.CompressType) string { return "" case storage.Gzip: return ".gz" + case storage.Snappy: + return ".snappy" + case storage.Zstd: + return ".zst" default: return "" } diff --git a/dumpling/install.sh b/dumpling/install.sh index d322b41242231..f24d54b499dea 100644 --- a/dumpling/install.sh +++ b/dumpling/install.sh @@ -15,3 +15,11 @@ chmod a+x bin/minio wget https://dl.minio.io/client/mc/release/linux-amd64/mc -O bin/mc chmod a+x bin/mc + +go get github.com/ma6174/snappy +go install github.com/ma6174/snappy + +wget https://github.com/facebook/zstd/releases/download/v1.5.2/zstd-1.5.2.tar.gz +tar xvfz zstd-1.5.2.tar.gz +cd zstd-1.5.2 +make diff --git a/dumpling/tests/_utils/run_services b/dumpling/tests/_utils/run_services index 363e39c8fef66..76e83e7bb7f55 100755 --- a/dumpling/tests/_utils/run_services +++ b/dumpling/tests/_utils/run_services @@ -36,6 +36,7 @@ start_services() { cat > "$DUMPLING_TEST_DIR/tidb.toml" <= 65536", nil), - ErrPartitionStatsMissing: mysql.Message("Build table: %s global-level stats failed due to missing partition-level stats", nil), - ErrPartitionColumnStatsMissing: mysql.Message("Build table: %s global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions", nil), + ErrPartitionStatsMissing: mysql.Message("Build global-level stats failed due to missing partition-level stats: %s", nil), + ErrPartitionColumnStatsMissing: mysql.Message("Build global-level stats failed due to missing partition-level column stats: %s, please run analyze table to refresh columns of all partitions", nil), ErrDDLSetting: mysql.Message("Error happened when enable/disable DDL: %s", nil), + ErrIngestFailed: mysql.Message("Ingest failed: %s", nil), ErrNotSupportedWithSem: mysql.Message("Feature '%s' is not supported when security enhanced mode is enabled", nil), ErrPlacementPolicyCheck: mysql.Message("Placement policy didn't meet the constraint, reason: %s", nil), @@ -1086,10 +1099,14 @@ var MySQLErrName = map[uint16]*mysql.ErrMessage{ ErrPlacementPolicyWithDirectOption: mysql.Message("Placement policy '%s' can't co-exist with direct placement options", nil), ErrPlacementPolicyInUse: mysql.Message("Placement policy '%-.192s' is still in use", nil), ErrOptOnCacheTable: mysql.Message("'%s' is unsupported on cache tables.", nil), + ErrResourceGroupExists: mysql.Message("Resource group '%-.192s' already exists", nil), + ErrResourceGroupNotExists: mysql.Message("Unknown resource group '%-.192s'", nil), + + ErrColumnInChange: mysql.Message("column %s id %d does not exist, this column may have been updated by other DDL ran in parallel", nil), + ErrResourceGroupSupportDisabled: mysql.Message("Resource control feature is disabled. Run `SET GLOBAL tidb_enable_resource_control='on'` to enable the feature", nil), - ErrColumnInChange: mysql.Message("column %s id %d does not exist, this column may have been updated by other DDL ran in parallel", nil), // TiKV/PD errors. - ErrPDServerTimeout: mysql.Message("PD server timeout", nil), + ErrPDServerTimeout: mysql.Message("PD server timeout: %s", nil), ErrTiKVServerTimeout: mysql.Message("TiKV server timeout", nil), ErrTiKVServerBusy: mysql.Message("TiKV server is busy", nil), ErrTiFlashServerTimeout: mysql.Message("TiFlash server timeout", nil), diff --git a/errors.toml b/errors.toml index 55b2f846ad7d6..d7808c34337a1 100644 --- a/errors.toml +++ b/errors.toml @@ -66,6 +66,11 @@ error = ''' restore met a invalid peer ''' +["BR:EBS:ErrRestoreRegionWithoutPeer"] +error = ''' +restore met a region without any peer +''' + ["BR:EBS:ErrRestoreTotalKVMismatch"] error = ''' restore total tikvs mismatch @@ -456,6 +461,11 @@ error = ''' update pd error ''' +["Lightning:PreCheck:ErrCheckCDCPiTR"] +error = ''' +check TiCDC/PiTR task error +''' + ["Lightning:PreCheck:ErrCheckCSVHeader"] error = ''' check csv header error @@ -516,6 +526,11 @@ error = ''' encode kv error in file %s at offset %d ''' +["Lightning:Restore:ErrFoundDuplicateKey"] +error = ''' +found duplicate key '%s', value '%s' +''' + ["Lightning:Restore:ErrInvalidMetaStatus"] error = ''' invalid meta status: '%s' @@ -756,6 +771,11 @@ error = ''' Incorrect usage of %s and %s ''' +["ddl:1235"] +error = ''' +This version of TiDB doesn't yet support '%s' +''' + ["ddl:1246"] error = ''' Converting column '%s' from %s to %s @@ -1161,6 +1181,11 @@ error = ''' Column '%s' has an expression index dependency and cannot be dropped or renamed ''' +["ddl:3855"] +error = ''' +Column '%s' has a partitioning function dependency and cannot be dropped or renamed +''' + ["ddl:4135"] error = ''' Sequence '%-.64s.%-.64s' has run out @@ -1191,6 +1216,36 @@ error = ''' `%s` is unsupported on temporary tables. ''' +["ddl:8148"] +error = ''' +Field '%-.192s' is of a not supported type for TTL config, expect DATETIME, DATE or TIMESTAMP +''' + +["ddl:8149"] +error = ''' +Cannot drop column '%-.192s': needed in TTL config +''' + +["ddl:8150"] +error = ''' +Cannot set %s on a table without TTL config +''' + +["ddl:8151"] +error = ''' +Set TTL for temporary table is not allowed +''' + +["ddl:8152"] +error = ''' +Set TTL for a table referenced by foreign key is not allowed +''' + +["ddl:8153"] +error = ''' +Unsupported clustered primary key type FLOAT/DOUBLE for TTL +''' + ["ddl:8200"] error = ''' Unsupported shard_row_id_bits for table with primary key as row id @@ -1336,6 +1391,11 @@ error = ''' Error happened when enable/disable DDL: %s ''' +["ddl:8247"] +error = ''' +Ingest failed: %s +''' + ["domain:8027"] error = ''' Information schema is out of date: schema failed to update in 1 lease, please make sure TiDB can connect to TiKV @@ -1451,11 +1511,26 @@ error = ''' SET PASSWORD has no significance for user '%-.48s'@'%-.255s' as authentication plugin does not support it. ''' +["executor:1819"] +error = ''' +Your password does not satisfy the current policy requirements +''' + ["executor:1827"] error = ''' The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function. ''' +["executor:3008"] +error = ''' +Foreign key cascade delete/update exceeds max depth of %v. +''' + +["executor:3016"] +error = ''' +The password for anonymous user cannot be expired. +''' + ["executor:3523"] error = ''' Unknown authorization ID %.256s @@ -1471,6 +1546,11 @@ error = ''' Recursive query aborted after %d iterations. Try increasing @@cte_max_recursion_depth to a larger value ''' +["executor:3638"] +error = ''' +Cannot use these credentials for '%s@%s' because they contradict the password history policy. +''' + ["executor:3929"] error = ''' Dynamic privilege '%s' is not registered with the server. @@ -1631,6 +1711,21 @@ error = ''' Invalid data type for JSON data in argument %d to function %s; a JSON string or JSON type is required. ''' +["expression:3752"] +error = ''' +Value is out of range for expression index '%s' at row %d +''' + +["expression:3903"] +error = ''' +Invalid JSON value for CAST for expression index '%s' +''' + +["expression:3907"] +error = ''' +Data too long for expression index '%s' +''' + ["expression:8128"] error = ''' Invalid TABLESAMPLE: %s @@ -1658,7 +1753,7 @@ Cannot create a JSON value from a string with CHARACTER SET '%s'. ["json:3149"] error = ''' -In this situation, path expressions may not contain the * and ** tokens. +In this situation, path expressions may not contain the * and ** tokens or range selection. ''' ["json:3150"] @@ -1776,6 +1871,16 @@ error = ''' Unknown placement policy '%-.192s' ''' +["meta:8248"] +error = ''' +Resource group '%-.192s' already exists +''' + +["meta:8249"] +error = ''' +Unknown resource group '%-.192s' +''' + ["planner:1044"] error = ''' Access denied for user '%-.48s'@'%-.255s' to database '%-.192s' @@ -2226,6 +2331,11 @@ error = ''' There is no such grant defined for user '%-.48s' on host '%-.255s' ''' +["privilege:1862"] +error = ''' +Your password has expired. To log in you must change it using a client that supports expired passwords. +''' + ["privilege:3530"] error = ''' %s is not granted to %s @@ -2341,6 +2451,11 @@ error = ''' Changing schema from '%-.192s' to '%-.192s' is not allowed. ''' +["schema:1506"] +error = ''' +Foreign key clause is not yet supported in conjunction with partitioning +''' + ["schema:1822"] error = ''' Failed to add the foreign key constraint. Missing index for constraint '%s' in the referenced table '%s' @@ -2411,6 +2526,21 @@ error = ''' Unknown placement policy '%-.192s' ''' +["schema:8248"] +error = ''' +Resource group '%-.192s' already exists +''' + +["schema:8249"] +error = ''' +Unknown resource group '%-.192s' +''' + +["schema:8250"] +error = ''' +Resource control feature is disabled. Run `SET GLOBAL tidb_enable_resource_control='on'` to enable the feature +''' + ["session:8002"] error = ''' [%d] can not retry select for update statement @@ -2583,7 +2713,7 @@ TTL manager has timed out, pessimistic locks may expire, please commit or rollba ["tikv:9001"] error = ''' -PD server timeout +PD server timeout: %s ''' ["tikv:9002"] @@ -2721,6 +2851,11 @@ error = ''' Datetime function: %-.32s field overflow ''' +["types:1525"] +error = ''' +Incorrect %-.32s value: '%-.128s' +''' + ["types:1690"] error = ''' %s value is out of range in '%s' @@ -2768,12 +2903,12 @@ TiDB does not yet support JSON objects with the key length >= 65536 ["types:8131"] error = ''' -Build table: %s global-level stats failed due to missing partition-level stats +Build global-level stats failed due to missing partition-level stats: %s ''' ["types:8244"] error = ''' -Build table: %s global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions +Build global-level stats failed due to missing partition-level column stats: %s, please run analyze table to refresh columns of all partitions ''' ["variable:1193"] diff --git a/executor/BUILD.bazel b/executor/BUILD.bazel index eb422597617af..35703034b1214 100644 --- a/executor/BUILD.bazel +++ b/executor/BUILD.bazel @@ -16,6 +16,7 @@ go_library( "analyze_idx.go", "analyze_incremental.go", "analyze_utils.go", + "analyze_worker.go", "apply_cache.go", "batch_checker.go", "batch_point_get.go", @@ -55,6 +56,7 @@ go_library( "joiner.go", "load_data.go", "load_stats.go", + "lock_stats.go", "mem_reader.go", "memtable_reader.go", "merge_join.go", @@ -119,9 +121,11 @@ go_library( "//parser/ast", "//parser/auth", "//parser/charset", + "//parser/format", "//parser/model", "//parser/mysql", "//parser/terror", + "//parser/tidb", "//parser/types", "//planner", "//planner/core", @@ -149,6 +153,7 @@ go_library( "//telemetry", "//tidb-binlog/node", "//types", + "//types/parser_driver", "//util", "//util/admin", "//util/bitmap", @@ -174,16 +179,20 @@ go_library( "//util/mathutil", "//util/memory", "//util/mvmap", + "//util/password-validation", "//util/pdapi", "//util/plancodec", "//util/printer", "//util/ranger", + "//util/replayer", "//util/resourcegrouptag", "//util/rowDecoder", "//util/rowcodec", "//util/sem", + "//util/servermemorylimit", "//util/set", "//util/size", + "//util/slice", "//util/sqlexec", "//util/stmtsummary", "//util/stringutil", @@ -241,7 +250,7 @@ go_library( go_test( name = "executor_test", - timeout = "moderate", + timeout = "short", srcs = [ "adapter_test.go", "admin_test.go", @@ -263,7 +272,6 @@ go_test( "delete_test.go", "distsql_test.go", "executor_failpoint_test.go", - "executor_issue_test.go", "executor_pkg_test.go", "executor_required_rows_test.go", "executor_test.go", @@ -273,6 +281,7 @@ go_test( "explainfor_test.go", "grant_test.go", "hash_table_test.go", + "historical_stats_test.go", "hot_regions_history_table_test.go", "index_advise_test.go", "index_lookup_join_test.go", @@ -324,7 +333,6 @@ go_test( "utils_test.go", "window_test.go", "write_concurrent_test.go", - "write_test.go", ], data = glob(["testdata/**"]), embed = [":executor"], @@ -352,7 +360,6 @@ go_test( "//parser", "//parser/ast", "//parser/auth", - "//parser/charset", "//parser/model", "//parser/mysql", "//parser/terror", @@ -366,6 +373,7 @@ go_test( "//sessionctx/binloginfo", "//sessionctx/stmtctx", "//sessionctx/variable", + "//sessionctx/variable/featuretag/distributereorg", "//sessiontxn", "//sessiontxn/staleread", "//statistics", @@ -405,6 +413,7 @@ go_test( "//util/pdapi", "//util/plancodec", "//util/ranger", + "//util/replayer", "//util/rowcodec", "//util/set", "//util/sqlexec", @@ -433,6 +442,7 @@ go_test( "@com_github_tikv_client_go_v2//testutils", "@com_github_tikv_client_go_v2//tikv", "@com_github_tikv_client_go_v2//tikvrpc", + "@com_github_tikv_client_go_v2//util", "@org_golang_google_grpc//:grpc", "@org_golang_x_exp//slices", "@org_uber_go_atomic//:atomic", diff --git a/executor/adapter.go b/executor/adapter.go index b83c50ecfd7e1..46d925ff82ac2 100644 --- a/executor/adapter.go +++ b/executor/adapter.go @@ -18,6 +18,7 @@ import ( "bytes" "context" "fmt" + "math" "runtime/trace" "strconv" "strings" @@ -28,6 +29,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/log" + "github.com/pingcap/tidb/bindinfo" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl/placement" "github.com/pingcap/tidb/domain" @@ -57,6 +59,7 @@ import ( "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/plancodec" + "github.com/pingcap/tidb/util/replayer" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/stmtsummary" "github.com/pingcap/tidb/util/stringutil" @@ -78,6 +81,11 @@ var ( totalQueryProcHistogramInternal = metrics.TotalQueryProcHistogram.WithLabelValues(metrics.LblInternal) totalCopProcHistogramInternal = metrics.TotalCopProcHistogram.WithLabelValues(metrics.LblInternal) totalCopWaitHistogramInternal = metrics.TotalCopWaitHistogram.WithLabelValues(metrics.LblInternal) + + selectForUpdateFirstAttemptDuration = metrics.PessimisticDMLDurationByAttempt.WithLabelValues("select-for-update", "first-attempt") + selectForUpdateRetryDuration = metrics.PessimisticDMLDurationByAttempt.WithLabelValues("select-for-update", "retry") + dmlFirstAttemptDuration = metrics.PessimisticDMLDurationByAttempt.WithLabelValues("dml", "first-attempt") + dmlRetryDuration = metrics.PessimisticDMLDurationByAttempt.WithLabelValues("dml", "retry") ) // processinfoSetter is the interface use to set current running process info. @@ -191,12 +199,14 @@ func (a *recordSet) OnFetchReturned() { // TelemetryInfo records some telemetry information during execution. type TelemetryInfo struct { - UseNonRecursive bool - UseRecursive bool - UseMultiSchemaChange bool - UesExchangePartition bool - PartitionTelemetry *PartitionTelemetryInfo - AccountLockTelemetry *AccountLockTelemetryInfo + UseNonRecursive bool + UseRecursive bool + UseMultiSchemaChange bool + UseExchangePartition bool + UseFlashbackToCluster bool + PartitionTelemetry *PartitionTelemetryInfo + AccountLockTelemetry *AccountLockTelemetryInfo + UseIndexMerge bool } // PartitionTelemetryInfo records table partition telemetry information during execution. @@ -214,6 +224,8 @@ type PartitionTelemetryInfo struct { UseCreateIntervalPartition bool UseAddIntervalPartition bool UseDropIntervalPartition bool + UseCompactTablePartition bool + UseReorganizePartition bool } // AccountLockTelemetryInfo records account lock/unlock information during execution @@ -292,8 +304,12 @@ func (a *ExecStmt) PointGet(ctx context.Context) (*recordSet, error) { } a.Ctx.GetSessionVars().StmtCtx.Priority = kv.PriorityHigh + var pointExecutor *PointGetExecutor + useMaxTS := startTs == math.MaxUint64 + // try to reuse point get executor - if a.PsStmt.Executor != nil { + // We should only use the cached the executor when the startTS is MaxUint64 + if a.PsStmt.Executor != nil && useMaxTS { exec, ok := a.PsStmt.Executor.(*PointGetExecutor) if !ok { logutil.Logger(ctx).Error("invalid executor type, not PointGetExecutor for point get path") @@ -303,17 +319,21 @@ func (a *ExecStmt) PointGet(ctx context.Context) (*recordSet, error) { pointGetPlan := a.PsStmt.PreparedAst.CachedPlan.(*plannercore.PointGetPlan) exec.Init(pointGetPlan) a.PsStmt.Executor = exec + pointExecutor = exec } } - if a.PsStmt.Executor == nil { + + if pointExecutor == nil { b := newExecutorBuilder(a.Ctx, a.InfoSchema, a.Ti) - newExecutor := b.build(a.Plan) + pointExecutor = b.build(a.Plan).(*PointGetExecutor) if b.err != nil { return nil, b.err } - a.PsStmt.Executor = newExecutor + + if useMaxTS { + a.PsStmt.Executor = pointExecutor + } } - pointExecutor := a.PsStmt.Executor.(*PointGetExecutor) if err = pointExecutor.Open(ctx); err != nil { terror.Call(pointExecutor.Close) @@ -363,7 +383,7 @@ func (a *ExecStmt) IsReadOnly(vars *variable.SessionVars) bool { // It returns the current information schema version that 'a' is using. func (a *ExecStmt) RebuildPlan(ctx context.Context) (int64, error) { ret := &plannercore.PreprocessorReturn{} - if err := plannercore.Preprocess(a.Ctx, a.StmtNode, plannercore.InTxnRetry, plannercore.InitTxnContextProvider, plannercore.WithPreprocessorReturn(ret)); err != nil { + if err := plannercore.Preprocess(ctx, a.Ctx, a.StmtNode, plannercore.InTxnRetry, plannercore.InitTxnContextProvider, plannercore.WithPreprocessorReturn(ret)); err != nil { return 0, err } @@ -466,8 +486,20 @@ func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) { if !ok { oriIso = "REPEATABLE-READ" } - terror.Log(sctx.GetSessionVars().SetSystemVar(variable.TiDBBuildStatsConcurrency, "1")) - sctx.GetSessionVars().SetDistSQLScanConcurrency(1) + autoConcurrency, err1 := sctx.GetSessionVars().GetSessionOrGlobalSystemVar(ctx, variable.TiDBAutoBuildStatsConcurrency) + terror.Log(err1) + if err1 == nil { + terror.Log(sctx.GetSessionVars().SetSystemVar(variable.TiDBBuildStatsConcurrency, autoConcurrency)) + } + sVal, err2 := sctx.GetSessionVars().GetSessionOrGlobalSystemVar(ctx, variable.TiDBSysProcScanConcurrency) + terror.Log(err2) + if err2 == nil { + concurrency, err3 := strconv.ParseInt(sVal, 10, 64) + terror.Log(err3) + if err3 == nil { + sctx.GetSessionVars().SetDistSQLScanConcurrency(int(concurrency)) + } + } sctx.GetSessionVars().SetIndexSerialScanConcurrency(1) terror.Log(sctx.GetSessionVars().SetSystemVar(variable.TxnIsolation, ast.ReadCommitted)) defer func() { @@ -479,7 +511,7 @@ func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) { } if sctx.GetSessionVars().StmtCtx.HasMemQuotaHint { - sctx.GetSessionVars().StmtCtx.MemTracker.SetBytesLimit(sctx.GetSessionVars().StmtCtx.MemQuotaQuery) + sctx.GetSessionVars().MemTracker.SetBytesLimit(sctx.GetSessionVars().StmtCtx.MemQuotaQuery) } e, err := a.buildExecutor() @@ -509,10 +541,14 @@ func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) { } maxExecutionTime := getMaxExecutionTime(sctx) // Update processinfo, ShowProcess() will use it. - pi.SetProcessInfo(sql, time.Now(), cmd, maxExecutionTime) if a.Ctx.GetSessionVars().StmtCtx.StmtType == "" { a.Ctx.GetSessionVars().StmtCtx.StmtType = ast.GetStmtLabel(a.StmtNode) } + // Since maxExecutionTime is used only for query statement, here we limit it affect scope. + if !a.IsReadOnly(a.Ctx.GetSessionVars()) { + maxExecutionTime = 0 + } + pi.SetProcessInfo(sql, time.Now(), cmd, maxExecutionTime) } failpoint.Inject("mockDelayInnerSessionExecute", func() { @@ -535,13 +571,8 @@ func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) { return a.handlePessimisticSelectForUpdate(ctx, e) } - // In function handlePessimisticDML may rebuild a Executor when handlePessimisticLockError, - // so need to return the rebuild executor. - if handled, result, e, err := a.handleNoDelay(ctx, e, isPessimistic); handled || err != nil { - if err != nil { - return result, err - } - err = a.handleForeignKeyTrigger(ctx, e) + a.prepareFKCascadeContext(e) + if handled, result, err := a.handleNoDelay(ctx, e, isPessimistic); handled || err != nil { return result, err } @@ -561,7 +592,32 @@ func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) { }, nil } -func (a *ExecStmt) handleForeignKeyTrigger(ctx context.Context, e Executor) error { +func (a *ExecStmt) handleStmtForeignKeyTrigger(ctx context.Context, e Executor) error { + stmtCtx := a.Ctx.GetSessionVars().StmtCtx + if stmtCtx.ForeignKeyTriggerCtx.HasFKCascades { + // If the ExecStmt has foreign key cascade to be executed, we need call `StmtCommit` to commit the ExecStmt itself + // change first. + // Since `UnionScanExec` use `SnapshotIter` and `SnapshotGetter` to read txn mem-buffer, if we don't do `StmtCommit`, + // then the fk cascade executor can't read the mem-buffer changed by the ExecStmt. + a.Ctx.StmtCommit(ctx) + } + err := a.handleForeignKeyTrigger(ctx, e, 1) + if err != nil { + err1 := a.handleFKTriggerError(stmtCtx) + if err1 != nil { + return errors.Errorf("handle foreign key trigger error failed, err: %v, original_err: %v", err1, err) + } + return err + } + if stmtCtx.ForeignKeyTriggerCtx.SavepointName != "" { + a.Ctx.GetSessionVars().TxnCtx.ReleaseSavepoint(stmtCtx.ForeignKeyTriggerCtx.SavepointName) + } + return nil +} + +var maxForeignKeyCascadeDepth = 15 + +func (a *ExecStmt) handleForeignKeyTrigger(ctx context.Context, e Executor, depth int) error { exec, ok := e.(WithForeignKeyTrigger) if !ok { return nil @@ -573,16 +629,128 @@ func (a *ExecStmt) handleForeignKeyTrigger(ctx context.Context, e Executor) erro return err } } + fkCascades := exec.GetFKCascades() + for _, fkCascade := range fkCascades { + err := a.handleForeignKeyCascade(ctx, fkCascade, depth) + if err != nil { + return err + } + } return nil } -func (a *ExecStmt) handleNoDelay(ctx context.Context, e Executor, isPessimistic bool) (handled bool, rs sqlexec.RecordSet, _ Executor, err error) { +// handleForeignKeyCascade uses to execute foreign key cascade behaviour, the progress is: +// 1. Build delete/update executor for foreign key on delete/update behaviour. +// a. Construct delete/update AST. We used to try generated SQL string first and then parse the SQL to get AST, +// but we need convert Datum to string, there may be some risks here, since assert_eq(datum_a, parse(datum_a.toString())) may be broken. +// so we chose to construct AST directly. +// b. Build plan by the delete/update AST. +// c. Build executor by the delete/update plan. +// 2. Execute the delete/update executor. +// 3. Close the executor. +// 4. `StmtCommit` to commit the kv change to transaction mem-buffer. +// 5. If the foreign key cascade behaviour has more fk value need to be cascaded, go to step 1. +func (a *ExecStmt) handleForeignKeyCascade(ctx context.Context, fkc *FKCascadeExec, depth int) error { + if a.Ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil { + fkc.stats = &FKCascadeRuntimeStats{} + defer a.Ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(fkc.plan.ID(), fkc.stats) + } + if len(fkc.fkValues) == 0 && len(fkc.fkUpdatedValuesMap) == 0 { + return nil + } + if depth > maxForeignKeyCascadeDepth { + return ErrForeignKeyCascadeDepthExceeded.GenWithStackByArgs(maxForeignKeyCascadeDepth) + } + a.Ctx.GetSessionVars().StmtCtx.InHandleForeignKeyTrigger = true + defer func() { + a.Ctx.GetSessionVars().StmtCtx.InHandleForeignKeyTrigger = false + }() + if fkc.stats != nil { + start := time.Now() + defer func() { + fkc.stats.Total += time.Since(start) + }() + } + for { + e, err := fkc.buildExecutor(ctx) + if err != nil || e == nil { + return err + } + if err := e.Open(ctx); err != nil { + terror.Call(e.Close) + return err + } + err = Next(ctx, e, newFirstChunk(e)) + if err != nil { + return err + } + err = e.Close() + if err != nil { + return err + } + // Call `StmtCommit` uses to flush the fk cascade executor change into txn mem-buffer, + // then the later fk cascade executors can see the mem-buffer changes. + a.Ctx.StmtCommit(ctx) + err = a.handleForeignKeyTrigger(ctx, e, depth+1) + if err != nil { + return err + } + } +} + +// prepareFKCascadeContext records a transaction savepoint for foreign key cascade when this ExecStmt has foreign key +// cascade behaviour and this ExecStmt is in transaction. +func (a *ExecStmt) prepareFKCascadeContext(e Executor) { + exec, ok := e.(WithForeignKeyTrigger) + if !ok || !exec.HasFKCascades() { + return + } + sessVar := a.Ctx.GetSessionVars() + sessVar.StmtCtx.ForeignKeyTriggerCtx.HasFKCascades = true + if !sessVar.InTxn() { + return + } + txn, err := a.Ctx.Txn(false) + if err != nil || !txn.Valid() { + return + } + // Record a txn savepoint if ExecStmt in transaction, the savepoint is use to do rollback when handle foreign key + // cascade failed. + savepointName := "fk_sp_" + strconv.FormatUint(txn.StartTS(), 10) + memDBCheckpoint := txn.GetMemDBCheckpoint() + sessVar.TxnCtx.AddSavepoint(savepointName, memDBCheckpoint) + sessVar.StmtCtx.ForeignKeyTriggerCtx.SavepointName = savepointName +} + +func (a *ExecStmt) handleFKTriggerError(sc *stmtctx.StatementContext) error { + if sc.ForeignKeyTriggerCtx.SavepointName == "" { + return nil + } + txn, err := a.Ctx.Txn(false) + if err != nil || !txn.Valid() { + return err + } + savepointRecord := a.Ctx.GetSessionVars().TxnCtx.RollbackToSavepoint(sc.ForeignKeyTriggerCtx.SavepointName) + if savepointRecord == nil { + // Normally should never run into here, but just in case, rollback the transaction. + err = txn.Rollback() + if err != nil { + return err + } + return errors.Errorf("foreign key cascade savepoint '%s' not found, transaction is rollback, should never happen", sc.ForeignKeyTriggerCtx.SavepointName) + } + txn.RollbackMemDBToCheckpoint(savepointRecord.MemDBCheckpoint) + a.Ctx.GetSessionVars().TxnCtx.ReleaseSavepoint(sc.ForeignKeyTriggerCtx.SavepointName) + return nil +} + +func (a *ExecStmt) handleNoDelay(ctx context.Context, e Executor, isPessimistic bool) (handled bool, rs sqlexec.RecordSet, err error) { sc := a.Ctx.GetSessionVars().StmtCtx defer func() { // If the stmt have no rs like `insert`, The session tracker detachment will be directly // done in the `defer` function. If the rs is not nil, the detachment will be done in // `rs.Close` in `handleStmt` - if sc != nil && rs == nil { + if handled && sc != nil && rs == nil { if sc.MemTracker != nil { sc.MemTracker.Detach() } @@ -606,20 +774,20 @@ func (a *ExecStmt) handleNoDelay(ctx context.Context, e Executor, isPessimistic if toCheck.Schema().Len() == 0 { handled = !isExplainAnalyze if isPessimistic { - e, err := a.handlePessimisticDML(ctx, toCheck) - return handled, nil, e, err + err := a.handlePessimisticDML(ctx, toCheck) + return handled, nil, err } r, err := a.handleNoDelayExecutor(ctx, toCheck) - return handled, r, e, err + return handled, r, err } else if proj, ok := toCheck.(*ProjectionExec); ok && proj.calculateNoDelay { // Currently this is only for the "DO" statement. Take "DO 1, @a=2;" as an example: // the Projection has two expressions and two columns in the schema, but we should // not return the result of the two expressions. r, err := a.handleNoDelayExecutor(ctx, e) - return true, r, e, err + return true, r, err } - return false, nil, e, nil + return false, nil, nil } func isNoResultPlan(p plannercore.Plan) bool { @@ -696,8 +864,25 @@ func (a *ExecStmt) handlePessimisticSelectForUpdate(ctx context.Context, e Execu return nil, errors.New("can not execute write statement when 'tidb_snapshot' is set") } + txnManager := sessiontxn.GetTxnManager(a.Ctx) + err := txnManager.OnHandlePessimisticStmtStart(ctx) + if err != nil { + return nil, err + } + + isFirstAttempt := true + for { + startTime := time.Now() rs, err := a.runPessimisticSelectForUpdate(ctx, e) + + if isFirstAttempt { + selectForUpdateFirstAttemptDuration.Observe(time.Since(startTime).Seconds()) + isFirstAttempt = false + } else { + selectForUpdateRetryDuration.Observe(time.Since(startTime).Seconds()) + } + e, err = a.handlePessimisticLockError(ctx, err) if err != nil { return nil, err @@ -705,6 +890,8 @@ func (a *ExecStmt) handlePessimisticSelectForUpdate(ctx context.Context, e Execu if e == nil { return rs, nil } + + failpoint.Inject("pessimisticSelectForUpdateRetry", nil) } } @@ -714,7 +901,7 @@ func (a *ExecStmt) runPessimisticSelectForUpdate(ctx context.Context, e Executor }() var rows []chunk.Row var err error - req := newFirstChunk(e) + req := tryNewCacheChunk(e) for { err = a.next(ctx, e, req) if err != nil { @@ -761,21 +948,22 @@ func (a *ExecStmt) handleNoDelayExecutor(ctx context.Context, e Executor) (sqlex } } - err = a.next(ctx, e, newFirstChunk(e)) + err = a.next(ctx, e, tryNewCacheChunk(e)) if err != nil { return nil, err } + err = a.handleStmtForeignKeyTrigger(ctx, e) return nil, err } -func (a *ExecStmt) handlePessimisticDML(ctx context.Context, e Executor) (_ Executor, err error) { +func (a *ExecStmt) handlePessimisticDML(ctx context.Context, e Executor) (err error) { sctx := a.Ctx // Do not activate the transaction here. // When autocommit = 0 and transaction in pessimistic mode, // statements like set xxx = xxx; should not active the transaction. txn, err := sctx.Txn(false) if err != nil { - return e, err + return err } txnCtx := sctx.GetSessionVars().TxnCtx defer func() { @@ -799,37 +987,58 @@ func (a *ExecStmt) handlePessimisticDML(ctx context.Context, e Executor) (_ Exec err = ErrLazyUniquenessCheckFailure.GenWithStackByArgs(err.Error()) } }() + + txnManager := sessiontxn.GetTxnManager(a.Ctx) + err = txnManager.OnHandlePessimisticStmtStart(ctx) + if err != nil { + return err + } + + isFirstAttempt := true + for { - startPointGetLocking := time.Now() + if !isFirstAttempt { + failpoint.Inject("pessimisticDMLRetry", nil) + } + + startTime := time.Now() _, err = a.handleNoDelayExecutor(ctx, e) if !txn.Valid() { - return e, err + return err } + + if isFirstAttempt { + dmlFirstAttemptDuration.Observe(time.Since(startTime).Seconds()) + isFirstAttempt = false + } else { + dmlRetryDuration.Observe(time.Since(startTime).Seconds()) + } + if err != nil { // It is possible the DML has point get plan that locks the key. e, err = a.handlePessimisticLockError(ctx, err) if err != nil { if ErrDeadlock.Equal(err) { - metrics.StatementDeadlockDetectDuration.Observe(time.Since(startPointGetLocking).Seconds()) + metrics.StatementDeadlockDetectDuration.Observe(time.Since(startTime).Seconds()) } - return e, err + return err } continue } keys, err1 := txn.(pessimisticTxn).KeysNeedToLock() if err1 != nil { - return e, err1 + return err1 } keys = txnCtx.CollectUnchangedRowKeys(keys) if len(keys) == 0 { - return e, nil + return nil } keys = filterTemporaryTableKeys(sctx.GetSessionVars(), keys) seVars := sctx.GetSessionVars() keys = filterLockTableKeys(seVars.StmtCtx, keys) lockCtx, err := newLockCtx(sctx, seVars.LockWaitTimeout, len(keys)) if err != nil { - return e, err + return err } var lockKeyStats *util.LockKeysDetails ctx = context.WithValue(ctx, util.LockKeysDetailCtxKey, &lockKeyStats) @@ -840,7 +1049,7 @@ func (a *ExecStmt) handlePessimisticDML(ctx context.Context, e Executor) (_ Exec seVars.StmtCtx.MergeLockKeysExecDetails(lockKeyStats) } if err == nil { - return e, nil + return nil } e, err = a.handlePessimisticLockError(ctx, err) if err != nil { @@ -848,7 +1057,7 @@ func (a *ExecStmt) handlePessimisticDML(ctx context.Context, e Executor) (_ Exec if ErrDeadlock.Equal(err) { metrics.StatementDeadlockDetectDuration.Observe(time.Since(startLocking).Seconds()) } - return e, err + return err } } } @@ -908,7 +1117,7 @@ func (a *ExecStmt) handlePessimisticLockError(ctx context.Context, lockErr error return nil, err } // Rollback the statement change before retry it. - a.Ctx.StmtRollback() + a.Ctx.StmtRollback(ctx, true) a.Ctx.GetSessionVars().StmtCtx.ResetForRetry() a.Ctx.GetSessionVars().RetryInfo.ResetOffset() @@ -1204,6 +1413,18 @@ func (a *ExecStmt) observePhaseDurations(internal bool, commitDetails *util.Comm // 4. update the `PrevStmt` in session variable. // 5. reset `DurationParse` in session variable. func (a *ExecStmt) FinishExecuteStmt(txnTS uint64, err error, hasMoreResults bool) { + se := a.Ctx + if !se.GetSessionVars().InRestrictedSQL && se.GetSessionVars().IsPlanReplayerCaptureEnabled() { + stmtNode := a.GetStmtNode() + if se.GetSessionVars().EnablePlanReplayedContinuesCapture { + if checkPlanReplayerContinuesCaptureValidStmt(stmtNode) { + checkPlanReplayerContinuesCapture(se, stmtNode, txnTS) + } + } else { + checkPlanReplayerCaptureTask(se, stmtNode, txnTS) + } + } + sessVars := a.Ctx.GetSessionVars() execDetail := sessVars.StmtCtx.GetExecDetails() // Attach commit/lockKeys runtime stats to executor runtime stats. @@ -1255,6 +1476,10 @@ func (a *ExecStmt) FinishExecuteStmt(txnTS uint64, err error, hasMoreResults boo sessVars.DurationParse = 0 // Clean the stale read flag when statement execution finish sessVars.StmtCtx.IsStaleness = false + // Clean the MPP query info + sessVars.StmtCtx.MPPQueryInfo.QueryID.Store(0) + sessVars.StmtCtx.MPPQueryInfo.QueryTS.Store(0) + sessVars.StmtCtx.MPPQueryInfo.AllocatedMPPTaskID.Store(0) if sessVars.StmtCtx.ReadFromTableCache { metrics.ReadFromTableCacheCounter.Inc() @@ -1327,8 +1552,8 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool, hasMoreResults bool) { execDetail := stmtCtx.GetExecDetails() copTaskInfo := stmtCtx.CopTasksDetails() statsInfos := plannercore.GetStatsInfoFromFlatPlan(flat) - memMax := stmtCtx.MemTracker.MaxConsumed() - diskMax := stmtCtx.DiskTracker.MaxConsumed() + memMax := sessVars.MemTracker.MaxConsumed() + diskMax := sessVars.DiskTracker.MaxConsumed() _, planDigest := getPlanDigest(stmtCtx) binaryPlan := "" @@ -1375,6 +1600,7 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool, hasMoreResults bool) { IsWriteCacheTable: stmtCtx.WaitLockLeaseTime > 0, StatsLoadStatus: convertStatusIntoString(a.Ctx, stmtCtx.StatsLoadStatus), IsSyncStatsFailed: stmtCtx.IsSyncStatsFailed, + Warnings: collectWarningsForSlowLog(stmtCtx), } failpoint.Inject("assertSyncStatsFailed", func(val failpoint.Value) { if val.(bool) { @@ -1386,7 +1612,7 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool, hasMoreResults bool) { if a.retryCount > 0 { slowItems.ExecRetryTime = costTime - sessVars.DurationParse - sessVars.DurationCompile - time.Since(a.retryStartTime) } - if _, ok := a.StmtNode.(*ast.CommitStmt); ok { + if _, ok := a.StmtNode.(*ast.CommitStmt); ok && sessVars.PrevStmt != nil { slowItems.PrevStmt = sessVars.PrevStmt.String() } slowLog := sessVars.SlowLogFormat(slowItems) @@ -1430,6 +1656,33 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool, hasMoreResults bool) { } } +func extractMsgFromSQLWarn(SQLWarn *stmtctx.SQLWarn) string { + // Currently, this function is only used in collectWarningsForSlowLog. + // collectWarningsForSlowLog can make sure SQLWarn is not nil so no need to add a nil check here. + warn := errors.Cause(SQLWarn.Err) + if x, ok := warn.(*terror.Error); ok && x != nil { + sqlErr := terror.ToSQLError(x) + return sqlErr.Message + } + return warn.Error() +} + +func collectWarningsForSlowLog(stmtCtx *stmtctx.StatementContext) []variable.JSONSQLWarnForSlowLog { + warnings := stmtCtx.GetWarnings() + extraWarnings := stmtCtx.GetExtraWarnings() + res := make([]variable.JSONSQLWarnForSlowLog, len(warnings)+len(extraWarnings)) + for i := range warnings { + res[i].Level = warnings[i].Level + res[i].Message = extractMsgFromSQLWarn(&warnings[i]) + } + for i := range extraWarnings { + res[len(warnings)+i].Level = extraWarnings[i].Level + res[len(warnings)+i].Message = extractMsgFromSQLWarn(&extraWarnings[i]) + res[len(warnings)+i].IsExtra = true + } + return res +} + // GetResultRowsCount gets the count of the statement result rows. func GetResultRowsCount(stmtCtx *stmtctx.StatementContext, p plannercore.Plan) int64 { runtimeStatsColl := stmtCtx.RuntimeStatsColl @@ -1501,6 +1754,11 @@ func getPlanDigest(stmtCtx *stmtctx.StatementContext) (string, *parser.Digest) { return normalized, planDigest } +// GetEncodedPlan returned same as getEncodedPlan +func GetEncodedPlan(stmtCtx *stmtctx.StatementContext, genHint bool) (encodedPlan, hintStr string) { + return getEncodedPlan(stmtCtx, genHint) +} + // getEncodedPlan gets the encoded plan, and generates the hint string if indicated. func getEncodedPlan(stmtCtx *stmtctx.StatementContext, genHint bool) (encodedPlan, hintStr string) { var hintSet bool @@ -1598,8 +1856,8 @@ func (a *ExecStmt) SummaryStmt(succ bool) { execDetail := stmtCtx.GetExecDetails() copTaskInfo := stmtCtx.CopTasksDetails() - memMax := stmtCtx.MemTracker.MaxConsumed() - diskMax := stmtCtx.DiskTracker.MaxConsumed() + memMax := sessVars.MemTracker.MaxConsumed() + diskMax := sessVars.DiskTracker.MaxConsumed() sql := a.GetTextToLog() var stmtDetail execdetails.StmtExecDetails stmtDetailRaw := a.GoCtx.Value(execdetails.StmtExecDetailKey) @@ -1745,7 +2003,6 @@ func (a *ExecStmt) getSQLPlanDigest() ([]byte, []byte) { } return sqlDigest, planDigest } - func convertStatusIntoString(sctx sessionctx.Context, statsLoadStatus map[model.TableItemID]string) map[string]map[string]string { if len(statsLoadStatus) < 1 { return nil @@ -1783,3 +2040,92 @@ func convertStatusIntoString(sctx sessionctx.Context, statsLoadStatus map[model. } return r } + +// only allow select/delete/update/insert/execute stmt captured by continues capture +func checkPlanReplayerContinuesCaptureValidStmt(stmtNode ast.StmtNode) bool { + switch stmtNode.(type) { + case *ast.SelectStmt, *ast.DeleteStmt, *ast.UpdateStmt, *ast.InsertStmt, *ast.ExecuteStmt: + return true + default: + return false + } +} + +func checkPlanReplayerCaptureTask(sctx sessionctx.Context, stmtNode ast.StmtNode, startTS uint64) { + dom := domain.GetDomain(sctx) + if dom == nil { + return + } + handle := dom.GetPlanReplayerHandle() + if handle == nil { + return + } + tasks := handle.GetTasks() + if len(tasks) == 0 { + return + } + _, sqlDigest := sctx.GetSessionVars().StmtCtx.SQLDigest() + _, planDigest := sctx.GetSessionVars().StmtCtx.GetPlanDigest() + if sqlDigest == nil || planDigest == nil { + return + } + key := replayer.PlanReplayerTaskKey{ + SQLDigest: sqlDigest.String(), + PlanDigest: planDigest.String(), + } + for _, task := range tasks { + if task.SQLDigest == sqlDigest.String() { + if task.PlanDigest == "*" || task.PlanDigest == planDigest.String() { + sendPlanReplayerDumpTask(key, sctx, stmtNode, startTS, false) + return + } + } + } +} + +func checkPlanReplayerContinuesCapture(sctx sessionctx.Context, stmtNode ast.StmtNode, startTS uint64) { + dom := domain.GetDomain(sctx) + if dom == nil { + return + } + handle := dom.GetPlanReplayerHandle() + if handle == nil { + return + } + _, sqlDigest := sctx.GetSessionVars().StmtCtx.SQLDigest() + _, planDigest := sctx.GetSessionVars().StmtCtx.GetPlanDigest() + key := replayer.PlanReplayerTaskKey{ + SQLDigest: sqlDigest.String(), + PlanDigest: planDigest.String(), + } + existed := sctx.GetSessionVars().CheckPlanReplayerFinishedTaskKey(key) + if existed { + return + } + sendPlanReplayerDumpTask(key, sctx, stmtNode, startTS, true) + sctx.GetSessionVars().AddPlanReplayerFinishedTaskKey(key) +} + +func sendPlanReplayerDumpTask(key replayer.PlanReplayerTaskKey, sctx sessionctx.Context, stmtNode ast.StmtNode, + startTS uint64, isContinuesCapture bool) { + stmtCtx := sctx.GetSessionVars().StmtCtx + handle := sctx.Value(bindinfo.SessionBindInfoKeyType).(*bindinfo.SessionHandle) + dumpTask := &domain.PlanReplayerDumpTask{ + PlanReplayerTaskKey: key, + StartTS: startTS, + EncodePlan: GetEncodedPlan, + TblStats: stmtCtx.TableStats, + SessionBindings: handle.GetAllBindRecord(), + SessionVars: sctx.GetSessionVars(), + ExecStmts: []ast.StmtNode{stmtNode}, + Analyze: false, + IsCapture: true, + IsContinuesCapture: isContinuesCapture, + } + if _, ok := stmtNode.(*ast.ExecuteStmt); ok { + nsql, _ := sctx.GetSessionVars().StmtCtx.SQLDigest() + dumpTask.InExecute = true + dumpTask.NormalizedSQL = nsql + } + domain.GetDomain(sctx).GetPlanReplayerHandle().SendTask(dumpTask) +} diff --git a/executor/admin.go b/executor/admin.go index ba219b70b6db3..21378b21b1677 100644 --- a/executor/admin.go +++ b/executor/admin.go @@ -111,7 +111,7 @@ func (e *CheckIndexRangeExec) Open(ctx context.Context) error { FieldType: *colTypeForHandle, }) - e.srcChunk = newFirstChunk(e) + e.srcChunk = tryNewCacheChunk(e) dagPB, err := e.buildDAGPB() if err != nil { return err @@ -151,7 +151,7 @@ func (e *CheckIndexRangeExec) buildDAGPB() (*tipb.DAGRequest, error) { execPB := e.constructIndexScanPB() dagReq.Executors = append(dagReq.Executors, execPB) - err := plannercore.SetPBColumnsDefaultValue(e.ctx, dagReq.Executors[0].IdxScan.Columns, e.cols) + err := tables.SetPBColumnsDefaultValue(e.ctx, dagReq.Executors[0].IdxScan.Columns, e.cols) if err != nil { return nil, err } @@ -163,7 +163,7 @@ func (e *CheckIndexRangeExec) constructIndexScanPB() *tipb.Executor { idxExec := &tipb.IndexScan{ TableId: e.table.ID, IndexId: e.index.ID, - Columns: util.ColumnsToProto(e.cols, e.table.PKIsHandle), + Columns: util.ColumnsToProto(e.cols, e.table.PKIsHandle, true), } return &tipb.Executor{Tp: tipb.ExecType_TypeIndexScan, IdxScan: idxExec} } @@ -227,7 +227,7 @@ func (e *RecoverIndexExec) Open(ctx context.Context) error { func (e *RecoverIndexExec) constructTableScanPB(tblInfo *model.TableInfo, colInfos []*model.ColumnInfo) (*tipb.Executor, error) { tblScan := tables.BuildTableScanFromInfos(tblInfo, colInfos) tblScan.TableId = e.physicalID - err := plannercore.SetPBColumnsDefaultValue(e.ctx, tblScan.Columns, colInfos) + err := tables.SetPBColumnsDefaultValue(e.ctx, tblScan.Columns, colInfos) return &tipb.Executor{Tp: tipb.ExecType_TypeTableScan, TblScan: tblScan}, err } @@ -265,10 +265,11 @@ func (e *RecoverIndexExec) buildTableScan(ctx context.Context, txn kv.Transactio return nil, err } var builder distsql.RequestBuilder - builder.KeyRanges, err = buildRecoverIndexKeyRanges(e.ctx.GetSessionVars().StmtCtx, e.physicalID, startHandle) + keyRanges, err := buildRecoverIndexKeyRanges(e.ctx.GetSessionVars().StmtCtx, e.physicalID, startHandle) if err != nil { return nil, err } + builder.KeyRanges = kv.NewNonParitionedKeyRanges(keyRanges) kvReq, err := builder. SetDAGRequest(dagPB). SetStartTS(txn.StartTS()). @@ -380,7 +381,7 @@ func (e *RecoverIndexExec) fetchRecoverRows(ctx context.Context, srcResult dists } idxVals := extractIdxVals(row, e.idxValsBufs[result.scanRowCount], e.colFieldTypes, idxValLen) e.idxValsBufs[result.scanRowCount] = idxVals - rsData := tables.TryGetHandleRestoredDataWrapper(e.table, plannercore.GetCommonHandleDatum(e.handleCols, row), nil, e.index.Meta()) + rsData := tables.TryGetHandleRestoredDataWrapper(e.table.Meta(), plannercore.GetCommonHandleDatum(e.handleCols, row), nil, e.index.Meta()) e.recoverRows = append(e.recoverRows, recoverRows{handle: handle, idxVals: idxVals, rsData: rsData, skip: false}) result.scanRowCount++ result.currentHandle = handle @@ -737,7 +738,16 @@ func (e *CleanupIndexExec) buildIndexScan(ctx context.Context, txn kv.Transactio sc := e.ctx.GetSessionVars().StmtCtx var builder distsql.RequestBuilder ranges := ranger.FullRange() - kvReq, err := builder.SetIndexRanges(sc, e.physicalID, e.index.Meta().ID, ranges). + keyRanges, err := distsql.IndexRangesToKVRanges(sc, e.physicalID, e.index.Meta().ID, ranges, nil) + if err != nil { + return nil, err + } + err = keyRanges.SetToNonPartitioned() + if err != nil { + return nil, err + } + keyRanges.FirstPartitionRange()[0].StartKey = kv.Key(e.lastIdxKey).PrefixNext() + kvReq, err := builder.SetWrappedKeyRanges(keyRanges). SetDAGRequest(dagPB). SetStartTS(txn.StartTS()). SetKeepOrder(true). @@ -748,7 +758,6 @@ func (e *CleanupIndexExec) buildIndexScan(ctx context.Context, txn kv.Transactio return nil, err } - kvReq.KeyRanges[0].StartKey = kv.Key(e.lastIdxKey).PrefixNext() kvReq.Concurrency = 1 result, err := distsql.Select(ctx, e.ctx, kvReq, e.getIdxColTypes(), statistics.NewQueryFeedback(0, nil, 0, false)) if err != nil { @@ -790,7 +799,7 @@ func (e *CleanupIndexExec) buildIdxDAGPB(txn kv.Transaction) (*tipb.DAGRequest, execPB := e.constructIndexScanPB() dagReq.Executors = append(dagReq.Executors, execPB) - err := plannercore.SetPBColumnsDefaultValue(e.ctx, dagReq.Executors[0].IdxScan.Columns, e.columns) + err := tables.SetPBColumnsDefaultValue(e.ctx, dagReq.Executors[0].IdxScan.Columns, e.columns) if err != nil { return nil, err } @@ -805,7 +814,7 @@ func (e *CleanupIndexExec) constructIndexScanPB() *tipb.Executor { idxExec := &tipb.IndexScan{ TableId: e.physicalID, IndexId: e.index.Meta().ID, - Columns: util.ColumnsToProto(e.columns, e.table.Meta().PKIsHandle), + Columns: util.ColumnsToProto(e.columns, e.table.Meta().PKIsHandle, true), PrimaryColumnIds: tables.TryGetCommonPkColumnIds(e.table.Meta()), } return &tipb.Executor{Tp: tipb.ExecType_TypeIndexScan, IdxScan: idxExec} diff --git a/executor/admin_test.go b/executor/admin_test.go index 23b57e9c316b6..cd5c0664d031a 100644 --- a/executor/admin_test.go +++ b/executor/admin_test.go @@ -133,7 +133,7 @@ func TestAdminCheckIndexInLocalTemporaryMode(t *testing.T) { tk.MustExec("drop table if exists local_temporary_admin_test;") tk.MustExec("create temporary table local_temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2))") tk.MustExec("insert local_temporary_admin_test (c1, c2) values (1,1), (2,2), (3,3);") - _, err := tk.Exec("admin check table local_temporary_admin_test;") + err := tk.ExecToErr("admin check table local_temporary_admin_test;") require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin check table").Error()) tk.MustExec("drop table if exists temporary_admin_test;") @@ -843,6 +843,65 @@ func TestClusteredAdminCleanupIndex(t *testing.T) { tk.MustExec("admin check table admin_test") } +func TestAdminCheckTableWithMultiValuedIndex(t *testing.T) { + store, domain := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(pk int primary key, a json, index idx((cast(a as signed array))))") + tk.MustExec("insert into t values (0, '[0,1,2]')") + tk.MustExec("insert into t values (1, '[1,2,3]')") + tk.MustExec("insert into t values (2, '[2,3,4]')") + tk.MustExec("insert into t values (3, '[3,4,5]')") + tk.MustExec("insert into t values (4, '[4,5,6]')") + tk.MustExec("admin check table t") + + // Make some corrupted index. Build the index information. + ctx := mock.NewContext() + ctx.Store = store + is := domain.InfoSchema() + dbName := model.NewCIStr("test") + tblName := model.NewCIStr("t") + tbl, err := is.TableByName(dbName, tblName) + require.NoError(t, err) + tblInfo := tbl.Meta() + idxInfo := tblInfo.Indices[0] + sc := ctx.GetSessionVars().StmtCtx + tk.Session().GetSessionVars().IndexLookupSize = 3 + tk.Session().GetSessionVars().MaxChunkSize = 3 + + cpIdx := idxInfo.Clone() + cpIdx.MVIndex = false + indexOpr := tables.NewIndex(tblInfo.ID, tblInfo, cpIdx) + txn, err := store.Begin() + require.NoError(t, err) + err = indexOpr.Delete(sc, txn, types.MakeDatums(0), kv.IntHandle(0)) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + err = tk.ExecToErr("admin check table t") + require.Error(t, err) + require.True(t, consistency.ErrAdminCheckInconsistent.Equal(err)) + + txn, err = store.Begin() + require.NoError(t, err) + _, err = indexOpr.Create(ctx, txn, types.MakeDatums(0), kv.IntHandle(0), nil) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + tk.MustExec("admin check table t") + + txn, err = store.Begin() + require.NoError(t, err) + _, err = indexOpr.Create(ctx, txn, types.MakeDatums(9), kv.IntHandle(9), nil) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + err = tk.ExecToErr("admin check table t") + require.Error(t, err) +} + func TestAdminCheckPartitionTableFailed(t *testing.T) { store, domain := testkit.CreateMockStoreAndDomain(t) @@ -1095,9 +1154,7 @@ func TestCheckFailReport(t *testing.T) { require.NoError(t, txn.Commit(tk.ctx)) ctx, hook := withLogHook(tk.ctx, t, "inconsistency") - _, err = tk.Exec(ctx, "admin check table admin_test") - require.Error(t, err) - require.Equal(t, "[admin:8223]data inconsistency in table: admin_test, index: uk1, handle: 1, index-values:\"\" != record-values:\"handle: 1, values: [KindInt64 1]\"", err.Error()) + tk.MustGetErrMsg(ctx, "admin check table admin_test", "[admin:8223]data inconsistency in table: admin_test, index: uk1, handle: 1, index-values:\"\" != record-values:\"handle: 1, values: [KindInt64 1]\"") hook.checkLogCount(t, 1) hook.logs[0].checkMsg(t, "admin check found data inconsistency") hook.logs[0].checkField(t, @@ -1119,9 +1176,7 @@ func TestCheckFailReport(t *testing.T) { require.NoError(t, txn.Commit(tk.ctx)) ctx, hook := withLogHook(tk.ctx, t, "inconsistency") - _, err = tk.Exec(ctx, "admin check table admin_test") - require.Error(t, err) - require.Equal(t, "[admin:8223]data inconsistency in table: admin_test, index: k2, handle: 1, index-values:\"\" != record-values:\"handle: 1, values: [KindString 10]\"", err.Error()) + tk.MustGetErrMsg(ctx, "admin check table admin_test", "[admin:8223]data inconsistency in table: admin_test, index: k2, handle: 1, index-values:\"\" != record-values:\"handle: 1, values: [KindString 10]\"") hook.checkLogCount(t, 1) hook.logs[0].checkMsg(t, "admin check found data inconsistency") hook.logs[0].checkField(t, @@ -1143,9 +1198,8 @@ func TestCheckFailReport(t *testing.T) { require.NoError(t, txn.Commit(tk.ctx)) ctx, hook := withLogHook(tk.ctx, t, "inconsistency") - _, err = tk.Exec(ctx, "admin check table admin_test") - require.Error(t, err) - require.Equal(t, "[admin:8223]data inconsistency in table: admin_test, index: k2, handle: 1, index-values:\"handle: 1, values: [KindString 100 KindInt64 1]\" != record-values:\"\"", err.Error()) + tk.MustGetErrMsg(ctx, "admin check table admin_test", + "[admin:8223]data inconsistency in table: admin_test, index: k2, handle: 1, index-values:\"handle: 1, values: [KindString 100 KindInt64 1]\" != record-values:\"\"") hook.checkLogCount(t, 1) logEntry := hook.logs[0] logEntry.checkMsg(t, "admin check found data inconsistency") @@ -1188,9 +1242,8 @@ func TestCheckFailReport(t *testing.T) { require.NoError(t, txn.Commit(tk.ctx)) ctx, hook := withLogHook(tk.ctx, t, "inconsistency") - _, err = tk.Exec(ctx, "admin check table admin_test") - require.Error(t, err) - require.Equal(t, "[admin:8223]data inconsistency in table: admin_test, index: uk1, handle: 1, index-values:\"handle: 1, values: [KindInt64 10 KindInt64 1]\" != record-values:\"\"", err.Error()) + tk.MustGetErrMsg(ctx, "admin check table admin_test", + "[admin:8223]data inconsistency in table: admin_test, index: uk1, handle: 1, index-values:\"handle: 1, values: [KindInt64 10 KindInt64 1]\" != record-values:\"\"") hook.checkLogCount(t, 1) logEntry := hook.logs[0] logEntry.checkMsg(t, "admin check found data inconsistency") @@ -1233,9 +1286,8 @@ func TestCheckFailReport(t *testing.T) { require.NoError(t, err) require.NoError(t, txn.Commit(tk.ctx)) ctx, hook := withLogHook(tk.ctx, t, "inconsistency") - _, err = tk.Exec(ctx, "admin check table admin_test") - require.Error(t, err) - require.Equal(t, "[executor:8134]data inconsistency in table: admin_test, index: uk1, col: c2, handle: \"1\", index-values:\"KindInt64 20\" != record-values:\"KindInt64 10\", compare err:", err.Error()) + tk.MustGetErrMsg(ctx, "admin check table admin_test", + "[executor:8134]data inconsistency in table: admin_test, index: uk1, col: c2, handle: \"1\", index-values:\"KindInt64 20\" != record-values:\"KindInt64 10\", compare err:") hook.checkLogCount(t, 1) logEntry := hook.logs[0] logEntry.checkMsg(t, "admin check found data inconsistency") @@ -1261,9 +1313,8 @@ func TestCheckFailReport(t *testing.T) { require.NoError(t, err) require.NoError(t, txn.Commit(tk.ctx)) ctx, hook := withLogHook(tk.ctx, t, "inconsistency") - _, err = tk.Exec(ctx, "admin check table admin_test") - require.Error(t, err) - require.Equal(t, "[executor:8134]data inconsistency in table: admin_test, index: k2, col: c3, handle: \"1\", index-values:\"KindString 200\" != record-values:\"KindString 100\", compare err:", err.Error()) + tk.MustGetErrMsg(ctx, "admin check table admin_test", + "[executor:8134]data inconsistency in table: admin_test, index: k2, col: c3, handle: \"1\", index-values:\"KindString 200\" != record-values:\"KindString 100\", compare err:") hook.checkLogCount(t, 1) logEntry := hook.logs[0] logEntry.checkMsg(t, "admin check found data inconsistency") @@ -1301,12 +1352,10 @@ func TestCheckFailReport(t *testing.T) { // TODO(tiancaiamao): admin check doesn't support the chunk protocol. // Remove this after https://github.com/pingcap/tidb/issues/35156 - _, err = tk.Exec(ctx, "set @@tidb_enable_chunk_rpc = off") - require.NoError(t, err) + tk.MustExec(ctx, "set @@tidb_enable_chunk_rpc = off") - _, err = tk.Exec(ctx, "admin check table admin_test") - require.Error(t, err) - require.Equal(t, `[admin:8223]data inconsistency in table: admin_test, index: uk1, handle: 282574488403969, index-values:"handle: 282574488403969, values: [KindInt64 282578800083201 KindInt64 282574488403969]" != record-values:""`, err.Error()) + tk.MustGetErrMsg(ctx, "admin check table admin_test", + `[admin:8223]data inconsistency in table: admin_test, index: uk1, handle: 282574488403969, index-values:"handle: 282574488403969, values: [KindInt64 282578800083201 KindInt64 282574488403969]" != record-values:""`) hook.checkLogCount(t, 1) logEntry := hook.logs[0] logEntry.checkMsg(t, "admin check found data inconsistency") diff --git a/executor/aggfuncs/BUILD.bazel b/executor/aggfuncs/BUILD.bazel index 5c01950eef836..a1d4a57dde1f5 100644 --- a/executor/aggfuncs/BUILD.bazel +++ b/executor/aggfuncs/BUILD.bazel @@ -89,7 +89,7 @@ go_test( embed = [":aggfuncs"], flaky = True, race = "on", - shard_count = 10, + shard_count = 20, deps = [ "//expression", "//expression/aggregation", diff --git a/executor/aggfuncs/builder.go b/executor/aggfuncs/builder.go index 51b72ebfc242b..f215983d3c7e4 100644 --- a/executor/aggfuncs/builder.go +++ b/executor/aggfuncs/builder.go @@ -15,6 +15,7 @@ package aggfuncs import ( + "context" "fmt" "strconv" @@ -462,7 +463,7 @@ func buildGroupConcat(ctx sessionctx.Context, aggFuncDesc *aggregation.AggFuncDe panic(fmt.Sprintf("Error happened when buildGroupConcat: %s", err.Error())) } var s string - s, err = ctx.GetSessionVars().GetSessionOrGlobalSystemVar(variable.GroupConcatMaxLen) + s, err = ctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), variable.GroupConcatMaxLen) if err != nil { panic(fmt.Sprintf("Error happened when buildGroupConcat: no system variable named '%s'", variable.GroupConcatMaxLen)) } diff --git a/executor/aggfuncs/main_test.go b/executor/aggfuncs/main_test.go index 9092f6a465d77..09b07cea808ec 100644 --- a/executor/aggfuncs/main_test.go +++ b/executor/aggfuncs/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/executor/aggregate.go b/executor/aggregate.go index d6ec79412b7f6..30b86164ec371 100644 --- a/executor/aggregate.go +++ b/executor/aggregate.go @@ -244,6 +244,9 @@ func (d *HashAggIntermData) getPartialResultBatch(_ *stmtctx.StatementContext, p // Close implements the Executor Close interface. func (e *HashAggExec) Close() error { + if e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } if e.isUnparallelExec { var firstErr error e.childResult = nil @@ -323,18 +326,19 @@ func (e *HashAggExec) initForUnparallelExec() { failpoint.Inject("ConsumeRandomPanic", nil) e.memTracker.Consume(hack.DefBucketMemoryUsageForMapStrToSlice*(1<")) } func TestIssue12759HashAggCalledByApply(t *testing.T) { @@ -1642,11 +1650,11 @@ func TestIssue26885(t *testing.T) { tk.MustExec("INSERT INTO t1 (c1) VALUES ('');") tk.MustExec("INSERT INTO t1 (c1) VALUES (0);") tk.MustQuery("select * from t1").Check(testkit.Rows("b", "", "a", "", "")) - tk.MustQuery("select c1 + 0 from t1").Check(testkit.Rows("3", "2", "1", "2", "0")) + tk.MustQuery("select c1 + 0 from t1").Sort().Check(testkit.Rows("0", "1", "2", "2", "3")) tk.MustQuery("SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1 order by c1;").Check(testkit.Rows("0 1", "1 1", "2 2", "3 1")) tk.MustExec("alter table t1 add index idx(c1); ") - tk.MustQuery("select c1 + 0 from t1").Check(testkit.Rows("3", "2", "1", "2", "0")) + tk.MustQuery("select c1 + 0 from t1").Sort().Check(testkit.Rows("0", "1", "2", "2", "3")) tk.MustQuery("SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1 order by c1;").Check(testkit.Rows("0 1", "1 1", "2 2", "3 1")) tk.MustExec(`DROP TABLE IF EXISTS t1;`) diff --git a/executor/analyze.go b/executor/analyze.go index 6fccec8a9bf5b..705e6eed6c590 100644 --- a/executor/analyze.go +++ b/executor/analyze.go @@ -20,6 +20,7 @@ import ( "math" "strconv" "strings" + "sync/atomic" "time" "github.com/pingcap/errors" @@ -81,19 +82,89 @@ const ( // Next implements the Executor Next interface. func (e *AnalyzeExec) Next(ctx context.Context, _ *chunk.Chunk) error { + statsHandle := domain.GetDomain(e.ctx).StatsHandle() + var tasks []*analyzeTask + tids := make([]int64, 0) + skipedTables := make([]string, 0) + is := e.ctx.GetInfoSchema().(infoschema.InfoSchema) + for _, task := range e.tasks { + var tableID statistics.AnalyzeTableID + switch task.taskType { + case colTask: + tableID = task.colExec.tableID + case idxTask: + tableID = task.idxExec.tableID + case fastTask: + tableID = task.fastExec.tableID + case pkIncrementalTask: + tableID = task.colIncrementalExec.tableID + case idxIncrementalTask: + tableID = task.idxIncrementalExec.tableID + } + // skip locked tables + if !statsHandle.IsTableLocked(tableID.TableID) { + tasks = append(tasks, task) + } + // generate warning message + dup := false + for _, id := range tids { + if id == tableID.TableID { + dup = true + break + } + } + //avoid generate duplicate tables + if !dup { + if statsHandle.IsTableLocked(tableID.TableID) { + tbl, ok := is.TableByID(tableID.TableID) + if !ok { + return nil + } + skipedTables = append(skipedTables, tbl.Meta().Name.L) + } + tids = append(tids, tableID.TableID) + } + } + + if len(skipedTables) > 0 { + tables := skipedTables[0] + for i, table := range skipedTables { + if i == 0 { + continue + } + tables += ", " + table + } + var msg string + if len(tids) > 1 { + if len(tids) > len(skipedTables) { + msg = "skip analyze locked tables: " + tables + ", other tables will be analyzed" + } else { + msg = "skip analyze locked tables: " + tables + } + } else { + msg = "skip analyze locked table: " + tables + } + + e.ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New(msg)) + } + + if len(tasks) == 0 { + return nil + } + concurrency, err := getBuildStatsConcurrency(e.ctx) if err != nil { return err } - taskCh := make(chan *analyzeTask, len(e.tasks)) - resultsCh := make(chan *statistics.AnalyzeResults, len(e.tasks)) - if len(e.tasks) < concurrency { - concurrency = len(e.tasks) + taskCh := make(chan *analyzeTask, len(tasks)) + resultsCh := make(chan *statistics.AnalyzeResults, len(tasks)) + if len(tasks) < concurrency { + concurrency = len(tasks) } for i := 0; i < concurrency; i++ { e.wg.Run(func() { e.analyzeWorker(taskCh, resultsCh) }) } - for _, task := range e.tasks { + for _, task := range tasks { prepareV2AnalyzeJobInfo(task.colExec, false) AddNewAnalyzeJob(e.ctx, task.job) } @@ -101,7 +172,7 @@ func (e *AnalyzeExec) Next(ctx context.Context, _ *chunk.Chunk) error { dom := domain.GetDomain(e.ctx) dom.SysProcTracker().KillSysProcess(util.GetAutoAnalyzeProcID(dom.ServerID)) }) - for _, task := range e.tasks { + for _, task := range tasks { taskCh <- task } close(taskCh) @@ -112,7 +183,7 @@ func (e *AnalyzeExec) Next(ctx context.Context, _ *chunk.Chunk) error { needGlobalStats := pruneMode == variable.Dynamic globalStatsMap := make(map[globalStatsKey]globalStatsInfo) err = e.handleResultsError(ctx, concurrency, needGlobalStats, globalStatsMap, resultsCh) - for _, task := range e.tasks { + for _, task := range tasks { if task.colExec != nil && task.colExec.memTracker != nil { task.colExec.memTracker.Detach() } @@ -134,7 +205,6 @@ func (e *AnalyzeExec) Next(ctx context.Context, _ *chunk.Chunk) error { if err != nil { e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) } - statsHandle := domain.GetDomain(e.ctx).StatsHandle() if e.ctx.GetSessionVars().InRestrictedSQL { return statsHandle.Update(e.ctx.GetInfoSchema().(infoschema.InfoSchema)) } @@ -188,8 +258,8 @@ func (e *AnalyzeExec) saveV2AnalyzeOpts() error { return nil } -func (e *AnalyzeExec) recordHistoricalStats(tableID int64) error { - statsHandle := domain.GetDomain(e.ctx).StatsHandle() +func recordHistoricalStats(sctx sessionctx.Context, tableID int64) error { + statsHandle := domain.GetDomain(sctx).StatsHandle() historicalStatsEnabled, err := statsHandle.CheckHistoricalStatsEnable() if err != nil { return errors.Errorf("check tidb_enable_historical_stats failed: %v", err) @@ -197,26 +267,33 @@ func (e *AnalyzeExec) recordHistoricalStats(tableID int64) error { if !historicalStatsEnabled { return nil } - - is := domain.GetDomain(e.ctx).InfoSchema() - tbl, existed := is.TableByID(tableID) - if !existed { - return errors.Errorf("cannot get table by id %d", tableID) - } - tblInfo := tbl.Meta() - dbInfo, existed := is.SchemaByTable(tblInfo) - if !existed { - return errors.Errorf("cannot get DBInfo by TableID %d", tableID) - } - if _, err := statsHandle.RecordHistoricalStatsToStorage(dbInfo.Name.O, tblInfo); err != nil { - return errors.Errorf("record table %s.%s's historical stats failed", dbInfo.Name.O, tblInfo.Name.O) - } + historicalStatsWorker := domain.GetDomain(sctx).GetHistoricalStatsWorker() + historicalStatsWorker.SendTblToDumpHistoricalStats(tableID) return nil } // handleResultsError will handle the error fetch from resultsCh and record it in log func (e *AnalyzeExec) handleResultsError(ctx context.Context, concurrency int, needGlobalStats bool, globalStatsMap globalStatsMap, resultsCh <-chan *statistics.AnalyzeResults) error { + partitionStatsConcurrency := e.ctx.GetSessionVars().AnalyzePartitionConcurrency + // If 'partitionStatsConcurrency' > 1, we will try to demand extra session from Domain to save Analyze results in concurrency. + // If there is no extra session we can use, we will save analyze results in single-thread. + if partitionStatsConcurrency > 1 { + dom := domain.GetDomain(e.ctx) + subSctxs := dom.FetchAnalyzeExec(partitionStatsConcurrency) + if len(subSctxs) > 0 { + defer func() { + dom.ReleaseAnalyzeExec(subSctxs) + }() + internalCtx := kv.WithInternalSourceType(ctx, kv.InternalTxnStats) + err := e.handleResultsErrorWithConcurrency(internalCtx, concurrency, needGlobalStats, subSctxs, globalStatsMap, resultsCh) + return err + } + } + + tableIDs := map[int64]struct{}{} + + // save analyze results in single-thread. statsHandle := domain.GetDomain(e.ctx).StatsHandle() panicCnt := 0 var err error @@ -235,40 +312,89 @@ func (e *AnalyzeExec) handleResultsError(ctx context.Context, concurrency int, n finishJobWithLog(e.ctx, results.Job, err) continue } - if results.TableID.IsPartitionTable() && needGlobalStats { - for _, result := range results.Ars { - if result.IsIndex == 0 { - // If it does not belong to the statistics of index, we need to set it to -1 to distinguish. - globalStatsID := globalStatsKey{tableID: results.TableID.TableID, indexID: int64(-1)} - histIDs := make([]int64, 0, len(result.Hist)) - for _, hg := range result.Hist { - // It's normal virtual column, skip. - if hg == nil { - continue - } - histIDs = append(histIDs, hg.ID) - } - globalStatsMap[globalStatsID] = globalStatsInfo{isIndex: result.IsIndex, histIDs: histIDs, statsVersion: results.StatsVer} - } else { - for _, hg := range result.Hist { - globalStatsID := globalStatsKey{tableID: results.TableID.TableID, indexID: hg.ID} - globalStatsMap[globalStatsID] = globalStatsInfo{isIndex: result.IsIndex, histIDs: []int64{hg.ID}, statsVersion: results.StatsVer} - } - } - } - } - if err1 := statsHandle.SaveTableStatsToStorage(results, results.TableID.IsPartitionTable(), e.ctx.GetSessionVars().EnableAnalyzeSnapshot); err1 != nil { + handleGlobalStats(needGlobalStats, globalStatsMap, results) + tableIDs[results.TableID.GetStatisticsID()] = struct{}{} + + if err1 := statsHandle.SaveTableStatsToStorage(results, e.ctx.GetSessionVars().EnableAnalyzeSnapshot, handle.StatsMetaHistorySourceAnalyze); err1 != nil { + tableID := results.TableID.TableID err = err1 - logutil.Logger(ctx).Error("save table stats to storage failed", zap.Error(err)) + logutil.Logger(ctx).Error("save table stats to storage failed", zap.Error(err), zap.Int64("tableID", tableID)) finishJobWithLog(e.ctx, results.Job, err) } else { finishJobWithLog(e.ctx, results.Job, nil) - // Dump stats to historical storage. - if err := e.recordHistoricalStats(results.TableID.TableID); err != nil { - logutil.BgLogger().Error("record historical stats failed", zap.Error(err)) - } } invalidInfoSchemaStatCache(results.TableID.GetStatisticsID()) + if atomic.LoadUint32(&e.ctx.GetSessionVars().Killed) == 1 { + finishJobWithLog(e.ctx, results.Job, ErrQueryInterrupted) + return errors.Trace(ErrQueryInterrupted) + } + } + // Dump stats to historical storage. + for tableID := range tableIDs { + if err := recordHistoricalStats(e.ctx, tableID); err != nil { + logutil.BgLogger().Error("record historical stats failed", zap.Error(err)) + } + } + + return err +} + +func (e *AnalyzeExec) handleResultsErrorWithConcurrency(ctx context.Context, statsConcurrency int, needGlobalStats bool, + subSctxs []sessionctx.Context, + globalStatsMap globalStatsMap, resultsCh <-chan *statistics.AnalyzeResults) error { + partitionStatsConcurrency := len(subSctxs) + + var wg util.WaitGroupWrapper + saveResultsCh := make(chan *statistics.AnalyzeResults, partitionStatsConcurrency) + errCh := make(chan error, partitionStatsConcurrency) + for i := 0; i < partitionStatsConcurrency; i++ { + worker := newAnalyzeSaveStatsWorker(saveResultsCh, subSctxs[i], errCh, &e.ctx.GetSessionVars().Killed) + ctx1 := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + wg.Run(func() { + worker.run(ctx1, e.ctx.GetSessionVars().EnableAnalyzeSnapshot) + }) + } + tableIDs := map[int64]struct{}{} + panicCnt := 0 + var err error + for panicCnt < statsConcurrency { + if atomic.LoadUint32(&e.ctx.GetSessionVars().Killed) == 1 { + close(saveResultsCh) + return errors.Trace(ErrQueryInterrupted) + } + results, ok := <-resultsCh + if !ok { + break + } + if results.Err != nil { + err = results.Err + if isAnalyzeWorkerPanic(err) { + panicCnt++ + } else { + logutil.Logger(ctx).Error("analyze failed", zap.Error(err)) + } + finishJobWithLog(e.ctx, results.Job, err) + continue + } + handleGlobalStats(needGlobalStats, globalStatsMap, results) + tableIDs[results.TableID.GetStatisticsID()] = struct{}{} + saveResultsCh <- results + } + close(saveResultsCh) + wg.Wait() + close(errCh) + if len(errCh) > 0 { + errMsg := make([]string, 0) + for err1 := range errCh { + errMsg = append(errMsg, err1.Error()) + } + err = errors.New(strings.Join(errMsg, ",")) + } + for tableID := range tableIDs { + // Dump stats to historical storage. + if err := recordHistoricalStats(e.ctx, tableID); err != nil { + logutil.BgLogger().Error("record historical stats failed", zap.Error(err)) + } } return err } @@ -381,6 +507,40 @@ func UpdateAnalyzeJob(sctx sessionctx.Context, job *statistics.AnalyzeJob, rowCo } } +// FinishAnalyzeMergeJob finishes analyze merge job +func FinishAnalyzeMergeJob(sctx sessionctx.Context, job *statistics.AnalyzeJob, analyzeErr error) { + if job == nil || job.ID == nil { + return + } + job.EndTime = time.Now() + var sql string + var args []interface{} + if analyzeErr != nil { + failReason := analyzeErr.Error() + const textMaxLength = 65535 + if len(failReason) > textMaxLength { + failReason = failReason[:textMaxLength] + } + sql = "UPDATE mysql.analyze_jobs SET end_time = CONVERT_TZ(%?, '+00:00', @@TIME_ZONE), state = %?, fail_reason = %?, process_id = NULL WHERE id = %?" + args = []interface{}{job.EndTime.UTC().Format(types.TimeFormat), statistics.AnalyzeFailed, failReason, *job.ID} + } else { + sql = "UPDATE mysql.analyze_jobs SET end_time = CONVERT_TZ(%?, '+00:00', @@TIME_ZONE), state = %?, process_id = NULL WHERE id = %?" + args = []interface{}{job.EndTime.UTC().Format(types.TimeFormat), statistics.AnalyzeFinished, *job.ID} + } + exec := sctx.(sqlexec.RestrictedSQLExecutor) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + _, _, err := exec.ExecRestrictedSQL(ctx, []sqlexec.OptionFuncAlias{sqlexec.ExecOptionUseSessionPool}, sql, args...) + if err != nil { + var state string + if analyzeErr != nil { + state = statistics.AnalyzeFailed + } else { + state = statistics.AnalyzeFinished + } + logutil.BgLogger().Warn("failed to update analyze job", zap.String("update", fmt.Sprintf("%s->%s", statistics.AnalyzeRunning, state)), zap.Error(err)) + } +} + // FinishAnalyzeJob updates the state of the analyze job to finished/failed according to `meetError` and sets the end time. func FinishAnalyzeJob(sctx sessionctx.Context, job *statistics.AnalyzeJob, analyzeErr error) { if job == nil || job.ID == nil { @@ -434,3 +594,28 @@ func finishJobWithLog(sctx sessionctx.Context, job *statistics.AnalyzeJob, analy zap.String("cost", job.EndTime.Sub(job.StartTime).String())) } } + +func handleGlobalStats(needGlobalStats bool, globalStatsMap globalStatsMap, results *statistics.AnalyzeResults) { + if results.TableID.IsPartitionTable() && needGlobalStats { + for _, result := range results.Ars { + if result.IsIndex == 0 { + // If it does not belong to the statistics of index, we need to set it to -1 to distinguish. + globalStatsID := globalStatsKey{tableID: results.TableID.TableID, indexID: int64(-1)} + histIDs := make([]int64, 0, len(result.Hist)) + for _, hg := range result.Hist { + // It's normal virtual column, skip. + if hg == nil { + continue + } + histIDs = append(histIDs, hg.ID) + } + globalStatsMap[globalStatsID] = globalStatsInfo{isIndex: result.IsIndex, histIDs: histIDs, statsVersion: results.StatsVer} + } else { + for _, hg := range result.Hist { + globalStatsID := globalStatsKey{tableID: results.TableID.TableID, indexID: hg.ID} + globalStatsMap[globalStatsID] = globalStatsInfo{isIndex: result.IsIndex, histIDs: []int64{hg.ID}, statsVersion: results.StatsVer} + } + } + } + } +} diff --git a/executor/analyze_col.go b/executor/analyze_col.go index a846816b18428..dc5194e9f8fa9 100644 --- a/executor/analyze_col.go +++ b/executor/analyze_col.go @@ -123,6 +123,7 @@ func (e *AnalyzeColumnsExec) buildResp(ranges []*ranger.Range) (distsql.SelectRe SetKeepOrder(true). SetConcurrency(e.concurrency). SetMemTracker(e.memTracker). + SetResourceGroupName(e.ctx.GetSessionVars().ResourceGroupName). Build() if err != nil { return nil, err diff --git a/executor/analyze_col_v2.go b/executor/analyze_col_v2.go index 68a02485c0048..1d9913d5f23e3 100644 --- a/executor/analyze_col_v2.go +++ b/executor/analyze_col_v2.go @@ -32,6 +32,7 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" @@ -187,7 +188,7 @@ func (e *AnalyzeColumnsExecV2) decodeSampleDataWithVirtualColumn( } } } - err := FillVirtualColumnValue(fieldTps, virtualColIdx, schema, e.colsInfo, e.ctx, chk) + err := table.FillVirtualColumnValue(fieldTps, virtualColIdx, schema.Columns, e.colsInfo, e.ctx, chk) if err != nil { return err } @@ -199,6 +200,27 @@ func (e *AnalyzeColumnsExecV2) decodeSampleDataWithVirtualColumn( return nil } +func printAnalyzeMergeCollectorLog(oldRootCount, newRootCount, subCount, tableID, partitionID int64, isPartition bool, info string, index int) { + if index < 0 { + logutil.BgLogger().Debug(info, + zap.Int64("tableID", tableID), + zap.Int64("partitionID", partitionID), + zap.Bool("isPartitionTable", isPartition), + zap.Int64("oldRootCount", oldRootCount), + zap.Int64("newRootCount", newRootCount), + zap.Int64("subCount", subCount)) + } else { + logutil.BgLogger().Debug(info, + zap.Int64("tableID", tableID), + zap.Int64("partitionID", partitionID), + zap.Bool("isPartitionTable", isPartition), + zap.Int64("oldRootCount", oldRootCount), + zap.Int64("newRootCount", newRootCount), + zap.Int64("subCount", subCount), + zap.Int("subCollectorIndex", index)) + } +} + func (e *AnalyzeColumnsExecV2) buildSamplingStats( ranges []*ranger.Range, needExtStats bool, @@ -235,7 +257,7 @@ func (e *AnalyzeColumnsExecV2) buildSamplingStats( e.samplingMergeWg = &util.WaitGroupWrapper{} e.samplingMergeWg.Add(statsConcurrency) for i := 0; i < statsConcurrency; i++ { - go e.subMergeWorker(mergeResultCh, mergeTaskCh, l, i == 0) + go e.subMergeWorker(mergeResultCh, mergeTaskCh, l, i) } if err = readDataAndSendTask(e.ctx, e.resultHandler, mergeTaskCh, e.memTracker); err != nil { return 0, nil, nil, nil, nil, getAnalyzePanicErr(err) @@ -255,7 +277,12 @@ func (e *AnalyzeColumnsExecV2) buildSamplingStats( continue } oldRootCollectorSize := rootRowCollector.Base().MemSize + oldRootCollectorCount := rootRowCollector.Base().Count rootRowCollector.MergeCollector(mergeResult.collector) + newRootCollectorCount := rootRowCollector.Base().Count + printAnalyzeMergeCollectorLog(oldRootCollectorCount, newRootCollectorCount, + mergeResult.collector.Base().Count, e.tableID.TableID, e.tableID.PartitionID, e.tableID.IsPartitionTable(), + "merge subMergeWorker in AnalyzeColumnsExecV2", -1) e.memTracker.Consume(rootRowCollector.Base().MemSize - oldRootCollectorSize - mergeResult.collector.Base().MemSize) } defer e.memTracker.Release(rootRowCollector.Base().MemSize) @@ -544,7 +571,8 @@ func (e *AnalyzeColumnsExecV2) buildSubIndexJobForSpecialIndex(indexInfos []*mod return tasks } -func (e *AnalyzeColumnsExecV2) subMergeWorker(resultCh chan<- *samplingMergeResult, taskCh <-chan []byte, l int, isClosedChanThread bool) { +func (e *AnalyzeColumnsExecV2) subMergeWorker(resultCh chan<- *samplingMergeResult, taskCh <-chan []byte, l int, index int) { + isClosedChanThread := index == 0 defer func() { if r := recover(); r != nil { logutil.BgLogger().Error("analyze worker panicked", zap.Any("recover", r), zap.Stack("stack")) @@ -567,6 +595,13 @@ func (e *AnalyzeColumnsExecV2) subMergeWorker(resultCh chan<- *samplingMergeResu failpoint.Inject("mockAnalyzeSamplingMergeWorkerPanic", func() { panic("failpoint triggered") }) + failpoint.Inject("mockAnalyzeMergeWorkerSlowConsume", func(val failpoint.Value) { + times := val.(int) + for i := 0; i < times; i++ { + e.memTracker.Consume(5 << 20) + time.Sleep(100 * time.Millisecond) + } + }) retCollector := statistics.NewRowSampleCollector(int(e.analyzePB.ColReq.SampleSize), e.analyzePB.ColReq.GetSampleRate(), l) for i := 0; i < l; i++ { retCollector.Base().FMSketches = append(retCollector.Base().FMSketches, statistics.NewFMSketch(maxSketchSize)) @@ -589,7 +624,12 @@ func (e *AnalyzeColumnsExecV2) subMergeWorker(resultCh chan<- *samplingMergeResu subCollector.Base().FromProto(colResp.RowCollector, e.memTracker) UpdateAnalyzeJob(e.ctx, e.job, subCollector.Base().Count) oldRetCollectorSize := retCollector.Base().MemSize + oldRetCollectorCount := retCollector.Base().Count retCollector.MergeCollector(subCollector) + newRetCollectorCount := retCollector.Base().Count + printAnalyzeMergeCollectorLog(oldRetCollectorCount, newRetCollectorCount, subCollector.Base().Count, + e.tableID.TableID, e.tableID.PartitionID, e.TableID.IsPartitionTable(), + "merge subCollector in concurrency in AnalyzeColumnsExecV2", index) newRetCollectorSize := retCollector.Base().MemSize subCollectorSize := subCollector.Base().MemSize e.memTracker.Consume(newRetCollectorSize - oldRetCollectorSize - subCollectorSize) diff --git a/executor/analyze_fast.go b/executor/analyze_fast.go index 5917a5b336ae0..b9dcc5d55ee97 100644 --- a/executor/analyze_fast.go +++ b/executor/analyze_fast.go @@ -404,6 +404,7 @@ func (e *AnalyzeFastExec) handleScanTasks(bo *tikv.Backoffer) (keysSize int, err snapshot.SetOption(kv.ReplicaRead, kv.ReplicaReadFollower) } setOptionForTopSQL(e.ctx.GetSessionVars().StmtCtx, snapshot) + snapshot.SetOption(kv.ResourceGroupName, e.ctx.GetSessionVars().ResourceGroupName) for _, t := range e.scanTasks { iter, err := snapshot.Iter(kv.Key(t.StartKey), kv.Key(t.EndKey)) if err != nil { @@ -430,6 +431,7 @@ func (e *AnalyzeFastExec) handleSampTasks(workID int, step uint32, err *error) { } snapshot.SetOption(kv.NotFillCache, true) snapshot.SetOption(kv.Priority, kv.PriorityLow) + snapshot.SetOption(kv.ResourceGroupName, e.ctx.GetSessionVars().ResourceGroupName) setOptionForTopSQL(e.ctx.GetSessionVars().StmtCtx, snapshot) readReplicaType := e.ctx.GetSessionVars().GetReplicaRead() if readReplicaType.IsFollowerRead() { diff --git a/executor/analyze_global_stats.go b/executor/analyze_global_stats.go index c9ff6217a195c..e8f8d53b8adbf 100644 --- a/executor/analyze_global_stats.go +++ b/executor/analyze_global_stats.go @@ -16,10 +16,12 @@ package executor import ( "context" + "fmt" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/statistics/handle" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/logutil" "go.uber.org/zap" @@ -52,42 +54,85 @@ func (e *AnalyzeExec) handleGlobalStats(ctx context.Context, needGlobalStats boo globalStatsTableIDs[globalStatsID.tableID] = struct{}{} } statsHandle := domain.GetDomain(e.ctx).StatsHandle() + tableIDs := map[int64]struct{}{} for tableID := range globalStatsTableIDs { + tableIDs[tableID] = struct{}{} tableAllPartitionStats := make(map[int64]*statistics.Table) for globalStatsID, info := range globalStatsMap { if globalStatsID.tableID != tableID { continue } - globalOpts := e.opts - if e.OptionsMap != nil { - if v2Options, ok := e.OptionsMap[globalStatsID.tableID]; ok { - globalOpts = v2Options.FilledOpts + job := e.newAnalyzeHandleGlobalStatsJob(globalStatsID) + AddNewAnalyzeJob(e.ctx, job) + StartAnalyzeJob(e.ctx, job) + mergeStatsErr := func() error { + globalOpts := e.opts + if e.OptionsMap != nil { + if v2Options, ok := e.OptionsMap[globalStatsID.tableID]; ok { + globalOpts = v2Options.FilledOpts + } } - } - globalStats, err := statsHandle.MergePartitionStats2GlobalStatsByTableID(e.ctx, globalOpts, e.ctx.GetInfoSchema().(infoschema.InfoSchema), - globalStatsID.tableID, info.isIndex, info.histIDs, - tableAllPartitionStats) - if err != nil { - if types.ErrPartitionStatsMissing.Equal(err) || types.ErrPartitionColumnStatsMissing.Equal(err) { - // When we find some partition-level stats are missing, we need to report warning. - e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) - continue - } - return err - } - for i := 0; i < globalStats.Num; i++ { - hg, cms, topN := globalStats.Hg[i], globalStats.Cms[i], globalStats.TopN[i] - // fms for global stats doesn't need to dump to kv. - err = statsHandle.SaveStatsToStorage(globalStatsID.tableID, globalStats.Count, info.isIndex, hg, cms, topN, info.statsVersion, 1, true) + globalStats, err := statsHandle.MergePartitionStats2GlobalStatsByTableID(e.ctx, globalOpts, e.ctx.GetInfoSchema().(infoschema.InfoSchema), + globalStatsID.tableID, info.isIndex, info.histIDs, + tableAllPartitionStats) if err != nil { - logutil.Logger(ctx).Error("save global-level stats to storage failed", zap.Error(err)) + logutil.BgLogger().Error("merge global stats failed", + zap.String("info", job.JobInfo), zap.Error(err), zap.Int64("tableID", tableID)) + if types.ErrPartitionStatsMissing.Equal(err) || types.ErrPartitionColumnStatsMissing.Equal(err) { + // When we find some partition-level stats are missing, we need to report warning. + e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) + } + return err } - // Dump stats to historical storage. - if err := e.recordHistoricalStats(globalStatsID.tableID); err != nil { - logutil.BgLogger().Error("record historical stats failed", zap.Error(err)) + for i := 0; i < globalStats.Num; i++ { + hg, cms, topN := globalStats.Hg[i], globalStats.Cms[i], globalStats.TopN[i] + // fms for global stats doesn't need to dump to kv. + err = statsHandle.SaveStatsToStorage(globalStatsID.tableID, + globalStats.Count, + globalStats.ModifyCount, + info.isIndex, + hg, + cms, + topN, + info.statsVersion, + 1, + true, + handle.StatsMetaHistorySourceAnalyze, + ) + if err != nil { + logutil.Logger(ctx).Error("save global-level stats to storage failed", zap.String("info", job.JobInfo), + zap.Int64("histID", hg.ID), zap.Error(err), zap.Int64("tableID", tableID)) + } } - } + return err + }() + FinishAnalyzeMergeJob(e.ctx, job, mergeStatsErr) + } + } + for tableID := range tableIDs { + // Dump stats to historical storage. + if err := recordHistoricalStats(e.ctx, tableID); err != nil { + logutil.BgLogger().Error("record historical stats failed", zap.Error(err)) } } return nil } + +func (e *AnalyzeExec) newAnalyzeHandleGlobalStatsJob(key globalStatsKey) *statistics.AnalyzeJob { + dom := domain.GetDomain(e.ctx) + is := dom.InfoSchema() + table, _ := is.TableByID(key.tableID) + db, _ := is.SchemaByTable(table.Meta()) + dbName := db.Name.String() + tableName := table.Meta().Name.String() + jobInfo := fmt.Sprintf("merge global stats for %v.%v columns", dbName, tableName) + if key.indexID != -1 { + idxName := table.Meta().FindIndexNameByID(key.indexID) + jobInfo = fmt.Sprintf("merge global stats for %v.%v's index %v", dbName, tableName, idxName) + } + return &statistics.AnalyzeJob{ + DBName: db.Name.String(), + TableName: table.Meta().Name.String(), + JobInfo: jobInfo, + } +} diff --git a/executor/analyze_idx.go b/executor/analyze_idx.go index 2ac3bce77c139..f89d804788edd 100644 --- a/executor/analyze_idx.go +++ b/executor/analyze_idx.go @@ -155,6 +155,7 @@ func (e *AnalyzeIndexExec) fetchAnalyzeResult(ranges []*ranger.Range, isNullRang SetStartTS(startTS). SetKeepOrder(true). SetConcurrency(e.concurrency). + SetResourceGroupName(e.ctx.GetSessionVars().ResourceGroupName). Build() if err != nil { return err diff --git a/executor/analyze_test.go b/executor/analyze_test.go index 2139816195b5f..a6cdea833df50 100644 --- a/executor/analyze_test.go +++ b/executor/analyze_test.go @@ -17,6 +17,7 @@ package executor_test import ( "fmt" "io/ioutil" + "strconv" "strings" "sync/atomic" "testing" @@ -338,3 +339,102 @@ func TestAnalyzePartitionTableForFloat(t *testing.T) { } tk.MustExec("analyze table t1") } + +func TestAnalyzePartitionTableByConcurrencyInDynamic(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@tidb_partition_prune_mode='dynamic'") + tk.MustExec("use test") + tk.MustExec("create table t(id int) partition by hash(id) partitions 4") + testcases := []struct { + concurrency string + }{ + { + concurrency: "1", + }, + { + concurrency: "2", + }, + { + concurrency: "3", + }, + { + concurrency: "4", + }, + { + concurrency: "5", + }, + } + // assert empty table + for _, tc := range testcases { + concurrency := tc.concurrency + fmt.Println("testcase ", concurrency) + tk.MustExec(fmt.Sprintf("set @@tidb_merge_partition_stats_concurrency=%v", concurrency)) + tk.MustQuery("select @@tidb_merge_partition_stats_concurrency").Check(testkit.Rows(concurrency)) + tk.MustExec(fmt.Sprintf("set @@tidb_analyze_partition_concurrency=%v", concurrency)) + tk.MustQuery("select @@tidb_analyze_partition_concurrency").Check(testkit.Rows(concurrency)) + + tk.MustExec("analyze table t") + tk.MustQuery("show stats_topn where partition_name = 'global' and table_name = 't'") + } + + for i := 1; i <= 500; i++ { + for j := 1; j <= 20; j++ { + tk.MustExec(fmt.Sprintf("insert into t (id) values (%v)", j)) + } + } + var expected [][]interface{} + for i := 1; i <= 20; i++ { + expected = append(expected, []interface{}{ + strconv.FormatInt(int64(i), 10), "500", + }) + } + testcases = []struct { + concurrency string + }{ + { + concurrency: "1", + }, + { + concurrency: "2", + }, + { + concurrency: "3", + }, + { + concurrency: "4", + }, + { + concurrency: "5", + }, + } + for _, tc := range testcases { + concurrency := tc.concurrency + fmt.Println("testcase ", concurrency) + tk.MustExec(fmt.Sprintf("set @@tidb_merge_partition_stats_concurrency=%v", concurrency)) + tk.MustQuery("select @@tidb_merge_partition_stats_concurrency").Check(testkit.Rows(concurrency)) + tk.MustExec("analyze table t") + tk.MustQuery("show stats_topn where partition_name = 'global' and table_name = 't'").CheckAt([]int{5, 6}, expected) + } +} + +func TestMergeGlobalStatsWithUnAnalyzedPartition(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set tidb_partition_prune_mode=dynamic;") + tk.MustExec("CREATE TABLE `t` ( `id` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL ) PARTITION BY RANGE (`id`) (PARTITION `p0` VALUES LESS THAN (3), PARTITION `p1` VALUES LESS THAN (7), PARTITION `p2` VALUES LESS THAN (11));") + tk.MustExec("insert into t values (1,1,1,1),(2,2,2,2),(4,4,4,4),(5,5,5,5),(6,6,6,6),(8,8,8,8),(9,9,9,9);") + tk.MustExec("create index idxa on t (a);") + tk.MustExec("create index idxb on t (b);") + tk.MustExec("create index idxc on t (c);") + tk.MustExec("analyze table t partition p0 index idxa;") + tk.MustExec("analyze table t partition p1 index idxb;") + tk.MustExec("analyze table t partition p2 index idxc;") + tk.MustQuery("show warnings").Check(testkit.Rows( + "Warning 1105 The version 2 would collect all statistics not only the selected indexes", + "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p2")) + tk.MustExec("analyze table t partition p0;") + tk.MustQuery("show warnings").Check(testkit.Rows( + "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p0")) +} diff --git a/executor/analyze_utils.go b/executor/analyze_utils.go index b4ec10a104ac5..cdf47373d29f0 100644 --- a/executor/analyze_utils.go +++ b/executor/analyze_utils.go @@ -15,7 +15,9 @@ package executor import ( + "context" "strconv" + "strings" "sync" "github.com/pingcap/errors" @@ -23,12 +25,13 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/util/memory" "go.uber.org/atomic" ) func getBuildStatsConcurrency(ctx sessionctx.Context) (int, error) { sessionVars := ctx.GetSessionVars() - concurrency, err := sessionVars.GetSessionOrGlobalSystemVar(variable.TiDBBuildStatsConcurrency) + concurrency, err := sessionVars.GetSessionOrGlobalSystemVar(context.Background(), variable.TiDBBuildStatsConcurrency) if err != nil { return 0, err } @@ -44,8 +47,13 @@ func isAnalyzeWorkerPanic(err error) bool { } func getAnalyzePanicErr(r interface{}) error { - if msg, ok := r.(string); ok && msg == globalPanicAnalyzeMemoryExceed { - return errAnalyzeOOM + if msg, ok := r.(string); ok { + if msg == globalPanicAnalyzeMemoryExceed { + return errAnalyzeOOM + } + if strings.Contains(msg, memory.PanicMemoryExceed) { + return errors.Errorf(msg, errAnalyzeOOM) + } } if err, ok := r.(error); ok { if err.Error() == globalPanicAnalyzeMemoryExceed { diff --git a/executor/analyze_worker.go b/executor/analyze_worker.go new file mode 100644 index 0000000000000..688f89f5a120d --- /dev/null +++ b/executor/analyze_worker.go @@ -0,0 +1,75 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package executor + +import ( + "context" + "sync/atomic" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/statistics/handle" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" +) + +type analyzeSaveStatsWorker struct { + resultsCh <-chan *statistics.AnalyzeResults + sctx sessionctx.Context + errCh chan<- error + killed *uint32 +} + +func newAnalyzeSaveStatsWorker( + resultsCh <-chan *statistics.AnalyzeResults, + sctx sessionctx.Context, + errCh chan<- error, + killed *uint32) *analyzeSaveStatsWorker { + worker := &analyzeSaveStatsWorker{ + resultsCh: resultsCh, + sctx: sctx, + errCh: errCh, + killed: killed, + } + return worker +} + +func (worker *analyzeSaveStatsWorker) run(ctx context.Context, analyzeSnapshot bool) { + defer func() { + if r := recover(); r != nil { + logutil.BgLogger().Error("analyze save stats worker panicked", zap.Any("recover", r), zap.Stack("stack")) + worker.errCh <- getAnalyzePanicErr(r) + } + }() + for results := range worker.resultsCh { + if atomic.LoadUint32(worker.killed) == 1 { + worker.errCh <- errors.Trace(ErrQueryInterrupted) + return + } + err := handle.SaveTableStatsToStorage(worker.sctx, results, analyzeSnapshot, handle.StatsMetaHistorySourceAnalyze) + if err != nil { + logutil.Logger(ctx).Error("save table stats to storage failed", zap.Error(err)) + finishJobWithLog(worker.sctx, results.Job, err) + worker.errCh <- err + } else { + finishJobWithLog(worker.sctx, results.Job, nil) + } + invalidInfoSchemaStatCache(results.TableID.GetStatisticsID()) + if err != nil { + return + } + } +} diff --git a/executor/analyzetest/BUILD.bazel b/executor/analyzetest/BUILD.bazel index 53126213363a5..3112abe57c00f 100644 --- a/executor/analyzetest/BUILD.bazel +++ b/executor/analyzetest/BUILD.bazel @@ -8,7 +8,6 @@ go_test( "main_test.go", ], flaky = True, - race = "on", shard_count = 50, deps = [ "//domain", @@ -30,6 +29,7 @@ go_test( "//tablecodec", "//testkit", "//types", + "//util", "//util/codec", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", diff --git a/executor/analyzetest/analyze_test.go b/executor/analyzetest/analyze_test.go index 9274fd62b423a..843200fea6cf9 100644 --- a/executor/analyzetest/analyze_test.go +++ b/executor/analyzetest/analyze_test.go @@ -16,8 +16,8 @@ package analyzetest import ( "context" - "encoding/json" "fmt" + "runtime" "strconv" "strings" "testing" @@ -44,6 +44,7 @@ import ( "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/codec" "github.com/stretchr/testify/require" "github.com/tikv/client-go/v2/testutils" @@ -975,6 +976,7 @@ func TestSavedAnalyzeOptions(t *testing.T) { tk.MustExec("use test") tk.MustExec("set @@session.tidb_analyze_version = 2") + tk.MustExec("set @@session.tidb_stats_load_sync_wait = 20000") // to stabilise test tk.MustExec("create table t(a int, b int, c int, primary key(a), key idx(b))") tk.MustExec("insert into t values (1,1,1),(2,1,2),(3,1,3),(4,1,4),(5,1,5),(6,1,6),(7,7,7),(8,8,8),(9,9,9)") @@ -1062,6 +1064,7 @@ func TestSavedPartitionAnalyzeOptions(t *testing.T) { tk.MustExec("use test") tk.MustExec("set @@session.tidb_analyze_version = 2") + tk.MustExec("set @@session.tidb_stats_load_sync_wait = 20000") // to stabilise test tk.MustExec("set @@session.tidb_partition_prune_mode = 'static'") createTable := `CREATE TABLE t (a int, b int, c varchar(10), primary key(a), index idx(b)) PARTITION BY RANGE ( a ) ( @@ -2161,102 +2164,6 @@ func TestAnalyzeColumnsErrorAndWarning(t *testing.T) { } } -func TestRecordHistoryStatsAfterAnalyze(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@tidb_analyze_version = 2") - tk.MustExec("set global tidb_enable_historical_stats = 0") - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t(a int, b varchar(10))") - - h := dom.StatsHandle() - is := dom.InfoSchema() - tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) - - // 1. switch off the tidb_enable_historical_stats, and there is no records in table `mysql.stats_history` - rows := tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", tableInfo.Meta().ID)).Rows() - num, _ := strconv.Atoi(rows[0][0].(string)) - require.Equal(t, num, 0) - - tk.MustExec("analyze table t with 2 topn") - rows = tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", tableInfo.Meta().ID)).Rows() - num, _ = strconv.Atoi(rows[0][0].(string)) - require.Equal(t, num, 0) - - // 2. switch on the tidb_enable_historical_stats and do analyze - tk.MustExec("set global tidb_enable_historical_stats = 1") - defer tk.MustExec("set global tidb_enable_historical_stats = 0") - tk.MustExec("analyze table t with 2 topn") - rows = tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", tableInfo.Meta().ID)).Rows() - num, _ = strconv.Atoi(rows[0][0].(string)) - require.GreaterOrEqual(t, num, 1) - - // 3. dump current stats json - dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil) - require.NoError(t, err) - jsOrigin, _ := json.Marshal(dumpJSONTable) - - // 4. get the historical stats json - rows = tk.MustQuery(fmt.Sprintf("select * from mysql.stats_history where table_id = '%d' and create_time = ("+ - "select create_time from mysql.stats_history where table_id = '%d' order by create_time desc limit 1) "+ - "order by seq_no", tableInfo.Meta().ID, tableInfo.Meta().ID)).Rows() - num = len(rows) - require.GreaterOrEqual(t, num, 1) - data := make([][]byte, num) - for i, row := range rows { - data[i] = []byte(row[1].(string)) - } - jsonTbl, err := handle.BlocksToJSONTable(data) - require.NoError(t, err) - jsCur, err := json.Marshal(jsonTbl) - require.NoError(t, err) - // 5. historical stats must be equal to the current stats - require.JSONEq(t, string(jsOrigin), string(jsCur)) -} - -func TestRecordHistoryStatsMetaAfterAnalyze(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@tidb_analyze_version = 2") - tk.MustExec("set global tidb_enable_historical_stats = 0") - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t(a int, b int)") - tk.MustExec("analyze table test.t") - - h := dom.StatsHandle() - is := dom.InfoSchema() - tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) - - // 1. switch off the tidb_enable_historical_stats, and there is no record in table `mysql.stats_meta_history` - tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d'", tableInfo.Meta().ID)).Check(testkit.Rows("0")) - // insert demo tuples, and there is no record either. - insertNums := 5 - for i := 0; i < insertNums; i++ { - tk.MustExec("insert into test.t (a,b) values (1,1), (2,2), (3,3)") - err := h.DumpStatsDeltaToKV(handle.DumpDelta) - require.NoError(t, err) - } - tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d'", tableInfo.Meta().ID)).Check(testkit.Rows("0")) - - // 2. switch on the tidb_enable_historical_stats and insert tuples to produce count/modifyCount delta change. - tk.MustExec("set global tidb_enable_historical_stats = 1") - defer tk.MustExec("set global tidb_enable_historical_stats = 0") - - for i := 0; i < insertNums; i++ { - tk.MustExec("insert into test.t (a,b) values (1,1), (2,2), (3,3)") - err := h.DumpStatsDeltaToKV(handle.DumpDelta) - require.NoError(t, err) - } - tk.MustQuery(fmt.Sprintf("select modify_count, count from mysql.stats_meta_history where table_id = '%d' order by create_time", tableInfo.Meta().ID)).Sort().Check( - testkit.Rows("18 18", "21 21", "24 24", "27 27", "30 30")) -} - func checkAnalyzeStatus(t *testing.T, tk *testkit.TestKit, jobInfo, status, failReason, comment string, timeLimit int64) { rows := tk.MustQuery("show analyze status where table_schema = 'test' and table_name = 't' and partition_name = ''").Rows() require.Equal(t, 1, len(rows), comment) @@ -2310,7 +2217,11 @@ func testKillAutoAnalyze(t *testing.T, ver int) { jobInfo += "table all columns with 256 buckets, 500 topn, 1 samplerate" } // kill auto analyze when it is pending/running/finished - for _, status := range []string{"pending", "running", "finished"} { + for _, status := range []string{ + "pending", + "running", + "finished", + } { func() { comment := fmt.Sprintf("kill %v analyze job", status) tk.MustExec("delete from mysql.analyze_jobs") @@ -2576,6 +2487,7 @@ func TestAnalyzePartitionTableWithDynamicMode(t *testing.T) { tk.MustExec("use test") tk.MustExec("set @@session.tidb_analyze_version = 2") + tk.MustExec("set @@session.tidb_stats_load_sync_wait = 20000") // to stabilise test tk.MustExec("set @@session.tidb_partition_prune_mode = 'dynamic'") createTable := `CREATE TABLE t (a int, b int, c varchar(10), d int, primary key(a), index idx(b)) PARTITION BY RANGE ( a ) ( @@ -2669,6 +2581,7 @@ func TestAnalyzePartitionTableStaticToDynamic(t *testing.T) { tk.MustExec("use test") tk.MustExec("set @@session.tidb_analyze_version = 2") + tk.MustExec("set @@session.tidb_stats_load_sync_wait = 20000") // to stabilise test tk.MustExec("set @@session.tidb_partition_prune_mode = 'static'") createTable := `CREATE TABLE t (a int, b int, c varchar(10), d int, primary key(a), index idx(b)) PARTITION BY RANGE ( a ) ( @@ -2828,8 +2741,8 @@ PARTITION BY RANGE ( a ) ( tk.MustQuery("show warnings").Sort().Check(testkit.Rows( "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p0", "Warning 1105 Ignore columns and options when analyze partition in dynamic mode", - "Warning 8131 Build table: `t` global-level stats failed due to missing partition-level stats", - "Warning 8131 Build table: `t` index: `idx` global-level stats failed due to missing partition-level stats", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", )) tk.MustQuery("select * from t where a > 1 and b > 1 and c > 1 and d > 1") require.NoError(t, h.LoadNeededHistograms()) @@ -2841,8 +2754,8 @@ PARTITION BY RANGE ( a ) ( tk.MustExec("analyze table t partition p0") tk.MustQuery("show warnings").Sort().Check(testkit.Rows( "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p0", - "Warning 8131 Build table: `t` global-level stats failed due to missing partition-level stats", - "Warning 8131 Build table: `t` index: `idx` global-level stats failed due to missing partition-level stats", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", )) tbl = h.GetTableStats(tableInfo) require.Equal(t, tbl.Version, lastVersion) // global stats not updated @@ -2860,6 +2773,7 @@ func TestAnalyzePartitionStaticToDynamic(t *testing.T) { tk.MustExec("use test") tk.MustExec("set @@session.tidb_analyze_version = 2") + tk.MustExec("set @@session.tidb_stats_load_sync_wait = 20000") // to stabilise test createTable := `CREATE TABLE t (a int, b int, c varchar(10), d int, primary key(a), index idx(b)) PARTITION BY RANGE ( a ) ( PARTITION p0 VALUES LESS THAN (10), @@ -2895,7 +2809,7 @@ PARTITION BY RANGE ( a ) ( tk.MustExec("analyze table t partition p1 columns a,b,d with 1 topn, 3 buckets") tk.MustQuery("show warnings").Sort().Check(testkit.Rows( "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p1", - "Warning 8244 Build table: `t` column: `d` global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions", + "Warning 8244 Build global-level stats failed due to missing partition-level column stats: table `t` partition `p0` column `d`, please run analyze table to refresh columns of all partitions", )) // analyze partition with existing table-level options and existing partition stats under dynamic @@ -2905,7 +2819,7 @@ PARTITION BY RANGE ( a ) ( tk.MustQuery("show warnings").Sort().Check(testkit.Rows( "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p1", "Warning 1105 Ignore columns and options when analyze partition in dynamic mode", - "Warning 8244 Build table: `t` column: `d` global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions", + "Warning 8244 Build global-level stats failed due to missing partition-level column stats: table `t` partition `p0` column `d`, please run analyze table to refresh columns of all partitions", )) // analyze partition with existing table-level & partition-level options and existing partition stats under dynamic @@ -2914,18 +2828,19 @@ PARTITION BY RANGE ( a ) ( tk.MustQuery("show warnings").Sort().Check(testkit.Rows( "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p1", "Warning 1105 Ignore columns and options when analyze partition in dynamic mode", - "Warning 8244 Build table: `t` column: `d` global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions", + "Warning 8244 Build global-level stats failed due to missing partition-level column stats: table `t` partition `p0` column `d`, please run analyze table to refresh columns of all partitions", )) - tk.MustQuery("select * from t where a > 1 and b > 1 and c > 1 and d > 1") - require.NoError(t, h.LoadNeededHistograms()) - tbl := h.GetTableStats(tableInfo) - require.Equal(t, 4, len(tbl.Columns)) + // flaky test, fix it later + //tk.MustQuery("select * from t where a > 1 and b > 1 and c > 1 and d > 1") + //require.NoError(t, h.LoadNeededHistograms()) + //tbl := h.GetTableStats(tableInfo) + //require.Equal(t, 0, len(tbl.Columns)) // ignore both p0's 3 buckets, persisted-partition-options' 1 bucket, just use table-level 2 buckets tk.MustExec("analyze table t partition p0") tk.MustQuery("select * from t where a > 1 and b > 1 and c > 1 and d > 1") require.NoError(t, h.LoadNeededHistograms()) - tbl = h.GetTableStats(tableInfo) + tbl := h.GetTableStats(tableInfo) require.Equal(t, 2, len(tbl.Columns[tableInfo.Columns[2].ID].Buckets)) } @@ -2939,6 +2854,7 @@ func TestAnalyzePartitionUnderV1Dynamic(t *testing.T) { tk.MustExec("use test") tk.MustExec("set @@session.tidb_analyze_version = 1") + tk.MustExec("set @@session.tidb_stats_load_sync_wait = 20000") // to stabilise test tk.MustExec("set @@session.tidb_partition_prune_mode = 'dynamic'") createTable := `CREATE TABLE t (a int, b int, c varchar(10), d int, primary key(a), index idx(b)) PARTITION BY RANGE ( a ) ( @@ -2964,8 +2880,8 @@ PARTITION BY RANGE ( a ) ( // analyze partition with index and with options are allowed under dynamic V1 tk.MustExec("analyze table t partition p0 with 1 topn, 3 buckets") tk.MustQuery("show warnings").Sort().Check(testkit.Rows( - "Warning 8131 Build table: `t` global-level stats failed due to missing partition-level stats", - "Warning 8131 Build table: `t` index: `idx` global-level stats failed due to missing partition-level stats", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", )) tk.MustExec("analyze table t partition p1 with 1 topn, 3 buckets") tk.MustQuery("show warnings").Sort().Check(testkit.Rows()) @@ -3147,3 +3063,115 @@ func TestAutoAnalyzeAwareGlobalVariableChange(t *testing.T) { require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/injectBaseCount")) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/injectBaseModifyCount")) } + +func TestGlobalMemoryControlForAnalyze(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk0 := testkit.NewTestKit(t, store) + tk0.MustExec("set global tidb_mem_oom_action = 'cancel'") + tk0.MustExec("set global tidb_server_memory_limit = 512MB") + tk0.MustExec("set global tidb_server_memory_limit_sess_min_size = 128") + + sm := &testkit.MockSessionManager{ + PS: []*util.ProcessInfo{tk0.Session().ShowProcess()}, + } + dom.ServerMemoryLimitHandle().SetSessionManager(sm) + go dom.ServerMemoryLimitHandle().Run() + + tk0.MustExec("use test") + tk0.MustExec("create table t(a int)") + tk0.MustExec("insert into t select 1") + for i := 1; i <= 8; i++ { + tk0.MustExec("insert into t select * from t") // 256 Lines + } + sql := "analyze table t with 1.0 samplerate;" // Need about 100MB + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/util/memory/ReadMemStats", `return(536870912)`)) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/mockAnalyzeMergeWorkerSlowConsume", `return(100)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/util/memory/ReadMemStats")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/mockAnalyzeMergeWorkerSlowConsume")) + }() + _, err := tk0.Exec(sql) + require.True(t, strings.Contains(err.Error(), "Out Of Memory Quota!")) + runtime.GC() +} + +func TestGlobalMemoryControlForAutoAnalyze(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + originalVal1 := tk.MustQuery("select @@global.tidb_mem_oom_action").Rows()[0][0].(string) + tk.MustExec("set global tidb_mem_oom_action = 'cancel'") + //originalVal2 := tk.MustQuery("select @@global.tidb_server_memory_limit").Rows()[0][0].(string) + tk.MustExec("set global tidb_server_memory_limit = 512MB") + originalVal3 := tk.MustQuery("select @@global.tidb_server_memory_limit_sess_min_size").Rows()[0][0].(string) + tk.MustExec("set global tidb_server_memory_limit_sess_min_size = 128") + defer func() { + tk.MustExec(fmt.Sprintf("set global tidb_mem_oom_action = %v", originalVal1)) + //tk.MustExec(fmt.Sprintf("set global tidb_server_memory_limit = %v", originalVal2)) + tk.MustExec(fmt.Sprintf("set global tidb_server_memory_limit_sess_min_size = %v", originalVal3)) + }() + + // clean child trackers + oldChildTrackers := executor.GlobalAnalyzeMemoryTracker.GetChildrenForTest() + for _, tracker := range oldChildTrackers { + tracker.Detach() + } + defer func() { + for _, tracker := range oldChildTrackers { + tracker.AttachTo(executor.GlobalAnalyzeMemoryTracker) + } + }() + childTrackers := executor.GlobalAnalyzeMemoryTracker.GetChildrenForTest() + require.Len(t, childTrackers, 0) + + tk.MustExec("use test") + tk.MustExec("create table t(a int)") + tk.MustExec("insert into t select 1") + for i := 1; i <= 8; i++ { + tk.MustExec("insert into t select * from t") // 256 Lines + } + _, err0 := tk.Exec("analyze table t with 1.0 samplerate;") + require.NoError(t, err0) + rs0 := tk.MustQuery("select fail_reason from mysql.analyze_jobs where table_name=? and state=? limit 1", "t", "failed") + require.Len(t, rs0.Rows(), 0) + + h := dom.StatsHandle() + originalVal4 := handle.AutoAnalyzeMinCnt + originalVal5 := tk.MustQuery("select @@global.tidb_auto_analyze_ratio").Rows()[0][0].(string) + handle.AutoAnalyzeMinCnt = 0 + tk.MustExec("set global tidb_auto_analyze_ratio = 0.001") + defer func() { + handle.AutoAnalyzeMinCnt = originalVal4 + tk.MustExec(fmt.Sprintf("set global tidb_auto_analyze_ratio = %v", originalVal5)) + }() + + sm := &testkit.MockSessionManager{ + Dom: dom, + PS: []*util.ProcessInfo{tk.Session().ShowProcess()}, + } + dom.ServerMemoryLimitHandle().SetSessionManager(sm) + go dom.ServerMemoryLimitHandle().Run() + + tk.MustExec("insert into t values(4),(5),(6)") + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + err := h.Update(dom.InfoSchema()) + require.NoError(t, err) + + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/util/memory/ReadMemStats", `return(536870912)`)) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/mockAnalyzeMergeWorkerSlowConsume", `return(100)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/util/memory/ReadMemStats")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/mockAnalyzeMergeWorkerSlowConsume")) + }() + tk.MustQuery("select 1") + childTrackers = executor.GlobalAnalyzeMemoryTracker.GetChildrenForTest() + require.Len(t, childTrackers, 0) + + h.HandleAutoAnalyze(dom.InfoSchema()) + rs := tk.MustQuery("select fail_reason from mysql.analyze_jobs where table_name=? and state=? limit 1", "t", "failed") + failReason := rs.Rows()[0][0].(string) + require.True(t, strings.Contains(failReason, "Out Of Memory Quota!")) + + childTrackers = executor.GlobalAnalyzeMemoryTracker.GetChildrenForTest() + require.Len(t, childTrackers, 0) +} diff --git a/executor/analyzetest/main_test.go b/executor/analyzetest/main_test.go index 386cd07da7beb..5ebf42dc764a2 100644 --- a/executor/analyzetest/main_test.go +++ b/executor/analyzetest/main_test.go @@ -23,6 +23,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) diff --git a/executor/autoidtest/BUILD.bazel b/executor/autoidtest/BUILD.bazel new file mode 100644 index 0000000000000..a59514bef3bd6 --- /dev/null +++ b/executor/autoidtest/BUILD.bazel @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "autoidtest_test", + srcs = [ + "autoid_test.go", + "main_test.go", + ], + flaky = True, + race = "on", + shard_count = 5, + deps = [ + "//autoid_service", + "//config", + "//ddl/testutil", + "//meta/autoid", + "//parser/mysql", + "//session", + "//sessionctx/variable", + "//testkit", + "//testkit/testutil", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//tikv", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/executor/autoidtest/autoid_test.go b/executor/autoidtest/autoid_test.go new file mode 100644 index 0000000000000..eb8cc3f874159 --- /dev/null +++ b/executor/autoidtest/autoid_test.go @@ -0,0 +1,769 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package autoid_test + +import ( + "context" + "fmt" + "strconv" + "strings" + "testing" + + "github.com/pingcap/failpoint" + _ "github.com/pingcap/tidb/autoid_service" + ddltestutil "github.com/pingcap/tidb/ddl/testutil" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/testkit/testutil" + "github.com/stretchr/testify/require" +) + +// Test filter different kind of allocators. +// In special ddl type, for example: +// 1: ActionRenameTable : it will abandon all the old allocators. +// 2: ActionRebaseAutoID : it will drop row-id-type allocator. +// 3: ActionModifyTableAutoIdCache : it will drop row-id-type allocator. +// 3: ActionRebaseAutoRandomBase : it will drop auto-rand-type allocator. +func TestFilterDifferentAllocators(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("drop table if exists t1") + + for _, str := range []string{"", " AUTO_ID_CACHE 1"} { + tk.MustExec("create table t(a bigint auto_random(5) key, b int auto_increment unique)" + str) + tk.MustExec("insert into t values()") + tk.MustQuery("select b from t").Check(testkit.Rows("1")) + allHandles, err := ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t") + require.NoError(t, err) + require.Equal(t, 1, len(allHandles)) + orderedHandles := testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) + require.Equal(t, int64(1), orderedHandles[0]) + tk.MustExec("delete from t") + + // Test rebase auto_increment. + tk.MustExec("alter table t auto_increment 3000000") + tk.MustExec("insert into t values()") + tk.MustQuery("select b from t").Check(testkit.Rows("3000000")) + allHandles, err = ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t") + require.NoError(t, err) + require.Equal(t, 1, len(allHandles)) + orderedHandles = testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) + require.Equal(t, int64(2), orderedHandles[0]) + tk.MustExec("delete from t") + + // Test rebase auto_random. + tk.MustExec("alter table t auto_random_base 3000000") + tk.MustExec("insert into t values()") + tk.MustQuery("select b from t").Check(testkit.Rows("3000001")) + allHandles, err = ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t") + require.NoError(t, err) + require.Equal(t, 1, len(allHandles)) + orderedHandles = testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) + require.Equal(t, int64(3000000), orderedHandles[0]) + tk.MustExec("delete from t") + + // Test rename table. + tk.MustExec("rename table t to t1") + tk.MustExec("insert into t1 values()") + res := tk.MustQuery("select b from t1") + strInt64, err := strconv.ParseInt(res.Rows()[0][0].(string), 10, 64) + require.NoError(t, err) + require.GreaterOrEqual(t, strInt64, int64(3000002)) + allHandles, err = ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t1") + require.NoError(t, err) + require.Equal(t, 1, len(allHandles)) + orderedHandles = testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) + require.Greater(t, orderedHandles[0], int64(3000001)) + + tk.MustExec("drop table t1") + } +} + +func TestAutoIncrementInsertMinMax(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + cases := []struct { + t string + s string + vals []int64 + expect [][]interface{} + }{ + {"tinyint", "signed", []int64{-128, 0, 127}, testkit.Rows("-128", "1", "2", "3", "127")}, + {"tinyint", "unsigned", []int64{0, 127, 255}, testkit.Rows("1", "2", "127", "128", "255")}, + {"smallint", "signed", []int64{-32768, 0, 32767}, testkit.Rows("-32768", "1", "2", "3", "32767")}, + {"smallint", "unsigned", []int64{0, 32767, 65535}, testkit.Rows("1", "2", "32767", "32768", "65535")}, + {"mediumint", "signed", []int64{-8388608, 0, 8388607}, testkit.Rows("-8388608", "1", "2", "3", "8388607")}, + {"mediumint", "unsigned", []int64{0, 8388607, 16777215}, testkit.Rows("1", "2", "8388607", "8388608", "16777215")}, + {"integer", "signed", []int64{-2147483648, 0, 2147483647}, testkit.Rows("-2147483648", "1", "2", "3", "2147483647")}, + {"integer", "unsigned", []int64{0, 2147483647, 4294967295}, testkit.Rows("1", "2", "2147483647", "2147483648", "4294967295")}, + {"bigint", "signed", []int64{-9223372036854775808, 0, 9223372036854775807}, testkit.Rows("-9223372036854775808", "1", "2", "3", "9223372036854775807")}, + {"bigint", "unsigned", []int64{0, 9223372036854775807}, testkit.Rows("1", "2", "9223372036854775807", "9223372036854775808")}, + } + + for _, option := range []string{"", "auto_id_cache 1", "auto_id_cache 100"} { + for idx, c := range cases { + sql := fmt.Sprintf("create table t%d (a %s %s key auto_increment) %s", idx, c.t, c.s, option) + tk.MustExec(sql) + + for _, val := range c.vals { + tk.MustExec(fmt.Sprintf("insert into t%d values (%d)", idx, val)) + tk.Exec(fmt.Sprintf("insert into t%d values ()", idx)) // ignore error + } + + tk.MustQuery(fmt.Sprintf("select * from t%d order by a", idx)).Check(c.expect) + + tk.MustExec(fmt.Sprintf("drop table t%d", idx)) + } + } + + tk.MustExec("create table t10 (a integer key auto_increment) auto_id_cache 1") + err := tk.ExecToErr("insert into t10 values (2147483648)") + require.Error(t, err) + err = tk.ExecToErr("insert into t10 values (-2147483649)") + require.Error(t, err) +} + +func TestInsertWithAutoidSchema(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec(`create table t1(id int primary key auto_increment, n int);`) + tk.MustExec(`create table t2(id int unsigned primary key auto_increment, n int);`) + tk.MustExec(`create table t3(id tinyint primary key auto_increment, n int);`) + tk.MustExec(`create table t4(id int primary key, n float auto_increment, key I_n(n));`) + tk.MustExec(`create table t5(id int primary key, n float unsigned auto_increment, key I_n(n));`) + tk.MustExec(`create table t6(id int primary key, n double auto_increment, key I_n(n));`) + tk.MustExec(`create table t7(id int primary key, n double unsigned auto_increment, key I_n(n));`) + // test for inserting multiple values + tk.MustExec(`create table t8(id int primary key auto_increment, n int);`) + + testInsertWithAutoidSchema(t, tk) +} + +func TestInsertWithAutoidSchemaCache(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec(`create table t1(id int primary key auto_increment, n int) AUTO_ID_CACHE 1;`) + tk.MustExec(`create table t2(id int unsigned primary key auto_increment, n int) AUTO_ID_CACHE 1;`) + tk.MustExec(`create table t3(id tinyint primary key auto_increment, n int) AUTO_ID_CACHE 1;`) + tk.MustExec(`create table t4(id int primary key, n float auto_increment, key I_n(n)) AUTO_ID_CACHE 1;`) + tk.MustExec(`create table t5(id int primary key, n float unsigned auto_increment, key I_n(n)) AUTO_ID_CACHE 1;`) + tk.MustExec(`create table t6(id int primary key, n double auto_increment, key I_n(n)) AUTO_ID_CACHE 1;`) + tk.MustExec(`create table t7(id int primary key, n double unsigned auto_increment, key I_n(n)) AUTO_ID_CACHE 1;`) + // test for inserting multiple values + tk.MustExec(`create table t8(id int primary key auto_increment, n int);`) + + testInsertWithAutoidSchema(t, tk) +} + +func testInsertWithAutoidSchema(t *testing.T, tk *testkit.TestKit) { + tests := []struct { + insert string + query string + result [][]interface{} + }{ + { + `insert into t1(id, n) values(1, 1)`, + `select * from t1 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t1(n) values(2)`, + `select * from t1 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t1(n) values(3)`, + `select * from t1 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t1(id, n) values(-1, 4)`, + `select * from t1 where id = -1`, + testkit.Rows(`-1 4`), + }, + { + `insert into t1(n) values(5)`, + `select * from t1 where id = 4`, + testkit.Rows(`4 5`), + }, + { + `insert into t1(id, n) values('5', 6)`, + `select * from t1 where id = 5`, + testkit.Rows(`5 6`), + }, + { + `insert into t1(n) values(7)`, + `select * from t1 where id = 6`, + testkit.Rows(`6 7`), + }, + { + `insert into t1(id, n) values(7.4, 8)`, + `select * from t1 where id = 7`, + testkit.Rows(`7 8`), + }, + { + `insert into t1(id, n) values(7.5, 9)`, + `select * from t1 where id = 8`, + testkit.Rows(`8 9`), + }, + { + `insert into t1(n) values(9)`, + `select * from t1 where id = 9`, + testkit.Rows(`9 9`), + }, + // test last insert id + { + `insert into t1 values(3000, -1), (null, -2)`, + `select * from t1 where id = 3000`, + testkit.Rows(`3000 -1`), + }, + { + `;`, + `select * from t1 where id = 3001`, + testkit.Rows(`3001 -2`), + }, + { + `;`, + `select last_insert_id()`, + testkit.Rows(`3001`), + }, + { + `insert into t2(id, n) values(1, 1)`, + `select * from t2 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t2(n) values(2)`, + `select * from t2 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t2(n) values(3)`, + `select * from t2 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t3(id, n) values(1, 1)`, + `select * from t3 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t3(n) values(2)`, + `select * from t3 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t3(n) values(3)`, + `select * from t3 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t3(id, n) values(-1, 4)`, + `select * from t3 where id = -1`, + testkit.Rows(`-1 4`), + }, + { + `insert into t3(n) values(5)`, + `select * from t3 where id = 4`, + testkit.Rows(`4 5`), + }, + { + `insert into t4(id, n) values(1, 1)`, + `select * from t4 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t4(id) values(2)`, + `select * from t4 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t4(id, n) values(3, -1)`, + `select * from t4 where id = 3`, + testkit.Rows(`3 -1`), + }, + { + `insert into t4(id) values(4)`, + `select * from t4 where id = 4`, + testkit.Rows(`4 3`), + }, + { + `insert into t4(id, n) values(5, 5.5)`, + `select * from t4 where id = 5`, + testkit.Rows(`5 5.5`), + }, + { + `insert into t4(id) values(6)`, + `select * from t4 where id = 6`, + testkit.Rows(`6 7`), + }, + { + `insert into t4(id, n) values(7, '7.7')`, + `select * from t4 where id = 7`, + testkit.Rows(`7 7.7`), + }, + { + `insert into t4(id) values(8)`, + `select * from t4 where id = 8`, + testkit.Rows(`8 9`), + }, + { + `insert into t4(id, n) values(9, 10.4)`, + `select * from t4 where id = 9`, + testkit.Rows(`9 10.4`), + }, + { + `insert into t4(id) values(10)`, + `select * from t4 where id = 10`, + testkit.Rows(`10 11`), + }, + { + `insert into t5(id, n) values(1, 1)`, + `select * from t5 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t5(id) values(2)`, + `select * from t5 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t5(id) values(3)`, + `select * from t5 where id = 3`, + testkit.Rows(`3 3`), + }, + { + `insert into t6(id, n) values(1, 1)`, + `select * from t6 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t6(id) values(2)`, + `select * from t6 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t6(id, n) values(3, -1)`, + `select * from t6 where id = 3`, + testkit.Rows(`3 -1`), + }, + { + `insert into t6(id) values(4)`, + `select * from t6 where id = 4`, + testkit.Rows(`4 3`), + }, + { + `insert into t6(id, n) values(5, 5.5)`, + `select * from t6 where id = 5`, + testkit.Rows(`5 5.5`), + }, + { + `insert into t6(id) values(6)`, + `select * from t6 where id = 6`, + testkit.Rows(`6 7`), + }, + { + `insert into t6(id, n) values(7, '7.7')`, + `select * from t4 where id = 7`, + testkit.Rows(`7 7.7`), + }, + { + `insert into t6(id) values(8)`, + `select * from t4 where id = 8`, + testkit.Rows(`8 9`), + }, + { + `insert into t6(id, n) values(9, 10.4)`, + `select * from t6 where id = 9`, + testkit.Rows(`9 10.4`), + }, + { + `insert into t6(id) values(10)`, + `select * from t6 where id = 10`, + testkit.Rows(`10 11`), + }, + { + `insert into t7(id, n) values(1, 1)`, + `select * from t7 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `insert into t7(id) values(2)`, + `select * from t7 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `insert into t7(id) values(3)`, + `select * from t7 where id = 3`, + testkit.Rows(`3 3`), + }, + + // the following is test for insert multiple values. + { + `insert into t8(n) values(1),(2)`, + `select * from t8 where id = 1`, + testkit.Rows(`1 1`), + }, + { + `;`, + `select * from t8 where id = 2`, + testkit.Rows(`2 2`), + }, + { + `;`, + `select last_insert_id();`, + testkit.Rows(`1`), + }, + // test user rebase and auto alloc mixture. + { + `insert into t8 values(null, 3),(-1, -1),(null,4),(null, 5)`, + `select * from t8 where id = 3`, + testkit.Rows(`3 3`), + }, + // -1 won't rebase allocator here cause -1 < base. + { + `;`, + `select * from t8 where id = -1`, + testkit.Rows(`-1 -1`), + }, + { + `;`, + `select * from t8 where id = 4`, + testkit.Rows(`4 4`), + }, + { + `;`, + `select * from t8 where id = 5`, + testkit.Rows(`5 5`), + }, + { + `;`, + `select last_insert_id();`, + testkit.Rows(`3`), + }, + { + `insert into t8 values(null, 6),(10, 7),(null, 8)`, + `select * from t8 where id = 6`, + testkit.Rows(`6 6`), + }, + // 10 will rebase allocator here. + { + `;`, + `select * from t8 where id = 10`, + testkit.Rows(`10 7`), + }, + { + `;`, + `select * from t8 where id = 11`, + testkit.Rows(`11 8`), + }, + { + `;`, + `select last_insert_id()`, + testkit.Rows(`6`), + }, + // fix bug for last_insert_id should be first allocated id in insert rows (skip the rebase id). + { + `insert into t8 values(100, 9),(null,10),(null,11)`, + `select * from t8 where id = 100`, + testkit.Rows(`100 9`), + }, + { + `;`, + `select * from t8 where id = 101`, + testkit.Rows(`101 10`), + }, + { + `;`, + `select * from t8 where id = 102`, + testkit.Rows(`102 11`), + }, + { + `;`, + `select last_insert_id()`, + testkit.Rows(`101`), + }, + // test with sql_mode: NO_AUTO_VALUE_ON_ZERO. + { + `;`, + `select @@sql_mode`, + testkit.Rows(`ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION`), + }, + { + `;`, + "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO`", + nil, + }, + { + `insert into t8 values (0, 12), (null, 13)`, + `select * from t8 where id = 0`, + testkit.Rows(`0 12`), + }, + { + `;`, + `select * from t8 where id = 103`, + testkit.Rows(`103 13`), + }, + { + `;`, + `select last_insert_id()`, + testkit.Rows(`103`), + }, + // test without sql_mode: NO_AUTO_VALUE_ON_ZERO. + { + `;`, + "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION`", + nil, + }, + // value 0 will be substitute by autoid. + { + `insert into t8 values (0, 14), (null, 15)`, + `select * from t8 where id = 104`, + testkit.Rows(`104 14`), + }, + { + `;`, + `select * from t8 where id = 105`, + testkit.Rows(`105 15`), + }, + { + `;`, + `select last_insert_id()`, + testkit.Rows(`104`), + }, + // last test : auto increment allocation can find in retryInfo. + { + `retry : insert into t8 values (null, 16), (null, 17)`, + `select * from t8 where id = 1000`, + testkit.Rows(`1000 16`), + }, + { + `;`, + `select * from t8 where id = 1001`, + testkit.Rows(`1001 17`), + }, + { + `;`, + `select last_insert_id()`, + // this insert doesn't has the last_insert_id, should be same as the last insert case. + testkit.Rows(`104`), + }, + } + + for _, tt := range tests { + if strings.HasPrefix(tt.insert, "retry : ") { + // it's the last retry insert case, change the sessionVars. + retryInfo := &variable.RetryInfo{Retrying: true} + retryInfo.AddAutoIncrementID(1000) + retryInfo.AddAutoIncrementID(1001) + tk.Session().GetSessionVars().RetryInfo = retryInfo + tk.MustExec(tt.insert[8:]) + tk.Session().GetSessionVars().RetryInfo = &variable.RetryInfo{} + } else { + tk.MustExec(tt.insert) + } + if tt.query == "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO`" || + tt.query == "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION`" { + tk.MustExec(tt.query) + } else { + tk.MustQuery(tt.query).Check(tt.result) + } + } +} + +// TestAutoIDIncrementAndOffset There is a potential issue in MySQL: when the value of auto_increment_offset is greater +// than that of auto_increment_increment, the value of auto_increment_offset is ignored +// (https://dev.mysql.com/doc/refman/8.0/en/replication-options-master.html#sysvar_auto_increment_increment), +// This issue is a flaw of the implementation of MySQL and it doesn't exist in TiDB. +func TestAutoIDIncrementAndOffset(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + // Test for offset is larger than increment. + tk.Session().GetSessionVars().AutoIncrementIncrement = 5 + tk.Session().GetSessionVars().AutoIncrementOffset = 10 + + for _, str := range []string{"", " AUTO_ID_CACHE 1"} { + tk.MustExec(`create table io (a int key auto_increment)` + str) + tk.MustExec(`insert into io values (null),(null),(null)`) + tk.MustQuery(`select * from io`).Check(testkit.Rows("10", "15", "20")) + tk.MustExec(`drop table io`) + } + + // Test handle is PK. + for _, str := range []string{"", " AUTO_ID_CACHE 1"} { + tk.MustExec(`create table io (a int key auto_increment)` + str) + tk.Session().GetSessionVars().AutoIncrementOffset = 10 + tk.Session().GetSessionVars().AutoIncrementIncrement = 2 + tk.MustExec(`insert into io values (),(),()`) + tk.MustQuery(`select * from io`).Check(testkit.Rows("10", "12", "14")) + tk.MustExec(`delete from io`) + + // Test reset the increment. + tk.Session().GetSessionVars().AutoIncrementIncrement = 5 + tk.MustExec(`insert into io values (),(),()`) + tk.MustQuery(`select * from io`).Check(testkit.Rows("15", "20", "25")) + tk.MustExec(`delete from io`) + + tk.Session().GetSessionVars().AutoIncrementIncrement = 10 + tk.MustExec(`insert into io values (),(),()`) + tk.MustQuery(`select * from io`).Check(testkit.Rows("30", "40", "50")) + tk.MustExec(`delete from io`) + + tk.Session().GetSessionVars().AutoIncrementIncrement = 5 + tk.MustExec(`insert into io values (),(),()`) + tk.MustQuery(`select * from io`).Check(testkit.Rows("55", "60", "65")) + tk.MustExec(`drop table io`) + } + + // Test handle is not PK. + for _, str := range []string{"", " AUTO_ID_CACHE 1"} { + tk.Session().GetSessionVars().AutoIncrementIncrement = 2 + tk.Session().GetSessionVars().AutoIncrementOffset = 10 + tk.MustExec(`create table io (a int, b int auto_increment, key(b))` + str) + tk.MustExec(`insert into io(b) values (null),(null),(null)`) + // AutoID allocation will take increment and offset into consideration. + tk.MustQuery(`select b from io`).Check(testkit.Rows("10", "12", "14")) + if str == "" { + // HandleID allocation will ignore the increment and offset. + tk.MustQuery(`select _tidb_rowid from io`).Check(testkit.Rows("15", "16", "17")) + } else { + // Separate row id and auto inc id, increment and offset works on auto inc id + tk.MustQuery(`select _tidb_rowid from io`).Check(testkit.Rows("1", "2", "3")) + } + tk.MustExec(`delete from io`) + + tk.Session().GetSessionVars().AutoIncrementIncrement = 10 + tk.MustExec(`insert into io(b) values (null),(null),(null)`) + tk.MustQuery(`select b from io`).Check(testkit.Rows("20", "30", "40")) + if str == "" { + tk.MustQuery(`select _tidb_rowid from io`).Check(testkit.Rows("41", "42", "43")) + } else { + tk.MustQuery(`select _tidb_rowid from io`).Check(testkit.Rows("4", "5", "6")) + } + + // Test invalid value. + tk.Session().GetSessionVars().AutoIncrementIncrement = -1 + tk.Session().GetSessionVars().AutoIncrementOffset = -2 + tk.MustGetErrMsg(`insert into io(b) values (null),(null),(null)`, + "[autoid:8060]Invalid auto_increment settings: auto_increment_increment: -1, auto_increment_offset: -2, both of them must be in range [1..65535]") + tk.MustExec(`delete from io`) + + tk.Session().GetSessionVars().AutoIncrementIncrement = 65536 + tk.Session().GetSessionVars().AutoIncrementOffset = 65536 + tk.MustGetErrMsg(`insert into io(b) values (null),(null),(null)`, + "[autoid:8060]Invalid auto_increment settings: auto_increment_increment: 65536, auto_increment_offset: 65536, both of them must be in range [1..65535]") + + tk.MustExec(`drop table io`) + } +} + +func TestRenameTableForAutoIncrement(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("USE test;") + tk.MustExec("drop table if exists t1, t2, t3;") + tk.MustExec("create table t1 (id int key auto_increment);") + tk.MustExec("insert into t1 values ()") + tk.MustExec("rename table t1 to t11") + tk.MustExec("insert into t11 values ()") + // TODO(tiancaiamao): fix bug and uncomment here, rename table should not discard the cached AUTO_ID. + // tk.MustQuery("select * from t11").Check(testkit.Rows("1", "2")) + + // auto_id_cache 1 use another implementation and do not have such bug. + tk.MustExec("create table t2 (id int key auto_increment) auto_id_cache 1;") + tk.MustExec("insert into t2 values ()") + tk.MustExec("rename table t2 to t22") + tk.MustExec("insert into t22 values ()") + tk.MustQuery("select * from t22").Check(testkit.Rows("1", "2")) + + tk.MustExec("create table t3 (id int key auto_increment) auto_id_cache 100;") + tk.MustExec("insert into t3 values ()") + tk.MustExec("rename table t3 to t33") + tk.MustExec("insert into t33 values ()") + // TODO(tiancaiamao): fix bug and uncomment here, rename table should not discard the cached AUTO_ID. + // tk.MustQuery("select * from t33").Check(testkit.Rows("1", "2")) +} + +func TestAlterTableAutoIDCache(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("USE test;") + tk.MustExec("drop table if exists t_473;") + tk.MustExec("create table t_473 (id int key auto_increment)") + tk.MustExec("insert into t_473 values ()") + tk.MustQuery("select * from t_473").Check(testkit.Rows("1")) + rs, err := tk.Exec("show table t_473 next_row_id") + require.NoError(t, err) + rows, err1 := session.ResultSetToStringSlice(context.Background(), tk.Session(), rs) + require.NoError(t, err1) + // "test t_473 id 1013608 AUTO_INCREMENT" + val, err2 := strconv.ParseUint(rows[0][3], 10, 64) + require.NoError(t, err2) + + tk.MustExec("alter table t_473 auto_id_cache = 100") + tk.MustQuery("show table t_473 next_row_id").Check(testkit.Rows( + fmt.Sprintf("test t_473 id %d _TIDB_ROWID", val), + "test t_473 id 1 AUTO_INCREMENT", + )) + tk.MustExec("insert into t_473 values ()") + tk.MustQuery("select * from t_473").Check(testkit.Rows("1", fmt.Sprintf("%d", val))) + tk.MustQuery("show table t_473 next_row_id").Check(testkit.Rows( + fmt.Sprintf("test t_473 id %d _TIDB_ROWID", val+100), + "test t_473 id 1 AUTO_INCREMENT", + )) + + // Note that auto_id_cache=1 use a different implementation, switch between them is not allowed. + // TODO: relax this restriction and update the test case. + tk.MustExecToErr("alter table t_473 auto_id_cache = 1") +} + +func TestMockAutoIDServiceError(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("USE test;") + tk.MustExec("create table t_mock_err (id int key auto_increment) auto_id_cache 1") + + failpoint.Enable("github.com/pingcap/tidb/autoid_service/mockErr", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/autoid_service/mockErr") + // Cover a bug that the autoid client retry non-retryable errors forever cause dead loop. + tk.MustExecToErr("insert into t_mock_err values (),()") // mock error, instead of dead loop +} + +func TestIssue39528(t *testing.T) { + // When AUTO_ID_CACHE is 1, it should not affect row id setting when autoid and rowid are separated. + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test;") + tk.MustExec("create table issue39528 (id int unsigned key nonclustered auto_increment) shard_row_id_bits=4 auto_id_cache 1;") + tk.MustExec("insert into issue39528 values ()") + tk.MustExec("insert into issue39528 values ()") + + ctx := context.Background() + var codeRun bool + ctx = context.WithValue(ctx, "testIssue39528", &codeRun) + _, err := tk.ExecWithContext(ctx, "insert into issue39528 values ()") + require.NoError(t, err) + // Make sure the code does not visit tikv on allocate path. + require.False(t, codeRun) +} diff --git a/executor/autoidtest/main_test.go b/executor/autoidtest/main_test.go new file mode 100644 index 0000000000000..f87db4afe1371 --- /dev/null +++ b/executor/autoidtest/main_test.go @@ -0,0 +1,44 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package autoid_test + +import ( + "testing" + + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/meta/autoid" + "github.com/tikv/client-go/v2/tikv" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + autoid.SetStep(5000) + config.UpdateGlobal(func(conf *config.Config) { + conf.Log.SlowThreshold = 30000 // 30s + conf.TiKVClient.AsyncCommit.SafeWindow = 0 + conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 + conf.Experimental.AllowsExpressionIndex = true + }) + tikv.EnableFailpoints() + + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), + goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + } + goleak.VerifyTestMain(m, opts...) +} diff --git a/executor/batch_checker.go b/executor/batch_checker.go index 76eea024bc3d3..838c6af7bace0 100644 --- a/executor/batch_checker.go +++ b/executor/batch_checker.go @@ -16,6 +16,7 @@ package executor import ( "context" + "fmt" "strings" "github.com/pingcap/errors" @@ -141,12 +142,37 @@ func getKeysNeedCheckOneRow(ctx sessionctx.Context, t table.Table, row []types.D } handleKey = &keyValueWithDupInfo{ newKey: tablecodec.EncodeRecordKey(t.RecordPrefix(), handle), - dupErr: kv.ErrKeyExists.FastGenByArgs(stringutil.MemoizeStr(fn), "PRIMARY"), + dupErr: kv.ErrKeyExists.FastGenByArgs(stringutil.MemoizeStr(fn), t.Meta().Name.String()+".PRIMARY"), } } - // addChangingColTimes is used to fetch values while processing "modify/change column" operation. - addChangingColTimes := 0 + // extraColumns is used to fetch values while processing "add/drop/modify/change column" operation. + extraColumns := 0 + for _, col := range t.WritableCols() { + // if there is a changing column, append the dependency column for index fetch values + if col.ChangeStateInfo != nil && col.State != model.StatePublic { + value, err := table.CastValue(ctx, row[col.DependencyColumnOffset], col.ColumnInfo, false, false) + if err != nil { + return nil, err + } + row = append(row, value) + extraColumns++ + continue + } + + if col.State != model.StatePublic { + // only append origin default value for index fetch values + if col.Offset >= len(row) { + value, err := table.GetColOriginDefaultValue(ctx, col.ToInfo()) + if err != nil { + return nil, err + } + + row = append(row, value) + extraColumns++ + } + } + } // append unique keys and errors for _, v := range t.Indices() { if !tables.IsIndexWritable(v) { @@ -158,40 +184,38 @@ func getKeysNeedCheckOneRow(ctx sessionctx.Context, t table.Table, row []types.D if t.Meta().IsCommonHandle && v.Meta().Primary { continue } - if len(row) < len(t.WritableCols()) && addChangingColTimes == 0 { - if col := tables.FindChangingCol(t.WritableCols(), v.Meta()); col != nil { - row = append(row, row[col.DependencyColumnOffset]) - addChangingColTimes++ - } - } colVals, err1 := v.FetchValues(row, nil) if err1 != nil { return nil, err1 } // Pass handle = 0 to GenIndexKey, // due to we only care about distinct key. - key, distinct, err1 := v.GenIndexKey(ctx.GetSessionVars().StmtCtx, - colVals, kv.IntHandle(0), nil) - if err1 != nil { - return nil, err1 - } - // Skip the non-distinct keys. - if !distinct { - continue - } - colValStr, err1 := formatDataForDupError(colVals) - if err1 != nil { - return nil, err1 + iter := v.GenIndexKVIter(ctx.GetSessionVars().StmtCtx, colVals, kv.IntHandle(0), nil) + for iter.Valid() { + key, _, distinct, err1 := iter.Next(nil) + if err1 != nil { + return nil, err1 + } + // Skip the non-distinct keys. + if !distinct { + continue + } + // If index is used ingest ways, then we should check key from temp index. + if v.Meta().State != model.StatePublic && v.Meta().BackfillState != model.BackfillStateInapplicable { + _, key, _ = tables.GenTempIdxKeyByState(v.Meta(), key) + } + colValStr, err1 := formatDataForDupError(colVals) + if err1 != nil { + return nil, err1 + } + uniqueKeys = append(uniqueKeys, &keyValueWithDupInfo{ + newKey: key, + dupErr: kv.ErrKeyExists.FastGenByArgs(colValStr, fmt.Sprintf("%s.%s", v.TableMeta().Name.String(), v.Meta().Name.String())), + commonHandle: t.Meta().IsCommonHandle, + }) } - uniqueKeys = append(uniqueKeys, &keyValueWithDupInfo{ - newKey: key, - dupErr: kv.ErrKeyExists.FastGenByArgs(colValStr, v.Meta().Name), - commonHandle: t.Meta().IsCommonHandle, - }) - } - if addChangingColTimes == 1 { - row = row[:len(row)-1] } + row = row[:len(row)-extraColumns] result = append(result, toBeCheckedRow{ row: row, handleKey: handleKey, diff --git a/executor/batch_point_get.go b/executor/batch_point_get.go index 1af256ade8c31..ee9808700aaec 100644 --- a/executor/batch_point_get.go +++ b/executor/batch_point_get.go @@ -29,6 +29,7 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" driver "github.com/pingcap/tidb/store/driver/txn" + "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" @@ -158,6 +159,9 @@ func MockNewCacheTableSnapShot(snapshot kv.Snapshot, memBuffer kv.MemBuffer) *ca // Close implements the Executor interface. func (e *BatchPointGetExec) Close() error { + if e.runtimeStats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } if e.runtimeStats != nil && e.snapshot != nil { e.snapshot.SetOption(kv.CollectRuntimeStats, nil) } @@ -190,7 +194,7 @@ func (e *BatchPointGetExec) Next(ctx context.Context, req *chunk.Chunk) error { e.index++ } - err := FillVirtualColumnValue(e.virtualColumnRetFieldTypes, e.virtualColumnIndex, e.schema, e.columns, e.ctx, req) + err := table.FillVirtualColumnValue(e.virtualColumnRetFieldTypes, e.virtualColumnIndex, e.schema.Columns, e.columns, e.ctx, req) if err != nil { return err } diff --git a/executor/benchmark_test.go b/executor/benchmark_test.go index d80f788ae533a..3f64164332ce7 100644 --- a/executor/benchmark_test.go +++ b/executor/benchmark_test.go @@ -906,35 +906,44 @@ func prepare4HashJoin(testCase *hashJoinTestCase, innerExec, outerExec Executor) joinSchema.Append(cols1...) } - joinKeys := make([]*expression.Column, 0, len(testCase.keyIdx)) - for _, keyIdx := range testCase.keyIdx { - joinKeys = append(joinKeys, cols0[keyIdx]) - } - probeKeys := make([]*expression.Column, 0, len(testCase.keyIdx)) - for _, keyIdx := range testCase.keyIdx { - probeKeys = append(probeKeys, cols1[keyIdx]) - } + joinKeysColIdx := make([]int, 0, len(testCase.keyIdx)) + joinKeysColIdx = append(joinKeysColIdx, testCase.keyIdx...) + probeKeysColIdx := make([]int, 0, len(testCase.keyIdx)) + probeKeysColIdx = append(probeKeysColIdx, testCase.keyIdx...) e := &HashJoinExec{ - baseExecutor: newBaseExecutor(testCase.ctx, joinSchema, 5, innerExec, outerExec), - concurrency: uint(testCase.concurrency), - joinType: testCase.joinType, // 0 for InnerJoin, 1 for LeftOutersJoin, 2 for RightOuterJoin - isOuterJoin: false, - buildKeys: joinKeys, - probeKeys: probeKeys, - buildSideExec: innerExec, - probeSideExec: outerExec, - buildSideEstCount: float64(testCase.rows), - useOuterToBuild: testCase.useOuterToBuild, + baseExecutor: newBaseExecutor(testCase.ctx, joinSchema, 5, innerExec, outerExec), + hashJoinCtx: &hashJoinCtx{ + sessCtx: testCase.ctx, + joinType: testCase.joinType, // 0 for InnerJoin, 1 for LeftOutersJoin, 2 for RightOuterJoin + isOuterJoin: false, + useOuterToBuild: testCase.useOuterToBuild, + concurrency: uint(testCase.concurrency), + probeTypes: retTypes(outerExec), + buildTypes: retTypes(innerExec), + }, + probeSideTupleFetcher: &probeSideTupleFetcher{ + probeSideExec: outerExec, + }, + probeWorkers: make([]*probeWorker, testCase.concurrency), + buildWorker: &buildWorker{ + buildKeyColIdx: joinKeysColIdx, + buildSideExec: innerExec, + }, } childrenUsedSchema := markChildrenUsedCols(e.Schema(), e.children[0].Schema(), e.children[1].Schema()) - defaultValues := make([]types.Datum, e.buildSideExec.Schema().Len()) + defaultValues := make([]types.Datum, e.buildWorker.buildSideExec.Schema().Len()) lhsTypes, rhsTypes := retTypes(innerExec), retTypes(outerExec) - e.joiners = make([]joiner, e.concurrency) for i := uint(0); i < e.concurrency; i++ { - e.joiners[i] = newJoiner(testCase.ctx, e.joinType, true, defaultValues, - nil, lhsTypes, rhsTypes, childrenUsedSchema, false) + e.probeWorkers[i] = &probeWorker{ + workerID: i, + hashJoinCtx: e.hashJoinCtx, + joiner: newJoiner(testCase.ctx, e.joinType, true, defaultValues, + nil, lhsTypes, rhsTypes, childrenUsedSchema, false), + probeKeyColIdx: probeKeysColIdx, + } } + e.buildWorker.hashJoinCtx = e.hashJoinCtx memLimit := int64(-1) if testCase.disk { memLimit = 1 @@ -942,8 +951,10 @@ func prepare4HashJoin(testCase *hashJoinTestCase, innerExec, outerExec Executor) t := memory.NewTracker(-1, memLimit) t.SetActionOnExceed(nil) t2 := disk.NewTracker(-1, -1) - e.ctx.GetSessionVars().StmtCtx.MemTracker = t - e.ctx.GetSessionVars().StmtCtx.DiskTracker = t2 + e.ctx.GetSessionVars().MemTracker = t + e.ctx.GetSessionVars().StmtCtx.MemTracker.AttachTo(t) + e.ctx.GetSessionVars().DiskTracker = t2 + e.ctx.GetSessionVars().StmtCtx.DiskTracker.AttachTo(t2) return e } @@ -1190,7 +1201,7 @@ func benchmarkBuildHashTable(b *testing.B, casTest *hashJoinTestCase, dataSource close(innerResultCh) b.StartTimer() - if err := exec.buildHashTableForList(innerResultCh); err != nil { + if err := exec.buildWorker.buildHashTableForList(innerResultCh); err != nil { b.Fatal(err) } diff --git a/executor/bind.go b/executor/bind.go index aed1ee3460e68..90272e6878620 100644 --- a/executor/bind.go +++ b/executor/bind.go @@ -38,6 +38,9 @@ type SQLBindExec struct { isGlobal bool bindAst ast.StmtNode newStatus string + source string // by manual or from history, only in create stmt + sqlDigest string + planDigest string } // Next implements the Executor Next interface. @@ -48,6 +51,8 @@ func (e *SQLBindExec) Next(ctx context.Context, req *chunk.Chunk) error { return e.createSQLBind() case plannercore.OpSQLBindDrop: return e.dropSQLBind() + case plannercore.OpSQLBindDropByDigest: + return e.dropSQLBindByDigest() case plannercore.OpFlushBindings: return e.flushBindings() case plannercore.OpCaptureBindings: @@ -58,6 +63,8 @@ func (e *SQLBindExec) Next(ctx context.Context, req *chunk.Chunk) error { return e.reloadBindings() case plannercore.OpSetBindingStatus: return e.setBindingStatus() + case plannercore.OpSetBindingStatusByDigest: + return e.setBindingStatusByDigest() default: return errors.Errorf("unsupported SQL bind operation: %v", e.sqlBindOp) } @@ -75,9 +82,26 @@ func (e *SQLBindExec) dropSQLBind() error { } if !e.isGlobal { handle := e.ctx.Value(bindinfo.SessionBindInfoKeyType).(*bindinfo.SessionHandle) - return handle.DropBindRecord(e.normdOrigSQL, e.db, bindInfo) + err := handle.DropBindRecord(e.normdOrigSQL, e.db, bindInfo) + return err } - return domain.GetDomain(e.ctx).BindHandle().DropBindRecord(e.normdOrigSQL, e.db, bindInfo) + affectedRows, err := domain.GetDomain(e.ctx).BindHandle().DropBindRecord(e.normdOrigSQL, e.db, bindInfo) + e.ctx.GetSessionVars().StmtCtx.AddAffectedRows(affectedRows) + return err +} + +func (e *SQLBindExec) dropSQLBindByDigest() error { + if e.sqlDigest == "" { + return errors.New("sql digest is empty") + } + if !e.isGlobal { + handle := e.ctx.Value(bindinfo.SessionBindInfoKeyType).(*bindinfo.SessionHandle) + err := handle.DropBindRecordByDigest(e.sqlDigest) + return err + } + affectedRows, err := domain.GetDomain(e.ctx).BindHandle().DropBindRecordByDigest(e.sqlDigest) + e.ctx.GetSessionVars().StmtCtx.AddAffectedRows(affectedRows) + return err } func (e *SQLBindExec) setBindingStatus() error { @@ -97,6 +121,15 @@ func (e *SQLBindExec) setBindingStatus() error { return err } +func (e *SQLBindExec) setBindingStatusByDigest() error { + ok, err := domain.GetDomain(e.ctx).BindHandle().SetBindRecordStatusByDigest(e.newStatus, e.sqlDigest) + if err == nil && !ok { + warningMess := errors.New("There are no bindings can be set the status. Please check the SQL text") + e.ctx.GetSessionVars().StmtCtx.AppendWarning(warningMess) + } + return err +} + func (e *SQLBindExec) createSQLBind() error { // For audit log, SQLBindExec execute "explain" statement internally, save and recover stmtctx // is necessary to avoid 'create binding' been recorded as 'explain'. @@ -106,11 +139,13 @@ func (e *SQLBindExec) createSQLBind() error { }() bindInfo := bindinfo.Binding{ - BindSQL: e.bindSQL, - Charset: e.charset, - Collation: e.collation, - Status: bindinfo.Enabled, - Source: bindinfo.Manual, + BindSQL: e.bindSQL, + Charset: e.charset, + Collation: e.collation, + Status: bindinfo.Enabled, + Source: e.source, + SQLDigest: e.sqlDigest, + PlanDigest: e.planDigest, } record := &bindinfo.BindRecord{ OriginalSQL: e.normdOrigSQL, diff --git a/executor/brie.go b/executor/brie.go index f26ae56aa32e4..608cfd6336b52 100644 --- a/executor/brie.go +++ b/executor/brie.go @@ -515,7 +515,7 @@ func (gs *tidbGlueSession) CreateDatabase(ctx context.Context, schema *model.DBI } // CreateTable implements glue.Session -func (gs *tidbGlueSession) CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo) error { +func (gs *tidbGlueSession) CreateTable(ctx context.Context, dbName model.CIStr, table *model.TableInfo, cs ...ddl.CreateTableWithInfoConfigurier) error { d := domain.GetDomain(gs.se).DDL() // 512 is defaultCapOfCreateTable. @@ -533,7 +533,7 @@ func (gs *tidbGlueSession) CreateTable(ctx context.Context, dbName model.CIStr, table.Partition = &newPartition } - return d.CreateTableWithInfo(gs.se, dbName, table, ddl.OnExistIgnore) + return d.CreateTableWithInfo(gs.se, dbName, table, append(cs, ddl.OnExistIgnore)...) } // CreatePlacementPolicy implements glue.Session diff --git a/executor/builder.go b/executor/builder.go index 007fe3a557b16..d44aa2110e047 100644 --- a/executor/builder.go +++ b/executor/builder.go @@ -201,6 +201,10 @@ func (b *executorBuilder) build(p plannercore.Plan) Executor { return b.buildLoadData(v) case *plannercore.LoadStats: return b.buildLoadStats(v) + case *plannercore.LockStats: + return b.buildLockStats(v) + case *plannercore.UnlockStats: + return b.buildUnlockStats(v) case *plannercore.IndexAdvise: return b.buildIndexAdvise(v) case *plannercore.PlanReplayer: @@ -429,7 +433,8 @@ func buildIndexLookUpChecker(b *executorBuilder, p *plannercore.PhysicalIndexLoo tps := make([]*types.FieldType, 0, fullColLen) for _, col := range is.Columns { - tps = append(tps, &(col.FieldType)) + // tps is used to decode the index, we should use the element type of the array if any. + tps = append(tps, col.FieldType.ArrayType()) } if !e.isCommonHandle() { @@ -773,6 +778,7 @@ func (b *executorBuilder) buildShow(v *plannercore.PhysicalShow) Executor { Partition: v.Partition, Column: v.Column, IndexName: v.IndexName, + ResourceGroupName: model.NewCIStr(v.ResourceGroupName), Flag: v.Flag, Roles: v.Roles, User: v.User, @@ -888,9 +894,12 @@ func (b *executorBuilder) buildInsert(v *plannercore.Insert) Executor { b.err = err return nil } - ivs.fkChecks, err = buildFKCheckExecs(b.ctx, ivs.Table, v.FKChecks) - if err != nil { - b.err = err + ivs.fkChecks, b.err = buildFKCheckExecs(b.ctx, ivs.Table, v.FKChecks) + if b.err != nil { + return nil + } + ivs.fkCascades, b.err = b.buildFKCascadeExecs(ivs.Table, v.FKCascades) + if b.err != nil { return nil } @@ -928,6 +937,7 @@ func (b *executorBuilder) buildLoadData(v *plannercore.LoadData) Executor { IgnoreLines: v.IgnoreLines, ColumnAssignments: v.ColumnAssignments, ColumnsAndUserVars: v.ColumnsAndUserVars, + OnDuplicate: v.OnDuplicate, Ctx: b.ctx, } columnNames := loadDataInfo.initFieldMappings() @@ -938,7 +948,7 @@ func (b *executorBuilder) buildLoadData(v *plannercore.LoadData) Executor { } loadDataExec := &LoadDataExec{ baseExecutor: newBaseExecutor(b.ctx, nil, v.ID()), - IsLocal: v.IsLocal, + FileLocRef: v.FileLocRef, OnDuplicate: v.OnDuplicate, loadDataInfo: loadDataInfo, } @@ -957,6 +967,22 @@ func (b *executorBuilder) buildLoadStats(v *plannercore.LoadStats) Executor { return e } +func (b *executorBuilder) buildLockStats(v *plannercore.LockStats) Executor { + e := &LockStatsExec{ + baseExecutor: newBaseExecutor(b.ctx, nil, v.ID()), + Tables: v.Tables, + } + return e +} + +func (b *executorBuilder) buildUnlockStats(v *plannercore.UnlockStats) Executor { + e := &UnlockStatsExec{ + baseExecutor: newBaseExecutor(b.ctx, nil, v.ID()), + Tables: v.Tables, + } + return e +} + func (b *executorBuilder) buildIndexAdvise(v *plannercore.IndexAdvise) Executor { e := &IndexAdviseExec{ baseExecutor: newBaseExecutor(b.ctx, nil, v.ID()), @@ -980,6 +1006,17 @@ func (b *executorBuilder) buildPlanReplayer(v *plannercore.PlanReplayer) Executo } return e } + if v.Capture { + e := &PlanReplayerExec{ + baseExecutor: newBaseExecutor(b.ctx, nil, v.ID()), + CaptureInfo: &PlanReplayerCaptureInfo{ + SQLDigest: v.SQLDigest, + PlanDigest: v.PlanDigest, + }, + } + return e + } + e := &PlanReplayerExec{ baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ID()), DumpInfo: &PlanReplayerDumpInfo{ @@ -1005,14 +1042,14 @@ func (b *executorBuilder) buildReplace(vals *InsertValues) Executor { func (b *executorBuilder) buildGrant(grant *ast.GrantStmt) Executor { e := &GrantExec{ - baseExecutor: newBaseExecutor(b.ctx, nil, 0), - Privs: grant.Privs, - ObjectType: grant.ObjectType, - Level: grant.Level, - Users: grant.Users, - WithGrant: grant.WithGrant, - TLSOptions: grant.TLSOptions, - is: b.is, + baseExecutor: newBaseExecutor(b.ctx, nil, 0), + Privs: grant.Privs, + ObjectType: grant.ObjectType, + Level: grant.Level, + Users: grant.Users, + WithGrant: grant.WithGrant, + AuthTokenOrTLSOptions: grant.AuthTokenOrTLSOptions, + is: b.is, } return e } @@ -1052,7 +1089,12 @@ func (b *executorBuilder) setTelemetryInfo(v *plannercore.DDL) { } b.Ti.PartitionTelemetry.UseAddIntervalPartition = true case ast.AlterTableExchangePartition: - b.Ti.UesExchangePartition = true + b.Ti.UseExchangePartition = true + case ast.AlterTableReorganizePartition: + if b.Ti.PartitionTelemetry == nil { + b.Ti.PartitionTelemetry = &PartitionTelemetryInfo{} + } + b.Ti.PartitionTelemetry.UseReorganizePartition = true } } case *ast.CreateTableStmt: @@ -1089,7 +1131,7 @@ func (b *executorBuilder) setTelemetryInfo(v *plannercore.DDL) { } } case model.PartitionTypeHash: - if !p.Linear && p.Sub == nil { + if p.Sub == nil { b.Ti.PartitionTelemetry.UseTablePartitionHash = true } case model.PartitionTypeList: @@ -1102,6 +1144,8 @@ func (b *executorBuilder) setTelemetryInfo(v *plannercore.DDL) { } } } + case *ast.FlashBackToTimestampStmt: + b.Ti.UseFlashbackToCluster = true } } @@ -1364,17 +1408,6 @@ func (b *executorBuilder) buildMergeJoin(v *plannercore.PhysicalMergeJoin) Execu return e } -func (b *executorBuilder) buildSideEstCount(v *plannercore.PhysicalHashJoin) float64 { - buildSide := v.Children()[v.InnerChildIdx] - if v.UseOuterToBuild { - buildSide = v.Children()[1-v.InnerChildIdx] - } - if buildSide.Stats().HistColl == nil || buildSide.Stats().HistColl.Pseudo { - return 0.0 - } - return buildSide.StatsCount() -} - func (b *executorBuilder) buildHashJoin(v *plannercore.PhysicalHashJoin) Executor { leftExec := b.build(v.Children()[0]) if b.err != nil { @@ -1387,12 +1420,19 @@ func (b *executorBuilder) buildHashJoin(v *plannercore.PhysicalHashJoin) Executo } e := &HashJoinExec{ - baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ID(), leftExec, rightExec), - concurrency: v.Concurrency, - joinType: v.JoinType, - isOuterJoin: v.JoinType.IsOuterJoin(), - useOuterToBuild: v.UseOuterToBuild, + baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ID(), leftExec, rightExec), + probeSideTupleFetcher: &probeSideTupleFetcher{}, + probeWorkers: make([]*probeWorker, v.Concurrency), + buildWorker: &buildWorker{}, + hashJoinCtx: &hashJoinCtx{ + sessCtx: b.ctx, + isOuterJoin: v.JoinType.IsOuterJoin(), + useOuterToBuild: v.UseOuterToBuild, + joinType: v.JoinType, + concurrency: v.Concurrency, + }, } + e.hashJoinCtx.allocPool = e.AllocPool defaultValues := v.DefaultValues lhsTypes, rhsTypes := retTypes(leftExec), retTypes(rightExec) if v.InnerChildIdx == 1 { @@ -1410,44 +1450,67 @@ func (b *executorBuilder) buildHashJoin(v *plannercore.PhysicalHashJoin) Executo leftIsBuildSide := true e.isNullEQ = v.IsNullEQ + var probeKeys, probeNAKeys, buildKeys, buildNAKeys []*expression.Column + var buildSideExec Executor if v.UseOuterToBuild { // update the buildSideEstCount due to changing the build side if v.InnerChildIdx == 1 { - e.buildSideExec, e.buildKeys, e.buildNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys - e.probeSideExec, e.probeKeys, e.probeNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys + buildSideExec, buildKeys, buildNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys + e.probeSideTupleFetcher.probeSideExec, probeKeys, probeNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys e.outerFilter = v.LeftConditions } else { - e.buildSideExec, e.buildKeys, e.buildNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys - e.probeSideExec, e.probeKeys, e.probeNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys + buildSideExec, buildKeys, buildNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys + e.probeSideTupleFetcher.probeSideExec, probeKeys, probeNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys e.outerFilter = v.RightConditions leftIsBuildSide = false } if defaultValues == nil { - defaultValues = make([]types.Datum, e.probeSideExec.Schema().Len()) + defaultValues = make([]types.Datum, e.probeSideTupleFetcher.probeSideExec.Schema().Len()) } } else { if v.InnerChildIdx == 0 { - e.buildSideExec, e.buildKeys, e.buildNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys - e.probeSideExec, e.probeKeys, e.probeNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys + buildSideExec, buildKeys, buildNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys + e.probeSideTupleFetcher.probeSideExec, probeKeys, probeNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys e.outerFilter = v.RightConditions } else { - e.buildSideExec, e.buildKeys, e.buildNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys - e.probeSideExec, e.probeKeys, e.probeNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys + buildSideExec, buildKeys, buildNAKeys = rightExec, v.RightJoinKeys, v.RightNAJoinKeys + e.probeSideTupleFetcher.probeSideExec, probeKeys, probeNAKeys = leftExec, v.LeftJoinKeys, v.LeftNAJoinKeys e.outerFilter = v.LeftConditions leftIsBuildSide = false } if defaultValues == nil { - defaultValues = make([]types.Datum, e.buildSideExec.Schema().Len()) + defaultValues = make([]types.Datum, buildSideExec.Schema().Len()) } } + probeKeyColIdx := make([]int, len(probeKeys)) + probeNAKeColIdx := make([]int, len(probeNAKeys)) + buildKeyColIdx := make([]int, len(buildKeys)) + buildNAKeyColIdx := make([]int, len(buildNAKeys)) + for i := range buildKeys { + buildKeyColIdx[i] = buildKeys[i].Index + } + for i := range buildNAKeys { + buildNAKeyColIdx[i] = buildNAKeys[i].Index + } + for i := range probeKeys { + probeKeyColIdx[i] = probeKeys[i].Index + } + for i := range probeNAKeys { + probeNAKeColIdx[i] = probeNAKeys[i].Index + } isNAJoin := len(v.LeftNAJoinKeys) > 0 - e.buildSideEstCount = b.buildSideEstCount(v) childrenUsedSchema := markChildrenUsedCols(v.Schema(), v.Children()[0].Schema(), v.Children()[1].Schema()) - e.joiners = make([]joiner, e.concurrency) for i := uint(0); i < e.concurrency; i++ { - e.joiners[i] = newJoiner(b.ctx, v.JoinType, v.InnerChildIdx == 0, defaultValues, - v.OtherConditions, lhsTypes, rhsTypes, childrenUsedSchema, isNAJoin) + e.probeWorkers[i] = &probeWorker{ + hashJoinCtx: e.hashJoinCtx, + workerID: i, + joiner: newJoiner(b.ctx, v.JoinType, v.InnerChildIdx == 0, defaultValues, v.OtherConditions, lhsTypes, rhsTypes, childrenUsedSchema, isNAJoin), + probeKeyColIdx: probeKeyColIdx, + probeNAKeyColIdx: probeNAKeColIdx, + } } + e.buildWorker.buildKeyColIdx, e.buildWorker.buildNAKeyColIdx, e.buildWorker.buildSideExec, e.buildWorker.hashJoinCtx = buildKeyColIdx, buildNAKeyColIdx, buildSideExec, e.hashJoinCtx + e.hashJoinCtx.isNullAware = isNAJoin executorCountHashJoinExec.Inc() // We should use JoinKey to construct the type information using by hashing, instead of using the child's schema directly. @@ -1535,7 +1598,7 @@ func (b *executorBuilder) buildHashAgg(v *plannercore.PhysicalHashAgg) Executor e.defaultVal = nil } else { if v.IsFinalAgg() { - e.defaultVal = chunk.NewChunkWithCapacity(retTypes(e), 1) + e.defaultVal = e.ctx.GetSessionVars().GetNewChunkWithCapacity(retTypes(e), 1, 1, e.AllocPool) } } for _, aggDesc := range v.AggFuncs { @@ -1598,7 +1661,7 @@ func (b *executorBuilder) buildStreamAgg(v *plannercore.PhysicalStreamAgg) Execu } else { // Only do this for final agg, see issue #35295, #30923 if v.IsFinalAgg() { - e.defaultVal = chunk.NewChunkWithCapacity(retTypes(e), 1) + e.defaultVal = e.ctx.GetSessionVars().GetNewChunkWithCapacity(retTypes(e), 1, 1, e.AllocPool) } } for i, aggDesc := range v.AggFuncs { @@ -1669,7 +1732,7 @@ func (b *executorBuilder) buildTableDual(v *plannercore.PhysicalTableDual) Execu // `getSnapshotTS` returns for-update-ts if in insert/update/delete/lock statement otherwise the isolation read ts // Please notice that in RC isolation, the above two ts are the same -func (b *executorBuilder) getSnapshotTS() (uint64, error) { +func (b *executorBuilder) getSnapshotTS() (ts uint64, err error) { if b.forDataReaderBuilder { return b.dataReaderTS, nil } @@ -1869,7 +1932,13 @@ func (b *executorBuilder) buildMemTable(v *plannercore.PhysicalMemTable) Executo strings.ToLower(infoschema.TablePlacementPolicies), strings.ToLower(infoschema.TableTrxSummary), strings.ToLower(infoschema.TableVariablesInfo), - strings.ToLower(infoschema.ClusterTableTrxSummary): + strings.ToLower(infoschema.TableUserAttributes), + strings.ToLower(infoschema.ClusterTableTrxSummary), + strings.ToLower(infoschema.TableMemoryUsage), + strings.ToLower(infoschema.TableMemoryUsageOpsHistory), + strings.ToLower(infoschema.ClusterTableMemoryUsage), + strings.ToLower(infoschema.ClusterTableMemoryUsageOpsHistory), + strings.ToLower(infoschema.TableResourceGroups): return &MemTableReaderExec{ baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ID()), table: v.Table, @@ -2252,6 +2321,10 @@ func (b *executorBuilder) buildUpdate(v *plannercore.Update) Executor { if b.err != nil { return nil } + updateExec.fkCascades, b.err = b.buildTblID2FKCascadeExecs(tblID2table, v.FKCascades) + if b.err != nil { + return nil + } return updateExec } @@ -2300,6 +2373,10 @@ func (b *executorBuilder) buildDelete(v *plannercore.Delete) Executor { if b.err != nil { return nil } + deleteExec.fkCascades, b.err = b.buildTblID2FKCascadeExecs(tblID2table, v.FKCascades) + if b.err != nil { + return nil + } return deleteExec } @@ -2512,7 +2589,7 @@ func (b *executorBuilder) buildAnalyzeSamplingPushdown(task plannercore.AnalyzeC SampleSize: int64(opts[ast.AnalyzeOptNumSamples]), SampleRate: sampleRate, SketchSize: maxSketchSize, - ColumnsInfo: util.ColumnsToProto(task.ColsInfo, task.TblInfo.PKIsHandle), + ColumnsInfo: util.ColumnsToProto(task.ColsInfo, task.TblInfo.PKIsHandle, false), ColumnGroups: colGroups, } if task.TblInfo != nil { @@ -2521,7 +2598,7 @@ func (b *executorBuilder) buildAnalyzeSamplingPushdown(task plannercore.AnalyzeC e.analyzePB.ColReq.PrimaryPrefixColumnIds = tables.PrimaryPrefixColumnIDs(task.TblInfo) } } - b.err = plannercore.SetPBColumnsDefaultValue(b.ctx, e.analyzePB.ColReq.ColumnsInfo, task.ColsInfo) + b.err = tables.SetPBColumnsDefaultValue(b.ctx, e.analyzePB.ColReq.ColumnsInfo, task.ColsInfo) return &analyzeTask{taskType: colTask, colExec: e, job: job} } @@ -2673,7 +2750,7 @@ func (b *executorBuilder) buildAnalyzeColumnsPushdown(task plannercore.AnalyzeCo BucketSize: int64(opts[ast.AnalyzeOptNumBuckets]), SampleSize: MaxRegionSampleSize, SketchSize: maxSketchSize, - ColumnsInfo: util.ColumnsToProto(cols, task.HandleCols != nil && task.HandleCols.IsInt()), + ColumnsInfo: util.ColumnsToProto(cols, task.HandleCols != nil && task.HandleCols.IsInt(), false), CmsketchDepth: &depth, CmsketchWidth: &width, } @@ -2703,7 +2780,7 @@ func (b *executorBuilder) buildAnalyzeColumnsPushdown(task plannercore.AnalyzeCo e.analyzePB.Tp = tipb.AnalyzeType_TypeMixed e.commonHandle = task.CommonHandleInfo } - b.err = plannercore.SetPBColumnsDefaultValue(b.ctx, e.analyzePB.ColReq.ColumnsInfo, cols) + b.err = tables.SetPBColumnsDefaultValue(b.ctx, e.analyzePB.ColReq.ColumnsInfo, cols) return &analyzeTask{taskType: colTask, colExec: e, job: job} } @@ -3117,7 +3194,7 @@ func (b *executorBuilder) buildIndexLookUpJoin(v *plannercore.PhysicalIndexJoin) e.innerCtx.hashCols = innerHashCols e.innerCtx.hashCollators = hashCollators - e.joinResult = newFirstChunk(e) + e.joinResult = tryNewCacheChunk(e) executorCounterIndexLookUpJoin.Inc() return e } @@ -3217,7 +3294,11 @@ func (b *executorBuilder) buildIndexLookUpMergeJoin(v *plannercore.PhysicalIndex } func (b *executorBuilder) buildIndexNestedLoopHashJoin(v *plannercore.PhysicalIndexHashJoin) Executor { - e := b.buildIndexLookUpJoin(&(v.PhysicalIndexJoin)).(*IndexLookUpJoin) + join := b.buildIndexLookUpJoin(&(v.PhysicalIndexJoin)) + if b.err != nil { + return nil + } + e := join.(*IndexLookUpJoin) idxHash := &IndexNestedLoopHashJoin{ IndexLookUpJoin: *e, keepOuterOrder: v.KeepOuterOrder, @@ -3330,6 +3411,7 @@ func (b *executorBuilder) buildMPPGather(v *plannercore.PhysicalTableReader) Exe is: b.is, originalPlan: v.GetTablePlan(), startTS: startTs, + mppQueryID: kv.MPPQueryID{QueryTs: getMPPQueryTS(b.ctx), LocalQueryID: getMPPQueryID(b.ctx), ServerID: domain.GetDomain(b.ctx).ServerID()}, } return gather } @@ -3337,10 +3419,6 @@ func (b *executorBuilder) buildMPPGather(v *plannercore.PhysicalTableReader) Exe // buildTableReader builds a table reader executor. It first build a no range table reader, // and then update it ranges from table scan plan. func (b *executorBuilder) buildTableReader(v *plannercore.PhysicalTableReader) Executor { - if v.StoreType != kv.TiKV && b.isStaleness { - b.err = errors.New("stale requests require tikv backend") - return nil - } failpoint.Inject("checkUseMPP", func(val failpoint.Value) { if !b.ctx.GetSessionVars().InRestrictedSQL && val.(bool) != useMPPExecution(b.ctx, v) { if val.(bool) { @@ -3439,17 +3517,43 @@ func buildIndexRangeForEachPartition(ctx sessionctx.Context, usedPartitions []ta return nextRange, nil } -func keyColumnsIncludeAllPartitionColumns(keyColumns []int, pe *tables.PartitionExpr) bool { - tmp := make(map[int]struct{}, len(keyColumns)) - for _, offset := range keyColumns { - tmp[offset] = struct{}{} +func getPartitionKeyColOffsets(keyColIDs []int64, pt table.PartitionedTable) []int { + keyColOffsets := make([]int, len(keyColIDs)) + for i, colID := range keyColIDs { + offset := -1 + for j, col := range pt.Cols() { + if colID == col.ID { + offset = j + break + } + } + if offset == -1 { + return nil + } + keyColOffsets[i] = offset + } + + t, ok := pt.(interface { + PartitionExpr() *tables.PartitionExpr + }) + if !ok { + return nil + } + pe := t.PartitionExpr() + if pe == nil { + return nil + } + + offsetMap := make(map[int]struct{}) + for _, offset := range keyColOffsets { + offsetMap[offset] = struct{}{} } for _, offset := range pe.ColumnOffset { - if _, ok := tmp[offset]; !ok { - return false + if _, ok := offsetMap[offset]; !ok { + return nil } } - return true + return keyColOffsets } func (builder *dataReaderBuilder) prunePartitionForInnerExecutor(tbl table.Table, schema *expression.Schema, partitionInfo *plannercore.PartitionInfo, @@ -3464,15 +3568,6 @@ func (builder *dataReaderBuilder) prunePartitionForInnerExecutor(tbl table.Table return nil, false, nil, err } - // check whether can runtime prune. - type partitionExpr interface { - PartitionExpr() (*tables.PartitionExpr, error) - } - pe, err := tbl.(partitionExpr).PartitionExpr() - if err != nil { - return nil, false, nil, err - } - // recalculate key column offsets if len(lookUpContent) == 0 { return nil, false, nil, nil @@ -3480,37 +3575,17 @@ func (builder *dataReaderBuilder) prunePartitionForInnerExecutor(tbl table.Table if lookUpContent[0].keyColIDs == nil { return nil, false, nil, plannercore.ErrInternal.GenWithStack("cannot get column IDs when dynamic pruning") } - keyColOffsets := make([]int, len(lookUpContent[0].keyColIDs)) - for i, colID := range lookUpContent[0].keyColIDs { - offset := -1 - for j, col := range partitionTbl.Cols() { - if colID == col.ID { - offset = j - break - } - } - if offset == -1 { - return nil, false, nil, plannercore.ErrInternal.GenWithStack("invalid column offset when dynamic pruning") - } - keyColOffsets[i] = offset - } - - offsetMap := make(map[int]bool) - for _, offset := range keyColOffsets { - offsetMap[offset] = true - } - for _, offset := range pe.ColumnOffset { - if _, ok := offsetMap[offset]; !ok { - return condPruneResult, false, nil, nil - } + keyColOffsets := getPartitionKeyColOffsets(lookUpContent[0].keyColIDs, partitionTbl) + if len(keyColOffsets) == 0 { + return condPruneResult, false, nil, nil } locateKey := make([]types.Datum, len(partitionTbl.Cols())) partitions := make(map[int64]table.PhysicalTable) contentPos = make([]int64, len(lookUpContent)) for idx, content := range lookUpContent { - for i, date := range content.keys { - locateKey[keyColOffsets[i]] = date + for i, data := range content.keys { + locateKey[keyColOffsets[i]] = data } p, err := partitionTbl.GetPartitionByRow(builder.ctx, locateKey) if err != nil { @@ -3902,6 +3977,7 @@ func buildNoRangeIndexMergeReader(b *executorBuilder, v *plannercore.PhysicalInd isCorColInPartialFilters: isCorColInPartialFilters, isCorColInTableFilter: isCorColInTableFilter, isCorColInPartialAccess: isCorColInPartialAccess, + isIntersection: v.IsIntersectionType, } collectTable := false e.tableRequest.CollectRangeCounts = &collectTable @@ -3909,6 +3985,9 @@ func buildNoRangeIndexMergeReader(b *executorBuilder, v *plannercore.PhysicalInd } func (b *executorBuilder) buildIndexMergeReader(v *plannercore.PhysicalIndexMergeReader) Executor { + if b.Ti != nil { + b.Ti.UseIndexMerge = true + } ts := v.TablePlans[0].(*plannercore.PhysicalTableScan) if err := b.validCanReadTemporaryOrCacheTable(ts.Table); err != nil { b.err = err @@ -4073,12 +4152,6 @@ func (builder *dataReaderBuilder) buildTableReaderForIndexJoin(ctx context.Conte } tbl, _ := builder.is.TableByID(tbInfo.ID) pt := tbl.(table.PartitionedTable) - pe, err := tbl.(interface { - PartitionExpr() (*tables.PartitionExpr, error) - }).PartitionExpr() - if err != nil { - return nil, err - } partitionInfo := &v.PartitionInfo usedPartitionList, err := builder.partitionPruning(pt, partitionInfo.PruningConds, partitionInfo.PartitionNames, partitionInfo.Columns, partitionInfo.ColumnNames) if err != nil { @@ -4089,15 +4162,19 @@ func (builder *dataReaderBuilder) buildTableReaderForIndexJoin(ctx context.Conte usedPartitions[p.GetPhysicalID()] = p } var kvRanges []kv.KeyRange + var keyColOffsets []int + if len(lookUpContents) > 0 { + keyColOffsets = getPartitionKeyColOffsets(lookUpContents[0].keyColIDs, pt) + } if v.IsCommonHandle { - if len(lookUpContents) > 0 && keyColumnsIncludeAllPartitionColumns(lookUpContents[0].keyCols, pe) { - locateKey := make([]types.Datum, e.Schema().Len()) + if len(keyColOffsets) > 0 { + locateKey := make([]types.Datum, len(pt.Cols())) kvRanges = make([]kv.KeyRange, 0, len(lookUpContents)) // lookUpContentsByPID groups lookUpContents by pid(partition) so that kv ranges for same partition can be merged. lookUpContentsByPID := make(map[int64][]*indexJoinLookUpContent) for _, content := range lookUpContents { - for i, date := range content.keys { - locateKey[content.keyCols[i]] = date + for i, data := range content.keys { + locateKey[keyColOffsets[i]] = data } p, err := pt.GetPartitionByRow(e.ctx, locateKey) if err != nil { @@ -4136,12 +4213,12 @@ func (builder *dataReaderBuilder) buildTableReaderForIndexJoin(ctx context.Conte handles, lookUpContents := dedupHandles(lookUpContents) - if len(lookUpContents) > 0 && keyColumnsIncludeAllPartitionColumns(lookUpContents[0].keyCols, pe) { - locateKey := make([]types.Datum, e.Schema().Len()) + if len(keyColOffsets) > 0 { + locateKey := make([]types.Datum, len(pt.Cols())) kvRanges = make([]kv.KeyRange, 0, len(lookUpContents)) for _, content := range lookUpContents { - for i, date := range content.keys { - locateKey[content.keyCols[i]] = date + for i, data := range content.keys { + locateKey[keyColOffsets[i]] = data } p, err := pt.GetPartitionByRow(e.ctx, locateKey) if err != nil { @@ -4152,13 +4229,13 @@ func (builder *dataReaderBuilder) buildTableReaderForIndexJoin(ctx context.Conte continue } handle := kv.IntHandle(content.keys[0].GetInt64()) - tmp := distsql.TableHandlesToKVRanges(pid, []kv.Handle{handle}) - kvRanges = append(kvRanges, tmp...) + ranges, _ := distsql.TableHandlesToKVRanges(pid, []kv.Handle{handle}) + kvRanges = append(kvRanges, ranges...) } } else { for _, p := range usedPartitionList { - tmp := distsql.TableHandlesToKVRanges(p.GetPhysicalID(), handles) - kvRanges = append(kvRanges, tmp...) + ranges, _ := distsql.TableHandlesToKVRanges(p.GetPhysicalID(), handles) + kvRanges = append(kvRanges, ranges...) } } @@ -4195,32 +4272,37 @@ type kvRangeBuilderFromRangeAndPartition struct { } func (h kvRangeBuilderFromRangeAndPartition) buildKeyRangeSeparately(ranges []*ranger.Range) ([]int64, [][]kv.KeyRange, error) { - ret := make([][]kv.KeyRange, 0, len(h.partitions)) + ret := make([][]kv.KeyRange, len(h.partitions)) pids := make([]int64, 0, len(h.partitions)) - for _, p := range h.partitions { + for i, p := range h.partitions { pid := p.GetPhysicalID() + pids = append(pids, pid) meta := p.Meta() + if len(ranges) == 0 { + continue + } kvRange, err := distsql.TableHandleRangesToKVRanges(h.sctx.GetSessionVars().StmtCtx, []int64{pid}, meta != nil && meta.IsCommonHandle, ranges, nil) if err != nil { return nil, nil, err } - pids = append(pids, pid) - ret = append(ret, kvRange) + ret[i] = kvRange.AppendSelfTo(ret[i]) } return pids, ret, nil } -func (h kvRangeBuilderFromRangeAndPartition) buildKeyRange(ranges []*ranger.Range) ([]kv.KeyRange, error) { - //nolint: prealloc - var ret []kv.KeyRange - for _, p := range h.partitions { +func (h kvRangeBuilderFromRangeAndPartition) buildKeyRange(ranges []*ranger.Range) ([][]kv.KeyRange, error) { + ret := make([][]kv.KeyRange, len(h.partitions)) + if len(ranges) == 0 { + return ret, nil + } + for i, p := range h.partitions { pid := p.GetPhysicalID() meta := p.Meta() kvRange, err := distsql.TableHandleRangesToKVRanges(h.sctx.GetSessionVars().StmtCtx, []int64{pid}, meta != nil && meta.IsCommonHandle, ranges, nil) if err != nil { return nil, err } - ret = append(ret, kvRange...) + ret[i] = kvRange.AppendSelfTo(ret[i]) } return ret, nil } @@ -4267,7 +4349,7 @@ func (builder *dataReaderBuilder) buildTableReaderBase(ctx context.Context, e *T if err != nil { return nil, err } - e.kvRanges = append(e.kvRanges, kvReq.KeyRanges...) + e.kvRanges = kvReq.KeyRanges.AppendSelfTo(e.kvRanges) e.resultHandler = &tableResultHandler{} result, err := builder.SelectResult(ctx, builder.ctx, kvReq, retTypes(e), e.feedback, getPhysicalPlanIDs(e.plans), e.id) if err != nil { @@ -4290,8 +4372,9 @@ func (builder *dataReaderBuilder) buildTableReaderFromHandles(ctx context.Contex } else { b.SetTableHandles(getPhysicalTableID(e.table), handles) } + } else { + b.SetKeyRanges(nil) } - return builder.buildTableReaderBase(ctx, e, b) } @@ -4479,6 +4562,9 @@ func buildRangesForIndexJoin(ctx sessionctx.Context, lookUpContents []*indexJoin func buildKvRangesForIndexJoin(ctx sessionctx.Context, tableID, indexID int64, lookUpContents []*indexJoinLookUpContent, ranges []*ranger.Range, keyOff2IdxOff []int, cwc *plannercore.ColWithCmpFuncManager, memTracker *memory.Tracker, interruptSignal *atomic.Value) (_ []kv.KeyRange, err error) { kvRanges := make([]kv.KeyRange, 0, len(ranges)*len(lookUpContents)) + if len(ranges) == 0 { + return []kv.KeyRange{}, nil + } lastPos := len(ranges[0].LowVal) - 1 sc := ctx.GetSessionVars().StmtCtx tmpDatumRanges := make([]*ranger.Range, 0, len(lookUpContents)) @@ -4491,7 +4577,7 @@ func buildKvRangesForIndexJoin(ctx sessionctx.Context, tableID, indexID int64, l } if cwc == nil { // Index id is -1 means it's a common handle. - var tmpKvRanges []kv.KeyRange + var tmpKvRanges *kv.KeyRanges var err error if indexID == -1 { tmpKvRanges, err = distsql.CommonHandleRangesToKVRanges(sc, []int64{tableID}, ranges) @@ -4501,7 +4587,7 @@ func buildKvRangesForIndexJoin(ctx sessionctx.Context, tableID, indexID int64, l if err != nil { return nil, err } - kvRanges = append(kvRanges, tmpKvRanges...) + kvRanges = tmpKvRanges.AppendSelfTo(kvRanges) continue } nextColRanges, err := cwc.BuildRangesByRow(ctx, content.row) @@ -4538,9 +4624,11 @@ func buildKvRangesForIndexJoin(ctx sessionctx.Context, tableID, indexID int64, l } // Index id is -1 means it's a common handle. if indexID == -1 { - return distsql.CommonHandleRangesToKVRanges(ctx.GetSessionVars().StmtCtx, []int64{tableID}, tmpDatumRanges) + tmpKeyRanges, err := distsql.CommonHandleRangesToKVRanges(ctx.GetSessionVars().StmtCtx, []int64{tableID}, tmpDatumRanges) + return tmpKeyRanges.FirstPartitionRange(), err } - return distsql.IndexRangesToKVRangesWithInterruptSignal(ctx.GetSessionVars().StmtCtx, tableID, indexID, tmpDatumRanges, nil, memTracker, interruptSignal) + tmpKeyRanges, err := distsql.IndexRangesToKVRangesWithInterruptSignal(ctx.GetSessionVars().StmtCtx, tableID, indexID, tmpDatumRanges, nil, memTracker, interruptSignal) + return tmpKeyRanges.FirstPartitionRange(), err } func (b *executorBuilder) buildWindow(v *plannercore.PhysicalWindow) Executor { @@ -4733,6 +4821,9 @@ func (b *executorBuilder) buildSQLBindExec(v *plannercore.SQLBindPlan) Executor isGlobal: v.IsGlobal, bindAst: v.BindStmt, newStatus: v.NewStatus, + source: v.Source, + sqlDigest: v.SQLDigest, + planDigest: v.PlanDigest, } return e } @@ -4822,13 +4913,13 @@ func (b *executorBuilder) buildBatchPointGet(plan *plannercore.BatchPointGetPlan if e.ctx.GetSessionVars().IsReplicaReadClosestAdaptive() { e.snapshot.SetOption(kv.ReplicaReadAdjuster, newReplicaReadAdjuster(e.ctx, plan.GetAvgRowSize())) } + e.snapshot.SetOption(kv.ResourceGroupName, b.ctx.GetSessionVars().ResourceGroupName) if e.runtimeStats != nil { snapshotStats := &txnsnapshot.SnapshotRuntimeStats{} e.stats = &runtimeStatsWithSnapshot{ SnapshotRuntimeStats: snapshotStats, } e.snapshot.SetOption(kv.CollectRuntimeStats, snapshotStats) - b.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } if plan.IndexInfo != nil { @@ -5224,6 +5315,10 @@ func (b *executorBuilder) buildCompactTable(v *plannercore.CompactTable) Executo } partitionIDs = append(partitionIDs, partitionID) } + if b.Ti.PartitionTelemetry == nil { + b.Ti.PartitionTelemetry = &PartitionTelemetryInfo{} + } + b.Ti.PartitionTelemetry.UseCompactTablePartition = true } return &CompactTableTiFlashExec{ diff --git a/executor/charset_test.go b/executor/charset_test.go index 72dd9351f1b6c..d40bc6a2fe296 100644 --- a/executor/charset_test.go +++ b/executor/charset_test.go @@ -101,9 +101,9 @@ func TestCharsetWithPrefixIndex(t *testing.T) { tk.MustExec("use test") tk.MustExec("create table t(a char(20) charset gbk, b char(20) charset gbk, primary key (a(2)))") tk.MustExec("insert into t values ('a', '中文'), ('中文', '中文'), ('一二三', '一二三'), ('b', '一二三')") - tk.MustQuery("select * from t").Check(testkit.Rows("a 中文", "中文 中文", "一二三 一二三", "b 一二三")) + tk.MustQuery("select * from t;").Sort().Check(testkit.Rows("a 中文", "b 一二三", "一二三 一二三", "中文 中文")) tk.MustExec("drop table t") tk.MustExec("create table t(a char(20) charset gbk, b char(20) charset gbk, unique index idx_a(a(2)))") tk.MustExec("insert into t values ('a', '中文'), ('中文', '中文'), ('一二三', '一二三'), ('b', '一二三')") - tk.MustQuery("select * from t").Check(testkit.Rows("a 中文", "中文 中文", "一二三 一二三", "b 一二三")) + tk.MustQuery("select * from t;").Sort().Check(testkit.Rows("a 中文", "b 一二三", "一二三 一二三", "中文 中文")) } diff --git a/executor/checksum.go b/executor/checksum.go index a23ec0b577b48..845c1b85d4c66 100644 --- a/executor/checksum.go +++ b/executor/checksum.go @@ -246,6 +246,7 @@ func (c *checksumContext) buildTableRequest(ctx sessionctx.Context, tableID int6 SetChecksumRequest(checksum). SetStartTS(c.StartTs). SetConcurrency(ctx.GetSessionVars().DistSQLScanConcurrency()). + SetResourceGroupName(ctx.GetSessionVars().ResourceGroupName). Build() } @@ -263,6 +264,7 @@ func (c *checksumContext) buildIndexRequest(ctx sessionctx.Context, tableID int6 SetChecksumRequest(checksum). SetStartTS(c.StartTs). SetConcurrency(ctx.GetSessionVars().DistSQLScanConcurrency()). + SetResourceGroupName(ctx.GetSessionVars().ResourceGroupName). Build() } @@ -272,7 +274,7 @@ func (c *checksumContext) HandleResponse(update *tipb.ChecksumResponse) { func getChecksumTableConcurrency(ctx sessionctx.Context) (int, error) { sessionVars := ctx.GetSessionVars() - concurrency, err := sessionVars.GetSessionOrGlobalSystemVar(variable.TiDBChecksumTableConcurrency) + concurrency, err := sessionVars.GetSessionOrGlobalSystemVar(context.Background(), variable.TiDBChecksumTableConcurrency) if err != nil { return 0, err } diff --git a/executor/compiler.go b/executor/compiler.go index 8f0ac913a30f1..9f089eed9bae0 100644 --- a/executor/compiler.go +++ b/executor/compiler.go @@ -76,7 +76,7 @@ func (c *Compiler) Compile(ctx context.Context, stmtNode ast.StmtNode) (_ *ExecS c.Ctx.GetSessionVars().StmtCtx.IsReadOnly = plannercore.IsReadOnly(stmtNode, c.Ctx.GetSessionVars()) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(c.Ctx, + err = plannercore.Preprocess(ctx, c.Ctx, stmtNode, plannercore.WithPreprocessorReturn(ret), plannercore.InitTxnContextProvider, @@ -154,6 +154,9 @@ func (c *Compiler) Compile(ctx context.Context, stmtNode ast.StmtNode) (_ *ExecS } } } + if err = sessiontxn.OptimizeWithPlanAndThenWarmUp(c.Ctx, stmt.Plan); err != nil { + return nil, err + } return stmt, nil } diff --git a/executor/coprocessor.go b/executor/coprocessor.go index 93a23dd6829ca..7a3389026c561 100644 --- a/executor/coprocessor.go +++ b/executor/coprocessor.go @@ -59,9 +59,10 @@ func (h *CoprocessorDAGHandler) HandleRequest(ctx context.Context, req *coproces return h.buildErrorResponse(err) } - chk := newFirstChunk(e) + chk := tryNewCacheChunk(e) tps := e.base().retFieldTypes var totalChunks, partChunks []tipb.Chunk + memTracker := h.sctx.GetSessionVars().StmtCtx.MemTracker for { chk.Reset() err = Next(ctx, e, chk) @@ -75,6 +76,9 @@ func (h *CoprocessorDAGHandler) HandleRequest(ctx context.Context, req *coproces if err != nil { return h.buildErrorResponse(err) } + for _, ch := range partChunks { + memTracker.Consume(int64(ch.Size())) + } totalChunks = append(totalChunks, partChunks...) } if err := e.Close(); err != nil { @@ -95,7 +99,7 @@ func (h *CoprocessorDAGHandler) HandleStreamRequest(ctx context.Context, req *co return stream.Send(h.buildErrorResponse(err)) } - chk := newFirstChunk(e) + chk := tryNewCacheChunk(e) tps := e.base().retFieldTypes for { chk.Reset() diff --git a/executor/cte.go b/executor/cte.go index 84389f9439214..4ae6113008fdf 100644 --- a/executor/cte.go +++ b/executor/cte.go @@ -234,7 +234,7 @@ func (e *CTEExec) computeSeedPart(ctx context.Context) (err error) { if e.limitDone(e.iterInTbl) { break } - chk := newFirstChunk(e.seedExec) + chk := tryNewCacheChunk(e.seedExec) if err = Next(ctx, e.seedExec, chk); err != nil { return err } @@ -273,7 +273,7 @@ func (e *CTEExec) computeRecursivePart(ctx context.Context) (err error) { } for { - chk := newFirstChunk(e.recursiveExec) + chk := tryNewCacheChunk(e.recursiveExec) if err = Next(ctx, e.recursiveExec, chk); err != nil { return err } @@ -438,7 +438,7 @@ func setupCTEStorageTracker(tbl cteutil.Storage, ctx sessionctx.Context, parentM actionSpill = tbl.(*cteutil.StorageRC).ActionSpillForTest() } }) - ctx.GetSessionVars().StmtCtx.MemTracker.FallbackOldAndSetNewAction(actionSpill) + ctx.GetSessionVars().MemTracker.FallbackOldAndSetNewAction(actionSpill) } return actionSpill } diff --git a/executor/ddl.go b/executor/ddl.go index 1fd2b20eb70a1..be8ffa4e48d9f 100644 --- a/executor/ddl.go +++ b/executor/ddl.go @@ -30,7 +30,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/planner/core" - "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/sessiontxn/staleread" @@ -150,10 +149,12 @@ func (e *DDLExec) Next(ctx context.Context, req *chunk.Chunk) (err error) { err = e.executeCreateIndex(x) case *ast.CreateDatabaseStmt: err = e.executeCreateDatabase(x) + case *ast.FlashBackDatabaseStmt: + err = e.executeFlashbackDatabase(x) case *ast.CreateTableStmt: err = e.executeCreateTable(x) case *ast.CreateViewStmt: - err = e.executeCreateView(x) + err = e.executeCreateView(ctx, x) case *ast.DropIndexStmt: err = e.executeDropIndex(x) case *ast.DropDatabaseStmt: @@ -171,8 +172,14 @@ func (e *DDLExec) Next(ctx context.Context, req *chunk.Chunk) (err error) { err = e.executeRecoverTable(x) case *ast.FlashBackTableStmt: err = e.executeFlashbackTable(x) - case *ast.FlashBackClusterStmt: - err = e.executeFlashBackCluster(ctx, x) + case *ast.FlashBackToTimestampStmt: + if len(x.Tables) != 0 { + err = dbterror.ErrGeneralUnsupportedDDL.GenWithStack("Unsupported FLASHBACK table TO TIMESTAMP") + } else if x.DBName.O != "" { + err = dbterror.ErrGeneralUnsupportedDDL.GenWithStack("Unsupported FLASHBACK database TO TIMESTAMP") + } else { + err = e.executeFlashBackCluster(x) + } case *ast.RenameTableStmt: err = e.executeRenameTable(x) case *ast.TruncateTableStmt: @@ -197,6 +204,12 @@ func (e *DDLExec) Next(ctx context.Context, req *chunk.Chunk) (err error) { err = e.executeDropPlacementPolicy(x) case *ast.AlterPlacementPolicyStmt: err = e.executeAlterPlacementPolicy(x) + case *ast.CreateResourceGroupStmt: + err = e.executeCreateResourceGroup(x) + case *ast.DropResourceGroupStmt: + err = e.executeDropResourceGroup(x) + case *ast.AlterResourceGroupStmt: + err = e.executeAlterResourceGroup(x) } if err != nil { // If the owner return ErrTableNotExists error when running this DDL, it may be caused by schema changed, @@ -281,9 +294,9 @@ func (e *DDLExec) createSessionTemporaryTable(s *ast.CreateTableStmt) error { return nil } -func (e *DDLExec) executeCreateView(s *ast.CreateViewStmt) error { +func (e *DDLExec) executeCreateView(ctx context.Context, s *ast.CreateViewStmt) error { ret := &core.PreprocessorReturn{} - err := core.Preprocess(e.ctx, s.Select, core.WithPreprocessorReturn(ret)) + err := core.Preprocess(ctx, e.ctx, s.Select, core.WithPreprocessorReturn(ret)) if err != nil { return errors.Trace(err) } @@ -523,20 +536,7 @@ func (e *DDLExec) getRecoverTableByTableName(tableName *ast.TableName) (*model.J return jobInfo, tableInfo, nil } -func (e *DDLExec) executeFlashBackCluster(ctx context.Context, s *ast.FlashBackClusterStmt) error { - checker := privilege.GetPrivilegeManager(e.ctx) - if !checker.RequestVerification(e.ctx.GetSessionVars().ActiveRoles, "", "", "", mysql.SuperPriv) { - return core.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER") - } - - tiFlashInfo, err := getTiFlashStores(e.ctx) - if err != nil { - return err - } - if len(tiFlashInfo) != 0 { - return errors.Errorf("not support flash back cluster with TiFlash stores") - } - +func (e *DDLExec) executeFlashBackCluster(s *ast.FlashBackToTimestampStmt) error { flashbackTS, err := staleread.CalculateAsOfTsExpr(e.ctx, s.FlashbackTS) if err != nil { return err @@ -583,6 +583,108 @@ func (e *DDLExec) executeFlashbackTable(s *ast.FlashBackTableStmt) error { return err } +// executeFlashbackDatabase represents a restore schema executor. +// It is built from "flashback schema" statement, +// is used to recover the schema that deleted by mistake. +func (e *DDLExec) executeFlashbackDatabase(s *ast.FlashBackDatabaseStmt) error { + dbName := s.DBName + if len(s.NewName) > 0 { + dbName = model.NewCIStr(s.NewName) + } + // Check the Schema Name was not exists. + is := domain.GetDomain(e.ctx).InfoSchema() + if is.SchemaExists(dbName) { + return infoschema.ErrDatabaseExists.GenWithStackByArgs(dbName) + } + recoverSchemaInfo, err := e.getRecoverDBByName(s.DBName) + if err != nil { + return err + } + // Check the Schema ID was not exists. + if schema, ok := is.SchemaByID(recoverSchemaInfo.ID); ok { + return infoschema.ErrDatabaseExists.GenWithStack("Schema '%-.192s' already been recover to '%-.192s', can't be recover repeatedly", s.DBName, schema.Name.O) + } + recoverSchemaInfo.Name = dbName + // Call DDL RecoverSchema. + err = domain.GetDomain(e.ctx).DDL().RecoverSchema(e.ctx, recoverSchemaInfo) + return err +} + +func (e *DDLExec) getRecoverDBByName(schemaName model.CIStr) (recoverSchemaInfo *ddl.RecoverSchemaInfo, err error) { + txn, err := e.ctx.Txn(true) + if err != nil { + return nil, err + } + gcSafePoint, err := gcutil.GetGCSafePoint(e.ctx) + if err != nil { + return nil, err + } + dom := domain.GetDomain(e.ctx) + fn := func(jobs []*model.Job) (bool, error) { + for _, job := range jobs { + // Check GC safe point for getting snapshot infoSchema. + err = gcutil.ValidateSnapshotWithGCSafePoint(job.StartTS, gcSafePoint) + if err != nil { + return false, err + } + if job.Type != model.ActionDropSchema { + continue + } + snapMeta, err := dom.GetSnapshotMeta(job.StartTS) + if err != nil { + return false, err + } + schemaInfo, err := snapMeta.GetDatabase(job.SchemaID) + if err != nil { + return false, err + } + if schemaInfo == nil { + // The dropped DDL maybe execute failed that caused by the parallel DDL execution, + // then can't find the schema from the snapshot info-schema. Should just ignore error here, + // see more in TestParallelDropSchemaAndDropTable. + continue + } + if schemaInfo.Name.L != schemaName.L { + continue + } + tables, err := snapMeta.ListTables(job.SchemaID) + if err != nil { + return false, err + } + recoverTabsInfo := make([]*ddl.RecoverInfo, 0) + for _, tblInfo := range tables { + autoIDs, err := snapMeta.GetAutoIDAccessors(job.SchemaID, tblInfo.ID).Get() + if err != nil { + return false, err + } + recoverTabsInfo = append(recoverTabsInfo, &ddl.RecoverInfo{ + SchemaID: job.SchemaID, + TableInfo: tblInfo, + DropJobID: job.ID, + SnapshotTS: job.StartTS, + AutoIDs: autoIDs, + OldSchemaName: schemaName.L, + OldTableName: tblInfo.Name.L, + }) + } + recoverSchemaInfo = &ddl.RecoverSchemaInfo{DBInfo: schemaInfo, RecoverTabsInfo: recoverTabsInfo, DropJobID: job.ID, SnapshotTS: job.StartTS, OldSchemaName: schemaName} + return true, nil + } + return false, nil + } + err = ddl.IterHistoryDDLJobs(txn, fn) + if err != nil { + if terror.ErrorEqual(variable.ErrSnapshotTooOld, err) { + return nil, errors.Errorf("Can't find dropped database '%s' in GC safe point %s", schemaName.O, model.TSConvert2Time(gcSafePoint).String()) + } + return nil, err + } + if recoverSchemaInfo == nil { + return nil, errors.Errorf("Can't find dropped database: %v in DDL history jobs", schemaName.O) + } + return +} + func (e *DDLExec) executeLockTables(s *ast.LockTablesStmt) error { if !config.TableLockEnabled() { e.ctx.GetSessionVars().StmtCtx.AppendWarning(ErrFuncNotEnabled.GenWithStackByArgs("LOCK TABLES", "enable-table-lock")) @@ -639,3 +741,24 @@ func (e *DDLExec) executeDropPlacementPolicy(s *ast.DropPlacementPolicyStmt) err func (e *DDLExec) executeAlterPlacementPolicy(s *ast.AlterPlacementPolicyStmt) error { return domain.GetDomain(e.ctx).DDL().AlterPlacementPolicy(e.ctx, s) } + +func (e *DDLExec) executeCreateResourceGroup(s *ast.CreateResourceGroupStmt) error { + if !variable.EnableResourceControl.Load() { + return infoschema.ErrResourceGroupSupportDisabled + } + return domain.GetDomain(e.ctx).DDL().CreateResourceGroup(e.ctx, s) +} + +func (e *DDLExec) executeAlterResourceGroup(s *ast.AlterResourceGroupStmt) error { + if !variable.EnableResourceControl.Load() { + return infoschema.ErrResourceGroupSupportDisabled + } + return domain.GetDomain(e.ctx).DDL().AlterResourceGroup(e.ctx, s) +} + +func (e *DDLExec) executeDropResourceGroup(s *ast.DropResourceGroupStmt) error { + if !variable.EnableResourceControl.Load() { + return infoschema.ErrResourceGroupSupportDisabled + } + return domain.GetDomain(e.ctx).DDL().DropResourceGroup(e.ctx, s) +} diff --git a/executor/ddl_test.go b/executor/ddl_test.go index 58f6fe1215975..9c19483f0d94c 100644 --- a/executor/ddl_test.go +++ b/executor/ddl_test.go @@ -39,6 +39,7 @@ import ( "github.com/pingcap/tidb/parser/terror" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/sessionctx/variable/featuretag/distributereorg" "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/table" @@ -79,10 +80,8 @@ func TestInTxnExecDDLFail(t *testing.T) { tk.MustExec("insert into t values (1);") tk.MustExec("begin;") tk.MustExec("insert into t values (1);") - _, err := tk.Exec("truncate table t;") - require.EqualError(t, err, "[kv:1062]Duplicate entry '1' for key 'PRIMARY'") - result := tk.MustQuery("select count(*) from t") - result.Check(testkit.Rows("1")) + tk.MustGetErrMsg("truncate table t;", "[kv:1062]Duplicate entry '1' for key 't.PRIMARY'") + tk.MustQuery("select count(*) from t").Check(testkit.Rows("1")) } func TestInTxnExecDDLInvalid(t *testing.T) { @@ -212,11 +211,9 @@ func TestCreateView(t *testing.T) { // test create a exist view tk.MustExec("CREATE VIEW view_t AS select id , name from source_table") defer tk.MustExec("DROP VIEW IF EXISTS view_t") - _, err := tk.Exec("CREATE VIEW view_t AS select id , name from source_table") - require.EqualError(t, err, "[schema:1050]Table 'test.view_t' already exists") + tk.MustGetErrMsg("CREATE VIEW view_t AS select id , name from source_table", "[schema:1050]Table 'test.view_t' already exists") // create view on nonexistent table - _, err = tk.Exec("create view v1 (c,d) as select a,b from t1") - require.EqualError(t, err, "[schema:1146]Table 'test.t1' doesn't exist") + tk.MustGetErrMsg("create view v1 (c,d) as select a,b from t1", "[schema:1146]Table 'test.t1' doesn't exist") // simple view tk.MustExec("create table t1 (a int ,b int)") tk.MustExec("insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)") @@ -231,26 +228,22 @@ func TestCreateView(t *testing.T) { // view with select wild card tk.MustExec("create view v5 as select * from t1") tk.MustExec("create view v6 (c,d) as select * from t1") - _, err = tk.Exec("create view v7 (c,d,e) as select * from t1") - require.Equal(t, dbterror.ErrViewWrongList.Error(), err.Error()) + tk.MustGetErrCode("create view v7 (c,d,e) as select * from t1", errno.ErrViewWrongList) // drop multiple views in a statement tk.MustExec("drop view v1,v2,v3,v4,v5,v6") // view with variable tk.MustExec("create view v1 (c,d) as select a,b+@@global.max_user_connections from t1") - _, err = tk.Exec("create view v1 (c,d) as select a,b from t1 where a = @@global.max_user_connections") - require.EqualError(t, err, "[schema:1050]Table 'test.v1' already exists") + tk.MustGetErrMsg("create view v1 (c,d) as select a,b from t1 where a = @@global.max_user_connections", "[schema:1050]Table 'test.v1' already exists") tk.MustExec("drop view v1") // view with different col counts - _, err = tk.Exec("create view v1 (c,d,e) as select a,b from t1 ") - require.Equal(t, dbterror.ErrViewWrongList.Error(), err.Error()) - _, err = tk.Exec("create view v1 (c) as select a,b from t1 ") - require.Equal(t, dbterror.ErrViewWrongList.Error(), err.Error()) + tk.MustGetErrCode("create view v1 (c,d,e) as select a,b from t1 ", errno.ErrViewWrongList) + tk.MustGetErrCode("create view v1 (c) as select a,b from t1 ", errno.ErrViewWrongList) // view with or_replace flag tk.MustExec("drop view if exists v1") tk.MustExec("create view v1 (c,d) as select a,b from t1") tk.MustExec("create or replace view v1 (c,d) as select a,b from t1 ") tk.MustExec("create table if not exists t1 (a int ,b int)") - _, err = tk.Exec("create or replace view t1 as select * from t1") + err := tk.ExecToErr("create or replace view t1 as select * from t1") require.Equal(t, dbterror.ErrWrongObject.GenWithStackByArgs("test", "t1", "VIEW").Error(), err.Error()) // create view using prepare tk.MustExec(`prepare stmt from "create view v10 (x) as select 1";`) @@ -259,8 +252,7 @@ func TestCreateView(t *testing.T) { // create view on union tk.MustExec("drop table if exists t1, t2") tk.MustExec("drop view if exists v") - _, err = tk.Exec("create view v as select * from t1 union select * from t2") - require.True(t, terror.ErrorEqual(err, infoschema.ErrTableNotExists)) + tk.MustGetDBError("create view v as select * from t1 union select * from t2", infoschema.ErrTableNotExists) tk.MustExec("create table t1(a int, b int)") tk.MustExec("create table t2(a int, b int)") tk.MustExec("insert into t1 values(1,2), (1,1), (1,2)") @@ -268,14 +260,12 @@ func TestCreateView(t *testing.T) { tk.MustExec("create definer='root'@'localhost' view v as select * from t1 union select * from t2") tk.MustQuery("select * from v").Sort().Check(testkit.Rows("1 1", "1 2", "1 3")) tk.MustExec("alter table t1 drop column a") - _, err = tk.Exec("select * from v") - require.True(t, terror.ErrorEqual(err, plannercore.ErrViewInvalid)) + tk.MustGetDBError("select * from v", plannercore.ErrViewInvalid) tk.MustExec("alter table t1 add column a int") tk.MustQuery("select * from v").Sort().Check(testkit.Rows("1 1", "1 3", " 1", " 2")) tk.MustExec("alter table t1 drop column a") tk.MustExec("alter table t2 drop column b") - _, err = tk.Exec("select * from v") - require.True(t, terror.ErrorEqual(err, plannercore.ErrViewInvalid)) + tk.MustGetDBError("select * from v", plannercore.ErrViewInvalid) tk.MustExec("drop view v") tk.MustExec("create view v as (select * from t1)") @@ -294,8 +284,7 @@ func TestCreateView(t *testing.T) { tk.MustExec("create table test_v_nested(a int)") tk.MustExec("create definer='root'@'localhost' view v_nested as select * from test_v_nested") tk.MustExec("create definer='root'@'localhost' view v_nested2 as select * from v_nested") - _, err = tk.Exec("create or replace definer='root'@'localhost' view v_nested as select * from v_nested2") - require.True(t, terror.ErrorEqual(err, plannercore.ErrNoSuchTable)) + tk.MustGetDBError("create or replace definer='root'@'localhost' view v_nested as select * from v_nested2", plannercore.ErrNoSuchTable) tk.MustExec("drop table test_v_nested") tk.MustExec("drop view v_nested, v_nested2") @@ -322,8 +311,7 @@ func TestViewRecursion(t *testing.T) { tk.MustExec("create definer='root'@'localhost' view recursive_view2 as select * from recursive_view1") tk.MustExec("drop table t") tk.MustExec("rename table recursive_view2 to t") - _, err := tk.Exec("select * from recursive_view1") - require.True(t, terror.ErrorEqual(err, plannercore.ErrViewRecursive)) + tk.MustGetDBError("select * from recursive_view1", plannercore.ErrViewRecursive) tk.MustExec("drop view recursive_view1, t") } @@ -333,8 +321,8 @@ func TestIssue16250(t *testing.T) { tk.MustExec("use test") tk.MustExec("create table if not exists t(a int)") tk.MustExec("create view view_issue16250 as select * from t") - _, err := tk.Exec("truncate table view_issue16250") - require.EqualError(t, err, "[schema:1146]Table 'test.view_issue16250' doesn't exist") + tk.MustGetErrMsg("truncate table view_issue16250", + "[schema:1146]Table 'test.view_issue16250' doesn't exist") } func TestIssue24771(t *testing.T) { @@ -564,12 +552,23 @@ func TestAlterTableAddColumn(t *testing.T) { tk.MustExec("alter table alter_test add column c3 varchar(50) default 'CURRENT_TIMESTAMP'") tk.MustQuery("select c3 from alter_test").Check(testkit.Rows("CURRENT_TIMESTAMP")) tk.MustExec("create or replace view alter_view as select c1,c2 from alter_test") - _, err = tk.Exec("alter table alter_view add column c4 varchar(50)") + err = tk.ExecToErr("alter table alter_view add column c4 varchar(50)") require.Equal(t, dbterror.ErrWrongObject.GenWithStackByArgs("test", "alter_view", "BASE TABLE").Error(), err.Error()) tk.MustExec("drop view alter_view") tk.MustExec("create sequence alter_seq") - _, err = tk.Exec("alter table alter_seq add column c int") + err = tk.ExecToErr("alter table alter_seq add column c int") require.Equal(t, dbterror.ErrWrongObject.GenWithStackByArgs("test", "alter_seq", "BASE TABLE").Error(), err.Error()) + tk.MustExec("alter table alter_test add column c4 date default current_date") + now = time.Now().Format(types.DateFormat) + r, err = tk.Exec("select c4 from alter_test") + require.NoError(t, err) + req = r.NewChunk(nil) + err = r.Next(context.Background(), req) + require.NoError(t, err) + row = req.GetRow(0) + require.Equal(t, 1, row.Len()) + require.GreaterOrEqual(t, now, row.GetTime(0).String()) + require.Nil(t, r.Close()) tk.MustExec("drop sequence alter_seq") } @@ -591,11 +590,11 @@ func TestAlterTableAddColumns(t *testing.T) { require.Nil(t, r.Close()) tk.MustQuery("select c3 from alter_test").Check(testkit.Rows("CURRENT_TIMESTAMP")) tk.MustExec("create or replace view alter_view as select c1,c2 from alter_test") - _, err = tk.Exec("alter table alter_view add column (c4 varchar(50), c5 varchar(50))") + err = tk.ExecToErr("alter table alter_view add column (c4 varchar(50), c5 varchar(50))") require.Equal(t, dbterror.ErrWrongObject.GenWithStackByArgs("test", "alter_view", "BASE TABLE").Error(), err.Error()) tk.MustExec("drop view alter_view") tk.MustExec("create sequence alter_seq") - _, err = tk.Exec("alter table alter_seq add column (c1 int, c2 varchar(10))") + err = tk.ExecToErr("alter table alter_seq add column (c1 int, c2 varchar(10))") require.Equal(t, dbterror.ErrWrongObject.GenWithStackByArgs("test", "alter_seq", "BASE TABLE").Error(), err.Error()) tk.MustExec("drop sequence alter_seq") } @@ -662,8 +661,7 @@ func TestAlterTableModifyColumn(t *testing.T) { tk.MustExec("drop table if exists modify_column_multiple_collate;") tk.MustExec("create table modify_column_multiple_collate (a char(1) collate utf8_bin collate utf8_general_ci) charset utf8mb4 collate utf8mb4_bin") - _, err = tk.Exec("alter table modify_column_multiple_collate modify column a char(1) charset utf8mb4 collate utf8mb4_bin;") - require.NoError(t, err) + tk.MustExec("alter table modify_column_multiple_collate modify column a char(1) charset utf8mb4 collate utf8mb4_bin;") tt, err = domain.GetDomain(tk.Session()).InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("modify_column_multiple_collate")) require.NoError(t, err) require.Equal(t, "utf8mb4", tt.Cols()[0].GetCharset()) @@ -919,10 +917,8 @@ func TestShardRowIDBits(t *testing.T) { tk.MustExec("insert into t1 values(1)") // continue inserting will fail. - _, err = tk.Exec("insert into t1 values(2)") - require.Truef(t, autoid.ErrAutoincReadFailed.Equal(err), "err:%v", err) - _, err = tk.Exec("insert into t1 values(3)") - require.Truef(t, autoid.ErrAutoincReadFailed.Equal(err), "err:%v", err) + tk.MustGetDBError("insert into t1 values(2)", autoid.ErrAutoincReadFailed) + tk.MustGetDBError("insert into t1 values(3)", autoid.ErrAutoincReadFailed) } func TestAutoRandomBitsData(t *testing.T) { @@ -1112,63 +1108,23 @@ func TestAutoRandomTableOption(t *testing.T) { require.Contains(t, err.Error(), autoid.AutoRandomRebaseNotApplicable) } -// Test filter different kind of allocators. -// In special ddl type, for example: -// 1: ActionRenameTable : it will abandon all the old allocators. -// 2: ActionRebaseAutoID : it will drop row-id-type allocator. -// 3: ActionModifyTableAutoIdCache : it will drop row-id-type allocator. -// 3: ActionRebaseAutoRandomBase : it will drop auto-rand-type allocator. -func TestFilterDifferentAllocators(t *testing.T) { +func TestAutoRandomClusteredPrimaryKey(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("drop table if exists t1") + tk.MustExec("create table t (a bigint auto_random(5), b int, primary key (a, b) clustered);") + tk.MustExec("insert into t (b) values (1);") + tk.MustExec("set @@allow_auto_random_explicit_insert = 0;") + tk.MustGetErrCode("insert into t values (100, 2);", errno.ErrInvalidAutoRandom) + tk.MustExec("set @@allow_auto_random_explicit_insert = 1;") + tk.MustExec("insert into t values (100, 2);") + tk.MustQuery("select b from t order by b;").Check(testkit.Rows("1", "2")) + tk.MustExec("alter table t modify column a bigint auto_random(6);") - tk.MustExec("create table t(a bigint auto_random(5) key, b int auto_increment unique)") - tk.MustExec("insert into t values()") - tk.MustQuery("select b from t").Check(testkit.Rows("1")) - allHandles, err := ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t") - require.NoError(t, err) - require.Equal(t, 1, len(allHandles)) - orderedHandles := testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) - require.Equal(t, int64(1), orderedHandles[0]) - tk.MustExec("delete from t") - - // Test rebase auto_increment. - tk.MustExec("alter table t auto_increment 3000000") - tk.MustExec("insert into t values()") - tk.MustQuery("select b from t").Check(testkit.Rows("3000000")) - allHandles, err = ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t") - require.NoError(t, err) - require.Equal(t, 1, len(allHandles)) - orderedHandles = testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) - require.Equal(t, int64(2), orderedHandles[0]) - tk.MustExec("delete from t") - - // Test rebase auto_random. - tk.MustExec("alter table t auto_random_base 3000000") - tk.MustExec("insert into t values()") - tk.MustQuery("select b from t").Check(testkit.Rows("3000001")) - allHandles, err = ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t") - require.NoError(t, err) - require.Equal(t, 1, len(allHandles)) - orderedHandles = testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) - require.Equal(t, int64(3000000), orderedHandles[0]) - tk.MustExec("delete from t") - - // Test rename table. - tk.MustExec("rename table t to t1") - tk.MustExec("insert into t1 values()") - res := tk.MustQuery("select b from t1") - strInt64, err := strconv.ParseInt(res.Rows()[0][0].(string), 10, 64) - require.NoError(t, err) - require.Greater(t, strInt64, int64(3000002)) - allHandles, err = ddltestutil.ExtractAllTableHandles(tk.Session(), "test", "t1") - require.NoError(t, err) - require.Equal(t, 1, len(allHandles)) - orderedHandles = testutil.MaskSortHandles(allHandles, 5, mysql.TypeLonglong) - require.Greater(t, orderedHandles[0], int64(3000001)) + tk.MustExec("drop table t;") + tk.MustExec("create table t (a bigint, b bigint auto_random(4, 32), primary key (b, a) clustered)") + tk.MustExec("insert into t (a) values (1);") + tk.MustQuery("select a from t;").Check(testkit.Rows("1")) } func TestMaxHandleAddIndex(t *testing.T) { @@ -1204,8 +1160,7 @@ func TestSetDDLReorgWorkerCnt(t *testing.T) { err = ddlutil.LoadDDLReorgVars(context.Background(), tk.Session()) require.NoError(t, err) require.Equal(t, int32(100), variable.GetDDLReorgWorkerCounter()) - _, err = tk.Exec("set @@global.tidb_ddl_reorg_worker_cnt = invalid_val") - require.Truef(t, terror.ErrorEqual(err, variable.ErrWrongTypeForVar), "err %v", err) + tk.MustGetDBError("set @@global.tidb_ddl_reorg_worker_cnt = invalid_val", variable.ErrWrongTypeForVar) tk.MustExec("set @@global.tidb_ddl_reorg_worker_cnt = 100") err = ddlutil.LoadDDLReorgVars(context.Background(), tk.Session()) require.NoError(t, err) @@ -1247,8 +1202,7 @@ func TestSetDDLReorgBatchSize(t *testing.T) { err = ddlutil.LoadDDLReorgVars(context.Background(), tk.Session()) require.NoError(t, err) require.Equal(t, variable.MaxDDLReorgBatchSize, variable.GetDDLReorgBatchSize()) - _, err = tk.Exec("set @@global.tidb_ddl_reorg_batch_size = invalid_val") - require.True(t, terror.ErrorEqual(err, variable.ErrWrongTypeForVar), "err %v", err) + tk.MustGetDBError("set @@global.tidb_ddl_reorg_batch_size = invalid_val", variable.ErrWrongTypeForVar) tk.MustExec("set @@global.tidb_ddl_reorg_batch_size = 100") err = ddlutil.LoadDDLReorgVars(context.Background(), tk.Session()) require.NoError(t, err) @@ -1355,8 +1309,7 @@ func TestSetDDLErrorCountLimit(t *testing.T) { err = ddlutil.LoadDDLVars(tk.Session()) require.NoError(t, err) require.Equal(t, int64(math.MaxInt64), variable.GetDDLErrorCountLimit()) - _, err = tk.Exec("set @@global.tidb_ddl_error_count_limit = invalid_val") - require.True(t, terror.ErrorEqual(err, variable.ErrWrongTypeForVar), "err %v", err) + tk.MustGetDBError("set @@global.tidb_ddl_error_count_limit = invalid_val", variable.ErrWrongTypeForVar) tk.MustExec("set @@global.tidb_ddl_error_count_limit = 100") err = ddlutil.LoadDDLVars(tk.Session()) require.NoError(t, err) @@ -1365,6 +1318,20 @@ func TestSetDDLErrorCountLimit(t *testing.T) { res.Check(testkit.Rows("100")) } +func TestLoadDDLDistributeVars(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + require.Equal(t, variable.DefTiDBDDLEnableDistributeReorg, distributereorg.TiDBEnableDistributeReorg) + + tk.MustGetDBError("set @@global.tidb_ddl_distribute_reorg = invalid_val", variable.ErrWrongValueForVar) + require.Equal(t, distributereorg.TiDBEnableDistributeReorg, variable.DDLEnableDistributeReorg.Load()) + tk.MustExec("set @@global.tidb_ddl_distribute_reorg = 'on'") + require.Equal(t, true, variable.DDLEnableDistributeReorg.Load()) + tk.MustExec(fmt.Sprintf("set @@global.tidb_ddl_distribute_reorg = %v", distributereorg.TiDBEnableDistributeReorg)) + require.Equal(t, distributereorg.TiDBEnableDistributeReorg, variable.DDLEnableDistributeReorg.Load()) +} + // Test issue #9205, fix the precision problem for time type default values // See https://github.com/pingcap/tidb/issues/9205 for details func TestIssue9205(t *testing.T) { @@ -1413,39 +1380,21 @@ func TestCheckDefaultFsp(t *testing.T) { tk.MustExec("use test") tk.MustExec(`drop table if exists t;`) - _, err := tk.Exec("create table t ( tt timestamp default now(1));") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'tt'") - - _, err = tk.Exec("create table t ( tt timestamp(1) default current_timestamp);") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'tt'") - - _, err = tk.Exec("create table t ( tt timestamp(1) default now(2));") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'tt'") + tk.MustGetErrMsg("create table t ( tt timestamp default now(1));", "[ddl:1067]Invalid default value for 'tt'") + tk.MustGetErrMsg("create table t ( tt timestamp(1) default current_timestamp);", "[ddl:1067]Invalid default value for 'tt'") + tk.MustGetErrMsg("create table t ( tt timestamp(1) default now(2));", "[ddl:1067]Invalid default value for 'tt'") tk.MustExec("create table t ( tt timestamp(1) default now(1));") tk.MustExec("create table t2 ( tt timestamp default current_timestamp());") tk.MustExec("create table t3 ( tt timestamp default current_timestamp(0));") - _, err = tk.Exec("alter table t add column ttt timestamp default now(2);") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'ttt'") - - _, err = tk.Exec("alter table t add column ttt timestamp(5) default current_timestamp;") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'ttt'") - - _, err = tk.Exec("alter table t add column ttt timestamp(5) default now(2);") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'ttt'") - - _, err = tk.Exec("alter table t modify column tt timestamp(1) default now();") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'tt'") - - _, err = tk.Exec("alter table t modify column tt timestamp(4) default now(5);") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'tt'") - - _, err = tk.Exec("alter table t change column tt tttt timestamp(4) default now(5);") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'tttt'") - - _, err = tk.Exec("alter table t change column tt tttt timestamp(1) default now();") - require.EqualError(t, err, "[ddl:1067]Invalid default value for 'tttt'") + tk.MustGetErrMsg("alter table t add column ttt timestamp default now(2);", "[ddl:1067]Invalid default value for 'ttt'") + tk.MustGetErrMsg("alter table t add column ttt timestamp(5) default current_timestamp;", "[ddl:1067]Invalid default value for 'ttt'") + tk.MustGetErrMsg("alter table t add column ttt timestamp(5) default now(2);", "[ddl:1067]Invalid default value for 'ttt'") + tk.MustGetErrMsg("alter table t modify column tt timestamp(1) default now();", "[ddl:1067]Invalid default value for 'tt'") + tk.MustGetErrMsg("alter table t modify column tt timestamp(4) default now(5);", "[ddl:1067]Invalid default value for 'tt'") + tk.MustGetErrMsg("alter table t change column tt tttt timestamp(4) default now(5);", "[ddl:1067]Invalid default value for 'tttt'") + tk.MustGetErrMsg("alter table t change column tt tttt timestamp(1) default now();", "[ddl:1067]Invalid default value for 'tttt'") } func TestTimestampMinDefaultValue(t *testing.T) { @@ -1599,3 +1548,138 @@ func TestRenameMultiTables(t *testing.T) { tk.MustExec("drop database rename2") tk.MustExec("drop database rename3") } + +func TestCreateTableWithTTL(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("CREATE TABLE t (created_at datetime) TTL = `created_at` + INTERVAL 5 DAY") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL 5 DAY */ /*T![ttl] TTL_ENABLE='ON' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + tk.MustExec("DROP TABLE t") + + tk.MustGetErrMsg("CREATE TABLE t (id int) TTL = `id` + INTERVAL 5 DAY", "[ddl:8148]Field 'id' is of a not supported type for TTL config, expect DATETIME, DATE or TIMESTAMP") + + tk.MustGetErrMsg("CREATE TABLE t (id int) TTL_ENABLE = 'ON'", "[ddl:8150]Cannot set TTL_ENABLE on a table without TTL config") + + tk.MustGetErrMsg("CREATE TABLE t (id int) TTL_JOB_INTERVAL = '1h'", "[ddl:8150]Cannot set TTL_JOB_INTERVAL on a table without TTL config") + + tk.MustExec("CREATE TABLE t (created_at datetime) TTL_ENABLE = 'ON' TTL = `created_at` + INTERVAL 1 DAY TTL_ENABLE = 'OFF' TTL_JOB_INTERVAL = '1d'") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL 1 DAY */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1d' */")) + tk.MustExec("DROP TABLE t") + + // when multiple ttl and ttl_enable configs are submitted, only the last one will be handled + tk.MustExec("CREATE TABLE t (created_at datetime) TTL_ENABLE = 'ON' TTL = `created_at` + INTERVAL 1 DAY TTL = `created_at` + INTERVAL 2 DAY TTL = `created_at` + INTERVAL 3 DAY TTL_ENABLE = 'OFF'") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL 3 DAY */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + tk.MustExec("DROP TABLE t") +} + +func TestAlterTTLInfo(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("CREATE TABLE t (created_at datetime, updated_at datetime, wrong_type int) TTL = `created_at` + INTERVAL 5 DAY") + tk.MustExec("ALTER TABLE t TTL = `updated_at` + INTERVAL 2 YEAR") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL,\n `updated_at` datetime DEFAULT NULL,\n `wrong_type` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`updated_at` + INTERVAL 2 YEAR */ /*T![ttl] TTL_ENABLE='ON' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + tk.MustExec("ALTER TABLE t TTL_ENABLE = 'OFF'") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL,\n `updated_at` datetime DEFAULT NULL,\n `wrong_type` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`updated_at` + INTERVAL 2 YEAR */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + tk.MustExec("ALTER TABLE t TTL_JOB_INTERVAL = '1d'") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL,\n `updated_at` datetime DEFAULT NULL,\n `wrong_type` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`updated_at` + INTERVAL 2 YEAR */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1d' */")) + + tk.MustGetErrMsg("ALTER TABLE t TTL = `not_exist` + INTERVAL 2 YEAR", "[ddl:1054]Unknown column 'not_exist' in 'TTL config'") + + tk.MustGetErrMsg("ALTER TABLE t TTL = `wrong_type` + INTERVAL 2 YEAR", "[ddl:8148]Field 'wrong_type' is of a not supported type for TTL config, expect DATETIME, DATE or TIMESTAMP") + + tk.MustGetErrMsg("ALTER TABLE t DROP COLUMN updated_at", "[ddl:8149]Cannot drop column 'updated_at': needed in TTL config") + tk.MustGetErrMsg("ALTER TABLE t CHANGE updated_at updated_at_new INT", "[ddl:8148]Field 'updated_at_new' is of a not supported type for TTL config, expect DATETIME, DATE or TIMESTAMP") + + tk.MustExec("ALTER TABLE t RENAME COLUMN `updated_at` TO `updated_at_2`") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL,\n `updated_at_2` datetime DEFAULT NULL,\n `wrong_type` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`updated_at_2` + INTERVAL 2 YEAR */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1d' */")) + + tk.MustExec("ALTER TABLE t CHANGE `updated_at_2` `updated_at_3` date") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL,\n `updated_at_3` date DEFAULT NULL,\n `wrong_type` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`updated_at_3` + INTERVAL 2 YEAR */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1d' */")) + + tk.MustExec("ALTER TABLE t TTL = `updated_at_3` + INTERVAL 3 YEAR") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL,\n `updated_at_3` date DEFAULT NULL,\n `wrong_type` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`updated_at_3` + INTERVAL 3 YEAR */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1d' */")) + + tk.MustGetErrMsg("ALTER TABLE t TTL_ENABLE = 'OFF' REMOVE TTL", "[ddl:8200]Unsupported multi schema change for alter table ttl") + + tk.MustExec("ALTER TABLE t REMOVE TTL") + tk.MustQuery("SHOW CREATE TABLE t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL,\n `updated_at_3` date DEFAULT NULL,\n `wrong_type` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + tk.MustGetErrMsg("ALTER TABLE t TTL_ENABLE = 'OFF'", "[ddl:8150]Cannot set TTL_ENABLE on a table without TTL config") + + tk.MustGetErrMsg("ALTER TABLE t TTL_JOB_INTERVAL = '1h'", "[ddl:8150]Cannot set TTL_JOB_INTERVAL on a table without TTL config") +} + +func TestDisableTTLForTempTable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustGetDBError("CREATE TEMPORARY TABLE t (created_at datetime) TTL = `created_at` + INTERVAL 5 DAY", dbterror.ErrTempTableNotAllowedWithTTL) +} + +func TestDisableTTLForFKParentTable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + // alter ttl for a FK parent table is not allowed + tk.MustExec("set global tidb_enable_foreign_key='ON'") + tk.MustExec("CREATE TABLE t (id int primary key, created_at datetime)") + tk.MustExec("CREATE TABLE t_1 (t_id int, foreign key fk_t_id(t_id) references t(id))") + tk.MustGetDBError("ALTER TABLE t TTL = created_at + INTERVAL 5 YEAR", dbterror.ErrUnsupportedTTLReferencedByFK) + tk.MustExec("drop table t,t_1") + + // refuse to reference TTL key when create table + tk.MustExec("CREATE TABLE t (id int primary key, created_at datetime) TTL = created_at + INTERVAL 5 YEAR") + tk.MustGetDBError("CREATE TABLE t_1 (t_id int, foreign key fk_t_id(t_id) references t(id))", dbterror.ErrUnsupportedTTLReferencedByFK) + tk.MustExec("drop table t") + + // refuse to add foreign key reference TTL table + tk.MustExec("CREATE TABLE t (id int primary key, created_at datetime) TTL = created_at + INTERVAL 5 YEAR") + tk.MustExec("CREATE TABLE t_1 (t_id int)") + tk.MustGetDBError("ALTER TABLE t_1 ADD FOREIGN KEY fk_t_id(t_id) references t(id)", dbterror.ErrUnsupportedTTLReferencedByFK) + tk.MustExec("drop table t,t_1") +} + +func TestCheckPrimaryKeyForTTLTable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + // create table should fail when pk contains double/float + tk.MustGetDBError("create table t1(id float primary key, t timestamp) TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("create table t1(id float(10,2) primary key, t timestamp) TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("create table t1(id double primary key, t timestamp) TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("create table t1(id float(10,2) primary key, t timestamp) TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("create table t1(id1 int, id2 float, t timestamp, primary key(id1, id2)) TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("create table t1(id1 int, id2 double, t timestamp, primary key(id1, id2)) TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + + // alter table should fail when pk contains double/float + tk.MustExec("create table t1(id float primary key, t timestamp)") + tk.MustExec("create table t2(id double primary key, t timestamp)") + tk.MustExec("create table t3(id1 int, id2 float, primary key(id1, id2), t timestamp)") + tk.MustExec("create table t4(id1 int, id2 double, primary key(id1, id2), t timestamp)") + tk.MustGetDBError("alter table t1 TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("alter table t2 TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("alter table t3 TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + tk.MustGetDBError("alter table t4 TTL=`t`+INTERVAL 1 DAY", dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL) + + // create table should not fail when the pk is not clustered + tk.MustExec("create table t11(id float primary key nonclustered, t timestamp) TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("create table t12(id double primary key nonclustered, t timestamp) TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("create table t13(id1 int, id2 float, t timestamp, primary key(id1, id2) nonclustered) TTL=`t`+INTERVAL 1 DAY") + + // alter table should not fail when the pk is not clustered + tk.MustExec("create table t21(id float primary key nonclustered, t timestamp)") + tk.MustExec("create table t22(id double primary key nonclustered, t timestamp)") + tk.MustExec("create table t23(id1 int, id2 float, t timestamp, primary key(id1, id2) nonclustered)") + tk.MustExec("alter table t21 TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("alter table t22 TTL=`t`+INTERVAL 1 DAY") + tk.MustExec("alter table t23 TTL=`t`+INTERVAL 1 DAY") +} diff --git a/executor/delete.go b/executor/delete.go index 36171eed88826..3fedb55806364 100644 --- a/executor/delete.go +++ b/executor/delete.go @@ -46,6 +46,8 @@ type DeleteExec struct { memTracker *memory.Tracker // fkChecks contains the foreign key checkers. the map is tableID -> []*FKCheckExec fkChecks map[int64][]*FKCheckExec + // fkCascades contains the foreign key cascade. the map is tableID -> []*FKCascadeExec + fkCascades map[int64][]*FKCascadeExec } // Next implements the Executor Next interface. @@ -93,7 +95,7 @@ func (e *DeleteExec) deleteSingleTableByChunk(ctx context.Context) error { batchDelete := e.ctx.GetSessionVars().BatchDelete && !e.ctx.GetSessionVars().InTxn() && variable.EnableBatchDML.Load() && batchDMLSize > 0 fields := retTypes(e.children[0]) - chk := newFirstChunk(e.children[0]) + chk := tryNewCacheChunk(e.children[0]) columns := e.children[0].Schema().Columns if len(columns) != len(fields) { logutil.BgLogger().Error("schema columns and fields mismatch", @@ -151,7 +153,7 @@ func (e *DeleteExec) doBatchDelete(ctx context.Context) error { return ErrBatchInsertFail.GenWithStack("BatchDelete failed with error: %v", err) } e.memTracker.Consume(-int64(txn.Size())) - e.ctx.StmtCommit() + e.ctx.StmtCommit(ctx) if err := sessiontxn.NewTxnInStmt(ctx, e.ctx); err != nil { // We should return a special error for batch insert. return ErrBatchInsertFail.GenWithStack("BatchDelete failed with error: %v", err) @@ -173,8 +175,14 @@ func (e *DeleteExec) composeTblRowMap(tblRowMap tableRowMapType, colPosInfos []p return err } // tblRowMap[info.TblID][handle] hold the row datas binding to this table and this handle. - _, exist := tblRowMap[info.TblID].Get(handle) - memDelta := tblRowMap[info.TblID].Set(handle, joinedRow[info.Start:info.End]) + row, exist := tblRowMap[info.TblID].Get(handle) + if !exist { + row = make([]types.Datum, info.End-info.Start) + } + for i, d := range joinedRow[info.Start:info.End] { + d.Copy(&row[i]) + } + memDelta := tblRowMap[info.TblID].Set(handle, row) if !exist { memDelta += types.EstimatedMemUsage(joinedRow, 1) memDelta += int64(handle.ExtraMemSize()) @@ -188,8 +196,9 @@ func (e *DeleteExec) deleteMultiTablesByChunk(ctx context.Context) error { colPosInfos := e.tblColPosInfos tblRowMap := make(tableRowMapType) fields := retTypes(e.children[0]) - chk := newFirstChunk(e.children[0]) + chk := tryNewCacheChunk(e.children[0]) memUsageOfChk := int64(0) + joinedDatumRowBuffer := make([]types.Datum, len(fields)) for { e.memTracker.Consume(-memUsageOfChk) iter := chunk.NewIterator4Chunk(chk) @@ -204,13 +213,13 @@ func (e *DeleteExec) deleteMultiTablesByChunk(ctx context.Context) error { e.memTracker.Consume(memUsageOfChk) for joinedChunkRow := iter.Begin(); joinedChunkRow != iter.End(); joinedChunkRow = iter.Next() { - joinedDatumRow := joinedChunkRow.GetDatumRow(fields) - err := e.composeTblRowMap(tblRowMap, colPosInfos, joinedDatumRow) + joinedDatumRowBuffer = joinedChunkRow.GetDatumRowWithBuffer(fields, joinedDatumRowBuffer) + err := e.composeTblRowMap(tblRowMap, colPosInfos, joinedDatumRowBuffer) if err != nil { return err } } - chk = chunk.Renew(chk, e.maxChunkSize) + chk = tryNewCacheChunk(e.children[0]) } return e.removeRowsInTblRowMap(tblRowMap) @@ -232,25 +241,33 @@ func (e *DeleteExec) removeRowsInTblRowMap(tblRowMap tableRowMapType) error { } func (e *DeleteExec) removeRow(ctx sessionctx.Context, t table.Table, h kv.Handle, data []types.Datum) error { - txnState, err := e.ctx.Txn(false) + err := t.RemoveRecord(ctx, h, data) if err != nil { return err } - memUsageOfTxnState := txnState.Size() - err = t.RemoveRecord(ctx, h, data) + tid := t.Meta().ID + err = onRemoveRowForFK(ctx, data, e.fkChecks[tid], e.fkCascades[tid]) if err != nil { return err } - fkChecks := e.fkChecks[t.Meta().ID] + ctx.GetSessionVars().StmtCtx.AddAffectedRows(1) + return nil +} + +func onRemoveRowForFK(ctx sessionctx.Context, data []types.Datum, fkChecks []*FKCheckExec, fkCascades []*FKCascadeExec) error { sc := ctx.GetSessionVars().StmtCtx for _, fkc := range fkChecks { - err = fkc.deleteRowNeedToCheck(sc, data) + err := fkc.deleteRowNeedToCheck(sc, data) + if err != nil { + return err + } + } + for _, fkc := range fkCascades { + err := fkc.onDeleteRow(sc, data) if err != nil { return err } } - e.memTracker.Consume(int64(txnState.Size() - memUsageOfTxnState)) - ctx.GetSessionVars().StmtCtx.AddAffectedRows(1) return nil } @@ -277,6 +294,20 @@ func (e *DeleteExec) GetFKChecks() []*FKCheckExec { return fkChecks } +// GetFKCascades implements WithForeignKeyTrigger interface. +func (e *DeleteExec) GetFKCascades() []*FKCascadeExec { + fkCascades := []*FKCascadeExec{} + for _, fkcs := range e.fkCascades { + fkCascades = append(fkCascades, fkcs...) + } + return fkCascades +} + +// HasFKCascades implements WithForeignKeyTrigger interface. +func (e *DeleteExec) HasFKCascades() bool { + return len(e.fkCascades) > 0 +} + // tableRowMapType is a map for unique (Table, Row) pair. key is the tableID. // the key in map[int64]Row is the joined table handle, which represent a unique reference row. // the value in map[int64]Row is the deleting row. diff --git a/executor/distsql.go b/executor/distsql.go index 6121d5fcaa4cd..3b9a6a7d4b288 100644 --- a/executor/distsql.go +++ b/executor/distsql.go @@ -39,6 +39,7 @@ import ( "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/table" + "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" @@ -243,11 +244,18 @@ func (e *IndexReaderExecutor) Next(ctx context.Context, req *chunk.Chunk) error return err } +// TODO: cleanup this method. func (e *IndexReaderExecutor) buildKeyRanges(sc *stmtctx.StatementContext, ranges []*ranger.Range, physicalID int64) ([]kv.KeyRange, error) { + var ( + rRanges *kv.KeyRanges + err error + ) if e.index.ID == -1 { - return distsql.CommonHandleRangesToKVRanges(sc, []int64{physicalID}, ranges) + rRanges, err = distsql.CommonHandleRangesToKVRanges(sc, []int64{physicalID}, ranges) + } else { + rRanges, err = distsql.IndexRangesToKVRanges(sc, physicalID, e.index.ID, ranges, e.feedback) } - return distsql.IndexRangesToKVRanges(sc, physicalID, e.index.ID, ranges, e.feedback) + return rRanges.FirstPartitionRange(), err } // Open implements the Executor Open interface. @@ -458,9 +466,6 @@ func (e *IndexLookUpExecutor) Open(ctx context.Context) error { func (e *IndexLookUpExecutor) buildTableKeyRanges() (err error) { sc := e.ctx.GetSessionVars().StmtCtx if e.partitionTableMode { - if e.keepOrder { // this case should be prevented by the optimizer - return errors.New("invalid execution plan: cannot keep order when accessing a partition table by IndexLookUpReader") - } e.feedback.Invalidate() // feedback for partition tables is not ready e.partitionKVRanges = make([][]kv.KeyRange, 0, len(e.prunedPartitions)) for _, p := range e.prunedPartitions { @@ -472,7 +477,7 @@ func (e *IndexLookUpExecutor) buildTableKeyRanges() (err error) { if e.partitionRangeMap != nil && e.partitionRangeMap[physicalID] != nil { ranges = e.partitionRangeMap[physicalID] } - var kvRange []kv.KeyRange + var kvRange *kv.KeyRanges if e.index.ID == -1 { kvRange, err = distsql.CommonHandleRangesToKVRanges(sc, []int64{physicalID}, ranges) } else { @@ -481,15 +486,17 @@ func (e *IndexLookUpExecutor) buildTableKeyRanges() (err error) { if err != nil { return err } - e.partitionKVRanges = append(e.partitionKVRanges, kvRange) + e.partitionKVRanges = append(e.partitionKVRanges, kvRange.FirstPartitionRange()) } } else { physicalID := getPhysicalTableID(e.table) + var kvRanges *kv.KeyRanges if e.index.ID == -1 { - e.kvRanges, err = distsql.CommonHandleRangesToKVRanges(sc, []int64{physicalID}, e.ranges) + kvRanges, err = distsql.CommonHandleRangesToKVRanges(sc, []int64{physicalID}, e.ranges) } else { - e.kvRanges, err = distsql.IndexRangesToKVRanges(sc, physicalID, e.index.ID, e.ranges, e.feedback) + kvRanges, err = distsql.IndexRangesToKVRanges(sc, physicalID, e.index.ID, e.ranges, e.feedback) } + e.kvRanges = kvRanges.FirstPartitionRange() } return err } @@ -718,6 +725,9 @@ func (e *IndexLookUpExecutor) buildTableReader(ctx context.Context, task *lookup // Close implements Exec Close interface. func (e *IndexLookUpExecutor) Close() error { + if e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } e.kvRanges = e.kvRanges[:0] if e.dummy { return nil @@ -802,7 +812,6 @@ func (e *IndexLookUpExecutor) initRuntimeStats() { indexScanBasicStats: &execdetails.BasicRuntimeStats{}, Concurrency: e.ctx.GetSessionVars().IndexLookupConcurrency(), } - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } } @@ -866,11 +875,11 @@ func (w *indexWorker) fetchHandles(ctx context.Context, result distsql.SelectRes } }() retTps := w.idxLookup.getRetTpsByHandle() - chk := chunk.NewChunkWithCapacity(retTps, w.idxLookup.maxChunkSize) + chk := w.idxLookup.ctx.GetSessionVars().GetNewChunkWithCapacity(retTps, w.idxLookup.maxChunkSize, w.idxLookup.maxChunkSize, w.idxLookup.AllocPool) idxID := w.idxLookup.getIndexPlanRootID() if w.idxLookup.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil { if idxID != w.idxLookup.id && w.idxLookup.stats != nil { - w.idxLookup.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(idxID, w.idxLookup.stats.indexScanBasicStats) + w.idxLookup.stats.indexScanBasicStats = w.idxLookup.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.GetBasicRuntimeStats(idxID) } } for { @@ -1161,7 +1170,7 @@ func (e *IndexLookUpRunTimeStats) Tp() int { } func (w *tableWorker) compareData(ctx context.Context, task *lookupTableTask, tableReader Executor) error { - chk := newFirstChunk(tableReader) + chk := tryNewCacheChunk(tableReader) tblInfo := w.idxLookup.table.Meta() vals := make([]types.Datum, 0, len(w.idxTblCols)) @@ -1246,36 +1255,27 @@ func (w *tableWorker) compareData(ctx context.Context, task *lookupTableTask, ta sctx := w.idxLookup.ctx.GetSessionVars().StmtCtx for i := range vals { col := w.idxTblCols[i] - tp := &col.FieldType - idxVal := idxRow.GetDatum(i, tp) + idxVal := idxRow.GetDatum(i, w.idxColTps[i]) tablecodec.TruncateIndexValue(&idxVal, w.idxLookup.index.Columns[i], col.ColumnInfo) - cmpRes, err := idxVal.Compare(sctx, &vals[i], collators[i]) + cmpRes, err := tables.CompareIndexAndVal(sctx, vals[i], idxVal, collators[i], col.FieldType.IsArray() && vals[i].Kind() == types.KindMysqlJSON) if err != nil { - fts := make([]*types.FieldType, 0, len(w.idxTblCols)) - for _, c := range w.idxTblCols { - fts = append(fts, &c.FieldType) - } return ir().ReportAdminCheckInconsistentWithColInfo(ctx, handle, col.Name.O, - idxRow.GetDatum(i, tp), + idxVal, vals[i], err, - &consistency.RecordData{Handle: handle, Values: getDatumRow(&idxRow, fts)}, + &consistency.RecordData{Handle: handle, Values: getDatumRow(&idxRow, w.idxColTps)}, ) } if cmpRes != 0 { - fts := make([]*types.FieldType, 0, len(w.idxTblCols)) - for _, c := range w.idxTblCols { - fts = append(fts, &c.FieldType) - } return ir().ReportAdminCheckInconsistentWithColInfo(ctx, handle, col.Name.O, - idxRow.GetDatum(i, tp), + idxRow.GetDatum(i, w.idxColTps[i]), vals[i], err, - &consistency.RecordData{Handle: handle, Values: getDatumRow(&idxRow, fts)}, + &consistency.RecordData{Handle: handle, Values: getDatumRow(&idxRow, w.idxColTps)}, ) } } @@ -1317,7 +1317,7 @@ func (w *tableWorker) executeTask(ctx context.Context, task *lookupTableTask) er handleCnt := len(task.handles) task.rows = make([]chunk.Row, 0, handleCnt) for { - chk := newFirstChunk(tableReader) + chk := tryNewCacheChunk(tableReader) err = Next(ctx, tableReader, chk) if err != nil { logutil.Logger(ctx).Error("table reader fetch next chunk failed", zap.Error(err)) diff --git a/executor/distsql_test.go b/executor/distsql_test.go index 59b3aecc2bb6a..65889a10d0377 100644 --- a/executor/distsql_test.go +++ b/executor/distsql_test.go @@ -316,9 +316,8 @@ func TestPartitionTableIndexLookUpReader(t *testing.T) { tk.MustQuery("select * from t where a>=1 and a<15 order by a").Check(testkit.Rows("1 1", "2 2", "11 11", "12 12")) tk.MustQuery("select * from t where a>=1 and a<15 order by a limit 1").Check(testkit.Rows("1 1")) tk.MustQuery("select * from t where a>=1 and a<15 order by a limit 3").Check(testkit.Rows("1 1", "2 2", "11 11")) - tk.MustQuery("select * from t where a>=1 and a<15 limit 3").Check(testkit.Rows("1 1", "2 2", "11 11")) - tk.MustQuery("select * from t where a between 1 and 15 limit 3").Check(testkit.Rows("1 1", "2 2", "11 11")) - tk.MustQuery("select * from t where a between 1 and 15 limit 3 offset 1").Check(testkit.Rows("2 2", "11 11", "12 12")) + tk.MustQuery("select * from t where a between 1 and 15 order by a limit 3").Check(testkit.Rows("1 1", "2 2", "11 11")) + tk.MustQuery("select * from t where a between 1 and 15 order by a limit 3 offset 1").Check(testkit.Rows("2 2", "11 11", "12 12")) } func TestPartitionTableRandomlyIndexLookUpReader(t *testing.T) { @@ -634,3 +633,61 @@ func TestCoprocessorPagingReqKeyRangeSorted(t *testing.T) { tk.MustExec(`set @a=0x61219F79C90D3541F70E, @b=5501707547099269248, @c=0xEC43EFD30131DEA2CB8B, @d="呣丼蒢咿卻鹻铴础湜僂頃dž縍套衞陀碵碼幓9", @e="鹹楞睕堚尛鉌翡佾搁紟精廬姆燵藝潐楻翇慸嵊";`) tk.MustExec(`execute stmt using @a,@b,@c,@d,@e;`) } + +func TestCoprocessorBatchByStore(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") + tk.MustExec("create table t(id int primary key, c1 int, c2 int, key i(c1))") + tk.MustExec(`create table t1(id int primary key, c1 int, c2 int, key i(c1)) partition by range(id) ( + partition p0 values less than(10000), + partition p1 values less than (50000), + partition p2 values less than (100000))`) + for i := 0; i < 10; i++ { + tk.MustExec("insert into t values(?, ?, ?)", i*10000, i*10000, i%2) + tk.MustExec("insert into t1 values(?, ?, ?)", i*10000, i*10000, i%2) + } + tk.MustQuery("split table t between (0) and (100000) regions 20").Check(testkit.Rows("20 1")) + tk.MustQuery("split table t1 between (0) and (100000) regions 20").Check(testkit.Rows("60 1")) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/store/copr/setRangesPerTask", "return(1)")) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/store/copr/setRangesPerTask")) + }() + ranges := []string{ + "(c1 >= 0 and c1 < 5000)", + "(c1 >= 10000 and c1 < 15000)", + "(c1 >= 20000 and c1 < 25000)", + "(c1 >= 30000 and c1 < 35000)", + "(c1 >= 40000 and c1 < 45000)", + "(c1 >= 50000 and c1 < 55000)", + "(c1 >= 60000 and c1 < 65000)", + "(c1 >= 70000 and c1 < 75000)", + "(c1 >= 80000 and c1 < 85000)", + "(c1 >= 90000 and c1 < 95000)", + } + evenRows := testkit.Rows("0 0 0", "20000 20000 0", "40000 40000 0", "60000 60000 0", "80000 80000 0") + oddRows := testkit.Rows("10000 10000 1", "30000 30000 1", "50000 50000 1", "70000 70000 1", "90000 90000 1") + reverseOddRows := testkit.Rows("90000 90000 1", "70000 70000 1", "50000 50000 1", "30000 30000 1", "10000 10000 1") + for _, table := range []string{"t", "t1"} { + baseSQL := fmt.Sprintf("select * from %s force index(i) where id < 100000 and (%s)", table, strings.Join(ranges, " or ")) + for _, paging := range []string{"on", "off"} { + tk.MustExec("set session tidb_enable_paging=?", paging) + for size := 0; size < 10; size++ { + tk.MustExec("set session tidb_store_batch_size=?", size) + tk.MustQuery(baseSQL + " and c2 = 0").Sort().Check(evenRows) + tk.MustQuery(baseSQL + " and c2 = 1").Sort().Check(oddRows) + tk.MustQuery(baseSQL + " and c2 = 0 order by c1 asc").Check(evenRows) + tk.MustQuery(baseSQL + " and c2 = 1 order by c1 desc").Check(reverseOddRows) + // every batched task will get region error and fallback. + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/store/copr/batchCopRegionError", "return")) + tk.MustQuery(baseSQL + " and c2 = 0").Sort().Check(evenRows) + tk.MustQuery(baseSQL + " and c2 = 1").Sort().Check(oddRows) + tk.MustQuery(baseSQL + " and c2 = 0 order by c1 asc").Check(evenRows) + tk.MustQuery(baseSQL + " and c2 = 1 order by c1 desc").Check(reverseOddRows) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/store/copr/batchCopRegionError")) + } + } + } +} diff --git a/executor/errors.go b/executor/errors.go index d38312947cc6a..565a712d1c7d9 100644 --- a/executor/errors.go +++ b/executor/errors.go @@ -58,18 +58,22 @@ var ( ErrSettingNoopVariable = dbterror.ClassExecutor.NewStd(mysql.ErrSettingNoopVariable) ErrLazyUniquenessCheckFailure = dbterror.ClassExecutor.NewStd(mysql.ErrLazyUniquenessCheckFailure) - ErrBRIEBackupFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIEBackupFailed) - ErrBRIERestoreFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIERestoreFailed) - ErrBRIEImportFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIEImportFailed) - ErrBRIEExportFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIEExportFailed) - ErrCTEMaxRecursionDepth = dbterror.ClassExecutor.NewStd(mysql.ErrCTEMaxRecursionDepth) - ErrNotSupportedWithSem = dbterror.ClassOptimizer.NewStd(mysql.ErrNotSupportedWithSem) - ErrPluginIsNotLoaded = dbterror.ClassExecutor.NewStd(mysql.ErrPluginIsNotLoaded) - ErrSetPasswordAuthPlugin = dbterror.ClassExecutor.NewStd(mysql.ErrSetPasswordAuthPlugin) - ErrFuncNotEnabled = dbterror.ClassExecutor.NewStdErr(mysql.ErrNotSupportedYet, parser_mysql.Message("%-.32s is not supported. To enable this experimental feature, set '%-.32s' in the configuration file.", nil)) - errSavepointNotExists = dbterror.ClassExecutor.NewStd(mysql.ErrSpDoesNotExist) + ErrBRIEBackupFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIEBackupFailed) + ErrBRIERestoreFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIERestoreFailed) + ErrBRIEImportFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIEImportFailed) + ErrBRIEExportFailed = dbterror.ClassExecutor.NewStd(mysql.ErrBRIEExportFailed) + ErrCTEMaxRecursionDepth = dbterror.ClassExecutor.NewStd(mysql.ErrCTEMaxRecursionDepth) + ErrNotSupportedWithSem = dbterror.ClassOptimizer.NewStd(mysql.ErrNotSupportedWithSem) + ErrPluginIsNotLoaded = dbterror.ClassExecutor.NewStd(mysql.ErrPluginIsNotLoaded) + ErrSetPasswordAuthPlugin = dbterror.ClassExecutor.NewStd(mysql.ErrSetPasswordAuthPlugin) + ErrFuncNotEnabled = dbterror.ClassExecutor.NewStdErr(mysql.ErrNotSupportedYet, parser_mysql.Message("%-.32s is not supported. To enable this experimental feature, set '%-.32s' in the configuration file.", nil)) + errSavepointNotExists = dbterror.ClassExecutor.NewStd(mysql.ErrSpDoesNotExist) + ErrForeignKeyCascadeDepthExceeded = dbterror.ClassExecutor.NewStd(mysql.ErrForeignKeyCascadeDepthExceeded) + ErrPasswordExpireAnonymousUser = dbterror.ClassExecutor.NewStd(mysql.ErrPasswordExpireAnonymousUser) + errMustChangePassword = dbterror.ClassExecutor.NewStd(mysql.ErrMustChangePassword) ErrWrongStringLength = dbterror.ClassDDL.NewStd(mysql.ErrWrongStringLength) errUnsupportedFlashbackTmpTable = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("Recover/flashback table is not supported on temporary tables", nil)) errTruncateWrongInsertValue = dbterror.ClassTable.NewStdErr(mysql.ErrTruncatedWrongValue, parser_mysql.Message("Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %d", nil)) + ErrExistsInHistoryPassword = dbterror.ClassExecutor.NewStd(mysql.ErrExistsInHistoryPassword) ) diff --git a/executor/executor.go b/executor/executor.go index d14f8a55a7de3..c2fcdaa2d7887 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -132,6 +132,7 @@ type baseExecutor struct { children []Executor retFieldTypes []*types.FieldType runtimeStats *execdetails.BasicRuntimeStats + AllocPool chunk.Allocator } const ( @@ -167,9 +168,6 @@ func init() { schematracker.ConstructResultOfShowCreateTable = ConstructResultOfShowCreateTable } -// SetLogHook sets a hook for PanicOnExceed. -func (a *globalPanicOnExceed) SetLogHook(hook func(uint64)) {} - // Action panics when storage usage exceeds storage quota. func (a *globalPanicOnExceed) Action(t *memory.Tracker) { a.mutex.Lock() @@ -234,6 +232,12 @@ func newFirstChunk(e Executor) *chunk.Chunk { return chunk.New(base.retFieldTypes, base.initCap, base.maxChunkSize) } +func tryNewCacheChunk(e Executor) *chunk.Chunk { + base := e.base() + s := base.ctx.GetSessionVars() + return s.GetNewChunkWithCapacity(base.retFieldTypes, base.initCap, base.maxChunkSize, base.AllocPool) +} + // newList creates a new List to buffer current executor's result. func newList(e Executor) *chunk.List { base := e.base() @@ -264,11 +268,11 @@ func newBaseExecutor(ctx sessionctx.Context, schema *expression.Schema, id int, schema: schema, initCap: ctx.GetSessionVars().InitChunkSize, maxChunkSize: ctx.GetSessionVars().MaxChunkSize, + AllocPool: ctx.GetSessionVars().ChunkPool.Alloc, } if ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil { if e.id > 0 { - e.runtimeStats = &execdetails.BasicRuntimeStats{} - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(id, e.runtimeStats) + e.runtimeStats = e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.GetBasicRuntimeStats(id) } } if schema != nil { @@ -318,7 +322,7 @@ func Next(ctx context.Context, e Executor, req *chunk.Chunk) error { if trace.IsEnabled() { defer trace.StartRegion(ctx, fmt.Sprintf("%T.Next", e)).End() } - if topsqlstate.TopSQLEnabled() && sessVars.StmtCtx.IsSQLAndPlanRegistered.CAS(false, true) { + if topsqlstate.TopSQLEnabled() && sessVars.StmtCtx.IsSQLAndPlanRegistered.CompareAndSwap(false, true) { registerSQLAndPlanInExecForTopSQL(sessVars) } err := e.Next(ctx, req) @@ -349,7 +353,7 @@ func (e *CancelDDLJobsExec) Open(ctx context.Context) error { if err != nil { return err } - e.errs, err = ddl.CancelJobs(newSess, e.ctx.GetStore(), e.jobIDs) + e.errs, err = ddl.CancelJobs(newSess, e.jobIDs) e.releaseSysSession(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), newSess) return err } @@ -394,7 +398,7 @@ func (e *ShowNextRowIDExec) Next(ctx context.Context, req *chunk.Chunk) error { tblMeta := tbl.Meta() allocators := tbl.Allocators(e.ctx) - for _, alloc := range allocators { + for _, alloc := range allocators.Allocs { nextGlobalID, err := alloc.NextGlobalAutoID() if err != nil { return err @@ -402,7 +406,16 @@ func (e *ShowNextRowIDExec) Next(ctx context.Context, req *chunk.Chunk) error { var colName, idType string switch alloc.GetType() { - case autoid.RowIDAllocType, autoid.AutoIncrementType: + case autoid.RowIDAllocType: + idType = "_TIDB_ROWID" + if tblMeta.PKIsHandle { + if col := tblMeta.GetAutoIncrementColInfo(); col != nil { + colName = col.Name.O + } + } else { + colName = model.ExtraHandleName.O + } + case autoid.AutoIncrementType: idType = "AUTO_INCREMENT" if tblMeta.PKIsHandle { if col := tblMeta.GetAutoIncrementColInfo(); col != nil { @@ -560,7 +573,7 @@ func (e *DDLJobRetriever) appendJobToChunk(req *chunk.Chunk, job *model.Job, che req.AppendInt64(0, job.ID) req.AppendString(1, schemaName) req.AppendString(2, tableName) - req.AppendString(3, job.Type.String()) + req.AppendString(3, job.Type.String()+showAddIdxReorgTp(job)) req.AppendString(4, job.SchemaState.String()) req.AppendInt64(5, job.SchemaID) req.AppendInt64(6, job.TableID) @@ -582,7 +595,7 @@ func (e *DDLJobRetriever) appendJobToChunk(req *chunk.Chunk, job *model.Job, che req.AppendInt64(0, job.ID) req.AppendString(1, schemaName) req.AppendString(2, tableName) - req.AppendString(3, subJob.Type.String()+" /* subjob */") + req.AppendString(3, subJob.Type.String()+" /* subjob */"+showAddIdxReorgTpInSubJob(subJob)) req.AppendString(4, subJob.SchemaState.String()) req.AppendInt64(5, job.SchemaID) req.AppendInt64(6, job.TableID) @@ -595,6 +608,28 @@ func (e *DDLJobRetriever) appendJobToChunk(req *chunk.Chunk, job *model.Job, che } } +func showAddIdxReorgTp(job *model.Job) string { + if job.Type == model.ActionAddIndex || job.Type == model.ActionAddPrimaryKey { + if job.ReorgMeta != nil { + tp := job.ReorgMeta.ReorgTp.String() + if len(tp) > 0 { + return " /* " + tp + " */" + } + } + } + return "" +} + +func showAddIdxReorgTpInSubJob(subJob *model.SubJob) string { + if subJob.Type == model.ActionAddIndex || subJob.Type == model.ActionAddPrimaryKey { + tp := subJob.ReorgTp.String() + if len(tp) > 0 { + return " /* " + tp + " */" + } + } + return "" +} + func ts2Time(timestamp uint64, loc *time.Location) types.Time { duration := time.Duration(math.Pow10(9-types.DefaultFsp)) * time.Nanosecond t := model.TSConvert2Time(timestamp) @@ -649,8 +684,21 @@ func (e *ShowDDLJobQueriesExec) Open(ctx context.Context) error { return err } - e.jobs = append(e.jobs, jobs...) - e.jobs = append(e.jobs, historyJobs...) + appendedJobID := make(map[int64]struct{}) + // deduplicate job results + // for situations when this operation happens at the same time with new DDLs being executed + for _, job := range jobs { + if _, ok := appendedJobID[job.ID]; !ok { + appendedJobID[job.ID] = struct{}{} + e.jobs = append(e.jobs, job) + } + } + for _, historyJob := range historyJobs { + if _, ok := appendedJobID[historyJob.ID]; !ok { + appendedJobID[historyJob.ID] = struct{}{} + e.jobs = append(e.jobs, historyJob) + } + } return nil } @@ -724,8 +772,25 @@ func (e *ShowDDLJobQueriesWithRangeExec) Open(ctx context.Context) error { return err } - e.jobs = append(e.jobs, jobs...) - e.jobs = append(e.jobs, historyJobs...) + appendedJobID := make(map[int64]struct{}) + // deduplicate job results + // for situations when this operation happens at the same time with new DDLs being executed + for _, job := range jobs { + if _, ok := appendedJobID[job.ID]; !ok { + appendedJobID[job.ID] = struct{}{} + e.jobs = append(e.jobs, job) + } + } + for _, historyJob := range historyJobs { + if _, ok := appendedJobID[historyJob.ID]; !ok { + appendedJobID[historyJob.ID] = struct{}{} + e.jobs = append(e.jobs, historyJob) + } + } + + if e.cursor < int(e.offset) { + e.cursor = int(e.offset) + } return nil } @@ -741,9 +806,12 @@ func (e *ShowDDLJobQueriesWithRangeExec) Next(ctx context.Context, req *chunk.Ch } numCurBatch := mathutil.Min(req.Capacity(), len(e.jobs)-e.cursor) for i := e.cursor; i < e.cursor+numCurBatch; i++ { - if i >= int(e.offset) && i < int(e.offset+e.limit) { + // i is make true to be >= int(e.offset) + if i < int(e.offset+e.limit) { req.AppendString(0, strconv.FormatInt(e.jobs[i].ID, 10)) req.AppendString(1, e.jobs[i].Query) + } else { + break } } e.cursor += numCurBatch @@ -934,6 +1002,9 @@ func (e *CheckTableExec) Next(ctx context.Context, req *chunk.Chunk) error { idxNames := make([]string, 0, len(e.indexInfos)) for _, idx := range e.indexInfos { + if idx.MVIndex { + continue + } idxNames = append(idxNames, idx.Name.O) } greater, idxOffset, err := admin.CheckIndicesCount(e.ctx, e.dbName, e.table.Meta().Name.O, idxNames) @@ -953,7 +1024,13 @@ func (e *CheckTableExec) Next(ctx context.Context, req *chunk.Chunk) error { // The number of table rows is equal to the number of index rows. // TODO: Make the value of concurrency adjustable. And we can consider the number of records. if len(e.srcs) == 1 { - return e.checkIndexHandle(ctx, e.srcs[0]) + err = e.checkIndexHandle(ctx, e.srcs[0]) + if err == nil && e.srcs[0].index.MVIndex { + err = e.checkTableRecord(ctx, 0) + } + if err != nil { + return err + } } taskCh := make(chan *IndexLookUpExecutor, len(e.srcs)) failure := atomicutil.NewBool(false) @@ -972,6 +1049,14 @@ func (e *CheckTableExec) Next(ctx context.Context, req *chunk.Chunk) error { select { case src := <-taskCh: err1 := e.checkIndexHandle(ctx, src) + if err1 == nil && src.index.MVIndex { + for offset, idx := range e.indexInfos { + if idx.ID == src.index.ID { + err1 = e.checkTableRecord(ctx, offset) + break + } + } + } if err1 != nil { failure.Store(true) logutil.Logger(ctx).Info("check index handle failed", zap.Error(err1)) @@ -1308,6 +1393,9 @@ type LimitExec struct { // columnIdxsUsedByChild keep column indexes of child executor used for inline projection columnIdxsUsedByChild []int + + // Log the close time when opentracing is enabled. + span opentracing.Span } // Next implements the Executor Next interface. @@ -1382,16 +1470,32 @@ func (e *LimitExec) Open(ctx context.Context) error { if err := e.baseExecutor.Open(ctx); err != nil { return err } - e.childResult = newFirstChunk(e.children[0]) + e.childResult = tryNewCacheChunk(e.children[0]) e.cursor = 0 e.meetFirstBatch = e.begin == 0 + if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { + e.span = span + } return nil } // Close implements the Executor Close interface. func (e *LimitExec) Close() error { + start := time.Now() + e.childResult = nil - return e.baseExecutor.Close() + err := e.baseExecutor.Close() + + elapsed := time.Since(start) + if elapsed > time.Millisecond { + logutil.BgLogger().Info("limit executor close takes a long time", + zap.Duration("elapsed", elapsed)) + if e.span != nil { + span1 := e.span.Tracer().StartSpan("limitExec.Close", opentracing.ChildOf(e.span.Context()), opentracing.StartTime(start)) + defer span1.Finish() + } + } + return err } func (e *LimitExec) adjustRequiredRows(chk *chunk.Chunk) *chunk.Chunk { @@ -1439,8 +1543,7 @@ func init() { if err != nil { return nil, err } - chk := newFirstChunk(exec) - + chk := tryNewCacheChunk(exec) err = Next(ctx, exec, chk) if err != nil { return nil, err @@ -1515,7 +1618,7 @@ func (e *SelectionExec) Open(ctx context.Context) error { func (e *SelectionExec) open(ctx context.Context) error { e.memTracker = memory.NewTracker(e.id, -1) e.memTracker.AttachTo(e.ctx.GetSessionVars().StmtCtx.MemTracker) - e.childResult = newFirstChunk(e.children[0]) + e.childResult = tryNewCacheChunk(e.children[0]) e.memTracker.Consume(e.childResult.MemoryUsage()) e.batched = expression.Vectorizable(e.filters) if e.batched { @@ -1630,9 +1733,9 @@ func (e *TableScanExec) nextChunk4InfoSchema(ctx context.Context, chk *chunk.Chu } mutableRow := chunk.MutRowFromTypes(retTypes(e)) type tableIter interface { - IterRecords(sessionctx.Context, []*table.Column, table.RecordIterFunc) error + IterRecords(ctx context.Context, sctx sessionctx.Context, cols []*table.Column, fn table.RecordIterFunc) error } - err := (e.t.(tableIter)).IterRecords(e.ctx, columns, func(_ kv.Handle, rec []types.Datum, cols []*table.Column) (bool, error) { + err := (e.t.(tableIter)).IterRecords(ctx, e.ctx, columns, func(_ kv.Handle, rec []types.Datum, cols []*table.Column) (bool, error) { mutableRow.SetDatums(rec...) e.virtualTableChunkList.AppendRow(mutableRow.ToRow()) return true, nil @@ -1695,7 +1798,7 @@ func (e *MaxOneRowExec) Next(ctx context.Context, req *chunk.Chunk) error { return ErrSubqueryMoreThan1Row } - childChunk := newFirstChunk(e.children[0]) + childChunk := tryNewCacheChunk(e.children[0]) err = Next(ctx, e.children[0], childChunk) if err != nil { return err @@ -1909,7 +2012,7 @@ func (e *UnionExec) Close() error { func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { vars := ctx.GetSessionVars() var sc *stmtctx.StatementContext - if vars.TxnCtx.CouldRetry { + if vars.TxnCtx.CouldRetry || mysql.HasCursorExistsFlag(vars.Status) { // Must construct new statement context object, the retry history need context for every statement. // TODO: Maybe one day we can get rid of transaction retry, then this logic can be deleted. sc = &stmtctx.StatementContext{} @@ -1935,33 +2038,46 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { sc.UseDynamicPruneMode = false } + sc.StatsLoad.Timeout = 0 + sc.StatsLoad.NeededItems = nil + sc.StatsLoad.ResultCh = nil + sc.SysdateIsNow = ctx.GetSessionVars().SysdateIsNow + vars.MemTracker.Detach() + vars.MemTracker.UnbindActions() + vars.MemTracker.SetBytesLimit(vars.MemQuotaQuery) + vars.MemTracker.ResetMaxConsumed() + vars.DiskTracker.ResetMaxConsumed() + vars.MemTracker.SessionID = vars.ConnectionID + vars.StmtCtx.TableStats = make(map[int64]interface{}) + if _, ok := s.(*ast.AnalyzeTableStmt); ok { sc.InitMemTracker(memory.LabelForAnalyzeMemory, -1) - sc.MemTracker.AttachTo(GlobalAnalyzeMemoryTracker) + vars.MemTracker.SetBytesLimit(-1) + vars.MemTracker.AttachTo(GlobalAnalyzeMemoryTracker) } else { - sc.InitMemTracker(memory.LabelForSQLText, vars.MemQuotaQuery) - sc.MemTracker.AttachToGlobalTracker(GlobalMemoryUsageTracker) - sc.MemTracker.IsRootTrackerOfSess, sc.MemTracker.SessionID = true, vars.ConnectionID - } - - sc.InitDiskTracker(memory.LabelForSQLText, -1) - globalConfig := config.GetGlobalConfig() - if variable.EnableTmpStorageOnOOM.Load() && GlobalDiskUsageTracker != nil { - sc.DiskTracker.AttachToGlobalTracker(GlobalDiskUsageTracker) + sc.InitMemTracker(memory.LabelForSQLText, -1) } + logOnQueryExceedMemQuota := domain.GetDomain(ctx).ExpensiveQueryHandle().LogOnQueryExceedMemQuota switch variable.OOMAction.Load() { case variable.OOMActionCancel: - action := &memory.PanicOnExceed{ConnID: ctx.GetSessionVars().ConnectionID} - action.SetLogHook(domain.GetDomain(ctx).ExpensiveQueryHandle().LogOnQueryExceedMemQuota) - sc.MemTracker.SetActionOnExceed(action) + action := &memory.PanicOnExceed{ConnID: vars.ConnectionID} + action.SetLogHook(logOnQueryExceedMemQuota) + vars.MemTracker.SetActionOnExceed(action) case variable.OOMActionLog: fallthrough default: - action := &memory.LogOnExceed{ConnID: ctx.GetSessionVars().ConnectionID} - action.SetLogHook(domain.GetDomain(ctx).ExpensiveQueryHandle().LogOnQueryExceedMemQuota) - sc.MemTracker.SetActionOnExceed(action) + action := &memory.LogOnExceed{ConnID: vars.ConnectionID} + action.SetLogHook(logOnQueryExceedMemQuota) + vars.MemTracker.SetActionOnExceed(action) + } + sc.MemTracker.SessionID = vars.ConnectionID + sc.MemTracker.AttachTo(vars.MemTracker) + sc.InitDiskTracker(memory.LabelForSQLText, -1) + globalConfig := config.GetGlobalConfig() + if variable.EnableTmpStorageOnOOM.Load() && sc.DiskTracker != nil { + sc.DiskTracker.AttachTo(vars.DiskTracker) } if execStmt, ok := s.(*ast.ExecuteStmt); ok { prepareStmt, err := plannercore.GetPreparedStmt(execStmt, vars) @@ -2024,6 +2140,7 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { sc.DupKeyAsWarning = stmt.IgnoreErr sc.BadNullAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr sc.IgnoreNoPartition = stmt.IgnoreErr + sc.ErrAutoincReadFailedAsWarning = stmt.IgnoreErr sc.TruncateAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr sc.DividedByZeroAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr sc.AllowInvalidDate = vars.SQLMode.HasAllowInvalidDatesMode() @@ -2123,12 +2240,16 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { errCount, warnCount := vars.StmtCtx.NumErrorWarnings() vars.SysErrorCount = errCount vars.SysWarningCount = warnCount + vars.ExchangeChunkStatus() vars.StmtCtx = sc vars.PrevFoundInPlanCache = vars.FoundInPlanCache vars.FoundInPlanCache = false vars.ClearStmtVars() vars.PrevFoundInBinding = vars.FoundInBinding vars.FoundInBinding = false + vars.DurationWaitTS = 0 + vars.CurrInsertBatchExtraCols = nil + vars.CurrInsertValues = chunk.Row{} return } @@ -2157,35 +2278,6 @@ func ResetUpdateStmtCtx(sc *stmtctx.StatementContext, stmt *ast.UpdateStmt, vars sc.IgnoreNoPartition = stmt.IgnoreErr } -// FillVirtualColumnValue will calculate the virtual column value by evaluating generated -// expression using rows from a chunk, and then fill this value into the chunk -func FillVirtualColumnValue(virtualRetTypes []*types.FieldType, virtualColumnIndex []int, - schema *expression.Schema, columns []*model.ColumnInfo, sctx sessionctx.Context, req *chunk.Chunk) error { - virCols := chunk.NewChunkWithCapacity(virtualRetTypes, req.Capacity()) - iter := chunk.NewIterator4Chunk(req) - for i, idx := range virtualColumnIndex { - for row := iter.Begin(); row != iter.End(); row = iter.Next() { - datum, err := schema.Columns[idx].EvalVirtualColumn(row) - if err != nil { - return err - } - // Because the expression might return different type from - // the generated column, we should wrap a CAST on the result. - castDatum, err := table.CastValue(sctx, datum, columns[idx], false, true) - if err != nil { - return err - } - // Handle the bad null error. - if (mysql.HasNotNullFlag(columns[idx].GetFlag()) || mysql.HasPreventNullInsertFlag(columns[idx].GetFlag())) && castDatum.IsNull() { - castDatum = table.GetZeroValue(columns[idx]) - } - virCols.AppendDatum(i, &castDatum) - } - req.SetCol(idx, virCols.Column(i)) - } - return nil -} - func setOptionForTopSQL(sc *stmtctx.StatementContext, snapshot kv.Snapshot) { if snapshot == nil { return diff --git a/executor/executor_pkg_test.go b/executor/executor_pkg_test.go index 6e8f2ba1e2921..44e985288556b 100644 --- a/executor/executor_pkg_test.go +++ b/executor/executor_pkg_test.go @@ -306,7 +306,9 @@ func TestSortSpillDisk(t *testing.T) { ctx.GetSessionVars().MemQuota.MemQuotaQuery = 1 ctx.GetSessionVars().InitChunkSize = variable.DefMaxChunkSize ctx.GetSessionVars().MaxChunkSize = variable.DefMaxChunkSize - ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(-1, -1) + ctx.GetSessionVars().MemTracker = memory.NewTracker(memory.LabelForSession, -1) + ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(memory.LabelForSQLText, -1) + ctx.GetSessionVars().StmtCtx.MemTracker.AttachTo(ctx.GetSessionVars().MemTracker) cas := &sortCase{rows: 2048, orderByIdx: []int{0, 1}, ndvs: []int{0, 0}, ctx: ctx} opt := mockDataSourceParameters{ schema: expression.NewSchema(cas.columns()...), @@ -342,7 +344,9 @@ func TestSortSpillDisk(t *testing.T) { err = exec.Close() require.NoError(t, err) - ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(-1, 1) + ctx.GetSessionVars().MemTracker = memory.NewTracker(memory.LabelForSession, 1) + ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(memory.LabelForSQLText, -1) + ctx.GetSessionVars().StmtCtx.MemTracker.AttachTo(ctx.GetSessionVars().MemTracker) dataSource.prepareChunks() err = exec.Open(tmpCtx) require.NoError(t, err) @@ -372,7 +376,9 @@ func TestSortSpillDisk(t *testing.T) { err = exec.Close() require.NoError(t, err) - ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(-1, 28000) + ctx.GetSessionVars().MemTracker = memory.NewTracker(memory.LabelForSession, 28000) + ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(memory.LabelForSQLText, -1) + ctx.GetSessionVars().StmtCtx.MemTracker.AttachTo(ctx.GetSessionVars().MemTracker) dataSource.prepareChunks() err = exec.Open(tmpCtx) require.NoError(t, err) @@ -394,8 +400,10 @@ func TestSortSpillDisk(t *testing.T) { ctx = mock.NewContext() ctx.GetSessionVars().InitChunkSize = variable.DefMaxChunkSize ctx.GetSessionVars().MaxChunkSize = variable.DefMaxChunkSize - ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(-1, 16864*50) - ctx.GetSessionVars().StmtCtx.MemTracker.Consume(16864 * 45) + ctx.GetSessionVars().MemTracker = memory.NewTracker(memory.LabelForSession, 16864*50) + ctx.GetSessionVars().MemTracker.Consume(16864 * 45) + ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(memory.LabelForSQLText, -1) + ctx.GetSessionVars().StmtCtx.MemTracker.AttachTo(ctx.GetSessionVars().MemTracker) cas = &sortCase{rows: 20480, orderByIdx: []int{0, 1}, ndvs: []int{0, 0}, ctx: ctx} opt = mockDataSourceParameters{ schema: expression.NewSchema(cas.columns()...), diff --git a/executor/executor_required_rows_test.go b/executor/executor_required_rows_test.go index cbca9914b5bc2..c3ac762050d24 100644 --- a/executor/executor_required_rows_test.go +++ b/executor/executor_required_rows_test.go @@ -22,6 +22,7 @@ import ( "testing" "time" + "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/expression/aggregation" "github.com/pingcap/tidb/parser/ast" @@ -211,6 +212,7 @@ func defaultCtx() sessionctx.Context { ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(-1, ctx.GetSessionVars().MemQuotaQuery) ctx.GetSessionVars().StmtCtx.DiskTracker = disk.NewTracker(-1, -1) ctx.GetSessionVars().SnapshotTS = uint64(1) + domain.BindDomain(ctx, domain.NewMockDomain()) return ctx } diff --git a/executor/executor_test.go b/executor/executor_test.go index 5063362462cb5..7e6a51799d778 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -66,6 +66,7 @@ import ( "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/mock" + "github.com/pingcap/tidb/util/replayer" "github.com/pingcap/tidb/util/rowcodec" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/timeutil" @@ -81,12 +82,15 @@ func checkFileName(s string) bool { "meta.txt", "stats/test.t_dump_single.json", "schema/test.t_dump_single.schema.txt", + "schema/schema_meta.txt", "table_tiflash_replica.txt", "variables.toml", "session_bindings.sql", "global_bindings.sql", "sql/sql0.sql", "explain/sql0.txt", + "statsMem/test.t_dump_single.txt", + "sql_meta.toml", } for _, f := range files { if strings.Compare(f, s) == 0 { @@ -165,6 +169,53 @@ func TestPlanReplayer(t *testing.T) { tk.MustQuery("plan replayer dump explain select * from v1") tk.MustQuery("plan replayer dump explain select * from v2") require.True(t, len(tk.Session().GetSessionVars().LastPlanReplayerToken) > 0) + + // clear the status table and assert + tk.MustExec("delete from mysql.plan_replayer_status") + tk.MustQuery("plan replayer dump explain select * from v2") + token := tk.Session().GetSessionVars().LastPlanReplayerToken + rows := tk.MustQuery(fmt.Sprintf("select * from mysql.plan_replayer_status where token = '%v'", token)).Rows() + require.Len(t, rows, 1) +} + +func TestPlanReplayerCapture(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("plan replayer capture '123' '123';") + tk.MustQuery("select sql_digest, plan_digest from mysql.plan_replayer_task;").Check(testkit.Rows("123 123")) + tk.MustGetErrMsg("plan replayer capture '123' '123';", "plan replayer capture task already exists") + tk.MustExec("delete from mysql.plan_replayer_task") + tk.MustExec("create table t(id int)") + tk.MustExec("prepare stmt from 'update t set id = ? where id = ? + 1';") + tk.MustExec("SET @number = 5;") + tk.MustExec("execute stmt using @number,@number") + _, sqlDigest := tk.Session().GetSessionVars().StmtCtx.SQLDigest() + _, planDigest := tk.Session().GetSessionVars().StmtCtx.GetPlanDigest() + tk.MustExec("SET @@tidb_enable_plan_replayer_capture = ON;") + tk.MustExec(fmt.Sprintf("plan replayer capture '%v' '%v'", sqlDigest.String(), planDigest.String())) + err := dom.GetPlanReplayerHandle().CollectPlanReplayerTask() + require.NoError(t, err) + tk.MustExec("execute stmt using @number,@number") + task := dom.GetPlanReplayerHandle().DrainTask() + require.NotNil(t, task) +} + +func TestPlanReplayerContinuesCapture(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + prHandle := dom.GetPlanReplayerHandle() + tk.MustExec("delete from mysql.plan_replayer_status;") + tk.MustExec("use test") + tk.MustExec("create table t(id int);") + tk.MustExec("set @@tidb_enable_plan_replayer_continues_capture = 'ON'") + tk.MustQuery("select * from t;") + task := prHandle.DrainTask() + require.NotNil(t, task) + worker := prHandle.GetWorker() + success := worker.HandleTask(task) + require.True(t, success) + tk.MustQuery("select count(*) from mysql.plan_replayer_status").Check(testkit.Rows("1")) } func TestShow(t *testing.T) { @@ -183,13 +234,16 @@ func TestShow(t *testing.T) { tk.MustQuery("show create database test_show").Check(testkit.Rows("test_show CREATE DATABASE `test_show` /*!40100 DEFAULT CHARACTER SET utf8mb4 */")) tk.MustQuery("show privileges").Check(testkit.Rows("Alter Tables To alter the table", "Alter routine Functions,Procedures To alter or drop stored functions/procedures", + "Config Server Admin To use SHOW CONFIG and SET CONFIG statements", "Create Databases,Tables,Indexes To create new databases and tables", "Create routine Databases To use CREATE FUNCTION/PROCEDURE", + "Create role Server Admin To create new roles", "Create temporary tables Databases To use CREATE TEMPORARY TABLE", "Create view Tables To create new views", "Create user Server Admin To create new users", "Delete Tables To delete existing rows", "Drop Databases,Tables To drop databases, tables, and views", + "Drop role Server Admin To drop roles", "Event Server Admin To create, alter, drop and execute events", "Execute Functions,Procedures To execute stored routines", "File File access on server To read and write files on the server", @@ -226,6 +280,7 @@ func TestShow(t *testing.T) { "RESTRICTED_USER_ADMIN Server Admin ", "RESTRICTED_CONNECTION_ADMIN Server Admin ", "RESTRICTED_REPLICA_WRITER_ADMIN Server Admin ", + "RESOURCE_GROUP_ADMIN Server Admin ", )) require.Len(t, tk.MustQuery("show table status").Rows(), 1) } @@ -1445,6 +1500,7 @@ func TestSetOperation(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec(`use test`) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`drop table if exists t1, t2, t3`) tk.MustExec(`create table t1(a int)`) tk.MustExec(`create table t2 like t1`) @@ -1469,6 +1525,21 @@ func TestSetOperation(t *testing.T) { tk.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Plan...)) tk.MustQuery(tt).Sort().Check(testkit.Rows(output[i].Res...)) } + + // from https://github.com/pingcap/tidb/issues/40279 + tk.MustExec("CREATE TABLE `issue40279` (`a` char(155) NOT NULL DEFAULT 'on1unvbxp5sko6mbetn3ku26tuiyju7w3wc0olzto9ew7gsrx',`b` mediumint(9) NOT NULL DEFAULT '2525518',PRIMARY KEY (`b`,`a`) /*T![clustered_index] CLUSTERED */);") + tk.MustExec("insert into `issue40279` values ();") + tk.MustQuery("( select `issue40279`.`b` as r0 , from_base64( `issue40279`.`a` ) as r1 from `issue40279` ) " + + "except ( " + + "select `issue40279`.`a` as r0 , elt(2, `issue40279`.`a` , `issue40279`.`a` ) as r1 from `issue40279`);"). + Check(testkit.Rows("2525518 ")) + tk.MustExec("drop table if exists t2") + + tk.MustExec("CREATE TABLE `t2` ( `a` varchar(20) CHARACTER SET gbk COLLATE gbk_chinese_ci DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin") + tk.MustExec("insert into t2 values(0xCED2)") + result := tk.MustQuery("(select elt(2,t2.a,t2.a) from t2) except (select 0xCED2 from t2)") + rows := result.Rows() + require.Len(t, rows, 0) } func TestSetOperationOnDiffColType(t *testing.T) { @@ -1506,6 +1577,7 @@ func TestIndexScanWithYearCol(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (c1 year(4), c2 int, key(c1));") tk.MustExec("insert into t values(2001, 1);") @@ -1551,7 +1623,7 @@ func TestPlanReplayerDumpSingle(t *testing.T) { res := tk.MustQuery("plan replayer dump explain select * from t_dump_single") path := testdata.ConvertRowsToStrings(res.Rows()) - reader, err := zip.OpenReader(filepath.Join(domain.GetPlanReplayerDirName(), path[0])) + reader, err := zip.OpenReader(filepath.Join(replayer.GetPlanReplayerDirName(), path[0])) require.NoError(t, err) defer func() { require.NoError(t, reader.Close()) }() for _, file := range reader.File { @@ -1904,7 +1976,7 @@ func TestCheckIndex(t *testing.T) { tbInfo := tbl.Meta() alloc := autoid.NewAllocator(store, dbInfo.ID, tbInfo.ID, false, autoid.RowIDAllocType) - tb, err := tables.TableFromMeta(autoid.NewAllocators(alloc), tbInfo) + tb, err := tables.TableFromMeta(autoid.NewAllocators(false, alloc), tbInfo) require.NoError(t, err) _, err = se.Execute(context.Background(), "admin check index t c") @@ -2825,7 +2897,7 @@ func TestInsertIntoGivenPartitionSet(t *testing.T) { tk.MustExec("insert into t1 partition(p0, p1) values(3, 'c'), (4, 'd')") tk.MustQuery("select * from t1 partition(p1)").Check(testkit.Rows()) - tk.MustGetErrMsg("insert into t1 values(1, 'a')", "[kv:1062]Duplicate entry '1' for key 'idx_a'") + tk.MustGetErrMsg("insert into t1 values(1, 'a')", "[kv:1062]Duplicate entry '1' for key 't1.idx_a'") tk.MustGetErrMsg("insert into t1 partition(p0, p_non_exist) values(1, 'a')", "[table:1735]Unknown partition 'p_non_exist' in table 't1'") tk.MustGetErrMsg("insert into t1 partition(p0, p1) values(40, 'a')", "[table:1748]Found a row not matching the given partition set") @@ -2856,7 +2928,7 @@ func TestInsertIntoGivenPartitionSet(t *testing.T) { tk.MustQuery("select * from t1 partition(p1) order by a").Check(testkit.Rows()) tk.MustQuery("select * from t1 partition(p0) order by a").Check(testkit.Rows("1 a", "2 b", "3 c", "4 d")) - tk.MustGetErrMsg("insert into t1 select 1, 'a'", "[kv:1062]Duplicate entry '1' for key 'idx_a'") + tk.MustGetErrMsg("insert into t1 select 1, 'a'", "[kv:1062]Duplicate entry '1' for key 't1.idx_a'") tk.MustGetErrMsg("insert into t1 partition(p0, p_non_exist) select 1, 'a'", "[table:1735]Unknown partition 'p_non_exist' in table 't1'") tk.MustGetErrMsg("insert into t1 partition(p0, p1) select 40, 'a'", "[table:1748]Found a row not matching the given partition set") @@ -3022,7 +3094,7 @@ func TestPrevStmtDesensitization(t *testing.T) { tk.MustExec("begin") tk.MustExec("insert into t values (1),(2)") require.Equal(t, "insert into `t` values ( ? ) , ( ? )", tk.Session().GetSessionVars().PrevStmt.String()) - tk.MustGetErrMsg("insert into t values (1)", `[kv:1062]Duplicate entry '?' for key 'a'`) + tk.MustGetErrMsg("insert into t values (1)", `[kv:1062]Duplicate entry '?' for key 't.a'`) } func TestIssue19372(t *testing.T) { @@ -3325,6 +3397,7 @@ func TestUnreasonablyClose(t *testing.T) { is := infoschema.MockInfoSchema([]*model.TableInfo{plannercore.MockSignedTable(), plannercore.MockUnsignedTable()}) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") // To enable the shuffleExec operator. tk.MustExec("set @@tidb_merge_join_concurrency=4") @@ -3365,7 +3438,7 @@ func TestUnreasonablyClose(t *testing.T) { "select /*+ inl_hash_join(t1) */ * from t t1 join t t2 on t1.f=t2.f", "SELECT count(1) FROM (SELECT (SELECT min(a) FROM t as t2 WHERE t2.a > t1.a) AS a from t as t1) t", "select /*+ hash_agg() */ count(f) from t group by a", - "select /*+ stream_agg() */ count(f) from t group by a", + "select /*+ stream_agg() */ count(f) from t", "select * from t order by a, f", "select * from t order by a, f limit 1", "select * from t limit 1", @@ -3568,10 +3641,10 @@ func TestPointGetPreparedPlan(t *testing.T) { pspk1Id, _, _, err := tk.Session().PrepareStmt("select * from t where a = ?") require.NoError(t, err) - tk.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).StmtCacheable = false pspk2Id, _, _, err := tk.Session().PrepareStmt("select * from t where ? = a ") require.NoError(t, err) - tk.Session().GetSessionVars().PreparedStmts[pspk2Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk.Session().GetSessionVars().PreparedStmts[pspk2Id].(*plannercore.PlanCacheStmt).StmtCacheable = false ctx := context.Background() // first time plan generated @@ -3611,7 +3684,7 @@ func TestPointGetPreparedPlan(t *testing.T) { // unique index psuk1Id, _, _, err := tk.Session().PrepareStmt("select * from t where b = ? ") require.NoError(t, err) - tk.Session().GetSessionVars().PreparedStmts[psuk1Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk.Session().GetSessionVars().PreparedStmts[psuk1Id].(*plannercore.PlanCacheStmt).StmtCacheable = false rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(1)) require.NoError(t, err) @@ -3729,7 +3802,7 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) { pspk1Id, _, _, err := tk1.Session().PrepareStmt("select * from t where a = ?") require.NoError(t, err) - tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).StmtCacheable = false ctx := context.Background() // first time plan generated @@ -3795,11 +3868,11 @@ func TestPointUpdatePreparedPlan(t *testing.T) { updateID1, pc, _, err := tk.Session().PrepareStmt(`update t set c = c + 1 where a = ?`) require.NoError(t, err) - tk.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).StmtCacheable = false require.Equal(t, 1, pc) updateID2, pc, _, err := tk.Session().PrepareStmt(`update t set c = c + 2 where ? = a`) require.NoError(t, err) - tk.Session().GetSessionVars().PreparedStmts[updateID2].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk.Session().GetSessionVars().PreparedStmts[updateID2].(*plannercore.PlanCacheStmt).StmtCacheable = false require.Equal(t, 1, pc) ctx := context.Background() @@ -3834,7 +3907,7 @@ func TestPointUpdatePreparedPlan(t *testing.T) { // unique index updUkID1, _, _, err := tk.Session().PrepareStmt(`update t set c = c + 10 where b = ?`) require.NoError(t, err) - tk.Session().GetSessionVars().PreparedStmts[updUkID1].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk.Session().GetSessionVars().PreparedStmts[updUkID1].(*plannercore.PlanCacheStmt).StmtCacheable = false rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3)) require.Nil(t, rs) require.NoError(t, err) @@ -3903,7 +3976,7 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) { ctx := context.Background() updateID1, _, _, err := tk1.Session().PrepareStmt(`update t set c = c + 1 where a = ?`) - tk1.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false + tk1.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).StmtCacheable = false require.NoError(t, err) // first time plan generated @@ -3972,12 +4045,13 @@ func TestApplyCache(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t;") tk.MustExec("create table t(a int);") tk.MustExec("insert into t values (1),(1),(1),(1),(1),(1),(1),(1),(1);") tk.MustExec("analyze table t;") result := tk.MustQuery("explain analyze SELECT count(1) FROM (SELECT (SELECT min(a) FROM t as t2 WHERE t2.a > t1.a) AS a from t as t1) t;") - require.Equal(t, "└─Apply_39", result.Rows()[1][0]) + require.Contains(t, result.Rows()[1][0], "Apply") var ( ind int flag bool @@ -3997,7 +4071,7 @@ func TestApplyCache(t *testing.T) { tk.MustExec("insert into t values (1),(2),(3),(4),(5),(6),(7),(8),(9);") tk.MustExec("analyze table t;") result = tk.MustQuery("explain analyze SELECT count(1) FROM (SELECT (SELECT min(a) FROM t as t2 WHERE t2.a > t1.a) AS a from t as t1) t;") - require.Equal(t, "└─Apply_39", result.Rows()[1][0]) + require.Contains(t, result.Rows()[1][0], "Apply") flag = false value = (result.Rows()[1][5]).(string) for ind = 0; ind < len(value)-5; ind++ { @@ -4309,7 +4383,7 @@ func TestAdminShowDDLJobs(t *testing.T) { require.NoError(t, err) err = meta.NewMeta(txn).AddHistoryDDLJob(job, true) require.NoError(t, err) - tk.Session().StmtCommit() + tk.Session().StmtCommit(context.Background()) re = tk.MustQuery("admin show ddl jobs 1") row = re.Rows()[0] @@ -4583,13 +4657,10 @@ func TestUnion2(t *testing.T) { terr = errors.Cause(err).(*terror.Error) require.Equal(t, errors.ErrCode(mysql.ErrWrongUsage), terr.Code()) - _, err = tk.Exec("(select a from t order by a) union all select a from t limit 1 union all select a from t limit 1") - require.Truef(t, terror.ErrorEqual(err, plannercore.ErrWrongUsage), "err %v", err) + tk.MustGetDBError("(select a from t order by a) union all select a from t limit 1 union all select a from t limit 1", plannercore.ErrWrongUsage) - _, err = tk.Exec("(select a from t limit 1) union all select a from t limit 1") - require.NoError(t, err) - _, err = tk.Exec("(select a from t order by a) union all select a from t order by a") - require.NoError(t, err) + tk.MustExec("(select a from t limit 1) union all select a from t limit 1") + tk.MustExec("(select a from t order by a) union all select a from t order by a") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int)") @@ -4660,8 +4731,8 @@ func TestUnion2(t *testing.T) { tk.MustExec("insert into t2 values(3,'c'),(4,'d'),(5,'f'),(6,'e')") tk.MustExec("analyze table t1") tk.MustExec("analyze table t2") - _, err = tk.Exec("(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b") - require.Equal(t, "[planner:1250]Table 't1' from one of the SELECTs cannot be used in global ORDER clause", err.Error()) + tk.MustGetErrMsg("(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b", + "[planner:1250]Table 't1' from one of the SELECTs cannot be used in global ORDER clause") // #issue 9900 tk.MustExec("drop table if exists t") @@ -4815,15 +4886,11 @@ func TestSQLMode(t *testing.T) { tk.MustExec("drop table if exists t") tk.MustExec("create table t (a tinyint not null)") tk.MustExec("set sql_mode = 'STRICT_TRANS_TABLES'") - _, err := tk.Exec("insert t values ()") - require.Error(t, err) - - _, err = tk.Exec("insert t values ('1000')") - require.Error(t, err) + tk.ExecToErr("insert t values ()") + tk.ExecToErr("insert t values ('1000')") tk.MustExec("create table if not exists tdouble (a double(3,2))") - _, err = tk.Exec("insert tdouble values (10.23)") - require.Error(t, err) + tk.ExecToErr("insert tdouble values (10.23)") tk.MustExec("set sql_mode = ''") tk.MustExec("insert t values ()") @@ -4851,8 +4918,7 @@ func TestSQLMode(t *testing.T) { tk2.MustQuery("select * from t2").Check(testkit.Rows("abc")) // session1 is still in strict mode. - _, err = tk.Exec("insert t2 values ('abcd')") - require.Error(t, err) + tk.ExecToErr("insert t2 values ('abcd')") // Restore original global strict mode. tk.MustExec("set @@global.sql_mode = 'STRICT_TRANS_TABLES'") } @@ -4931,7 +4997,7 @@ func TestIsPointGet(t *testing.T) { stmtNode, err := s.ParseOneStmt(sqlStr, "", "") require.NoError(t, err) preprocessorReturn := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(ctx, stmtNode, plannercore.WithPreprocessorReturn(preprocessorReturn)) + err = plannercore.Preprocess(context.Background(), ctx, stmtNode, plannercore.WithPreprocessorReturn(preprocessorReturn)) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), ctx, stmtNode, preprocessorReturn.InfoSchema) require.NoError(t, err) @@ -4964,7 +5030,7 @@ func TestClusteredIndexIsPointGet(t *testing.T) { stmtNode, err := s.ParseOneStmt(sqlStr, "", "") require.NoError(t, err) preprocessorReturn := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(ctx, stmtNode, plannercore.WithPreprocessorReturn(preprocessorReturn)) + err = plannercore.Preprocess(context.Background(), ctx, stmtNode, plannercore.WithPreprocessorReturn(preprocessorReturn)) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), ctx, stmtNode, preprocessorReturn.InfoSchema) require.NoError(t, err) @@ -5491,6 +5557,8 @@ func TestAdmin(t *testing.T) { })) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") tk.MustExec("drop table if exists admin_test") tk.MustExec("create table admin_test (c1 int, c2 int, c3 int default 1, index (c1))") tk.MustExec("insert admin_test (c1) values (1),(2),(NULL)") @@ -5600,6 +5668,68 @@ func TestAdmin(t *testing.T) { result.Check(testkit.Rows(fmt.Sprintf("%d %s", historyJobs[2].ID, historyJobs[2].Query), fmt.Sprintf("%d %s", historyJobs[3].ID, historyJobs[3].Query), fmt.Sprintf("%d %s", historyJobs[4].ID, historyJobs[4].Query))) require.NoError(t, err) + // check situations when `admin show ddl job 20` happens at the same time with new DDLs being executed + var wg sync.WaitGroup + wg.Add(2) + flag := true + go func() { + defer wg.Done() + for i := 0; i < 10; i++ { + tk.MustExec("drop table if exists admin_test9") + tk.MustExec("create table admin_test9 (c1 int, c2 int, c3 int default 1, index (c1))") + } + }() + go func() { + // check that the result set has no duplication + defer wg.Done() + for i := 0; i < 10; i++ { + result := tk2.MustQuery(`admin show ddl job queries 20`) + rows := result.Rows() + rowIDs := make(map[string]struct{}) + for _, row := range rows { + rowID := fmt.Sprintf("%v", row[0]) + if _, ok := rowIDs[rowID]; ok { + flag = false + return + } + rowIDs[rowID] = struct{}{} + } + } + }() + wg.Wait() + require.True(t, flag) + + // check situations when `admin show ddl job queries limit 3 offset 2` happens at the same time with new DDLs being executed + var wg2 sync.WaitGroup + wg2.Add(2) + flag = true + go func() { + defer wg2.Done() + for i := 0; i < 10; i++ { + tk.MustExec("drop table if exists admin_test9") + tk.MustExec("create table admin_test9 (c1 int, c2 int, c3 int default 1, index (c1))") + } + }() + go func() { + // check that the result set has no duplication + defer wg2.Done() + for i := 0; i < 10; i++ { + result := tk2.MustQuery(`admin show ddl job queries limit 3 offset 2`) + rows := result.Rows() + rowIDs := make(map[string]struct{}) + for _, row := range rows { + rowID := fmt.Sprintf("%v", row[0]) + if _, ok := rowIDs[rowID]; ok { + flag = false + return + } + rowIDs[rowID] = struct{}{} + } + } + }() + wg2.Wait() + require.True(t, flag) + // check table test tk.MustExec("create table admin_test1 (c1 int, c2 int default 1, index (c1))") tk.MustExec("insert admin_test1 (c1) values (21),(22)") @@ -5936,6 +6066,8 @@ func TestSummaryFailedUpdate(t *testing.T) { tk.Session().SetSessionManager(sm) dom.ExpensiveQueryHandle().SetSessionManager(sm) defer tk.MustExec("SET GLOBAL tidb_mem_oom_action = DEFAULT") + tk.MustQuery("select variable_value from mysql.GLOBAL_VARIABLES where variable_name = 'tidb_mem_oom_action'").Check(testkit.Rows("LOG")) + tk.MustExec("SET GLOBAL tidb_mem_oom_action='CANCEL'") require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) tk.MustExec("set @@tidb_mem_quota_query=1") @@ -6071,13 +6203,16 @@ func TestGlobalMemoryControl(t *testing.T) { tk0.MustExec("set global tidb_server_memory_limit_sess_min_size = 128") tk1 := testkit.NewTestKit(t, store) - tracker1 := tk1.Session().GetSessionVars().StmtCtx.MemTracker + tracker1 := tk1.Session().GetSessionVars().MemTracker + tracker1.FallbackOldAndSetNewAction(&memory.PanicOnExceed{}) tk2 := testkit.NewTestKit(t, store) - tracker2 := tk2.Session().GetSessionVars().StmtCtx.MemTracker + tracker2 := tk2.Session().GetSessionVars().MemTracker + tracker2.FallbackOldAndSetNewAction(&memory.PanicOnExceed{}) tk3 := testkit.NewTestKit(t, store) - tracker3 := tk3.Session().GetSessionVars().StmtCtx.MemTracker + tracker3 := tk3.Session().GetSessionVars().MemTracker + tracker3.FallbackOldAndSetNewAction(&memory.PanicOnExceed{}) sm := &testkit.MockSessionManager{ PS: []*util.ProcessInfo{tk1.Session().ShowProcess(), tk2.Session().ShowProcess(), tk3.Session().ShowProcess()}, @@ -6156,7 +6291,7 @@ func TestGlobalMemoryControl2(t *testing.T) { }() sql := "select * from t t1 join t t2 join t t3 on t1.a=t2.a and t1.a=t3.a order by t1.a;" // Need 500MB require.True(t, strings.Contains(tk0.QueryToErr(sql).Error(), "Out Of Memory Quota!")) - require.Equal(t, tk0.Session().GetSessionVars().StmtCtx.DiskTracker.MaxConsumed(), int64(0)) + require.Equal(t, tk0.Session().GetSessionVars().DiskTracker.MaxConsumed(), int64(0)) wg.Wait() test[0] = 0 runtime.GC() @@ -6176,3 +6311,79 @@ func TestCompileOutOfMemoryQuota(t *testing.T) { err := tk.ExecToErr("select t.a, t1.a from t use index(idx), t1 use index(idx) where t.a = t1.a") require.Contains(t, err.Error(), "Out Of Memory Quota!") } + +func TestSignalCheckpointForSort(t *testing.T) { + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/SignalCheckpointForSort", `return(true)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/SignalCheckpointForSort")) + }() + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/util/chunk/SignalCheckpointForSort", `return(true)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/util/chunk/SignalCheckpointForSort")) + }() + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + defer tk.MustExec("set global tidb_mem_oom_action = DEFAULT") + tk.MustExec("set global tidb_mem_oom_action='CANCEL'") + tk.MustExec("set tidb_mem_quota_query = 100000000") + tk.MustExec("use test") + tk.MustExec("create table t(a int)") + for i := 0; i < 20; i++ { + tk.MustExec(fmt.Sprintf("insert into t values(%d)", i)) + } + tk.Session().GetSessionVars().ConnectionID = 123456 + + err := tk.QueryToErr("select * from t order by a") + require.Contains(t, err.Error(), "Out Of Memory Quota!") +} + +func TestSessionRootTrackerDetach(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + defer tk.MustExec("set global tidb_mem_oom_action = DEFAULT") + tk.MustExec("set global tidb_mem_oom_action='CANCEL'") + tk.MustExec("use test") + tk.MustExec("create table t(a int, b int, index idx(a))") + tk.MustExec("create table t1(a int, c int, index idx(a))") + tk.MustExec("set tidb_mem_quota_query=10") + tk.MustContainErrMsg("select /*+hash_join(t1)*/ t.a, t1.a from t use index(idx), t1 use index(idx) where t.a = t1.a", "Out Of Memory Quota!") + tk.MustExec("set tidb_mem_quota_query=1000") + rs, err := tk.Exec("select /*+hash_join(t1)*/ t.a, t1.a from t use index(idx), t1 use index(idx) where t.a = t1.a") + require.NoError(t, err) + require.NotNil(t, tk.Session().GetSessionVars().MemTracker.GetFallbackForTest(false)) + err = rs.Close() + require.NoError(t, err) + require.Nil(t, tk.Session().GetSessionVars().MemTracker.GetFallbackForTest(false)) +} + +func TestIssue39211(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t;") + tk.MustExec("drop table if exists s;") + + tk.MustExec("CREATE TABLE `t` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL);") + tk.MustExec("CREATE TABLE `s` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL);") + tk.MustExec("insert into t values(1,1),(2,2);") + tk.MustExec("insert into t select * from t;") + tk.MustExec("insert into t select * from t;") + tk.MustExec("insert into t select * from t;") + tk.MustExec("insert into t select * from t;") + tk.MustExec("insert into t select * from t;") + tk.MustExec("insert into t select * from t;") + tk.MustExec("insert into t select * from t;") + tk.MustExec("insert into t select * from t;") + + tk.MustExec("insert into s values(3,3),(4,4),(1,null),(2,null),(null,null);") + tk.MustExec("insert into s select * from s;") + tk.MustExec("insert into s select * from s;") + tk.MustExec("insert into s select * from s;") + tk.MustExec("insert into s select * from s;") + tk.MustExec("insert into s select * from s;") + + tk.MustExec("set @@tidb_max_chunk_size=32;") + tk.MustExec("set @@tidb_enable_null_aware_anti_join=true;") + tk.MustQuery("select * from t where (a,b) not in (select a, b from s);").Check(testkit.Rows()) +} diff --git a/executor/explain.go b/executor/explain.go index 7699751600b89..3f9f1eec6704e 100644 --- a/executor/explain.go +++ b/executor/explain.go @@ -20,6 +20,7 @@ import ( "path/filepath" "runtime" rpprof "runtime/pprof" + "sort" "strconv" "sync" "time" @@ -114,12 +115,12 @@ func (e *ExplainExec) executeAnalyzeExec(ctx context.Context) (err error) { minHeapInUse: mathutil.Abs(minHeapInUse), alarmRatio: alarmRatio, autoGC: minHeapInUse > 0, - memTracker: e.ctx.GetSessionVars().StmtCtx.MemTracker, + memTracker: e.ctx.GetSessionVars().MemTracker, wg: &waitGroup, }).run() } e.executed = true - chk := newFirstChunk(e.analyzeExec) + chk := tryNewCacheChunk(e.analyzeExec) for { err = Next(ctx, e.analyzeExec, chk) if err != nil || chk.NumRows() == 0 { @@ -168,8 +169,7 @@ func (h *memoryDebugModeHandler) fetchCurrentMemoryUsage(gc bool) (heapInUse, tr if gc { runtime.GC() } - instanceStats := &runtime.MemStats{} - runtime.ReadMemStats(instanceStats) + instanceStats := memory.ForceReadMemStats() heapInUse = instanceStats.HeapInuse trackedMem = uint64(h.memTracker.BytesConsumed()) return @@ -188,6 +188,20 @@ func (h *memoryDebugModeHandler) genInfo(status string, needProfile bool, heapIn return h.infoField, err } +func (h *memoryDebugModeHandler) getTrackerTreeMemUseLogs() []zap.Field { + trackerMemUseMap := h.memTracker.CountAllChildrenMemUse() + logs := make([]zap.Field, 0, len(trackerMemUseMap)) + keys := make([]string, 0, len(trackerMemUseMap)) + for k := range trackerMemUseMap { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + logs = append(logs, zap.String("TrackerTree "+k, memory.FormatBytes(trackerMemUseMap[k]))) + } + return logs +} + func updateTriggerIntervalByHeapInUse(heapInUse uint64) (time.Duration, int) { const GB uint64 = 1 << 30 if heapInUse < 30*GB { @@ -264,7 +278,8 @@ func (h *memoryDebugModeHandler) run() { for _, t := range ts { logs = append(logs, zap.String("Executor_"+strconv.Itoa(t.Label()), memory.FormatBytes(t.BytesConsumed()))) } - logutil.BgLogger().Warn("Memory Debug Mode, Log all trackers that consumes more than threshold * 20%", logs...) + logutil.BgLogger().Warn("Memory Debug Mode, Log all executors that consumes more than threshold * 20%", logs...) + logutil.BgLogger().Warn("Memory Debug Mode, Log the tracker tree", h.getTrackerTreeMemUseLogs()...) } } } diff --git a/executor/explain_test.go b/executor/explain_test.go index 4899f8a354403..28dbbbe12fcf6 100644 --- a/executor/explain_test.go +++ b/executor/explain_test.go @@ -16,6 +16,7 @@ package executor_test import ( "bytes" + "encoding/json" "fmt" "regexp" "strconv" @@ -246,6 +247,7 @@ func TestExplainAnalyzeExecutionInfo(t *testing.T) { checkExecutionInfo(t, tk, "explain analyze select * from t use index(k)") checkExecutionInfo(t, tk, "explain analyze with recursive cte(a) as (select 1 union select a + 1 from cte where a < 1000) select * from cte;") + tk.MustExec("set @@foreign_key_checks=0") tk.MustExec("CREATE TABLE IF NOT EXISTS nation ( N_NATIONKEY BIGINT NOT NULL,N_NAME CHAR(25) NOT NULL,N_REGIONKEY BIGINT NOT NULL,N_COMMENT VARCHAR(152),PRIMARY KEY (N_NATIONKEY));") tk.MustExec("CREATE TABLE IF NOT EXISTS part ( P_PARTKEY BIGINT NOT NULL,P_NAME VARCHAR(55) NOT NULL,P_MFGR CHAR(25) NOT NULL,P_BRAND CHAR(10) NOT NULL,P_TYPE VARCHAR(25) NOT NULL,P_SIZE BIGINT NOT NULL,P_CONTAINER CHAR(10) NOT NULL,P_RETAILPRICE DECIMAL(15,2) NOT NULL,P_COMMENT VARCHAR(23) NOT NULL,PRIMARY KEY (P_PARTKEY));") tk.MustExec("CREATE TABLE IF NOT EXISTS supplier ( S_SUPPKEY BIGINT NOT NULL,S_NAME CHAR(25) NOT NULL,S_ADDRESS VARCHAR(40) NOT NULL,S_NATIONKEY BIGINT NOT NULL,S_PHONE CHAR(15) NOT NULL,S_ACCTBAL DECIMAL(15,2) NOT NULL,S_COMMENT VARCHAR(101) NOT NULL,PRIMARY KEY (S_SUPPKEY),CONSTRAINT FOREIGN KEY SUPPLIER_FK1 (S_NATIONKEY) references nation(N_NATIONKEY));") @@ -321,6 +323,7 @@ func TestCheckActRowsWithUnistore(t *testing.T) { // testSuite1 use default mockstore which is unistore tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t_unistore_act_rows") tk.MustExec("create table t_unistore_act_rows(a int, b int, index(a, b))") tk.MustExec("insert into t_unistore_act_rows values (1, 0), (1, 0), (2, 0), (2, 1)") @@ -363,7 +366,7 @@ func TestCheckActRowsWithUnistore(t *testing.T) { }, { sql: "select count(*) from t_unistore_act_rows group by b", - expected: []string{"2", "2", "2", "4"}, + expected: []string{"2", "4", "4"}, }, { sql: "with cte(a) as (select a from t_unistore_act_rows) select (select 1 from cte limit 1) from cte;", @@ -514,3 +517,96 @@ func TestIssue35105(t *testing.T) { require.Error(t, tk.ExecToErr("explain analyze insert into t values (1), (2), (3)")) tk.MustQuery("select * from t").Check(testkit.Rows("2")) } + +func flatJSONPlan(j *plannercore.ExplainInfoForEncode) (res []*plannercore.ExplainInfoForEncode) { + if j == nil { + return + } + res = append(res, j) + for _, child := range j.SubOperators { + res = append(res, flatJSONPlan(child)...) + } + return +} + +func TestExplainJSON(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1(id int, key(id))") + tk.MustExec("create table t2(id int, key(id))") + cases := []string{ + "select * from t1", + "select count(*) from t2", + "select * from t1, t2 where t1.id = t2.id", + "select /*+ merge_join(t1, t2)*/ * from t1, t2 where t1.id = t2.id", + "with top10 as ( select * from t1 order by id desc limit 10 ) select * from top10 where id in (1,2)", + "insert into t1 values(1)", + "delete from t2 where t2.id > 10", + "update t2 set id = 1 where id =2", + "select * from t1 where t1.id < (select sum(t2.id) from t2 where t2.id = t1.id)", + } + // test syntax + tk.MustExec("explain format = 'tidb_json' select * from t1") + tk.MustExec("explain format = tidb_json select * from t1") + tk.MustExec("explain format = 'TIDB_JSON' select * from t1") + tk.MustExec("explain format = TIDB_JSON select * from t1") + tk.MustExec("explain analyze format = 'tidb_json' select * from t1") + tk.MustExec("explain analyze format = tidb_json select * from t1") + tk.MustExec("explain analyze format = 'TIDB_JSON' select * from t1") + tk.MustExec("explain analyze format = TIDB_JSON select * from t1") + + // explain + for _, sql := range cases { + jsonForamt := "explain format = tidb_json " + sql + rowForamt := "explain format = row " + sql + resJSON := tk.MustQuery(jsonForamt).Rows() + resRow := tk.MustQuery(rowForamt).Rows() + + j := new([]*plannercore.ExplainInfoForEncode) + require.NoError(t, json.Unmarshal([]byte(resJSON[0][0].(string)), j)) + var flatJSONRows []*plannercore.ExplainInfoForEncode + for _, row := range *j { + flatJSONRows = append(flatJSONRows, flatJSONPlan(row)...) + } + require.Equal(t, len(flatJSONRows), len(resRow)) + + for i, row := range resRow { + require.Contains(t, row[0], flatJSONRows[i].ID) + require.Equal(t, flatJSONRows[i].EstRows, row[1]) + require.Equal(t, flatJSONRows[i].TaskType, row[2]) + require.Equal(t, flatJSONRows[i].AccessObject, row[3]) + require.Equal(t, flatJSONRows[i].OperatorInfo, row[4]) + } + } + + // explain analyze + for _, sql := range cases { + jsonForamt := "explain analyze format = tidb_json " + sql + rowForamt := "explain analyze format = row " + sql + resJSON := tk.MustQuery(jsonForamt).Rows() + resRow := tk.MustQuery(rowForamt).Rows() + + j := new([]*plannercore.ExplainInfoForEncode) + require.NoError(t, json.Unmarshal([]byte(resJSON[0][0].(string)), j)) + var flatJSONRows []*plannercore.ExplainInfoForEncode + for _, row := range *j { + flatJSONRows = append(flatJSONRows, flatJSONPlan(row)...) + } + require.Equal(t, len(flatJSONRows), len(resRow)) + + for i, row := range resRow { + require.Contains(t, row[0], flatJSONRows[i].ID) + require.Equal(t, flatJSONRows[i].EstRows, row[1]) + require.Equal(t, flatJSONRows[i].ActRows, row[2]) + require.Equal(t, flatJSONRows[i].TaskType, row[3]) + require.Equal(t, flatJSONRows[i].AccessObject, row[4]) + require.Equal(t, flatJSONRows[i].OperatorInfo, row[6]) + // executeInfo, memory, disk maybe vary in multi execution + require.NotEqual(t, flatJSONRows[i].ExecuteInfo, "") + require.NotEqual(t, flatJSONRows[i].MemoryInfo, "") + require.NotEqual(t, flatJSONRows[i].DiskInfo, "") + } + } +} diff --git a/executor/explainfor_test.go b/executor/explainfor_test.go index 21617c95aa1b7..ddb0578338c6f 100644 --- a/executor/explainfor_test.go +++ b/executor/explainfor_test.go @@ -16,6 +16,7 @@ package executor_test import ( "bytes" + "encoding/json" "fmt" "strconv" "testing" @@ -443,6 +444,7 @@ func TestPointGetUserVarPlanCache(t *testing.T) { tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost", CurrentUser: true, AuthUsername: "root", AuthHostname: "%"}, nil, []byte("012345678901234567890")) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@tidb_enable_collect_execution_info=0;") tk.Session().GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeOn tk.MustExec("drop table if exists t1") @@ -461,12 +463,12 @@ func TestPointGetUserVarPlanCache(t *testing.T) { tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Check(testkit.Rows( // can use idx_a `Projection_9 1.00 root test.t1.a, test.t1.b, test.t2.a, test.t2.b`, - `└─IndexJoin_17 1.00 root inner join, inner:TableReader_13, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)`, - ` ├─Selection_44(Build) 0.80 root not(isnull(test.t2.a))`, - ` │ └─Point_Get_43 1.00 root table:t2, index:idx_a(a) `, - ` └─TableReader_13(Probe) 0.00 root data:Selection_12`, - ` └─Selection_12 0.00 cop[tikv] eq(test.t1.a, 1)`, - ` └─TableRangeScan_11 1.00 cop[tikv] table:t1 range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo`)) + `└─MergeJoin_10 1.00 root inner join, left key:test.t2.a, right key:test.t1.a`, + ` ├─Selection_42(Build) 10.00 root eq(test.t1.a, 1)`, + ` │ └─TableReader_41 10.00 root data:TableRangeScan_40`, + ` │ └─TableRangeScan_40 10.00 cop[tikv] table:t1 range:[1,1], keep order:true, stats:pseudo`, + ` └─Selection_39(Probe) 0.80 root not(isnull(test.t2.a))`, + ` └─Point_Get_38 1.00 root table:t2, index:idx_a(a) `)) tk.MustExec("set @a=2") tk.MustQuery("execute stmt using @a").Check(testkit.Rows( @@ -477,12 +479,12 @@ func TestPointGetUserVarPlanCache(t *testing.T) { tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Check(testkit.Rows( // can use idx_a `Projection_9 1.00 root test.t1.a, test.t1.b, test.t2.a, test.t2.b`, - `└─IndexJoin_17 1.00 root inner join, inner:TableReader_13, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)`, - ` ├─Selection_44(Build) 0.80 root not(isnull(test.t2.a))`, - ` │ └─Point_Get_43 1.00 root table:t2, index:idx_a(a) `, - ` └─TableReader_13(Probe) 0.00 root data:Selection_12`, - ` └─Selection_12 0.00 cop[tikv] eq(test.t1.a, 2)`, - ` └─TableRangeScan_11 1.00 cop[tikv] table:t1 range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo`)) + `└─MergeJoin_10 1.00 root inner join, left key:test.t2.a, right key:test.t1.a`, + ` ├─Selection_42(Build) 10.00 root eq(test.t1.a, 2)`, + ` │ └─TableReader_41 10.00 root data:TableRangeScan_40`, + ` │ └─TableRangeScan_40 10.00 cop[tikv] table:t1 range:[2,2], keep order:true, stats:pseudo`, + ` └─Selection_39(Probe) 0.80 root not(isnull(test.t2.a))`, + ` └─Point_Get_38 1.00 root table:t2, index:idx_a(a) `)) tk.MustQuery("execute stmt using @a").Check(testkit.Rows( "2 4 2 2", )) @@ -549,9 +551,9 @@ func TestIssue28259(t *testing.T) { ps = []*util.ProcessInfo{tkProcess} tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10)) - require.Len(t, res.Rows(), 4) - require.Regexp(t, ".*Selection.*", res.Rows()[0][0]) - require.Regexp(t, ".*IndexFullScan.*", res.Rows()[3][0]) + require.Len(t, res.Rows(), 3) + require.Regexp(t, ".*Selection.*", res.Rows()[1][0]) + require.Regexp(t, ".*IndexFullScan.*", res.Rows()[2][0]) res = tk.MustQuery("explain format = 'brief' select col1 from UK_GCOL_VIRTUAL_18588 use index(UK_COL1) " + "where col1 between -1696020282760139948 and -2619168038882941276 or col1 < -4004648990067362699;") @@ -587,11 +589,9 @@ func TestIssue28259(t *testing.T) { ps = []*util.ProcessInfo{tkProcess} tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10)) - require.Len(t, res.Rows(), 5) - require.Regexp(t, ".*Selection.*", res.Rows()[1][0]) - require.Equal(t, "lt(test.t.b, 1), or(and(ge(test.t.a, 2), le(test.t.a, 1)), lt(test.t.a, 1))", res.Rows()[1][4]) - require.Regexp(t, ".*IndexReader.*", res.Rows()[2][0]) - require.Regexp(t, ".*IndexRangeScan.*", res.Rows()[4][0]) + require.Len(t, res.Rows(), 4) + require.Regexp(t, ".*Selection.*", res.Rows()[2][0]) + require.Regexp(t, ".*IndexRangeScan.*", res.Rows()[3][0]) res = tk.MustQuery("explain format = 'brief' select a from t use index(idx) " + "where (a between 0 and 2 or a < 2) and b < 1;") @@ -634,12 +634,11 @@ func TestIssue28259(t *testing.T) { ps = []*util.ProcessInfo{tkProcess} tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10)) - require.Len(t, res.Rows(), 6) - require.Regexp(t, ".*Selection.*", res.Rows()[1][0]) - require.Regexp(t, ".*IndexLookUp.*", res.Rows()[2][0]) - require.Regexp(t, ".*IndexRangeScan.*", res.Rows()[3][0]) - require.Regexp(t, ".*Selection.*", res.Rows()[4][0]) - require.Regexp(t, ".*TableRowIDScan.*", res.Rows()[5][0]) + require.Len(t, res.Rows(), 5) + require.Regexp(t, ".*IndexLookUp.*", res.Rows()[1][0]) + require.Regexp(t, ".*IndexRangeScan.*", res.Rows()[2][0]) + require.Regexp(t, ".*Selection.*", res.Rows()[3][0]) + require.Regexp(t, ".*TableRowIDScan.*", res.Rows()[4][0]) res = tk.MustQuery("explain format = 'brief' select /*+ USE_INDEX(t, idx) */ a from t use index(idx) " + "where (a between 0 and 2 or a < 2) and b < 1;") @@ -858,13 +857,13 @@ func TestIndexMerge4PlanCache(t *testing.T) { tk.MustExec("prepare stmt from 'select /*+ use_index_merge(t1) */ * from t1 where c=? or (b=? and (a >= ? and a <= ?));';") tk.MustQuery("execute stmt using @a, @a, @b, @a").Check(testkit.Rows("10 10 10")) tk.MustQuery("execute stmt using @b, @b, @b, @b").Check(testkit.Rows("11 11 11")) - tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0")) tk.MustExec("prepare stmt from 'select /*+ use_index_merge(t1) */ * from t1 where c=10 or (a >=? and a <= ?);';") tk.MustExec("set @a=9, @b=10, @c=11;") tk.MustQuery("execute stmt using @a, @a;").Check(testkit.Rows("10 10 10")) tk.MustQuery("execute stmt using @a, @c;").Check(testkit.Rows("10 10 10", "11 11 11")) - tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0")) // a>=9 and a<=9 --> a=9 tk.MustQuery("execute stmt using @c, @a;").Check(testkit.Rows("10 10 10")) tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1")) @@ -979,6 +978,7 @@ func TestSetOperations4PlanCache(t *testing.T) { func TestSPM4PlanCache(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`set tidb_enable_prepared_plan_cache=1`) tk.MustExec("use test") @@ -989,8 +989,8 @@ func TestSPM4PlanCache(t *testing.T) { tk.MustExec("admin reload bindings;") res := tk.MustQuery("explain format = 'brief' select * from t;") - require.Regexp(t, ".*TableReader.*", res.Rows()[0][0]) - require.Regexp(t, ".*TableFullScan.*", res.Rows()[1][0]) + require.Regexp(t, ".*IndexReader.*", res.Rows()[0][0]) + require.Regexp(t, ".*IndexFullScan.*", res.Rows()[1][0]) tk.MustExec("prepare stmt from 'select * from t;';") tk.MustQuery("execute stmt;").Check(testkit.Rows()) @@ -999,8 +999,8 @@ func TestSPM4PlanCache(t *testing.T) { ps := []*util.ProcessInfo{tkProcess} tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10)) - require.Regexp(t, ".*TableReader.*", res.Rows()[0][0]) - require.Regexp(t, ".*TableFullScan.*", res.Rows()[1][0]) + require.Regexp(t, ".*IndexReader.*", res.Rows()[0][0]) + require.Regexp(t, ".*IndexFullScan.*", res.Rows()[1][0]) tk.MustExec("create global binding for select * from t using select * from t use index(idx_a);") @@ -1393,3 +1393,74 @@ func TestIssue28792(t *testing.T) { r2 := tk.MustQuery("EXPLAIN SELECT t12.a, t12.b FROM t12 LEFT JOIN t97 use index () on t12.b = t97.b;").Rows() require.Equal(t, r2, r1) } + +func TestExplainForJSON(t *testing.T) { + store := testkit.CreateMockStore(t) + tk1 := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + + tk1.MustExec("use test") + tk1.MustExec("set @@tidb_enable_collect_execution_info=0;") + tk1.MustExec("drop table if exists t1") + tk1.MustExec("create table t1(id int);") + tk1.MustQuery("select * from t1;") + tk1RootProcess := tk1.Session().ShowProcess() + ps := []*util.ProcessInfo{tk1RootProcess} + tk1.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) + tk2.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) + resRow := tk2.MustQuery(fmt.Sprintf("explain format = 'row' for connection %d", tk1RootProcess.ID)).Rows() + resJSON := tk2.MustQuery(fmt.Sprintf("explain format = 'tidb_json' for connection %d", tk1RootProcess.ID)).Rows() + + j := new([]*core.ExplainInfoForEncode) + require.NoError(t, json.Unmarshal([]byte(resJSON[0][0].(string)), j)) + flatJSONRows := make([]*core.ExplainInfoForEncode, 0) + for _, row := range *j { + flatJSONRows = append(flatJSONRows, flatJSONPlan(row)...) + } + require.Equal(t, len(flatJSONRows), len(resRow)) + + for i, row := range resRow { + require.Contains(t, row[0], flatJSONRows[i].ID) + require.Equal(t, flatJSONRows[i].EstRows, row[1]) + require.Equal(t, flatJSONRows[i].TaskType, row[2]) + require.Equal(t, flatJSONRows[i].AccessObject, row[3]) + require.Equal(t, flatJSONRows[i].OperatorInfo, row[4]) + } + + tk1.MustExec("set @@tidb_enable_collect_execution_info=1;") + tk1.MustExec("drop table if exists t2") + tk1.MustExec("create table t2(id int);") + tk1.MustQuery("select * from t2;") + tk1RootProcess = tk1.Session().ShowProcess() + ps = []*util.ProcessInfo{tk1RootProcess} + tk1.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) + tk2.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) + resRow = tk2.MustQuery(fmt.Sprintf("explain format = 'row' for connection %d", tk1RootProcess.ID)).Rows() + resJSON = tk2.MustQuery(fmt.Sprintf("explain format = 'tidb_json' for connection %d", tk1RootProcess.ID)).Rows() + + j = new([]*core.ExplainInfoForEncode) + require.NoError(t, json.Unmarshal([]byte(resJSON[0][0].(string)), j)) + flatJSONRows = []*core.ExplainInfoForEncode{} + for _, row := range *j { + flatJSONRows = append(flatJSONRows, flatJSONPlan(row)...) + } + require.Equal(t, len(flatJSONRows), len(resRow)) + + for i, row := range resRow { + require.Contains(t, row[0], flatJSONRows[i].ID) + require.Equal(t, flatJSONRows[i].EstRows, row[1]) + require.Equal(t, flatJSONRows[i].ActRows, row[2]) + require.Equal(t, flatJSONRows[i].TaskType, row[3]) + require.Equal(t, flatJSONRows[i].AccessObject, row[4]) + require.Equal(t, flatJSONRows[i].OperatorInfo, row[6]) + // executeInfo, memory, disk maybe vary in multi execution + require.NotEqual(t, flatJSONRows[i].ExecuteInfo, "") + require.NotEqual(t, flatJSONRows[i].MemoryInfo, "") + require.NotEqual(t, flatJSONRows[i].DiskInfo, "") + } + // test syntax + tk2.MustExec(fmt.Sprintf("explain format = 'tidb_json' for connection %d", tk1RootProcess.ID)) + tk2.MustExec(fmt.Sprintf("explain format = tidb_json for connection %d", tk1RootProcess.ID)) + tk2.MustExec(fmt.Sprintf("explain format = 'TIDB_JSON' for connection %d", tk1RootProcess.ID)) + tk2.MustExec(fmt.Sprintf("explain format = TIDB_JSON for connection %d", tk1RootProcess.ID)) +} diff --git a/executor/fktest/BUILD.bazel b/executor/fktest/BUILD.bazel index 2b3151024fdd8..2c9f00dfa0624 100644 --- a/executor/fktest/BUILD.bazel +++ b/executor/fktest/BUILD.bazel @@ -8,11 +8,23 @@ go_test( "main_test.go", ], flaky = True, + shard_count = 20, deps = [ "//config", + "//executor", + "//infoschema", + "//kv", "//meta/autoid", + "//parser", + "//parser/ast", + "//parser/auth", + "//parser/format", + "//parser/model", + "//parser/mysql", "//planner/core", "//testkit", + "//types", + "//util/sqlexec", "@com_github_stretchr_testify//require", "@com_github_tikv_client_go_v2//tikv", "@org_uber_go_goleak//:goleak", diff --git a/executor/fktest/foreign_key_test.go b/executor/fktest/foreign_key_test.go index 3e52bd0a2ea31..fb29d391aaf09 100644 --- a/executor/fktest/foreign_key_test.go +++ b/executor/fktest/foreign_key_test.go @@ -15,13 +15,30 @@ package fk_test import ( + "bytes" + "context" "fmt" + "strconv" + "strings" "sync" + "sync/atomic" "testing" "time" + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/format" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/sqlexec" "github.com/stretchr/testify/require" ) @@ -479,14 +496,22 @@ func TestForeignKeyOnInsertIgnore(t *testing.T) { tk.MustExec("set @@global.tidb_enable_foreign_key=1") tk.MustExec("set @@foreign_key_checks=1") tk.MustExec("use test") - + // Test for foreign key index is primary key. tk.MustExec("CREATE TABLE t1 (i INT PRIMARY KEY);") tk.MustExec("CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i));") tk.MustExec("INSERT INTO t1 VALUES (1),(3);") - tk.MustExec("INSERT IGNORE INTO t2 VALUES (1),(2),(3),(4);") + tk.MustExec("INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2),(3),(4);") warning := "Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`))" tk.MustQuery("show warnings;").Check(testkit.Rows(warning, warning)) - tk.MustQuery("select * from t2").Check(testkit.Rows("1", "3")) + tk.MustQuery("select * from t2 order by i").Check(testkit.Rows("", "1", "1", "3")) + // Test for foreign key index is non-unique key. + tk.MustExec("drop table t1,t2") + tk.MustExec("CREATE TABLE t1 (i INT, index(i));") + tk.MustExec("CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i));") + tk.MustExec("INSERT INTO t1 VALUES (1),(3);") + tk.MustExec("INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2), (3), (2);") + tk.MustQuery("show warnings;").Check(testkit.Rows(warning, warning)) + tk.MustQuery("select * from t2 order by i").Check(testkit.Rows("", "1", "1", "3")) } func TestForeignKeyOnInsertOnDuplicateParentTableCheck(t *testing.T) { @@ -525,7 +550,7 @@ func TestForeignKeyOnInsertOnDuplicateParentTableCheck(t *testing.T) { tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 11 21 a")) tk.MustExec("insert into t1 (id, a, b) values (1, 11, 21) on duplicate key update id=11") - tk.MustGetDBError("insert into t1 (id, a, b) values (1, 11, 21) on duplicate key update a=a+10, b=b+20", plannercore.ErrRowIsReferenced2) + tk.MustGetDBError("insert into t1 (id, a, b) values (11, 11, 21) on duplicate key update a=a+10, b=b+20", plannercore.ErrRowIsReferenced2) tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("2 1112 2222", "3 1013 2023", "4 14 24", "11 11 21")) tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 11 21 a")) } @@ -547,6 +572,15 @@ func TestForeignKeyOnInsertOnDuplicateParentTableCheck(t *testing.T) { tk.MustGetDBError("insert into t1 (id, a, b) values (1, 0, 0) on duplicate key update id=100+id", plannercore.ErrRowIsReferenced2) tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 111 21", "4 14 24", "102 12 22", "103 13 23")) tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("11 1 21 a")) + + // Case-10: Test insert into parent table failed cause by foreign key check, see https://github.com/pingcap/tidb/issues/39200. + tk.MustExec("drop table if exists t1,t2;") + tk.MustExec("create table t1 (id int key);") + tk.MustExec("create table t2 (id int, foreign key fk(id) references t1(id));") + tk.MustExec("set @@foreign_key_checks=0") + tk.MustExec("insert into t2 values (1)") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("insert into t1 values (1) on duplicate key update id=2") } func TestForeignKey(t *testing.T) { @@ -832,3 +866,1976 @@ func TestForeignKeyOnDeleteParentTableCheck(t *testing.T) { tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) tk.MustQuery("select id, a from t1 order by id").Check(testkit.Rows("1 1")) } + +func TestForeignKeyOnDeleteCascade(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + cases := []struct { + prepareSQLs []string + }{ + // Case-1: test unique index only contain foreign key columns. + { + prepareSQLs: []string{ + "create table t1 (id int, a int, b int, unique index(a, b));", + "create table t2 (b int, name varchar(10), a int, id int, unique index (a,b), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + // Case-2: test unique index contain foreign key columns and other columns. + { + prepareSQLs: []string{ + "create table t1 (id int key, a int, b int, unique index(a, b, id));", + "create table t2 (b int, a int, id int key, name varchar(10), unique index (a,b, id), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + // Case-3: test non-unique index only contain foreign key columns. + { + prepareSQLs: []string{ + "create table t1 (id int key,a int, b int, index(a, b));", + "create table t2 (b int, a int, name varchar(10), id int key, index (a, b), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + // Case-4: test non-unique index contain foreign key columns and other columns. + { + prepareSQLs: []string{ + "create table t1 (id int key,a int, b int, index(a, b, id));", + "create table t2 (name varchar(10), b int, a int, id int key, index (a, b, id), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + } + + for idx, ca := range cases { + tk.MustExec("drop table if exists t1, t2;") + for _, sql := range ca.prepareSQLs { + tk.MustExec(sql) + } + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, null), (6, null, 6), (7, null, null);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd'), (5, 5, null, 'e'), (6, null, 6, 'f'), (7, null, null, 'g');") + tk.MustExec("delete from t1 where id = 1") + tk.MustExec("delete from t1 where id = 2 or a = 2") + tk.MustExec("delete from t1 where a in (2,3,4) or b in (5,6,7) or id=7") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("5 5 ")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("5 5 e", "6 6 f", "7 g")) + + // Test in transaction. + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, null), (6, null, 6), (7, null, null);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd'), (5, 5, null, 'e'), (6, null, 6, 'f'), (7, null, null, 'g');") + tk.MustExec("delete from t1 where id = 1 or a = 2") + tk.MustExec("delete from t1 where a in (2,3,4) or b in (5,6,7)") + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("5 5 e", "6 6 f", "7 g")) + tk.MustExec("rollback") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2);") + tk.MustExec("begin") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b')") + tk.MustExec("delete from t1 where id = 1") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("2 2 2 b")) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (1, 1, 1, 'a')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (1, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'c')") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 1 1", "2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 1 1 c", "2 2 2 b")) + tk.MustExec("delete from t1") + tk.MustExec("commit") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + + // only test in non-unique index + if idx >= 2 { + tk.MustExec("insert into t1 values (1, 1, 1),(2, 1, 1);") + tk.MustExec("begin") + tk.MustExec("delete from t1 where id = 1") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a')") + tk.MustExec("delete from t1 where id = 2") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (1, 1, 1, 'a')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (3, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (3, 1, 1, 'e')") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("3 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("3 1 1 e")) + + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'), (2, 1, 1, 'b')") + tk.MustExec("delete from t1 where id = 1") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("2 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows()) + } + } + + cases = []struct { + prepareSQLs []string + }{ + // Case-5: test primary key only contain foreign key columns, and disable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=0;", + "create table t1 (id int, a int, b int, primary key (a, b));", + "create table t2 (b int, name varchar(10), a int, id int, primary key (a, b), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + // Case-6: test primary key only contain foreign key columns, and enable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=1;", + "create table t1 (id int, a int, b int, primary key (a, b));", + "create table t2 (name varchar(10), b int, a int, id int, primary key (a, b), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + // Case-7: test primary key contain foreign key columns and other column, and disable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=0;", + "create table t1 (id int, a int, b int, primary key (a, b, id));", + "create table t2 (b int, a int, name varchar(10), id int, primary key (a, b, id), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + // Case-8: test primary key contain foreign key columns and other column, and enable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=1;", + "create table t1 (id int, a int, b int, primary key (a, b, id));", + "create table t2 (b int, name varchar(10), a int, id int, primary key (a, b, id), foreign key fk(a, b) references t1(a, b) ON DELETE CASCADE);", + }, + }, + // Case-9: test primary key is handle and contain foreign key column. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=0;", + "create table t1 (id int, a int, b int, primary key (id));", + "create table t2 (b int, a int, id int, name varchar(10), primary key (a), foreign key fk(a) references t1(id) ON DELETE CASCADE);", + }, + }, + } + for _, ca := range cases { + tk.MustExec("drop table if exists t1, t2;") + for _, sql := range ca.prepareSQLs { + tk.MustExec(sql) + } + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd');") + tk.MustExec("delete from t1 where id = 1 or a = 2") + tk.MustQuery("select id, a, b from t2 order by id").Check(testkit.Rows("3 3 3", "4 4 4")) + tk.MustExec("delete from t1 where a in (2,3) or b < 5") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + + // test in transaction. + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd');") + tk.MustExec("delete from t1 where id = 1 or a = 2") + tk.MustExec("delete from t1 where a in (2,3,4) or b in (5,6,7)") + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows()) + tk.MustExec("rollback") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2);") + tk.MustExec("begin") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b')") + tk.MustExec("delete from t1 where id = 1") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("2 2 2 b")) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (1, 1, 1, 'a')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (1, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'c')") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 1 1", "2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 1 1 c", "2 2 2 b")) + tk.MustExec("delete from t1") + tk.MustExec("commit") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + } +} + +func TestForeignKeyOnDeleteCascade2(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + // Test cascade delete in self table. + tk.MustExec("create table t1 (id int key, name varchar(10), leader int, index(leader), foreign key (leader) references t1(id) ON DELETE CASCADE);") + tk.MustExec("insert into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("insert into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10)") + tk.MustExec("insert into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11)") + tk.MustExec("insert into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12)") + tk.MustExec("insert into t1 values (1000,'l3_a1', 100)") + tk.MustExec("delete from t1 where id=11") + tk.MustQuery("select id from t1 order by id").Check(testkit.Rows("1", "10", "12", "100", "101", "102", "120", "121", "122", "1000")) + tk.MustExec("delete from t1 where id=1") + // The affect rows doesn't contain the cascade deleted rows, the behavior is compatible with MySQL. + require.Equal(t, uint64(1), tk.Session().GetSessionVars().StmtCtx.AffectedRows()) + tk.MustQuery("select id from t1 order by id").Check(testkit.Rows()) + + // Test explain analyze with foreign key cascade. + tk.MustExec("insert into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("explain analyze delete from t1 where id=1") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + + // Test string type foreign key. + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id varchar(10) key, name varchar(10), leader varchar(10), index(leader), foreign key (leader) references t1(id) ON DELETE CASCADE);") + tk.MustExec("insert into t1 values (1, 'boss', null)") + tk.MustExec("insert into t1 values (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("insert into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10)") + tk.MustExec("insert into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11)") + tk.MustExec("insert into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12)") + tk.MustExec("insert into t1 values (1000,'l3_a1', 100)") + tk.MustExec("delete from t1 where id=11") + tk.MustQuery("select id from t1 order by id").Check(testkit.Rows("1", "10", "100", "1000", "101", "102", "12", "120", "121", "122")) + tk.MustExec("delete from t1 where id=1") + require.Equal(t, uint64(1), tk.Session().GetSessionVars().StmtCtx.AffectedRows()) + tk.MustQuery("select id from t1 order by id").Check(testkit.Rows()) + + // Test cascade delete depth. + tk.MustExec("drop table t1") + tk.MustExec("create table t1(id int primary key, pid int, index(pid), foreign key(pid) references t1(id) on delete cascade);") + tk.MustExec("insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);") + tk.MustGetDBError("delete from t1 where id=0;", executor.ErrForeignKeyCascadeDepthExceeded) + tk.MustExec("delete from t1 where id=15;") + tk.MustExec("delete from t1 where id=0;") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustExec("insert into t1 values(0,0)") + tk.MustExec("delete from t1 where id=0;") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + + // Test for cascade delete failed. + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id int key)") + tk.MustExec("create table t2 (id int key, foreign key (id) references t1 (id) on delete cascade)") + tk.MustExec("create table t3 (id int key, foreign key (id) references t2(id))") + tk.MustExec("insert into t1 values (1)") + tk.MustExec("insert into t2 values (1)") + tk.MustExec("insert into t3 values (1)") + // test in autocommit transaction + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1").Check(testkit.Rows("1")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1")) + // Test in transaction and commit transaction. + tk.MustExec("begin") + tk.MustExec("insert into t1 values (2),(3),(4)") + tk.MustExec("insert into t2 values (2),(3)") + tk.MustExec("insert into t3 values (3)") + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("delete from t1 where id = 2") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3")) + tk.MustExec("commit") + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3")) + // Test in transaction and rollback transaction. + tk.MustExec("begin") + tk.MustExec("insert into t1 values (5), (6)") + tk.MustExec("insert into t2 values (4), (5), (6)") + tk.MustExec("insert into t3 values (5)") + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("delete from t1 where id = 4") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "5", "6")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "3", "5", "6")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3", "5")) + tk.MustExec("rollback") + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3")) + tk.MustExec("delete from t3 where id = 1") + tk.MustExec("delete from t1 where id = 1") + tk.MustQuery("select * from t1").Check(testkit.Rows("3", "4")) + tk.MustQuery("select * from t2").Check(testkit.Rows("3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("3")) + // Test in autocommit=0 transaction + tk.MustExec("set autocommit=0") + tk.MustExec("insert into t1 values (1), (2)") + tk.MustExec("insert into t2 values (1), (2)") + tk.MustExec("insert into t3 values (1)") + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("delete from t1 where id = 2") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3")) + tk.MustExec("set autocommit=1") + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3")) + + // Test StmtCommit after fk cascade executor execute finish. + tk.MustExec("drop table if exists t1,t2,t3") + tk.MustExec("create table t0(id int primary key);") + tk.MustExec("create table t1(id int primary key, pid int, index(pid), a int, foreign key(pid) references t1(id) on delete cascade, foreign key(a) references t0(id) on delete cascade);") + tk.MustExec("insert into t0 values (0)") + tk.MustExec("insert into t1 values (0, 0, 0)") + tk.MustExec("insert into t1 (id, pid) values(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13);") + tk.MustGetDBError("delete from t0 where id=0;", executor.ErrForeignKeyCascadeDepthExceeded) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("delete from t1 where id=14;") + tk.MustExec("delete from t0 where id=0;") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t0").Check(testkit.Rows()) + tk.MustQuery("select * from t1").Check(testkit.Rows()) + + // Test multi-foreign key cascade in one table. + tk.MustExec("drop table if exists t1,t2,t3") + tk.MustExec("create table t1 (id int key)") + tk.MustExec("create table t2 (id int key)") + tk.MustExec("create table t3 (id1 int, id2 int, constraint fk_id1 foreign key (id1) references t1 (id) on delete cascade, " + + "constraint fk_id2 foreign key (id2) references t2 (id) on delete cascade)") + tk.MustExec("insert into t1 values (1), (2), (3)") + tk.MustExec("insert into t2 values (1), (2), (3)") + tk.MustExec("insert into t3 values (1,1), (1, 2), (1, 3), (2, 1), (2, 2)") + tk.MustExec("delete from t1 where id=1") + tk.MustQuery("select * from t1").Check(testkit.Rows("2", "3")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "2", "3")) + tk.MustQuery("select * from t3 order by id1").Check(testkit.Rows("2 1", "2 2")) + tk.MustExec("create table t4 (id3 int key, constraint fk_id3 foreign key (id3) references t3 (id2))") + tk.MustExec("insert into t4 values (2)") + tk.MustGetDBError("delete from t1 where id = 2", plannercore.ErrRowIsReferenced2) + tk.MustGetDBError("delete from t2 where id = 2", plannercore.ErrRowIsReferenced2) + tk.MustExec("delete from t2 where id=1") + tk.MustQuery("select * from t1").Check(testkit.Rows("2", "3")) + tk.MustQuery("select * from t2").Check(testkit.Rows("2", "3")) + tk.MustQuery("select * from t3 order by id1").Check(testkit.Rows("2 2")) + + // Test multi-foreign key cascade in one table. + tk.MustExec("drop table if exists t1,t2,t3, t4") + tk.MustExec(`create table t1 (c0 int, index(c0))`) + cnt := 20 + for i := 1; i < cnt; i++ { + tk.MustExec(fmt.Sprintf("alter table t1 add column c%v int", i)) + tk.MustExec(fmt.Sprintf("alter table t1 add index idx_%v (c%v) ", i, i)) + tk.MustExec(fmt.Sprintf("alter table t1 add foreign key (c%v) references t1 (c%v) on delete cascade", i, i-1)) + } + for i := 0; i < cnt; i++ { + vals := strings.Repeat(strconv.Itoa(i)+",", 20) + tk.MustExec(fmt.Sprintf("insert into t1 values (%v)", vals[:len(vals)-1])) + } + tk.MustExec("delete from t1 where c0 in (0, 1, 2, 3, 4)") + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("15")) + + // Test foreign key cascade execution meet lock and do retry. + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("set @@global.tidb_enable_foreign_key=1") + tk2.MustExec("set @@foreign_key_checks=1") + tk2.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (id int key, name varchar(10), pid int, index(pid), constraint fk foreign key (pid) references t1 (id) on delete cascade)") + tk.MustExec("insert into t1 values (1, 'boss', null), (2, 'a', 1), (3, 'b', 1), (4, 'c', '2')") + tk.MustExec("begin pessimistic") + tk.MustExec("insert into t1 values (5, 'd', 3)") + tk2.MustExec("begin pessimistic") + tk2.MustExec("insert into t1 values (6, 'e', 4)") + tk2.MustExec("delete from t1 where id=2") + tk2.MustExec("commit") + tk.MustExec("delete from t1 where id = 1") + tk.MustExec("commit") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + + // Test handle many foreign key value in one cascade. + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1 (id int auto_increment key, b int);") + tk.MustExec("create table t2 (id int, b int, foreign key fk(id) references t1(id) on delete cascade)") + tk.MustExec("insert into t1 (b) values (1),(1),(1),(1),(1),(1),(1),(1);") + for i := 0; i < 12; i++ { + tk.MustExec("insert into t1 (b) select b from t1") + } + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("32768")) + tk.MustExec("insert into t2 select * from t1") + tk.MustExec("delete from t1") + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0")) + tk.MustQuery("select count(*) from t2").Check(testkit.Rows("0")) +} + +func TestForeignKeyGenerateCascadeAST(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test;") + fkValues := [][]types.Datum{ + {types.NewDatum(1), types.NewDatum("a")}, + {types.NewDatum(2), types.NewDatum("b")}, + } + cols := []*model.ColumnInfo{ + {ID: 1, Name: model.NewCIStr("a"), FieldType: *types.NewFieldType(mysql.TypeLonglong)}, + {ID: 2, Name: model.NewCIStr("name"), FieldType: *types.NewFieldType(mysql.TypeVarchar)}, + } + restoreFn := func(stmt ast.StmtNode) string { + var sb strings.Builder + fctx := format.NewRestoreCtx(format.DefaultRestoreFlags, &sb) + err := stmt.Restore(fctx) + require.NoError(t, err) + return sb.String() + } + checkStmtFn := func(stmt ast.StmtNode, sql string) { + exec, ok := tk.Session().(sqlexec.RestrictedSQLExecutor) + require.True(t, ok) + expectedStmt, err := exec.ParseWithParams(context.Background(), sql) + require.NoError(t, err) + require.Equal(t, restoreFn(expectedStmt), restoreFn(stmt)) + } + var stmt ast.StmtNode + stmt = executor.GenCascadeDeleteAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr(""), cols, fkValues) + checkStmtFn(stmt, "delete from test.t2 where (a,name) in ((1,'a'), (2,'b'))") + stmt = executor.GenCascadeDeleteAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr("idx"), cols, fkValues) + checkStmtFn(stmt, "delete from test.t2 use index(idx) where (a,name) in ((1,'a'), (2,'b'))") + stmt = executor.GenCascadeSetNullAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr(""), cols, fkValues) + checkStmtFn(stmt, "update test.t2 set a = null, name = null where (a,name) in ((1,'a'), (2,'b'))") + stmt = executor.GenCascadeSetNullAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr("idx"), cols, fkValues) + checkStmtFn(stmt, "update test.t2 use index(idx) set a = null, name = null where (a,name) in ((1,'a'), (2,'b'))") + newValue1 := []types.Datum{types.NewDatum(10), types.NewDatum("aa")} + couple := &executor.UpdatedValuesCouple{ + NewValues: newValue1, + OldValuesList: fkValues, + } + stmt = executor.GenCascadeUpdateAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr(""), cols, couple) + checkStmtFn(stmt, "update test.t2 set a = 10, name = 'aa' where (a,name) in ((1,'a'), (2,'b'))") + stmt = executor.GenCascadeUpdateAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr("idx"), cols, couple) + checkStmtFn(stmt, "update test.t2 use index(idx) set a = 10, name = 'aa' where (a,name) in ((1,'a'), (2,'b'))") + // Test for 1 fk column. + fkValues = [][]types.Datum{{types.NewDatum(1)}, {types.NewDatum(2)}} + cols = []*model.ColumnInfo{{ID: 1, Name: model.NewCIStr("a"), FieldType: *types.NewFieldType(mysql.TypeLonglong)}} + stmt = executor.GenCascadeDeleteAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr(""), cols, fkValues) + checkStmtFn(stmt, "delete from test.t2 where a in (1,2)") + stmt = executor.GenCascadeDeleteAST(model.NewCIStr("test"), model.NewCIStr("t2"), model.NewCIStr("idx"), cols, fkValues) + checkStmtFn(stmt, "delete from test.t2 use index(idx) where a in (1,2)") +} + +func TestForeignKeyOnDeleteSetNull(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + cases := []struct { + prepareSQLs []string + }{ + // Case-1: test unique index only contain foreign key columns. + { + prepareSQLs: []string{ + "create table t1 (id int, a int, b int, unique index(a, b));", + "create table t2 (b int, name varchar(10), a int, id int, unique index (a,b), foreign key fk(a, b) references t1(a, b) ON DELETE SET NULL);", + }, + }, + // Case-2: test unique index contain foreign key columns and other columns. + { + prepareSQLs: []string{ + "create table t1 (id int key, a int, b int, unique index(a, b, id));", + "create table t2 (b int, a int, id int key, name varchar(10), unique index (a,b, id), foreign key fk(a, b) references t1(a, b) ON DELETE SET NULL);", + }, + }, + // Case-3: test non-unique index only contain foreign key columns. + { + prepareSQLs: []string{ + "create table t1 (id int key,a int, b int, index(a, b));", + "create table t2 (b int, a int, name varchar(10), id int key, index (a, b), foreign key fk(a, b) references t1(a, b) ON DELETE SET NULL);", + }, + }, + // Case-4: test non-unique index contain foreign key columns and other columns. + { + prepareSQLs: []string{ + "create table t1 (id int key,a int, b int, index(a, b, id));", + "create table t2 (name varchar(10), b int, a int, id int key, index (a, b, id), foreign key fk(a, b) references t1(a, b) ON DELETE SET NULL);", + }, + }, + } + + for idx, ca := range cases { + tk.MustExec("drop table if exists t2;") + tk.MustExec("drop table if exists t1;") + for _, sql := range ca.prepareSQLs { + tk.MustExec(sql) + } + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, null), (6, null, 6), (7, null, null);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd'), (5, 5, null, 'e'), (6, null, 6, 'f'), (7, null, null, 'g');") + tk.MustExec("delete from t1 where id = 1 or a = 2") + tk.MustExec("delete from t1 where a in (2,3,4) or b in (5,6,7)") + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 a", "2 b", "3 c", "4 d", "5 5 e", "6 6 f", "7 g")) + + // Test in transaction. + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, null), (6, null, 6), (7, null, null);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd'), (5, 5, null, 'e'), (6, null, 6, 'f'), (7, null, null, 'g');") + tk.MustExec("delete from t1 where id = 1 or a = 2") + tk.MustExec("delete from t1 where a in (2,3,4) or b in (5,6,7)") + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 a", "2 b", "3 c", "4 d", "5 5 e", "6 6 f", "7 g")) + tk.MustExec("rollback") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2);") + tk.MustExec("begin") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b')") + tk.MustExec("delete from t1 where id = 1") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 a", "2 2 2 b")) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (11, 1, 1, 'c')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (1, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (11, 1, 1, 'c')") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 1 1", "2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 a", "2 2 2 b", "11 1 1 c")) + tk.MustExec("delete from t1") + tk.MustExec("commit") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 a", "2 b", "11 c")) + + // only test in non-unique index + if idx >= 2 { + tk.MustExec("delete from t2") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 1, 1);") + tk.MustExec("begin") + tk.MustExec("delete from t1 where id = 1") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a')") + tk.MustExec("delete from t1 where id = 2") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select id, a, b, name from t2").Check(testkit.Rows("1 a")) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (2, 1, 1, 'b')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (3, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (3, 1, 1, 'e')") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("3 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 a", "3 1 1 e")) + + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'), (2, 1, 1, 'b')") + tk.MustExec("delete from t1 where id = 1") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("2 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 a", "2 b")) + } + } +} + +func TestForeignKeyOnDeleteSetNull2(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + // Test cascade delete in self table. + tk.MustExec("create table t1 (id int key, name varchar(10), leader int, index(leader), foreign key (leader) references t1(id) ON DELETE SET NULL);") + tk.MustExec("insert into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("insert into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10)") + tk.MustExec("insert into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11)") + tk.MustExec("insert into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12)") + tk.MustExec("insert into t1 values (1000,'l3_a1', 100)") + tk.MustExec("delete from t1 where id=11") + tk.MustQuery("select id, name, leader from t1 order by id").Check(testkit.Rows("1 boss ", "10 l1_a 1", "12 l1_c 1", "100 l2_a1 10", "101 l2_a2 10", "102 l2_a3 10", "110 l2_b1 ", "111 l2_b2 ", "112 l2_b3 ", "120 l2_c1 12", "121 l2_c2 12", "122 l2_c3 12", "1000 l3_a1 100")) + tk.MustExec("delete from t1 where id=1") + // The affect rows doesn't contain the cascade deleted rows, the behavior is compatible with MySQL. + require.Equal(t, uint64(1), tk.Session().GetSessionVars().StmtCtx.AffectedRows()) + tk.MustQuery("select id, name, leader from t1 order by id").Check(testkit.Rows("10 l1_a ", "12 l1_c ", "100 l2_a1 10", "101 l2_a2 10", "102 l2_a3 10", "110 l2_b1 ", "111 l2_b2 ", "112 l2_b3 ", "120 l2_c1 12", "121 l2_c2 12", "122 l2_c3 12", "1000 l3_a1 100")) + + // Test explain analyze with foreign key cascade. + tk.MustExec("delete from t1") + tk.MustExec("insert into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("explain analyze delete from t1 where id=1") + tk.MustQuery("select id, name, leader from t1 order by id").Check(testkit.Rows("10 l1_a ", "11 l1_b ", "12 l1_c ")) + + // Test string type foreign key. + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id varchar(10) key, name varchar(10), leader varchar(10), index(leader), foreign key (leader) references t1(id) ON DELETE SET NULL);") + tk.MustExec("insert into t1 values (1, 'boss', null)") + tk.MustExec("insert into t1 values (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("insert into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10)") + tk.MustExec("insert into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11)") + tk.MustExec("insert into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12)") + tk.MustExec("insert into t1 values (1000,'l3_a1', 100)") + tk.MustExec("delete from t1 where id=11") + tk.MustQuery("select id, name, leader from t1 order by name").Check(testkit.Rows("1 boss ", "10 l1_a 1", "12 l1_c 1", "100 l2_a1 10", "101 l2_a2 10", "102 l2_a3 10", "110 l2_b1 ", "111 l2_b2 ", "112 l2_b3 ", "120 l2_c1 12", "121 l2_c2 12", "122 l2_c3 12", "1000 l3_a1 100")) + tk.MustExec("delete from t1 where id=1") + require.Equal(t, uint64(1), tk.Session().GetSessionVars().StmtCtx.AffectedRows()) + tk.MustQuery("select id, name, leader from t1 order by name").Check(testkit.Rows("10 l1_a ", "12 l1_c ", "100 l2_a1 10", "101 l2_a2 10", "102 l2_a3 10", "110 l2_b1 ", "111 l2_b2 ", "112 l2_b3 ", "120 l2_c1 12", "121 l2_c2 12", "122 l2_c3 12", "1000 l3_a1 100")) + + // Test cascade set null depth. + tk.MustExec("drop table t1") + tk.MustExec("create table t1(id int primary key, pid int, index(pid), foreign key(pid) references t1(id) on delete set null);") + tk.MustExec("insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);") + tk.MustExec("delete from t1 where id=0;") + tk.MustQuery("select id, pid from t1").Check(testkit.Rows("1 ", "2 1", "3 2", "4 3", "5 4", "6 5", "7 6", "8 7", "9 8", "10 9", "11 10", "12 11", "13 12", "14 13", "15 14")) + + // Test for cascade delete failed. + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id int key)") + tk.MustExec("create table t2 (id int, foreign key (id) references t1 (id) on delete set null)") + tk.MustExec("create table t3 (id int, foreign key (id) references t2(id))") + tk.MustExec("insert into t1 values (1)") + tk.MustExec("insert into t2 values (1)") + tk.MustExec("insert into t3 values (1)") + // test in autocommit transaction + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1").Check(testkit.Rows("1")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1")) + // Test in transaction and commit transaction. + tk.MustExec("begin") + tk.MustExec("insert into t1 values (2),(3),(4)") + tk.MustExec("insert into t2 values (2),(3)") + tk.MustExec("insert into t3 values (3)") + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("delete from t1 where id = 2") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("", "1", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3")) + tk.MustExec("commit") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("", "1", "3")) + tk.MustQuery("select * from t3 order by id").Check(testkit.Rows("1", "3")) + // Test in transaction and rollback transaction. + tk.MustExec("begin") + tk.MustExec("insert into t1 values (5), (6)") + tk.MustExec("insert into t2 values (4), (5), (6)") + tk.MustExec("insert into t3 values (5)") + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("delete from t1 where id = 4") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1", "3", "5", "6")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("", "", "1", "3", "5", "6")) + tk.MustQuery("select * from t3 order by id").Check(testkit.Rows("1", "3", "5")) + tk.MustExec("rollback") + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("", "1", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1", "3")) + tk.MustExec("delete from t3 where id = 1") + tk.MustExec("delete from t1 where id = 1") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("3", "4")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("", "", "3")) + tk.MustQuery("select * from t3").Check(testkit.Rows("3")) + + // Test in autocommit=0 transaction + tk.MustExec("set autocommit=0") + tk.MustExec("insert into t1 values (1), (2)") + tk.MustExec("insert into t2 values (1), (2)") + tk.MustExec("insert into t3 values (1)") + tk.MustGetDBError("delete from t1 where id = 1", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("delete from t1 where id = 2") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("", "", "", "1", "3")) + tk.MustQuery("select * from t3 order by id").Check(testkit.Rows("1", "3")) + tk.MustExec("set autocommit=1") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1", "3", "4")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("", "", "", "1", "3")) + tk.MustQuery("select * from t3 order by id").Check(testkit.Rows("1", "3")) + + // Test StmtCommit after fk cascade executor execute finish. + tk.MustExec("drop table if exists t1,t2,t3") + tk.MustExec("create table t0(id int primary key);") + tk.MustExec("create table t1(id int primary key, pid int, index(pid), a int, foreign key(pid) references t1(id) on delete set null, foreign key(a) references t0(id) on delete set null);") + tk.MustExec("insert into t0 values (0), (1)") + tk.MustExec("insert into t1 values (0, 0, 0)") + tk.MustExec("insert into t1 (id, pid) values(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13);") + tk.MustExec("update t1 set a=1 where a is null") + tk.MustExec("delete from t0 where id=0;") + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustQuery("select * from t0").Check(testkit.Rows("1")) + tk.MustQuery("select id, pid, a from t1 order by id").Check(testkit.Rows("0 0 ", "1 0 1", "2 1 1", "3 2 1", "4 3 1", "5 4 1", "6 5 1", "7 6 1", "8 7 1", "9 8 1", "10 9 1", "11 10 1", "12 11 1", "13 12 1", "14 13 1")) + + // Test multi-foreign key set null in one table. + tk.MustExec("drop table if exists t1,t2,t3") + tk.MustExec("create table t1 (id int key)") + tk.MustExec("create table t2 (id int key)") + tk.MustExec("create table t3 (id1 int, id2 int, constraint fk_id1 foreign key (id1) references t1 (id) on delete set null, " + + "constraint fk_id2 foreign key (id2) references t2 (id) on delete set null)") + tk.MustExec("insert into t1 values (1), (2), (3)") + tk.MustExec("insert into t2 values (1), (2), (3)") + tk.MustExec("insert into t3 values (1,1), (1, 2), (1, 3), (2, 1), (2, 2)") + tk.MustExec("delete from t1 where id=1") + tk.MustQuery("select * from t1").Check(testkit.Rows("2", "3")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1", "2", "3")) + tk.MustQuery("select * from t3 order by id1").Check(testkit.Rows(" 1", " 2", " 3", "2 1", "2 2")) + tk.MustExec("create table t4 (id3 int key, constraint fk_id3 foreign key (id3) references t3 (id2))") + tk.MustExec("insert into t4 values (2)") + tk.MustExec("delete from t1 where id=2") + tk.MustGetDBError("delete from t2 where id = 2", plannercore.ErrRowIsReferenced2) + tk.MustQuery("select * from t1").Check(testkit.Rows("3")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1", "2", "3")) + tk.MustQuery("select * from t3 order by id1, id2").Check(testkit.Rows(" 1", " 1", " 2", " 2", " 3")) + + // Test foreign key set null execution meet lock and do retry. + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("set @@global.tidb_enable_foreign_key=1") + tk2.MustExec("set @@foreign_key_checks=1") + tk2.MustExec("use test") + tk.MustExec("drop table if exists t1, t2, t3, t4") + tk.MustExec("create table t1 (id int key, name varchar(10), pid int, index(pid), constraint fk foreign key (pid) references t1 (id) on delete set null)") + tk.MustExec("insert into t1 values (1, 'boss', null), (2, 'a', 1), (3, 'b', 1), (4, 'c', '2')") + tk.MustExec("begin pessimistic") + tk.MustExec("insert into t1 values (5, 'd', 3)") + tk2.MustExec("begin pessimistic") + tk2.MustExec("insert into t1 values (6, 'e', 4)") + tk2.MustExec("delete from t1 where id=2") + tk2.MustExec("commit") + tk.MustExec("delete from t1 where id = 1") + tk.MustExec("commit") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("3 b ", "4 c ", "5 d 3", "6 e 4")) + + // Test foreign key cascade delete and set null in one row. + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (id int key, name varchar(10), pid int, ppid int, index(pid), index(ppid) , constraint fk_pid foreign key (pid) references t1 (id) on delete cascade, " + + "constraint fk_ppid foreign key (ppid) references t1 (id) on delete set null)") + tk.MustExec("insert into t1 values (1, 'boss', null, null), (2, 'a', 1, 1), (3, 'b', 1, 1), (4, 'c', '2', 1)") + tk.MustExec("delete from t1 where id = 1") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows()) + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (id int key, name varchar(10), pid int, oid int, poid int, index(pid), index (oid), index(poid) , constraint fk_pid foreign key (pid) references t1 (id) on delete cascade, " + + "constraint fk_poid foreign key (poid) references t1 (oid) on delete set null)") + tk.MustExec("insert into t1 values (1, 'boss', null, 0, 0), (2, 'a', 1, 1, 0), (3, 'b', null, 2, 1), (4, 'c', 2, 3, 2)") + tk.MustExec("delete from t1 where id = 1") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("3 b 2 ")) + + // Test handle many foreign key value in one cascade. + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1 (id int auto_increment key, b int);") + tk.MustExec("create table t2 (id int, b int, foreign key fk(id) references t1(id) on delete set null)") + tk.MustExec("insert into t1 (b) values (1),(1),(1),(1),(1),(1),(1),(1);") + for i := 0; i < 12; i++ { + tk.MustExec("insert into t1 (b) select b from t1") + } + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("32768")) + tk.MustExec("insert into t2 select * from t1") + tk.MustExec("delete from t1") + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0")) + tk.MustQuery("select count(*) from t2 where id is null").Check(testkit.Rows("32768")) +} + +func TestForeignKeyOnUpdateCascade(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + cases := []struct { + prepareSQLs []string + }{ + // Case-1: test unique index only contain foreign key columns. + { + prepareSQLs: []string{ + "create table t1 (id int, a int, b int, unique index(a, b));", + "create table t2 (b int, name varchar(10), a int, id int, unique index (a,b), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + // Case-2: test unique index contain foreign key columns and other columns. + { + prepareSQLs: []string{ + "create table t1 (id int key, a int, b int, unique index(a, b, id));", + "create table t2 (b int, name varchar(10), a int, id int key, unique index (a,b, id), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + // Case-3: test non-unique index only contain foreign key columns. + { + prepareSQLs: []string{ + "create table t1 (id int key,a int, b int, index(a, b));", + "create table t2 (b int, a int, name varchar(10), id int key, index (a, b), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + // Case-4: test non-unique index contain foreign key columns and other columns. + { + prepareSQLs: []string{ + "create table t1 (id int key,a int, b int, index(a, b, id));", + "create table t2 (name varchar(10), b int, id int key, a int, index (a, b, id), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + } + + for idx, ca := range cases { + tk.MustExec("drop table if exists t2;") + tk.MustExec("drop table if exists t1;") + for _, sql := range ca.prepareSQLs { + tk.MustExec(sql) + } + tk.MustExec("insert into t1 (id, a, b) values (1, 11, 21),(2, 12, 22), (3, 13, 23), (4, 14, 24), (5, 15, null), (6, null, 26), (7, null, null);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 11, 21, 'a'),(2, 12, 22, 'b'), (3, 13, 23, 'c'), (4, 14, 24, 'd'), (5, 15, null, 'e'), (6, null, 26, 'f'), (7, null, null, 'g');") + tk.MustExec("update t1 set a=a+100, b = b+200 where id in (1, 2)") + tk.MustQuery("select id, a, b from t1 where id in (1,2) order by id").Check(testkit.Rows("1 111 221", "2 112 222")) + tk.MustQuery("select id, a, b, name from t2 where id in (1,2,3) order by id").Check(testkit.Rows("1 111 221 a", "2 112 222 b", "3 13 23 c")) + // Test update fk column to null + tk.MustExec("update t1 set a=101, b=null where id = 1 or b = 222") + tk.MustQuery("select id, a, b from t1 where id in (1,2) order by id").Check(testkit.Rows("1 101 ", "2 101 ")) + tk.MustQuery("select id, a, b, name from t2 where id in (1,2,3) order by id").Check(testkit.Rows("1 101 a", "2 101 b", "3 13 23 c")) + tk.MustExec("update t1 set a=null where b is null") + tk.MustQuery("select id, a, b from t1 where b is null order by id").Check(testkit.Rows("1 ", "2 ", "5 ", "7 ")) + tk.MustQuery("select id, a, b, name from t2 where b is null order by id").Check(testkit.Rows("1 101 a", "2 101 b", "5 15 e", "7 g")) + // Test update fk column from null to not-null value + tk.MustExec("update t1 set a=0, b = 0 where id = 7") + tk.MustQuery("select id, a, b from t1 where a=0 and b=0 order by id").Check(testkit.Rows("7 0 0")) + tk.MustQuery("select id, a, b from t2 where a=0 and b=0 order by id").Check(testkit.Rows()) + + // Test in transaction. + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, null), (6, null, 6), (7, null, null);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd'), (5, 5, null, 'e'), (6, null, 6, 'f'), (7, null, null, 'g');") + tk.MustExec("update t1 set a=a+100, b = b+200 where id in (1, 2)") + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 101 201 a", "2 102 202 b", "3 3 3 c", "4 4 4 d", "5 5 e", "6 6 f", "7 g")) + tk.MustExec("rollback") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2);") + tk.MustExec("begin") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b')") + tk.MustExec("update t1 set a=101 where a = 1") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 101 1", "2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 101 1 a", "2 2 2 b")) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (3, 1, 1, 'c')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (3, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (3, 1, 1, 'c')") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 101 1", "2 2 2", "3 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id, a").Check(testkit.Rows("1 101 1 a", "2 2 2 b", "3 1 1 c")) + tk.MustExec("update t1 set a=null, b=2000 where id in (1, 2)") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 2000", "2 2000", "3 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 2000 a", "2 2000 b", "3 1 1 c")) + + // only test in non-unique index + if idx >= 2 { + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 1, 1);") + tk.MustExec("begin") + tk.MustExec("update t1 set a=101 where id = 1") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a')") + tk.MustExec("update t1 set b=102 where id = 2") + tk.MustQuery("select * from t1").Check(testkit.Rows("1 101 1", "2 1 102")) + tk.MustQuery("select id, a, b, name from t2").Check(testkit.Rows("1 1 102 a")) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (3, 1, 1, 'e')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (3, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (3, 1, 1, 'e')") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 101 1", "2 1 102", "3 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 1 102 a", "3 1 1 e")) + + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'), (2, 1, 1, 'b')") + tk.MustExec("update t1 set a=101, b=102 where id = 1") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 101 102", "2 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 101 102 a", "2 101 102 b")) + } + } + + cases = []struct { + prepareSQLs []string + }{ + // Case-5: test primary key only contain foreign key columns, and disable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=0;", + "create table t1 (id int, a int, b int, primary key (a, b));", + "create table t2 (b int, a int, name varchar(10), id int, primary key (a, b), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + // Case-6: test primary key only contain foreign key columns, and enable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=1;", + "create table t1 (id int, a int, b int, primary key (a, b));", + "create table t2 (name varchar(10), b int, a int, id int, primary key (a, b), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + // Case-7: test primary key contain foreign key columns and other column, and disable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=0;", + "create table t1 (id int, a int, b int, primary key (a, b, id));", + "create table t2 (b int, name varchar(10), a int, id int, primary key (a, b, id), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + // Case-8: test primary key contain foreign key columns and other column, and enable tidb_enable_clustered_index. + { + prepareSQLs: []string{ + "set @@tidb_enable_clustered_index=1;", + "create table t1 (id int, a int, b int, primary key (a, b, id));", + "create table t2 (b int, a int, id int, name varchar(10), primary key (a, b, id), foreign key fk(a, b) references t1(a, b) ON UPDATE CASCADE);", + }, + }, + } + for idx, ca := range cases { + tk.MustExec("drop table if exists t2;") + tk.MustExec("drop table if exists t1;") + for _, sql := range ca.prepareSQLs { + tk.MustExec(sql) + } + tk.MustExec("insert into t1 (id, a, b) values (1, 11, 21),(2, 12, 22), (3, 13, 23), (4, 14, 24)") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 11, 21, 'a'),(2, 12, 22, 'b'), (3, 13, 23, 'c'), (4, 14, 24, 'd')") + tk.MustExec("update t1 set a=a+100, b = b+200 where id in (1, 2)") + tk.MustQuery("select id, a, b from t1 where id in (1,2) order by id").Check(testkit.Rows("1 111 221", "2 112 222")) + tk.MustQuery("select id, a, b, name from t2 where id in (1,2,3) order by id").Check(testkit.Rows("1 111 221 a", "2 112 222 b", "3 13 23 c")) + tk.MustExec("update t1 set a=101 where id = 1 or b = 222") + tk.MustQuery("select id, a, b from t1 where id in (1,2) order by id").Check(testkit.Rows("1 101 221", "2 101 222")) + tk.MustQuery("select id, a, b, name from t2 where id in (1,2,3) order by id").Check(testkit.Rows("1 101 221 a", "2 101 222 b", "3 13 23 c")) + + if idx < 2 { + tk.MustGetDBError("update t1 set b=200 where id in (1,2);", kv.ErrKeyExists) + } + + // test in transaction. + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2), (3, 3, 3), (4, 4, 4);") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b'), (3, 3, 3, 'c'), (4, 4, 4, 'd');") + tk.MustExec("update t1 set a=a+100, b=b+200 where id = 1 or a = 2") + tk.MustExec("update t1 set a=a+1000, b=b+2000 where a in (2,3,4) or b in (5,6,7) or id=2") + tk.MustQuery("select id, a, b from t2 order by id").Check(testkit.Rows("1 101 201", "2 1102 2202", "3 1003 2003", "4 1004 2004")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 101 201 a", "2 1102 2202 b", "3 1003 2003 c", "4 1004 2004 d")) + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t2 order by id").Check(testkit.Rows("1 101 201", "2 1102 2202", "3 1003 2003", "4 1004 2004")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 101 201 a", "2 1102 2202 b", "3 1003 2003 c", "4 1004 2004 d")) + + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("insert into t1 values (1, 1, 1),(2, 2, 2);") + tk.MustExec("begin") + tk.MustExec("insert into t2 (id, a, b, name) values (1, 1, 1, 'a'),(2, 2, 2, 'b')") + tk.MustExec("update t1 set a=a+100, b=b+200 where id = 1") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 101 201", "2 2 2")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 101 201 a", "2 2 2 b")) + err := tk.ExecToErr("insert into t2 (id, a, b, name) values (3, 1, 1, 'e')") + require.Error(t, err) + require.True(t, plannercore.ErrNoReferencedRow2.Equal(err), err.Error()) + tk.MustExec("insert into t1 values (3, 1, 1);") + tk.MustExec("insert into t2 (id, a, b, name) values (3, 1, 1, 'c')") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 101 201", "2 2 2", "3 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 101 201 a", "2 2 2 b", "3 1 1 c")) + tk.MustExec("update t1 set a=a+1000, b=b+2000 where a>1") + tk.MustExec("commit") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 1101 2201", "2 1002 2002", "3 1 1")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("1 1101 2201 a", "2 1002 2002 b", "3 1 1 c")) + } + + // Case-9: test primary key is handle and contain foreign key column. + tk.MustExec("drop table if exists t2;") + tk.MustExec("drop table if exists t1;") + tk.MustExec("set @@tidb_enable_clustered_index=0;") + tk.MustExec("create table t1 (id int, a int, b int, primary key (id));") + tk.MustExec("create table t2 (b int, a int, id int, name varchar(10), primary key (a), foreign key fk(a) references t1(id) ON UPDATE CASCADE);") + tk.MustExec("insert into t1 (id, a, b) values (1, 11, 21),(2, 12, 22), (3, 13, 23), (4, 14, 24)") + tk.MustExec("insert into t2 (id, a, b, name) values (11, 1, 21, 'a'),(12, 2, 22, 'b'), (13, 3, 23, 'c'), (14, 4, 24, 'd')") + tk.MustExec("update t1 set id = id + 100 where id in (1, 2, 3)") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("4 14 24", "101 11 21", "102 12 22", "103 13 23")) + tk.MustQuery("select id, a, b, name from t2 order by id").Check(testkit.Rows("11 101 21 a", "12 102 22 b", "13 103 23 c", "14 4 24 d")) +} + +func TestForeignKeyOnUpdateCascade2(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + // Test update same old row in parent, but only the first old row do cascade update + tk.MustExec("create table t1 (id int key, a int, index (a));") + tk.MustExec("create table t2 (id int key, pid int, constraint fk_pid foreign key (pid) references t1(a) ON UPDATE CASCADE);") + tk.MustExec("insert into t1 (id, a) values (1,1), (2, 1)") + tk.MustExec("insert into t2 (id, pid) values (1,1), (2, 1)") + tk.MustExec("update t1 set a=id+1") + tk.MustQuery("select id, a from t1 order by id").Check(testkit.Rows("1 2", "2 3")) + tk.MustQuery("select id, pid from t2 order by id").Check(testkit.Rows("1 2", "2 2")) + + // Test cascade delete in self table. + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1 (id int key, name varchar(10), leader int, index(leader), foreign key (leader) references t1(id) ON UPDATE CASCADE);") + tk.MustExec("insert into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("insert into t1 values (100, 'l2_a1', 10)") + tk.MustExec("insert into t1 values (110, 'l2_b1', 11)") + tk.MustExec("insert into t1 values (1000,'l3_a1', 100)") + tk.MustExec("update t1 set id=id+10000 where id=11") + tk.MustQuery("select id, name, leader from t1 order by id").Check(testkit.Rows("1 boss ", "10 l1_a 1", "12 l1_c 1", "100 l2_a1 10", "110 l2_b1 10011", "1000 l3_a1 100", "10011 l1_b 1")) + tk.MustExec("update t1 set id=0 where id=1") + tk.MustQuery("select id, name, leader from t1 order by id").Check(testkit.Rows("0 boss ", "10 l1_a 0", "12 l1_c 0", "100 l2_a1 10", "110 l2_b1 10011", "1000 l3_a1 100", "10011 l1_b 0")) + + // Test explain analyze with foreign key cascade. + tk.MustExec("explain analyze update t1 set id=1 where id=10") + tk.MustQuery("select id, name, leader from t1 order by id").Check(testkit.Rows("0 boss ", "1 l1_a 0", "12 l1_c 0", "100 l2_a1 1", "110 l2_b1 10011", "1000 l3_a1 100", "10011 l1_b 0")) + + // Test cascade delete in self table with string type foreign key. + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1 (id varchar(100) key, name varchar(10), leader varchar(100), index(leader), foreign key (leader) references t1(id) ON UPDATE CASCADE);") + tk.MustExec("insert into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("insert into t1 values (100, 'l2_a1', 10)") + tk.MustExec("insert into t1 values (110, 'l2_b1', 11)") + tk.MustExec("insert into t1 values (1000,'l3_a1', 100)") + tk.MustExec("update t1 set id=id+10000 where id=11") + tk.MustQuery("select id, name, leader from t1 order by name").Check(testkit.Rows("1 boss ", "10 l1_a 1", "10011 l1_b 1", "12 l1_c 1", "100 l2_a1 10", "110 l2_b1 10011", "1000 l3_a1 100")) + tk.MustExec("update t1 set id=0 where id=1") + tk.MustQuery("select id, name, leader from t1 order by name").Check(testkit.Rows("0 boss ", "10 l1_a 0", "10011 l1_b 0", "12 l1_c 0", "100 l2_a1 10", "110 l2_b1 10011", "1000 l3_a1 100")) + + // Test cascade delete depth error. + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t0 (id int, unique index(id))") + tk.MustExec("insert into t0 values (1)") + for i := 1; i < 17; i++ { + tk.MustExec(fmt.Sprintf("create table t%v (id int, unique index(id), foreign key (id) references t%v(id) on update cascade)", i, i-1)) + tk.MustExec(fmt.Sprintf("insert into t%v values (1)", i)) + } + tk.MustGetDBError("update t0 set id=10 where id=1;", executor.ErrForeignKeyCascadeDepthExceeded) + tk.MustQuery("select id from t0").Check(testkit.Rows("1")) + tk.MustQuery("select id from t15").Check(testkit.Rows("1")) + tk.MustExec("drop table if exists t16") + tk.MustExec("update t0 set id=10 where id=1;") + tk.MustQuery("select id from t0").Check(testkit.Rows("10")) + tk.MustQuery("select id from t15").Check(testkit.Rows("10")) + for i := 16; i > -1; i-- { + tk.MustExec("drop table if exists t" + strconv.Itoa(i)) + } + + // Test handle many foreign key value in one cascade. + tk.MustExec("create table t1 (id int auto_increment key, b int, index(b));") + tk.MustExec("create table t2 (id int, b int, foreign key fk(b) references t1(b) on update cascade)") + tk.MustExec("insert into t1 (b) values (1),(2),(3),(4),(5),(6),(7),(8);") + for i := 0; i < 12; i++ { + tk.MustExec("insert into t1 (b) select id from t1") + } + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("32768")) + tk.MustExec("insert into t2 select * from t1") + tk.MustExec("update t1 set b=2") + tk.MustQuery("select count(*) from t1 join t2 where t1.id=t2.id and t1.b=t2.b").Check(testkit.Rows("32768")) +} + +func TestForeignKeyOnUpdateSetNull(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + // Test handle many foreign key value in one cascade. + tk.MustExec("create table t1 (id int auto_increment key, b int, index(b));") + tk.MustExec("create table t2 (id int, b int, foreign key fk(b) references t1(b) on update set null)") + tk.MustExec("insert into t1 (b) values (1),(2),(3),(4),(5),(6),(7),(8);") + for i := 0; i < 12; i++ { + tk.MustExec("insert into t1 (b) select id from t1") + } + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("32768")) + tk.MustExec("insert into t2 select * from t1") + tk.MustExec("update t1 set b=b+100000000") + tk.MustQuery("select count(*) from t2 where b is null").Check(testkit.Rows("32768")) +} + +func TestShowCreateTableWithForeignKey(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("set @@global.tidb_enable_foreign_key=0") + tk.MustExec("create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) ON DELETE CASCADE ON UPDATE SET NULL);") + tk.MustQuery("show create table t1").Check(testkit.Rows("t1 CREATE TABLE `t1` (\n" + + " `id` int(11) NOT NULL,\n" + + " `leader` int(11) DEFAULT NULL,\n" + + " `leader2` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `leader` (`leader`),\n KEY `leader2` (`leader2`),\n" + + " CONSTRAINT `fk` FOREIGN KEY (`leader`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE SET NULL /* FOREIGN KEY INVALID */\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("alter table t1 add constraint fk2 foreign key (leader2) references t1 (id)") + tk.MustQuery("show create table t1").Check(testkit.Rows("t1 CREATE TABLE `t1` (\n" + + " `id` int(11) NOT NULL,\n" + + " `leader` int(11) DEFAULT NULL,\n" + + " `leader2` int(11) DEFAULT NULL,\n" + + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `leader` (`leader`),\n KEY `leader2` (`leader2`),\n" + + " CONSTRAINT `fk` FOREIGN KEY (`leader`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE SET NULL /* FOREIGN KEY INVALID */,\n" + + " CONSTRAINT `fk2` FOREIGN KEY (`leader2`) REFERENCES `test`.`t1` (`id`)\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) /* FOREIGN KEY INVALID */);") +} + +func TestDMLExplainAnalyzeFKInfo(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + // Test for Insert ignore foreign check runtime stats. + tk.MustExec("drop table if exists t1,t2,t3") + tk.MustExec("create table t1 (id int key)") + tk.MustExec("create table t2 (id int key)") + tk.MustExec("create table t3 (id int key, id1 int, id2 int, constraint fk_id1 foreign key (id1) references t1 (id) on delete cascade, " + + "constraint fk_id2 foreign key (id2) references t2 (id) on delete cascade)") + tk.MustExec("insert into t1 values (1), (2)") + tk.MustExec("insert into t2 values (1)") + res := tk.MustQuery("explain analyze insert ignore into t3 values (1, 1, 1), (2, 1, 1), (3, 2, 1), (4, 1, 1), (5, 2, 1), (6, 2, 1)") + explain := getExplainResult(res) + require.Regexpf(t, "time:.* loops:.* prepare:.* check_insert: {total_time:.* mem_insert_time:.* prefetch:.* fk_check:.*", explain, "") + res = tk.MustQuery("explain analyze insert ignore into t3 values (7, null, null), (8, null, null)") + explain = getExplainResult(res) + require.Regexpf(t, "time:.* loops:.* prepare:.* check_insert: {total_time:.* mem_insert_time:.* prefetch:.* fk_check:.*", explain, "") +} + +func getExplainResult(res *testkit.Result) string { + resBuff := bytes.NewBufferString("") + for _, row := range res.Rows() { + _, _ = fmt.Fprintf(resBuff, "%s\t", row) + } + return resBuff.String() +} + +func TestForeignKeyCascadeOnDiffColumnType(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + + tk.MustExec("create table t1 (id bit(10), index(id));") + tk.MustExec("create table t2 (id int key, b bit(10), constraint fk foreign key (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE);") + tk.MustExec("insert into t1 values (b'01'), (b'10');") + tk.MustExec("insert into t2 values (1, b'01'), (2, b'10');") + tk.MustExec("delete from t1 where id = b'01';") + tk.MustExec("update t1 set id = b'110' where id = b'10';") + tk.MustQuery("select cast(id as unsigned) from t1;").Check(testkit.Rows("6")) + tk.MustQuery("select id, cast(b as unsigned) from t2;").Check(testkit.Rows("2 6")) +} + +func TestForeignKeyOnInsertOnDuplicateUpdate(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, name varchar(10));") + tk.MustExec("create table t2 (id int key, pid int, foreign key fk(pid) references t1(id) ON UPDATE CASCADE ON DELETE CASCADE);") + tk.MustExec("insert into t1 values (1, 'a'), (2, 'b')") + tk.MustExec("insert into t2 values (1, 1), (2, 2), (3, 1), (4, 2), (5, null)") + tk.MustExec("insert into t1 values (1, 'aa') on duplicate key update name = 'aa'") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1 aa", "2 b")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 1", "2 2", "3 1", "4 2", "5 ")) + tk.MustExec("insert into t1 values (1, 'aaa') on duplicate key update id = 10") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("2 b", "10 aa")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 10", "2 2", "3 10", "4 2", "5 ")) + // Test in transaction. + tk.MustExec("begin") + tk.MustExec("insert into t1 values (3, 'c')") + tk.MustExec("insert into t2 values (6, 3)") + tk.MustExec("insert into t1 values (2, 'bb'), (3, 'cc') on duplicate key update id =id*10") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("10 aa", "20 b", "30 c")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 10", "2 20", "3 10", "4 20", "5 ", "6 30")) + tk.MustExec("commit") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("10 aa", "20 b", "30 c")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 10", "2 20", "3 10", "4 20", "5 ", "6 30")) + tk.MustExec("delete from t1") + tk.MustQuery("select * from t2").Check(testkit.Rows("5 ")) + // Test for cascade update failed. + tk.MustExec("drop table t1, t2") + tk.MustExec("create table t1 (id int key)") + tk.MustExec("create table t2 (id int key, foreign key (id) references t1 (id) on update cascade)") + tk.MustExec("create table t3 (id int key, foreign key (id) references t2(id))") + tk.MustExec("begin") + tk.MustExec("insert into t1 values (1)") + tk.MustExec("insert into t2 values (1)") + tk.MustExec("insert into t3 values (1)") + tk.MustGetDBError("insert into t1 values (1) on duplicate key update id = 2", plannercore.ErrRowIsReferenced2) + require.Equal(t, 0, len(tk.Session().GetSessionVars().TxnCtx.Savepoints)) + tk.MustExec("commit") + tk.MustQuery("select * from t1").Check(testkit.Rows("1")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1")) +} + +func TestForeignKeyIssue39419(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key);") + tk.MustExec("create table t2 (id int key, a int, b int, " + + "foreign key fk_1 (a) references t1(id) ON DELETE SET NULL ON UPDATE SET NULL, " + + "foreign key fk_2 (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE);") + tk.MustExec("insert into t1 values (1), (2), (3);") + tk.MustExec("insert into t2 values (1, 1, 1), (2, 2, 2), (3, 3, 3);") + tk.MustExec("update t1 set id=id+10 where id in (1, 3);") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("2", "11", "13")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 11", "2 2 2", "3 13")) + tk.MustExec("delete from t1 where id = 2;") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("11", "13")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 11", "3 13")) + + tk.MustExec("drop table t1,t2") + tk.MustExec("create table t1 (id int, b int, index(id), foreign key fk_2 (b) references t1(id) ON UPDATE CASCADE);") + tk.MustExec("insert into t1 values (1, 1), (2, 2), (3, 3);") + tk.MustExec("update t1 set id=id+10 where id > 1") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1 1", "12 12", "13 13")) +} + +func TestExplainAnalyzeDMLWithFKInfo(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key);") + tk.MustExec("create table t2 (id int key, foreign key fk(id) references t1(id) ON UPDATE CASCADE ON DELETE CASCADE);") + tk.MustExec("create table t3 (id int, unique index idx(id));") + tk.MustExec("create table t4 (id int, index idx_id(id),foreign key fk(id) references t3(id));") + tk.MustExec("create table t5 (id int key, id2 int, id3 int, unique index idx2(id2), index idx3(id3));") + tk.MustExec("create table t6 (id int, id2 int, id3 int, index idx_id(id), index idx_id2(id2), " + + "foreign key fk_1 (id) references t5(id) ON UPDATE CASCADE ON DELETE SET NULL, " + + "foreign key fk_2 (id2) references t5(id2) ON UPDATE CASCADE, " + + "foreign key fk_3 (id3) references t5(id3) ON DELETE CASCADE);") + tk.MustExec("create table t7(id int primary key, pid int, index(pid), foreign key(pid) references t7(id) on delete cascade);") + + cases := []struct { + prepare []string + sql string + plan string + }{ + // Test foreign key use primary key. + { + prepare: []string{ + "insert into t1 values (1),(2),(3),(4),(5)", + }, + sql: "explain analyze insert into t2 values (1),(2),(3);", + plan: "Insert_. N/A 0 root time:.*, loops:1, prepare:.*, insert:.*" + + "└─Foreign_Key_Check_. 0.00 0 root table:t1 total:.*, check:.*, lock:.*, foreign_keys:3 foreign_key:fk, check_exist N/A N/A", + }, + { + sql: "explain analyze insert ignore into t2 values (10),(11),(12);", + plan: "Insert_.* fk_check.*" + + "└─Foreign_Key_Check_.* 0 root table:t1 total:0s, foreign_keys:3 foreign_key:fk, check_exist N/A N/A", + }, + { + sql: "explain analyze update t2 set id=id+2 where id >1", + plan: "Update_.* 0 root time:.*, loops:1.*" + + "├─TableReader_.*" + + "│ └─TableRangeScan.*" + + "└─Foreign_Key_Check_.* 0 root table:t1 total:.*, check:.*, lock:.*, foreign_keys:2 foreign_key:fk, check_exist N/A N/A", + }, + { + sql: "explain analyze delete from t1 where id>1", + plan: "Delete_.*" + + "├─TableReader_.*" + + "│ └─TableRangeScan_.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t2 total:.*, foreign_keys:4 foreign_key:fk, on_delete:CASCADE N/A N/A.*" + + " └─Delete_.*" + + " └─Batch_Point_Get_.*", + }, + { + sql: "explain analyze update t1 set id=id+1 where id = 1", + plan: "Update_.*" + + "├─Point_Get_.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t2 total:.*, foreign_keys:1 foreign_key:fk, on_update:CASCADE N/A N/A.*" + + " └─Update_.*" + + " ├─Point_Get_.*" + + " └─Foreign_Key_Check_.*", + }, + { + sql: "explain analyze insert into t1 values (1) on duplicate key update id = 100", + plan: "Insert_.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t2 total:0s foreign_key:fk, on_update:CASCADE N/A N/A", + }, + { + sql: "explain analyze insert into t1 values (2) on duplicate key update id = 100", + plan: "Insert_.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t2 total:.*, foreign_keys:1 foreign_key:fk, on_update:CASCADE N/A N/A.*" + + " └─Update_.*" + + " ├─Point_Get_.*" + + " └─Foreign_Key_Check_.* 0 root table:t1 total:.*, check:.*, lock:.*, foreign_keys:1 foreign_key:fk, check_exist N/A N/A", + }, + // Test foreign key use index. + { + prepare: []string{ + "insert into t3 values (1),(2),(3),(4),(5)", + }, + sql: "explain analyze insert into t4 values (1),(2),(3);", + plan: "Insert_.*" + + "└─Foreign_Key_Check_.* 0 root table:t3, index:idx total:.*, check:.*, lock:.*, foreign_keys:3 foreign_key:fk, check_exist N/A N/A", + }, + { + sql: "explain analyze update t4 set id=id+2 where id >1", + plan: "Update_.*" + + "├─IndexReader_.*" + + "│ └─IndexRangeScan_.*" + + "└─Foreign_Key_Check_.* 0 root table:t3, index:idx total:.*, check:.*, lock:.*, foreign_keys:2 foreign_key:fk, check_exist N/A N/A", + }, + { + sql: "explain analyze delete from t3 where id in (2,3)", + plan: "Delete_.*" + + "├─Batch_Point_Get_.*" + + "└─Foreign_Key_Check_.* 0 root table:t4, index:idx_id total:.*, check:.*, foreign_keys:2 foreign_key:fk, check_not_exist N/A N/A", + }, + { + prepare: []string{ + "insert into t3 values (2)", + }, + sql: "explain analyze update t3 set id=id+1 where id = 2", + plan: "Update_.*" + + "├─Point_Get_.*" + + "└─Foreign_Key_Check_.* 0 root table:t4, index:idx_id total:.*, check:.*, foreign_keys:1 foreign_key:fk, check_not_exist N/A N/A", + }, + + { + sql: "explain analyze insert into t3 values (2) on duplicate key update id = 100", + plan: "Insert_.*" + + "└─Foreign_Key_Check_.* 0 root table:t4, index:idx_id total:0s foreign_key:fk, check_not_exist N/A N/A", + }, + { + sql: "explain analyze insert into t3 values (3) on duplicate key update id = 100", + plan: "Insert_.*" + + "└─Foreign_Key_Check_.* 0 root table:t4, index:idx_id total:.*, check:.*, foreign_keys:1 foreign_key:fk, check_not_exist N/A N/A", + }, + // Test multi-foreign keys in on table. + { + prepare: []string{ + "insert into t5 values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5)", + }, + sql: "explain analyze insert into t6 values (1,1,1)", + plan: "Insert_.*" + + "├─Foreign_Key_Check_.* 0 root table:t5 total:.*, check:.*, lock:.*, foreign_keys:1 foreign_key:fk_1, check_exist N/A N/A.*" + + "├─Foreign_Key_Check_.* 0 root table:t5, index:idx2 total:.*, check:.*, lock:.*, foreign_keys:1 foreign_key:fk_2, check_exist N/A N/A.*" + + "└─Foreign_Key_Check_.* 0 root table:t5, index:idx3 total:.*, check:.*, lock:.*, foreign_keys:1 foreign_key:fk_3, check_exist N/A N/A", + }, + { + sql: "explain analyze insert ignore into t6 values (1,1,10)", + plan: "Insert_.* root time:.* loops:.* prepare:.* check_insert.* fk_check:.*" + + "├─Foreign_Key_Check.* 0 root table:t5 total:0s, foreign_keys:1 foreign_key:fk_1, check_exist N/A N/A.*" + + "├─Foreign_Key_Check.* 0 root table:t5, index:idx2 total:0s, foreign_keys:1 foreign_key:fk_2, check_exist N/A N/A.*" + + "└─Foreign_Key_Check.* 0 root table:t5, index:idx3 total:0s, foreign_keys:1 foreign_key:fk_3, check_exist N/A N/A", + }, + { + sql: "explain analyze update t6 set id=id+1, id3=id2+1 where id = 1", + plan: "Update_.*" + + "├─IndexLookUp_.*" + + "│ ├─IndexRangeScan_.*" + + "│ └─TableRowIDScan_.*" + + "├─Foreign_Key_Check_.* 0 root table:t5 total:.*, check:.*, lock:.*, foreign_keys:1 foreign_key:fk_1, check_exist N/A N/A.*" + + "└─Foreign_Key_Check_.* 0 root table:t5, index:idx3 total:.*, check:.*, lock:.*, foreign_keys:1 foreign_key:fk_3, check_exist N/A N/A", + }, + { + sql: "explain analyze delete from t5 where id in (4,5)", + plan: "Delete_.*" + + "├─Batch_Point_Get_.*" + + "├─Foreign_Key_Check_.* 0 root table:t6, index:idx_id2 total:.*, check:.*, foreign_keys:2 foreign_key:fk_2, check_not_exist N/A N/A.*" + + "├─Foreign_Key_Cascade_.* 0 root table:t6, index:idx_id total:.*, foreign_keys:2 foreign_key:fk_1, on_delete:SET NULL N/A N/A.*" + + "│ └─Update_.*" + + "│ │ ├─IndexRangeScan_.*" + + "│ │ └─TableRowIDScan_.*" + + "│ └─Foreign_Key_Check_.* 0 root table:t5 total:0s foreign_key:fk_1, check_exist N/A N/A.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t6, index:fk_3 total:.*, foreign_keys:2 foreign_key:fk_3, on_delete:CASCADE N/A N/A.*" + + " └─Delete_.*" + + " └─IndexLookUp_.*" + + " ├─IndexRangeScan_.*" + + " └─TableRowIDScan_.*", + }, + { + sql: "explain analyze update t5 set id=id+1, id2=id2+1 where id = 3", + plan: "Update_.*" + + "├─Point_Get_.*" + + "├─Foreign_Key_Cascade_.* 0 root table:t6, index:idx_id total:.*, foreign_keys:1 foreign_key:fk_1, on_update:CASCADE N/A N/A.*" + + "│ └─Update_.*" + + "│ ├─IndexLookUp_.*" + + "│ │ ├─IndexRangeScan_.*" + + "│ │ └─TableRowIDScan_.*" + + "│ └─Foreign_Key_Check_.* 0 root table:t5 total:0s foreign_key:fk_1, check_exist N/A N/A.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t6, index:idx_id2 total:.*, foreign_keys:1 foreign_key:fk_2, on_update:CASCADE N/A N/A.*" + + " └─Update_.*" + + " ├─IndexLookUp_.*" + + " │ ├─IndexRangeScan_.*" + + " │ └─TableRowIDScan_.*" + + " └─Foreign_Key_Check_.* 0 root table:t5, index:idx2 total:0s foreign_key:fk_2, check_exist N/A N/A", + }, + { + prepare: []string{ + "insert into t5 values (10,10,10)", + }, + sql: "explain analyze update t5 set id=id+1, id2=id2+1, id3=id3+1 where id = 10", + plan: "Update_.*" + + "├─Point_Get_.*" + + "├─Foreign_Key_Check_.* 0 root table:t6, index:fk_3 total:.*, check:.*, foreign_keys:1 foreign_key:.*, check_not_exist N/A N/A.*" + + "├─Foreign_Key_Cascade_.* 0 root table:t6, index:idx_id total:.*, foreign_keys:1 foreign_key:fk_1, on_update:CASCADE N/A N/A.*" + + "│ └─Update_.*" + + "│ ├─IndexLookUp_.*" + + "│ │ ├─IndexRangeScan_.*" + + "│ │ └─TableRowIDScan_.*" + + "│ └─Foreign_Key_Check_.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t6, index:idx_id2 total:.*, foreign_keys:1 foreign_key:fk_2, on_update:CASCADE N/A N/A.*" + + " └─Update_.*" + + " ├─IndexLookUp_.*" + + " │ ├─IndexRangeScan_.*" + + " │ └─TableRowIDScan_.*" + + " └─Foreign_Key_Check_.* 0 root table:t5, index:idx2 total:0s foreign_key:fk_2, check_exist N/A N/A", + }, + { + sql: "explain analyze insert into t5 values (1,1,1) on duplicate key update id = 100, id3=100", + plan: "Insert_.*" + + "├─Foreign_Key_Check_.* 0 root table:t6, index:fk_3 total:.*, check:.*, foreign_keys:1 foreign_key:fk_3, check_not_exist N/A N/A.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t6, index:idx_id total:.*, foreign_keys:1 foreign_key:fk_1, on_update:CASCADE N/A N/A.*" + + " └─Update_.*" + + " ├─IndexLookUp_.*" + + " │ ├─IndexRangeScan_.*" + + " │ └─TableRowIDScan_.*" + + " └─Foreign_Key_Check_.* 0 root table:t5 total:0s foreign_key:fk_1, check_exist N/A N/A", + }, + { + prepare: []string{ + "insert into t7 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13);", + }, + sql: "explain analyze delete from t7 where id = 0;", + plan: "Delete_.*" + + "├─Point_Get_.*" + + "└─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.* foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.* foreign_keys:2 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:.*, foreign_keys:1 foreign_key:fk_1, on_delete:CASCADE.*" + + " └─Delete_.*" + + " ├─UnionScan_.*" + + " │ └─IndexReader_.*" + + " │ └─IndexRangeScan_.*" + + " └─Foreign_Key_Cascade_.* 0 root table:t7, index:pid total:0s foreign_key:fk_1, on_delete:CASCADE.*", + }, + } + for _, ca := range cases { + for _, sql := range ca.prepare { + tk.MustExec(sql) + } + res := tk.MustQuery(ca.sql) + explain := getExplainResult(res) + require.Regexp(t, ca.plan, explain) + } +} + +func TestForeignKeyRuntimeStats(t *testing.T) { + checkStats := executor.FKCheckRuntimeStats{ + Total: time.Second * 3, + Check: time.Second * 2, + Lock: time.Second, + Keys: 10, + } + require.Equal(t, "total:3s, check:2s, lock:1s, foreign_keys:10", checkStats.String()) + checkStats.Merge(checkStats.Clone()) + require.Equal(t, "total:6s, check:4s, lock:2s, foreign_keys:20", checkStats.String()) + cascadeStats := executor.FKCascadeRuntimeStats{ + Total: time.Second, + Keys: 10, + } + require.Equal(t, "total:1s, foreign_keys:10", cascadeStats.String()) + cascadeStats.Merge(cascadeStats.Clone()) + require.Equal(t, "total:2s, foreign_keys:20", cascadeStats.String()) +} + +func TestPrivilegeCheckInForeignKeyCascade(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key);") + tk.MustExec("create table t2 (id int key, foreign key fk (id) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE);") + tk.MustExec("insert into t1 values (1), (2), (3);") + cases := []struct { + prepares []string + sql string + err error + t1Rows []string + t2Rows []string + }{ + { + prepares: []string{"grant insert on test.t2 to 'u1'@'%';"}, + sql: "insert into t2 values (1), (2), (3);", + t1Rows: []string{"1", "2", "3"}, + t2Rows: []string{"1", "2", "3"}, + }, + { + prepares: []string{"grant select, delete on test.t1 to 'u1'@'%';"}, + sql: "delete from t1 where id=1;", + t1Rows: []string{"2", "3"}, + t2Rows: []string{"2", "3"}, + }, + { + prepares: []string{"grant select, update on test.t1 to 'u1'@'%';"}, + sql: "update t1 set id=id+10 where id=2;", + t1Rows: []string{"3", "12"}, + t2Rows: []string{"3", "12"}, + }, + } + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec("set @@foreign_key_checks=1") + for _, ca := range cases { + tk.MustExec("drop user if exists 'u1'@'%'") + tk.MustExec("create user 'u1'@'%' identified by '';") + for _, sql := range ca.prepares { + tk.MustExec(sql) + } + err := tk2.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost", CurrentUser: true, AuthUsername: "u1", AuthHostname: "%"}, nil, []byte("012345678901234567890")) + require.NoError(t, err) + if ca.err == nil { + tk2.MustExec(ca.sql) + } else { + err = tk2.ExecToErr(ca.sql) + require.Error(t, err) + } + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows(ca.t1Rows...)) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows(ca.t2Rows...)) + } +} + +func TestTableLockInForeignKeyCascade(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec("set @@foreign_key_checks=1") + // enable table lock + config.UpdateGlobal(func(conf *config.Config) { + conf.EnableTableLock = true + }) + defer func() { + config.UpdateGlobal(func(conf *config.Config) { + conf.EnableTableLock = false + }) + }() + tk.MustExec("create table t1 (id int key);") + tk.MustExec("create table t2 (id int key, foreign key fk (id) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE);") + tk.MustExec("insert into t1 values (1), (2), (3);") + tk.MustExec("insert into t2 values (1), (2), (3);") + tk.MustExec("lock table t2 read;") + tk2.MustGetDBError("delete from t1 where id = 1", infoschema.ErrTableLocked) + tk.MustExec("unlock tables;") + tk2.MustExec("delete from t1 where id = 1") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("2", "3")) + tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("2", "3")) +} + +func TestForeignKeyIssue39732(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_stmt_summary=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create user 'u1'@'%' identified by '';") + tk.MustExec("GRANT ALL PRIVILEGES ON *.* TO 'u1'@'%'") + err := tk.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost", CurrentUser: true, AuthUsername: "u1", AuthHostname: "%"}, nil, []byte("012345678901234567890")) + require.NoError(t, err) + tk.MustExec("create table t1 (id int key, leader int, index(leader), foreign key (leader) references t1(id) ON DELETE CASCADE);") + tk.MustExec("insert into t1 values (1, null), (10, 1), (11, 1), (20, 10)") + tk.MustExec(`prepare stmt1 from 'delete from t1 where id = ?';`) + tk.MustExec(`set @a = 1;`) + tk.MustExec("execute stmt1 using @a;") + tk.MustQuery("select * from t1 order by id").Check(testkit.Rows()) +} + +func TestForeignKeyOnReplaceIntoChildTable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t_data (id int, a int, b int)") + tk.MustExec("insert into t_data (id, a, b) values (1, 1, 1), (2, 2, 2);") + for _, ca := range foreignKeyTestCase1 { + tk.MustExec("drop table if exists t2;") + tk.MustExec("drop table if exists t1;") + for _, sql := range ca.prepareSQLs { + tk.MustExec(sql) + } + tk.MustExec("replace into t1 (id, a, b) values (1, 1, 1);") + tk.MustExec("replace into t2 (id, a, b) values (1, 1, 1)") + tk.MustGetDBError("replace into t1 (id, a, b) values (1, 2, 3);", plannercore.ErrRowIsReferenced2) + if !ca.notNull { + tk.MustExec("replace into t2 (id, a, b) values (2, null, 1)") + tk.MustExec("replace into t2 (id, a, b) values (3, 1, null)") + tk.MustExec("replace into t2 (id, a, b) values (4, null, null)") + } + tk.MustGetDBError("replace into t2 (id, a, b) values (5, 1, 0);", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("replace into t2 (id, a, b) values (6, 0, 1);", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("replace into t2 (id, a, b) values (7, 2, 2);", plannercore.ErrNoReferencedRow2) + // Test replace into from select. + tk.MustExec("delete from t2") + tk.MustExec("replace into t2 (id, a, b) select id, a, b from t_data where t_data.id=1") + tk.MustGetDBError("replace into t2 (id, a, b) select id, a, b from t_data where t_data.id=2", plannercore.ErrNoReferencedRow2) + + // Test in txn + tk.MustExec("delete from t2") + tk.MustExec("begin") + tk.MustExec("delete from t1 where a=1") + tk.MustGetDBError("replace into t2 (id, a, b) values (1, 1, 1)", plannercore.ErrNoReferencedRow2) + tk.MustExec("replace into t1 (id, a, b) values (2, 2, 2)") + tk.MustExec("replace into t2 (id, a, b) values (2, 2, 2)") + tk.MustGetDBError("replace into t1 (id, a, b) values (2, 2, 3);", plannercore.ErrRowIsReferenced2) + tk.MustExec("rollback") + tk.MustQuery("select id, a, b from t1 order by id").Check(testkit.Rows("1 1 1")) + tk.MustQuery("select id, a, b from t2 order by id").Check(testkit.Rows()) + } + + // Case-10: test primary key is handle and contain foreign key column, and foreign key column has default value. + tk.MustExec("drop table if exists t2;") + tk.MustExec("drop table if exists t1;") + tk.MustExec("set @@tidb_enable_clustered_index=0;") + tk.MustExec("create table t1 (id int,a int, primary key(id));") + tk.MustExec("create table t2 (id int key,a int not null default 0, index (a), foreign key fk(a) references t1(id));") + tk.MustExec("replace into t1 values (1, 1);") + tk.MustExec("replace into t2 values (1, 1);") + tk.MustGetDBError("replace into t2 (id) values (10);", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("replace into t2 values (3, 2);", plannercore.ErrNoReferencedRow2) + + // Case-11: test primary key is handle and contain foreign key column, and foreign key column doesn't have default value. + tk.MustExec("drop table if exists t2;") + tk.MustExec("create table t2 (id int key,a int, index (a), foreign key fk(a) references t1(id));") + tk.MustExec("replace into t2 values (1, 1);") + tk.MustExec("replace into t2 (id) values (10);") + tk.MustGetDBError("replace into t2 values (3, 2);", plannercore.ErrNoReferencedRow2) +} + +func TestForeignKeyOnReplaceInto(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key, a int, index (a));") + tk.MustExec("create table t2 (id int key, a int, index (a), constraint fk_1 foreign key (a) references t1(a));") + tk.MustExec("replace into t1 values (1, 1);") + tk.MustExec("replace into t2 values (1, 1);") + tk.MustExec("replace into t2 (id) values (2);") + tk.MustGetDBError("replace into t2 values (1, 2);", plannercore.ErrNoReferencedRow2) + // Test fk check on replace into parent table. + tk.MustGetDBError("replace into t1 values (1, 2);", plannercore.ErrRowIsReferenced2) + // Test fk cascade delete on replace into parent table. + tk.MustExec("alter table t2 drop foreign key fk_1") + tk.MustExec("alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete cascade") + tk.MustExec("replace into t1 values (1, 2);") + tk.MustQuery("select id, a from t1").Check(testkit.Rows("1 2")) + tk.MustQuery("select * from t2").Check(testkit.Rows("2 ")) + // Test fk cascade delete on replace into parent table. + tk.MustExec("alter table t2 drop foreign key fk_1") + tk.MustExec("alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete set null") + tk.MustExec("delete from t2") + tk.MustExec("delete from t1") + tk.MustExec("replace into t1 values (1, 1);") + tk.MustExec("replace into t2 values (1, 1);") + tk.MustExec("replace into t1 values (1, 2);") + tk.MustQuery("select id, a from t1").Check(testkit.Rows("1 2")) + tk.MustQuery("select id, a from t2").Check(testkit.Rows("1 ")) + + // Test cascade delete in self table by replace into statement. + tk.MustExec("drop table t1,t2") + tk.MustExec("create table t1 (id int key, name varchar(10), leader int, index(leader), foreign key (leader) references t1(id) ON DELETE CASCADE);") + tk.MustExec("replace into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") + tk.MustExec("replace into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10)") + tk.MustExec("replace into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11)") + tk.MustExec("replace into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12)") + tk.MustExec("replace into t1 values (1000,'l3_a1', 100)") + tk.MustExec("replace into t1 values (1, 'new-boss', null)") + tk.MustQuery("select id from t1 order by id").Check(testkit.Rows("1")) +} + +func TestForeignKeyLargeTxnErr(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int auto_increment key, pid int, name varchar(200), index(pid));") + tk.MustExec("insert into t1 (name) values ('abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890');") + for i := 0; i < 8; i++ { + tk.MustExec("insert into t1 (name) select name from t1;") + } + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("256")) + tk.MustExec("update t1 set pid=1 where id>1") + tk.MustExec("alter table t1 add foreign key (pid) references t1 (id) on update cascade") + originLimit := atomic.LoadUint64(&kv.TxnTotalSizeLimit) + defer func() { + atomic.StoreUint64(&kv.TxnTotalSizeLimit, originLimit) + }() + // Set the limitation to a small value, make it easier to reach the limitation. + atomic.StoreUint64(&kv.TxnTotalSizeLimit, 10240) + tk.MustQuery("select sum(id) from t1").Check(testkit.Rows("32896")) + // foreign key cascade behaviour will cause ErrTxnTooLarge. + tk.MustGetDBError("update t1 set id=id+100000 where id=1", kv.ErrTxnTooLarge) + tk.MustQuery("select sum(id) from t1").Check(testkit.Rows("32896")) + tk.MustGetDBError("update t1 set id=id+100000 where id=1", kv.ErrTxnTooLarge) + tk.MustQuery("select id,pid from t1 where id<3 order by id").Check(testkit.Rows("1 ", "2 1")) + tk.MustExec("set @@foreign_key_checks=0") + tk.MustExec("update t1 set id=id+100000 where id=1") + tk.MustQuery("select id,pid from t1 where id<3 or pid is null order by id").Check(testkit.Rows("2 1", "100001 ")) +} + +func TestForeignKeyAndLockView(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t1 (id int key)") + tk.MustExec("create table t2 (id int key, foreign key (id) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE)") + tk.MustExec("insert into t1 values (1)") + tk.MustExec("insert into t2 values (1)") + tk.MustExec("begin pessimistic") + tk.MustExec("set @@foreign_key_checks=0") + tk.MustExec("update t2 set id=2") + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("set @@foreign_key_checks=1") + tk2.MustExec("use test") + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t1 set id=2 where id=1") + tk2.MustExec("commit") + }() + time.Sleep(time.Millisecond * 200) + _, digest := parser.NormalizeDigest("update t1 set id=2 where id=1") + tk.MustQuery("select CURRENT_SQL_DIGEST from information_schema.tidb_trx where state='LockWaiting' and db='test'").Check(testkit.Rows(digest.String())) + tk.MustGetErrMsg("update t1 set id=2", "[executor:1213]Deadlock found when trying to get lock; try restarting transaction") + wg.Wait() +} + +func TestForeignKeyAndMemoryTracker(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int auto_increment key, pid int, name varchar(200), index(pid));") + tk.MustExec("insert into t1 (name) values ('abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz');") + for i := 0; i < 8; i++ { + tk.MustExec("insert into t1 (name) select name from t1;") + } + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("256")) + tk.MustExec("update t1 set pid=1 where id>1") + tk.MustExec("alter table t1 add foreign key (pid) references t1 (id) on update cascade") + tk.MustQuery("select sum(id) from t1").Check(testkit.Rows("32896")) + defer tk.MustExec("SET GLOBAL tidb_mem_oom_action = DEFAULT") + tk.MustExec("SET GLOBAL tidb_mem_oom_action='CANCEL'") + tk.MustExec("set @@tidb_mem_quota_query=40960;") + // foreign key cascade behaviour will exceed memory quota. + err := tk.ExecToErr("update t1 set id=id+100000 where id=1") + require.Error(t, err) + require.Contains(t, err.Error(), "Out Of Memory Quota!") + tk.MustQuery("select id,pid from t1 where id = 1").Check(testkit.Rows("1 ")) + tk.MustExec("set @@foreign_key_checks=0") + // After disable foreign_key_checks, following DML will execute successful. + tk.MustExec("update t1 set id=id+100000 where id=1") + tk.MustQuery("select id,pid from t1 where id<3 or pid is null order by id").Check(testkit.Rows("2 1", "100001 ")) +} + +func TestForeignKeyMetaInKeyColumnUsage(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (a int, b int, index(a, b));") + tk.MustExec("create table t2 (a int, b int, index(a, b), constraint fk foreign key(a, b) references t1(a, b));") + tk.MustQuery("select CONSTRAINT_NAME, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from " + + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA='test' and TABLE_NAME='t2' and REFERENCED_TABLE_SCHEMA is not null and REFERENCED_COLUMN_NAME is not null;"). + Check(testkit.Rows("fk test t2 a test t1 a", "fk test t2 b test t1 b")) +} + +func TestForeignKeyAndGeneratedColumn(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + // Test foreign key with parent column is virtual generated column. + tk.MustExec("create table t1 (a int, b int as (a+1) virtual, index(b));") + tk.MustGetErrMsg("create table t2 (a int, b int, constraint fk foreign key(b) references t1(b));", "[schema:3733]Foreign key 'fk' uses virtual column 'b' which is not supported.") + // Test foreign key with child column is virtual generated column. + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (a int key);") + tk.MustGetErrMsg("create table t2 (a int, c int as (a+1) virtual, constraint fk foreign key(c) references t1(a));", "[schema:3733]Foreign key 'fk' uses virtual column 'c' which is not supported.") + // Test foreign key with parent column is stored generated column. + tk.MustExec("drop table if exists t1,t2") + tk.MustExec("create table t1 (a int, b int as (a) stored, index(b));") + tk.MustExec("create table t2 (a int, b int, constraint fk foreign key(b) references t1(b) on delete cascade on update cascade);") + tk.MustExec("insert into t1 (a) values (1),(2)") + tk.MustExec("insert into t2 (a) values (1),(2)") + tk.MustExec("update t2 set b=a") + tk.MustExec("insert into t2 values (1,1),(2,2)") + tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) + tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 1", "1 1", "2 2", "2 2")) + tk.MustExec("update t1 set a=a+10 where a=1") + tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("2 2", "11 11")) + tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "1 11", "2 2", "2 2")) + tk.MustExec("delete from t1 where a=2") + tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("11 11")) + tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "1 11")) + // Test foreign key with parent and child column is stored generated column. + tk.MustExec("drop table if exists t1,t2") + tk.MustExec("create table t1 (a int, b int as (a) stored, index(b));") + tk.MustGetErrMsg("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on update cascade);", "[ddl:3104]Cannot define foreign key with ON UPDATE CASCADE clause on a generated column.") + tk.MustGetErrMsg("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on delete set null);", "[ddl:3104]Cannot define foreign key with ON DELETE SET NULL clause on a generated column.") + tk.MustExec("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b));") + tk.MustExec("insert into t1 (a) values (1),(2)") + tk.MustExec("insert into t2 (a) values (1),(2)") + tk.MustGetDBError("insert into t2 (a) values (3)", plannercore.ErrNoReferencedRow2) + tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 1", "2 2")) + tk.MustGetDBError("delete from t1 where b=1", plannercore.ErrRowIsReferenced2) + tk.MustGetDBError("update t1 set a=a+10 where a=1", plannercore.ErrRowIsReferenced2) + tk.MustExec("alter table t2 drop foreign key fk") + tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete cascade") + tk.MustExec("delete from t1 where a=1") + tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("2 2")) + tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("2 2")) +} + +func TestForeignKeyAndExpressionIndex(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (a int, b int, index idx1 (b), index idx2 ((b*2)));") + tk.MustExec("create table t2 (a int, b int, index((b*2)), constraint fk foreign key(b) references t1(b));") + tk.MustExec("insert into t1 values (1,1),(2,2)") + tk.MustExec("insert into t2 values (1,1),(2,2)") + tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError("update t1 set b=b+10 where b=1", plannercore.ErrRowIsReferenced2) + tk.MustGetDBError("delete from t1 where b=1", plannercore.ErrRowIsReferenced2) + tk.MustGetErrMsg("alter table t1 drop index idx1", "[ddl:1553]Cannot drop index 'idx1': needed in a foreign key constraint") + tk.MustGetErrMsg("alter table t2 drop index fk", "[ddl:1553]Cannot drop index 'fk': needed in a foreign key constraint") + tk.MustExec("alter table t2 drop foreign key fk") + tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade") + tk.MustExec("update t1 set b=b+10 where b=1") + tk.MustExec("delete from t1 where b=2") + tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("1 11")) + tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "2 ")) + tk.MustExec("admin check table t1") + tk.MustExec("admin check table t2") +} + +func TestForeignKeyAndMultiValuedIndex(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("use test") + tk.MustExec("create table t1 (id int primary key, a json, b int generated always as (a->'$.id') stored, index idx1(b), index idx2((cast(a ->'$.data' as signed array))))") + tk.MustExec("create table t2 (id int, b int, constraint fk foreign key(b) references t1(b));") + tk.MustExec(`insert into t1 (id, a) values (1, '{"id": "1", "data": [1,11,111]}')`) + tk.MustExec(`insert into t1 (id, a) values (2, '{"id": "2", "data": [2,22,222]}')`) + tk.MustExec("insert into t2 values (1,1),(2,2)") + tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) + tk.MustGetDBError(`update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1`, plannercore.ErrRowIsReferenced2) + tk.MustGetDBError(`delete from t1 where id=1`, plannercore.ErrRowIsReferenced2) + tk.MustExec("alter table t2 drop foreign key fk") + tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade") + tk.MustExec(`update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1`) + tk.MustExec(`delete from t1 where id=2`) + tk.MustQuery("select id,b from t1 order by id").Check(testkit.Rows("1 10")) + tk.MustQuery("select id,b from t2 order by id").Check(testkit.Rows("1 10", "2 ")) + tk.MustExec("admin check table t1") + tk.MustExec("admin check table t2") +} diff --git a/executor/fktest/main_test.go b/executor/fktest/main_test.go index ebdcfdd1c9a1c..00c470717f529 100644 --- a/executor/fktest/main_test.go +++ b/executor/fktest/main_test.go @@ -35,6 +35,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), diff --git a/executor/foreign_key.go b/executor/foreign_key.go index 608ebe1e64005..9908a72fd4b04 100644 --- a/executor/foreign_key.go +++ b/executor/foreign_key.go @@ -15,18 +15,26 @@ package executor import ( + "bytes" "context" + "strconv" "sync/atomic" + "time" + "github.com/pingcap/errors" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/planner" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" + driver "github.com/pingcap/tidb/types/parser_driver" "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/set" "github.com/tikv/client-go/v2/txnkv/txnsnapshot" ) @@ -34,6 +42,8 @@ import ( // WithForeignKeyTrigger indicates the executor has foreign key check or cascade. type WithForeignKeyTrigger interface { GetFKChecks() []*FKCheckExec + GetFKCascades() []*FKCascadeExec + HasFKCascades() bool } // FKCheckExec uses to check foreign key constraint. @@ -49,18 +59,61 @@ type FKCheckExec struct { toBeLockedKeys []kv.Key checkRowsCache map[string]bool + stats *FKCheckRuntimeStats +} + +// FKCheckRuntimeStats contains the FKCheckExec runtime stats. +type FKCheckRuntimeStats struct { + Total time.Duration + Check time.Duration + Lock time.Duration + Keys int +} + +// FKCascadeExec uses to execute foreign key cascade behaviour. +type FKCascadeExec struct { + *fkValueHelper + plan *plannercore.FKCascade + b *executorBuilder + tp plannercore.FKCascadeType + referredFK *model.ReferredFKInfo + childTable *model.TableInfo + fk *model.FKInfo + fkCols []*model.ColumnInfo + fkIdx *model.IndexInfo + // On delete statement, fkValues stores the delete foreign key values. + // On update statement and the foreign key cascade is `SET NULL`, fkValues stores the old foreign key values. + fkValues [][]types.Datum + // new-value-key => UpdatedValuesCouple + fkUpdatedValuesMap map[string]*UpdatedValuesCouple + + stats *FKCascadeRuntimeStats +} + +// UpdatedValuesCouple contains the updated new row the old rows, exporting for test. +type UpdatedValuesCouple struct { + NewValues []types.Datum + OldValuesList [][]types.Datum +} + +// FKCascadeRuntimeStats contains the FKCascadeExec runtime stats. +type FKCascadeRuntimeStats struct { + Total time.Duration + Keys int } func buildTblID2FKCheckExecs(sctx sessionctx.Context, tblID2Table map[int64]table.Table, tblID2FKChecks map[int64][]*plannercore.FKCheck) (map[int64][]*FKCheckExec, error) { - var err error - fkChecks := make(map[int64][]*FKCheckExec) + fkChecksMap := make(map[int64][]*FKCheckExec) for tid, tbl := range tblID2Table { - fkChecks[tid], err = buildFKCheckExecs(sctx, tbl, tblID2FKChecks[tid]) + fkChecks, err := buildFKCheckExecs(sctx, tbl, tblID2FKChecks[tid]) if err != nil { return nil, err } + if len(fkChecks) > 0 { + fkChecksMap[tid] = fkChecks + } } - return fkChecks, nil + return fkChecksMap, nil } func buildFKCheckExecs(sctx sessionctx.Context, tbl table.Table, fkChecks []*plannercore.FKCheck) ([]*FKCheckExec, error) { @@ -100,6 +153,10 @@ func buildFKCheckExec(sctx sessionctx.Context, tbl table.Table, fkCheck *planner } func (fkc *FKCheckExec) insertRowNeedToCheck(sc *stmtctx.StatementContext, row []types.Datum) error { + if fkc.ReferredFK != nil { + // Insert into parent table doesn't need to do foreign key check. + return nil + } return fkc.addRowNeedToCheck(sc, row) } @@ -134,6 +191,20 @@ func (fkc *FKCheckExec) addRowNeedToCheck(sc *stmtctx.StatementContext, row []ty } func (fkc *FKCheckExec) doCheck(ctx context.Context) error { + if fkc.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil { + fkc.stats = &FKCheckRuntimeStats{} + defer fkc.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(fkc.ID(), fkc.stats) + } + if len(fkc.toBeCheckedKeys) == 0 && len(fkc.toBeCheckedPrefixKeys) == 0 { + return nil + } + start := time.Now() + if fkc.stats != nil { + defer func() { + fkc.stats.Keys = len(fkc.toBeCheckedKeys) + len(fkc.toBeCheckedPrefixKeys) + fkc.stats.Total = time.Since(start) + }() + } txn, err := fkc.ctx.Txn(false) if err != nil { return err @@ -146,6 +217,9 @@ func (fkc *FKCheckExec) doCheck(ctx context.Context) error { if err != nil { return err } + if fkc.stats != nil { + fkc.stats.Check = time.Since(start) + } if len(fkc.toBeLockedKeys) == 0 { return nil } @@ -161,6 +235,9 @@ func (fkc *FKCheckExec) doCheck(ctx context.Context) error { // doLockKeys may set TxnCtx.ForUpdate to 1, then if the lock meet write conflict, TiDB can't retry for update. // So reset TxnCtx.ForUpdate to 0 then can be retry if meet write conflict. atomic.StoreUint32(&sessVars.TxnCtx.ForUpdate, forUpdate) + if fkc.stats != nil { + fkc.stats.Lock = time.Since(start) - fkc.stats.Check + } return err } @@ -436,6 +513,10 @@ type fkCheckKey struct { } func (fkc FKCheckExec) checkRows(ctx context.Context, sc *stmtctx.StatementContext, txn kv.Transaction, rows []toBeCheckedRow) error { + if fkc.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl != nil { + fkc.stats = &FKCheckRuntimeStats{} + defer fkc.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(fkc.ID(), fkc.stats) + } if len(rows) == 0 { return nil } @@ -498,8 +579,371 @@ func (fkc FKCheckExec) checkRows(ctx context.Context, sc *stmtctx.StatementConte rows[i].ignored = true sc.AppendWarning(fkc.FailedErr) fkc.checkRowsCache[string(k)] = true + } else { + fkc.checkRowsCache[string(k)] = false + } + if fkc.stats != nil { + fkc.stats.Keys++ + } + } + return nil +} + +func (b *executorBuilder) buildTblID2FKCascadeExecs(tblID2Table map[int64]table.Table, tblID2FKCascades map[int64][]*plannercore.FKCascade) (map[int64][]*FKCascadeExec, error) { + fkCascadesMap := make(map[int64][]*FKCascadeExec) + for tid, tbl := range tblID2Table { + fkCascades, err := b.buildFKCascadeExecs(tbl, tblID2FKCascades[tid]) + if err != nil { + return nil, err + } + if len(fkCascades) > 0 { + fkCascadesMap[tid] = fkCascades + } + } + return fkCascadesMap, nil +} + +func (b *executorBuilder) buildFKCascadeExecs(tbl table.Table, fkCascades []*plannercore.FKCascade) ([]*FKCascadeExec, error) { + fkCascadeExecs := make([]*FKCascadeExec, 0, len(fkCascades)) + for _, fkCascade := range fkCascades { + fkCascadeExec, err := b.buildFKCascadeExec(tbl, fkCascade) + if err != nil { + return nil, err + } + if fkCascadeExec != nil { + fkCascadeExecs = append(fkCascadeExecs, fkCascadeExec) + } + } + return fkCascadeExecs, nil +} + +func (b *executorBuilder) buildFKCascadeExec(tbl table.Table, fkCascade *plannercore.FKCascade) (*FKCascadeExec, error) { + colsOffsets, err := getFKColumnsOffsets(tbl.Meta(), fkCascade.ReferredFK.Cols) + if err != nil { + return nil, err + } + helper := &fkValueHelper{ + colsOffsets: colsOffsets, + fkValuesSet: set.NewStringSet(), + } + return &FKCascadeExec{ + b: b, + fkValueHelper: helper, + plan: fkCascade, + tp: fkCascade.Tp, + referredFK: fkCascade.ReferredFK, + childTable: fkCascade.ChildTable.Meta(), + fk: fkCascade.FK, + fkCols: fkCascade.FKCols, + fkIdx: fkCascade.FKIdx, + fkUpdatedValuesMap: make(map[string]*UpdatedValuesCouple), + }, nil +} + +func (fkc *FKCascadeExec) onDeleteRow(sc *stmtctx.StatementContext, row []types.Datum) error { + vals, err := fkc.fetchFKValuesWithCheck(sc, row) + if err != nil || len(vals) == 0 { + return err + } + fkc.fkValues = append(fkc.fkValues, vals) + return nil +} + +func (fkc *FKCascadeExec) onUpdateRow(sc *stmtctx.StatementContext, oldRow, newRow []types.Datum) error { + oldVals, err := fkc.fetchFKValuesWithCheck(sc, oldRow) + if err != nil || len(oldVals) == 0 { + return err + } + if model.ReferOptionType(fkc.fk.OnUpdate) == model.ReferOptionSetNull { + fkc.fkValues = append(fkc.fkValues, oldVals) + return nil + } + newVals, err := fkc.fetchFKValues(newRow) + if err != nil { + return err + } + newValsKey, err := codec.EncodeKey(sc, nil, newVals...) + if err != nil { + return err + } + couple := fkc.fkUpdatedValuesMap[string(newValsKey)] + if couple == nil { + couple = &UpdatedValuesCouple{ + NewValues: newVals, + } + } + couple.OldValuesList = append(couple.OldValuesList, oldVals) + fkc.fkUpdatedValuesMap[string(newValsKey)] = couple + return nil +} + +func (fkc *FKCascadeExec) buildExecutor(ctx context.Context) (Executor, error) { + p, err := fkc.buildFKCascadePlan(ctx) + if err != nil || p == nil { + return nil, err + } + fkc.plan.CascadePlans = append(fkc.plan.CascadePlans, p) + e := fkc.b.build(p) + return e, fkc.b.err +} + +// maxHandleFKValueInOneCascade uses to limit the max handle fk value in one cascade executor, +// this is to avoid performance issue, see: https://github.com/pingcap/tidb/issues/38631 +var maxHandleFKValueInOneCascade = 1024 + +func (fkc *FKCascadeExec) buildFKCascadePlan(ctx context.Context) (plannercore.Plan, error) { + if len(fkc.fkValues) == 0 && len(fkc.fkUpdatedValuesMap) == 0 { + return nil, nil + } + var indexName model.CIStr + if fkc.fkIdx != nil { + indexName = fkc.fkIdx.Name + } + var stmtNode ast.StmtNode + switch fkc.tp { + case plannercore.FKCascadeOnDelete: + fkValues := fkc.fetchOnDeleteOrUpdateFKValues() + switch model.ReferOptionType(fkc.fk.OnDelete) { + case model.ReferOptionCascade: + stmtNode = GenCascadeDeleteAST(fkc.referredFK.ChildSchema, fkc.childTable.Name, indexName, fkc.fkCols, fkValues) + case model.ReferOptionSetNull: + stmtNode = GenCascadeSetNullAST(fkc.referredFK.ChildSchema, fkc.childTable.Name, indexName, fkc.fkCols, fkValues) + } + case plannercore.FKCascadeOnUpdate: + switch model.ReferOptionType(fkc.fk.OnUpdate) { + case model.ReferOptionCascade: + couple := fkc.fetchUpdatedValuesCouple() + if couple != nil && len(couple.NewValues) != 0 { + if fkc.stats != nil { + fkc.stats.Keys += len(couple.OldValuesList) + } + stmtNode = GenCascadeUpdateAST(fkc.referredFK.ChildSchema, fkc.childTable.Name, indexName, fkc.fkCols, couple) + } + case model.ReferOptionSetNull: + fkValues := fkc.fetchOnDeleteOrUpdateFKValues() + stmtNode = GenCascadeSetNullAST(fkc.referredFK.ChildSchema, fkc.childTable.Name, indexName, fkc.fkCols, fkValues) } - fkc.checkRowsCache[string(k)] = false + } + if stmtNode == nil { + return nil, errors.Errorf("generate foreign key cascade ast failed, %v", fkc.tp) + } + sctx := fkc.b.ctx + err := plannercore.Preprocess(ctx, sctx, stmtNode) + if err != nil { + return nil, err + } + finalPlan, err := planner.OptimizeForForeignKeyCascade(ctx, sctx, stmtNode, fkc.b.is) + if err != nil { + return nil, err + } + return finalPlan, err +} + +func (fkc *FKCascadeExec) fetchOnDeleteOrUpdateFKValues() [][]types.Datum { + var fkValues [][]types.Datum + if len(fkc.fkValues) <= maxHandleFKValueInOneCascade { + fkValues = fkc.fkValues + fkc.fkValues = nil + } else { + fkValues = fkc.fkValues[:maxHandleFKValueInOneCascade] + fkc.fkValues = fkc.fkValues[maxHandleFKValueInOneCascade:] + } + if fkc.stats != nil { + fkc.stats.Keys += len(fkValues) + } + return fkValues +} + +func (fkc *FKCascadeExec) fetchUpdatedValuesCouple() *UpdatedValuesCouple { + for k, couple := range fkc.fkUpdatedValuesMap { + if len(couple.OldValuesList) <= maxHandleFKValueInOneCascade { + delete(fkc.fkUpdatedValuesMap, k) + return couple + } + result := &UpdatedValuesCouple{ + NewValues: couple.NewValues, + OldValuesList: couple.OldValuesList[:maxHandleFKValueInOneCascade], + } + couple.OldValuesList = couple.OldValuesList[maxHandleFKValueInOneCascade:] + return result } return nil } + +// GenCascadeDeleteAST uses to generate cascade delete ast, export for test. +func GenCascadeDeleteAST(schema, table, idx model.CIStr, cols []*model.ColumnInfo, fkValues [][]types.Datum) *ast.DeleteStmt { + deleteStmt := &ast.DeleteStmt{ + TableRefs: genTableRefsAST(schema, table, idx), + Where: genWhereConditionAst(cols, fkValues), + } + return deleteStmt +} + +// GenCascadeSetNullAST uses to generate foreign key `SET NULL` ast, export for test. +func GenCascadeSetNullAST(schema, table, idx model.CIStr, cols []*model.ColumnInfo, fkValues [][]types.Datum) *ast.UpdateStmt { + newValues := make([]types.Datum, len(cols)) + for i := range cols { + newValues[i] = types.NewDatum(nil) + } + couple := &UpdatedValuesCouple{ + NewValues: newValues, + OldValuesList: fkValues, + } + return GenCascadeUpdateAST(schema, table, idx, cols, couple) +} + +// GenCascadeUpdateAST uses to generate cascade update ast, export for test. +func GenCascadeUpdateAST(schema, table, idx model.CIStr, cols []*model.ColumnInfo, couple *UpdatedValuesCouple) *ast.UpdateStmt { + list := make([]*ast.Assignment, 0, len(cols)) + for i, col := range cols { + v := &driver.ValueExpr{Datum: couple.NewValues[i]} + v.Type = col.FieldType + assignment := &ast.Assignment{ + Column: &ast.ColumnName{Name: col.Name}, + Expr: v, + } + list = append(list, assignment) + } + updateStmt := &ast.UpdateStmt{ + TableRefs: genTableRefsAST(schema, table, idx), + Where: genWhereConditionAst(cols, couple.OldValuesList), + List: list, + } + return updateStmt +} + +func genTableRefsAST(schema, table, idx model.CIStr) *ast.TableRefsClause { + tn := &ast.TableName{Schema: schema, Name: table} + if idx.L != "" { + tn.IndexHints = []*ast.IndexHint{{ + IndexNames: []model.CIStr{idx}, + HintType: ast.HintUse, + HintScope: ast.HintForScan, + }} + } + join := &ast.Join{Left: &ast.TableSource{Source: tn}} + return &ast.TableRefsClause{TableRefs: join} +} + +func genWhereConditionAst(cols []*model.ColumnInfo, fkValues [][]types.Datum) ast.ExprNode { + if len(cols) > 1 { + return genWhereConditionAstForMultiColumn(cols, fkValues) + } + valueList := make([]ast.ExprNode, 0, len(fkValues)) + for _, fkVals := range fkValues { + v := &driver.ValueExpr{Datum: fkVals[0]} + v.Type = cols[0].FieldType + valueList = append(valueList, v) + } + return &ast.PatternInExpr{ + Expr: &ast.ColumnNameExpr{Name: &ast.ColumnName{Name: cols[0].Name}}, + List: valueList, + } +} + +func genWhereConditionAstForMultiColumn(cols []*model.ColumnInfo, fkValues [][]types.Datum) ast.ExprNode { + colValues := make([]ast.ExprNode, len(cols)) + for i := range cols { + col := &ast.ColumnNameExpr{Name: &ast.ColumnName{Name: cols[i].Name}} + colValues[i] = col + } + valueList := make([]ast.ExprNode, 0, len(fkValues)) + for _, fkVals := range fkValues { + values := make([]ast.ExprNode, len(fkVals)) + for i, v := range fkVals { + val := &driver.ValueExpr{Datum: v} + val.Type = cols[i].FieldType + values[i] = val + } + row := &ast.RowExpr{Values: values} + valueList = append(valueList, row) + } + return &ast.PatternInExpr{ + Expr: &ast.RowExpr{Values: colValues}, + List: valueList, + } +} + +// String implements the RuntimeStats interface. +func (s *FKCheckRuntimeStats) String() string { + buf := bytes.NewBuffer(make([]byte, 0, 32)) + buf.WriteString("total:") + buf.WriteString(execdetails.FormatDuration(s.Total)) + if s.Check > 0 { + buf.WriteString(", check:") + buf.WriteString(execdetails.FormatDuration(s.Check)) + } + if s.Lock > 0 { + buf.WriteString(", lock:") + buf.WriteString(execdetails.FormatDuration(s.Lock)) + } + if s.Keys > 0 { + buf.WriteString(", foreign_keys:") + buf.WriteString(strconv.Itoa(s.Keys)) + } + return buf.String() +} + +// Clone implements the RuntimeStats interface. +func (s *FKCheckRuntimeStats) Clone() execdetails.RuntimeStats { + newRs := &FKCheckRuntimeStats{ + Total: s.Total, + Check: s.Check, + Lock: s.Lock, + Keys: s.Keys, + } + return newRs +} + +// Merge implements the RuntimeStats interface. +func (s *FKCheckRuntimeStats) Merge(other execdetails.RuntimeStats) { + tmp, ok := other.(*FKCheckRuntimeStats) + if !ok { + return + } + s.Total += tmp.Total + s.Check += tmp.Check + s.Lock += tmp.Lock + s.Keys += tmp.Keys +} + +// Tp implements the RuntimeStats interface. +func (s *FKCheckRuntimeStats) Tp() int { + return execdetails.TpFKCheckRuntimeStats +} + +// String implements the RuntimeStats interface. +func (s *FKCascadeRuntimeStats) String() string { + buf := bytes.NewBuffer(make([]byte, 0, 32)) + buf.WriteString("total:") + buf.WriteString(execdetails.FormatDuration(s.Total)) + if s.Keys > 0 { + buf.WriteString(", foreign_keys:") + buf.WriteString(strconv.Itoa(s.Keys)) + } + return buf.String() +} + +// Clone implements the RuntimeStats interface. +func (s *FKCascadeRuntimeStats) Clone() execdetails.RuntimeStats { + newRs := &FKCascadeRuntimeStats{ + Total: s.Total, + Keys: s.Keys, + } + return newRs +} + +// Merge implements the RuntimeStats interface. +func (s *FKCascadeRuntimeStats) Merge(other execdetails.RuntimeStats) { + tmp, ok := other.(*FKCascadeRuntimeStats) + if !ok { + return + } + s.Total += tmp.Total + s.Keys += tmp.Keys +} + +// Tp implements the RuntimeStats interface. +func (s *FKCascadeRuntimeStats) Tp() int { + return execdetails.TpFKCascadeRuntimeStats +} diff --git a/executor/grant.go b/executor/grant.go index 219f8b663b77d..3bae8e4956075 100644 --- a/executor/grant.go +++ b/executor/grant.go @@ -51,11 +51,11 @@ var ( type GrantExec struct { baseExecutor - Privs []*ast.PrivElem - ObjectType ast.ObjectTypeType - Level *ast.GrantLevel - Users []*ast.UserSpec - TLSOptions []*ast.TLSOption + Privs []*ast.PrivElem + ObjectType ast.ObjectTypeType + Level *ast.GrantLevel + Users []*ast.UserSpec + AuthTokenOrTLSOptions []*ast.AuthTokenOrTLSOption is infoschema.InfoSchema WithGrant bool @@ -130,6 +130,7 @@ func (e *GrantExec) Next(ctx context.Context, req *chunk.Chunk) error { // Create internal session to start internal transaction. isCommit := false internalSession, err := e.getSysSession() + internalSession.GetSessionVars().User = e.ctx.GetSessionVars().User if err != nil { return err } @@ -185,7 +186,7 @@ func (e *GrantExec) Next(ctx context.Context, req *chunk.Chunk) error { // DB scope: mysql.DB // Table scope: mysql.Tables_priv // Column scope: mysql.Columns_priv - if e.TLSOptions != nil { + if e.AuthTokenOrTLSOptions != nil { err = checkAndInitGlobalPriv(internalSession, user.User.Username, user.User.Hostname) if err != nil { return err @@ -355,10 +356,10 @@ func initColumnPrivEntry(sctx sessionctx.Context, user string, host string, db s // grantGlobalPriv grants priv to user in global scope. func (e *GrantExec) grantGlobalPriv(sctx sessionctx.Context, user *ast.UserSpec) error { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) - if len(e.TLSOptions) == 0 { + if len(e.AuthTokenOrTLSOptions) == 0 { return nil } - priv, err := tlsOption2GlobalPriv(e.TLSOptions) + priv, err := tlsOption2GlobalPriv(e.AuthTokenOrTLSOptions) if err != nil { return errors.Trace(err) } @@ -366,13 +367,13 @@ func (e *GrantExec) grantGlobalPriv(sctx sessionctx.Context, user *ast.UserSpec) return err } -func tlsOption2GlobalPriv(tlsOptions []*ast.TLSOption) (priv []byte, err error) { - if len(tlsOptions) == 0 { +func tlsOption2GlobalPriv(authTokenOrTLSOptions []*ast.AuthTokenOrTLSOption) (priv []byte, err error) { + if len(authTokenOrTLSOptions) == 0 { priv = []byte("{}") return } - dupSet := make(map[int]struct{}) - for _, opt := range tlsOptions { + dupSet := make(map[ast.AuthTokenOrTLSOptionType]struct{}) + for _, opt := range authTokenOrTLSOptions { if _, dup := dupSet[opt.Type]; dup { var typeName string switch opt.Type { @@ -384,6 +385,7 @@ func tlsOption2GlobalPriv(tlsOptions []*ast.TLSOption) (priv []byte, err error) typeName = "SUBJECT" case ast.SAN: typeName = "SAN" + case ast.TokenIssuer: } err = errors.Errorf("Duplicate require %s clause", typeName) return @@ -391,8 +393,8 @@ func tlsOption2GlobalPriv(tlsOptions []*ast.TLSOption) (priv []byte, err error) dupSet[opt.Type] = struct{}{} } gp := privileges.GlobalPrivValue{SSLType: privileges.SslTypeNotSpecified} - for _, tlsOpt := range tlsOptions { - switch tlsOpt.Type { + for _, opt := range authTokenOrTLSOptions { + switch opt.Type { case ast.TlsNone: gp.SSLType = privileges.SslTypeNone case ast.Ssl: @@ -401,36 +403,37 @@ func tlsOption2GlobalPriv(tlsOptions []*ast.TLSOption) (priv []byte, err error) gp.SSLType = privileges.SslTypeX509 case ast.Cipher: gp.SSLType = privileges.SslTypeSpecified - if len(tlsOpt.Value) > 0 { - if _, ok := util.SupportCipher[tlsOpt.Value]; !ok { - err = errors.Errorf("Unsupported cipher suit: %s", tlsOpt.Value) + if len(opt.Value) > 0 { + if _, ok := util.SupportCipher[opt.Value]; !ok { + err = errors.Errorf("Unsupported cipher suit: %s", opt.Value) return } - gp.SSLCipher = tlsOpt.Value + gp.SSLCipher = opt.Value } case ast.Issuer: - err = util.CheckSupportX509NameOneline(tlsOpt.Value) + err = util.CheckSupportX509NameOneline(opt.Value) if err != nil { return } gp.SSLType = privileges.SslTypeSpecified - gp.X509Issuer = tlsOpt.Value + gp.X509Issuer = opt.Value case ast.Subject: - err = util.CheckSupportX509NameOneline(tlsOpt.Value) + err = util.CheckSupportX509NameOneline(opt.Value) if err != nil { return } gp.SSLType = privileges.SslTypeSpecified - gp.X509Subject = tlsOpt.Value + gp.X509Subject = opt.Value case ast.SAN: gp.SSLType = privileges.SslTypeSpecified - _, err = util.ParseAndCheckSAN(tlsOpt.Value) + _, err = util.ParseAndCheckSAN(opt.Value) if err != nil { return } - gp.SAN = tlsOpt.Value + gp.SAN = opt.Value + case ast.TokenIssuer: default: - err = errors.Errorf("Unknown ssl type: %#v", tlsOpt.Type) + err = errors.Errorf("Unknown ssl type: %#v", opt.Type) return } } diff --git a/executor/grant_test.go b/executor/grant_test.go index 1045631dbc732..3a7720d620673 100644 --- a/executor/grant_test.go +++ b/executor/grant_test.go @@ -99,10 +99,10 @@ func TestGrantDBScope(t *testing.T) { } // Grant in wrong scope. - _, err := tk.Exec(` grant create user on test.* to 'testDB1'@'localhost';`) + err := tk.ExecToErr(` grant create user on test.* to 'testDB1'@'localhost';`) require.True(t, terror.ErrorEqual(err, executor.ErrWrongUsage.GenWithStackByArgs("DB GRANT", "GLOBAL PRIVILEGES"))) - _, err = tk.Exec("GRANT SUPER ON test.* TO 'testDB1'@'localhost';") + err = tk.ExecToErr("GRANT SUPER ON test.* TO 'testDB1'@'localhost';") require.True(t, terror.ErrorEqual(err, executor.ErrWrongUsage.GenWithStackByArgs("DB GRANT", "NON-DB PRIVILEGES"))) } @@ -168,8 +168,8 @@ func TestGrantTableScope(t *testing.T) { require.Greater(t, strings.Index(p, mysql.Priv2SetStr[v]), -1) } - _, err := tk.Exec("GRANT SUPER ON test2 TO 'testTbl1'@'localhost';") - require.EqualError(t, err, "[executor:1144]Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used") + tk.MustGetErrMsg("GRANT SUPER ON test2 TO 'testTbl1'@'localhost';", + "[executor:1144]Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used") } func TestGrantColumnScope(t *testing.T) { @@ -213,8 +213,8 @@ func TestGrantColumnScope(t *testing.T) { require.Greater(t, strings.Index(p, mysql.Priv2SetStr[v]), -1) } - _, err := tk.Exec("GRANT SUPER(c2) ON test3 TO 'testCol1'@'localhost';") - require.EqualError(t, err, "[executor:1221]Incorrect usage of COLUMN GRANT and NON-COLUMN PRIVILEGES") + tk.MustGetErrMsg("GRANT SUPER(c2) ON test3 TO 'testCol1'@'localhost';", + "[executor:1221]Incorrect usage of COLUMN GRANT and NON-COLUMN PRIVILEGES") } func TestIssue2456(t *testing.T) { @@ -394,7 +394,7 @@ func TestMaintainRequire(t *testing.T) { // test show create user tk.MustExec(`CREATE USER 'u3'@'%' require issuer '/CN=TiDB admin/OU=TiDB/O=PingCAP/L=San Francisco/ST=California/C=US' subject '/CN=tester1/OU=TiDB/O=PingCAP.Inc/L=Haidian/ST=Beijing/C=ZH' cipher 'AES128-GCM-SHA256'`) - tk.MustQuery("show create user 'u3'").Check(testkit.Rows("CREATE USER 'u3'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE CIPHER 'AES128-GCM-SHA256' ISSUER '/CN=TiDB admin/OU=TiDB/O=PingCAP/L=San Francisco/ST=California/C=US' SUBJECT '/CN=tester1/OU=TiDB/O=PingCAP.Inc/L=Haidian/ST=Beijing/C=ZH' PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK")) + tk.MustQuery("show create user 'u3'").Check(testkit.Rows("CREATE USER 'u3'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE CIPHER 'AES128-GCM-SHA256' ISSUER '/CN=TiDB admin/OU=TiDB/O=PingCAP/L=San Francisco/ST=California/C=US' SUBJECT '/CN=tester1/OU=TiDB/O=PingCAP.Inc/L=Haidian/ST=Beijing/C=ZH' PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT")) // check issuer/subject/cipher value err := tk.ExecToErr(`CREATE USER 'u4'@'%' require issuer 'CN=TiDB,OU=PingCAP'`) @@ -588,3 +588,16 @@ func TestIssue34610(t *testing.T) { tk.MustExec("GRANT SELECT ON T1 to user_1@localhost;") tk.MustExec("GRANT SELECT ON t1 to user_1@localhost;") } + +func TestIssue38293(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.Session().GetSessionVars().User = &auth.UserIdentity{Username: "root", Hostname: "localhost"} + tk.MustExec("DROP USER IF EXISTS test") + tk.MustExec("CREATE USER test") + defer func() { + tk.MustExec("DROP USER test") + }() + tk.MustExec("GRANT SELECT ON `mysql`.`db` TO test") + tk.MustQuery("SELECT `Grantor` FROM `mysql`.`tables_priv` WHERE User = 'test'").Check(testkit.Rows("root@localhost")) +} diff --git a/executor/hash_table.go b/executor/hash_table.go index d2b294f52d9ad..2ba840d04fdc9 100644 --- a/executor/hash_table.go +++ b/executor/hash_table.go @@ -92,6 +92,10 @@ func (s *hashStatistic) String() string { return fmt.Sprintf("probe_collision:%v, build:%v", s.probeCollision, execdetails.FormatDuration(s.buildTableElapse)) } +type hashNANullBucket struct { + entries []*naEntry +} + // hashRowContainer handles the rows and the hash map of a table. // NOTE: a hashRowContainer may be shallow copied by the invoker, define all the // member attributes as pointer type to avoid unexpected problems. @@ -104,7 +108,7 @@ type hashRowContainer struct { hashTable baseHashTable // hashNANullBucket stores the rows with any null value in NAAJ join key columns. // After build process, NANUllBucket is read only here for multi probe worker. - hashNANullBucket []*naEntry + hashNANullBucket *hashNANullBucket rowContainer *chunk.RowContainer memTracker *memory.Tracker @@ -113,7 +117,7 @@ type hashRowContainer struct { chkBuf *chunk.Chunk } -func newHashRowContainer(sCtx sessionctx.Context, estCount int, hCtx *hashContext, allTypes []*types.FieldType) *hashRowContainer { +func newHashRowContainer(sCtx sessionctx.Context, hCtx *hashContext, allTypes []*types.FieldType) *hashRowContainer { maxChunkSize := sCtx.GetSessionVars().MaxChunkSize rc := chunk.NewRowContainer(allTypes, maxChunkSize) c := &hashRowContainer{ @@ -124,6 +128,9 @@ func newHashRowContainer(sCtx sessionctx.Context, estCount int, hCtx *hashContex rowContainer: rc, memTracker: memory.NewTracker(memory.LabelForRowContainer, -1), } + if isNAAJ := len(hCtx.naKeyColIdx) > 0; isNAAJ { + c.hashNANullBucket = &hashNANullBucket{} + } rc.GetMemTracker().AttachTo(c.GetMemTracker()) return c } @@ -248,7 +255,7 @@ func (c *hashRowContainer) GetNullBucketRows(probeHCtx *hashContext, probeSideRo mayMatchedRow chunk.Row ) matched = matched[:0] - for _, nullEntry := range c.hashNANullBucket { + for _, nullEntry := range c.hashNANullBucket.entries { mayMatchedRow, c.chkBuf, err = c.rowContainer.GetRowAndAppendToChunk(nullEntry.ptr, c.chkBuf) if err != nil { return nil, err @@ -394,7 +401,7 @@ func (c *hashRowContainer) PutChunkSelected(chk *chunk.Chunk, selected, ignoreNu // collect the null rows to slice. rowPtr := chunk.RowPtr{ChkIdx: chkIdx, RowIdx: uint32(i)} // do not directly ref the null bits map here, because the bit map will be reset and reused in next batch of chunk data. - c.hashNANullBucket = append(c.hashNANullBucket, &naEntry{rowPtr, c.hCtx.naColNullBitMap[i].Clone()}) + c.hashNANullBucket.entries = append(c.hashNANullBucket.entries, &naEntry{rowPtr, c.hCtx.naColNullBitMap[i].Clone()}) } else { // insert the not-null rows to hash table. key := c.hCtx.hashVals[i].Sum64() diff --git a/executor/hash_table_test.go b/executor/hash_table_test.go index 3b4a4acee5284..0a387e0e7e5b6 100644 --- a/executor/hash_table_test.go +++ b/executor/hash_table_test.go @@ -127,7 +127,7 @@ func testHashRowContainer(t *testing.T, hashFunc func() hash.Hash64, spill bool) for i := 0; i < numRows; i++ { hCtx.hashVals = append(hCtx.hashVals, hashFunc()) } - rowContainer := newHashRowContainer(sctx, 0, hCtx, colTypes) + rowContainer := newHashRowContainer(sctx, hCtx, colTypes) copiedRC = rowContainer.ShallowCopy() tracker := rowContainer.GetMemTracker() tracker.SetLabel(memory.LabelForBuildSideResult) diff --git a/executor/historical_stats_test.go b/executor/historical_stats_test.go new file mode 100644 index 0000000000000..0b00d3182f019 --- /dev/null +++ b/executor/historical_stats_test.go @@ -0,0 +1,308 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package executor_test + +import ( + "encoding/json" + "fmt" + "strconv" + "testing" + "time" + + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/statistics/handle" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/oracle" +) + +func TestRecordHistoryStatsAfterAnalyze(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@tidb_analyze_version = 2") + tk.MustExec("set global tidb_enable_historical_stats = 0") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b varchar(10))") + + h := dom.StatsHandle() + is := dom.InfoSchema() + tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + + // 1. switch off the tidb_enable_historical_stats, and there is no records in table `mysql.stats_history` + rows := tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", tableInfo.Meta().ID)).Rows() + num, _ := strconv.Atoi(rows[0][0].(string)) + require.Equal(t, num, 0) + + tk.MustExec("analyze table t with 2 topn") + rows = tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", tableInfo.Meta().ID)).Rows() + num, _ = strconv.Atoi(rows[0][0].(string)) + require.Equal(t, num, 0) + + // 2. switch on the tidb_enable_historical_stats and do analyze + tk.MustExec("set global tidb_enable_historical_stats = 1") + defer tk.MustExec("set global tidb_enable_historical_stats = 0") + tk.MustExec("analyze table t with 2 topn") + // dump historical stats + hsWorker := dom.GetHistoricalStatsWorker() + tblID := hsWorker.GetOneHistoricalStatsTable() + err = hsWorker.DumpHistoricalStats(tblID, h) + require.Nil(t, err) + rows = tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", tableInfo.Meta().ID)).Rows() + num, _ = strconv.Atoi(rows[0][0].(string)) + require.GreaterOrEqual(t, num, 1) + + // 3. dump current stats json + dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil, true) + require.NoError(t, err) + jsOrigin, _ := json.Marshal(dumpJSONTable) + + // 4. get the historical stats json + rows = tk.MustQuery(fmt.Sprintf("select * from mysql.stats_history where table_id = '%d' and create_time = ("+ + "select create_time from mysql.stats_history where table_id = '%d' order by create_time desc limit 1) "+ + "order by seq_no", tableInfo.Meta().ID, tableInfo.Meta().ID)).Rows() + num = len(rows) + require.GreaterOrEqual(t, num, 1) + data := make([][]byte, num) + for i, row := range rows { + data[i] = []byte(row[1].(string)) + } + jsonTbl, err := handle.BlocksToJSONTable(data) + require.NoError(t, err) + jsCur, err := json.Marshal(jsonTbl) + require.NoError(t, err) + // 5. historical stats must be equal to the current stats + require.JSONEq(t, string(jsOrigin), string(jsCur)) +} + +func TestRecordHistoryStatsMetaAfterAnalyze(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@tidb_analyze_version = 2") + tk.MustExec("set global tidb_enable_historical_stats = 0") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int)") + tk.MustExec("analyze table test.t") + + h := dom.StatsHandle() + is := dom.InfoSchema() + tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + + // 1. switch off the tidb_enable_historical_stats, and there is no record in table `mysql.stats_meta_history` + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d'", tableInfo.Meta().ID)).Check(testkit.Rows("0")) + // insert demo tuples, and there is no record either. + insertNums := 5 + for i := 0; i < insertNums; i++ { + tk.MustExec("insert into test.t (a,b) values (1,1), (2,2), (3,3)") + err := h.DumpStatsDeltaToKV(handle.DumpDelta) + require.NoError(t, err) + } + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d'", tableInfo.Meta().ID)).Check(testkit.Rows("0")) + + // 2. switch on the tidb_enable_historical_stats and insert tuples to produce count/modifyCount delta change. + tk.MustExec("set global tidb_enable_historical_stats = 1") + defer tk.MustExec("set global tidb_enable_historical_stats = 0") + + for i := 0; i < insertNums; i++ { + tk.MustExec("insert into test.t (a,b) values (1,1), (2,2), (3,3)") + err := h.DumpStatsDeltaToKV(handle.DumpDelta) + require.NoError(t, err) + } + tk.MustQuery(fmt.Sprintf("select modify_count, count from mysql.stats_meta_history where table_id = '%d' order by create_time", tableInfo.Meta().ID)).Sort().Check( + testkit.Rows("18 18", "21 21", "24 24", "27 27", "30 30")) + tk.MustQuery(fmt.Sprintf("select distinct source from mysql.stats_meta_history where table_id = '%d'", tableInfo.Meta().ID)).Sort().Check(testkit.Rows("flush stats")) + + // assert delete + tk.MustExec("delete from test.t where test.t.a = 1") + err = h.DumpStatsDeltaToKV(handle.DumpAll) + require.NoError(t, err) + tk.MustQuery(fmt.Sprintf("select modify_count, count from mysql.stats_meta where table_id = '%d' order by create_time desc", tableInfo.Meta().ID)).Sort().Check( + testkit.Rows("40 20")) + tk.MustQuery(fmt.Sprintf("select modify_count, count from mysql.stats_meta_history where table_id = '%d' order by create_time desc limit 1", tableInfo.Meta().ID)).Sort().Check( + testkit.Rows("40 20")) + + // assert update + tk.MustExec("update test.t set test.t.b = 4 where test.t.a = 2") + err = h.DumpStatsDeltaToKV(handle.DumpAll) + require.NoError(t, err) + tk.MustQuery(fmt.Sprintf("select modify_count, count from mysql.stats_meta where table_id = '%d' order by create_time desc", tableInfo.Meta().ID)).Sort().Check( + testkit.Rows("50 20")) + tk.MustQuery(fmt.Sprintf("select modify_count, count from mysql.stats_meta_history where table_id = '%d' order by create_time desc limit 1", tableInfo.Meta().ID)).Sort().Check( + testkit.Rows("50 20")) +} + +func TestGCHistoryStatsAfterDropTable(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set global tidb_enable_historical_stats = 1") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b varchar(10))") + tk.MustExec("analyze table test.t") + is := dom.InfoSchema() + tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + // dump historical stats + h := dom.StatsHandle() + hsWorker := dom.GetHistoricalStatsWorker() + tblID := hsWorker.GetOneHistoricalStatsTable() + err = hsWorker.DumpHistoricalStats(tblID, h) + require.Nil(t, err) + + // assert the records of history stats table + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d' order by create_time", + tableInfo.Meta().ID)).Check(testkit.Rows("1")) + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", + tableInfo.Meta().ID)).Check(testkit.Rows("1")) + // drop the table and gc stats + tk.MustExec("drop table t") + h.GCStats(is, 0) + + // assert stats_history tables delete the record of dropped table + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d' order by create_time", + tableInfo.Meta().ID)).Check(testkit.Rows("0")) + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", + tableInfo.Meta().ID)).Check(testkit.Rows("0")) +} + +func TestGCOutdatedHistoryStats(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set global tidb_enable_historical_stats = 1") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b varchar(10))") + tk.MustExec("analyze table test.t") + is := dom.InfoSchema() + tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + // dump historical stats + h := dom.StatsHandle() + hsWorker := dom.GetHistoricalStatsWorker() + tblID := hsWorker.GetOneHistoricalStatsTable() + err = hsWorker.DumpHistoricalStats(tblID, h) + require.Nil(t, err) + + // assert the records of history stats table + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d' order by create_time", + tableInfo.Meta().ID)).Check(testkit.Rows("1")) + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", + tableInfo.Meta().ID)).Check(testkit.Rows("1")) + + variable.HistoricalStatsDuration.Store(1 * time.Second) + time.Sleep(2 * time.Second) + err = dom.StatsHandle().ClearOutdatedHistoryStats() + require.NoError(t, err) + // assert the records of history stats table + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_meta_history where table_id = '%d' order by create_time", + tableInfo.Meta().ID)).Check(testkit.Rows("0")) + tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id = '%d'", + tableInfo.Meta().ID)).Check(testkit.Rows("0")) +} + +func TestPartitionTableHistoricalStats(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set global tidb_enable_historical_stats = 1") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec(`CREATE TABLE t (a int, b int, index idx(b)) +PARTITION BY RANGE ( a ) ( +PARTITION p0 VALUES LESS THAN (6) +)`) + tk.MustExec("delete from mysql.stats_history") + + tk.MustExec("analyze table test.t") + // dump historical stats + h := dom.StatsHandle() + hsWorker := dom.GetHistoricalStatsWorker() + + // assert global table and partition table be dumped + tblID := hsWorker.GetOneHistoricalStatsTable() + err := hsWorker.DumpHistoricalStats(tblID, h) + require.NoError(t, err) + tblID = hsWorker.GetOneHistoricalStatsTable() + err = hsWorker.DumpHistoricalStats(tblID, h) + require.NoError(t, err) + tk.MustQuery("select count(*) from mysql.stats_history").Check(testkit.Rows("2")) +} + +func TestDumpHistoricalStatsByTable(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set global tidb_enable_historical_stats = 1") + tk.MustExec("set @@tidb_partition_prune_mode='static'") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec(`CREATE TABLE t (a int, b int, index idx(b)) +PARTITION BY RANGE ( a ) ( +PARTITION p0 VALUES LESS THAN (6) +)`) + // dump historical stats + h := dom.StatsHandle() + + tk.MustExec("analyze table t") + is := dom.InfoSchema() + tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + require.NotNil(t, tbl) + + // dump historical stats + hsWorker := dom.GetHistoricalStatsWorker() + // only partition p0 stats will be dumped in static mode + tblID := hsWorker.GetOneHistoricalStatsTable() + require.NotEqual(t, tblID, -1) + err = hsWorker.DumpHistoricalStats(tblID, h) + require.NoError(t, err) + tblID = hsWorker.GetOneHistoricalStatsTable() + require.Equal(t, tblID, int64(-1)) + + time.Sleep(1 * time.Second) + snapshot := oracle.GoTimeToTS(time.Now()) + jsTable, err := h.DumpHistoricalStatsBySnapshot("test", tbl.Meta(), snapshot) + require.NoError(t, err) + require.NotNil(t, jsTable) + // only has p0 stats + require.NotNil(t, jsTable.Partitions["p0"]) + require.Nil(t, jsTable.Partitions["global"]) + + // change static to dynamic then assert + tk.MustExec("set @@tidb_partition_prune_mode='dynamic'") + tk.MustExec("analyze table t") + require.NoError(t, err) + // global and p0's stats will be dumped + tblID = hsWorker.GetOneHistoricalStatsTable() + require.NotEqual(t, tblID, -1) + err = hsWorker.DumpHistoricalStats(tblID, h) + require.NoError(t, err) + tblID = hsWorker.GetOneHistoricalStatsTable() + require.NotEqual(t, tblID, -1) + err = hsWorker.DumpHistoricalStats(tblID, h) + require.NoError(t, err) + time.Sleep(1 * time.Second) + snapshot = oracle.GoTimeToTS(time.Now()) + jsTable, err = h.DumpHistoricalStatsBySnapshot("test", tbl.Meta(), snapshot) + require.NoError(t, err) + require.NotNil(t, jsTable) + // has both global and p0 stats + require.NotNil(t, jsTable.Partitions["p0"]) + require.NotNil(t, jsTable.Partitions["global"]) +} diff --git a/executor/index_lookup_hash_join.go b/executor/index_lookup_hash_join.go index d7e20c33bf94c..58bd84ff6e4d6 100644 --- a/executor/index_lookup_hash_join.go +++ b/executor/index_lookup_hash_join.go @@ -96,6 +96,7 @@ type indexHashJoinInnerWorker struct { wg *sync.WaitGroup joinKeyBuf []byte outerRowStatus []outerRowStatusFlag + rowIter *chunk.Iterator4Slice } type indexHashJoinResult struct { @@ -133,7 +134,6 @@ func (e *IndexNestedLoopHashJoin) Open(ctx context.Context) error { e.innerPtrBytes = make([][]byte, 0, 8) if e.runtimeStats != nil { e.stats = &indexLookUpJoinRuntimeStats{} - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } e.finished.Store(false) return nil @@ -287,6 +287,9 @@ func (e *IndexNestedLoopHashJoin) isDryUpTasks(ctx context.Context) bool { // Close implements the IndexNestedLoopHashJoin Executor interface. func (e *IndexNestedLoopHashJoin) Close() error { + if e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } if e.cancelFunc != nil { e.cancelFunc() } @@ -417,7 +420,7 @@ func (e *IndexNestedLoopHashJoin) newInnerWorker(taskCh chan *indexHashJoinTask, innerCtx: e.innerCtx, outerCtx: e.outerCtx, ctx: e.ctx, - executorChk: chunk.NewChunkWithCapacity(e.innerCtx.rowTypes, e.maxChunkSize), + executorChk: e.ctx.GetSessionVars().GetNewChunkWithCapacity(e.innerCtx.rowTypes, e.maxChunkSize, e.maxChunkSize, e.AllocPool), indexRanges: copiedRanges, keyOff2IdxOff: e.keyOff2IdxOff, stats: innerStats, @@ -431,6 +434,7 @@ func (e *IndexNestedLoopHashJoin) newInnerWorker(taskCh chan *indexHashJoinTask, matchedOuterPtrs: make([]chunk.RowPtr, 0, e.maxChunkSize), joinKeyBuf: make([]byte, 1), outerRowStatus: make([]outerRowStatusFlag, 0, e.maxChunkSize), + rowIter: chunk.NewIterator4Slice([]chunk.Row{}).(*chunk.Iterator4Slice), } iw.memTracker.AttachTo(e.memTracker) if len(copiedRanges) != 0 { @@ -733,12 +737,11 @@ func (iw *indexHashJoinInnerWorker) joinMatchedInnerRow2Chunk(ctx context.Contex if len(matchedOuterRows) == 0 { return true, joinResult } - var ( - ok bool - iter = chunk.NewIterator4Slice(matchedOuterRows) - cursor = 0 - ) - for iter.Begin(); iter.Current() != iter.End(); { + var ok bool + cursor := 0 + iw.rowIter.Reset(matchedOuterRows) + iter := iw.rowIter + for iw.rowIter.Begin(); iter.Current() != iter.End(); { iw.outerRowStatus, err = iw.joiner.tryToMatchOuters(iter, innerRow, joinResult.chk, iw.outerRowStatus) if err != nil { joinResult.err = err @@ -821,7 +824,8 @@ func (iw *indexHashJoinInnerWorker) doJoinInOrder(ctx context.Context, task *ind for _, ptr := range innerRowPtrs { matchedInnerRows = append(matchedInnerRows, task.innerResult.GetRow(ptr)) } - iter := chunk.NewIterator4Slice(matchedInnerRows) + iw.rowIter.Reset(matchedInnerRows) + iter := iw.rowIter for iter.Begin(); iter.Current() != iter.End(); { matched, isNull, err := iw.joiner.tryToMatchInners(outerRow, iter, joinResult.chk) if err != nil { diff --git a/executor/index_lookup_join.go b/executor/index_lookup_join.go index cf2722275dbe5..187e83cc0f763 100644 --- a/executor/index_lookup_join.go +++ b/executor/index_lookup_join.go @@ -67,7 +67,7 @@ type IndexLookUpJoin struct { task *lookUpJoinTask joinResult *chunk.Chunk - innerIter chunk.Iterator + innerIter *chunk.Iterator4Slice joiner joiner isOuterJoin bool @@ -171,7 +171,6 @@ func (e *IndexLookUpJoin) Open(ctx context.Context) error { e.finished.Store(false) if e.runtimeStats != nil { e.stats = &indexLookUpJoinRuntimeStats{} - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } e.cancelFunc = nil return nil @@ -226,7 +225,7 @@ func (e *IndexLookUpJoin) newInnerWorker(taskCh chan *lookUpJoinTask) *innerWork outerCtx: e.outerCtx, taskCh: taskCh, ctx: e.ctx, - executorChk: chunk.NewChunkWithCapacity(e.innerCtx.rowTypes, e.maxChunkSize), + executorChk: e.ctx.GetSessionVars().GetNewChunkWithCapacity(e.innerCtx.rowTypes, e.maxChunkSize, e.maxChunkSize, e.AllocPool), indexRanges: copiedRanges, keyOff2IdxOff: e.keyOff2IdxOff, stats: innerStats, @@ -277,7 +276,10 @@ func (e *IndexLookUpJoin) Next(ctx context.Context, req *chunk.Chunk) error { startTime := time.Now() if e.innerIter == nil || e.innerIter.Current() == e.innerIter.End() { e.lookUpMatchedInners(task, task.cursor) - e.innerIter = chunk.NewIterator4Slice(task.matchedInners) + if e.innerIter == nil { + e.innerIter = chunk.NewIterator4Slice(task.matchedInners).(*chunk.Iterator4Slice) + } + e.innerIter.Reset(task.matchedInners) e.innerIter.Begin() } @@ -428,7 +430,7 @@ func (ow *outerWorker) buildTask(ctx context.Context) (*lookUpJoinTask, error) { } maxChunkSize := ow.ctx.GetSessionVars().MaxChunkSize for requiredRows > task.outerResult.Len() { - chk := chunk.NewChunkWithCapacity(ow.outerCtx.rowTypes, maxChunkSize) + chk := ow.ctx.GetSessionVars().GetNewChunkWithCapacity(ow.outerCtx.rowTypes, maxChunkSize, maxChunkSize, ow.executor.base().AllocPool) chk = chk.SetRequiredRows(requiredRows, maxChunkSize) err := Next(ctx, ow.executor, chk) if err != nil { @@ -459,7 +461,7 @@ func (ow *outerWorker) buildTask(ctx context.Context) (*lookUpJoinTask, error) { } task.encodedLookUpKeys = make([]*chunk.Chunk, task.outerResult.NumChunks()) for i := range task.encodedLookUpKeys { - task.encodedLookUpKeys[i] = chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeBlob)}, task.outerResult.GetChunk(i).NumRows()) + task.encodedLookUpKeys[i] = ow.ctx.GetSessionVars().GetNewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeBlob)}, task.outerResult.GetChunk(i).NumRows(), task.outerResult.GetChunk(i).NumRows(), ow.executor.base().AllocPool) } return task, nil } @@ -711,7 +713,7 @@ func (iw *innerWorker) fetchInnerResults(ctx context.Context, task *lookUpJoinTa break } innerResult.Add(iw.executorChk) - iw.executorChk = newFirstChunk(innerExec) + iw.executorChk = tryNewCacheChunk(innerExec) } task.innerResult = innerResult return nil @@ -762,6 +764,9 @@ func (iw *innerWorker) hasNullInJoinKey(row chunk.Row) bool { // Close implements the Executor interface. func (e *IndexLookUpJoin) Close() error { + if e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } if e.cancelFunc != nil { e.cancelFunc() } diff --git a/executor/index_lookup_join_test.go b/executor/index_lookup_join_test.go index ef8b582fb151f..600f052b1225e 100644 --- a/executor/index_lookup_join_test.go +++ b/executor/index_lookup_join_test.go @@ -352,13 +352,16 @@ func TestIssue23722(t *testing.T) { tk.MustExec("insert into t values (20301,'Charlie',x'7a');") tk.MustQuery("select * from t;").Check(testkit.Rows("20301 Charlie z")) tk.MustQuery("select * from t where c in (select c from t where t.c >= 'a');").Check(testkit.Rows("20301 Charlie z")) + tk.MustQuery("select @@last_sql_use_alloc").Check(testkit.Rows("1")) // Test lookup content exceeds primary key prefix. tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a int, b char(10), c varchar(255), primary key (c(5)) clustered);") tk.MustExec("insert into t values (20301,'Charlie','aaaaaaa');") + tk.MustQuery("select @@last_sql_use_alloc").Check(testkit.Rows("1")) tk.MustQuery("select * from t;").Check(testkit.Rows("20301 Charlie aaaaaaa")) tk.MustQuery("select * from t where c in (select c from t where t.c >= 'a');").Check(testkit.Rows("20301 Charlie aaaaaaa")) + tk.MustQuery("select @@last_sql_use_alloc").Check(testkit.Rows("1")) // Test the original case. tk.MustExec("drop table if exists t;") @@ -398,6 +401,7 @@ func TestIssue27138(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec("drop table if exists t1,t2") tk.MustExec("set @old_tidb_partition_prune_mode=@@tidb_partition_prune_mode") @@ -424,17 +428,19 @@ PARTITIONS 1`) // Why does the t2.prefiller need be at least 2^32 ? If smaller the bug will not appear!?! tk.MustExec("insert into t2 values ( pow(2,32), 1, 1), ( pow(2,32)+1, 2, 0)") + tk.MustExec(`analyze table t1`) + tk.MustExec(`analyze table t2`) // Why must it be = 1 and not 2? - tk.MustQuery("explain select /* +INL_JOIN(t1,t2) */ t1.id, t1.pc from t1 where id in ( select prefiller from t2 where t2.postfiller = 1 )").Check(testkit.Rows("" + - "IndexJoin_15 10.00 root inner join, inner:TableReader_14, outer key:test.t2.prefiller, inner key:test.t1.id, equal cond:eq(test.t2.prefiller, test.t1.id)]\n" + - "[├─HashAgg_25(Build) 8.00 root group by:test.t2.prefiller, funcs:firstrow(test.t2.prefiller)->test.t2.prefiller]\n" + - "[│ └─TableReader_26 8.00 root data:HashAgg_20]\n" + - "[│ └─HashAgg_20 8.00 cop[tikv] group by:test.t2.prefiller, ]\n" + - "[│ └─Selection_24 10.00 cop[tikv] eq(test.t2.postfiller, 1)]\n" + - "[│ └─TableFullScan_23 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo]\n" + - "[└─TableReader_14(Probe) 1.00 root partition:all data:TableRangeScan_13]\n" + - "[ └─TableRangeScan_13 1.00 cop[tikv] table:t1 range: decided by [eq(test.t1.id, test.t2.prefiller)], keep order:false, stats:pseudo")) + tk.MustQuery("explain format='brief' select /* +INL_JOIN(t1,t2) */ t1.id, t1.pc from t1 where id in ( select prefiller from t2 where t2.postfiller = 1 )").Check(testkit.Rows(""+ + `IndexJoin 1.25 root inner join, inner:TableReader, outer key:test.t2.prefiller, inner key:test.t1.id, equal cond:eq(test.t2.prefiller, test.t1.id)`, + `├─HashAgg(Build) 1.00 root group by:test.t2.prefiller, funcs:firstrow(test.t2.prefiller)->test.t2.prefiller`, + `│ └─TableReader 1.00 root data:HashAgg`, + `│ └─HashAgg 1.00 cop[tikv] group by:test.t2.prefiller, `, + `│ └─Selection 1.00 cop[tikv] eq(test.t2.postfiller, 1)`, + `│ └─TableFullScan 2.00 cop[tikv] table:t2 keep order:false`, + `└─TableReader(Probe) 1.00 root partition:all data:TableRangeScan`, + ` └─TableRangeScan 1.00 cop[tikv] table:t1 range: decided by [eq(test.t1.id, test.t2.prefiller)], keep order:false, stats:pseudo`)) tk.MustQuery("show warnings").Check(testkit.Rows()) // without fix it fails with: "runtime error: index out of range [0] with length 0" tk.MustQuery("select /* +INL_JOIN(t1,t2) */ t1.id, t1.pc from t1 where id in ( select prefiller from t2 where t2.postfiller = 1 )").Check(testkit.Rows()) @@ -452,7 +458,9 @@ func TestIssue27893(t *testing.T) { tk.MustExec("insert into t1 values('x')") tk.MustExec("insert into t2 values(1)") tk.MustQuery("select /*+ inl_join(t2) */ count(*) from t1 join t2 on t1.a = t2.a").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_sql_use_alloc").Check(testkit.Rows("1")) tk.MustQuery("select /*+ inl_hash_join(t2) */ count(*) from t1 join t2 on t1.a = t2.a").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_sql_use_alloc").Check(testkit.Rows("1")) } func TestPartitionTableIndexJoinAndIndexReader(t *testing.T) { diff --git a/executor/index_lookup_merge_join.go b/executor/index_lookup_merge_join.go index 369c18716dbc3..e0fb176fff589 100644 --- a/executor/index_lookup_merge_join.go +++ b/executor/index_lookup_merge_join.go @@ -357,7 +357,7 @@ func (omw *outerMergeWorker) buildTask(ctx context.Context) (*lookUpMergeJoinTas requiredRows = omw.maxBatchSize } for requiredRows > 0 { - execChk := newFirstChunk(omw.executor) + execChk := tryNewCacheChunk(omw.executor) err := Next(ctx, omw.executor, execChk) if err != nil { return task, err @@ -706,7 +706,7 @@ func (imw *innerMergeWorker) dedupDatumLookUpKeys(lookUpContents []*indexJoinLoo // fetchNextInnerResult collects a chunk of inner results from inner child executor. func (imw *innerMergeWorker) fetchNextInnerResult(ctx context.Context, task *lookUpMergeJoinTask) (beginRow chunk.Row, err error) { - task.innerResult = chunk.NewChunkWithCapacity(retTypes(imw.innerExec), imw.ctx.GetSessionVars().MaxChunkSize) + task.innerResult = imw.ctx.GetSessionVars().GetNewChunkWithCapacity(retTypes(imw.innerExec), imw.ctx.GetSessionVars().MaxChunkSize, imw.ctx.GetSessionVars().MaxChunkSize, imw.innerExec.base().AllocPool) err = Next(ctx, imw.innerExec, task.innerResult) task.innerIter = chunk.NewIterator4Chunk(task.innerResult) beginRow = task.innerIter.Begin() @@ -715,6 +715,9 @@ func (imw *innerMergeWorker) fetchNextInnerResult(ctx context.Context, task *loo // Close implements the Executor interface. func (e *IndexLookUpMergeJoin) Close() error { + if e.runtimeStats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.runtimeStats) + } if e.cancelFunc != nil { e.cancelFunc() e.cancelFunc = nil diff --git a/executor/index_merge_reader.go b/executor/index_merge_reader.go index bc29199a2c2b7..8dc359fa37163 100644 --- a/executor/index_merge_reader.go +++ b/executor/index_merge_reader.go @@ -94,8 +94,8 @@ type IndexMergeReaderExecutor struct { workerStarted bool keyRanges [][]kv.KeyRange - resultCh chan *lookupTableTask - resultCurr *lookupTableTask + resultCh chan *indexMergeTableTask + resultCurr *indexMergeTableTask feedbacks []*statistics.QueryFeedback // memTracker is used to track the memory usage of this executor. @@ -118,6 +118,16 @@ type IndexMergeReaderExecutor struct { isCorColInPartialFilters []bool isCorColInTableFilter bool isCorColInPartialAccess []bool + + // Whether it's intersection or union. + isIntersection bool +} + +type indexMergeTableTask struct { + lookupTableTask + + // parTblIdx are only used in indexMergeProcessWorker.fetchLoopIntersection. + parTblIdx int } // Table implements the dataSourceExecutor interface. @@ -129,7 +139,12 @@ func (e *IndexMergeReaderExecutor) Table() table.Table { func (e *IndexMergeReaderExecutor) Open(ctx context.Context) (err error) { e.keyRanges = make([][]kv.KeyRange, 0, len(e.partialPlans)) e.initRuntimeStats() - + if e.isCorColInTableFilter { + e.tableRequest.Executors, err = constructDistExec(e.ctx, e.tblPlans) + if err != nil { + return err + } + } if err = e.rebuildRangeForCorCol(); err != nil { return err } @@ -150,7 +165,7 @@ func (e *IndexMergeReaderExecutor) Open(ctx context.Context) (err error) { } } e.finished = make(chan struct{}) - e.resultCh = make(chan *lookupTableTask, atomic.LoadInt32(&LookupTableTaskChannelSize)) + e.resultCh = make(chan *indexMergeTableTask, atomic.LoadInt32(&LookupTableTaskChannelSize)) e.memTracker = memory.NewTracker(e.id, -1) e.memTracker.AttachTo(e.ctx.GetSessionVars().StmtCtx.MemTracker) return nil @@ -194,7 +209,7 @@ func (e *IndexMergeReaderExecutor) buildKeyRangesForTable(tbl table.Table) (rang if err != nil { return nil, err } - keyRanges := append(firstKeyRanges, secondKeyRanges...) + keyRanges := append(firstKeyRanges.FirstPartitionRange(), secondKeyRanges.FirstPartitionRange()...) ranges = append(ranges, keyRanges) continue } @@ -202,15 +217,15 @@ func (e *IndexMergeReaderExecutor) buildKeyRangesForTable(tbl table.Table) (rang if err != nil { return nil, err } - ranges = append(ranges, keyRange) + ranges = append(ranges, keyRange.FirstPartitionRange()) } return ranges, nil } func (e *IndexMergeReaderExecutor) startWorkers(ctx context.Context) error { exitCh := make(chan struct{}) - workCh := make(chan *lookupTableTask, 1) - fetchCh := make(chan *lookupTableTask, len(e.keyRanges)) + workCh := make(chan *indexMergeTableTask, 1) + fetchCh := make(chan *indexMergeTableTask, len(e.keyRanges)) e.startIndexMergeProcessWorker(ctx, workCh, fetchCh) @@ -237,12 +252,12 @@ func (e *IndexMergeReaderExecutor) startWorkers(ctx context.Context) error { return nil } -func (e *IndexMergeReaderExecutor) waitPartialWorkersAndCloseFetchChan(fetchCh chan *lookupTableTask) { +func (e *IndexMergeReaderExecutor) waitPartialWorkersAndCloseFetchChan(fetchCh chan *indexMergeTableTask) { e.idxWorkerWg.Wait() close(fetchCh) } -func (e *IndexMergeReaderExecutor) startIndexMergeProcessWorker(ctx context.Context, workCh chan<- *lookupTableTask, fetch <-chan *lookupTableTask) { +func (e *IndexMergeReaderExecutor) startIndexMergeProcessWorker(ctx context.Context, workCh chan<- *indexMergeTableTask, fetch <-chan *indexMergeTableTask) { idxMergeProcessWorker := &indexMergeProcessWorker{ indexMerge: e, stats: e.stats, @@ -252,15 +267,19 @@ func (e *IndexMergeReaderExecutor) startIndexMergeProcessWorker(ctx context.Cont defer trace.StartRegion(ctx, "IndexMergeProcessWorker").End() util.WithRecovery( func() { - idxMergeProcessWorker.fetchLoop(ctx, fetch, workCh, e.resultCh, e.finished) + if e.isIntersection { + idxMergeProcessWorker.fetchLoopIntersection(ctx, fetch, workCh, e.resultCh, e.finished) + } else { + idxMergeProcessWorker.fetchLoopUnion(ctx, fetch, workCh, e.resultCh, e.finished) + } }, - idxMergeProcessWorker.handleLoopFetcherPanic(ctx, e.resultCh), + idxMergeProcessWorker.handleLoopFetcherPanic(ctx, e.resultCh, "IndexMergeProcessWorker", nil), ) e.processWokerWg.Done() }() } -func (e *IndexMergeReaderExecutor) startPartialIndexWorker(ctx context.Context, exitCh <-chan struct{}, fetchCh chan<- *lookupTableTask, workID int) error { +func (e *IndexMergeReaderExecutor) startPartialIndexWorker(ctx context.Context, exitCh <-chan struct{}, fetchCh chan<- *indexMergeTableTask, workID int) error { if e.runtimeStats != nil { collExec := true e.dagPBs[workID].CollectExecutionSummaries = &collExec @@ -297,7 +316,7 @@ func (e *IndexMergeReaderExecutor) startPartialIndexWorker(ctx context.Context, // We got correlated column, so need to refresh Selection operator. var err error if e.dagPBs[workID].Executors, err = constructDistExec(e.ctx, e.partialPlans[workID]); err != nil { - worker.syncErr(e.resultCh, err) + syncErr(e.resultCh, err) return } } @@ -331,12 +350,12 @@ func (e *IndexMergeReaderExecutor) startPartialIndexWorker(ctx context.Context, }) kvReq, err := builder.SetKeyRanges(keyRange).Build() if err != nil { - worker.syncErr(e.resultCh, err) + syncErr(e.resultCh, err) return } result, err := distsql.SelectWithRuntimeStats(ctx, e.ctx, kvReq, e.handleCols.GetFieldsTypes(), e.feedbacks[workID], getPhysicalPlanIDs(e.partialPlans[workID]), e.getPartitalPlanID(workID)) if err != nil { - worker.syncErr(e.resultCh, err) + syncErr(e.resultCh, err) return } worker.batchSize = e.maxChunkSize @@ -349,7 +368,7 @@ func (e *IndexMergeReaderExecutor) startPartialIndexWorker(ctx context.Context, // fetch all data from this partition ctx1, cancel := context.WithCancel(ctx) - _, fetchErr := worker.fetchHandles(ctx1, result, exitCh, fetchCh, e.resultCh, e.finished, e.handleCols) + _, fetchErr := worker.fetchHandles(ctx1, result, exitCh, fetchCh, e.resultCh, e.finished, e.handleCols, parTblIdx) if fetchErr != nil { // this error is synced in fetchHandles(), don't sync it again e.feedbacks[workID].Invalidate() } @@ -370,7 +389,7 @@ func (e *IndexMergeReaderExecutor) startPartialIndexWorker(ctx context.Context, return nil } -func (e *IndexMergeReaderExecutor) startPartialTableWorker(ctx context.Context, exitCh <-chan struct{}, fetchCh chan<- *lookupTableTask, workID int) error { +func (e *IndexMergeReaderExecutor) startPartialTableWorker(ctx context.Context, exitCh <-chan struct{}, fetchCh chan<- *indexMergeTableTask, workID int) error { ts := e.partialPlans[workID][0].(*plannercore.PhysicalTableScan) tbls := make([]table.Table, 0, 1) @@ -412,13 +431,13 @@ func (e *IndexMergeReaderExecutor) startPartialTableWorker(ctx context.Context, if e.isCorColInPartialFilters[workID] { if e.dagPBs[workID].Executors, err = constructDistExec(e.ctx, e.partialPlans[workID]); err != nil { - worker.syncErr(e.resultCh, err) + syncErr(e.resultCh, err) return } partialTableReader.dagPB = e.dagPBs[workID] } - for _, tbl := range tbls { + for parTblIdx, tbl := range tbls { // check if this executor is closed select { case <-e.finished: @@ -430,7 +449,7 @@ func (e *IndexMergeReaderExecutor) startPartialTableWorker(ctx context.Context, partialTableReader.table = tbl if err = partialTableReader.Open(ctx); err != nil { logutil.Logger(ctx).Error("open Select result failed:", zap.Error(err)) - worker.syncErr(e.resultCh, err) + syncErr(e.resultCh, err) break } worker.batchSize = e.maxChunkSize @@ -443,7 +462,7 @@ func (e *IndexMergeReaderExecutor) startPartialTableWorker(ctx context.Context, // fetch all handles from this table ctx1, cancel := context.WithCancel(ctx) - _, fetchErr := worker.fetchHandles(ctx1, exitCh, fetchCh, e.resultCh, e.finished, e.handleCols) + _, fetchErr := worker.fetchHandles(ctx1, exitCh, fetchCh, e.resultCh, e.finished, e.handleCols, parTblIdx) if fetchErr != nil { // this error is synced in fetchHandles, so don't sync it again e.feedbacks[workID].Invalidate() } @@ -470,7 +489,6 @@ func (e *IndexMergeReaderExecutor) initRuntimeStats() { e.stats = &IndexMergeRuntimeStat{ Concurrency: e.ctx.GetSessionVars().IndexLookupConcurrency(), } - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } } @@ -498,17 +516,9 @@ type partialTableWorker struct { partition table.PhysicalTable // it indicates if this worker is accessing a particular partition table } -func (w *partialTableWorker) syncErr(resultCh chan<- *lookupTableTask, err error) { - doneCh := make(chan error, 1) - doneCh <- err - resultCh <- &lookupTableTask{ - doneCh: doneCh, - } -} - -func (w *partialTableWorker) fetchHandles(ctx context.Context, exitCh <-chan struct{}, fetchCh chan<- *lookupTableTask, resultCh chan<- *lookupTableTask, - finished <-chan struct{}, handleCols plannercore.HandleCols) (count int64, err error) { - chk := chunk.NewChunkWithCapacity(retTypes(w.tableReader), w.maxChunkSize) +func (w *partialTableWorker) fetchHandles(ctx context.Context, exitCh <-chan struct{}, fetchCh chan<- *indexMergeTableTask, resultCh chan<- *indexMergeTableTask, + finished <-chan struct{}, handleCols plannercore.HandleCols, parTblIdx int) (count int64, err error) { + chk := w.sc.GetSessionVars().GetNewChunkWithCapacity(retTypes(w.tableReader), w.maxChunkSize, w.maxChunkSize, w.tableReader.base().AllocPool) var basic *execdetails.BasicRuntimeStats if be := w.tableReader.base(); be != nil && be.runtimeStats != nil { basic = be.runtimeStats @@ -517,14 +527,14 @@ func (w *partialTableWorker) fetchHandles(ctx context.Context, exitCh <-chan str start := time.Now() handles, retChunk, err := w.extractTaskHandles(ctx, chk, handleCols) if err != nil { - w.syncErr(resultCh, err) + syncErr(resultCh, err) return count, err } if len(handles) == 0 { return count, nil } count += int64(len(handles)) - task := w.buildTableTask(handles, retChunk) + task := w.buildTableTask(handles, retChunk, parTblIdx) if w.stats != nil { atomic.AddInt64(&w.stats.FetchIdxTime, int64(time.Since(start))) } @@ -570,19 +580,22 @@ func (w *partialTableWorker) extractTaskHandles(ctx context.Context, chk *chunk. return handles, retChk, nil } -func (w *partialTableWorker) buildTableTask(handles []kv.Handle, retChk *chunk.Chunk) *lookupTableTask { - task := &lookupTableTask{ - handles: handles, - idxRows: retChk, +func (w *partialTableWorker) buildTableTask(handles []kv.Handle, retChk *chunk.Chunk, parTblIdx int) *indexMergeTableTask { + task := &indexMergeTableTask{ + lookupTableTask: lookupTableTask{ + handles: handles, + idxRows: retChk, - partitionTable: w.partition, + partitionTable: w.partition, + }, + parTblIdx: parTblIdx, } task.doneCh = make(chan error, 1) return task } -func (e *IndexMergeReaderExecutor) startIndexMergeTableScanWorker(ctx context.Context, workCh <-chan *lookupTableTask) { +func (e *IndexMergeReaderExecutor) startIndexMergeTableScanWorker(ctx context.Context, workCh <-chan *indexMergeTableTask) { lookupConcurrencyLimit := e.ctx.GetSessionVars().IndexLookupConcurrency() e.tblWorkerWg.Add(lookupConcurrencyLimit) for i := 0; i < lookupConcurrencyLimit; i++ { @@ -597,7 +610,7 @@ func (e *IndexMergeReaderExecutor) startIndexMergeTableScanWorker(ctx context.Co ctx1, cancel := context.WithCancel(ctx) go func() { defer trace.StartRegion(ctx, "IndexMergeTableScanWorker").End() - var task *lookupTableTask + var task *indexMergeTableTask util.WithRecovery( func() { task = worker.pickAndExecTask(ctx1) }, worker.handlePickAndExecTaskPanic(ctx1, task), @@ -622,11 +635,6 @@ func (e *IndexMergeReaderExecutor) buildFinalTableReader(ctx context.Context, tb plans: e.tblPlans, netDataSize: e.dataAvgRowSize * float64(len(handles)), } - if e.isCorColInTableFilter { - if tableReaderExec.dagPB.Executors, err = constructDistExec(e.ctx, e.tblPlans); err != nil { - return nil, err - } - } tableReaderExec.buildVirtualColumnInfo() // Reorder handles because SplitKeyRangesByLocations() requires startKey of kvRanges is ordered. // Also it's good for performance. @@ -666,7 +674,7 @@ func (e *IndexMergeReaderExecutor) Next(ctx context.Context, req *chunk.Chunk) e } } -func (e *IndexMergeReaderExecutor) getResultTask() (*lookupTableTask, error) { +func (e *IndexMergeReaderExecutor) getResultTask() (*indexMergeTableTask, error) { if e.resultCurr != nil && e.resultCurr.cursor < len(e.resultCurr.rows) { return e.resultCurr, nil } @@ -686,7 +694,7 @@ func (e *IndexMergeReaderExecutor) getResultTask() (*lookupTableTask, error) { return e.resultCurr, nil } -func (e *IndexMergeReaderExecutor) handleHandlesFetcherPanic(ctx context.Context, resultCh chan<- *lookupTableTask, worker string) func(r interface{}) { +func (e *IndexMergeReaderExecutor) handleHandlesFetcherPanic(ctx context.Context, resultCh chan<- *indexMergeTableTask, worker string) func(r interface{}) { return func(r interface{}) { if r == nil { return @@ -696,14 +704,19 @@ func (e *IndexMergeReaderExecutor) handleHandlesFetcherPanic(ctx context.Context logutil.Logger(ctx).Error(err4Panic.Error()) doneCh := make(chan error, 1) doneCh <- err4Panic - resultCh <- &lookupTableTask{ - doneCh: doneCh, + resultCh <- &indexMergeTableTask{ + lookupTableTask: lookupTableTask{ + doneCh: doneCh, + }, } } } // Close implements Exec Close interface. func (e *IndexMergeReaderExecutor) Close() error { + if e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } if e.finished == nil { return nil } @@ -722,8 +735,8 @@ type indexMergeProcessWorker struct { stats *IndexMergeRuntimeStat } -func (w *indexMergeProcessWorker) fetchLoop(ctx context.Context, fetchCh <-chan *lookupTableTask, - workCh chan<- *lookupTableTask, resultCh chan<- *lookupTableTask, finished <-chan struct{}) { +func (w *indexMergeProcessWorker) fetchLoopUnion(ctx context.Context, fetchCh <-chan *indexMergeTableTask, + workCh chan<- *indexMergeTableTask, resultCh chan<- *indexMergeTableTask, finished <-chan struct{}) { defer func() { close(workCh) close(resultCh) @@ -755,11 +768,13 @@ func (w *indexMergeProcessWorker) fetchLoop(ctx context.Context, fetchCh <-chan if len(fhs) == 0 { continue } - task := &lookupTableTask{ - handles: fhs, - doneCh: make(chan error, 1), + task := &indexMergeTableTask{ + lookupTableTask: lookupTableTask{ + handles: fhs, + doneCh: make(chan error, 1), - partitionTable: task.partitionTable, + partitionTable: task.partitionTable, + }, } if w.stats != nil { w.stats.IndexMergeProcess += time.Since(start) @@ -775,18 +790,197 @@ func (w *indexMergeProcessWorker) fetchLoop(ctx context.Context, fetchCh <-chan } } -func (w *indexMergeProcessWorker) handleLoopFetcherPanic(ctx context.Context, resultCh chan<- *lookupTableTask) func(r interface{}) { +type intersectionProcessWorker struct { + // key: parTblIdx, val: HandleMap + // Value of MemAwareHandleMap is *int to avoid extra Get(). + handleMapsPerWorker map[int]*kv.MemAwareHandleMap[*int] + workerID int + workerCh chan *indexMergeTableTask + indexMerge *IndexMergeReaderExecutor + memTracker *memory.Tracker + batchSize int + + // When rowDelta == memConsumeBatchSize, Consume(memUsage) + rowDelta int64 + mapUsageDelta int64 +} + +func (w *intersectionProcessWorker) consumeMemDelta() { + w.memTracker.Consume(w.mapUsageDelta + w.rowDelta*int64(unsafe.Sizeof(int(0)))) + w.mapUsageDelta = 0 + w.rowDelta = 0 +} + +func (w *intersectionProcessWorker) doIntersectionPerPartition(ctx context.Context, workCh chan<- *indexMergeTableTask, resultCh chan<- *indexMergeTableTask, finished <-chan struct{}) { + defer w.memTracker.Detach() + + for task := range w.workerCh { + var ok bool + var hMap *kv.MemAwareHandleMap[*int] + if hMap, ok = w.handleMapsPerWorker[task.parTblIdx]; !ok { + hMap = kv.NewMemAwareHandleMap[*int]() + w.handleMapsPerWorker[task.parTblIdx] = hMap + } + var mapDelta int64 + var rowDelta int64 + for _, h := range task.handles { + // Use *int to avoid Get() again. + if cntPtr, ok := hMap.Get(h); ok { + (*cntPtr)++ + } else { + cnt := 1 + mapDelta += hMap.Set(h, &cnt) + int64(h.ExtraMemSize()) + rowDelta += 1 + } + } + + logutil.BgLogger().Debug("intersectionProcessWorker handle tasks", zap.Int("workerID", w.workerID), + zap.Int("task.handles", len(task.handles)), zap.Int64("rowDelta", rowDelta)) + + w.mapUsageDelta += mapDelta + w.rowDelta += rowDelta + if w.rowDelta >= int64(w.batchSize) { + w.consumeMemDelta() + } + failpoint.Inject("testIndexMergeIntersectionWorkerPanic", nil) + } + if w.rowDelta > 0 { + w.consumeMemDelta() + } + + // We assume the result of intersection is small, so no need to track memory. + intersectedMap := make(map[int][]kv.Handle, len(w.handleMapsPerWorker)) + for parTblIdx, hMap := range w.handleMapsPerWorker { + hMap.Range(func(h kv.Handle, val interface{}) bool { + if *(val.(*int)) == len(w.indexMerge.partialPlans) { + // Means all partial paths have this handle. + intersectedMap[parTblIdx] = append(intersectedMap[parTblIdx], h) + } + return true + }) + } + + tasks := make([]*indexMergeTableTask, 0, len(w.handleMapsPerWorker)) + for parTblIdx, intersected := range intersectedMap { + // Split intersected[parTblIdx] to avoid task is too large. + for len(intersected) > 0 { + length := w.batchSize + if length > len(intersected) { + length = len(intersected) + } + task := &indexMergeTableTask{ + lookupTableTask: lookupTableTask{ + handles: intersected[:length], + doneCh: make(chan error, 1), + }, + } + intersected = intersected[length:] + if w.indexMerge.partitionTableMode { + task.partitionTable = w.indexMerge.prunedPartitions[parTblIdx] + } + tasks = append(tasks, task) + logutil.BgLogger().Debug("intersectionProcessWorker build tasks", + zap.Int("parTblIdx", parTblIdx), zap.Int("task.handles", len(task.handles))) + } + } + for _, task := range tasks { + select { + case <-ctx.Done(): + return + case <-finished: + return + case workCh <- task: + resultCh <- task + } + } +} + +// For each partition(dynamic mode), a map is used to do intersection. Key of the map is handle, and value is the number of times it occurs. +// If the value of handle equals the number of partial paths, it should be sent to final_table_scan_worker. +// To avoid too many goroutines, each intersectionProcessWorker can handle multiple partitions. +func (w *indexMergeProcessWorker) fetchLoopIntersection(ctx context.Context, fetchCh <-chan *indexMergeTableTask, + workCh chan<- *indexMergeTableTask, resultCh chan<- *indexMergeTableTask, finished <-chan struct{}) { + defer func() { + close(workCh) + close(resultCh) + }() + + if w.stats != nil { + start := time.Now() + defer func() { + w.stats.IndexMergeProcess += time.Since(start) + }() + } + + // One goroutine may handle one or multiple partitions. + // Max number of partition number is 8192, we use ExecutorConcurrency to avoid too many goroutines. + maxWorkerCnt := w.indexMerge.ctx.GetSessionVars().IndexMergeIntersectionConcurrency() + maxChannelSize := atomic.LoadInt32(&LookupTableTaskChannelSize) + batchSize := w.indexMerge.ctx.GetSessionVars().IndexLookupSize + + partCnt := 1 + if w.indexMerge.partitionTableMode { + partCnt = len(w.indexMerge.prunedPartitions) + } + workerCnt := mathutil.Min(partCnt, maxWorkerCnt) + failpoint.Inject("testIndexMergeIntersectionConcurrency", func(val failpoint.Value) { + con := val.(int) + if con != workerCnt { + panic(fmt.Sprintf("unexpected workerCnt, expect %d, got %d", con, workerCnt)) + } + }) + + workers := make([]*intersectionProcessWorker, 0, workerCnt) + wg := util.WaitGroupWrapper{} + errCh := make(chan bool, workerCnt) + for i := 0; i < workerCnt; i++ { + tracker := memory.NewTracker(w.indexMerge.id, -1) + tracker.AttachTo(w.indexMerge.memTracker) + worker := &intersectionProcessWorker{ + workerID: i, + handleMapsPerWorker: make(map[int]*kv.MemAwareHandleMap[*int]), + workerCh: make(chan *indexMergeTableTask, maxChannelSize), + indexMerge: w.indexMerge, + memTracker: tracker, + batchSize: batchSize, + } + wg.RunWithRecover(func() { + defer trace.StartRegion(ctx, "IndexMergeIntersectionProcessWorker").End() + worker.doIntersectionPerPartition(ctx, workCh, resultCh, finished) + }, w.handleLoopFetcherPanic(ctx, resultCh, "IndexMergeIntersectionProcessWorker", errCh)) + workers = append(workers, worker) + } +loop: + for task := range fetchCh { + select { + case workers[task.parTblIdx%workerCnt].workerCh <- task: + case <-errCh: + break loop + } + } + for _, processWorker := range workers { + close(processWorker.workerCh) + } + wg.Wait() +} + +func (w *indexMergeProcessWorker) handleLoopFetcherPanic(ctx context.Context, resultCh chan<- *indexMergeTableTask, worker string, extraCh chan bool) func(r interface{}) { return func(r interface{}) { if r == nil { return } + if extraCh != nil { + extraCh <- true + } - err4Panic := errors.Errorf("panic in IndexMergeReaderExecutor indexMergeTableWorker: %v", r) + err4Panic := errors.Errorf("panic in IndexMergeReaderExecutor %s: %v", worker, r) logutil.Logger(ctx).Error(err4Panic.Error()) doneCh := make(chan error, 1) doneCh <- err4Panic - resultCh <- &lookupTableTask{ - doneCh: doneCh, + resultCh <- &indexMergeTableTask{ + lookupTableTask: lookupTableTask{ + doneCh: doneCh, + }, } } } @@ -801,11 +995,13 @@ type partialIndexWorker struct { partition table.PhysicalTable // it indicates if this worker is accessing a particular partition table } -func (w *partialIndexWorker) syncErr(resultCh chan<- *lookupTableTask, err error) { +func syncErr(resultCh chan<- *indexMergeTableTask, err error) { doneCh := make(chan error, 1) doneCh <- err - resultCh <- &lookupTableTask{ - doneCh: doneCh, + resultCh <- &indexMergeTableTask{ + lookupTableTask: lookupTableTask{ + doneCh: doneCh, + }, } } @@ -813,23 +1009,23 @@ func (w *partialIndexWorker) fetchHandles( ctx context.Context, result distsql.SelectResult, exitCh <-chan struct{}, - fetchCh chan<- *lookupTableTask, - resultCh chan<- *lookupTableTask, + fetchCh chan<- *indexMergeTableTask, + resultCh chan<- *indexMergeTableTask, finished <-chan struct{}, - handleCols plannercore.HandleCols) (count int64, err error) { + handleCols plannercore.HandleCols, + parTblIdx int) (count int64, err error) { chk := chunk.NewChunkWithCapacity(handleCols.GetFieldsTypes(), w.maxChunkSize) var basicStats *execdetails.BasicRuntimeStats if w.stats != nil { if w.idxID != 0 { - basicStats = &execdetails.BasicRuntimeStats{} - w.sc.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(w.idxID, basicStats) + basicStats = w.sc.GetSessionVars().StmtCtx.RuntimeStatsColl.GetBasicRuntimeStats(w.idxID) } } for { start := time.Now() handles, retChunk, err := w.extractTaskHandles(ctx, chk, result, handleCols) if err != nil { - w.syncErr(resultCh, err) + syncErr(resultCh, err) return count, err } if len(handles) == 0 { @@ -839,7 +1035,7 @@ func (w *partialIndexWorker) fetchHandles( return count, nil } count += int64(len(handles)) - task := w.buildTableTask(handles, retChunk) + task := w.buildTableTask(handles, retChunk, parTblIdx) if w.stats != nil { atomic.AddInt64(&w.stats.FetchIdxTime, int64(time.Since(start))) } @@ -885,12 +1081,15 @@ func (w *partialIndexWorker) extractTaskHandles(ctx context.Context, chk *chunk. return handles, retChk, nil } -func (w *partialIndexWorker) buildTableTask(handles []kv.Handle, retChk *chunk.Chunk) *lookupTableTask { - task := &lookupTableTask{ - handles: handles, - idxRows: retChk, +func (w *partialIndexWorker) buildTableTask(handles []kv.Handle, retChk *chunk.Chunk, parTblIdx int) *indexMergeTableTask { + task := &indexMergeTableTask{ + lookupTableTask: lookupTableTask{ + handles: handles, + idxRows: retChk, - partitionTable: w.partition, + partitionTable: w.partition, + }, + parTblIdx: parTblIdx, } task.doneCh = make(chan error, 1) @@ -899,7 +1098,7 @@ func (w *partialIndexWorker) buildTableTask(handles []kv.Handle, retChk *chunk.C type indexMergeTableScanWorker struct { stats *IndexMergeRuntimeStat - workCh <-chan *lookupTableTask + workCh <-chan *indexMergeTableTask finished <-chan struct{} indexMergeExec *IndexMergeReaderExecutor tblPlans []plannercore.PhysicalPlan @@ -908,7 +1107,7 @@ type indexMergeTableScanWorker struct { memTracker *memory.Tracker } -func (w *indexMergeTableScanWorker) pickAndExecTask(ctx context.Context) (task *lookupTableTask) { +func (w *indexMergeTableScanWorker) pickAndExecTask(ctx context.Context) (task *indexMergeTableTask) { var ok bool for { waitStart := time.Now() @@ -931,7 +1130,7 @@ func (w *indexMergeTableScanWorker) pickAndExecTask(ctx context.Context) (task * } } -func (w *indexMergeTableScanWorker) handlePickAndExecTaskPanic(ctx context.Context, task *lookupTableTask) func(r interface{}) { +func (w *indexMergeTableScanWorker) handlePickAndExecTaskPanic(ctx context.Context, task *indexMergeTableTask) func(r interface{}) { return func(r interface{}) { if r == nil { return @@ -943,7 +1142,7 @@ func (w *indexMergeTableScanWorker) handlePickAndExecTaskPanic(ctx context.Conte } } -func (w *indexMergeTableScanWorker) executeTask(ctx context.Context, task *lookupTableTask) error { +func (w *indexMergeTableScanWorker) executeTask(ctx context.Context, task *indexMergeTableTask) error { tbl := w.indexMergeExec.table if w.indexMergeExec.partitionTableMode { tbl = task.partitionTable @@ -961,7 +1160,7 @@ func (w *indexMergeTableScanWorker) executeTask(ctx context.Context, task *looku handleCnt := len(task.handles) task.rows = make([]chunk.Row, 0, handleCnt) for { - chk := newFirstChunk(tableReader) + chk := tryNewCacheChunk(tableReader) err = Next(ctx, tableReader, chk) if err != nil { logutil.Logger(ctx).Error("table reader fetch next chunk failed", zap.Error(err)) diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 2e33eef27d12d..79d2d8b895a81 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -23,7 +23,9 @@ import ( "testing" "time" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/testkit/testutil" "github.com/pingcap/tidb/util" "github.com/stretchr/testify/require" ) @@ -86,7 +88,7 @@ func TestIndexMergeReaderIssue25045(t *testing.T) { tk.MustExec("create table t1(a int primary key, b int, c int, key(b), key(c));") tk.MustExec("INSERT INTO t1 VALUES (10, 10, 10), (11, 11, 11)") tk.MustQuery("explain format='brief' select /*+ use_index_merge(t1) */ * from t1 where c=10 or (b=10 and a=10);").Check(testkit.Rows( - "IndexMerge 0.01 root ", + "IndexMerge 0.01 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c(c) range:[10,10], keep order:false, stats:pseudo", "├─TableRangeScan(Build) 1.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo", "└─Selection(Probe) 0.01 cop[tikv] or(eq(test.t1.c, 10), and(eq(test.t1.b, 10), eq(test.t1.a, 10)))", @@ -230,44 +232,64 @@ func TestIndexMergeInTransaction(t *testing.T) { tk.MustExec("begin;") // Expect two IndexScan(c1, c2). tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows( - "IndexMerge_9 1841.86 root ", + "IndexMerge_9 1841.86 root type: union", "├─IndexRangeScan_5(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo", "├─IndexRangeScan_6(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", "└─Selection_8(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10)", " └─TableRowIDScan_7 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo")) // Expect one IndexScan(c2) and one TableScan(pk). tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10;").Check(testkit.Rows( - "IndexMerge_9 1106.67 root ", + "IndexMerge_9 1106.67 root type: union", "├─TableRangeScan_5(Build) 3333.33 cop[tikv] table:t1 range:[-inf,10), keep order:false, stats:pseudo", "├─IndexRangeScan_6(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", "└─Selection_8(Probe) 1106.67 cop[tikv] lt(test.t1.c3, 10)", " └─TableRowIDScan_7 3330.01 cop[tikv] table:t1 keep order:false, stats:pseudo")) + tk.MustQuery("explain select /*+ use_index_merge(t1, c1, c2, c3) */ * from t1 where c1 < 10 and c2 < 10 and c3 < 10;").Check(testkit.Rows( + "IndexMerge_9 367.05 root type: intersection", + "├─IndexRangeScan_5(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", + "├─IndexRangeScan_7(Build) 3323.33 cop[tikv] table:t1, index:c3(c3) range:[-inf,10), keep order:false, stats:pseudo", + "└─TableRowIDScan_8(Probe) 367.05 cop[tikv] table:t1 keep order:false, stats:pseudo")) // Test with normal key. tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c1, c2, c3) */ * from t1 where (c1 < 10 and c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c1, c2, c3) */ * from t1 where (c1 < -1 and c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustExec("insert into t1 values(1, 1, 1, 1);") tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1, c1, c2, c3) */ * from t1 where (c1 < 10 and c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1, c1, c2, c3) */ * from t1 where (c1 < 10 and c2 < 10) and c3 > 10;").Check(testkit.Rows()) + tk.MustExec("update t1 set c3 = 100 where c3 = 1;") tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c1, c2, c3) */ * from t1 where (c1 < 10 and c2 < 10) and c3 > 10;").Check(testkit.Rows("1 1 100 1")) + tk.MustExec("delete from t1;") tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c1, c2, c3) */ * from t1 where (c1 < 10 and c2 < 10) and c3 > 10;").Check(testkit.Rows()) // Test with primary key, so the partialPlan is TableScan. tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c2, c3, primary) */ * from t1 where (pk < -1 and c2 < 10) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c2, c3, primary) */ * from t1 where (pk < 10 and c2 < -1) and c3 < 10;").Check(testkit.Rows()) tk.MustExec("insert into t1 values(1, 1, 1, 1);") tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) + tk.MustQuery("select /*+ use_index_merge(t1, c2, c3, primary) */ * from t1 where (pk < 10 and c2 < 10) and c3 < 10;").Check(testkit.Rows("1 1 1 1")) tk.MustExec("update t1 set c3 = 100 where c3 = 1;") tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c2, c3, primary) */ * from t1 where (pk < 10 and c2 < 10) and c3 > 10;").Check(testkit.Rows("1 1 100 1")) tk.MustExec("delete from t1;") tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < -1 or c2 < 10) and c3 < 10;").Check(testkit.Rows()) tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < -1) and c3 < 10;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1, c2, c3, primary) */ * from t1 where (pk < 10 and c2 < 10) and c3 > 10;").Check(testkit.Rows()) tk.MustExec("commit;") if i == 1 { @@ -281,14 +303,14 @@ func TestIndexMergeInTransaction(t *testing.T) { tk.MustExec("begin;") tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 10 or c2 < 10) and c3 < 10 for update;").Check(testkit.Rows( "SelectLock_6 1841.86 root for update 0", - "└─IndexMerge_11 1841.86 root ", + "└─IndexMerge_11 1841.86 root type: union", " ├─IndexRangeScan_7(Build) 3323.33 cop[tikv] table:t1, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo", " ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", " └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c3, 10)", " └─TableRowIDScan_9 5542.21 cop[tikv] table:t1 keep order:false, stats:pseudo")) tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (pk < 10 or c2 < 10) and c3 < 10 for update;").Check(testkit.Rows( "SelectLock_6 1106.67 root for update 0", - "└─IndexMerge_11 1106.67 root ", + "└─IndexMerge_11 1106.67 root type: union", " ├─TableRangeScan_7(Build) 3333.33 cop[tikv] table:t1 range:[-inf,10), keep order:false, stats:pseudo", " ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", " └─Selection_10(Probe) 1106.67 cop[tikv] lt(test.t1.c3, 10)", @@ -403,7 +425,7 @@ func TestIndexMergeReaderInTransIssue30685(t *testing.T) { tk.MustExec("insert into t1 values(1, 1, 1, 1);") tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < -1 or c3 < 10) and c4 < 10;").Check(testkit.Rows( "UnionScan_6 1841.86 root lt(test.t1.c4, 10), or(lt(test.t1.c1, -1), lt(test.t1.c3, 10))", - "└─IndexMerge_11 1841.86 root ", + "└─IndexMerge_11 1841.86 root type: union", " ├─TableRangeScan_7(Build) 3323.33 cop[tikv] table:t1 range:[-inf,-1), keep order:false, stats:pseudo", " ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c3(c3) range:[-inf,10), keep order:false, stats:pseudo", " └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c4, 10)", @@ -422,7 +444,7 @@ func TestIndexMergeReaderInTransIssue30685(t *testing.T) { tk.MustExec("insert into t1 values('b', 1, 1, 1);") tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where (c1 < 'a' or c3 < 10) and c4 < 10;").Check(testkit.Rows( "UnionScan_6 1841.86 root lt(test.t1.c4, 10), or(lt(test.t1.c1, \"a\"), lt(test.t1.c3, 10))", - "└─IndexMerge_11 1841.86 root ", + "└─IndexMerge_11 1841.86 root type: union", " ├─TableRangeScan_7(Build) 3323.33 cop[tikv] table:t1 range:[-inf,\"a\"), keep order:false, stats:pseudo", " ├─IndexRangeScan_8(Build) 3323.33 cop[tikv] table:t1, index:c3(c3) range:[-inf,10), keep order:false, stats:pseudo", " └─Selection_10(Probe) 1841.86 cop[tikv] lt(test.t1.c4, 10)", @@ -446,17 +468,15 @@ func TestIndexMergeReaderMemTracker(t *testing.T) { insertStr += fmt.Sprintf(" ,(%d, %d, %d)", i, i, i) } insertStr += ";" - memTracker := tk.Session().GetSessionVars().StmtCtx.MemTracker + memTracker := tk.Session().GetSessionVars().MemTracker tk.MustExec(insertStr) - oriMaxUsage := memTracker.MaxConsumed() - // We select all rows in t1, so the mem usage is more clear. tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where c1 > 1 or c2 > 1") - newMaxUsage := memTracker.MaxConsumed() - require.Greater(t, newMaxUsage, oriMaxUsage) + memUsage := memTracker.MaxConsumed() + require.Greater(t, memUsage, int64(0)) res := tk.MustQuery("explain analyze select /*+ use_index_merge(t1) */ * from t1 where c1 > 1 or c2 > 1") require.Len(t, res.Rows(), 4) @@ -498,7 +518,7 @@ func TestPessimisticLockOnPartitionForIndexMerge(t *testing.T) { tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") - tk.MustExec(`create table t1 (c_datetime datetime, c1 int, c2 int, primary key (c_datetime), key(c1), key(c2)) + tk.MustExec(`create table t1 (c_datetime datetime, c1 int, c2 int, primary key (c_datetime) NONCLUSTERED, key(c1), key(c2)) partition by range (to_days(c_datetime)) ( partition p0 values less than (to_days('2020-02-01')), partition p1 values less than (to_days('2020-04-01')), @@ -526,19 +546,19 @@ func TestPessimisticLockOnPartitionForIndexMerge(t *testing.T) { " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t2, index:c_datetime(c_datetime) keep order:false", " └─PartitionUnion(Probe) 5545.21 root ", - " ├─IndexMerge 5542.21 root ", + " ├─IndexMerge 5542.21 root type: union", " │ ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t1, partition:p0, index:c1(c1) range:[-inf,10), keep order:false, stats:pseudo", " │ ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t1, partition:p0, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", " │ └─TableRowIDScan(Probe) 5542.21 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " ├─IndexMerge 1.00 root ", + " ├─IndexMerge 1.00 root type: union", " │ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:c1(c1) range:[-inf,10), keep order:false", " │ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:c2(c2) range:[-inf,10), keep order:false", " │ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p1 keep order:false", - " ├─IndexMerge 1.00 root ", + " ├─IndexMerge 1.00 root type: union", " │ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p2, index:c1(c1) range:[-inf,10), keep order:false", " │ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p2, index:c2(c2) range:[-inf,10), keep order:false", " │ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p2 keep order:false", - " └─IndexMerge 1.00 root ", + " └─IndexMerge 1.00 root type: union", " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p3, index:c1(c1) range:[-inf,10), keep order:false", " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p3, index:c2(c2) range:[-inf,10), keep order:false", " └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p3 keep order:false", @@ -568,3 +588,193 @@ func TestPessimisticLockOnPartitionForIndexMerge(t *testing.T) { // TODO: add support for index merge reader in dynamic tidb_partition_prune_mode } + +func TestIndexMergeIntersectionConcurrency(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(c1 int, c2 bigint, c3 bigint, primary key(c1), key(c2), key(c3)) partition by hash(c1) partitions 10;") + tk.MustExec("insert into t1 values(1, 1, 3000), (2, 1, 1)") + tk.MustExec("analyze table t1;") + tk.MustExec("set tidb_partition_prune_mode = 'dynamic'") + res := tk.MustQuery("explain select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Rows() + require.Contains(t, res[1][0], "IndexMerge") + + // Default is tidb_executor_concurrency. + res = tk.MustQuery("select @@tidb_executor_concurrency;").Sort().Rows() + defExecCon := res[0][0].(string) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", fmt.Sprintf("return(%s)", defExecCon))) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency")) + }() + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + + tk.MustExec("set tidb_executor_concurrency = 10") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(10)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + // workerCnt = min(part_num, concurrency) + tk.MustExec("set tidb_executor_concurrency = 20") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(10)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + tk.MustExec("set tidb_executor_concurrency = 2") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(2)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + + tk.MustExec("set tidb_index_merge_intersection_concurrency = 9") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(9)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + tk.MustExec("set tidb_index_merge_intersection_concurrency = 21") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(10)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + tk.MustExec("set tidb_index_merge_intersection_concurrency = 3") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(3)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + + // Concurrency only works for dynamic pruning partition table, so real concurrency is 1. + tk.MustExec("set tidb_partition_prune_mode = 'static'") + tk.MustExec("set tidb_index_merge_intersection_concurrency = 9") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(1)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) + + // Concurrency only works for dynamic pruning partition table. so real concurrency is 1. + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(c1 int, c2 bigint, c3 bigint, primary key(c1), key(c2), key(c3));") + tk.MustExec("insert into t1 values(1, 1, 3000), (2, 1, 1)") + tk.MustExec("set tidb_index_merge_intersection_concurrency = 9") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionConcurrency", "return(1)")) + tk.MustQuery("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Check(testkit.Rows("1")) +} + +func TestIntersectionWithDifferentConcurrency(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + var execCon []int + tblSchemas := []string{ + // partition table + "create table t1(c1 int, c2 bigint, c3 bigint, primary key(c1), key(c2), key(c3)) partition by hash(c1) partitions 10;", + // non-partition table + "create table t1(c1 int, c2 bigint, c3 bigint, primary key(c1), key(c2), key(c3));", + } + + for tblIdx, tblSchema := range tblSchemas { + if tblIdx == 0 { + // Test different intersectionProcessWorker with partition table(10 partitions). + execCon = []int{1, 3, 10, 11, 20} + } else { + // Default concurrency. + execCon = []int{5} + } + tk.MustExec("use test") + tk.MustExec("drop table if exists t1;") + tk.MustExec(tblSchema) + + const queryCnt int = 10 + const rowCnt int = 1000 + curRowCnt := 0 + insertStr := "insert into t1 values" + for i := 0; i < rowCnt; i++ { + if i != 0 { + insertStr += ", " + } + insertStr += fmt.Sprintf("(%d, %d, %d)", i, rand.Int(), rand.Int()) + curRowCnt++ + } + tk.MustExec(insertStr) + tk.MustExec("analyze table t1") + + for _, concurrency := range execCon { + tk.MustExec(fmt.Sprintf("set tidb_executor_concurrency = %d", concurrency)) + for i := 0; i < 2; i++ { + if i == 0 { + // Dynamic mode. + tk.MustExec("set tidb_partition_prune_mode = 'dynamic'") + res := tk.MustQuery("explain select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024") + require.Contains(t, res.Rows()[1][0], "IndexMerge") + } else { + tk.MustExec("set tidb_partition_prune_mode = 'static'") + res := tk.MustQuery("explain select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024") + if tblIdx == 0 { + // partition table + require.Contains(t, res.Rows()[1][0], "PartitionUnion") + require.Contains(t, res.Rows()[2][0], "IndexMerge") + } else { + require.Contains(t, res.Rows()[1][0], "IndexMerge") + } + } + for i := 0; i < queryCnt; i++ { + c3 := rand.Intn(1024) + res := tk.MustQuery(fmt.Sprintf("select /*+ no_index_merge() */ c1 from t1 where c2 < 1024 and c3 > %d", c3)).Sort().Rows() + tk.MustQuery(fmt.Sprintf("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > %d", c3)).Sort().Check(res) + } + + // In tranaction + for i := 0; i < queryCnt; i++ { + tk.MustExec("begin;") + r := rand.Intn(3) + if r == 0 { + tk.MustExec(fmt.Sprintf("update t1 set c3 = %d where c1 = %d", rand.Int(), rand.Intn(rowCnt))) + } else if r == 1 { + tk.MustExec(fmt.Sprintf("delete from t1 where c1 = %d", rand.Intn(rowCnt))) + } else if r == 2 { + tk.MustExec(fmt.Sprintf("insert into t1 values(%d, %d, %d)", curRowCnt, rand.Int(), rand.Int())) + curRowCnt++ + } + c3 := rand.Intn(1024) + res := tk.MustQuery(fmt.Sprintf("select /*+ no_index_merge() */ c1 from t1 where c2 < 1024 and c3 > %d", c3)).Sort().Rows() + tk.MustQuery(fmt.Sprintf("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > %d", c3)).Sort().Check(res) + tk.MustExec("commit;") + } + } + } + tk.MustExec("drop table t1") + } +} + +func TestIntersectionWorkerPanic(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(c1 int, c2 bigint, c3 bigint, primary key(c1), key(c2), key(c3)) partition by hash(c1) partitions 10;") + tk.MustExec("insert into t1 values(1, 1, 3000), (2, 1, 1)") + tk.MustExec("analyze table t1;") + tk.MustExec("set tidb_partition_prune_mode = 'dynamic'") + res := tk.MustQuery("explain select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024").Rows() + require.Contains(t, res[1][0], "IndexMerge") + + // Test panic in intersection. + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionWorkerPanic", "panic")) + err := tk.QueryToErr("select /*+ use_index_merge(t1, primary, c2, c3) */ c1 from t1 where c2 < 1024 and c3 > 1024") + require.Contains(t, err.Error(), "IndexMergeReaderExecutor") + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/testIndexMergeIntersectionWorkerPanic")) +} + +func TestIntersectionMemQuota(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(pk varchar(100) primary key, c1 int, c2 int, index idx1(c1), index idx2(c2))") + + insertStr := "insert into t1 values" + for i := 0; i < 20; i++ { + if i != 0 { + insertStr += ", " + } + insertStr += fmt.Sprintf("('%s', %d, %d)", testutil.RandStringRunes(100), 1, 1) + } + tk.MustExec(insertStr) + res := tk.MustQuery("explain select /*+ use_index_merge(t1, primary, idx1, idx2) */ c1 from t1 where c1 < 1024 and c2 < 1024").Rows() + require.Contains(t, res[1][0], "IndexMerge") + + tk.MustExec("set global tidb_mem_oom_action='CANCEL'") + defer tk.MustExec("set global tidb_mem_oom_action = DEFAULT") + tk.MustExec("set @@tidb_mem_quota_query = 4000") + err := tk.QueryToErr("select /*+ use_index_merge(t1, primary, idx1, idx2) */ c1 from t1 where c1 < 1024 and c2 < 1024") + require.Contains(t, err.Error(), "Out Of Memory Quota!") +} diff --git a/executor/infoschema_cluster_table_test.go b/executor/infoschema_cluster_table_test.go index 38fe23036e313..be2f04cb5c6ac 100644 --- a/executor/infoschema_cluster_table_test.go +++ b/executor/infoschema_cluster_table_test.go @@ -290,7 +290,7 @@ func TestTableStorageStats(t *testing.T) { "test 2", )) rows := tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'mysql';").Rows() - result := 37 + result := 45 require.Len(t, rows, result) // More tests about the privileges. diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go index 66ddbc2271afc..83e6f4e213e8b 100644 --- a/executor/infoschema_reader.go +++ b/executor/infoschema_reader.go @@ -62,9 +62,11 @@ import ( "github.com/pingcap/tidb/util/keydecoder" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" + "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/pdapi" "github.com/pingcap/tidb/util/resourcegrouptag" "github.com/pingcap/tidb/util/sem" + "github.com/pingcap/tidb/util/servermemorylimit" "github.com/pingcap/tidb/util/set" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/stmtsummary" @@ -148,7 +150,7 @@ func (e *memtableRetriever) retrieve(ctx context.Context, sctx sessionctx.Contex case infoschema.TableConstraints: e.setDataFromTableConstraints(sctx, dbs) case infoschema.TableSessionVar: - e.rows, err = infoschema.GetDataFromSessionVariables(sctx) + e.rows, err = infoschema.GetDataFromSessionVariables(ctx, sctx) case infoschema.TableTiDBServersInfo: err = e.setDataForServersInfo(sctx) case infoschema.TableTiFlashReplica: @@ -172,6 +174,18 @@ func (e *memtableRetriever) retrieve(ctx context.Context, sctx sessionctx.Contex err = e.setDataForClusterTrxSummary(sctx) case infoschema.TableVariablesInfo: err = e.setDataForVariablesInfo(sctx) + case infoschema.TableUserAttributes: + err = e.setDataForUserAttributes(ctx, sctx) + case infoschema.TableMemoryUsage: + err = e.setDataForMemoryUsage(sctx) + case infoschema.ClusterTableMemoryUsage: + err = e.setDataForClusterMemoryUsage(sctx) + case infoschema.TableMemoryUsageOpsHistory: + err = e.setDataForMemoryUsageOpsHistory(sctx) + case infoschema.ClusterTableMemoryUsageOpsHistory: + err = e.setDataForClusterMemoryUsageOpsHistory(sctx) + case infoschema.TableResourceGroups: + err = e.setDataFromResourceGroups(sctx) } if err != nil { return nil, err @@ -374,7 +388,7 @@ func getAutoIncrementID(ctx sessionctx.Context, schema *model.DBInfo, tblInfo *m if err != nil { return 0, err } - return tbl.Allocators(ctx).Get(autoid.RowIDAllocType).Base() + 1, nil + return tbl.Allocators(ctx).Get(autoid.AutoIncrementType).Base() + 1, nil } func hasPriv(ctx sessionctx.Context, priv mysql.PrivilegeType) bool { @@ -402,7 +416,7 @@ func (e *memtableRetriever) setDataForVariablesInfo(ctx sessionctx.Context) erro if infoschema.SysVarHiddenForSem(ctx, sv.Name) { continue } - currentVal, err := ctx.GetSessionVars().GetSessionOrGlobalSystemVar(sv.Name) + currentVal, err := ctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), sv.Name) if err != nil { currentVal = "" } @@ -435,6 +449,35 @@ func (e *memtableRetriever) setDataForVariablesInfo(ctx sessionctx.Context) erro return nil } +func (e *memtableRetriever) setDataForUserAttributes(ctx context.Context, sctx sessionctx.Context) error { + exec, _ := sctx.(sqlexec.RestrictedSQLExecutor) + chunkRows, _, err := exec.ExecRestrictedSQL(ctx, nil, `SELECT user, host, JSON_UNQUOTE(JSON_EXTRACT(user_attributes, '$.metadata')) FROM mysql.user`) + if err != nil { + return err + } + if len(chunkRows) == 0 { + return nil + } + rows := make([][]types.Datum, 0, len(chunkRows)) + for _, chunkRow := range chunkRows { + if chunkRow.Len() != 3 { + continue + } + user := chunkRow.GetString(0) + host := chunkRow.GetString(1) + // Compatible with results in MySQL + var attribute any + if attribute = chunkRow.GetString(2); attribute == "" { + attribute = nil + } + row := types.MakeDatums(user, host, attribute) + rows = append(rows, row) + } + + e.rows = rows + return nil +} + func (e *memtableRetriever) setDataFromSchemata(ctx sessionctx.Context, schemas []*model.DBInfo) { checker := privilege.GetPrivilegeManager(ctx) rows := make([][]types.Datum, 0, len(schemas)) @@ -794,7 +837,7 @@ func (e *hugeMemTableRetriever) dataForColumnsInTable(ctx context.Context, sctx if err := runWithSystemSession(internalCtx, sctx, func(s sessionctx.Context) error { planBuilder, _ := plannercore.NewPlanBuilder().Init(s, is, &hint.BlockHintProcessor{}) var err error - viewLogicalPlan, err = planBuilder.BuildDataSourceFromView(ctx, schema.Name, tbl) + viewLogicalPlan, err = planBuilder.BuildDataSourceFromView(ctx, schema.Name, tbl, nil, nil) return errors.Trace(err) }); err != nil { sctx.GetSessionVars().StmtCtx.AppendWarning(err) @@ -1636,11 +1679,11 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ } } for _, fk := range table.ForeignKeys { - fkRefCol := "" - if len(fk.RefCols) > 0 { - fkRefCol = fk.RefCols[0].O - } for i, key := range fk.Cols { + fkRefCol := "" + if len(fk.RefCols) > i { + fkRefCol = fk.RefCols[i].O + } col := nameToCol[key.L] record := types.MakeDatums( infoschema.CatalogVal, // CONSTRAINT_CATALOG @@ -1662,8 +1705,10 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ return rows } -func (e *memtableRetriever) setDataForTiKVRegionStatus(ctx sessionctx.Context) (err error) { - tikvStore, ok := ctx.GetStore().(helper.Storage) +func (e *memtableRetriever) setDataForTiKVRegionStatus(sctx sessionctx.Context) (err error) { + checker := privilege.GetPrivilegeManager(sctx) + var extractorTableIDs []int64 + tikvStore, ok := sctx.GetStore().(helper.Storage) if !ok { return errors.New("Information about TiKV region status can be gotten only when the storage is TiKV") } @@ -1673,13 +1718,17 @@ func (e *memtableRetriever) setDataForTiKVRegionStatus(ctx sessionctx.Context) ( } requestByTableRange := false allRegionsInfo := helper.NewRegionsInfo() - is := ctx.GetDomainInfoSchema().(infoschema.InfoSchema) + is := sctx.GetDomainInfoSchema().(infoschema.InfoSchema) if e.extractor != nil { extractor, ok := e.extractor.(*plannercore.TiKVRegionStatusExtractor) if ok && len(extractor.GetTablesID()) > 0 { - for _, tableID := range extractor.GetTablesID() { + extractorTableIDs = extractor.GetTablesID() + for _, tableID := range extractorTableIDs { regionsInfo, err := e.getRegionsInfoForTable(tikvHelper, is, tableID) if err != nil { + if errors.ErrorEqual(err, infoschema.ErrTableExists) { + continue + } return err } allRegionsInfo = allRegionsInfo.Merge(regionsInfo) @@ -1695,12 +1744,20 @@ func (e *memtableRetriever) setDataForTiKVRegionStatus(ctx sessionctx.Context) ( } tableInfos := tikvHelper.GetRegionsTableInfo(allRegionsInfo, is.AllSchemas()) for i := range allRegionsInfo.Regions { - tableList := tableInfos[allRegionsInfo.Regions[i].ID] - if len(tableList) == 0 { + regionTableList := tableInfos[allRegionsInfo.Regions[i].ID] + if len(regionTableList) == 0 { e.setNewTiKVRegionStatusCol(&allRegionsInfo.Regions[i], nil) } - for j := range tableList { - e.setNewTiKVRegionStatusCol(&allRegionsInfo.Regions[i], &tableList[j]) + for j, regionTable := range regionTableList { + if checker != nil && !checker.RequestVerification(sctx.GetSessionVars().ActiveRoles, regionTable.DB.Name.L, regionTable.Table.Name.L, "", mysql.AllPrivMask) { + continue + } + if len(extractorTableIDs) == 0 { + e.setNewTiKVRegionStatusCol(&allRegionsInfo.Regions[i], ®ionTable) + } + if slices.Contains(extractorTableIDs, regionTableList[j].Table.ID) { + e.setNewTiKVRegionStatusCol(&allRegionsInfo.Regions[i], ®ionTable) + } } } return nil @@ -2208,10 +2265,7 @@ func (e *memtableRetriever) setDataFromSequences(ctx sessionctx.Context, schemas // dataForTableTiFlashReplica constructs data for table tiflash replica info. func (e *memtableRetriever) dataForTableTiFlashReplica(ctx sessionctx.Context, schemas []*model.DBInfo) { var rows [][]types.Datum - progressMap, err := infosync.GetTiFlashTableSyncProgress(context.Background()) - if err != nil { - ctx.GetSessionVars().StmtCtx.AppendWarning(err) - } + var tiFlashStores map[int64]helper.StoreStat for _, schema := range schemas { for _, tbl := range schema.Tables { if tbl.TiFlashReplica == nil { @@ -2220,14 +2274,22 @@ func (e *memtableRetriever) dataForTableTiFlashReplica(ctx sessionctx.Context, s var progress float64 if pi := tbl.GetPartitionInfo(); pi != nil && len(pi.Definitions) > 0 { for _, p := range pi.Definitions { - progress += progressMap[p.ID] + progressOfPartition, err := infosync.MustGetTiFlashProgress(p.ID, tbl.TiFlashReplica.Count, &tiFlashStores) + if err != nil { + logutil.BgLogger().Error("dataForTableTiFlashReplica error", zap.Int64("tableID", tbl.ID), zap.Int64("partitionID", p.ID), zap.Error(err)) + } + progress += progressOfPartition } progress = progress / float64(len(pi.Definitions)) - progressString := types.TruncateFloatToString(progress, 2) - progress, _ = strconv.ParseFloat(progressString, 64) } else { - progress = progressMap[tbl.ID] + var err error + progress, err = infosync.MustGetTiFlashProgress(tbl.ID, tbl.TiFlashReplica.Count, &tiFlashStores) + if err != nil { + logutil.BgLogger().Error("dataForTableTiFlashReplica error", zap.Int64("tableID", tbl.ID), zap.Error(err)) + } } + progressString := types.TruncateFloatToString(progress, 2) + progress, _ = strconv.ParseFloat(progressString, 64) record := types.MakeDatums( schema.Name.O, // TABLE_SCHEMA tbl.Name.O, // TABLE_NAME @@ -2353,6 +2415,66 @@ func (e *memtableRetriever) setDataForClusterTrxSummary(ctx sessionctx.Context) return nil } +func (e *memtableRetriever) setDataForMemoryUsage(ctx sessionctx.Context) error { + r := memory.ReadMemStats() + currentOps, sessionKillLastDatum := types.NewDatum(nil), types.NewDatum(nil) + if memory.TriggerMemoryLimitGC.Load() || servermemorylimit.IsKilling.Load() { + currentOps.SetString("shrink", mysql.DefaultCollationName) + } + sessionKillLast := servermemorylimit.SessionKillLast.Load() + if !sessionKillLast.IsZero() { + sessionKillLastDatum.SetMysqlTime(types.NewTime(types.FromGoTime(sessionKillLast), mysql.TypeDatetime, 0)) + } + gcLast := types.NewTime(types.FromGoTime(memory.MemoryLimitGCLast.Load()), mysql.TypeDatetime, 0) + + row := []types.Datum{ + types.NewIntDatum(int64(memory.GetMemTotalIgnoreErr())), // MEMORY_TOTAL + types.NewIntDatum(int64(memory.ServerMemoryLimit.Load())), // MEMORY_LIMIT + types.NewIntDatum(int64(r.HeapInuse)), // MEMORY_CURRENT + types.NewIntDatum(int64(servermemorylimit.MemoryMaxUsed.Load())), // MEMORY_MAX_USED + currentOps, // CURRENT_OPS + sessionKillLastDatum, // SESSION_KILL_LAST + types.NewIntDatum(servermemorylimit.SessionKillTotal.Load()), // SESSION_KILL_TOTAL + types.NewTimeDatum(gcLast), // GC_LAST + types.NewIntDatum(memory.MemoryLimitGCTotal.Load()), // GC_TOTAL + types.NewDatum(GlobalDiskUsageTracker.BytesConsumed()), // DISK_USAGE + types.NewDatum(memory.QueryForceDisk.Load()), // QUERY_FORCE_DISK + } + e.rows = append(e.rows, row) + return nil +} + +func (e *memtableRetriever) setDataForClusterMemoryUsage(ctx sessionctx.Context) error { + err := e.setDataForMemoryUsage(ctx) + if err != nil { + return err + } + rows, err := infoschema.AppendHostInfoToRows(ctx, e.rows) + if err != nil { + return err + } + e.rows = rows + return nil +} + +func (e *memtableRetriever) setDataForMemoryUsageOpsHistory(ctx sessionctx.Context) error { + e.rows = servermemorylimit.GlobalMemoryOpsHistoryManager.GetRows() + return nil +} + +func (e *memtableRetriever) setDataForClusterMemoryUsageOpsHistory(ctx sessionctx.Context) error { + err := e.setDataForMemoryUsageOpsHistory(ctx) + if err != nil { + return err + } + rows, err := infoschema.AppendHostInfoToRows(ctx, e.rows) + if err != nil { + return err + } + e.rows = rows + return nil +} + type stmtSummaryTableRetriever struct { dummyCloser table *model.TableInfo @@ -2487,7 +2609,17 @@ func (e *tidbTrxTableRetriever) retrieve(ctx context.Context, sctx sessionctx.Co row = append(row, types.NewDatum(nil)) } } else { - row = append(row, e.txnInfo[i].ToDatum(c.Name.O)) + switch c.Name.O { + case txninfo.MemBufferBytesStr: + memDBFootprint := sctx.GetSessionVars().MemDBFootprint + var bytesConsumed int64 + if memDBFootprint != nil { + bytesConsumed = memDBFootprint.BytesConsumed() + } + row = append(row, types.NewDatum(bytesConsumed)) + default: + row = append(row, e.txnInfo[i].ToDatum(c.Name.O)) + } } } res = append(res, row) @@ -3256,6 +3388,23 @@ func (e *memtableRetriever) setDataFromPlacementPolicies(sctx sessionctx.Context return nil } +func (e *memtableRetriever) setDataFromResourceGroups(sctx sessionctx.Context) error { + is := sessiontxn.GetTxnManager(sctx).GetTxnInfoSchema() + resourceGroups := is.AllResourceGroups() + rows := make([][]types.Datum, 0, len(resourceGroups)) + for _, group := range resourceGroups { + row := types.MakeDatums( + group.ID, + group.Name.O, + group.RRURate, + group.WRURate, + ) + rows = append(rows, row) + } + e.rows = rows + return nil +} + func checkRule(rule *label.Rule) (dbName, tableName string, partitionName string, err error) { s := strings.Split(rule.ID, "/") if len(s) < 3 { diff --git a/executor/infoschema_reader_test.go b/executor/infoschema_reader_test.go index e8b776731bf2a..79c2b418e18d2 100644 --- a/executor/infoschema_reader_test.go +++ b/executor/infoschema_reader_test.go @@ -24,11 +24,9 @@ import ( "github.com/jarcoal/httpmock" "github.com/pingcap/failpoint" - "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/parser/auth" - "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics/handle" @@ -153,7 +151,7 @@ func TestColumnsTables(t *testing.T) { tk.MustExec("drop table if exists t") tk.MustExec("create table t (bit bit(10) DEFAULT b'100')") tk.MustQuery("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't'").Check(testkit.Rows( - "def test t bit 1 b'100' YES bit 10 0 bit(10) unsigned select,insert,update,references ")) + "def test t bit 1 b'100' YES bit 10 0 bit(10) select,insert,update,references ")) tk.MustExec("drop table if exists t") tk.MustExec("set time_zone='+08:00'") @@ -167,6 +165,11 @@ func TestColumnsTables(t *testing.T) { tk.MustExec("drop table if exists t") tk.MustExec("create table t (a bit DEFAULT (rand()))") tk.MustQuery("select column_default from information_schema.columns where TABLE_NAME='t' and TABLE_SCHEMA='test';").Check(testkit.Rows("rand()")) + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE t (`COL3` bit(1) NOT NULL,b year) ;") + tk.MustQuery("select column_type from information_schema.columns where TABLE_SCHEMA = 'test' and TABLE_NAME = 't';"). + Check(testkit.Rows("bit(1)", "year(4)")) } func TestEngines(t *testing.T) { @@ -251,7 +254,7 @@ func TestDDLJobs(t *testing.T) { tk.MustExec("create table tt (a int);") tk.MustExec("alter table tt add index t(a), add column b int") tk.MustQuery("select db_name, table_name, job_type from information_schema.DDL_JOBS limit 3").Check( - testkit.Rows("test_ddl_jobs tt alter table multi-schema change", "test_ddl_jobs tt add index /* subjob */", "test_ddl_jobs tt add column /* subjob */")) + testkit.Rows("test_ddl_jobs tt alter table multi-schema change", "test_ddl_jobs tt add index /* subjob */ /* txn-merge */", "test_ddl_jobs tt add column /* subjob */")) } func TestKeyColumnUsage(t *testing.T) { @@ -619,25 +622,6 @@ func TestForServersInfo(t *testing.T) { require.Equal(t, stringutil.BuildStringFromLabels(info.Labels), rows[0][8]) } -func TestForTableTiFlashReplica(t *testing.T) { - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/infoschema/mockTiFlashStoreCount", `return(true)`)) - defer func() { - require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/infoschema/mockTiFlashStoreCount")) - }() - - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (a int, b int, index idx(a))") - tk.MustExec("alter table t set tiflash replica 2 location labels 'a','b';") - tk.MustQuery("select TABLE_SCHEMA,TABLE_NAME,REPLICA_COUNT,LOCATION_LABELS,AVAILABLE,PROGRESS from information_schema.tiflash_replica").Check(testkit.Rows("test t 2 a,b 0 0")) - tbl, err := domain.GetDomain(tk.Session()).InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) - require.NoError(t, err) - tbl.Meta().TiFlashReplica.Available = true - tk.MustQuery("select TABLE_SCHEMA,TABLE_NAME,REPLICA_COUNT,LOCATION_LABELS,AVAILABLE,PROGRESS from information_schema.tiflash_replica").Check(testkit.Rows("test t 2 a,b 1 0")) -} - func TestSequences(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -693,9 +677,9 @@ func TestTiFlashSystemTableWithTiFlashV620(t *testing.T) { tk.MustQuery("show warnings").Check(testkit.Rows()) tk.MustQuery("select * from information_schema.TIFLASH_TABLES;").Check(testkit.Rows( - "db_1 t_10 mysql tables_priv 10 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 127.0.0.1:3933", - "db_1 t_8 mysql db 8 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 127.0.0.1:3933", - "db_2 t_70 test segment 70 0 1 102000 169873868 0 0 0 0 0 102000 169873868 0 0 0 1 102000 169873868 43867622 102000 169873868 0 13 13 7846.153846153846 13067220.615384616 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_1 t_10 mysql tables_priv 10 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 127.0.0.1:3933", + "db_1 t_8 mysql db 8 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 127.0.0.1:3933", + "db_2 t_70 test segment 70 0 1 102000 169873868 0 0 0 0 0 102000 169873868 0 0 0 1 102000 169873868 43867622 102000 169873868 0 13 13 7846.153846153846 13067220.615384616 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", )) tk.MustQuery("show warnings").Check(testkit.Rows()) } @@ -744,6 +728,50 @@ func TestTiFlashSystemTableWithTiFlashV630(t *testing.T) { tk.MustQuery("show warnings").Check(testkit.Rows()) } +func TestTiFlashSystemTableWithTiFlashV640(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + instances := []string{ + "tiflash,127.0.0.1:3933,127.0.0.1:7777,,", + "tikv,127.0.0.1:11080,127.0.0.1:10080,,", + } + fpName := "github.com/pingcap/tidb/infoschema/mockStoreServerInfo" + fpExpr := `return("` + strings.Join(instances, ";") + `")` + require.NoError(t, failpoint.Enable(fpName, fpExpr)) + defer func() { require.NoError(t, failpoint.Disable(fpName)) }() + + httpmock.RegisterResponder("GET", "http://127.0.0.1:7777/config", + httpmock.NewStringResponder(200, ` +{ + "raftstore-proxy": {}, + "engine-store":{ + "http_port":8123, + "tcp_port":9000 + } +} + `)) + + data, err := os.ReadFile("testdata/tiflash_v640_dt_tables.json") + require.NoError(t, err) + httpmock.RegisterResponder("GET", "http://127.0.0.1:8123?default_format=JSONCompact&query=SELECT+%2A+FROM+system.dt_tables+LIMIT+0%2C+1024", httpmock.NewBytesResponder(200, data)) + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustQuery("select * from information_schema.TIFLASH_TABLES;").Check(testkit.Rows( + "db_70 t_135 tpcc customer 135 0 4 3528714 2464079200 0 0.002329177144988231 1 0 929227 0.16169850346757514 0 8128 882178.5 616019800 4 8219 5747810 2054.75 1436952.5 0 4 3520495 2458331390 1601563417 880123.75 614582847.5 24 8 6 342.4583333333333 239492.08333333334 482 120.5 7303.9315352697095 5100272.593360996 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_137 tpcc district 137 0 1 7993 1346259 0 0.8748905292130614 1 0.8055198055198055 252168 0.21407121407121407 0 147272 7993 1346259 1 6993 1178050 6993 1178050 0 1 1000 168209 91344 1000 168209 6 6 6 1165.5 196341.66666666666 10 10 100 16820.9 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_139 tpcc history 139 0 19 19379697 1629276978 0 0.0006053758219233252 0.5789473684210527 0.4626662120695534 253640 0.25434708489601093 0 293544 1019984.052631579 85751419.89473684 11 11732 997220 1066.5454545454545 90656.36363636363 0 19 19367965 1628279758 625147717 1019366.5789473684 85698934.63157895 15 4 1.3636363636363635 782.1333333333333 66481.33333333333 2378 125.15789473684211 8144.644659377628 684726.559293524 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_141 tpcc item 141 0 1 100000 10799081 0 0 0 0 0 100000 10799081 0 0 0 1 100000 10799081 7357726 100000 10799081 0 0 13 13 7692.307692307692 830698.5384615385 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_143 tpcc new_order 143 0 4 2717707 78813503 0 0.02266763856442214 1 0.9678592299201351 52809 0.029559768846178818 0 1434208 679426.75 19703375.75 4 61604 1786516 15401 446629 0 3 2656103 77026987 40906492 885367.6666666666 25675662.333333332 37 24 9.25 1664.972972972973 48284.21621621621 380 126.66666666666667 6989.744736842105 202702.59736842106 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_145 tpcc order_line 145 0 203 210607202 20007684190 0 0.0054566462546708164 0.5862068965517241 0.7810067620424135 620065 0.005679558722564825 0 22607144 1037473.9014778325 98560020.64039409 119 1149209 109174855 9657.218487394957 917435.756302521 0 203 209457993 19898509335 8724002804 1031812.7733990147 98022213.47290641 893 39 7.504201680672269 1286.9081746920492 122256.27659574468 31507 155.20689655172413 6647.982765734599 631558.3627447869 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_147 tpcc orders 147 0 22 21903301 1270391458 0 0.02021357420052804 0.7272727272727273 0.9239944527763222 260536 0.010145817899282655 0 10025264 995604.5909090909 57745066.27272727 16 442744 25679152 27671.5 1604947 0 22 21460557 1244712306 452173775 975479.8636363636 56577832.09090909 242 34 15.125 1829.5206611570247 106112.19834710743 2973 135.13636363636363 7218.485368314833 418672.15136226034 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_149 tpcc stock 149 0 42 11112720 4811805131 0 0.028085203262567582 0.9761904761904762 0.8463391893060944 10227093 0.07567373591410528 0 6719064 264588.5714285714 114566788.83333333 41 312103 135131097 7612.268292682927 3295880.4146341463 0 42 10800617 4676674034 3231872509 257157.54761904763 111349381.76190476 238 26 5.804878048780488 1311.357142857143 567777.718487395 1644 39.142857142857146 6569.718369829684 2844692.234793187 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + "db_70 t_151 tpcc warehouse 151 0 1 5842 923615 0 0.9828825744608011 1 0.9669104841518634 70220 0.07732497387669801 0 133048 5842 923615 1 5742 907807 5742 907807 0 1 100 15808 11642 100 15808 5 5 5 1148.4 181561.4 5 5 20 3161.6 0 0 0 0 0 0 0 0 0 0 127.0.0.1:3933", + )) + tk.MustQuery("show warnings").Check(testkit.Rows()) +} + func TestTablesPKType(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/executor/insert.go b/executor/insert.go index 29c0231ed4c05..1a4eb27d3c6f6 100644 --- a/executor/insert.go +++ b/executor/insert.go @@ -22,11 +22,14 @@ import ( "time" "github.com/opentracing/opentracing-go" + "github.com/pingcap/errors" + "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" @@ -67,7 +70,6 @@ func (e *InsertExec) exec(ctx context.Context, rows [][]types.Datum) error { return err } setOptionForTopSQL(sessVars.StmtCtx, txn) - txnSize := txn.Size() sessVars.StmtCtx.AddRecordRows(uint64(len(rows))) // If you use the IGNORE keyword, duplicate-key error that occurs while executing the INSERT statement are ignored. // For example, without IGNORE, a row that duplicates an existing UNIQUE index or PRIMARY KEY value in @@ -110,7 +112,6 @@ func (e *InsertExec) exec(ctx context.Context, rows [][]types.Datum) error { e.stats.CheckInsertTime += time.Since(start) } } - e.memTracker.Consume(int64(txn.Size() - txnSize)) return nil } @@ -157,6 +158,12 @@ func prefetchConflictedOldRows(ctx context.Context, txn kv.Transaction, rows []t for _, r := range rows { for _, uk := range r.uniqueKeys { if val, found := values[string(uk.newKey)]; found { + if tablecodec.IsTempIndexKey(uk.newKey) { + if tablecodec.CheckTempIndexValueIsDelete(val) { + continue + } + val = tablecodec.DecodeTempIndexOriginValue(val) + } handle, err := tablecodec.DecodeHandleInUniqueIndexValue(val, uk.commonHandle) if err != nil { return err @@ -261,6 +268,14 @@ func (e *InsertExec) batchUpdateDupRows(ctx context.Context, newRows [][]types.D } return err } + // Since the temp index stores deleted key with marked 'deleteu' for unique key at the end + // of value, So if return a key we check and skip deleted key. + if tablecodec.IsTempIndexKey(uk.newKey) { + if tablecodec.CheckTempIndexValueIsDelete(val) { + continue + } + val = tablecodec.DecodeTempIndexOriginValue(val) + } handle, err := tablecodec.DecodeHandleInUniqueIndexValue(val, uk.commonHandle) if err != nil { return err @@ -310,14 +325,26 @@ func (e *InsertExec) Next(ctx context.Context, req *chunk.Chunk) error { if len(e.children) > 0 && e.children[0] != nil { return insertRowsFromSelect(ctx, e) } - return insertRows(ctx, e) + err := insertRows(ctx, e) + if err != nil { + terr, ok := errors.Cause(err).(*terror.Error) + if ok && len(e.OnDuplicate) == 0 && + e.ctx.GetSessionVars().StmtCtx.ErrAutoincReadFailedAsWarning && + terr.Code() == errno.ErrAutoincReadFailed { + e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) + return nil + } + return err + } + return nil } // Close implements the Executor Close interface. func (e *InsertExec) Close() error { + if e.runtimeStats != nil && e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } defer e.memTracker.ReplaceBytesUsed(0) - e.ctx.GetSessionVars().CurrInsertValues = chunk.Row{} - e.ctx.GetSessionVars().CurrInsertBatchExtraCols = e.ctx.GetSessionVars().CurrInsertBatchExtraCols[0:0:0] e.setMessage() if e.SelectExec != nil { return e.SelectExec.Close() @@ -420,7 +447,7 @@ func (e *InsertExec) doDupRowUpdate(ctx context.Context, handle kv.Handle, oldRo } newData := e.row4Update[:len(oldRow)] - _, err := updateRecord(ctx, e.ctx, handle, oldRow, newData, assignFlag, e.Table, true, e.memTracker, e.fkChecks) + _, err := updateRecord(ctx, e.ctx, handle, oldRow, newData, assignFlag, e.Table, true, e.memTracker, e.fkChecks, e.fkCascades) if err != nil { return err } @@ -453,3 +480,13 @@ func (e *InsertExec) setMessage() { func (e *InsertExec) GetFKChecks() []*FKCheckExec { return e.fkChecks } + +// GetFKCascades implements WithForeignKeyTrigger interface. +func (e *InsertExec) GetFKCascades() []*FKCascadeExec { + return e.fkCascades +} + +// HasFKCascades implements WithForeignKeyTrigger interface. +func (e *InsertExec) HasFKCascades() bool { + return len(e.fkCascades) > 0 +} diff --git a/executor/insert_common.go b/executor/insert_common.go index d708a59770fdd..21b78b878028b 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -32,6 +32,7 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" @@ -98,7 +99,8 @@ type InsertValues struct { isLoadData bool txnInUse sync.Mutex // fkChecks contains the foreign key checkers. - fkChecks []*FKCheckExec + fkChecks []*FKCheckExec + fkCascades []*FKCascadeExec } type defaultVal struct { @@ -387,7 +389,7 @@ func (e *InsertValues) evalRow(ctx context.Context, list []expression.Expression e.evalBuffer.SetDatum(offset, val1) } // Row may lack of generated column, autoIncrement column, empty column here. - return e.fillRow(ctx, row, hasValue) + return e.fillRow(ctx, row, hasValue, rowIdx) } var emptyRow chunk.Row @@ -421,7 +423,7 @@ func (e *InsertValues) fastEvalRow(ctx context.Context, list []expression.Expres offset := e.insertColumns[i].Offset row[offset], hasValue[offset] = val1, true } - return e.fillRow(ctx, row, hasValue) + return e.fillRow(ctx, row, hasValue, rowIdx) } // setValueForRefColumn set some default values for the row to eval the row value with other columns, @@ -459,7 +461,7 @@ func insertRowsFromSelect(ctx context.Context, base insertCommon) error { e := base.insertCommon() selectExec := e.children[0] fields := retTypes(selectExec) - chk := newFirstChunk(selectExec) + chk := tryNewCacheChunk(selectExec) iter := chunk.NewIterator4Chunk(chk) rows := make([][]types.Datum, 0, chk.Capacity()) @@ -536,7 +538,7 @@ func (e *InsertValues) doBatchInsert(ctx context.Context) error { return ErrBatchInsertFail.GenWithStack("BatchInsert failed with error: %v", err) } e.memTracker.Consume(-int64(txn.Size())) - e.ctx.StmtCommit() + e.ctx.StmtCommit(ctx) if err := sessiontxn.NewTxnInStmt(ctx, e.ctx); err != nil { // We should return a special error for batch insert. return ErrBatchInsertFail.GenWithStack("BatchInsert failed with error: %v", err) @@ -561,7 +563,7 @@ func (e *InsertValues) getRow(ctx context.Context, vals []types.Datum) ([]types. hasValue[offset] = true } - return e.fillRow(ctx, row, hasValue) + return e.fillRow(ctx, row, hasValue, 0) } // getColDefaultValue gets the column default value. @@ -646,7 +648,7 @@ func (e *InsertValues) fillColValue(ctx context.Context, datum types.Datum, idx // `insert|replace values` can guarantee consecutive autoID in a batch. // Other statements like `insert select from` don't guarantee consecutive autoID. // https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html -func (e *InsertValues) fillRow(ctx context.Context, row []types.Datum, hasValue []bool) ([]types.Datum, error) { +func (e *InsertValues) fillRow(ctx context.Context, row []types.Datum, hasValue []bool, rowIdx int) ([]types.Datum, error) { gCols := make([]*table.Column, 0) tCols := e.Table.Cols() if e.hasExtraHandle { @@ -692,6 +694,9 @@ func (e *InsertValues) fillRow(ctx context.Context, row []types.Datum, hasValue for i, gCol := range gCols { colIdx := gCol.ColumnInfo.Offset val, err := e.GenExprs[i].Eval(chunk.MutRowFromDatums(row).ToRow()) + if err != nil && gCol.FieldType.IsArray() { + return nil, completeError(tbl, gCol.Offset, rowIdx, err) + } if e.ctx.GetSessionVars().StmtCtx.HandleTruncate(err) != nil { return nil, err } @@ -707,6 +712,29 @@ func (e *InsertValues) fillRow(ctx context.Context, row []types.Datum, hasValue return row, nil } +func completeError(tbl *model.TableInfo, offset int, rowIdx int, err error) error { + name := "expression_index" + for _, idx := range tbl.Indices { + for _, column := range idx.Columns { + if column.Offset == offset { + name = idx.Name.O + break + } + } + } + + if expression.ErrInvalidJSONForFuncIndex.Equal(err) { + return expression.ErrInvalidJSONForFuncIndex.GenWithStackByArgs(name) + } + if types.ErrOverflow.Equal(err) { + return expression.ErrDataOutOfRangeFuncIndex.GenWithStackByArgs(name, rowIdx+1) + } + if types.ErrDataTooLong.Equal(err) { + return expression.ErrFuncIndexDataIsTooLong.GenWithStackByArgs(name) + } + return err +} + // isAutoNull can help judge whether a datum is AutoIncrement Null quickly. // This used to help lazyFillAutoIncrement to find consecutive N datum backwards for batch autoID alloc. func (e *InsertValues) isAutoNull(ctx context.Context, d types.Datum, col *table.Column) bool { @@ -744,7 +772,16 @@ func setDatumAutoIDAndCast(ctx sessionctx.Context, d *types.Datum, id int64, col var err error *d, err = table.CastValue(ctx, *d, col.ToInfo(), false, false) if err == nil && d.GetInt64() < id { - // Auto ID is out of range, the truncated ID is possible to duplicate with an existing ID. + // Auto ID is out of range. + sc := ctx.GetSessionVars().StmtCtx + insertPlan, ok := sc.GetPlan().(*core.Insert) + if ok && sc.TruncateAsWarning && len(insertPlan.OnDuplicate) > 0 { + // Fix issue #38950: AUTO_INCREMENT is incompatible with mysql + // An auto id out of range error occurs in `insert ignore into ... on duplicate ...`. + // We should allow the SQL to be executed successfully. + return nil + } + // The truncated ID is possible to duplicate with an existing ID. // To prevent updating unrelated rows in the REPLACE statement, it is better to throw an error. return autoid.ErrAutoincReadFailed } @@ -777,7 +814,8 @@ func (e *InsertValues) lazyAdjustAutoIncrementDatum(ctx context.Context, rows [] } // Use the value if it's not null and not 0. if recordID != 0 { - err = e.Table.Allocators(e.ctx).Get(autoid.RowIDAllocType).Rebase(ctx, recordID, true) + alloc := e.Table.Allocators(e.ctx).Get(autoid.AutoIncrementType) + err = alloc.Rebase(ctx, recordID, true) if err != nil { return nil, err } @@ -870,7 +908,7 @@ func (e *InsertValues) adjustAutoIncrementDatum(ctx context.Context, d types.Dat } // Use the value if it's not null and not 0. if recordID != 0 { - err = e.Table.Allocators(e.ctx).Get(autoid.RowIDAllocType).Rebase(ctx, recordID, true) + err = e.Table.Allocators(e.ctx).Get(autoid.AutoIncrementType).Rebase(ctx, recordID, true) if err != nil { return types.Datum{}, err } @@ -1006,7 +1044,7 @@ func (e *InsertValues) allocAutoRandomID(ctx context.Context, fieldType *types.F if err != nil { return 0, err } - currentShard := e.ctx.GetSessionVars().TxnCtx.GetCurrentShard(1) + currentShard := e.ctx.GetSessionVars().GetCurrentShard(1) return shardFmt.Compose(currentShard, autoRandomID), nil } @@ -1091,7 +1129,6 @@ func (e *InsertValues) collectRuntimeStatsEnabled() bool { SnapshotRuntimeStats: snapshotStats, AllocatorRuntimeStats: autoid.NewAllocatorRuntimeStats(), } - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } return true } @@ -1145,6 +1182,7 @@ func (e *InsertValues) batchCheckAndInsert(ctx context.Context, rows [][]types.D } if e.stats != nil { + e.stats.FKCheckTime += prefetchStart.Sub(start) e.stats.Prefetch += time.Since(prefetchStart) } @@ -1292,6 +1330,7 @@ type InsertRuntimeStat struct { *autoid.AllocatorRuntimeStats CheckInsertTime time.Duration Prefetch time.Duration + FKCheckTime time.Duration } func (e *InsertRuntimeStat) String() string { @@ -1314,9 +1353,8 @@ func (e *InsertRuntimeStat) String() string { buf.WriteString(", rpc: {") buf.WriteString(e.SnapshotRuntimeStats.String()) buf.WriteString("}") - return buf.String() } - return "" + return buf.String() } if allocatorStatsStr != "" { buf.WriteString("prepare: {total: ") @@ -1334,6 +1372,9 @@ func (e *InsertRuntimeStat) String() string { execdetails.FormatDuration(e.CheckInsertTime), execdetails.FormatDuration(e.CheckInsertTime-e.Prefetch), execdetails.FormatDuration(e.Prefetch))) + if e.FKCheckTime > 0 { + buf.WriteString(fmt.Sprintf(", fk_check: %v", execdetails.FormatDuration(e.FKCheckTime))) + } if e.SnapshotRuntimeStats != nil { if rpc := e.SnapshotRuntimeStats.String(); len(rpc) > 0 { buf.WriteString(fmt.Sprintf(", rpc:{%s}", rpc)) @@ -1351,6 +1392,7 @@ func (e *InsertRuntimeStat) Clone() execdetails.RuntimeStats { newRs := &InsertRuntimeStat{ CheckInsertTime: e.CheckInsertTime, Prefetch: e.Prefetch, + FKCheckTime: e.FKCheckTime, } if e.SnapshotRuntimeStats != nil { snapshotStats := e.SnapshotRuntimeStats.Clone() @@ -1396,6 +1438,7 @@ func (e *InsertRuntimeStat) Merge(other execdetails.RuntimeStats) { } } e.Prefetch += tmp.Prefetch + e.FKCheckTime += tmp.FKCheckTime e.CheckInsertTime += tmp.CheckInsertTime } diff --git a/executor/insert_test.go b/executor/insert_test.go index 06c9927bba008..acd8d6736b219 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -349,7 +349,7 @@ func TestUpdateDuplicateKey(t *testing.T) { tk.MustExec(`insert into c values(1,2,3);`) tk.MustExec(`insert into c values(1,2,4);`) tk.MustGetErrMsg(`update c set i=1,j=2,k=4 where i=1 and j=2 and k=3;`, - "[kv:1062]Duplicate entry '1-2-4' for key 'PRIMARY'") + "[kv:1062]Duplicate entry '1-2-4' for key 'c.PRIMARY'") } func TestIssue37187(t *testing.T) { @@ -398,6 +398,14 @@ func TestInsertWrongValueForField(t *testing.T) { tk.MustExec(`SET @@sql_mode='STRICT_TRANS_TABLES'`) tk.MustGetErrMsg(`INSERT INTO ts (id, time1) VALUES (2, TIMESTAMP '1018-12-24 00:00:00')`, `[table:1292]Incorrect timestamp value: '1018-12-24 00:00:00' for column 'time1' at row 1`) tk.MustExec(`DROP TABLE ts`) + + tk.MustExec(`CREATE TABLE t0(c0 SMALLINT AUTO_INCREMENT PRIMARY KEY);`) + tk.MustExec(`INSERT IGNORE INTO t0(c0) VALUES (194626268);`) + tk.MustExec(`INSERT IGNORE INTO t0(c0) VALUES ('*')`) + tk.MustQuery(`SHOW WARNINGS`).Check(testkit.Rows( + `Warning 1366 Incorrect smallint value: '*' for column 'c0' at row 1`, + `Warning 1690 constant 32768 overflows smallint`, + `Warning 1467 Failed to read auto-increment value from storage engine`)) } func TestInsertValueForCastDecimalField(t *testing.T) { @@ -411,6 +419,34 @@ func TestInsertValueForCastDecimalField(t *testing.T) { tk.MustQuery(`select cast(a as decimal) from t1;`).Check(testkit.Rows(`9999999999`)) } +func TestInsertForMultiValuedIndex(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`drop table if exists t1;`) + tk.MustExec(`create table t1(a json, b int, unique index idx((cast(a as signed array))));`) + tk.MustExec(`insert into t1 values ('[1,11]', 1);`) + tk.MustExec(`insert into t1 values ('[2, 22]', 2);`) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`[1, 11] 1`, `[2, 22] 2`)) + tk.MustGetErrMsg(`insert into t1 values ('[2, 222]', 2);`, "[kv:1062]Duplicate entry '2' for key 't1.idx'") + tk.MustExec(`replace into t1 values ('[1, 10]', 10)`) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`[2, 22] 2`, `[1, 10] 10`)) + tk.MustExec(`replace into t1 values ('[1, 2]', 1)`) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`[1, 2] 1`)) + tk.MustExec(`replace into t1 values ('[1, 11]', 1)`) + tk.MustExec(`insert into t1 values ('[2, 22]', 2);`) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`[1, 11] 1`, `[2, 22] 2`)) + tk.MustExec(`insert ignore into t1 values ('[1]', 2);`) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`[1, 11] 1`, `[2, 22] 2`)) + tk.MustExec(`insert ignore into t1 values ('[1, 2]', 2);`) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`[1, 11] 1`, `[2, 22] 2`)) + tk.MustExec(`insert into t1 values ('[2]', 2) on duplicate key update b = 10;`) + tk.MustQuery(`select * from t1;`).Check(testkit.Rows(`[1, 11] 1`, `[2, 22] 10`)) + tk.MustGetErrMsg(`insert into t1 values ('[2, 1]', 2) on duplicate key update a = '[1,2]';`, "[kv:1062]Duplicate entry '[1, 2]' for key 't1.idx'") + tk.MustGetErrMsg(`insert into t1 values ('[1,2]', 2) on duplicate key update a = '[1,2]';`, "[kv:1062]Duplicate entry '[1, 2]' for key 't1.idx'") + tk.MustGetErrMsg(`insert into t1 values ('[11, 22]', 2) on duplicate key update a = '[1,2]';`, "[kv:1062]Duplicate entry '[1, 2]' for key 't1.idx'") +} + func TestInsertDateTimeWithTimeZone(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -581,435 +617,6 @@ func TestAllowInvalidDates(t *testing.T) { runWithMode("ALLOW_INVALID_DATES") } -func TestInsertWithAutoidSchema(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec(`use test`) - tk.MustExec(`create table t1(id int primary key auto_increment, n int);`) - tk.MustExec(`create table t2(id int unsigned primary key auto_increment, n int);`) - tk.MustExec(`create table t3(id tinyint primary key auto_increment, n int);`) - tk.MustExec(`create table t4(id int primary key, n float auto_increment, key I_n(n));`) - tk.MustExec(`create table t5(id int primary key, n float unsigned auto_increment, key I_n(n));`) - tk.MustExec(`create table t6(id int primary key, n double auto_increment, key I_n(n));`) - tk.MustExec(`create table t7(id int primary key, n double unsigned auto_increment, key I_n(n));`) - // test for inserting multiple values - tk.MustExec(`create table t8(id int primary key auto_increment, n int);`) - - tests := []struct { - insert string - query string - result [][]interface{} - }{ - { - `insert into t1(id, n) values(1, 1)`, - `select * from t1 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `insert into t1(n) values(2)`, - `select * from t1 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `insert into t1(n) values(3)`, - `select * from t1 where id = 3`, - testkit.Rows(`3 3`), - }, - { - `insert into t1(id, n) values(-1, 4)`, - `select * from t1 where id = -1`, - testkit.Rows(`-1 4`), - }, - { - `insert into t1(n) values(5)`, - `select * from t1 where id = 4`, - testkit.Rows(`4 5`), - }, - { - `insert into t1(id, n) values('5', 6)`, - `select * from t1 where id = 5`, - testkit.Rows(`5 6`), - }, - { - `insert into t1(n) values(7)`, - `select * from t1 where id = 6`, - testkit.Rows(`6 7`), - }, - { - `insert into t1(id, n) values(7.4, 8)`, - `select * from t1 where id = 7`, - testkit.Rows(`7 8`), - }, - { - `insert into t1(id, n) values(7.5, 9)`, - `select * from t1 where id = 8`, - testkit.Rows(`8 9`), - }, - { - `insert into t1(n) values(9)`, - `select * from t1 where id = 9`, - testkit.Rows(`9 9`), - }, - // test last insert id - { - `insert into t1 values(3000, -1), (null, -2)`, - `select * from t1 where id = 3000`, - testkit.Rows(`3000 -1`), - }, - { - `;`, - `select * from t1 where id = 3001`, - testkit.Rows(`3001 -2`), - }, - { - `;`, - `select last_insert_id()`, - testkit.Rows(`3001`), - }, - { - `insert into t2(id, n) values(1, 1)`, - `select * from t2 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `insert into t2(n) values(2)`, - `select * from t2 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `insert into t2(n) values(3)`, - `select * from t2 where id = 3`, - testkit.Rows(`3 3`), - }, - { - `insert into t3(id, n) values(1, 1)`, - `select * from t3 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `insert into t3(n) values(2)`, - `select * from t3 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `insert into t3(n) values(3)`, - `select * from t3 where id = 3`, - testkit.Rows(`3 3`), - }, - { - `insert into t3(id, n) values(-1, 4)`, - `select * from t3 where id = -1`, - testkit.Rows(`-1 4`), - }, - { - `insert into t3(n) values(5)`, - `select * from t3 where id = 4`, - testkit.Rows(`4 5`), - }, - { - `insert into t4(id, n) values(1, 1)`, - `select * from t4 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `insert into t4(id) values(2)`, - `select * from t4 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `insert into t4(id, n) values(3, -1)`, - `select * from t4 where id = 3`, - testkit.Rows(`3 -1`), - }, - { - `insert into t4(id) values(4)`, - `select * from t4 where id = 4`, - testkit.Rows(`4 3`), - }, - { - `insert into t4(id, n) values(5, 5.5)`, - `select * from t4 where id = 5`, - testkit.Rows(`5 5.5`), - }, - { - `insert into t4(id) values(6)`, - `select * from t4 where id = 6`, - testkit.Rows(`6 7`), - }, - { - `insert into t4(id, n) values(7, '7.7')`, - `select * from t4 where id = 7`, - testkit.Rows(`7 7.7`), - }, - { - `insert into t4(id) values(8)`, - `select * from t4 where id = 8`, - testkit.Rows(`8 9`), - }, - { - `insert into t4(id, n) values(9, 10.4)`, - `select * from t4 where id = 9`, - testkit.Rows(`9 10.4`), - }, - { - `insert into t4(id) values(10)`, - `select * from t4 where id = 10`, - testkit.Rows(`10 11`), - }, - { - `insert into t5(id, n) values(1, 1)`, - `select * from t5 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `insert into t5(id) values(2)`, - `select * from t5 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `insert into t5(id) values(3)`, - `select * from t5 where id = 3`, - testkit.Rows(`3 3`), - }, - { - `insert into t6(id, n) values(1, 1)`, - `select * from t6 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `insert into t6(id) values(2)`, - `select * from t6 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `insert into t6(id, n) values(3, -1)`, - `select * from t6 where id = 3`, - testkit.Rows(`3 -1`), - }, - { - `insert into t6(id) values(4)`, - `select * from t6 where id = 4`, - testkit.Rows(`4 3`), - }, - { - `insert into t6(id, n) values(5, 5.5)`, - `select * from t6 where id = 5`, - testkit.Rows(`5 5.5`), - }, - { - `insert into t6(id) values(6)`, - `select * from t6 where id = 6`, - testkit.Rows(`6 7`), - }, - { - `insert into t6(id, n) values(7, '7.7')`, - `select * from t4 where id = 7`, - testkit.Rows(`7 7.7`), - }, - { - `insert into t6(id) values(8)`, - `select * from t4 where id = 8`, - testkit.Rows(`8 9`), - }, - { - `insert into t6(id, n) values(9, 10.4)`, - `select * from t6 where id = 9`, - testkit.Rows(`9 10.4`), - }, - { - `insert into t6(id) values(10)`, - `select * from t6 where id = 10`, - testkit.Rows(`10 11`), - }, - { - `insert into t7(id, n) values(1, 1)`, - `select * from t7 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `insert into t7(id) values(2)`, - `select * from t7 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `insert into t7(id) values(3)`, - `select * from t7 where id = 3`, - testkit.Rows(`3 3`), - }, - - // the following is test for insert multiple values. - { - `insert into t8(n) values(1),(2)`, - `select * from t8 where id = 1`, - testkit.Rows(`1 1`), - }, - { - `;`, - `select * from t8 where id = 2`, - testkit.Rows(`2 2`), - }, - { - `;`, - `select last_insert_id();`, - testkit.Rows(`1`), - }, - // test user rebase and auto alloc mixture. - { - `insert into t8 values(null, 3),(-1, -1),(null,4),(null, 5)`, - `select * from t8 where id = 3`, - testkit.Rows(`3 3`), - }, - // -1 won't rebase allocator here cause -1 < base. - { - `;`, - `select * from t8 where id = -1`, - testkit.Rows(`-1 -1`), - }, - { - `;`, - `select * from t8 where id = 4`, - testkit.Rows(`4 4`), - }, - { - `;`, - `select * from t8 where id = 5`, - testkit.Rows(`5 5`), - }, - { - `;`, - `select last_insert_id();`, - testkit.Rows(`3`), - }, - { - `insert into t8 values(null, 6),(10, 7),(null, 8)`, - `select * from t8 where id = 6`, - testkit.Rows(`6 6`), - }, - // 10 will rebase allocator here. - { - `;`, - `select * from t8 where id = 10`, - testkit.Rows(`10 7`), - }, - { - `;`, - `select * from t8 where id = 11`, - testkit.Rows(`11 8`), - }, - { - `;`, - `select last_insert_id()`, - testkit.Rows(`6`), - }, - // fix bug for last_insert_id should be first allocated id in insert rows (skip the rebase id). - { - `insert into t8 values(100, 9),(null,10),(null,11)`, - `select * from t8 where id = 100`, - testkit.Rows(`100 9`), - }, - { - `;`, - `select * from t8 where id = 101`, - testkit.Rows(`101 10`), - }, - { - `;`, - `select * from t8 where id = 102`, - testkit.Rows(`102 11`), - }, - { - `;`, - `select last_insert_id()`, - testkit.Rows(`101`), - }, - // test with sql_mode: NO_AUTO_VALUE_ON_ZERO. - { - `;`, - `select @@sql_mode`, - testkit.Rows(`ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION`), - }, - { - `;`, - "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO`", - nil, - }, - { - `insert into t8 values (0, 12), (null, 13)`, - `select * from t8 where id = 0`, - testkit.Rows(`0 12`), - }, - { - `;`, - `select * from t8 where id = 103`, - testkit.Rows(`103 13`), - }, - { - `;`, - `select last_insert_id()`, - testkit.Rows(`103`), - }, - // test without sql_mode: NO_AUTO_VALUE_ON_ZERO. - { - `;`, - "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION`", - nil, - }, - // value 0 will be substitute by autoid. - { - `insert into t8 values (0, 14), (null, 15)`, - `select * from t8 where id = 104`, - testkit.Rows(`104 14`), - }, - { - `;`, - `select * from t8 where id = 105`, - testkit.Rows(`105 15`), - }, - { - `;`, - `select last_insert_id()`, - testkit.Rows(`104`), - }, - // last test : auto increment allocation can find in retryInfo. - { - `retry : insert into t8 values (null, 16), (null, 17)`, - `select * from t8 where id = 1000`, - testkit.Rows(`1000 16`), - }, - { - `;`, - `select * from t8 where id = 1001`, - testkit.Rows(`1001 17`), - }, - { - `;`, - `select last_insert_id()`, - // this insert doesn't has the last_insert_id, should be same as the last insert case. - testkit.Rows(`104`), - }, - } - - for _, tt := range tests { - if strings.HasPrefix(tt.insert, "retry : ") { - // it's the last retry insert case, change the sessionVars. - retryInfo := &variable.RetryInfo{Retrying: true} - retryInfo.AddAutoIncrementID(1000) - retryInfo.AddAutoIncrementID(1001) - tk.Session().GetSessionVars().RetryInfo = retryInfo - tk.MustExec(tt.insert[8:]) - tk.Session().GetSessionVars().RetryInfo = &variable.RetryInfo{} - } else { - tk.MustExec(tt.insert) - } - if tt.query == "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO`" || - tt.query == "set session sql_mode = `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION`" { - tk.MustExec(tt.query) - } else { - tk.MustQuery(tt.query).Check(tt.result) - } - } -} - func TestPartitionInsertOnDuplicate(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -1131,75 +738,6 @@ func TestInsertFloatOverflow(t *testing.T) { tk.MustExec("drop table if exists t,t1") } -// TestAutoIDIncrementAndOffset There is a potential issue in MySQL: when the value of auto_increment_offset is greater -// than that of auto_increment_increment, the value of auto_increment_offset is ignored -// (https://dev.mysql.com/doc/refman/8.0/en/replication-options-master.html#sysvar_auto_increment_increment), -// This issue is a flaw of the implementation of MySQL and it doesn't exist in TiDB. -func TestAutoIDIncrementAndOffset(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec(`use test`) - // Test for offset is larger than increment. - tk.Session().GetSessionVars().AutoIncrementIncrement = 5 - tk.Session().GetSessionVars().AutoIncrementOffset = 10 - tk.MustExec(`create table io (a int key auto_increment)`) - tk.MustExec(`insert into io values (null),(null),(null)`) - tk.MustQuery(`select * from io`).Check(testkit.Rows("10", "15", "20")) - tk.MustExec(`drop table io`) - - // Test handle is PK. - tk.MustExec(`create table io (a int key auto_increment)`) - tk.Session().GetSessionVars().AutoIncrementOffset = 10 - tk.Session().GetSessionVars().AutoIncrementIncrement = 2 - tk.MustExec(`insert into io values (),(),()`) - tk.MustQuery(`select * from io`).Check(testkit.Rows("10", "12", "14")) - tk.MustExec(`delete from io`) - - // Test reset the increment. - tk.Session().GetSessionVars().AutoIncrementIncrement = 5 - tk.MustExec(`insert into io values (),(),()`) - tk.MustQuery(`select * from io`).Check(testkit.Rows("15", "20", "25")) - tk.MustExec(`delete from io`) - - tk.Session().GetSessionVars().AutoIncrementIncrement = 10 - tk.MustExec(`insert into io values (),(),()`) - tk.MustQuery(`select * from io`).Check(testkit.Rows("30", "40", "50")) - tk.MustExec(`delete from io`) - - tk.Session().GetSessionVars().AutoIncrementIncrement = 5 - tk.MustExec(`insert into io values (),(),()`) - tk.MustQuery(`select * from io`).Check(testkit.Rows("55", "60", "65")) - tk.MustExec(`drop table io`) - - // Test handle is not PK. - tk.Session().GetSessionVars().AutoIncrementIncrement = 2 - tk.Session().GetSessionVars().AutoIncrementOffset = 10 - tk.MustExec(`create table io (a int, b int auto_increment, key(b))`) - tk.MustExec(`insert into io(b) values (null),(null),(null)`) - // AutoID allocation will take increment and offset into consideration. - tk.MustQuery(`select b from io`).Check(testkit.Rows("10", "12", "14")) - // HandleID allocation will ignore the increment and offset. - tk.MustQuery(`select _tidb_rowid from io`).Check(testkit.Rows("15", "16", "17")) - tk.MustExec(`delete from io`) - - tk.Session().GetSessionVars().AutoIncrementIncrement = 10 - tk.MustExec(`insert into io(b) values (null),(null),(null)`) - tk.MustQuery(`select b from io`).Check(testkit.Rows("20", "30", "40")) - tk.MustQuery(`select _tidb_rowid from io`).Check(testkit.Rows("41", "42", "43")) - - // Test invalid value. - tk.Session().GetSessionVars().AutoIncrementIncrement = -1 - tk.Session().GetSessionVars().AutoIncrementOffset = -2 - tk.MustGetErrMsg(`insert into io(b) values (null),(null),(null)`, - "[autoid:8060]Invalid auto_increment settings: auto_increment_increment: -1, auto_increment_offset: -2, both of them must be in range [1..65535]") - tk.MustExec(`delete from io`) - - tk.Session().GetSessionVars().AutoIncrementIncrement = 65536 - tk.Session().GetSessionVars().AutoIncrementOffset = 65536 - tk.MustGetErrMsg(`insert into io(b) values (null),(null),(null)`, - "[autoid:8060]Invalid auto_increment settings: auto_increment_increment: 65536, auto_increment_offset: 65536, both of them must be in range [1..65535]") -} - // Fix https://github.com/pingcap/tidb/issues/32601. func TestTextTooLongError(t *testing.T) { store := testkit.CreateMockStore(t) @@ -1385,6 +923,22 @@ func TestInsertErrorMsg(t *testing.T) { tk.MustExec(`create table t (a int primary key, b datetime, d date)`) tk.MustContainErrMsg(`insert into t values (1, '2019-02-11 30:00:00', '2019-01-31')`, "Incorrect datetime value: '2019-02-11 30:00:00' for column 'b' at row 1") + + // test for Issue #35289 + tk.MustExec("CREATE TABLE t1 (a BINARY(16) PRIMARY KEY);") + tk.MustExec(`INSERT INTO t1 VALUES (AES_ENCRYPT('a','a'));`) + err := tk.ExecToErr(`INSERT INTO t1 VALUES (AES_ENCRYPT('a','a'));`) + require.Error(t, err, `ERROR 1062 (23000): Duplicate entry '{ W]\xA1\x06u\x9D\xBD\xB1\xA3.\xE2\xD9\xA7t' for key 't1.PRIMARY'`) + + tk.MustExec(`INSERT INTO t1 VALUES (AES_ENCRYPT('b','b'));`) + err = tk.ExecToErr(`INSERT INTO t1 VALUES (AES_ENCRYPT('b','b'));`) + require.Error(t, err, "ERROR 1062 (23000): Duplicate entry '\\x0C\\x1E\\x8DG`\\xEB\\x93 F&BC\\xF0\\xB5\\xF4\\xB7' for key 't1.PRIMARY'") + + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (a bit primary key) engine=innodb;") + tk.MustExec("insert into t1 values (b'0');") + err = tk.ExecToErr(`insert into t1 values (b'0');`) + require.Error(t, err, `ERROR 1062 (23000): Duplicate entry '\x00' for key 't1.PRIMARY'`) } func TestIssue16366(t *testing.T) { @@ -1394,7 +948,7 @@ func TestIssue16366(t *testing.T) { tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(c numeric primary key);`) tk.MustExec("insert ignore into t values(null);") - tk.MustContainErrMsg(`insert into t values(0);`, "Duplicate entry '0' for key 'PRIMARY'") + tk.MustContainErrMsg(`insert into t values(0);`, "Duplicate entry '0' for key 't.PRIMARY'") } func TestClusterPrimaryTablePlainInsert(t *testing.T) { @@ -1545,6 +1099,8 @@ func TestInsertRuntimeStat(t *testing.T) { require.Equal(t, stats.Clone().String(), stats.String()) stats.Merge(stats.Clone()) require.Equal(t, "prepare: 6s, check_insert: {total_time: 4s, mem_insert_time: 2s, prefetch: 2s}", stats.String()) + stats.FKCheckTime = time.Second + require.Equal(t, "prepare: 6s, check_insert: {total_time: 4s, mem_insert_time: 2s, prefetch: 2s, fk_check: 1s}", stats.String()) } func TestDuplicateEntryMessage(t *testing.T) { @@ -1556,52 +1112,52 @@ func TestDuplicateEntryMessage(t *testing.T) { tk.MustExec("drop table if exists t;") tk.MustExec("create table t(a int, b char(10), unique key(b)) collate utf8mb4_general_ci;") tk.MustExec("insert into t value (34, '12Ak');") - tk.MustGetErrMsg("insert into t value (34, '12Ak');", "[kv:1062]Duplicate entry '12Ak' for key 'b'") + tk.MustGetErrMsg("insert into t value (34, '12Ak');", "[kv:1062]Duplicate entry '12Ak' for key 't.b'") tk.MustExec("begin optimistic;") tk.MustExec("insert into t value (34, '12ak');") tk.MustExec("delete from t where b = '12ak';") - tk.MustGetErrMsg("commit;", "previous statement: delete from t where b = '12ak';: [kv:1062]Duplicate entry '12ak' for key 'b'") + tk.MustGetErrMsg("commit;", "previous statement: delete from t where b = '12ak';: [kv:1062]Duplicate entry '12ak' for key 't.b'") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a datetime primary key);") tk.MustExec("insert into t values ('2020-01-01');") - tk.MustGetErrMsg("insert into t values ('2020-01-01');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00' for key 'PRIMARY'") + tk.MustGetErrMsg("insert into t values ('2020-01-01');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00' for key 't.PRIMARY'") tk.MustExec("begin optimistic;") tk.MustExec("insert into t values ('2020-01-01');") tk.MustExec("delete from t where a = '2020-01-01';") - tk.MustGetErrMsg("commit;", "previous statement: delete from t where a = '2020-01-01';: [kv:1062]Duplicate entry '2020-01-01 00:00:00' for key 'PRIMARY'") + tk.MustGetErrMsg("commit;", "previous statement: delete from t where a = '2020-01-01';: [kv:1062]Duplicate entry '2020-01-01 00:00:00' for key 't.PRIMARY'") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a int primary key );") tk.MustExec("insert into t value (1);") - tk.MustGetErrMsg("insert into t value (1);", "[kv:1062]Duplicate entry '1' for key 'PRIMARY'") + tk.MustGetErrMsg("insert into t value (1);", "[kv:1062]Duplicate entry '1' for key 't.PRIMARY'") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a datetime unique);") tk.MustExec("insert into t values ('2020-01-01');") - tk.MustGetErrMsg("insert into t values ('2020-01-01');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00' for key 'a'") + tk.MustGetErrMsg("insert into t values ('2020-01-01');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00' for key 't.a'") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a datetime, b int, c varchar(10), primary key (a, b, c)) collate utf8mb4_general_ci;") tk.MustExec("insert into t values ('2020-01-01', 1, 'aSDd');") - tk.MustGetErrMsg("insert into t values ('2020-01-01', 1, 'ASDD');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00-1-ASDD' for key 'PRIMARY'") + tk.MustGetErrMsg("insert into t values ('2020-01-01', 1, 'ASDD');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00-1-ASDD' for key 't.PRIMARY'") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a datetime, b int, c varchar(10), unique key (a, b, c)) collate utf8mb4_general_ci;") tk.MustExec("insert into t values ('2020-01-01', 1, 'aSDd');") - tk.MustGetErrMsg("insert into t values ('2020-01-01', 1, 'ASDD');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00-1-ASDD' for key 'a'") + tk.MustGetErrMsg("insert into t values ('2020-01-01', 1, 'ASDD');", "[kv:1062]Duplicate entry '2020-01-01 00:00:00-1-ASDD' for key 't.a'") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a char(10) collate utf8mb4_unicode_ci, b char(20) collate utf8mb4_general_ci, c int(11), primary key (a, b, c), unique key (a));") tk.MustExec("insert ignore into t values ('$', 'C', 10);") tk.MustExec("insert ignore into t values ('$', 'C', 10);") - tk.MustQuery("show warnings;").Check(testkit.RowsWithSep("|", "Warning|1062|Duplicate entry '$-C-10' for key 'PRIMARY'")) + tk.MustQuery("show warnings;").Check(testkit.RowsWithSep("|", "Warning|1062|Duplicate entry '$-C-10' for key 't.PRIMARY'")) tk.MustExec("begin pessimistic;") tk.MustExec("insert into t values ('a7', 'a', 10);") - tk.MustGetErrMsg("insert into t values ('a7', 'a', 10);", "[kv:1062]Duplicate entry 'a7-a-10' for key 'PRIMARY'") + tk.MustGetErrMsg("insert into t values ('a7', 'a', 10);", "[kv:1062]Duplicate entry 'a7-a-10' for key 't.PRIMARY'") tk.MustExec("rollback;") // Test for large unsigned integer handle. @@ -1609,7 +1165,7 @@ func TestDuplicateEntryMessage(t *testing.T) { tk.MustExec("drop table if exists t;") tk.MustExec("create table t(a bigint unsigned primary key);") tk.MustExec("insert into t values(18446744073709551615);") - tk.MustGetErrMsg("insert into t values(18446744073709551615);", "[kv:1062]Duplicate entry '18446744073709551615' for key 'PRIMARY'") + tk.MustGetErrMsg("insert into t values(18446744073709551615);", "[kv:1062]Duplicate entry '18446744073709551615' for key 't.PRIMARY'") } } @@ -1675,12 +1231,12 @@ func TestDuplicatedEntryErr(t *testing.T) { tk.MustExec("create table t1(a int, b varchar(20), primary key(a,b(3)) clustered);") tk.MustExec("insert into t1 values(1,'aaaaa');") err := tk.ExecToErr("insert into t1 values(1,'aaaaa');") - require.EqualError(t, err, "[kv:1062]Duplicate entry '1-aaa' for key 'PRIMARY'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '1-aaa' for key 't1.PRIMARY'") err = tk.ExecToErr("insert into t1 select 1, 'aaa'") - require.EqualError(t, err, "[kv:1062]Duplicate entry '1-aaa' for key 'PRIMARY'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '1-aaa' for key 't1.PRIMARY'") tk.MustExec("insert into t1 select 1, 'bb'") err = tk.ExecToErr("insert into t1 select 1, 'bb'") - require.EqualError(t, err, "[kv:1062]Duplicate entry '1-bb' for key 'PRIMARY'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '1-bb' for key 't1.PRIMARY'") } func TestBinaryLiteralInsertToEnum(t *testing.T) { diff --git a/executor/issuetest/BUILD.bazel b/executor/issuetest/BUILD.bazel new file mode 100644 index 0000000000000..8d930738d2b7c --- /dev/null +++ b/executor/issuetest/BUILD.bazel @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "issuetest_test", + srcs = [ + "executor_issue_test.go", + "main_test.go", + ], + flaky = True, + shard_count = 50, + deps = [ + "//autoid_service", + "//config", + "//kv", + "//meta/autoid", + "//parser/auth", + "//parser/charset", + "//parser/mysql", + "//sessionctx/variable", + "//statistics", + "//testkit", + "//util", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//tikv", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/executor/executor_issue_test.go b/executor/issuetest/executor_issue_test.go similarity index 86% rename from executor/executor_issue_test.go rename to executor/issuetest/executor_issue_test.go index f0b52422c19a2..b97df5a5c11c1 100644 --- a/executor/executor_issue_test.go +++ b/executor/issuetest/executor_issue_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package executor_test +package issuetest_test import ( "context" @@ -22,6 +22,7 @@ import ( "testing" "github.com/pingcap/failpoint" + _ "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/auth" @@ -133,6 +134,7 @@ func TestIssue24210(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") // for ProjectionExec require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/mockProjectionExecBaseExecutorOpenReturnedError", `return(true)`)) @@ -531,6 +533,7 @@ func TestFix31537(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set @@foreign_key_checks=0") tk.MustExec(`CREATE TABLE trade ( t_id bigint(16) NOT NULL AUTO_INCREMENT, t_dts datetime NOT NULL, @@ -579,6 +582,7 @@ func TestIssue30382(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@session.tidb_enable_list_partition = ON;") tk.MustExec("drop table if exists t1, t2;") tk.MustExec("create table t1 (c_int int, c_str varchar(40), c_decimal decimal(12, 6), primary key (c_int) , key(c_str(2)) , key(c_decimal) ) partition by list (c_int) ( partition p0 values IN (1, 5, 9, 13, 17, 21, 25, 29, 33, 37), partition p1 values IN (2, 6, 10, 14, 18, 22, 26, 30, 34, 38), partition p2 values IN (3, 7, 11, 15, 19, 23, 27, 31, 35, 39), partition p3 values IN (4, 8, 12, 16, 20, 24, 28, 32, 36, 40)) ;") @@ -596,7 +600,7 @@ func TestIssue30382(t *testing.T) { "SelectLock 6400.00 root for update 0", "└─HashJoin 6400.00 root CARTESIAN inner join, other cond:or(gt(Column#8, 1), or(ne(test.t1.c_str, Column#7), if(ne(Column#9, 0), NULL, 0)))", " ├─Selection(Build) 0.80 root ne(Column#10, 0)", - " │ └─StreamAgg 1.00 root funcs:max(Column#17)->Column#7, funcs:count(distinct Column#18)->Column#8, funcs:sum(Column#19)->Column#9, funcs:count(1)->Column#10", + " │ └─HashAgg 1.00 root funcs:max(Column#17)->Column#7, funcs:count(distinct Column#18)->Column#8, funcs:sum(Column#19)->Column#9, funcs:count(1)->Column#10", " │ └─Projection 3323.33 root test.t2.c_str, test.t2.c_str, cast(isnull(test.t2.c_str), decimal(20,0) BINARY)->Column#19", " │ └─TableReader 3323.33 root partition:all data:Selection", " │ └─Selection 3323.33 cop[tikv] lt(test.t2.c_decimal, 5)", @@ -682,6 +686,9 @@ func TestIssue22231(t *testing.T) { tk.MustQuery("select cast('2020-05-28 23:59:59 00:00:00' as datetime)").Check(testkit.Rows("2020-05-28 23:59:59")) tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 Truncated incorrect datetime value: '2020-05-28 23:59:59 00:00:00'")) tk.MustExec("drop table if exists t_issue_22231") + + tk.MustQuery("SELECT CAST(\"1111111111-\" AS DATE);") + tk.MustQuery("SHOW WARNINGS").Check(testkit.Rows("Warning 1292 Incorrect datetime value: '1111111111-'")) } // TestIssue2612 is related with https://github.com/pingcap/tidb/issues/2612 @@ -1235,3 +1242,148 @@ func TestIssue33214(t *testing.T) { } } } + +func TestIssue982(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (c int auto_increment, key(c)) auto_id_cache 1;") + tk.MustExec("insert into t values();") + tk.MustExec("insert into t values();") + tk.MustQuery("select * from t;").Check(testkit.Rows("1", "2")) +} + +func TestIssue24627(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + for _, sql := range []string{ + "create table test(id float primary key clustered AUTO_INCREMENT, col1 int);", + "create table test(id float primary key nonclustered AUTO_INCREMENT, col1 int) AUTO_ID_CACHE 1;", + } { + tk.MustExec("drop table if exists test;") + tk.MustExec(sql) + tk.MustExec("replace into test(col1) values(1);") + tk.MustExec("replace into test(col1) values(2);") + tk.MustQuery("select * from test;").Check(testkit.Rows("1 1", "2 2")) + tk.MustExec("drop table test") + } + + for _, sql := range []string{ + "create table test2(id double primary key clustered AUTO_INCREMENT, col1 int);", + "create table test2(id double primary key nonclustered AUTO_INCREMENT, col1 int) AUTO_ID_CACHE 1;", + } { + tk.MustExec(sql) + tk.MustExec("replace into test2(col1) values(1);") + tk.MustExec("insert into test2(col1) values(1);") + tk.MustExec("replace into test2(col1) values(1);") + tk.MustExec("insert into test2(col1) values(1);") + tk.MustExec("replace into test2(col1) values(1);") + tk.MustExec("replace into test2(col1) values(1);") + tk.MustQuery("select * from test2").Check(testkit.Rows("1 1", "2 1", "3 1", "4 1", "5 1", "6 1")) + tk.MustExec("drop table test2") + } +} + +func TestIssue39618(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1;") + tk.MustExec(`CREATE TABLE t1 ( + c_int int(11) NOT NULL, + c_str varbinary(40) NOT NULL, + c_datetime datetime DEFAULT NULL, + c_timestamp timestamp NULL DEFAULT NULL, + c_double double DEFAULT NULL, + c_decimal decimal(12,6) DEFAULT NULL, + c_enum enum('blue','green','red','yellow','white','orange','purple') DEFAULT NULL, + PRIMARY KEY (c_int,c_str) /*T![clustered_index] CLUSTERED */, + KEY c_int_2 (c_int), + KEY c_decimal (c_decimal), + KEY c_datetime (c_datetime) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin +PARTITION BY LIST COLUMNS(c_int) +(PARTITION p0 VALUES IN (1,5,9,13,17,21,25,29,33,37), + PARTITION p1 VALUES IN (2,6,10,14,18,22,26,30,34,38), + PARTITION p2 VALUES IN (3,7,11,15,19,23,27,31,35,39), + PARTITION p3 VALUES IN (4,8,12,16,20,24,28,32,36,40));`) + tk.MustExec("INSERT INTO t1 VALUES (3,'bold goldberg','2020-01-07 12:08:19','2020-06-19 08:13:35',0.941002,5.303000,'yellow'),(1,'crazy wescoff','2020-03-24 21:51:02','2020-06-19 08:13:35',47.565275,6.313000,'orange'),(5,'relaxed gagarin','2020-05-20 11:36:26','2020-06-19 08:13:35',38.948617,3.143000,'green'),(9,'gifted vaughan','2020-04-09 16:19:45','2020-06-19 08:13:35',95.922976,8.708000,'yellow'),(2,'focused taussig','2020-05-17 17:58:34','2020-06-19 08:13:35',4.137803,4.902000,'white'),(6,'fervent yonath','2020-05-26 03:55:25','2020-06-19 08:13:35',72.394272,6.491000,'white'),(18,'mystifying bhaskara','2020-02-19 10:41:48','2020-06-19 08:13:35',10.832397,9.707000,'red'),(4,'goofy saha','2020-03-11 13:24:31','2020-06-19 08:13:35',39.007216,2.446000,'blue'),(20,'mystifying bhaskara','2020-04-03 11:33:27','2020-06-19 08:13:35',85.190386,6.787000,'blue');") + + tk.MustExec("DROP TABLE IF EXISTS t2;") + tk.MustExec(`CREATE TABLE t2 ( + c_int int(11) NOT NULL, + c_str varbinary(40) NOT NULL, + c_datetime datetime DEFAULT NULL, + c_timestamp timestamp NULL DEFAULT NULL, + c_double double DEFAULT NULL, + c_decimal decimal(12,6) DEFAULT NULL, + c_enum enum('blue','green','red','yellow','white','orange','purple') DEFAULT NULL, + PRIMARY KEY (c_int,c_str) /*T![clustered_index] CLUSTERED */, + KEY c_int_2 (c_int), + KEY c_decimal (c_decimal), + KEY c_datetime (c_datetime) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin +PARTITION BY LIST COLUMNS(c_int) +(PARTITION p0 VALUES IN (1,5,9,13,17,21,25,29,33,37), + PARTITION p1 VALUES IN (2,6,10,14,18,22,26,30,34,38), + PARTITION p2 VALUES IN (3,7,11,15,19,23,27,31,35,39), + PARTITION p3 VALUES IN (4,8,12,16,20,24,28,32,36,40)); +`) + + tk.MustExec("INSERT INTO t2 VALUES (1,'crazy wescoff','2020-03-24 21:51:02','2020-04-01 12:11:56',47.565275,6.313000,'orange'),(1,'unruffled johnson','2020-06-30 03:42:58','2020-06-14 00:16:50',35.444084,1.090000,'red'),(5,'relaxed gagarin','2020-05-20 11:36:26','2020-02-19 12:25:48',38.948617,3.143000,'green'),(9,'eloquent archimedes','2020-02-16 04:20:21','2020-05-23 15:42:33',32.310878,5.855000,'orange'),(9,'gifted vaughan','2020-04-09 16:19:45','2020-05-15 01:42:16',95.922976,8.708000,'yellow'),(13,'dreamy benz','2020-04-27 17:43:44','2020-03-27 06:33:03',39.539233,4.823000,'red'),(3,'bold goldberg','2020-01-07 12:08:19','2020-03-10 18:37:09',0.941002,5.303000,'yellow'),(3,'youthful yonath','2020-01-12 17:10:39','2020-06-10 15:13:44',66.288511,6.046000,'white'),(7,'upbeat bhabha','2020-04-29 01:17:05','2020-03-11 22:58:43',23.316987,9.026000,'yellow'),(11,'quizzical ritchie','2020-05-16 08:21:36','2020-03-05 19:23:25',75.019379,0.260000,'purple'),(2,'dazzling kepler','2020-04-11 04:38:59','2020-05-06 04:42:32',78.798503,2.274000,'purple'),(2,'focused taussig','2020-05-17 17:58:34','2020-02-25 09:11:03',4.137803,4.902000,'white'),(2,'sharp ptolemy',NULL,'2020-05-17 18:04:19',NULL,5.573000,'purple'),(6,'fervent yonath','2020-05-26 03:55:25','2020-05-06 14:23:44',72.394272,6.491000,'white'),(10,'musing wu','2020-04-03 11:33:27','2020-05-24 06:11:56',85.190386,6.787000,'blue'),(8,'hopeful keller','2020-02-19 10:41:48','2020-04-19 17:10:36',10.832397,9.707000,'red'),(12,'exciting boyd',NULL,'2020-03-28 18:27:23',NULL,9.249000,'blue');") + + tk.MustExec("set tidb_txn_assertion_level=strict;") + tk.MustExec("begin") + tk.MustExec("delete t1, t2 from t1, t2 where t1.c_enum in ('blue');") + tk.MustExec("commit") +} + +func TestIssue40158(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (_id int PRIMARY KEY, c1 char, index (c1));") + tk.MustExec("insert into t1 values (1, null);") + tk.MustQuery("select * from t1 where c1 is null and _id < 1;").Check(testkit.Rows()) +} + +func TestIssue40596(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec(`CREATE TABLE t1 ( + c1 double DEFAULT '1.335088259490289', + c2 set('mj','4s7ht','z','3i','b26','9','cg11','uvzcp','c','ns','fl9') NOT NULL DEFAULT 'mj,z,3i,9,cg11,c', + PRIMARY KEY (c2) /*T![clustered_index] CLUSTERED */, + KEY i1 (c1), + KEY i2 (c1), + KEY i3 (c1) +) ENGINE=InnoDB DEFAULT CHARSET=gbk COLLATE=gbk_chinese_ci;`) + tk.MustExec("INSERT INTO t1 VALUES (634.2783557491367,''),(2000.5041449792013,'4s7ht'),(634.2783557491367,'3i'),(634.2783557491367,'9'),(7803.173688589342,'uvzcp'),(634.2783557491367,'ns'),(634.2783557491367,'fl9');") + tk.MustExec(`CREATE TABLE t2 ( + c3 decimal(56,16) DEFAULT '931359772706767457132645278260455518957.9866038319986886', + c4 set('3bqx','g','6op3','2g','jf','arkd3','y0b','jdy','1g','ff5z','224b') DEFAULT '3bqx,2g,ff5z,224b', + c5 smallint(6) NOT NULL DEFAULT '-25973', + c6 year(4) DEFAULT '2122', + c7 text DEFAULT NULL, + PRIMARY KEY (c5) /*T![clustered_index] CLUSTERED */, + KEY i4 (c6), + KEY i5 (c5) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='' +PARTITION BY HASH (c5) PARTITIONS 4;`) + tk.MustExec("INSERT INTO t2 VALUES (465.0000000000000000,'jdy',-8542,2008,'FgZXe');") + tk.MustExec("set @@sql_mode='';") + tk.MustExec("set tidb_partition_prune_mode=dynamic;") + tk.MustExec("analyze table t1;") + tk.MustExec("analyze table t2;") + + // No nil pointer panic + tk.MustQuery("select /*+ inl_join( t1 , t2 ) */ avg( t2.c5 ) as r0 , repeat( t2.c7 , t2.c5 ) as r1 , locate( t2.c7 , t2.c7 ) as r2 , unhex( t1.c1 ) as r3 from t1 right join t2 on t1.c2 = t2.c5 where not( t2.c5 in ( -7860 ,-13384 ,-12940 ) ) and not( t1.c2 between '4s7ht' and 'mj' );").Check(testkit.Rows(" ")) + // Again, a simpler reproduce. + tk.MustQuery("select /*+ inl_join (t1, t2) */ t2.c5 from t1 right join t2 on t1.c2 = t2.c5 where not( t1.c2 between '4s7ht' and 'mj' );").Check(testkit.Rows()) +} diff --git a/executor/issuetest/main_test.go b/executor/issuetest/main_test.go new file mode 100644 index 0000000000000..daecbf2f06859 --- /dev/null +++ b/executor/issuetest/main_test.go @@ -0,0 +1,45 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package issuetest + +import ( + "testing" + + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/meta/autoid" + "github.com/tikv/client-go/v2/tikv" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + autoid.SetStep(5000) + config.UpdateGlobal(func(conf *config.Config) { + conf.Instance.SlowThreshold = 30000 // 30s + conf.TiKVClient.AsyncCommit.SafeWindow = 0 + conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 + conf.Experimental.AllowsExpressionIndex = true + }) + tikv.EnableFailpoints() + + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), + goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + } + goleak.VerifyTestMain(m, opts...) +} diff --git a/executor/join.go b/executor/join.go index 706895e44d06f..91533be2259cf 100644 --- a/executor/join.go +++ b/executor/join.go @@ -20,7 +20,6 @@ import ( "fmt" "runtime/trace" "strconv" - "sync" "sync/atomic" "time" @@ -47,64 +46,84 @@ var ( _ Executor = &NestedLoopApplyExec{} ) -// HashJoinExec implements the hash join algorithm. -type HashJoinExec struct { - baseExecutor +type hashJoinCtx struct { + sessCtx sessionctx.Context + allocPool chunk.Allocator + // concurrency is the number of partition, build and join workers. + concurrency uint + joinResultCh chan *hashjoinWorkerResult + // closeCh add a lock for closing executor. + closeCh chan struct{} + finished atomic.Bool + useOuterToBuild bool + isOuterJoin bool + isNullEQ []bool + buildFinished chan error + rowContainer *hashRowContainer + joinType plannercore.JoinType + outerMatchedStatus []*bitmap.ConcurrentBitmap + stats *hashJoinRuntimeStats + probeTypes []*types.FieldType + buildTypes []*types.FieldType + outerFilter expression.CNFExprs + isNullAware bool + memTracker *memory.Tracker // track memory usage. + diskTracker *disk.Tracker // track disk usage. +} - probeSideExec Executor - buildSideExec Executor - buildSideEstCount float64 - outerFilter expression.CNFExprs - probeKeys []*expression.Column - probeNAKeys []*expression.Column - buildKeys []*expression.Column - buildNAKeys []*expression.Column - isNullEQ []bool - probeTypes []*types.FieldType - buildTypes []*types.FieldType +// probeSideTupleFetcher reads tuples from probeSideExec and send them to probeWorkers. +type probeSideTupleFetcher struct { + *hashJoinCtx - // concurrency is the number of partition, build and join workers. - concurrency uint - rowContainer *hashRowContainer - buildFinished chan error + probeSideExec Executor + probeChkResourceCh chan *probeChkResource + probeResultChs []chan *chunk.Chunk + requiredRows int64 +} - // closeCh add a lock for closing executor. - closeCh chan struct{} - joinType plannercore.JoinType - requiredRows int64 +type probeWorker struct { + hashJoinCtx *hashJoinCtx + workerID uint + + probeKeyColIdx []int + probeNAKeyColIdx []int + // We pre-alloc and reuse the Rows and RowPtrs for each probe goroutine, to avoid allocation frequently + buildSideRows []chunk.Row + buildSideRowPtrs []chunk.RowPtr // We build individual joiner for each join worker when use chunk-based // execution, to avoid the concurrency of joiner.chk and joiner.selected. - joiners []joiner - + joiner joiner + rowIters *chunk.Iterator4Slice + rowContainerForProbe *hashRowContainer + // for every naaj probe worker, pre-allocate the int slice for store the join column index to check. + needCheckBuildRowPos []int + needCheckProbeRowPos []int probeChkResourceCh chan *probeChkResource - probeResultChs []chan *chunk.Chunk - joinChkResourceCh []chan *chunk.Chunk - joinResultCh chan *hashjoinWorkerResult - rowContainerForProbe []*hashRowContainer - - memTracker *memory.Tracker // track memory usage. - diskTracker *disk.Tracker // track disk usage. - - outerMatchedStatus []*bitmap.ConcurrentBitmap - useOuterToBuild bool + joinChkResourceCh chan *chunk.Chunk + probeResultCh chan *chunk.Chunk +} - prepared bool - isOuterJoin bool +type buildWorker struct { + hashJoinCtx *hashJoinCtx + buildSideExec Executor + buildKeyColIdx []int + buildNAKeyColIdx []int +} - // joinWorkerWaitGroup is for sync multiple join workers. - joinWorkerWaitGroup sync.WaitGroup - finished atomic.Value +// HashJoinExec implements the hash join algorithm. +type HashJoinExec struct { + baseExecutor + *hashJoinCtx - stats *hashJoinRuntimeStats + probeSideTupleFetcher *probeSideTupleFetcher + probeWorkers []*probeWorker + buildWorker *buildWorker - // We pre-alloc and reuse the Rows and RowPtrs for each probe goroutine, to avoid allocation frequently - buildSideRows [][]chunk.Row - buildSideRowPtrs [][]chunk.RowPtr + workerWg util.WaitGroupWrapper + waiterWg util.WaitGroupWrapper - // for every naaj probe worker, pre-allocate the int slice for store the join column index to check. - needCheckBuildRowPos [][]int - needCheckProbeRowPos [][]int + prepared bool } // probeChkResource stores the result of the join probe side fetch worker, @@ -138,29 +157,36 @@ func (e *HashJoinExec) Close() error { if e.joinResultCh != nil { channel.Clear(e.joinResultCh) } - if e.probeChkResourceCh != nil { - close(e.probeChkResourceCh) - channel.Clear(e.probeChkResourceCh) + if e.probeSideTupleFetcher.probeChkResourceCh != nil { + close(e.probeSideTupleFetcher.probeChkResourceCh) + channel.Clear(e.probeSideTupleFetcher.probeChkResourceCh) } - for i := range e.probeResultChs { - channel.Clear(e.probeResultChs[i]) + for i := range e.probeSideTupleFetcher.probeResultChs { + channel.Clear(e.probeSideTupleFetcher.probeResultChs[i]) } - for i := range e.joinChkResourceCh { - close(e.joinChkResourceCh[i]) - channel.Clear(e.joinChkResourceCh[i]) + for i := range e.probeWorkers { + close(e.probeWorkers[i].joinChkResourceCh) + channel.Clear(e.probeWorkers[i].joinChkResourceCh) } - e.probeChkResourceCh = nil - e.joinChkResourceCh = nil + e.probeSideTupleFetcher.probeChkResourceCh = nil terror.Call(e.rowContainer.Close) + e.waiterWg.Wait() } e.outerMatchedStatus = e.outerMatchedStatus[:0] - e.buildSideRows = nil - e.buildSideRowPtrs = nil - e.needCheckBuildRowPos = nil - e.needCheckProbeRowPos = nil + for _, w := range e.probeWorkers { + w.buildSideRows = nil + w.buildSideRowPtrs = nil + w.needCheckBuildRowPos = nil + w.needCheckProbeRowPos = nil + w.joinChkResourceCh = nil + } + if e.stats != nil && e.rowContainer != nil { e.stats.hashStat = *e.rowContainer.stat } + if e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } err := e.baseExecutor.Close() return err } @@ -168,62 +194,58 @@ func (e *HashJoinExec) Close() error { // Open implements the Executor Open interface. func (e *HashJoinExec) Open(ctx context.Context) error { if err := e.baseExecutor.Open(ctx); err != nil { + e.closeCh = nil + e.prepared = false return err } e.prepared = false - e.memTracker = memory.NewTracker(e.id, -1) - e.memTracker.AttachTo(e.ctx.GetSessionVars().StmtCtx.MemTracker) + e.hashJoinCtx.memTracker = memory.NewTracker(e.id, -1) + e.hashJoinCtx.memTracker.AttachTo(e.ctx.GetSessionVars().StmtCtx.MemTracker) e.diskTracker = disk.NewTracker(e.id, -1) e.diskTracker.AttachTo(e.ctx.GetSessionVars().StmtCtx.DiskTracker) + e.workerWg = util.WaitGroupWrapper{} + e.waiterWg = util.WaitGroupWrapper{} e.closeCh = make(chan struct{}) e.finished.Store(false) - e.joinWorkerWaitGroup = sync.WaitGroup{} - if e.probeTypes == nil { - e.probeTypes = retTypes(e.probeSideExec) - } - if e.buildTypes == nil { - e.buildTypes = retTypes(e.buildSideExec) - } if e.runtimeStats != nil { e.stats = &hashJoinRuntimeStats{ - concurrent: cap(e.joiners), + concurrent: int(e.concurrency), } - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } return nil } // fetchProbeSideChunks get chunks from fetches chunks from the big table in a background goroutine // and sends the chunks to multiple channels which will be read by multiple join workers. -func (e *HashJoinExec) fetchProbeSideChunks(ctx context.Context) { +func (fetcher *probeSideTupleFetcher) fetchProbeSideChunks(ctx context.Context, maxChunkSize int) { hasWaitedForBuild := false for { - if e.finished.Load().(bool) { + if fetcher.finished.Load() { return } var probeSideResource *probeChkResource var ok bool select { - case <-e.closeCh: + case <-fetcher.closeCh: return - case probeSideResource, ok = <-e.probeChkResourceCh: + case probeSideResource, ok = <-fetcher.probeChkResourceCh: if !ok { return } } probeSideResult := probeSideResource.chk - if e.isOuterJoin { - required := int(atomic.LoadInt64(&e.requiredRows)) - probeSideResult.SetRequiredRows(required, e.maxChunkSize) + if fetcher.isOuterJoin { + required := int(atomic.LoadInt64(&fetcher.requiredRows)) + probeSideResult.SetRequiredRows(required, maxChunkSize) } - err := Next(ctx, e.probeSideExec, probeSideResult) + err := Next(ctx, fetcher.probeSideExec, probeSideResult) failpoint.Inject("ConsumeRandomPanic", nil) if err != nil { - e.joinResultCh <- &hashjoinWorkerResult{ + fetcher.joinResultCh <- &hashjoinWorkerResult{ err: err, } return @@ -234,23 +256,18 @@ func (e *HashJoinExec) fetchProbeSideChunks(ctx context.Context) { probeSideResult.Reset() } }) - if probeSideResult.NumRows() == 0 && !e.useOuterToBuild { - e.finished.Store(true) + if probeSideResult.NumRows() == 0 && !fetcher.useOuterToBuild { + fetcher.finished.Store(true) } - emptyBuild, buildErr := e.wait4BuildSide() + emptyBuild, buildErr := fetcher.wait4BuildSide() if buildErr != nil { - e.joinResultCh <- &hashjoinWorkerResult{ + fetcher.joinResultCh <- &hashjoinWorkerResult{ err: buildErr, } return } else if emptyBuild { return } - // after building is finished. the hash null bucket slice is allocated and determined. - // copy it for multi probe worker. - for i := range e.rowContainerForProbe { - e.rowContainerForProbe[i].hashNANullBucket = e.rowContainer.hashNANullBucket - } hasWaitedForBuild = true } @@ -262,16 +279,16 @@ func (e *HashJoinExec) fetchProbeSideChunks(ctx context.Context) { } } -func (e *HashJoinExec) wait4BuildSide() (emptyBuild bool, err error) { +func (fetcher *probeSideTupleFetcher) wait4BuildSide() (emptyBuild bool, err error) { select { - case <-e.closeCh: + case <-fetcher.closeCh: return true, nil - case err := <-e.buildFinished: + case err := <-fetcher.buildFinished: if err != nil { return false, err } } - if e.rowContainer.Len() == uint64(0) && (e.joinType == plannercore.InnerJoin || e.joinType == plannercore.SemiJoin) { + if fetcher.rowContainer.Len() == uint64(0) && (fetcher.joinType == plannercore.InnerJoin || fetcher.joinType == plannercore.SemiJoin) { return true, nil } return false, nil @@ -279,24 +296,25 @@ func (e *HashJoinExec) wait4BuildSide() (emptyBuild bool, err error) { // fetchBuildSideRows fetches all rows from build side executor, and append them // to e.buildSideResult. -func (e *HashJoinExec) fetchBuildSideRows(ctx context.Context, chkCh chan<- *chunk.Chunk, doneCh <-chan struct{}) { +func (w *buildWorker) fetchBuildSideRows(ctx context.Context, chkCh chan<- *chunk.Chunk, errCh chan<- error, doneCh <-chan struct{}) { defer close(chkCh) var err error failpoint.Inject("issue30289", func(val failpoint.Value) { if val.(bool) { err = errors.Errorf("issue30289 build return error") - e.buildFinished <- errors.Trace(err) + errCh <- errors.Trace(err) return } }) + sessVars := w.hashJoinCtx.sessCtx.GetSessionVars() for { - if e.finished.Load().(bool) { + if w.hashJoinCtx.finished.Load() { return } - chk := chunk.NewChunkWithCapacity(e.buildSideExec.base().retFieldTypes, e.ctx.GetSessionVars().MaxChunkSize) - err = Next(ctx, e.buildSideExec, chk) + chk := sessVars.GetNewChunkWithCapacity(w.buildSideExec.base().retFieldTypes, sessVars.MaxChunkSize, sessVars.MaxChunkSize, w.hashJoinCtx.allocPool) + err = Next(ctx, w.buildSideExec, chk) if err != nil { - e.buildFinished <- errors.Trace(err) + errCh <- errors.Trace(err) return } failpoint.Inject("errorFetchBuildSideRowsMockOOMPanic", nil) @@ -307,7 +325,7 @@ func (e *HashJoinExec) fetchBuildSideRows(ctx context.Context, chkCh chan<- *chu select { case <-doneCh: return - case <-e.closeCh: + case <-w.hashJoinCtx.closeCh: return case chkCh <- chk: } @@ -315,109 +333,99 @@ func (e *HashJoinExec) fetchBuildSideRows(ctx context.Context, chkCh chan<- *chu } func (e *HashJoinExec) initializeForProbe() { - // e.probeResultChs is for transmitting the chunks which store the data of + // e.joinResultCh is for transmitting the join result chunks to the main + // thread. + e.joinResultCh = make(chan *hashjoinWorkerResult, e.concurrency+1) + + e.probeSideTupleFetcher.hashJoinCtx = e.hashJoinCtx + // e.probeSideTupleFetcher.probeResultChs is for transmitting the chunks which store the data of // probeSideExec, it'll be written by probe side worker goroutine, and read by join // workers. - e.probeResultChs = make([]chan *chunk.Chunk, e.concurrency) + e.probeSideTupleFetcher.probeResultChs = make([]chan *chunk.Chunk, e.concurrency) for i := uint(0); i < e.concurrency; i++ { - e.probeResultChs[i] = make(chan *chunk.Chunk, 1) + e.probeSideTupleFetcher.probeResultChs[i] = make(chan *chunk.Chunk, 1) + e.probeWorkers[i].probeResultCh = e.probeSideTupleFetcher.probeResultChs[i] } // e.probeChkResourceCh is for transmitting the used probeSideExec chunks from // join workers to probeSideExec worker. - e.probeChkResourceCh = make(chan *probeChkResource, e.concurrency) + e.probeSideTupleFetcher.probeChkResourceCh = make(chan *probeChkResource, e.concurrency) for i := uint(0); i < e.concurrency; i++ { - e.probeChkResourceCh <- &probeChkResource{ - chk: newFirstChunk(e.probeSideExec), - dest: e.probeResultChs[i], + e.probeSideTupleFetcher.probeChkResourceCh <- &probeChkResource{ + chk: newFirstChunk(e.probeSideTupleFetcher.probeSideExec), + dest: e.probeSideTupleFetcher.probeResultChs[i], } } - // e.joinChkResourceCh is for transmitting the reused join result chunks - // from the main thread to join worker goroutines. - e.joinChkResourceCh = make([]chan *chunk.Chunk, e.concurrency) + // e.probeWorker.joinChkResourceCh is for transmitting the reused join result chunks + // from the main thread to probe worker goroutines. for i := uint(0); i < e.concurrency; i++ { - e.joinChkResourceCh[i] = make(chan *chunk.Chunk, 1) - e.joinChkResourceCh[i] <- newFirstChunk(e) + e.probeWorkers[i].joinChkResourceCh = make(chan *chunk.Chunk, 1) + e.probeWorkers[i].joinChkResourceCh <- newFirstChunk(e) + e.probeWorkers[i].probeChkResourceCh = e.probeSideTupleFetcher.probeChkResourceCh } - - // e.joinResultCh is for transmitting the join result chunks to the main - // thread. - e.joinResultCh = make(chan *hashjoinWorkerResult, e.concurrency+1) - - e.buildSideRows = make([][]chunk.Row, e.concurrency) - e.buildSideRowPtrs = make([][]chunk.RowPtr, e.concurrency) - e.needCheckBuildRowPos = make([][]int, e.concurrency) - e.needCheckProbeRowPos = make([][]int, e.concurrency) } func (e *HashJoinExec) fetchAndProbeHashTable(ctx context.Context) { e.initializeForProbe() - e.joinWorkerWaitGroup.Add(1) - go util.WithRecovery(func() { + e.workerWg.RunWithRecover(func() { defer trace.StartRegion(ctx, "HashJoinProbeSideFetcher").End() - e.fetchProbeSideChunks(ctx) - }, e.handleProbeSideFetcherPanic) - - probeKeyColIdx := make([]int, len(e.probeKeys)) - probeNAKeColIdx := make([]int, len(e.probeNAKeys)) - for i := range e.probeKeys { - probeKeyColIdx[i] = e.probeKeys[i].Index - } - for i := range e.probeNAKeys { - probeNAKeColIdx[i] = e.probeNAKeys[i].Index - } + e.probeSideTupleFetcher.fetchProbeSideChunks(ctx, e.maxChunkSize) + }, e.probeSideTupleFetcher.handleProbeSideFetcherPanic) for i := uint(0); i < e.concurrency; i++ { - e.joinWorkerWaitGroup.Add(1) - workID := i - go util.WithRecovery(func() { + workerID := i + e.workerWg.RunWithRecover(func() { defer trace.StartRegion(ctx, "HashJoinWorker").End() - e.runJoinWorker(workID, probeKeyColIdx, probeNAKeColIdx) - }, e.handleJoinWorkerPanic) + e.probeWorkers[workerID].runJoinWorker() + }, e.probeWorkers[workerID].handleProbeWorkerPanic) } - go util.WithRecovery(e.waitJoinWorkersAndCloseResultChan, nil) + e.waiterWg.RunWithRecover(e.waitJoinWorkersAndCloseResultChan, nil) } -func (e *HashJoinExec) handleProbeSideFetcherPanic(r interface{}) { - for i := range e.probeResultChs { - close(e.probeResultChs[i]) +func (fetcher *probeSideTupleFetcher) handleProbeSideFetcherPanic(r interface{}) { + for i := range fetcher.probeResultChs { + close(fetcher.probeResultChs[i]) } if r != nil { - e.joinResultCh <- &hashjoinWorkerResult{err: errors.Errorf("%v", r)} + fetcher.joinResultCh <- &hashjoinWorkerResult{err: errors.Errorf("%v", r)} + } +} + +func (w *probeWorker) handleProbeWorkerPanic(r interface{}) { + if r != nil { + w.hashJoinCtx.joinResultCh <- &hashjoinWorkerResult{err: errors.Errorf("probeWorker[%d] meets error: %v", w.workerID, r)} } - e.joinWorkerWaitGroup.Done() } func (e *HashJoinExec) handleJoinWorkerPanic(r interface{}) { if r != nil { e.joinResultCh <- &hashjoinWorkerResult{err: errors.Errorf("%v", r)} } - e.joinWorkerWaitGroup.Done() } // Concurrently handling unmatched rows from the hash table -func (e *HashJoinExec) handleUnmatchedRowsFromHashTable(workerID uint) { - ok, joinResult := e.getNewJoinResult(workerID) +func (w *probeWorker) handleUnmatchedRowsFromHashTable() { + ok, joinResult := w.getNewJoinResult() if !ok { return } - numChks := e.rowContainer.NumChunks() - for i := int(workerID); i < numChks; i += int(e.concurrency) { - chk, err := e.rowContainer.GetChunk(i) + numChks := w.rowContainerForProbe.NumChunks() + for i := int(w.workerID); i < numChks; i += int(w.hashJoinCtx.concurrency) { + chk, err := w.rowContainerForProbe.GetChunk(i) if err != nil { // Catching the error and send it joinResult.err = err - e.joinResultCh <- joinResult + w.hashJoinCtx.joinResultCh <- joinResult return } for j := 0; j < chk.NumRows(); j++ { - if !e.outerMatchedStatus[i].UnsafeIsSet(j) { // process unmatched outer rows - e.joiners[workerID].onMissMatch(false, chk.GetRow(j), joinResult.chk) + if !w.hashJoinCtx.outerMatchedStatus[i].UnsafeIsSet(j) { // process unmatched outer rows + w.joiner.onMissMatch(false, chk.GetRow(j), joinResult.chk) } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return } @@ -428,33 +436,32 @@ func (e *HashJoinExec) handleUnmatchedRowsFromHashTable(workerID uint) { if joinResult == nil { return } else if joinResult.err != nil || (joinResult.chk != nil && joinResult.chk.NumRows() > 0) { - e.joinResultCh <- joinResult + w.hashJoinCtx.joinResultCh <- joinResult } } func (e *HashJoinExec) waitJoinWorkersAndCloseResultChan() { - e.joinWorkerWaitGroup.Wait() + e.workerWg.Wait() if e.useOuterToBuild { // Concurrently handling unmatched rows from the hash table at the tail for i := uint(0); i < e.concurrency; i++ { var workerID = i - e.joinWorkerWaitGroup.Add(1) - go util.WithRecovery(func() { e.handleUnmatchedRowsFromHashTable(workerID) }, e.handleJoinWorkerPanic) + e.workerWg.RunWithRecover(func() { e.probeWorkers[workerID].handleUnmatchedRowsFromHashTable() }, e.handleJoinWorkerPanic) } - e.joinWorkerWaitGroup.Wait() + e.workerWg.Wait() } close(e.joinResultCh) } -func (e *HashJoinExec) runJoinWorker(workerID uint, probeKeyColIdx, probeNAKeyColIdx []int) { +func (w *probeWorker) runJoinWorker() { probeTime := int64(0) - if e.stats != nil { + if w.hashJoinCtx.stats != nil { start := time.Now() defer func() { t := time.Since(start) - atomic.AddInt64(&e.stats.probe, probeTime) - atomic.AddInt64(&e.stats.fetchAndProbe, int64(t)) - e.stats.setMaxFetchAndProbeTime(int64(t)) + atomic.AddInt64(&w.hashJoinCtx.stats.probe, probeTime) + atomic.AddInt64(&w.hashJoinCtx.stats.fetchAndProbe, int64(t)) + w.hashJoinCtx.stats.setMaxFetchAndProbeTime(int64(t)) }() } @@ -462,38 +469,38 @@ func (e *HashJoinExec) runJoinWorker(workerID uint, probeKeyColIdx, probeNAKeyCo probeSideResult *chunk.Chunk selected = make([]bool, 0, chunk.InitialCapacity) ) - ok, joinResult := e.getNewJoinResult(workerID) + ok, joinResult := w.getNewJoinResult() if !ok { return } // Read and filter probeSideResult, and join the probeSideResult with the build side rows. emptyProbeSideResult := &probeChkResource{ - dest: e.probeResultChs[workerID], + dest: w.probeResultCh, } hCtx := &hashContext{ - allTypes: e.probeTypes, - keyColIdx: probeKeyColIdx, - naKeyColIdx: probeNAKeyColIdx, + allTypes: w.hashJoinCtx.probeTypes, + keyColIdx: w.probeKeyColIdx, + naKeyColIdx: w.probeNAKeyColIdx, } for ok := true; ok; { - if e.finished.Load().(bool) { + if w.hashJoinCtx.finished.Load() { break } select { - case <-e.closeCh: + case <-w.hashJoinCtx.closeCh: return - case probeSideResult, ok = <-e.probeResultChs[workerID]: + case probeSideResult, ok = <-w.probeResultCh: } failpoint.Inject("ConsumeRandomPanic", nil) if !ok { break } start := time.Now() - if e.useOuterToBuild { - ok, joinResult = e.join2ChunkForOuterHashJoin(workerID, probeSideResult, hCtx, e.rowContainerForProbe[workerID], joinResult) + if w.hashJoinCtx.useOuterToBuild { + ok, joinResult = w.join2ChunkForOuterHashJoin(probeSideResult, hCtx, joinResult) } else { - ok, joinResult = e.join2Chunk(workerID, probeSideResult, hCtx, e.rowContainerForProbe[workerID], joinResult, selected) + ok, joinResult = w.join2Chunk(probeSideResult, hCtx, joinResult, selected) } probeTime += int64(time.Since(start)) if !ok { @@ -501,22 +508,22 @@ func (e *HashJoinExec) runJoinWorker(workerID uint, probeKeyColIdx, probeNAKeyCo } probeSideResult.Reset() emptyProbeSideResult.chk = probeSideResult - e.probeChkResourceCh <- emptyProbeSideResult + w.probeChkResourceCh <- emptyProbeSideResult } // note joinResult.chk may be nil when getNewJoinResult fails in loops if joinResult == nil { return } else if joinResult.err != nil || (joinResult.chk != nil && joinResult.chk.NumRows() > 0) { - e.joinResultCh <- joinResult + w.hashJoinCtx.joinResultCh <- joinResult } else if joinResult.chk != nil && joinResult.chk.NumRows() == 0 { - e.joinChkResourceCh[workerID] <- joinResult.chk + w.joinChkResourceCh <- joinResult.chk } } -func (e *HashJoinExec) joinMatchedProbeSideRow2ChunkForOuterHashJoin(workerID uint, probeKey uint64, probeSideRow chunk.Row, hCtx *hashContext, rowContainer *hashRowContainer, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { +func (w *probeWorker) joinMatchedProbeSideRow2ChunkForOuterHashJoin(probeKey uint64, probeSideRow chunk.Row, hCtx *hashContext, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { var err error - e.buildSideRows[workerID], e.buildSideRowPtrs[workerID], err = rowContainer.GetMatchedRowsAndPtrs(probeKey, probeSideRow, hCtx, e.buildSideRows[workerID], e.buildSideRowPtrs[workerID], true) - buildSideRows, rowsPtrs := e.buildSideRows[workerID], e.buildSideRowPtrs[workerID] + w.buildSideRows, w.buildSideRowPtrs, err = w.rowContainerForProbe.GetMatchedRowsAndPtrs(probeKey, probeSideRow, hCtx, w.buildSideRows, w.buildSideRowPtrs, true) + buildSideRows, rowsPtrs := w.buildSideRows, w.buildSideRowPtrs if err != nil { joinResult.err = err return false, joinResult @@ -525,25 +532,25 @@ func (e *HashJoinExec) joinMatchedProbeSideRow2ChunkForOuterHashJoin(workerID ui return true, joinResult } - iter := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter) + iter := w.rowIters + iter.Reset(buildSideRows) var outerMatchStatus []outerRowStatusFlag rowIdx, ok := 0, false for iter.Begin(); iter.Current() != iter.End(); { - outerMatchStatus, err = e.joiners[workerID].tryToMatchOuters(iter, probeSideRow, joinResult.chk, outerMatchStatus) + outerMatchStatus, err = w.joiner.tryToMatchOuters(iter, probeSideRow, joinResult.chk, outerMatchStatus) if err != nil { joinResult.err = err return false, joinResult } for i := range outerMatchStatus { if outerMatchStatus[i] == outerRowMatched { - e.outerMatchedStatus[rowsPtrs[rowIdx+i].ChkIdx].Set(int(rowsPtrs[rowIdx+i].RowIdx)) + w.hashJoinCtx.outerMatchedStatus[rowsPtrs[rowIdx+i].ChkIdx].Set(int(rowsPtrs[rowIdx+i].RowIdx)) } } rowIdx += len(outerMatchStatus) if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -553,8 +560,7 @@ func (e *HashJoinExec) joinMatchedProbeSideRow2ChunkForOuterHashJoin(workerID ui } // joinNAALOSJMatchProbeSideRow2Chunk implement the matching logic for NA-AntiLeftOuterSemiJoin -func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKey uint64, probeKeyNullBits *bitmap.ConcurrentBitmap, probeSideRow chunk.Row, hCtx *hashContext, - rowContainer *hashRowContainer, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { +func (w *probeWorker) joinNAALOSJMatchProbeSideRow2Chunk(probeKey uint64, probeKeyNullBits *bitmap.ConcurrentBitmap, probeSideRow chunk.Row, hCtx *hashContext, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { var ( err error ok bool @@ -564,17 +570,17 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe // because AntiLeftOuterSemiJoin cares about the scalar value. If we both have a match from null // bucket and same key bucket, we should return the result as from same-key bucket // rather than from null bucket. - e.buildSideRows[workerID], err = rowContainer.GetMatchedRows(probeKey, probeSideRow, hCtx, e.buildSideRows[workerID]) - buildSideRows := e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetMatchedRows(probeKey, probeSideRow, hCtx, w.buildSideRows) + buildSideRows := w.buildSideRows if err != nil { joinResult.err = err return false, joinResult } if len(buildSideRows) != 0 { - iter1 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter1) + iter1 := w.rowIters + iter1.Reset(buildSideRows) for iter1.Begin(); iter1.Current() != iter1.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter1, joinResult.chk, LeftNotNullRightNotNull) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter1, joinResult.chk, LeftNotNullRightNotNull) if err != nil { joinResult.err = err return false, joinResult @@ -585,8 +591,8 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -594,8 +600,8 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe } } // step2: match the null bucket secondly. - e.buildSideRows[workerID], err = rowContainer.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, e.buildSideRows[workerID], e.needCheckBuildRowPos[workerID], e.needCheckProbeRowPos[workerID]) - buildSideRows = e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, w.buildSideRows, w.needCheckBuildRowPos, w.needCheckProbeRowPos) + buildSideRows = w.buildSideRows if err != nil { joinResult.err = err return false, joinResult @@ -603,13 +609,13 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe if len(buildSideRows) == 0 { // when reach here, it means we couldn't find a valid same key match from same-key bucket yet // and the null bucket is empty. so the result should be . - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } - iter2 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter2) + iter2 := w.rowIters + iter2.Reset(buildSideRows) for iter2.Begin(); iter2.Current() != iter2.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter2, joinResult.chk, LeftNotNullRightHasNull) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter2, joinResult.chk, LeftNotNullRightHasNull) if err != nil { joinResult.err = err return false, joinResult @@ -620,8 +626,8 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -631,7 +637,7 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe // case1: x NOT IN (empty set): if other key bucket don't have the valid rows yet. // case2: x NOT IN (l,m,n...): if other key bucket do have the valid rows. // both cases mean the result should be - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } // when left side has null values, all we want is to find a valid build side rows (past other condition) @@ -639,17 +645,17 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe // case1: NOT IN (empty set): ----------------------> result is . // case2: NOT IN (at least a valid inner row) ------------------> result is . // Step1: match null bucket (assumption that null bucket is quite smaller than all hash table bucket rows) - e.buildSideRows[workerID], err = rowContainer.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, e.buildSideRows[workerID], e.needCheckBuildRowPos[workerID], e.needCheckProbeRowPos[workerID]) - buildSideRows := e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, w.buildSideRows, w.needCheckBuildRowPos, w.needCheckProbeRowPos) + buildSideRows := w.buildSideRows if err != nil { joinResult.err = err return false, joinResult } if len(buildSideRows) != 0 { - iter1 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter1) + iter1 := w.rowIters + iter1.Reset(buildSideRows) for iter1.Begin(); iter1.Current() != iter1.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter1, joinResult.chk, LeftHasNullRightHasNull) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter1, joinResult.chk, LeftHasNullRightHasNull) if err != nil { joinResult.err = err return false, joinResult @@ -660,8 +666,8 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -669,8 +675,8 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe } } // Step2: match all hash table bucket build rows (use probeKeyNullBits to filter if any). - e.buildSideRows[workerID], err = rowContainer.GetAllMatchedRows(hCtx, probeSideRow, probeKeyNullBits, e.buildSideRows[workerID], e.needCheckBuildRowPos[workerID], e.needCheckProbeRowPos[workerID]) - buildSideRows = e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetAllMatchedRows(hCtx, probeSideRow, probeKeyNullBits, w.buildSideRows, w.needCheckBuildRowPos, w.needCheckProbeRowPos) + buildSideRows = w.buildSideRows if err != nil { joinResult.err = err return false, joinResult @@ -678,13 +684,13 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe if len(buildSideRows) == 0 { // when reach here, it means we couldn't return it quickly in null bucket, and same-bucket is empty, // which means x NOT IN (empty set) or x NOT IN (l,m,n), the result should be - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } - iter2 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter2) + iter2 := w.rowIters + iter2.Reset(buildSideRows) for iter2.Begin(); iter2.Current() != iter2.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter2, joinResult.chk, LeftHasNullRightNotNull) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter2, joinResult.chk, LeftHasNullRightNotNull) if err != nil { joinResult.err = err return false, joinResult @@ -695,8 +701,8 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -705,13 +711,12 @@ func (e *HashJoinExec) joinNAALOSJMatchProbeSideRow2Chunk(workerID uint, probeKe // step3: if we couldn't return it quickly in null bucket and all hash bucket, here means only one cases: // case1: NOT IN (empty set): // empty set comes from no rows from all bucket can pass other condition. the result should be - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } // joinNAASJMatchProbeSideRow2Chunk implement the matching logic for NA-AntiSemiJoin -func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey uint64, probeKeyNullBits *bitmap.ConcurrentBitmap, probeSideRow chunk.Row, hCtx *hashContext, - rowContainer *hashRowContainer, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { +func (w *probeWorker) joinNAASJMatchProbeSideRow2Chunk(probeKey uint64, probeKeyNullBits *bitmap.ConcurrentBitmap, probeSideRow chunk.Row, hCtx *hashContext, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { var ( err error ok bool @@ -719,17 +724,17 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey if probeKeyNullBits == nil { // step1: match null bucket first. // need fetch the "valid" rows every time. (nullBits map check is necessary) - e.buildSideRows[workerID], err = rowContainer.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, e.buildSideRows[workerID], e.needCheckBuildRowPos[workerID], e.needCheckProbeRowPos[workerID]) - buildSideRows := e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, w.buildSideRows, w.needCheckBuildRowPos, w.needCheckProbeRowPos) + buildSideRows := w.buildSideRows if err != nil { joinResult.err = err return false, joinResult } if len(buildSideRows) != 0 { - iter1 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter1) + iter1 := w.rowIters + iter1.Reset(buildSideRows) for iter1.Begin(); iter1.Current() != iter1.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter1, joinResult.chk) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter1, joinResult.chk) if err != nil { joinResult.err = err return false, joinResult @@ -740,8 +745,8 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -749,8 +754,8 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey } } // step2: then same key bucket. - e.buildSideRows[workerID], err = rowContainer.GetMatchedRows(probeKey, probeSideRow, hCtx, e.buildSideRows[workerID]) - buildSideRows = e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetMatchedRows(probeKey, probeSideRow, hCtx, w.buildSideRows) + buildSideRows = w.buildSideRows if err != nil { joinResult.err = err return false, joinResult @@ -758,13 +763,13 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey if len(buildSideRows) == 0 { // when reach here, it means we couldn't return it quickly in null bucket, and same-bucket is empty, // which means x NOT IN (empty set), accept the rhs row. - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } - iter2 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter2) + iter2 := w.rowIters + iter2.Reset(buildSideRows) for iter2.Begin(); iter2.Current() != iter2.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter2, joinResult.chk) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter2, joinResult.chk) if err != nil { joinResult.err = err return false, joinResult @@ -775,8 +780,8 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -786,7 +791,7 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey // case1: x NOT IN (empty set): if other key bucket don't have the valid rows yet. // case2: x NOT IN (l,m,n...): if other key bucket do have the valid rows. // both cases should accept the rhs row. - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } // when left side has null values, all we want is to find a valid build side rows (passed from other condition) @@ -794,17 +799,17 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey // case1: NOT IN (empty set): ----------------------> accept rhs row. // case2: NOT IN (at least a valid inner row) ------------------> unknown result, refuse rhs row. // Step1: match null bucket (assumption that null bucket is quite smaller than all hash table bucket rows) - e.buildSideRows[workerID], err = rowContainer.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, e.buildSideRows[workerID], e.needCheckBuildRowPos[workerID], e.needCheckProbeRowPos[workerID]) - buildSideRows := e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetNullBucketRows(hCtx, probeSideRow, probeKeyNullBits, w.buildSideRows, w.needCheckBuildRowPos, w.needCheckProbeRowPos) + buildSideRows := w.buildSideRows if err != nil { joinResult.err = err return false, joinResult } if len(buildSideRows) != 0 { - iter1 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter1) + iter1 := w.rowIters + iter1.Reset(buildSideRows) for iter1.Begin(); iter1.Current() != iter1.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter1, joinResult.chk) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter1, joinResult.chk) if err != nil { joinResult.err = err return false, joinResult @@ -815,8 +820,8 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -824,8 +829,8 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey } } // Step2: match all hash table bucket build rows. - e.buildSideRows[workerID], err = rowContainer.GetAllMatchedRows(hCtx, probeSideRow, probeKeyNullBits, e.buildSideRows[workerID], e.needCheckBuildRowPos[workerID], e.needCheckProbeRowPos[workerID]) - buildSideRows = e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetAllMatchedRows(hCtx, probeSideRow, probeKeyNullBits, w.buildSideRows, w.needCheckBuildRowPos, w.needCheckProbeRowPos) + buildSideRows = w.buildSideRows if err != nil { joinResult.err = err return false, joinResult @@ -833,13 +838,13 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey if len(buildSideRows) == 0 { // when reach here, it means we couldn't return it quickly in null bucket, and same-bucket is empty, // which means NOT IN (empty set) or NOT IN (no valid rows) accept the rhs row. - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } - iter2 := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter2) + iter2 := w.rowIters + iter2.Reset(buildSideRows) for iter2.Begin(); iter2.Current() != iter2.End(); { - matched, _, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter2, joinResult.chk) + matched, _, err := w.joiner.tryToMatchInners(probeSideRow, iter2, joinResult.chk) if err != nil { joinResult.err = err return false, joinResult @@ -850,8 +855,8 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey return true, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -860,7 +865,7 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey // step3: if we couldn't return it quickly in null bucket and all hash bucket, here means only one cases: // case1: NOT IN (empty set): // empty set comes from no rows from all bucket can pass other condition. we should accept the rhs row. - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } @@ -883,38 +888,37 @@ func (e *HashJoinExec) joinNAASJMatchProbeSideRow2Chunk(workerID uint, probeKey // // For NA-AntiLeftOuterSemiJoin, we couldn't match null-bucket first, because once y set has a same key x and null // key, we should return the result as left side row appended with a scalar value 0 which is from same key matching failure. -func (e *HashJoinExec) joinNAAJMatchProbeSideRow2Chunk(workerID uint, probeKey uint64, probeKeyNullBits *bitmap.ConcurrentBitmap, probeSideRow chunk.Row, hCtx *hashContext, - rowContainer *hashRowContainer, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { - NAAntiSemiJoin := e.joinType == plannercore.AntiSemiJoin && len(e.buildNAKeys) > 0 - NAAntiLeftOuterSemiJoin := e.joinType == plannercore.AntiLeftOuterSemiJoin && len(e.buildNAKeys) > 0 +func (w *probeWorker) joinNAAJMatchProbeSideRow2Chunk(probeKey uint64, probeKeyNullBits *bitmap.ConcurrentBitmap, probeSideRow chunk.Row, hCtx *hashContext, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { + NAAntiSemiJoin := w.hashJoinCtx.joinType == plannercore.AntiSemiJoin && w.hashJoinCtx.isNullAware + NAAntiLeftOuterSemiJoin := w.hashJoinCtx.joinType == plannercore.AntiLeftOuterSemiJoin && w.hashJoinCtx.isNullAware if NAAntiSemiJoin { - return e.joinNAASJMatchProbeSideRow2Chunk(workerID, probeKey, probeKeyNullBits, probeSideRow, hCtx, rowContainer, joinResult) + return w.joinNAASJMatchProbeSideRow2Chunk(probeKey, probeKeyNullBits, probeSideRow, hCtx, joinResult) } if NAAntiLeftOuterSemiJoin { - return e.joinNAALOSJMatchProbeSideRow2Chunk(workerID, probeKey, probeKeyNullBits, probeSideRow, hCtx, rowContainer, joinResult) + return w.joinNAALOSJMatchProbeSideRow2Chunk(probeKey, probeKeyNullBits, probeSideRow, hCtx, joinResult) } // shouldn't be here, not a valid NAAJ. return false, joinResult } -func (e *HashJoinExec) joinMatchedProbeSideRow2Chunk(workerID uint, probeKey uint64, probeSideRow chunk.Row, hCtx *hashContext, - rowContainer *hashRowContainer, joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { +func (w *probeWorker) joinMatchedProbeSideRow2Chunk(probeKey uint64, probeSideRow chunk.Row, hCtx *hashContext, + joinResult *hashjoinWorkerResult) (bool, *hashjoinWorkerResult) { var err error - e.buildSideRows[workerID], err = rowContainer.GetMatchedRows(probeKey, probeSideRow, hCtx, e.buildSideRows[workerID]) - buildSideRows := e.buildSideRows[workerID] + w.buildSideRows, err = w.rowContainerForProbe.GetMatchedRows(probeKey, probeSideRow, hCtx, w.buildSideRows) + buildSideRows := w.buildSideRows if err != nil { joinResult.err = err return false, joinResult } if len(buildSideRows) == 0 { - e.joiners[workerID].onMissMatch(false, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(false, probeSideRow, joinResult.chk) return true, joinResult } - iter := chunk.NewIterator4Slice(buildSideRows) - defer chunk.FreeIterator(iter) + iter := w.rowIters + iter.Reset(buildSideRows) hasMatch, hasNull, ok := false, false, false for iter.Begin(); iter.Current() != iter.End(); { - matched, isNull, err := e.joiners[workerID].tryToMatchInners(probeSideRow, iter, joinResult.chk) + matched, isNull, err := w.joiner.tryToMatchInners(probeSideRow, iter, joinResult.chk) if err != nil { joinResult.err = err return false, joinResult @@ -923,36 +927,36 @@ func (e *HashJoinExec) joinMatchedProbeSideRow2Chunk(workerID uint, probeKey uin hasNull = hasNull || isNull if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } } } if !hasMatch { - e.joiners[workerID].onMissMatch(hasNull, probeSideRow, joinResult.chk) + w.joiner.onMissMatch(hasNull, probeSideRow, joinResult.chk) } return true, joinResult } -func (e *HashJoinExec) getNewJoinResult(workerID uint) (bool, *hashjoinWorkerResult) { +func (w *probeWorker) getNewJoinResult() (bool, *hashjoinWorkerResult) { joinResult := &hashjoinWorkerResult{ - src: e.joinChkResourceCh[workerID], + src: w.joinChkResourceCh, } ok := true select { - case <-e.closeCh: + case <-w.hashJoinCtx.closeCh: ok = false - case joinResult.chk, ok = <-e.joinChkResourceCh[workerID]: + case joinResult.chk, ok = <-w.joinChkResourceCh: } return ok, joinResult } -func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx *hashContext, rowContainer *hashRowContainer, joinResult *hashjoinWorkerResult, +func (w *probeWorker) join2Chunk(probeSideChk *chunk.Chunk, hCtx *hashContext, joinResult *hashjoinWorkerResult, selected []bool) (ok bool, _ *hashjoinWorkerResult) { var err error - selected, err = expression.VectorizedFilter(e.ctx, e.outerFilter, chunk.NewIterator4Chunk(probeSideChk), selected) + selected, err = expression.VectorizedFilter(w.hashJoinCtx.sessCtx, w.hashJoinCtx.outerFilter, chunk.NewIterator4Chunk(probeSideChk), selected) if err != nil { joinResult.err = err return false, joinResult @@ -963,8 +967,8 @@ func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx // By now, path 1 and 2 won't be conducted at the same time. // 1: write the row data of join key to hashVals. (normal EQ key should ignore the null values.) null-EQ for Except statement is an exception. for keyIdx, i := range hCtx.keyColIdx { - ignoreNull := len(e.isNullEQ) > keyIdx && e.isNullEQ[keyIdx] - err = codec.HashChunkSelected(rowContainer.sc, hCtx.hashVals, probeSideChk, hCtx.allTypes[keyIdx], i, hCtx.buf, hCtx.hasNull, selected, ignoreNull) + ignoreNull := len(w.hashJoinCtx.isNullEQ) > keyIdx && w.hashJoinCtx.isNullEQ[keyIdx] + err = codec.HashChunkSelected(w.rowContainerForProbe.sc, hCtx.hashVals, probeSideChk, hCtx.allTypes[keyIdx], i, hCtx.buf, hCtx.hasNull, selected, ignoreNull) if err != nil { joinResult.err = err return false, joinResult @@ -974,7 +978,7 @@ func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx isNAAJ := len(hCtx.naKeyColIdx) > 0 for keyIdx, i := range hCtx.naKeyColIdx { // NAAJ won't ignore any null values, but collect them up to probe. - err = codec.HashChunkSelected(rowContainer.sc, hCtx.hashVals, probeSideChk, hCtx.allTypes[keyIdx], i, hCtx.buf, hCtx.hasNull, selected, false) + err = codec.HashChunkSelected(w.rowContainerForProbe.sc, hCtx.hashVals, probeSideChk, hCtx.allTypes[keyIdx], i, hCtx.buf, hCtx.hasNull, selected, false) if err != nil { joinResult.err = err return false, joinResult @@ -992,7 +996,7 @@ func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx } for i := range selected { - killed := atomic.LoadUint32(&e.ctx.GetSessionVars().Killed) == 1 + killed := atomic.LoadUint32(&w.hashJoinCtx.sessCtx.GetSessionVars().Killed) == 1 failpoint.Inject("killedInJoin2Chunk", func(val failpoint.Value) { if val.(bool) { killed = true @@ -1005,13 +1009,13 @@ func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx if isNAAJ { if !selected[i] { // since this is the case of using inner to build, so for an outer row unselected, we should fill the result when it's outer join. - e.joiners[workerID].onMissMatch(false, probeSideChk.GetRow(i), joinResult.chk) + w.joiner.onMissMatch(false, probeSideChk.GetRow(i), joinResult.chk) } if hCtx.naHasNull[i] { // here means the probe join connecting column has null value in it and this is special for matching all the hash buckets // for it. (probeKey is not necessary here) probeRow := probeSideChk.GetRow(i) - ok, joinResult = e.joinNAAJMatchProbeSideRow2Chunk(workerID, 0, hCtx.naColNullBitMap[i].Clone(), probeRow, hCtx, rowContainer, joinResult) + ok, joinResult = w.joinNAAJMatchProbeSideRow2Chunk(0, hCtx.naColNullBitMap[i].Clone(), probeRow, hCtx, joinResult) if !ok { return false, joinResult } @@ -1019,7 +1023,7 @@ func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx // here means the probe join connecting column without null values, where we should match same key bucket and null bucket for it at its order. // step1: process same key matched probe side rows probeKey, probeRow := hCtx.hashVals[i].Sum64(), probeSideChk.GetRow(i) - ok, joinResult = e.joinNAAJMatchProbeSideRow2Chunk(workerID, probeKey, nil, probeRow, hCtx, rowContainer, joinResult) + ok, joinResult = w.joinNAAJMatchProbeSideRow2Chunk(probeKey, nil, probeRow, hCtx, joinResult) if !ok { return false, joinResult } @@ -1027,18 +1031,18 @@ func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx } else { // since this is the case of using inner to build, so for an outer row unselected, we should fill the result when it's outer join. if !selected[i] || hCtx.hasNull[i] { // process unmatched probe side rows - e.joiners[workerID].onMissMatch(false, probeSideChk.GetRow(i), joinResult.chk) + w.joiner.onMissMatch(false, probeSideChk.GetRow(i), joinResult.chk) } else { // process matched probe side rows probeKey, probeRow := hCtx.hashVals[i].Sum64(), probeSideChk.GetRow(i) - ok, joinResult = e.joinMatchedProbeSideRow2Chunk(workerID, probeKey, probeRow, hCtx, rowContainer, joinResult) + ok, joinResult = w.joinMatchedProbeSideRow2Chunk(probeKey, probeRow, hCtx, joinResult) if !ok { return false, joinResult } } } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -1048,17 +1052,17 @@ func (e *HashJoinExec) join2Chunk(workerID uint, probeSideChk *chunk.Chunk, hCtx } // join2ChunkForOuterHashJoin joins chunks when using the outer to build a hash table (refer to outer hash join) -func (e *HashJoinExec) join2ChunkForOuterHashJoin(workerID uint, probeSideChk *chunk.Chunk, hCtx *hashContext, rowContainer *hashRowContainer, joinResult *hashjoinWorkerResult) (ok bool, _ *hashjoinWorkerResult) { +func (w *probeWorker) join2ChunkForOuterHashJoin(probeSideChk *chunk.Chunk, hCtx *hashContext, joinResult *hashjoinWorkerResult) (ok bool, _ *hashjoinWorkerResult) { hCtx.initHash(probeSideChk.NumRows()) for keyIdx, i := range hCtx.keyColIdx { - err := codec.HashChunkColumns(rowContainer.sc, hCtx.hashVals, probeSideChk, hCtx.allTypes[keyIdx], i, hCtx.buf, hCtx.hasNull) + err := codec.HashChunkColumns(w.rowContainerForProbe.sc, hCtx.hashVals, probeSideChk, hCtx.allTypes[keyIdx], i, hCtx.buf, hCtx.hasNull) if err != nil { joinResult.err = err return false, joinResult } } for i := 0; i < probeSideChk.NumRows(); i++ { - killed := atomic.LoadUint32(&e.ctx.GetSessionVars().Killed) == 1 + killed := atomic.LoadUint32(&w.hashJoinCtx.sessCtx.GetSessionVars().Killed) == 1 failpoint.Inject("killedInJoin2ChunkForOuterHashJoin", func(val failpoint.Value) { if val.(bool) { killed = true @@ -1069,13 +1073,13 @@ func (e *HashJoinExec) join2ChunkForOuterHashJoin(workerID uint, probeSideChk *c return false, joinResult } probeKey, probeRow := hCtx.hashVals[i].Sum64(), probeSideChk.GetRow(i) - ok, joinResult = e.joinMatchedProbeSideRow2ChunkForOuterHashJoin(workerID, probeKey, probeRow, hCtx, rowContainer, joinResult) + ok, joinResult = w.joinMatchedProbeSideRow2ChunkForOuterHashJoin(probeKey, probeRow, hCtx, joinResult) if !ok { return false, joinResult } if joinResult.chk.IsFull() { - e.joinResultCh <- joinResult - ok, joinResult = e.getNewJoinResult(workerID) + w.hashJoinCtx.joinResultCh <- joinResult + ok, joinResult = w.getNewJoinResult() if !ok { return false, joinResult } @@ -1091,30 +1095,24 @@ func (e *HashJoinExec) join2ChunkForOuterHashJoin(workerID uint, probeSideChk *c func (e *HashJoinExec) Next(ctx context.Context, req *chunk.Chunk) (err error) { if !e.prepared { e.buildFinished = make(chan error, 1) - buildKeyColIdx := make([]int, len(e.buildKeys)) - for i := range e.buildKeys { - buildKeyColIdx[i] = e.buildKeys[i].Index - } - buildNAKeyColIdx := make([]int, len(e.buildNAKeys)) - for i := range e.buildNAKeys { - buildNAKeyColIdx[i] = e.buildNAKeys[i].Index - } hCtx := &hashContext{ allTypes: e.buildTypes, - keyColIdx: buildKeyColIdx, - naKeyColIdx: buildNAKeyColIdx, + keyColIdx: e.buildWorker.buildKeyColIdx, + naKeyColIdx: e.buildWorker.buildNAKeyColIdx, } - e.rowContainer = newHashRowContainer(e.ctx, int(e.buildSideEstCount), hCtx, retTypes(e.buildSideExec)) + e.rowContainer = newHashRowContainer(e.ctx, hCtx, retTypes(e.buildWorker.buildSideExec)) // we shallow copies rowContainer for each probe worker to avoid lock contention - e.rowContainerForProbe = make([]*hashRowContainer, e.concurrency) for i := uint(0); i < e.concurrency; i++ { if i == 0 { - e.rowContainerForProbe[i] = e.rowContainer + e.probeWorkers[i].rowContainerForProbe = e.rowContainer } else { - e.rowContainerForProbe[i] = e.rowContainer.ShallowCopy() + e.probeWorkers[i].rowContainerForProbe = e.rowContainer.ShallowCopy() } } - go util.WithRecovery(func() { + for i := uint(0); i < e.concurrency; i++ { + e.probeWorkers[i].rowIters = chunk.NewIterator4Slice([]chunk.Row{}).(*chunk.Iterator4Slice) + } + e.workerWg.RunWithRecover(func() { defer trace.StartRegion(ctx, "HashJoinHashTableBuilder").End() e.fetchAndBuildHashTable(ctx) }, e.handleFetchAndBuildHashTablePanic) @@ -1122,7 +1120,7 @@ func (e *HashJoinExec) Next(ctx context.Context, req *chunk.Chunk) (err error) { e.prepared = true } if e.isOuterJoin { - atomic.StoreInt64(&e.requiredRows, int64(req.RequiredRows())) + atomic.StoreInt64(&e.probeSideTupleFetcher.requiredRows, int64(req.RequiredRows())) } req.Reset() @@ -1157,10 +1155,10 @@ func (e *HashJoinExec) fetchAndBuildHashTable(ctx context.Context) { buildSideResultCh := make(chan *chunk.Chunk, 1) doneCh := make(chan struct{}) fetchBuildSideRowsOk := make(chan error, 1) - go util.WithRecovery( + e.workerWg.RunWithRecover( func() { defer trace.StartRegion(ctx, "HashJoinBuildSideFetcher").End() - e.fetchBuildSideRows(ctx, buildSideResultCh, doneCh) + e.buildWorker.fetchBuildSideRows(ctx, buildSideResultCh, fetchBuildSideRowsOk, doneCh) }, func(r interface{}) { if r != nil { @@ -1171,7 +1169,7 @@ func (e *HashJoinExec) fetchAndBuildHashTable(ctx context.Context) { ) // TODO: Parallel build hash table. Currently not support because `unsafeHashTable` is not thread-safe. - err := e.buildHashTableForList(buildSideResultCh) + err := e.buildWorker.buildHashTableForList(buildSideResultCh) if err != nil { e.buildFinished <- errors.Trace(err) close(doneCh) @@ -1189,41 +1187,42 @@ func (e *HashJoinExec) fetchAndBuildHashTable(ctx context.Context) { } // buildHashTableForList builds hash table from `list`. -func (e *HashJoinExec) buildHashTableForList(buildSideResultCh <-chan *chunk.Chunk) error { +func (w *buildWorker) buildHashTableForList(buildSideResultCh <-chan *chunk.Chunk) error { var err error var selected []bool - e.rowContainer.GetMemTracker().AttachTo(e.memTracker) - e.rowContainer.GetMemTracker().SetLabel(memory.LabelForBuildSideResult) - e.rowContainer.GetDiskTracker().AttachTo(e.diskTracker) - e.rowContainer.GetDiskTracker().SetLabel(memory.LabelForBuildSideResult) + rowContainer := w.hashJoinCtx.rowContainer + rowContainer.GetMemTracker().AttachTo(w.hashJoinCtx.memTracker) + rowContainer.GetMemTracker().SetLabel(memory.LabelForBuildSideResult) + rowContainer.GetDiskTracker().AttachTo(w.hashJoinCtx.diskTracker) + rowContainer.GetDiskTracker().SetLabel(memory.LabelForBuildSideResult) if variable.EnableTmpStorageOnOOM.Load() { - actionSpill := e.rowContainer.ActionSpill() + actionSpill := rowContainer.ActionSpill() failpoint.Inject("testRowContainerSpill", func(val failpoint.Value) { if val.(bool) { - actionSpill = e.rowContainer.rowContainer.ActionSpillForTest() + actionSpill = rowContainer.rowContainer.ActionSpillForTest() defer actionSpill.(*chunk.SpillDiskAction).WaitForTest() } }) - e.ctx.GetSessionVars().StmtCtx.MemTracker.FallbackOldAndSetNewAction(actionSpill) + w.hashJoinCtx.sessCtx.GetSessionVars().MemTracker.FallbackOldAndSetNewAction(actionSpill) } for chk := range buildSideResultCh { - if e.finished.Load().(bool) { + if w.hashJoinCtx.finished.Load() { return nil } - if !e.useOuterToBuild { - err = e.rowContainer.PutChunk(chk, e.isNullEQ) + if !w.hashJoinCtx.useOuterToBuild { + err = rowContainer.PutChunk(chk, w.hashJoinCtx.isNullEQ) } else { var bitMap = bitmap.NewConcurrentBitmap(chk.NumRows()) - e.outerMatchedStatus = append(e.outerMatchedStatus, bitMap) - e.memTracker.Consume(bitMap.BytesConsumed()) - if len(e.outerFilter) == 0 { - err = e.rowContainer.PutChunk(chk, e.isNullEQ) + w.hashJoinCtx.outerMatchedStatus = append(w.hashJoinCtx.outerMatchedStatus, bitMap) + w.hashJoinCtx.memTracker.Consume(bitMap.BytesConsumed()) + if len(w.hashJoinCtx.outerFilter) == 0 { + err = w.hashJoinCtx.rowContainer.PutChunk(chk, w.hashJoinCtx.isNullEQ) } else { - selected, err = expression.VectorizedFilter(e.ctx, e.outerFilter, chunk.NewIterator4Chunk(chk), selected) + selected, err = expression.VectorizedFilter(w.hashJoinCtx.sessCtx, w.hashJoinCtx.outerFilter, chunk.NewIterator4Chunk(chk), selected) if err != nil { return err } - err = e.rowContainer.PutChunkSelected(chk, selected, e.isNullEQ) + err = rowContainer.PutChunkSelected(chk, selected, w.hashJoinCtx.isNullEQ) } } failpoint.Inject("ConsumeRandomPanic", nil) @@ -1277,7 +1276,6 @@ func (e *NestedLoopApplyExec) Close() error { e.memTracker = nil if e.runtimeStats != nil { runtimeStats := newJoinRuntimeStats() - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, runtimeStats) if e.canUseCache { var hitRatio float64 if e.cacheAccessCounter > 0 { @@ -1288,6 +1286,7 @@ func (e *NestedLoopApplyExec) Close() error { runtimeStats.setCacheInfo(false, 0) } runtimeStats.SetConcurrencyInfo(execdetails.NewConcurrencyInfo("Concurrency", 0)) + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, runtimeStats) } return e.outerExec.Close() } @@ -1300,8 +1299,8 @@ func (e *NestedLoopApplyExec) Open(ctx context.Context) error { } e.cursor = 0 e.innerRows = e.innerRows[:0] - e.outerChunk = newFirstChunk(e.outerExec) - e.innerChunk = newFirstChunk(e.innerExec) + e.outerChunk = tryNewCacheChunk(e.outerExec) + e.innerChunk = tryNewCacheChunk(e.innerExec) e.innerList = chunk.NewList(retTypes(e.innerExec), e.initCap, e.maxChunkSize) e.memTracker = memory.NewTracker(e.id, -1) @@ -1545,6 +1544,17 @@ func (e *joinRuntimeStats) Tp() int { return execdetails.TpJoinRuntimeStats } +func (e *joinRuntimeStats) Clone() execdetails.RuntimeStats { + newJRS := &joinRuntimeStats{ + RuntimeStatsWithConcurrencyInfo: e.RuntimeStatsWithConcurrencyInfo, + applyCache: e.applyCache, + cache: e.cache, + hasHashStat: e.hasHashStat, + hashStat: e.hashStat, + } + return newJRS +} + type hashJoinRuntimeStats struct { fetchAndBuildHashTable time.Duration hashStat hashStatistic diff --git a/executor/join_test.go b/executor/join_test.go index 0b9c1aad9f8be..a5d5f6efc9fb5 100644 --- a/executor/join_test.go +++ b/executor/join_test.go @@ -198,9 +198,9 @@ func TestJoin2(t *testing.T) { tk.MustQuery("select /*+ INL_JOIN(t, t1) */ t1.b from t1 join t on t.b=t1.b").Check(testkit.Rows("2", "3")) tk.MustQuery("select /*+ INL_HASH_JOIN(t, t1) */ t1.b from t1 join t on t.b=t1.b").Sort().Check(testkit.Rows("2", "3")) tk.MustQuery("select /*+ INL_MERGE_JOIN(t, t1) */ t1.b from t1 join t on t.b=t1.b").Check(testkit.Rows("2", "3")) - tk.MustQuery("select /*+ INL_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", " 4 5")) - tk.MustQuery("select /*+ INL_HASH_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", " 4 5")) - tk.MustQuery("select /*+ INL_MERGE_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", " 4 5")) + tk.MustQuery("select /*+ INL_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Sort().Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", " 4 5")) + tk.MustQuery("select /*+ INL_HASH_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Sort().Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", " 4 5")) + tk.MustQuery("select /*+ INL_MERGE_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Sort().Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", " 4 5")) tk.MustQuery("select /*+ INL_JOIN(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000")) tk.MustQuery("select /*+ INL_HASH_JOIN(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000")) tk.MustQuery("select /*+ INL_MERGE_JOIN(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000")) @@ -1222,6 +1222,7 @@ func TestIndexLookupJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@tidb_init_chunk_size=2") tk.MustExec("DROP TABLE IF EXISTS t") tk.MustExec("CREATE TABLE `t` (`a` int, pk integer auto_increment,`b` char (20),primary key (pk))") @@ -1361,9 +1362,9 @@ func TestIndexLookupJoin(t *testing.T) { " ├─TableReader(Build) 64.00 root data:Selection", " │ └─Selection 64.00 cop[tikv] not(isnull(test.t.b))", " │ └─TableFullScan 64.00 cop[tikv] table:t keep order:false", - " └─IndexReader(Probe) 1.00 root index:Selection", - " └─Selection 1.00 cop[tikv] not(isnull(test.s.a)), not(isnull(test.s.b))", - " └─IndexRangeScan 1.00 cop[tikv] table:s, index:idx(a, b) range: decided by [eq(test.s.a, test.t.a) lt(test.s.b, test.t.b)], keep order:false")) + " └─IndexReader(Probe) 64.00 root index:Selection", + " └─Selection 64.00 cop[tikv] not(isnull(test.s.a)), not(isnull(test.s.b))", + " └─IndexRangeScan 64.00 cop[tikv] table:s, index:idx(a, b) range: decided by [eq(test.s.a, test.t.a) lt(test.s.b, test.t.b)], keep order:false")) tk.MustQuery("select /*+ TIDB_INLJ(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows("64")) tk.MustExec("set @@tidb_index_lookup_join_concurrency=1;") tk.MustQuery("select /*+ TIDB_INLJ(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows("64")) @@ -1374,9 +1375,9 @@ func TestIndexLookupJoin(t *testing.T) { " ├─TableReader(Build) 64.00 root data:Selection", " │ └─Selection 64.00 cop[tikv] not(isnull(test.t.b))", " │ └─TableFullScan 64.00 cop[tikv] table:t keep order:false", - " └─IndexReader(Probe) 1.00 root index:Selection", - " └─Selection 1.00 cop[tikv] not(isnull(test.s.a)), not(isnull(test.s.b))", - " └─IndexRangeScan 1.00 cop[tikv] table:s, index:idx(a, b) range: decided by [eq(test.s.a, test.t.a) lt(test.s.b, test.t.b)], keep order:true", + " └─IndexReader(Probe) 64.00 root index:Selection", + " └─Selection 64.00 cop[tikv] not(isnull(test.s.a)), not(isnull(test.s.b))", + " └─IndexRangeScan 64.00 cop[tikv] table:s, index:idx(a, b) range: decided by [eq(test.s.a, test.t.a) lt(test.s.b, test.t.b)], keep order:true", )) tk.MustQuery("select /*+ INL_MERGE_JOIN(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows("64")) tk.MustExec("set @@tidb_index_lookup_join_concurrency=1;") @@ -1388,9 +1389,9 @@ func TestIndexLookupJoin(t *testing.T) { " ├─TableReader(Build) 64.00 root data:Selection", " │ └─Selection 64.00 cop[tikv] not(isnull(test.t.b))", " │ └─TableFullScan 64.00 cop[tikv] table:t keep order:false", - " └─IndexReader(Probe) 1.00 root index:Selection", - " └─Selection 1.00 cop[tikv] not(isnull(test.s.a)), not(isnull(test.s.b))", - " └─IndexRangeScan 1.00 cop[tikv] table:s, index:idx(a, b) range: decided by [eq(test.s.a, test.t.a) lt(test.s.b, test.t.b)], keep order:false", + " └─IndexReader(Probe) 64.00 root index:Selection", + " └─Selection 64.00 cop[tikv] not(isnull(test.s.a)), not(isnull(test.s.b))", + " └─IndexRangeScan 64.00 cop[tikv] table:s, index:idx(a, b) range: decided by [eq(test.s.a, test.t.a) lt(test.s.b, test.t.b)], keep order:false", )) tk.MustQuery("select /*+ INL_HASH_JOIN(s) */ count(*) from t join s use index(idx) on s.a = t.a and s.b < t.b").Check(testkit.Rows("64")) tk.MustExec("set @@tidb_index_lookup_join_concurrency=1;") @@ -1411,6 +1412,7 @@ func TestIndexNestedLoopHashJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@tidb_init_chunk_size=2") tk.MustExec("set @@tidb_index_join_batch_size=10") tk.MustExec("DROP TABLE IF EXISTS t, s") @@ -1434,8 +1436,8 @@ func TestIndexNestedLoopHashJoin(t *testing.T) { "IndexHashJoin 100.00 root left outer join, inner:TableReader, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a)", "├─TableReader(Build) 100.00 root data:TableFullScan", "│ └─TableFullScan 100.00 cop[tikv] table:t keep order:true", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:s range: decided by [test.t.a], keep order:false", + "└─TableReader(Probe) 100.00 root data:TableRangeScan", + " └─TableRangeScan 100.00 cop[tikv] table:s range: decided by [test.t.a], keep order:false", )) rs := tk.MustQuery("select /*+ INL_HASH_JOIN(s) */ * from t left join s on t.a=s.a order by t.pk") for i, row := range rs.Rows() { @@ -1471,10 +1473,10 @@ func TestIndexNestedLoopHashJoin(t *testing.T) { " ├─TableReader(Build) 9.00 root data:Selection", " │ └─Selection 9.00 cop[tikv] not(isnull(test.t.l_suppkey))", " │ └─TableFullScan 9.00 cop[tikv] table:l1 keep order:false", - " └─IndexLookUp(Probe) 3.00 root ", - " ├─IndexRangeScan(Build) 3.00 cop[tikv] table:l2, index:PRIMARY(l_orderkey, l_linenumber) range: decided by [eq(test.t.l_orderkey, test.t.l_orderkey)], keep order:false", - " └─Selection(Probe) 3.00 cop[tikv] not(isnull(test.t.l_suppkey))", - " └─TableRowIDScan 3.00 cop[tikv] table:l2 keep order:false")) + " └─IndexLookUp(Probe) 27.00 root ", + " ├─IndexRangeScan(Build) 27.00 cop[tikv] table:l2, index:PRIMARY(l_orderkey, l_linenumber) range: decided by [eq(test.t.l_orderkey, test.t.l_orderkey)], keep order:false", + " └─Selection(Probe) 27.00 cop[tikv] not(isnull(test.t.l_suppkey))", + " └─TableRowIDScan 27.00 cop[tikv] table:l2 keep order:false")) tk.MustQuery("select * from t l1 where exists ( select * from t l2 where l2.l_orderkey = l1.l_orderkey and l2.l_suppkey <> l1.l_suppkey )order by `l_orderkey`,`l_linenumber`;").Check(testkit.Rows("0 0 0 0", "0 1 0 1", "0 2 0 0", "1 0 1 0", "1 1 1 1", "1 2 1 0", "2 0 0 0", "2 1 0 1", "2 2 0 0")) tk.MustQuery("desc format = 'brief' select count(*) from t l1 where exists ( select * from t l2 where l2.l_orderkey = l1.l_orderkey and l2.l_suppkey <> l1.l_suppkey );").Check(testkit.Rows( "StreamAgg 1.00 root funcs:count(1)->Column#11", @@ -1482,10 +1484,10 @@ func TestIndexNestedLoopHashJoin(t *testing.T) { " ├─TableReader(Build) 9.00 root data:Selection", " │ └─Selection 9.00 cop[tikv] not(isnull(test.t.l_suppkey))", " │ └─TableFullScan 9.00 cop[tikv] table:l1 keep order:false", - " └─IndexLookUp(Probe) 3.00 root ", - " ├─IndexRangeScan(Build) 3.00 cop[tikv] table:l2, index:PRIMARY(l_orderkey, l_linenumber) range: decided by [eq(test.t.l_orderkey, test.t.l_orderkey)], keep order:false", - " └─Selection(Probe) 3.00 cop[tikv] not(isnull(test.t.l_suppkey))", - " └─TableRowIDScan 3.00 cop[tikv] table:l2 keep order:false")) + " └─IndexLookUp(Probe) 27.00 root ", + " ├─IndexRangeScan(Build) 27.00 cop[tikv] table:l2, index:PRIMARY(l_orderkey, l_linenumber) range: decided by [eq(test.t.l_orderkey, test.t.l_orderkey)], keep order:false", + " └─Selection(Probe) 27.00 cop[tikv] not(isnull(test.t.l_suppkey))", + " └─TableRowIDScan 27.00 cop[tikv] table:l2 keep order:false")) tk.MustQuery("select count(*) from t l1 where exists ( select * from t l2 where l2.l_orderkey = l1.l_orderkey and l2.l_suppkey <> l1.l_suppkey );").Check(testkit.Rows("9")) tk.MustExec("DROP TABLE IF EXISTS t, s") @@ -1579,9 +1581,9 @@ func TestIssue13449(t *testing.T) { "IndexHashJoin 12487.50 root inner join, inner:IndexReader, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a)", "├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ └─IndexFullScan 9990.00 cop[tikv] table:t, index:a(a) keep order:true, stats:pseudo", - "└─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.s.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo")) + "└─IndexReader(Probe) 12487.50 root index:Selection", + " └─Selection 12487.50 cop[tikv] not(isnull(test.s.a))", + " └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo")) tk.MustQuery("select /*+ INL_HASH_JOIN(s) */ * from t join s on t.a=s.a order by t.a;").Check(testkit.Rows("1 1", "128 128")) } @@ -2177,11 +2179,11 @@ func TestOuterTableBuildHashTableIsuse13933(t *testing.T) { "IndexHashJoin 12475.01 root left outer join, inner:IndexLookUp, outer key:test.t.b, inner key:test.s.b, equal cond:eq(test.t.b, test.s.b), other cond:lt(test.s.a, test.t.a)", "├─TableReader(Build) 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.s.b))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:s, index:b(b) range: decided by [eq(test.s.b, test.t.b)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.s.a))", - " └─TableRowIDScan 1.25 cop[tikv] table:s keep order:false, stats:pseudo")) + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.s.b))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:b(b) range: decided by [eq(test.s.b, test.t.b)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.s.a))", + " └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo")) } func TestIssue13177(t *testing.T) { @@ -2305,16 +2307,14 @@ func TestIssue18070(t *testing.T) { tk.MustExec("insert into t1 values(1),(2)") tk.MustExec("insert into t2 values(1),(1),(2),(2)") tk.MustExec("set @@tidb_mem_quota_query=1000") - err := tk.QueryToErr("select /*+ inl_hash_join(t1)*/ * from t1 join t2 on t1.a = t2.a;") - require.True(t, strings.Contains(err.Error(), "Out Of Memory Quota!")) + tk.MustContainErrMsg("select /*+ inl_hash_join(t1)*/ * from t1 join t2 on t1.a = t2.a;", "Out Of Memory Quota!") fpName := "github.com/pingcap/tidb/executor/mockIndexMergeJoinOOMPanic" require.NoError(t, failpoint.Enable(fpName, `panic("ERROR 1105 (HY000): Out Of Memory Quota![conn_id=1]")`)) defer func() { require.NoError(t, failpoint.Disable(fpName)) }() - err = tk.QueryToErr("select /*+ inl_merge_join(t1)*/ * from t1 join t2 on t1.a = t2.a;") - require.True(t, strings.Contains(err.Error(), "Out Of Memory Quota!")) + tk.MustContainErrMsg("select /*+ inl_merge_join(t1)*/ * from t1 join t2 on t1.a = t2.a;", "Out Of Memory Quota!") } func TestIssue18564(t *testing.T) { @@ -2769,6 +2769,88 @@ func TestIssue31129(t *testing.T) { require.NoError(t, failpoint.Disable(fpName2)) } +func TestIssue37932(t *testing.T) { + store := testkit.CreateMockStore(t) + tk1 := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk1.MustExec("use test") + tk2.MustExec("use test") + tk1.MustExec("create table tbl_1 ( col_1 set ( 'Alice','Bob','Charlie','David' ) not null default 'Alice' ,col_2 tinyint unsigned ,col_3 decimal ( 34 , 3 ) not null default 79 ,col_4 bigint unsigned not null ,col_5 bit ( 12 ) not null , unique key idx_1 ( col_2 ) ,unique key idx_2 ( col_2 ) ) charset utf8mb4 collate utf8mb4_bin ;") + tk1.MustExec("create table tbl_2 ( col_6 text ( 52 ) collate utf8_unicode_ci not null ,col_7 int unsigned not null ,col_8 blob ( 369 ) ,col_9 bit ( 51 ) ,col_10 decimal ( 38 , 16 ) , unique key idx_3 ( col_7 ) ,unique key idx_4 ( col_7 ) ) charset utf8 collate utf8_unicode_ci ;") + tk1.MustExec("create table tbl_3 ( col_11 set ( 'Alice','Bob','Charlie','David' ) not null ,col_12 bigint unsigned not null default 1678891638492596595 ,col_13 text ( 18 ) ,col_14 set ( 'Alice','Bob','Charlie','David' ) not null default 'Alice' ,col_15 mediumint , key idx_5 ( col_12 ) ,unique key idx_6 ( col_12 ) ) charset utf8mb4 collate utf8mb4_general_ci ;") + tk1.MustExec("create table tbl_4 ( col_16 set ( 'Alice','Bob','Charlie','David' ) not null ,col_17 tinyint unsigned ,col_18 int unsigned not null default 4279145838 ,col_19 varbinary ( 210 ) not null ,col_20 timestamp , primary key ( col_18 ) /*T![clustered_index] nonclustered */ ,key idx_8 ( col_19 ) ) charset utf8mb4 collate utf8mb4_unicode_ci ;") + tk1.MustExec("create table tbl_5 ( col_21 bigint ,col_22 set ( 'Alice','Bob','Charlie','David' ) ,col_23 blob ( 311 ) ,col_24 bigint unsigned not null default 3415443099312152509 ,col_25 time , unique key idx_9 ( col_21 ) ,unique key idx_10 ( col_21 ) ) charset gbk collate gbk_bin ;") + tk1.MustExec("insert into tbl_1 values ( 'Bob',null,0.04,2650749963804575036,4044 );") + tk1.MustExec("insert into tbl_1 values ( 'Alice',171,1838.2,6452757231340518222,1190 );") + tk1.MustExec("insert into tbl_1 values ( 'Bob',202,2.962,4304284252076747481,2112 );") + tk1.MustExec("insert into tbl_1 values ( 'David',155,32610.05,5899651588546531414,104 );") + tk1.MustExec("insert into tbl_1 values ( 'Charlie',52,4219.7,6151233689319516187,1246 );") + tk1.MustExec("insert into tbl_1 values ( 'Bob',55,3963.11,3614977408465893392,1188 );") + tk1.MustExec("insert into tbl_1 values ( 'Alice',203,72.01,1553550133494908281,1658 );") + tk1.MustExec("insert into tbl_1 values ( 'Bob',40,871.569,8114062926218465773,1397 );") + tk1.MustExec("insert into tbl_1 values ( 'Alice',165,7765,4481202107781982005,2089 );") + tk1.MustExec("insert into tbl_1 values ( 'David',79,7.02,993594504887208796,514 );") + tk1.MustExec("insert into tbl_2 values ( 'iB_%7c&q!6-gY4bkvg',2064909882,'dLN52t1YZSdJ',2251679806445488,32 );") + tk1.MustExec("insert into tbl_2 values ( 'h_',1478443689,'EqP+iN=',180492371752598,0.1 );") + tk1.MustExec("insert into tbl_2 values ( 'U@U&*WKfPzil=6YaDxp',4271201457,'QWuo24qkSSo',823931105457505,88514 );") + tk1.MustExec("insert into tbl_2 values ( 'FR4GA=',505128825,'RpEmV6ph5Z7',568030123046798,609381 );") + tk1.MustExec("insert into tbl_2 values ( '3GsU',166660047,'',1061132816887762,6.4605 );") + tk1.MustExec("insert into tbl_2 values ( 'BA4hPRD0lm*pbg#NE',3440634757,'7gUPe2',288001159469205,6664.9 );") + tk1.MustExec("insert into tbl_2 values ( '+z',2117152318,'WTkD(N',215697667226264,7.88 );") + tk1.MustExec("insert into tbl_2 values ( 'x@SPhy9lOomPa4LF',2881759652,'ETUXQQ0b4HnBSKgTWIU',153379720424625,null );") + tk1.MustExec("insert into tbl_2 values ( '',2075177391,'MPae!9%ufd',115899580476733,341.23 );") + tk1.MustExec("insert into tbl_2 values ( '~udi',1839363347,'iQj$$YsZc5ULTxG)yH',111454353417190,6.6 );") + tk1.MustExec("insert into tbl_3 values ( 'Alice',7032411265967085555,'P7*KBZ159','Alice',7516989 );") + tk1.MustExec("insert into tbl_3 values ( 'David',486417871670147038,'','Charlie',-2135446 );") + tk1.MustExec("insert into tbl_3 values ( 'Charlie',5784081664185069254,'7V_&YzKM~Q','Charlie',5583839 );") + tk1.MustExec("insert into tbl_3 values ( 'David',6346366522897598558,')Lp&$2)SC@','Bob',2522913 );") + tk1.MustExec("insert into tbl_3 values ( 'Charlie',224922711063053272,'gY','David',6624398 );") + tk1.MustExec("insert into tbl_3 values ( 'Alice',4678579167560495958,'fPIXY%R8WyY(=u&O','David',-3267160 );") + tk1.MustExec("insert into tbl_3 values ( 'David',8817108026311573677,'Cs0dZW*SPnKhV1','Alice',2359718 );") + tk1.MustExec("insert into tbl_3 values ( 'Bob',3177426155683033662,'o2=@zv2qQDhKUs)4y','Bob',-8091802 );") + tk1.MustExec("insert into tbl_3 values ( 'Bob',2543586640437235142,'hDa*CsOUzxmjf2m','Charlie',-8091935 );") + tk1.MustExec("insert into tbl_3 values ( 'Charlie',6204182067887668945,'DX-!=)dbGPQO','David',-1954600 );") + tk1.MustExec("insert into tbl_4 values ( 'David',167,576262750,'lX&x04W','2035-09-28' );") + tk1.MustExec("insert into tbl_4 values ( 'Charlie',236,2637776757,'92OhsL!w%7','2036-02-08' );") + tk1.MustExec("insert into tbl_4 values ( 'Bob',68,1077999933,'M0l','1997-09-16' );") + tk1.MustExec("insert into tbl_4 values ( 'Charlie',184,1280264753,'FhjkfeXsK1Q(','2030-03-16' );") + tk1.MustExec("insert into tbl_4 values ( 'Alice',10,2150711295,'Eqip)^tr*MoL','2032-07-02' );") + tk1.MustExec("insert into tbl_4 values ( 'Bob',108,2421602476,'Eul~~Df_Q8s&I3Y-7','2019-06-10' );") + tk1.MustExec("insert into tbl_4 values ( 'Alice',36,2811198561,'%XgRou0#iKtn*','2022-06-13' );") + tk1.MustExec("insert into tbl_4 values ( 'Charlie',115,330972286,'hKeJS','2000-11-15' );") + tk1.MustExec("insert into tbl_4 values ( 'Alice',6,2958326555,'c6+=1','2001-02-11' );") + tk1.MustExec("insert into tbl_4 values ( 'Alice',99,387404826,'figc(@9R*k3!QM_Vve','2036-02-17' );") + tk1.MustExec("insert into tbl_5 values ( -401358236474313609,'Charlie','4J$',701059766304691317,'08:19:10.00' );") + tk1.MustExec("insert into tbl_5 values ( 2759837898825557143,'Bob','E',5158554038674310466,'11:04:03.00' );") + tk1.MustExec("insert into tbl_5 values ( 273910054423832204,'Alice',null,8944547065167499612,'08:02:30.00' );") + tk1.MustExec("insert into tbl_5 values ( 2875669873527090798,'Alice','4^SpR84',4072881341903432150,'18:24:55.00' );") + tk1.MustExec("insert into tbl_5 values ( -8446590100588981557,'David','yBj8',8760380566452862549,'09:01:10.00' );") + tk1.MustExec("insert into tbl_5 values ( -1075861460175889441,'Charlie','ti11Pl0lJ',9139997565676405627,'08:30:14.00' );") + tk1.MustExec("insert into tbl_5 values ( 95663565223131772,'Alice','6$',8467839300407531400,'23:31:42.00' );") + tk1.MustExec("insert into tbl_5 values ( -5661709703968335255,'Charlie','',8122758569495329946,'19:36:24.00' );") + tk1.MustExec("insert into tbl_5 values ( 3338588216091909518,'Bob','',6558557574025196860,'15:22:56.00' );") + tk1.MustExec("insert into tbl_5 values ( 8918630521194612922,'David','I$w',5981981639362947650,'22:03:24.00' );") + tk1.MustExec("begin pessimistic;") + tk1.MustExec("insert ignore into tbl_1 set col_1 = 'David', col_2 = 110, col_3 = 37065, col_4 = 8164500960513474805, col_5 = 1264 on duplicate key update col_3 = 22151.5, col_4 = 6266058887081523571, col_5 = 3254, col_2 = 59, col_1 = 'Bob';") + tk1.MustExec("insert into tbl_4 (col_16,col_17,col_18,col_19,col_20) values ( 'Charlie',34,2499970462,'Z','1978-10-27' ) ,( 'David',217,1732485689,'*)~@@Q8ryi','2004-12-01' ) ,( 'Charlie',40,1360558255,'H(Y','1998-06-25' ) ,( 'Alice',108,2973455447,'%CcP4$','1979-03-28' ) ,( 'David',9,3835209932,'tdKXUzLmAzwFf$','2009-03-03' ) ,( 'David',68,163270003,'uimsclz@FQJN','1988-09-11' ) ,( 'Alice',76,297067264,'BzFF','1989-01-05' ) on duplicate key update col_16 = 'Charlie', col_17 = 14, col_18 = 4062155275, col_20 = '2002-03-07', col_19 = 'tmvchLzp*o8';") + tk2.MustExec("delete from tbl_3 where tbl_3.col_13 in ( null ,'' ,'g8EEzUU7LQ' ,'~fC3&B*cnOOx_' ,'%RF~AFto&x' ,'NlWkMWG^00' ,'e^4o2Ji^q_*Fa52Z' ) ;") + tk2.MustExec("delete from tbl_5 where not( tbl_5.col_21 between -1075861460175889441 and 3338588216091909518 ) ;") + tk1.MustExec("replace into tbl_1 (col_1,col_2,col_3,col_4,col_5) values ( 'Alice',83,8.33,4070808626051569664,455 ) ,( 'Alice',53,2.8,2763362085715461014,1912 ) ,( 'David',178,4242.8,962727993466011464,1844 ) ,( 'Alice',16,650054,5638988670318229867,565 ) ,( 'Alice',76,89783.1,3968605744540056024,2563 ) ,( 'Bob',120,0.89,1003144931151245839,2670 );") + tk1.MustExec("delete from tbl_5 where col_24 is null ;") + tk1.MustExec("delete from tbl_3 where tbl_3.col_11 in ( 'Alice' ,'Bob' ,'Alice' ) ;") + tk2.MustExec("insert into tbl_3 set col_11 = 'Bob', col_12 = 5701982550256146475, col_13 = 'Hhl)yCsQ2K3cfc^', col_14 = 'Alice', col_15 = -3718868 on duplicate key update col_15 = 7210750, col_12 = 6133680876296985245, col_14 = 'Alice', col_11 = 'David', col_13 = 'F+RMGE!_2^Cfr3Fw';") + tk2.MustExec("insert ignore into tbl_5 set col_21 = 2439343116426563397, col_22 = 'Charlie', col_23 = '~Spa2YzRFFom16XD', col_24 = 5571575017340582365, col_25 = '13:24:38.00' ;") + err := tk1.ExecToErr("update tbl_4 set tbl_4.col_20 = '2006-01-24' where tbl_4.col_18 in ( select col_11 from tbl_3 where IsNull( tbl_4.col_16 ) or not( tbl_4.col_19 in ( select col_3 from tbl_1 where tbl_4.col_16 between 'Alice' and 'David' and tbl_4.col_19 <= '%XgRou0#iKtn*' ) ) ) ;") + if err != nil { + print(err.Error()) + if strings.Contains(err.Error(), "Truncated incorrect DOUBLE value") { + t.Log("Truncated incorrect DOUBLE value is within expectations, skipping") + return + } + } + require.NoError(t, err) +} + func TestOuterJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/executor/kvtest/main_test.go b/executor/kvtest/main_test.go index 4ca44232f2973..592d8ba5276bf 100644 --- a/executor/kvtest/main_test.go +++ b/executor/kvtest/main_test.go @@ -35,6 +35,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), diff --git a/executor/load_data.go b/executor/load_data.go index e11137c3916ae..d99ec712ed8fd 100644 --- a/executor/load_data.go +++ b/executor/load_data.go @@ -15,20 +15,27 @@ package executor import ( + "bufio" "bytes" "context" "fmt" + "io" + "path/filepath" "strings" + "sync" "sync/atomic" "time" "github.com/pingcap/errors" "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/br/pkg/storage" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" @@ -40,13 +47,15 @@ import ( var ( null = []byte("NULL") taskQueueSize = 16 // the maximum number of pending tasks to commit in queue + // InTest is a flag that bypass gcs authentication in unit tests. + InTest bool ) // LoadDataExec represents a load data executor. type LoadDataExec struct { baseExecutor - IsLocal bool + FileLocRef ast.FileLocRefTp OnDuplicate ast.OnDuplicateKeyHandlingType loadDataInfo *LoadDataInfo } @@ -55,31 +64,78 @@ type LoadDataExec struct { func (e *LoadDataExec) Next(ctx context.Context, req *chunk.Chunk) error { req.GrowAndReset(e.maxChunkSize) // TODO: support load data without local field. - if !e.IsLocal { + if e.FileLocRef == ast.FileLocServer { return errors.New("Load Data: don't support load data without local field") } - e.loadDataInfo.OnDuplicate = e.OnDuplicate // TODO: support lines terminated is "". if len(e.loadDataInfo.LinesInfo.Terminated) == 0 { return errors.New("Load Data: don't support load data terminated is nil") } - - sctx := e.loadDataInfo.ctx - val := sctx.Value(LoadDataVarKey) - if val != nil { - sctx.SetValue(LoadDataVarKey, nil) - return errors.New("Load Data: previous load data option isn't closed normal") - } if e.loadDataInfo.Path == "" { return errors.New("Load Data: infile path is empty") } - sctx.SetValue(LoadDataVarKey, e.loadDataInfo) + if !e.loadDataInfo.Table.Meta().IsBaseTable() { + return errors.New("can only load data into base tables") + } + switch e.FileLocRef { + case ast.FileLocServer: + panic("FileLocServer should be handled earlier") + case ast.FileLocClient: + // let caller use handleQuerySpecial to read data in this connection + sctx := e.loadDataInfo.ctx + val := sctx.Value(LoadDataVarKey) + if val != nil { + sctx.SetValue(LoadDataVarKey, nil) + return errors.New("Load Data: previous load data option wasn't closed normally") + } + sctx.SetValue(LoadDataVarKey, e.loadDataInfo) + case ast.FileLocRemote: + return e.loadFromRemote(ctx) + } return nil } +func (e *LoadDataExec) loadFromRemote(ctx context.Context) error { + u, err := storage.ParseRawURL(e.loadDataInfo.Path) + if err != nil { + return err + } + var filename string + u.Path, filename = filepath.Split(u.Path) + b, err := storage.ParseBackendFromURL(u, nil) + if err != nil { + return err + } + if b.GetLocal() != nil { + return errors.Errorf("Load Data: don't support load data from tidb-server when set REMOTE, path %s", e.loadDataInfo.Path) + } + + opt := &storage.ExternalStorageOptions{} + if InTest { + opt.NoCredentials = true + } + s, err := storage.New(ctx, b, opt) + if err != nil { + return err + } + fileReader, err := s.Open(ctx, filename) + if err != nil { + return err + } + defer fileReader.Close() + reader := bufio.NewReader(fileReader) + + return e.loadDataInfo.Load(ctx, func() ([]byte, error) { + return reader.ReadBytes('\n') + }) +} + // Close implements the Executor Close interface. func (e *LoadDataExec) Close() error { + if e.runtimeStats != nil && e.loadDataInfo != nil && e.loadDataInfo.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.loadDataInfo.stats) + } return nil } @@ -100,6 +156,7 @@ type CommitTask struct { } // LoadDataInfo saves the information of loading data operation. +// TODO: rename it and remove unnecessary public methods. type LoadDataInfo struct { *InsertValues @@ -129,6 +186,111 @@ type FieldMapping struct { UserVar *ast.VariableExpr } +// Load reads from readerFn and do load data job. +func (e *LoadDataInfo) Load(ctx context.Context, readerFn func() ([]byte, error)) error { + e.InitQueues() + e.SetMaxRowsInBatch(uint64(e.Ctx.GetSessionVars().DMLBatchSize)) + e.StartStopWatcher() + // let stop watcher goroutine quit + defer e.ForceQuit() + err := sessiontxn.NewTxn(ctx, e.Ctx) + if err != nil { + return err + } + // processStream process input data, enqueue commit task + wg := new(sync.WaitGroup) + wg.Add(1) + go processStream(ctx, readerFn, e, wg) + err = e.CommitWork(ctx) + wg.Wait() + return err +} + +// processStream process input stream from network +func processStream(ctx context.Context, readerFn func() ([]byte, error), loadDataInfo *LoadDataInfo, wg *sync.WaitGroup) { + var err error + var shouldBreak bool + var prevData, curData []byte + defer func() { + r := recover() + if r != nil { + logutil.Logger(ctx).Error("process routine panicked", + zap.Reflect("r", r), + zap.Stack("stack")) + } + if err != nil || r != nil { + loadDataInfo.ForceQuit() + } else { + loadDataInfo.CloseTaskQueue() + } + wg.Done() + }() + for { + curData, err = readerFn() + if err != nil { + if terror.ErrorNotEqual(err, io.EOF) { + logutil.Logger(ctx).Error("read data for LOAD DATA failed", zap.Error(err)) + break + } + err = nil + } + if len(curData) == 0 { + loadDataInfo.Drained = true + shouldBreak = true + if len(prevData) == 0 { + break + } + } + select { + case <-loadDataInfo.QuitCh: + err = errors.New("processStream forced to quit") + default: + } + if err != nil { + break + } + // prepare batch and enqueue task + prevData, err = insertDataWithCommit(ctx, prevData, curData, loadDataInfo) + if err != nil { + break + } + if shouldBreak { + break + } + } + if err != nil { + logutil.Logger(ctx).Error("load data process stream error", zap.Error(err)) + return + } + if err = loadDataInfo.EnqOneTask(ctx); err != nil { + logutil.Logger(ctx).Error("load data process stream error", zap.Error(err)) + return + } +} + +func insertDataWithCommit(ctx context.Context, prevData, + curData []byte, loadDataInfo *LoadDataInfo) ([]byte, error) { + var err error + var reachLimit bool + for { + prevData, reachLimit, err = loadDataInfo.InsertData(ctx, prevData, curData) + if err != nil { + return nil, err + } + if !reachLimit { + break + } + // push into commit task queue + err = loadDataInfo.EnqOneTask(ctx) + if err != nil { + return prevData, err + } + curData = prevData + prevData = nil + } + return prevData, nil +} + // reorderColumns reorder the e.insertColumns according to the order of columnNames // Note: We must ensure there must be one-to-one mapping between e.insertColumns and columnNames in terms of column name. func (e *LoadDataInfo) reorderColumns(columnNames []string) error { @@ -313,7 +475,7 @@ func (e *LoadDataInfo) CommitOneTask(ctx context.Context, task CommitTask) error var err error defer func() { if err != nil { - e.Ctx.StmtRollback() + e.Ctx.StmtRollback(ctx, false) } }() err = e.CheckAndInsertOneBatch(ctx, task.rows, task.cnt) @@ -324,7 +486,7 @@ func (e *LoadDataInfo) CommitOneTask(ctx context.Context, task CommitTask) error failpoint.Inject("commitOneTaskErr", func() error { return errors.New("mock commit one task error") }) - e.Ctx.StmtCommit() + e.Ctx.StmtCommit(ctx) // Make sure process stream routine never use invalid txn e.txnInUse.Lock() defer e.txnInUse.Unlock() @@ -350,7 +512,7 @@ func (e *LoadDataInfo) CommitWork(ctx context.Context) error { e.ForceQuit() } if err != nil { - e.ctx.StmtRollback() + e.ctx.StmtRollback(ctx, false) } }() var tasks uint64 diff --git a/executor/loadremotetest/BUILD.bazel b/executor/loadremotetest/BUILD.bazel new file mode 100644 index 0000000000000..ed2cd5bb848e2 --- /dev/null +++ b/executor/loadremotetest/BUILD.bazel @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "loadremotetest_test", + srcs = [ + "main_test.go", + "one_csv_test.go", + "util_test.go", + ], + deps = [ + "//executor", + "//kv", + "//testkit", + "@com_github_fsouza_fake_gcs_server//fakestorage", + "@com_github_stretchr_testify//suite", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/executor/loadremotetest/main_test.go b/executor/loadremotetest/main_test.go new file mode 100644 index 0000000000000..82f95ed8dd112 --- /dev/null +++ b/executor/loadremotetest/main_test.go @@ -0,0 +1,33 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadremotetest + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), + goleak.IgnoreTopFunction("net.(*netFD).connect.func2"), + } + goleak.VerifyTestMain(m, opts...) +} diff --git a/executor/loadremotetest/one_csv_test.go b/executor/loadremotetest/one_csv_test.go new file mode 100644 index 0000000000000..6120120b241eb --- /dev/null +++ b/executor/loadremotetest/one_csv_test.go @@ -0,0 +1,57 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadremotetest + +import ( + "fmt" + + "github.com/pingcap/tidb/testkit" +) + +func (s *mockGCSSuite) TestLoadCSV() { + s.tk.MustExec("DROP DATABASE IF EXISTS load_csv;") + s.tk.MustExec("CREATE DATABASE load_csv;") + s.tk.MustExec("CREATE TABLE load_csv.t (i INT, s varchar(32));") + + // no-new-line-at-end + sql := fmt.Sprintf(`LOAD DATA REMOTE INFILE 'gcs://test-bucket/no-new-line-at-end.csv?endpoint=%s' INTO TABLE load_csv.t + FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' + LINES TERMINATED BY '\n' IGNORE 1 LINES;`, gcsEndpoint) + s.tk.MustExec(sql) + s.tk.MustQuery("SELECT * FROM load_csv.t;").Check(testkit.Rows( + "100 test100", + "101 \"", + "102 😄😄😄😄😄", + "104 ", + )) + s.tk.MustExec("TRUNCATE TABLE load_csv.t;") + + // new-line-at-end + sql = fmt.Sprintf(`LOAD DATA REMOTE INFILE 'gcs://test-bucket/new-line-at-end.csv?endpoint=%s' INTO TABLE load_csv.t + FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' + LINES TERMINATED BY '\n' IGNORE 1 LINES;`, gcsEndpoint) + s.tk.MustExec(sql) + s.tk.MustQuery("SELECT * FROM load_csv.t;").Check(testkit.Rows( + "100 test100", + "101 \"", + "102 😄😄😄😄😄", + "104 ", + )) + s.tk.MustExec("TRUNCATE TABLE load_csv.t;") + + // can't read file at tidb-server + sql = "LOAD DATA REMOTE INFILE '/etc/passwd' INTO TABLE load_csv.t;" + s.tk.MustContainErrMsg(sql, "don't support load data from tidb-server") +} diff --git a/executor/loadremotetest/util_test.go b/executor/loadremotetest/util_test.go new file mode 100644 index 0000000000000..713a3883fa616 --- /dev/null +++ b/executor/loadremotetest/util_test.go @@ -0,0 +1,87 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadremotetest + +import ( + "fmt" + "testing" + + "github.com/fsouza/fake-gcs-server/fakestorage" + "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/suite" +) + +type mockGCSSuite struct { + suite.Suite + + server *fakestorage.Server + store kv.Storage + tk *testkit.TestKit +} + +var ( + gcsHost = "127.0.0.1" + gcsPort = uint16(4443) + gcsEndpoint = fmt.Sprintf("http://%s:%d", gcsHost, gcsPort) +) + +func TestLoadRemote(t *testing.T) { + suite.Run(t, &mockGCSSuite{}) +} + +func (s *mockGCSSuite) SetupSuite() { + objects := []fakestorage.Object{ + { + BucketName: "test-bucket", + Name: "no-new-line-at-end.csv", + Content: []byte(`i,s +100,"test100" +101,"\"" +102,"😄😄😄😄😄" +104,""`), + }, + { + BucketName: "test-bucket", + Name: "new-line-at-end.csv", + Content: []byte(`i,s +100,"test100" +101,"\"" +102,"😄😄😄😄😄" +104,"" +`), + }, + } + + var err error + opt := fakestorage.Options{ + InitialObjects: objects, + Scheme: "http", + Host: gcsHost, + Port: gcsPort, + PublicHost: gcsHost, + } + s.server, err = fakestorage.NewServerWithOptions(opt) + s.Require().NoError(err) + s.store = testkit.CreateMockStore(s.T()) + s.tk = testkit.NewTestKit(s.T(), s.store) + executor.InTest = true +} + +func (s *mockGCSSuite) TearDownSuite() { + s.server.Stop() + executor.InTest = false +} diff --git a/executor/lock_stats.go b/executor/lock_stats.go new file mode 100644 index 0000000000000..540670e8119fc --- /dev/null +++ b/executor/lock_stats.go @@ -0,0 +1,157 @@ +// Copyright 2018 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package executor + +import ( + "context" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/util/chunk" +) + +var _ Executor = &LockStatsExec{} +var _ Executor = &UnlockStatsExec{} + +// LockStatsExec represents a lock statistic executor. +type LockStatsExec struct { + baseExecutor + Tables []*ast.TableName +} + +// lockStatsVarKeyType is a dummy type to avoid naming collision in context. +type lockStatsVarKeyType int + +// String defines a Stringer function for debugging and pretty printing. +func (k lockStatsVarKeyType) String() string { + return "lock_stats_var" +} + +// LockStatsVarKey is a variable key for lock statistic. +const LockStatsVarKey lockStatsVarKeyType = 0 + +// Next implements the Executor Next interface. +func (e *LockStatsExec) Next(ctx context.Context, req *chunk.Chunk) error { + do := domain.GetDomain(e.ctx) + is := do.InfoSchema() + h := do.StatsHandle() + if h == nil { + return errors.New("Lock Stats: handle is nil") + } + + tableNum := len(e.Tables) + if tableNum == 0 { + return errors.New("Lock Stats: table should not empty ") + } + + tids := make([]int64, 0, len(e.Tables)) + pids := make([]int64, 0) + for _, table := range e.Tables { + tbl, err := is.TableByName(table.Schema, table.Name) + if err != nil { + return err + } + tids = append(tids, tbl.Meta().ID) + + pi := tbl.Meta().GetPartitionInfo() + if pi == nil { + continue + } + for _, p := range pi.Definitions { + pids = append(pids, p.ID) + } + } + msg, err := h.AddLockedTables(tids, pids, e.Tables) + if msg != "" { + e.ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New(msg)) + } + return err +} + +// Close implements the Executor Close interface. +func (e *LockStatsExec) Close() error { + return nil +} + +// Open implements the Executor Open interface. +func (e *LockStatsExec) Open(ctx context.Context) error { + return nil +} + +// UnlockStatsExec represents a unlock statistic executor. +type UnlockStatsExec struct { + baseExecutor + Tables []*ast.TableName +} + +// unlockStatsVarKeyType is a dummy type to avoid naming collision in context. +type unlockStatsVarKeyType int + +// String defines a Stringer function for debugging and pretty printing. +func (k unlockStatsVarKeyType) String() string { + return "unlock_stats_var" +} + +// UnlockStatsVarKey is a variable key for unlock statistic. +const UnlockStatsVarKey unlockStatsVarKeyType = 0 + +// Next implements the Executor Next interface. +func (e *UnlockStatsExec) Next(ctx context.Context, req *chunk.Chunk) error { + do := domain.GetDomain(e.ctx) + is := do.InfoSchema() + h := do.StatsHandle() + if h == nil { + return errors.New("Unlock Stats: handle is nil") + } + + tableNum := len(e.Tables) + if tableNum == 0 { + return errors.New("Unlock Stats: table should not empty ") + } + + tids := make([]int64, 0, len(e.Tables)) + pids := make([]int64, 0) + for _, table := range e.Tables { + tbl, err := is.TableByName(table.Schema, table.Name) + if err != nil { + return err + } + tids = append(tids, tbl.Meta().ID) + + pi := tbl.Meta().GetPartitionInfo() + if pi == nil { + continue + } + for _, p := range pi.Definitions { + pids = append(pids, p.ID) + } + } + msg, err := h.RemoveLockedTables(tids, pids, e.Tables) + if msg != "" { + e.ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New(msg)) + } + return err +} + +// Close implements the Executor Close interface. +func (e *UnlockStatsExec) Close() error { + return nil +} + +// Open implements the Executor Open interface. +func (e *UnlockStatsExec) Open(ctx context.Context) error { + return nil +} diff --git a/executor/main_test.go b/executor/main_test.go index f418387a5ed25..4bf8cfb8f1bac 100644 --- a/executor/main_test.go +++ b/executor/main_test.go @@ -33,6 +33,7 @@ var prepareMergeSuiteData testdata.TestData var aggMergeSuiteData testdata.TestData var executorSuiteData testdata.TestData var pointGetSuiteData testdata.TestData +var slowQuerySuiteData testdata.TestData func TestMain(m *testing.M) { testsetup.SetupForCommonTest() @@ -40,10 +41,12 @@ func TestMain(m *testing.M) { testDataMap.LoadTestSuiteData("testdata", "executor_suite") testDataMap.LoadTestSuiteData("testdata", "prepare_suite") testDataMap.LoadTestSuiteData("testdata", "point_get_suite") + testDataMap.LoadTestSuiteData("testdata", "slow_query_suite") aggMergeSuiteData = testDataMap["agg_suite"] executorSuiteData = testDataMap["executor_suite"] prepareMergeSuiteData = testDataMap["prepare_suite"] pointGetSuiteData = testDataMap["point_get_suite"] + slowQuerySuiteData = testDataMap["slow_query_suite"] autoid.SetStep(5000) config.UpdateGlobal(func(conf *config.Config) { @@ -56,9 +59,11 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } callback := func(i int) int { testDataMap.GenerateOutputIfNeeded() diff --git a/executor/mem_reader.go b/executor/mem_reader.go index 0fa74bb01271e..647d785caeafc 100644 --- a/executor/mem_reader.go +++ b/executor/mem_reader.go @@ -555,7 +555,8 @@ func (m *memIndexLookUpReader) getMemRows(ctx context.Context) ([][]types.Datum, continue } numHandles += len(handles) - tblKVRanges = append(tblKVRanges, distsql.TableHandlesToKVRanges(getPhysicalTableID(tbl), handles)...) + ranges, _ := distsql.TableHandlesToKVRanges(getPhysicalTableID(tbl), handles) + tblKVRanges = append(tblKVRanges, ranges...) } if numHandles == 0 { return nil, nil @@ -594,6 +595,7 @@ type memIndexMergeReader struct { retFieldTypes []*types.FieldType indexMergeReader *IndexMergeReaderExecutor memReaders []memReader + isIntersection bool // partition mode partitionMode bool // if it is accessing a partition table @@ -650,6 +652,7 @@ func buildMemIndexMergeReader(ctx context.Context, us *UnionScanExec, indexMerge retFieldTypes: retTypes(us), indexMergeReader: indexMergeReader, memReaders: memReaders, + isIntersection: indexMergeReader.isIntersection, partitionMode: indexMergeReader.partitionTableMode, partitionTables: indexMergeReader.prunedPartitions, @@ -675,11 +678,20 @@ func (m *memIndexMergeReader) getMemRows(ctx context.Context) ([][]types.Datum, } else { kvRanges = append(kvRanges, m.indexMergeReader.keyRanges) } + if len(kvRanges) != len(tbls) { + return nil, errors.Errorf("length of tbls(size: %d) should be equals to length of kvRanges(size: %d)", len(tbls), len(kvRanges)) + } tblKVRanges := make([]kv.KeyRange, 0, 16) numHandles := 0 + var handles []kv.Handle + var err error for i, tbl := range tbls { - handles, err := m.unionHandles(kvRanges[i]) + if m.isIntersection { + handles, err = m.intersectionHandles(kvRanges[i]) + } else { + handles, err = m.unionHandles(kvRanges[i]) + } if err != nil { return nil, err } @@ -687,7 +699,8 @@ func (m *memIndexMergeReader) getMemRows(ctx context.Context) ([][]types.Datum, continue } numHandles += len(handles) - tblKVRanges = append(tblKVRanges, distsql.TableHandlesToKVRanges(getPhysicalTableID(tbl), handles)...) + ranges, _ := distsql.TableHandlesToKVRanges(getPhysicalTableID(tbl), handles) + tblKVRanges = append(tblKVRanges, ranges...) } if numHandles == 0 { @@ -714,7 +727,7 @@ func (m *memIndexMergeReader) getMemRows(ctx context.Context) ([][]types.Datum, return memTblReader.getMemRows(ctx) } -// Union all handles of different Indexes. +// Union all handles of all partial paths. func (m *memIndexMergeReader) unionHandles(kvRanges [][]kv.KeyRange) (finalHandles []kv.Handle, err error) { if len(m.memReaders) != len(kvRanges) { return nil, errors.Errorf("len(kvRanges) should be equal to len(memReaders)") @@ -745,6 +758,44 @@ func (m *memIndexMergeReader) unionHandles(kvRanges [][]kv.KeyRange) (finalHandl return finalHandles, nil } +// Intersect handles of each partial paths. +func (m *memIndexMergeReader) intersectionHandles(kvRanges [][]kv.KeyRange) (finalHandles []kv.Handle, err error) { + if len(m.memReaders) != len(kvRanges) { + return nil, errors.Errorf("len(kvRanges) should be equal to len(memReaders)") + } + + hMap := kv.NewHandleMap() + var handles []kv.Handle + for i, reader := range m.memReaders { + switch r := reader.(type) { + case *memTableReader: + r.kvRanges = kvRanges[i] + case *memIndexReader: + r.kvRanges = kvRanges[i] + default: + return nil, errors.New("memReader have to be memTableReader or memIndexReader") + } + if handles, err = reader.getMemRowsHandle(); err != nil { + return nil, err + } + for _, h := range handles { + if cntPtr, ok := hMap.Get(h); !ok { + cnt := 1 + hMap.Set(h, &cnt) + } else { + *(cntPtr.(*int)) += 1 + } + } + } + hMap.Range(func(h kv.Handle, val interface{}) bool { + if *(val.(*int)) == len(m.memReaders) { + finalHandles = append(finalHandles, h) + } + return true + }) + return finalHandles, nil +} + func (m *memIndexMergeReader) getMemRowsHandle() ([]kv.Handle, error) { return nil, errors.New("getMemRowsHandle has not been implemented for memIndexMergeReader") } diff --git a/executor/memtable_reader.go b/executor/memtable_reader.go index dc215e71fe3bb..3c1530ed714cf 100644 --- a/executor/memtable_reader.go +++ b/executor/memtable_reader.go @@ -29,7 +29,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/diagnosticspb" - "github.com/pingcap/log" "github.com/pingcap/sysutil" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/infoschema" @@ -47,7 +46,6 @@ import ( "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/pdapi" "github.com/pingcap/tidb/util/set" - "go.uber.org/zap" "golang.org/x/exp/slices" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -138,7 +136,7 @@ func (e *MemTableReaderExec) Next(ctx context.Context, req *chunk.Chunk) error { // Close implements the Executor Close interface. func (e *MemTableReaderExec) Close() error { if stats := e.retriever.getRuntimeStats(); stats != nil && e.runtimeStats != nil { - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, stats) + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, stats) } return e.retriever.close() } @@ -177,7 +175,7 @@ func fetchClusterConfig(sctx sessionctx.Context, nodeTypes, nodeAddrs set.String if err != nil { return nil, err } - serversInfo = filterClusterServerInfo(serversInfo, nodeTypes, nodeAddrs) + serversInfo = infoschema.FilterClusterServerInfo(serversInfo, nodeTypes, nodeAddrs) //nolint: prealloc var finalRows [][]types.Datum wg := sync.WaitGroup{} @@ -310,108 +308,12 @@ func (e *clusterServerInfoRetriever) retrieve(ctx context.Context, sctx sessionc return nil, nil } e.retrieved = true - serversInfo, err := infoschema.GetClusterServerInfo(sctx) if err != nil { return nil, err } - serversInfo = filterClusterServerInfo(serversInfo, e.extractor.NodeTypes, e.extractor.Instances) - - type result struct { - idx int - rows [][]types.Datum - err error - } - wg := sync.WaitGroup{} - ch := make(chan result, len(serversInfo)) - infoTp := e.serverInfoType - finalRows := make([][]types.Datum, 0, len(serversInfo)*10) - for i, srv := range serversInfo { - address := srv.Address - remote := address - if srv.ServerType == "tidb" { - remote = srv.StatusAddr - } - wg.Add(1) - go func(index int, remote, address, serverTP string) { - util.WithRecovery(func() { - defer wg.Done() - items, err := getServerInfoByGRPC(ctx, remote, infoTp) - if err != nil { - ch <- result{idx: index, err: err} - return - } - partRows := serverInfoItemToRows(items, serverTP, address) - ch <- result{idx: index, rows: partRows} - }, nil) - }(i, remote, address, srv.ServerType) - } - wg.Wait() - close(ch) - // Keep the original order to make the result more stable - var results []result //nolint: prealloc - for result := range ch { - if result.err != nil { - sctx.GetSessionVars().StmtCtx.AppendWarning(result.err) - continue - } - results = append(results, result) - } - slices.SortFunc(results, func(i, j result) bool { return i.idx < j.idx }) - for _, result := range results { - finalRows = append(finalRows, result.rows...) - } - return finalRows, nil -} - -func serverInfoItemToRows(items []*diagnosticspb.ServerInfoItem, tp, addr string) [][]types.Datum { - rows := make([][]types.Datum, 0, len(items)) - for _, v := range items { - for _, item := range v.Pairs { - row := types.MakeDatums( - tp, - addr, - v.Tp, - v.Name, - item.Key, - item.Value, - ) - rows = append(rows, row) - } - } - return rows -} - -func getServerInfoByGRPC(ctx context.Context, address string, tp diagnosticspb.ServerInfoType) ([]*diagnosticspb.ServerInfoItem, error) { - opt := grpc.WithInsecure() - security := config.GetGlobalConfig().Security - if len(security.ClusterSSLCA) != 0 { - clusterSecurity := security.ClusterSecurity() - tlsConfig, err := clusterSecurity.ToTLSConfig() - if err != nil { - return nil, errors.Trace(err) - } - opt = grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)) - } - conn, err := grpc.Dial(address, opt) - if err != nil { - return nil, err - } - defer func() { - err := conn.Close() - if err != nil { - log.Error("close grpc connection error", zap.Error(err)) - } - }() - - cli := diagnosticspb.NewDiagnosticsClient(conn) - ctx, cancel := context.WithTimeout(ctx, time.Second*10) - defer cancel() - r, err := cli.ServerInfo(ctx, &diagnosticspb.ServerInfoRequest{Tp: tp}) - if err != nil { - return nil, err - } - return r.Items, nil + serversInfo = infoschema.FilterClusterServerInfo(serversInfo, e.extractor.NodeTypes, e.extractor.Instances) + return infoschema.FetchClusterServerInfoWithoutPrivilegeCheck(ctx, sctx, serversInfo, e.serverInfoType, true) } func parseFailpointServerInfo(s string) []infoschema.ServerInfo { @@ -428,28 +330,6 @@ func parseFailpointServerInfo(s string) []infoschema.ServerInfo { return serversInfo } -func filterClusterServerInfo(serversInfo []infoschema.ServerInfo, nodeTypes, addresses set.StringSet) []infoschema.ServerInfo { - if len(nodeTypes) == 0 && len(addresses) == 0 { - return serversInfo - } - - filterServers := make([]infoschema.ServerInfo, 0, len(serversInfo)) - for _, srv := range serversInfo { - // Skip some node type which has been filtered in WHERE clause - // e.g: SELECT * FROM cluster_config WHERE type='tikv' - if len(nodeTypes) > 0 && !nodeTypes.Exist(srv.ServerType) { - continue - } - // Skip some node address which has been filtered in WHERE clause - // e.g: SELECT * FROM cluster_config WHERE address='192.16.8.12:2379' - if len(addresses) > 0 && !addresses.Exist(srv.Address) { - continue - } - filterServers = append(filterServers, srv) - } - return filterServers -} - type clusterLogRetriever struct { isDrained bool retrieving bool @@ -515,7 +395,7 @@ func (e *clusterLogRetriever) initialize(ctx context.Context, sctx sessionctx.Co instances := e.extractor.Instances nodeTypes := e.extractor.NodeTypes - serversInfo = filterClusterServerInfo(serversInfo, nodeTypes, instances) + serversInfo = infoschema.FilterClusterServerInfo(serversInfo, nodeTypes, instances) var levels = make([]diagnosticspb.LogLevel, 0, len(e.extractor.LogLevels)) for l := range e.extractor.LogLevels { diff --git a/executor/memtest/main_test.go b/executor/memtest/main_test.go index 5d3f98d407583..a3b3edb4ff962 100644 --- a/executor/memtest/main_test.go +++ b/executor/memtest/main_test.go @@ -35,6 +35,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), diff --git a/executor/merge_join.go b/executor/merge_join.go index e8d195e3085ae..a64a9fa0c33dc 100644 --- a/executor/merge_join.go +++ b/executor/merge_join.go @@ -77,7 +77,7 @@ type mergeJoinTable struct { func (t *mergeJoinTable) init(exec *MergeJoinExec) { child := exec.children[t.childIndex] - t.childChunk = newFirstChunk(child) + t.childChunk = tryNewCacheChunk(child) t.childChunkIter = chunk.NewIterator4Chunk(t.childChunk) items := make([]expression.Expression, 0, len(t.joinKeys)) @@ -100,7 +100,7 @@ func (t *mergeJoinTable) init(exec *MergeJoinExec) { actionSpill = t.rowContainer.ActionSpillForTest() } }) - exec.ctx.GetSessionVars().StmtCtx.MemTracker.FallbackOldAndSetNewAction(actionSpill) + exec.ctx.GetSessionVars().MemTracker.FallbackOldAndSetNewAction(actionSpill) } t.memTracker = memory.NewTracker(memory.LabelForInnerTable, -1) } else { diff --git a/executor/merge_join_test.go b/executor/merge_join_test.go index 01d6d37a8cd65..7246589e40412 100644 --- a/executor/merge_join_test.go +++ b/executor/merge_join_test.go @@ -18,6 +18,7 @@ import ( "bytes" "fmt" "math/rand" + "sort" "strconv" "testing" @@ -255,19 +256,28 @@ func TestShuffleMergeJoinInDisk(t *testing.T) { tk.MustExec("set @@tidb_mem_quota_query=1;") tk.MustExec("set @@tidb_merge_join_concurrency=4;") + tk.MustExec("set @@tidb_max_chunk_size=32;") tk.MustExec("drop table if exists t") tk.MustExec("drop table if exists t1") tk.MustExec("create table t(c1 int, c2 int)") tk.MustExec("create table t1(c1 int, c2 int)") - tk.MustExec("insert into t values(1,1)") - tk.MustExec("insert into t1 values(1,3),(4,4)") - + tk.MustExec("insert into t values(1,1),(2,2),(3,3),(4,4)") + for i := 1; i <= 1024; i += 4 { + tk.MustExec(fmt.Sprintf("insert into t1 values(%v,%v),(%v,%v),(%v,%v),(%v,%v)", i, i, i+1, i+1, i+2, i+2, i+3, i+3)) + } result := checkMergeAndRun(tk, t, "select /*+ TIDB_SMJ(t) */ * from t1 left outer join t on t.c1 = t1.c1 where t.c1 = 1 or t1.c2 > 20") - result.Check(testkit.Rows("1 3 1 1")) - require.Equal(t, int64(0), tk.Session().GetSessionVars().StmtCtx.MemTracker.BytesConsumed()) - require.Greater(t, tk.Session().GetSessionVars().StmtCtx.MemTracker.MaxConsumed(), int64(0)) - require.Equal(t, int64(0), tk.Session().GetSessionVars().StmtCtx.DiskTracker.BytesConsumed()) - require.Greater(t, tk.Session().GetSessionVars().StmtCtx.DiskTracker.MaxConsumed(), int64(0)) + + var expect []string + expect = append(expect, "1 1 1 1") + for i := 21; i <= 1024; i++ { + expect = append(expect, fmt.Sprintf("%v %v ", i, i)) + } + sort.Strings(expect) + result.Sort().Check(testkit.Rows(expect...)) + require.Equal(t, int64(0), tk.Session().GetSessionVars().MemTracker.BytesConsumed()) + require.Greater(t, tk.Session().GetSessionVars().MemTracker.MaxConsumed(), int64(0)) + require.Equal(t, int64(0), tk.Session().GetSessionVars().DiskTracker.BytesConsumed()) + require.Greater(t, tk.Session().GetSessionVars().DiskTracker.MaxConsumed(), int64(0)) } func TestMergeJoinInDisk(t *testing.T) { diff --git a/executor/metrics_reader_test.go b/executor/metrics_reader_test.go index 680bfd872e9e3..276c99c8ac22d 100644 --- a/executor/metrics_reader_test.go +++ b/executor/metrics_reader_test.go @@ -64,7 +64,7 @@ func TestStmtLabel(t *testing.T) { stmtNode, err := parser.New().ParseOneStmt(tt.sql, "", "") require.NoError(t, err) preprocessorReturn := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(tk.Session(), stmtNode, plannercore.WithPreprocessorReturn(preprocessorReturn)) + err = plannercore.Preprocess(context.Background(), tk.Session(), stmtNode, plannercore.WithPreprocessorReturn(preprocessorReturn)) require.NoError(t, err) _, _, err = planner.Optimize(context.TODO(), tk.Session(), stmtNode, preprocessorReturn.InfoSchema) require.NoError(t, err) diff --git a/executor/mpp_gather.go b/executor/mpp_gather.go index 42526774dbdd5..eba5498f8869d 100644 --- a/executor/mpp_gather.go +++ b/executor/mpp_gather.go @@ -16,6 +16,7 @@ package executor import ( "context" + "time" "github.com/pingcap/errors" "github.com/pingcap/failpoint" @@ -38,6 +39,18 @@ func useMPPExecution(ctx sessionctx.Context, tr *plannercore.PhysicalTableReader return ok } +func getMPPQueryID(ctx sessionctx.Context) uint64 { + mppQueryInfo := &ctx.GetSessionVars().StmtCtx.MPPQueryInfo + mppQueryInfo.QueryID.CompareAndSwap(0, plannercore.AllocMPPQueryID()) + return mppQueryInfo.QueryID.Load() +} + +func getMPPQueryTS(ctx sessionctx.Context) uint64 { + mppQueryInfo := &ctx.GetSessionVars().StmtCtx.MPPQueryInfo + mppQueryInfo.QueryTS.CompareAndSwap(0, uint64(time.Now().UnixNano())) + return mppQueryInfo.QueryTS.Load() +} + // MPPGather dispatch MPP tasks and read data from root tasks. type MPPGather struct { // following fields are construct needed @@ -45,6 +58,7 @@ type MPPGather struct { is infoschema.InfoSchema originalPlan plannercore.PhysicalPlan startTS uint64 + mppQueryID kv.MPPQueryID mppReqs []*kv.MPPDispatchRequest @@ -67,7 +81,9 @@ func (e *MPPGather) appendMPPDispatchReq(pf *plannercore.Fragment) error { for _, mppTask := range pf.ExchangeSender.Tasks { if mppTask.PartitionTableIDs != nil { err = updateExecutorTableID(context.Background(), dagReq.RootExecutor, true, mppTask.PartitionTableIDs) - } else { + } else if !mppTask.IsDisaggregatedTiFlashStaticPrune { + // If isDisaggregatedTiFlashStaticPrune is true, it means this TableScan is under PartitionUnoin, + // tableID in TableScan is already the physical table id of this partition, no need to update again. err = updateExecutorTableID(context.Background(), dagReq.RootExecutor, true, []int64{mppTask.TableID}) } if err != nil { @@ -78,17 +94,19 @@ func (e *MPPGather) appendMPPDispatchReq(pf *plannercore.Fragment) error { return errors.Trace(err) } logutil.BgLogger().Info("Dispatch mpp task", zap.Uint64("timestamp", mppTask.StartTs), - zap.Int64("ID", mppTask.ID), zap.String("address", mppTask.Meta.GetAddress()), + zap.Int64("ID", mppTask.ID), zap.Uint64("QueryTs", mppTask.MppQueryID.QueryTs), zap.Uint64("LocalQueryId", mppTask.MppQueryID.LocalQueryID), + zap.Uint64("ServerID", mppTask.MppQueryID.ServerID), zap.String("address", mppTask.Meta.GetAddress()), zap.String("plan", plannercore.ToString(pf.ExchangeSender))) req := &kv.MPPDispatchRequest{ - Data: pbData, - Meta: mppTask.Meta, - ID: mppTask.ID, - IsRoot: pf.IsRoot, - Timeout: 10, - SchemaVar: e.is.SchemaMetaVersion(), - StartTs: e.startTS, - State: kv.MppTaskReady, + Data: pbData, + Meta: mppTask.Meta, + ID: mppTask.ID, + IsRoot: pf.IsRoot, + Timeout: 10, + SchemaVar: e.is.SchemaMetaVersion(), + StartTs: e.startTS, + MppQueryID: mppTask.MppQueryID, + State: kv.MppTaskReady, } e.mppReqs = append(e.mppReqs, req) } @@ -109,7 +127,7 @@ func (e *MPPGather) Open(ctx context.Context) (err error) { // TODO: Move the construct tasks logic to planner, so we can see the explain results. sender := e.originalPlan.(*plannercore.PhysicalExchangeSender) planIDs := collectPlanIDS(e.originalPlan, nil) - frags, err := plannercore.GenerateRootMPPTasks(e.ctx, e.startTS, sender, e.is) + frags, err := plannercore.GenerateRootMPPTasks(e.ctx, e.startTS, e.mppQueryID, sender, e.is) if err != nil { return errors.Trace(err) } @@ -124,7 +142,7 @@ func (e *MPPGather) Open(ctx context.Context) (err error) { failpoint.Return(errors.Errorf("The number of tasks is not right, expect %d tasks but actually there are %d tasks", val.(int), len(e.mppReqs))) } }) - e.respIter, err = distsql.DispatchMPPTasks(ctx, e.ctx, e.mppReqs, e.retFieldTypes, planIDs, e.id, e.startTS) + e.respIter, err = distsql.DispatchMPPTasks(ctx, e.ctx, e.mppReqs, e.retFieldTypes, planIDs, e.id, e.startTS, e.mppQueryID) if err != nil { return errors.Trace(err) } diff --git a/executor/oomtest/BUILD.bazel b/executor/oomtest/BUILD.bazel index 029b3b105c8f1..2fd8fe00f7d23 100644 --- a/executor/oomtest/BUILD.bazel +++ b/executor/oomtest/BUILD.bazel @@ -5,9 +5,11 @@ go_test( timeout = "short", srcs = ["oom_test.go"], flaky = True, + race = "on", deps = [ "//testkit", "//testkit/testsetup", + "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_log//:log", "@com_github_stretchr_testify//require", "@org_uber_go_goleak//:goleak", diff --git a/executor/oomtest/oom_test.go b/executor/oomtest/oom_test.go index a8c86388c7bfe..fc95bb47ceab8 100644 --- a/executor/oomtest/oom_test.go +++ b/executor/oomtest/oom_test.go @@ -22,6 +22,7 @@ import ( "sync" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/log" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/testsetup" @@ -36,6 +37,7 @@ func TestMain(m *testing.M) { registerHook() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) @@ -135,6 +137,7 @@ func TestMemTracker4DeleteExec(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec("create table MemTracker4DeleteExec1 (id int, a int, b int, index idx_a(`a`))") tk.MustExec("create table MemTracker4DeleteExec2 (id int, a int, b int, index idx_a(`a`))") @@ -148,6 +151,7 @@ func TestMemTracker4DeleteExec(t *testing.T) { require.Equal(t, "", oom.GetTracker()) tk.MustExec("insert into MemTracker4DeleteExec1 values (1,1,1), (2,2,2), (3,3,3)") tk.Session().GetSessionVars().MemQuotaQuery = 1 + tk.Session().GetSessionVars().MemTracker.SetBytesLimit(1) tk.MustExec("delete from MemTracker4DeleteExec1") require.Equal(t, "expensive_query during bootstrap phase", oom.GetTracker()) @@ -165,6 +169,10 @@ func TestMemTracker4DeleteExec(t *testing.T) { oom.SetTracker("") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/store/copr/disableFixedRowCountHint", "return")) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/store/copr/disableFixedRowCountHint")) + }() tk.Session().GetSessionVars().EnabledRateLimitAction = true tk.Session().GetSessionVars().MemQuotaQuery = 10000 tk.MustExec("delete MemTracker4DeleteExec1, MemTracker4DeleteExec2 from MemTracker4DeleteExec1 join MemTracker4DeleteExec2 on MemTracker4DeleteExec1.a=MemTracker4DeleteExec2.a") @@ -214,6 +222,11 @@ func (h *oomCapture) Write(entry zapcore.Entry, fields []zapcore.Field) error { h.tracker = str[begin+len("8001]") : end] return nil } + // They are just common background task and not related to the oom. + if entry.Message == "SetTiFlashGroupConfig" || + entry.Message == "record table item load status failed due to not finding item" { + return nil + } h.mu.Lock() h.tracker = entry.Message diff --git a/executor/parallel_apply.go b/executor/parallel_apply.go index d0aa68af87d2b..a0d418cc0e441 100644 --- a/executor/parallel_apply.go +++ b/executor/parallel_apply.go @@ -107,7 +107,7 @@ func (e *ParallelNestedLoopApplyExec) Open(ctx context.Context) error { e.hasMatch = make([]bool, e.concurrency) e.hasNull = make([]bool, e.concurrency) for i := 0; i < e.concurrency; i++ { - e.innerChunk[i] = newFirstChunk(e.innerExecs[i]) + e.innerChunk[i] = tryNewCacheChunk(e.innerExecs[i]) e.innerList[i] = chunk.NewList(retTypes(e.innerExecs[i]), e.initCap, e.maxChunkSize) e.innerList[i].GetMemTracker().SetLabel(memory.LabelForInnerList) e.innerList[i].GetMemTracker().AttachTo(e.memTracker) @@ -176,7 +176,6 @@ func (e *ParallelNestedLoopApplyExec) Close() error { if e.runtimeStats != nil { runtimeStats := newJoinRuntimeStats() - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, runtimeStats) if e.useCache { var hitRatio float64 if e.cacheAccessCounter > 0 { @@ -187,6 +186,7 @@ func (e *ParallelNestedLoopApplyExec) Close() error { runtimeStats.setCacheInfo(false, 0) } runtimeStats.SetConcurrencyInfo(execdetails.NewConcurrencyInfo("Concurrency", e.concurrency)) + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, runtimeStats) } return err } @@ -206,7 +206,7 @@ func (e *ParallelNestedLoopApplyExec) outerWorker(ctx context.Context) { var err error for { failpoint.Inject("parallelApplyOuterWorkerPanic", nil) - chk := newFirstChunk(e.outerExec) + chk := tryNewCacheChunk(e.outerExec) if err := Next(ctx, e.outerExec, chk); err != nil { e.putResult(nil, err) return diff --git a/executor/partition_table_test.go b/executor/partition_table_test.go index 0d6b05b7b2640..85b096c28ff0d 100644 --- a/executor/partition_table_test.go +++ b/executor/partition_table_test.go @@ -17,6 +17,7 @@ package executor_test import ( "fmt" "math/rand" + "strconv" "strings" "testing" "time" @@ -84,7 +85,7 @@ partition p2 values less than (10))`) // Table reader: one partition tk.MustQuery("select * from pt where c > 8").Check(testkit.Rows("9 9")) // Table reader: more than one partition - tk.MustQuery("select * from pt where c < 2 or c >= 9").Check(testkit.Rows("0 0", "9 9")) + tk.MustQuery("select * from pt where c < 2 or c >= 9").Sort().Check(testkit.Rows("0 0", "9 9")) // Index reader tk.MustQuery("select c from pt").Sort().Check(testkit.Rows("0", "2", "4", "6", "7", "9", "")) @@ -96,7 +97,7 @@ partition p2 values less than (10))`) tk.MustQuery("select /*+ use_index(pt, i_id) */ * from pt").Sort().Check(testkit.Rows("0 0", "2 2", "4 4", "6 6", "7 7", "9 9", " ")) tk.MustQuery("select /*+ use_index(pt, i_id) */ * from pt where id < 4 and c > 10").Check(testkit.Rows()) tk.MustQuery("select /*+ use_index(pt, i_id) */ * from pt where id < 10 and c > 8").Check(testkit.Rows("9 9")) - tk.MustQuery("select /*+ use_index(pt, i_id) */ * from pt where id < 10 and c < 2 or c >= 9").Check(testkit.Rows("0 0", "9 9")) + tk.MustQuery("select /*+ use_index(pt, i_id) */ * from pt where id < 10 and c < 2 or c >= 9").Sort().Check(testkit.Rows("0 0", "9 9")) // Index Merge tk.MustExec("set @@tidb_enable_index_merge = 1") @@ -356,7 +357,7 @@ func TestPartitionInfoDisable(t *testing.T) { tk.MustQuery("select * from t_info_null where (date = '2020-10-02' or date = '2020-10-06') and app = 'xxx' and media = '19003006'").Check(testkit.Rows()) } -func TestOrderByandLimit(t *testing.T) { +func TestOrderByAndLimit(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -377,14 +378,148 @@ func TestOrderByandLimit(t *testing.T) { // regular table tk.MustExec("create table tregular(a int, b int, index idx_a(a))") + // range partition table with int pk + tk.MustExec(`create table trange_intpk(a int primary key, b int) partition by range(a) ( + partition p0 values less than(300), + partition p1 values less than (500), + partition p2 values less than(1100));`) + + // hash partition table with int pk + tk.MustExec("create table thash_intpk(a int primary key, b int) partition by hash(a) partitions 4;") + + // regular table with int pk + tk.MustExec("create table tregular_intpk(a int primary key, b int)") + + // range partition table with clustered index + tk.MustExec(`create table trange_clustered(a int, b int, primary key(a, b) clustered) partition by range(a) ( + partition p0 values less than(300), + partition p1 values less than (500), + partition p2 values less than(1100));`) + + // hash partition table with clustered index + tk.MustExec("create table thash_clustered(a int, b int, primary key(a, b) clustered) partition by hash(a) partitions 4;") + + // regular table with clustered index + tk.MustExec("create table tregular_clustered(a int, b int, primary key(a, b) clustered)") + + listVals := make([]int, 0, 2000) + + for i := 0; i < 2000; i++ { + listVals = append(listVals, i) + } + rand.Shuffle(len(listVals), func(i, j int) { + listVals[i], listVals[j] = listVals[j], listVals[i] + }) + + var listVals1, listVals2, listVals3 string + + for i := 0; i <= 600; i++ { + listVals1 += strconv.Itoa(listVals[i]) + if i != 600 { + listVals1 += "," + } + } + for i := 601; i <= 1200; i++ { + listVals2 += strconv.Itoa(listVals[i]) + if i != 1200 { + listVals2 += "," + } + } + for i := 1201; i <= 1999; i++ { + listVals3 += strconv.Itoa(listVals[i]) + if i != 1999 { + listVals3 += "," + } + } + + tk.MustExec(fmt.Sprintf(`create table tlist_intpk(a int primary key, b int) partition by list(a)( + partition p1 values in (%s), + partition p2 values in (%s), + partition p3 values in (%s) + )`, listVals1, listVals2, listVals3)) + tk.MustExec(fmt.Sprintf(`create table tlist(a int, b int, index idx_a(a)) partition by list(a)( + partition p1 values in (%s), + partition p2 values in (%s), + partition p3 values in (%s) + )`, listVals1, listVals2, listVals3)) + tk.MustExec(fmt.Sprintf(`create table tlist_clustered(a int, b int, primary key(a, b)) partition by list(a)( + partition p1 values in (%s), + partition p2 values in (%s), + partition p3 values in (%s) + )`, listVals1, listVals2, listVals3)) + // generate some random data to be inserted vals := make([]string, 0, 2000) for i := 0; i < 2000; i++ { vals = append(vals, fmt.Sprintf("(%v, %v)", rand.Intn(1100), rand.Intn(2000))) } - tk.MustExec("insert into trange values " + strings.Join(vals, ",")) - tk.MustExec("insert into thash values " + strings.Join(vals, ",")) - tk.MustExec("insert into tregular values " + strings.Join(vals, ",")) + + dedupValsA := make([]string, 0, 2000) + dedupMapA := make(map[int]struct{}, 2000) + for i := 0; i < 2000; i++ { + valA := rand.Intn(1100) + if _, ok := dedupMapA[valA]; ok { + continue + } + dedupValsA = append(dedupValsA, fmt.Sprintf("(%v, %v)", valA, rand.Intn(2000))) + dedupMapA[valA] = struct{}{} + } + + dedupValsAB := make([]string, 0, 2000) + dedupMapAB := make(map[string]struct{}, 2000) + for i := 0; i < 2000; i++ { + val := fmt.Sprintf("(%v, %v)", rand.Intn(1100), rand.Intn(2000)) + if _, ok := dedupMapAB[val]; ok { + continue + } + dedupValsAB = append(dedupValsAB, val) + dedupMapAB[val] = struct{}{} + } + + valInserted := strings.Join(vals, ",") + valDedupAInserted := strings.Join(dedupValsA, ",") + valDedupABInserted := strings.Join(dedupValsAB, ",") + + tk.MustExec("insert into trange values " + valInserted) + tk.MustExec("insert into thash values " + valInserted) + tk.MustExec("insert into tlist values" + valInserted) + tk.MustExec("insert into tregular values " + valInserted) + tk.MustExec("insert into trange_intpk values " + valDedupAInserted) + tk.MustExec("insert into thash_intpk values " + valDedupAInserted) + tk.MustExec("insert into tlist_intpk values " + valDedupAInserted) + tk.MustExec("insert into tregular_intpk values " + valDedupAInserted) + tk.MustExec("insert into trange_clustered values " + valDedupABInserted) + tk.MustExec("insert into thash_clustered values " + valDedupABInserted) + tk.MustExec("insert into tlist_clustered values " + valDedupABInserted) + tk.MustExec("insert into tregular_clustered values " + valDedupABInserted) + + tk.MustExec("analyze table trange") + tk.MustExec("analyze table trange_intpk") + tk.MustExec("analyze table trange_clustered") + tk.MustExec("analyze table thash") + tk.MustExec("analyze table thash_intpk") + tk.MustExec("analyze table thash_clustered") + tk.MustExec("analyze table tregular") + tk.MustExec("analyze table tregular_intpk") + tk.MustExec("analyze table tregular_clustered") + tk.MustExec("analyze table tlist") + tk.MustExec("analyze table tlist_intpk") + tk.MustExec("analyze table tlist_clustered") + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Session()) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test_orderby_limit")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if strings.HasPrefix(tblInfo.Name.L, "tr") || strings.HasPrefix(tblInfo.Name.L, "thash") || strings.HasPrefix(tblInfo.Name.L, "tlist") { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + tk.MustExec("set @@session.tidb_isolation_read_engines=\"tikv\"") // test indexLookUp for i := 0; i < 100; i++ { @@ -398,6 +533,34 @@ func TestOrderByandLimit(t *testing.T) { tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) } + // test indexLookUp with order property pushed down. + for i := 0; i < 100; i++ { + // explain select * from t where a > {y} use index(idx_a) order by a limit {x}; // check if IndexLookUp is used + // select * from t where a > {y} use index(idx_a) order by a limit {x}; // it can return the correct result + x := rand.Intn(1099) + y := rand.Intn(2000) + 1 + // Since we only use order by a not order by a, b, the result is not stable when we read both a and b. + // We cut the max element so that the result can be stable. + maxEle := tk.MustQuery(fmt.Sprintf("select ifnull(max(a), 1100) from (select * from tregular use index(idx_a) where a > %v order by a limit %v) t", x, y)).Rows()[0][0] + queryRangePartitionWithLimitHint := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from trange use index(idx_a) where a > %v and a < greatest(%v+1, %v) order by a limit %v", x, x+1, maxEle, y) + queryHashPartitionWithLimitHint := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from thash use index(idx_a) where a > %v and a < greatest(%v+1, %v) order by a limit %v", x, x+1, maxEle, y) + queryListPartitionWithLimitHint := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from thash use index(idx_a) where a > %v and a < greatest(%v+1, %v) order by a limit %v", x, x+1, maxEle, y) + queryRegular := fmt.Sprintf("select * from tregular use index(idx_a) where a > %v and a < greatest(%v+1, %v) order by a limit %v;", x, x+1, maxEle, y) + require.True(t, tk.HasPlan(queryRangePartitionWithLimitHint, "Limit")) + require.True(t, tk.HasPlan(queryRangePartitionWithLimitHint, "IndexLookUp")) + require.True(t, tk.HasPlan(queryHashPartitionWithLimitHint, "Limit")) + require.True(t, tk.HasPlan(queryHashPartitionWithLimitHint, "IndexLookUp")) + require.True(t, tk.HasPlan(queryListPartitionWithLimitHint, "Limit")) + require.True(t, tk.HasPlan(queryListPartitionWithLimitHint, "IndexLookUp")) + require.True(t, tk.HasPlan(queryRangePartitionWithLimitHint, "TopN")) // but not fully pushed + require.True(t, tk.HasPlan(queryHashPartitionWithLimitHint, "TopN")) + require.True(t, tk.HasPlan(queryListPartitionWithLimitHint, "TopN")) + regularResult := tk.MustQuery(queryRegular).Sort().Rows() + tk.MustQuery(queryRangePartitionWithLimitHint).Sort().Check(regularResult) + tk.MustQuery(queryHashPartitionWithLimitHint).Sort().Check(regularResult) + tk.MustQuery(queryListPartitionWithLimitHint).Sort().Check(regularResult) + } + // test tableReader for i := 0; i < 100; i++ { // explain select * from t where a > {y} ignore index(idx_a) order by a limit {x}; // check if IndexLookUp is used @@ -410,6 +573,119 @@ func TestOrderByandLimit(t *testing.T) { tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) } + // test tableReader with order property pushed down. + for i := 0; i < 100; i++ { + // explain select * from t where a > {y} ignore index(idx_a) order by a limit {x}; // check if IndexLookUp is used + // select * from t where a > {y} ignore index(idx_a) order by a limit {x}; // it can return the correct result + x := rand.Intn(1099) + y := rand.Intn(2000) + 1 + queryRangePartition := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from trange ignore index(idx_a) where a > %v order by a, b limit %v;", x, y) + queryHashPartition := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from thash ignore index(idx_a) where a > %v order by a, b limit %v;", x, y) + queryListPartition := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from tlist ignore index(idx_a) where a > %v order by a, b limit %v;", x, y) + queryRegular := fmt.Sprintf("select * from tregular ignore index(idx_a) where a > %v order by a, b limit %v;", x, y) + require.True(t, tk.HasPlan(queryRangePartition, "TableReader")) // check if tableReader is used + require.True(t, tk.HasPlan(queryHashPartition, "TableReader")) + require.True(t, tk.HasPlan(queryListPartition, "TableReader")) + require.False(t, tk.HasPlan(queryRangePartition, "Limit")) // check if order property is not pushed + require.False(t, tk.HasPlan(queryHashPartition, "Limit")) + require.False(t, tk.HasPlan(queryListPartition, "Limit")) + regularResult := tk.MustQuery(queryRegular).Sort().Rows() + tk.MustQuery(queryRangePartition).Sort().Check(regularResult) + tk.MustQuery(queryHashPartition).Sort().Check(regularResult) + tk.MustQuery(queryListPartition).Sort().Check(regularResult) + + // test int pk + // To be simplified, we only read column a. + queryRangePartition = fmt.Sprintf("select /*+ LIMIT_TO_COP() */ a from trange_intpk use index(primary) where a > %v order by a limit %v", x, y) + queryHashPartition = fmt.Sprintf("select /*+ LIMIT_TO_COP() */ a from thash_intpk use index(primary) where a > %v order by a limit %v", x, y) + queryListPartition = fmt.Sprintf("select /*+ LIMIT_TO_COP() */ a from tlist_intpk use index(primary) where a > %v order by a limit %v", x, y) + queryRegular = fmt.Sprintf("select a from tregular_intpk where a > %v order by a limit %v", x, y) + require.True(t, tk.HasPlan(queryRangePartition, "TableReader")) + require.True(t, tk.HasPlan(queryHashPartition, "TableReader")) + require.True(t, tk.HasPlan(queryListPartition, "TableReader")) + require.True(t, tk.HasPlan(queryRangePartition, "Limit")) // check if order property is not pushed + require.True(t, tk.HasPlan(queryHashPartition, "Limit")) + require.True(t, tk.HasPlan(queryListPartition, "Limit")) + regularResult = tk.MustQuery(queryRegular).Rows() + tk.MustQuery(queryRangePartition).Check(regularResult) + tk.MustQuery(queryHashPartition).Check(regularResult) + tk.MustQuery(queryListPartition).Check(regularResult) + + // test clustered index + queryRangePartition = fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from trange_clustered use index(primary) where a > %v order by a, b limit %v;", x, y) + queryHashPartition = fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from thash_clustered use index(primary) where a > %v order by a, b limit %v;", x, y) + queryListPartition = fmt.Sprintf("select /*+ LIMIT_TO_COP() */ * from tlist_clustered use index(primary) where a > %v order by a, b limit %v;", x, y) + queryRegular = fmt.Sprintf("select * from tregular_clustered where a > %v order by a, b limit %v;", x, y) + require.True(t, tk.HasPlan(queryRangePartition, "TableReader")) // check if tableReader is used + require.True(t, tk.HasPlan(queryHashPartition, "TableReader")) + require.True(t, tk.HasPlan(queryListPartition, "TableReader")) + require.True(t, tk.HasPlan(queryRangePartition, "Limit")) // check if order property is pushed + require.True(t, tk.HasPlan(queryHashPartition, "Limit")) + require.True(t, tk.HasPlan(queryListPartition, "Limit")) + require.True(t, tk.HasPlan(queryRangePartition, "TopN")) // but not fully pushed + require.True(t, tk.HasPlan(queryHashPartition, "TopN")) + require.True(t, tk.HasPlan(queryListPartition, "TopN")) + regularResult = tk.MustQuery(queryRegular).Rows() + tk.MustQuery(queryRangePartition).Check(regularResult) + tk.MustQuery(queryHashPartition).Check(regularResult) + tk.MustQuery(queryListPartition).Check(regularResult) + + tk.MustExec(" set @@tidb_allow_mpp=1;") + tk.MustExec("set @@session.tidb_isolation_read_engines=\"tiflash,tikv\"") + queryPartitionWithTiFlash := fmt.Sprintf("select /*+ read_from_storage(tiflash[trange_intpk]) */ * from trange_intpk where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + // but order is not pushed + require.False(t, tk.HasPlan(queryPartitionWithTiFlash, "Limit"), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[trange_intpk]) */ /*+ LIMIT_TO_COP() */ * from trange_intpk where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + // but order is not pushed + require.False(t, tk.HasPlan(queryPartitionWithTiFlash, "Limit"), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[trange_clustered]) */ * from trange_clustered where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[trange_clustered]) */ /*+ LIMIT_TO_COP() */ * from trange_clustered where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash)) + // but order is not pushed + require.False(t, tk.HasPlan(queryPartitionWithTiFlash, "Limit"), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[thash_intpk]) */ * from thash_intpk where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[thash_intpk]) */ /*+ LIMIT_TO_COP() */ * from thash_intpk where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash)) + // but order is not pushed + require.False(t, tk.HasPlan(queryPartitionWithTiFlash, "Limit"), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[thash_clustered]) */ * from thash_clustered where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[thash_clustered]) */ /*+ LIMIT_TO_COP() */ * from thash_clustered where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash)) + // but order is not pushed + require.False(t, tk.HasPlan(queryPartitionWithTiFlash, "Limit"), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[tlist_intpk]) */ * from tlist_intpk where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[tlist_intpk]) */ /*+ LIMIT_TO_COP() */ * from tlist_intpk where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash)) + // but order is not pushed + require.False(t, tk.HasPlan(queryPartitionWithTiFlash, "Limit"), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[tlist_clustered]) */ * from tlist_clustered where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + queryPartitionWithTiFlash = fmt.Sprintf("select /*+ read_from_storage(tiflash[tlist_clustered]) */ /*+ LIMIT_TO_COP() */ * from tlist_clustered where a > %v order by a limit %v", x, y) + // check if tiflash is used + require.True(t, tk.HasTiFlashPlan(queryPartitionWithTiFlash)) + // but order is not pushed + require.False(t, tk.HasPlan(queryPartitionWithTiFlash, "Limit"), fmt.Sprintf("%v", tk.MustQuery("explain "+queryPartitionWithTiFlash).Rows())) + tk.MustExec(" set @@tidb_allow_mpp=0;") + tk.MustExec("set @@session.tidb_isolation_read_engines=\"tikv\"") + } + // test indexReader for i := 0; i < 100; i++ { // explain select a from t where a > {y} use index(idx_a) order by a limit {x}; // check if IndexLookUp is used @@ -422,6 +698,24 @@ func TestOrderByandLimit(t *testing.T) { tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) } + // test indexReader with order property pushed down. + for i := 0; i < 100; i++ { + // explain select a from t where a > {y} use index(idx_a) order by a limit {x}; // check if IndexLookUp is used + // select a from t where a > {y} use index(idx_a) order by a limit {x}; // it can return the correct result + x := rand.Intn(1099) + y := rand.Intn(2000) + 1 + queryRangePartition := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ a from trange use index(idx_a) where a > %v order by a limit %v;", x, y) + queryHashPartition := fmt.Sprintf("select /*+ LIMIT_TO_COP() */ a from trange use index(idx_a) where a > %v order by a limit %v;", x, y) + queryRegular := fmt.Sprintf("select a from tregular use index(idx_a) where a > %v order by a limit %v;", x, y) + require.True(t, tk.HasPlan(queryRangePartition, "IndexReader")) // check if indexReader is used + require.True(t, tk.HasPlan(queryHashPartition, "IndexReader")) + require.True(t, tk.HasPlan(queryRangePartition, "Limit")) // check if order property is pushed + require.True(t, tk.HasPlan(queryHashPartition, "Limit")) + regularResult := tk.MustQuery(queryRegular).Sort().Rows() + tk.MustQuery(queryRangePartition).Sort().Check(regularResult) + tk.MustQuery(queryHashPartition).Sort().Check(regularResult) + } + // test indexMerge for i := 0; i < 100; i++ { // explain select /*+ use_index_merge(t) */ * from t where a > 2 or b < 5 order by a limit {x}; // check if IndexMerge is used @@ -434,6 +728,17 @@ func TestOrderByandLimit(t *testing.T) { } } +func TestOrderByOnUnsignedPk(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table tunsigned_hash(a bigint unsigned primary key) partition by hash(a) partitions 6") + tk.MustExec("insert into tunsigned_hash values(25), (9279808998424041135)") + tk.MustQuery("select min(a) from tunsigned_hash").Check(testkit.Rows("25")) + tk.MustQuery("select max(a) from tunsigned_hash").Check(testkit.Rows("9279808998424041135")) +} + func TestBatchGetandPointGetwithHashPartition(t *testing.T) { store := testkit.CreateMockStore(t) @@ -602,10 +907,10 @@ func TestDirectReadingwithIndexJoin(t *testing.T) { "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test_dr_join.touter.b))", "│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root partition:all ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test_dr_join.thash.b))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(test_dr_join.thash.b, test_dr_join.touter.b)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:thash keep order:false, stats:pseudo")) // check if IndexLookUp is used + "└─IndexLookUp(Probe) 12487.50 root partition:all ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test_dr_join.thash.b))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(test_dr_join.thash.b, test_dr_join.touter.b)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12487.50 cop[tikv] table:thash keep order:false, stats:pseudo")) // check if IndexLookUp is used tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) // test tableReader + hash @@ -616,8 +921,8 @@ func TestDirectReadingwithIndexJoin(t *testing.T) { "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test_dr_join.touter.a))", "│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root partition:all data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:thash range: decided by [test_dr_join.touter.a], keep order:false, stats:pseudo")) // check if tableReader is used + "└─TableReader(Probe) 9990.00 root partition:all data:TableRangeScan", + " └─TableRangeScan 9990.00 cop[tikv] table:thash range: decided by [test_dr_join.touter.a], keep order:false, stats:pseudo")) // check if tableReader is used tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) // test indexReader + hash @@ -628,9 +933,9 @@ func TestDirectReadingwithIndexJoin(t *testing.T) { "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test_dr_join.touter.b))", "│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo", - "└─IndexReader(Probe) 1.25 root partition:all index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test_dr_join.thash.b))", - " └─IndexRangeScan 1.25 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(test_dr_join.thash.b, test_dr_join.touter.b)], keep order:false, stats:pseudo")) // check if indexReader is used + "└─IndexReader(Probe) 12487.50 root partition:all index:Selection", + " └─Selection 12487.50 cop[tikv] not(isnull(test_dr_join.thash.b))", + " └─IndexRangeScan 12500.00 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(test_dr_join.thash.b, test_dr_join.touter.b)], keep order:false, stats:pseudo")) // check if indexReader is used tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) // test indexLookUp + range @@ -642,10 +947,10 @@ func TestDirectReadingwithIndexJoin(t *testing.T) { "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test_dr_join.touter.b))", "│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root partition:all ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test_dr_join.trange.b))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:trange, index:idx_b(b) range: decided by [eq(test_dr_join.trange.b, test_dr_join.touter.b)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:trange keep order:false, stats:pseudo")) // check if IndexLookUp is used + "└─IndexLookUp(Probe) 12487.50 root partition:all ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test_dr_join.trange.b))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:trange, index:idx_b(b) range: decided by [eq(test_dr_join.trange.b, test_dr_join.touter.b)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12487.50 cop[tikv] table:trange keep order:false, stats:pseudo")) // check if IndexLookUp is used tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) // test tableReader + range @@ -656,8 +961,8 @@ func TestDirectReadingwithIndexJoin(t *testing.T) { "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test_dr_join.touter.a))", "│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root partition:all data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:trange range: decided by [test_dr_join.touter.a], keep order:false, stats:pseudo")) // check if tableReader is used + "└─TableReader(Probe) 9990.00 root partition:all data:TableRangeScan", + " └─TableRangeScan 9990.00 cop[tikv] table:trange range: decided by [test_dr_join.touter.a], keep order:false, stats:pseudo")) // check if tableReader is used tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) // test indexReader + range @@ -669,9 +974,9 @@ func TestDirectReadingwithIndexJoin(t *testing.T) { "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test_dr_join.touter.b))", "│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo", - "└─IndexReader(Probe) 1.25 root partition:all index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test_dr_join.trange.b))", - " └─IndexRangeScan 1.25 cop[tikv] table:trange, index:idx_b(b) range: decided by [eq(test_dr_join.trange.b, test_dr_join.touter.b)], keep order:false, stats:pseudo")) // check if indexReader is used + "└─IndexReader(Probe) 12487.50 root partition:all index:Selection", + " └─Selection 12487.50 cop[tikv] not(isnull(test_dr_join.trange.b))", + " └─IndexRangeScan 12500.00 cop[tikv] table:trange, index:idx_b(b) range: decided by [eq(test_dr_join.trange.b, test_dr_join.touter.b)], keep order:false, stats:pseudo")) // check if indexReader is used tk.MustQuery(queryPartition).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows()) } @@ -705,9 +1010,9 @@ func TestDynamicPruningUnderIndexJoin(t *testing.T) { `├─TableReader(Build) 9990.00 root data:Selection`, `│ └─Selection 9990.00 cop[tikv] not(isnull(pruing_under_index_join.touter.b))`, `│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - `└─IndexReader(Probe) 1.25 root partition:all index:Selection`, - ` └─Selection 1.25 cop[tikv] not(isnull(pruing_under_index_join.thash.b))`, - ` └─IndexRangeScan 1.25 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(pruing_under_index_join.thash.b, pruing_under_index_join.touter.b)], keep order:false, stats:pseudo`)) + `└─IndexReader(Probe) 12487.50 root partition:all index:Selection`, + ` └─Selection 12487.50 cop[tikv] not(isnull(pruing_under_index_join.thash.b))`, + ` └─IndexRangeScan 12500.00 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(pruing_under_index_join.thash.b, pruing_under_index_join.touter.b)], keep order:false, stats:pseudo`)) tk.MustQuery(`select /*+ INL_JOIN(touter, thash) */ thash.b from touter join thash use index(idx_b) on touter.b = thash.b`).Sort().Check( tk.MustQuery(`select /*+ INL_JOIN(touter, tnormal) */ tnormal.b from touter join tnormal use index(idx_b) on touter.b = tnormal.b`).Sort().Rows()) @@ -717,8 +1022,8 @@ func TestDynamicPruningUnderIndexJoin(t *testing.T) { `├─TableReader(Build) 9990.00 root data:Selection`, `│ └─Selection 9990.00 cop[tikv] not(isnull(pruing_under_index_join.touter.b))`, `│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - `└─TableReader(Probe) 1.00 root partition:all data:TableRangeScan`, - ` └─TableRangeScan 1.00 cop[tikv] table:thash range: decided by [pruing_under_index_join.touter.b], keep order:false, stats:pseudo`)) + `└─TableReader(Probe) 9990.00 root partition:all data:TableRangeScan`, + ` └─TableRangeScan 9990.00 cop[tikv] table:thash range: decided by [pruing_under_index_join.touter.b], keep order:false, stats:pseudo`)) tk.MustQuery(`select /*+ INL_JOIN(touter, thash) */ thash.* from touter join thash use index(primary) on touter.b = thash.a`).Sort().Check( tk.MustQuery(`select /*+ INL_JOIN(touter, tnormal) */ tnormal.* from touter join tnormal use index(primary) on touter.b = tnormal.a`).Sort().Rows()) @@ -728,10 +1033,10 @@ func TestDynamicPruningUnderIndexJoin(t *testing.T) { `├─TableReader(Build) 9990.00 root data:Selection`, `│ └─Selection 9990.00 cop[tikv] not(isnull(pruing_under_index_join.touter.b))`, `│ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - `└─IndexLookUp(Probe) 1.25 root partition:all `, - ` ├─Selection(Build) 1.25 cop[tikv] not(isnull(pruing_under_index_join.thash.b))`, - ` │ └─IndexRangeScan 1.25 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(pruing_under_index_join.thash.b, pruing_under_index_join.touter.b)], keep order:false, stats:pseudo`, - ` └─TableRowIDScan(Probe) 1.25 cop[tikv] table:thash keep order:false, stats:pseudo`)) + `└─IndexLookUp(Probe) 12487.50 root partition:all `, + ` ├─Selection(Build) 12487.50 cop[tikv] not(isnull(pruing_under_index_join.thash.b))`, + ` │ └─IndexRangeScan 12500.00 cop[tikv] table:thash, index:idx_b(b) range: decided by [eq(pruing_under_index_join.thash.b, pruing_under_index_join.touter.b)], keep order:false, stats:pseudo`, + ` └─TableRowIDScan(Probe) 12487.50 cop[tikv] table:thash keep order:false, stats:pseudo`)) tk.MustQuery(`select /*+ INL_JOIN(touter, thash) */ thash.* from touter join thash use index(idx_b) on touter.b = thash.b`).Sort().Check( tk.MustQuery(`select /*+ INL_JOIN(touter, tnormal) */ tnormal.* from touter join tnormal use index(idx_b) on touter.b = tnormal.b`).Sort().Rows()) } @@ -910,6 +1215,7 @@ func TestGlobalStatsAndSQLBinding(t *testing.T) { tk.MustExec("create database test_global_stats") tk.MustExec("use test_global_stats") tk.MustExec("set @@tidb_partition_prune_mode = 'dynamic'") + tk.MustExec("set tidb_cost_model_version=2") // hash and range and list partition tk.MustExec("create table thash(a int, b int, key(a)) partition by hash(a) partitions 4") @@ -953,10 +1259,9 @@ func TestGlobalStatsAndSQLBinding(t *testing.T) { tk.MustExec("analyze table trange") tk.MustExec("analyze table tlist") - // after analyzing, the planner will use the Index(a) - tk.MustIndexLookup("select * from thash where a<100") - tk.MustIndexLookup("select * from trange where a<100") - tk.MustIndexLookup("select * from tlist where a<1") + require.True(t, tk.HasPlan("select * from thash where a<100", "TableFullScan")) + require.True(t, tk.HasPlan("select * from trange where a<100", "TableFullScan")) + require.True(t, tk.HasPlan("select * from tlist where a<1", "TableFullScan")) // create SQL bindings tk.MustExec("create session binding for select * from thash where a<100 using select * from thash ignore index(a) where a<100") @@ -973,10 +1278,9 @@ func TestGlobalStatsAndSQLBinding(t *testing.T) { tk.MustExec("drop session binding for select * from trange where a<100") tk.MustExec("drop session binding for select * from tlist where a<100") - // use Index(a) again - tk.MustIndexLookup("select * from thash where a<100") - tk.MustIndexLookup("select * from trange where a<100") - tk.MustIndexLookup("select * from tlist where a<1") + require.True(t, tk.HasPlan("select * from thash where a<100", "TableFullScan")) + require.True(t, tk.HasPlan("select * from trange where a<100", "TableFullScan")) + require.True(t, tk.HasPlan("select * from tlist where a<1", "TableFullScan")) } func TestPartitionTableWithDifferentJoin(t *testing.T) { @@ -2116,6 +2420,7 @@ func TestParallelApply(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("create database test_parallel_apply") tk.MustExec("use test_parallel_apply") tk.MustExec("set @@tidb_partition_prune_mode = 'dynamic'") @@ -2150,11 +2455,11 @@ func TestParallelApply(t *testing.T) { `└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(cast(test_parallel_apply.touter.a, decimal(10,0) BINARY), Column#7)`, ` ├─TableReader(Build) 10000.00 root data:TableFullScan`, ` │ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - ` └─StreamAgg(Probe) 1.00 root funcs:sum(Column#9)->Column#7`, - ` └─IndexReader 1.00 root partition:all index:StreamAgg`, // IndexReader is a inner child of Apply - ` └─StreamAgg 1.00 cop[tikv] funcs:sum(test_parallel_apply.thash.a)->Column#9`, - ` └─Selection 8000.00 cop[tikv] gt(test_parallel_apply.thash.a, test_parallel_apply.touter.b)`, - ` └─IndexFullScan 10000.00 cop[tikv] table:thash, index:a(a) keep order:false, stats:pseudo`)) + ` └─HashAgg(Probe) 10000.00 root funcs:sum(Column#8)->Column#7`, + ` └─IndexReader 10000.00 root partition:all index:HashAgg`, // IndexReader is a inner child of Apply + ` └─HashAgg 10000.00 cop[tikv] funcs:sum(test_parallel_apply.thash.a)->Column#8`, + ` └─Selection 80000000.00 cop[tikv] gt(test_parallel_apply.thash.a, test_parallel_apply.touter.b)`, + ` └─IndexFullScan 100000000.00 cop[tikv] table:thash, index:a(a) keep order:false, stats:pseudo`)) tk.MustQuery(`select * from touter where touter.a > (select sum(thash.a) from thash use index(a) where thash.a>touter.b)`).Sort().Check( tk.MustQuery(`select * from touter where touter.a > (select sum(tinner.a) from tinner use index(a) where tinner.a>touter.b)`).Sort().Rows()) @@ -2164,11 +2469,11 @@ func TestParallelApply(t *testing.T) { `└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(cast(test_parallel_apply.touter.a, decimal(10,0) BINARY), Column#7)`, ` ├─TableReader(Build) 10000.00 root data:TableFullScan`, ` │ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - ` └─StreamAgg(Probe) 1.00 root funcs:sum(Column#9)->Column#7`, - ` └─TableReader 1.00 root partition:all data:StreamAgg`, // TableReader is a inner child of Apply - ` └─StreamAgg 1.00 cop[tikv] funcs:sum(test_parallel_apply.thash.b)->Column#9`, - ` └─Selection 8000.00 cop[tikv] gt(test_parallel_apply.thash.a, test_parallel_apply.touter.b)`, - ` └─TableFullScan 10000.00 cop[tikv] table:thash keep order:false, stats:pseudo`)) + ` └─HashAgg(Probe) 10000.00 root funcs:sum(Column#8)->Column#7`, + ` └─TableReader 10000.00 root partition:all data:HashAgg`, // TableReader is a inner child of Apply + ` └─HashAgg 10000.00 cop[tikv] funcs:sum(test_parallel_apply.thash.b)->Column#8`, + ` └─Selection 80000000.00 cop[tikv] gt(test_parallel_apply.thash.a, test_parallel_apply.touter.b)`, + ` └─TableFullScan 100000000.00 cop[tikv] table:thash keep order:false, stats:pseudo`)) tk.MustQuery(`select * from touter where touter.a > (select sum(thash.b) from thash ignore index(a) where thash.a>touter.b)`).Sort().Check( tk.MustQuery(`select * from touter where touter.a > (select sum(tinner.b) from tinner ignore index(a) where tinner.a>touter.b)`).Sort().Rows()) @@ -2178,12 +2483,12 @@ func TestParallelApply(t *testing.T) { `└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(cast(test_parallel_apply.touter.a, decimal(10,0) BINARY), Column#7)`, ` ├─TableReader(Build) 10000.00 root data:TableFullScan`, ` │ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - ` └─HashAgg(Probe) 1.00 root funcs:sum(Column#9)->Column#7`, - ` └─IndexLookUp 1.00 root `, // IndexLookUp is a inner child of Apply - ` ├─Selection(Build) 8000.00 cop[tikv] gt(test_parallel_apply.tinner.a, test_parallel_apply.touter.b)`, - ` │ └─IndexFullScan 10000.00 cop[tikv] table:tinner, index:a(a) keep order:false, stats:pseudo`, - ` └─HashAgg(Probe) 1.00 cop[tikv] funcs:sum(test_parallel_apply.tinner.b)->Column#9`, - ` └─TableRowIDScan 8000.00 cop[tikv] table:tinner keep order:false, stats:pseudo`)) + ` └─HashAgg(Probe) 10000.00 root funcs:sum(Column#9)->Column#7`, + ` └─IndexLookUp 10000.00 root `, // IndexLookUp is a inner child of Apply + ` ├─Selection(Build) 80000000.00 cop[tikv] gt(test_parallel_apply.tinner.a, test_parallel_apply.touter.b)`, + ` │ └─IndexFullScan 100000000.00 cop[tikv] table:tinner, index:a(a) keep order:false, stats:pseudo`, + ` └─HashAgg(Probe) 10000.00 cop[tikv] funcs:sum(test_parallel_apply.tinner.b)->Column#9`, + ` └─TableRowIDScan 80000000.00 cop[tikv] table:tinner keep order:false, stats:pseudo`)) tk.MustQuery(`select * from touter where touter.a > (select sum(thash.b) from thash use index(a) where thash.a>touter.b)`).Sort().Check( tk.MustQuery(`select * from touter where touter.a > (select sum(tinner.b) from tinner use index(a) where tinner.a>touter.b)`).Sort().Rows()) @@ -2193,11 +2498,11 @@ func TestParallelApply(t *testing.T) { `└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(cast(test_parallel_apply.touter.a, decimal(10,0) BINARY), Column#7)`, ` ├─TableReader(Build) 10000.00 root data:TableFullScan`, ` │ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - ` └─StreamAgg(Probe) 1.00 root funcs:sum(Column#9)->Column#7`, - ` └─IndexReader 1.00 root partition:all index:StreamAgg`, // IndexReader is a inner child of Apply - ` └─StreamAgg 1.00 cop[tikv] funcs:sum(test_parallel_apply.trange.a)->Column#9`, - ` └─Selection 8000.00 cop[tikv] gt(test_parallel_apply.trange.a, test_parallel_apply.touter.b)`, - ` └─IndexFullScan 10000.00 cop[tikv] table:trange, index:a(a) keep order:false, stats:pseudo`)) + ` └─HashAgg(Probe) 10000.00 root funcs:sum(Column#8)->Column#7`, + ` └─IndexReader 10000.00 root partition:all index:HashAgg`, // IndexReader is a inner child of Apply + ` └─HashAgg 10000.00 cop[tikv] funcs:sum(test_parallel_apply.trange.a)->Column#8`, + ` └─Selection 80000000.00 cop[tikv] gt(test_parallel_apply.trange.a, test_parallel_apply.touter.b)`, + ` └─IndexFullScan 100000000.00 cop[tikv] table:trange, index:a(a) keep order:false, stats:pseudo`)) tk.MustQuery(`select * from touter where touter.a > (select sum(trange.a) from trange use index(a) where trange.a>touter.b)`).Sort().Check( tk.MustQuery(`select * from touter where touter.a > (select sum(tinner.a) from tinner use index(a) where tinner.a>touter.b)`).Sort().Rows()) @@ -2207,11 +2512,11 @@ func TestParallelApply(t *testing.T) { `└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(cast(test_parallel_apply.touter.a, decimal(10,0) BINARY), Column#7)`, ` ├─TableReader(Build) 10000.00 root data:TableFullScan`, ` │ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - ` └─StreamAgg(Probe) 1.00 root funcs:sum(Column#9)->Column#7`, - ` └─TableReader 1.00 root partition:all data:StreamAgg`, // TableReader is a inner child of Apply - ` └─StreamAgg 1.00 cop[tikv] funcs:sum(test_parallel_apply.trange.b)->Column#9`, - ` └─Selection 8000.00 cop[tikv] gt(test_parallel_apply.trange.a, test_parallel_apply.touter.b)`, - ` └─TableFullScan 10000.00 cop[tikv] table:trange keep order:false, stats:pseudo`)) + ` └─HashAgg(Probe) 10000.00 root funcs:sum(Column#8)->Column#7`, + ` └─TableReader 10000.00 root partition:all data:HashAgg`, // TableReader is a inner child of Apply + ` └─HashAgg 10000.00 cop[tikv] funcs:sum(test_parallel_apply.trange.b)->Column#8`, + ` └─Selection 80000000.00 cop[tikv] gt(test_parallel_apply.trange.a, test_parallel_apply.touter.b)`, + ` └─TableFullScan 100000000.00 cop[tikv] table:trange keep order:false, stats:pseudo`)) tk.MustQuery(`select * from touter where touter.a > (select sum(trange.b) from trange ignore index(a) where trange.a>touter.b)`).Sort().Check( tk.MustQuery(`select * from touter where touter.a > (select sum(tinner.b) from tinner ignore index(a) where tinner.a>touter.b)`).Sort().Rows()) @@ -2221,12 +2526,12 @@ func TestParallelApply(t *testing.T) { `└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(cast(test_parallel_apply.touter.a, decimal(10,0) BINARY), Column#7)`, ` ├─TableReader(Build) 10000.00 root data:TableFullScan`, ` │ └─TableFullScan 10000.00 cop[tikv] table:touter keep order:false, stats:pseudo`, - ` └─HashAgg(Probe) 1.00 root funcs:sum(Column#9)->Column#7`, - ` └─IndexLookUp 1.00 root `, // IndexLookUp is a inner child of Apply - ` ├─Selection(Build) 8000.00 cop[tikv] gt(test_parallel_apply.tinner.a, test_parallel_apply.touter.b)`, - ` │ └─IndexFullScan 10000.00 cop[tikv] table:tinner, index:a(a) keep order:false, stats:pseudo`, - ` └─HashAgg(Probe) 1.00 cop[tikv] funcs:sum(test_parallel_apply.tinner.b)->Column#9`, - ` └─TableRowIDScan 8000.00 cop[tikv] table:tinner keep order:false, stats:pseudo`)) + ` └─HashAgg(Probe) 10000.00 root funcs:sum(Column#9)->Column#7`, + ` └─IndexLookUp 10000.00 root `, // IndexLookUp is a inner child of Apply + ` ├─Selection(Build) 80000000.00 cop[tikv] gt(test_parallel_apply.tinner.a, test_parallel_apply.touter.b)`, + ` │ └─IndexFullScan 100000000.00 cop[tikv] table:tinner, index:a(a) keep order:false, stats:pseudo`, + ` └─HashAgg(Probe) 10000.00 cop[tikv] funcs:sum(test_parallel_apply.tinner.b)->Column#9`, + ` └─TableRowIDScan 80000000.00 cop[tikv] table:tinner keep order:false, stats:pseudo`)) tk.MustQuery(`select * from touter where touter.a > (select sum(trange.b) from trange use index(a) where trange.a>touter.b)`).Sort().Check( tk.MustQuery(`select * from touter where touter.a > (select sum(tinner.b) from tinner use index(a) where tinner.a>touter.b)`).Sort().Rows()) @@ -2834,7 +3139,7 @@ partition p1 values less than (7), partition p2 values less than (10))`) tk.MustExec("alter table p add unique idx(id)") tk.MustExec("insert into p values (1,3), (3,4), (5,6), (7,9)") - tk.MustQuery("select id from p use index (idx)").Check(testkit.Rows("1", "3", "5", "7")) + tk.MustQuery("select id from p use index (idx) order by id").Check(testkit.Rows("1", "3", "5", "7")) } func TestGlobalIndexDoubleRead(t *testing.T) { @@ -3435,6 +3740,7 @@ func TestPartitionTableExplain(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("create database TestPartitionTableExplain") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("use TestPartitionTableExplain") tk.MustExec("set @@tidb_partition_prune_mode = 'static'") tk.MustExec(`create table t (a int primary key, b int, key (b)) partition by hash(a) (partition P0, partition p1, partition P2)`) @@ -3530,11 +3836,11 @@ func TestPartitionTableExplain(t *testing.T) { " └─IndexFullScan 1.00 cop[tikv] table:t, partition:p1, index:b(b) keep order:false")) tk.MustQuery(`explain format = 'brief' select * from t,t2 where t2.a = 1 and t2.b = t.b and t.a = 1`).Check(testkit.Rows( "HashJoin 1.00 root inner join, equal:[eq(testpartitiontableexplain.t.b, testpartitiontableexplain.t2.b)]", - "├─TableReader(Build) 1.00 root data:Selection", - "│ └─Selection 1.00 cop[tikv] eq(testpartitiontableexplain.t2.a, 1), not(isnull(testpartitiontableexplain.t2.b))", - "│ └─TableFullScan 3.00 cop[tikv] table:t2 keep order:false", - "└─Selection(Probe) 1.00 root not(isnull(testpartitiontableexplain.t.b))", - " └─Point_Get 1.00 root table:t, partition:p1 handle:1")) + `├─Selection(Build) 1.00 root not(isnull(testpartitiontableexplain.t.b))`, + `│ └─Point_Get 1.00 root table:t, partition:p1 handle:1`, + `└─TableReader(Probe) 1.00 root data:Selection`, + ` └─Selection 1.00 cop[tikv] eq(testpartitiontableexplain.t2.a, 1), not(isnull(testpartitiontableexplain.t2.b))`, + ` └─TableFullScan 3.00 cop[tikv] table:t2 keep order:false`)) tk.MustExec("set @@tidb_partition_prune_mode = 'dynamic'") tk.MustExec(`analyze table t`) @@ -3571,22 +3877,20 @@ func TestPartitionTableExplain(t *testing.T) { "└─IndexRangeScan 2.00 cop[tikv] table:t, index:b(b) range:[2,2], [3,3], keep order:false")) tk.MustQuery(`explain format = 'brief' select * from t,t2 where t2.a = 1 and t2.b = t.b`).Check(testkit.Rows( "Projection 1.00 root testpartitiontableexplain.t.a, testpartitiontableexplain.t.b, testpartitiontableexplain.t2.a, testpartitiontableexplain.t2.b", - "└─IndexJoin 1.00 root inner join, inner:IndexReader, outer key:testpartitiontableexplain.t2.b, inner key:testpartitiontableexplain.t.b, equal cond:eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)", + "└─HashJoin 1.00 root inner join, equal:[eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)]", " ├─TableReader(Build) 1.00 root data:Selection", " │ └─Selection 1.00 cop[tikv] eq(testpartitiontableexplain.t2.a, 1), not(isnull(testpartitiontableexplain.t2.b))", " │ └─TableFullScan 3.00 cop[tikv] table:t2 keep order:false", - " └─IndexReader(Probe) 1.00 root partition:all index:Selection", - " └─Selection 1.00 cop[tikv] not(isnull(testpartitiontableexplain.t.b))", - " └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range: decided by [eq(testpartitiontableexplain.t.b, testpartitiontableexplain.t2.b)], keep order:false")) + " └─IndexReader(Probe) 3.00 root partition:all index:IndexFullScan", + " └─IndexFullScan 3.00 cop[tikv] table:t, index:b(b) keep order:false")) tk.MustQuery(`explain format = 'brief' select * from t partition (p1),t2 where t2.a = 1 and t2.b = t.b`).Check(testkit.Rows( "Projection 1.00 root testpartitiontableexplain.t.a, testpartitiontableexplain.t.b, testpartitiontableexplain.t2.a, testpartitiontableexplain.t2.b", - "└─IndexJoin 1.00 root inner join, inner:IndexReader, outer key:testpartitiontableexplain.t2.b, inner key:testpartitiontableexplain.t.b, equal cond:eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)", + "└─HashJoin 1.00 root inner join, equal:[eq(testpartitiontableexplain.t2.b, testpartitiontableexplain.t.b)]", " ├─TableReader(Build) 1.00 root data:Selection", " │ └─Selection 1.00 cop[tikv] eq(testpartitiontableexplain.t2.a, 1), not(isnull(testpartitiontableexplain.t2.b))", " │ └─TableFullScan 3.00 cop[tikv] table:t2 keep order:false", - " └─IndexReader(Probe) 1.00 root partition:p1 index:Selection", - " └─Selection 1.00 cop[tikv] not(isnull(testpartitiontableexplain.t.b))", - " └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range: decided by [eq(testpartitiontableexplain.t.b, testpartitiontableexplain.t2.b)], keep order:false")) + " └─IndexReader(Probe) 3.00 root partition:p1 index:IndexFullScan", + " └─IndexFullScan 3.00 cop[tikv] table:t, index:b(b) keep order:false")) tk.MustQuery(`explain format = 'brief' select * from t,t2 where t2.a = 1 and t2.b = t.b and t.a = 1`).Check(testkit.Rows( "HashJoin 1.00 root inner join, equal:[eq(testpartitiontableexplain.t.b, testpartitiontableexplain.t2.b)]", "├─TableReader(Build) 1.00 root data:Selection", @@ -3629,3 +3933,72 @@ func TestIssue21732(t *testing.T) { }) } } + +func TestIssue39999(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + + tk.MustExec(`create schema test39999`) + tk.MustExec(`use test39999`) + tk.MustExec(`drop table if exists c, t`) + tk.MustExec("CREATE TABLE `c` (" + + "`serial_id` varchar(24)," + + "`occur_trade_date` date," + + "`txt_account_id` varchar(24)," + + "`capital_sub_class` varchar(10)," + + "`occur_amount` decimal(16,2)," + + "`broker` varchar(10)," + + "PRIMARY KEY (`txt_account_id`,`occur_trade_date`,`serial_id`) /*T![clustered_index] CLUSTERED */," + + "KEY `idx_serial_id` (`serial_id`)" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci " + + "PARTITION BY RANGE COLUMNS(`serial_id`) (" + + "PARTITION `p202209` VALUES LESS THAN ('20221001')," + + "PARTITION `p202210` VALUES LESS THAN ('20221101')," + + "PARTITION `p202211` VALUES LESS THAN ('20221201')" + + ")") + + tk.MustExec("CREATE TABLE `t` ( " + + "`txn_account_id` varchar(24), " + + "`account_id` varchar(32), " + + "`broker` varchar(10), " + + "PRIMARY KEY (`txn_account_id`) /*T![clustered_index] CLUSTERED */ " + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci") + + tk.MustExec("INSERT INTO `c` (serial_id, txt_account_id, capital_sub_class, occur_trade_date, occur_amount, broker) VALUES ('2022111700196920','04482786','CUST','2022-11-17',-2.01,'0009')") + tk.MustExec("INSERT INTO `t` VALUES ('04482786','1142927','0009')") + + tk.MustExec(`set tidb_partition_prune_mode='dynamic'`) + tk.MustExec(`analyze table c`) + tk.MustExec(`analyze table t`) + query := `select + /*+ inl_join(c) */ + c.occur_amount +from + c + join t on c.txt_account_id = t.txn_account_id + and t.broker = '0009' + and c.occur_trade_date = '2022-11-17'` + tk.MustQuery("explain " + query).Check(testkit.Rows(""+ + "IndexJoin_22 1.00 root inner join, inner:TableReader_21, outer key:test39999.t.txn_account_id, inner key:test39999.c.txt_account_id, equal cond:eq(test39999.t.txn_account_id, test39999.c.txt_account_id)", + "├─TableReader_27(Build) 1.00 root data:Selection_26", + "│ └─Selection_26 1.00 cop[tikv] eq(test39999.t.broker, \"0009\")", + "│ └─TableFullScan_25 1.00 cop[tikv] table:t keep order:false", + "└─TableReader_21(Probe) 1.00 root partition:all data:Selection_20", + " └─Selection_20 1.00 cop[tikv] eq(test39999.c.occur_trade_date, 2022-11-17 00:00:00.000000)", + " └─TableRangeScan_19 1.00 cop[tikv] table:c range: decided by [eq(test39999.c.txt_account_id, test39999.t.txn_account_id) eq(test39999.c.occur_trade_date, 2022-11-17 00:00:00.000000)], keep order:false")) + tk.MustQuery(query).Check(testkit.Rows("-2.01")) + + // Add the missing partition key part. + tk.MustExec(`alter table t add column serial_id varchar(24) default '2022111700196920'`) + query += ` and c.serial_id = t.serial_id` + tk.MustQuery(query).Check(testkit.Rows("-2.01")) + tk.MustQuery("explain " + query).Check(testkit.Rows(""+ + `IndexJoin_20 0.80 root inner join, inner:TableReader_19, outer key:test39999.t.txn_account_id, test39999.t.serial_id, inner key:test39999.c.txt_account_id, test39999.c.serial_id, equal cond:eq(test39999.t.serial_id, test39999.c.serial_id), eq(test39999.t.txn_account_id, test39999.c.txt_account_id)`, + `├─TableReader_25(Build) 0.80 root data:Selection_24`, + `│ └─Selection_24 0.80 cop[tikv] eq(test39999.t.broker, "0009"), not(isnull(test39999.t.serial_id))`, + `│ └─TableFullScan_23 1.00 cop[tikv] table:t keep order:false`, + `└─TableReader_19(Probe) 0.80 root partition:all data:Selection_18`, + ` └─Selection_18 0.80 cop[tikv] eq(test39999.c.occur_trade_date, 2022-11-17 00:00:00.000000)`, + ` └─TableRangeScan_17 0.80 cop[tikv] table:c range: decided by [eq(test39999.c.txt_account_id, test39999.t.txn_account_id) eq(test39999.c.serial_id, test39999.t.serial_id) eq(test39999.c.occur_trade_date, 2022-11-17 00:00:00.000000)], keep order:false`)) +} diff --git a/executor/pipelined_window.go b/executor/pipelined_window.go index 1a72864bcf225..cda1d9c389fd0 100644 --- a/executor/pipelined_window.go +++ b/executor/pipelined_window.go @@ -205,7 +205,7 @@ func (e *PipelinedWindowExec) getRowsInPartition(ctx context.Context) (err error func (e *PipelinedWindowExec) fetchChild(ctx context.Context) (EOF bool, err error) { // TODO: reuse chunks - childResult := newFirstChunk(e.children[0]) + childResult := tryNewCacheChunk(e.children[0]) err = Next(ctx, e.children[0], childResult) if err != nil { return false, errors.Trace(err) @@ -217,7 +217,7 @@ func (e *PipelinedWindowExec) fetchChild(ctx context.Context) (EOF bool, err err } // TODO: reuse chunks - resultChk := chunk.New(e.retFieldTypes, 0, numRows) + resultChk := e.ctx.GetSessionVars().GetNewChunkWithCapacity(e.retFieldTypes, 0, numRows, e.AllocPool) err = e.copyChk(childResult, resultChk) if err != nil { return false, err diff --git a/executor/plan_replayer.go b/executor/plan_replayer.go index 33fdf5da4507c..868b969e78247 100644 --- a/executor/plan_replayer.go +++ b/executor/plan_replayer.go @@ -18,30 +18,24 @@ import ( "archive/zip" "bytes" "context" - "crypto/rand" - "encoding/base64" "encoding/json" "fmt" - "io" "os" - "path/filepath" - "strconv" "strings" - "time" "github.com/BurntSushi/toml" "github.com/pingcap/errors" - "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" - "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/statistics/handle" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/logutil" - "github.com/pingcap/tidb/util/printer" + "github.com/pingcap/tidb/util/replayer" "github.com/pingcap/tidb/util/sqlexec" "go.uber.org/zap" ) @@ -49,20 +43,18 @@ import ( var _ Executor = &PlanReplayerExec{} var _ Executor = &PlanReplayerLoadExec{} -const ( - configFile = "config.toml" - metaFile = "meta.txt" - variablesFile = "variables.toml" - tiFlashReplicasFile = "table_tiflash_replica.txt" - sessionBindingFile = "session_bindings.sql" - globalBindingFile = "global_bindings.sql" -) - // PlanReplayerExec represents a plan replayer executor. type PlanReplayerExec struct { baseExecutor - DumpInfo *PlanReplayerDumpInfo - endFlag bool + CaptureInfo *PlanReplayerCaptureInfo + DumpInfo *PlanReplayerDumpInfo + endFlag bool +} + +// PlanReplayerCaptureInfo indicates capture info +type PlanReplayerCaptureInfo struct { + SQLDigest string + PlanDigest string } // PlanReplayerDumpInfo indicates dump info @@ -75,86 +67,16 @@ type PlanReplayerDumpInfo struct { ctx sessionctx.Context } -type tableNamePair struct { - DBName string - TableName string - IsView bool -} - -type tableNameExtractor struct { - ctx context.Context - executor sqlexec.RestrictedSQLExecutor - is infoschema.InfoSchema - curDB model.CIStr - names map[tableNamePair]struct{} - cteNames map[string]struct{} - err error -} - -func (tne *tableNameExtractor) Enter(in ast.Node) (ast.Node, bool) { - if _, ok := in.(*ast.TableName); ok { - return in, true - } - return in, false -} - -func (tne *tableNameExtractor) Leave(in ast.Node) (ast.Node, bool) { - if tne.err != nil { - return in, true - } - if t, ok := in.(*ast.TableName); ok { - isView, err := tne.handleIsView(t) - if err != nil { - tne.err = err - return in, true - } - tp := tableNamePair{DBName: t.Schema.L, TableName: t.Name.L, IsView: isView} - if tp.DBName == "" { - tp.DBName = tne.curDB.L - } - if _, ok := tne.names[tp]; !ok { - tne.names[tp] = struct{}{} - } - } else if s, ok := in.(*ast.SelectStmt); ok { - if s.With != nil && len(s.With.CTEs) > 0 { - for _, cte := range s.With.CTEs { - tne.cteNames[cte.Name.L] = struct{}{} - } - } - } - return in, true -} - -func (tne *tableNameExtractor) handleIsView(t *ast.TableName) (bool, error) { - schema := t.Schema - if schema.L == "" { - schema = tne.curDB - } - table := t.Name - isView := tne.is.TableIsView(schema, table) - if !isView { - return false, nil - } - viewTbl, err := tne.is.TableByName(schema, table) - if err != nil { - return false, err - } - sql := viewTbl.Meta().View.SelectStmt - node, err := tne.executor.ParseWithParams(tne.ctx, sql) - if err != nil { - return false, err - } - node.Accept(tne) - return true, nil -} - // Next implements the Executor Next interface. func (e *PlanReplayerExec) Next(ctx context.Context, req *chunk.Chunk) error { req.GrowAndReset(e.maxChunkSize) if e.endFlag { return nil } - err := e.createFile(domain.GetPlanReplayerDirName()) + if e.CaptureInfo != nil { + return e.registerCaptureTask(ctx) + } + err := e.createFile() if err != nil { return err } @@ -180,384 +102,65 @@ func (e *PlanReplayerExec) Next(ctx context.Context, req *chunk.Chunk) error { return nil } -func (e *PlanReplayerExec) createFile(path string) error { - // Create path - err := os.MkdirAll(path, os.ModePerm) - if err != nil { - return errors.AddStack(err) - } - - // Generate key and create zip file - time := time.Now().UnixNano() - b := make([]byte, 16) - //nolint: gosec - _, err = rand.Read(b) +func (e *PlanReplayerExec) registerCaptureTask(ctx context.Context) error { + ctx1 := kv.WithInternalSourceType(ctx, kv.InternalTxnStats) + exists, err := domain.CheckPlanReplayerTaskExists(ctx1, e.ctx, e.CaptureInfo.SQLDigest, e.CaptureInfo.PlanDigest) if err != nil { return err } - key := base64.URLEncoding.EncodeToString(b) - fileName := fmt.Sprintf("replayer_%v_%v.zip", key, time) - zf, err := os.Create(filepath.Join(path, fileName)) - if err != nil { - return errors.AddStack(err) + if exists { + return errors.New("plan replayer capture task already exists") } - e.DumpInfo.File = zf - e.DumpInfo.FileName = fileName - return nil -} - -// dumpSingle will dump the information about sqls. -// The files will be organized into the following format: -/* - |-meta.txt - |-schema - | |-db1.table1.schema.txt - | |-db2.table2.schema.txt - | |-.... - |-view - | |-db1.view1.view.txt - | |-db2.view2.view.txt - | |-.... - |-stats - | |-stats1.json - | |-stats2.json - | |-.... - |-config.toml - |-table_tiflash_replica.txt - |-variables.toml - |-bindings.sql - |-sql - | |-sql1.sql - | |-sql2.sql - | |-.... - |_explain - |-explain1.txt - |-explain2.txt - |-.... -*/ -func (e *PlanReplayerDumpInfo) dump(ctx context.Context) (err error) { - fileName := e.FileName - zf := e.File - // Create zip writer - zw := zip.NewWriter(zf) - defer func() { - err = zw.Close() - if err != nil { - logutil.BgLogger().Error("Closing zip writer failed", zap.Error(err), zap.String("filename", fileName)) - } - err = zf.Close() - if err != nil { - logutil.BgLogger().Error("Closing zip file failed", zap.Error(err), zap.String("filename", fileName)) - } - }() - - // Dump config - if err = dumpConfig(zw); err != nil { - return err - } - - // Dump meta - if err = dumpMeta(zw); err != nil { - return err - } - - // Retrieve current DB - sessionVars := e.ctx.GetSessionVars() - dbName := model.NewCIStr(sessionVars.CurrentDB) - do := domain.GetDomain(e.ctx) - - // Retrieve all tables - pairs, err := e.extractTableNames(ctx, e.ExecStmts, dbName) + exec := e.ctx.(sqlexec.SQLExecutor) + _, err = exec.ExecuteInternal(ctx1, fmt.Sprintf("insert into mysql.plan_replayer_task (sql_digest, plan_digest) values ('%s','%s')", + e.CaptureInfo.SQLDigest, e.CaptureInfo.PlanDigest)) if err != nil { - return errors.AddStack(fmt.Errorf("plan replayer: invalid SQL text, err: %v", err)) - } - - // Dump Schema and View - if err = dumpSchemas(e.ctx, zw, pairs); err != nil { + logutil.BgLogger().Warn("insert mysql.plan_replayer_status record failed", + zap.Error(err)) return err } - - // Dump tables tiflash replicas - if err = dumpTiFlashReplica(e.ctx, zw, pairs); err != nil { - return err - } - - // Dump stats - if err = dumpStats(zw, pairs, do); err != nil { - return err - } - - // Dump variables - if err = dumpVariables(e.ctx, zw); err != nil { - return err - } - - // Dump sql - if err = dumpSQLs(e.ExecStmts, zw); err != nil { - return err - } - - // Dump session bindings - if err = dumpSessionBindings(e.ctx, zw); err != nil { - return err - } - - // Dump global bindings - if err = dumpGlobalBindings(e.ctx, zw); err != nil { - return err - } - - // Dump explain - if err = dumpExplain(e.ctx, zw, e.ExecStmts, e.Analyze); err != nil { - return err - } - - e.ctx.GetSessionVars().LastPlanReplayerToken = e.FileName - return nil -} - -func dumpConfig(zw *zip.Writer) error { - cf, err := zw.Create(configFile) - if err != nil { - return errors.AddStack(err) - } - if err := toml.NewEncoder(cf).Encode(config.GetGlobalConfig()); err != nil { - return errors.AddStack(err) - } - return nil -} - -func dumpMeta(zw *zip.Writer) error { - mt, err := zw.Create(metaFile) - if err != nil { - return errors.AddStack(err) - } - _, err = mt.Write([]byte(printer.GetTiDBInfo())) - if err != nil { - return errors.AddStack(err) - } - return nil -} - -func dumpTiFlashReplica(ctx sessionctx.Context, zw *zip.Writer, pairs map[tableNamePair]struct{}) error { - bf, err := zw.Create(tiFlashReplicasFile) + err = domain.GetDomain(e.ctx).GetPlanReplayerHandle().CollectPlanReplayerTask() if err != nil { - return errors.AddStack(err) - } - is := domain.GetDomain(ctx).InfoSchema() - for pair := range pairs { - dbName := model.NewCIStr(pair.DBName) - tableName := model.NewCIStr(pair.TableName) - t, err := is.TableByName(dbName, tableName) - if err != nil { - logutil.BgLogger().Warn("failed to find table info", zap.Error(err), - zap.String("dbName", dbName.L), zap.String("tableName", tableName.L)) - continue - } - if t.Meta().TiFlashReplica != nil && t.Meta().TiFlashReplica.Count > 0 { - row := []string{ - pair.DBName, pair.TableName, strconv.FormatUint(t.Meta().TiFlashReplica.Count, 10), - } - fmt.Fprintf(bf, "%s\n", strings.Join(row, "\t")) - } - } - return nil -} - -func dumpSchemas(ctx sessionctx.Context, zw *zip.Writer, pairs map[tableNamePair]struct{}) error { - for pair := range pairs { - err := getShowCreateTable(pair, zw, ctx) - if err != nil { - return err - } - } - return nil -} - -func dumpStats(zw *zip.Writer, pairs map[tableNamePair]struct{}, do *domain.Domain) error { - for pair := range pairs { - if pair.IsView { - continue - } - jsonTbl, err := getStatsForTable(do, pair) - if err != nil { - return err - } - statsFw, err := zw.Create(fmt.Sprintf("stats/%v.%v.json", pair.DBName, pair.TableName)) - if err != nil { - return errors.AddStack(err) - } - data, err := json.Marshal(jsonTbl) - if err != nil { - return errors.AddStack(err) - } - _, err = statsFw.Write(data) - if err != nil { - return errors.AddStack(err) - } - } - return nil -} - -func dumpSQLs(execStmts []ast.StmtNode, zw *zip.Writer) error { - for i, stmtExec := range execStmts { - zf, err := zw.Create(fmt.Sprintf("sql/sql%v.sql", i)) - if err != nil { - return err - } - _, err = zf.Write([]byte(stmtExec.Text())) - if err != nil { - return err - } + logutil.BgLogger().Warn("collect task failed", zap.Error(err)) } + logutil.BgLogger().Info("collect plan replayer task success") + e.endFlag = true return nil } -func dumpVariables(ctx sessionctx.Context, zw *zip.Writer) error { - varMap := make(map[string]string) - recordSets, err := ctx.(sqlexec.SQLExecutor).Execute(context.Background(), "show variables") - if err != nil { - return err - } - sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) +func (e *PlanReplayerExec) createFile() error { + var err error + e.DumpInfo.File, e.DumpInfo.FileName, err = replayer.GeneratePlanReplayerFile(false, false, false) if err != nil { return err } - vf, err := zw.Create(variablesFile) - if err != nil { - return errors.AddStack(err) - } - for _, row := range sRows { - varMap[row[0]] = row[1] - } - if err := toml.NewEncoder(vf).Encode(varMap); err != nil { - return errors.AddStack(err) - } - if len(recordSets) > 0 { - if err := recordSets[0].Close(); err != nil { - return err - } - } return nil } -func dumpSessionBindings(ctx sessionctx.Context, zw *zip.Writer) error { - recordSets, err := ctx.(sqlexec.SQLExecutor).Execute(context.Background(), "show bindings") +func (e *PlanReplayerDumpInfo) dump(ctx context.Context) (err error) { + fileName := e.FileName + zf := e.File + startTS, err := sessiontxn.GetTxnManager(e.ctx).GetStmtReadTS() if err != nil { return err } - sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], true) - if err != nil { - return err + task := &domain.PlanReplayerDumpTask{ + StartTS: startTS, + FileName: fileName, + Zf: zf, + SessionVars: e.ctx.GetSessionVars(), + TblStats: nil, + ExecStmts: e.ExecStmts, + Analyze: e.Analyze, } - bf, err := zw.Create(sessionBindingFile) - if err != nil { - return errors.AddStack(err) - } - for _, row := range sRows { - fmt.Fprintf(bf, "%s\n", strings.Join(row, "\t")) - } - if len(recordSets) > 0 { - if err := recordSets[0].Close(); err != nil { - return err - } - } - return nil -} - -func dumpGlobalBindings(ctx sessionctx.Context, zw *zip.Writer) error { - recordSets, err := ctx.(sqlexec.SQLExecutor).Execute(context.Background(), "show global bindings") - if err != nil { - return err - } - sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) + err = domain.DumpPlanReplayerInfo(ctx, e.ctx, task) if err != nil { return err } - bf, err := zw.Create(globalBindingFile) - if err != nil { - return errors.AddStack(err) - } - for _, row := range sRows { - fmt.Fprintf(bf, "%s\n", strings.Join(row, "\t")) - } - if len(recordSets) > 0 { - if err := recordSets[0].Close(); err != nil { - return err - } - } - return nil -} - -func dumpExplain(ctx sessionctx.Context, zw *zip.Writer, execStmts []ast.StmtNode, isAnalyze bool) error { - for i, stmtExec := range execStmts { - sql := stmtExec.Text() - var recordSets []sqlexec.RecordSet - var err error - if isAnalyze { - // Explain analyze - recordSets, err = ctx.(sqlexec.SQLExecutor).Execute(context.Background(), fmt.Sprintf("explain analyze %s", sql)) - if err != nil { - return err - } - } else { - // Explain - recordSets, err = ctx.(sqlexec.SQLExecutor).Execute(context.Background(), fmt.Sprintf("explain %s", sql)) - if err != nil { - return err - } - } - sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) - if err != nil { - return err - } - fw, err := zw.Create(fmt.Sprintf("explain/sql%v.txt", i)) - if err != nil { - return errors.AddStack(err) - } - for _, row := range sRows { - fmt.Fprintf(fw, "%s\n", strings.Join(row, "\t")) - } - if len(recordSets) > 0 { - if err := recordSets[0].Close(); err != nil { - return err - } - } - } + e.ctx.GetSessionVars().LastPlanReplayerToken = e.FileName return nil } -func (e *PlanReplayerDumpInfo) extractTableNames(ctx context.Context, - ExecStmts []ast.StmtNode, curDB model.CIStr) (map[tableNamePair]struct{}, error) { - tableExtractor := &tableNameExtractor{ - ctx: ctx, - executor: e.ctx.(sqlexec.RestrictedSQLExecutor), - is: domain.GetDomain(e.ctx).InfoSchema(), - curDB: curDB, - names: make(map[tableNamePair]struct{}), - cteNames: make(map[string]struct{}), - } - for _, execStmt := range ExecStmts { - execStmt.Accept(tableExtractor) - } - if tableExtractor.err != nil { - return nil, tableExtractor.err - } - r := make(map[tableNamePair]struct{}) - for tablePair := range tableExtractor.names { - if tablePair.IsView { - r[tablePair] = struct{}{} - continue - } - // remove cte in table names - _, ok := tableExtractor.cteNames[tablePair.TableName] - if !ok { - r[tablePair] = struct{}{} - } - } - return r, nil -} - func (e *PlanReplayerExec) prepare() error { val := e.ctx.Value(PlanReplayerDumpVarKey) if val != nil { @@ -586,109 +189,6 @@ func (e *PlanReplayerDumpInfo) DumpSQLsFromFile(ctx context.Context, b []byte) e return e.dump(ctx) } -func getStatsForTable(do *domain.Domain, pair tableNamePair) (*handle.JSONTable, error) { - is := do.InfoSchema() - h := do.StatsHandle() - tbl, err := is.TableByName(model.NewCIStr(pair.DBName), model.NewCIStr(pair.TableName)) - if err != nil { - return nil, err - } - js, err := h.DumpStatsToJSON(pair.DBName, tbl.Meta(), nil) - return js, err -} - -func getShowCreateTable(pair tableNamePair, zw *zip.Writer, ctx sessionctx.Context) error { - recordSets, err := ctx.(sqlexec.SQLExecutor).Execute(context.Background(), fmt.Sprintf("show create table `%v`.`%v`", pair.DBName, pair.TableName)) - if err != nil { - return err - } - sRows, err := resultSetToStringSlice(context.Background(), recordSets[0], false) - if err != nil { - return err - } - var fw io.Writer - if pair.IsView { - fw, err = zw.Create(fmt.Sprintf("view/%v.%v.view.txt", pair.DBName, pair.TableName)) - if err != nil { - return errors.AddStack(err) - } - if len(sRows) == 0 || len(sRows[0]) != 4 { - return fmt.Errorf("plan replayer: get create view %v.%v failed", pair.DBName, pair.TableName) - } - } else { - fw, err = zw.Create(fmt.Sprintf("schema/%v.%v.schema.txt", pair.DBName, pair.TableName)) - if err != nil { - return errors.AddStack(err) - } - if len(sRows) == 0 || len(sRows[0]) != 2 { - return fmt.Errorf("plan replayer: get create table %v.%v failed", pair.DBName, pair.TableName) - } - } - fmt.Fprintf(fw, "create database if not exists `%v`; use `%v`;", pair.DBName, pair.DBName) - fmt.Fprintf(fw, "%s", sRows[0][1]) - if len(recordSets) > 0 { - if err := recordSets[0].Close(); err != nil { - return err - } - } - return nil -} - -func resultSetToStringSlice(ctx context.Context, rs sqlexec.RecordSet, emptyAsNil bool) ([][]string, error) { - rows, err := getRows(ctx, rs) - if err != nil { - return nil, err - } - err = rs.Close() - if err != nil { - return nil, err - } - sRows := make([][]string, len(rows)) - for i, row := range rows { - iRow := make([]string, row.Len()) - for j := 0; j < row.Len(); j++ { - if row.IsNull(j) { - iRow[j] = "" - } else { - d := row.GetDatum(j, &rs.Fields()[j].Column.FieldType) - iRow[j], err = d.ToString() - if err != nil { - return nil, err - } - if len(iRow[j]) < 1 && emptyAsNil { - iRow[j] = "" - } - } - } - sRows[i] = iRow - } - return sRows, nil -} - -func getRows(ctx context.Context, rs sqlexec.RecordSet) ([]chunk.Row, error) { - if rs == nil { - return nil, nil - } - var rows []chunk.Row - req := rs.NewChunk(nil) - // Must reuse `req` for imitating server.(*clientConn).writeChunks - for { - err := rs.Next(ctx, req) - if err != nil { - return nil, err - } - if req.NumRows() == 0 { - break - } - - iter := chunk.NewIterator4Chunk(req.CopyConstruct()) - for row := iter.Begin(); row != iter.End(); row = iter.Next() { - rows = append(rows, row) - } - } - return rows, nil -} - // PlanReplayerLoadExec represents a plan replayer load executor. type PlanReplayerLoadExec struct { baseExecutor @@ -736,7 +236,7 @@ func (e *PlanReplayerLoadExec) Next(ctx context.Context, req *chunk.Chunk) error func loadSetTiFlashReplica(ctx sessionctx.Context, z *zip.Reader) error { for _, zipFile := range z.File { - if strings.Compare(zipFile.Name, tiFlashReplicasFile) == 0 { + if strings.Compare(zipFile.Name, domain.PlanReplayerTiFlashReplicasFile) == 0 { v, err := zipFile.Open() if err != nil { return errors.AddStack(err) @@ -774,12 +274,12 @@ func loadSetTiFlashReplica(ctx sessionctx.Context, z *zip.Reader) error { func loadAllBindings(ctx sessionctx.Context, z *zip.Reader) error { for _, f := range z.File { - if strings.Compare(f.Name, sessionBindingFile) == 0 { + if strings.Compare(f.Name, domain.PlanReplayerSessionBindingFile) == 0 { err := loadBindings(ctx, f, true) if err != nil { return err } - } else if strings.Compare(f.Name, globalBindingFile) == 0 { + } else if strings.Compare(f.Name, domain.PlanReplayerGlobalBindingFile) == 0 { err := loadBindings(ctx, f, false) if err != nil { return err @@ -833,7 +333,7 @@ func loadBindings(ctx sessionctx.Context, f *zip.File, isSession bool) error { func loadVariables(ctx sessionctx.Context, z *zip.Reader) error { unLoadVars := make([]string, 0) for _, zipFile := range z.File { - if strings.Compare(zipFile.Name, variablesFile) == 0 { + if strings.Compare(zipFile.Name, domain.PlanReplayerVariablesFile) == 0 { varMap := make(map[string]string) v, err := zipFile.Open() if err != nil { @@ -887,21 +387,23 @@ func createSchemaAndItems(ctx sessionctx.Context, f *zip.File) error { if err != nil { return errors.AddStack(err) } - sqls := strings.Split(buf.String(), ";") - if len(sqls) != 3 { - return errors.New("plan replayer: create schema and tables failed") - } + originText := buf.String() + index1 := strings.Index(originText, ";") + createDatabaseSQL := originText[:index1+1] + index2 := strings.Index(originText[index1+1:], ";") + useDatabaseSQL := originText[index1+1:][:index2+1] + createTableSQL := originText[index1+1:][index2+1:] c := context.Background() // create database if not exists - _, err = ctx.(sqlexec.SQLExecutor).Execute(c, sqls[0]) + _, err = ctx.(sqlexec.SQLExecutor).Execute(c, createDatabaseSQL) logutil.BgLogger().Debug("plan replayer: skip error", zap.Error(err)) // use database - _, err = ctx.(sqlexec.SQLExecutor).Execute(c, sqls[1]) + _, err = ctx.(sqlexec.SQLExecutor).Execute(c, useDatabaseSQL) if err != nil { return err } // create table or view - _, err = ctx.(sqlexec.SQLExecutor).Execute(c, sqls[2]) + _, err = ctx.(sqlexec.SQLExecutor).Execute(c, createTableSQL) if err != nil { return err } @@ -948,6 +450,9 @@ func (e *PlanReplayerLoadInfo) Update(data []byte) error { // build schema and table first for _, zipFile := range z.File { + if zipFile.Name == fmt.Sprintf("schema/%v", domain.PlanReplayerSchemaMetaFile) { + continue + } path := strings.Split(zipFile.Name, "/") if len(path) == 2 && strings.Compare(path[0], "schema") == 0 { err = createSchemaAndItems(e.Ctx, zipFile) diff --git a/executor/point_get.go b/executor/point_get.go index f65c52c06cb1b..8efda04a970e5 100644 --- a/executor/point_get.go +++ b/executor/point_get.go @@ -74,13 +74,13 @@ func (b *executorBuilder) buildPointGet(p *plannercore.PointGetPlan) Executor { if b.ctx.GetSessionVars().IsReplicaReadClosestAdaptive() { e.snapshot.SetOption(kv.ReplicaReadAdjuster, newReplicaReadAdjuster(e.ctx, p.GetAvgRowSize())) } + e.snapshot.SetOption(kv.ResourceGroupName, b.ctx.GetSessionVars().ResourceGroupName) if e.runtimeStats != nil { snapshotStats := &txnsnapshot.SnapshotRuntimeStats{} e.stats = &runtimeStatsWithSnapshot{ SnapshotRuntimeStats: snapshotStats, } e.snapshot.SetOption(kv.CollectRuntimeStats, snapshotStats) - b.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } if p.IndexInfo != nil { @@ -194,6 +194,9 @@ func (e *PointGetExecutor) Open(context.Context) error { // Close implements the Executor interface. func (e *PointGetExecutor) Close() error { + if e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } if e.runtimeStats != nil && e.snapshot != nil { e.snapshot.SetOption(kv.CollectRuntimeStats, nil) } @@ -347,8 +350,8 @@ func (e *PointGetExecutor) Next(ctx context.Context, req *chunk.Chunk) error { return err } - err = FillVirtualColumnValue(e.virtualColumnRetFieldTypes, e.virtualColumnIndex, - e.schema, e.columns, e.ctx, req) + err = table.FillVirtualColumnValue(e.virtualColumnRetFieldTypes, e.virtualColumnIndex, + e.schema.Columns, e.columns, e.ctx, req) if err != nil { return err } diff --git a/executor/point_get_test.go b/executor/point_get_test.go index c615c3a75cb1a..8f13675457481 100644 --- a/executor/point_get_test.go +++ b/executor/point_get_test.go @@ -825,3 +825,20 @@ func TestPointGetIssue25167(t *testing.T) { tk.MustExec("insert into t values (1)") tk.MustQuery("select * from t as of timestamp @a where a = 1").Check(testkit.Rows()) } + +func TestPointGetIssue40194(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t1(id int primary key, v int)") + tk.MustExec("insert into t1 values(1, 10)") + tk.MustExec("prepare s from 'select * from t1 where id=1'") + tk.MustExec("set @@tidb_enable_plan_replayer_capture=1") + tk.MustQuery("execute s").Check(testkit.Rows("1 10")) + tk.MustQuery("execute s").Check(testkit.Rows("1 10")) + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec("update t1 set v=v+1") + tk.MustQuery("execute s").Check(testkit.Rows("1 11")) +} diff --git a/executor/prepared.go b/executor/prepared.go index ae742a30d8bb5..6a5025e0d539b 100644 --- a/executor/prepared.go +++ b/executor/prepared.go @@ -53,8 +53,6 @@ type PrepareExec struct { Fields []*ast.ResultField Stmt interface{} - IsGeneralStmt bool - // If it's generated from executing "prepare stmt from '...'", the process is parse -> plan -> executor // If it's generated from the prepare protocol, the process is session.PrepareStmt -> NewPrepareExec // They both generate a PrepareExec struct, but the second case needs to reset the statement context while the first already do that. @@ -117,7 +115,7 @@ func (e *PrepareExec) Next(ctx context.Context, req *chunk.Chunk) error { return err } } - stmt, p, paramCnt, err := plannercore.GeneratePlanCacheStmtWithAST(ctx, e.ctx, stmt0) + stmt, p, paramCnt, err := plannercore.GeneratePlanCacheStmtWithAST(ctx, e.ctx, stmt0.Text(), stmt0) if err != nil { return err } @@ -135,19 +133,15 @@ func (e *PrepareExec) Next(ctx context.Context, req *chunk.Chunk) error { if !isNoResultPlan(p) { e.Fields = colNames2ResultFields(p.Schema(), p.OutputNames(), vars.CurrentDB) } - if e.ID == 0 && !e.IsGeneralStmt { + if e.ID == 0 { e.ID = vars.GetNextPreparedStmtID() } - if e.name != "" && !e.IsGeneralStmt { + if e.name != "" { vars.PreparedStmtNameToID[e.name] = e.ID } e.ParamCount = paramCnt e.Stmt = stmt - if e.IsGeneralStmt { - vars.AddGeneralPlanCacheStmt(e.sqlText, stmt) - return nil - } return vars.AddPreparedStmt(e.ID, stmt) } diff --git a/executor/prepared_test.go b/executor/prepared_test.go index f5629a41e9297..739ba1c0cd659 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -18,11 +18,13 @@ import ( "fmt" "strconv" "strings" + "sync/atomic" "testing" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/parser/terror" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/server" "github.com/pingcap/tidb/sessionctx/variable" @@ -228,6 +230,7 @@ func TestIssue28064(t *testing.T) { func TestPreparePlanCache4Blacklist(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`set tidb_enable_prepared_plan_cache=1`) tk.MustExec("use test") tk.MustExec("set @@tidb_enable_collect_execution_info=0;") @@ -260,7 +263,7 @@ func TestPreparePlanCache4Blacklist(t *testing.T) { require.Contains(t, res.Rows()[1][0], "TopN") res = tk.MustQuery("explain format = 'brief' select min(a) from t") - require.Contains(t, res.Rows()[0][0], "StreamAgg") + require.Contains(t, res.Rows()[0][0], "HashAgg") // test the blacklist of Expression Pushdown tk.MustExec("drop table if exists t;") @@ -420,6 +423,7 @@ func TestPlanCacheWithDifferentVariableTypes(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec(`set tidb_enable_prepared_plan_cache=1`) + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") tk.MustExec("set @@tidb_enable_collect_execution_info=0;") @@ -849,6 +853,7 @@ func TestIssue28782(t *testing.T) { func TestIssue29101(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec(`set tidb_enable_prepared_plan_cache=1`) tk.MustExec(`use test`) tk.MustExec("set @@tidb_enable_collect_execution_info=0;") @@ -860,7 +865,7 @@ func TestIssue29101(t *testing.T) { c_last varchar(16) DEFAULT NULL, c_credit char(2) DEFAULT NULL, c_discount decimal(4,4) DEFAULT NULL, - PRIMARY KEY (c_w_id,c_d_id,c_id), + PRIMARY KEY (c_w_id,c_d_id,c_id) NONCLUSTERED, KEY idx_customer (c_w_id,c_d_id,c_last,c_first) )`) tk.MustExec(`CREATE TABLE warehouse ( @@ -890,12 +895,12 @@ func TestIssue29101(t *testing.T) { ol_w_id int(11) NOT NULL, ol_number int(11) NOT NULL, ol_i_id int(11) NOT NULL, - PRIMARY KEY (ol_w_id,ol_d_id,ol_o_id,ol_number))`) + PRIMARY KEY (ol_w_id,ol_d_id,ol_o_id,ol_number) NONCLUSTERED)`) tk.MustExec(`CREATE TABLE stock ( s_i_id int(11) NOT NULL, s_w_id int(11) NOT NULL, s_quantity int(11) DEFAULT NULL, - PRIMARY KEY (s_w_id,s_i_id))`) + PRIMARY KEY (s_w_id,s_i_id) NONCLUSTERED)`) tk.MustExec(`prepare s1 from 'SELECT /*+ TIDB_INLJ(order_line,stock) */ COUNT(DISTINCT (s_i_id)) stock_count FROM order_line, stock WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id < ? AND ol_o_id >= ? - 20 AND s_w_id = ? AND s_i_id = ol_i_id AND s_quantity < ?'`) tk.MustExec(`set @a=391,@b=1,@c=3058,@d=18`) tk.MustExec(`execute s1 using @a,@b,@c,@c,@a,@d`) @@ -909,10 +914,10 @@ func TestIssue29101(t *testing.T) { ` │ └─IndexLookUp_29 0.03 root `, ` │ ├─IndexRangeScan_27(Build) 0.03 cop[tikv] table:order_line, index:PRIMARY(ol_w_id, ol_d_id, ol_o_id, ol_number) range:[391 1 3038,391 1 3058), keep order:false, stats:pseudo`, ` │ └─TableRowIDScan_28(Probe) 0.03 cop[tikv] table:order_line keep order:false, stats:pseudo`, - ` └─IndexLookUp_13(Probe) 1.00 root `, - ` ├─IndexRangeScan_10(Build) 1.00 cop[tikv] table:stock, index:PRIMARY(s_w_id, s_i_id) range: decided by [eq(test.stock.s_i_id, test.order_line.ol_i_id) eq(test.stock.s_w_id, 391)], keep order:false, stats:pseudo`, - ` └─Selection_12(Probe) 1.00 cop[tikv] lt(test.stock.s_quantity, 18)`, - ` └─TableRowIDScan_11 1.00 cop[tikv] table:stock keep order:false, stats:pseudo`)) + ` └─IndexLookUp_13(Probe) 0.03 root `, + ` ├─IndexRangeScan_10(Build) 0.03 cop[tikv] table:stock, index:PRIMARY(s_w_id, s_i_id) range: decided by [eq(test.stock.s_i_id, test.order_line.ol_i_id) eq(test.stock.s_w_id, 391)], keep order:false, stats:pseudo`, + ` └─Selection_12(Probe) 0.03 cop[tikv] lt(test.stock.s_quantity, 18)`, + ` └─TableRowIDScan_11 0.03 cop[tikv] table:stock keep order:false, stats:pseudo`)) tk.MustExec(`execute s1 using @a,@b,@c,@c,@a,@d`) tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1")) // can use the plan-cache } @@ -1030,7 +1035,7 @@ func TestPreparePlanCache4Function(t *testing.T) { tk.MustExec("set @a = 0, @b = 1, @c = 2, @d = null;") tk.MustQuery("execute stmt using @a, @b;").Check(testkit.Rows(" 2", "0 0", "1 1", "2 2")) tk.MustQuery("execute stmt using @c, @d;").Check(testkit.Rows(" 1", "0 2", "1 2", "2 0")) - tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0")) } func TestPreparePlanCache4DifferentSystemVars(t *testing.T) { @@ -1252,3 +1257,18 @@ func TestIssue31141(t *testing.T) { tk.MustExec("set @@tidb_txn_mode = 'optimistic'") tk.MustExec("prepare stmt1 from 'do 1'") } + +func TestMaxPreparedStmtCount(t *testing.T) { + oldVal := atomic.LoadInt64(&variable.PreparedStmtCount) + atomic.StoreInt64(&variable.PreparedStmtCount, 0) + defer func() { + atomic.StoreInt64(&variable.PreparedStmtCount, oldVal) + }() + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.max_prepared_stmt_count = 2") + tk.MustExec("prepare stmt1 from 'select ? as num from dual'") + tk.MustExec("prepare stmt2 from 'select ? as num from dual'") + err := tk.ExecToErr("prepare stmt3 from 'select ? as num from dual'") + require.True(t, terror.ErrorEqual(err, variable.ErrMaxPreparedStmtCountReached)) +} diff --git a/executor/projection.go b/executor/projection.go index ac060e7e4a391..c6c33d02651ff 100644 --- a/executor/projection.go +++ b/executor/projection.go @@ -94,7 +94,7 @@ func (e *ProjectionExec) Open(ctx context.Context) error { return e.open(ctx) } -func (e *ProjectionExec) open(ctx context.Context) error { +func (e *ProjectionExec) open(_ context.Context) error { e.prepared = false e.parentReqRows = int64(e.maxChunkSize) @@ -109,7 +109,7 @@ func (e *ProjectionExec) open(ctx context.Context) error { } if e.isUnparallelExec() { - e.childResult = newFirstChunk(e.children[0]) + e.childResult = tryNewCacheChunk(e.children[0]) e.memTracker.Consume(e.childResult.MemoryUsage()) } @@ -364,14 +364,14 @@ func (f *projectionInputFetcher) run(ctx context.Context) { }() for { - input := readProjectionInput(f.inputCh, f.globalFinishCh) - if input == nil { + input, isNil := readProjection[*projectionInput](f.inputCh, f.globalFinishCh) + if isNil { return } targetWorker := input.targetWorker - output = readProjectionOutput(f.outputCh, f.globalFinishCh) - if output == nil { + output, isNil = readProjection[*projectionOutput](f.outputCh, f.globalFinishCh) + if isNil { f.proj.memTracker.Consume(-input.chk.MemoryUsage()) return } @@ -431,13 +431,13 @@ func (w *projectionWorker) run(ctx context.Context) { w.proj.wg.Done() }() for { - input := readProjectionInput(w.inputCh, w.globalFinishCh) - if input == nil { + input, isNil := readProjection[*projectionInput](w.inputCh, w.globalFinishCh) + if isNil { return } - output = readProjectionOutput(w.outputCh, w.globalFinishCh) - if output == nil { + output, isNil = readProjection[*projectionOutput](w.outputCh, w.globalFinishCh) + if isNil { return } @@ -462,26 +462,14 @@ func recoveryProjection(output *projectionOutput, r interface{}) { logutil.BgLogger().Error("projection executor panicked", zap.String("error", fmt.Sprintf("%v", r)), zap.Stack("stack")) } -func readProjectionInput(inputCh <-chan *projectionInput, finishCh <-chan struct{}) *projectionInput { +func readProjection[T any](ch <-chan T, finishCh <-chan struct{}) (t T, isNil bool) { select { case <-finishCh: - return nil - case input, ok := <-inputCh: - if !ok { - return nil - } - return input - } -} - -func readProjectionOutput(outputCh <-chan *projectionOutput, finishCh <-chan struct{}) *projectionOutput { - select { - case <-finishCh: - return nil - case output, ok := <-outputCh: + return t, true + case t, ok := <-ch: if !ok { - return nil + return t, true } - return output + return t, false } } diff --git a/executor/recover_test.go b/executor/recover_test.go index f5328eb6b1527..cbe3ec2c6799b 100644 --- a/executor/recover_test.go +++ b/executor/recover_test.go @@ -25,12 +25,13 @@ import ( "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/parser/auth" - "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/gcutil" "github.com/stretchr/testify/require" "github.com/tikv/client-go/v2/oracle" + tikvutil "github.com/tikv/client-go/v2/util" ) func TestRecoverTable(t *testing.T) { @@ -172,6 +173,7 @@ func TestFlashbackTable(t *testing.T) { // Test for flashback to new table. tk.MustExec("drop table t_flashback") tk.MustExec("create table t_flashback (a int);") + tk.MustGetErrMsg("flashback table t_flashback to ` `", dbterror.ErrWrongTableName.GenWithStack("Incorrect table name ' '").Error()) tk.MustExec("flashback table t_flashback to t_flashback2") // Check flashback table meta and data record. tk.MustQuery("select * from t_flashback2;").Check(testkit.Rows("1", "2", "3", "4", "5", "6")) @@ -327,40 +329,26 @@ func TestRecoverClusterMeetError(t *testing.T) { tk.MustExec("CREATE USER 'testflashback'@'localhost';") newTk := testkit.NewTestKit(t, store) require.NoError(t, newTk.Session().Auth(&auth.UserIdentity{Username: "testflashback", Hostname: "localhost"}, nil, nil)) - newTk.MustGetErrCode(fmt.Sprintf("flashback cluster to timestamp '%s'", time.Now().Add(0-30*time.Second)), int(core.ErrSpecificAccessDenied.Code())) + newTk.MustGetErrCode(fmt.Sprintf("flashback cluster to timestamp '%s'", time.Now().Add(0-30*time.Second)), errno.ErrPrivilegeCheckFail) tk.MustExec("drop user 'testflashback'@'localhost';") - // Flashback failed because of ddl history. - tk.MustExec("use test;") - tk.MustExec("create table t(a int);") - tk.MustContainErrMsg(fmt.Sprintf("flashback cluster to timestamp '%s'", flashbackTs), "schema version not same, have done ddl during [flashbackTS, now)") - - require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) - require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) - require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockFlashbackTest")) -} - -func TestRecoverClusterWithTiFlash(t *testing.T) { - store := testkit.CreateMockStore(t, withMockTiFlash(1)) - tk := testkit.NewTestKit(t, store) - - injectSafeTS := oracle.GoTimeToTS(time.Now().Add(-10 * time.Second)) - require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", - fmt.Sprintf("return(%v)", injectSafeTS))) - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", - fmt.Sprintf("return(%v)", injectSafeTS))) - - timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) - defer resetGC() - - // Set GC safe point - tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + // detect modify system table + nowTS, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + tk.MustExec("truncate table mysql.stats_meta") + errorMsg := fmt.Sprintf("[ddl:-1]Detected modified system table during [%s, now), can't do flashback", oracle.GetTimeFromTS(nowTS).String()) + tk.MustGetErrMsg(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(nowTS)), errorMsg) - tk.MustContainErrMsg(fmt.Sprintf("flashback cluster to timestamp '%s'", time.Now().Add(0-30*time.Second)), - "not support flash back cluster with TiFlash stores") + // update tidb_server_version + nowTS, err = tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + tk.MustExec("update mysql.tidb set VARIABLE_VALUE=VARIABLE_VALUE+1 where VARIABLE_NAME='tidb_server_version'") + errorMsg = fmt.Sprintf("[ddl:-1]Detected TiDB upgrade during [%s, now), can't do flashback", oracle.GetTimeFromTS(nowTS).String()) + tk.MustGetErrMsg(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(nowTS)), errorMsg) require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockFlashbackTest")) } func TestFlashbackWithSafeTs(t *testing.T) { @@ -423,6 +411,63 @@ func TestFlashbackWithSafeTs(t *testing.T) { require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockFlashbackTest")) } +func TestFlashbackSchema(t *testing.T) { + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/meta/autoid/mockAutoIDChange", `return(true)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/meta/autoid/mockAutoIDChange")) + }() + + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("create database if not exists test_flashback") + tk.MustExec("use test_flashback") + tk.MustExec("drop table if exists t_flashback") + tk.MustExec("create table t_flashback (a int)") + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + // if GC safe point is not exists in mysql.tidb + tk.MustGetErrMsg("flashback database db_not_exists", "can not get 'tikv_gc_safe_point'") + // Set GC safe point + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + // Set GC enable. + require.NoError(t, gcutil.EnableGC(tk.Session())) + + tk.MustExec("insert into t_flashback values (1),(2),(3)") + tk.MustExec("drop database test_flashback") + + // Test flashback database with db_not_exists name. + tk.MustGetErrMsg("flashback database db_not_exists", "Can't find dropped database: db_not_exists in DDL history jobs") + tk.MustExec("flashback database test_flashback") + tk.MustGetErrMsg("flashback database test_flashback to test_flashback2", infoschema.ErrDatabaseExists.GenWithStack("Schema 'test_flashback' already been recover to 'test_flashback', can't be recover repeatedly").Error()) + + // Test flashback database failed by there is already a new database with the same name. + // If there is a new database with the same name, should return failed. + tk.MustExec("create database db_flashback") + tk.MustGetErrMsg("flashback schema db_flashback", infoschema.ErrDatabaseExists.GenWithStackByArgs("db_flashback").Error()) + + // Test for flashback schema. + tk.MustExec("drop database if exists test1") + tk.MustExec("create database test1") + tk.MustExec("use test1") + tk.MustExec("create table t (a int)") + tk.MustExec("create table t1 (a int)") + tk.MustExec("insert into t values (1),(2),(3)") + tk.MustExec("insert into t1 values (4),(5),(6)") + tk.MustExec("drop database test1") + tk.MustExec("flashback schema test1") + tk.MustExec("use test1") + tk.MustQuery("select a from t order by a").Check(testkit.Rows("1", "2", "3")) + tk.MustQuery("select a from t1 order by a").Check(testkit.Rows("4", "5", "6")) + tk.MustExec("drop database test1") + tk.MustExec("flashback schema test1 to test2") + tk.MustExec("use test2") + tk.MustQuery("select a from t order by a").Check(testkit.Rows("1", "2", "3")) + tk.MustQuery("select a from t1 order by a").Check(testkit.Rows("4", "5", "6")) +} + // MockGC is used to make GC work in the test environment. func MockGC(tk *testkit.TestKit) (string, string, string, func()) { originGC := ddlutil.IsEmulatorGCEnable() @@ -437,9 +482,8 @@ func MockGC(tk *testkit.TestKit) (string, string, string, func()) { // disable emulator GC. // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. ddlutil.EmulatorGCDisable() - gcTimeFormat := "20060102-15:04:05 -0700 MST" - timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(gcTimeFormat) - timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(gcTimeFormat) + timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(tikvutil.GCTimeFormat) + timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(tikvutil.GCTimeFormat) safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') ON DUPLICATE KEY UPDATE variable_value = '%[1]s'` diff --git a/executor/replace.go b/executor/replace.go index 221cbf87b2504..bfc70ebc4451c 100644 --- a/executor/replace.go +++ b/executor/replace.go @@ -43,6 +43,9 @@ type ReplaceExec struct { // Close implements the Executor Close interface. func (e *ReplaceExec) Close() error { e.setMessage() + if e.runtimeStats != nil && e.stats != nil { + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) + } if e.SelectExec != nil { return e.SelectExec.Close() } @@ -89,6 +92,10 @@ func (e *ReplaceExec) removeRow(ctx context.Context, txn kv.Transaction, handle if err != nil { return false, err } + err = onRemoveRowForFK(e.ctx, oldRow, e.fkChecks, e.fkCascades) + if err != nil { + return false, err + } e.ctx.GetSessionVars().StmtCtx.AddAffectedRows(1) return false, nil } @@ -176,6 +183,12 @@ func (e *ReplaceExec) removeIndexRow(ctx context.Context, txn kv.Transaction, r } return false, false, err } + if tablecodec.IsTempIndexKey(uk.newKey) { + if tablecodec.CheckTempIndexValueIsDelete(val) { + continue + } + val = tablecodec.DecodeTempIndexOriginValue(val) + } handle, err := tablecodec.DecodeHandleInUniqueIndexValue(val, uk.commonHandle) if err != nil { return false, true, err @@ -268,3 +281,18 @@ func (e *ReplaceExec) setMessage() { stmtCtx.SetMessage(msg) } } + +// GetFKChecks implements WithForeignKeyTrigger interface. +func (e *ReplaceExec) GetFKChecks() []*FKCheckExec { + return e.fkChecks +} + +// GetFKCascades implements WithForeignKeyTrigger interface. +func (e *ReplaceExec) GetFKCascades() []*FKCascadeExec { + return e.fkCascades +} + +// HasFKCascades implements WithForeignKeyTrigger interface. +func (e *ReplaceExec) HasFKCascades() bool { + return len(e.fkCascades) > 0 +} diff --git a/executor/revoke.go b/executor/revoke.go index c00a1308e5eab..337e387c5b28f 100644 --- a/executor/revoke.go +++ b/executor/revoke.go @@ -271,13 +271,22 @@ func (e *RevokeExec) revokeTablePriv(internalSession sessionctx.Context, priv *a } sql := new(strings.Builder) sqlexec.MustFormatSQL(sql, "UPDATE %n.%n SET ", mysql.SystemDB, mysql.TablePrivTable) - err = composeTablePrivUpdateForRevoke(internalSession, sql, priv.Priv, user, host, dbName, tblName) + isDelRow, err := composeTablePrivUpdateForRevoke(internalSession, sql, priv.Priv, user, host, dbName, tblName) if err != nil { return err } - sqlexec.MustFormatSQL(sql, " WHERE User=%? AND Host=%? AND DB=%? AND Table_name=%?", user, host, dbName, tblName) + sqlexec.MustFormatSQL(sql, " WHERE User=%? AND Host=%? AND DB=%? AND Table_name=%?", user, host, dbName, tblName) _, err = internalSession.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql.String()) + if err != nil { + return err + } + + if isDelRow { + sql.Reset() + sqlexec.MustFormatSQL(sql, "DELETE FROM %n.%n WHERE User=%? AND Host=%? AND DB=%? AND Table_name=%?", mysql.SystemDB, mysql.TablePrivTable, user, host, dbName, tblName) + _, err = internalSession.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql.String()) + } return err } @@ -296,7 +305,7 @@ func (e *RevokeExec) revokeColumnPriv(internalSession sessionctx.Context, priv * sql.Reset() sqlexec.MustFormatSQL(sql, "UPDATE %n.%n SET ", mysql.SystemDB, mysql.ColumnPrivTable) - err = composeColumnPrivUpdateForRevoke(internalSession, sql, priv.Priv, user, host, dbName, tbl.Meta().Name.O, col.Name.O) + isDelRow, err := composeColumnPrivUpdateForRevoke(internalSession, sql, priv.Priv, user, host, dbName, tbl.Meta().Name.O, col.Name.O) if err != nil { return err } @@ -306,6 +315,17 @@ func (e *RevokeExec) revokeColumnPriv(internalSession sessionctx.Context, priv * if err != nil { return err } + + if isDelRow { + sql.Reset() + sqlexec.MustFormatSQL(sql, "DELETE FROM %n.%n WHERE User=%? AND Host=%? AND DB=%? AND Table_name=%? AND Column_name=%?", mysql.SystemDB, mysql.ColumnPrivTable, user, host, dbName, tbl.Meta().Name.O, col.Name.O) + _, err = internalSession.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql.String()) + if err != nil { + return err + } + break + } + //TODO Optimized for batch, one-shot. } return nil } @@ -319,12 +339,12 @@ func privUpdateForRevoke(cur []string, priv mysql.PrivilegeType) ([]string, erro return cur, nil } -func composeTablePrivUpdateForRevoke(ctx sessionctx.Context, sql *strings.Builder, priv mysql.PrivilegeType, name string, host string, db string, tbl string) error { +func composeTablePrivUpdateForRevoke(ctx sessionctx.Context, sql *strings.Builder, priv mysql.PrivilegeType, name string, host string, db string, tbl string) (bool, error) { var newTablePriv, newColumnPriv []string currTablePriv, currColumnPriv, err := getTablePriv(ctx, name, host, db, tbl) if err != nil { - return err + return false, err } if priv == mysql.AllPriv { @@ -340,36 +360,35 @@ func composeTablePrivUpdateForRevoke(ctx sessionctx.Context, sql *strings.Builde newTablePriv = SetFromString(currTablePriv) newTablePriv, err = privUpdateForRevoke(newTablePriv, priv) if err != nil { - return err + return false, err } newColumnPriv = SetFromString(currColumnPriv) newColumnPriv, err = privUpdateForRevoke(newColumnPriv, priv) if err != nil { - return err + return false, err } } - sqlexec.MustFormatSQL(sql, `Table_priv=%?, Column_priv=%?, Grantor=%?`, strings.Join(newTablePriv, ","), strings.Join(newColumnPriv, ","), ctx.GetSessionVars().User.String()) - return nil + return len(newTablePriv) == 0, nil } -func composeColumnPrivUpdateForRevoke(ctx sessionctx.Context, sql *strings.Builder, priv mysql.PrivilegeType, name string, host string, db string, tbl string, col string) error { +func composeColumnPrivUpdateForRevoke(ctx sessionctx.Context, sql *strings.Builder, priv mysql.PrivilegeType, name string, host string, db string, tbl string, col string) (bool, error) { var newColumnPriv []string if priv != mysql.AllPriv { currColumnPriv, err := getColumnPriv(ctx, name, host, db, tbl, col) if err != nil { - return err + return false, err } newColumnPriv = SetFromString(currColumnPriv) newColumnPriv, err = privUpdateForRevoke(newColumnPriv, priv) if err != nil { - return err + return false, err } } sqlexec.MustFormatSQL(sql, `Column_priv=%?`, strings.Join(newColumnPriv, ",")) - return nil + return len(newColumnPriv) == 0, nil } diff --git a/executor/revoke_test.go b/executor/revoke_test.go index 1330b76bc6b59..635fa18552df5 100644 --- a/executor/revoke_test.go +++ b/executor/revoke_test.go @@ -98,28 +98,35 @@ func TestRevokeTableScope(t *testing.T) { res.Check(testkit.Rows("Select,Insert,Update,Delete,Create,Drop,Index,Alter,Create View,Show View,Trigger,References")) // Revoke each priv from the user. - for _, v := range mysql.AllTablePrivs { + for index, v := range mysql.AllTablePrivs { sql := fmt.Sprintf("REVOKE %s ON test.test1 FROM 'testTblRevoke'@'localhost';", mysql.Priv2Str[v]) tk.MustExec(sql) rows := tk.MustQuery(`SELECT Table_priv FROM mysql.tables_priv WHERE User="testTblRevoke" and host="localhost" and db="test" and Table_name="test1";`).Rows() - require.Len(t, rows, 1) - row := rows[0] - require.Len(t, row, 1) - - op := v.SetString() - found := false - for _, p := range executor.SetFromString(fmt.Sprintf("%s", row[0])) { - if op == p { - found = true - break + if index < len(mysql.AllTablePrivs)-1 { + require.Len(t, rows, 1) + row := rows[0] + require.Len(t, row, 1) + op := v.SetString() + found := false + for _, p := range executor.SetFromString(fmt.Sprintf("%s", row[0])) { + if op == p { + found = true + break + } } + require.False(t, found, "%s", mysql.Priv2SetStr[v]) + } else { + //delete row when last prv , updated by issue #38421 + require.Len(t, rows, 0) } - require.False(t, found, "%s", mysql.Priv2SetStr[v]) } // Revoke all table scope privs. + tk.MustExec(`GRANT ALL PRIVILEGES ON test.test1 TO 'testTblRevoke'@'localhost';`) tk.MustExec("REVOKE ALL ON test.test1 FROM 'testTblRevoke'@'localhost';") - tk.MustQuery(`SELECT Table_priv FROM mysql.Tables_priv WHERE User="testTblRevoke" and host="localhost" and db="test" and Table_name="test1"`).Check(testkit.Rows("")) + //delete row when last prv , updated by issue #38421 + rows := tk.MustQuery(`SELECT Table_priv FROM mysql.Tables_priv WHERE User="testTblRevoke" and host="localhost" and db="test" and Table_name="test1"`).Rows() + require.Len(t, rows, 0) } func TestRevokeColumnScope(t *testing.T) { @@ -145,7 +152,9 @@ func TestRevokeColumnScope(t *testing.T) { require.Greater(t, strings.Index(p, mysql.Priv2SetStr[v]), -1) tk.MustExec(revokeSQL) - tk.MustQuery(checkSQL).Check(testkit.Rows("")) + //delete row when last prv , updated by issue #38421 + rows = tk.MustQuery(checkSQL).Rows() + require.Len(t, rows, 0) } // Create a new user. @@ -163,7 +172,40 @@ func TestRevokeColumnScope(t *testing.T) { require.Greater(t, strings.Index(p, mysql.Priv2SetStr[v]), -1) } tk.MustExec("REVOKE ALL(c2) ON test3 FROM 'testCol1Revoke'@'localhost'") - tk.MustQuery(`SELECT Column_priv FROM mysql.Columns_priv WHERE User="testCol1Revoke" and host="localhost" and db="test" and Table_name="test3"`).Check(testkit.Rows("")) + //delete row when last prv , updated by issue #38421 + rows := tk.MustQuery(`SELECT Column_priv FROM mysql.Columns_priv WHERE User="testCol1Revoke" and host="localhost" and db="test" and Table_name="test3"`).Rows() + require.Len(t, rows, 0) +} + +// ref issue #38421 +func TestRevokeTableSingle(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + // Create a new user. + tk.MustExec(`CREATE USER test;`) + tk.MustExec(`CREATE TABLE test.test1(c1 int);`) + tk.MustExec(`GRANT SELECT ON test.test1 TO test;`) + + tk.MustExec(`REVOKE SELECT ON test.test1 from test;`) + + rows := tk.MustQuery(`SELECT Column_priv FROM mysql.tables_priv WHERE User="test" `).Rows() + require.Len(t, rows, 0) +} + +// ref issue #38421(column fix) +func TestRevokeTableSingleColumn(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + // Create a new user. + tk.MustExec(`CREATE USER test;`) + tk.MustExec(`GRANT SELECT(Host) ON mysql.db TO test`) + tk.MustExec(`GRANT SELECT(DB) ON mysql.db TO test`) + tk.MustExec(`REVOKE SELECT(Host) ON mysql.db FROM test`) + + rows := tk.MustQuery(`SELECT Column_priv FROM mysql.columns_priv WHERE User="test" and Column_name ='Host' `).Rows() + require.Len(t, rows, 0) + rows = tk.MustQuery(`SELECT Column_priv FROM mysql.columns_priv WHERE User="test" and Column_name ='DB' `).Rows() + require.Len(t, rows, 1) } func TestRevokeDynamicPrivs(t *testing.T) { diff --git a/executor/select_into.go b/executor/select_into.go index d526edec874f4..556edc58c7cbe 100644 --- a/executor/select_into.go +++ b/executor/select_into.go @@ -60,7 +60,7 @@ func (s *SelectIntoExec) Open(ctx context.Context) error { s.started = true s.dstFile = f s.writer = bufio.NewWriter(s.dstFile) - s.chk = newFirstChunk(s.children[0]) + s.chk = tryNewCacheChunk(s.children[0]) s.lineBuf = make([]byte, 0, 1024) s.fieldBuf = make([]byte, 0, 64) s.escapeBuf = make([]byte, 0, 64) diff --git a/executor/seqtest/BUILD.bazel b/executor/seqtest/BUILD.bazel index 5de83a3501269..6d582ded16630 100644 --- a/executor/seqtest/BUILD.bazel +++ b/executor/seqtest/BUILD.bazel @@ -2,13 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_test") go_test( name = "seqtest_test", - timeout = "moderate", + timeout = "short", srcs = [ "main_test.go", "prepared_test.go", "seq_executor_test.go", ], flaky = True, + race = "on", shard_count = 39, deps = [ "//config", @@ -23,7 +24,6 @@ go_test( "//parser/ast", "//parser/model", "//parser/mysql", - "//parser/terror", "//planner/core", "//server", "//session", diff --git a/executor/seqtest/main_test.go b/executor/seqtest/main_test.go index 5a1e3d84813f4..067680fb23365 100644 --- a/executor/seqtest/main_test.go +++ b/executor/seqtest/main_test.go @@ -30,7 +30,8 @@ func TestMain(m *testing.M) { }) opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), - goleak.IgnoreTopFunction("github.com/pingcap/tidb/executor.readProjectionInput"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("github.com/pingcap/tidb/executor.readProjection[...]"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/executor/seqtest/prepared_test.go b/executor/seqtest/prepared_test.go index 05331dcce2c1d..12a99a7b90ca7 100644 --- a/executor/seqtest/prepared_test.go +++ b/executor/seqtest/prepared_test.go @@ -280,11 +280,11 @@ func TestPreparedLimitOffset(t *testing.T) { r.Check(testkit.Rows("2")) tk.MustExec(`set @a=1.1`) - r = tk.MustQuery(`execute stmt_test_1 using @a, @b;`) - r.Check(testkit.Rows("2")) + _, err := tk.Exec(`execute stmt_test_1 using @a, @b;`) + require.True(t, plannercore.ErrWrongArguments.Equal(err)) tk.MustExec(`set @c="-1"`) - _, err := tk.Exec("execute stmt_test_1 using @c, @c") + _, err = tk.Exec("execute stmt_test_1 using @c, @c") require.True(t, plannercore.ErrWrongArguments.Equal(err)) stmtID, _, _, err := tk.Session().PrepareStmt("select id from prepare_test limit ?") @@ -334,7 +334,7 @@ func TestPrepareWithAggregation(t *testing.T) { tk.MustExec(fmt.Sprintf(`set @@tidb_enable_prepared_plan_cache=%v`, flag)) se, err := session.CreateSession4TestWithOpt(store, &session.Opt{ - PreparedPlanCache: plannercore.NewLRUPlanCache(100, 0.1, math.MaxUint64, plannercore.PickPlanFromBucket), + PreparedPlanCache: plannercore.NewLRUPlanCache(100, 0.1, math.MaxUint64, plannercore.PickPlanFromBucket, tk.Session()), }) require.NoError(t, err) tk.SetSession(se) @@ -420,14 +420,14 @@ func TestPreparedInsert(t *testing.T) { err = counter.Write(pb) require.NoError(t, err) hit := pb.GetCounter().GetValue() - require.Equal(t, float64(1), hit) + require.Equal(t, float64(0), hit) // insert-values-stmt cannot use the plan cache } tk.MustExec(`set @a=3,@b=3; execute stmt_insert using @a, @b;`) if flag { err = counter.Write(pb) require.NoError(t, err) hit := pb.GetCounter().GetValue() - require.Equal(t, float64(2), hit) + require.Equal(t, float64(0), hit) } result := tk.MustQuery("select id, c1 from prepare_test where id = ?", 1) @@ -443,21 +443,21 @@ func TestPreparedInsert(t *testing.T) { err = counter.Write(pb) require.NoError(t, err) hit := pb.GetCounter().GetValue() - require.Equal(t, float64(2), hit) + require.Equal(t, float64(0), hit) } tk.MustExec(`set @a=2; execute stmt_insert_select using @a;`) if flag { err = counter.Write(pb) require.NoError(t, err) hit := pb.GetCounter().GetValue() - require.Equal(t, float64(3), hit) + require.Equal(t, float64(1), hit) } tk.MustExec(`set @a=3; execute stmt_insert_select using @a;`) if flag { err = counter.Write(pb) require.NoError(t, err) hit := pb.GetCounter().GetValue() - require.Equal(t, float64(4), hit) + require.Equal(t, float64(2), hit) } result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 101) @@ -599,7 +599,7 @@ func TestPrepareDealloc(t *testing.T) { tk.MustExec(`set @@tidb_enable_prepared_plan_cache=true`) se, err := session.CreateSession4TestWithOpt(store, &session.Opt{ - PreparedPlanCache: plannercore.NewLRUPlanCache(3, 0.1, math.MaxUint64, plannercore.PickPlanFromBucket), + PreparedPlanCache: plannercore.NewLRUPlanCache(3, 0.1, math.MaxUint64, plannercore.PickPlanFromBucket, tk.Session()), }) require.NoError(t, err) tk.SetSession(se) @@ -767,3 +767,42 @@ func TestPreparedIssue17419(t *testing.T) { // _, ok := tk1.Session().ShowProcess().Plan.(*plannercore.Execute) // require.True(t, ok) } + +func TestLimitUnsupportedCase(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, key(a))") + tk.MustExec("prepare stmt from 'select * from t limit ?'") + + tk.MustExec("set @a = 1.2") + tk.MustGetErrMsg("execute stmt using @a", "[planner:1210]Incorrect arguments to LIMIT") + tk.MustExec("set @a = 1.") + tk.MustGetErrMsg("execute stmt using @a", "[planner:1210]Incorrect arguments to LIMIT") + tk.MustExec("set @a = '0'") + tk.MustGetErrMsg("execute stmt using @a", "[planner:1210]Incorrect arguments to LIMIT") + tk.MustExec("set @a = '1'") + tk.MustGetErrMsg("execute stmt using @a", "[planner:1210]Incorrect arguments to LIMIT") + tk.MustExec("set @a = 1_2") + tk.MustGetErrMsg("execute stmt using @a", "[planner:1210]Incorrect arguments to LIMIT") +} + +func TestIssue38323(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int, k int);") + + tk.MustExec("prepare stmt from 'explain select * from t where id = ? and k = ? group by id, k';") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: not a SELECT/UPDATE/INSERT/DELETE/SET statement")) + tk.MustExec("set @a = 1;") + tk.MustExec("execute stmt using @a, @a") + tk.MustQuery("execute stmt using @a, @a").Check(tk.MustQuery("explain select * from t where id = 1 and k = 1 group by id, k").Rows()) + + tk.MustExec("prepare stmt from 'explain select * from t where ? = id and ? = k group by id, k';") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: not a SELECT/UPDATE/INSERT/DELETE/SET statement")) + tk.MustExec("set @a = 1;") + tk.MustQuery("execute stmt using @a, @a").Check(tk.MustQuery("explain select * from t where 1 = id and 1 = k group by id, k").Rows()) +} diff --git a/executor/seqtest/seq_executor_test.go b/executor/seqtest/seq_executor_test.go index cac879acd4111..6c042340740e8 100644 --- a/executor/seqtest/seq_executor_test.go +++ b/executor/seqtest/seq_executor_test.go @@ -41,7 +41,6 @@ import ( "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" - "github.com/pingcap/tidb/parser/terror" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/variable" @@ -496,11 +495,10 @@ func TestShow(t *testing.T) { )) tk.MustExec(`drop table if exists t`) - _, err := tk.Exec(`CREATE TABLE t (x int, y char) PARTITION BY RANGE(y) ( + tk.MustExecToErr(`CREATE TABLE t (x int, y char) PARTITION BY RANGE(y) ( PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20), PARTITION p2 VALUES LESS THAN (MAXVALUE))`) - require.Error(t, err) // Test range columns partition tk.MustExec(`drop table if exists t`) @@ -543,7 +541,7 @@ func TestShow(t *testing.T) { // Test show create table year type tk.MustExec(`drop table if exists t`) - tk.MustExec(`create table t(y year unsigned signed zerofill zerofill, x int, primary key(y));`) + tk.MustExec(`create table t(y year unsigned signed zerofill zerofill, x int, primary key(y) nonclustered);`) tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", "t CREATE TABLE `t` (\n"+ " `y` year(4) NOT NULL,\n"+ @@ -775,43 +773,45 @@ func HelperTestAdminShowNextID(t *testing.T, store kv.Storage, str string) { tk.MustExec("create table t(id int, c int)") // Start handle is 1. r := tk.MustQuery(str + " t next_row_id") - r.Check(testkit.Rows("test t _tidb_rowid 1 AUTO_INCREMENT")) + r.Check(testkit.Rows("test t _tidb_rowid 1 _TIDB_ROWID")) // Row ID is step + 1. tk.MustExec("insert into t values(1, 1)") r = tk.MustQuery(str + " t next_row_id") - r.Check(testkit.Rows("test t _tidb_rowid 11 AUTO_INCREMENT")) + r.Check(testkit.Rows("test t _tidb_rowid 11 _TIDB_ROWID")) // Row ID is original + step. for i := 0; i < int(step); i++ { tk.MustExec("insert into t values(10000, 1)") } r = tk.MustQuery(str + " t next_row_id") - r.Check(testkit.Rows("test t _tidb_rowid 21 AUTO_INCREMENT")) + r.Check(testkit.Rows("test t _tidb_rowid 21 _TIDB_ROWID")) tk.MustExec("drop table t") // test for a table with the primary key tk.MustExec("create table tt(id int primary key auto_increment, c int)") // Start handle is 1. r = tk.MustQuery(str + " tt next_row_id") - r.Check(testkit.Rows("test tt id 1 AUTO_INCREMENT")) + r.Check(testkit.Rows("test tt id 1 _TIDB_ROWID", "test tt id 1 AUTO_INCREMENT")) // After rebasing auto ID, row ID is 20 + step + 1. tk.MustExec("insert into tt values(20, 1)") r = tk.MustQuery(str + " tt next_row_id") - r.Check(testkit.Rows("test tt id 31 AUTO_INCREMENT")) + r.Check(testkit.Rows("test tt id 31 _TIDB_ROWID", "test tt id 1 AUTO_INCREMENT")) // test for renaming the table tk.MustExec("drop database if exists test1") tk.MustExec("create database test1") tk.MustExec("rename table test.tt to test1.tt") tk.MustExec("use test1") r = tk.MustQuery(str + " tt next_row_id") - r.Check(testkit.Rows("test1 tt id 31 AUTO_INCREMENT")) + r.Check(testkit.Rows("test1 tt id 31 _TIDB_ROWID", "test1 tt id 1 AUTO_INCREMENT")) tk.MustExec("insert test1.tt values ()") r = tk.MustQuery(str + " tt next_row_id") - r.Check(testkit.Rows("test1 tt id 41 AUTO_INCREMENT")) + r.Check(testkit.Rows("test1 tt id 41 _TIDB_ROWID", "test1 tt id 1 AUTO_INCREMENT")) tk.MustExec("drop table tt") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a int auto_increment primary key nonclustered, b int);") - tk.MustQuery("show table t next_row_id;").Check(testkit.Rows("test1 t _tidb_rowid 1 AUTO_INCREMENT")) + tk.MustQuery("show table t next_row_id;").Check(testkit.Rows( + "test1 t _tidb_rowid 1 _TIDB_ROWID", + "test1 t _tidb_rowid 1 AUTO_INCREMENT")) tk.MustExec("set @@allow_auto_random_explicit_insert = true") @@ -832,19 +832,19 @@ func HelperTestAdminShowNextID(t *testing.T, store kv.Storage, str string) { // Test for a sequence. tk.MustExec("create sequence seq1 start 15 cache 57") r = tk.MustQuery(str + " seq1 next_row_id") - r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 AUTO_INCREMENT", "test1 seq1 15 SEQUENCE")) + r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 _TIDB_ROWID", "test1 seq1 15 SEQUENCE")) r = tk.MustQuery("select nextval(seq1)") r.Check(testkit.Rows("15")) r = tk.MustQuery(str + " seq1 next_row_id") - r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 AUTO_INCREMENT", "test1 seq1 72 SEQUENCE")) + r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 _TIDB_ROWID", "test1 seq1 72 SEQUENCE")) r = tk.MustQuery("select nextval(seq1)") r.Check(testkit.Rows("16")) r = tk.MustQuery(str + " seq1 next_row_id") - r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 AUTO_INCREMENT", "test1 seq1 72 SEQUENCE")) + r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 _TIDB_ROWID", "test1 seq1 72 SEQUENCE")) r = tk.MustQuery("select setval(seq1, 96)") r.Check(testkit.Rows("96")) r = tk.MustQuery(str + " seq1 next_row_id") - r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 AUTO_INCREMENT", "test1 seq1 97 SEQUENCE")) + r.Check(testkit.Rows("test1 seq1 _tidb_rowid 1 _TIDB_ROWID", "test1 seq1 97 SEQUENCE")) } func TestNoHistoryWhenDisableRetry(t *testing.T) { @@ -900,7 +900,7 @@ func TestPrepareMaxParamCountCheck(t *testing.T) { require.NoError(t, err) bigSQL, bigParams := generateBatchSQL(math.MaxUint16 + 2) - _, err = tk.Exec(bigSQL, bigParams...) + err = tk.ExecToErr(bigSQL, bigParams...) require.Error(t, err) require.EqualError(t, err, "[executor:1390]Prepared statement contains too many placeholders") } @@ -940,7 +940,7 @@ func TestBatchInsertDelete(t *testing.T) { atomic.StoreUint64(&kv.TxnTotalSizeLimit, originLimit) }() // Set the limitation to a small value, make it easier to reach the limitation. - atomic.StoreUint64(&kv.TxnTotalSizeLimit, 5700) + atomic.StoreUint64(&kv.TxnTotalSizeLimit, 5900) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -987,16 +987,12 @@ func TestBatchInsertDelete(t *testing.T) { // Test tidb_batch_insert could not work if enable-batch-dml is disabled. tk.MustExec("set @@session.tidb_batch_insert=1;") - _, err = tk.Exec("insert into batch_insert (c) select * from batch_insert;") - require.Error(t, err) - require.True(t, kv.ErrTxnTooLarge.Equal(err)) + tk.MustGetErrCode("insert into batch_insert (c) select * from batch_insert;", errno.ErrTxnTooLarge) tk.MustExec("set @@session.tidb_batch_insert=0;") // for on duplicate key - _, err = tk.Exec(`insert into batch_insert_on_duplicate select * from batch_insert_on_duplicate as tt - on duplicate key update batch_insert_on_duplicate.id=batch_insert_on_duplicate.id+1000;`) - require.Error(t, err) - require.Truef(t, kv.ErrTxnTooLarge.Equal(err), "%v", err) + tk.MustGetErrCode(`insert into batch_insert_on_duplicate select * from batch_insert_on_duplicate as tt + on duplicate key update batch_insert_on_duplicate.id=batch_insert_on_duplicate.id+1000;`, errno.ErrTxnTooLarge) r = tk.MustQuery("select count(*) from batch_insert;") r.Check(testkit.Rows("320")) @@ -1022,17 +1018,14 @@ func TestBatchInsertDelete(t *testing.T) { tk.MustExec("set @@session.tidb_dml_batch_size=50;") // for on duplicate key - _, err = tk.Exec(`insert into batch_insert_on_duplicate select * from batch_insert_on_duplicate as tt + tk.MustExec(`insert into batch_insert_on_duplicate select * from batch_insert_on_duplicate as tt on duplicate key update batch_insert_on_duplicate.id=batch_insert_on_duplicate.id+1000;`) - require.NoError(t, err) r = tk.MustQuery("select count(*) from batch_insert_on_duplicate;") r.Check(testkit.Rows("320")) // Disable BachInsert mode in transition. tk.MustExec("begin;") - _, err = tk.Exec("insert into batch_insert (c) select * from batch_insert;") - require.Error(t, err) - require.True(t, kv.ErrTxnTooLarge.Equal(err)) + tk.MustGetErrCode("insert into batch_insert (c) select * from batch_insert;", errno.ErrTxnTooLarge) tk.MustExec("rollback;") r = tk.MustQuery("select count(*) from batch_insert;") r.Check(testkit.Rows("640")) @@ -1050,9 +1043,7 @@ func TestBatchInsertDelete(t *testing.T) { // Test case for batch delete. // This will meet txn too large error. - _, err = tk.Exec("delete from batch_insert;") - require.Error(t, err) - require.True(t, kv.ErrTxnTooLarge.Equal(err)) + tk.MustGetErrCode("delete from batch_insert;", errno.ErrTxnTooLarge) r = tk.MustQuery("select count(*) from batch_insert;") r.Check(testkit.Rows("640")) // Enable batch delete and set batch size to 50. @@ -1458,8 +1449,7 @@ func TestMaxDeltaSchemaCount(t *testing.T) { tk.RefreshSession() tk.MustExec("use test") require.Equal(t, int64(16384), variable.GetMaxDeltaSchemaCount()) - _, err := tk.Exec("set @@global.tidb_max_delta_schema_count= invalid_val") - require.Truef(t, terror.ErrorEqual(err, variable.ErrWrongTypeForVar), "err %v", err) + tk.MustGetErrCode("set @@global.tidb_max_delta_schema_count= invalid_val", errno.ErrWrongTypeForVar) tk.MustExec("set @@global.tidb_max_delta_schema_count= 2048") tk.RefreshSession() diff --git a/executor/set.go b/executor/set.go index 90ec6d750299c..2396356c1245b 100644 --- a/executor/set.go +++ b/executor/set.go @@ -24,7 +24,9 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/plugin" + "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/table/temptable" @@ -32,6 +34,7 @@ import ( "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/gcutil" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/sem" "go.uber.org/zap" ) @@ -109,6 +112,22 @@ func (e *SetExecutor) setSysVariable(ctx context.Context, name string, v *expres } return variable.ErrUnknownSystemVar.GenWithStackByArgs(name) } + + if sysVar.RequireDynamicPrivileges != nil { + semEnabled := sem.IsEnabled() + pm := privilege.GetPrivilegeManager(e.ctx) + privs := sysVar.RequireDynamicPrivileges(v.IsGlobal, semEnabled) + for _, priv := range privs { + if !pm.RequestDynamicVerification(sessionVars.ActiveRoles, priv, false) { + msg := priv + if !semEnabled { + msg = "SUPER or " + msg + } + return core.ErrSpecificAccessDenied.GenWithStackByArgs(msg) + } + } + } + if sysVar.IsNoop && !variable.EnableNoopVariables.Load() { // The variable is a noop. For compatibility we allow it to still // be changed, but we append a warning since users might be expecting @@ -123,11 +142,11 @@ func (e *SetExecutor) setSysVariable(ctx context.Context, name string, v *expres } if v.IsGlobal { - valStr, err := e.getVarValue(v, sysVar) + valStr, err := e.getVarValue(ctx, v, sysVar) if err != nil { return err } - err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(name, valStr) + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(ctx, name, valStr) if err != nil { return err } @@ -142,7 +161,7 @@ func (e *SetExecutor) setSysVariable(ctx context.Context, name string, v *expres return err } // Set session variable - valStr, err := e.getVarValue(v, nil) + valStr, err := e.getVarValue(ctx, v, nil) if err != nil { return err } @@ -251,7 +270,7 @@ func (e *SetExecutor) setCharset(cs, co string, isSetName bool) error { return errors.Trace(sessionVars.SetSystemVar(variable.CollationConnection, coDb)) } -func (e *SetExecutor) getVarValue(v *expression.VarAssignment, sysVar *variable.SysVar) (value string, err error) { +func (e *SetExecutor) getVarValue(ctx context.Context, v *expression.VarAssignment, sysVar *variable.SysVar) (value string, err error) { if v.IsDefault { // To set a SESSION variable to the GLOBAL value or a GLOBAL value // to the compiled-in MySQL default value, use the DEFAULT keyword. @@ -259,7 +278,7 @@ func (e *SetExecutor) getVarValue(v *expression.VarAssignment, sysVar *variable. if sysVar != nil { return sysVar.Value, nil } - return e.ctx.GetSessionVars().GetGlobalSystemVar(v.Name) + return e.ctx.GetSessionVars().GetGlobalSystemVar(ctx, v.Name) } nativeVal, err := v.Expr.Eval(chunk.Row{}) if err != nil || nativeVal.IsNull() { diff --git a/executor/set_config.go b/executor/set_config.go index 531a61acdc4a0..b508b55eb2fc7 100644 --- a/executor/set_config.go +++ b/executor/set_config.go @@ -102,7 +102,7 @@ func (s *SetConfigExec) Next(ctx context.Context, req *chunk.Chunk) error { if s.p.Instance != "" { nodeAddrs.Insert(s.p.Instance) } - serversInfo = filterClusterServerInfo(serversInfo, nodeTypes, nodeAddrs) + serversInfo = infoschema.FilterClusterServerInfo(serversInfo, nodeTypes, nodeAddrs) if s.p.Instance != "" && len(serversInfo) == 0 { return errors.Errorf("instance %v is not found in this cluster", s.p.Instance) } diff --git a/executor/set_test.go b/executor/set_test.go index 0f099e8182e44..1b2b4186bb4a3 100644 --- a/executor/set_test.go +++ b/executor/set_test.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "strconv" "testing" @@ -744,7 +743,7 @@ func TestSetVar(t *testing.T) { tk.MustQuery("select @@tidb_max_auto_analyze_time").Check(testkit.Rows("0")) // test variables for cost model ver2 - tk.MustQuery("select @@tidb_cost_model_version").Check(testkit.Rows("1")) + tk.MustQuery("select @@tidb_cost_model_version").Check(testkit.Rows(fmt.Sprintf("%v", variable.DefTiDBCostModelVer))) tk.MustExec("set tidb_cost_model_version=3") tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect tidb_cost_model_version value: '3'")) tk.MustExec("set tidb_cost_model_version=0") @@ -767,51 +766,51 @@ func TestSetVar(t *testing.T) { tk.MustGetErrCode("set global init_connect = 'invalidstring'", mysql.ErrWrongTypeForVar) tk.MustExec("set global init_connect = 'select now(); select timestamp()'") - // test variable 'tidb_enable_general_plan_cache' + // test variable 'tidb_enable_non_prepared_plan_cache' // global scope - tk.MustQuery("select @@global.tidb_enable_general_plan_cache").Check(testkit.Rows("0")) // default value - tk.MustExec("set global tidb_enable_general_plan_cache = 1") - tk.MustQuery("select @@global.tidb_enable_general_plan_cache").Check(testkit.Rows("1")) - tk.MustExec("set global tidb_enable_general_plan_cache = 0") - tk.MustQuery("select @@global.tidb_enable_general_plan_cache").Check(testkit.Rows("0")) + tk.MustQuery("select @@global.tidb_enable_non_prepared_plan_cache").Check(testkit.Rows("0")) // default value + tk.MustExec("set global tidb_enable_non_prepared_plan_cache = 1") + tk.MustQuery("select @@global.tidb_enable_non_prepared_plan_cache").Check(testkit.Rows("1")) + tk.MustExec("set global tidb_enable_non_prepared_plan_cache = 0") + tk.MustQuery("select @@global.tidb_enable_non_prepared_plan_cache").Check(testkit.Rows("0")) // session scope - tk.MustQuery("select @@session.tidb_enable_general_plan_cache").Check(testkit.Rows("0")) // default value - tk.MustExec("set session tidb_enable_general_plan_cache = 1") - tk.MustQuery("select @@session.tidb_enable_general_plan_cache").Check(testkit.Rows("1")) - tk.MustExec("set session tidb_enable_general_plan_cache = 0") - tk.MustQuery("select @@session.tidb_enable_general_plan_cache").Check(testkit.Rows("0")) + tk.MustQuery("select @@session.tidb_enable_non_prepared_plan_cache").Check(testkit.Rows("0")) // default value + tk.MustExec("set session tidb_enable_non_prepared_plan_cache = 1") + tk.MustQuery("select @@session.tidb_enable_non_prepared_plan_cache").Check(testkit.Rows("1")) + tk.MustExec("set session tidb_enable_non_prepared_plan_cache = 0") + tk.MustQuery("select @@session.tidb_enable_non_prepared_plan_cache").Check(testkit.Rows("0")) - // test variable 'tidb_general_plan_cache-size' + // test variable 'tidb_non_prepared_plan_cache-size' // global scope - tk.MustQuery("select @@global.tidb_general_plan_cache_size").Check(testkit.Rows("100")) // default value - tk.MustExec("set global tidb_general_plan_cache_size = 200") - tk.MustQuery("select @@global.tidb_general_plan_cache_size").Check(testkit.Rows("200")) - tk.MustExec("set global tidb_general_plan_cache_size = 200000000") // overflow - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 Truncated incorrect tidb_general_plan_cache_size value: '200000000'")) - tk.MustQuery("select @@global.tidb_general_plan_cache_size").Check(testkit.Rows("100000")) + tk.MustQuery("select @@global.tidb_non_prepared_plan_cache_size").Check(testkit.Rows("100")) // default value + tk.MustExec("set global tidb_non_prepared_plan_cache_size = 200") + tk.MustQuery("select @@global.tidb_non_prepared_plan_cache_size").Check(testkit.Rows("200")) + tk.MustExec("set global tidb_non_prepared_plan_cache_size = 200000000") // overflow + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 Truncated incorrect tidb_non_prepared_plan_cache_size value: '200000000'")) + tk.MustQuery("select @@global.tidb_non_prepared_plan_cache_size").Check(testkit.Rows("100000")) // session scope - tk.MustQuery("select @@session.tidb_general_plan_cache_size").Check(testkit.Rows("100")) // default value - tk.MustExec("set session tidb_general_plan_cache_size = 300") - tk.MustQuery("select @@session.tidb_general_plan_cache_size").Check(testkit.Rows("300")) - tk.MustExec("set session tidb_general_plan_cache_size = -1") // underflow - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 Truncated incorrect tidb_general_plan_cache_size value: '-1'")) - tk.MustQuery("select @@session.tidb_general_plan_cache_size").Check(testkit.Rows("1")) + tk.MustQuery("select @@session.tidb_non_prepared_plan_cache_size").Check(testkit.Rows("100")) // default value + tk.MustExec("set session tidb_non_prepared_plan_cache_size = 300") + tk.MustQuery("select @@session.tidb_non_prepared_plan_cache_size").Check(testkit.Rows("300")) + tk.MustExec("set session tidb_non_prepared_plan_cache_size = -1") // underflow + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 Truncated incorrect tidb_non_prepared_plan_cache_size value: '-1'")) + tk.MustQuery("select @@session.tidb_non_prepared_plan_cache_size").Check(testkit.Rows("1")) // test variable 'foreign_key_checks' // global scope - tk.MustQuery("select @@global.foreign_key_checks").Check(testkit.Rows("0")) // default value - tk.MustExec("set global foreign_key_checks = 1") - tk.MustQuery("select @@global.foreign_key_checks").Check(testkit.Rows("1")) + tk.MustQuery("select @@global.foreign_key_checks").Check(testkit.Rows("1")) // default value + tk.MustExec("set global foreign_key_checks = 0") + tk.MustQuery("select @@global.foreign_key_checks").Check(testkit.Rows("0")) // session scope - tk.MustQuery("select @@session.foreign_key_checks").Check(testkit.Rows("0")) // default value - tk.MustExec("set session foreign_key_checks = 1") - tk.MustQuery("select @@session.foreign_key_checks").Check(testkit.Rows("1")) + tk.MustQuery("select @@session.foreign_key_checks").Check(testkit.Rows("1")) // default value + tk.MustExec("set session foreign_key_checks = 0") + tk.MustQuery("select @@session.foreign_key_checks").Check(testkit.Rows("0")) - // test variable 'foreign_key_checks' + // test variable 'tidb_enable_foreign_key' // global scope - tk.MustQuery("select @@global.tidb_enable_foreign_key").Check(testkit.Rows("0")) // default value - tk.MustExec("set global tidb_enable_foreign_key = 1") - tk.MustQuery("select @@global.tidb_enable_foreign_key").Check(testkit.Rows("1")) + tk.MustQuery("select @@global.tidb_enable_foreign_key").Check(testkit.Rows("1")) // default value + tk.MustExec("set global tidb_enable_foreign_key = 0") + tk.MustQuery("select @@global.tidb_enable_foreign_key").Check(testkit.Rows("0")) // test variable 'tidb_opt_force_inline_cte' tk.MustQuery("select @@session.tidb_opt_force_inline_cte").Check(testkit.Rows("0")) // default value is 0 @@ -829,6 +828,47 @@ func TestSetVar(t *testing.T) { tk.MustQuery("select @@global.tidb_auto_analyze_partition_batch_size").Check(testkit.Rows("1")) // min value is 1 tk.MustExec("set global tidb_auto_analyze_partition_batch_size = 9999") tk.MustQuery("select @@global.tidb_auto_analyze_partition_batch_size").Check(testkit.Rows("1024")) // max value is 1024 + + // test variable 'tidb_opt_prefix_index_single_scan' + // global scope + tk.MustQuery("select @@global.tidb_opt_prefix_index_single_scan").Check(testkit.Rows("1")) // default value + tk.MustExec("set global tidb_opt_prefix_index_single_scan = 0") + tk.MustQuery("select @@global.tidb_opt_prefix_index_single_scan").Check(testkit.Rows("0")) + tk.MustExec("set global tidb_opt_prefix_index_single_scan = 1") + tk.MustQuery("select @@global.tidb_opt_prefix_index_single_scan").Check(testkit.Rows("1")) + // session scope + tk.MustQuery("select @@session.tidb_opt_prefix_index_single_scan").Check(testkit.Rows("1")) // default value + tk.MustExec("set session tidb_opt_prefix_index_single_scan = 0") + tk.MustQuery("select @@session.tidb_opt_prefix_index_single_scan").Check(testkit.Rows("0")) + tk.MustExec("set session tidb_opt_prefix_index_single_scan = 1") + tk.MustQuery("select @@session.tidb_opt_prefix_index_single_scan").Check(testkit.Rows("1")) + + // test tidb_opt_range_max_size + tk.MustQuery("select @@tidb_opt_range_max_size").Check(testkit.Rows("67108864")) + tk.MustExec("set global tidb_opt_range_max_size = -1") + tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect tidb_opt_range_max_size value: '-1'")) + tk.MustQuery("select @@global.tidb_opt_range_max_size").Check(testkit.Rows("0")) + tk.MustExec("set global tidb_opt_range_max_size = 1048576") + tk.MustQuery("select @@global.tidb_opt_range_max_size").Check(testkit.Rows("1048576")) + tk.MustExec("set session tidb_opt_range_max_size = 2097152") + tk.MustQuery("select @@session.tidb_opt_range_max_size").Check(testkit.Rows("2097152")) + + // test for password validation + tk.MustQuery("SELECT @@GLOBAL.validate_password.enable").Check(testkit.Rows("0")) + tk.MustQuery("SELECT @@GLOBAL.validate_password.length").Check(testkit.Rows("8")) + tk.MustExec("SET GLOBAL validate_password.length = 3") + tk.MustQuery("SELECT @@GLOBAL.validate_password.length").Check(testkit.Rows("4")) + tk.MustExec("SET GLOBAL validate_password.mixed_case_count = 2") + tk.MustQuery("SELECT @@GLOBAL.validate_password.length").Check(testkit.Rows("6")) + + // test tidb_cdc_write_source + require.Equal(t, uint64(0), tk.Session().GetSessionVars().CDCWriteSource) + tk.MustQuery("select @@tidb_cdc_write_source").Check(testkit.Rows("0")) + tk.MustExec("set @@session.tidb_cdc_write_source = 2") + tk.MustQuery("select @@tidb_cdc_write_source").Check(testkit.Rows("2")) + require.Equal(t, uint64(2), tk.Session().GetSessionVars().CDCWriteSource) + tk.MustExec("set @@session.tidb_cdc_write_source = 0") + require.Equal(t, uint64(0), tk.Session().GetSessionVars().CDCWriteSource) } func TestGetSetNoopVars(t *testing.T) { @@ -862,15 +902,6 @@ func TestGetSetNoopVars(t *testing.T) { err = tk.ExecToErr("SET GLOBAL tidb_enable_noop_variables = 'warn'") require.Error(t, err) require.Equal(t, "[variable:1231]Variable 'tidb_enable_noop_variables' can't be set to the value of 'warn'", err.Error()) - - tk.MustQuery("select @@tidb_opt_range_max_size").Check(testkit.Rows("0")) - tk.MustExec("set global tidb_opt_range_max_size = 1048576") - tk.MustQuery("select @@global.tidb_opt_range_max_size").Check(testkit.Rows("1048576")) - tk.MustExec("set global tidb_opt_range_max_size = -1") - tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect tidb_opt_range_max_size value: '-1'")) - tk.MustQuery("select @@global.tidb_opt_range_max_size").Check(testkit.Rows("0")) - tk.MustExec("set session tidb_opt_range_max_size = 2097152") - tk.MustQuery("select @@session.tidb_opt_range_max_size").Check(testkit.Rows("2097152")) } func TestTruncateIncorrectIntSessionVar(t *testing.T) { @@ -922,7 +953,7 @@ func TestSetCharset(t *testing.T) { check := func(args ...string) { for i, v := range characterSetVariables { - sVar, err := sessionVars.GetSessionOrGlobalSystemVar(v) + sVar, err := sessionVars.GetSessionOrGlobalSystemVar(context.Background(), v) require.NoError(t, err) require.Equal(t, args[i], sVar, fmt.Sprintf("%d: %s", i, characterSetVariables[i])) } @@ -1392,14 +1423,11 @@ func TestValidateSetVar(t *testing.T) { tk.MustExec("set @@innodb_lock_wait_timeout = 1073741825") tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect innodb_lock_wait_timeout value: '1073741825'")) - tk.MustExec("set @@global.validate_password_number_count=-1") - tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect validate_password_number_count value: '-1'")) + tk.MustExec("set @@global.validate_password.number_count=-1") + tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect validate_password.number_count value: '-1'")) - tk.MustExec("set @@global.validate_password_length=-1") - tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect validate_password_length value: '-1'")) - - tk.MustExec("set @@global.validate_password_length=8") - tk.MustQuery("show warnings").Check(testkit.Rows()) + tk.MustExec("set @@global.validate_password.length=-1") + tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect validate_password.length value: '-1'")) err = tk.ExecToErr("set @@tx_isolation=''") require.True(t, terror.ErrorEqual(err, variable.ErrWrongValueForVar), fmt.Sprintf("err %v", err)) @@ -1773,7 +1801,7 @@ func TestSetClusterConfig(t *testing.T) { httpCnt = 0 tk.Session().SetValue(executor.TestSetConfigHTTPHandlerKey, func(req *http.Request) (*http.Response, error) { httpCnt++ - body, err := ioutil.ReadAll(req.Body) + body, err := io.ReadAll(req.Body) require.NoError(t, err) // The `raftstore.` prefix is stripped. require.JSONEq(t, `{"server.snap-max-write-bytes-per-sec":"500MB"}`, string(body)) @@ -2008,3 +2036,38 @@ func TestSetTiFlashFastScanVariable(t *testing.T) { tk.MustExec("set GLOBAL tiflash_fastscan=OFF;") tk.MustQuery("select @@global.tiflash_fastscan").Check(testkit.Rows("0")) } + +func TestSetPlanCacheMemoryMonitor(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustQuery("select @@session.tidb_enable_prepared_plan_cache_memory_monitor").Check(testkit.Rows("1")) + tk.MustQuery("select @@global.tidb_enable_prepared_plan_cache_memory_monitor").Check(testkit.Rows("1")) + + tk.MustExec("set @@session.tidb_enable_prepared_plan_cache_memory_monitor=OFF;") + tk.MustQuery("select @@session.tidb_enable_prepared_plan_cache_memory_monitor").Check(testkit.Rows("0")) + + tk.MustExec("set @@session.tidb_enable_prepared_plan_cache_memory_monitor=1;") + tk.MustQuery("select @@session.tidb_enable_prepared_plan_cache_memory_monitor").Check(testkit.Rows("1")) + + tk.MustExec("set @@global.tidb_enable_prepared_plan_cache_memory_monitor=off;") + tk.MustQuery("select @@global.tidb_enable_prepared_plan_cache_memory_monitor").Check(testkit.Rows("0")) +} + +func TestSetChunkReuseVariable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@tidb_enable_reuse_chunk=ON;") + tk.MustQuery("select @@session.tidb_enable_reuse_chunk").Check(testkit.Rows("1")) + tk.MustExec("set GLOBAL tidb_enable_reuse_chunk=ON;") + tk.MustQuery("select @@global.tidb_enable_reuse_chunk").Check(testkit.Rows("1")) + + tk.MustExec("set @@tidb_enable_reuse_chunk=OFF;") + tk.MustQuery("select @@session.tidb_enable_reuse_chunk").Check(testkit.Rows("0")) + tk.MustExec("set GLOBAL tidb_enable_reuse_chunk=OFF;") + tk.MustQuery("select @@global.tidb_enable_reuse_chunk").Check(testkit.Rows("0")) + + // error value + tk.MustGetErrCode("set @@tidb_enable_reuse_chunk=s;", errno.ErrWrongValueForVar) +} diff --git a/executor/show.go b/executor/show.go index 9f5a1ba0d2194..36a9b8485822b 100644 --- a/executor/show.go +++ b/executor/show.go @@ -39,9 +39,11 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/charset" + parserformat "github.com/pingcap/tidb/parser/format" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/parser/tidb" field_types "github.com/pingcap/tidb/parser/types" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/plugin" @@ -67,6 +69,7 @@ import ( "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/sem" "github.com/pingcap/tidb/util/set" + "github.com/pingcap/tidb/util/slice" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/stringutil" "golang.org/x/exp/slices" @@ -78,16 +81,17 @@ var etcdDialTimeout = 5 * time.Second type ShowExec struct { baseExecutor - Tp ast.ShowStmtType // Databases/Tables/Columns/.... - DBName model.CIStr - Table *ast.TableName // Used for showing columns. - Partition model.CIStr // Used for showing partition - Column *ast.ColumnName // Used for `desc table column`. - IndexName model.CIStr // Used for show table regions. - Flag int // Some flag parsed from sql, such as FULL. - Roles []*auth.RoleIdentity // Used for show grants. - User *auth.UserIdentity // Used by show grants, show create user. - Extractor plannercore.ShowPredicateExtractor + Tp ast.ShowStmtType // Databases/Tables/Columns/.... + DBName model.CIStr + Table *ast.TableName // Used for showing columns. + Partition model.CIStr // Used for showing partition + Column *ast.ColumnName // Used for `desc table column`. + IndexName model.CIStr // Used for show table regions. + ResourceGroupName model.CIStr // Used for showing resource group + Flag int // Some flag parsed from sql, such as FULL. + Roles []*auth.RoleIdentity // Used for show grants. + User *auth.UserIdentity // Used by show grants, show create user. + Extractor plannercore.ShowPredicateExtractor is infoschema.InfoSchema @@ -179,6 +183,8 @@ func (e *ShowExec) fetchAll(ctx context.Context) error { return e.fetchShowCreateDatabase() case ast.ShowCreatePlacementPolicy: return e.fetchShowCreatePlacementPolicy() + case ast.ShowCreateResourceGroup: + return e.fetchShowCreateResourceGroup() case ast.ShowDatabases: return e.fetchShowDatabases() case ast.ShowDrainerStatus: @@ -204,7 +210,7 @@ func (e *ShowExec) fetchAll(ctx context.Context) error { case ast.ShowTriggers: return e.fetchShowTriggers() case ast.ShowVariables: - return e.fetchShowVariables() + return e.fetchShowVariables(ctx) case ast.ShowWarnings: return e.fetchShowWarnings(false) case ast.ShowErrors: @@ -226,6 +232,8 @@ func (e *ShowExec) fetchAll(ctx context.Context) error { case ast.ShowStatsHealthy: e.fetchShowStatsHealthy() return nil + case ast.ShowStatsLocked: + return e.fetchShowStatsLocked() case ast.ShowHistogramsInFlight: e.fetchShowHistogramsInFlight() return nil @@ -302,13 +310,14 @@ func (v *visibleChecker) Leave(in ast.Node) (out ast.Node, ok bool) { } func (e *ShowExec) fetchShowBind() error { - var bindRecords []*bindinfo.BindRecord + var tmp []*bindinfo.BindRecord if !e.GlobalScope { handle := e.ctx.Value(bindinfo.SessionBindInfoKeyType).(*bindinfo.SessionHandle) - bindRecords = handle.GetAllBindRecord() + tmp = handle.GetAllBindRecord() } else { - bindRecords = domain.GetDomain(e.ctx).BindHandle().GetAllBindRecord() + tmp = domain.GetDomain(e.ctx).BindHandle().GetAllBindRecord() } + bindRecords := slice.Copy(tmp) // Remove the invalid bindRecord. ind := 0 for _, bindData := range bindRecords { @@ -366,6 +375,8 @@ func (e *ShowExec) fetchShowBind() error { hint.Charset, hint.Collation, hint.Source, + hint.SQLDigest, + hint.PlanDigest, }) } } @@ -817,7 +828,7 @@ func (e *ShowExec) fetchShowMasterStatus() error { return nil } -func (e *ShowExec) fetchShowVariables() (err error) { +func (e *ShowExec) fetchShowVariables(ctx context.Context) (err error) { var ( value string sessionVars = e.ctx.GetSessionVars() @@ -849,7 +860,7 @@ func (e *ShowExec) fetchShowVariables() (err error) { if infoschema.SysVarHiddenForSem(e.ctx, v.Name) { continue } - value, err = sessionVars.GetGlobalSystemVar(v.Name) + value, err = sessionVars.GetGlobalSystemVar(ctx, v.Name) if err != nil { return errors.Trace(err) } @@ -874,7 +885,7 @@ func (e *ShowExec) fetchShowVariables() (err error) { if infoschema.SysVarHiddenForSem(e.ctx, v.Name) { continue } - value, err = sessionVars.GetSessionOrGlobalSystemVar(v.Name) + value, err = sessionVars.GetSessionOrGlobalSystemVar(context.Background(), v.Name) if err != nil { return errors.Trace(err) } @@ -1004,8 +1015,9 @@ func ConstructResultOfShowCreateTable(ctx sessionctx.Context, tableInfo *model.T } buf.WriteString(" DEFAULT NULL") } - case "CURRENT_TIMESTAMP": - buf.WriteString(" DEFAULT CURRENT_TIMESTAMP") + case "CURRENT_TIMESTAMP", "CURRENT_DATE": + buf.WriteString(" DEFAULT ") + buf.WriteString(defaultValue.(string)) if col.GetDecimal() > 0 { buf.WriteString(fmt.Sprintf("(%d)", col.GetDecimal())) } @@ -1139,6 +1151,9 @@ func ConstructResultOfShowCreateTable(ctx sessionctx.Context, tableInfo *model.T if model.ReferOptionType(fk.OnUpdate) != 0 { buf.WriteString(fmt.Sprintf(" ON UPDATE %s", model.ReferOptionType(fk.OnUpdate).String())) } + if fk.Version < model.FKVersion1 { + buf.WriteString(" /* FOREIGN KEY INVALID */") + } } buf.WriteString("\n") @@ -1216,7 +1231,55 @@ func ConstructResultOfShowCreateTable(ctx sessionctx.Context, tableInfo *model.T } // add partition info here. - appendPartitionInfo(tableInfo.Partition, buf, sqlMode) + ddl.AppendPartitionInfo(tableInfo.Partition, buf, sqlMode) + + if tableInfo.TTLInfo != nil { + restoreFlags := parserformat.RestoreStringSingleQuotes | parserformat.RestoreNameBackQuotes | parserformat.RestoreTiDBSpecialComment + restoreCtx := parserformat.NewRestoreCtx(restoreFlags, buf) + + restoreCtx.WritePlain(" ") + err = restoreCtx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error { + columnName := ast.ColumnName{Name: tableInfo.TTLInfo.ColumnName} + timeUnit := ast.TimeUnitExpr{Unit: ast.TimeUnitType(tableInfo.TTLInfo.IntervalTimeUnit)} + restoreCtx.WriteKeyWord("TTL") + restoreCtx.WritePlain("=") + restoreCtx.WriteName(columnName.String()) + restoreCtx.WritePlainf(" + INTERVAL %s ", tableInfo.TTLInfo.IntervalExprStr) + return timeUnit.Restore(restoreCtx) + }) + + if err != nil { + return err + } + + restoreCtx.WritePlain(" ") + err = restoreCtx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error { + restoreCtx.WriteKeyWord("TTL_ENABLE") + restoreCtx.WritePlain("=") + if tableInfo.TTLInfo.Enable { + restoreCtx.WriteString("ON") + } else { + restoreCtx.WriteString("OFF") + } + return nil + }) + + if err != nil { + return err + } + + restoreCtx.WritePlain(" ") + err = restoreCtx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error { + restoreCtx.WriteKeyWord("TTL_JOB_INTERVAL") + restoreCtx.WritePlain("=") + restoreCtx.WriteString(tableInfo.TTLInfo.JobInterval) + return nil + }) + + if err != nil { + return err + } + } return nil } @@ -1349,52 +1412,6 @@ func fetchShowCreateTable4View(ctx sessionctx.Context, tb *model.TableInfo, buf fmt.Fprintf(buf, ") AS %s", tb.View.SelectStmt) } -func appendPartitionInfo(partitionInfo *model.PartitionInfo, buf *bytes.Buffer, sqlMode mysql.SQLMode) { - if partitionInfo == nil { - return - } - // Since MySQL 5.1/5.5 is very old and TiDB aims for 5.7/8.0 compatibility, we will not - // include the /*!50100 or /*!50500 comments for TiDB. - // This also solves the issue with comments within comments that would happen for - // PLACEMENT POLICY options. - if partitionInfo.Type == model.PartitionTypeHash { - defaultPartitionDefinitions := true - for i, def := range partitionInfo.Definitions { - if def.Name.O != fmt.Sprintf("p%d", i) { - defaultPartitionDefinitions = false - break - } - if len(def.Comment) > 0 || def.PlacementPolicyRef != nil { - defaultPartitionDefinitions = false - break - } - } - - if defaultPartitionDefinitions { - fmt.Fprintf(buf, "\nPARTITION BY HASH (%s) PARTITIONS %d", partitionInfo.Expr, partitionInfo.Num) - return - } - } - // this if statement takes care of lists/range columns case - if len(partitionInfo.Columns) > 0 { - // partitionInfo.Type == model.PartitionTypeRange || partitionInfo.Type == model.PartitionTypeList - // Notice that MySQL uses two spaces between LIST and COLUMNS... - fmt.Fprintf(buf, "\nPARTITION BY %s COLUMNS(", partitionInfo.Type.String()) - for i, col := range partitionInfo.Columns { - buf.WriteString(stringutil.Escape(col.O, sqlMode)) - if i < len(partitionInfo.Columns)-1 { - buf.WriteString(",") - } - } - buf.WriteString(")\n(") - } else { - fmt.Fprintf(buf, "\nPARTITION BY %s (%s)\n(", partitionInfo.Type.String(), partitionInfo.Expr) - } - - ddl.AppendPartitionDefs(partitionInfo, buf, sqlMode) - buf.WriteString(")") -} - // ConstructResultOfShowCreateDatabase constructs the result for show create database. func ConstructResultOfShowCreateDatabase(ctx sessionctx.Context, dbInfo *model.DBInfo, ifNotExists bool, buf *bytes.Buffer) (err error) { sqlMode := ctx.GetSessionVars().SQLMode @@ -1438,6 +1455,11 @@ func ConstructResultOfShowCreatePlacementPolicy(policyInfo *model.PolicyInfo) st return fmt.Sprintf("CREATE PLACEMENT POLICY `%s` %s", policyInfo.Name.O, policyInfo.PlacementSettings.String()) } +// constructResultOfShowCreateResourceGroup constructs the result for show create resource group. +func constructResultOfShowCreateResourceGroup(resourceGroup *model.ResourceGroupInfo) string { + return fmt.Sprintf("CREATE RESOURCE GROUP `%s` %s", resourceGroup.Name.O, resourceGroup.ResourceGroupSettings.String()) +} + // fetchShowCreateDatabase composes show create database result. func (e *ShowExec) fetchShowCreateDatabase() error { checker := privilege.GetPrivilegeManager(e.ctx) @@ -1471,6 +1493,17 @@ func (e *ShowExec) fetchShowCreatePlacementPolicy() error { return nil } +// fetchShowCreateResourceGroup composes show create resource group result. +func (e *ShowExec) fetchShowCreateResourceGroup() error { + group, found := e.is.ResourceGroupByName(e.ResourceGroupName) + if !found { + return infoschema.ErrResourceGroupNotExists.GenWithStackByArgs(e.ResourceGroupName.O) + } + showCreate := constructResultOfShowCreateResourceGroup(group) + e.appendRow([]interface{}{e.ResourceGroupName.O, showCreate}) + return nil +} + func (e *ShowExec) fetchShowCollation() error { var ( fieldPatternsLike collate.WildcardPattern @@ -1504,7 +1537,7 @@ func (e *ShowExec) fetchShowCollation() error { return nil } -// fetchShowCreateUser composes show create create user result. +// fetchShowCreateUser composes 'show create user' result. func (e *ShowExec) fetchShowCreateUser(ctx context.Context) error { checker := privilege.GetPrivilegeManager(e.ctx) if checker == nil { @@ -1528,7 +1561,13 @@ func (e *ShowExec) fetchShowCreateUser(ctx context.Context) error { exec := e.ctx.(sqlexec.RestrictedSQLExecutor) - rows, _, err := exec.ExecRestrictedSQL(ctx, nil, `SELECT plugin, Account_locked FROM %n.%n WHERE User=%? AND Host=%?`, mysql.SystemDB, mysql.UserTable, userName, strings.ToLower(hostName)) + rows, _, err := exec.ExecRestrictedSQL(ctx, nil, + `SELECT plugin, Account_locked, user_attributes->>'$.metadata', Token_issuer, + Password_reuse_history, Password_reuse_time, Password_expired, Password_lifetime, + user_attributes->>'$.Password_locking.failed_login_attempts', + user_attributes->>'$.Password_locking.password_lock_time_days' + FROM %n.%n WHERE User=%? AND Host=%?`, + mysql.SystemDB, mysql.UserTable, userName, strings.ToLower(hostName)) if err != nil { return errors.Trace(err) } @@ -1550,6 +1589,57 @@ func (e *ShowExec) fetchShowCreateUser(ctx context.Context) error { accountLocked = "UNLOCK" } + userAttributes := rows[0].GetString(2) + if len(userAttributes) > 0 { + userAttributes = fmt.Sprintf(" ATTRIBUTE '%s'", userAttributes) + } + + tokenIssuer := rows[0].GetString(3) + if len(tokenIssuer) > 0 { + tokenIssuer = " token_issuer " + tokenIssuer + } + + var passwordHistory string + if rows[0].IsNull(4) { + passwordHistory = "DEFAULT" + } else { + passwordHistory = strconv.FormatUint(rows[0].GetUint64(4), 10) + } + + var passwordReuseInterval string + if rows[0].IsNull(5) { + passwordReuseInterval = "DEFAULT" + } else { + passwordReuseInterval = strconv.FormatUint(rows[0].GetUint64(5), 10) + " DAY" + } + + passwordExpired := rows[0].GetEnum(6).String() + passwordLifetime := int64(-1) + if !rows[0].IsNull(7) { + passwordLifetime = rows[0].GetInt64(7) + } + passwordExpiredStr := "PASSWORD EXPIRE DEFAULT" + if passwordExpired == "Y" { + passwordExpiredStr = "PASSWORD EXPIRE" + } else if passwordLifetime == 0 { + passwordExpiredStr = "PASSWORD EXPIRE NEVER" + } else if passwordLifetime > 0 { + passwordExpiredStr = fmt.Sprintf("PASSWORD EXPIRE INTERVAL %d DAY", passwordLifetime) + } + + failedLoginAttempts := rows[0].GetString(8) + if len(failedLoginAttempts) > 0 { + failedLoginAttempts = " FAILED_LOGIN_ATTEMPTS " + failedLoginAttempts + } + + passwordLockTimeDays := rows[0].GetString(9) + if len(passwordLockTimeDays) > 0 { + if passwordLockTimeDays == "-1" { + passwordLockTimeDays = " PASSWORD_LOCK_TIME UNBOUNDED" + } else { + passwordLockTimeDays = " PASSWORD_LOCK_TIME " + passwordLockTimeDays + } + } rows, _, err = exec.ExecRestrictedSQL(ctx, nil, `SELECT Priv FROM %n.%n WHERE User=%? AND Host=%?`, mysql.SystemDB, mysql.GlobalPrivTable, userName, hostName) if err != nil { return errors.Trace(err) @@ -1573,8 +1663,8 @@ func (e *ShowExec) fetchShowCreateUser(ctx context.Context) error { } // FIXME: the returned string is not escaped safely - showStr := fmt.Sprintf("CREATE USER '%s'@'%s' IDENTIFIED WITH '%s'%s REQUIRE %s PASSWORD EXPIRE DEFAULT ACCOUNT %s", - e.User.Username, e.User.Hostname, authplugin, authStr, require, accountLocked) + showStr := fmt.Sprintf("CREATE USER '%s'@'%s' IDENTIFIED WITH '%s'%s REQUIRE %s%s %s ACCOUNT %s PASSWORD HISTORY %s PASSWORD REUSE INTERVAL %s%s%s%s", + e.User.Username, e.User.Hostname, authplugin, authStr, require, tokenIssuer, passwordExpiredStr, accountLocked, passwordHistory, passwordReuseInterval, failedLoginAttempts, passwordLockTimeDays, userAttributes) e.appendRow([]interface{}{showStr}) return nil } @@ -1625,13 +1715,16 @@ func (e *ShowExec) fetchShowGrants() error { func (e *ShowExec) fetchShowPrivileges() error { e.appendRow([]interface{}{"Alter", "Tables", "To alter the table"}) e.appendRow([]interface{}{"Alter routine", "Functions,Procedures", "To alter or drop stored functions/procedures"}) + e.appendRow([]interface{}{"Config", "Server Admin", "To use SHOW CONFIG and SET CONFIG statements"}) e.appendRow([]interface{}{"Create", "Databases,Tables,Indexes", "To create new databases and tables"}) e.appendRow([]interface{}{"Create routine", "Databases", "To use CREATE FUNCTION/PROCEDURE"}) + e.appendRow([]interface{}{"Create role", "Server Admin", "To create new roles"}) e.appendRow([]interface{}{"Create temporary tables", "Databases", "To use CREATE TEMPORARY TABLE"}) e.appendRow([]interface{}{"Create view", "Tables", "To create new views"}) e.appendRow([]interface{}{"Create user", "Server Admin", "To create new users"}) e.appendRow([]interface{}{"Delete", "Tables", "To delete existing rows"}) e.appendRow([]interface{}{"Drop", "Databases,Tables", "To drop databases, tables, and views"}) + e.appendRow([]interface{}{"Drop role", "Server Admin", "To drop roles"}) e.appendRow([]interface{}{"Event", "Server Admin", "To create, alter, drop and execute events"}) e.appendRow([]interface{}{"Execute", "Functions,Procedures", "To execute stored routines"}) e.appendRow([]interface{}{"File", "File access on server", "To read and write files on the server"}) @@ -2016,10 +2109,8 @@ func (e *ShowExec) fetchShowSessionStates(ctx context.Context) error { var token *sessionstates.SessionToken // In testing, user may be nil. if user := e.ctx.GetSessionVars().User; user != nil { - // The token may be leaked without secure transport, so we enforce secure transport (TLS or Unix Socket). - if !e.ctx.GetSessionVars().ConnectionInfo.IsSecureTransport() { - return sessionstates.ErrCannotMigrateSession.GenWithStackByArgs("the token must be queried with secure transport") - } + // The token may be leaked without secure transport, but the cloud can ensure security in some situations, + // so we don't enforce secure connections. if token, err = sessionstates.CreateSessionToken(user.Username); err != nil { return err } @@ -2051,7 +2142,7 @@ func tryFillViewColumnType(ctx context.Context, sctx sessionctx.Context, is info // Retrieve view columns info. planBuilder, _ := plannercore.NewPlanBuilder( plannercore.PlanBuilderOptNoExecution{}).Init(s, is, &hint.BlockHintProcessor{}) - if viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, dbName, tbl); err == nil { + if viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, dbName, tbl, nil, nil); err == nil { viewSchema := viewLogicalPlan.Schema() viewOutputNames := viewLogicalPlan.OutputNames() for _, col := range tbl.Columns { diff --git a/executor/show_stats.go b/executor/show_stats.go index 058b3ed7c62da..6161a173e8fe4 100644 --- a/executor/show_stats.go +++ b/executor/show_stats.go @@ -143,6 +143,49 @@ func (e *ShowExec) appendTableForStatsMeta(dbName, tblName, partitionName string }) } +func (e *ShowExec) appendTableForStatsLocked(dbName, tblName, partitionName string) { + e.appendRow([]interface{}{ + dbName, + tblName, + partitionName, + "locked", + }) +} + +func (e *ShowExec) fetchShowStatsLocked() error { + do := domain.GetDomain(e.ctx) + h := do.StatsHandle() + dbs := do.InfoSchema().AllSchemas() + for _, db := range dbs { + for _, tbl := range db.Tables { + pi := tbl.GetPartitionInfo() + if pi == nil || e.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { + partitionName := "" + if pi != nil { + partitionName = "global" + } + if h.IsTableLocked(tbl.ID) { + e.appendTableForStatsLocked(db.Name.O, tbl.Name.O, partitionName) + } + if pi != nil { + for _, def := range pi.Definitions { + if h.IsTableLocked(def.ID) { + e.appendTableForStatsLocked(db.Name.O, tbl.Name.O, def.Name.O) + } + } + } + } else { + for _, def := range pi.Definitions { + if h.IsTableLocked(def.ID) { + e.appendTableForStatsLocked(db.Name.O, tbl.Name.O, def.Name.O) + } + } + } + } + } + return nil +} + func (e *ShowExec) fetchShowStatsHistogram() error { do := domain.GetDomain(e.ctx) h := do.StatsHandle() diff --git a/executor/show_stats_test.go b/executor/show_stats_test.go index cb8bdebcad8ac..4046c2303b429 100644 --- a/executor/show_stats_test.go +++ b/executor/show_stats_test.go @@ -44,6 +44,24 @@ func TestShowStatsMeta(t *testing.T) { require.Equal(t, "t", result.Rows()[0][1]) } +func TestShowStatsLocked(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") + tk.MustExec("create table t (a int, b int)") + tk.MustExec("create table t1 (a int, b int)") + tk.MustExec("lock stats t, t1") + result := tk.MustQuery("show stats_locked") + require.Len(t, result.Rows(), 2) + require.Equal(t, "t", result.Rows()[0][1]) + require.Equal(t, "t1", result.Rows()[1][1]) + result = tk.MustQuery("show stats_locked where table_name = 't'") + require.Len(t, result.Rows(), 1) + require.Equal(t, "t", result.Rows()[0][1]) +} + func TestShowStatsHistograms(t *testing.T) { store := testkit.CreateMockStore(t) @@ -397,4 +415,19 @@ func TestShowAnalyzeStatus(t *testing.T) { require.Equal(t, "", rows[1][8]) require.Equal(t, addr, rows[1][9]) require.Equal(t, "", rows[1][10]) + + tk.MustExec("delete from mysql.analyze_jobs") + tk.MustExec("create table t2 (a int, b int, primary key(a)) PARTITION BY RANGE ( a )(PARTITION p0 VALUES LESS THAN (6))") + tk.MustExec(`insert into t2 values (1, 1), (2, 2)`) + tk.MustExec("analyze table t2") + rows = tk.MustQuery("show analyze status").Rows() + require.Len(t, rows, 2) + require.Equal(t, "merge global stats for test.t2 columns", rows[0][3]) + + tk.MustExec("delete from mysql.analyze_jobs") + tk.MustExec("alter table t2 add index idx(b)") + tk.MustExec("analyze table t2 index idx") + rows = tk.MustQuery("show analyze status").Rows() + require.Len(t, rows, 2) + require.Equal(t, "merge global stats for test.t2's index idx", rows[0][3]) } diff --git a/executor/showtest/BUILD.bazel b/executor/showtest/BUILD.bazel index 807e00c8e88ec..1882c92e0627d 100644 --- a/executor/showtest/BUILD.bazel +++ b/executor/showtest/BUILD.bazel @@ -11,6 +11,7 @@ go_test( race = "on", shard_count = 45, deps = [ + "//autoid_service", "//config", "//executor", "//infoschema", diff --git a/executor/showtest/main_test.go b/executor/showtest/main_test.go index 131b0b82b1289..cc9e1f5aecbb3 100644 --- a/executor/showtest/main_test.go +++ b/executor/showtest/main_test.go @@ -35,6 +35,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), diff --git a/executor/showtest/show_test.go b/executor/showtest/show_test.go index 5b398be80deb8..6ff3db919ee9f 100644 --- a/executor/showtest/show_test.go +++ b/executor/showtest/show_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/pingcap/failpoint" + _ "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/parser/auth" @@ -142,7 +143,8 @@ func TestShowCreateTable(t *testing.T) { "`d` datetime(4) default current_timestamp(4),\n" + "`e` varchar(20) default 'cUrrent_tImestamp',\n" + "`f` datetime(2) default current_timestamp(2) on update current_timestamp(2),\n" + - "`g` timestamp(2) default current_timestamp(2) on update current_timestamp(2))") + "`g` timestamp(2) default current_timestamp(2) on update current_timestamp(2),\n" + + "`h` date default current_date )") tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|", ""+ "t CREATE TABLE `t` (\n"+ @@ -152,7 +154,8 @@ func TestShowCreateTable(t *testing.T) { " `d` datetime(4) DEFAULT CURRENT_TIMESTAMP(4),\n"+ " `e` varchar(20) DEFAULT 'cUrrent_tImestamp',\n"+ " `f` datetime(2) DEFAULT CURRENT_TIMESTAMP(2) ON UPDATE CURRENT_TIMESTAMP(2),\n"+ - " `g` timestamp(2) DEFAULT CURRENT_TIMESTAMP(2) ON UPDATE CURRENT_TIMESTAMP(2)\n"+ + " `g` timestamp(2) DEFAULT CURRENT_TIMESTAMP(2) ON UPDATE CURRENT_TIMESTAMP(2),\n"+ + " `h` date DEFAULT CURRENT_DATE\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", )) tk.MustExec("drop table t") @@ -186,7 +189,7 @@ func TestShowCreateTable(t *testing.T) { "`END_TIME` datetime NOT NULL," + "`USER_TYPE` int(11) DEFAULT NULL," + "`APP_ID` int(11) DEFAULT NULL," + - "PRIMARY KEY (`LOG_ID`,`END_TIME`)," + + "PRIMARY KEY (`LOG_ID`,`END_TIME`) NONCLUSTERED," + "KEY `IDX_EndTime` (`END_TIME`)," + "KEY `IDX_RoundId` (`ROUND_ID`)," + "KEY `IDX_UserId_EndTime` (`USER_ID`,`END_TIME`)" + @@ -317,9 +320,10 @@ func TestShowCreateTable(t *testing.T) { ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", )) - // TiDB defaults (and only supports) foreign_key_checks=0 + // set @@foreign_key_checks=0, // This means that the child table can be created before the parent table. // This behavior is required for mysqldump restores. + tk.MustExec("set @@foreign_key_checks=0") tk.MustExec(`DROP TABLE IF EXISTS parent, child`) tk.MustExec(`CREATE TABLE child (id INT NOT NULL PRIMARY KEY auto_increment, parent_id INT NOT NULL, INDEX par_ind (parent_id), CONSTRAINT child_ibfk_1 FOREIGN KEY (parent_id) REFERENCES parent(id))`) tk.MustExec(`CREATE TABLE parent ( id INT NOT NULL PRIMARY KEY auto_increment )`) @@ -357,6 +361,7 @@ func TestShowCreateTable(t *testing.T) { " `id` int(11) NOT NULL,\n" + " `b` int(11) DEFAULT NULL,\n" + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + + " KEY `fk` (`b`),\n" + " CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `test1`.`t1` (`id`)\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) @@ -775,6 +780,7 @@ func TestShowWarningsForExprPushdown(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec(`set tidb_cost_model_version=2`) testSQL := `create table if not exists show_warnings_expr_pushdown (a int, value date)` tk.MustExec(testSQL) @@ -796,10 +802,10 @@ func TestShowWarningsForExprPushdown(t *testing.T) { tk.MustExec("explain select * from show_warnings_expr_pushdown t where md5(value) = '2020-01-01'") require.Equal(t, uint16(1), tk.Session().GetSessionVars().StmtCtx.WarningCount()) tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now.")) - tk.MustExec("explain select max(md5(value)) from show_warnings_expr_pushdown group by a") + tk.MustExec("explain select /*+ read_from_storage(tiflash[show_warnings_expr_pushdown]) */ max(md5(value)) from show_warnings_expr_pushdown group by a") require.Equal(t, uint16(2), tk.Session().GetSessionVars().StmtCtx.WarningCount()) tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now.", "Warning|1105|Aggregation can not be pushed to tiflash because arguments of AggFunc `max` contains unsupported exprs")) - tk.MustExec("explain select max(a) from show_warnings_expr_pushdown group by md5(value)") + tk.MustExec("explain select /*+ read_from_storage(tiflash[show_warnings_expr_pushdown]) */ max(a) from show_warnings_expr_pushdown group by md5(value)") require.Equal(t, uint16(2), tk.Session().GetSessionVars().StmtCtx.WarningCount()) tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now.", "Warning|1105|Aggregation can not be pushed to tiflash because groupByItems contain unsupported exprs")) tk.MustExec("set tidb_opt_distinct_agg_push_down=0") @@ -962,6 +968,8 @@ func TestShow2(t *testing.T) { c_timestamp_default timestamp default current_timestamp, c_timestamp_default_3 timestamp(3) default current_timestamp(3), c_timestamp_default_4 timestamp(3) default current_timestamp(3) on update current_timestamp(3), + c_date_default date default current_date, + c_date_default_2 date default (curdate()), c_blob blob, c_tinyblob tinyblob, c_mediumblob mediumblob, @@ -998,6 +1006,8 @@ func TestShow2(t *testing.T) { "[c_timestamp_default timestamp YES CURRENT_TIMESTAMP select,insert,update,references ]\n" + "[c_timestamp_default_3 timestamp(3) YES CURRENT_TIMESTAMP(3) select,insert,update,references ]\n" + "[c_timestamp_default_4 timestamp(3) YES CURRENT_TIMESTAMP(3) DEFAULT_GENERATED on update CURRENT_TIMESTAMP(3) select,insert,update,references ]\n" + + "[c_date_default date YES CURRENT_DATE select,insert,update,references ]\n" + + "[c_date_default_2 date YES CURRENT_DATE select,insert,update,references ]\n" + "[c_blob blob YES select,insert,update,references ]\n" + "[c_tinyblob tinyblob YES select,insert,update,references ]\n" + "[c_mediumblob mediumblob YES select,insert,update,references ]\n" + @@ -1056,11 +1066,11 @@ func TestShowCreateUser(t *testing.T) { // Create a new user. tk.MustExec(`CREATE USER 'test_show_create_user'@'%' IDENTIFIED BY 'root';`) tk.MustQuery("show create user 'test_show_create_user'@'%'"). - Check(testkit.Rows(`CREATE USER 'test_show_create_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK`)) + Check(testkit.Rows(`CREATE USER 'test_show_create_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`)) tk.MustExec(`CREATE USER 'test_show_create_user'@'localhost' IDENTIFIED BY 'test';`) tk.MustQuery("show create user 'test_show_create_user'@'localhost';"). - Check(testkit.Rows(`CREATE USER 'test_show_create_user'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK`)) + Check(testkit.Rows(`CREATE USER 'test_show_create_user'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`)) // Case: the user exists but the host portion doesn't match err := tk.QueryToErr("show create user 'test_show_create_user'@'asdf';") @@ -1072,10 +1082,10 @@ func TestShowCreateUser(t *testing.T) { tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "127.0.0.1", AuthUsername: "root", AuthHostname: "%"}, nil, nil) tk.MustQuery("show create user current_user"). - Check(testkit.Rows("CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK")) + Check(testkit.Rows("CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT")) tk.MustQuery("show create user current_user()"). - Check(testkit.Rows("CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK")) + Check(testkit.Rows("CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT")) tk.MustExec("create user 'check_priv'") @@ -1088,9 +1098,9 @@ func TestShowCreateUser(t *testing.T) { // "show create user" for current user doesn't check privileges. tk1.MustQuery("show create user current_user"). - Check(testkit.Rows("CREATE USER 'check_priv'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK")) + Check(testkit.Rows("CREATE USER 'check_priv'@'127.0.0.1' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT")) - // Creating users with `IDENTIFIED WITH 'caching_sha2_password'` + // Creating users with `IDENTIFIED WITH 'caching_sha2_password'`. tk.MustExec("CREATE USER 'sha_test'@'%' IDENTIFIED WITH 'caching_sha2_password' BY 'temp_passwd'") // Compare only the start of the output as the salt changes every time. @@ -1101,17 +1111,57 @@ func TestShowCreateUser(t *testing.T) { // Compare only the start of the output as the salt changes every time. rows = tk.MustQuery("SHOW CREATE USER 'sock'@'%'") - require.Equal(t, "CREATE USER 'sock'@'%' IDENTIFIED WITH 'auth_socket' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK", rows.Rows()[0][0].(string)) + require.Equal(t, "CREATE USER 'sock'@'%' IDENTIFIED WITH 'auth_socket' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT", rows.Rows()[0][0].(string)) tk.MustExec("CREATE USER 'sock2'@'%' IDENTIFIED WITH 'auth_socket' AS 'sock3'") // Compare only the start of the output as the salt changes every time. rows = tk.MustQuery("SHOW CREATE USER 'sock2'@'%'") - require.Equal(t, "CREATE USER 'sock2'@'%' IDENTIFIED WITH 'auth_socket' AS 'sock3' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK", rows.Rows()[0][0].(string)) + require.Equal(t, "CREATE USER 'sock2'@'%' IDENTIFIED WITH 'auth_socket' AS 'sock3' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT", rows.Rows()[0][0].(string)) - // Test ACCOUNT LOCK/UNLOCK + // Test ACCOUNT LOCK/UNLOCK. tk.MustExec("CREATE USER 'lockness'@'%' IDENTIFIED BY 'monster' ACCOUNT LOCK") rows = tk.MustQuery("SHOW CREATE USER 'lockness'@'%'") - require.Equal(t, "CREATE USER 'lockness'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*BC05309E7FE12AFD4EBB9FFE7E488A6320F12FF3' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT LOCK", rows.Rows()[0][0].(string)) + require.Equal(t, "CREATE USER 'lockness'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*BC05309E7FE12AFD4EBB9FFE7E488A6320F12FF3' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT LOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT", rows.Rows()[0][0].(string)) + + // Test COMMENT and ATTRIBUTE. + tk.MustExec("CREATE USER commentUser COMMENT '1234'") + tk.MustQuery("SHOW CREATE USER commentUser").Check(testkit.Rows(`CREATE USER 'commentUser'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT ATTRIBUTE '{"comment": "1234"}'`)) + tk.MustExec(`CREATE USER attributeUser attribute '{"name": "Tom", "age": 19}'`) + tk.MustQuery("SHOW CREATE USER attributeUser").Check(testkit.Rows(`CREATE USER 'attributeUser'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT ATTRIBUTE '{"age": 19, "name": "Tom"}'`)) + + // Creating users with IDENTIFIED WITH 'tidb_auth_token'. + tk.MustExec(`CREATE USER 'token_user'@'%' IDENTIFIED WITH 'tidb_auth_token' ATTRIBUTE '{"email": "user@pingcap.com"}'`) + tk.MustQuery("SHOW CREATE USER token_user").Check(testkit.Rows(`CREATE USER 'token_user'@'%' IDENTIFIED WITH 'tidb_auth_token' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT ATTRIBUTE '{"email": "user@pingcap.com"}'`)) + tk.MustExec(`ALTER USER 'token_user'@'%' REQUIRE token_issuer 'issuer-ABC'`) + tk.MustQuery("SHOW CREATE USER token_user").Check(testkit.Rows(`CREATE USER 'token_user'@'%' IDENTIFIED WITH 'tidb_auth_token' AS '' REQUIRE NONE token_issuer issuer-ABC PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT ATTRIBUTE '{"email": "user@pingcap.com"}'`)) + + // create users with password reuse. + tk.MustExec(`CREATE USER 'reuse_user'@'%' IDENTIFIED WITH 'tidb_auth_token' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 3 DAY`) + tk.MustQuery("SHOW CREATE USER reuse_user").Check(testkit.Rows(`CREATE USER 'reuse_user'@'%' IDENTIFIED WITH 'tidb_auth_token' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 3 DAY`)) + tk.MustExec(`ALTER USER 'reuse_user'@'%' PASSWORD HISTORY 50`) + tk.MustQuery("SHOW CREATE USER reuse_user").Check(testkit.Rows(`CREATE USER 'reuse_user'@'%' IDENTIFIED WITH 'tidb_auth_token' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 50 PASSWORD REUSE INTERVAL 3 DAY`)) + tk.MustExec(`ALTER USER 'reuse_user'@'%' PASSWORD REUSE INTERVAL 31 DAY`) + tk.MustQuery("SHOW CREATE USER reuse_user").Check(testkit.Rows(`CREATE USER 'reuse_user'@'%' IDENTIFIED WITH 'tidb_auth_token' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 50 PASSWORD REUSE INTERVAL 31 DAY`)) + + tk.MustExec("CREATE USER 'jeffrey1'@'localhost' PASSWORD EXPIRE") + tk.MustQuery("SHOW CREATE USER 'jeffrey1'@'localhost'").Check(testkit.Rows(`CREATE USER 'jeffrey1'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`)) + tk.MustExec("CREATE USER 'jeffrey2'@'localhost' PASSWORD EXPIRE DEFAULT") + tk.MustQuery("SHOW CREATE USER 'jeffrey2'@'localhost'").Check(testkit.Rows(`CREATE USER 'jeffrey2'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`)) + tk.MustExec("CREATE USER 'jeffrey3'@'localhost' PASSWORD EXPIRE NEVER") + tk.MustQuery("SHOW CREATE USER 'jeffrey3'@'localhost'").Check(testkit.Rows(`CREATE USER 'jeffrey3'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE NEVER ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`)) + tk.MustExec("CREATE USER 'jeffrey4'@'localhost' PASSWORD EXPIRE INTERVAL 180 DAY") + tk.MustQuery("SHOW CREATE USER 'jeffrey4'@'localhost'").Check(testkit.Rows(`CREATE USER 'jeffrey4'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE INTERVAL 180 DAY ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`)) + + tk.MustExec("CREATE USER failed_login_user") + tk.MustQuery("SHOW CREATE USER failed_login_user").Check(testkit.Rows(`CREATE USER 'failed_login_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`)) + tk.MustExec("ALTER USER failed_login_user FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 2") + tk.MustQuery("SHOW CREATE USER failed_login_user").Check(testkit.Rows(`CREATE USER 'failed_login_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 2`)) + tk.MustExec("ALTER USER failed_login_user PASSWORD_LOCK_TIME UNBOUNDED") + tk.MustQuery("SHOW CREATE USER failed_login_user").Check(testkit.Rows(`CREATE USER 'failed_login_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME UNBOUNDED`)) + tk.MustExec("ALTER USER failed_login_user comment 'testcomment'") + tk.MustQuery("SHOW CREATE USER failed_login_user").Check(testkit.Rows(`CREATE USER 'failed_login_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME UNBOUNDED ATTRIBUTE '{"comment": "testcomment"}'`)) + tk.MustExec("ALTER USER failed_login_user ATTRIBUTE '{\"attribute\": \"testattribute\"}'") + tk.MustQuery("SHOW CREATE USER failed_login_user").Check(testkit.Rows(`CREATE USER 'failed_login_user'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME UNBOUNDED ATTRIBUTE '{"attribute": "testattribute", "comment": "testcomment"}'`)) } func TestUnprivilegedShow(t *testing.T) { @@ -1472,7 +1522,7 @@ func TestShowBuiltin(t *testing.T) { res := tk.MustQuery("show builtins;") require.NotNil(t, res) rows := res.Rows() - const builtinFuncNum = 282 + const builtinFuncNum = 285 require.Equal(t, builtinFuncNum, len(rows)) require.Equal(t, rows[0][0].(string), "abs") require.Equal(t, rows[builtinFuncNum-1][0].(string), "yearweek") @@ -1976,3 +2026,55 @@ func TestShowLimitReturnRow(t *testing.T) { rows = result.Rows() require.Equal(t, rows[0][2], "idx_b") } + +func TestShowTTLOption(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(created_at datetime) ttl = `created_at` + INTERVAL 100 YEAR") + tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL 100 YEAR */ /*T![ttl] TTL_ENABLE='ON' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(created_at datetime) ttl = `created_at` + INTERVAL 100 YEAR ttl_enable = 'OFF'") + tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL 100 YEAR */ /*T![ttl] TTL_ENABLE='OFF' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (created_at datetime) TTL = created_at + INTERVAL 3.14159 HOUR_MINUTE") + tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL 3.14159 HOUR_MINUTE */ /*T![ttl] TTL_ENABLE='ON' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (created_at datetime) TTL = created_at + INTERVAL \"15:20\" HOUR_MINUTE") + tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL _utf8mb4'15:20' HOUR_MINUTE */ /*T![ttl] TTL_ENABLE='ON' */ /*T![ttl] TTL_JOB_INTERVAL='1h' */")) + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (created_at datetime) TTL = created_at + INTERVAL 100 YEAR TTL_JOB_INTERVAL = '1d'") + tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n `created_at` datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![ttl] TTL=`created_at` + INTERVAL 100 YEAR */ /*T![ttl] TTL_ENABLE='ON' */ /*T![ttl] TTL_JOB_INTERVAL='1d' */")) +} + +func TestShowBindingDigestField(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1(id int, key(id))") + tk.MustExec("create table t2(id int, key(id))") + tk.MustExec("create binding for select * from t1, t2 where t1.id = t2.id using select /*+ merge_join(t1, t2)*/ * from t1, t2 where t1.id = t2.id") + result := tk.MustQuery("show bindings;") + rows := result.Rows()[0] + require.Equal(t, len(rows), 11) + require.Equal(t, rows[9], "ac1ceb4eb5c01f7c03e29b7d0d6ab567e563f4c93164184cde218f20d07fd77c") + tk.MustExec("drop binding for select * from t1, t2 where t1.id = t2.id") + result = tk.MustQuery("show bindings;") + require.Equal(t, len(result.Rows()), 0) + + tk.MustExec("create global binding for select * from t1, t2 where t1.id = t2.id using select /*+ merge_join(t1, t2)*/ * from t1, t2 where t1.id = t2.id") + result = tk.MustQuery("show global bindings;") + rows = result.Rows()[0] + require.Equal(t, len(rows), 11) + require.Equal(t, rows[9], "ac1ceb4eb5c01f7c03e29b7d0d6ab567e563f4c93164184cde218f20d07fd77c") + tk.MustExec("drop global binding for select * from t1, t2 where t1.id = t2.id") + result = tk.MustQuery("show global bindings;") + require.Equal(t, len(result.Rows()), 0) +} diff --git a/executor/shuffle.go b/executor/shuffle.go index 2827d0e1cece7..7596d2cef1970 100644 --- a/executor/shuffle.go +++ b/executor/shuffle.go @@ -262,7 +262,7 @@ func (e *ShuffleExec) fetchDataAndSplit(ctx context.Context, dataSourceIndex int workerIndices []int ) results := make([]*chunk.Chunk, len(e.workers)) - chk := newFirstChunk(e.dataSources[dataSourceIndex]) + chk := tryNewCacheChunk(e.dataSources[dataSourceIndex]) defer func() { if r := recover(); r != nil { diff --git a/executor/simple.go b/executor/simple.go index 33fd448fb0ae8..2beab893bb5f9 100644 --- a/executor/simple.go +++ b/executor/simple.go @@ -19,7 +19,9 @@ import ( "context" "encoding/json" "fmt" + "math" "os" + "strconv" "strings" "syscall" "time" @@ -51,15 +53,18 @@ import ( "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mathutil" + pwdValidator "github.com/pingcap/tidb/util/password-validation" "github.com/pingcap/tidb/util/sem" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/timeutil" "github.com/pingcap/tidb/util/tls" "github.com/pingcap/tipb/go-tipb" - tikvutil "github.com/tikv/client-go/v2/util" "go.uber.org/zap" ) +const notSpecified = -1 + var ( transactionDurationPessimisticRollback = metrics.TransactionDuration.WithLabelValues(metrics.LblPessimistic, metrics.LblRollback) transactionDurationOptimisticRollback = metrics.TransactionDuration.WithLabelValues(metrics.LblOptimistic, metrics.LblRollback) @@ -85,6 +90,33 @@ type SimpleExec struct { staleTxnStartTS uint64 } +type passwordOrLockOptionsInfo struct { + lockAccount string + passwordExpired string + passwordLifetime any + passwordHistory int64 + passwordHistoryChange bool + passwordReuseInterval int64 + passwordReuseIntervalChange bool + failedLoginAttempts int64 + passwordLockTime int64 + failedLoginAttemptsChange bool + passwordLockTimeChange bool +} + +type passwordReuseInfo struct { + passwordHistory int64 + passwordReuseInterval int64 +} + +type userInfo struct { + host string + user string + pLI *passwordOrLockOptionsInfo + pwd string + authString string +} + func (e *baseExecutor) getSysSession() (sessionctx.Context, error) { dom := domain.GetDomain(e.ctx) sysSessionPool := dom.SysSessionPool() @@ -110,6 +142,16 @@ func (e *baseExecutor) releaseSysSession(ctx context.Context, sctx sessionctx.Co sysSessionPool.Put(sctx.(pools.Resource)) } +// clearSysSession close the session does not return the session. +// Since the environment variables in the session are changed, the session object is not returned. +func clearSysSession(ctx context.Context, sctx sessionctx.Context) { + if sctx == nil { + return + } + _, _ = sctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, "rollback") + sctx.(pools.Resource).Close() +} + // Next implements the Executor Next interface. func (e *SimpleExec) Next(ctx context.Context, req *chunk.Chunk) (err error) { if e.done { @@ -783,6 +825,215 @@ func (e *SimpleExec) executeRollback(s *ast.RollbackStmt) error { return nil } +func whetherSavePasswordHistory(plOptions *passwordOrLockOptionsInfo) bool { + var passwdSaveNum, passwdSaveTime int64 + // If the user specifies a default, read the global variable. + if plOptions.passwordHistoryChange && plOptions.passwordHistory != notSpecified { + passwdSaveNum = plOptions.passwordHistory + } else { + passwdSaveNum = variable.PasswordHistory.Load() + } + if plOptions.passwordReuseIntervalChange && plOptions.passwordReuseInterval != notSpecified { + passwdSaveTime = plOptions.passwordReuseInterval + } else { + passwdSaveTime = variable.PasswordReuseInterval.Load() + } + return passwdSaveTime > 0 || passwdSaveNum > 0 +} + +type alterUserPasswordLocking struct { + failedLoginAttempts int64 + passwordLockTime int64 + failedLoginAttemptsNotFound bool + passwordLockTimeChangeNotFound bool + // containsNoOthers indicates whether User_attributes only contains one "Password_locking" element. + containsNoOthers bool +} + +func (info *passwordOrLockOptionsInfo) loadOptions(plOption []*ast.PasswordOrLockOption) error { + if length := len(plOption); length > 0 { + // If "PASSWORD EXPIRE ..." appears many times, + // only the last declaration takes effect. + Loop: + for i := length - 1; i >= 0; i-- { + switch plOption[i].Type { + case ast.PasswordExpire: + info.passwordExpired = "Y" + break Loop + case ast.PasswordExpireDefault: + info.passwordLifetime = nil + break Loop + case ast.PasswordExpireNever: + info.passwordLifetime = 0 + break Loop + case ast.PasswordExpireInterval: + if plOption[i].Count == 0 || plOption[i].Count > math.MaxUint16 { + return types.ErrWrongValue2.GenWithStackByArgs("DAY", fmt.Sprintf("%v", plOption[i].Count)) + } + info.passwordLifetime = plOption[i].Count + break Loop + } + } + } + // only the last declaration takes effect. + for _, option := range plOption { + switch option.Type { + case ast.Lock: + info.lockAccount = "Y" + case ast.Unlock: + info.lockAccount = "N" + case ast.FailedLoginAttempts: + info.failedLoginAttempts = mathutil.Min(option.Count, math.MaxInt16) + info.failedLoginAttemptsChange = true + case ast.PasswordLockTime: + info.passwordLockTime = mathutil.Min(option.Count, math.MaxInt16) + info.passwordLockTimeChange = true + case ast.PasswordLockTimeUnbounded: + info.passwordLockTime = -1 + info.passwordLockTimeChange = true + case ast.PasswordHistory: + info.passwordHistory = mathutil.Min(option.Count, math.MaxUint16) + info.passwordHistoryChange = true + case ast.PasswordHistoryDefault: + info.passwordHistory = notSpecified + info.passwordHistoryChange = true + case ast.PasswordReuseInterval: + info.passwordReuseInterval = mathutil.Min(option.Count, math.MaxUint16) + info.passwordReuseIntervalChange = true + case ast.PasswordReuseDefault: + info.passwordReuseInterval = notSpecified + info.passwordReuseIntervalChange = true + } + } + return nil +} + +func createUserFailedLoginJSON(info *passwordOrLockOptionsInfo) string { + // Record only when either failedLoginAttempts and passwordLockTime is not 0 + if (info.failedLoginAttemptsChange && info.failedLoginAttempts != 0) || (info.passwordLockTimeChange && info.passwordLockTime != 0) { + return fmt.Sprintf("\"Password_locking\": {\"failed_login_attempts\": %d,\"password_lock_time_days\": %d}", + info.failedLoginAttempts, info.passwordLockTime) + } + return "" +} + +func alterUserFailedLoginJSON(info *alterUserPasswordLocking, lockAccount string) string { + // alterUserPasswordLocking is the user's actual configuration. + var passwordLockingArray []string + if info.failedLoginAttempts != 0 || info.passwordLockTime != 0 { + if lockAccount == "N" { + passwordLockingArray = append(passwordLockingArray, + fmt.Sprintf("\"auto_account_locked\": \"%s\"", lockAccount), + fmt.Sprintf("\"auto_locked_last_changed\": \"%s\"", time.Now().Format(time.UnixDate)), + fmt.Sprintf("\"failed_login_count\": %d", 0)) + } + passwordLockingArray = append(passwordLockingArray, + fmt.Sprintf("\"failed_login_attempts\": %d", info.failedLoginAttempts), + fmt.Sprintf("\"password_lock_time_days\": %d", info.passwordLockTime)) + } + if len(passwordLockingArray) > 0 { + return fmt.Sprintf("\"Password_locking\": {%s}", strings.Join(passwordLockingArray, ",")) + } + return "" +} + +func readPasswordLockingInfo(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, name string, host string, pLO *passwordOrLockOptionsInfo) (aUPL *alterUserPasswordLocking, err error) { + alterUserInfo := &alterUserPasswordLocking{ + failedLoginAttempts: 0, + passwordLockTime: 0, + failedLoginAttemptsNotFound: false, + passwordLockTimeChangeNotFound: false, + containsNoOthers: false, + } + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `SELECT JSON_UNQUOTE(JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_attempts')), + JSON_UNQUOTE(JSON_EXTRACT(user_attributes, '$.Password_locking.password_lock_time_days')), + JSON_LENGTH(JSON_REMOVE(user_attributes, '$.Password_locking')) FROM %n.%n WHERE User=%? AND Host=%?;`, + mysql.SystemDB, mysql.UserTable, name, strings.ToLower(host)) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return nil, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, 3) + if err != nil { + return nil, err + } + + // Configuration priority is User Changes > User History + if pLO.failedLoginAttemptsChange { + alterUserInfo.failedLoginAttempts = pLO.failedLoginAttempts + } else if !rows[0].IsNull(0) { + str := rows[0].GetString(0) + alterUserInfo.failedLoginAttempts, err = strconv.ParseInt(str, 10, 64) + if err != nil { + return nil, err + } + alterUserInfo.failedLoginAttempts = mathutil.Max(alterUserInfo.failedLoginAttempts, 0) + alterUserInfo.failedLoginAttempts = mathutil.Min(alterUserInfo.failedLoginAttempts, math.MaxInt16) + } else { + alterUserInfo.failedLoginAttemptsNotFound = true + } + + if pLO.passwordLockTimeChange { + alterUserInfo.passwordLockTime = pLO.passwordLockTime + } else if !rows[0].IsNull(1) { + str := rows[0].GetString(1) + alterUserInfo.passwordLockTime, err = strconv.ParseInt(str, 10, 64) + if err != nil { + return nil, err + } + alterUserInfo.passwordLockTime = mathutil.Max(alterUserInfo.passwordLockTime, -1) + alterUserInfo.passwordLockTime = mathutil.Min(alterUserInfo.passwordLockTime, math.MaxInt16) + } else { + alterUserInfo.passwordLockTimeChangeNotFound = true + } + + alterUserInfo.containsNoOthers = rows[0].IsNull(2) || rows[0].GetInt64(2) == 0 + return alterUserInfo, nil +} + +// deletePasswordLockingAttribute deletes "$.Password_locking" in "User_attributes" when failedLoginAttempts and passwordLockTime both 0. +func deletePasswordLockingAttribute(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, name string, host string, alterUser *alterUserPasswordLocking) error { + // No password_locking information. + if alterUser.failedLoginAttemptsNotFound && alterUser.passwordLockTimeChangeNotFound { + return nil + } + // Password_locking information is still in used. + if alterUser.failedLoginAttempts != 0 || alterUser.passwordLockTime != 0 { + return nil + } + sql := new(strings.Builder) + if alterUser.containsNoOthers { + // If we use JSON_REMOVE(user_attributes, '$.Password_locking') directly here, the result is not compatible with MySQL. + sqlexec.MustFormatSQL(sql, `UPDATE %n.%n SET user_attributes=NULL`, mysql.SystemDB, mysql.UserTable) + } else { + sqlexec.MustFormatSQL(sql, `UPDATE %n.%n SET user_attributes=JSON_REMOVE(user_attributes, '$.Password_locking') `, mysql.SystemDB, mysql.UserTable) + } + sqlexec.MustFormatSQL(sql, " WHERE Host=%? and User=%?;", host, name) + _, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + return err +} + +func (e *SimpleExec) authUsingCleartextPwd(authOpt *ast.AuthOption, authPlugin string) bool { + if authOpt == nil || !authOpt.ByAuthString { + return false + } + return mysql.IsAuthPluginClearText(authPlugin) +} + +func (e *SimpleExec) isValidatePasswordEnabled() bool { + validatePwdEnable, err := e.ctx.GetSessionVars().GlobalVarsAccessor.GetGlobalSysVar(variable.ValidatePasswordEnable) + if err != nil { + return false + } + return variable.TiDBOptOn(validatePwdEnable) +} + func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStmt) error { internalCtx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) // Check `CREATE USER` privilege. @@ -805,30 +1056,84 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm } } - privData, err := tlsOption2GlobalPriv(s.TLSOptions) + privData, err := tlsOption2GlobalPriv(s.AuthTokenOrTLSOptions) if err != nil { return err } - lockAccount := false - if len(s.PasswordOrLockOptions) > 0 { - // If "ACCOUNT LOCK" or "ACCOUNT UNLOCK" appears many times, - // the last declaration takes effect. - for i := len(s.PasswordOrLockOptions) - 1; i >= 0; i-- { - if s.PasswordOrLockOptions[i].Type == ast.Lock { - lockAccount = true - break - } else if s.PasswordOrLockOptions[i].Type == ast.Unlock { - break + plOptions := &passwordOrLockOptionsInfo{ + lockAccount: "N", + passwordExpired: "N", + passwordLifetime: nil, + passwordHistory: notSpecified, + passwordReuseInterval: notSpecified, + failedLoginAttemptsChange: false, + passwordLockTimeChange: false, + passwordHistoryChange: false, + passwordReuseIntervalChange: false, + } + err = plOptions.loadOptions(s.PasswordOrLockOptions) + if err != nil { + return err + } + PasswordLocking := createUserFailedLoginJSON(plOptions) + if s.IsCreateRole { + plOptions.lockAccount = "Y" + plOptions.passwordExpired = "Y" + } + + var userAttributes []string + if s.CommentOrAttributeOption != nil { + if s.CommentOrAttributeOption.Type == ast.UserCommentType { + userAttributes = append(userAttributes, fmt.Sprintf("\"metadata\": {\"comment\": \"%s\"}", s.CommentOrAttributeOption.Value)) + } else if s.CommentOrAttributeOption.Type == ast.UserAttributeType { + userAttributes = append(userAttributes, fmt.Sprintf("\"metadata\": %s", s.CommentOrAttributeOption.Value)) + } + } + resourceGroupName := "default" + if s.ResourceGroupNameOption != nil { + if !variable.EnableResourceControl.Load() { + return infoschema.ErrResourceGroupSupportDisabled + } + if s.ResourceGroupNameOption.Type == ast.UserResourceGroupName { + resourceGroupName = s.ResourceGroupNameOption.Value + } + + // check if specified resource group exists + if resourceGroupName != "default" && resourceGroupName != "" { + _, exists := e.is.ResourceGroupByName(model.NewCIStr(resourceGroupName)) + if !exists { + return infoschema.ErrResourceGroupNotExists } } } + userAttributes = append(userAttributes, fmt.Sprintf("\"resource_group\": \"%s\"", resourceGroupName)) + // If FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME are both specified to 0, a string of 0 length is generated. + // When inserting the attempts into json, an error occurs. This requires special handling. + if PasswordLocking != "" { + userAttributes = append(userAttributes, PasswordLocking) + } + userAttributesStr := fmt.Sprintf("{%s}", strings.Join(userAttributes, ",")) + + tokenIssuer := "" + for _, authTokenOption := range s.AuthTokenOrTLSOptions { + switch authTokenOption.Type { + case ast.TokenIssuer: + tokenIssuer = authTokenOption.Value + } + } sql := new(strings.Builder) - if s.IsCreateRole || lockAccount { - sqlexec.MustFormatSQL(sql, `INSERT INTO %n.%n (Host, User, authentication_string, plugin, Account_locked) VALUES `, mysql.SystemDB, mysql.UserTable) - } else { - sqlexec.MustFormatSQL(sql, `INSERT INTO %n.%n (Host, User, authentication_string, plugin) VALUES `, mysql.SystemDB, mysql.UserTable) + sqlPasswordHistory := new(strings.Builder) + passwordInit := true + // Get changed user password reuse info. + savePasswdHistory := whetherSavePasswordHistory(plOptions) + sqlTemplate := "INSERT INTO %n.%n (Host, User, authentication_string, plugin, user_attributes, Account_locked, Token_issuer, Password_expired, Password_lifetime, Password_reuse_time, Password_reuse_history) VALUES " + valueTemplate := "(%?, %?, %?, %?, %?, %?, %?, %?, %?" + + sqlexec.MustFormatSQL(sql, sqlTemplate, mysql.SystemDB, mysql.UserTable) + if savePasswdHistory { + sqlexec.MustFormatSQL(sqlPasswordHistory, `INSERT INTO %n.%n (Host, User, Password) VALUES `, mysql.SystemDB, mysql.PasswordHistoryTable) } users := make([]*auth.UserIdentity, 0, len(s.Specs)) @@ -836,6 +1141,9 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm if len(spec.User.Username) > auth.UserNameMaxLength { return ErrWrongStringLength.GenWithStackByArgs(spec.User.Username, "user name", auth.UserNameMaxLength) } + if len(spec.User.Username) == 0 && plOptions.passwordExpired == "Y" { + return ErrPasswordExpireAnonymousUser.GenWithStackByArgs() + } if len(spec.User.Hostname) > auth.HostNameMaxLength { return ErrWrongStringLength.GenWithStackByArgs(spec.User.Hostname, "host name", auth.HostNameMaxLength) } @@ -858,27 +1166,67 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm e.ctx.GetSessionVars().StmtCtx.AppendNote(err) continue } + authPlugin := mysql.AuthNativePassword + if spec.AuthOpt != nil && spec.AuthOpt.AuthPlugin != "" { + authPlugin = spec.AuthOpt.AuthPlugin + } + if e.isValidatePasswordEnabled() && !s.IsCreateRole { + if spec.AuthOpt == nil || !spec.AuthOpt.ByAuthString && spec.AuthOpt.HashString == "" { + return variable.ErrNotValidPassword.GenWithStackByArgs() + } + if e.authUsingCleartextPwd(spec.AuthOpt, authPlugin) { + if err := pwdValidator.ValidatePassword(e.ctx.GetSessionVars(), spec.AuthOpt.AuthString); err != nil { + return err + } + } + } pwd, ok := spec.EncodedPassword() if !ok { return errors.Trace(ErrPasswordFormat) } - authPlugin := mysql.AuthNativePassword - if spec.AuthOpt != nil && spec.AuthOpt.AuthPlugin != "" { - authPlugin = spec.AuthOpt.AuthPlugin - } switch authPlugin { - case mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password, mysql.AuthSocket: + case mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password, mysql.AuthSocket, mysql.AuthTiDBAuthToken: default: return ErrPluginIsNotLoaded.GenWithStackByArgs(spec.AuthOpt.AuthPlugin) } + recordTokenIssuer := tokenIssuer + if len(recordTokenIssuer) > 0 && authPlugin != mysql.AuthTiDBAuthToken { + err := fmt.Errorf("TOKEN_ISSUER is not needed for '%s' user", authPlugin) + e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) + recordTokenIssuer = "" + } else if len(recordTokenIssuer) == 0 && authPlugin == mysql.AuthTiDBAuthToken { + err := fmt.Errorf("TOKEN_ISSUER is needed for 'tidb_auth_token' user, please use 'alter user' to declare it") + e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) + } + hostName := strings.ToLower(spec.User.Hostname) - if s.IsCreateRole || lockAccount { - sqlexec.MustFormatSQL(sql, `(%?, %?, %?, %?, %?)`, hostName, spec.User.Username, pwd, authPlugin, "Y") + sqlexec.MustFormatSQL(sql, valueTemplate, hostName, spec.User.Username, pwd, authPlugin, userAttributesStr, plOptions.lockAccount, recordTokenIssuer, plOptions.passwordExpired, plOptions.passwordLifetime) + // add Password_reuse_time value. + if plOptions.passwordReuseIntervalChange && (plOptions.passwordReuseInterval != notSpecified) { + sqlexec.MustFormatSQL(sql, `, %?`, plOptions.passwordReuseInterval) } else { - sqlexec.MustFormatSQL(sql, `(%?, %?, %?, %?)`, hostName, spec.User.Username, pwd, authPlugin) + sqlexec.MustFormatSQL(sql, `, %?`, nil) + } + // add Password_reuse_history value. + if plOptions.passwordHistoryChange && (plOptions.passwordHistory != notSpecified) { + sqlexec.MustFormatSQL(sql, `, %?`, plOptions.passwordHistory) + } else { + sqlexec.MustFormatSQL(sql, `, %?`, nil) + } + sqlexec.MustFormatSQL(sql, `)`) + // The empty password does not count in the password history and is subject to reuse at any time. + // AuthTiDBAuthToken is the token login method on the cloud, + // and the Password Reuse Policy does not take effect. + if savePasswdHistory && len(pwd) != 0 && !strings.EqualFold(authPlugin, mysql.AuthTiDBAuthToken) { + if !passwordInit { + sqlexec.MustFormatSQL(sqlPasswordHistory, ",") + } else { + passwordInit = false + } + sqlexec.MustFormatSQL(sqlPasswordHistory, `( %?, %?, %?)`, hostName, spec.User.Username, pwd) } users = append(users, spec.User) } @@ -898,11 +1246,23 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm } _, err = sqlExecutor.ExecuteInternal(internalCtx, sql.String()) if err != nil { + logutil.BgLogger().Warn("Fail to create user", zap.String("sql", sql.String())) if _, rollbackErr := sqlExecutor.ExecuteInternal(internalCtx, "rollback"); rollbackErr != nil { return rollbackErr } return err } + + if savePasswdHistory && !passwordInit { + _, err = sqlExecutor.ExecuteInternal(internalCtx, sqlPasswordHistory.String()) + if err != nil { + if _, rollbackErr := sqlExecutor.ExecuteInternal(internalCtx, "rollback"); rollbackErr != nil { + return errors.Trace(rollbackErr) + } + return errors.Trace(err) + } + } + if len(privData) != 0 { sql.Reset() sqlexec.MustFormatSQL(sql, "INSERT IGNORE INTO %n.%n (Host, User, Priv) VALUES ", mysql.SystemDB, mysql.GlobalPrivTable) @@ -926,7 +1286,377 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm return domain.GetDomain(e.ctx).NotifyUpdatePrivilege() } +func getUserPasswordLimit(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, name string, host string, plOptions *passwordOrLockOptionsInfo) (pRI *passwordReuseInfo, err error) { + res := &passwordReuseInfo{notSpecified, notSpecified} + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `SELECT Password_reuse_history,Password_reuse_time FROM %n.%n WHERE User=%? AND Host=%?;`, + mysql.SystemDB, mysql.UserTable, name, strings.ToLower(host)) + // Query the specified user password reuse rules. + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return nil, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, 3) + if err != nil { + return nil, err + } + for _, row := range rows { + if !row.IsNull(0) { + res.passwordHistory = int64(row.GetUint64(0)) + } else { + res.passwordHistory = variable.PasswordHistory.Load() + } + if !row.IsNull(1) { + res.passwordReuseInterval = int64(row.GetUint64(1)) + } else { + res.passwordReuseInterval = variable.PasswordReuseInterval.Load() + } + } + if plOptions.passwordHistoryChange { + // If the user specifies a default, the global variable needs to be re-read. + if plOptions.passwordHistory != notSpecified { + res.passwordHistory = plOptions.passwordHistory + } else { + res.passwordHistory = variable.PasswordHistory.Load() + } + } + if plOptions.passwordReuseIntervalChange { + // If the user specifies a default, the global variable needs to be re-read. + if plOptions.passwordReuseInterval != notSpecified { + res.passwordReuseInterval = plOptions.passwordReuseInterval + } else { + res.passwordReuseInterval = variable.PasswordReuseInterval.Load() + } + } + return res, nil +} + +// getValidTime get the boundary of password valid time. +func getValidTime(sctx sessionctx.Context, passwordReuse *passwordReuseInfo) string { + nowTime := time.Now().In(sctx.GetSessionVars().TimeZone) + nowTimeS := nowTime.Unix() + beforeTimeS := nowTimeS - passwordReuse.passwordReuseInterval*24*int64(time.Hour/time.Second) + if beforeTimeS < 0 { + beforeTimeS = 0 + } + return time.Unix(beforeTimeS, 0).Format("2006-01-02 15:04:05.999999999") +} + +// deleteHistoricalData delete useless password history. +// The deleted password must meet the following conditions at the same time. +// 1. Exceeded the maximum number of saves. +// 2. The password has exceeded the prohibition time. +func deleteHistoricalData(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo, maxDelRows int64, passwordReuse *passwordReuseInfo, sctx sessionctx.Context) error { + //never times out or no row need delete. + if (passwordReuse.passwordReuseInterval > math.MaxInt32) || maxDelRows == 0 { + return nil + } + sql := new(strings.Builder) + // no prohibition time. + if passwordReuse.passwordReuseInterval == 0 { + deleteTemplate := `DELETE from %n.%n WHERE User= %? AND Host= %? order by Password_timestamp ASC LIMIT ` + deleteTemplate = deleteTemplate + strconv.FormatInt(maxDelRows, 10) + sqlexec.MustFormatSQL(sql, deleteTemplate, mysql.SystemDB, mysql.PasswordHistoryTable, + userDetail.user, strings.ToLower(userDetail.host)) + _, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return err + } + } else { + beforeDate := getValidTime(sctx, passwordReuse) + // Deletion must satisfy 1. Exceed the prohibition time 2. Exceed the maximum number of saved records. + deleteTemplate := `DELETE from %n.%n WHERE User= %? AND Host= %? AND Password_timestamp < %? order by Password_timestamp ASC LIMIT ` + deleteTemplate = deleteTemplate + strconv.FormatInt(maxDelRows, 10) + sql.Reset() + sqlexec.MustFormatSQL(sql, deleteTemplate, mysql.SystemDB, mysql.PasswordHistoryTable, + userDetail.user, strings.ToLower(userDetail.host), beforeDate) + _, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return err + } + } + return nil +} + +func addHistoricalData(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo, passwordReuse *passwordReuseInfo) error { + if passwordReuse.passwordHistory <= 0 && passwordReuse.passwordReuseInterval <= 0 { + return nil + } + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `INSERT INTO %n.%n (Host, User, Password) VALUES (%?, %?, %?) `, mysql.SystemDB, mysql.PasswordHistoryTable, strings.ToLower(userDetail.host), userDetail.user, userDetail.pwd) + _, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return errors.Trace(err) + } + return nil +} + +// checkPasswordsMatch used to compare whether the password encrypted with mysql.AuthCachingSha2Password or mysql.AuthTiDBSM3Password is repeated. +func checkPasswordsMatch(rows []chunk.Row, oldPwd, authPlugin string) (bool, error) { + for _, row := range rows { + if !row.IsNull(0) { + pwd := row.GetString(0) + authok, err := auth.CheckHashingPassword([]byte(pwd), oldPwd, authPlugin) + if err != nil { + logutil.BgLogger().Error("Failed to check caching_sha2_password", zap.Error(err)) + return false, err + } + if authok { + return false, nil + } + } + } + return true, nil +} + +func getUserPasswordNum(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo) (deleteNum int64, err error) { + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `SELECT count(*) FROM %n.%n WHERE User=%? AND Host=%?;`, mysql.SystemDB, mysql.PasswordHistoryTable, userDetail.user, strings.ToLower(userDetail.host)) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return 0, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, 3) + if err != nil { + return 0, err + } + if len(rows) != 1 { + err := fmt.Errorf("`%s`@`%s` is not unique, please confirm the mysql.password_history table structure", userDetail.user, strings.ToLower(userDetail.host)) + return 0, err + } + + return rows[0].GetInt64(0), nil +} + +func fullRecordCheck(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo, authPlugin string) (canUse bool, err error) { + switch authPlugin { + case mysql.AuthNativePassword, "": + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `SELECT count(*) FROM %n.%n WHERE User= %? AND Host= %? AND Password = %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, userDetail.user, strings.ToLower(userDetail.host), userDetail.pwd) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return false, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, 3) + if err != nil { + return false, err + } + if rows[0].GetInt64(0) == 0 { + return true, nil + } + return false, nil + case mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password: + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `SELECT Password FROM %n.%n WHERE User= %? AND Host= %? ;`, mysql.SystemDB, mysql.PasswordHistoryTable, userDetail.user, strings.ToLower(userDetail.host)) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return false, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, variable.DefMaxChunkSize) + if err != nil { + return false, err + } + return checkPasswordsMatch(rows, userDetail.authString, authPlugin) + default: + return false, ErrPluginIsNotLoaded.GenWithStackByArgs(authPlugin) + } +} + +func checkPasswordHistoryRule(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo, passwordReuse *passwordReuseInfo, authPlugin string) (canUse bool, err error) { + switch authPlugin { + case mysql.AuthNativePassword, "": + sql := new(strings.Builder) + // Exceeded the maximum number of saved items, only check the ones within the limit. + checkRows := `SELECT count(*) FROM (SELECT Password FROM %n.%n WHERE User=%? AND Host=%? ORDER BY Password_timestamp DESC LIMIT ` + checkRows = checkRows + strconv.FormatInt(passwordReuse.passwordHistory, 10) + checkRows = checkRows + ` ) as t where t.Password = %? ` + sqlexec.MustFormatSQL(sql, checkRows, mysql.SystemDB, mysql.PasswordHistoryTable, userDetail.user, strings.ToLower(userDetail.host), userDetail.pwd) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return false, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, 3) + if err != nil { + return false, err + } + if rows[0].GetInt64(0) != 0 { + return false, nil + } + return true, nil + case mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password: + sql := new(strings.Builder) + checkRows := `SELECT Password FROM %n.%n WHERE User=%? AND Host=%? ORDER BY Password_timestamp DESC LIMIT ` + checkRows = checkRows + strconv.FormatInt(passwordReuse.passwordHistory, 10) + sqlexec.MustFormatSQL(sql, checkRows, mysql.SystemDB, mysql.PasswordHistoryTable, userDetail.user, strings.ToLower(userDetail.host)) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return false, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, variable.DefMaxChunkSize) + if err != nil { + return false, err + } + return checkPasswordsMatch(rows, userDetail.authString, authPlugin) + default: + return false, ErrPluginIsNotLoaded.GenWithStackByArgs(authPlugin) + } +} + +func checkPasswordTimeRule(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo, passwordReuse *passwordReuseInfo, + sctx sessionctx.Context, authPlugin string) (canUse bool, err error) { + beforeDate := getValidTime(sctx, passwordReuse) + switch authPlugin { + case mysql.AuthNativePassword, "": + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `SELECT count(*) FROM %n.%n WHERE User=%? AND Host=%? AND Password = %? AND Password_timestamp >= %?;`, + mysql.SystemDB, mysql.PasswordHistoryTable, userDetail.user, strings.ToLower(userDetail.host), userDetail.pwd, beforeDate) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return false, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, 3) + if err != nil { + return false, err + } + if rows[0].GetInt64(0) == 0 { + return true, nil + } + case mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password: + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `SELECT Password FROM %n.%n WHERE User=%? AND Host=%? AND Password_timestamp >= %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, userDetail.user, strings.ToLower(userDetail.host), beforeDate) + recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) + if err != nil { + return false, err + } + defer func() { + if closeErr := recordSet.Close(); closeErr != nil { + err = closeErr + } + }() + rows, err := sqlexec.DrainRecordSet(ctx, recordSet, variable.DefMaxChunkSize) + if err != nil { + return false, err + } + return checkPasswordsMatch(rows, userDetail.authString, authPlugin) + default: + return false, ErrPluginIsNotLoaded.GenWithStackByArgs(authPlugin) + } + return false, nil +} + +func passwordVerification(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo, passwordReuse *passwordReuseInfo, sctx sessionctx.Context, authPlugin string) (bool, int64, error) { + passwordNum, err := getUserPasswordNum(ctx, sqlExecutor, userDetail) + if err != nil { + return false, 0, err + } + + // the maximum number of records that can be deleted. + canDeleteNum := passwordNum - passwordReuse.passwordHistory + 1 + if canDeleteNum < 0 { + canDeleteNum = 0 + } + + if passwordReuse.passwordHistory <= 0 && passwordReuse.passwordReuseInterval <= 0 { + return true, canDeleteNum, nil + } + + // The maximum number of saves has not been exceeded. + // There are too many retention days, and it is impossible to time out in one's lifetime. + if (passwordNum <= passwordReuse.passwordHistory) || (passwordReuse.passwordReuseInterval > math.MaxInt32) { + passChecking, err := fullRecordCheck(ctx, sqlExecutor, userDetail, authPlugin) + return passChecking, canDeleteNum, err + } + + if passwordReuse.passwordHistory > 0 { + passChecking, err := checkPasswordHistoryRule(ctx, sqlExecutor, userDetail, passwordReuse, authPlugin) + if err != nil || !passChecking { + return false, 0, err + } + } + if passwordReuse.passwordReuseInterval > 0 { + passChecking, err := checkPasswordTimeRule(ctx, sqlExecutor, userDetail, passwordReuse, sctx, authPlugin) + if err != nil || !passChecking { + return false, 0, err + } + } + return true, canDeleteNum, nil +} + +func checkPasswordReusePolicy(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, userDetail *userInfo, sctx sessionctx.Context, authPlugin string) error { + if strings.EqualFold(authPlugin, mysql.AuthTiDBAuthToken) { + // AuthTiDBAuthToken is the token login method on the cloud, + // and the Password Reuse Policy does not take effect. + return nil + } + // read password reuse info from mysql.user and global variables. + passwdReuseInfo, err := getUserPasswordLimit(ctx, sqlExecutor, userDetail.user, userDetail.host, userDetail.pLI) + if err != nil { + return err + } + // check whether password can be used. + res, maxDelNum, err := passwordVerification(ctx, sqlExecutor, userDetail, passwdReuseInfo, sctx, authPlugin) + if err != nil { + return err + } + if !res { + return ErrExistsInHistoryPassword.GenWithStackByArgs(userDetail.user, userDetail.host) + } + err = deleteHistoricalData(ctx, sqlExecutor, userDetail, maxDelNum, passwdReuseInfo, sctx) + if err != nil { + return err + } + // insert password history. + err = addHistoricalData(ctx, sqlExecutor, userDetail, passwdReuseInfo) + if err != nil { + return err + } + return nil +} + func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt) error { + disableSandBoxMode := false + var err error + if e.ctx.InSandBoxMode() { + if err = e.checkSandboxMode(s.Specs); err != nil { + return err + } + disableSandBoxMode = true + } ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnPrivilege) if s.CurrentAuth != nil { user := e.ctx.GetSessionVars().User @@ -943,27 +1673,29 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt) s.Specs = []*ast.UserSpec{spec} } - lockAccount := "" - if len(s.PasswordOrLockOptions) > 0 { - // If "ACCOUNT LOCK" or "ACCOUNT UNLOCK" appears many times, - // the last declaration takes effect. - for i := len(s.PasswordOrLockOptions) - 1; i >= 0; i-- { - if s.PasswordOrLockOptions[i].Type == ast.Lock { - lockAccount = "Y" - break - } else if s.PasswordOrLockOptions[i].Type == ast.Unlock { - lockAccount = "N" - break - } - } + plOptions := passwordOrLockOptionsInfo{ + lockAccount: "", + passwordExpired: "", + passwordLifetime: notSpecified, + passwordHistory: notSpecified, + passwordReuseInterval: notSpecified, + failedLoginAttemptsChange: false, + passwordLockTimeChange: false, + passwordHistoryChange: false, + passwordReuseIntervalChange: false, + } + err = plOptions.loadOptions(s.PasswordOrLockOptions) + if err != nil { + return err } - privData, err := tlsOption2GlobalPriv(s.TLSOptions) + privData, err := tlsOption2GlobalPriv(s.AuthTokenOrTLSOptions) if err != nil { return err } failedUsers := make([]string, 0, len(s.Specs)) + needRollback := false checker := privilege.GetPrivilegeManager(e.ctx) if checker == nil { return errors.New("could not load privilege checker") @@ -974,6 +1706,31 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt) hasRestrictedUserPriv := checker.RequestDynamicVerification(activeRoles, "RESTRICTED_USER_ADMIN", false) hasSystemSchemaPriv := checker.RequestVerification(activeRoles, mysql.SystemDB, mysql.UserTable, "", mysql.UpdatePriv) + var authTokenOptions []*ast.AuthTokenOrTLSOption + for _, authTokenOrTLSOption := range s.AuthTokenOrTLSOptions { + if authTokenOrTLSOption.Type == ast.TokenIssuer { + authTokenOptions = append(authTokenOptions, authTokenOrTLSOption) + } + } + + sysSession, err := e.getSysSession() + defer clearSysSession(ctx, sysSession) + if err != nil { + return err + } + sqlExecutor := sysSession.(sqlexec.SQLExecutor) + // session isolation level changed to READ-COMMITTED. + // When tidb is at the RR isolation level, executing `begin` will obtain a consistent state. + // When operating the same user concurrently, it may happen that historical versions are read. + // In order to avoid this risk, change the isolation level to RC. + _, err = sqlExecutor.ExecuteInternal(ctx, "set tx_isolation = 'READ-COMMITTED'") + if err != nil { + return err + } + if _, err := sqlExecutor.ExecuteInternal(ctx, "BEGIN PESSIMISTIC"); err != nil { + return err + } + for _, spec := range s.Specs { user := e.ctx.GetSessionVars().User if spec.User.CurrentUser || ((user != nil) && (user.Username == spec.User.Username) && (user.AuthHostname == spec.User.Hostname)) { @@ -1007,7 +1764,7 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt) } } - exists, err := userExists(ctx, e.ctx, spec.User.Username, spec.User.Hostname) + exists, err := userExistsInternal(ctx, sqlExecutor, spec.User.Username, spec.User.Hostname) if err != nil { return err } @@ -1017,60 +1774,224 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt) continue } - exec := e.ctx.(sqlexec.RestrictedSQLExecutor) + type AuthTokenOptionHandler int + const ( + // NoNeedAuthTokenOptions means the final auth plugin is NOT tidb_auth_plugin + NoNeedAuthTokenOptions AuthTokenOptionHandler = iota + // OptionalAuthTokenOptions means the final auth_plugin is tidb_auth_plugin, + // and whether to declare AuthTokenOptions or not is ok. + OptionalAuthTokenOptions + // RequireAuthTokenOptions means the final auth_plugin is tidb_auth_plugin and need AuthTokenOptions here + RequireAuthTokenOptions + ) + authTokenOptionHandler := NoNeedAuthTokenOptions + currentAuthPlugin, err := privilege.GetPrivilegeManager(e.ctx).GetAuthPlugin(spec.User.Username, spec.User.Hostname) + if err != nil { + return err + } + if currentAuthPlugin == mysql.AuthTiDBAuthToken { + authTokenOptionHandler = OptionalAuthTokenOptions + } + + type alterField struct { + expr string + value any + } + var fields []alterField if spec.AuthOpt != nil { + fields = append(fields, alterField{"password_last_changed=current_timestamp()", nil}) if spec.AuthOpt.AuthPlugin == "" { - authplugin, err := e.userAuthPlugin(spec.User.Username, spec.User.Hostname) - if err != nil { - return err - } - spec.AuthOpt.AuthPlugin = authplugin + spec.AuthOpt.AuthPlugin = currentAuthPlugin } switch spec.AuthOpt.AuthPlugin { case mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password, mysql.AuthSocket, "": + authTokenOptionHandler = NoNeedAuthTokenOptions + case mysql.AuthTiDBAuthToken: + if authTokenOptionHandler != OptionalAuthTokenOptions { + authTokenOptionHandler = RequireAuthTokenOptions + } default: return ErrPluginIsNotLoaded.GenWithStackByArgs(spec.AuthOpt.AuthPlugin) } + // changing the auth method prunes history. + if spec.AuthOpt.AuthPlugin != currentAuthPlugin { + // delete password history from mysql.password_history. + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `DELETE FROM %n.%n WHERE Host = %? and User = %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, spec.User.Hostname, spec.User.Username) + if _, err := sqlExecutor.ExecuteInternal(ctx, sql.String()); err != nil { + failedUsers = append(failedUsers, spec.User.String()) + needRollback = true + break + } + } + if e.isValidatePasswordEnabled() && e.authUsingCleartextPwd(spec.AuthOpt, spec.AuthOpt.AuthPlugin) { + if err := pwdValidator.ValidatePassword(e.ctx.GetSessionVars(), spec.AuthOpt.AuthString); err != nil { + return err + } + } pwd, ok := spec.EncodedPassword() if !ok { return errors.Trace(ErrPasswordFormat) } - _, _, err := exec.ExecRestrictedSQL(ctx, nil, - `UPDATE %n.%n SET authentication_string=%?, plugin=%? WHERE Host=%? and User=%?;`, - mysql.SystemDB, mysql.UserTable, pwd, spec.AuthOpt.AuthPlugin, strings.ToLower(spec.User.Hostname), spec.User.Username, - ) - if err != nil { - failedUsers = append(failedUsers, spec.User.String()) + // for Support Password Reuse Policy. + // The empty password does not count in the password history and is subject to reuse at any time. + // https://dev.mysql.com/doc/refman/8.0/en/password-management.html#password-reuse-policy + if len(pwd) != 0 { + userDetail := &userInfo{ + host: spec.User.Hostname, + user: spec.User.Username, + pLI: &plOptions, + pwd: pwd, + authString: spec.AuthOpt.AuthString, + } + err := checkPasswordReusePolicy(ctx, sqlExecutor, userDetail, e.ctx, spec.AuthOpt.AuthPlugin) + if err != nil { + return err + } + } + fields = append(fields, alterField{"authentication_string=%?", pwd}) + if spec.AuthOpt.AuthPlugin != "" { + fields = append(fields, alterField{"plugin=%?", spec.AuthOpt.AuthPlugin}) + } + if spec.AuthOpt.ByAuthString || spec.AuthOpt.ByHashString { + if plOptions.passwordExpired == "" { + plOptions.passwordExpired = "N" + } + } + } + + if len(plOptions.lockAccount) != 0 { + fields = append(fields, alterField{"account_locked=%?", plOptions.lockAccount}) + } + + // support alter Password_reuse_history and Password_reuse_time. + if plOptions.passwordHistoryChange { + if plOptions.passwordHistory == notSpecified { + fields = append(fields, alterField{"Password_reuse_history = NULL ", ""}) + } else { + fields = append(fields, alterField{"Password_reuse_history = %? ", strconv.FormatInt(plOptions.passwordHistory, 10)}) + } + } + if plOptions.passwordReuseIntervalChange { + if plOptions.passwordReuseInterval == notSpecified { + fields = append(fields, alterField{"Password_reuse_time = NULL ", ""}) + } else { + fields = append(fields, alterField{"Password_reuse_time = %? ", strconv.FormatInt(plOptions.passwordReuseInterval, 10)}) + } + } + + passwordLockingInfo, err := readPasswordLockingInfo(ctx, sqlExecutor, spec.User.Username, spec.User.Hostname, &plOptions) + if err != nil { + return err + } + passwordLockingStr := alterUserFailedLoginJSON(passwordLockingInfo, plOptions.lockAccount) + + if len(plOptions.passwordExpired) != 0 { + if len(spec.User.Username) == 0 && plOptions.passwordExpired == "Y" { + return ErrPasswordExpireAnonymousUser.GenWithStackByArgs() + } + fields = append(fields, alterField{"password_expired=%?", plOptions.passwordExpired}) + } + if plOptions.passwordLifetime != notSpecified { + fields = append(fields, alterField{"password_lifetime=%?", plOptions.passwordLifetime}) + } + + var newAttributes []string + if s.CommentOrAttributeOption != nil { + if s.CommentOrAttributeOption.Type == ast.UserCommentType { + newAttributes = append(newAttributes, fmt.Sprintf(`"metadata": {"comment": "%s"}`, s.CommentOrAttributeOption.Value)) + } else { + newAttributes = append(newAttributes, fmt.Sprintf(`"metadata": %s`, s.CommentOrAttributeOption.Value)) + } + } + if s.ResourceGroupNameOption != nil && s.ResourceGroupNameOption.Type == ast.UserResourceGroupName { + if !variable.EnableResourceControl.Load() { + return infoschema.ErrResourceGroupSupportDisabled + } + + // check if specified resource group exists + if s.ResourceGroupNameOption.Value != "default" && s.ResourceGroupNameOption.Value != "" { + _, exists := e.is.ResourceGroupByName(model.NewCIStr(s.ResourceGroupNameOption.Value)) + if !exists { + return infoschema.ErrResourceGroupNotExists + } + } + + newAttributes = append(newAttributes, fmt.Sprintf(`"resource_group": "%s"`, s.ResourceGroupNameOption.Value)) + } + if passwordLockingStr != "" { + newAttributes = append(newAttributes, passwordLockingStr) + } + if length := len(newAttributes); length > 0 { + if length > 1 || passwordLockingStr == "" { + passwordLockingInfo.containsNoOthers = false + } + newAttributesStr := fmt.Sprintf("{%s}", strings.Join(newAttributes, ",")) + fields = append(fields, alterField{"user_attributes=json_merge_patch(coalesce(user_attributes, '{}'), %?)", newAttributesStr}) + } + + switch authTokenOptionHandler { + case NoNeedAuthTokenOptions: + if len(authTokenOptions) > 0 { + err := errors.New("TOKEN_ISSUER is not needed for the auth plugin") + e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) + } + case OptionalAuthTokenOptions: + if len(authTokenOptions) > 0 { + for _, authTokenOption := range authTokenOptions { + fields = append(fields, alterField{authTokenOption.Type.String() + "=%?", authTokenOption.Value}) + } + } + case RequireAuthTokenOptions: + if len(authTokenOptions) > 0 { + for _, authTokenOption := range authTokenOptions { + fields = append(fields, alterField{authTokenOption.Type.String() + "=%?", authTokenOption.Value}) + } + } else { + err := errors.New("Auth plugin 'tidb_auth_plugin' needs TOKEN_ISSUER") + e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) } } - if len(lockAccount) != 0 { - _, _, err := exec.ExecRestrictedSQL(ctx, nil, - `UPDATE %n.%n SET account_locked=%? WHERE Host=%? and User=%?;`, - mysql.SystemDB, mysql.UserTable, lockAccount, spec.User.Hostname, spec.User.Username) + if len(fields) > 0 { + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, "UPDATE %n.%n SET ", mysql.SystemDB, mysql.UserTable) + for i, f := range fields { + sqlexec.MustFormatSQL(sql, f.expr, f.value) + if i < len(fields)-1 { + sqlexec.MustFormatSQL(sql, ",") + } + } + sqlexec.MustFormatSQL(sql, " WHERE Host=%? and User=%?;", spec.User.Hostname, spec.User.Username) + _, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) if err != nil { failedUsers = append(failedUsers, spec.User.String()) + needRollback = true + continue } } + // Remove useless Password_locking from User_attributes. + err = deletePasswordLockingAttribute(ctx, sqlExecutor, spec.User.Username, spec.User.Hostname, passwordLockingInfo) + if err != nil { + failedUsers = append(failedUsers, spec.User.String()) + needRollback = true + continue + } + if len(privData) > 0 { - _, _, err := exec.ExecRestrictedSQL(ctx, nil, "INSERT INTO %n.%n (Host, User, Priv) VALUES (%?,%?,%?) ON DUPLICATE KEY UPDATE Priv = values(Priv)", mysql.SystemDB, mysql.GlobalPrivTable, spec.User.Hostname, spec.User.Username, string(hack.String(privData))) + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, "INSERT INTO %n.%n (Host, User, Priv) VALUES (%?,%?,%?) ON DUPLICATE KEY UPDATE Priv = values(Priv)", mysql.SystemDB, mysql.GlobalPrivTable, spec.User.Hostname, spec.User.Username, string(hack.String(privData))) + _, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) if err != nil { failedUsers = append(failedUsers, spec.User.String()) + needRollback = true } } } if len(failedUsers) > 0 { - // Commit the transaction even if we returns error - txn, err := e.ctx.Txn(true) - if err != nil { - return err - } - err = txn.Commit(tikvutil.SetSessionID(context.TODO(), e.ctx.GetSessionVars().ConnectionID)) - if err != nil { - return err - } - if !s.IfExists { + // Compatible with MySQL 8.0, `ALTER USER` realizes atomic operation. + if !s.IfExists || needRollback { return ErrCannotUser.GenWithStackByArgs("ALTER USER", strings.Join(failedUsers, ",")) } for _, user := range failedUsers { @@ -1078,7 +1999,30 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt) e.ctx.GetSessionVars().StmtCtx.AppendNote(err) } } - return domain.GetDomain(e.ctx).NotifyUpdatePrivilege() + if _, err := sqlExecutor.ExecuteInternal(ctx, "commit"); err != nil { + return err + } + if err = domain.GetDomain(e.ctx).NotifyUpdatePrivilege(); err != nil { + return err + } + if disableSandBoxMode { + e.ctx.DisableSandBoxMode() + } + return nil +} + +func (e *SimpleExec) checkSandboxMode(specs []*ast.UserSpec) error { + for _, spec := range specs { + if spec.AuthOpt == nil { + continue + } + if spec.AuthOpt.ByAuthString || spec.AuthOpt.ByHashString { + if spec.User.CurrentUser || e.ctx.GetSessionVars().User.Username == spec.User.Username { + return nil + } + } + } + return errMustChangePassword.GenWithStackByArgs() } func (e *SimpleExec) executeGrantRole(ctx context.Context, s *ast.GrantRoleStmt) error { @@ -1148,10 +2092,9 @@ func (e *SimpleExec) executeRenameUser(s *ast.RenameUserStmt) error { } sqlExecutor := sysSession.(sqlexec.SQLExecutor) - if _, err := sqlExecutor.ExecuteInternal(ctx, "begin"); err != nil { + if _, err := sqlExecutor.ExecuteInternal(ctx, "BEGIN PESSIMISTIC"); err != nil { return err } - for _, userToUser := range s.UserToUsers { oldUser, newUser := userToUser.OldUser, userToUser.NewUser if len(newUser.Username) > auth.UserNameMaxLength { @@ -1224,6 +2167,12 @@ func (e *SimpleExec) executeRenameUser(s *ast.RenameUserStmt) error { break } + // rename passwordhistory from PasswordHistoryTable. + if err = renameUserHostInSystemTable(sqlExecutor, mysql.PasswordHistoryTable, "USER", "HOST", userToUser); err != nil { + failedUser = oldUser.String() + " TO " + newUser.String() + " " + mysql.PasswordHistoryTable + " error" + break + } + // rename relationship from mysql.global_grants // TODO: add global_grants into the parser // TODO: need update columns_priv once we implement columns_priv functionality. @@ -1328,6 +2277,14 @@ func (e *SimpleExec) executeDropUser(ctx context.Context, s *ast.DropUserStmt) e break } + // delete password history from mysql.password_history. + sql.Reset() + sqlexec.MustFormatSQL(sql, `DELETE FROM %n.%n WHERE Host = %? and User = %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, strings.ToLower(user.Hostname), user.Username) + if _, err = sqlExecutor.ExecuteInternal(internalCtx, sql.String()); err != nil { + failedUsers = append(failedUsers, user.String()) + break + } + // delete privileges from mysql.global_priv sql.Reset() sqlexec.MustFormatSQL(sql, `DELETE FROM %n.%n WHERE Host = %? and User = %?;`, mysql.SystemDB, mysql.GlobalPrivTable, user.Hostname, user.Username) @@ -1448,7 +2405,7 @@ func userExists(ctx context.Context, sctx sessionctx.Context, name string, host // use the same internal executor to read within the same transaction, otherwise same as userExists func userExistsInternal(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, name string, host string) (bool, error) { sql := new(strings.Builder) - sqlexec.MustFormatSQL(sql, `SELECT * FROM %n.%n WHERE User=%? AND Host=%?;`, mysql.SystemDB, mysql.UserTable, name, strings.ToLower(host)) + sqlexec.MustFormatSQL(sql, `SELECT * FROM %n.%n WHERE User=%? AND Host=%? FOR UPDATE;`, mysql.SystemDB, mysql.UserTable, name, strings.ToLower(host)) recordSet, err := sqlExecutor.ExecuteInternal(ctx, sql.String()) if err != nil { return false, err @@ -1466,18 +2423,29 @@ func userExistsInternal(ctx context.Context, sqlExecutor sqlexec.SQLExecutor, na return rows > 0, err } -func (e *SimpleExec) userAuthPlugin(name string, host string) (string, error) { - pm := privilege.GetPrivilegeManager(e.ctx) - authplugin, err := pm.GetAuthPlugin(name, host) +func (e *SimpleExec) executeSetPwd(ctx context.Context, s *ast.SetPwdStmt) error { + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnPrivilege) + sysSession, err := e.getSysSession() + defer clearSysSession(ctx, sysSession) + if err != nil { + return err + } + + sqlExecutor := sysSession.(sqlexec.SQLExecutor) + // session isolation level changed to READ-COMMITTED. + // When tidb is at the RR isolation level, executing `begin` will obtain a consistent state. + // When operating the same user concurrently, it may happen that historical versions are read. + // In order to avoid this risk, change the isolation level to RC. + _, err = sqlExecutor.ExecuteInternal(ctx, "set tx_isolation = 'READ-COMMITTED'") if err != nil { - return "", err + return err + } + if _, err := sqlExecutor.ExecuteInternal(ctx, "BEGIN PESSIMISTIC"); err != nil { + return err } - return authplugin, nil -} -func (e *SimpleExec) executeSetPwd(ctx context.Context, s *ast.SetPwdStmt) error { - ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnPrivilege) var u, h string + disableSandboxMode := false if s.User == nil || s.User.CurrentUser { if e.ctx.GetSessionVars().User == nil { return errors.New("Session error is empty") @@ -1493,18 +2461,31 @@ func (e *SimpleExec) executeSetPwd(ctx context.Context, s *ast.SetPwdStmt) error u = s.User.Username h = s.User.Hostname } - exists, err := userExists(ctx, e.ctx, u, h) + exists, err := userExistsInternal(ctx, sqlExecutor, u, h) if err != nil { return err } if !exists { return errors.Trace(ErrPasswordNoMatch) } + if e.ctx.InSandBoxMode() { + if s.User == nil || s.User.CurrentUser || + e.ctx.GetSessionVars().User.AuthUsername == u && e.ctx.GetSessionVars().User.AuthHostname == strings.ToLower(h) { + disableSandboxMode = true + } else { + return errMustChangePassword.GenWithStackByArgs() + } + } - authplugin, err := e.userAuthPlugin(u, h) + authplugin, err := privilege.GetPrivilegeManager(e.ctx).GetAuthPlugin(u, h) if err != nil { return err } + if e.isValidatePasswordEnabled() { + if err := pwdValidator.ValidatePassword(e.ctx.GetSessionVars(), s.Password); err != nil { + return err + } + } var pwd string switch authplugin { case mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password: @@ -1516,16 +2497,58 @@ func (e *SimpleExec) executeSetPwd(ctx context.Context, s *ast.SetPwdStmt) error pwd = auth.EncodePassword(s.Password) } + // for Support Password Reuse Policy. + plOptions := &passwordOrLockOptionsInfo{ + lockAccount: "", + passwordHistory: notSpecified, + passwordReuseInterval: notSpecified, + passwordHistoryChange: false, + passwordReuseIntervalChange: false, + } + // The empty password does not count in the password history and is subject to reuse at any time. + // https://dev.mysql.com/doc/refman/8.0/en/password-management.html#password-reuse-policy + if len(pwd) != 0 { + userDetail := &userInfo{ + host: h, + user: u, + pLI: plOptions, + pwd: pwd, + authString: s.Password, + } + err := checkPasswordReusePolicy(ctx, sqlExecutor, userDetail, e.ctx, authplugin) + if err != nil { + return err + } + } // update mysql.user - exec := e.ctx.(sqlexec.RestrictedSQLExecutor) - _, _, err = exec.ExecRestrictedSQL(ctx, nil, `UPDATE %n.%n SET authentication_string=%? WHERE User=%? AND Host=%?;`, mysql.SystemDB, mysql.UserTable, pwd, u, strings.ToLower(h)) + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, `UPDATE %n.%n SET authentication_string=%?,password_expired='N',password_last_changed=current_timestamp() WHERE User=%? AND Host=%?;`, mysql.SystemDB, mysql.UserTable, pwd, u, strings.ToLower(h)) + _, err = sqlExecutor.ExecuteInternal(ctx, sql.String()) if err != nil { return err } - return domain.GetDomain(e.ctx).NotifyUpdatePrivilege() + if _, err := sqlExecutor.ExecuteInternal(ctx, "commit"); err != nil { + return err + } + err = domain.GetDomain(e.ctx).NotifyUpdatePrivilege() + if err != nil { + return err + } + if disableSandboxMode { + e.ctx.DisableSandBoxMode() + } + return nil } func (e *SimpleExec) executeKillStmt(ctx context.Context, s *ast.KillStmt) error { + if x, ok := s.Expr.(*ast.FuncCallExpr); ok { + if x.FnName.L == ast.ConnectionID { + sm := e.ctx.GetSessionManager() + sm.Kill(e.ctx.GetSessionVars().ConnectionID, s.Query) + return nil + } + return errors.New("Invalid operation. Please use 'KILL TIDB [CONNECTION | QUERY] [connectionID | CONNECTION_ID()]' instead") + } if !config.GetGlobalConfig().EnableGlobalKill { conf := config.GetGlobalConfig() if s.TiDBExtension || conf.CompatibleKillQuery { @@ -1535,7 +2558,7 @@ func (e *SimpleExec) executeKillStmt(ctx context.Context, s *ast.KillStmt) error } sm.Kill(s.ConnectionID, s.Query) } else { - err := errors.New("Invalid operation. Please use 'KILL TIDB [CONNECTION | QUERY] connectionID' instead") + err := errors.New("Invalid operation. Please use 'KILL TIDB [CONNECTION | QUERY] [connectionID | CONNECTION_ID()]' instead") e.ctx.GetSessionVars().StmtCtx.AppendWarning(err) } return nil @@ -1670,14 +2693,24 @@ func (e *SimpleExec) executeAlterInstance(s *ast.AlterInstanceStmt) error { func (e *SimpleExec) executeDropStats(s *ast.DropStatsStmt) (err error) { h := domain.GetDomain(e.ctx).StatsHandle() var statsIDs []int64 + // TODO: GLOBAL option will be deprecated. Also remove this condition when the syntax is removed if s.IsGlobalStats { - statsIDs = []int64{s.Table.TableInfo.ID} + statsIDs = []int64{s.Tables[0].TableInfo.ID} } else { - if statsIDs, _, err = core.GetPhysicalIDsAndPartitionNames(s.Table.TableInfo, s.PartitionNames); err != nil { - return err - } if len(s.PartitionNames) == 0 { - statsIDs = append(statsIDs, s.Table.TableInfo.ID) + for _, table := range s.Tables { + partitionStatIds, _, err := core.GetPhysicalIDsAndPartitionNames(table.TableInfo, nil) + if err != nil { + return err + } + statsIDs = append(statsIDs, partitionStatIds...) + statsIDs = append(statsIDs, table.TableInfo.ID) + } + } else { + // TODO: drop stats for specific partition is deprecated. Also remove this condition when the syntax is removed + if statsIDs, _, err = core.GetPhysicalIDsAndPartitionNames(s.Tables[0].TableInfo, s.PartitionNames); err != nil { + return err + } } } if err := h.DeleteTableStatsFromKV(statsIDs); err != nil { diff --git a/executor/simple_test.go b/executor/simple_test.go index 2cad7698d2522..4eb355778b954 100644 --- a/executor/simple_test.go +++ b/executor/simple_test.go @@ -15,14 +15,19 @@ package executor_test import ( + "context" "fmt" "strconv" "testing" "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/server" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/util" + "github.com/stretchr/testify/require" ) func TestKillStmt(t *testing.T) { @@ -47,7 +52,7 @@ func TestKillStmt(t *testing.T) { tk.MustExec("use test") tk.MustExec(fmt.Sprintf("kill %d", connID)) result := tk.MustQuery("show warnings") - result.Check(testkit.Rows("Warning 1105 Invalid operation. Please use 'KILL TIDB [CONNECTION | QUERY] connectionID' instead")) + result.Check(testkit.Rows("Warning 1105 Invalid operation. Please use 'KILL TIDB [CONNECTION | QUERY] [connectionID | CONNECTION_ID()]' instead")) newCfg2 := *originCfg newCfg2.EnableGlobalKill = true @@ -74,5 +79,57 @@ func TestKillStmt(t *testing.T) { result = tk.MustQuery("show warnings") result.Check(testkit.Rows()) + tk.MustExecToErr("kill rand()", "Invalid operation. Please use 'KILL TIDB [CONNECTION | QUERY] [connectionID | CONNECTION_ID()]' instead") // remote kill is tested in `tests/globalkilltest` } + +func TestUserAttributes(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + rootTK := testkit.NewTestKit(t, store) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) + + // https://dev.mysql.com/doc/refman/8.0/en/create-user.html#create-user-comments-attributes + rootTK.MustExec(`CREATE USER testuser COMMENT '1234'`) + rootTK.MustExec(`CREATE USER testuser1 ATTRIBUTE '{"name": "Tom", "age": 19}'`) + _, err := rootTK.Exec(`CREATE USER testuser2 ATTRIBUTE '{"name": "Tom", age: 19}'`) + rootTK.MustExec(`CREATE USER testuser2`) + require.Error(t, err) + rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser'`).Check(testkit.Rows(`{"metadata": {"comment": "1234"}, "resource_group": "default"}`)) + rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser1'`).Check(testkit.Rows(`{"metadata": {"age": 19, "name": "Tom"}, "resource_group": "default"}`)) + rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser2'`).Check(testkit.Rows(`{"resource_group": "default"}`)) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser'`).Check(testkit.Rows(`{"comment": "1234"}`)) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 19, "name": "Tom"}`)) + rootTK.MustQueryWithContext(ctx, `SELECT attribute->>"$.age" AS age, attribute->>"$.name" AS name FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`19 Tom`)) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser2'`).Check(testkit.Rows(``)) + + // https://dev.mysql.com/doc/refman/8.0/en/alter-user.html#alter-user-comments-attributes + rootTK.MustExec(`ALTER USER testuser1 ATTRIBUTE '{"age": 20, "sex": "male"}'`) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 20, "name": "Tom", "sex": "male"}`)) + rootTK.MustExec(`ALTER USER testuser1 ATTRIBUTE '{"hobby": "soccer"}'`) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 20, "hobby": "soccer", "name": "Tom", "sex": "male"}`)) + rootTK.MustExec(`ALTER USER testuser1 ATTRIBUTE '{"sex": null, "hobby": null}'`) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 20, "name": "Tom"}`)) + rootTK.MustExec(`ALTER USER testuser1 COMMENT '5678'`) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 20, "comment": "5678", "name": "Tom"}`)) + rootTK.MustExec(`ALTER USER testuser1 COMMENT ''`) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 20, "comment": "", "name": "Tom"}`)) + rootTK.MustExec(`ALTER USER testuser1 ATTRIBUTE '{"comment": null}'`) + rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 20, "name": "Tom"}`)) + + // Non-root users could access COMMENT or ATTRIBUTE of all users via the view, + // but not via the mysql.user table. + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "testuser1"}, nil, nil)) + tk.MustQueryWithContext(ctx, `SELECT user, host, attribute FROM information_schema.user_attributes ORDER BY user`).Check( + testkit.Rows("root % ", "testuser % {\"comment\": \"1234\"}", "testuser1 % {\"age\": 20, \"name\": \"Tom\"}", "testuser2 % ")) + tk.MustGetErrCode(`SELECT user, host, user_attributes FROM mysql.user ORDER BY user`, mysql.ErrTableaccessDenied) + + // https://github.com/pingcap/tidb/issues/39207 + rootTK.MustExec("create user usr1@'%' identified by 'passord'") + rootTK.MustExec("alter user usr1 comment 'comment1'") + rootTK.MustQuery("select user_attributes from mysql.user where user = 'usr1'").Check(testkit.Rows(`{"metadata": {"comment": "comment1"}, "resource_group": "default"}`)) + rootTK.MustExec("set global tidb_enable_resource_control = 'on'") + rootTK.MustExec("CREATE RESOURCE GROUP rg1 rru_per_sec = 100 wru_per_sec = 200") + rootTK.MustExec("alter user usr1 resource group rg1") + rootTK.MustQuery("select user_attributes from mysql.user where user = 'usr1'").Check(testkit.Rows(`{"metadata": {"comment": "comment1"}, "resource_group": "rg1"}`)) +} diff --git a/executor/simpletest/BUILD.bazel b/executor/simpletest/BUILD.bazel index 0f8c010c0bc99..2da6aa029e3cd 100644 --- a/executor/simpletest/BUILD.bazel +++ b/executor/simpletest/BUILD.bazel @@ -5,6 +5,7 @@ go_test( timeout = "short", srcs = [ "main_test.go", + "password_management_test.go", "simple_test.go", ], flaky = True, @@ -12,17 +13,23 @@ go_test( shard_count = 30, deps = [ "//config", + "//domain", + "//errno", "//executor", + "//kv", "//parser/auth", "//parser/model", "//parser/mysql", "//parser/terror", "//planner/core", + "//privilege/privileges", "//session", "//sessionctx", + "//sessionctx/variable", "//statistics/handle", "//store/mockstore", "//testkit", + "//util/sqlexec", "@com_github_pingcap_errors//:errors", "@com_github_stretchr_testify//require", "@io_opencensus_go//stats/view", diff --git a/executor/simpletest/main_test.go b/executor/simpletest/main_test.go index d90b80dbc4a84..6772de87c1301 100644 --- a/executor/simpletest/main_test.go +++ b/executor/simpletest/main_test.go @@ -23,6 +23,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), } goleak.VerifyTestMain(m, opts...) diff --git a/executor/simpletest/password_management_test.go b/executor/simpletest/password_management_test.go new file mode 100644 index 0000000000000..ae3352cdf84b7 --- /dev/null +++ b/executor/simpletest/password_management_test.go @@ -0,0 +1,1363 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package simpletest + +import ( + "bytes" + "crypto/sha1" + "encoding/json" + "fmt" + "strconv" + "strings" + "testing" + "time" + + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/privilege/privileges" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/util/sqlexec" + "github.com/stretchr/testify/require" +) + +func TestValidatePassword(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + subtk := testkit.NewTestKit(t, store) + err := tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil) + require.NoError(t, err) + tk.MustExec("CREATE USER ''@'localhost'") + tk.MustExec("GRANT ALL PRIVILEGES ON mysql.* TO ''@'localhost';") + err = subtk.Session().Auth(&auth.UserIdentity{Hostname: "localhost"}, nil, nil) + require.NoError(t, err) + + authPlugins := []string{mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password} + tk.MustQuery("SELECT @@global.validate_password.enable").Check(testkit.Rows("0")) + tk.MustExec("SET GLOBAL validate_password.enable = 1") + tk.MustQuery("SELECT @@global.validate_password.enable").Check(testkit.Rows("1")) + + for _, authPlugin := range authPlugins { + tk.MustExec("DROP USER IF EXISTS testuser") + tk.MustExec(fmt.Sprintf("CREATE USER testuser IDENTIFIED WITH %s BY '!Abc12345678'", authPlugin)) + + tk.MustExec("SET GLOBAL validate_password.policy = 'LOW'") + // check user name + tk.MustQuery("SELECT @@global.validate_password.check_user_name").Check(testkit.Rows("1")) + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '!Abcdroot1234'", "Password Contains User Name") + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '!Abcdtoor1234'", "Password Contains Reversed User Name") + tk.MustExec("SET PASSWORD FOR 'testuser' = 'testuser'") // password the same as the user name, but run by root + tk.MustExec("ALTER USER testuser IDENTIFIED BY 'testuser'") + tk.MustExec("SET GLOBAL validate_password.check_user_name = 0") + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abcdroot1234'") + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abcdtoor1234'") + tk.MustExec("SET GLOBAL validate_password.check_user_name = 1") + + // LOW: Length + tk.MustExec("SET GLOBAL validate_password.length = 8") + tk.MustQuery("SELECT @@global.validate_password.length").Check(testkit.Rows("8")) + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '1234567'", "Require Password Length: 8") + tk.MustExec("SET GLOBAL validate_password.length = 12") + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '!Abcdefg123'", "Require Password Length: 12") + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abcdefg1234'") + tk.MustExec("SET GLOBAL validate_password.length = 8") + + // MEDIUM: Length; numeric, lowercase/uppercase, and special characters + tk.MustExec("SET GLOBAL validate_password.policy = 'MEDIUM'") + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abc1234567'") + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '!ABC1234567'", "Require Password Lowercase Count: 1") + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '!abc1234567'", "Require Password Uppercase Count: 1") + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '!ABCDabcd'", "Require Password Digit Count: 1") + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY 'Abc1234567'", "Require Password Non-alphanumeric Count: 1") + tk.MustExec("SET GLOBAL validate_password.special_char_count = 0") + tk.MustExec("ALTER USER testuser IDENTIFIED BY 'Abc1234567'") + tk.MustExec("SET GLOBAL validate_password.special_char_count = 1") + tk.MustExec("SET GLOBAL validate_password.length = 3") + tk.MustQuery("SELECT @@GLOBAL.validate_password.length").Check(testkit.Rows("4")) + + // STRONG: Length; numeric, lowercase/uppercase, and special characters; dictionary file + tk.MustExec("SET GLOBAL validate_password.policy = 'STRONG'") + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abc1234567'") + tk.MustExec(fmt.Sprintf("SET GLOBAL validate_password.dictionary = '%s'", "1234;5678")) + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abc123567'") + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abc43218765'") + tk.MustContainErrMsg("ALTER USER testuser IDENTIFIED BY '!Abc1234567'", "Password contains word in the dictionary") + tk.MustExec("SET GLOBAL validate_password.dictionary = ''") + tk.MustExec("ALTER USER testuser IDENTIFIED BY '!Abc1234567'") + + // "IDENTIFIED AS 'xxx'" is not affected by validation + tk.MustExec(fmt.Sprintf("ALTER USER testuser IDENTIFIED WITH '%s' AS ''", authPlugin)) + } + tk.MustContainErrMsg("CREATE USER 'testuser1'@'localhost'", "Your password does not satisfy the current policy requirements") + tk.MustContainErrMsg("CREATE USER 'testuser1'@'localhost' IDENTIFIED WITH 'caching_sha2_password'", "Your password does not satisfy the current policy requirements") + tk.MustContainErrMsg("CREATE USER 'testuser1'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS ''", "Your password does not satisfy the current policy requirements") + + // if the username is '', all password can pass the check_user_name + subtk.MustQuery("SELECT user(), current_user()").Check(testkit.Rows("@localhost @localhost")) + subtk.MustQuery("SELECT @@global.validate_password.check_user_name").Check(testkit.Rows("1")) + subtk.MustQuery("SELECT @@global.validate_password.enable").Check(testkit.Rows("1")) + tk.MustExec("SET GLOBAL validate_password.number_count = 0") + tk.MustExec("SET GLOBAL validate_password.special_char_count = 0") + tk.MustExec("SET GLOBAL validate_password.mixed_case_count = 0") + tk.MustExec("SET GLOBAL validate_password.length = 0") + subtk.MustExec("ALTER USER ''@'localhost' IDENTIFIED BY ''") + subtk.MustExec("ALTER USER ''@'localhost' IDENTIFIED BY 'abcd'") + + // CREATE ROLE is not affected by password validation + tk.MustExec("SET GLOBAL validate_password.enable = 1") + tk.MustExec("SET GLOBAL validate_password.number_count = default") + tk.MustExec("SET GLOBAL validate_password.special_char_count = default") + tk.MustExec("SET GLOBAL validate_password.mixed_case_count = default") + tk.MustExec("SET GLOBAL validate_password.length = default") + tk.MustExec("CREATE ROLE role1") +} + +func expectedPasswordExpiration(t *testing.T, tk *testkit.TestKit, testuser, expired string, lifetime string) { + res := tk.MustQuery(fmt.Sprintf("SELECT password_expired, password_last_changed, password_lifetime FROM mysql.user WHERE user = '%s'", testuser)) + rows := res.Rows() + require.NotEmpty(t, rows) + row := rows[0] + require.Equal(t, 3, len(row)) + require.Equal(t, expired, row[0].(string), testuser) + require.True(t, len(row[1].(string)) > 0, testuser) + require.Equal(t, lifetime, row[2].(string), testuser) +} + +func TestPasswordExpiration(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + // CREATE USER + tk.MustExec(`CREATE USER testuser`) + expectedPasswordExpiration(t, tk, "testuser", "N", "") + tk.MustExec(`CREATE USER testuser1 PASSWORD EXPIRE`) + expectedPasswordExpiration(t, tk, "testuser1", "Y", "") + tk.MustExec(`CREATE USER testuser2 PASSWORD EXPIRE DEFAULT`) + expectedPasswordExpiration(t, tk, "testuser2", "N", "") + tk.MustExec(`CREATE USER testuser3 PASSWORD EXPIRE NEVER`) + expectedPasswordExpiration(t, tk, "testuser3", "N", "0") + tk.MustExec(`CREATE USER testuser4 PASSWORD EXPIRE INTERVAL 3 DAY`) + expectedPasswordExpiration(t, tk, "testuser4", "N", "3") + tk.MustExec(`CREATE ROLE role1`) + expectedPasswordExpiration(t, tk, "role1", "Y", "") + + // ALTER USER + testcases := []struct { + user string + expired string + }{ + {"testuser", "N"}, + {"testuser1", "Y"}, + {"testuser2", "N"}, + {"testuser3", "N"}, + {"testuser4", "N"}, + {"role1", "Y"}, + } + for _, testcase := range testcases { + tk.MustExec(fmt.Sprintf("ALTER USER %s PASSWORD EXPIRE NEVER", testcase.user)) + expectedPasswordExpiration(t, tk, testcase.user, testcase.expired, "0") + tk.MustExec(fmt.Sprintf("ALTER USER %s PASSWORD EXPIRE DEFAULT", testcase.user)) + expectedPasswordExpiration(t, tk, testcase.user, testcase.expired, "") + tk.MustExec(fmt.Sprintf("ALTER USER %s PASSWORD EXPIRE INTERVAL 3 DAY", testcase.user)) + expectedPasswordExpiration(t, tk, testcase.user, testcase.expired, "3") + tk.MustExec(fmt.Sprintf("ALTER USER %s PASSWORD EXPIRE", testcase.user)) + expectedPasswordExpiration(t, tk, testcase.user, "Y", "3") + tk.MustExec(fmt.Sprintf("ALTER USER %s IDENTIFIED BY '' PASSWORD EXPIRE", testcase.user)) + expectedPasswordExpiration(t, tk, testcase.user, "Y", "3") + tk.MustExec(fmt.Sprintf("ALTER USER %s IDENTIFIED WITH 'mysql_native_password' AS ''", testcase.user)) + expectedPasswordExpiration(t, tk, testcase.user, "N", "3") + tk.MustExec(fmt.Sprintf("ALTER USER %s IDENTIFIED BY ''", testcase.user)) + expectedPasswordExpiration(t, tk, testcase.user, "N", "3") + } + + // SET PASSWORD + tk.MustExec("ALTER USER testuser PASSWORD EXPIRE") + expectedPasswordExpiration(t, tk, "testuser", "Y", "3") + tk.MustExec("SET PASSWORD FOR testuser = '1234'") + expectedPasswordExpiration(t, tk, "testuser", "N", "3") + + tk.MustGetErrCode(`CREATE USER ''@localhost IDENTIFIED BY 'pass' PASSWORD EXPIRE`, mysql.ErrPasswordExpireAnonymousUser) + tk.MustExec(`CREATE USER ''@localhost IDENTIFIED BY 'pass'`) + tk.MustGetErrCode(`ALTER USER ''@localhost PASSWORD EXPIRE`, mysql.ErrPasswordExpireAnonymousUser) + + // different cleartext authentication plugin + for _, authplugin := range []string{mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password} { + tk.MustExec("DROP USER IF EXISTS 'u1'@'localhost'") + tk.MustExec(fmt.Sprintf("CREATE USER 'u1'@'localhost' IDENTIFIED WITH '%s'", authplugin)) + tk.MustExec("ALTER USER 'u1'@'localhost' IDENTIFIED BY 'pass'") + tk.MustExec("ALTER USER 'u1'@'localhost' PASSWORD EXPIRE") + tk.MustQuery("SELECT password_expired FROM mysql.user WHERE user = 'u1'").Check(testkit.Rows("Y")) + } +} + +// Test cases that related to PASSWORD VALIDATION, PASSWORD EXPIRATION, PASSWORD REUSE POLICY, and PASSWORD FAILED-LOGIN TRACK. +func TestPasswordManagement(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("SET GLOBAL validate_password.enable = 1") + + // PASSWORD VALIDATION can work with user-specified PASSWORD REUSE POLICY. + tk.MustExec("CREATE USER u1 IDENTIFIED BY '!Abc1234' password history 1") + tk.MustGetErrCode("ALTER USER u1 IDENTIFIED BY '!Abc1234'", errno.ErrExistsInHistoryPassword) + tk.MustGetErrCode("ALTER USER u1 IDENTIFIED BY '!abc1234'", errno.ErrNotValidPassword) + + // PASSWORD VALIDATION can work with global PASSWORD REUSE POLICY. + tk.MustExec("SET GLOBAL password_history = 1") + tk.MustExec("DROP USER u1") + tk.MustExec("CREATE USER u1 IDENTIFIED BY '!Abc1234'") + tk.MustGetErrCode("ALTER USER u1 IDENTIFIED BY '!Abc1234'", errno.ErrExistsInHistoryPassword) + tk.MustGetErrCode("ALTER USER u1 IDENTIFIED BY '!abc1234'", errno.ErrNotValidPassword) + + // PASSWORD EXPIRATION can work with ACCOUNT LOCK. + // PASSWORD EXPIRE NEVER and ACCOUNT UNLOCK take effect. + tk.MustExec(`ALTER USER u1 ACCOUNT LOCK PASSWORD EXPIRE NEVER PASSWORD EXPIRE NEVER ACCOUNT UNLOCK ACCOUNT LOCK ACCOUNT LOCK ACCOUNT UNLOCK;`) + tk.MustQuery(`SELECT password_expired, password_lifetime, account_locked FROM mysql.user WHERE USER='u1';`).Check( + testkit.Rows("N 0 N")) + + // PASSWORD EXPIRATION can work with PASSWORD REUSE POLICY + tk.MustExec(`create user u2 identified by '!Abc1234' password expire password reuse interval default password expire never password + reuse interval 3 day password history 5 password history default password expire default`) + tk.MustQuery(`select password_expired, password_lifetime, password_reuse_history, password_reuse_time from mysql.user where user = 'u2'`).Check( + testkit.Rows("N 3")) + tk.MustExec(`alter user u2 password expire default password reuse interval 3 day password history default + password expire never password expire interval 5 day password reuse interval default password expire password history 5`) + tk.MustQuery(`select password_expired, password_lifetime, password_reuse_history, password_reuse_time from mysql.user where user = 'u2'`).Check( + testkit.Rows("Y 5 ")) + tk.MustExec(`alter user u2 identified by '!Abc12345'`) + tk.MustQuery(`select password_expired, password_lifetime, password_reuse_history, password_reuse_time from mysql.user where user = 'u2'`).Check( + testkit.Rows("N 5 ")) + + // PASSWORD FAILED-LOGIN TRACK can work with USER COMMENT and USER ATTRIBUTE + tk.MustExec(`CREATE USER u3 IDENTIFIED BY '!Abc12345' FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME 3 COMMENT 'Some statements to test create user'`) + tk.MustQuery(`select user_attributes->>"$.metadata" from mysql.user where user = 'u3'`).Check(testkit.Rows(`{"comment": "Some statements to test create user"}`)) + tk.MustQuery(`select user_attributes->>"$.Password_locking" from mysql.user where user = 'u3'`).Check(testkit.Rows(`{"failed_login_attempts": 4, "password_lock_time_days": 3}`)) + tk.MustExec(`ALTER USER u3 FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME unbounded FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 5 ATTRIBUTE '{"name": "John", "age": 19}'`) + tk.MustQuery(`select user_attributes->>"$.metadata" from mysql.user where user = 'u3'`).Check(testkit.Rows(`{"age": 19, "comment": "Some statements to test create user", "name": "John"}`)) + tk.MustQuery(`select user_attributes->>"$.Password_locking" from mysql.user where user = 'u3'`).Check(testkit.Rows(`{"failed_login_attempts": 5, "password_lock_time_days": 5}`)) + + tk.MustExec("SET GLOBAL validate_password.enable = 0") + + rootTK := testkit.NewTestKit(t, store) + // Password Strength Check. + rootTK.MustExec(`set global validate_password.enable = ON`) + rootTK.MustExec(`drop user u2`) + rootTK.MustGetErrCode(`create user u2 identified by 'u2' PASSWORD EXPIRE INTERVAL 2 DAY password history 2 + password reuse interval 2 day FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1`, 1819) + rootTK.MustGetErrCode(`create user u2`, 1819) + rootTK.MustGetErrCode(`create user u2 identified by 'u2222222' PASSWORD EXPIRE INTERVAL 2 DAY password history 2 + password reuse interval 2 day FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1`, 1819) + rootTK.MustGetErrCode(`create user u2 identified by 'Uu2222222' PASSWORD EXPIRE INTERVAL 2 DAY password history 2 + password reuse interval 2 day FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1`, 1819) + rootTK.MustGetErrCode(`create user u2 identified by 'Uu3222222' PASSWORD EXPIRE INTERVAL 2 DAY password history 2 + password reuse interval 2 day FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1`, 1819) + rootTK.MustExec(`create user u2 identified by 'Uu3@22222' PASSWORD EXPIRE INTERVAL 2 DAY password history 2 + password reuse interval 2 day FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1`) + rootTK.MustQuery(`Select count(*) from mysql.password_history where user = 'u2' and host = '%'`).Check(testkit.Rows("1")) + result := rootTK.MustQuery(`Select authentication_string from mysql.user where user = 'u2' and host = '%'`) + result.Check(testkit.Rows(auth.EncodePassword("Uu3@22222"))) + // Disable password reuse. + rootTK.MustGetErrCode(`Alter user u2 identified by 'Uu3@22222'`, 3638) + rootTK.MustGetErrCode(`Set password for 'u2' = 'Uu3@22222'`, 3638) + // Password Strength Check. + rootTK.MustGetErrCode(`Alter user u2 identified by 'U2'`, 1819) + rootTK.MustGetErrCode(`Set password for 'u2' = 'U2'`, 1819) + // Did not modify successfully. + result = rootTK.MustQuery(`Select authentication_string from mysql.user where user = 'u2' and host = '%'`) + result.Check(testkit.Rows(auth.EncodePassword("Uu3@22222"))) + // Auto-lock in effect. + err := tk.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "%"}, sha1Password(""), nil) + require.ErrorContains(t, err, "Account is blocked for 1 day(s) (1 day(s) remaining) due to 1 consecutive failed logins.") + result = rootTK.MustQuery(`SELECT + JSON_UNQUOTE(JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_count')), + JSON_UNQUOTE(JSON_EXTRACT(user_attributes, '$.Password_locking.auto_account_locked')) from mysql.user where user = 'u2' and host = '%'`) + result.Check(testkit.Rows(`1 Y`)) + rootTK.MustExec(`ALTER user u2 account unlock`) + + // Unlock in effect. + result = rootTK.MustQuery(`SELECT + JSON_UNQUOTE(JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_count')), + JSON_UNQUOTE(JSON_EXTRACT(user_attributes, '$.Password_locking.auto_account_locked')) from mysql.user where user = 'u2' and host = '%'`) + result.Check(testkit.Rows(`0 N`)) + + rootTK.MustExec(`set global validate_password.enable = OFF`) + rootTK.MustExec(`update mysql.user set Password_last_changed = date_sub(Password_last_changed,interval '3 0:0:1' DAY_SECOND) where user = 'u2' and host = '%'`) + err = domain.GetDomain(rootTK.Session()).NotifyUpdatePrivilege() + require.NoError(t, err) + // Password expires and takes effect. + err = tk.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "%"}, sha1Password("Uu3@22222"), nil) + require.ErrorContains(t, err, "Your password has expired.") + variable.IsSandBoxModeEnabled.Store(true) + err = tk.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "%"}, sha1Password("Uu3@22222"), nil) + require.NoError(t, err) + require.True(t, tk.Session().InSandBoxMode()) + + rootTK.MustExec(`set global validate_password.enable = ON`) + // Forbid other users to change password. + tk.MustGetErrCode(`Alter user root identified by 'Uu3@22222'`, 1820) + // Disable password reuse. + tk.MustGetErrCode(`Alter user u2 identified by 'Uu3@22222'`, 3638) + tk.MustGetErrCode(`set password = 'Uu3@22222'`, 3638) + // Password Strength Check. + tk.MustGetErrCode(`Alter user u2 identified by 'U2'`, 1819) + tk.MustGetErrCode(`set password = 'U2'`, 1819) + tk.MustExec(`Set password = 'Uu3@22223'`) + require.False(t, tk.Session().InSandBoxMode()) + rootTK.MustQuery(`Select count(*) from mysql.password_history where user = 'u2' and host = '%'`).Check(testkit.Rows("2")) + result = rootTK.MustQuery(`Select authentication_string from mysql.user where user = 'u2' and host = '%'`) + result.Check(testkit.Rows(auth.EncodePassword("Uu3@22223"))) + tk = testkit.NewTestKit(t, store) + err = tk.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "%"}, sha1Password("Uu3@22223"), nil) + require.NoError(t, err) +} + +// Test basic CREATE/ALTER USER with failed-login track. +func TestFailedLoginTrackingBasic(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + createUserTestCases := []struct { + sql string + rsJSON string + user string + }{ + {"CREATE USER 'u1'@'localhost' IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;", + "{\"failed_login_attempts\": 3, \"password_lock_time_days\": 3}", "u1"}, + {"CREATE USER 'u2'@'localhost' IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME UNBOUNDED;", + "{\"failed_login_attempts\": 3, \"password_lock_time_days\": -1}", "u2"}, + {"CREATE USER 'u3'@'localhost' IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3;", + "{\"failed_login_attempts\": 3, \"password_lock_time_days\": 0}", "u3"}, + {"CREATE USER 'u4'@'localhost' IDENTIFIED BY 'password' PASSWORD_LOCK_TIME 3;", + "{\"failed_login_attempts\": 0, \"password_lock_time_days\": 3}", "u4"}, + {"CREATE USER 'u5'@'localhost' IDENTIFIED BY 'password' PASSWORD_LOCK_TIME UNBOUNDED;", + "{\"failed_login_attempts\": 0, \"password_lock_time_days\": -1}", "u5"}, + } + for _, tc := range createUserTestCases { + tk.MustExec(tc.sql) + sql := fmt.Sprintf("SELECT user_attributes->>\"$.Password_locking\" from mysql.user WHERE USER = '%s' AND HOST = 'localhost' for update", tc.user) + tk.MustQuery(sql).Check(testkit.Rows(tc.rsJSON)) + } + + alterUserTestCases := []struct { + sql string + user string + failedLoginAttempts int64 + passwordLockTimeDays int64 + failedLoginCount int64 + comment string + }{ + {"ALTER USER 'u1'@'localhost' FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME 6;", "u1", + 4, 6, 0, ""}, + {"ALTER USER 'u2'@'localhost' FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME UNBOUNDED;", + "u2", 4, -1, 0, ""}, + {"ALTER USER 'u3'@'localhost' PASSWORD_LOCK_TIME 6;", + "u3", 3, 6, 0, ""}, + {"ALTER USER 'u4'@'localhost' FAILED_LOGIN_ATTEMPTS 4;", + "u4", 4, 3, 0, ""}, + {"ALTER USER 'u4'@'localhost' PASSWORD_LOCK_TIME UNBOUNDED;", + "u4", 4, -1, 0, ""}, + {"ALTER USER 'u5'@'localhost' ACCOUNT UNLOCK FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 6;", + "u5", 3, 6, 0, ""}, + {"ALTER USER 'u5'@'localhost' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 6 COMMENT 'Something';", + "u5", 3, 6, 0, "Something"}, + } + for _, tc := range alterUserTestCases { + tk.MustExec(tc.sql) + sql := fmt.Sprintf("SELECT user_attributes from mysql.user WHERE USER = '%s' AND HOST = 'localhost' for update", tc.user) + rs := tk.MustQuery(sql) + buf := bytes.NewBufferString("") + for _, row := range rs.Rows() { + _, err := fmt.Fprintf(buf, "%s\n", row) + require.NoError(t, err) + } + str := buf.String() + var ua []userAttributes + err := json.Unmarshal([]byte(str), &ua) + require.NoError(t, err) + require.Equal(t, tc.failedLoginAttempts, ua[0].PasswordLocking.FailedLoginAttempts, tc.sql, str) + require.Equal(t, tc.passwordLockTimeDays, ua[0].PasswordLocking.PasswordLockTimeDays, tc.sql, str) + require.Equal(t, tc.failedLoginCount, ua[0].PasswordLocking.FailedLoginCount, tc.sql, str) + require.Equal(t, tc.comment, ua[0].Metadata.Comment, tc.sql, str) + } + + tk.MustExec("CREATE USER 'u6'@'localhost' IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;") + tk.MustQuery(" SHOW CREATE USER 'u6'@'localhost';").Check( + testkit.Rows("CREATE USER 'u6'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3")) + + tk.MustExec("CREATE USER 'u7'@'localhost' IDENTIFIED BY 'password';") + tk.MustQuery(" SHOW CREATE USER 'u7'@'localhost';").Check( + testkit.Rows("CREATE USER 'u7'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT")) + + tk.MustExec("CREATE USER 'u8'@'localhost' IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME UNBOUNDED;") + tk.MustQuery(" SHOW CREATE USER 'u8'@'localhost';").Check( + testkit.Rows("CREATE USER 'u8'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME UNBOUNDED")) + + tk.MustExec("ALTER USER 'u4'@'localhost' PASSWORD_LOCK_TIME 0 FAILED_LOGIN_ATTEMPTS 0") + tk.MustQuery("select user_attributes from mysql.user where user = 'u4' and host = 'localhost'").Check(testkit.Rows(`{"resource_group": "default"}`)) + tk.MustExec("ALTER USER 'u4'@'localhost' account unlock") + tk.MustQuery("select user_attributes from mysql.user where user = 'u4' and host = 'localhost'").Check(testkit.Rows(`{"resource_group": "default"}`)) + tk.MustExec("ALTER USER 'u4'@'localhost' PASSWORD_LOCK_TIME 6") + tk.MustQuery("select user_attributes from mysql.user where user = 'u4' and host = 'localhost'").Check(testkit.Rows(`{"Password_locking": {"failed_login_attempts": 0, "password_lock_time_days": 6}, "resource_group": "default"}`)) +} + +func TestUserReuseControl(t *testing.T) { + store := testkit.CreateMockStore(t) + rootTK := testkit.NewTestKit(t, store) + rootTK.MustQuery(`show variables like "password_history"`).Check(testkit.Rows("password_history 0")) + rootTK.MustQuery(`show variables like "password_reuse_interval"`).Check(testkit.Rows("password_reuse_interval 0")) + rootTK.MustExec(`set global password_history = -1`) + rootTK.MustExec(`set global password_reuse_interval = -1`) + rootTK.MustQuery(`show variables like "password_history"`).Check(testkit.Rows("password_history 0")) + rootTK.MustQuery(`show variables like "password_reuse_interval"`).Check(testkit.Rows("password_reuse_interval 0")) + rootTK.MustExec(`set global password_history = 4294967295`) + rootTK.MustExec(`set global password_reuse_interval = 4294967295`) + rootTK.MustQuery(`show variables like "password_history"`).Check(testkit.Rows("password_history 4294967295")) + rootTK.MustQuery(`show variables like "password_reuse_interval"`).Check(testkit.Rows("password_reuse_interval 4294967295")) + rootTK.MustExec(`set global password_history = 4294967296`) + rootTK.MustExec(`set global password_reuse_interval = 4294967296`) + rootTK.MustQuery(`show variables like "password_history"`).Check(testkit.Rows("password_history 4294967295")) + rootTK.MustQuery(`show variables like "password_reuse_interval"`).Check(testkit.Rows("password_reuse_interval 4294967295")) + rootTK.MustGetErrCode(`set session password_history = 42949`, 1229) + rootTK.MustGetErrCode(`set session password_reuse_interval = 42949`, 1229) +} + +func TestUserReuseInfo(t *testing.T) { + store := testkit.CreateMockStore(t) + rootTK := testkit.NewTestKit(t, store) + rootTK.MustExec(`CREATE USER testReuse`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(` `)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 5`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 `)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 0`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`0 `)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY DEFAULT`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(` `)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 65536`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 `)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL 5 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 5`)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL 0 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 0`)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL DEFAULT`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 `)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL 65536 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 65535`)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 6 PASSWORD REUSE INTERVAL 6 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`6 6`)) + rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 6 PASSWORD HISTORY 7 `) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`7 6`)) + + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 5`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 `)) + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD REUSE INTERVAL 5 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(` 5`)) + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD REUSE INTERVAL 5 DAY PASSWORD REUSE INTERVAL 6 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(` 6`)) + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 6 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 6`)) + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD REUSE INTERVAL 6 DAY PASSWORD HISTORY 5`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 6`)) + + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustGetErrCode(`CREATE USER testReuse PASSWORD HISTORY -5`, 1064) + rootTK.MustGetErrCode(`CREATE USER testReuse PASSWORD REUSE INTERVAL -6 DAY`, 1064) + rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 65535 PASSWORD REUSE INTERVAL 65535 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 65535`)) + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 65536 PASSWORD REUSE INTERVAL 65536 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 65535`)) + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(` `)) + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 0 PASSWORD REUSE INTERVAL 0 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`0 0`)) +} + +func TestUserReuseFunction(t *testing.T) { + store := testkit.CreateMockStore(t) + rootTK := testkit.NewTestKit(t, store) + rootTK.MustExec(`CREATE USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`set global password_history = 1;`) + rootTK.MustExec(`alter USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustExec(`DROP USER testReuse`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + + rootTK.MustExec(`set global password_history = 0;`) + rootTK.MustExec(`set global password_reuse_interval = 1;`) + rootTK.MustExec(`CREATE USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`2`)) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`3`)) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`)) + rootTK.MustExec(`update mysql.password_history set Password_timestamp = date_sub(Password_timestamp,interval '1 0:0:1' DAY_SECOND)`) + rootTK.MustExec(`alter USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustExec(`drop USER testReuse `) + + rootTK.MustExec(`set global password_reuse_interval = 0;`) + //password nil is not stored + rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 6 DAY`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`drop USER testReuse `) + + rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY 5`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustExec(`alter USER testReuse identified by 'test4'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`5`)) + rootTK.MustExec(`alter USER testReuse identified by 'test5'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`5`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test1'`, 3638) + rootTK.MustExec(`alter USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`5`)) + rootTK.MustExec(`drop USER testReuse`) + + rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 3 DAY`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustExec(`alter USER testReuse identified by 'test4'`) + rootTK.MustExec(`alter USER testReuse identified by 'test5'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`6`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustExec(`update mysql.password_history set Password_timestamp = date_sub(Password_timestamp,interval '3 0:0:1' DAY_SECOND) where user = 'testReuse' order by Password_timestamp asc limit 1`) + rootTK.MustExec(`alter USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`6`)) + rootTK.MustExec(`drop USER testReuse`) + + rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 3 DAY`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustExec(`update mysql.password_history set Password_timestamp = date_sub(Password_timestamp,interval '3 0:0:1' DAY_SECOND) where user = 'testReuse' order by Password_timestamp asc limit 1`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 3`) + rootTK.MustExec(`alter USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`)) + rootTK.MustExec(`drop USER testReuse`) + + rootTK.MustExec(`set global password_history = 1;`) + rootTK.MustExec(`set global password_reuse_interval = 1;`) + rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY 0 PASSWORD REUSE INTERVAL 0 DAY`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`alter USER testReuse identified by 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`drop USER testReuse`) + + rootTK.MustExec(`set global password_history = 0;`) + rootTK.MustExec(`set global password_reuse_interval = 360000000;`) + rootTK.MustExec(`CREATE USER testReuse identified by 'test'`) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustGetErrCode(`set PASSWORD FOR testReuse = 'test'`, 3638) + rootTK.MustExec(`alter USER testReuse identified by ''`) + rootTK.MustExec(`alter USER testReuse identified by ''`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`2`)) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustExec(`set global password_reuse_interval = 4294967295;`) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`)) + rootTK.MustExec(`set PASSWORD FOR testReuse = 'test4'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`5`)) + rootTK.MustExec(`drop USER testReuse`) + + rootTK.MustExec(`set global password_reuse_interval = 0;`) + rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY 5`) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`2`)) + rootTK.MustExec(`alter USER testReuse identified by 'test1' PASSWORD HISTORY 0`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`alter USER testReuse identified by 'test1' PASSWORD HISTORY 2 PASSWORD REUSE INTERVAL 1 DAY`) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustExec(`alter USER testReuse identified by 'test1' PASSWORD HISTORY 2 PASSWORD REUSE INTERVAL 0 DAY`) + + // Support password and default value modification at the same time. + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`set global password_history = 1`) + rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustGetErrCode(`ALTER USER testReuse identified by 'test' PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`, 3638) + rootTK.MustExec(`ALTER USER testReuse identified by 'test1' PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) +} + +func TestUserReuseDifferentAuth(t *testing.T) { + store := testkit.CreateMockStore(t) + rootTK := testkit.NewTestKit(t, store) + // test caching_sha2_password. + rootTK.MustExec(`CREATE USER testReuse identified with 'caching_sha2_password' by 'test' PASSWORD HISTORY 1 `) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustGetErrCode(`set password for testReuse = 'test'`, 3638) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustExec(`alter USER testReuse identified with 'tidb_sm3_password'`) + // changing the auth method prunes history. + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse identified with 'tidb_sm3_password' by 'test' PASSWORD HISTORY 1 `) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustGetErrCode(`set password for testReuse = 'test'`, 3638) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustExec(`alter USER testReuse identified with 'caching_sha2_password'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustExec(`CREATE USER testReuse identified with 'caching_sha2_password' by 'test' PASSWORD REUSE INTERVAL 1 DAY`) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustGetErrCode(`set password for testReuse = 'test'`, 3638) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustExec(`update mysql.password_history set Password_timestamp = date_sub(Password_timestamp,interval '1 0:0:1' DAY_SECOND) where user = 'testReuse' order by Password_timestamp asc limit 1`) + rootTK.MustExec(`alter USER testReuse identified by 'test'`) + + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustGetErrCode(`CREATE USER testReuse identified with 'mysql_clear_password' by 'test' PASSWORD REUSE INTERVAL 1 DAY`, 1524) + rootTK.MustGetErrCode(`CREATE USER testReuse identified with 'tidb_session_token' by 'test' PASSWORD REUSE INTERVAL 1 DAY`, 1524) + // no password. + rootTK.MustExec(`CREATE USER testReuse identified with 'auth_socket' by 'test' PASSWORD REUSE INTERVAL 1 DAY`) + rootTK.MustExec(`ALTER USER testReuse identified by 'test' `) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustQuery(`SELECT authentication_string FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows("")) + rootTK.MustExec(`ALTER USER testReuse identified with 'caching_sha2_password' by 'test' `) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + // AuthTiDBAuthToken is the token login method on the cloud, + // and the Password Reuse Policy does not take effect. + rootTK.MustExec(`drop USER testReuse`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`CREATE USER testReuse identified with 'tidb_auth_token' by 'test' PASSWORD REUSE INTERVAL 1 DAY`) + rootTK.MustExec(`ALTER USER testReuse identified by 'test' `) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`set password for testReuse = 'test'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustExec(`ALTER USER testReuse identified with 'caching_sha2_password' by 'test' `) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638) + rootTK.MustGetErrCode(`set password for testReuse = 'test'`, 3638) + rootTK.MustExec(`drop USER testReuse`) +} + +func TestUserReuseMultiuser(t *testing.T) { + store := testkit.CreateMockStore(t) + rootTK := testkit.NewTestKit(t, store) + //alter multi user success + rootTK.MustExec(`CREATE USER testReuse identified by 'test', testReuse1 identified by 'test', testReuse2 identified by 'test' PASSWORD HISTORY 65535 PASSWORD REUSE INTERVAL 65535 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user like 'testReuse%'`).Check(testkit.Rows(`65535 65535`, `65535 65535`, `65535 65535`)) + rootTK.MustExec(`ALTER USER testReuse identified by 'test1', testReuse1 identified by 'test1', testReuse2 identified by 'test1' PASSWORD HISTORY 3 PASSWORD REUSE INTERVAL 3 DAY`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user like 'testReuse%'`).Check(testkit.Rows(`3 3`, `3 3`, `3 3`)) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user like 'testReuse%' group by user`).Check(testkit.Rows(`2`, `2`, `2`)) + //alter multi user fail + rootTK.MustExec(`CREATE USER testReuse3 identified by 'test'`) + rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user like 'testReuse%'`).Check(testkit.Rows(`3 3`, `3 3`, `3 3`, ` `)) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user like 'testReuse%' group by user`).Check(testkit.Rows(`2`, `2`, `2`)) + rootTK.MustGetErrCode(`ALTER USER testReuse identified by 'test1', testReuse3 identified by 'test1'`, 3638) + //drop user + rootTK.MustExec(`drop User testReuse, testReuse1, testReuse2, testReuse3`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user like 'testReuse%' `).Check(testkit.Rows(`0`)) +} + +func TestUserReuseRename(t *testing.T) { + store := testkit.CreateMockStore(t) + rootTK := testkit.NewTestKit(t, store) + rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY 5`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`)) + rootTK.MustExec(`alter USER testReuse identified by 'test1'`) + rootTK.MustExec(`alter USER testReuse identified by 'test2'`) + rootTK.MustExec(`alter USER testReuse identified by 'test3'`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`)) + rootTK.MustExec(`rename USER testReuse to testReuse1`) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`)) + rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse1'`).Check(testkit.Rows(`4`)) +} + +func TestUserAlterUser(t *testing.T) { + store := testkit.CreateMockStore(t) + rootTK := testkit.NewTestKit(t, store) + rootTK.MustExec(`CREATE USER test1 IDENTIFIED WITH 'mysql_native_password' BY '1234'`) + alterUserSQL := `ALTER USER 'test1' IDENTIFIED BY '222', 'test_not_exist'@'localhost' IDENTIFIED BY '111';` + rootTK.MustGetErrCode(alterUserSQL, mysql.ErrCannotUser) + result := rootTK.MustQuery(`SELECT authentication_string FROM mysql.User WHERE User="test1" and Host="%"`) + result.Check(testkit.Rows(auth.EncodePassword("1234"))) + alterUserSQL = `ALTER USER IF EXISTS 'test1' IDENTIFIED BY '222', 'test_not_exist'@'localhost' IDENTIFIED BY '111';` + rootTK.MustExec(alterUserSQL) + rootTK.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Note|3162|User 'test_not_exist'@'localhost' does not exist.")) + result = rootTK.MustQuery(`SELECT authentication_string FROM mysql.User WHERE User="test1" and Host="%"`) + result.Check(testkit.Rows(auth.EncodePassword("222"))) +} + +func sha1Password(s string) []byte { + crypt := sha1.New() + crypt.Write([]byte(s)) + hashStage1 := crypt.Sum(nil) + crypt.Reset() + crypt.Write(hashStage1) + hashStage2 := crypt.Sum(nil) + crypt.Reset() + crypt.Write(hashStage2) + hashStage3 := crypt.Sum(nil) + for i := range hashStage3 { + hashStage3[i] ^= hashStage1[i] + } + return hashStage3 +} + +func TestFailedLoginTracking(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + // Set FAILED_LOGIN_ATTEMPTS to 1, and check error messages after login failure once. + createAndCheck(tk, "CREATE USER 'testu1'@'localhost' IDENTIFIED BY 'testu1' FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1", + "{\"Password_locking\": {\"failed_login_attempts\": 1, \"password_lock_time_days\": 1}, \"resource_group\": \"default\"}", "testu1") + err := tk.Session().Auth(&auth.UserIdentity{Username: "testu1", Hostname: "localhost"}, sha1Password("password"), nil) + lds := strconv.FormatInt(1, 10) + errTarget := privileges.GenerateAccountAutoLockErr(1, "testu1", "localhost", lds, lds) + require.Equal(t, err.Error(), errTarget.Error()) + checkAuthUser(t, tk, "testu1", 1, "Y") + + // Check the login error message after the account is locked. + err = tk.Session().Auth(&auth.UserIdentity{Username: "testu1", Hostname: "localhost"}, sha1Password("password"), nil) + require.Equal(t, err.Error(), errTarget.Error()) + checkAuthUser(t, tk, "testu1", 1, "Y") + + // Set FAILED_LOGIN_ATTEMPTS to 1 and PASSWORD_LOCK_TIME to UNBOUNDED. Check error messages after failed login once. + createAndCheck(tk, "CREATE USER 'testu2'@'localhost' IDENTIFIED BY 'testu2' FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME UNBOUNDED", + "{\"Password_locking\": {\"failed_login_attempts\": 1, \"password_lock_time_days\": -1}, \"resource_group\": \"default\"}", "testu2") + err = tk.Session().Auth(&auth.UserIdentity{Username: "testu2", Hostname: "localhost"}, sha1Password("password"), nil) + errTarget = privileges.GenerateAccountAutoLockErr(1, "testu2", "localhost", "unlimited", "unlimited") + require.Equal(t, err.Error(), errTarget.Error()) + checkAuthUser(t, tk, "testu2", 1, "Y") + + // Check the login error message after the account is locked. + err = tk.Session().Auth(&auth.UserIdentity{Username: "testu2", Hostname: "localhost"}, sha1Password("password"), nil) + require.Equal(t, err.Error(), errTarget.Error()) + checkAuthUser(t, tk, "testu2", 1, "Y") + + // Set FAILED_LOGIN_ATTEMPTS to 0 or PASSWORD_LOCK_TIME to 0. Check error messages after failed login once. + createAndCheck(tk, "CREATE USER 'testu3'@'localhost' IDENTIFIED BY 'testu3' FAILED_LOGIN_ATTEMPTS 0 PASSWORD_LOCK_TIME UNBOUNDED", + "{\"Password_locking\": {\"failed_login_attempts\": 0, \"password_lock_time_days\": -1}, \"resource_group\": \"default\"}", "testu3") + err = tk.Session().Auth(&auth.UserIdentity{Username: "testu3", Hostname: "localhost"}, sha1Password("password"), nil) + require.ErrorContains(t, err, "Access denied for user 'testu3'@'localhost' (using password: YES)") + checkAuthUser(t, tk, "testu3", 0, "") + createAndCheck(tk, "CREATE USER 'testu4'@'localhost' IDENTIFIED BY 'testu4' FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 0", + "{\"Password_locking\": {\"failed_login_attempts\": 1, \"password_lock_time_days\": 0}, \"resource_group\": \"default\"}", "testu4") + err = tk.Session().Auth(&auth.UserIdentity{Username: "testu4", Hostname: "localhost"}, sha1Password("password"), nil) + require.ErrorContains(t, err, "Access denied for user 'testu4'@'localhost' (using password: YES)") + checkAuthUser(t, tk, "testu4", 0, "") + tk.MustExec("CREATE USER 'testu5'@'localhost' IDENTIFIED BY 'testu5' FAILED_LOGIN_ATTEMPTS 0 PASSWORD_LOCK_TIME 0") + err = tk.Session().Auth(&auth.UserIdentity{Username: "testu5", Hostname: "localhost"}, sha1Password("password"), nil) + require.ErrorContains(t, err, "Access denied for user 'testu5'@'localhost' (using password: YES)") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu5' and host = 'localhost'").Check(testkit.Rows("{\"resource_group\": \"default\"}")) + + tk.MustExec("DROP USER 'testu1'@'localhost', 'testu2'@'localhost', 'testu3'@'localhost', 'testu4'@'localhost', 'testu5'@'localhost'") + + // Create user specifying only comment. + tk.MustExec("CREATE USER 'testu1'@'localhost' IDENTIFIED BY 'testu1' comment 'testcomment' ") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu1' and host = 'localhost'"). + Check(testkit.Rows("{\"metadata\": {\"comment\": \"testcomment\"}, \"resource_group\": \"default\"}")) + + // Create user specifying only attribute. + tk.MustExec("create user testu2@'localhost' identified by 'testu2' ATTRIBUTE '{\"attribute\":\"testattribute\"}'") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu2' and host = 'localhost'"). + Check(testkit.Rows("{\"metadata\": {\"attribute\": \"testattribute\"}, \"resource_group\": \"default\"}")) + + // Create user specified comment and FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME. + tk.MustExec("create user testu3@'localhost' identified by 'testu3' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1 comment 'testcomment'") + checkUserUserAttributes(tk, "testu3", "localhost", "1 1 {\"comment\": \"testcomment\"}") + + // Create user specified attribute and FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME. + tk.MustExec("create user testu4@'localhost' identified by 'testu4' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1 ATTRIBUTE '{\"attribute\":\"testattribute\"}'") + checkUserUserAttributes(tk, "testu4", "localhost", "1 1 {\"attribute\": \"testattribute\"}") + + // Create user specified comment, FAILED_LOGIN_ATTEMPTS, and PASSWORD_LOCK_TIME, + // and confirm the user_attributes column value after login fails. + tk.MustExec("create user testu5@'localhost' identified by 'testu5' FAILED_LOGIN_ATTEMPTS 2 " + + "PASSWORD_LOCK_TIME 1 comment 'testcomment'") + checkUserUserAttributes(tk, "testu5", "localhost", "2 1 {\"comment\": \"testcomment\"}") + + // Confirm the user_attributes value after login failure once. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu5", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu5", "localhost", "2 \"N\" 1 1 {\"comment\": \"testcomment\"}") + + // After the number of failed login attempts reaches FAILED_LOGIN_ATTEMPTS, check the account lock status. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu5", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu5", "localhost", "2 \"Y\" 2 1 {\"comment\": \"testcomment\"}") + // After the account is locked, manually unlock the account and check the user_attributes value. + tk.MustExec("alter user testu5@'localhost' account unlock") + checkUserUserAttributes(tk, "testu5", "localhost", "2 \"N\" 0 1 {\"comment\": \"testcomment\"}") + + // Create user specified comment, FAILED_LOGIN_ATTEMPTS, and PASSWORD_LOCK_TIME, + // and confirm the user_attributes column value after login fails. + tk.MustExec("create user testu6@'localhost' identified by '' FAILED_LOGIN_ATTEMPTS 2 PASSWORD_LOCK_TIME 1 " + + "comment 'testcomment'") + // Confirm the user_attributes value after login failure once. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu6", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu6", "localhost", "2 \"N\" 1 1 {\"comment\": \"testcomment\"}") + + // After the number of failed login attempts reaches FAILED_LOGIN_ATTEMPTS, check the account lock status. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu6", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu6", "localhost", "2 \"Y\" 2 1 {\"comment\": \"testcomment\"}") + + // After the account is automatically locked, change the lock time and check + // the user_attributes value after logging in successfully. + changeAutoLockedLastChanged(tk, "-72h1s", "testu6") + sk1 := testkit.NewTestKit(t, store) + require.NoError(t, sk1.Session().Auth(&auth.UserIdentity{Username: "testu6", Hostname: "localhost"}, nil, nil)) + checkUserUserAttributes(tk, "testu6", "localhost", "3 \"N\" 0 3 {\"comment\": \"testcomment\"}") + + // Create user specified attributes, FAILED_LOGIN_ATTEMPTS, and PASSWORD_LOCK_TIME, + // and confirm the user_attributes column value after login fails. + tk.MustExec("create user testu7@'localhost' identified by 'testu7' FAILED_LOGIN_ATTEMPTS 2 PASSWORD_LOCK_TIME 1 " + + "ATTRIBUTE '{\"attribute\":\"testattribute\"}'") + checkUserUserAttributes(tk, "testu7", "localhost", "2 1 {\"attribute\": \"testattribute\"}") + + // Confirm the user_attributes value after login failure once. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu7", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu7", "localhost", "2 \"N\" 1 1 {\"attribute\": \"testattribute\"}") + + // After the number of failed login attempts reaches FAILED_LOGIN_ATTEMPTS, check the account lock status. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu7", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu7", "localhost", "2 \"Y\" 2 1 {\"attribute\": \"testattribute\"}") + + // After the account is locked, manually unlock the account and check the user_attributes value. + tk.MustExec("alter user testu7@'localhost' account unlock") + checkUserUserAttributes(tk, "testu7", "localhost", "2 \"N\" 0 1 {\"attribute\": \"testattribute\"}") + + tk.MustExec("create user testu8@'localhost' identified by '' FAILED_LOGIN_ATTEMPTS 2 PASSWORD_LOCK_TIME 1" + + " ATTRIBUTE '{\"attribute\":\"testattribute\"}'") + // Confirm the user_attributes value after login failure once. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu8", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu8", "localhost", "2 \"N\" 1 1 {\"attribute\": \"testattribute\"}") + + // After the number of failed login attempts reaches FAILED_LOGIN_ATTEMPTS, check the account lock status. + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu8", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu8", "localhost", "2 \"Y\" 2 1 {\"attribute\": \"testattribute\"}") + + // After the account is automatically locked, change the lock time and check + // the user_attributes value after logging in successfully. + changeAutoLockedLastChanged(tk, "-72h1s", "testu8") + sk2 := testkit.NewTestKit(t, store) + require.NoError(t, sk2.Session().Auth(&auth.UserIdentity{Username: "testu8", Hostname: "localhost"}, nil, nil)) + checkUserUserAttributes(tk, "testu8", "localhost", "3 \"N\" 0 3 {\"attribute\": \"testattribute\"}") + + // FAILED_LOGIN_ATTEMPTS is set to 2 . check user_attributes value after + // the user login fails once ,and login success at second time. + tk.MustExec("create user testu9@'localhost' identified by '' FAILED_LOGIN_ATTEMPTS 2 PASSWORD_LOCK_TIME 1" + + " comment 'testcomment'") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu9", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu9", "localhost", "2 \"N\" 1 1 {\"comment\": \"testcomment\"}") + sk3 := testkit.NewTestKit(t, store) + require.NoError(t, sk3.Session().Auth(&auth.UserIdentity{Username: "testu9", Hostname: "localhost"}, + nil, nil)) + checkUserUserAttributes(tk, "testu9", "localhost", "2 \"N\" 0 1 {\"comment\": \"testcomment\"}") + + // FAILED_LOGIN_ATTEMPTS or PASSWORD_LOCK_TIME is set to 0. Check user_attributes value after login fail. + tk.MustExec("create user testu10@'localhost' identified by '' FAILED_LOGIN_ATTEMPTS 2 PASSWORD_LOCK_TIME 0 " + + "comment 'testcomment'") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu10", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu10", "localhost", "2 0 {\"comment\": \"testcomment\"}") + + tk.MustExec("create user testu11@'localhost' identified by '' FAILED_LOGIN_ATTEMPTS 0 PASSWORD_LOCK_TIME 2 " + + "comment 'testcomment'") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu11", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu11", "localhost", "0 2 {\"comment\": \"testcomment\"}") + + // The account is automatically locked after the user specifies FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME. + // Change FAILED_LOGIN_ATTEMPTS or PASSWORD_LOCK_TIME to 0, and check whether the user can login. + tk.MustExec("create user testu12@'localhost' identified by '' FAILED_LOGIN_ATTEMPTS 2 PASSWORD_LOCK_TIME 1 " + + "comment 'testcomment'") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu12", Hostname: "localhost"}, + sha1Password("password"), nil)) + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu12", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu12", "localhost", "2 \"Y\" 2 1 {\"comment\": \"testcomment\"}") + tk.MustExec("alter user testu12@'localhost' FAILED_LOGIN_ATTEMPTS 0") + checkUserUserAttributes(tk, "testu12", "localhost", "0 \"Y\" 2 1 {\"comment\": \"testcomment\"}") + sk4 := testkit.NewTestKit(t, store) + require.NoError(t, sk4.Session().Auth(&auth.UserIdentity{Username: "testu12", Hostname: "localhost"}, + nil, nil)) + + rootk := testkit.NewTestKit(t, store) + createAndCheck(tk, "CREATE USER 'u6'@'localhost' IDENTIFIED BY '' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3", + "{\"Password_locking\": {\"failed_login_attempts\": 3, \"password_lock_time_days\": 3}, \"resource_group\": \"default\"}", "u6") + createAndCheck(tk, "CREATE USER 'u5'@'localhost' IDENTIFIED BY '' FAILED_LOGIN_ATTEMPTS 60 PASSWORD_LOCK_TIME 3", + "{\"Password_locking\": {\"failed_login_attempts\": 60, \"password_lock_time_days\": 3}, \"resource_group\": \"default\"}", "u5") + + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 1, "N") + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, nil, nil)) + checkAuthUser(t, rootk, "u6", 0, "N") + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 1, "N") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 2, "N") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 3, "Y") + + changeAutoLockedLastChanged(rootk, "-72h1s", "u6") + loadUser(t, tk, 1, rootk) + checkAuthUser(t, rootk, "u6", 3, "Y") + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, nil, nil)) + checkAuthUser(t, rootk, "u6", 0, "N") + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 1, "N") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 2, "N") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 3, "Y") + alterAndCheck(t, rootk, "ALTER USER 'u6'@'localhost' ACCOUNT UNLOCK;", "u6", 3, 3, 0) + loadUser(t, tk, 2, rootk) + checkAuthUser(t, rootk, "u6", 0, "N") + + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 1, "N") + alterAndCheck(t, rootk, "ALTER USER 'u6'@'localhost' ACCOUNT UNLOCK;", "u6", 3, 3, 0) + checkAuthUser(t, rootk, "u6", 0, "N") + + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 1, "N") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 2, "N") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 3, "Y") + changeAutoLockedLastChanged(rootk, "-72h1s", "u6") + loadUser(t, tk, 3, rootk) + checkAuthUser(t, rootk, "u6", 3, "Y") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u6", 1, "N") + + createAndCheck(rootk, "CREATE USER 'u1'@'localhost' IDENTIFIED BY '' FAILED_LOGIN_ATTEMPTS 3", + "{\"Password_locking\": {\"failed_login_attempts\": 3, \"password_lock_time_days\": 0}, \"resource_group\": \"default\"}", "u1") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u6", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u1", 0, "") + alterAndCheck(t, rootk, "ALTER USER 'u1'@'localhost' PASSWORD_LOCK_TIME 6;", "u1", 3, 6, 0) + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u1", 1, "N") +} + +func TestFailedLoginTrackingAlterUser(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + // Create user specifying only comment. + tk.MustExec("CREATE USER 'testu1'@'localhost' IDENTIFIED BY 'testu1' comment 'testcomment' ") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu1' and host = 'localhost'"). + Check(testkit.Rows("{\"metadata\": {\"comment\": \"testcomment\"}, \"resource_group\": \"default\"}")) + tk.MustExec("Alter USER 'testu1'@'localhost' comment ''") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu1' and host = 'localhost'"). + Check(testkit.Rows("{\"metadata\": {\"comment\": \"\"}, \"resource_group\": \"default\"}")) + + // Create user specifying only attribute. + tk.MustExec("CREATE USER 'testu2'@'localhost' IDENTIFIED BY 'testu2' ATTRIBUTE '{\"attribute\":\"testattribute\"}'") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu2' and host = 'localhost'"). + Check(testkit.Rows("{\"metadata\": {\"attribute\": \"testattribute\"}, \"resource_group\": \"default\"}")) + tk.MustExec("Alter USER 'testu2'@'localhost' ATTRIBUTE '{\"attribute\":\"test\"}'") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu2' and host = 'localhost'"). + Check(testkit.Rows("{\"metadata\": {\"attribute\": \"test\"}, \"resource_group\": \"default\"}")) + + // Create a user and specify FAILED_LOGIN_ATTEMPTS, PASSWORD_LOCK_TIME, and COMMENT. + // Check the user_attributes value after alter user. + tk.MustExec("CREATE USER 'testu3'@'localhost' IDENTIFIED BY 'testu3' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1 comment 'testcomment'") + checkUserUserAttributes(tk, "testu3", "localhost", "1 1 {\"comment\": \"testcomment\"}") + tk.MustExec("alter user 'testu3'@'localhost' FAILED_LOGIN_ATTEMPTS 0") + checkUserUserAttributes(tk, "testu3", "localhost", "0 1 {\"comment\": \"testcomment\"}") + tk.MustExec("alter user 'testu3'@'localhost' PASSWORD_LOCK_TIME 0") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking')," + + "JSON_EXTRACT(user_attributes, '$.metadata')from mysql.user where user= 'testu3' and host = 'localhost'"). + Check(testkit.Rows(" {\"comment\": \"testcomment\"}")) + + // Create a user and specify FAILED_LOGIN_ATTEMPTS, PASSWORD_LOCK_TIME, and ATTRIBUTE. + // Check the user_attributes value after alter user. + tk.MustExec("CREATE USER 'testu4'@'localhost' IDENTIFIED BY 'testu4' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1 ATTRIBUTE '{\"attribute\":\"testattribute\"}'") + checkUserUserAttributes(tk, "testu4", "localhost", "1 1 {\"attribute\": \"testattribute\"}") + tk.MustExec("alter user 'testu4'@'localhost' FAILED_LOGIN_ATTEMPTS 0") + checkUserUserAttributes(tk, "testu4", "localhost", "0 1 {\"attribute\": \"testattribute\"}") + tk.MustExec("alter user 'testu4'@'localhost' PASSWORD_LOCK_TIME 0") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking')," + + "JSON_EXTRACT(user_attributes, '$.metadata')from mysql.user where user= 'testu4' and host = 'localhost'"). + Check(testkit.Rows(" {\"attribute\": \"testattribute\"}")) + + // Create a user and specify FAILED_LOGIN_ATTEMPTS, PASSWORD_LOCK_TIME, and ATTRIBUTE. + // Check the user_attributes value after alter user. + tk.MustExec("CREATE USER 'testu5'@'localhost' IDENTIFIED BY 'testu5' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1 ATTRIBUTE '{\"attribute\":\"testattribute\"}'") + checkUserUserAttributes(tk, "testu5", "localhost", "1 1 {\"attribute\": \"testattribute\"}") + tk.MustExec("alter user 'testu5'@'localhost' FAILED_LOGIN_ATTEMPTS 0 PASSWORD_LOCK_TIME 0 ATTRIBUTE '{\"attribute\":\"test\"}'") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking')," + + "JSON_EXTRACT(user_attributes, '$.metadata')from mysql.user where user= 'testu5' and host = 'localhost'"). + Check(testkit.Rows(" {\"attribute\": \"test\"}")) + + // Create a user to specify a comment, modify the user to add an ATTRIBUTE, + // modify the user to delete a comment, and check the user_attributes value. + tk.MustExec("CREATE USER 'testu6'@'localhost' IDENTIFIED BY 'testu6' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1 comment 'testcomment'") + checkUserUserAttributes(tk, "testu6", "localhost", "1 1 {\"comment\": \"testcomment\"}") + tk.MustExec("alter user 'testu6'@'localhost' ATTRIBUTE '{\"attribute\": \"testattribute\"}'") + checkUserUserAttributes(tk, "testu6", "localhost", "1 1 {\"attribute\": \"testattribute\", \"comment\": \"testcomment\"}") + tk.MustExec("alter user 'testu6'@'localhost' ATTRIBUTE '{\"comment\": null}'") + checkUserUserAttributes(tk, "testu6", "localhost", "1 1 {\"attribute\": \"testattribute\"}") + + // After consecutive login failures and the account is locked, + // change the values of FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME to 0 and check the user_attributes value + tk.MustExec("CREATE USER 'testu7'@'localhost' IDENTIFIED BY 'testu7' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1 comment 'testcomment'") + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu7", Hostname: "localhost"}, + sha1Password("password"), nil)) + checkUserUserAttributes(tk, "testu7", "localhost", "1 \"Y\" 1 1 {\"comment\": \"testcomment\"}") + tk.MustExec("alter user 'testu7'@'localhost' FAILED_LOGIN_ATTEMPTS 0 PASSWORD_LOCK_TIME 0") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking'),JSON_EXTRACT(user_attributes,'$.metadata') " + + "from mysql.user where user='testu7' and host ='localhost'").Check(testkit.Rows(" {\"comment\": \"testcomment\"}")) + + // Create a user and specify FAILED_LOGIN_ATTEMPTS, PASSWORD_LOCK_TIME. + // Check the user_attributes value after alter user. + tk.MustExec("CREATE USER 'testu8'@'localhost' IDENTIFIED BY 'testu5' FAILED_LOGIN_ATTEMPTS 1 " + + "PASSWORD_LOCK_TIME 1") + checkUserUserAttributes(tk, "testu8", "localhost", "1 1 ") + tk.MustExec("alter user 'testu8'@'localhost' FAILED_LOGIN_ATTEMPTS 0 PASSWORD_LOCK_TIME 0") + tk.MustQuery("select user_attributes from mysql.user where user= 'testu8' and host = 'localhost'"). + Check(testkit.Rows("{\"resource_group\": \"default\"}")) + + // Specify only FAILED_LOGIN_ATTEMPTS one attribute when creating user. + // Change the value to 0 and check the user_attributes value. + tk.MustExec("CREATE USER 'testu9'@'localhost' IDENTIFIED BY 'testu9' FAILED_LOGIN_ATTEMPTS 1 ") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_attempts') " + + "from mysql.user where user='testu9' and host ='localhost'").Check(testkit.Rows("1")) + tk.MustExec("ALTER USER 'testu9'@'localhost' FAILED_LOGIN_ATTEMPTS 0") + tk.MustQuery("select user_attributes from mysql.user where user='testu9' and host ='localhost'").Check(testkit.Rows("{\"resource_group\": \"default\"}")) + + // Specify only PASSWORD_LOCK_TIME one attribute when creating user. + // Change the value to 0 and check the user_attributes value. + tk.MustExec("CREATE USER 'testu10'@'localhost' IDENTIFIED BY 'testu10' PASSWORD_LOCK_TIME 1 ") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking.password_lock_time_days') " + + "from mysql.user where user='testu10' and host ='localhost'").Check(testkit.Rows("1")) + tk.MustExec("ALTER USER 'testu10'@'localhost' PASSWORD_LOCK_TIME 0") + tk.MustQuery("select user_attributes from mysql.user where user='testu10' and host ='localhost'").Check(testkit.Rows("{\"resource_group\": \"default\"}")) + + // Specify FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME attributes when creating user , + // change the values of the two attributes to 0, and check the value of user_attributes. + tk.MustExec("CREATE USER 'testu11'@'localhost' IDENTIFIED BY 'testu11' FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1 ") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_attempts')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.password_lock_time_days') " + + "from mysql.user where user='testu11' and host ='localhost'").Check(testkit.Rows("1 1")) + tk.MustExec("ALTER USER 'testu11'@'localhost' PASSWORD_LOCK_TIME 0") + tk.MustQuery("select JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_attempts')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.password_lock_time_days') " + + "from mysql.user where user='testu11' and host ='localhost'").Check(testkit.Rows("1 0")) + tk.MustExec("ALTER USER 'testu11'@'localhost' FAILED_LOGIN_ATTEMPTS 0") + tk.MustQuery("select user_attributes " + + "from mysql.user where user='testu11' and host ='localhost'").Check(testkit.Rows("{\"resource_group\": \"default\"}")) + + rootTK := testkit.NewTestKit(t, store) + sql := new(strings.Builder) + checkUserAttributes := "select JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_attempts')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.auto_account_locked')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_count')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.password_lock_time_days')," + + "JSON_EXTRACT(user_attributes, '$.metadata')from mysql.user where user= %? and host = %?" + err := domain.GetDomain(rootTK.Session()).NotifyUpdatePrivilege() + require.NoError(t, err) + rootTK.MustExec(`CREATE USER test1 IDENTIFIED BY '1234' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3 COMMENT 'test'`) + err = tk.Session().Auth(&auth.UserIdentity{Username: "test1", Hostname: "%"}, sha1Password("1234"), nil) + require.NoError(t, err) + sqlexec.MustFormatSQL(sql, checkUserAttributes, "test1", "%") + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`3 3 {"comment": "test"}`)) + tk = testkit.NewTestKit(t, store) + err = tk.Session().Auth(&auth.UserIdentity{Username: "test1", Hostname: "%"}, sha1Password(""), nil) + require.Error(t, err) + + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`3 "N" 1 3 {"comment": "test"}`)) + rootTK.MustExec(`Alter user test1 FAILED_LOGIN_ATTEMPTS 4 `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "N" 1 3 {"comment": "test"}`)) + rootTK.MustExec(`Alter user test1 PASSWORD_LOCK_TIME 4 `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "N" 1 4 {"comment": "test"}`)) + rootTK.MustExec(`Alter user test1 COMMENT 'test1' `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "N" 1 4 {"comment": "test1"}`)) + rootTK.MustExec(`Alter user test1 FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3 COMMENT 'test'`) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`3 "N" 1 3 {"comment": "test"}`)) + + err = tk.Session().Auth(&auth.UserIdentity{Username: "test1", Hostname: "%"}, sha1Password(""), nil) + require.Error(t, err) + err = tk.Session().Auth(&auth.UserIdentity{Username: "test1", Hostname: "%"}, sha1Password(""), nil) + require.Error(t, err) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`3 "Y" 3 3 {"comment": "test"}`)) + rootTK.MustExec(`Alter user test1 FAILED_LOGIN_ATTEMPTS 4 `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "Y" 3 3 {"comment": "test"}`)) + rootTK.MustExec(`Alter user test1 PASSWORD_LOCK_TIME 4 `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "Y" 3 4 {"comment": "test"}`)) + rootTK.MustExec(`Alter user test1 COMMENT 'test2' `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "Y" 3 4 {"comment": "test2"}`)) + rootTK.MustExec(`Alter user test1 account unlock `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "N" 0 4 {"comment": "test2"}`)) + + rootTK.MustExec(`Alter user test1 FAILED_LOGIN_ATTEMPTS 0 `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`0 "N" 0 4 {"comment": "test2"}`)) + rootTK.MustExec(`Alter user test1 PASSWORD_LOCK_TIME 0 `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(` {"comment": "test2"}`)) + + rootTK.MustExec(`Alter user test1 account unlock `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(` {"comment": "test2"}`)) + rootTK.MustExec(`Alter user test1 FAILED_LOGIN_ATTEMPTS 4 `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 0 {"comment": "test2"}`)) + rootTK.MustExec(`Alter user test1 account unlock `) + rootTK.MustQuery(sql.String()).Check(testkit.Rows(`4 "N" 0 0 {"comment": "test2"}`)) +} + +func TestFailedLoginTrackingCheckPrivilges(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + createAndCheck(tk, "CREATE USER 'testu1'@'localhost' IDENTIFIED BY '' FAILED_LOGIN_ATTEMPTS 1 PASSWORD_LOCK_TIME 1", + "{\"Password_locking\": {\"failed_login_attempts\": 1, \"password_lock_time_days\": 1}, \"resource_group\": \"default\"}", "testu1") + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "testu1", Hostname: "localhost"}, nil, nil)) + // Specify FAILED_LOGIN_ATTEMPTS and PASSWORD_LOCK_TIME attributes when creating user , + // Check user privileges after successful login. + tk.MustQuery(`show grants`).Check(testkit.Rows("GRANT USAGE ON *.* TO 'testu1'@'localhost'")) + tk.MustQuery(`select user()`).Check(testkit.Rows("testu1@localhost")) +} + +func TestUserPassword(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`set global validate_password.enable = ON`) + + testcases := []struct { + errSQL string + sucSQL string + user string + host string + rsJSON string + simplePassword string + strongPassword string + }{ + { + "CREATE USER 'u1'@'localhost' IDENTIFIED BY 'qwe123' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 4;", + "CREATE USER 'u1'@'localhost' IDENTIFIED BY '!@#HASHhs123' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 4;", + "u1", + "localhost", + "{\"Password_locking\": {\"failed_login_attempts\": 3, \"password_lock_time_days\": 4}, \"resource_group\": \"default\"}", + "qwe123", + "!@#HASHhs123", + }, + { + `CREATE USER 'u2'@'localhost' IDENTIFIED BY 'qwe123' FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME 3 COMMENT 'Some statements to test create user'`, + `CREATE USER 'u2'@'localhost' IDENTIFIED BY '!@#HASHhs123' FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME 3 COMMENT 'Some statements to test create user'`, + "u2", + "localhost", + "{\"Password_locking\": {\"failed_login_attempts\": 4, \"password_lock_time_days\": 3}, \"metadata\": {\"comment\": \"Some statements to test create user\"}, \"resource_group\": \"default\"}", + "qwe123", + "!@#HASHhs123", + }, + } + for _, tc := range testcases { + tk := testkit.NewTestKit(t, store) + rootk := testkit.NewTestKit(t, store) + createAndCheckToErr(t, rootk, tc.errSQL, tc.user) + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: tc.user, Hostname: tc.host}, sha1Password(tc.simplePassword), nil)) + createAndCheck(rootk, tc.sucSQL, tc.rsJSON, tc.user) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: tc.user, Hostname: tc.host}, sha1Password(tc.strongPassword), nil)) + } +} + +func TestPasswordExpiredAndTacking(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + user := "u3" + host := "localhost" + tk.MustExec(`set global validate_password.enable = ON`) + tk = testkit.NewTestKit(t, store) + createAndCheckToErr(t, tk, `CREATE USER 'u3'@'localhost' IDENTIFIED BY 'qwe123' PASSWORD EXPIRE INTERVAL 3 DAY FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME 3 COMMENT 'Some statements to test create user'`, user) + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: user, Hostname: host}, sha1Password("qwe123"), nil)) + tk = testkit.NewTestKit(t, store) + createAndCheck(tk, `CREATE USER 'u3'@'localhost' IDENTIFIED BY '!@#HASHhs123' PASSWORD EXPIRE INTERVAL 3 DAY FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME 3 COMMENT 'Some statements to test create user'`, + "{\"Password_locking\": {\"failed_login_attempts\": 4, \"password_lock_time_days\": 3}, \"metadata\": {\"comment\": \"Some statements to test create user\"}, \"resource_group\": \"default\"}", user) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: user, Hostname: host}, sha1Password("!@#HASHhs123"), nil)) + + tk = testkit.NewTestKit(t, store) + tk.MustExec(fmt.Sprintf("ALTER USER '%s'@'%s' PASSWORD EXPIRE NEVER", user, host)) + tk = testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: user, Hostname: host}, sha1Password("!@#HASHhs123"), nil)) + + loginFailedAncCheck(t, store, user, host, "password", 1, "N") + loginSucAncCheck(t, store, user, host, "!@#HASHhs123", 0, "N") + loginFailedAncCheck(t, store, user, host, "password", 1, "N") + loginFailedAncCheck(t, store, user, host, "password", 2, "N") + loginFailedAncCheck(t, store, user, host, "password", 3, "N") + loginFailedAncCheck(t, store, user, host, "password", 4, "Y") + + tk = testkit.NewTestKit(t, store) + tk.MustExec(fmt.Sprintf("ALTER USER '%s'@'%s' PASSWORD EXPIRE", user, host)) + tk = testkit.NewTestKit(t, store) + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: user, Hostname: host}, sha1Password("!@#HASHhs123"), nil)) +} + +func loginFailedAncCheck(t *testing.T, store kv.Storage, user, host, password string, failedLoginCount int64, autoAccountLocked string) { + tk := testkit.NewTestKit(t, store) + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: user, Hostname: host}, sha1Password(password), nil)) + checkAuthUser(t, tk, user, failedLoginCount, autoAccountLocked) +} + +func loginSucAncCheck(t *testing.T, store kv.Storage, user, host, password string, failedLoginCount int64, autoAccountLocked string) { + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: user, Hostname: host}, sha1Password(password), nil)) + tk = testkit.NewTestKit(t, store) + checkAuthUser(t, tk, user, failedLoginCount, autoAccountLocked) +} + +func loadUser(t *testing.T, tk *testkit.TestKit, useCount int64, rootk *testkit.TestKit) { + require.Error(t, tk.Session().Auth(&auth.UserIdentity{Username: "u5", Hostname: "localhost"}, sha1Password("password"), nil)) + checkAuthUser(t, rootk, "u5", useCount, "N") +} + +func changeAutoLockedLastChanged(tk *testkit.TestKit, ds, user string) { + SQL := "UPDATE `mysql`.`User` SET user_attributes=json_merge_patch(user_attributes, '{\"Password_locking\": {\"failed_login_attempts\": 3," + + "\"password_lock_time_days\": 3,\"auto_account_locked\": \"Y\",\"failed_login_count\": 3,\"auto_locked_last_changed\": \"%s\"}}') " + + "WHERE Host='localhost' and User='%s'" + d, _ := time.ParseDuration(ds) + changeTime := time.Now().Add(d).Format(time.UnixDate) + SQL = fmt.Sprintf(SQL, changeTime, user) + tk.MustExec(SQL) + domain.GetDomain(tk.Session()).NotifyUpdatePrivilege() +} + +func checkUserUserAttributes(tk *testkit.TestKit, user, host, row string) { + sqlTemplate := "select JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_attempts')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.auto_account_locked')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.failed_login_count')," + + "JSON_EXTRACT(user_attributes, '$.Password_locking.password_lock_time_days')," + + "JSON_EXTRACT(user_attributes, '$.metadata')from mysql.user where user= %? and host = %?" + userAttributesSQL := new(strings.Builder) + sqlexec.MustFormatSQL(userAttributesSQL, sqlTemplate, user, host) + tk.MustQuery(userAttributesSQL.String()).Check(testkit.Rows(row)) +} + +func alterAndCheck(t *testing.T, tk *testkit.TestKit, sql string, user string, failedLoginAttempts, passwordLockTimeDays, failedLoginCount int64) { + tk.MustExec(sql) + userAttributesSQL := selectSQL(user) + resBuff := bytes.NewBufferString("") + rs := tk.MustQuery(userAttributesSQL) + for _, row := range rs.Rows() { + _, err := fmt.Fprintf(resBuff, "%s\n", row) + require.NoError(t, err) + } + err := checkUser(t, resBuff.String(), failedLoginAttempts, passwordLockTimeDays, failedLoginCount) + require.NoError(t, err) +} + +func checkUser(t *testing.T, rs string, failedLoginAttempts, passwordLockTimeDays, failedLoginCount int64) error { + var ua []userAttributes + if err := json.Unmarshal([]byte(rs), &ua); err != nil { + return err + } + require.Equal(t, failedLoginAttempts, ua[0].PasswordLocking.FailedLoginAttempts) + require.Equal(t, passwordLockTimeDays, ua[0].PasswordLocking.PasswordLockTimeDays) + require.Equal(t, failedLoginCount, ua[0].PasswordLocking.FailedLoginCount) + return nil +} + +func createAndCheck(tk *testkit.TestKit, sql, rsJSON, user string) { + tk.MustExec(sql) + sql = selectSQL(user) + tk.MustQuery(sql).Check(testkit.Rows(rsJSON)) +} + +func createAndCheckToErr(t *testing.T, tk *testkit.TestKit, sql, user string) { + tk.MustExecToErr(sql) + sql = selectSQL(user) + require.Equal(t, 0, len(tk.MustQuery(sql).Rows())) +} + +func checkAuthUser(t *testing.T, tk *testkit.TestKit, user string, failedLoginCount int64, autoAccountLocked string) { + userAttributesSQL := selectSQL(user) + resBuff := bytes.NewBufferString("") + rs := tk.MustQuery(userAttributesSQL) + for _, row := range rs.Rows() { + _, err := fmt.Fprintf(resBuff, "%s\n", row) + require.NoError(t, err) + } + var ua []userAttributes + err := json.Unmarshal(resBuff.Bytes(), &ua) + require.NoError(t, err) + require.Equal(t, failedLoginCount, ua[0].PasswordLocking.FailedLoginCount) + require.Equal(t, autoAccountLocked, ua[0].PasswordLocking.AutoAccountLocked) +} + +func selectSQL(user string) string { + userAttributesSQL := new(strings.Builder) + sqlexec.MustFormatSQL(userAttributesSQL, "SELECT user_attributes from mysql.user WHERE USER = %? AND HOST = 'localhost' for update", user) + return userAttributesSQL.String() +} + +type passwordLocking struct { + FailedLoginAttempts int64 `json:"failed_login_attempts"` + PasswordLockTimeDays int64 `json:"password_lock_time_days"` + AutoAccountLocked string `json:"auto_account_locked"` + FailedLoginCount int64 `json:"failed_login_count"` + AutoLockedLastChanged string `json:"auto_locked_last_changed"` +} + +type metadata struct { + Comment string `json:"comment"` +} + +type userAttributes struct { + PasswordLocking passwordLocking `json:"Password_locking"` + Metadata metadata `json:"metadata"` +} diff --git a/executor/simpletest/simple_test.go b/executor/simpletest/simple_test.go index 1f886a18c4323..06f7e72c030d5 100644 --- a/executor/simpletest/simple_test.go +++ b/executor/simpletest/simple_test.go @@ -712,6 +712,29 @@ func TestUser(t *testing.T) { dropUserSQL = `DROP USER IF EXISTS 'test1'@'localhost' ;` tk.MustExec(dropUserSQL) + // Test create/alter user with `tidb_auth_token` + tk.MustExec(`CREATE USER token_user IDENTIFIED WITH 'tidb_auth_token' REQUIRE token_issuer 'issuer-abc'`) + tk.MustQuery(`SELECT plugin, token_issuer FROM mysql.user WHERE user = 'token_user'`).Check(testkit.Rows("tidb_auth_token issuer-abc")) + tk.MustExec(`ALTER USER token_user REQUIRE token_issuer 'issuer-123'`) + tk.MustQuery(`SELECT plugin, token_issuer FROM mysql.user WHERE user = 'token_user'`).Check(testkit.Rows("tidb_auth_token issuer-123")) + tk.MustExec(`ALTER USER token_user IDENTIFIED WITH 'tidb_auth_token'`) + tk.MustExec(`CREATE USER token_user1 IDENTIFIED WITH 'tidb_auth_token'`) + tk.MustQuery(`show warnings`).Check(testkit.RowsWithSep("|", "Warning|1105|TOKEN_ISSUER is needed for 'tidb_auth_token' user, please use 'alter user' to declare it")) + tk.MustExec(`CREATE USER temp_user IDENTIFIED WITH 'mysql_native_password' BY '1234' REQUIRE token_issuer 'issuer-abc'`) + tk.MustQuery(`show warnings`).Check(testkit.RowsWithSep("|", "Warning|1105|TOKEN_ISSUER is not needed for 'mysql_native_password' user")) + tk.MustExec(`ALTER USER temp_user IDENTIFIED WITH 'tidb_auth_token' REQUIRE token_issuer 'issuer-abc'`) + tk.MustQuery(`show warnings`).Check(testkit.Rows()) + tk.MustExec(`ALTER USER temp_user IDENTIFIED WITH 'mysql_native_password' REQUIRE token_issuer 'issuer-abc'`) + tk.MustQuery(`show warnings`).Check(testkit.RowsWithSep("|", "Warning|1105|TOKEN_ISSUER is not needed for the auth plugin")) + tk.MustExec(`ALTER USER temp_user IDENTIFIED WITH 'tidb_auth_token'`) + tk.MustQuery(`show warnings`).Check(testkit.RowsWithSep("|", "Warning|1105|Auth plugin 'tidb_auth_plugin' needs TOKEN_ISSUER")) + tk.MustExec(`ALTER USER token_user REQUIRE SSL`) + tk.MustQuery(`show warnings`).Check(testkit.Rows()) + tk.MustExec(`ALTER USER token_user IDENTIFIED WITH 'mysql_native_password' BY '1234'`) + tk.MustQuery(`show warnings`).Check(testkit.Rows()) + tk.MustExec(`ALTER USER token_user IDENTIFIED WITH 'tidb_auth_token' REQUIRE token_issuer 'issuer-abc'`) + tk.MustQuery(`show warnings`).Check(testkit.Rows()) + // Test alter user. createUserSQL = `CREATE USER 'test1'@'localhost' IDENTIFIED BY '123', 'test2'@'localhost' IDENTIFIED BY '123', 'test3'@'localhost' IDENTIFIED BY '123', 'test4'@'localhost' IDENTIFIED BY '123';` tk.MustExec(createUserSQL) @@ -724,7 +747,7 @@ func TestUser(t *testing.T) { alterUserSQL = `ALTER USER 'test1'@'localhost' IDENTIFIED BY '222', 'test_not_exist'@'localhost' IDENTIFIED BY '111';` tk.MustGetErrCode(alterUserSQL, mysql.ErrCannotUser) result = tk.MustQuery(`SELECT authentication_string FROM mysql.User WHERE User="test1" and Host="localhost"`) - result.Check(testkit.Rows(auth.EncodePassword("222"))) + result.Check(testkit.Rows(auth.EncodePassword("111"))) alterUserSQL = `ALTER USER 'test4'@'localhost' IDENTIFIED WITH 'auth_socket';` tk.MustExec(alterUserSQL) result = tk.MustQuery(`SELECT plugin FROM mysql.User WHERE User="test4" and Host="localhost"`) @@ -977,6 +1000,7 @@ partition by range (a) ( checkPartitionStats("global", "p0", "p1", "global") tk.MustExec("drop stats test_drop_gstats partition p0") + tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1681|'DROP STATS ... PARTITION ...' is deprecated and will be removed in a future release.")) checkPartitionStats("global", "p1", "global") err := tk.ExecToErr("drop stats test_drop_gstats partition abcde") @@ -987,6 +1011,7 @@ partition by range (a) ( checkPartitionStats("global", "p1") tk.MustExec("drop stats test_drop_gstats global") + tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1287|'DROP STATS ... GLOBAL' is deprecated and will be removed in a future release. Please use DROP STATS ... instead")) checkPartitionStats("p1") tk.MustExec("analyze table test_drop_gstats") @@ -1033,3 +1058,50 @@ func TestDropStats(t *testing.T) { require.True(t, statsTbl.Pseudo) h.SetLease(0) } + +func TestDropStatsForMultipleTable(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + testKit := testkit.NewTestKit(t, store) + testKit.MustExec("use test") + testKit.MustExec("create table t1 (c1 int, c2 int)") + testKit.MustExec("create table t2 (c1 int, c2 int)") + + is := dom.InfoSchema() + tbl1, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + tableInfo1 := tbl1.Meta() + + tbl2, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t2")) + require.NoError(t, err) + tableInfo2 := tbl2.Meta() + + h := dom.StatsHandle() + h.Clear() + testKit.MustExec("analyze table t1, t2") + statsTbl1 := h.GetTableStats(tableInfo1) + require.False(t, statsTbl1.Pseudo) + statsTbl2 := h.GetTableStats(tableInfo2) + require.False(t, statsTbl2.Pseudo) + + testKit.MustExec("drop stats t1, t2") + require.Nil(t, h.Update(is)) + statsTbl1 = h.GetTableStats(tableInfo1) + require.True(t, statsTbl1.Pseudo) + statsTbl2 = h.GetTableStats(tableInfo2) + require.True(t, statsTbl2.Pseudo) + + testKit.MustExec("analyze table t1, t2") + statsTbl1 = h.GetTableStats(tableInfo1) + require.False(t, statsTbl1.Pseudo) + statsTbl2 = h.GetTableStats(tableInfo2) + require.False(t, statsTbl2.Pseudo) + + h.SetLease(1) + testKit.MustExec("drop stats t1, t2") + require.Nil(t, h.Update(is)) + statsTbl1 = h.GetTableStats(tableInfo1) + require.True(t, statsTbl1.Pseudo) + statsTbl2 = h.GetTableStats(tableInfo2) + require.True(t, statsTbl2.Pseudo) + h.SetLease(0) +} diff --git a/executor/slow_query.go b/executor/slow_query.go index 395d8f4eba8ac..b83a480f85857 100644 --- a/executor/slow_query.go +++ b/executor/slow_query.go @@ -622,6 +622,9 @@ func (e *slowQueryRetriever) parseLog(ctx context.Context, sctx sessionctx.Conte valid = e.setColumnValue(sctx, row, tz, variable.SlowLogHostStr, host, e.checker, fileLine) } else if strings.HasPrefix(line, variable.SlowLogCopBackoffPrefix) { valid = e.setColumnValue(sctx, row, tz, variable.SlowLogBackoffDetail, line, e.checker, fileLine) + } else if strings.HasPrefix(line, variable.SlowLogWarnings) { + line = line[len(variable.SlowLogWarnings+variable.SlowLogSpaceMarkStr):] + valid = e.setColumnValue(sctx, row, tz, variable.SlowLogWarnings, line, e.checker, fileLine) } else { fields, values := splitByColon(line) for i := 0; i < len(fields); i++ { @@ -781,7 +784,7 @@ func getColumnValueFactoryByName(sctx sessionctx.Context, colName string, column }, nil case variable.SlowLogUserStr, variable.SlowLogHostStr, execdetails.BackoffTypesStr, variable.SlowLogDBStr, variable.SlowLogIndexNamesStr, variable.SlowLogDigestStr, variable.SlowLogStatsInfoStr, variable.SlowLogCopProcAddr, variable.SlowLogCopWaitAddr, variable.SlowLogPlanDigest, - variable.SlowLogPrevStmt, variable.SlowLogQuerySQLStr: + variable.SlowLogPrevStmt, variable.SlowLogQuerySQLStr, variable.SlowLogWarnings: return func(row []types.Datum, value string, tz *time.Location, checker *slowLogChecker) (valid bool, err error) { row[columnIdx] = types.NewStringDatum(value) return true, nil diff --git a/executor/slow_query_sql_test.go b/executor/slow_query_sql_test.go index a77e32e3bfb16..cdf13f2a9ccf9 100644 --- a/executor/slow_query_sql_test.go +++ b/executor/slow_query_sql_test.go @@ -23,6 +23,7 @@ import ( "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/testdata" "github.com/pingcap/tidb/util/logutil" @@ -46,8 +47,6 @@ func TestSlowQueryWithoutSlowLog(t *testing.T) { } func TestSlowQuerySensitiveQuery(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) originCfg := config.GetGlobalConfig() newCfg := *originCfg @@ -57,11 +56,15 @@ func TestSlowQuerySensitiveQuery(t *testing.T) { newCfg.Log.SlowQueryFile = f.Name() config.StoreGlobalConfig(&newCfg) defer func() { - tk.MustExec("set tidb_slow_log_threshold=300;") config.StoreGlobalConfig(originCfg) require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + defer func() { + tk.MustExec("set tidb_slow_log_threshold=300;") + }() tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("set tidb_slow_log_threshold=0;") @@ -80,8 +83,6 @@ func TestSlowQuerySensitiveQuery(t *testing.T) { } func TestSlowQueryPrepared(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) originCfg := config.GetGlobalConfig() newCfg := *originCfg @@ -91,12 +92,16 @@ func TestSlowQueryPrepared(t *testing.T) { newCfg.Log.SlowQueryFile = f.Name() config.StoreGlobalConfig(&newCfg) defer func() { - tk.MustExec("set tidb_slow_log_threshold=300;") - tk.MustExec("set tidb_redact_log=0;") config.StoreGlobalConfig(originCfg) require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + defer func() { + tk.MustExec("set tidb_slow_log_threshold=300;") + tk.MustExec("set tidb_redact_log=0;") + }() tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("set tidb_slow_log_threshold=0;") @@ -116,8 +121,6 @@ func TestSlowQueryPrepared(t *testing.T) { } func TestLogSlowLogIndex(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) f, err := os.CreateTemp("", "tidb-slow-*.log") require.NoError(t, err) require.NoError(t, f.Close()) @@ -127,6 +130,8 @@ func TestLogSlowLogIndex(t *testing.T) { conf.Log.SlowQueryFile = f.Name() }) require.NoError(t, logutil.InitLogger(config.GetGlobalConfig().Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("use test") @@ -140,9 +145,6 @@ func TestLogSlowLogIndex(t *testing.T) { } func TestSlowQuery(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - f, err := os.CreateTemp("", "tidb-slow-*.log") require.NoError(t, err) _, err = f.WriteString(` @@ -197,6 +199,8 @@ SELECT original_sql, bind_sql, default_db, status, create_time, update_time, cha require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustQuery("select count(*) from `information_schema`.`slow_query` where time > '2020-10-16 20:08:13' and time < '2020-10-16 21:08:13'").Check(testkit.Rows("1")) @@ -208,10 +212,6 @@ SELECT original_sql, bind_sql, default_db, status, create_time, update_time, cha } func TestIssue37066(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) - originCfg := config.GetGlobalConfig() newCfg := *originCfg f, err := os.CreateTemp("", "tidb-slow-*.log") @@ -224,6 +224,9 @@ func TestIssue37066(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("set tidb_slow_log_threshold=0;") defer func() { @@ -281,3 +284,61 @@ func TestIssue37066(t *testing.T) { } } } + +func TestWarningsInSlowQuery(t *testing.T) { + // Prepare the slow log + originCfg := config.GetGlobalConfig() + newCfg := *originCfg + f, err := os.CreateTemp("", "tidb-slow-*.log") + require.NoError(t, err) + newCfg.Log.SlowQueryFile = f.Name() + config.StoreGlobalConfig(&newCfg) + defer func() { + config.StoreGlobalConfig(originCfg) + require.NoError(t, f.Close()) + require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) + }() + require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) + tk.MustExec("set tidb_slow_log_threshold=0;") + defer func() { + tk.MustExec("set tidb_slow_log_threshold=300;") + }() + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int, c int, d int, e int, f int, g int, h set('11', '22', '33')," + + "primary key (a), unique key c_d_e (c, d, e), unique key f (f), unique key f_g (f, g), key g (g))") + tbl, err := dom.InfoSchema().TableByName(model.CIStr{O: "test", L: "test"}, model.CIStr{O: "t", L: "t"}) + require.NoError(t, err) + tbl.Meta().TiFlashReplica = &model.TiFlashReplicaInfo{Count: 1, Available: true} + + var input []string + var output []struct { + SQL string + Result string + } + slowQuerySuiteData.LoadTestCases(t, &input, &output) + for i, test := range input { + comment := fmt.Sprintf("case:%v sql:%s", i, test) + if len(test) < 6 || test[:6] != "select" { + tk.MustExec(test) + } else { + tk.MustQuery(test) + } + res := testdata.ConvertRowsToStrings( + tk.MustQuery("select warnings from information_schema.slow_query " + + `where query = "` + test + `;" ` + + "order by time desc limit 1").Rows(), + ) + require.Lenf(t, res, 1, comment) + + testdata.OnRecord(func() { + output[i].SQL = test + output[i].Result = res[0] + }) + require.Equal(t, output[i].Result, res[0]) + } +} diff --git a/executor/slow_query_test.go b/executor/slow_query_test.go index 32412d2f1ac70..d696afa3c945d 100644 --- a/executor/slow_query_test.go +++ b/executor/slow_query_test.go @@ -55,7 +55,7 @@ func parseLog(retriever *slowQueryRetriever, sctx sessionctx.Context, reader *bu } func newSlowQueryRetriever() (*slowQueryRetriever, error) { - newISBuilder, err := infoschema.NewBuilder(nil, nil).InitWithDBInfos(nil, nil, 0) + newISBuilder, err := infoschema.NewBuilder(nil, nil).InitWithDBInfos(nil, nil, nil, 0) if err != nil { return nil, err } @@ -160,7 +160,7 @@ select * from t;` expectRecordString := `2019-04-28 15:24:04.309074,` + `405888132465033227,root,localhost,0,57,0.12,0.216905,` + `0,0,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0.38,0.021,0,0,0,1,637,0,10,10,10,10,100,,,1,42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772,t1:1,t2:2,` + - `0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,65536,0,0,0,0,0,` + + `0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,65536,0,0,0,0,0,,` + `Cop_backoff_regionMiss_total_times: 200 Cop_backoff_regionMiss_total_time: 0.2 Cop_backoff_regionMiss_max_time: 0.2 Cop_backoff_regionMiss_max_addr: 127.0.0.1 Cop_backoff_regionMiss_avg_time: 0.2 Cop_backoff_regionMiss_p90_time: 0.2 Cop_backoff_rpcPD_total_times: 200 Cop_backoff_rpcPD_total_time: 0.2 Cop_backoff_rpcPD_max_time: 0.2 Cop_backoff_rpcPD_max_addr: 127.0.0.1 Cop_backoff_rpcPD_avg_time: 0.2 Cop_backoff_rpcPD_p90_time: 0.2 Cop_backoff_rpcTiKV_total_times: 200 Cop_backoff_rpcTiKV_total_time: 0.2 Cop_backoff_rpcTiKV_max_time: 0.2 Cop_backoff_rpcTiKV_max_addr: 127.0.0.1 Cop_backoff_rpcTiKV_avg_time: 0.2 Cop_backoff_rpcTiKV_p90_time: 0.2,` + `0,0,1,0,1,1,0,,60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4,` + `,update t set i = 1;,select * from t;` @@ -183,7 +183,7 @@ select * from t;` expectRecordString = `2019-04-28 15:24:04.309074,` + `405888132465033227,root,localhost,0,57,0.12,0.216905,` + `0,0,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0.38,0.021,0,0,0,1,637,0,10,10,10,10,100,,,1,42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772,t1:1,t2:2,` + - `0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,65536,0,0,0,0,0,` + + `0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,65536,0,0,0,0,0,,` + `Cop_backoff_regionMiss_total_times: 200 Cop_backoff_regionMiss_total_time: 0.2 Cop_backoff_regionMiss_max_time: 0.2 Cop_backoff_regionMiss_max_addr: 127.0.0.1 Cop_backoff_regionMiss_avg_time: 0.2 Cop_backoff_regionMiss_p90_time: 0.2 Cop_backoff_rpcPD_total_times: 200 Cop_backoff_rpcPD_total_time: 0.2 Cop_backoff_rpcPD_max_time: 0.2 Cop_backoff_rpcPD_max_addr: 127.0.0.1 Cop_backoff_rpcPD_avg_time: 0.2 Cop_backoff_rpcPD_p90_time: 0.2 Cop_backoff_rpcTiKV_total_times: 200 Cop_backoff_rpcTiKV_total_time: 0.2 Cop_backoff_rpcTiKV_max_time: 0.2 Cop_backoff_rpcTiKV_max_addr: 127.0.0.1 Cop_backoff_rpcTiKV_avg_time: 0.2 Cop_backoff_rpcTiKV_p90_time: 0.2,` + `0,0,1,0,1,1,0,,60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4,` + `,update t set i = 1;,select * from t;` diff --git a/executor/sort.go b/executor/sort.go index efc56aa058d2a..06241993e05f3 100644 --- a/executor/sort.go +++ b/executor/sort.go @@ -189,12 +189,12 @@ func (e *SortExec) fetchRowChunks(ctx context.Context) error { defer e.spillAction.WaitForTest() } }) - e.ctx.GetSessionVars().StmtCtx.MemTracker.FallbackOldAndSetNewAction(e.spillAction) + e.ctx.GetSessionVars().MemTracker.FallbackOldAndSetNewAction(e.spillAction) e.rowChunks.GetDiskTracker().AttachTo(e.diskTracker) e.rowChunks.GetDiskTracker().SetLabel(memory.LabelForRowChunks) } for { - chk := newFirstChunk(e.children[0]) + chk := tryNewCacheChunk(e.children[0]) err := Next(ctx, e.children[0], chk) if err != nil { return err @@ -218,7 +218,7 @@ func (e *SortExec) fetchRowChunks(ctx context.Context) error { defer e.spillAction.WaitForTest() } }) - e.ctx.GetSessionVars().StmtCtx.MemTracker.FallbackOldAndSetNewAction(e.spillAction) + e.ctx.GetSessionVars().MemTracker.FallbackOldAndSetNewAction(e.spillAction) err = e.rowChunks.Add(chk) } if err != nil { @@ -226,6 +226,13 @@ func (e *SortExec) fetchRowChunks(ctx context.Context) error { } } } + failpoint.Inject("SignalCheckpointForSort", func(val failpoint.Value) { + if val.(bool) { + if e.ctx.GetSessionVars().ConnectionID == 123456 { + e.ctx.GetSessionVars().MemTracker.NeedKill.Store(true) + } + } + }) if e.rowChunks.NumRow() > 0 { e.rowChunks.Sort() e.partitionList = append(e.partitionList, e.rowChunks) @@ -427,7 +434,7 @@ func (e *TopNExec) loadChunksUntilTotalLimit(ctx context.Context) error { e.rowChunks.GetMemTracker().AttachTo(e.memTracker) e.rowChunks.GetMemTracker().SetLabel(memory.LabelForRowChunks) for uint64(e.rowChunks.Len()) < e.totalLimit { - srcChk := newFirstChunk(e.children[0]) + srcChk := tryNewCacheChunk(e.children[0]) // adjust required rows by total limit srcChk.SetRequiredRows(int(e.totalLimit-uint64(e.rowChunks.Len())), e.maxChunkSize) err := Next(ctx, e.children[0], srcChk) @@ -453,7 +460,7 @@ func (e *TopNExec) executeTopN(ctx context.Context) error { // The number of rows we loaded may exceeds total limit, remove greatest rows by Pop. heap.Pop(e.chkHeap) } - childRowChk := newFirstChunk(e.children[0]) + childRowChk := tryNewCacheChunk(e.children[0]) for { err := Next(ctx, e.children[0], childRowChk) if err != nil { diff --git a/executor/splittest/BUILD.bazel b/executor/splittest/BUILD.bazel index 77dd2a7e225f8..f3f9f90128bcc 100644 --- a/executor/splittest/BUILD.bazel +++ b/executor/splittest/BUILD.bazel @@ -8,6 +8,7 @@ go_test( "split_table_test.go", ], flaky = True, + race = "on", shard_count = 5, deps = [ "//ddl", diff --git a/executor/splittest/main_test.go b/executor/splittest/main_test.go index a9d6be9bc0212..c7f44e57f49d5 100644 --- a/executor/splittest/main_test.go +++ b/executor/splittest/main_test.go @@ -23,6 +23,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), } goleak.VerifyTestMain(m, opts...) } diff --git a/executor/table_reader.go b/executor/table_reader.go index 7aed132691804..984212dcf7328 100644 --- a/executor/table_reader.go +++ b/executor/table_reader.go @@ -22,7 +22,10 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pingcap/failpoint" "github.com/pingcap/tidb/distsql" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" plannercore "github.com/pingcap/tidb/planner/core" @@ -58,7 +61,7 @@ func (sr selectResultHook) SelectResult(ctx context.Context, sctx sessionctx.Con } type kvRangeBuilder interface { - buildKeyRange(ranges []*ranger.Range) ([]kv.KeyRange, error) + buildKeyRange(ranges []*ranger.Range) ([][]kv.KeyRange, error) buildKeyRangeSeparately(ranges []*ranger.Range) ([]int64, [][]kv.KeyRange, error) } @@ -202,13 +205,13 @@ func (e *TableReaderExecutor) Open(ctx context.Context) error { if err != nil { return err } - e.kvRanges = append(e.kvRanges, kvReq.KeyRanges...) + e.kvRanges = kvReq.KeyRanges.AppendSelfTo(e.kvRanges) if len(secondPartRanges) != 0 { kvReq, err = e.buildKVReq(ctx, secondPartRanges) if err != nil { return err } - e.kvRanges = append(e.kvRanges, kvReq.KeyRanges...) + e.kvRanges = kvReq.KeyRanges.AppendSelfTo(e.kvRanges) } return nil } @@ -253,7 +256,7 @@ func (e *TableReaderExecutor) Next(ctx context.Context, req *chunk.Chunk) error return err } - err := FillVirtualColumnValue(e.virtualColumnRetFieldTypes, e.virtualColumnIndex, e.schema, e.columns, e.ctx, req) + err := table.FillVirtualColumnValue(e.virtualColumnRetFieldTypes, e.virtualColumnIndex, e.schema.Columns, e.columns, e.ctx, req) if err != nil { return err } @@ -311,10 +314,10 @@ func (e *TableReaderExecutor) buildResp(ctx context.Context, ranges []*ranger.Ra if err != nil { return nil, err } - slices.SortFunc(kvReq.KeyRanges, func(i, j kv.KeyRange) bool { + kvReq.KeyRanges.SortByFunc(func(i, j kv.KeyRange) bool { return bytes.Compare(i.StartKey, j.StartKey) < 0 }) - e.kvRanges = append(e.kvRanges, kvReq.KeyRanges...) + e.kvRanges = kvReq.KeyRanges.AppendSelfTo(e.kvRanges) result, err := e.SelectResult(ctx, e.ctx, kvReq, retTypes(e), e.feedback, getPhysicalPlanIDs(e.plans), e.id) if err != nil { @@ -406,10 +409,25 @@ func (e *TableReaderExecutor) buildKVReq(ctx context.Context, ranges []*ranger.R if err != nil { return nil, err } - reqBuilder = builder.SetKeyRanges(kvRange) + reqBuilder = builder.SetPartitionKeyRanges(kvRange) } else { reqBuilder = builder.SetHandleRanges(e.ctx.GetSessionVars().StmtCtx, getPhysicalTableID(e.table), e.table.Meta() != nil && e.table.Meta().IsCommonHandle, ranges, e.feedback) } + if e.table != nil && e.table.Type().IsClusterTable() { + copDestination := infoschema.GetClusterTableCopDestination(e.table.Meta().Name.L) + if copDestination == infoschema.DDLOwner { + ownerManager := domain.GetDomain(e.ctx).DDL().OwnerManager() + ddlOwnerID, err := ownerManager.GetOwnerID(ctx) + if err != nil { + return nil, err + } + serverInfo, err := infosync.GetServerInfoByID(ctx, ddlOwnerID) + if err != nil { + return nil, err + } + reqBuilder.SetTiDBServerID(serverInfo.ServerIDGetter()) + } + } reqBuilder. SetDAGRequest(e.dagPB). SetStartTS(e.startTS). diff --git a/executor/testdata/executor_suite_out.json b/executor/testdata/executor_suite_out.json index bb3f91c1d9548..e0fbfecb07095 100644 --- a/executor/testdata/executor_suite_out.json +++ b/executor/testdata/executor_suite_out.json @@ -46,9 +46,10 @@ "HashJoin_7 6400.00 root anti semi join, equal:[nulleq(test.t1.a, test.t3.a)]", "├─TableReader_18(Build) 10000.00 root data:TableFullScan_17", "│ └─TableFullScan_17 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - "└─HashAgg_10(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", - " └─TableReader_15 10000.00 root data:TableFullScan_14", - " └─TableFullScan_14 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─HashAgg_12(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_13 8000.00 root data:HashAgg_8", + " └─HashAgg_8 8000.00 cop[tikv] group by:test.t1.a, ", + " └─TableFullScan_11 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -61,9 +62,10 @@ "HashJoin_7 6400.00 root semi join, equal:[nulleq(test.t1.a, test.t2.a)]", "├─TableReader_18(Build) 10000.00 root data:TableFullScan_17", "│ └─TableFullScan_17 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─HashAgg_10(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", - " └─TableReader_15 10000.00 root data:TableFullScan_14", - " └─TableFullScan_14 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─HashAgg_12(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_13 8000.00 root data:HashAgg_8", + " └─HashAgg_8 8000.00 cop[tikv] group by:test.t1.a, ", + " └─TableFullScan_11 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -123,9 +125,10 @@ "└─HashJoin_14(Probe) 6400.00 root semi join, equal:[nulleq(test.t1.a, test.t2.a)]", " ├─TableReader_24(Build) 10000.00 root data:TableFullScan_23", " │ └─TableFullScan_23 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─HashAgg_17(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", - " └─TableReader_22 10000.00 root data:TableFullScan_21", - " └─TableFullScan_21 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─HashAgg_19(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_20 8000.00 root data:HashAgg_15", + " └─HashAgg_15 8000.00 cop[tikv] group by:test.t1.a, ", + " └─TableFullScan_18 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -142,9 +145,10 @@ "└─HashJoin_17 6400.00 root semi join, equal:[nulleq(test.t2.a, test.t3.a)]", " ├─TableReader_27(Build) 10000.00 root data:TableFullScan_26", " │ └─TableFullScan_26 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " └─HashAgg_20(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - " └─TableReader_25 10000.00 root data:TableFullScan_24", - " └─TableFullScan_24 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─HashAgg_22(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─TableReader_23 8000.00 root data:HashAgg_18", + " └─HashAgg_18 8000.00 cop[tikv] group by:test.t2.a, ", + " └─TableFullScan_21 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -162,12 +166,14 @@ "├─HashJoin_20(Build) 6400.00 root semi join, equal:[nulleq(test.t2.a, test.t3.a)]", "│ ├─TableReader_31(Build) 10000.00 root data:TableFullScan_30", "│ │ └─TableFullScan_30 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - "│ └─HashAgg_23(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - "│ └─TableReader_28 10000.00 root data:TableFullScan_27", - "│ └─TableFullScan_27 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─HashAgg_14(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", - " └─TableReader_19 10000.00 root data:TableFullScan_18", - " └─TableFullScan_18 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "│ └─HashAgg_25(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader_26 8000.00 root data:HashAgg_21", + "│ └─HashAgg_21 8000.00 cop[tikv] group by:test.t2.a, ", + "│ └─TableFullScan_24 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─HashAgg_16(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_17 8000.00 root data:HashAgg_12", + " └─HashAgg_12 8000.00 cop[tikv] group by:test.t1.a, ", + " └─TableFullScan_15 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -182,12 +188,14 @@ "├─HashJoin_20(Build) 6400.00 root anti semi join, equal:[nulleq(test.t2.a, test.t3.a)]", "│ ├─TableReader_31(Build) 10000.00 root data:TableFullScan_30", "│ │ └─TableFullScan_30 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - "│ └─HashAgg_23(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - "│ └─TableReader_28 10000.00 root data:TableFullScan_27", - "│ └─TableFullScan_27 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─HashAgg_14(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", - " └─TableReader_19 10000.00 root data:TableFullScan_18", - " └─TableFullScan_18 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "│ └─HashAgg_25(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader_26 8000.00 root data:HashAgg_21", + "│ └─HashAgg_21 8000.00 cop[tikv] group by:test.t2.a, ", + "│ └─TableFullScan_24 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─HashAgg_16(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_17 8000.00 root data:HashAgg_12", + " └─HashAgg_12 8000.00 cop[tikv] group by:test.t1.a, ", + " └─TableFullScan_15 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -203,9 +211,10 @@ "└─HashJoin_17 6400.00 root anti semi join, equal:[nulleq(test.t2.a, test.t3.a)]", " ├─TableReader_27(Build) 10000.00 root data:TableFullScan_26", " │ └─TableFullScan_26 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " └─HashAgg_20(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - " └─TableReader_25 10000.00 root data:TableFullScan_24", - " └─TableFullScan_24 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─HashAgg_22(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─TableReader_23 8000.00 root data:HashAgg_18", + " └─HashAgg_18 8000.00 cop[tikv] group by:test.t2.a, ", + " └─TableFullScan_21 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -250,9 +259,10 @@ "└─HashJoin_20(Probe) 6400.00 root semi join, equal:[nulleq(test.t1.a, test.t1.a)]", " ├─TableReader_30(Build) 10000.00 root data:TableFullScan_29", " │ └─TableFullScan_29 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─HashAgg_23(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", - " └─TableReader_28 10000.00 root data:TableFullScan_27", - " └─TableFullScan_27 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─HashAgg_25(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_26 8000.00 root data:HashAgg_21", + " └─HashAgg_21 8000.00 cop[tikv] group by:test.t1.a, ", + " └─TableFullScan_24 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": null } diff --git a/executor/testdata/slow_query_suite_in.json b/executor/testdata/slow_query_suite_in.json new file mode 100644 index 0000000000000..4b2c95b6aa378 --- /dev/null +++ b/executor/testdata/slow_query_suite_in.json @@ -0,0 +1,19 @@ +[ + { + "name": "TestWarningsInSlowQuery", + "cases": [ + "insert into t(a) value (1)", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ a/0 from t", + "create binding for select * from t where c = 10 using select * from t use index (c_d_e) where c = 10", + "select * from t where c = 10", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where a > 1 order by f", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where f > 1", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ f from t where f > 1", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where f > 3 and g = 5", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where g = 5 order by f", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where d = 3 order by c, e", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where h = '11,22'", + "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where a > rand()*100" + ] + } +] diff --git a/executor/testdata/slow_query_suite_out.json b/executor/testdata/slow_query_suite_out.json new file mode 100644 index 0000000000000..adf6606709859 --- /dev/null +++ b/executor/testdata/slow_query_suite_out.json @@ -0,0 +1,55 @@ +[ + { + "Name": "TestWarningsInSlowQuery", + "Cases": [ + { + "SQL": "insert into t(a) value (1)", + "Result": "" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ a/0 from t", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Division by 0\"}]" + }, + { + "SQL": "create binding for select * from t where c = 10 using select * from t use index (c_d_e) where c = 10", + "Result": "" + }, + { + "SQL": "select * from t where c = 10", + "Result": "[{\"Level\":\"Note\",\"Message\":\"Using the bindSQL: SELECT * FROM `test`.`t` USE INDEX (`c_d_e`) WHERE `c` = 10\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where a > 1 order by f", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash)] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true},{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash),f,f_g] remain after pruning paths for t given Prop{SortItems: [{test.t.f asc}], TaskTp: rootTask}\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where f > 1", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash),f,f_g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ f from t where f > 1", + "Result": "[{\"Level\":\"Note\",\"Message\":\"[t(tiflash),f,f_g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where f > 3 and g = 5", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash),f_g,g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where g = 5 order by f", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash),g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true},{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash),f_g,g] remain after pruning paths for t given Prop{SortItems: [{test.t.f asc}], TaskTp: rootTask}\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where d = 3 order by c, e", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash)] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true},{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash),c_d_e] remain after pruning paths for t given Prop{SortItems: [{test.t.c asc} {test.t.e asc}], TaskTp: rootTask}\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where h = '11,22'", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash)] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true}]" + }, + { + "SQL": "select /*+ READ_FROM_STORAGE(TIKV[t]) */ * from t where a > rand()*100", + "Result": "[{\"Level\":\"Warning\",\"Message\":\"Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to storage layer now.\",\"IsExtra\":true},{\"Level\":\"Warning\",\"Message\":\"Expression about 'test.t.h' can not be pushed to TiFlash because it contains unsupported calculation of type 'set'.\",\"IsExtra\":true},{\"Level\":\"Warning\",\"Message\":\"Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.\",\"IsExtra\":true},{\"Level\":\"Note\",\"Message\":\"[t,t(tiflash)] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}\",\"IsExtra\":true}]" + } + ] + } +] diff --git a/executor/testdata/tiflash_v640_dt_tables.json b/executor/testdata/tiflash_v640_dt_tables.json new file mode 100644 index 0000000000000..d86ce41f6124c --- /dev/null +++ b/executor/testdata/tiflash_v640_dt_tables.json @@ -0,0 +1,241 @@ +{ + "meta": + [ + { + "name": "database", + "type": "String" + }, + { + "name": "table", + "type": "String" + }, + { + "name": "tidb_database", + "type": "String" + }, + { + "name": "tidb_table", + "type": "String" + }, + { + "name": "table_id", + "type": "Int64" + }, + { + "name": "is_tombstone", + "type": "UInt64" + }, + { + "name": "segment_count", + "type": "UInt64" + }, + { + "name": "total_rows", + "type": "UInt64" + }, + { + "name": "total_size", + "type": "UInt64" + }, + { + "name": "total_delete_ranges", + "type": "UInt64" + }, + { + "name": "delta_rate_rows", + "type": "Float64" + }, + { + "name": "delta_rate_segments", + "type": "Float64" + }, + { + "name": "delta_placed_rate", + "type": "Float64" + }, + { + "name": "delta_cache_size", + "type": "UInt64" + }, + { + "name": "delta_cache_rate", + "type": "Float64" + }, + { + "name": "delta_cache_wasted_rate", + "type": "Float64" + }, + { + "name": "delta_index_size", + "type": "UInt64" + }, + { + "name": "avg_segment_rows", + "type": "Float64" + }, + { + "name": "avg_segment_size", + "type": "Float64" + }, + { + "name": "delta_count", + "type": "UInt64" + }, + { + "name": "total_delta_rows", + "type": "UInt64" + }, + { + "name": "total_delta_size", + "type": "UInt64" + }, + { + "name": "avg_delta_rows", + "type": "Float64" + }, + { + "name": "avg_delta_size", + "type": "Float64" + }, + { + "name": "avg_delta_delete_ranges", + "type": "Float64" + }, + { + "name": "stable_count", + "type": "UInt64" + }, + { + "name": "total_stable_rows", + "type": "UInt64" + }, + { + "name": "total_stable_size", + "type": "UInt64" + }, + { + "name": "total_stable_size_on_disk", + "type": "UInt64" + }, + { + "name": "avg_stable_rows", + "type": "Float64" + }, + { + "name": "avg_stable_size", + "type": "Float64" + }, + { + "name": "total_pack_count_in_delta", + "type": "UInt64" + }, + { + "name": "max_pack_count_in_delta", + "type": "UInt64" + }, + { + "name": "avg_pack_count_in_delta", + "type": "Float64" + }, + { + "name": "avg_pack_rows_in_delta", + "type": "Float64" + }, + { + "name": "avg_pack_size_in_delta", + "type": "Float64" + }, + { + "name": "total_pack_count_in_stable", + "type": "UInt64" + }, + { + "name": "avg_pack_count_in_stable", + "type": "Float64" + }, + { + "name": "avg_pack_rows_in_stable", + "type": "Float64" + }, + { + "name": "avg_pack_size_in_stable", + "type": "Float64" + }, + { + "name": "storage_stable_num_snapshots", + "type": "UInt64" + }, + { + "name": "storage_stable_oldest_snapshot_lifetime", + "type": "Float64" + }, + { + "name": "storage_stable_oldest_snapshot_thread_id", + "type": "UInt64" + }, + { + "name": "storage_stable_oldest_snapshot_tracing_id", + "type": "String" + }, + { + "name": "storage_delta_num_snapshots", + "type": "UInt64" + }, + { + "name": "storage_delta_oldest_snapshot_lifetime", + "type": "Float64" + }, + { + "name": "storage_delta_oldest_snapshot_thread_id", + "type": "UInt64" + }, + { + "name": "storage_delta_oldest_snapshot_tracing_id", + "type": "String" + }, + { + "name": "storage_meta_num_snapshots", + "type": "UInt64" + }, + { + "name": "storage_meta_oldest_snapshot_lifetime", + "type": "Float64" + }, + { + "name": "storage_meta_oldest_snapshot_thread_id", + "type": "UInt64" + }, + { + "name": "storage_meta_oldest_snapshot_tracing_id", + "type": "String" + }, + { + "name": "background_tasks_length", + "type": "UInt64" + } + ], + + "data": + [ + ["db_70", "t_135", "tpcc", "customer", "135", "0", "4", "3528714", "2464079200", "0", 0.002329177144988231, 1, 0, "929227", 0.16169850346757514, 0, "8128", 882178.5, 616019800, "4", "8219", "5747810", 2054.75, 1436952.5, 0, "4", "3520495", "2458331390", "1601563417", 880123.75, 614582847.5, "24", "8", 6, 342.4583333333333, 239492.08333333334, "482", 120.5, 7303.9315352697095, 5100272.593360996, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_137", "tpcc", "district", "137", "0", "1", "7993", "1346259", "0", 0.8748905292130614, 1, 0.8055198055198055, "252168", 0.21407121407121407, 0, "147272", 7993, 1346259, "1", "6993", "1178050", 6993, 1178050, 0, "1", "1000", "168209", "91344", 1000, 168209, "6", "6", 6, 1165.5, 196341.66666666666, "10", 10, 100, 16820.9, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_139", "tpcc", "history", "139", "0", "19", "19379697", "1629276978", "0", 0.0006053758219233252, 0.5789473684210527, 0.4626662120695534, "253640", 0.25434708489601093, 0, "293544", 1019984.052631579, 85751419.89473684, "11", "11732", "997220", 1066.5454545454545, 90656.36363636363, 0, "19", "19367965", "1628279758", "625147717", 1019366.5789473684, 85698934.63157895, "15", "4", 1.3636363636363635, 782.1333333333333, 66481.33333333333, "2378", 125.15789473684211, 8144.644659377628, 684726.559293524, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_141", "tpcc", "item", "141", "0", "1", "100000", "10799081", "0", 0, 0, null, "0", null, null, "0", 100000, 10799081, "0", "0", "0", null, null, null, "1", "100000", "10799081", "7357726", 100000, 10799081, "0", "0", null, null, null, "13", 13, 7692.307692307692, 830698.5384615385, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_143", "tpcc", "new_order", "143", "0", "4", "2717707", "78813503", "0", 0.02266763856442214, 1, 0.9678592299201351, "52809", 0.029559768846178818, 0, "1434208", 679426.75, 19703375.75, "4", "61604", "1786516", 15401, 446629, 0, "3", "2656103", "77026987", "40906492", 885367.6666666666, 25675662.333333332, "37", "24", 9.25, 1664.972972972973, 48284.21621621621, "380", 126.66666666666667, 6989.744736842105, 202702.59736842106, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_145", "tpcc", "order_line", "145", "0", "203", "210607202", "20007684190", "0", 0.0054566462546708164, 0.5862068965517241, 0.7810067620424135, "620065", 0.005679558722564825, 0, "22607144", 1037473.9014778325, 98560020.64039409, "119", "1149209", "109174855", 9657.218487394957, 917435.756302521, 0, "203", "209457993", "19898509335", "8724002804", 1031812.7733990147, 98022213.47290641, "893", "39", 7.504201680672269, 1286.9081746920492, 122256.27659574468, "31507", 155.20689655172413, 6647.982765734599, 631558.3627447869, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_147", "tpcc", "orders", "147", "0", "22", "21903301", "1270391458", "0", 0.02021357420052804, 0.7272727272727273, 0.9239944527763222, "260536", 0.010145817899282655, 0, "10025264", 995604.5909090909, 57745066.27272727, "16", "442744", "25679152", 27671.5, 1604947, 0, "22", "21460557", "1244712306", "452173775", 975479.8636363636, 56577832.09090909, "242", "34", 15.125, 1829.5206611570247, 106112.19834710743, "2973", 135.13636363636363, 7218.485368314833, 418672.15136226034, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_149", "tpcc", "stock", "149", "0", "42", "11112720", "4811805131", "0", 0.028085203262567582, 0.9761904761904762, 0.8463391893060944, "10227093", 0.07567373591410528, 0, "6719064", 264588.5714285714, 114566788.83333333, "41", "312103", "135131097", 7612.268292682927, 3295880.4146341463, 0, "42", "10800617", "4676674034", "3231872509", 257157.54761904763, 111349381.76190476, "238", "26", 5.804878048780488, 1311.357142857143, 567777.718487395, "1644", 39.142857142857146, 6569.718369829684, 2844692.234793187, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"], + ["db_70", "t_151", "tpcc", "warehouse", "151", "0", "1", "5842", "923615", "0", 0.9828825744608011, 1, 0.9669104841518634, "70220", 0.07732497387669801, 0, "133048", 5842, 923615, "1", "5742", "907807", 5742, 907807, 0, "1", "100", "15808", "11642", 100, 15808, "5", "5", 5, 1148.4, 181561.4, "5", 5, 20, 3161.6, "0", 0, "0", "", "0", 0, "0", "", "0", 0, "0", "", "0"] + ], + + "rows": 9, + + "rows_before_limit_at_least": 9, + + "statistics": + { + "elapsed": 0.000217252, + "rows_read": 9, + "bytes_read": 4071 + } +} diff --git a/executor/tiflashtest/BUILD.bazel b/executor/tiflashtest/BUILD.bazel index 5223fa79cc2d9..c7678e569522d 100644 --- a/executor/tiflashtest/BUILD.bazel +++ b/executor/tiflashtest/BUILD.bazel @@ -16,6 +16,7 @@ go_test( "//executor", "//meta/autoid", "//parser/terror", + "//planner/core", "//store/mockstore", "//store/mockstore/unistore", "//testkit", diff --git a/executor/tiflashtest/main_test.go b/executor/tiflashtest/main_test.go index 60681a496f07a..708cb54bb0283 100644 --- a/executor/tiflashtest/main_test.go +++ b/executor/tiflashtest/main_test.go @@ -39,6 +39,7 @@ func TestMain(m *testing.M) { view.Stop() }), goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), diff --git a/executor/tiflashtest/tiflash_test.go b/executor/tiflashtest/tiflash_test.go index 37bcc7272575e..e8cd94d889188 100644 --- a/executor/tiflashtest/tiflash_test.go +++ b/executor/tiflashtest/tiflash_test.go @@ -27,9 +27,11 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/parser/terror" + plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/store/mockstore/unistore" "github.com/pingcap/tidb/testkit" @@ -266,14 +268,9 @@ func TestMppExecution(t *testing.T) { tk.MustExec("begin") tk.MustQuery("select count(*) from ( select * from t2 group by a, b) A group by A.b").Check(testkit.Rows("3")) tk.MustQuery("select count(*) from t1 where t1.a+100 > ( select count(*) from t2 where t1.a=t2.a and t1.b=t2.b) group by t1.b").Check(testkit.Rows("4")) - txn, err := tk.Session().Txn(true) - require.NoError(t, err) - ts := txn.StartTS() - taskID := tk.Session().GetSessionVars().AllocMPPTaskID(ts) - require.Equal(t, int64(6), taskID) - tk.MustExec("commit") - taskID = tk.Session().GetSessionVars().AllocMPPTaskID(ts + 1) + taskID := plannercore.AllocMPPTaskID(tk.Session()) require.Equal(t, int64(1), taskID) + tk.MustExec("commit") failpoint.Enable("github.com/pingcap/tidb/executor/checkTotalMPPTasks", `return(3)`) // all the data is related to one store, so there are three tasks. @@ -462,6 +459,7 @@ func TestPartitionTable(t *testing.T) { store := testkit.CreateMockStore(t, withMockTiFlash(2)) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec("drop table if exists t") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") @@ -1041,7 +1039,7 @@ func TestTiFlashPartitionTableBroadcastJoin(t *testing.T) { } } -func TestForbidTiflashDuringStaleRead(t *testing.T) { +func TestTiflashSupportStaleRead(t *testing.T) { store := testkit.CreateMockStore(t, withMockTiFlash(2)) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -1073,8 +1071,8 @@ func TestForbidTiflashDuringStaleRead(t *testing.T) { fmt.Fprintf(resBuff, "%s\n", row) } res = resBuff.String() - require.NotContains(t, res, "tiflash") - require.Contains(t, res, "tikv") + require.Contains(t, res, "tiflash") + require.NotContains(t, res, "tikv") } func TestForbidTiFlashIfExtraPhysTableIDIsNeeded(t *testing.T) { @@ -1089,6 +1087,7 @@ func TestForbidTiFlashIfExtraPhysTableIDIsNeeded(t *testing.T) { require.NoError(t, err) tk.MustExec("set tidb_partition_prune_mode=dynamic") tk.MustExec("set tidb_enforce_mpp=1") + tk.MustExec("set tidb_cost_model_version=2") rows := tk.MustQuery("explain select count(*) from t").Rows() resBuff := bytes.NewBufferString("") @@ -1205,6 +1204,35 @@ func TestAggPushDownCountStar(t *testing.T) { tk.MustQuery("select count(*) from c, o where c.c_id=o.c_id").Check(testkit.Rows("5")) } +func TestGroupStreamAggOnTiFlash(t *testing.T) { + store := testkit.CreateMockStore(t, withMockTiFlash(2)) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists foo") + tk.MustExec("create table foo(a int, b int, c int, d int, primary key(a,b,c,d))") + tk.MustExec("alter table foo set tiflash replica 1") + tk.MustExec("insert into foo values(1,2,3,1),(1,2,3,6),(1,2,3,5)," + + "(1,2,3,2),(1,2,3,4),(1,2,3,7),(1,2,3,3),(1,2,3,0)") + tb := external.GetTableByName(t, tk, "test", "foo") + err := domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + tk.MustExec("set @@tidb_allow_mpp=0") + sql := "select a,b,c,count(*) from foo group by a,b,c order by a,b,c" + tk.MustQuery(sql).Check(testkit.Rows("1 2 3 8")) + rows := tk.MustQuery("explain " + sql).Rows() + + for _, row := range rows { + resBuff := bytes.NewBufferString("") + fmt.Fprintf(resBuff, "%s\n", row) + res := resBuff.String() + // StreamAgg with group keys on TiFlash is not supported + if strings.Contains(res, "tiflash") { + require.NotContains(t, res, "StreamAgg") + } + } +} + func TestTiflashEmptyDynamicPruneResult(t *testing.T) { store := testkit.CreateMockStore(t, withMockTiFlash(2)) tk := testkit.NewTestKit(t, store) @@ -1225,3 +1253,83 @@ func TestTiflashEmptyDynamicPruneResult(t *testing.T) { tk.MustQuery("select /*+ read_from_storage(tiflash[t2]) */ * from IDT_RP24833 partition(p2) t2 where t2. col1 <= -8448770111093677011;").Check(testkit.Rows()) tk.MustQuery("select /*+ read_from_storage(tiflash[t1, t2]) */ * from IDT_RP24833 partition(p3, p4) t1 join IDT_RP24833 partition(p2) t2 on t1.col1 = t2.col1 where t1. col1 between -8448770111093677011 and -8448770111093677011 and t2. col1 <= -8448770111093677011;").Check(testkit.Rows()) } + +func TestDisaggregatedTiFlash(t *testing.T) { + config.UpdateGlobal(func(conf *config.Config) { + conf.DisaggregatedTiFlash = true + }) + store := testkit.CreateMockStore(t, withMockTiFlash(2)) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(c1 int)") + tk.MustExec("alter table t set tiflash replica 1") + tb := external.GetTableByName(t, tk, "test", "t") + err := domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + tk.MustExec("set @@session.tidb_isolation_read_engines=\"tiflash\"") + + err = tk.ExecToErr("select * from t;") + require.Contains(t, err.Error(), "Please check tiflash_compute node is available") + + config.UpdateGlobal(func(conf *config.Config) { + conf.DisaggregatedTiFlash = false + }) + tk.MustQuery("select * from t;").Check(testkit.Rows()) +} + +func TestDisaggregatedTiFlashQuery(t *testing.T) { + config.UpdateGlobal(func(conf *config.Config) { + conf.DisaggregatedTiFlash = true + }) + defer config.UpdateGlobal(func(conf *config.Config) { + conf.DisaggregatedTiFlash = false + }) + + store := testkit.CreateMockStore(t, withMockTiFlash(2)) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists tbl_1") + tk.MustExec(`create table tbl_1 ( col_1 bigint not null default -1443635317331776148, + col_2 text ( 176 ) collate utf8mb4_bin not null, + col_3 decimal ( 8, 3 ), + col_4 varchar ( 128 ) collate utf8mb4_bin not null, + col_5 varchar ( 377 ) collate utf8mb4_bin, + col_6 double, + col_7 varchar ( 459 ) collate utf8mb4_bin, + col_8 tinyint default -88 ) charset utf8mb4 collate utf8mb4_bin ;`) + tk.MustExec("alter table tbl_1 set tiflash replica 1") + tb := external.GetTableByName(t, tk, "test", "tbl_1") + err := domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + tk.MustExec("set @@session.tidb_isolation_read_engines=\"tiflash\"") + + needCheckTiFlashComputeNode := "false" + failpoint.Enable("github.com/pingcap/tidb/planner/core/testDisaggregatedTiFlashQuery", fmt.Sprintf("return(%s)", needCheckTiFlashComputeNode)) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/testDisaggregatedTiFlashQuery") + tk.MustExec("explain select max( tbl_1.col_1 ) as r0 , sum( tbl_1.col_1 ) as r1 , sum( tbl_1.col_8 ) as r2 from tbl_1 where tbl_1.col_8 != 68 or tbl_1.col_3 between null and 939 order by r0,r1,r2;") + + tk.MustExec("set @@tidb_partition_prune_mode = 'static';") + tk.MustExec("set @@session.tidb_isolation_read_engines=\"tiflash\"") + tk.MustExec("create table t1(c1 int, c2 int) partition by hash(c1) partitions 3") + tk.MustExec("insert into t1 values(1, 1), (2, 2), (3, 3)") + tk.MustExec("alter table t1 set tiflash replica 1") + tb = external.GetTableByName(t, tk, "test", "t1") + err = domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + tk.MustQuery("explain select * from t1 where c1 < 2").Check(testkit.Rows( + "PartitionUnion_10 9970.00 root ", + "├─TableReader_15 3323.33 root data:ExchangeSender_14", + "│ └─ExchangeSender_14 3323.33 mpp[tiflash] ExchangeType: PassThrough", + "│ └─Selection_13 3323.33 mpp[tiflash] lt(test.t1.c1, 2)", + "│ └─TableFullScan_12 10000.00 mpp[tiflash] table:t1, partition:p0 keep order:false, stats:pseudo", + "├─TableReader_19 3323.33 root data:ExchangeSender_18", + "│ └─ExchangeSender_18 3323.33 mpp[tiflash] ExchangeType: PassThrough", + "│ └─Selection_17 3323.33 mpp[tiflash] lt(test.t1.c1, 2)", + "│ └─TableFullScan_16 10000.00 mpp[tiflash] table:t1, partition:p1 keep order:false, stats:pseudo", + "└─TableReader_23 3323.33 root data:ExchangeSender_22", + " └─ExchangeSender_22 3323.33 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection_21 3323.33 mpp[tiflash] lt(test.t1.c1, 2)", + " └─TableFullScan_20 10000.00 mpp[tiflash] table:t1, partition:p2 keep order:false, stats:pseudo")) + // tk.MustQuery("select * from t1 where c1 < 2").Check(testkit.Rows("1 1")) +} diff --git a/executor/union_scan.go b/executor/union_scan.go index 9c0483d974f1c..a23cd8b8c7873 100644 --- a/executor/union_scan.go +++ b/executor/union_scan.go @@ -129,7 +129,7 @@ func (us *UnionScanExec) open(ctx context.Context) error { if err != nil { return err } - us.snapshotChunkBuffer = newFirstChunk(us) + us.snapshotChunkBuffer = tryNewCacheChunk(us) return nil } diff --git a/executor/union_scan_test.go b/executor/union_scan_test.go index 8800e16d750dd..ecc3e0b6bbbfd 100644 --- a/executor/union_scan_test.go +++ b/executor/union_scan_test.go @@ -223,7 +223,7 @@ func TestUnionScanForMemBufferReader(t *testing.T) { tk.MustExec("create table t (a int,b int, unique index idx(b))") tk.MustExec("insert t values (1,1),(2,2)") tk.MustExec("begin") - tk.MustGetErrMsg("update t set b=b+1", "[kv:1062]Duplicate entry '2' for key 'idx'") + tk.MustGetErrMsg("update t set b=b+1", "[kv:1062]Duplicate entry '2' for key 't.idx'") // update with unchange index column. tk.MustExec("update t set a=a+1") tk.MustQuery("select * from t use index (idx)").Check(testkit.Rows("2 1", "3 2")) @@ -340,7 +340,7 @@ func TestForUpdateUntouchedIndex(t *testing.T) { tk.MustExec("begin") _, err := tk.Exec("insert into t values (1, 1), (2, 2), (1, 3) on duplicate key update a = a + 1;") require.NotNil(t, err) - require.EqualError(t, err, "[kv:1062]Duplicate entry '2' for key 'a'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '2' for key 't.a'") tk.MustExec("commit") tk.MustExec("admin check table t") } @@ -544,7 +544,7 @@ func TestIssue36903(t *testing.T) { tk.MustExec("insert into t_vwvgdc values (2, 15000, 61.75);") tk.MustExec("BEGIN OPTIMISTIC;") tk.MustExec("insert into t_vwvgdc (wkey, pkey, c_rdsfbc) values (155, 228000, 99.50);") - tk.MustQuery("select pkey from t_vwvgdc where 0 <> 0 union select pkey from t_vwvgdc;") + tk.MustQuery("select pkey from t_vwvgdc where 0 <> 0 union select pkey from t_vwvgdc;").Sort().Check(testkit.Rows("15000", "228000")) } func BenchmarkUnionScanRead(b *testing.B) { diff --git a/executor/update.go b/executor/update.go index e10875404b912..0068392653cdd 100644 --- a/executor/update.go +++ b/executor/update.go @@ -68,6 +68,8 @@ type UpdateExec struct { matches []bool // fkChecks contains the foreign key checkers. the map is tableID -> []*FKCheckExec fkChecks map[int64][]*FKCheckExec + // fkCascades contains the foreign key cascade. the map is tableID -> []*FKCascadeExec + fkCascades map[int64][]*FKCascadeExec } // prepare `handles`, `tableUpdatable`, `changed` to avoid re-computations. @@ -194,7 +196,8 @@ func (e *UpdateExec) exec(ctx context.Context, schema *expression.Schema, row, n // Update row fkChecks := e.fkChecks[content.TblID] - changed, err1 := updateRecord(ctx, e.ctx, handle, oldData, newTableData, flags, tbl, false, e.memTracker, fkChecks) + fkCascades := e.fkCascades[content.TblID] + changed, err1 := updateRecord(ctx, e.ctx, handle, oldData, newTableData, flags, tbl, false, e.memTracker, fkChecks, fkCascades) if err1 == nil { _, exist := e.updatedRowKeys[content.Start].Get(handle) memDelta := e.updatedRowKeys[content.Start].Set(handle, changed) @@ -247,7 +250,7 @@ func (e *UpdateExec) updateRows(ctx context.Context) (int, error) { fields := retTypes(e.children[0]) colsInfo := plannercore.GetUpdateColumnsInfo(e.tblID2table, e.tblColPosInfos, len(fields)) globalRowIdx := 0 - chk := newFirstChunk(e.children[0]) + chk := tryNewCacheChunk(e.children[0]) if !e.allAssignmentsAreConstant { e.evalBuffer = chunk.MutRowFromTypes(fields) } @@ -431,6 +434,7 @@ func (e *UpdateExec) Close() error { if err == nil && txn.Valid() && txn.GetSnapshot() != nil { txn.GetSnapshot().SetOption(kv.CollectRuntimeStats, nil) } + defer e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } return e.children[0].Close() } @@ -460,7 +464,6 @@ func (e *UpdateExec) collectRuntimeStatsEnabled() bool { SnapshotRuntimeStats: &txnsnapshot.SnapshotRuntimeStats{}, AllocatorRuntimeStats: autoid.NewAllocatorRuntimeStats(), } - e.ctx.GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.id, e.stats) } return true } @@ -543,3 +546,17 @@ func (e *UpdateExec) GetFKChecks() []*FKCheckExec { } return fkChecks } + +// GetFKCascades implements WithForeignKeyTrigger interface. +func (e *UpdateExec) GetFKCascades() []*FKCascadeExec { + fkCascades := make([]*FKCascadeExec, 0, len(e.fkChecks)) + for _, fkc := range e.fkCascades { + fkCascades = append(fkCascades, fkc...) + } + return fkCascades +} + +// HasFKCascades implements WithForeignKeyTrigger interface. +func (e *UpdateExec) HasFKCascades() bool { + return len(e.fkCascades) > 0 +} diff --git a/executor/window.go b/executor/window.go index 3ce26a03e59cf..aaa1e51cacc85 100644 --- a/executor/window.go +++ b/executor/window.go @@ -151,7 +151,7 @@ func (e *WindowExec) consumeGroupRows(groupRows []chunk.Row) (err error) { } func (e *WindowExec) fetchChild(ctx context.Context) (EOF bool, err error) { - childResult := newFirstChunk(e.children[0]) + childResult := tryNewCacheChunk(e.children[0]) err = Next(ctx, e.children[0], childResult) if err != nil { return false, errors.Trace(err) @@ -162,7 +162,7 @@ func (e *WindowExec) fetchChild(ctx context.Context) (EOF bool, err error) { return true, nil } - resultChk := chunk.New(e.retFieldTypes, 0, numRows) + resultChk := e.ctx.GetSessionVars().GetNewChunkWithCapacity(e.retFieldTypes, 0, numRows, e.AllocPool) err = e.copyChk(childResult, resultChk) if err != nil { return false, err diff --git a/executor/write.go b/executor/write.go index 8d4336b07b960..363bb097fd02c 100644 --- a/executor/write.go +++ b/executor/write.go @@ -51,18 +51,12 @@ var ( // 1. changed (bool) : does the update really change the row values. e.g. update set i = 1 where i = 1; // 2. err (error) : error in the update. func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, oldData, newData []types.Datum, modified []bool, t table.Table, - onDup bool, memTracker *memory.Tracker, fkChecks []*FKCheckExec) (bool, error) { + onDup bool, memTracker *memory.Tracker, fkChecks []*FKCheckExec, fkCascades []*FKCascadeExec) (bool, error) { if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { span1 := span.Tracer().StartSpan("executor.updateRecord", opentracing.ChildOf(span.Context())) defer span1.Finish() ctx = opentracing.ContextWithSpan(ctx, span1) } - txn, err := sctx.Txn(false) - if err != nil { - return false, err - } - memUsageOfTxnState := txn.Size() - defer memTracker.Consume(int64(txn.Size() - memUsageOfTxnState)) sc := sctx.GetSessionVars().StmtCtx changed, handleChanged := false, false // onUpdateSpecified is for "UPDATE SET ts_field = old_value", the @@ -115,7 +109,7 @@ func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, old if err != nil { return false, err } - if err = t.Allocators(sctx).Get(autoid.RowIDAllocType).Rebase(ctx, recordID, true); err != nil { + if err = t.Allocators(sctx).Get(autoid.AutoIncrementType).Rebase(ctx, recordID, true); err != nil { return false, err } } @@ -207,7 +201,7 @@ func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, old } } else { // Update record to new value and update index. - if err = t.UpdateRecord(ctx, sctx, h, oldData, newData, modified); err != nil { + if err := t.UpdateRecord(ctx, sctx, h, oldData, newData, modified); err != nil { if terr, ok := errors.Cause(err).(*terror.Error); sctx.GetSessionVars().StmtCtx.IgnoreNoPartition && ok && terr.Code() == errno.ErrNoPartitionForGivenValue { return false, nil } @@ -220,6 +214,12 @@ func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, old return false, err } } + for _, fkc := range fkCascades { + err := fkc.onUpdateRow(sc, oldData, newData) + if err != nil { + return false, err + } + } if onDup { sc.AddAffectedRows(2) } else { diff --git a/executor/writetest/BUILD.bazel b/executor/writetest/BUILD.bazel new file mode 100644 index 0000000000000..2ddc46c29ad82 --- /dev/null +++ b/executor/writetest/BUILD.bazel @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "writetest_test", + srcs = [ + "main_test.go", + "write_test.go", + ], + flaky = True, + race = "on", + shard_count = 50, + deps = [ + "//config", + "//executor", + "//kv", + "//meta/autoid", + "//parser/model", + "//parser/mysql", + "//planner/core", + "//session", + "//sessionctx", + "//sessionctx/stmtctx", + "//sessionctx/variable", + "//sessiontxn", + "//store/mockstore", + "//table", + "//table/tables", + "//testkit", + "//types", + "//util", + "//util/mock", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//tikv", + "@io_opencensus_go//stats/view", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/executor/writetest/main_test.go b/executor/writetest/main_test.go new file mode 100644 index 0000000000000..075e1f91b488a --- /dev/null +++ b/executor/writetest/main_test.go @@ -0,0 +1,60 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package writetest + +import ( + "fmt" + "testing" + + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/meta/autoid" + "github.com/pingcap/tidb/testkit" + "github.com/tikv/client-go/v2/tikv" + "go.opencensus.io/stats/view" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + autoid.SetStep(5000) + config.UpdateGlobal(func(conf *config.Config) { + conf.Log.SlowThreshold = 30000 // 30s + conf.TiKVClient.AsyncCommit.SafeWindow = 0 + conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 + conf.Experimental.AllowsExpressionIndex = true + }) + tikv.EnableFailpoints() + + opts := []goleak.Option{ + goleak.Cleanup(func(_ int) { + view.Stop() + }), + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), + goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + } + + goleak.VerifyTestMain(m, opts...) +} + +func fillData(tk *testkit.TestKit, table string) { + tk.MustExec("use test") + tk.MustExec(fmt.Sprintf("create table %s(id int not null default 1, name varchar(255), PRIMARY KEY(id));", table)) + + // insert data + tk.MustExec(fmt.Sprintf("insert INTO %s VALUES (1, \"hello\");", table)) + tk.MustExec(fmt.Sprintf("insert into %s values (2, \"hello\");", table)) +} diff --git a/executor/write_test.go b/executor/writetest/write_test.go similarity index 98% rename from executor/write_test.go rename to executor/writetest/write_test.go index ab3ec6813f5c7..9aca357032b68 100644 --- a/executor/write_test.go +++ b/executor/writetest/write_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package executor_test +package writetest import ( "context" @@ -319,10 +319,10 @@ func TestInsert(t *testing.T) { tk.MustExec("create table t(name varchar(255), b int, c int, primary key(name(2)))") tk.MustExec("insert into t(name, b) values(\"cha\", 3)") err = tk.ExecToErr("insert into t(name, b) values(\"chb\", 3)") - require.EqualError(t, err, "[kv:1062]Duplicate entry 'ch' for key 'PRIMARY'") + require.EqualError(t, err, "[kv:1062]Duplicate entry 'ch' for key 't.PRIMARY'") tk.MustExec("insert into t(name, b) values(\"测试\", 3)") err = tk.ExecToErr("insert into t(name, b) values(\"测试\", 3)") - require.EqualError(t, err, "[kv:1062]Duplicate entry '测试' for key 'PRIMARY'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '\xe6\xb5' for key 't.PRIMARY'") } func TestMultiBatch(t *testing.T) { @@ -542,7 +542,7 @@ func TestInsertIgnore(t *testing.T) { require.Empty(t, tk.Session().LastMessage()) require.NoError(t, err) r = tk.MustQuery("SHOW WARNINGS") - r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'PRIMARY'")) + r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.PRIMARY'")) testSQL = `drop table if exists test; create table test (i int primary key, j int unique); @@ -592,6 +592,25 @@ commit;` tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3")) } +func TestIssue38950(t *testing.T) { + store := testkit.CreateMockStore(t) + var cfg kv.InjectionConfig + tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg)) + tk.MustExec("use test;") + tk.MustExec("drop table if exists t; create table t (id smallint auto_increment primary key);") + tk.MustExec("alter table t add column c1 int default 1;") + tk.MustExec("insert ignore into t(id) values (194626268);") + require.Empty(t, tk.Session().LastMessage()) + + tk.MustQuery("select * from t").Check(testkit.Rows("32767 1")) + + tk.MustExec("insert ignore into t(id) values ('*') on duplicate key update c1 = 2;") + require.Equal(t, int64(2), int64(tk.Session().AffectedRows())) + require.Empty(t, tk.Session().LastMessage()) + + tk.MustQuery("select * from t").Check(testkit.Rows("32767 2")) +} + func TestInsertOnDup(t *testing.T) { store := testkit.CreateMockStore(t) var cfg kv.InjectionConfig @@ -785,21 +804,21 @@ func TestInsertIgnoreOnDup(t *testing.T) { tk.MustExec("create table t2(`col_25` set('Alice','Bob','Charlie','David') NOT NULL,`col_26` date NOT NULL DEFAULT '2016-04-15', PRIMARY KEY (`col_26`) clustered, UNIQUE KEY `idx_9` (`col_25`,`col_26`),UNIQUE KEY `idx_10` (`col_25`))") tk.MustExec("insert into t2(col_25, col_26) values('Bob', '1989-03-23'),('Alice', '2023-11-24'), ('Charlie', '2023-12-05')") tk.MustExec("insert ignore into t2 (col_25,col_26) values ( 'Bob','1977-11-23' ) on duplicate key update col_25 = 'Alice', col_26 = '2036-12-13'") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'Alice' for key 'idx_10'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'Alice' for key 't2.idx_10'")) tk.MustQuery("select * from t2").Check(testkit.Rows("Bob 1989-03-23", "Alice 2023-11-24", "Charlie 2023-12-05")) tk.MustExec("drop table if exists t4") tk.MustExec("create table t4(id int primary key clustered, k int, v int, unique key uk1(k))") tk.MustExec("insert into t4 values (1, 10, 100), (3, 30, 300)") tk.MustExec("insert ignore into t4 (id, k, v) values(1, 0, 0) on duplicate key update id = 2, k = 30") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '30' for key 'uk1'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '30' for key 't4.uk1'")) tk.MustQuery("select * from t4").Check(testkit.Rows("1 10 100", "3 30 300")) tk.MustExec("drop table if exists t5") tk.MustExec("create table t5(k1 varchar(100), k2 varchar(100), uk1 int, v int, primary key(k1, k2) clustered, unique key ukk1(uk1), unique key ukk2(v))") tk.MustExec("insert into t5(k1, k2, uk1, v) values('1', '1', 1, '100'), ('1', '3', 2, '200')") tk.MustExec("update ignore t5 set k2 = '2', uk1 = 2 where k1 = '1' and k2 = '1'") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '2' for key 'ukk1'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '2' for key 't5.ukk1'")) tk.MustQuery("select * from t5").Check(testkit.Rows("1 1 1 100", "1 3 2 200")) tk.MustExec("drop table if exists t6") @@ -1535,7 +1554,7 @@ func TestPartitionedTableUpdate(t *testing.T) { require.NoError(t, err) require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 1") r = tk.MustQuery("SHOW WARNINGS;") - r.Check(testkit.Rows("Warning 1062 Duplicate entry '5' for key 'PRIMARY'")) + r.Check(testkit.Rows("Warning 1062 Duplicate entry '5' for key 't.PRIMARY'")) tk.MustQuery("select * from t order by a").Check(testkit.Rows("5", "7")) // test update ignore for truncate as warning @@ -1556,7 +1575,7 @@ func TestPartitionedTableUpdate(t *testing.T) { require.NoError(t, err) require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 1") r = tk.MustQuery("SHOW WARNINGS;") - r.Check(testkit.Rows("Warning 1062 Duplicate entry '5' for key 'I_uniq'")) + r.Check(testkit.Rows("Warning 1062 Duplicate entry '5' for key 't.I_uniq'")) tk.MustQuery("select * from t order by a").Check(testkit.Rows("5", "7")) } @@ -1877,7 +1896,7 @@ func checkCases(tests []testCase, ld *executor.LoadDataInfo, t *testing.T, tk *t } ld.SetMessage() require.Equal(t, tt.expectedMsg, tk.Session().LastMessage()) - ctx.StmtCommit() + ctx.StmtCommit(context.Background()) txn, err := ctx.Txn(true) require.NoError(t, err) err = txn.Commit(context.Background()) @@ -2334,7 +2353,7 @@ func TestLoadDataIntoPartitionedTable(t *testing.T) { require.NoError(t, err) ld.SetMaxRowsInBatch(20000) ld.SetMessage() - ctx.StmtCommit() + ctx.StmtCommit(context.Background()) txn, err := ctx.Txn(true) require.NoError(t, err) err = txn.Commit(context.Background()) @@ -2710,7 +2729,7 @@ func TestDeferConstraintCheckForDelete(t *testing.T) { tk.MustExec("begin") tk.MustExec("insert into t1 values(1, 3)") tk.MustExec("delete from t1 where j = 3") - tk.MustGetErrMsg("commit", "previous statement: delete from t1 where j = 3: [kv:1062]Duplicate entry '1' for key 'PRIMARY'") + tk.MustGetErrMsg("commit", "previous statement: delete from t1 where j = 3: [kv:1062]Duplicate entry '1' for key 't1.PRIMARY'") tk.MustExec("rollback") tk.MustExec("create table t2(i int, j int, unique index idx(i))") @@ -2718,7 +2737,7 @@ func TestDeferConstraintCheckForDelete(t *testing.T) { tk.MustExec("begin") tk.MustExec("insert into t2 values(1, 3)") tk.MustExec("delete from t2 where j = 3") - tk.MustGetErrMsg("commit", "previous statement: delete from t2 where j = 3: [kv:1062]Duplicate entry '1' for key 'idx'") + tk.MustGetErrMsg("commit", "previous statement: delete from t2 where j = 3: [kv:1062]Duplicate entry '1' for key 't2.idx'") tk.MustExec("admin check table t2") tk.MustExec("create table t3(i int, j int, primary key(i))") @@ -3051,7 +3070,7 @@ func TestWriteListPartitionTable(t *testing.T) { // Test insert error tk.MustExec("insert into t values (1, 'a')") - tk.MustGetErrMsg("insert into t values (1, 'd')", "[kv:1062]Duplicate entry '1' for key 'idx'") + tk.MustGetErrMsg("insert into t values (1, 'd')", "[kv:1062]Duplicate entry '1' for key 't.idx'") tk.MustGetErrMsg("insert into t values (100, 'd')", "[table:1526]Table has no partition for value 100") tk.MustExec("admin check table t;") @@ -3099,7 +3118,7 @@ func TestWriteListColumnsPartitionTable(t *testing.T) { // Test insert error tk.MustExec("insert into t values (1, 'a')") err := tk.ExecToErr("insert into t values (1, 'd')") - require.EqualError(t, err, "[kv:1062]Duplicate entry '1' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '1' for key 't.idx'") err = tk.ExecToErr("insert into t values (100, 'd')") require.EqualError(t, err, "[table:1526]Table has no partition for value from column_list") tk.MustExec("admin check table t;") @@ -3133,7 +3152,7 @@ func TestWriteListPartitionTable1(t *testing.T) { // Test add unique index failed. tk.MustExec("insert into t values (1, 'a'),(1,'b')") err := tk.ExecToErr("alter table t add unique index idx (id)") - require.EqualError(t, err, "[kv:1062]Duplicate entry '1' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '1' for key 't.idx'") // Test add unique index success. tk.MustExec("delete from t where name='b'") tk.MustExec("alter table t add unique index idx (id)") @@ -3158,11 +3177,11 @@ func TestWriteListPartitionTable1(t *testing.T) { tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows()) // Test insert on duplicate error err = tk.ExecToErr("insert into t values (3, 'a'), (11,'x') on duplicate key update id=id+1") - require.EqualError(t, err, "[kv:1062]Duplicate entry '4' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '4' for key 't.idx'") tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g")) // Test insert ignore with duplicate tk.MustExec("insert ignore into t values (1, 'b'), (5,'a'),(null,'y')") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'idx'", "Warning 1062 Duplicate entry '5' for key 'idx'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.idx'", "Warning 1062 Duplicate entry '5' for key 't.idx'")) tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g")) tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 x")) tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e")) @@ -3187,7 +3206,7 @@ func TestWriteListPartitionTable1(t *testing.T) { tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c")) // Test update meet duplicate error. err = tk.ExecToErr("update t set id=2 where id = 1") - require.EqualError(t, err, "[kv:1062]Duplicate entry '2' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '2' for key 't.idx'") tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c")) // Test update multi-partitions @@ -3199,7 +3218,7 @@ func TestWriteListPartitionTable1(t *testing.T) { tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a")) // Test update meet duplicate error. err = tk.ExecToErr("update t set id=id+17 where id in (3,10)") - require.EqualError(t, err, "[kv:1062]Duplicate entry '20' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '20' for key 't.idx'") tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a")) // Test update meet no partition error. err = tk.ExecToErr("update t set id=id*2 where id in (3,20)") @@ -3262,7 +3281,7 @@ func TestWriteListPartitionTable2(t *testing.T) { // Test add unique index failed. tk.MustExec("insert into t (id,name) values (1, 'a'),(1,'b')") err := tk.ExecToErr("alter table t add unique index idx (id,b)") - require.EqualError(t, err, "[kv:1062]Duplicate entry '1-2' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '1-2' for key 't.idx'") // Test add unique index success. tk.MustExec("delete from t where name='b'") tk.MustExec("alter table t add unique index idx (id,b)") @@ -3287,11 +3306,11 @@ func TestWriteListPartitionTable2(t *testing.T) { tk.MustQuery("select id,name from t partition(p3) order by id").Check(testkit.Rows()) // Test insert on duplicate error err = tk.ExecToErr("insert into t (id,name) values (3, 'a'), (11,'x') on duplicate key update id=id+1") - require.EqualError(t, err, "[kv:1062]Duplicate entry '4-2' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry '4-2' for key 't.idx'") tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g")) // Test insert ignore with duplicate tk.MustExec("insert ignore into t (id,name) values (1, 'b'), (5,'a'),(null,'y')") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1-2' for key 'idx'", "Warning 1062 Duplicate entry '5-2' for key 'idx'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1-2' for key 't.idx'", "Warning 1062 Duplicate entry '5-2' for key 't.idx'")) tk.MustQuery("select id,name from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g")) tk.MustQuery("select id,name from t partition(p1) order by id").Check(testkit.Rows("1 x")) tk.MustQuery("select id,name from t partition(p2) order by id").Check(testkit.Rows("4 e")) @@ -3315,7 +3334,7 @@ func TestWriteListPartitionTable2(t *testing.T) { tk.MustExec("update t set name='y' where id < 3") tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c")) // Test update meet duplicate error. - tk.MustGetErrMsg("update t set id=2 where id = 1", "[kv:1062]Duplicate entry '2-2' for key 'idx'") + tk.MustGetErrMsg("update t set id=2 where id = 1", "[kv:1062]Duplicate entry '2-2' for key 't.idx'") tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c")) // Test update multi-partitions @@ -3326,7 +3345,7 @@ func TestWriteListPartitionTable2(t *testing.T) { tk.MustExec("update t set id=id*10 where id in (1,2)") tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a")) // Test update meet duplicate error. - tk.MustGetErrMsg("update t set id=id+17 where id in (3,10)", "[kv:1062]Duplicate entry '20-2' for key 'idx'") + tk.MustGetErrMsg("update t set id=id+17 where id in (3,10)", "[kv:1062]Duplicate entry '20-2' for key 't.idx'") tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a")) // Test update meet no partition error. tk.MustGetErrMsg("update t set id=id*2 where id in (3,20)", "[table:1526]Table has no partition for value 40") @@ -3385,7 +3404,7 @@ func TestWriteListColumnsPartitionTable1(t *testing.T) { // Test add unique index failed. tk.MustExec("insert into t values (1, 'a'),(1,'b')") - tk.MustGetErrMsg("alter table t add unique index idx (id)", "[kv:1062]Duplicate entry '1' for key 'idx'") + tk.MustGetErrMsg("alter table t add unique index idx (id)", "[kv:1062]Duplicate entry '1' for key 't.idx'") // Test add unique index success. tk.MustExec("delete from t where name='b'") tk.MustExec("alter table t add unique index idx (id)") @@ -3409,11 +3428,11 @@ func TestWriteListColumnsPartitionTable1(t *testing.T) { tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e")) tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows()) // Test insert on duplicate error - tk.MustGetErrMsg("insert into t values (3, 'a'), (11,'x') on duplicate key update id=id+1", "[kv:1062]Duplicate entry '4' for key 'idx'") + tk.MustGetErrMsg("insert into t values (3, 'a'), (11,'x') on duplicate key update id=id+1", "[kv:1062]Duplicate entry '4' for key 't.idx'") tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g")) // Test insert ignore with duplicate tk.MustExec("insert ignore into t values (1, 'b'), (5,'a'),(null,'y')") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'idx'", "Warning 1062 Duplicate entry '5' for key 'idx'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.idx'", "Warning 1062 Duplicate entry '5' for key 't.idx'")) tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g")) tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 x")) tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e")) @@ -3436,7 +3455,7 @@ func TestWriteListColumnsPartitionTable1(t *testing.T) { tk.MustExec("update t set name='y' where id < 3") tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c")) // Test update meet duplicate error. - tk.MustGetErrMsg("update t set id=2 where id = 1", "[kv:1062]Duplicate entry '2' for key 'idx'") + tk.MustGetErrMsg("update t set id=2 where id = 1", "[kv:1062]Duplicate entry '2' for key 't.idx'") tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c")) // Test update multi-partitions @@ -3447,7 +3466,7 @@ func TestWriteListColumnsPartitionTable1(t *testing.T) { tk.MustExec("update t set id=id*10 where id in (1,2)") tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a")) // Test update meet duplicate error. - tk.MustGetErrMsg("update t set id=id+17 where id in (3,10)", "[kv:1062]Duplicate entry '20' for key 'idx'") + tk.MustGetErrMsg("update t set id=id+17 where id in (3,10)", "[kv:1062]Duplicate entry '20' for key 't.idx'") tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a")) // Test update meet no partition error. tk.MustGetErrMsg("update t set id=id*2 where id in (3,20)", "[table:1526]Table has no partition for value from column_list") @@ -3505,7 +3524,7 @@ func TestWriteListColumnsPartitionTable2(t *testing.T) { // Test add unique index failed. tk.MustExec("insert into t values ('w', 1, 1),('w', 1, 2)") err := tk.ExecToErr("alter table t add unique index idx (location,id)") - require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-1' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-1' for key 't.idx'") // Test add unique index success. tk.MustExec("delete from t where a=2") tk.MustExec("alter table t add unique index idx (location,id)") @@ -3531,11 +3550,11 @@ func TestWriteListColumnsPartitionTable2(t *testing.T) { tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows()) // Test insert on duplicate error tk.MustExec("insert into t values ('w', 2, 2), ('w', 1, 1)") - tk.MustGetErrMsg("insert into t values ('w', 2, 3) on duplicate key update id=1", "[kv:1062]Duplicate entry 'w-1' for key 'idx'") + tk.MustGetErrMsg("insert into t values ('w', 2, 3) on duplicate key update id=1", "[kv:1062]Duplicate entry 'w-1' for key 't.idx'") tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1", "w 2 2")) // Test insert ignore with duplicate tk.MustExec("insert ignore into t values ('w', 2, 2), ('w', 3, 3), ('n', 10, 10)") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'w-2' for key 'idx'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'w-2' for key 't.idx'")) tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1", "w 2 2", "w 3 3")) tk.MustQuery("select * from t partition(p_north) order by id").Check(testkit.Rows("n 9 9", "n 10 10")) // Test insert ignore without duplicate @@ -3564,7 +3583,7 @@ func TestWriteListColumnsPartitionTable2(t *testing.T) { tk.MustQuery("select * from t partition(p_west) order by id,a").Check(testkit.Rows("w 1 5", "w 2 5", "w 3 6")) // Test update meet duplicate error. err = tk.ExecToErr("update t set id=id+1 where location='w' and id<2") - require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-2' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-2' for key 't.idx'") tk.MustQuery("select * from t partition(p_west) order by id,a").Check(testkit.Rows("w 1 5", "w 2 5", "w 3 6")) // Test update multi-partitions @@ -3582,7 +3601,7 @@ func TestWriteListColumnsPartitionTable2(t *testing.T) { tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "e 8 9", "n 11 15")) // Test update meet duplicate error. err = tk.ExecToErr("update t set id=id+1 where location='w' and id in (1,2)") - require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-2' for key 'idx'") + require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-2' for key 't.idx'") tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "e 8 9", "n 11 15")) // Test update meet no partition error. err = tk.ExecToErr("update t set id=id+3 where location='w' and id in (1,2)") @@ -4016,14 +4035,14 @@ func TestUpdate(t *testing.T) { require.NoError(t, err) require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 1") r = tk.MustQuery("SHOW WARNINGS;") - r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'PRIMARY'")) + r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.PRIMARY'")) tk.MustQuery("select * from t").Check(testkit.Rows("1", "2")) // test update ignore for truncate as warning err = tk.ExecToErr("update ignore t set a = 1 where a = (select '2a')") require.NoError(t, err) r = tk.MustQuery("SHOW WARNINGS;") - r.Check(testkit.Rows("Warning 1292 Truncated incorrect DOUBLE value: '2a'", "Warning 1292 Truncated incorrect DOUBLE value: '2a'", "Warning 1062 Duplicate entry '1' for key 'PRIMARY'")) + r.Check(testkit.Rows("Warning 1292 Truncated incorrect DOUBLE value: '2a'", "Warning 1292 Truncated incorrect DOUBLE value: '2a'", "Warning 1062 Duplicate entry '1' for key 't.PRIMARY'")) tk.MustExec("update ignore t set a = 42 where a = 2;") tk.MustQuery("select * from t").Check(testkit.Rows("1", "42")) @@ -4037,7 +4056,7 @@ func TestUpdate(t *testing.T) { require.NoError(t, err) require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 1") r = tk.MustQuery("SHOW WARNINGS;") - r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'I_uniq'")) + r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.I_uniq'")) tk.MustQuery("select * from t").Check(testkit.Rows("1", "2")) // test issue21965 @@ -4299,3 +4318,23 @@ func TestIssueInsertPrefixIndexForNonUTF8Collation(t *testing.T) { tk.MustExec("insert into t3 select 'abc '") tk.MustGetErrCode("insert into t3 select 'abc d'", 1062) } + +func TestMutipleReplaceAndInsertInOneSession(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t_securities(id bigint not null auto_increment primary key, security_id varchar(8), market_id smallint, security_type int, unique key uu(security_id, market_id))") + tk.MustExec(`insert into t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + tk.MustExec(`replace into t_securities (security_id, market_id, security_type) select security_id+1, 1, security_type from t_securities where security_id="7";`) + tk.MustExec(`INSERT INTO t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + + tk.MustQuery("select * from t_securities").Sort().Check(testkit.Rows("1 1 2 7", "2 7 1 7", "3 8 1 7")) + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec(`insert into t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + tk2.MustExec(`insert into t_securities (security_id, market_id, security_type) select security_id+2, 1, security_type from t_securities where security_id="7";`) + tk2.MustExec(`INSERT INTO t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + + tk2.MustQuery("select * from t_securities").Sort().Check(testkit.Rows("1 1 2 7", "2 7 1 7", "3 8 1 7", "8 9 1 7")) +} diff --git a/expression/BUILD.bazel b/expression/BUILD.bazel index c98dcdb1ec483..17436f517a673 100644 --- a/expression/BUILD.bazel +++ b/expression/BUILD.bazel @@ -52,6 +52,7 @@ go_library( "explain.go", "expr_to_pb.go", "expression.go", + "extension.go", "function_traits.go", "helper.go", "partition_pruner.go", @@ -66,6 +67,7 @@ go_library( deps = [ "//config", "//errno", + "//extension", "//kv", "//parser", "//parser/ast", @@ -95,8 +97,10 @@ go_library( "//util/mathutil", "//util/mock", "//util/parser", + "//util/password-validation", "//util/plancodec", "//util/printer", + "//util/sem", "//util/set", "//util/size", "//util/sqlexec", @@ -107,6 +111,7 @@ go_library( "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_tipb//go-tipb", + "@com_github_pkg_errors//:errors", "@com_github_tikv_client_go_v2//oracle", "@org_golang_x_exp//slices", "@org_golang_x_tools//container/intsets", @@ -117,7 +122,7 @@ go_library( go_test( name = "expression_test", - timeout = "short", + timeout = "moderate", srcs = [ "bench_test.go", "builtin_arithmetic_test.go", @@ -172,6 +177,7 @@ go_test( "integration_serial_test.go", "integration_test.go", "main_test.go", + "multi_valued_index_test.go", "scalar_function_test.go", "schema_test.go", "typeinfer_test.go", @@ -180,6 +186,7 @@ go_test( data = glob(["testdata/**"]), embed = [":expression"], flaky = True, + race = "on", shard_count = 50, deps = [ "//config", diff --git a/expression/aggregation/agg_to_pb.go b/expression/aggregation/agg_to_pb.go index 54fbce47df23a..1d90ab02fb253 100644 --- a/expression/aggregation/agg_to_pb.go +++ b/expression/aggregation/agg_to_pb.go @@ -15,6 +15,7 @@ package aggregation import ( + "context" "strconv" "github.com/pingcap/errors" @@ -130,7 +131,7 @@ func AggFuncToPBExpr(sctx sessionctx.Context, client kv.Client, aggFunc *AggFunc orderBy = append(orderBy, pbArg) } // encode GroupConcatMaxLen - GCMaxLen, err := sctx.GetSessionVars().GetSessionOrGlobalSystemVar(variable.GroupConcatMaxLen) + GCMaxLen, err := sctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), variable.GroupConcatMaxLen) if err != nil { return nil, errors.Errorf("Error happened when buildGroupConcat: no system variable named '%s'", variable.GroupConcatMaxLen) } diff --git a/expression/aggregation/descriptor.go b/expression/aggregation/descriptor.go index e174108cbd9b4..2af7d4d49f348 100644 --- a/expression/aggregation/descriptor.go +++ b/expression/aggregation/descriptor.go @@ -16,6 +16,7 @@ package aggregation import ( "bytes" + "context" "fmt" "math" "strconv" @@ -229,7 +230,7 @@ func (a *AggFuncDesc) GetAggFunc(ctx sessionctx.Context) Aggregation { var s string var err error var maxLen uint64 - s, err = ctx.GetSessionVars().GetSessionOrGlobalSystemVar(variable.GroupConcatMaxLen) + s, err = ctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), variable.GroupConcatMaxLen) if err != nil { panic(fmt.Sprintf("Error happened when GetAggFunc: no system variable named '%s'", variable.GroupConcatMaxLen)) } diff --git a/expression/aggregation/main_test.go b/expression/aggregation/main_test.go index deead25faaadc..11504899f250f 100644 --- a/expression/aggregation/main_test.go +++ b/expression/aggregation/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/expression/builtin.go b/expression/builtin.go index a24d2ac737806..66abac551a3e6 100644 --- a/expression/builtin.go +++ b/expression/builtin.go @@ -873,7 +873,9 @@ var funcs = map[string]functionClass{ ast.JSONMerge: &jsonMergeFunctionClass{baseFunctionClass{ast.JSONMerge, 2, -1}}, ast.JSONObject: &jsonObjectFunctionClass{baseFunctionClass{ast.JSONObject, 0, -1}}, ast.JSONArray: &jsonArrayFunctionClass{baseFunctionClass{ast.JSONArray, 0, -1}}, + ast.JSONMemberOf: &jsonMemberOfFunctionClass{baseFunctionClass{ast.JSONMemberOf, 2, 2}}, ast.JSONContains: &jsonContainsFunctionClass{baseFunctionClass{ast.JSONContains, 2, 3}}, + ast.JSONOverlaps: &jsonOverlapsFunctionClass{baseFunctionClass{ast.JSONOverlaps, 2, 2}}, ast.JSONContainsPath: &jsonContainsPathFunctionClass{baseFunctionClass{ast.JSONContainsPath, 3, -1}}, ast.JSONValid: &jsonValidFunctionClass{baseFunctionClass{ast.JSONValid, 1, 1}}, ast.JSONArrayAppend: &jsonArrayAppendFunctionClass{baseFunctionClass{ast.JSONArrayAppend, 3, -1}}, @@ -883,6 +885,7 @@ var funcs = map[string]functionClass{ ast.JSONPretty: &jsonPrettyFunctionClass{baseFunctionClass{ast.JSONPretty, 1, 1}}, ast.JSONQuote: &jsonQuoteFunctionClass{baseFunctionClass{ast.JSONQuote, 1, 1}}, ast.JSONSearch: &jsonSearchFunctionClass{baseFunctionClass{ast.JSONSearch, 3, -1}}, + ast.JSONStorageFree: &jsonStorageFreeFunctionClass{baseFunctionClass{ast.JSONStorageFree, 1, 1}}, ast.JSONStorageSize: &jsonStorageSizeFunctionClass{baseFunctionClass{ast.JSONStorageSize, 1, 1}}, ast.JSONDepth: &jsonDepthFunctionClass{baseFunctionClass{ast.JSONDepth, 1, 1}}, ast.JSONKeys: &jsonKeysFunctionClass{baseFunctionClass{ast.JSONKeys, 1, 2}}, @@ -943,6 +946,13 @@ func GetBuiltinList() []string { } res = append(res, funcName) } + + extensionFuncs.Range(func(key, _ any) bool { + funcName := key.(string) + res = append(res, funcName) + return true + }) + slices.Sort(res) return res } @@ -980,8 +990,13 @@ func (b *baseBuiltinFunc) MemoryUsage() (sum int64) { return } - sum = emptyBaseBuiltinFunc + b.bufAllocator.MemoryUsage() + - b.tp.MemoryUsage() + int64(len(b.charset)+len(b.collation)) + sum = emptyBaseBuiltinFunc + int64(len(b.charset)+len(b.collation)) + if b.bufAllocator != nil { + sum += b.bufAllocator.MemoryUsage() + } + if b.tp != nil { + sum += b.tp.MemoryUsage() + } if b.childrenVectorizedOnce != nil { sum += onceSize } diff --git a/expression/builtin_cast.go b/expression/builtin_cast.go index 0dd7e20cce24e..e7501656e91dc 100644 --- a/expression/builtin_cast.go +++ b/expression/builtin_cast.go @@ -23,6 +23,7 @@ package expression import ( + "fmt" "math" "strconv" "strings" @@ -35,6 +36,7 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" @@ -407,6 +409,149 @@ func (c *castAsDurationFunctionClass) getFunction(ctx sessionctx.Context, args [ return sig, nil } +type castAsArrayFunctionClass struct { + baseFunctionClass + + tp *types.FieldType +} + +func (c *castAsArrayFunctionClass) verifyArgs(args []Expression) error { + if err := c.baseFunctionClass.verifyArgs(args); err != nil { + return err + } + + if args[0].GetType().EvalType() != types.ETJson { + return ErrInvalidTypeForJSON.GenWithStackByArgs(1, "cast_as_array") + } + + return nil +} + +func (c *castAsArrayFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (sig builtinFunc, err error) { + if err := c.verifyArgs(args); err != nil { + return nil, err + } + arrayType := c.tp.ArrayType() + switch arrayType.GetType() { + case mysql.TypeYear, mysql.TypeJSON, mysql.TypeDouble, mysql.TypeFloat, mysql.TypeNewDecimal: + return nil, ErrNotSupportedYet.GenWithStackByArgs(fmt.Sprintf("CAST-ing data to array of %s", arrayType.String())) + } + if arrayType.EvalType() == types.ETString && arrayType.GetCharset() != charset.CharsetUTF8MB4 && arrayType.GetCharset() != charset.CharsetBin { + return nil, ErrNotSupportedYet.GenWithStackByArgs("specifying charset for multi-valued index") + } + if arrayType.EvalType() == types.ETString && arrayType.GetFlen() == types.UnspecifiedLength { + return nil, ErrNotSupportedYet.GenWithStackByArgs("CAST-ing data to array of char/binary BLOBs") + } + + bf, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp) + if err != nil { + return nil, err + } + sig = &castJSONAsArrayFunctionSig{bf} + return sig, nil +} + +type castJSONAsArrayFunctionSig struct { + baseBuiltinFunc +} + +func (b *castJSONAsArrayFunctionSig) Clone() builtinFunc { + newSig := &castJSONAsArrayFunctionSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +// fakeSctx is used to ignore the sql mode, `cast as array` should always return error if any. +var fakeSctx = &stmtctx.StatementContext{InInsertStmt: true} + +func (b *castJSONAsArrayFunctionSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { + val, isNull, err := b.args[0].EvalJSON(b.ctx, row) + if isNull || err != nil { + return res, isNull, err + } + + if val.TypeCode == types.JSONTypeCodeObject { + return types.BinaryJSON{}, false, ErrNotSupportedYet.GenWithStackByArgs("CAST-ing JSON OBJECT type to array") + } + + arrayVals := make([]any, 0, 8) + ft := b.tp.ArrayType() + f := convertJSON2Tp(ft.EvalType()) + if f == nil { + return types.BinaryJSON{}, false, ErrNotSupportedYet.GenWithStackByArgs(fmt.Sprintf("CAS-ing data to array of %s", ft.String())) + } + if val.TypeCode != types.JSONTypeCodeArray { + item, err := f(fakeSctx, val, ft) + if err != nil { + return types.BinaryJSON{}, false, err + } + arrayVals = append(arrayVals, item) + } else { + for i := 0; i < val.GetElemCount(); i++ { + item, err := f(fakeSctx, val.ArrayGetElem(i), ft) + if err != nil { + return types.BinaryJSON{}, false, err + } + arrayVals = append(arrayVals, item) + } + } + return types.CreateBinaryJSON(arrayVals), false, nil +} + +// ConvertJSON2Tp returns a function that can convert JSON to the specified type. +func ConvertJSON2Tp(v types.BinaryJSON, targetType *types.FieldType) (any, error) { + convertFunc := convertJSON2Tp(targetType.EvalType()) + if convertFunc == nil { + return nil, ErrInvalidJSONForFuncIndex + } + return convertFunc(fakeSctx, v, targetType) +} + +func convertJSON2Tp(evalType types.EvalType) func(*stmtctx.StatementContext, types.BinaryJSON, *types.FieldType) (any, error) { + switch evalType { + case types.ETString: + return func(sc *stmtctx.StatementContext, item types.BinaryJSON, tp *types.FieldType) (any, error) { + if item.TypeCode != types.JSONTypeCodeString { + return nil, ErrInvalidJSONForFuncIndex + } + return types.ProduceStrWithSpecifiedTp(string(item.GetString()), tp, sc, false) + } + case types.ETInt: + return func(sc *stmtctx.StatementContext, item types.BinaryJSON, tp *types.FieldType) (any, error) { + if item.TypeCode != types.JSONTypeCodeInt64 && item.TypeCode != types.JSONTypeCodeUint64 { + return nil, ErrInvalidJSONForFuncIndex + } + jsonToInt, err := types.ConvertJSONToInt(sc, item, mysql.HasUnsignedFlag(tp.GetFlag()), tp.GetType()) + if mysql.HasUnsignedFlag(tp.GetFlag()) { + return uint64(jsonToInt), err + } + return jsonToInt, err + } + case types.ETDatetime: + return func(sc *stmtctx.StatementContext, item types.BinaryJSON, tp *types.FieldType) (any, error) { + if (tp.GetType() == mysql.TypeDatetime && item.TypeCode != types.JSONTypeCodeDatetime) || (tp.GetType() == mysql.TypeDate && item.TypeCode != types.JSONTypeCodeDate) { + return nil, ErrInvalidJSONForFuncIndex + } + res := item.GetTime() + res.SetType(tp.GetType()) + if tp.GetType() == mysql.TypeDate { + // Truncate hh:mm:ss part if the type is Date. + res.SetCoreTime(types.FromDate(res.Year(), res.Month(), res.Day(), 0, 0, 0, 0)) + } + return res, nil + } + case types.ETDuration: + return func(sc *stmtctx.StatementContext, item types.BinaryJSON, tp *types.FieldType) (any, error) { + if item.TypeCode != types.JSONTypeCodeDuration { + return nil, ErrInvalidJSONForFuncIndex + } + return item.GetDuration(), nil + } + default: + return nil + } +} + type castAsJSONFunctionClass struct { baseFunctionClass @@ -1722,7 +1867,11 @@ func (b *builtinCastJSONAsStringSig) evalString(row chunk.Row) (res string, isNu if isNull || err != nil { return res, isNull, err } - return val.String(), false, nil + s, err := types.ProduceStrWithSpecifiedTp(val.String(), b.tp, b.ctx.GetSessionVars().StmtCtx, false) + if err != nil { + return res, false, err + } + return s, false, nil } type builtinCastJSONAsTimeSig struct { @@ -1910,6 +2059,13 @@ func BuildCastCollationFunction(ctx sessionctx.Context, expr Expression, ec *Exp // BuildCastFunction builds a CAST ScalarFunction from the Expression. func BuildCastFunction(ctx sessionctx.Context, expr Expression, tp *types.FieldType) (res Expression) { + res, err := BuildCastFunctionWithCheck(ctx, expr, tp) + terror.Log(err) + return +} + +// BuildCastFunctionWithCheck builds a CAST ScalarFunction from the Expression and return error if any. +func BuildCastFunctionWithCheck(ctx sessionctx.Context, expr Expression, tp *types.FieldType) (res Expression, err error) { argType := expr.GetType() // If source argument's nullable, then target type should be nullable if !mysql.HasNotNullFlag(argType.GetFlag()) { @@ -1929,7 +2085,11 @@ func BuildCastFunction(ctx sessionctx.Context, expr Expression, tp *types.FieldT case types.ETDuration: fc = &castAsDurationFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} case types.ETJson: - fc = &castAsJSONFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} + if tp.IsArray() { + fc = &castAsArrayFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} + } else { + fc = &castAsJSONFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} + } case types.ETString: fc = &castAsStringFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} if expr.GetType().GetType() == mysql.TypeBit { @@ -1937,7 +2097,6 @@ func BuildCastFunction(ctx sessionctx.Context, expr Expression, tp *types.FieldT } } f, err := fc.getFunction(ctx, []Expression{expr}) - terror.Log(err) res = &ScalarFunction{ FuncName: model.NewCIStr(ast.Cast), RetType: tp, @@ -1946,10 +2105,10 @@ func BuildCastFunction(ctx sessionctx.Context, expr Expression, tp *types.FieldT // We do not fold CAST if the eval type of this scalar function is ETJson // since we may reset the flag of the field type of CastAsJson later which // would affect the evaluation of it. - if tp.EvalType() != types.ETJson { + if tp.EvalType() != types.ETJson && err == nil { res = FoldConstant(res) } - return res + return res, err } // WrapWithCastAsInt wraps `expr` with `cast` if the return type of expr is not diff --git a/expression/builtin_cast_test.go b/expression/builtin_cast_test.go index f8e789a527620..b33c70e19d60f 100644 --- a/expression/builtin_cast_test.go +++ b/expression/builtin_cast_test.go @@ -719,6 +719,13 @@ func TestCastFuncSig(t *testing.T) { 3, chunk.MutRowFromDatums([]types.Datum{types.NewStringDatum("你好world")}), }, + // cast json as string + { + &Column{RetType: types.NewFieldType(mysql.TypeJSON), Index: 0}, + fmt.Sprintf(`"%s`, curTimeString[:2]), + 3, + chunk.MutRowFromDatums([]types.Datum{jsonTime}), + }, } for i, c := range castToStringCases2 { args := []Expression{c.before} @@ -741,6 +748,8 @@ func TestCastFuncSig(t *testing.T) { case 5: stringFunc.tp.SetCharset(charset.CharsetUTF8) sig = &builtinCastStringAsStringSig{stringFunc} + case 6: + sig = &builtinCastJSONAsStringSig{stringFunc} } res, isNull, err := sig.evalString(c.row.ToRow()) require.False(t, isNull) @@ -1610,3 +1619,59 @@ func TestCastBinaryStringAsJSONSig(t *testing.T) { require.Equal(t, tt.resultStr, res.String()) } } + +func TestCastArrayFunc(t *testing.T) { + ctx := createContext(t) + tbl := []struct { + input interface{} + expected interface{} + tp *types.FieldType + success bool + buildFuncSuccess bool + }{ + { + []interface{}{int64(-1), int64(2), int64(3)}, + []interface{}{int64(-1), int64(2), int64(3)}, + types.NewFieldTypeBuilder().SetType(mysql.TypeLonglong).SetCharset(charset.CharsetBin).SetCollate(charset.CollationBin).SetArray(true).BuildP(), + true, + true, + }, + { + []interface{}{int64(-1), int64(2), int64(3)}, + nil, + types.NewFieldTypeBuilder().SetType(mysql.TypeString).SetCharset(charset.CharsetUTF8MB4).SetCollate(charset.CollationUTF8MB4).SetArray(true).BuildP(), + false, + true, + }, + { + []interface{}{"1"}, + nil, + types.NewFieldTypeBuilder().SetType(mysql.TypeLonglong).SetCharset(charset.CharsetBin).SetCollate(charset.CharsetBin).SetArray(true).BuildP(), + false, + true, + }, + } + for _, tt := range tbl { + f, err := BuildCastFunctionWithCheck(ctx, datumsToConstants(types.MakeDatums(types.CreateBinaryJSON(tt.input)))[0], tt.tp) + if tt.buildFuncSuccess { + require.NoError(t, err, tt.input) + } else { + require.Error(t, err, tt.input) + continue + } + + val, isNull, err := f.EvalJSON(ctx, chunk.Row{}) + if tt.success { + require.NoError(t, err, tt.input) + if tt.expected == nil { + require.True(t, isNull, tt.input) + } else { + j1 := types.CreateBinaryJSON(tt.expected) + cmp := types.CompareBinaryJSON(j1, val) + require.Equal(t, 0, cmp, tt.input) + } + } else { + require.Error(t, err, tt.input) + } + } +} diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index 8b82d86b776e5..2b8a029c4b03b 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -1186,7 +1186,11 @@ func (b *builtinCastJSONAsStringSig) vecEvalString(input *chunk.Chunk, result *c result.AppendNull() continue } - result.AppendString(buf.GetJSON(i).String()) + s, err := types.ProduceStrWithSpecifiedTp(buf.GetJSON(i).String(), b.tp, b.ctx.GetSessionVars().StmtCtx, false) + if err != nil { + return err + } + result.AppendString(s) } return nil } diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 3baa86b635ba6..dec5d06983679 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -28,6 +28,7 @@ import ( "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tipb/go-tipb" + "github.com/pkg/errors" ) var ( @@ -1574,12 +1575,18 @@ func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Express // To keep the result be compatible with MySQL, refine `int non-constant str constant` // here and skip this refine operation in all other cases for safety. if (arg0IsInt && !arg0IsCon && arg1IsString && arg1IsCon) || (arg1IsInt && !arg1IsCon && arg0IsString && arg0IsCon) { - ctx.GetSessionVars().StmtCtx.SkipPlanCache = true + var reason error + if arg1IsString { + reason = errors.Errorf("skip plan-cache: '%v' may be converted to INT", arg1.String()) + } else { // arg0IsString + reason = errors.Errorf("skip plan-cache: '%v' may be converted to INT", arg0.String()) + } + ctx.GetSessionVars().StmtCtx.SetSkipPlanCache(reason) RemoveMutableConst(ctx, args) } else { return args } - } else if ctx.GetSessionVars().StmtCtx.SkipPlanCache { + } else if !ctx.GetSessionVars().StmtCtx.UseCache { // We should remove the mutable constant for correctness, because its value may be changed. RemoveMutableConst(ctx, args) } diff --git a/expression/builtin_control.go b/expression/builtin_control.go index de055b936505e..643e6cf89e29a 100644 --- a/expression/builtin_control.go +++ b/expression/builtin_control.go @@ -146,6 +146,11 @@ func InferType4ControlFuncs(ctx sessionctx.Context, funcName string, lexp, rexp } flen := maxlen(lhsFlen, rhsFlen) + resultFieldType.GetDecimal() + 1 // account for -1 len fields resultFieldType.SetFlenUnderLimit(flen) + } else if evalType == types.ETString { + lhsLen, rhsLen := lhs.GetFlen(), rhs.GetFlen() + if lhsLen != types.UnspecifiedLength && rhsLen != types.UnspecifiedLength { + resultFieldType.SetFlen(mathutil.Max(lhsLen, rhsLen)) + } } else { resultFieldType.SetFlen(maxlen(lhs.GetFlen(), rhs.GetFlen())) } diff --git a/expression/builtin_encryption.go b/expression/builtin_encryption.go index a206a9d4970bb..fb451f9714cd4 100644 --- a/expression/builtin_encryption.go +++ b/expression/builtin_encryption.go @@ -37,6 +37,7 @@ import ( "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/encrypt" + pwdValidator "github.com/pingcap/tidb/util/password-validation" "github.com/pingcap/tipb/go-tipb" ) @@ -73,6 +74,7 @@ var ( _ builtinFunc = &builtinSHA2Sig{} _ builtinFunc = &builtinUncompressSig{} _ builtinFunc = &builtinUncompressedLengthSig{} + _ builtinFunc = &builtinValidatePasswordStrengthSig{} ) // aesModeAttr indicates that the key length and iv attribute for specific block_encryption_mode. @@ -728,7 +730,6 @@ func (c *sm3FunctionClass) getFunction(ctx sessionctx.Context, args []Expression bf.tp.SetCollate(collate) bf.tp.SetFlen(40) sig := &builtinSM3Sig{bf} - //sig.setPbCode(tipb.ScalarFuncSig_SM3) // TODO return sig, nil } @@ -1010,5 +1011,66 @@ type validatePasswordStrengthFunctionClass struct { } func (c *validatePasswordStrengthFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) { - return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "VALIDATE_PASSWORD_STRENGTH") + if err := c.verifyArgs(args); err != nil { + return nil, err + } + bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString) + if err != nil { + return nil, err + } + bf.tp.SetFlen(21) + sig := &builtinValidatePasswordStrengthSig{bf} + return sig, nil +} + +type builtinValidatePasswordStrengthSig struct { + baseBuiltinFunc +} + +func (b *builtinValidatePasswordStrengthSig) Clone() builtinFunc { + newSig := &builtinValidatePasswordStrengthSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +// evalInt evals VALIDATE_PASSWORD_STRENGTH(str). +// See https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_validate-password-strength +func (b *builtinValidatePasswordStrengthSig) evalInt(row chunk.Row) (int64, bool, error) { + globalVars := b.ctx.GetSessionVars().GlobalVarsAccessor + str, isNull, err := b.args[0].EvalString(b.ctx, row) + if err != nil || isNull { + return 0, true, err + } else if len([]rune(str)) < 4 { + return 0, false, nil + } + if validation, err := globalVars.GetGlobalSysVar(variable.ValidatePasswordEnable); err != nil { + return 0, true, err + } else if !variable.TiDBOptOn(validation) { + return 0, false, nil + } + return b.validateStr(str, &globalVars) +} + +func (b *builtinValidatePasswordStrengthSig) validateStr(str string, globalVars *variable.GlobalVarAccessor) (int64, bool, error) { + if warn, err := pwdValidator.ValidateUserNameInPassword(str, b.ctx.GetSessionVars()); err != nil { + return 0, true, err + } else if len(warn) > 0 { + return 0, false, nil + } + if warn, err := pwdValidator.ValidatePasswordLowPolicy(str, globalVars); err != nil { + return 0, true, err + } else if len(warn) > 0 { + return 25, false, nil + } + if warn, err := pwdValidator.ValidatePasswordMediumPolicy(str, globalVars); err != nil { + return 0, true, err + } else if len(warn) > 0 { + return 50, false, nil + } + if ok, err := pwdValidator.ValidateDictionaryPassword(str, globalVars); err != nil { + return 0, true, err + } else if !ok { + return 75, false, nil + } + return 100, false, nil } diff --git a/expression/builtin_encryption_test.go b/expression/builtin_encryption_test.go index 0f74ab611aa48..087fb3f35e466 100644 --- a/expression/builtin_encryption_test.go +++ b/expression/builtin_encryption_test.go @@ -15,12 +15,14 @@ package expression import ( + "context" "encoding/hex" "fmt" "strings" "testing" "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" @@ -631,6 +633,55 @@ func TestUncompressLength(t *testing.T) { } } +func TestValidatePasswordStrength(t *testing.T) { + ctx := createContext(t) + ctx.GetSessionVars().User = &auth.UserIdentity{Username: "testuser"} + globalVarsAccessor := variable.NewMockGlobalAccessor4Tests() + ctx.GetSessionVars().GlobalVarsAccessor = globalVarsAccessor + err := globalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordDictionary, "1234") + require.NoError(t, err) + + tests := []struct { + in interface{} + expect interface{} + }{ + {nil, nil}, + {"123", 0}, + {"testuser123", 0}, + {"resutset123", 0}, + {"12345", 25}, + {"12345678", 50}, + {"!Abc12345678", 75}, + {"!Abc87654321", 100}, + } + + fc := funcs[ast.ValidatePasswordStrength] + // disable password validation + for _, test := range tests { + arg := types.NewDatum(test.in) + f, err := fc.getFunction(ctx, datumsToConstants([]types.Datum{arg})) + require.NoErrorf(t, err, "%v", test) + out, err := evalBuiltinFunc(f, chunk.Row{}) + require.NoErrorf(t, err, "%v", test) + if test.expect == nil { + require.Equal(t, types.NewDatum(nil), out) + } else { + require.Equalf(t, types.NewDatum(0), out, "%v", test) + } + } + // enable password validation + err = globalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordEnable, "ON") + require.NoError(t, err) + for _, test := range tests { + arg := types.NewDatum(test.in) + f, err := fc.getFunction(ctx, datumsToConstants([]types.Datum{arg})) + require.NoErrorf(t, err, "%v", test) + out, err := evalBuiltinFunc(f, chunk.Row{}) + require.NoErrorf(t, err, "%v", test) + require.Equalf(t, types.NewDatum(test.expect), out, "%v", test) + } +} + func TestPassword(t *testing.T) { ctx := createContext(t) cases := []struct { diff --git a/expression/builtin_encryption_vec.go b/expression/builtin_encryption_vec.go index e9a1d45ae67be..ff71913f8d70b 100644 --- a/expression/builtin_encryption_vec.go +++ b/expression/builtin_encryption_vec.go @@ -30,6 +30,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/encrypt" @@ -863,3 +864,45 @@ func (b *builtinUncompressedLengthSig) vecEvalInt(input *chunk.Chunk, result *ch } return nil } + +func (b *builtinValidatePasswordStrengthSig) vectorized() bool { + return true +} + +func (b *builtinValidatePasswordStrengthSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + buf, err := b.bufAllocator.get() + if err != nil { + return err + } + defer b.bufAllocator.put(buf) + if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { + return err + } + + result.ResizeInt64(n, false) + result.MergeNulls(buf) + i64s := result.Int64s() + globalVars := b.ctx.GetSessionVars().GlobalVarsAccessor + enableValidation := false + validation, err := globalVars.GetGlobalSysVar(variable.ValidatePasswordEnable) + if err != nil { + return err + } + enableValidation = variable.TiDBOptOn(validation) + for i := 0; i < n; i++ { + if result.IsNull(i) { + continue + } + if !enableValidation { + i64s[i] = 0 + } else if score, isNull, err := b.validateStr(buf.GetString(i), &globalVars); err != nil { + return err + } else if !isNull { + i64s[i] = score + } else { + result.SetNull(i, true) + } + } + return nil +} diff --git a/expression/builtin_encryption_vec_test.go b/expression/builtin_encryption_vec_test.go index c6caa1eb60d51..46395e51bcb6b 100644 --- a/expression/builtin_encryption_vec_test.go +++ b/expression/builtin_encryption_vec_test.go @@ -75,6 +75,9 @@ var vecBuiltinEncryptionCases = map[string][]vecExprBenchCase{ ast.Decode: { {retEvalType: types.ETString, childrenTypes: []types.EvalType{types.ETString, types.ETString}, geners: []dataGenerator{newRandLenStrGener(10, 20)}}, }, + ast.ValidatePasswordStrength: { + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString}}, + }, } func TestVectorizedBuiltinEncryptionFunc(t *testing.T) { diff --git a/expression/builtin_json.go b/expression/builtin_json.go index 97891152c82ee..e9f803dcc86df 100644 --- a/expression/builtin_json.go +++ b/expression/builtin_json.go @@ -43,7 +43,9 @@ var ( _ functionClass = &jsonMergeFunctionClass{} _ functionClass = &jsonObjectFunctionClass{} _ functionClass = &jsonArrayFunctionClass{} + _ functionClass = &jsonMemberOfFunctionClass{} _ functionClass = &jsonContainsFunctionClass{} + _ functionClass = &jsonOverlapsFunctionClass{} _ functionClass = &jsonContainsPathFunctionClass{} _ functionClass = &jsonValidFunctionClass{} _ functionClass = &jsonArrayAppendFunctionClass{} @@ -71,7 +73,9 @@ var ( _ builtinFunc = &builtinJSONReplaceSig{} _ builtinFunc = &builtinJSONRemoveSig{} _ builtinFunc = &builtinJSONMergeSig{} + _ builtinFunc = &builtinJSONMemberOfSig{} _ builtinFunc = &builtinJSONContainsSig{} + _ builtinFunc = &builtinJSONOverlapsSig{} _ builtinFunc = &builtinJSONStorageSizeSig{} _ builtinFunc = &builtinJSONDepthSig{} _ builtinFunc = &builtinJSONSearchSig{} @@ -740,6 +744,68 @@ func jsonModify(ctx sessionctx.Context, args []Expression, row chunk.Row, mt typ return res, false, nil } +type jsonMemberOfFunctionClass struct { + baseFunctionClass +} + +type builtinJSONMemberOfSig struct { + baseBuiltinFunc +} + +func (b *builtinJSONMemberOfSig) Clone() builtinFunc { + newSig := &builtinJSONMemberOfSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +func (c *jsonMemberOfFunctionClass) verifyArgs(args []Expression) error { + if err := c.baseFunctionClass.verifyArgs(args); err != nil { + return err + } + if evalType := args[1].GetType().EvalType(); evalType != types.ETJson && evalType != types.ETString { + return types.ErrInvalidJSONData.GenWithStackByArgs(2, "member of") + } + return nil +} + +func (c *jsonMemberOfFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) { + if err := c.verifyArgs(args); err != nil { + return nil, err + } + argTps := []types.EvalType{types.ETJson, types.ETJson} + bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...) + if err != nil { + return nil, err + } + DisableParseJSONFlag4Expr(args[0]) + sig := &builtinJSONMemberOfSig{bf} + return sig, nil +} + +func (b *builtinJSONMemberOfSig) evalInt(row chunk.Row) (res int64, isNull bool, err error) { + target, isNull, err := b.args[0].EvalJSON(b.ctx, row) + if isNull || err != nil { + return res, isNull, err + } + obj, isNull, err := b.args[1].EvalJSON(b.ctx, row) + if isNull || err != nil { + return res, isNull, err + } + + if obj.TypeCode != types.JSONTypeCodeArray { + return boolToInt64(types.CompareBinaryJSON(obj, target) == 0), false, nil + } + + elemCount := obj.GetElemCount() + for i := 0; i < elemCount; i++ { + if types.CompareBinaryJSON(obj.ArrayGetElem(i), target) == 0 { + return 1, false, nil + } + } + + return 0, false, nil +} + type jsonContainsFunctionClass struct { baseFunctionClass } @@ -804,8 +870,8 @@ func (b *builtinJSONContainsSig) evalInt(row chunk.Row) (res int64, isNull bool, if err != nil { return res, true, err } - if pathExpr.ContainsAnyAsterisk() { - return res, true, types.ErrInvalidJSONPathWildcard + if pathExpr.CouldMatchMultipleValues() { + return res, true, types.ErrInvalidJSONPathMultipleSelection } var exists bool obj, exists = obj.Extract([]types.JSONPathExpression{pathExpr}) @@ -820,6 +886,62 @@ func (b *builtinJSONContainsSig) evalInt(row chunk.Row) (res int64, isNull bool, return 0, false, nil } +type jsonOverlapsFunctionClass struct { + baseFunctionClass +} + +type builtinJSONOverlapsSig struct { + baseBuiltinFunc +} + +func (b *builtinJSONOverlapsSig) Clone() builtinFunc { + newSig := &builtinJSONOverlapsSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +func (c *jsonOverlapsFunctionClass) verifyArgs(args []Expression) error { + if err := c.baseFunctionClass.verifyArgs(args); err != nil { + return err + } + if evalType := args[0].GetType().EvalType(); evalType != types.ETJson && evalType != types.ETString { + return types.ErrInvalidJSONData.GenWithStackByArgs(1, "json_overlaps") + } + if evalType := args[1].GetType().EvalType(); evalType != types.ETJson && evalType != types.ETString { + return types.ErrInvalidJSONData.GenWithStackByArgs(2, "json_overlaps") + } + return nil +} + +func (c *jsonOverlapsFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) { + if err := c.verifyArgs(args); err != nil { + return nil, err + } + + argTps := []types.EvalType{types.ETJson, types.ETJson} + bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...) + if err != nil { + return nil, err + } + sig := &builtinJSONOverlapsSig{bf} + return sig, nil +} + +func (b *builtinJSONOverlapsSig) evalInt(row chunk.Row) (res int64, isNull bool, err error) { + obj, isNull, err := b.args[0].EvalJSON(b.ctx, row) + if isNull || err != nil { + return res, isNull, err + } + target, isNull, err := b.args[1].EvalJSON(b.ctx, row) + if isNull || err != nil { + return res, isNull, err + } + if types.OverlapsBinaryJSON(obj, target) { + return 1, false, nil + } + return 0, false, nil +} + type jsonValidFunctionClass struct { baseFunctionClass } @@ -990,8 +1112,8 @@ func (b *builtinJSONArrayAppendSig) appendJSONArray(res types.BinaryJSON, p stri if err != nil { return res, true, types.ErrInvalidJSONPath.GenWithStackByArgs(p) } - if pathExpr.ContainsAnyAsterisk() { - return res, true, types.ErrInvalidJSONPathWildcard.GenWithStackByArgs(p) + if pathExpr.CouldMatchMultipleValues() { + return res, true, types.ErrInvalidJSONPathMultipleSelection } obj, exists := res.Extract([]types.JSONPathExpression{pathExpr}) @@ -1071,8 +1193,8 @@ func (b *builtinJSONArrayInsertSig) evalJSON(row chunk.Row) (res types.BinaryJSO if err != nil { return res, true, types.ErrInvalidJSONPath.GenWithStackByArgs(s) } - if pathExpr.ContainsAnyAsterisk() { - return res, true, types.ErrInvalidJSONPathWildcard.GenWithStackByArgs(s) + if pathExpr.CouldMatchMultipleValues() { + return res, true, types.ErrInvalidJSONPathMultipleSelection } value, isnull, err := b.args[i+1].EvalJSON(b.ctx, row) @@ -1392,6 +1514,43 @@ func (b *builtinJSONSearchSig) evalJSON(row chunk.Row) (res types.BinaryJSON, is return obj.Search(containType, searchStr, escape, nil) } +type jsonStorageFreeFunctionClass struct { + baseFunctionClass +} + +type builtinJSONStorageFreeSig struct { + baseBuiltinFunc +} + +func (b *builtinJSONStorageFreeSig) Clone() builtinFunc { + newSig := &builtinJSONStorageFreeSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +func (c *jsonStorageFreeFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) { + if err := c.verifyArgs(args); err != nil { + return nil, err + } + + bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETJson) + if err != nil { + return nil, err + } + sig := &builtinJSONStorageFreeSig{bf} + sig.setPbCode(tipb.ScalarFuncSig_JsonStorageFreeSig) + return sig, nil +} + +func (b *builtinJSONStorageFreeSig) evalInt(row chunk.Row) (res int64, isNull bool, err error) { + _, isNull, err = b.args[0].EvalJSON(b.ctx, row) + if isNull || err != nil { + return res, isNull, err + } + + return 0, false, nil +} + type jsonStorageSizeFunctionClass struct { baseFunctionClass } @@ -1459,6 +1618,10 @@ func (c *jsonDepthFunctionClass) getFunction(ctx sessionctx.Context, args []Expr } func (b *builtinJSONDepthSig) evalInt(row chunk.Row) (res int64, isNull bool, err error) { + // as TiDB doesn't support partial update json value, so only check the + // json format and whether it's NULL. For NULL return NULL, for invalid json, return + // an error, otherwise return 0 + obj, isNull, err := b.args[0].EvalJSON(b.ctx, row) if isNull || err != nil { return res, isNull, err @@ -1551,8 +1714,8 @@ func (b *builtinJSONKeys2ArgsSig) evalJSON(row chunk.Row) (res types.BinaryJSON, if err != nil { return res, true, err } - if pathExpr.ContainsAnyAsterisk() { - return res, true, types.ErrInvalidJSONPathWildcard + if pathExpr.CouldMatchMultipleValues() { + return res, true, types.ErrInvalidJSONPathMultipleSelection } res, exists := res.Extract([]types.JSONPathExpression{pathExpr}) @@ -1620,8 +1783,8 @@ func (b *builtinJSONLengthSig) evalInt(row chunk.Row) (res int64, isNull bool, e if err != nil { return res, true, err } - if pathExpr.ContainsAnyAsterisk() { - return res, true, types.ErrInvalidJSONPathWildcard + if pathExpr.CouldMatchMultipleValues() { + return res, true, types.ErrInvalidJSONPathMultipleSelection } var exists bool diff --git a/expression/builtin_json_test.go b/expression/builtin_json_test.go index 566122cfd3b48..23da60f380652 100644 --- a/expression/builtin_json_test.go +++ b/expression/builtin_json_test.go @@ -386,6 +386,47 @@ func TestJSONRemove(t *testing.T) { } } +func TestJSONMemberOf(t *testing.T) { + ctx := createContext(t) + fc := funcs[ast.JSONMemberOf] + tbl := []struct { + input []interface{} + expected interface{} + err error + }{ + {[]interface{}{`1`, `a:1`}, 1, types.ErrInvalidJSONText}, + + {[]interface{}{1, `[1, 2]`}, 1, nil}, + {[]interface{}{1, `[1]`}, 1, nil}, + {[]interface{}{1, `[0]`}, 0, nil}, + {[]interface{}{1, `[1]`}, 1, nil}, + {[]interface{}{1, `[[1]]`}, 0, nil}, + {[]interface{}{"1", `[1]`}, 0, nil}, + {[]interface{}{"1", `["1"]`}, 1, nil}, + {[]interface{}{`{"a":1}`, `{"a":1}`}, 0, nil}, + {[]interface{}{`{"a":1}`, `[{"a":1}]`}, 0, nil}, + {[]interface{}{`{"a":1}`, `[{"a":1}, 1]`}, 0, nil}, + {[]interface{}{`{"a":1}`, `["{\"a\":1}"]`}, 1, nil}, + {[]interface{}{`{"a":1}`, `["{\"a\":1}", 1]`}, 1, nil}, + } + for _, tt := range tbl { + args := types.MakeDatums(tt.input...) + f, err := fc.getFunction(ctx, datumsToConstants(args)) + require.NoError(t, err, tt.input) + d, err := evalBuiltinFunc(f, chunk.Row{}) + if tt.err == nil { + require.NoError(t, err, tt.input) + if tt.expected == nil { + require.True(t, d.IsNull(), tt.input) + } else { + require.Equal(t, int64(tt.expected.(int)), d.GetInt64(), tt.input) + } + } else { + require.True(t, tt.err.(*terror.Error).Equal(err), tt.input) + } + } +} + func TestJSONContains(t *testing.T) { ctx := createContext(t) fc := funcs[ast.JSONContains] @@ -423,9 +464,9 @@ func TestJSONContains(t *testing.T) { {[]interface{}{`[{"a":1,"b":2}]`, `{"a":1}`}, 1, nil}, {[]interface{}{`[{"a":{"a":1},"b":2}]`, `{"a":1}`}, 0, nil}, // Tests path expression contains any asterisk - {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.*"}, nil, types.ErrInvalidJSONPathWildcard}, - {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$[*]"}, nil, types.ErrInvalidJSONPathWildcard}, - {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$**.a"}, nil, types.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.*"}, nil, types.ErrInvalidJSONPathMultipleSelection}, + {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$[*]"}, nil, types.ErrInvalidJSONPathMultipleSelection}, + {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$**.a"}, nil, types.ErrInvalidJSONPathMultipleSelection}, // Tests path expression does not identify a section of the target document {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.c"}, nil, nil}, {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.a[3]"}, nil, nil}, @@ -466,6 +507,71 @@ func TestJSONContains(t *testing.T) { } } +func TestJSONOverlaps(t *testing.T) { + ctx := createContext(t) + fc := funcs[ast.JSONOverlaps] + tbl := []struct { + input []any + expected any + err error + }{ + {[]any{`[1,2,[1,3]]`, `a:1`}, 1, types.ErrInvalidJSONText}, + {[]any{`a:1`, `1`}, 1, types.ErrInvalidJSONText}, + {[]any{nil, `1`}, nil, nil}, + {[]any{`1`, nil}, nil, nil}, + + {[]any{`[1, 2]`, `[2,3]`}, 1, nil}, + {[]any{`[1, 2]`, `[2]`}, 1, nil}, + {[]any{`[1, 2]`, `2`}, 1, nil}, + {[]any{`[{"a":1}]`, `{"a":1}`}, 1, nil}, + {[]any{`[{"a":1}]`, `{"a":1,"b":2}`}, 0, nil}, + {[]any{`[{"a":1}]`, `{"a":2}`}, 0, nil}, + {[]any{`{"a":[1,2]}`, `{"a":[1]}`}, 0, nil}, + {[]any{`{"a":[1,2]}`, `{"a":[2,1]}`}, 0, nil}, + {[]any{`[1,1,1]`, `1`}, 1, nil}, + {[]any{`1`, `1`}, 1, nil}, + {[]any{`0`, `1`}, 0, nil}, + {[]any{`[[1,2], 3]`, `[1,[2,3]]`}, 0, nil}, + {[]any{`[[1,2], 3]`, `[1,3]`}, 1, nil}, + {[]any{`{"a":1,"b":10,"d":10}`, `{"a":5,"e":10,"f":1,"d":20}`}, 0, nil}, + {[]any{`[4,5,"6",7]`, `6`}, 0, nil}, + {[]any{`[4,5,6,7]`, `"6"`}, 0, nil}, + + {[]any{`[2,3]`, `[1, 2]`}, 1, nil}, + {[]any{`[2]`, `[1, 2]`}, 1, nil}, + {[]any{`2`, `[1, 2]`}, 1, nil}, + {[]any{`{"a":1}`, `[{"a":1}]`}, 1, nil}, + {[]any{`{"a":1,"b":2}`, `[{"a":1}]`}, 0, nil}, + {[]any{`{"a":2}`, `[{"a":1}]`}, 0, nil}, + {[]any{`{"a":[1]}`, `{"a":[1,2]}`}, 0, nil}, + {[]any{`{"a":[2,1]}`, `{"a":[1,2]}`}, 0, nil}, + {[]any{`1`, `[1,1,1]`}, 1, nil}, + {[]any{`1`, `1`}, 1, nil}, + {[]any{`1`, `0`}, 0, nil}, + {[]any{`[1,[2,3]]`, `[[1,2], 3]`}, 0, nil}, + {[]any{`[1,3]`, `[[1,2], 3]`}, 1, nil}, + {[]any{`{"a":5,"e":10,"f":1,"d":20}`, `{"a":1,"b":10,"d":10}`}, 0, nil}, + {[]any{`6`, `[4,5,"6",7]`}, 0, nil}, + {[]any{`"6"`, `[4,5,6,7]`}, 0, nil}, + } + for _, tt := range tbl { + args := types.MakeDatums(tt.input...) + f, err := fc.getFunction(ctx, datumsToConstants(args)) + require.NoError(t, err, tt.input) + d, err := evalBuiltinFunc(f, chunk.Row{}) + if tt.err == nil { + require.NoError(t, err, tt.input) + if tt.expected == nil { + require.True(t, d.IsNull(), tt.input) + } else { + require.Equal(t, int64(tt.expected.(int)), d.GetInt64(), tt.input) + } + } else { + require.True(t, tt.err.(*terror.Error).Equal(err), tt.input) + } + } +} + func TestJSONContainsPath(t *testing.T) { ctx := createContext(t) fc := funcs[ast.JSONContainsPath] @@ -758,7 +864,7 @@ func TestJSONArrayAppend(t *testing.T) { {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, nil, nil}, nil, nil}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, types.ErrInvalidJSONPath}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, types.ErrInvalidJSONPath}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, types.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, types.ErrInvalidJSONPathMultipleSelection}, // Following tests come from MySQL doc. {[]interface{}{`["a", ["b", "c"], "d"]`, `$[1]`, 1}, `["a", ["b", "c", 1], "d"]`, nil}, {[]interface{}{`["a", ["b", "c"], "d"]`, `$[0]`, 2}, `[["a", 2], ["b", "c"], "d"]`, nil}, @@ -910,7 +1016,7 @@ func TestJSONArrayInsert(t *testing.T) { {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, nil, nil}, nil, true, nil}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, false, types.ErrInvalidJSONPath}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, false, types.ErrInvalidJSONPath}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, false, types.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, false, types.ErrInvalidJSONPathMultipleSelection}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.b[0]`, nil, `$.a`, nil}, nil, false, types.ErrInvalidJSONPathArrayCell}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.a`, nil}, nil, false, types.ErrInvalidJSONPathArrayCell}, // Following tests come from MySQL doc. @@ -985,6 +1091,49 @@ func TestJSONValid(t *testing.T) { } } +func TestJSONStorageFree(t *testing.T) { + ctx := createContext(t) + fc := funcs[ast.JSONStorageFree] + tbl := []struct { + input []interface{} + expected interface{} + success bool + }{ + // Tests scalar arguments + {[]interface{}{`null`}, 0, true}, + {[]interface{}{`true`}, 0, true}, + {[]interface{}{`1`}, 0, true}, + {[]interface{}{`"1"`}, 0, true}, + // Tests nil arguments + {[]interface{}{nil}, nil, true}, + // Tests valid json documents + {[]interface{}{`{}`}, 0, true}, + {[]interface{}{`{"a":1}`}, 0, true}, + {[]interface{}{`[{"a":{"a":1},"b":2}]`}, 0, true}, + {[]interface{}{`{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}`}, 0, true}, + // Tests invalid json documents + {[]interface{}{`[{"a":1]`}, 0, false}, + {[]interface{}{`[{a":1]`}, 0, false}, + } + for _, tt := range tbl { + args := types.MakeDatums(tt.input...) + f, err := fc.getFunction(ctx, datumsToConstants(args)) + require.NoError(t, err) + d, err := evalBuiltinFunc(f, chunk.Row{}) + if tt.success { + require.NoError(t, err) + + if tt.expected == nil { + require.True(t, d.IsNull()) + } else { + require.Equal(t, int64(tt.expected.(int)), d.GetInt64()) + } + } else { + require.Error(t, err) + } + } +} + func TestJSONStorageSize(t *testing.T) { ctx := createContext(t) fc := funcs[ast.JSONStorageSize] diff --git a/expression/builtin_json_vec.go b/expression/builtin_json_vec.go index 7c6d9e5f519f8..0610a1f6ea3ca 100644 --- a/expression/builtin_json_vec.go +++ b/expression/builtin_json_vec.go @@ -103,6 +103,33 @@ func vecJSONModify(ctx sessionctx.Context, args []Expression, bufAllocator colum return nil } +func (b *builtinJSONStorageFreeSig) vectorized() bool { + return true +} + +func (b *builtinJSONStorageFreeSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + buf, err := b.bufAllocator.get() + if err != nil { + return err + } + defer b.bufAllocator.put(buf) + if err := b.args[0].VecEvalJSON(b.ctx, input, buf); err != nil { + return err + } + result.ResizeInt64(n, false) + result.MergeNulls(buf) + int64s := result.Int64s() + for i := 0; i < n; i++ { + if result.IsNull(i) { + continue + } + + int64s[i] = 0 + } + return nil +} + func (b *builtinJSONStorageSizeSig) vectorized() bool { return true } @@ -247,6 +274,59 @@ func (b *builtinJSONArraySig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colu return nil } +func (b *builtinJSONMemberOfSig) vectorized() bool { + return true +} + +func (b *builtinJSONMemberOfSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + nr := input.NumRows() + + targetCol, err := b.bufAllocator.get() + if err != nil { + return err + } + defer b.bufAllocator.put(targetCol) + + if err := b.args[0].VecEvalJSON(b.ctx, input, targetCol); err != nil { + return err + } + + objCol, err := b.bufAllocator.get() + if err != nil { + return err + } + defer b.bufAllocator.put(objCol) + + if err := b.args[1].VecEvalJSON(b.ctx, input, objCol); err != nil { + return err + } + + result.ResizeInt64(nr, false) + resI64s := result.Int64s() + + result.MergeNulls(targetCol, objCol) + for i := 0; i < nr; i++ { + if result.IsNull(i) { + continue + } + obj := objCol.GetJSON(i) + target := targetCol.GetJSON(i) + if obj.TypeCode != types.JSONTypeCodeArray { + resI64s[i] = boolToInt64(types.CompareBinaryJSON(obj, target) == 0) + } else { + elemCount := obj.GetElemCount() + for j := 0; j < elemCount; j++ { + if types.CompareBinaryJSON(obj.ArrayGetElem(j), target) == 0 { + resI64s[i] = 1 + break + } + } + } + } + + return nil +} + func (b *builtinJSONContainsSig) vectorized() bool { return true } @@ -299,8 +379,8 @@ func (b *builtinJSONContainsSig) vecEvalInt(input *chunk.Chunk, result *chunk.Co if err != nil { return err } - if pathExpr.ContainsAnyAsterisk() { - return types.ErrInvalidJSONPathWildcard + if pathExpr.CouldMatchMultipleValues() { + return types.ErrInvalidJSONPathMultipleSelection } obj, exists := objCol.GetJSON(i).Extract([]types.JSONPathExpression{pathExpr}) @@ -332,6 +412,51 @@ func (b *builtinJSONContainsSig) vecEvalInt(input *chunk.Chunk, result *chunk.Co return nil } +func (b *builtinJSONOverlapsSig) vectorized() bool { + return true +} + +func (b *builtinJSONOverlapsSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + nr := input.NumRows() + + objCol, err := b.bufAllocator.get() + if err != nil { + return err + } + defer b.bufAllocator.put(objCol) + + if err := b.args[0].VecEvalJSON(b.ctx, input, objCol); err != nil { + return err + } + + targetCol, err := b.bufAllocator.get() + if err != nil { + return err + } + defer b.bufAllocator.put(targetCol) + + if err := b.args[1].VecEvalJSON(b.ctx, input, targetCol); err != nil { + return err + } + + result.ResizeInt64(nr, false) + resI64s := result.Int64s() + + result.MergeNulls(objCol, targetCol) + for i := 0; i < nr; i++ { + if result.IsNull(i) { + continue + } + if types.OverlapsBinaryJSON(objCol.GetJSON(i), targetCol.GetJSON(i)) { + resI64s[i] = 1 + } else { + resI64s[i] = 0 + } + } + + return nil +} + func (b *builtinJSONQuoteSig) vectorized() bool { return true } @@ -607,8 +732,8 @@ func (b *builtinJSONArrayInsertSig) vecEvalJSON(input *chunk.Chunk, result *chun if err != nil { return types.ErrInvalidJSONPath.GenWithStackByArgs(pathBufs[j].GetString(i)) } - if pathExpr.ContainsAnyAsterisk() { - return types.ErrInvalidJSONPathWildcard.GenWithStackByArgs(pathBufs[j].GetString(i)) + if pathExpr.CouldMatchMultipleValues() { + return types.ErrInvalidJSONPathMultipleSelection } if valueBufs[j].IsNull(i) { value = types.CreateBinaryJSON(nil) @@ -663,8 +788,8 @@ func (b *builtinJSONKeys2ArgsSig) vecEvalJSON(input *chunk.Chunk, result *chunk. if err != nil { return err } - if pathExpr.ContainsAnyAsterisk() { - return types.ErrInvalidJSONPathWildcard + if pathExpr.CouldMatchMultipleValues() { + return types.ErrInvalidJSONPathMultipleSelection } jsonItem := jsonBuf.GetJSON(i) @@ -732,8 +857,8 @@ func (b *builtinJSONLengthSig) vecEvalInt(input *chunk.Chunk, result *chunk.Colu if err != nil { return err } - if pathExpr.ContainsAnyAsterisk() { - return types.ErrInvalidJSONPathWildcard + if pathExpr.CouldMatchMultipleValues() { + return types.ErrInvalidJSONPathMultipleSelection } obj, exists := jsonItem.Extract([]types.JSONPathExpression{pathExpr}) diff --git a/expression/builtin_math.go b/expression/builtin_math.go index 7cdff524fe110..35914aa21cd94 100644 --- a/expression/builtin_math.go +++ b/expression/builtin_math.go @@ -1255,7 +1255,7 @@ func (b *builtinConvSig) conv(str string, fromBase, toBase int64) (res string, i val, err := strconv.ParseUint(str, int(fromBase), 64) if err != nil { - return res, false, types.ErrOverflow.GenWithStackByArgs("BIGINT UNSINGED", str) + return res, false, types.ErrOverflow.GenWithStackByArgs("BIGINT UNSIGNED", str) } if signed { if negative && val > -math.MinInt64 { diff --git a/expression/builtin_op.go b/expression/builtin_op.go index cbb2afcc9377a..e15d1730c8cd9 100644 --- a/expression/builtin_op.go +++ b/expression/builtin_op.go @@ -718,7 +718,7 @@ func (c *unaryNotFunctionClass) getFunction(ctx sessionctx.Context, args []Expre argTp := args[0].GetType().EvalType() if argTp == types.ETTimestamp || argTp == types.ETDatetime || argTp == types.ETDuration { argTp = types.ETInt - } else if argTp == types.ETJson || argTp == types.ETString { + } else if argTp == types.ETString { argTp = types.ETReal } @@ -739,6 +739,10 @@ func (c *unaryNotFunctionClass) getFunction(ctx sessionctx.Context, args []Expre case types.ETInt: sig = &builtinUnaryNotIntSig{bf} sig.setPbCode(tipb.ScalarFuncSig_UnaryNotInt) + case types.ETJson: + ctx.GetSessionVars().StmtCtx.AppendWarning(errJSONInBooleanContext) + sig = &builtinUnaryNotJSONSig{bf} + sig.setPbCode(tipb.ScalarFuncSig_UnaryNotJSON) default: return nil, errors.Errorf("unexpected types.EvalType %v", argTp) } @@ -808,6 +812,28 @@ func (b *builtinUnaryNotIntSig) evalInt(row chunk.Row) (int64, bool, error) { return 0, false, nil } +type builtinUnaryNotJSONSig struct { + baseBuiltinFunc +} + +func (b *builtinUnaryNotJSONSig) Clone() builtinFunc { + newSig := &builtinUnaryNotJSONSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +func (b *builtinUnaryNotJSONSig) evalInt(row chunk.Row) (int64, bool, error) { + arg, isNull, err := b.args[0].EvalJSON(b.ctx, row) + if isNull || err != nil { + return 0, true, err + } + + if types.CompareBinaryJSON(arg, types.CreateBinaryJSON(int64(0))) == 0 { + return 1, false, nil + } + return 0, false, nil +} + type unaryMinusFunctionClass struct { baseFunctionClass } diff --git a/expression/builtin_op_test.go b/expression/builtin_op_test.go index 04024c90cb70f..c771b95da89d3 100644 --- a/expression/builtin_op_test.go +++ b/expression/builtin_op_test.go @@ -462,6 +462,8 @@ func TestUnaryNot(t *testing.T) { {[]interface{}{"0.3"}, 0, false, false}, {[]interface{}{types.NewDecFromFloatForTest(0.3)}, 0, false, false}, {[]interface{}{nil}, 0, true, false}, + {[]interface{}{types.CreateBinaryJSON(int64(0))}, 1, false, false}, + {[]interface{}{types.CreateBinaryJSON(map[string]interface{}{"test": "test"})}, 0, false, false}, {[]interface{}{errors.New("must error")}, 0, false, true}, } diff --git a/expression/builtin_other.go b/expression/builtin_other.go index 0f4bd85d45b43..c5bd6738aa9df 100644 --- a/expression/builtin_other.go +++ b/expression/builtin_other.go @@ -165,7 +165,7 @@ func (c *inFunctionClass) verifyArgs(ctx sessionctx.Context, args []Expression) case columnType.GetType() == mysql.TypeBit && constant.Value.Kind() == types.KindInt64: if constant.Value.GetInt64() < 0 { if MaybeOverOptimized4PlanCache(ctx, args) { - ctx.GetSessionVars().StmtCtx.SkipPlanCache = true + ctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: Bit Column in (%v)", constant.Value.GetInt64())) } continue } diff --git a/expression/builtin_time.go b/expression/builtin_time.go index e6bc7fe57371b..e97f2ef862a3b 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -19,6 +19,7 @@ package expression import ( + "context" "fmt" "math" "regexp" @@ -6086,7 +6087,7 @@ func (c *timestampAddFunctionClass) getFunction(ctx sessionctx.Context, args []E if err := c.verifyArgs(args); err != nil { return nil, err } - bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETInt, types.ETDatetime) + bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETReal, types.ETDatetime) if err != nil { return nil, err } @@ -6119,6 +6120,82 @@ func (b *builtinTimestampAddSig) Clone() builtinFunc { return newSig } +var ( + minDatetimeInGoTime, _ = types.MinDatetime.GoTime(time.Local) + minDatetimeNanos = float64(minDatetimeInGoTime.Unix())*1e9 + float64(minDatetimeInGoTime.Nanosecond()) + maxDatetimeInGoTime, _ = types.MaxDatetime.GoTime(time.Local) + maxDatetimeNanos = float64(maxDatetimeInGoTime.Unix())*1e9 + float64(maxDatetimeInGoTime.Nanosecond()) + minDatetimeMonths = float64(types.MinDatetime.Year()*12 + types.MinDatetime.Month() - 1) // 0001-01-01 00:00:00 + maxDatetimeMonths = float64(types.MaxDatetime.Year()*12 + types.MaxDatetime.Month() - 1) // 9999-12-31 00:00:00 +) + +func validAddTime(nano1 float64, nano2 float64) bool { + return nano1+nano2 >= minDatetimeNanos && nano1+nano2 <= maxDatetimeNanos +} + +func validAddMonth(month1 float64, year, month int) bool { + tmp := month1 + float64(year)*12 + float64(month-1) + return tmp >= minDatetimeMonths && tmp <= maxDatetimeMonths +} + +func addUnitToTime(unit string, t time.Time, v float64) (time.Time, bool, error) { + s := math.Trunc(v * 1000000) + // round to the nearest int + v = math.Round(v) + var tb time.Time + nano := float64(t.Unix())*1e9 + float64(t.Nanosecond()) + switch unit { + case "MICROSECOND": + if !validAddTime(v*float64(time.Microsecond), nano) { + return tb, true, nil + } + tb = t.Add(time.Duration(v) * time.Microsecond) + case "SECOND": + if !validAddTime(s*float64(time.Microsecond), nano) { + return tb, true, nil + } + tb = t.Add(time.Duration(s) * time.Microsecond) + case "MINUTE": + if !validAddTime(v*float64(time.Minute), nano) { + return tb, true, nil + } + tb = t.Add(time.Duration(v) * time.Minute) + case "HOUR": + if !validAddTime(v*float64(time.Hour), nano) { + return tb, true, nil + } + tb = t.Add(time.Duration(v) * time.Hour) + case "DAY": + if !validAddTime(v*24*float64(time.Hour), nano) { + return tb, true, nil + } + tb = t.AddDate(0, 0, int(v)) + case "WEEK": + if !validAddTime(v*24*7*float64(time.Hour), nano) { + return tb, true, nil + } + tb = t.AddDate(0, 0, 7*int(v)) + case "MONTH": + if !validAddMonth(v, t.Year(), int(t.Month())) { + return tb, true, nil + } + tb = t.AddDate(0, int(v), 0) + case "QUARTER": + if !validAddMonth(v*3, t.Year(), int(t.Month())) { + return tb, true, nil + } + tb = t.AddDate(0, 3*int(v), 0) + case "YEAR": + if !validAddMonth(v*12, t.Year(), int(t.Month())) { + return tb, true, nil + } + tb = t.AddDate(int(v), 0, 0) + default: + return tb, false, types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, unit) + } + return tb, false, nil +} + // evalString evals a builtinTimestampAddSig. // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestampadd func (b *builtinTimestampAddSig) evalString(row chunk.Row) (string, bool, error) { @@ -6126,7 +6203,7 @@ func (b *builtinTimestampAddSig) evalString(row chunk.Row) (string, bool, error) if isNull || err != nil { return "", isNull, err } - v, isNull, err := b.args[1].EvalInt(b.ctx, row) + v, isNull, err := b.args[1].EvalReal(b.ctx, row) if isNull || err != nil { return "", isNull, err } @@ -6139,30 +6216,17 @@ func (b *builtinTimestampAddSig) evalString(row chunk.Row) (string, bool, error) b.ctx.GetSessionVars().StmtCtx.AppendWarning(err) return "", true, nil } - var tb time.Time + tb, overflow, err := addUnitToTime(unit, tm1, v) + if err != nil { + return "", true, err + } + if overflow { + return "", true, handleInvalidTimeError(b.ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime")) + } fsp := types.DefaultFsp - switch unit { - case "MICROSECOND": - tb = tm1.Add(time.Duration(v) * time.Microsecond) + // use MaxFsp when microsecond is not zero + if tb.Nanosecond()/1000 != 0 { fsp = types.MaxFsp - case "SECOND": - tb = tm1.Add(time.Duration(v) * time.Second) - case "MINUTE": - tb = tm1.Add(time.Duration(v) * time.Minute) - case "HOUR": - tb = tm1.Add(time.Duration(v) * time.Hour) - case "DAY": - tb = tm1.AddDate(0, 0, int(v)) - case "WEEK": - tb = tm1.AddDate(0, 0, 7*int(v)) - case "MONTH": - tb = tm1.AddDate(0, int(v), 0) - case "QUARTER": - tb = tm1.AddDate(0, 3*int(v), 0) - case "YEAR": - tb = tm1.AddDate(int(v), 0, 0) - default: - return "", true, types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, unit) } r := types.NewTime(types.FromGoTime(tb), b.resolveType(arg.Type(), unit), fsp) if err = r.Check(b.ctx.GetSessionVars().StmtCtx); err != nil { @@ -6643,7 +6707,7 @@ func (b *builtinTiDBCurrentTsoSig) Clone() builtinFunc { // evalInt evals currentTSO(). func (b *builtinTiDBCurrentTsoSig) evalInt(row chunk.Row) (d int64, isNull bool, err error) { - tso, _ := b.ctx.GetSessionVars().GetSessionOrGlobalSystemVar("tidb_current_ts") + tso, _ := b.ctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), "tidb_current_ts") itso, _ := strconv.ParseInt(tso, 10, 64) return itso, false, nil } diff --git a/expression/builtin_time_test.go b/expression/builtin_time_test.go index fe33a92e2a99a..2010bf0a225b5 100644 --- a/expression/builtin_time_test.go +++ b/expression/builtin_time_test.go @@ -15,6 +15,7 @@ package expression import ( + "context" "fmt" "math" "strconv" @@ -2505,7 +2506,7 @@ func TestTimestampAdd(t *testing.T) { ctx := createContext(t) tests := []struct { unit string - interval int64 + interval float64 date interface{} expect string }{ @@ -2513,11 +2514,22 @@ func TestTimestampAdd(t *testing.T) { {"WEEK", 1, "2003-01-02 23:59:59", "2003-01-09 23:59:59"}, {"MICROSECOND", 1, 950501, "1995-05-01 00:00:00.000001"}, {"DAY", 28768, 0, ""}, + {"QUARTER", 3, "1995-05-01", "1996-02-01 00:00:00"}, + {"SECOND", 1.1, "1995-05-01", "1995-05-01 00:00:01.100000"}, + {"SECOND", -1, "1995-05-01", "1995-04-30 23:59:59"}, + {"SECOND", -1.1, "1995-05-01", "1995-04-30 23:59:58.900000"}, + {"SECOND", 9.9999e-6, "1995-05-01", "1995-05-01 00:00:00.000009"}, + {"SECOND", 9.9999e-7, "1995-05-01", "1995-05-01 00:00:00"}, + {"SECOND", -9.9999e-6, "1995-05-01", "1995-04-30 23:59:59.999991"}, + {"SECOND", -9.9999e-7, "1995-05-01", "1995-05-01 00:00:00"}, + {"MINUTE", 1.5, "1995-05-01 00:00:00", "1995-05-01 00:02:00"}, + {"MINUTE", 1.5, "1995-05-01 00:00:00.000000", "1995-05-01 00:02:00"}, + {"MICROSECOND", -100, "1995-05-01 00:00:00.0001", "1995-05-01 00:00:00"}, } fc := funcs[ast.TimestampAdd] for _, test := range tests { - dat := []types.Datum{types.NewStringDatum(test.unit), types.NewIntDatum(test.interval), types.NewDatum(test.date)} + dat := []types.Datum{types.NewStringDatum(test.unit), types.NewFloat64Datum(test.interval), types.NewDatum(test.date)} f, err := fc.getFunction(ctx, datumsToConstants(dat)) require.NoError(t, err) d, err := evalBuiltinFunc(f, chunk.Row{}) @@ -3112,7 +3124,7 @@ func TestCurrentTso(t *testing.T) { v, err := evalBuiltinFunc(f, chunk.Row{}) require.NoError(t, err) n := v.GetInt64() - tso, _ := ctx.GetSessionVars().GetSessionOrGlobalSystemVar("tidb_current_ts") + tso, _ := ctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), "tidb_current_ts") itso, _ := strconv.ParseInt(tso, 10, 64) require.Equal(t, itso, n, v.Kind()) } diff --git a/expression/builtin_time_vec.go b/expression/builtin_time_vec.go index 0d6b4321095f5..eb8c91e50bc84 100644 --- a/expression/builtin_time_vec.go +++ b/expression/builtin_time_vec.go @@ -1133,7 +1133,6 @@ func (b *builtinStrToDateDurationSig) vecEvalDuration(input *chunk.Chunk, result result.MergeNulls(bufStrings, bufFormats) d64s := result.GoDurations() sc := b.ctx.GetSessionVars().StmtCtx - hasNoZeroDateMode := b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() for i := 0; i < n; i++ { if result.IsNull(i) { continue @@ -1147,13 +1146,6 @@ func (b *builtinStrToDateDurationSig) vecEvalDuration(input *chunk.Chunk, result result.SetNull(i, true) continue } - if hasNoZeroDateMode && (t.Year() == 0 || t.Month() == 0 || t.Day() == 0) { - if err := handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String())); err != nil { - return err - } - result.SetNull(i, true) - continue - } t.SetFsp(b.tp.GetDecimal()) dur, err := t.ConvertToDuration() if err != nil { @@ -1703,7 +1695,7 @@ func (b *builtinTimestampAddSig) vecEvalString(input *chunk.Chunk, result *chunk return err } defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { + if err := b.args[1].VecEvalReal(b.ctx, input, buf1); err != nil { return err } @@ -1717,7 +1709,7 @@ func (b *builtinTimestampAddSig) vecEvalString(input *chunk.Chunk, result *chunk } result.ReserveString(n) - nums := buf1.Int64s() + nums := buf1.Float64s() ds := buf2.Times() for i := 0; i < n; i++ { if buf.IsNull(i) || buf1.IsNull(i) || buf2.IsNull(i) { @@ -1735,30 +1727,21 @@ func (b *builtinTimestampAddSig) vecEvalString(input *chunk.Chunk, result *chunk result.AppendNull() continue } - var tb time.Time + tb, overflow, err := addUnitToTime(unit, tm1, v) + if err != nil { + return err + } + if overflow { + if err = handleInvalidTimeError(b.ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime")); err != nil { + return err + } + result.AppendNull() + continue + } fsp := types.DefaultFsp - switch unit { - case "MICROSECOND": - tb = tm1.Add(time.Duration(v) * time.Microsecond) + // use MaxFsp when microsecond is not zero + if tb.Nanosecond()/1000 != 0 { fsp = types.MaxFsp - case "SECOND": - tb = tm1.Add(time.Duration(v) * time.Second) - case "MINUTE": - tb = tm1.Add(time.Duration(v) * time.Minute) - case "HOUR": - tb = tm1.Add(time.Duration(v) * time.Hour) - case "DAY": - tb = tm1.AddDate(0, 0, int(v)) - case "WEEK": - tb = tm1.AddDate(0, 0, 7*int(v)) - case "MONTH": - tb = tm1.AddDate(0, int(v), 0) - case "QUARTER": - tb = tm1.AddDate(0, 3*int(v), 0) - case "YEAR": - tb = tm1.AddDate(int(v), 0, 0) - default: - return types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, unit) } r := types.NewTime(types.FromGoTime(tb), b.resolveType(arg.Type(), unit), fsp) if err = r.Check(b.ctx.GetSessionVars().StmtCtx); err != nil { diff --git a/expression/column.go b/expression/column.go index 1ea8a319aadb3..abeca17409ce9 100644 --- a/expression/column.go +++ b/expression/column.go @@ -767,9 +767,11 @@ func (col *Column) MemoryUsage() (sum int64) { return } - sum = emptyColumnSize + col.RetType.MemoryUsage() + int64(cap(col.hashcode)) + - int64(len(col.OrigName)+len(col.charset)+len(col.collation)) + sum = emptyColumnSize + int64(cap(col.hashcode)) + int64(len(col.OrigName)+len(col.charset)+len(col.collation)) + if col.RetType != nil { + sum += col.RetType.MemoryUsage() + } if col.VirtualExpr != nil { sum += col.VirtualExpr.MemoryUsage() } diff --git a/expression/constant.go b/expression/constant.go index 9e2a1cfa14947..db9f94147f38a 100644 --- a/expression/constant.go +++ b/expression/constant.go @@ -464,6 +464,9 @@ func (c *Constant) MemoryUsage() (sum int64) { return } - sum = emptyConstantSize + c.RetType.MemoryUsage() + c.Value.MemUsage() + int64(cap(c.hashcode)) + sum = emptyConstantSize + c.Value.MemUsage() + int64(cap(c.hashcode)) + if c.RetType != nil { + sum += c.RetType.MemoryUsage() + } return } diff --git a/expression/constant_fold.go b/expression/constant_fold.go index f43cb75a1ff3c..0d73757b3161b 100644 --- a/expression/constant_fold.go +++ b/expression/constant_fold.go @@ -178,7 +178,12 @@ func foldConstant(expr Expression) (Expression, bool) { } } if !allConstArg { - if !hasNullArg || !sc.InNullRejectCheck || x.FuncName.L == ast.NullEQ { + // try to optimize on the situation when not all arguments are const + // for most functions, if one of the arguments are NULL, the result can be a constant (NULL or something else) + // + // NullEQ and ConcatWS are excluded, because they could have different value when the non-constant value is + // 1 or NULL. For example, concat_ws(NULL, NULL) gives NULL, but concat_ws(1, NULL) gives '' + if !hasNullArg || !sc.InNullRejectCheck || x.FuncName.L == ast.NullEQ || x.FuncName.L == ast.ConcatWS { return expr, isDeferredConst } constArgs := make([]Expression, len(args)) diff --git a/expression/constant_propagation_test.go b/expression/constant_propagation_test.go index 9c10d9ddd982b..d2ebfdef4080d 100644 --- a/expression/constant_propagation_test.go +++ b/expression/constant_propagation_test.go @@ -27,6 +27,7 @@ func TestOuterJoinPropConst(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2;") tk.MustExec("create table t1(id bigint primary key, a int, b int);") tk.MustExec("create table t2(id bigint primary key, a int, b int);") diff --git a/expression/constant_test.go b/expression/constant_test.go index 82c3d8e489fdf..2c2e226eabb5c 100644 --- a/expression/constant_test.go +++ b/expression/constant_test.go @@ -217,6 +217,15 @@ func TestConstantFolding(t *testing.T) { condition: newFunction(ast.LT, newColumn(0), newFunction(ast.Plus, newColumn(1), newFunction(ast.Plus, newLonglong(2), newLonglong(1)))), result: "lt(Column#0, plus(Column#1, 3))", }, + { + condition: func() Expression { + expr := newFunction(ast.ConcatWS, newColumn(0), NewNull()) + function := expr.(*ScalarFunction) + function.GetCtx().GetSessionVars().StmtCtx.InNullRejectCheck = true + return function + }(), + result: "concat_ws(cast(Column#0, var_string(20)), )", + }, } for _, tt := range tests { newConds := FoldConstant(tt.condition) diff --git a/expression/errors.go b/expression/errors.go index 0db38645f78d4..536ef065d7664 100644 --- a/expression/errors.go +++ b/expression/errors.go @@ -37,6 +37,10 @@ var ( ErrInvalidTableSample = dbterror.ClassExpression.NewStd(mysql.ErrInvalidTableSample) ErrInternal = dbterror.ClassOptimizer.NewStd(mysql.ErrInternal) ErrNoDB = dbterror.ClassOptimizer.NewStd(mysql.ErrNoDB) + ErrNotSupportedYet = dbterror.ClassExpression.NewStd(mysql.ErrNotSupportedYet) + ErrInvalidJSONForFuncIndex = dbterror.ClassExpression.NewStd(mysql.ErrInvalidJSONValueForFuncIndex) + ErrDataOutOfRangeFuncIndex = dbterror.ClassExpression.NewStd(mysql.ErrDataOutOfRangeFunctionalIndex) + ErrFuncIndexDataIsTooLong = dbterror.ClassExpression.NewStd(mysql.ErrFunctionalIndexDataIsTooLong) // All the un-exported errors are defined here: errFunctionNotExists = dbterror.ClassExpression.NewStd(mysql.ErrSpDoesNotExist) @@ -56,6 +60,7 @@ var ( errSpecificAccessDenied = dbterror.ClassExpression.NewStd(mysql.ErrSpecificAccessDenied) errUserLockDeadlock = dbterror.ClassExpression.NewStd(mysql.ErrUserLockDeadlock) errUserLockWrongName = dbterror.ClassExpression.NewStd(mysql.ErrUserLockWrongName) + errJSONInBooleanContext = dbterror.ClassExpression.NewStd(mysql.ErrJSONInBooleanContext) // Sequence usage privilege check. errSequenceAccessDenied = dbterror.ClassExpression.NewStd(mysql.ErrTableaccessDenied) diff --git a/expression/expr_to_pb_test.go b/expression/expr_to_pb_test.go index 802d559eb3c80..5e78459408701 100644 --- a/expression/expr_to_pb_test.go +++ b/expression/expr_to_pb_test.go @@ -528,6 +528,18 @@ func TestExprPushDownToFlash(t *testing.T) { require.NoError(t, err) exprs = append(exprs, function) + // json_extract + function, err = NewFunction(mock.NewContext(), ast.JSONExtract, types.NewFieldType(mysql.TypeJSON), jsonColumn, stringColumn) + require.NoError(t, err) + exprs = append(exprs, function) + + // json_unquote argument is cast(json as string) + subFunc, subErr := NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeString), jsonColumn) + require.NoError(t, subErr) + function, err = NewFunction(mock.NewContext(), ast.JSONUnquote, types.NewFieldType(mysql.TypeString), subFunc) + require.NoError(t, err) + exprs = append(exprs, function) + // lpad function, err = NewFunction(mock.NewContext(), ast.Lpad, types.NewFieldType(mysql.TypeString), stringColumn, int32Column, stringColumn) require.NoError(t, err) @@ -558,6 +570,14 @@ func TestExprPushDownToFlash(t *testing.T) { require.NoError(t, err) exprs = append(exprs, function) + // ExtractDuration + extractDurationUnitCol := new(Constant) + extractDurationUnitCol.Value = types.NewStringDatum("microsecond") + extractDurationUnitCol.RetType = types.NewFieldType(mysql.TypeString) + function, err = NewFunction(mock.NewContext(), ast.Extract, types.NewFieldType(mysql.TypeLonglong), extractDurationUnitCol, durationColumn) + require.NoError(t, err) + exprs = append(exprs, function) + // CastIntAsInt function, err = NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeLonglong), intColumn) require.NoError(t, err) @@ -631,6 +651,11 @@ func TestExprPushDownToFlash(t *testing.T) { require.NoError(t, err) exprs = append(exprs, function) + // CastJsonAsString + function, err = NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeString), jsonColumn) + require.NoError(t, err) + exprs = append(exprs, function) + // CastIntAsTime function, err = NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeDatetime), intColumn) require.NoError(t, err) @@ -950,6 +975,11 @@ func TestExprPushDownToFlash(t *testing.T) { exprs = exprs[:0] + // json_unquote's argument is not cast(json as string) + function, err = NewFunction(mock.NewContext(), ast.JSONUnquote, types.NewFieldType(mysql.TypeString), stringColumn) + require.NoError(t, err) + exprs = append(exprs, function) + // Substring2Args: can not be pushed function, err = NewFunction(mock.NewContext(), ast.Substr, types.NewFieldType(mysql.TypeString), binaryStringColumn, intColumn) require.NoError(t, err) @@ -1065,6 +1095,26 @@ func TestExprPushDownToFlash(t *testing.T) { require.NoError(t, err) exprs = append(exprs, function) + // regexp_like: supported + function, err = NewFunction(mock.NewContext(), ast.RegexpLike, types.NewFieldType(mysql.TypeLonglong), binaryStringColumn, binaryStringColumn, binaryStringColumn) + require.NoError(t, err) + exprs = append(exprs, function) + + // regexp_instr: supported + function, err = NewFunction(mock.NewContext(), ast.RegexpInStr, types.NewFieldType(mysql.TypeLonglong), stringColumn, stringColumn, intColumn, intColumn, intColumn, stringColumn) + require.NoError(t, err) + exprs = append(exprs, function) + + // regexp_substr: supported + function, err = NewFunction(mock.NewContext(), ast.RegexpSubstr, types.NewFieldType(mysql.TypeString), stringColumn, stringColumn, intColumn, intColumn, stringColumn) + require.NoError(t, err) + exprs = append(exprs, function) + + // regexp_replace: supported + function, err = NewFunction(mock.NewContext(), ast.RegexpReplace, types.NewFieldType(mysql.TypeString), stringColumn, stringColumn, stringColumn, intColumn, intColumn, stringColumn) + require.NoError(t, err) + exprs = append(exprs, function) + // greatest function, err = NewFunction(mock.NewContext(), ast.Greatest, types.NewFieldType(mysql.TypeLonglong), int32Column, intColumn) require.NoError(t, err) @@ -1194,6 +1244,11 @@ func TestExprPushDownToFlash(t *testing.T) { require.Equal(t, tipb.ScalarFuncSig_CastTimeAsDuration, function.(*ScalarFunction).Function.PbCode()) exprs = append(exprs, function) + // Unhex + function, err = NewFunction(mock.NewContext(), ast.Unhex, types.NewFieldType(mysql.TypeString), stringColumn) + require.NoError(t, err) + exprs = append(exprs, function) + pushed, remained = PushDownExprs(sc, exprs, client, kv.TiFlash) require.Len(t, pushed, len(exprs)) require.Len(t, remained, 0) diff --git a/expression/expression.go b/expression/expression.go index e8f38910c1264..6b6ce4c26e0a0 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -59,7 +59,7 @@ var EvalAstExpr func(sctx sessionctx.Context, expr ast.ExprNode) (types.Datum, e // RewriteAstExpr rewrites ast expression directly. // Note: initialized in planner/core // import expression and planner/core together to use EvalAstExpr -var RewriteAstExpr func(sctx sessionctx.Context, expr ast.ExprNode, schema *Schema, names types.NameSlice) (Expression, error) +var RewriteAstExpr func(sctx sessionctx.Context, expr ast.ExprNode, schema *Schema, names types.NameSlice, allowCastArray bool) (Expression, error) // VecExpr contains all vectorized evaluation methods. type VecExpr interface { @@ -816,6 +816,10 @@ func SplitDNFItems(onExpr Expression) []Expression { // If the Expression is a non-constant value, it means the result is unknown. func EvaluateExprWithNull(ctx sessionctx.Context, schema *Schema, expr Expression) Expression { if MaybeOverOptimized4PlanCache(ctx, []Expression{expr}) { + ctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.New("skip plan-cache: %v affects null check")) + } + if ctx.GetSessionVars().StmtCtx.InNullRejectCheck { + expr, _ = evaluateExprWithNullInNullRejectCheck(ctx, schema, expr) return expr } return evaluateExprWithNull(ctx, schema, expr) @@ -842,6 +846,71 @@ func evaluateExprWithNull(ctx sessionctx.Context, schema *Schema, expr Expressio return expr } +// evaluateExprWithNullInNullRejectCheck sets columns in schema as null and calculate the final result of the scalar function. +// If the Expression is a non-constant value, it means the result is unknown. +// The returned bool values indicates whether the value is influenced by the Null Constant transformed from schema column +// when the value is Null Constant. +func evaluateExprWithNullInNullRejectCheck(ctx sessionctx.Context, schema *Schema, expr Expression) (Expression, bool) { + switch x := expr.(type) { + case *ScalarFunction: + args := make([]Expression, len(x.GetArgs())) + nullFromSets := make([]bool, len(x.GetArgs())) + for i, arg := range x.GetArgs() { + args[i], nullFromSets[i] = evaluateExprWithNullInNullRejectCheck(ctx, schema, arg) + } + allArgsNullFromSet := true + for i := range args { + if cons, ok := args[i].(*Constant); ok && cons.Value.IsNull() && !nullFromSets[i] { + allArgsNullFromSet = false + break + } + } + + // If one of the args of `AND` and `OR` are Null Constant from the column schema, and the another argument is Constant, then we should keep it. + // Otherwise, we shouldn't let Null Constant which affected by the column schema participate in computing in `And` and `OR` + // due to the result of `AND` and `OR` are uncertain if one of the arguments is NULL. + if x.FuncName.L == ast.LogicAnd || x.FuncName.L == ast.LogicOr { + hasNonConstantArg := false + for _, arg := range args { + if _, ok := arg.(*Constant); !ok { + hasNonConstantArg = true + break + } + } + if hasNonConstantArg { + for i := range args { + if cons, ok := args[i].(*Constant); ok && cons.Value.IsNull() && nullFromSets[i] { + if x.FuncName.L == ast.LogicAnd { + args[i] = NewOne() + break + } + if x.FuncName.L == ast.LogicOr { + args[i] = NewZero() + break + } + } + } + } + } + + c := NewFunctionInternal(ctx, x.FuncName.L, x.RetType.Clone(), args...) + cons, ok := c.(*Constant) + // If the return expr is Null Constant, and all the Null Constant arguments are affected by column schema, + // then we think the result Null Constant is also affected by the column schema + return c, ok && cons.Value.IsNull() && allArgsNullFromSet + case *Column: + if !schema.Contains(x) { + return x, false + } + return &Constant{Value: types.Datum{}, RetType: types.NewFieldType(mysql.TypeNull)}, true + case *Constant: + if x.DeferredExpr != nil { + return FoldConstant(x), false + } + } + return expr, false +} + // TableInfo2SchemaAndNames converts the TableInfo to the schema and name slice. func TableInfo2SchemaAndNames(ctx sessionctx.Context, dbName model.CIStr, tbl *model.TableInfo) (*Schema, []*types.FieldName, error) { cols, names, err := ColumnInfos2ColumnsAndNames(ctx, dbName, tbl.Name, tbl.Cols(), tbl) @@ -929,7 +998,7 @@ func ColumnInfos2ColumnsAndNames(ctx sessionctx.Context, dbName, tblName model.C if err != nil { return nil, nil, errors.Trace(err) } - e, err := RewriteAstExpr(ctx, expr, mockSchema, names) + e, err := RewriteAstExpr(ctx, expr, mockSchema, names, true) if err != nil { return nil, nil, errors.Trace(err) } @@ -1002,8 +1071,7 @@ func scalarExprSupportedByTiKV(sf *ScalarFunction) bool { // json functions. ast.JSONType, ast.JSONExtract, ast.JSONObject, ast.JSONArray, ast.JSONMerge, ast.JSONSet, ast.JSONInsert /*ast.JSONReplace,*/, ast.JSONRemove, ast.JSONLength, - // FIXME: JSONUnquote is incompatible with Coprocessor - ast.JSONUnquote, ast.JSONContains, + ast.JSONUnquote, ast.JSONContains, ast.JSONValid, // date functions. ast.Date, ast.Week /* ast.YearWeek, ast.ToSeconds */, ast.DateDiff, @@ -1082,10 +1150,10 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool { ast.Sqrt, ast.Log, ast.Log2, ast.Log10, ast.Ln, ast.Exp, ast.Pow, ast.Sign, ast.Radians, ast.Degrees, ast.Conv, ast.CRC32, - ast.JSONLength, ast.Repeat, + ast.JSONLength, ast.JSONExtract, ast.JSONUnquote, ast.Repeat, ast.InetNtoa, ast.InetAton, ast.Inet6Ntoa, ast.Inet6Aton, ast.Coalesce, ast.ASCII, ast.Length, ast.Trim, ast.Position, ast.Format, ast.Elt, - ast.LTrim, ast.RTrim, ast.Lpad, ast.Rpad, ast.Regexp, + ast.LTrim, ast.RTrim, ast.Lpad, ast.Rpad, ast.Hour, ast.Minute, ast.Second, ast.MicroSecond, ast.TimeToSec: switch function.Function.PbCode() { @@ -1095,6 +1163,18 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool { tipb.ScalarFuncSig_IfDuration, tipb.ScalarFuncSig_CaseWhenDuration: return false + case tipb.ScalarFuncSig_JsonUnquoteSig: + // TiFlash json_unquote now only supports json string generated by cast(json as string) + if childFunc, ok := function.GetArgs()[0].(*ScalarFunction); ok { + return childFunc.Function.PbCode() == tipb.ScalarFuncSig_CastJsonAsString + } + return false + } + return true + case ast.Regexp, ast.RegexpLike, ast.RegexpInStr, ast.RegexpSubstr, ast.RegexpReplace: + funcCharset, funcCollation := function.Function.CharsetAndCollation() + if funcCharset == charset.CharsetBin && funcCollation == charset.CollationBin { + return false } return true case ast.Substr, ast.Substring, ast.Left, ast.Right, ast.CharLength, ast.SubstringIndex, ast.Reverse: @@ -1126,7 +1206,7 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool { tipb.ScalarFuncSig_CastStringAsDecimal /*, tipb.ScalarFuncSig_CastDurationAsDecimal, tipb.ScalarFuncSig_CastJsonAsDecimal*/ : return function.RetType.IsDecimalValid() case tipb.ScalarFuncSig_CastDecimalAsString, tipb.ScalarFuncSig_CastIntAsString, tipb.ScalarFuncSig_CastRealAsString, tipb.ScalarFuncSig_CastTimeAsString, - tipb.ScalarFuncSig_CastStringAsString /*, tipb.ScalarFuncSig_CastDurationAsString, tipb.ScalarFuncSig_CastJsonAsString*/ : + tipb.ScalarFuncSig_CastStringAsString, tipb.ScalarFuncSig_CastJsonAsString /*, tipb.ScalarFuncSig_CastDurationAsString*/ : return true case tipb.ScalarFuncSig_CastDecimalAsTime, tipb.ScalarFuncSig_CastIntAsTime, tipb.ScalarFuncSig_CastRealAsTime, tipb.ScalarFuncSig_CastTimeAsTime, tipb.ScalarFuncSig_CastStringAsTime /*, tipb.ScalarFuncSig_CastDurationAsTime, tipb.ScalarFuncSig_CastJsonAsTime*/ : @@ -1158,7 +1238,7 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool { } case ast.Extract: switch function.Function.PbCode() { - case tipb.ScalarFuncSig_ExtractDatetime: + case tipb.ScalarFuncSig_ExtractDatetime, tipb.ScalarFuncSig_ExtractDuration: return true } case ast.Replace: @@ -1187,7 +1267,7 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool { } case ast.IsTruthWithNull, ast.IsTruthWithoutNull, ast.IsFalsity: return true - case ast.Hex, ast.Bin: + case ast.Hex, ast.Unhex, ast.Bin: return true case ast.GetFormat: return true @@ -1278,12 +1358,15 @@ func canScalarFuncPushDown(scalarFunc *ScalarFunction, pc PbConverter, storeType panic(errors.Errorf("unspecified PbCode: %T", scalarFunc.Function)) }) } + storageName := storeType.Name() + if storeType == kv.UnSpecified { + storageName = "storage layer" + } + warnErr := errors.New("Scalar function '" + scalarFunc.FuncName.L + "'(signature: " + scalarFunc.Function.PbCode().String() + ", return type: " + scalarFunc.RetType.CompactStr() + ") is not supported to push down to " + storageName + " now.") if pc.sc.InExplainStmt { - storageName := storeType.Name() - if storeType == kv.UnSpecified { - storageName = "storage layer" - } - pc.sc.AppendWarning(errors.New("Scalar function '" + scalarFunc.FuncName.L + "'(signature: " + scalarFunc.Function.PbCode().String() + ", return type: " + scalarFunc.RetType.CompactStr() + ") is not supported to push down to " + storageName + " now.")) + pc.sc.AppendWarning(warnErr) + } else { + pc.sc.AppendExtraWarning(warnErr) } return false } @@ -1313,14 +1396,20 @@ func canExprPushDown(expr Expression, pc PbConverter, storeType kv.StoreType, ca if expr.GetType().GetType() == mysql.TypeEnum && canEnumPush { break } + warnErr := errors.New("Expression about '" + expr.String() + "' can not be pushed to TiFlash because it contains unsupported calculation of type '" + types.TypeStr(expr.GetType().GetType()) + "'.") if pc.sc.InExplainStmt { - pc.sc.AppendWarning(errors.New("Expression about '" + expr.String() + "' can not be pushed to TiFlash because it contains unsupported calculation of type '" + types.TypeStr(expr.GetType().GetType()) + "'.")) + pc.sc.AppendWarning(warnErr) + } else { + pc.sc.AppendExtraWarning(warnErr) } return false case mysql.TypeNewDecimal: if !expr.GetType().IsDecimalValid() { + warnErr := errors.New("Expression about '" + expr.String() + "' can not be pushed to TiFlash because it contains invalid decimal('" + strconv.Itoa(expr.GetType().GetFlen()) + "','" + strconv.Itoa(expr.GetType().GetDecimal()) + "').") if pc.sc.InExplainStmt { - pc.sc.AppendWarning(errors.New("Expression about '" + expr.String() + "' can not be pushed to TiFlash because it contains invalid decimal('" + strconv.Itoa(expr.GetType().GetFlen()) + "','" + strconv.Itoa(expr.GetType().GetDecimal()) + "').")) + pc.sc.AppendWarning(warnErr) + } else { + pc.sc.AppendExtraWarning(warnErr) } return false } @@ -1485,6 +1574,10 @@ func Args2Expressions4Test(args ...interface{}) []Expression { ft = types.NewFieldType(mysql.TypeDouble) case types.KindString: ft = types.NewFieldType(mysql.TypeVarString) + case types.KindMysqlTime: + ft = types.NewFieldType(mysql.TypeTimestamp) + case types.KindBytes: + ft = types.NewFieldType(mysql.TypeBlob) default: exprs[i] = nil continue diff --git a/expression/expression_test.go b/expression/expression_test.go index 79ee1970ba800..4a24cb5eef759 100644 --- a/expression/expression_test.go +++ b/expression/expression_test.go @@ -75,8 +75,9 @@ func TestEvaluateExprWithNullAndParameters(t *testing.T) { ltWithParam, err := newFunctionForTest(ctx, ast.LT, col0, param) require.NoError(t, err) res = EvaluateExprWithNull(ctx, schema, ltWithParam) - _, isScalarFunc := res.(*ScalarFunction) - require.True(t, isScalarFunc) // the expression with parameters is not evaluated + _, isConst := res.(*Constant) + require.True(t, isConst) // this expression is evaluated and skip-plan cache flag is set. + require.True(t, !ctx.GetSessionVars().StmtCtx.UseCache) } func TestEvaluateExprWithNullNoChangeRetType(t *testing.T) { diff --git a/expression/extension.go b/expression/extension.go new file mode 100644 index 0000000000000..9ab506213d5f0 --- /dev/null +++ b/expression/extension.go @@ -0,0 +1,209 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expression + +import ( + "context" + "strings" + "sync" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/extension" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/privilege" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/sem" +) + +var extensionFuncs sync.Map + +func registerExtensionFunc(def *extension.FunctionDef) error { + if def == nil { + return errors.New("extension function def is nil") + } + + if err := def.Validate(); err != nil { + return err + } + + lowerName := strings.ToLower(def.Name) + if _, ok := funcs[lowerName]; ok { + return errors.Errorf("extension function name '%s' conflict with builtin", def.Name) + } + + class, err := newExtensionFuncClass(def) + if err != nil { + return err + } + + _, exist := extensionFuncs.LoadOrStore(lowerName, class) + if exist { + return errors.Errorf("duplicated extension function name '%s'", def.Name) + } + + return nil +} + +func removeExtensionFunc(name string) { + extensionFuncs.Delete(name) +} + +type extensionFuncClass struct { + baseFunctionClass + funcDef extension.FunctionDef + flen int +} + +func newExtensionFuncClass(def *extension.FunctionDef) (*extensionFuncClass, error) { + var flen int + switch def.EvalTp { + case types.ETString: + flen = mysql.MaxFieldVarCharLength + if def.EvalStringFunc == nil { + return nil, errors.New("eval function is nil") + } + case types.ETInt: + flen = mysql.MaxIntWidth + if def.EvalIntFunc == nil { + return nil, errors.New("eval function is nil") + } + default: + return nil, errors.Errorf("unsupported extension function ret type: '%v'", def.EvalTp) + } + + maxArgs := len(def.ArgTps) + minArgs := maxArgs - def.OptionalArgsLen + return &extensionFuncClass{ + baseFunctionClass: baseFunctionClass{def.Name, minArgs, maxArgs}, + flen: flen, + funcDef: *def, + }, nil +} + +func (c *extensionFuncClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) { + if err := c.checkPrivileges(ctx); err != nil { + return nil, err + } + + if err := c.verifyArgs(args); err != nil { + return nil, err + } + bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, c.funcDef.EvalTp, c.funcDef.ArgTps[:len(args)]...) + if err != nil { + return nil, err + } + bf.tp.SetFlen(c.flen) + sig := &extensionFuncSig{context.TODO(), bf, c.funcDef} + return sig, nil +} + +func (c *extensionFuncClass) checkPrivileges(ctx sessionctx.Context) error { + fn := c.funcDef.RequireDynamicPrivileges + if fn == nil { + return nil + } + + semEnabled := sem.IsEnabled() + privs := fn(semEnabled) + if len(privs) == 0 { + return nil + } + + manager := privilege.GetPrivilegeManager(ctx) + activeRoles := ctx.GetSessionVars().ActiveRoles + + for _, priv := range privs { + if !manager.RequestDynamicVerification(activeRoles, priv, false) { + msg := priv + if !semEnabled { + msg = "SUPER or " + msg + } + return errSpecificAccessDenied.GenWithStackByArgs(msg) + } + } + + return nil +} + +var _ extension.FunctionContext = &extensionFuncSig{} + +type extensionFuncSig struct { + context.Context + baseBuiltinFunc + extension.FunctionDef +} + +func (b *extensionFuncSig) Clone() builtinFunc { + newSig := &extensionFuncSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + newSig.FunctionDef = b.FunctionDef + return newSig +} + +func (b *extensionFuncSig) evalString(row chunk.Row) (string, bool, error) { + if b.EvalTp == types.ETString { + return b.EvalStringFunc(b, row) + } + return b.baseBuiltinFunc.evalString(row) +} + +func (b *extensionFuncSig) evalInt(row chunk.Row) (int64, bool, error) { + if b.EvalTp == types.ETInt { + return b.EvalIntFunc(b, row) + } + return b.baseBuiltinFunc.evalInt(row) +} + +func (b *extensionFuncSig) EvalArgs(row chunk.Row) ([]types.Datum, error) { + if len(b.args) == 0 { + return nil, nil + } + + result := make([]types.Datum, 0, len(b.args)) + for _, arg := range b.args { + val, err := arg.Eval(row) + if err != nil { + return nil, err + } + result = append(result, val) + } + + return result, nil +} + +func (b *extensionFuncSig) ConnectionInfo() *variable.ConnectionInfo { + return b.ctx.GetSessionVars().ConnectionInfo +} + +func (b *extensionFuncSig) User() *auth.UserIdentity { + return b.ctx.GetSessionVars().User +} + +func (b *extensionFuncSig) ActiveRoles() []*auth.RoleIdentity { + return b.ctx.GetSessionVars().ActiveRoles +} + +func (b *extensionFuncSig) CurrentDB() string { + return b.ctx.GetSessionVars().CurrentDB +} + +func init() { + extension.RegisterExtensionFunc = registerExtensionFunc + extension.RemoveExtensionFunc = removeExtensionFunc +} diff --git a/expression/function_traits.go b/expression/function_traits.go index aba61d9b2d92a..4d6fa98da6a99 100644 --- a/expression/function_traits.go +++ b/expression/function_traits.go @@ -19,8 +19,8 @@ import ( "github.com/pingcap/tidb/parser/opcode" ) -// GeneralPlanCacheableOp stores function which can be cached to general plan cache. -var GeneralPlanCacheableOp = map[string]struct{}{ +// NonPreparedPlanCacheableOp stores function which can be cached to non-prepared plan cache. +var NonPreparedPlanCacheableOp = map[string]struct{}{ ast.LogicAnd: {}, ast.LogicOr: {}, ast.GE: {}, diff --git a/expression/helper.go b/expression/helper.go index 6e235d1abcc96..d31765a28634b 100644 --- a/expression/helper.go +++ b/expression/helper.go @@ -15,6 +15,7 @@ package expression import ( + "context" "math" "strings" "time" @@ -73,7 +74,7 @@ func getTimeCurrentTimeStamp(ctx sessionctx.Context, tp byte, fsp int) (t types. return value, err } value.SetCoreTime(types.FromGoTime(defaultTime.Truncate(time.Duration(math.Pow10(9-fsp)) * time.Nanosecond))) - if tp == mysql.TypeTimestamp || tp == mysql.TypeDatetime { + if tp == mysql.TypeTimestamp || tp == mysql.TypeDatetime || tp == mysql.TypeDate { err = value.ConvertTimeZone(time.Local, ctx.GetSessionVars().Location()) if err != nil { return value, err @@ -89,12 +90,12 @@ func GetTimeValue(ctx sessionctx.Context, v interface{}, tp byte, fsp int) (d ty sc := ctx.GetSessionVars().StmtCtx switch x := v.(type) { case string: - upperX := strings.ToUpper(x) - if upperX == strings.ToUpper(ast.CurrentTimestamp) { + lowerX := strings.ToLower(x) + if lowerX == ast.CurrentTimestamp || lowerX == ast.CurrentDate { if value, err = getTimeCurrentTimeStamp(ctx, tp, fsp); err != nil { return d, err } - } else if upperX == types.ZeroDatetimeStr { + } else if lowerX == types.ZeroDatetimeStr { value, err = types.ParseTimeFromNum(sc, 0, tp, fsp) terror.Log(err) } else { @@ -121,8 +122,8 @@ func GetTimeValue(ctx sessionctx.Context, v interface{}, tp byte, fsp int) (d ty return d, errDefaultValue } case *ast.FuncCallExpr: - if x.FnName.L == ast.CurrentTimestamp { - d.SetString(strings.ToUpper(ast.CurrentTimestamp), mysql.DefaultCollationName) + if x.FnName.L == ast.CurrentTimestamp || x.FnName.L == ast.CurrentDate { + d.SetString(strings.ToUpper(x.FnName.L), mysql.DefaultCollationName) return d, nil } return d, errDefaultValue @@ -164,7 +165,7 @@ func getStmtTimestamp(ctx sessionctx.Context) (time.Time, error) { } sessionVars := ctx.GetSessionVars() - timestampStr, err := sessionVars.GetSessionOrGlobalSystemVar("timestamp") + timestampStr, err := sessionVars.GetSessionOrGlobalSystemVar(context.Background(), "timestamp") if err != nil { return now, err } diff --git a/expression/integration_serial_test.go b/expression/integration_serial_test.go index 48d85d813f205..b70b7be4a5070 100644 --- a/expression/integration_serial_test.go +++ b/expression/integration_serial_test.go @@ -3762,15 +3762,6 @@ func TestSetVariables(t *testing.T) { _, err = tk.Exec("set @@global.max_prepared_stmt_count='';") require.Error(t, err) require.Error(t, err, variable.ErrWrongTypeForVar.GenWithStackByArgs("max_prepared_stmt_count").Error()) - - tk.MustExec("set @@global.tidb_enable_concurrent_ddl=1") - tk.MustQuery("select @@global.tidb_enable_concurrent_ddl").Check(testkit.Rows("1")) - require.True(t, variable.EnableConcurrentDDL.Load()) - tk.MustExec("set @@global.tidb_enable_concurrent_ddl=0") - tk.MustQuery("select @@global.tidb_enable_concurrent_ddl").Check(testkit.Rows("0")) - require.False(t, variable.EnableConcurrentDDL.Load()) - testkit.NewTestKit(t, store).MustQuery("select @@global.tidb_enable_concurrent_ddl").Check(testkit.Rows("0")) - tk.MustExec("set @@global.tidb_enable_concurrent_ddl=1") } func TestPreparePlanCache(t *testing.T) { @@ -3795,10 +3786,11 @@ func TestPreparePlanCacheOnCachedTable(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("set tidb_enable_prepared_plan_cache=ON") + tk.Session() var err error se, err := session.CreateSession4TestWithOpt(store, &session.Opt{ - PreparedPlanCache: plannercore.NewLRUPlanCache(100, 0.1, math.MaxUint64, plannercore.PickPlanFromBucket), + PreparedPlanCache: plannercore.NewLRUPlanCache(100, 0.1, math.MaxUint64, plannercore.PickPlanFromBucket, tk.Session()), }) require.NoError(t, err) tk.SetSession(se) diff --git a/expression/integration_test.go b/expression/integration_test.go index 5c47118c1ca46..a49df593d201c 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -968,6 +968,7 @@ func TestEncryptionBuiltin(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.Session().GetSessionVars().User = &auth.UserIdentity{Username: "root"} ctx := context.Background() // for password @@ -1143,6 +1144,25 @@ func TestEncryptionBuiltin(t *testing.T) { tk.MustQuery("SELECT RANDOM_BYTES(1024);") result = tk.MustQuery("SELECT RANDOM_BYTES(NULL);") result.Check(testkit.Rows("")) + + // for VALIDATE_PASSWORD_STRENGTH + tk.MustExec(fmt.Sprintf("SET GLOBAL validate_password.dictionary='%s'", "password")) + tk.MustExec("SET GLOBAL validate_password.enable = 1") + tk.MustQuery("SELECT validate_password_strength('root')").Check(testkit.Rows("0")) + tk.MustQuery("SELECT validate_password_strength('toor')").Check(testkit.Rows("0")) + tk.MustQuery("SELECT validate_password_strength('ROOT')").Check(testkit.Rows("25")) + tk.MustQuery("SELECT validate_password_strength('TOOR')").Check(testkit.Rows("25")) + tk.MustQuery("SELECT validate_password_strength('fooHoHo%1')").Check(testkit.Rows("100")) + tk.MustQuery("SELECT validate_password_strength('pass')").Check(testkit.Rows("25")) + tk.MustQuery("SELECT validate_password_strength('password')").Check(testkit.Rows("50")) + tk.MustQuery("SELECT validate_password_strength('password0000')").Check(testkit.Rows("50")) + tk.MustQuery("SELECT validate_password_strength('password1A#')").Check(testkit.Rows("75")) + tk.MustQuery("SELECT validate_password_strength('PA12wrd!#')").Check(testkit.Rows("100")) + tk.MustQuery("SELECT VALIDATE_PASSWORD_STRENGTH(REPEAT(\"aA1#\", 26))").Check(testkit.Rows("100")) + tk.MustQuery("SELECT validate_password_strength(null)").Check(testkit.Rows("")) + tk.MustQuery("SELECT validate_password_strength('null')").Check(testkit.Rows("25")) + tk.MustQuery("SELECT VALIDATE_PASSWORD_STRENGTH( 0x6E616E646F73617135234552 )").Check(testkit.Rows("100")) + tk.MustQuery("SELECT VALIDATE_PASSWORD_STRENGTH(CAST(0xd2 AS BINARY(10)))").Check(testkit.Rows("50")) } func TestOpBuiltin(t *testing.T) { @@ -1208,8 +1228,7 @@ func TestDatetimeOverflow(t *testing.T) { } for _, sql := range overflowSQLs { - _, err := tk.Exec(sql) - require.Error(t, err, "[types:1441]Datetime function: datetime field overflow") + tk.MustGetErrMsg(sql, "[types:1441]Datetime function: datetime field overflow") } tk.MustExec("set sql_mode=''") @@ -1696,8 +1715,7 @@ func TestArithmeticBuiltin(t *testing.T) { tk.MustQuery("select v from t;").Check(testkit.Rows("")) tk.MustQuery("select 0.000 % 0.11234500000000000000;").Check(testkit.Rows("0.00000000000000000000")) - _, err = tk.Exec("INSERT INTO t VALUE(12 MOD 0);") - require.True(t, terror.ErrorEqual(err, expression.ErrDivisionByZero)) + tk.MustGetDBError("INSERT INTO t VALUE(12 MOD 0);", expression.ErrDivisionByZero) tk.MustQuery("select sum(1.2e2) * 0.1").Check(testkit.Rows("12")) tk.MustExec("drop table if exists t") @@ -1940,8 +1958,7 @@ func TestCompareBuiltin(t *testing.T) { tk.MustQuery("select * from t").Check(testkit.Rows("1991-05-06 13:59:28")) // insert an nonexistent time tk.MustExec("set time_zone = 'America/Los_Angeles'") - _, err := tk.Exec("insert into t value('2011-03-13 02:00:00')") - require.Error(t, err) + tk.MustExecToErr("insert into t value('2011-03-13 02:00:00')") // reset timezone to a +8 offset tk.MustExec("set time_zone = '+08:00'") tk.MustQuery("select * from t").Check(testkit.Rows("1991-05-06 12:59:28")) @@ -2105,11 +2122,9 @@ func TestAggregationBuiltinGroupConcat(t *testing.T) { result.Check(testkit.Rows("hello,h")) tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning 1260 Some rows were cut by GROUPCONCAT(test.t.a)")) - _, err := tk.Exec("insert into d select group_concat(a) from t") - require.Equal(t, errors.ErrCode(mysql.ErrCutValueGroupConcat), errors.Cause(err).(*terror.Error).Code()) + tk.MustGetErrCode("insert into d select group_concat(a) from t", mysql.ErrCutValueGroupConcat) - _, err = tk.Exec("set sql_mode=''") - require.NoError(t, err) + tk.MustExec("set sql_mode=''") tk.MustExec("insert into d select group_concat(a) from t") tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning 1260 Some rows were cut by GROUPCONCAT(test.t.a)")) tk.MustQuery("select * from d").Check(testkit.Rows("hello,h")) @@ -2193,6 +2208,22 @@ func TestAggregationBuiltinJSONObjectAgg(t *testing.T) { result.Check(testkit.Rows(`{"first": "json_objectagg_test"}`)) result = tk.MustQuery("select json_objectagg(a, null) from t group by a order by a;") result.Check(testkit.Rows(`{"1": null}`)) + + // For issue: https://github.com/pingcap/tidb/issues/39806 + // Optimization shouldn't rewrite the flag of `castStringAsJson`. + tk.MustQuery(` + select a from ( + select JSON_OBJECT('number', number, 'name', name) 'a' from + ( + select 1 as number, 'name-1' as name union + (select 2, 'name-2' ) union + (select 3, 'name-3' ) union + (select 4, 'name-4' ) union + (select 5, 'name-5' ) union + (select 6, 'name-2' ) + ) temp1 + ) temp + where a ->> '$.number' = 1`).Check(testkit.Rows(`{"name": "name-1", "number": 1}`)) } func TestOtherBuiltin(t *testing.T) { @@ -2354,23 +2385,18 @@ func TestDateBuiltin(t *testing.T) { r = tk.MustQuery("select date'731124', date '011124'") r.Check(testkit.Rows("1973-11-24 2001-11-24")) - _, err = tk.Exec("select date '0000-00-00 00:00:00';") + err = tk.ExecToErr("select date '0000-00-00 00:00:00';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.DateStr, "0000-00-00 00:00:00"))) - _, err = tk.Exec("select date '2017-99-99';") - require.Error(t, err) - require.True(t, terror.ErrorEqual(err, types.ErrWrongValue), "err: %v", err) + tk.MustGetDBError("select date '2017-99-99';", types.ErrWrongValue) + tk.MustGetDBError("select date '2017-2-31';", types.ErrWrongValue) - _, err = tk.Exec("select date '2017-2-31';") - require.Error(t, err) - require.True(t, terror.ErrorEqual(err, types.ErrWrongValue), "err: %v", err) - - _, err = tk.Exec("select date '201712-31';") + err = tk.ExecToErr("select date '201712-31';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.DateStr, "201712-31")), "err: %v", err) - _, err = tk.Exec("select date 'abcdefg';") + err = tk.ExecToErr("select date 'abcdefg';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.DateStr, "abcdefg")), "err: %v", err) } @@ -2382,8 +2408,7 @@ func TestJSONBuiltin(t *testing.T) { tk.MustExec("USE test;") tk.MustExec("DROP TABLE IF EXISTS t;") tk.MustExec("CREATE TABLE `my_collection` ( `doc` json DEFAULT NULL, `_id` varchar(32) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(doc,'$._id'))) STORED NOT NULL, PRIMARY KEY (`_id`))") - _, err := tk.Exec("UPDATE `test`.`my_collection` SET doc=JSON_SET(doc) WHERE (JSON_EXTRACT(doc,'$.name') = 'clare');") - require.Error(t, err) + tk.MustExecToErr("UPDATE `test`.`my_collection` SET doc=JSON_SET(doc) WHERE (JSON_EXTRACT(doc,'$.name') = 'clare');") r := tk.MustQuery("select json_valid(null);") r.Check(testkit.Rows("")) @@ -2459,20 +2484,19 @@ func TestTimeLiteral(t *testing.T) { r = tk.MustQuery("select time '20 20:20';") r.Check(testkit.Rows("500:20:00")) - _, err := tk.Exec("select time '2017-01-01 00:00:00';") + err := tk.ExecToErr("select time '2017-01-01 00:00:00';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, "2017-01-01 00:00:00"))) - _, err = tk.Exec("select time '071231235959.999999';") + err = tk.ExecToErr("select time '071231235959.999999';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, "071231235959.999999"))) - _, err = tk.Exec("select time '20171231235959.999999';") + err = tk.ExecToErr("select time '20171231235959.999999';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, "20171231235959.999999"))) - _, err = tk.Exec("select ADDDATE('2008-01-34', -1);") - require.NoError(t, err) + tk.MustExec("select ADDDATE('2008-01-34', -1);") tk.MustQuery("Show warnings;").Check(testkit.RowsWithSep("|", "Warning|1292|Incorrect datetime value: '2008-01-34'")) } @@ -2502,15 +2526,15 @@ func TestTimestampLiteral(t *testing.T) { r = tk.MustQuery("select timestamp '2017@01@0001 00~00~00.333';") r.Check(testkit.Rows("2017-01-01 00:00:00.333")) - _, err := tk.Exec("select timestamp '00:00:00';") + err := tk.ExecToErr("select timestamp '00:00:00';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, "00:00:00"))) - _, err = tk.Exec("select timestamp '1992-01-03';") + err = tk.ExecToErr("select timestamp '1992-01-03';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, "1992-01-03"))) - _, err = tk.Exec("select timestamp '20171231235959.999999';") + err = tk.ExecToErr("select timestamp '20171231235959.999999';") require.Error(t, err) require.True(t, terror.ErrorEqual(err, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, "20171231235959.999999"))) } @@ -2701,12 +2725,36 @@ func TestFuncJSON(t *testing.T) { // #16267 tk.MustQuery(`select json_array(922337203685477580) = json_array(922337203685477581);`).Check(testkit.Rows("0")) + tk.MustQuery("select json_overlaps('[[1,2], 3]', '[1, 3]');").Check(testkit.Rows("1")) + tk.MustQuery("select json_overlaps('[{\"a\":1}]', '{\"a\":1}');").Check(testkit.Rows("1")) + tk.MustQuery("select json_overlaps('{\"a\":1}', '[{\"a\":1}]');").Check(testkit.Rows("1")) + tk.MustQuery("select json_overlaps('[1,[2,3]]', '[[1,2], 3]');").Check(testkit.Rows("0")) + tk.MustQuery("select json_overlaps('{\"a\":[1,2]}', '{\"a\":[2,1]}');").Check(testkit.Rows("0")) + tk.MustQuery("select json_overlaps('{\"a\":[1,2]}', '{\"a\":[2,1]}');").Check(testkit.Rows("0")) + // #10461 tk.MustExec("drop table if exists tx1") tk.MustExec("create table tx1(id int key, a double, b double, c double, d double)") tk.MustExec("insert into tx1 values (1, 0.1, 0.2, 0.3, 0.0)") tk.MustQuery("select a+b, c from tx1").Check(testkit.Rows("0.30000000000000004 0.3")) tk.MustQuery("select json_array(a+b) = json_array(c) from tx1").Check(testkit.Rows("0")) + + tk.MustQuery("SELECT '{\"a\":1}' MEMBER OF('{\"a\":1}');").Check(testkit.Rows("0")) + tk.MustQuery("SELECT '{\"a\":1}' MEMBER OF('[{\"a\":1}]');").Check(testkit.Rows("0")) + tk.MustQuery("SELECT 1 MEMBER OF('1');").Check(testkit.Rows("1")) + tk.MustQuery("SELECT '{\"a\":1}' MEMBER OF('{\"a\":1}');").Check(testkit.Rows("0")) + tk.MustQuery("SELECT '[4,5]' MEMBER OF('[[3,4],[4,5]]');").Check(testkit.Rows("0")) + tk.MustQuery("SELECT '[4,5]' MEMBER OF('[[3,4],\"[4,5]\"]');").Check(testkit.Rows("1")) + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a enum('a', 'b'), b time, c binary(10))") + tk.MustExec("insert into t values ('a', '11:00:00', 'a')") + tk.MustQuery("select a member of ('\"a\"') from t").Check(testkit.Rows(`1`)) + tk.MustQuery("select b member of (json_array(cast('11:00:00' as time))) from t;").Check(testkit.Rows(`1`)) + tk.MustQuery("select b member of ('\"11:00:00\"') from t").Check(testkit.Rows(`0`)) + tk.MustQuery("select c member of ('\"a\"') from t").Check(testkit.Rows(`0`)) + err = tk.QueryToErr("select 'a' member of ('a')") + require.Error(t, err, "ERROR 3140 (22032): Invalid JSON text: The document root must not be followed by other values.") } func TestColumnInfoModified(t *testing.T) { @@ -2852,7 +2900,7 @@ func TestFilterExtractFromDNF(t *testing.T) { require.NoError(t, err, "error %v, for expr %s", err, tt.exprStr) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err, "error %v, for resolve name, expr %s", err, tt.exprStr) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err, "error %v, for build plan, expr %s", err, tt.exprStr) @@ -3050,6 +3098,30 @@ func TestTiDBDecodeKeyFunc(t *testing.T) { sql = fmt.Sprintf("select tidb_decode_key( '%s' )", hexKey) rs = fmt.Sprintf(`{"%s":%d,"table_id":"%d"}`, tbl.Meta().GetPkName().String(), rowID, tbl.Meta().ID) tk.MustQuery(sql).Check(testkit.Rows(rs)) + + // Test partition table. + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (a int primary key clustered, b int, key bk (b)) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (1), PARTITION p1 VALUES LESS THAN (2));") + dom = domain.GetDomain(tk.Session()) + is = dom.InfoSchema() + tbl, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + require.NotNil(t, tbl.Meta().Partition) + hexKey = buildTableRowKey(tbl.Meta().Partition.Definitions[0].ID, rowID) + sql = fmt.Sprintf("select tidb_decode_key( '%s' )", hexKey) + rs = fmt.Sprintf(`{"%s":%d,"partition_id":%d,"table_id":"%d"}`, tbl.Meta().GetPkName().String(), rowID, tbl.Meta().Partition.Definitions[0].ID, tbl.Meta().ID) + tk.MustQuery(sql).Check(testkit.Rows(rs)) + + hexKey = tablecodec.EncodeTablePrefix(tbl.Meta().Partition.Definitions[0].ID).String() + sql = fmt.Sprintf("select tidb_decode_key( '%s' )", hexKey) + rs = fmt.Sprintf(`{"partition_id":%d,"table_id":%d}`, tbl.Meta().Partition.Definitions[0].ID, tbl.Meta().ID) + tk.MustQuery(sql).Check(testkit.Rows(rs)) + + data = []types.Datum{types.NewIntDatum(100)} + hexKey = buildIndexKeyFromData(tbl.Meta().Partition.Definitions[0].ID, tbl.Indices()[0].Meta().ID, data) + sql = fmt.Sprintf("select tidb_decode_key( '%s' )", hexKey) + rs = fmt.Sprintf(`{"index_id":1,"index_vals":{"b":"100"},"partition_id":%d,"table_id":%d}`, tbl.Meta().Partition.Definitions[0].ID, tbl.Meta().ID) + tk.MustQuery(sql).Check(testkit.Rows(rs)) } func TestTwoDecimalTruncate(t *testing.T) { @@ -3718,8 +3790,6 @@ func TestExprPushdownBlacklist(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) - tk.MustQuery(`select * from mysql.expr_pushdown_blacklist`).Check(testkit.Rows( - "date_add tiflash DST(daylight saving time) does not take effect in TiFlash date_add")) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -3791,7 +3861,7 @@ func TestInvalidEndingStatement(t *testing.T) { errMsgLen := len(parseErrMsg) assertParseErr := func(sql string) { - _, err := tk.Exec(sql) + err := tk.ExecToErr(sql) require.Error(t, err) require.Equal(t, err.Error()[:errMsgLen], parseErrMsg) } @@ -4110,23 +4180,17 @@ func TestNotExistFunc(t *testing.T) { tk := testkit.NewTestKit(t, store) // current db is empty - _, err := tk.Exec("SELECT xxx(1)") - require.Error(t, err, "[planner:1046]No database selected") + tk.MustGetErrMsg("SELECT xxx(1)", "[planner:1046]No database selected") - _, err = tk.Exec("SELECT yyy()") - require.Error(t, err, "[planner:1046]No database selected") + tk.MustGetErrMsg("SELECT yyy()", "[planner:1046]No database selected") // current db is not empty tk.MustExec("use test") - _, err = tk.Exec("SELECT xxx(1)") - require.Error(t, err, "[expression:1305]FUNCTION test.xxx does not exist") - - _, err = tk.Exec("SELECT yyy()") - require.Error(t, err, "[expression:1305]FUNCTION test.yyy does not exist") + tk.MustGetErrMsg("SELECT xxx(1)", "[expression:1305]FUNCTION test.xxx does not exist") + tk.MustGetErrMsg("SELECT yyy()", "[expression:1305]FUNCTION test.yyy does not exist") tk.MustExec("use test") - _, err = tk.Exec("SELECT timestampliteral(rand())") - require.Error(t, err, "[expression:1305]FUNCTION test.timestampliteral does not exist") + tk.MustGetErrMsg("SELECT timestampliteral(rand())", "[expression:1305]FUNCTION test.timestampliteral does not exist") } func TestDecodetoChunkReuse(t *testing.T) { @@ -4925,24 +4989,6 @@ func TestIssue18525(t *testing.T) { tk.MustQuery("select INTERVAL( ( CONVERT( -11752 USING utf8 ) ), 6558853612195285496, `col1`) from t1").Check(testkit.Rows("0", "0", "0")) } -func TestSchemaDMLNotChange(t *testing.T) { - store := testkit.CreateMockStore(t) - - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk2.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (id int primary key, c_json json);") - tk.MustExec("insert into t values (1, '{\"k\": 1}');") - tk.MustExec("begin") - tk.MustExec("update t set c_json = '{\"k\": 2}' where id = 1;") - tk2.MustExec("alter table t rename column c_json to cc_json;") - tk.MustExec("commit") -} - func TestIssue18850(t *testing.T) { store := testkit.CreateMockStore(t) @@ -5908,8 +5954,7 @@ func TestSecurityEnhancedMode(t *testing.T) { // When SEM is enabled these features are restricted to all users // regardless of what privileges they have available. - _, err := tk.Exec("SELECT 1 INTO OUTFILE '/tmp/aaaa'") - require.Error(t, err, "[planner:8132]Feature 'SELECT INTO' is not supported when security enhanced mode is enabled") + tk.MustGetErrMsg("SELECT 1 INTO OUTFILE '/tmp/aaaa'", "[planner:8132]Feature 'SELECT INTO' is not supported when security enhanced mode is enabled") } func TestIssue23925(t *testing.T) { @@ -7102,29 +7147,25 @@ func TestIssue29708(t *testing.T) { tk.MustExec("use test;") tk.MustExec("drop table if exists t1;") tk.MustExec("CREATE TABLE t1 (a text)character set utf8 ;") - _, err := tk.Exec("INSERT INTO t1 VALUES (REPEAT(0125,200000000));") - require.NotNil(t, err) + tk.MustExecToErr("INSERT INTO t1 VALUES (REPEAT(0125,200000000));") tk.MustQuery("select * from t1").Check(nil) // test vectorized build-in function tk.MustExec("insert into t1 (a) values ('a'),('b');") - _, err = tk.Exec("insert into t1 select REPEAT(a,200000000) from t1;") - require.NotNil(t, err) + tk.MustExecToErr("insert into t1 select REPEAT(a,200000000) from t1;") tk.MustQuery("select a from t1 order by a;").Check([][]interface{}{ {"a"}, {"b"}, }) // test cast - _, err = tk.Exec(`insert into t1 values (cast("a" as binary(4294967295)));`) - require.NotNil(t, err) + tk.MustExecToErr(`insert into t1 values (cast("a" as binary(4294967295)));`) tk.MustQuery("select a from t1 order by a;").Check([][]interface{}{ {"a"}, {"b"}, }) - _, err = tk.Exec("INSERT IGNORE INTO t1 VALUES (REPEAT(0125,200000000));") - require.NoError(t, err) + tk.MustExec("INSERT IGNORE INTO t1 VALUES (REPEAT(0125,200000000));") tk.MustQuery("show warnings;").Check(testkit.Rows("Warning 1301 Result of repeat() was larger than max_allowed_packet (67108864) - truncated")) tk.MustQuery("select a from t1 order by a;").Check([][]interface{}{ {nil}, @@ -7390,6 +7431,29 @@ func TestIssue31569(t *testing.T) { tk.MustExec("drop table t") } +func TestTimestampAddWithFractionalSecond(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a date)") + tk.MustExec("insert into t values ('2021-08-20');") + tk.MustQuery("select timestampadd(microsecond, 1, a) from t").Check(testkit.Rows("2021-08-20 00:00:00.000001")) + tk.MustQuery("select timestampadd(second, 6/4, a) from t").Check(testkit.Rows("2021-08-20 00:00:01.500000")) + tk.MustQuery("select timestampadd(second, 9.9999e2, a) from t").Check(testkit.Rows("2021-08-20 00:16:39.990000")) + tk.MustQuery("select timestampadd(second, 1, '2021-08-20 00:00:01.0001')").Check(testkit.Rows("2021-08-20 00:00:02.000100")) + tk.MustQuery("select timestampadd(minute, 1.5, '2021-08-20 00:00:00')").Check(testkit.Rows("2021-08-20 00:02:00")) + tk.MustQuery("select timestampadd(minute, 1.5, '2021-08-20 00:00:00.0001')").Check(testkit.Rows("2021-08-20 00:02:00.000100")) + // overflow + tk.MustQuery("SELECT timestampadd(year,1.212208e+308,'1995-01-05 06:32:20.859724') as result").Check(testkit.Rows("")) + warnings := tk.Session().GetSessionVars().StmtCtx.GetWarnings() + require.Len(t, warnings, 1) + for _, warning := range warnings { + require.EqualError(t, warning.Err, "[types:1441]Datetime function: datetime field overflow") + } +} + func TestDateAddForNonExistingTimestamp(t *testing.T) { store := testkit.CreateMockStore(t) @@ -7755,3 +7819,77 @@ func TestFix38127(t *testing.T) { tk.MustQuery("select from_unixtime(dou, '%Y-%m-%d') from t").Check(testkit.Rows("")) tk.MustQuery("select from_unixtime(varc, '%Y-%m-%d') from t").Check(testkit.Rows("")) } + +func TestJSONStorageFree(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustQuery("select json_storage_free(NULL)").Check(testkit.Rows("")) + tk.MustQuery("select json_storage_free('{}')").Check(testkit.Rows("0")) + tk.MustQuery("select json_storage_free('1')").Check(testkit.Rows("0")) + tk.MustQuery(`select json_storage_free('{"a": "b"}')`).Check(testkit.Rows("0")) + err := tk.ExecToErr(`select json_storage_free('{"c":["a","b"]`) + require.Error(t, err, "[json:3140]Invalid JSON text: The document root must not be followed by other values.") +} + +func TestIssue38736(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("CREATE TABLE t0(c0 BOOL, c1 INT);") + tk.MustExec("CREATE TABLE t1 LIKE t0;") + tk.MustExec("CREATE definer='root'@'localhost' VIEW v0(c0) AS SELECT IS_IPV4(t0.c1) FROM t0, t1;") + tk.MustExec("INSERT INTO t0(c0, c1) VALUES (true, 0);") + tk.MustExec("INSERT INTO t1(c0, c1) VALUES (true, 2);") + + // The filter is evaled as false. + tk.MustQuery("SELECT v0.c0 FROM v0 WHERE (v0.c0)NOT LIKE(BINARY v0.c0);").Check(testkit.Rows()) + + // Also the filter is evaled as false. + tk.MustQuery("SELECT v0.c0 FROM v0 WHERE (v0.c0)NOT LIKE(BINARY v0.c0) or v0.c0 > 0").Check(testkit.Rows()) +} + +func TestJSONExtractFromLast(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0] . a[last]')`).Check(testkit.Rows("4")) + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0] . a [last - 1]')`).Check(testkit.Rows("3")) + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0].a [last - 100]')`).Check(testkit.Rows("")) +} + +func TestJSONExtractRange(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[1 to last]')`).Check(testkit.Rows("[2, 3, 4]")) + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[1 to last - 1]')`).Check(testkit.Rows("[2, 3]")) + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[1 to last - 100]')`).Check(testkit.Rows("")) + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[1 to 100]')`).Check(testkit.Rows("[2, 3, 4]")) + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[0 to last]')`).Check(testkit.Rows("[1, 2, 3, 4]")) + tk.MustQuery(`select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[0 to 2]')`).Check(testkit.Rows("[1, 2, 3]")) +} + +func TestIfNullParamMarker(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (c1 varchar(100), c2 varchar(128));") + tk.MustExec(`prepare pr1 from "insert into t values(ifnull(?,' '),ifnull(?,' '))";`) + tk.MustExec(`set @a='1',@b=repeat('x', 80);`) + // Should not report 'Data too long for column' error. + tk.MustExec(`execute pr1 using @a,@b;`) +} + +func TestIssue39146(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("CREATE TABLE `sun` ( `dest` varchar(10) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;") + tk.MustExec("insert into sun values('20231020');") + tk.MustExec("set @@sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';") + tk.MustExec("set @@tidb_enable_vectorized_expression = on;") + tk.MustQuery(`select str_to_date(substr(dest,1,6),'%H%i%s') from sun;`).Check(testkit.Rows("20:23:10")) + tk.MustExec("set @@tidb_enable_vectorized_expression = off;") + tk.MustQuery(`select str_to_date(substr(dest,1,6),'%H%i%s') from sun;`).Check(testkit.Rows("20:23:10")) +} diff --git a/expression/main_test.go b/expression/main_test.go index 55af0163dc0fd..1875fcaf9869d 100644 --- a/expression/main_test.go +++ b/expression/main_test.go @@ -53,7 +53,9 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } callback := func(i int) int { diff --git a/expression/multi_valued_index_test.go b/expression/multi_valued_index_test.go new file mode 100644 index 0000000000000..1172d06f78986 --- /dev/null +++ b/expression/multi_valued_index_test.go @@ -0,0 +1,504 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expression_test + +import ( + "context" + "fmt" + "testing" + + "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/sessiontxn" + "github.com/pingcap/tidb/table" + "github.com/pingcap/tidb/tablecodec" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/codec" + "github.com/stretchr/testify/require" +) + +func TestMultiValuedIndexDDL(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("USE test;") + + tk.MustExec("create table t(a json);") + tk.MustGetErrCode("select cast(a as signed array) from t", errno.ErrNotSupportedYet) + tk.MustGetErrCode("select json_extract(cast(a as signed array), '$[0]') from t", errno.ErrNotSupportedYet) + tk.MustGetErrCode("select * from t where cast(a as signed array)", errno.ErrNotSupportedYet) + tk.MustGetErrCode("select cast('[1,2,3]' as unsigned array);", errno.ErrNotSupportedYet) + + tk.MustExec("drop table t") + tk.MustGetErrCode("CREATE TABLE t(x INT, KEY k ((1 AND CAST(JSON_ARRAY(x) AS UNSIGNED ARRAY))));", errno.ErrNotSupportedYet) + tk.MustGetErrCode("CREATE TABLE t1 (f1 json, key mvi((cast(cast(f1 as unsigned array) as unsigned array))));", errno.ErrNotSupportedYet) + tk.MustGetErrCode("CREATE TABLE t1 (f1 json, key mvi((cast(f1->>'$[*]' as unsigned array))));", errno.ErrInvalidTypeForJSON) + tk.MustGetErrCode("CREATE TABLE t1 (f1 json, key mvi((cast(f1->'$[*]' as year array))));", errno.ErrNotSupportedYet) + tk.MustGetErrCode("CREATE TABLE t1 (f1 json, key mvi((cast(f1->'$[*]' as json array))));", errno.ErrNotSupportedYet) + tk.MustGetErrCode("CREATE TABLE t1 (f1 json, key mvi((cast(f1->'$[*]' as char(10) charset gbk array))));", errno.ErrNotSupportedYet) + tk.MustGetErrCode("create table t(j json, gc json as ((concat(cast(j->'$[*]' as unsigned array),\"x\"))));", errno.ErrNotSupportedYet) + tk.MustGetErrCode("create table t(j json, gc json as (cast(j->'$[*]' as unsigned array)));", errno.ErrNotSupportedYet) + tk.MustGetErrCode(`create table t1(j json, key i1((cast(j->"$" as char array))));`, errno.ErrNotSupportedYet) + tk.MustGetErrCode(`create table t1(j json, key i1((cast(j->"$" as binary array))));`, errno.ErrNotSupportedYet) + tk.MustGetErrCode(`create table t1(j json, key i1((cast(j->"$" as float array))));`, errno.ErrNotSupportedYet) + tk.MustGetErrCode(`create table t1(j json, key i1((cast(j->"$" as double array))));`, errno.ErrNotSupportedYet) + tk.MustGetErrCode(`create table t1(j json, key i1((cast(j->"$" as decimal(4,2) array))));`, errno.ErrNotSupportedYet) + tk.MustGetErrCode("create view v as select cast('[1,2,3]' as unsigned array);", errno.ErrNotSupportedYet) + tk.MustExec("create table t(a json, index idx((cast(a as signed array))));") + tk.MustExec("drop table t;") + tk.MustExec("create table t(a json, index idx(((cast(a as signed array)))))") + + tk.MustExec("drop table t") + tk.MustGetErrCode("create table t(a json, b int, index idx(b, (cast(a as signed array)), (cast(a as signed array))));", errno.ErrNotSupportedYet) + tk.MustExec("create table t(a json, b int);") + tk.MustGetErrCode("create index idx on t (b, (cast(a as signed array)), (cast(a as signed array)))", errno.ErrNotSupportedYet) + tk.MustGetErrCode("alter table t add index idx(b, (cast(a as signed array)), (cast(a as signed array)))", errno.ErrNotSupportedYet) + tk.MustExec("create index idx1 on t (b, (cast(a as signed array)))") + tk.MustExec("alter table t add index idx2(b, (cast(a as signed array)))") + + tk.MustExec("drop table t") + tk.MustExec("create table t(a json, b int, index idx3(b, (cast(a as signed array))));") + tk.MustExec("drop table t") + tk.MustExec("set names gbk") + tk.MustExec("create table t(a json, b int, index idx3(b, (cast(a as char(10) array))));") +} + +func TestMultiValuedIndexDML(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("USE test;") + + mode := []string{`''`, `default`} + + for _, m := range mode { + tk.MustExec(fmt.Sprintf("set @@sql_mode=%s", m)) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as unsigned array))));`) + tk.MustExec(`insert into t values ('[1,2,3]');`) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrDataOutOfRangeFunctionalIndex) + tk.MustGetErrCode(`insert into t values ('["1"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["a"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as signed array))));`) + tk.MustExec(`insert into t values ('[1,2,3]');`) + tk.MustExec(`insert into t values ('[-1]');`) + tk.MustGetErrCode(`insert into t values ('["1"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["a"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as char(1) array))));`) + tk.MustGetErrCode(`insert into t values ('[1,2,3]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustExec(`insert into t values ('["1"]');`) + tk.MustExec(`insert into t values ('["a"]');`) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrFunctionalIndexDataIsTooLong) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as char(2) array))));`) + tk.MustGetErrCode(`insert into t values ('[1,2,3]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustExec(`insert into t values ('["1"]');`) + tk.MustExec(`insert into t values ('["a"]');`) + tk.MustExec(`insert into t values ('["汉字"]');`) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as binary(1) array))));`) + tk.MustGetErrCode(`insert into t values ('[1,2,3]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustExec(`insert into t values ('["1"]');`) + tk.MustExec(`insert into t values ('["a"]');`) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrFunctionalIndexDataIsTooLong) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as binary(2) array))));`) + tk.MustGetErrCode(`insert into t values ('[1,2,3]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustExec(`insert into t values ('["1"]');`) + tk.MustExec(`insert into t values ('["a"]');`) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrFunctionalIndexDataIsTooLong) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as date array))));`) + tk.MustGetErrCode(`insert into t values ('[1,2,3]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["1"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["a"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustExec(`insert into t values (json_array(cast("2022-02-02" as date)));`) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as time array))));`) + tk.MustGetErrCode(`insert into t values ('[1,2,3]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["1"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["a"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustExec(`insert into t values (json_array(cast("11:00:00" as time)));`) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json, index idx((cast(a as datetime array))));`) + tk.MustGetErrCode(`insert into t values ('[1,2,3]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[-1]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["1"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["a"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('["汉字"]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.2]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values ('[1.0]');`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("11:00:00" as time)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustGetErrCode(`insert into t values (json_array(cast("2022-02-02" as date)));`, errno.ErrInvalidJSONValueForFuncIndex) + tk.MustExec(`insert into t values (json_array(cast("2022-02-02 11:00:00" as datetime)));`) + tk.MustGetErrCode(`insert into t values (json_array(cast('{"a":1}' as json)));`, errno.ErrInvalidJSONValueForFuncIndex) + } +} + +func TestWriteMultiValuedIndex(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t1(pk int primary key, a json, index idx((cast(a as signed array))))") + tk.MustExec("insert into t1 values (1, '[1,2,2,3]')") + tk.MustExec("insert into t1 values (2, '[1,2,3]')") + tk.MustExec("insert into t1 values (3, '[]')") + tk.MustExec("insert into t1 values (4, '[2,3,4]')") + tk.MustExec("insert into t1 values (5, null)") + tk.MustExec("insert into t1 values (6, '1')") + + t1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 11) + checkKey(t, t1.IndexPrefix(), index, store, [][]types.Datum{ + {types.NewDatum(nil), types.NewIntDatum(5)}, + {types.NewIntDatum(1), types.NewIntDatum(1)}, + {types.NewIntDatum(1), types.NewIntDatum(2)}, + {types.NewIntDatum(1), types.NewIntDatum(6)}, + {types.NewIntDatum(2), types.NewIntDatum(1)}, + {types.NewIntDatum(2), types.NewIntDatum(2)}, + {types.NewIntDatum(2), types.NewIntDatum(4)}, + {types.NewIntDatum(3), types.NewIntDatum(1)}, + {types.NewIntDatum(3), types.NewIntDatum(2)}, + {types.NewIntDatum(3), types.NewIntDatum(4)}, + {types.NewIntDatum(4), types.NewIntDatum(4)}, + }) + } + } + tk.MustExec("delete from t1") + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 0) + } + } + + tk.MustExec("drop table t1") + tk.MustExec("create table t1(pk int primary key, a json, index idx((cast(a as char(5) array))))") + tk.MustExec("insert into t1 values (1, '[\"abc\", \"abc \"]')") + tk.MustExec("insert into t1 values (2, '[\"b\"]')") + tk.MustExec("insert into t1 values (3, '[\"b \"]')") + tk.MustQuery("select pk from t1 where 'b ' member of (a)").Check(testkit.Rows("3")) + + t1, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 4) + checkKey(t, t1.IndexPrefix(), index, store, [][]types.Datum{ + {types.NewBytesDatum([]byte("abc")), types.NewIntDatum(1)}, + {types.NewBytesDatum([]byte("abc ")), types.NewIntDatum(1)}, + {types.NewBytesDatum([]byte("b")), types.NewIntDatum(2)}, + {types.NewBytesDatum([]byte("b ")), types.NewIntDatum(3)}, + }) + } + } + + tk.MustExec("update t1 set a = json_array_append(a, '$', 'bcd') where pk = 1") + tk.MustExec("update t1 set a = '[]' where pk = 2") + tk.MustExec("update t1 set a = '[\"abc\"]' where pk = 3") + + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 4) + checkKey(t, t1.IndexPrefix(), index, store, [][]types.Datum{ + {types.NewBytesDatum([]byte("abc")), types.NewIntDatum(1)}, + {types.NewBytesDatum([]byte("abc")), types.NewIntDatum(3)}, + {types.NewBytesDatum([]byte("abc ")), types.NewIntDatum(1)}, + {types.NewBytesDatum([]byte("bcd")), types.NewIntDatum(1)}, + }) + } + } + + tk.MustExec("delete from t1") + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 0) + } + } + + tk.MustExec("drop table t1") + tk.MustExec("create table t1(pk int primary key, a json, index idx((cast(a as unsigned array))))") + tk.MustExec("insert into t1 values (1, '[1,2,2,3]')") + tk.MustExec("insert into t1 values (2, '[1,2,3]')") + tk.MustExec("insert into t1 values (3, '[]')") + tk.MustExec("insert into t1 values (4, '[2,3,4]')") + tk.MustExec("insert into t1 values (5, null)") + tk.MustExec("insert into t1 values (6, '1')") + + t1, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 11) + checkKey(t, t1.IndexPrefix(), index, store, [][]types.Datum{ + {types.NewDatum(nil), types.NewIntDatum(5)}, + {types.NewUintDatum(1), types.NewIntDatum(1)}, + {types.NewUintDatum(1), types.NewIntDatum(2)}, + {types.NewUintDatum(1), types.NewIntDatum(6)}, + {types.NewUintDatum(2), types.NewIntDatum(1)}, + {types.NewUintDatum(2), types.NewIntDatum(2)}, + {types.NewUintDatum(2), types.NewIntDatum(4)}, + {types.NewUintDatum(3), types.NewIntDatum(1)}, + {types.NewUintDatum(3), types.NewIntDatum(2)}, + {types.NewUintDatum(3), types.NewIntDatum(4)}, + {types.NewUintDatum(4), types.NewIntDatum(4)}, + }) + } + } + tk.MustExec("delete from t1") + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 0) + } + } +} + +func TestWriteMultiValuedIndexPartitionTable(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t1 +( + pk int primary key, + a json, + index idx ((cast(a as signed array))) +) partition by range columns (pk) (partition p0 values less than (10), partition p1 values less than (20));`) + tk.MustExec("insert into t1 values (1, '[1,2,2,3]')") + tk.MustExec("insert into t1 values (11, '[1,2,3]')") + tk.MustExec("insert into t1 values (2, '[]')") + tk.MustExec("insert into t1 values (12, '[2,3,4]')") + tk.MustExec("insert into t1 values (3, null)") + tk.MustExec("insert into t1 values (13, null)") + + t1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + + expect := map[string]struct { + count int + vals [][]types.Datum + }{ + "p0": {4, [][]types.Datum{ + {types.NewDatum(nil), types.NewIntDatum(3)}, + {types.NewIntDatum(1), types.NewIntDatum(1)}, + {types.NewIntDatum(2), types.NewIntDatum(1)}, + {types.NewIntDatum(3), types.NewIntDatum(1)}, + }}, + "p1": {7, [][]types.Datum{ + {types.NewDatum(nil), types.NewIntDatum(13)}, + {types.NewIntDatum(1), types.NewIntDatum(11)}, + {types.NewIntDatum(2), types.NewIntDatum(11)}, + {types.NewIntDatum(2), types.NewIntDatum(12)}, + {types.NewIntDatum(3), types.NewIntDatum(11)}, + {types.NewIntDatum(3), types.NewIntDatum(12)}, + {types.NewIntDatum(4), types.NewIntDatum(12)}, + }}, + } + + for _, def := range t1.Meta().GetPartitionInfo().Definitions { + partition := t1.(table.PartitionedTable).GetPartition(def.ID) + for _, index := range partition.Indices() { + if index.Meta().MVIndex { + checkCount(t, partition.IndexPrefix(), index, store, expect[def.Name.L].count) + checkKey(t, partition.IndexPrefix(), index, store, expect[def.Name.L].vals) + } + } + } + + tk.MustExec("delete from t1") + for _, def := range t1.Meta().GetPartitionInfo().Definitions { + partition := t1.(table.PartitionedTable).GetPartition(def.ID) + for _, index := range partition.Indices() { + if index.Meta().MVIndex { + checkCount(t, partition.IndexPrefix(), index, store, 0) + } + } + } +} + +func TestWriteMultiValuedIndexUnique(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t1(pk int primary key, a json, unique index idx((cast(a as signed array))))") + tk.MustExec("insert into t1 values (1, '[1,2,2]')") + tk.MustGetErrCode("insert into t1 values (2, '[1]')", errno.ErrDupEntry) + tk.MustExec("insert into t1 values (3, '[3,3,4]')") + + t1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 4) + checkKey(t, t1.IndexPrefix(), index, store, [][]types.Datum{ + {types.NewIntDatum(1)}, + {types.NewIntDatum(2)}, + {types.NewIntDatum(3)}, + {types.NewIntDatum(4)}, + }) + } + } +} + +func TestWriteMultiValuedIndexComposite(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t1(pk int primary key, a json, c int, d int, index idx(c, (cast(a as signed array)), d))") + tk.MustExec("insert into t1 values (1, '[1,2,2]', 1, 1)") + tk.MustExec("insert into t1 values (2, '[2,2,2]', 2, 2)") + tk.MustExec("insert into t1 values (3, '[3,3,4]', 3, 3)") + tk.MustExec("insert into t1 values (4, null, 4, 4)") + tk.MustExec("insert into t1 values (5, '[]', 5, 5)") + + t1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + for _, index := range t1.Indices() { + if index.Meta().MVIndex { + checkCount(t, t1.IndexPrefix(), index, store, 6) + checkKey(t, t1.IndexPrefix(), index, store, [][]types.Datum{ + {types.NewIntDatum(1), types.NewIntDatum(1), types.NewIntDatum(1), types.NewIntDatum(1)}, + {types.NewIntDatum(1), types.NewIntDatum(2), types.NewIntDatum(1), types.NewIntDatum(1)}, + {types.NewIntDatum(2), types.NewIntDatum(2), types.NewIntDatum(2), types.NewIntDatum(2)}, + {types.NewIntDatum(3), types.NewIntDatum(3), types.NewIntDatum(3), types.NewIntDatum(3)}, + {types.NewIntDatum(3), types.NewIntDatum(4), types.NewIntDatum(3), types.NewIntDatum(3)}, + {types.NewIntDatum(4), types.NewDatum(nil), types.NewIntDatum(4), types.NewIntDatum(4)}, + }) + } + } +} + +func checkCount(t *testing.T, prefix kv.Key, index table.Index, store kv.Storage, except int) { + c := 0 + checkIndex(t, prefix, index, store, func(it kv.Iterator) { + c++ + }) + require.Equal(t, except, c) +} + +func checkKey(t *testing.T, prefix kv.Key, index table.Index, store kv.Storage, except [][]types.Datum) { + idx := 0 + checkIndex(t, prefix, index, store, func(it kv.Iterator) { + indexKey := decodeIndexKey(t, it.Key()) + require.Equal(t, except[idx], indexKey) + idx++ + }) +} + +func checkIndex(t *testing.T, prefix kv.Key, index table.Index, store kv.Storage, fn func(kv.Iterator)) { + startKey := codec.EncodeInt(prefix, index.Meta().ID) + prefix.Next() + se := testkit.NewTestKit(t, store).Session() + err := sessiontxn.NewTxn(context.Background(), se) + require.NoError(t, err) + txn, err := se.Txn(true) + require.NoError(t, err) + it, err := txn.Iter(startKey, prefix.PrefixNext()) + require.NoError(t, err) + for it.Valid() && it.Key().HasPrefix(prefix) { + fn(it) + err = it.Next() + require.NoError(t, err) + } + it.Close() + se.Close() +} + +func decodeIndexKey(t *testing.T, key kv.Key) []types.Datum { + var idLen = 8 + var prefixLen = 1 + idLen /*tableID*/ + 2 + _, _, isRecord, err := tablecodec.DecodeKeyHead(key) + require.NoError(t, err) + require.False(t, isRecord) + indexKey := key[prefixLen+idLen:] + var datumValues []types.Datum + for len(indexKey) > 0 { + remain, d, err := codec.DecodeOne(indexKey) + require.NoError(t, err) + datumValues = append(datumValues, d) + indexKey = remain + } + return datumValues +} diff --git a/expression/scalar_function.go b/expression/scalar_function.go index 2483d342b662b..131e018fba550 100644 --- a/expression/scalar_function.go +++ b/expression/scalar_function.go @@ -193,6 +193,13 @@ func newFunctionImpl(ctx sessionctx.Context, fold int, funcName string, retType } } fc, ok := funcs[funcName] + if !ok { + if extFunc, exist := extensionFuncs.Load(funcName); exist { + fc = extFunc.(functionClass) + ok = true + } + } + if !ok { db := ctx.GetSessionVars().CurrentDB if db == "" { @@ -618,7 +625,12 @@ func (sf *ScalarFunction) MemoryUsage() (sum int64) { return } - sum = emptyScalarFunctionSize + int64(len(sf.FuncName.L)+len(sf.FuncName.O)) + sf.RetType.MemoryUsage() + - int64(cap(sf.hashcode)) + sf.Function.MemoryUsage() + sum = emptyScalarFunctionSize + int64(len(sf.FuncName.L)+len(sf.FuncName.O)) + int64(cap(sf.hashcode)) + if sf.RetType != nil { + sum += sf.RetType.MemoryUsage() + } + if sf.Function != nil { + sum += sf.Function.MemoryUsage() + } return sum } diff --git a/expression/simple_rewriter.go b/expression/simple_rewriter.go index 808db9f69b4cf..3343a0cbaa169 100644 --- a/expression/simple_rewriter.go +++ b/expression/simple_rewriter.go @@ -48,7 +48,7 @@ func ParseSimpleExprWithTableInfo(ctx sessionctx.Context, exprStr string, tableI return nil, errors.Trace(err) } expr := stmts[0].(*ast.SelectStmt).Fields.Fields[0].Expr - return RewriteSimpleExprWithTableInfo(ctx, tableInfo, expr) + return RewriteSimpleExprWithTableInfo(ctx, tableInfo, expr, false) } // ParseSimpleExprCastWithTableInfo parses simple expression string to Expression. @@ -63,13 +63,13 @@ func ParseSimpleExprCastWithTableInfo(ctx sessionctx.Context, exprStr string, ta } // RewriteSimpleExprWithTableInfo rewrites simple ast.ExprNode to expression.Expression. -func RewriteSimpleExprWithTableInfo(ctx sessionctx.Context, tbl *model.TableInfo, expr ast.ExprNode) (Expression, error) { +func RewriteSimpleExprWithTableInfo(ctx sessionctx.Context, tbl *model.TableInfo, expr ast.ExprNode, allowCastArray bool) (Expression, error) { dbName := model.NewCIStr(ctx.GetSessionVars().CurrentDB) columns, names, err := ColumnInfos2ColumnsAndNames(ctx, dbName, tbl.Name, tbl.Cols(), tbl) if err != nil { return nil, err } - e, err := RewriteAstExpr(ctx, expr, NewSchema(columns...), names) + e, err := RewriteAstExpr(ctx, expr, NewSchema(columns...), names, allowCastArray) if err != nil { return nil, err } @@ -111,7 +111,7 @@ func ParseSimpleExprsWithNames(ctx sessionctx.Context, exprStr string, schema *S // RewriteSimpleExprWithNames rewrites simple ast.ExprNode to expression.Expression. func RewriteSimpleExprWithNames(ctx sessionctx.Context, expr ast.ExprNode, schema *Schema, names []*types.FieldName) (Expression, error) { - e, err := RewriteAstExpr(ctx, expr, schema, names) + e, err := RewriteAstExpr(ctx, expr, schema, names, false) if err != nil { return nil, err } diff --git a/expression/testdata/expression_suite_out.json b/expression/testdata/expression_suite_out.json index 7047b62ba1156..164ccd7f50311 100644 --- a/expression/testdata/expression_suite_out.json +++ b/expression/testdata/expression_suite_out.json @@ -65,11 +65,11 @@ "Result": [ "HashJoin 4166.67 root right outer join, equal:[eq(test.t1.a, test.t2.a)]", "├─TableReader(Build) 3333.33 root data:Selection", - "│ └─Selection 3333.33 cop[tikv] gt(test.t1.a, 1), not(isnull(test.t1.a))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─Selection 3333.33 cop[tikv] gt(test.t2.a, 1)", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", "└─TableReader(Probe) 3333.33 root data:Selection", - " └─Selection 3333.33 cop[tikv] gt(test.t2.a, 1)", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─Selection 3333.33 cop[tikv] gt(test.t1.a, 1), not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ] }, { diff --git a/expression/typeinfer_test.go b/expression/typeinfer_test.go index b2554c4f3d548..28f71099e9c46 100644 --- a/expression/typeinfer_test.go +++ b/expression/typeinfer_test.go @@ -126,7 +126,7 @@ func TestInferType(t *testing.T) { require.NoError(t, err) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmt, plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmt, plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err, comment) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmt, ret.InfoSchema) require.NoError(t, err, comment) diff --git a/expression/util.go b/expression/util.go index 72f512038f162..3f4b826239a1d 100644 --- a/expression/util.go +++ b/expression/util.go @@ -58,7 +58,7 @@ func (c *cowExprRef) Set(i int, changed bool, val Expression) { return } c.new = make([]Expression, len(c.ref)) - copy(c.new, c.ref[:i]) + copy(c.new, c.ref) c.new[i] = val } @@ -382,17 +382,6 @@ func SetExprColumnInOperand(expr Expression) Expression { return expr } -// ColumnSubstitute4PPD substitutes the columns in filter to expressions in select fields. -// Only used for predicate push down to projection. Some columns can not be substituted for some reasons. -// So we should return the bool value to indicate some expressions can not be pushed down. -// e.g. CREATE TABLE t3(c0 INT, primary key(c0)); -// SELECT v2.c0 FROM (select 1 as c0 from t3) v2 WHERE (v2.c0)like(True); -// The cond `(v2.c0)like(True)` can not be substituted when the new collation enable. So we shouldn't push the cond down to the projection. -func ColumnSubstitute4PPD(expr Expression, schema *Schema, newExprs []Expression) (bool, Expression) { - substituted, _, resExpr := ColumnSubstituteImpl(expr, schema, newExprs, false) - return substituted, resExpr -} - // ColumnSubstitute substitutes the columns in filter to expressions in select fields. // e.g. select * from (select b as a from t) k where a < 10 => select * from (select b as a from t where b < 10) k. func ColumnSubstitute(expr Expression, schema *Schema, newExprs []Expression) Expression { @@ -432,41 +421,45 @@ func ColumnSubstituteImpl(expr Expression, schema *Schema, newExprs []Expression substituted := false hasFail := false if v.FuncName.L == ast.Cast { - newFunc := v.Clone().(*ScalarFunction) - substituted, hasFail, newFunc.GetArgs()[0] = ColumnSubstituteImpl(newFunc.GetArgs()[0], schema, newExprs, fail1Return) + var newArg Expression + substituted, hasFail, newArg = ColumnSubstituteImpl(v.GetArgs()[0], schema, newExprs, fail1Return) if fail1Return && hasFail { - return substituted, hasFail, newFunc + return substituted, hasFail, v } if substituted { - // Workaround for issue https://github.com/pingcap/tidb/issues/28804 - e := NewFunctionInternal(v.GetCtx(), v.FuncName.L, v.RetType, newFunc.GetArgs()...) + flag := v.RetType.GetFlag() + e := BuildCastFunction(v.GetCtx(), newArg, v.RetType) e.SetCoercibility(v.Coercibility()) + e.GetType().SetFlag(flag) return true, false, e } - return false, false, newFunc + return false, false, v } // cowExprRef is a copy-on-write util, args array allocation happens only // when expr in args is changed refExprArr := cowExprRef{v.GetArgs(), nil} _, coll := DeriveCollationFromExprs(v.GetCtx(), v.GetArgs()...) + var tmpArgForCollCheck []Expression + if collate.NewCollationEnabled() { + tmpArgForCollCheck = make([]Expression, len(v.GetArgs())) + } for idx, arg := range v.GetArgs() { - changed, hasFail, newFuncExpr := ColumnSubstituteImpl(arg, schema, newExprs, fail1Return) - if fail1Return && hasFail { - return changed, hasFail, v + changed, failed, newFuncExpr := ColumnSubstituteImpl(arg, schema, newExprs, fail1Return) + if fail1Return && failed { + return changed, failed, v } oldChanged := changed - if collate.NewCollationEnabled() { + if collate.NewCollationEnabled() && changed { // Make sure the collation used by the ScalarFunction isn't changed and its result collation is not weaker than the collation used by the ScalarFunction. - if changed { - changed = false - tmpArgs := make([]Expression, 0, len(v.GetArgs())) - _ = append(append(append(tmpArgs, refExprArr.Result()[0:idx]...), refExprArr.Result()[idx+1:]...), newFuncExpr) - _, newColl := DeriveCollationFromExprs(v.GetCtx(), append(v.GetArgs(), newFuncExpr)...) - if coll == newColl { - changed = checkCollationStrictness(coll, newFuncExpr.GetType().GetCollate()) - } + changed = false + copy(tmpArgForCollCheck, refExprArr.Result()) + tmpArgForCollCheck[idx] = newFuncExpr + _, newColl := DeriveCollationFromExprs(v.GetCtx(), tmpArgForCollCheck...) + if coll == newColl { + changed = checkCollationStrictness(coll, newFuncExpr.GetType().GetCollate()) } } + hasFail = hasFail || failed || oldChanged != changed if fail1Return && oldChanged != changed { // Only when the oldChanged is true and changed is false, we will get here. // And this means there some dependency in this arg can be substituted with @@ -481,7 +474,7 @@ func ColumnSubstituteImpl(expr Expression, schema *Schema, newExprs []Expression } } if substituted { - return true, false, NewFunctionInternal(v.GetCtx(), v.FuncName.L, v.RetType, refExprArr.Result()...) + return true, hasFail, NewFunctionInternal(v.GetCtx(), v.FuncName.L, v.RetType, refExprArr.Result()...) } } return false, false, expr @@ -1152,6 +1145,33 @@ func IsMutableEffectsExpr(expr Expression) bool { return false } +// IsInmutableExpr checks whether this expression only consists of foldable functions and inmutable constants. +// This expression can be evaluated by using `expr.Eval(chunk.Row{})` directly if it's inmutable. +func IsInmutableExpr(expr Expression) bool { + switch x := expr.(type) { + case *ScalarFunction: + if _, ok := unFoldableFunctions[x.FuncName.L]; ok { + return false + } + if _, ok := mutableEffectsFunctions[x.FuncName.L]; ok { + return false + } + for _, arg := range x.GetArgs() { + if !IsInmutableExpr(arg) { + return false + } + } + return true + case *Constant: + if x.DeferredExpr != nil || x.ParamMarker != nil { + return false + } + return true + default: + return false + } +} + // RemoveDupExprs removes identical exprs. Not that if expr contains functions which // are mutable or have side effects, we cannot remove it even if it has duplicates; // if the plan is going to be cached, we cannot remove expressions containing `?` neither. @@ -1248,7 +1268,7 @@ func ContainCorrelatedColumn(exprs []Expression) bool { // TODO: Do more careful check here. func MaybeOverOptimized4PlanCache(ctx sessionctx.Context, exprs []Expression) bool { // If we do not enable plan cache, all the optimization can work correctly. - if !ctx.GetSessionVars().StmtCtx.UseCache || ctx.GetSessionVars().StmtCtx.SkipPlanCache { + if !ctx.GetSessionVars().StmtCtx.UseCache { return false } return containMutableConst(ctx, exprs) diff --git a/extension/BUILD.bazel b/extension/BUILD.bazel new file mode 100644 index 0000000000000..12ca672b3c86f --- /dev/null +++ b/extension/BUILD.bazel @@ -0,0 +1,60 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "extension", + srcs = [ + "extensions.go", + "function.go", + "manifest.go", + "registry.go", + "session.go", + "util.go", + ], + importpath = "github.com/pingcap/tidb/extension", + visibility = ["//visibility:public"], + deps = [ + "//parser", + "//parser/ast", + "//parser/auth", + "//parser/mysql", + "//sessionctx/stmtctx", + "//sessionctx/variable", + "//types", + "//util/chunk", + "@com_github_ngaut_pools//:pools", + "@com_github_pingcap_errors//:errors", + "@io_etcd_go_etcd_client_v3//:client", + ], +) + +go_test( + name = "extension_test", + srcs = [ + "bootstrap_test.go", + "event_listener_test.go", + "function_test.go", + "main_test.go", + "registry_test.go", + ], + embed = [":extension"], + deps = [ + "//expression", + "//parser/ast", + "//parser/auth", + "//parser/mysql", + "//privilege/privileges", + "//server", + "//sessionctx", + "//sessionctx/sessionstates", + "//sessionctx/stmtctx", + "//sessionctx/variable", + "//testkit", + "//testkit/testsetup", + "//types", + "//util/chunk", + "//util/sem", + "@com_github_pingcap_errors//:errors", + "@com_github_stretchr_testify//require", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/extension/bootstrap_test.go b/extension/bootstrap_test.go new file mode 100644 index 0000000000000..ae4a7ff03f091 --- /dev/null +++ b/extension/bootstrap_test.go @@ -0,0 +1,48 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension_test + +import ( + "testing" + + "github.com/pingcap/tidb/extension" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" +) + +func TestBootstrap(t *testing.T) { + defer func() { + extension.Reset() + }() + + extension.Reset() + require.NoError(t, extension.Register("test1", extension.WithBootstrapSQL("create table test.t1 (a int)"))) + require.NoError(t, extension.Register("test2", extension.WithBootstrap(func(ctx extension.BootstrapContext) error { + _, err := ctx.ExecuteSQL(ctx, "insert into test.t1 values(1)") + require.NoError(t, err) + + rows, err := ctx.ExecuteSQL(ctx, "select * from test.t1 where a=1") + require.NoError(t, err) + + require.Equal(t, 1, len(rows)) + require.Equal(t, int64(1), rows[0].GetInt64(0)) + return nil + }))) + require.NoError(t, extension.Setup()) + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustQuery("select * from test.t1").Check(testkit.Rows("1")) +} diff --git a/extension/event_listener_test.go b/extension/event_listener_test.go new file mode 100644 index 0000000000000..be998980b15f8 --- /dev/null +++ b/extension/event_listener_test.go @@ -0,0 +1,468 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension_test + +import ( + "context" + "encoding/binary" + "sort" + "strings" + "testing" + "time" + + "github.com/pingcap/tidb/extension" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/server" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/sessionstates" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" + "github.com/stretchr/testify/require" +) + +type stmtEventRecord struct { + tp extension.StmtEventTp + user *auth.UserIdentity + originalText string + redactText string + params []types.Datum + connInfo *variable.ConnectionInfo + err string + tables []stmtctx.TableEntry + affectedRows uint64 + stmtNode ast.StmtNode + executeStmtNode *ast.ExecuteStmt + preparedNode ast.StmtNode +} + +type sessionHandler struct { + records []stmtEventRecord +} + +func (h *sessionHandler) OnStmtEvent(tp extension.StmtEventTp, info extension.StmtEventInfo) { + tables := make([]stmtctx.TableEntry, len(info.RelatedTables())) + copy(tables, info.RelatedTables()) + + redactText, _ := info.SQLDigest() + r := stmtEventRecord{ + tp: tp, + user: info.User(), + originalText: info.OriginalText(), + redactText: redactText, + params: info.PreparedParams(), + connInfo: info.ConnectionInfo(), + tables: tables, + affectedRows: info.AffectedRows(), + stmtNode: info.StmtNode(), + executeStmtNode: info.ExecuteStmtNode(), + preparedNode: info.ExecutePreparedStmt(), + } + + if err := info.GetError(); err != nil { + r.err = err.Error() + } + + h.records = append(h.records, r) +} + +func (h *sessionHandler) Reset() { + h.records = nil +} + +func (h *sessionHandler) GetHandler() *extension.SessionHandler { + return &extension.SessionHandler{ + OnStmtEvent: h.OnStmtEvent, + } +} + +func registerHandler(t *testing.T) *sessionHandler { + h := &sessionHandler{} + err := extension.Register( + "test", + extension.WithSessionHandlerFactory(h.GetHandler), + ) + require.NoError(t, err) + return h +} + +func getPreparedID(t *testing.T, sctx sessionctx.Context) uint32 { + sessStates := &sessionstates.SessionStates{} + require.NoError(t, sctx.GetSessionVars().EncodeSessionStates(context.Background(), sessStates)) + return sessStates.PreparedStmtID +} + +type stmtEventCase struct { + sql string + binaryExecute uint32 + executeParams []paramInfo + + err string + originalText string + redactText string + affectedRows uint64 + tables []stmtctx.TableEntry + parseError bool + prepareNotFound bool + multiQueryCases []stmtEventCase +} + +func TestExtensionStmtEvents(t *testing.T) { + defer extension.Reset() + extension.Reset() + h := registerHandler(t) + require.NoError(t, extension.Setup()) + + store := testkit.CreateMockStore(t) + serv := server.CreateMockServer(t, store) + defer serv.Close() + conn := server.CreateMockConn(t, serv) + defer conn.Close() + + require.NoError(t, conn.HandleQuery(context.Background(), "SET tidb_multi_statement_mode='ON'")) + require.NoError(t, conn.HandleQuery(context.Background(), "use test")) + require.NoError(t, conn.HandleQuery(context.Background(), "create table t1(a int, b int)")) + require.NoError(t, conn.HandleQuery(context.Background(), "create table t2(id int primary key)")) + require.NoError(t, conn.HandleQuery(context.Background(), "create database test2")) + require.NoError(t, conn.HandleQuery(context.Background(), "create table test2.t1(c int, d int)")) + require.NoError(t, conn.HandleQuery(context.Background(), "set @a=1")) + require.NoError(t, conn.HandleQuery(context.Background(), "set @b=2")) + + cmd := append([]byte{mysql.ComStmtPrepare}, []byte("select ?")...) + require.NoError(t, conn.Dispatch(context.Background(), cmd)) + stmtID1 := getPreparedID(t, conn.Context()) + + cmd = append( + []byte{mysql.ComStmtPrepare}, + []byte("select a, b from t1 left join test2.t1 as t2 on t2.c = t1.a where t1.a = 3 and t1.b = ? and t2.d = ?")...) + require.NoError(t, conn.Dispatch(context.Background(), cmd)) + stmtID2 := getPreparedID(t, conn.Context()) + + require.NoError(t, conn.HandleQuery(context.Background(), "create table tnoexist(n int)")) + cmd = append([]byte{mysql.ComStmtPrepare}, []byte("select * from tnoexist where n=?")...) + require.NoError(t, conn.Dispatch(context.Background(), cmd)) + stmtID3 := getPreparedID(t, conn.Context()) + require.NoError(t, conn.HandleQuery(context.Background(), "drop table tnoexist")) + + cmd = append([]byte{mysql.ComStmtPrepare}, []byte("insert into t2 values(?)")...) + require.NoError(t, conn.Dispatch(context.Background(), cmd)) + stmtID4 := getPreparedID(t, conn.Context()) + + connID := conn.Context().Session.GetSessionVars().ConnectionID + require.NotEqual(t, uint64(0), connID) + + cases := []stmtEventCase{ + { + sql: "select 1", + redactText: "select ?", + }, + { + sql: "invalid sql", + parseError: true, + err: "[parser:1064]You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 7 near \"invalid sql\" ", + }, + { + binaryExecute: stmtID1, + executeParams: []paramInfo{ + {value: 7}, + }, + originalText: "select ?", + redactText: "select ?", + }, + { + sql: "select a, b from t1 where a > 1 and b < 2", + redactText: "select `a` , `b` from `t1` where `a` > ? and `b` < ?", + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t1"}, + }, + }, + { + sql: "insert into t2 values(1)", + redactText: "insert into `t2` values ( ? )", + affectedRows: 1, + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t2"}, + }, + }, + { + binaryExecute: stmtID2, + executeParams: []paramInfo{ + {value: 3}, + {value: 4}, + }, + originalText: "select a, b from t1 left join test2.t1 as t2 on t2.c = t1.a where t1.a = 3 and t1.b = ? and t2.d = ?", + redactText: "select `a` , `b` from `t1` left join `test2` . `t1` as `t2` on `t2` . `c` = `t1` . `a` where `t1` . `a` = ? and `t1` . `b` = ? and `t2` . `d` = ?", + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t1"}, + {DB: "test2", Table: "t1"}, + }, + }, + { + binaryExecute: stmtID3, + executeParams: []paramInfo{ + {value: 5}, + }, + originalText: "select * from tnoexist where n=?", + redactText: "select * from `tnoexist` where `n` = ?", + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "tnoexist"}, + }, + err: "select * from tnoexist where n=? [arguments: 5]: [planner:8113]Schema change caused error: [schema:1146]Table 'test.tnoexist' doesn't exist", + }, + { + binaryExecute: stmtID4, + executeParams: []paramInfo{ + {value: 3}, + }, + originalText: "insert into t2 values(?)", + redactText: "insert into `t2` values ( ? )", + affectedRows: 1, + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t2"}, + }, + }, + { + sql: "prepare s from 'select * from t1 where a=1 and b>? and b? and b ? and `b` < ?", + executeParams: []paramInfo{ + {value: 1}, + {value: 2}, + }, + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t1"}, + }, + }, + { + sql: "execute sn using @a, @b", + redactText: "execute `sn` using @a , @b", + executeParams: []paramInfo{ + {value: 1}, + {value: 2}, + }, + prepareNotFound: true, + err: "[planner:8111]Prepared statement not found", + }, + { + sql: "insert into t1 values(1, 10), (2, 20)", + redactText: "insert into `t1` values ( ... ) , ( ... )", + affectedRows: 2, + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t1"}, + }, + }, + { + sql: "insert into t2 values(1)", + redactText: "insert into `t2` values ( ? )", + affectedRows: 0, + err: "[kv:1062]Duplicate entry '1' for key 't2.PRIMARY'", + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t2"}, + }, + }, + { + sql: "select 1;select * from t1 where a > 1", + multiQueryCases: []stmtEventCase{ + { + originalText: "select 1;", + redactText: "select ? ;", + }, + { + originalText: "select * from t1 where a > 1", + redactText: "select * from `t1` where `a` > ?", + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t1"}, + }, + }, + }, + }, + { + binaryExecute: stmtID4, + executeParams: []paramInfo{ + {value: 3}, + }, + err: "insert into t2 values(?) [arguments: 3]: [kv:1062]Duplicate entry '3' for key 't2.PRIMARY'", + originalText: "insert into t2 values(?)", + redactText: "insert into `t2` values ( ? )", + affectedRows: 0, + tables: []stmtctx.TableEntry{ + {DB: "test", Table: "t2"}, + }, + }, + { + sql: "create database db1", + redactText: "create database `db1`", + tables: []stmtctx.TableEntry{ + {DB: "db1", Table: ""}, + }, + }, + { + sql: "kill query 1", + redactText: "kill query ?", + }, + { + sql: "create placement policy p1 followers=1", + redactText: "create placement policy `p1` followers = ?", + }, + } + + for i, c := range cases { + h.Reset() + conn.Context().SetProcessInfo("", time.Now(), mysql.ComSleep, 0) + + var err error + switch { + case c.sql != "": + err = conn.HandleQuery(context.Background(), c.sql) + if c.originalText == "" { + c.originalText = c.sql + } + if c.redactText == "" { + c.redactText = c.sql + } + case c.binaryExecute != 0: + err = conn.Dispatch(context.Background(), getExecuteBytes(c.binaryExecute, false, true, c.executeParams...)) + } + + if c.err != "" { + require.EqualError(t, err, c.err) + } else { + require.NoError(t, err) + } + + subCases := c.multiQueryCases + if subCases == nil { + subCases = []stmtEventCase{c} + } + + require.Equal(t, len(subCases), len(h.records), "%d", i) + for j, subCase := range subCases { + record := h.records[j] + if subCase.err != "" { + require.Equal(t, subCase.err, record.err) + require.Equal(t, extension.StmtError, record.tp) + } else { + require.Empty(t, record.err) + require.Equal(t, extension.StmtSuccess, record.tp) + } + + require.NotNil(t, record.connInfo) + if subCase.parseError { + require.Nil(t, record.stmtNode) + require.Nil(t, record.executeStmtNode) + require.Nil(t, record.preparedNode) + } else { + require.NotNil(t, record.stmtNode) + if subCase.binaryExecute != 0 || strings.HasPrefix(strings.ToLower(subCase.sql), "execute ") { + require.NotNil(t, record.executeStmtNode) + require.Equal(t, record.stmtNode, record.executeStmtNode) + if c.prepareNotFound { + require.Nil(t, record.preparedNode) + } else { + require.NotNil(t, record.preparedNode) + require.NotEqual(t, record.preparedNode, record.executeStmtNode) + } + } else { + require.Nil(t, record.executeStmtNode) + require.Nil(t, record.preparedNode) + } + } + + require.Equal(t, connID, record.connInfo.ConnectionID) + require.Equal(t, "root", record.user.Username) + require.Equal(t, "localhost", record.user.Hostname) + require.Equal(t, "root", record.user.AuthUsername) + require.Equal(t, "%", record.user.AuthHostname) + + require.Equal(t, subCase.originalText, record.originalText) + require.Equal(t, subCase.redactText, record.redactText) + require.Equal(t, subCase.affectedRows, record.affectedRows) + if subCase.tables == nil { + subCase.tables = []stmtctx.TableEntry{} + } + sort.Slice(subCase.tables, func(i, j int) bool { + l := subCase.tables[i] + r := subCase.tables[j] + return l.DB < r.DB || (l.DB == r.DB && l.Table < r.Table) + }) + sort.Slice(record.tables, func(i, j int) bool { + l := subCase.tables[i] + r := subCase.tables[j] + return l.DB < r.DB || (l.DB == r.DB && l.Table < r.Table) + }) + require.Equal(t, subCase.tables, record.tables) + + require.Equal(t, len(subCase.executeParams), len(record.params)) + for k, param := range subCase.executeParams { + require.Equal(t, uint64(param.value), record.params[k].GetUint64()) + } + } + } +} + +type paramInfo struct { + value uint32 + isNull bool +} + +// create bytes for COM_STMT_EXECUTE. It only supports int type for convenience. +func getExecuteBytes(stmtID uint32, useCursor bool, newParam bool, params ...paramInfo) []byte { + nullBitmapLen := (len(params) + 7) >> 3 + buf := make([]byte, 11+nullBitmapLen+len(params)*6) + pos := 0 + buf[pos] = mysql.ComStmtExecute + pos++ + binary.LittleEndian.PutUint32(buf[pos:], stmtID) + pos += 4 + if useCursor { + buf[pos] = 1 + } + pos++ + binary.LittleEndian.PutUint32(buf[pos:], 1) + pos += 4 + for i, param := range params { + if param.isNull { + buf[pos+(i>>3)] |= 1 << (i % 8) + } + } + pos += nullBitmapLen + if newParam { + buf[pos] = 1 + pos++ + for i := 0; i < len(params); i++ { + buf[pos] = mysql.TypeLong + pos++ + buf[pos] = 0 + pos++ + } + } else { + buf[pos] = 0 + pos++ + } + for _, param := range params { + if !param.isNull { + binary.LittleEndian.PutUint32(buf[pos:], param.value) + pos += 4 + } + } + return buf[:pos] +} diff --git a/extension/extensionimpl/BUILD.bazel b/extension/extensionimpl/BUILD.bazel new file mode 100644 index 0000000000000..8c062a16ae7c9 --- /dev/null +++ b/extension/extensionimpl/BUILD.bazel @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "extensionimpl", + srcs = ["bootstrap.go"], + importpath = "github.com/pingcap/tidb/extension/extensionimpl", + visibility = ["//visibility:public"], + deps = [ + "//domain", + "//extension", + "//kv", + "//util/chunk", + "//util/sqlexec", + "@com_github_pingcap_errors//:errors", + "@io_etcd_go_etcd_client_v3//:client", + ], +) diff --git a/extension/extensionimpl/bootstrap.go b/extension/extensionimpl/bootstrap.go new file mode 100644 index 0000000000000..8b6b154f988ab --- /dev/null +++ b/extension/extensionimpl/bootstrap.go @@ -0,0 +1,95 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extensionimpl + +import ( + "context" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/extension" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/sqlexec" + clientv3 "go.etcd.io/etcd/client/v3" +) + +type bootstrapContext struct { + context.Context + + sqlExecutor sqlexec.SQLExecutor + etcdCli *clientv3.Client + sessionPool extension.SessionPool +} + +func (c *bootstrapContext) ExecuteSQL(ctx context.Context, sql string) (rows []chunk.Row, err error) { + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnBootstrap) + rs, err := c.sqlExecutor.ExecuteInternal(ctx, sql) + if err != nil { + return nil, err + } + + if rs == nil { + return nil, nil + } + + defer func() { + closeErr := rs.Close() + if err == nil { + err = closeErr + } + }() + + return sqlexec.DrainRecordSet(ctx, rs, 8) +} + +func (c *bootstrapContext) EtcdClient() *clientv3.Client { + return c.etcdCli +} + +func (c *bootstrapContext) SessionPool() extension.SessionPool { + return c.sessionPool +} + +// Bootstrap bootstraps all extensions +func Bootstrap(ctx context.Context, do *domain.Domain) error { + extensions, err := extension.GetExtensions() + if err != nil { + return err + } + + if extensions == nil { + return nil + } + + pool := do.SysSessionPool() + sctx, err := pool.Get() + if err != nil { + return err + } + defer pool.Put(sctx) + + executor, ok := sctx.(sqlexec.SQLExecutor) + if !ok { + return errors.Errorf("type '%T' cannot be casted to 'sqlexec.SQLExecutor'", sctx) + } + + return extensions.Bootstrap(&bootstrapContext{ + Context: ctx, + sessionPool: pool, + sqlExecutor: executor, + etcdCli: do.GetEtcdClient(), + }) +} diff --git a/extension/extensions.go b/extension/extensions.go new file mode 100644 index 0000000000000..55f9c0bb83606 --- /dev/null +++ b/extension/extensions.go @@ -0,0 +1,69 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension + +// Extensions contains all extensions that have already setup +type Extensions struct { + manifests []*Manifest +} + +// Manifests returns a extension manifests +func (es *Extensions) Manifests() []*Manifest { + if es == nil { + return nil + } + manifests := make([]*Manifest, len(es.manifests)) + copy(manifests, es.manifests) + return manifests +} + +// Bootstrap bootstraps all extensions +func (es *Extensions) Bootstrap(ctx BootstrapContext) error { + if es == nil { + return nil + } + + for _, m := range es.manifests { + if m.bootstrap != nil { + if err := m.bootstrap(ctx); err != nil { + return err + } + } + } + return nil +} + +// GetAccessCheckFuncs returns spec functions of the custom access check +func (es *Extensions) GetAccessCheckFuncs() (funcs []AccessCheckFunc) { + if es == nil { + return nil + } + + for _, m := range es.manifests { + if m.accessCheckFunc != nil { + funcs = append(funcs, m.accessCheckFunc) + } + } + + return funcs +} + +// NewSessionExtensions creates a new ConnExtensions object +func (es *Extensions) NewSessionExtensions() *SessionExtensions { + if es == nil { + return nil + } + return newSessionExtensions(es) +} diff --git a/extension/function.go b/extension/function.go new file mode 100644 index 0000000000000..cb7c19de0a507 --- /dev/null +++ b/extension/function.go @@ -0,0 +1,72 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension + +import ( + "context" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" +) + +// FunctionContext is an interface to provide context to the custom function +type FunctionContext interface { + context.Context + User() *auth.UserIdentity + ActiveRoles() []*auth.RoleIdentity + CurrentDB() string + ConnectionInfo() *variable.ConnectionInfo + EvalArgs(row chunk.Row) ([]types.Datum, error) +} + +// FunctionDef is the definition for the custom function +type FunctionDef struct { + // Name is the function's name + Name string + // EvalTp is the type of the return value + EvalTp types.EvalType + // ArgTps is the argument types + ArgTps []types.EvalType + // OptionalArgsLen is the length of the optional args + OptionalArgsLen int + // EvalStringFunc is the eval function when `EvalTp` is `types.ETString` + EvalStringFunc func(ctx FunctionContext, row chunk.Row) (string, bool, error) + // EvalIntFunc is the eval function when `EvalTp` is `types.ETInt` + EvalIntFunc func(ctx FunctionContext, row chunk.Row) (int64, bool, error) + // RequireDynamicPrivileges is a function to return a list of dynamic privileges to check. + RequireDynamicPrivileges func(sem bool) []string +} + +// Validate validates the function definition +func (def *FunctionDef) Validate() error { + if def.Name == "" { + return errors.New("extension function name should not be empty") + } + + for def.OptionalArgsLen < 0 || def.OptionalArgsLen > len(def.ArgTps) { + return errors.Errorf("invalid OptionalArgsLen: %d", def.OptionalArgsLen) + } + + return nil +} + +// RegisterExtensionFunc is to avoid dependency cycle +var RegisterExtensionFunc func(*FunctionDef) error + +// RemoveExtensionFunc is to avoid dependency cycle +var RemoveExtensionFunc func(string) diff --git a/extension/function_test.go b/extension/function_test.go new file mode 100644 index 0000000000000..86fcd0be845c3 --- /dev/null +++ b/extension/function_test.go @@ -0,0 +1,417 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension_test + +import ( + "fmt" + "sort" + "strings" + "testing" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/extension" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/sem" + "github.com/stretchr/testify/require" +) + +var customFunc1 = &extension.FunctionDef{ + Name: "custom_func1", + EvalTp: types.ETString, + ArgTps: []types.EvalType{ + types.ETInt, + types.ETString, + }, + EvalStringFunc: func(ctx extension.FunctionContext, row chunk.Row) (string, bool, error) { + args, err := ctx.EvalArgs(row) + if err != nil { + return "", false, err + } + + if args[1].GetString() == "error" { + return "", false, errors.New("custom error") + } + + return fmt.Sprintf("%d,%s", args[0].GetInt64(), args[1].GetString()), false, nil + }, +} + +var customFunc2 = &extension.FunctionDef{ + Name: "custom_func2", + EvalTp: types.ETInt, + ArgTps: []types.EvalType{ + types.ETInt, + types.ETInt, + }, + EvalIntFunc: func(ctx extension.FunctionContext, row chunk.Row) (int64, bool, error) { + args, err := ctx.EvalArgs(row) + if err != nil { + return 0, false, err + } + return args[0].GetInt64()*100 + args[1].GetInt64(), false, nil + }, +} + +func TestExtensionFuncCtx(t *testing.T) { + defer extension.Reset() + extension.Reset() + + invoked := false + var user *auth.UserIdentity + var currentDB string + var activeRoles []*auth.RoleIdentity + var conn *variable.ConnectionInfo + + require.NoError(t, extension.Register("test", extension.WithCustomFunctions([]*extension.FunctionDef{ + { + Name: "custom_get_ctx", + EvalTp: types.ETString, + EvalStringFunc: func(ctx extension.FunctionContext, row chunk.Row) (string, bool, error) { + require.False(t, invoked) + invoked = true + user = ctx.User() + currentDB = ctx.CurrentDB() + activeRoles = ctx.ActiveRoles() + conn = ctx.ConnectionInfo() + return "done", false, nil + }, + }, + }))) + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create user u1@localhost") + tk.MustExec("create role r1") + tk.MustExec("grant r1 to u1@localhost") + tk.MustExec("grant ALL ON test.* to u1@localhost") + + tk1 := testkit.NewTestKit(t, store) + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil)) + tk1.MustExec("set role r1") + tk1.MustExec("use test") + tk1.Session().GetSessionVars().ConnectionInfo = &variable.ConnectionInfo{ + ConnectionID: 12345, + User: "u1", + } + + tk1.MustQuery("select custom_get_ctx()").Check(testkit.Rows("done")) + + require.True(t, invoked) + require.NotNil(t, user) + require.Equal(t, *tk1.Session().GetSessionVars().User, *user) + require.Equal(t, "test", currentDB) + require.NotNil(t, conn) + require.Equal(t, *tk1.Session().GetSessionVars().ConnectionInfo, *conn) + require.Equal(t, 1, len(activeRoles)) + require.Equal(t, auth.RoleIdentity{Username: "r1", Hostname: "%"}, *activeRoles[0]) +} + +func TestInvokeExtensionFunc(t *testing.T) { + defer extension.Reset() + extension.Reset() + + extension.Reset() + orgFuncList := expression.GetBuiltinList() + checkFuncList(t, orgFuncList) + require.NoError(t, extension.Register("test", extension.WithCustomFunctions([]*extension.FunctionDef{ + customFunc1, + customFunc2, + }))) + require.NoError(t, extension.Setup()) + checkFuncList(t, orgFuncList, "custom_func1", "custom_func2") + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustQuery("select custom_func1(1, 'abc')").Check(testkit.Rows("1,abc")) + tk.MustQuery("select custom_func2(7, 8)").Check(testkit.Rows("708")) + require.EqualError(t, tk.QueryToErr("select custom_func1(1, 'error')"), "custom error") + require.EqualError(t, tk.ExecToErr("select custom_func1(1)"), "[expression:1582]Incorrect parameter count in the call to native function 'custom_func1'") + + extension.Reset() + checkFuncList(t, orgFuncList) + store2 := testkit.CreateMockStore(t) + tk2 := testkit.NewTestKit(t, store2) + tk2.MustExec("use test") + require.EqualError(t, tk2.ExecToErr("select custom_func1(1, 'abc')"), "[expression:1305]FUNCTION test.custom_func1 does not exist") + require.EqualError(t, tk2.ExecToErr("select custom_func2(1, 2)"), "[expression:1305]FUNCTION test.custom_func2 does not exist") +} + +func TestExtensionFuncDynamicArgLen(t *testing.T) { + defer extension.Reset() + extension.Reset() + + fnDef := &extension.FunctionDef{ + Name: "dynamic_arg_func", + EvalTp: types.ETInt, + OptionalArgsLen: 1, + ArgTps: []types.EvalType{ + types.ETInt, + types.ETInt, + types.ETInt, + types.ETInt, + }, + EvalIntFunc: func(ctx extension.FunctionContext, row chunk.Row) (int64, bool, error) { + args, err := ctx.EvalArgs(row) + if err != nil { + return 0, false, err + } + + result := int64(0) + for _, arg := range args { + result = result*10 + arg.GetInt64() + } + + return result, false, nil + }, + } + + require.NoError(t, extension.Register("test", extension.WithCustomFunctions([]*extension.FunctionDef{fnDef}))) + require.NoError(t, extension.Setup()) + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustQuery("select dynamic_arg_func(1, 2, 3)").Check(testkit.Rows("123")) + tk.MustQuery("select dynamic_arg_func(1, 2, 3, 4)").Check(testkit.Rows("1234")) + + expectedErrMsg := "[expression:1582]Incorrect parameter count in the call to native function 'dynamic_arg_func'" + require.EqualError(t, tk.ExecToErr("select dynamic_arg_func()"), expectedErrMsg) + require.EqualError(t, tk.ExecToErr("select dynamic_arg_func(1)"), expectedErrMsg) + require.EqualError(t, tk.ExecToErr("select dynamic_arg_func(1, 2)"), expectedErrMsg) +} + +func TestRegisterExtensionFunc(t *testing.T) { + defer extension.Reset() + + // nil func + extension.Reset() + orgFuncList := expression.GetBuiltinList() + checkFuncList(t, orgFuncList) + require.NoError(t, extension.Register("test", extension.WithCustomFunctions([]*extension.FunctionDef{ + customFunc1, + nil, + }))) + require.EqualError(t, extension.Setup(), "extension function def is nil") + checkFuncList(t, orgFuncList) + + // dup name with builtin + extension.Reset() + var def extension.FunctionDef + def = *customFunc1 + def.Name = "substring" + require.NoError(t, extension.Register("test", extension.WithCustomFunctions([]*extension.FunctionDef{ + customFunc1, + &def, + }))) + require.EqualError(t, extension.Setup(), "extension function name 'substring' conflict with builtin") + checkFuncList(t, orgFuncList) + + // empty func name + extension.Reset() + def = *customFunc1 + def.Name = "" + require.NoError(t, extension.Register("test", extension.WithCustomFunctions([]*extension.FunctionDef{ + &def, + }))) + require.EqualError(t, extension.Setup(), "extension function name should not be empty") + checkFuncList(t, orgFuncList) + + // dup name with other func in one extension + extension.Reset() + require.NoError(t, extension.Register("test", extension.WithCustomFunctions([]*extension.FunctionDef{ + customFunc1, + customFunc1, + }))) + require.EqualError(t, extension.Setup(), "duplicated extension function name 'custom_func1'") + checkFuncList(t, orgFuncList) + + // dup name with other func in different extension + extension.Reset() + require.NoError(t, extension.Register("test1", extension.WithCustomFunctions([]*extension.FunctionDef{ + customFunc1, + }))) + require.NoError(t, extension.Register("test2", extension.WithCustomFunctions([]*extension.FunctionDef{ + customFunc1, + }))) + require.EqualError(t, extension.Setup(), "duplicated extension function name 'custom_func1'") + checkFuncList(t, orgFuncList) +} + +func checkFuncList(t *testing.T, orgList []string, customFuncs ...string) { + for _, name := range orgList { + require.False(t, strings.HasPrefix(name, "custom_"), name) + } + + checkList := make([]string, 0, len(orgList)+len(customFuncs)) + checkList = append(checkList, orgList...) + checkList = append(checkList, customFuncs...) + sort.Strings(checkList) + require.Equal(t, checkList, expression.GetBuiltinList()) +} + +func TestExtensionFuncPrivilege(t *testing.T) { + defer func() { + extension.Reset() + sem.Disable() + }() + + extension.Reset() + require.NoError(t, extension.Register("test", + extension.WithCustomFunctions([]*extension.FunctionDef{ + { + Name: "custom_no_priv_func", + EvalTp: types.ETString, + EvalStringFunc: func(ctx extension.FunctionContext, row chunk.Row) (string, bool, error) { + return "zzz", false, nil + }, + }, + { + Name: "custom_only_dyn_priv_func", + EvalTp: types.ETString, + RequireDynamicPrivileges: func(sem bool) []string { + return []string{"CUSTOM_DYN_PRIV_1"} + }, + EvalStringFunc: func(ctx extension.FunctionContext, row chunk.Row) (string, bool, error) { + return "abc", false, nil + }, + }, + { + Name: "custom_only_sem_dyn_priv_func", + EvalTp: types.ETString, + RequireDynamicPrivileges: func(sem bool) []string { + if sem { + return []string{"RESTRICTED_CUSTOM_DYN_PRIV_2"} + } + return nil + }, + EvalStringFunc: func(ctx extension.FunctionContext, row chunk.Row) (string, bool, error) { + return "def", false, nil + }, + }, + { + Name: "custom_both_dyn_priv_func", + EvalTp: types.ETString, + RequireDynamicPrivileges: func(sem bool) []string { + if sem { + return []string{"RESTRICTED_CUSTOM_DYN_PRIV_2"} + } + return []string{"CUSTOM_DYN_PRIV_1"} + }, + EvalStringFunc: func(ctx extension.FunctionContext, row chunk.Row) (string, bool, error) { + return "ghi", false, nil + }, + }, + }), + extension.WithCustomDynPrivs([]string{ + "CUSTOM_DYN_PRIV_1", + "RESTRICTED_CUSTOM_DYN_PRIV_2", + }), + )) + require.NoError(t, extension.Setup()) + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("create user u1@localhost") + + tk.MustExec("create user u2@localhost") + tk.MustExec("GRANT CUSTOM_DYN_PRIV_1 on *.* TO u2@localhost") + + tk.MustExec("create user u3@localhost") + tk.MustExec("GRANT RESTRICTED_CUSTOM_DYN_PRIV_2 on *.* TO u3@localhost") + + tk.MustExec("create user u4@localhost") + tk.MustExec("GRANT CUSTOM_DYN_PRIV_1, RESTRICTED_CUSTOM_DYN_PRIV_2 on *.* TO u4@localhost") + + tk1 := testkit.NewTestKit(t, store) + + // root has all privileges by default + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + tk1.MustQuery("select custom_only_dyn_priv_func()").Check(testkit.Rows("abc")) + tk1.MustQuery("select custom_only_sem_dyn_priv_func()").Check(testkit.Rows("def")) + tk1.MustQuery("select custom_both_dyn_priv_func()").Check(testkit.Rows("ghi")) + + // u1 in non-sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + require.EqualError(t, tk1.ExecToErr("select custom_only_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the SUPER or CUSTOM_DYN_PRIV_1 privilege(s) for this operation") + tk1.MustQuery("select custom_only_sem_dyn_priv_func()").Check(testkit.Rows("def")) + require.EqualError(t, tk1.ExecToErr("select custom_both_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the SUPER or CUSTOM_DYN_PRIV_1 privilege(s) for this operation") + + // u2 in non-sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + tk1.MustQuery("select custom_only_dyn_priv_func()").Check(testkit.Rows("abc")) + tk1.MustQuery("select custom_only_sem_dyn_priv_func()").Check(testkit.Rows("def")) + tk1.MustQuery("select custom_both_dyn_priv_func()").Check(testkit.Rows("ghi")) + + // u3 in non-sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u3", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + require.EqualError(t, tk1.ExecToErr("select custom_only_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the SUPER or CUSTOM_DYN_PRIV_1 privilege(s) for this operation") + tk1.MustQuery("select custom_only_sem_dyn_priv_func()").Check(testkit.Rows("def")) + require.EqualError(t, tk1.ExecToErr("select custom_both_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the SUPER or CUSTOM_DYN_PRIV_1 privilege(s) for this operation") + + // u4 in non-sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + tk1.MustQuery("select custom_only_dyn_priv_func()").Check(testkit.Rows("abc")) + tk1.MustQuery("select custom_only_sem_dyn_priv_func()").Check(testkit.Rows("def")) + tk1.MustQuery("select custom_both_dyn_priv_func()").Check(testkit.Rows("ghi")) + + sem.Enable() + + // root in sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + tk1.MustQuery("select custom_only_dyn_priv_func()").Check(testkit.Rows("abc")) + require.EqualError(t, tk1.ExecToErr("select custom_only_sem_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the RESTRICTED_CUSTOM_DYN_PRIV_2 privilege(s) for this operation") + require.EqualError(t, tk1.ExecToErr("select custom_both_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the RESTRICTED_CUSTOM_DYN_PRIV_2 privilege(s) for this operation") + + // u1 in sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + require.EqualError(t, tk1.ExecToErr("select custom_only_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the CUSTOM_DYN_PRIV_1 privilege(s) for this operation") + require.EqualError(t, tk1.ExecToErr("select custom_only_sem_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the RESTRICTED_CUSTOM_DYN_PRIV_2 privilege(s) for this operation") + require.EqualError(t, tk1.ExecToErr("select custom_both_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the RESTRICTED_CUSTOM_DYN_PRIV_2 privilege(s) for this operation") + + // u2 in sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + tk1.MustQuery("select custom_only_dyn_priv_func()").Check(testkit.Rows("abc")) + require.EqualError(t, tk1.ExecToErr("select custom_only_sem_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the RESTRICTED_CUSTOM_DYN_PRIV_2 privilege(s) for this operation") + require.EqualError(t, tk1.ExecToErr("select custom_both_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the RESTRICTED_CUSTOM_DYN_PRIV_2 privilege(s) for this operation") + + // u3 in sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u3", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + require.EqualError(t, tk1.ExecToErr("select custom_only_dyn_priv_func()"), "[expression:1227]Access denied; you need (at least one of) the CUSTOM_DYN_PRIV_1 privilege(s) for this operation") + tk1.MustQuery("select custom_only_sem_dyn_priv_func()").Check(testkit.Rows("def")) + tk1.MustQuery("select custom_both_dyn_priv_func()").Check(testkit.Rows("ghi")) + + // u4 in sem + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil)) + tk1.MustQuery("select custom_no_priv_func()").Check(testkit.Rows("zzz")) + tk1.MustQuery("select custom_only_dyn_priv_func()").Check(testkit.Rows("abc")) + tk1.MustQuery("select custom_only_sem_dyn_priv_func()").Check(testkit.Rows("def")) + tk1.MustQuery("select custom_both_dyn_priv_func()").Check(testkit.Rows("ghi")) +} diff --git a/extension/main_test.go b/extension/main_test.go new file mode 100644 index 0000000000000..7ffc36a917470 --- /dev/null +++ b/extension/main_test.go @@ -0,0 +1,33 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension + +import ( + "testing" + + "github.com/pingcap/tidb/testkit/testsetup" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + testsetup.SetupForCommonTest() + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + } + goleak.VerifyTestMain(m, opts...) +} diff --git a/extension/manifest.go b/extension/manifest.go new file mode 100644 index 0000000000000..436067c11d704 --- /dev/null +++ b/extension/manifest.go @@ -0,0 +1,225 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension + +import ( + "context" + + "github.com/ngaut/pools" + "github.com/pingcap/errors" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/util/chunk" + clientv3 "go.etcd.io/etcd/client/v3" +) + +// SessionPool is the pool for session +type SessionPool interface { + Get() (pools.Resource, error) + Put(pools.Resource) +} + +// Option represents an option to initialize an extension +type Option func(m *Manifest) + +// WithCustomSysVariables specifies custom variables of an extension +func WithCustomSysVariables(vars []*variable.SysVar) Option { + return func(m *Manifest) { + m.sysVariables = vars + } +} + +// WithCustomDynPrivs specifies dynamic privileges of an extension +func WithCustomDynPrivs(privs []string) Option { + return func(m *Manifest) { + m.dynPrivs = privs + } +} + +// WithCustomFunctions specifies custom functions +func WithCustomFunctions(funcs []*FunctionDef) Option { + return func(m *Manifest) { + m.funcs = funcs + } +} + +// AccessCheckFunc is a function that returns a dynamic privilege list for db/tbl/column access +type AccessCheckFunc func(db, tbl, column string, priv mysql.PrivilegeType, sem bool) []string + +// WithCustomAccessCheck specifies the custom db/tbl/column dynamic privilege check +func WithCustomAccessCheck(fn AccessCheckFunc) Option { + return func(m *Manifest) { + m.accessCheckFunc = fn + } +} + +// WithSessionHandlerFactory specifies a factory function to handle session +func WithSessionHandlerFactory(factory func() *SessionHandler) Option { + return func(m *Manifest) { + m.sessionHandlerFactory = factory + } +} + +// WithClose specifies the close function of an extension. +// It will be invoked when `extension.Reset` is called +func WithClose(fn func()) Option { + return func(m *Manifest) { + m.close = fn + } +} + +// BootstrapContext is the context used by extension in bootstrap +type BootstrapContext interface { + context.Context + // ExecuteSQL is used to execute a sql + ExecuteSQL(ctx context.Context, sql string) ([]chunk.Row, error) + // EtcdClient returns the etcd client + EtcdClient() *clientv3.Client + // SessionPool returns the session pool of domain + SessionPool() SessionPool +} + +// WithBootstrap specifies the bootstrap func of an extension +func WithBootstrap(fn func(BootstrapContext) error) Option { + return func(m *Manifest) { + m.bootstrap = fn + } +} + +// WithBootstrapSQL the bootstrap SQL list +func WithBootstrapSQL(sqlList ...string) Option { + return WithBootstrap(func(ctx BootstrapContext) error { + for _, sql := range sqlList { + if _, err := ctx.ExecuteSQL(ctx, sql); err != nil { + return err + } + } + return nil + }) +} + +// Manifest is an extension's manifest +type Manifest struct { + name string + sysVariables []*variable.SysVar + dynPrivs []string + bootstrap func(BootstrapContext) error + funcs []*FunctionDef + accessCheckFunc AccessCheckFunc + sessionHandlerFactory func() *SessionHandler + close func() +} + +// Name returns the extension's name +func (m *Manifest) Name() string { + return m.name +} + +func newManifestWithSetup(name string, factory func() ([]Option, error)) (_ *Manifest, _ func(), err error) { + clearBuilder := &clearFuncBuilder{} + defer func() { + if err != nil { + clearBuilder.Build()() + } + }() + + // new manifest with factory + m := &Manifest{name: name} + err = clearBuilder.DoWithCollectClear(func() (func(), error) { + options, err := factory() + if err != nil { + return nil, err + } + + for _, opt := range options { + opt(m) + } + + return m.close, nil + }) + + if err != nil { + return nil, nil, err + } + + // setup dynamic privileges + for i := range m.dynPrivs { + priv := m.dynPrivs[i] + err = clearBuilder.DoWithCollectClear(func() (func(), error) { + if err = RegisterDynamicPrivilege(priv); err != nil { + return nil, err + } + return func() { + RemoveDynamicPrivilege(priv) + }, nil + }) + if err != nil { + return nil, nil, err + } + } + + // setup sys vars + for i := range m.sysVariables { + sysVar := m.sysVariables[i] + err = clearBuilder.DoWithCollectClear(func() (func(), error) { + if sysVar == nil { + return nil, errors.New("system var should not be nil") + } + + if sysVar.Name == "" { + return nil, errors.New("system var name should not be empty") + } + + if variable.GetSysVar(sysVar.Name) != nil { + return nil, errors.Errorf("system var '%s' has already registered", sysVar.Name) + } + + variable.RegisterSysVar(sysVar) + return func() { + variable.UnregisterSysVar(sysVar.Name) + }, nil + }) + + if err != nil { + return nil, nil, err + } + } + + // setup functions + for i := range m.funcs { + def := m.funcs[i] + err = clearBuilder.DoWithCollectClear(func() (func(), error) { + if err := RegisterExtensionFunc(def); err != nil { + return nil, err + } + + return func() { + RemoveExtensionFunc(def.Name) + }, nil + }) + + if err != nil { + return nil, nil, err + } + } + + return m, clearBuilder.Build(), nil +} + +// RegisterDynamicPrivilege is used to resolve dependency cycle +var RegisterDynamicPrivilege func(string) error + +// RemoveDynamicPrivilege is used to resolve dependency cycle +var RemoveDynamicPrivilege func(string) bool diff --git a/extension/registry.go b/extension/registry.go new file mode 100644 index 0000000000000..4e838181f9b56 --- /dev/null +++ b/extension/registry.go @@ -0,0 +1,170 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension + +import ( + "sort" + "sync" + + "github.com/pingcap/errors" +) + +type registry struct { + sync.RWMutex + factories map[string]func() ([]Option, error) + extensionNames []string + setup bool + extensions *Extensions + close func() +} + +// Setup sets up the extensions +func (r *registry) Setup() error { + r.Lock() + defer r.Unlock() + + if _, err := r.doSetup(); err != nil { + return err + } + return nil +} + +// Extensions returns the extensions after setup +func (r *registry) Extensions() (*Extensions, error) { + r.RLock() + if r.setup { + extensions := r.extensions + r.RUnlock() + return extensions, nil + } + r.RUnlock() + + r.Lock() + defer r.Unlock() + return r.doSetup() +} + +// RegisterFactory registers a new extension with a factory +func (r *registry) RegisterFactory(name string, factory func() ([]Option, error)) error { + r.Lock() + defer r.Unlock() + + if r.setup { + return errors.New("Cannot register new extension because registry has already been setup") + } + + if name == "" { + return errors.New("extension name should not be empty") + } + + if _, ok := r.factories[name]; ok { + return errors.Errorf("extension with name '%s' already registered", name) + } + + if r.factories == nil { + r.factories = make(map[string]func() ([]Option, error)) + } + + r.factories[name] = factory + r.extensionNames = append(r.extensionNames, name) + sort.Strings(r.extensionNames) + return nil +} + +// Setup setups all extensions +func (r *registry) doSetup() (_ *Extensions, err error) { + if r.setup { + return r.extensions, nil + } + + if len(r.factories) == 0 { + r.extensions = nil + r.setup = true + return nil, nil + } + + clearBuilder := &clearFuncBuilder{} + defer func() { + if err != nil { + clearBuilder.Build()() + } + }() + + manifests := make([]*Manifest, 0, len(r.factories)) + for i := range r.extensionNames { + name := r.extensionNames[i] + err = clearBuilder.DoWithCollectClear(func() (func(), error) { + factory := r.factories[name] + m, clear, err := newManifestWithSetup(name, factory) + if err != nil { + return nil, err + } + manifests = append(manifests, m) + return clear, nil + }) + + if err != nil { + return nil, err + } + } + r.extensions = &Extensions{manifests: manifests} + r.setup = true + r.close = clearBuilder.Build() + return r.extensions, nil +} + +// Reset resets the registry. It is only used by test +func (r *registry) Reset() { + r.Lock() + defer r.Unlock() + + if r.close != nil { + r.close() + r.close = nil + } + r.factories = nil + r.extensionNames = nil + r.extensions = nil + r.setup = false +} + +var globalRegistry registry + +// RegisterFactory registers a new extension with a factory +func RegisterFactory(name string, factory func() ([]Option, error)) error { + return globalRegistry.RegisterFactory(name, factory) +} + +// Register registers a new extension with options +func Register(name string, options ...Option) error { + return RegisterFactory(name, func() ([]Option, error) { + return options, nil + }) +} + +// Setup setups extensions +func Setup() error { + return globalRegistry.Setup() +} + +// GetExtensions returns all extensions after setup +func GetExtensions() (*Extensions, error) { + return globalRegistry.Extensions() +} + +// Reset resets the registry. It is only used by test +func Reset() { + globalRegistry.Reset() +} diff --git a/extension/registry_test.go b/extension/registry_test.go new file mode 100644 index 0000000000000..ba1130d815fbf --- /dev/null +++ b/extension/registry_test.go @@ -0,0 +1,349 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension_test + +import ( + "testing" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/extension" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/privilege/privileges" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/util/sem" + "github.com/stretchr/testify/require" +) + +func TestSetupExtensions(t *testing.T) { + defer func() { + extension.Reset() + }() + + extension.Reset() + require.NoError(t, extension.Setup()) + extensions, err := extension.GetExtensions() + require.NoError(t, err) + require.Equal(t, 0, len(extensions.Manifests())) + + extension.Reset() + require.NoError(t, extension.Register("test1")) + require.NoError(t, extension.Register("test2")) + require.NoError(t, extension.Setup()) + extensions, err = extension.GetExtensions() + require.NoError(t, err) + require.Equal(t, 2, len(extensions.Manifests())) + require.Equal(t, "test1", extensions.Manifests()[0].Name()) + require.Equal(t, "test2", extensions.Manifests()[1].Name()) +} + +func TestExtensionRegisterName(t *testing.T) { + defer extension.Reset() + + // test empty name + extension.Reset() + require.EqualError(t, extension.Register(""), "extension name should not be empty") + + // test dup name + extension.Reset() + require.NoError(t, extension.Register("test")) + require.EqualError(t, extension.Register("test"), "extension with name 'test' already registered") +} + +func TestRegisterExtensionWithClose(t *testing.T) { + defer extension.Reset() + + // normal register + extension.Reset() + cnt := 0 + require.NoError(t, extension.Register("test1", extension.WithClose(func() { + cnt++ + }))) + require.NoError(t, extension.Setup()) + require.Equal(t, 0, cnt) + + // reset will call close + extension.Reset() + require.Equal(t, 1, cnt) + + // reset again has no effect + extension.Reset() + require.Equal(t, 1, cnt) + + // Auto close when error + cnt = 0 + extension.Reset() + require.NoError(t, extension.Register("test1", extension.WithClose(func() { + cnt++ + }))) + require.NoError(t, extension.RegisterFactory("test2", func() ([]extension.Option, error) { + return nil, errors.New("error abc") + })) + require.EqualError(t, extension.Setup(), "error abc") + require.Equal(t, 1, cnt) +} + +func TestRegisterExtensionWithDyncPrivs(t *testing.T) { + defer extension.Reset() + + origDynPrivs := privileges.GetDynamicPrivileges() + origDynPrivs = append([]string{}, origDynPrivs...) + + extension.Reset() + require.NoError(t, extension.Register("test", extension.WithCustomDynPrivs([]string{"priv1", "priv2"}))) + require.NoError(t, extension.Setup()) + privs := privileges.GetDynamicPrivileges() + require.Equal(t, origDynPrivs, privs[:len(origDynPrivs)]) + require.Equal(t, []string{"PRIV1", "PRIV2"}, privs[len(origDynPrivs):]) + + // test for empty dynamic privilege name + extension.Reset() + require.NoError(t, extension.Register("test", extension.WithCustomDynPrivs([]string{"priv1", ""}))) + require.EqualError(t, extension.Setup(), "privilege name should not be empty") + require.Equal(t, origDynPrivs, privileges.GetDynamicPrivileges()) + + // test for duplicate name with builtin + extension.Reset() + require.NoError(t, extension.Register("test", extension.WithCustomDynPrivs([]string{"priv1", "ROLE_ADMIN"}))) + require.EqualError(t, extension.Setup(), "privilege is already registered") + require.Equal(t, origDynPrivs, privileges.GetDynamicPrivileges()) + + // test for duplicate name with other extension + extension.Reset() + require.NoError(t, extension.Register("test1", extension.WithCustomDynPrivs([]string{"priv1"}))) + require.NoError(t, extension.Register("test2", extension.WithCustomDynPrivs([]string{"priv2", "priv1"}))) + require.EqualError(t, extension.Setup(), "privilege is already registered") + require.Equal(t, origDynPrivs, privileges.GetDynamicPrivileges()) +} + +func TestRegisterExtensionWithSysVars(t *testing.T) { + defer extension.Reset() + + sysVar1 := &variable.SysVar{ + Scope: variable.ScopeGlobal | variable.ScopeSession, + Name: "var1", + Value: variable.On, + Type: variable.TypeBool, + } + + sysVar2 := &variable.SysVar{ + Scope: variable.ScopeSession, + Name: "var2", + Value: "val2", + Type: variable.TypeStr, + } + + // normal register + extension.Reset() + require.NoError(t, extension.Register("test", extension.WithCustomSysVariables([]*variable.SysVar{sysVar1, sysVar2}))) + require.NoError(t, extension.Setup()) + require.Same(t, sysVar1, variable.GetSysVar("var1")) + require.Same(t, sysVar2, variable.GetSysVar("var2")) + + // test for empty name + extension.Reset() + require.NoError(t, extension.Register("test", extension.WithCustomSysVariables([]*variable.SysVar{ + {Scope: variable.ScopeGlobal, Name: "", Value: "val3"}, + }))) + require.EqualError(t, extension.Setup(), "system var name should not be empty") + require.Nil(t, variable.GetSysVar("")) + + // test for duplicate name with builtin + extension.Reset() + require.NoError(t, extension.Register("test", extension.WithCustomSysVariables([]*variable.SysVar{ + sysVar1, + {Scope: variable.ScopeGlobal, Name: variable.TiDBSnapshot, Value: "val3"}, + }))) + require.EqualError(t, extension.Setup(), "system var 'tidb_snapshot' has already registered") + require.Nil(t, variable.GetSysVar("var1")) + require.Equal(t, "", variable.GetSysVar(variable.TiDBSnapshot).Value) + require.Equal(t, variable.ScopeSession, variable.GetSysVar(variable.TiDBSnapshot).Scope) + + // test for duplicate name with other extension + extension.Reset() + require.NoError(t, extension.Register("test1", extension.WithCustomSysVariables([]*variable.SysVar{sysVar1, sysVar2}))) + require.NoError(t, extension.Register("test2", extension.WithCustomSysVariables([]*variable.SysVar{sysVar1}))) + require.EqualError(t, extension.Setup(), "system var 'var1' has already registered") + require.Nil(t, variable.GetSysVar("var1")) + require.Nil(t, variable.GetSysVar("var2")) +} + +func TestSetVariablePrivilege(t *testing.T) { + defer extension.Reset() + + sysVar1 := &variable.SysVar{ + Scope: variable.ScopeGlobal | variable.ScopeSession, + Name: "var1", + Value: "1", + MinValue: 0, + MaxValue: 100, + Type: variable.TypeInt, + RequireDynamicPrivileges: func(isGlobal bool, sem bool) []string { + privs := []string{"priv1"} + if isGlobal { + privs = append(privs, "priv2") + } + + if sem { + privs = append(privs, "restricted_priv3") + } + + return privs + }, + } + + extension.Reset() + require.NoError(t, extension.Register( + "test", + extension.WithCustomSysVariables([]*variable.SysVar{sysVar1}), + extension.WithCustomDynPrivs([]string{"priv1", "priv2", "restricted_priv3"}), + )) + require.NoError(t, extension.Setup()) + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("create user u2@localhost") + + tk1 := testkit.NewTestKit(t, store) + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + + tk2 := testkit.NewTestKit(t, store) + require.NoError(t, tk2.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil)) + + sem.Disable() + tk1.MustExec("set @@var1=7") + tk1.MustQuery("select @@var1").Check(testkit.Rows("7")) + + require.EqualError(t, tk2.ExecToErr("set @@var1=10"), "[planner:1227]Access denied; you need (at least one of) the SUPER or priv1 privilege(s) for this operation") + tk2.MustQuery("select @@var1").Check(testkit.Rows("1")) + + tk.MustExec("GRANT priv1 on *.* TO u2@localhost") + tk2.MustExec("set @@var1=8") + tk2.MustQuery("select @@var1").Check(testkit.Rows("8")) + + tk1.MustExec("set @@global.var1=17") + tk1.MustQuery("select @@global.var1").Check(testkit.Rows("17")) + + tk.MustExec("GRANT SYSTEM_VARIABLES_ADMIN on *.* TO u2@localhost") + require.EqualError(t, tk2.ExecToErr("set @@global.var1=18"), "[planner:1227]Access denied; you need (at least one of) the SUPER or priv2 privilege(s) for this operation") + tk2.MustQuery("select @@global.var1").Check(testkit.Rows("17")) + + tk.MustExec("GRANT priv2 on *.* TO u2@localhost") + tk2.MustExec("set @@global.var1=18") + tk2.MustQuery("select @@global.var1").Check(testkit.Rows("18")) + + sem.Enable() + defer sem.Disable() + + require.EqualError(t, tk1.ExecToErr("set @@global.var1=27"), "[planner:1227]Access denied; you need (at least one of) the restricted_priv3 privilege(s) for this operation") + tk1.MustQuery("select @@global.var1").Check(testkit.Rows("18")) + + require.EqualError(t, tk2.ExecToErr("set @@global.var1=27"), "[planner:1227]Access denied; you need (at least one of) the restricted_priv3 privilege(s) for this operation") + tk2.MustQuery("select @@global.var1").Check(testkit.Rows("18")) + + tk.MustExec("GRANT restricted_priv3 on *.* TO u2@localhost") + tk2.MustExec("set @@global.var1=28") + tk2.MustQuery("select @@global.var1").Check(testkit.Rows("28")) +} + +func TestCustomAccessCheck(t *testing.T) { + defer extension.Reset() + extension.Reset() + + require.NoError(t, extension.Register( + "test", + extension.WithCustomDynPrivs([]string{"priv1", "priv2", "restricted_priv3"}), + extension.WithCustomAccessCheck(func(db, tbl, column string, priv mysql.PrivilegeType, sem bool) []string { + if db != "test" || tbl != "t1" { + return nil + } + + var privs []string + if priv == mysql.SelectPriv { + privs = append(privs, "priv1") + } else if priv == mysql.UpdatePriv { + privs = append(privs, "priv2") + if sem { + privs = append(privs, "restricted_priv3") + } + } else { + return nil + } + + return privs + }), + )) + require.NoError(t, extension.Setup()) + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("create user u2@localhost") + + tk1 := testkit.NewTestKit(t, store) + require.NoError(t, tk1.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + tk1.MustExec("use test") + + tk2 := testkit.NewTestKit(t, store) + require.NoError(t, tk2.Session().Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil)) + tk.MustExec("GRANT all on test.t1 TO u2@localhost") + tk2.MustExec("use test") + + tk1.MustExec("create table t1(id int primary key, v int)") + tk1.MustExec("insert into t1 values (1, 10), (2, 20)") + + tk1.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 10")) + tk1.MustQuery("select * from t1").Check(testkit.Rows("1 10", "2 20")) + + require.EqualError(t, tk2.ExecToErr("select * from t1 where id=1"), "[planner:1142]SELECT command denied to user 'u2'@'localhost' for table 't1'") + require.EqualError(t, tk2.ExecToErr("select * from t1"), "[planner:1142]SELECT command denied to user 'u2'@'localhost' for table 't1'") + + tk.MustExec("GRANT priv1 on *.* TO u2@localhost") + tk2.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 10")) + tk2.MustQuery("select * from t1").Check(testkit.Rows("1 10", "2 20")) + + require.EqualError(t, tk2.ExecToErr("update t1 set v=11 where id=1"), "[planner:8121]privilege check for 'Update' fail") + require.EqualError(t, tk2.ExecToErr("update t1 set v=11 where id<2"), "[planner:8121]privilege check for 'Update' fail") + tk2.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 10")) + + tk.MustExec("GRANT priv2 on *.* TO u2@localhost") + tk2.MustExec("update t1 set v=11 where id=1") + tk2.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 11")) + + tk2.MustExec("update t1 set v=12 where id<2") + tk2.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 12")) + + sem.Enable() + defer sem.Disable() + + require.EqualError(t, tk1.ExecToErr("update t1 set v=21 where id=1"), "[planner:8121]privilege check for 'Update' fail") + require.EqualError(t, tk1.ExecToErr("update t1 set v=21 where id<2"), "[planner:8121]privilege check for 'Update' fail") + tk1.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 12")) + + require.EqualError(t, tk2.ExecToErr("update t1 set v=21 where id=1"), "[planner:8121]privilege check for 'Update' fail") + require.EqualError(t, tk2.ExecToErr("update t1 set v=21 where id<2"), "[planner:8121]privilege check for 'Update' fail") + tk2.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 12")) + + tk.MustExec("GRANT restricted_priv3 on *.* TO u2@localhost") + tk2.MustExec("update t1 set v=31 where id=1") + tk2.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 31")) + + tk2.MustExec("update t1 set v=32 where id<2") + tk2.MustQuery("select * from t1 where id=1").Check(testkit.Rows("1 32")) +} diff --git a/extension/session.go b/extension/session.go new file mode 100644 index 0000000000000..e35f31ec68920 --- /dev/null +++ b/extension/session.go @@ -0,0 +1,147 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension + +import ( + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/types" +) + +// ConnEventInfo is the connection info for the event +type ConnEventInfo struct { + *variable.ConnectionInfo + ActiveRoles []*auth.RoleIdentity + Error error +} + +// ConnEventTp is the type of the connection event +type ConnEventTp uint8 + +const ( + // ConnConnected means connection connected, but not handshake yet + ConnConnected ConnEventTp = iota + // ConnHandshakeAccepted means connection is accepted after handshake + ConnHandshakeAccepted + // ConnHandshakeRejected means connections is rejected after handshake + ConnHandshakeRejected + // ConnReset means the connection is reset + ConnReset + // ConnDisconnected means the connection is disconnected + ConnDisconnected +) + +// StmtEventTp is the type of the statement event +type StmtEventTp uint8 + +const ( + // StmtError means the stmt is failed + StmtError StmtEventTp = iota + // StmtSuccess means the stmt is successfully executed + StmtSuccess +) + +// StmtEventInfo is the information of stmt event +type StmtEventInfo interface { + // User returns the user of the session + User() *auth.UserIdentity + // ActiveRoles returns the active roles of the user + ActiveRoles() []*auth.RoleIdentity + // CurrentDB returns the current database + CurrentDB() string + // ConnectionInfo returns the connection info of the current session + ConnectionInfo() *variable.ConnectionInfo + // StmtNode returns the parsed ast of the statement + // When parse error, this method will return a nil value + StmtNode() ast.StmtNode + // ExecuteStmtNode will return the `ast.ExecuteStmt` node when the current statement is EXECUTE, + // otherwise a nil value will be returned + ExecuteStmtNode() *ast.ExecuteStmt + // ExecutePreparedStmt will return the prepared stmt node for the EXECUTE statement. + // If the current statement is not EXECUTE or prepared statement is not found, a nil value will be returned + ExecutePreparedStmt() ast.StmtNode + // PreparedParams will return the params for the EXECUTE statement + PreparedParams() []types.Datum + // OriginalText will return the text of the statement. + // Notice that for the EXECUTE statement, the prepared statement text will be used as the return value + OriginalText() string + // SQLDigest will return the normalized and redact text of the `OriginalText()` + SQLDigest() (normalized string, digest *parser.Digest) + // AffectedRows will return the affected rows of the current statement + AffectedRows() uint64 + // RelatedTables will return the related tables of the current statement + RelatedTables() []stmtctx.TableEntry + // GetError will return the error when the current statement is failed + GetError() error +} + +// SessionHandler is used to listen session events +type SessionHandler struct { + OnConnectionEvent func(ConnEventTp, *ConnEventInfo) + OnStmtEvent func(StmtEventTp, StmtEventInfo) +} + +func newSessionExtensions(es *Extensions) *SessionExtensions { + connExtensions := &SessionExtensions{} + for _, m := range es.Manifests() { + if m.sessionHandlerFactory != nil { + if handler := m.sessionHandlerFactory(); handler != nil { + if fn := handler.OnConnectionEvent; fn != nil { + connExtensions.connectionEventFuncs = append(connExtensions.connectionEventFuncs, fn) + } + if fn := handler.OnStmtEvent; fn != nil { + connExtensions.stmtEventFuncs = append(connExtensions.stmtEventFuncs, fn) + } + } + } + } + return connExtensions +} + +// SessionExtensions is the extensions +type SessionExtensions struct { + connectionEventFuncs []func(ConnEventTp, *ConnEventInfo) + stmtEventFuncs []func(StmtEventTp, StmtEventInfo) +} + +// OnConnectionEvent will be called when a connection event happens +func (es *SessionExtensions) OnConnectionEvent(tp ConnEventTp, event *ConnEventInfo) { + if es == nil { + return + } + + for _, fn := range es.connectionEventFuncs { + fn(tp, event) + } +} + +// HasStmtEventListeners returns a bool that indicates if any stmt event listener exists +func (es *SessionExtensions) HasStmtEventListeners() bool { + return es != nil && len(es.stmtEventFuncs) > 0 +} + +// OnStmtEvent will be called when a stmt event happens +func (es *SessionExtensions) OnStmtEvent(tp StmtEventTp, event StmtEventInfo) { + if es == nil { + return + } + + for _, fn := range es.stmtEventFuncs { + fn(tp, event) + } +} diff --git a/extension/util.go b/extension/util.go new file mode 100644 index 0000000000000..0d0ab6cff7084 --- /dev/null +++ b/extension/util.go @@ -0,0 +1,42 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package extension + +type clearFuncBuilder struct { + clears []func() +} + +// DoWithCollectClear executes a function and collect it clear function +func (b *clearFuncBuilder) DoWithCollectClear(fn func() (func(), error)) error { + clear, err := fn() + if err != nil { + return err + } + + if clear != nil { + b.clears = append(b.clears, clear) + } + + return nil +} + +// Build builds a clear function +func (b *clearFuncBuilder) Build() func() { + return func() { + for _, fn := range b.clears { + fn() + } + } +} diff --git a/go.mod b/go.mod index 853421bf23d5d..a11045833f165 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,11 @@ module github.com/pingcap/tidb go 1.19 require ( - cloud.google.com/go/storage v1.21.0 + cloud.google.com/go/storage v1.27.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v0.20.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.12.0 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.2.0 - github.com/BurntSushi/toml v1.2.0 + github.com/BurntSushi/toml v1.2.1 github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/Jeffail/gabs/v2 v2.5.1 github.com/Masterminds/semver v1.5.0 @@ -19,26 +20,27 @@ require ( github.com/charithe/durationcheck v0.0.9 github.com/cheggaaa/pb/v3 v3.0.8 github.com/cheynewallace/tabby v1.1.1 + github.com/cloudfoundry/gosigar v1.3.4 github.com/cockroachdb/errors v1.8.1 github.com/cockroachdb/pebble v0.0.0-20210719141320-8c3bd06debb5 github.com/coocood/freecache v1.2.1 github.com/coreos/go-semver v0.3.0 - github.com/daixiang0/gci v0.6.3 + github.com/daixiang0/gci v0.8.5 github.com/danjacques/gofslock v0.0.0-20191023191349-0a45f885bc37 - github.com/dgraph-io/ristretto v0.1.1-0.20220403145359-8e850b710d6d + github.com/dgraph-io/ristretto v0.1.1 github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 github.com/docker/go-units v0.4.0 github.com/emirpasic/gods v1.18.1 github.com/fatanugraha/noloopclosure v0.1.1 github.com/fatih/color v1.13.0 github.com/fsouza/fake-gcs-server v1.19.0 - github.com/go-sql-driver/mysql v1.6.0 + github.com/go-sql-driver/mysql v1.7.0 github.com/gogo/protobuf v1.3.2 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 github.com/golang/snappy v0.0.4 - github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a - github.com/golangci/golangci-lint v1.49.0 + github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 + github.com/golangci/golangci-lint v1.50.1 github.com/golangci/gosec v0.0.0-20180901114220-8afd9cbb6cfb github.com/golangci/misspell v0.3.5 github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 @@ -55,41 +57,46 @@ require ( github.com/jingyugao/rowserrcheck v1.1.1 github.com/joho/sqltocsv v0.0.0-20210428211105-a6d6801d59df github.com/kisielk/errcheck v1.6.2 - github.com/klauspost/compress v1.15.1 + github.com/klauspost/compress v1.15.13 github.com/kyoh86/exportloopref v0.1.8 + github.com/lestrrat-go/jwx/v2 v2.0.6 github.com/mgechev/revive v1.2.4 github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7 github.com/nishanths/predeclared v0.2.2 github.com/opentracing/basictracer-go v1.0.0 github.com/opentracing/opentracing-go v1.2.0 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 - github.com/pingcap/badger v1.5.1-0.20220314162537-ab58fbf40580 - github.com/pingcap/errors v0.11.5-0.20220729040631-518f63d66278 + github.com/pingcap/badger v1.5.1-0.20230103063557-828f39b09b6d + github.com/pingcap/errors v0.11.5-0.20221009092201-b66cddb77c32 github.com/pingcap/failpoint v0.0.0-20220423142525-ae43b7f4e5c3 github.com/pingcap/fn v0.0.0-20200306044125-d5540d389059 - github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c - github.com/pingcap/log v1.1.0 + github.com/pingcap/kvproto v0.0.0-20230119031034-25f1909b7934 + github.com/pingcap/log v1.1.1-0.20221116035753-734d527bc87c github.com/pingcap/sysutil v0.0.0-20220114020952-ea68d2dbf5b4 github.com/pingcap/tidb/parser v0.0.0-20211011031125-9b13dc409c5e - github.com/pingcap/tipb v0.0.0-20220824081009-0714a57aff1d + github.com/pingcap/tipb v0.0.0-20230119054146-c6b7a5a1623b github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.13.0 - github.com/prometheus/client_model v0.2.0 - github.com/prometheus/common v0.37.0 + github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_model v0.3.0 + github.com/prometheus/common v0.39.0 github.com/prometheus/prometheus v0.0.0-20190525122359-d20e84d0fb64 - github.com/shirou/gopsutil/v3 v3.22.7 + github.com/sasha-s/go-deadlock v0.2.0 + github.com/shirou/gopsutil/v3 v3.22.9 github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0 github.com/soheilhy/cmux v0.1.5 - github.com/spf13/cobra v1.5.0 + github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.0 + github.com/stathat/consistent v1.0.0 + github.com/stretchr/testify v1.8.1 github.com/tdakkota/asciicheck v0.1.1 github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 - github.com/tikv/client-go/v2 v2.0.1-0.20221012074856-6def8d7b90c4 - github.com/tikv/pd/client v0.0.0-20221010134149-d50e5fe43f14 + github.com/tikv/client-go/v2 v2.0.5-0.20230120021435-f89383775234 + github.com/tikv/pd v1.1.0-beta.0.20230119114149-402c2bfee2f3 + github.com/tikv/pd/client v0.0.0-20230119115149-5c518d079b93 github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 github.com/twmb/murmur3 v1.1.3 github.com/uber/jaeger-client-go v2.22.1+incompatible + github.com/vbauerster/mpb/v7 v7.5.3 github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f github.com/xitongsys/parquet-go v1.5.5-0.20201110004701-b09c49d6d457 github.com/xitongsys/parquet-go-source v0.0.0-20200817004010-026bad9b25d0 @@ -98,44 +105,46 @@ require ( go.etcd.io/etcd/client/v3 v3.5.2 go.etcd.io/etcd/server/v3 v3.5.2 go.etcd.io/etcd/tests/v3 v3.5.2 - go.opencensus.io v0.23.0 + go.opencensus.io v0.24.0 go.uber.org/atomic v1.10.0 go.uber.org/automaxprocs v1.4.0 go.uber.org/goleak v1.2.0 - go.uber.org/multierr v1.8.0 - go.uber.org/zap v1.21.0 - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e - golang.org/x/net v0.0.0-20220722155237-a158d28d115b - golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 - golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 - golang.org/x/text v0.3.7 - golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 - golang.org/x/tools v0.1.12 - google.golang.org/api v0.74.0 - google.golang.org/grpc v1.45.0 + go.uber.org/multierr v1.9.0 + go.uber.org/zap v1.24.0 + golang.org/x/exp v0.0.0-20221023144134-a1e5550cf13e + golang.org/x/net v0.5.0 + golang.org/x/oauth2 v0.3.0 + golang.org/x/sync v0.1.0 + golang.org/x/sys v0.4.0 + golang.org/x/term v0.4.0 + golang.org/x/text v0.6.0 + golang.org/x/time v0.3.0 + golang.org/x/tools v0.2.0 + google.golang.org/api v0.103.0 + google.golang.org/grpc v1.51.0 gopkg.in/yaml.v2 v2.4.0 honnef.co/go/tools v0.3.3 + k8s.io/apimachinery v0.26.0 sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 ) require ( - cloud.google.com/go v0.100.2 // indirect - cloud.google.com/go/compute v1.5.0 // indirect - cloud.google.com/go/iam v0.1.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v0.20.0 // indirect + cloud.google.com/go v0.105.0 // indirect + cloud.google.com/go/compute v1.13.0 // indirect + cloud.google.com/go/compute/metadata v0.2.1 // indirect + cloud.google.com/go/iam v0.7.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.1 // indirect github.com/DataDog/zstd v1.4.5 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect - github.com/VividCortex/ewma v1.1.1 // indirect + github.com/VividCortex/ewma v1.2.0 // indirect + github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect github.com/cockroachdb/redact v1.0.8 // indirect @@ -145,6 +154,7 @@ require ( github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/eapache/go-resiliency v1.2.0 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect @@ -155,10 +165,12 @@ require ( github.com/go-kit/kit v0.9.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/goccy/go-json v0.9.11 // indirect github.com/golang/glog v1.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/go-cmp v0.5.8 // indirect - github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect @@ -167,7 +179,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/gofork v1.0.0 // indirect @@ -179,11 +191,16 @@ require ( github.com/klauspost/cpuid v1.3.1 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/kr/text v0.2.0 // indirect + github.com/lestrrat-go/blackmagic v1.0.1 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc v1.0.4 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/option v1.0.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect @@ -191,21 +208,24 @@ require ( github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/petermattis/goid v0.0.0-20211229010228-4d14c490ee36 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect + github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712 // indirect github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 // indirect github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/tsdb v0.8.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/rivo/uniseg v0.4.2 // indirect github.com/rogpeppe/go-internal v1.6.1 // indirect github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect - github.com/shurcooL/vfsgen v0.0.0-20180711163814-62bca832be04 // indirect + github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd // indirect github.com/sirupsen/logrus v1.9.0 // indirect - github.com/stathat/consistent v1.0.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a // indirect github.com/tklauser/go-sysconf v0.3.10 // indirect github.com/tklauser/numcpus v0.4.0 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect @@ -226,16 +246,17 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect go.opentelemetry.io/otel/trace v0.20.0 // indirect go.opentelemetry.io/proto/otlp v0.7.0 // indirect - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect - golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + golang.org/x/crypto v0.5.0 // indirect + golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb // indirect + google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 3b5ae428f06fd..8bfacd2bddec7 100644 --- a/go.sum +++ b/go.sum @@ -27,35 +27,359 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0 h1:AYrLkB8NPdDRslNp4Jxmzrhdr03fUAIDbiGFjLWowoU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v0.1.1 h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68= -cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.21.0 h1:HwnT2u2D309SFDHQII6m18HlrCi3jAXhUMTLOWXYH14= -cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= @@ -70,8 +394,8 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.2.0 h1:62Ew5xXg5UCGIXDOM github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.2.0/go.mod h1:eHWhQKXc1Gv1DvWH//UzgWjWFEo0Pp4pH2vBzjBw8Fc= github.com/Azure/go-autorest v11.2.8+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= -github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= @@ -96,8 +420,11 @@ github.com/Shopify/sarama v1.29.0/go.mod h1:2QpgD79wpdAESqNQMxNc0KYMkycd4slxGdV3 github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= +github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= +github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -108,7 +435,6 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2c github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1581 h1:Q/yk4z/cHUVZfgTqtD09qeYBxHwshQAjVRX73qs8UH0= github.com/aliyun/alibaba-cloud-sdk-go v1.61.1581/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.0.0-20181112125854-24918abba929/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.1-0.20201008052519-daf620915714 h1:Jz3KVLYY5+JO7rDiX0sAuRGtuv2vG01r17Y9nLMWNUw= @@ -142,14 +468,16 @@ github.com/carlmjohnson/flagext v0.21.0/go.mod h1:Eenv0epIUAr4NuedNmkzI8WmBmjIxZ github.com/cenk/backoff v2.0.0+incompatible/go.mod h1:7FtoeaSnHoZnmZzz47cM35Y9nSW7tNyaidugnHTaFDE= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= @@ -162,6 +490,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudfoundry/gosigar v1.3.4 h1:T3MoGdugg1vdHn8Az7wDn7cZ4+QCjZph+eXf2CjSjo4= +github.com/cloudfoundry/gosigar v1.3.4/go.mod h1:g9r7ETZ1tpvJCT9TpqxO53+5BUZiM2FDSFSENzjK5Z8= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -169,6 +499,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68mZX1lGBkTWyp3CLcenw9I94W2dLeRvMzcn9N4= @@ -217,16 +548,19 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso= github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E= -github.com/daixiang0/gci v0.6.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/daixiang0/gci v0.8.5 h1:yBdsd376w+RIBvFXjj0MAcGWS8cSCfAlRNPfn5xvjl0= +github.com/daixiang0/gci v0.8.5/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= github.com/danjacques/gofslock v0.0.0-20191023191349-0a45f885bc37 h1:X6mKGhCFOxrKeeHAjv/3UvT6e5RRxW6wRdlqlV6/H4w= github.com/danjacques/gofslock v0.0.0-20191023191349-0a45f885bc37/go.mod h1:DC3JtzuG7kxMvJ6dZmf2ymjNyoXwgtklr7FN+Um2B0U= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/ristretto v0.1.1-0.20220403145359-8e850b710d6d h1:Wrc3UKTS+cffkOx0xRGFC+ZesNuTfn0ThvEC72N0krk= -github.com/dgraph-io/ristretto v0.1.1-0.20220403145359-8e850b710d6d/go.mod h1:RAy2GVV4sTWVlNMavv3xhLsk18rxhfhDnombTe6EF5c= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= @@ -258,6 +592,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE= @@ -309,7 +644,6 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -321,13 +655,15 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -385,10 +721,10 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.49.0 h1:I8WHOavragDttlLHtSraHn/h39C+R60bEQ5NoGcHQr8= -github.com/golangci/golangci-lint v1.49.0/go.mod h1:+V/7lLv449R6w9mQ3WdV0EKh7Je/jTylMeSwBZcLeWE= +github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= +github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= +github.com/golangci/golangci-lint v1.50.1 h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY= +github.com/golangci/golangci-lint v1.50.1/go.mod h1:AQjHBopYS//oB8xs0y0M/dtxdKHkdhl0RvmjUct0/4w= github.com/golangci/gosec v0.0.0-20180901114220-8afd9cbb6cfb h1:Bi7BYmZVg4C+mKGi8LeohcP2GGUl2XJD4xCkJoZSaYc= github.com/golangci/gosec v0.0.0-20180901114220-8afd9cbb6cfb/go.mod h1:ON/c2UR0VAAv6ZEAFKhjCLplESSmRFfZcDLASbI1GWo= github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= @@ -414,11 +750,13 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -446,13 +784,23 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gophercloud/gophercloud v0.0.0-20190301152420-fca40860790e/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= @@ -484,7 +832,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= @@ -526,8 +873,9 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb v0.0.0-20170331210902-15e594fc09f1/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= @@ -603,8 +951,8 @@ github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.13 h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0= +github.com/klauspost/compress v1.15.13/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= @@ -624,6 +972,18 @@ github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77 github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= +github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8= +github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= +github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx/v2 v2.0.6 h1:RlyYNLV892Ed7+FTfj1ROoF6x7WxL965PGTHso/60G0= +github.com/lestrrat-go/jwx/v2 v2.0.6/go.mod h1:aVrGuwEr3cp2Prw6TtQvr8sQxe+84gruID5C9TxT64Q= +github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -647,11 +1007,13 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxatome/go-testdeep v1.11.0 h1:Tgh5efyCYyJFGUYiT0qxBSIDeXw0F5zSoatlou685kk= github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= @@ -712,7 +1074,7 @@ github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1ls github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/opentracing-contrib/go-stdlib v0.0.0-20170113013457-1de4cc2120e7/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= @@ -731,22 +1093,25 @@ github.com/pborman/getopt v0.0.0-20180729010549-6fdd0a2c7117/go.mod h1:85jBQOZwp github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/g2s v0.0.0-20170223122336-d4e7ad98afea/go.mod h1:1VcHEd3ro4QMoHfiNl/j7Jkln9+KQuorp0PItHMJYNg= github.com/petermattis/goid v0.0.0-20170504144140-0ded85884ba5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20211229010228-4d14c490ee36 h1:64bxqeTEN0/xoEqhKGowgihNuzISS9rEG6YUMU4bzJo= +github.com/petermattis/goid v0.0.0-20211229010228-4d14c490ee36/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pingcap/badger v1.5.1-0.20220314162537-ab58fbf40580 h1:MKVFZuqFvAMiDtv3AbihOQ6rY5IE8LWflI1BuZ/hF0Y= -github.com/pingcap/badger v1.5.1-0.20220314162537-ab58fbf40580/go.mod h1:upwDfet29M5y5koWilbWWA6ca3Lr0YVuzwX/DK58Vdk= +github.com/pingcap/badger v1.5.1-0.20230103063557-828f39b09b6d h1:AEcvKyVM8CUII3bYzgz8haFXtGiqcrtXW1csu/5UELY= +github.com/pingcap/badger v1.5.1-0.20230103063557-828f39b09b6d/go.mod h1:p8QnkZnmyV8L/M/jzYb8rT7kv3bz9m7bn1Ju94wDifs= github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ= -github.com/pingcap/check v0.0.0-20191107115940-caf2b9e6ccf4 h1:iRtOAQ6FXkY/BGvst3CDfTva4nTqh6CL8WXvanLdbu0= github.com/pingcap/check v0.0.0-20191107115940-caf2b9e6ccf4/go.mod h1:PYMCGwN0JHjoqGr3HrZoD+b8Tgx8bKnArhSq8YVzUMc= +github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712 h1:R8gStypOBmpnHEx1qi//SaqxJVI4inOqljg/Aj5/390= +github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712/go.mod h1:PYMCGwN0JHjoqGr3HrZoD+b8Tgx8bKnArhSq8YVzUMc= github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pingcap/errors v0.11.5-0.20190809092503-95897b64e011/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= -github.com/pingcap/errors v0.11.5-0.20220729040631-518f63d66278 h1:3Dm0DWeQlwV8LbpQxP2tojHhxd9aY59KI+QN0ns6bBo= -github.com/pingcap/errors v0.11.5-0.20220729040631-518f63d66278/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= +github.com/pingcap/errors v0.11.5-0.20221009092201-b66cddb77c32 h1:m5ZsBa5o/0CkzZXfXLaThzKuR85SnHHetqBCpzQ30h8= +github.com/pingcap/errors v0.11.5-0.20221009092201-b66cddb77c32/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew= github.com/pingcap/failpoint v0.0.0-20220423142525-ae43b7f4e5c3 h1:kJolJWbyadVeL8RKBlqmXQR7FRKPsIeU85TUYyhbhiQ= github.com/pingcap/failpoint v0.0.0-20220423142525-ae43b7f4e5c3/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew= @@ -755,19 +1120,18 @@ github.com/pingcap/fn v0.0.0-20200306044125-d5540d389059/go.mod h1:fMRU1BA1y+r89 github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 h1:surzm05a8C9dN8dIUmo4Be2+pMRb6f55i+UIYrluu2E= github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20191211054548-3c6b38ea5107/go.mod h1:WWLmULLO7l8IOcQG+t+ItJ3fEcrL5FxF0Wu+HrMy26w= -github.com/pingcap/kvproto v0.0.0-20220818063303-5c20f55db5ad/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= -github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c h1:ceg4xjEEXNgPsScTQ5dtidiltLF4h17Y/jUqfyLAy9E= -github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= +github.com/pingcap/kvproto v0.0.0-20230119031034-25f1909b7934 h1:LB+BrfyO5fsz5pwN3V4HvTrpZTAmsjB4VkCEBLbjYUw= +github.com/pingcap/kvproto v0.0.0-20230119031034-25f1909b7934/go.mod h1:+on3Lfk/fb1lXkud3XvskJumhSIEEgN2TTbMObUlrxE= github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= -github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM= -github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= -github.com/pingcap/log v1.1.0 h1:ELiPxACz7vdo1qAvvaWJg1NrYFoY6gqAh/+Uo6aXdD8= github.com/pingcap/log v1.1.0/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= +github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= +github.com/pingcap/log v1.1.1-0.20221116035753-734d527bc87c h1:crhkw6DD+07Bg1wYhW5Piw+kYNKZqFQqfC2puUf6gMI= +github.com/pingcap/log v1.1.1-0.20221116035753-734d527bc87c/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pingcap/sysutil v0.0.0-20220114020952-ea68d2dbf5b4 h1:HYbcxtnkN3s5tqrZ/z3eJS4j3Db8wMphEm1q10lY/TM= github.com/pingcap/sysutil v0.0.0-20220114020952-ea68d2dbf5b4/go.mod h1:sDCsM39cGiv2vwunZkaFA917vVkqDTGSPbbV7z4Oops= -github.com/pingcap/tipb v0.0.0-20220824081009-0714a57aff1d h1:kWYridgsn8xSKYJ2EkXp7uj5HwJnG5snpY3XP8oYmPU= -github.com/pingcap/tipb v0.0.0-20220824081009-0714a57aff1d/go.mod h1:A7mrd7WHBl1o63LE2bIBGEJMTNWXqhgmYiOvMLxozfs= +github.com/pingcap/tipb v0.0.0-20230119054146-c6b7a5a1623b h1:j5sw2YZY7QfgIFZEoUcn1P5cYflms1PCVVS96i+IQiI= +github.com/pingcap/tipb v0.0.0-20230119054146-c6b7a5a1623b/go.mod h1:A7mrd7WHBl1o63LE2bIBGEJMTNWXqhgmYiOvMLxozfs= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -786,31 +1150,29 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/prometheus v0.0.0-20190525122359-d20e84d0fb64 h1:3DyLm+sTAJkfLyR/1pJ3L+fU2lFufWbpcgMFlGtqeyA= github.com/prometheus/prometheus v0.0.0-20190525122359-d20e84d0fb64/go.mod h1:oYrT4Vs22/NcnoVYXt5m4cIHP+znvgyusahVpyETKTw= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -838,13 +1200,15 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20161028232340-1d7be4effb13/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.0.0-20161201235124-341000892f3d/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10= +github.com/sasha-s/go-deadlock v0.2.0 h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y= +github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil/v3 v3.21.12/go.mod h1:BToYZVTlSVlfazpDDYFnsVZLaoRG+g8ufT6fPQLdJzA= -github.com/shirou/gopsutil/v3 v3.22.7 h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4= -github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= +github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= +github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= @@ -852,8 +1216,9 @@ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJ github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0 h1:mj/nMDAwTBiaCqMEs4cYCqF7pO6Np7vhy1D1wcQGz+E= github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20180711163814-62bca832be04 h1:y0cMJ0qjii33BnD6tMGcF/+gHYsoKQ6tbwQpy233OII= github.com/shurcooL/vfsgen v0.0.0-20180711163814-62bca832be04/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -866,15 +1231,16 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -886,6 +1252,7 @@ github.com/stathat/consistent v1.0.0/go.mod h1:uajTPbgSygZBJ+V+0mY7meZ8i0XAcZs7A github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -894,8 +1261,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= @@ -905,10 +1273,14 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= -github.com/tikv/client-go/v2 v2.0.1-0.20221012074856-6def8d7b90c4 h1:/13jzD/AR7v3dCLweFQ2JG8bihh3HLVIci2tbOHHGW0= -github.com/tikv/client-go/v2 v2.0.1-0.20221012074856-6def8d7b90c4/go.mod h1:gdXot2ofS2EOGtrXQ2qyESonQX/gFmgtfBCqCOSWg9E= -github.com/tikv/pd/client v0.0.0-20221010134149-d50e5fe43f14 h1:REQOR1XraH1fT9BCoNBPZs1CAe+w7VPLU+d+si7DLYo= -github.com/tikv/pd/client v0.0.0-20221010134149-d50e5fe43f14/go.mod h1:E/7+Fkqzwsrp4duzJ2gLPqFl6awU7QG+5yFRXaQwimM= +github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a h1:J/YdBZ46WKpXsxsW93SG+q0F8KI+yFrcIDT4c/RNoc4= +github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a/go.mod h1:h4xBhSNtOeEosLJ4P7JyKXX7Cabg7AVkWCK5gV2vOrM= +github.com/tikv/client-go/v2 v2.0.5-0.20230120021435-f89383775234 h1:2BmijiUk1Hcv0z58DVk4ypwaNmgutzLc2YJm0SHPEWE= +github.com/tikv/client-go/v2 v2.0.5-0.20230120021435-f89383775234/go.mod h1:jc7J2EbNeVvU6eXmB50wAGrTPyJwdi+0ENccMXMFSpw= +github.com/tikv/pd v1.1.0-beta.0.20230119114149-402c2bfee2f3 h1:cj3bhdIBJcLL2304EDEmd3eX+r73+hbGSYRFn/APiDU= +github.com/tikv/pd v1.1.0-beta.0.20230119114149-402c2bfee2f3/go.mod h1:IFQZ85uu1438yp7Tb0xCgvw/BdSPReB9zcJsxXbyTP4= +github.com/tikv/pd/client v0.0.0-20230119115149-5c518d079b93 h1:KK5bx0KLcpYUCnuQ06THPYT6QdAMfvwAtRQ0saVGD7k= +github.com/tikv/pd/client v0.0.0-20230119115149-5c518d079b93/go.mod h1:NrbwVp9afaCmJjJEwFNtEQWfCChAW1ndnwjteHHS+d0= github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= @@ -933,6 +1305,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vbauerster/mpb/v7 v7.5.3 h1:BkGfmb6nMrrBQDFECR/Q7RkKCw7ylMetCb4079CGs4w= +github.com/vbauerster/mpb/v7 v7.5.3/go.mod h1:i+h4QY6lmLvBNK2ah1fSreiw3ajskRlBp9AhY/PnuOE= github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f h1:9DDCDwOyEy/gId+IEMrFHLuQ5R/WV0KNxWLler8X2OY= github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f/go.mod h1:8sdOQnirw1PrcnTJYkmW1iOHtUmblMmGdUOHyWYycLI= github.com/xdg/scram v1.0.3/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= @@ -959,6 +1333,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1024,8 +1399,9 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -1033,8 +1409,9 @@ go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.20.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1052,8 +1429,9 @@ golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1068,10 +1446,10 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp v0.0.0-20221023144134-a1e5550cf13e h1:SkwG94eNiiYJhbeDE018Grw09HIN/KB9NlRmZsrzfWs= +golang.org/x/exp v0.0.0-20221023144134-a1e5550cf13e/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk= +golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1101,8 +1479,9 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1124,7 +1503,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1152,15 +1530,25 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210427231257-85d9c07bbe3a/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1179,8 +1567,15 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= +golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1192,8 +1587,11 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1275,19 +1673,31 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI= -golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1296,15 +1706,20 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1380,14 +1795,18 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= @@ -1425,14 +1844,27 @@ google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= -google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1450,7 +1882,6 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -1483,6 +1914,7 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -1504,20 +1936,53 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd h1:OjndDrsik+Gt+e6fs45z9AxiewiKyLKYpA45W5Kpkks= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= google.golang.org/grpc v0.0.0-20180607172857-7a6a684ca69e/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1548,10 +2013,17 @@ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1566,6 +2038,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1580,6 +2053,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/fsnotify/fsnotify.v1 v1.3.1/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -1619,6 +2093,8 @@ honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg= +k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/kube-openapi v0.0.0-20180629012420-d83b052f768a/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= @@ -1628,8 +2104,9 @@ rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI= diff --git a/infoschema/BUILD.bazel b/infoschema/BUILD.bazel index fb8abc3b33938..a92608a8df1b3 100644 --- a/infoschema/BUILD.bazel +++ b/infoschema/BUILD.bazel @@ -50,8 +50,12 @@ go_library( "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_kvproto//pkg/diagnosticspb", "@com_github_pingcap_kvproto//pkg/metapb", + "@com_github_pingcap_log//:log", "@com_github_tikv_client_go_v2//tikv", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials", "@org_golang_x_exp//slices", "@org_uber_go_zap//:zap", ], @@ -93,23 +97,30 @@ go_test( "//store/helper", "//store/mockstore", "//store/mockstore/mockstorage", + "//store/mockstore/unistore", "//table", "//testkit", + "//testkit/external", "//testkit/testsetup", "//testkit/testutil", "//types", "//util", + "//util/gctuner", + "//util/memory", "//util/pdapi", "//util/resourcegrouptag", "//util/set", + "//util/stmtsummary", "@com_github_gorilla_mux//:mux", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_fn//:fn", "@com_github_pingcap_kvproto//pkg/deadlock", + "@com_github_pingcap_kvproto//pkg/metapb", "@com_github_pingcap_tipb//go-tipb", "@com_github_prometheus_prometheus//promql", "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//testutils", "@org_golang_google_grpc//:grpc", "@org_uber_go_goleak//:goleak", ], diff --git a/infoschema/builder.go b/infoschema/builder.go index cb1a0edac8b01..a1ac015ec0bfa 100644 --- a/infoschema/builder.go +++ b/infoschema/builder.go @@ -199,6 +199,8 @@ func (b *Builder) ApplyDiff(m *meta.Meta, diff *model.SchemaDiff) ([]int64, erro return nil, b.applyCreateSchema(m, diff) case model.ActionDropSchema: return b.applyDropSchema(diff.SchemaID), nil + case model.ActionRecoverSchema: + return b.applyRecoverSchema(m, diff) case model.ActionModifySchemaCharsetAndCollate: return nil, b.applyModifySchemaCharsetAndCollate(m, diff) case model.ActionModifySchemaDefaultPlacement: @@ -209,14 +211,25 @@ func (b *Builder) ApplyDiff(m *meta.Meta, diff *model.SchemaDiff) ([]int64, erro return b.applyDropPolicy(diff.SchemaID), nil case model.ActionAlterPlacementPolicy: return b.applyAlterPolicy(m, diff) + case model.ActionCreateResourceGroup: + return nil, b.applyCreateOrAlterResourceGroup(m, diff) + case model.ActionAlterResourceGroup: + return nil, b.applyCreateOrAlterResourceGroup(m, diff) + case model.ActionDropResourceGroup: + return b.applyDropResourceGroup(m, diff), nil case model.ActionTruncateTablePartition, model.ActionTruncateTable: return b.applyTruncateTableOrPartition(m, diff) case model.ActionDropTable, model.ActionDropTablePartition: - return b.applyDropTableOrParition(m, diff) + return b.applyDropTableOrPartition(m, diff) case model.ActionRecoverTable: return b.applyRecoverTable(m, diff) case model.ActionCreateTables: return b.applyCreateTables(m, diff) + case model.ActionReorganizePartition: + // TODO: How to test? + return b.applyReorganizePartition(m, diff) + case model.ActionFlashbackCluster: + return []int64{-1}, nil default: return b.applyDefaultAction(m, diff) } @@ -265,7 +278,7 @@ func (b *Builder) applyTruncateTableOrPartition(m *meta.Meta, diff *model.Schema return tblIDs, nil } -func (b *Builder) applyDropTableOrParition(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) { +func (b *Builder) applyDropTableOrPartition(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) { tblIDs, err := b.applyTableUpdate(m, diff) if err != nil { return nil, errors.Trace(err) @@ -277,6 +290,24 @@ func (b *Builder) applyDropTableOrParition(m *meta.Meta, diff *model.SchemaDiff) return tblIDs, nil } +// TODO: How to test this? +func (b *Builder) applyReorganizePartition(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) { + // Is this needed? Since there should be no difference more than partition changes? + tblIDs, err := b.applyTableUpdate(m, diff) + if err != nil { + return nil, errors.Trace(err) + } + for _, opt := range diff.AffectedOpts { + if opt.OldTableID != 0 { + b.deleteBundle(b.is, opt.OldTableID) + } + if opt.TableID != 0 { + b.markTableBundleShouldUpdate(opt.TableID) + } + } + return tblIDs, nil +} + func (b *Builder) applyRecoverTable(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) { tblIDs, err := b.applyTableUpdate(m, diff) if err != nil { @@ -497,13 +528,36 @@ func (b *Builder) copySortedTables(oldTableID, newTableID int64) { } } +func (b *Builder) applyCreateOrAlterResourceGroup(m *meta.Meta, diff *model.SchemaDiff) error { + group, err := m.GetResourceGroup(diff.SchemaID) + if err != nil { + return errors.Trace(err) + } + if group == nil { + return ErrResourceGroupNotExists.GenWithStackByArgs(fmt.Sprintf("(Group ID %d)", diff.SchemaID)) + } + // TODO: need mark updated? + b.is.setResourceGroup(group) + return nil +} + +func (b *Builder) applyDropResourceGroup(m *meta.Meta, diff *model.SchemaDiff) []int64 { + group, ok := b.is.ResourceGroupByID(diff.SchemaID) + if !ok { + return nil + } + b.is.deleteResourceGroup(group.Name.L) + // TODO: return the related information. + return []int64{} +} + func (b *Builder) applyCreatePolicy(m *meta.Meta, diff *model.SchemaDiff) error { po, err := m.GetPolicy(diff.SchemaID) if err != nil { return errors.Trace(err) } if po == nil { - return ErrPlacementPolicyExists.GenWithStackByArgs( + return ErrPlacementPolicyNotExists.GenWithStackByArgs( fmt.Sprintf("(Policy ID %d)", diff.SchemaID), ) } @@ -525,7 +579,7 @@ func (b *Builder) applyAlterPolicy(m *meta.Meta, diff *model.SchemaDiff) ([]int6 } if po == nil { - return nil, ErrPlacementPolicyExists.GenWithStackByArgs( + return nil, ErrPlacementPolicyNotExists.GenWithStackByArgs( fmt.Sprintf("(Policy ID %d)", diff.SchemaID), ) } @@ -622,6 +676,23 @@ func (b *Builder) applyDropSchema(schemaID int64) []int64 { return tableIDs } +func (b *Builder) applyRecoverSchema(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) { + if di, ok := b.is.SchemaByID(diff.SchemaID); ok { + return nil, ErrDatabaseExists.GenWithStackByArgs( + fmt.Sprintf("(Schema ID %d)", di.ID), + ) + } + di, err := m.GetDatabase(diff.SchemaID) + if err != nil { + return nil, errors.Trace(err) + } + b.is.schemaMap[di.Name.L] = &schemaTables{ + dbInfo: di, + tables: make(map[string]table.Table, len(diff.AffectedOpts)), + } + return b.applyCreateTables(m, diff) +} + func (b *Builder) copySortedTablesBucket(bucketIdx int) { oldSortedTables := b.is.sortedTablesBuckets[bucketIdx] newSortedTables := make(sortedTables, len(oldSortedTables)) @@ -646,6 +717,8 @@ func (b *Builder) applyCreateTable(m *meta.Meta, dbInfo *model.DBInfo, tableID i switch tp { case model.ActionDropTablePartition: case model.ActionTruncateTablePartition: + // ReorganizePartition handle the bundles in applyReorganizePartition + case model.ActionReorganizePartition: default: pi := tblInfo.GetPartitionInfo() if pi != nil { @@ -672,17 +745,23 @@ func (b *Builder) applyCreateTable(m *meta.Meta, dbInfo *model.DBInfo, tableID i ConvertCharsetCollateToLowerCaseIfNeed(tblInfo) ConvertOldVersionUTF8ToUTF8MB4IfNeed(tblInfo) - if len(allocs) == 0 { + if len(allocs.Allocs) == 0 { allocs = autoid.NewAllocatorsFromTblInfo(b.store, dbInfo.ID, tblInfo) } else { tblVer := autoid.AllocOptionTableInfoVersion(tblInfo.Version) switch tp { case model.ActionRebaseAutoID, model.ActionModifyTableAutoIdCache: - newAlloc := autoid.NewAllocator(b.store, dbInfo.ID, tblInfo.ID, tblInfo.IsAutoIncColUnsigned(), autoid.RowIDAllocType, tblVer) - allocs = append(allocs, newAlloc) + idCacheOpt := autoid.CustomAutoIncCacheOption(tblInfo.AutoIdCache) + // If the allocator type might be AutoIncrementType, create both AutoIncrementType + // and RowIDAllocType allocator for it. Because auto id and row id could share the same allocator. + // Allocate auto id may route to allocate row id, if row id allocator is nil, the program panic! + for _, tp := range [2]autoid.AllocatorType{autoid.AutoIncrementType, autoid.RowIDAllocType} { + newAlloc := autoid.NewAllocator(b.store, dbInfo.ID, tblInfo.ID, tblInfo.IsAutoIncColUnsigned(), tp, tblVer, idCacheOpt) + allocs = allocs.Append(newAlloc) + } case model.ActionRebaseAutoRandomBase: newAlloc := autoid.NewAllocator(b.store, dbInfo.ID, tblInfo.ID, tblInfo.IsAutoRandomBitColUnsigned(), autoid.AutoRandomType, tblVer) - allocs = append(allocs, newAlloc) + allocs = allocs.Append(newAlloc) case model.ActionModifyColumn: // Change column attribute from auto_increment to auto_random. if tblInfo.ContainsAutoRandomBits() && allocs.Get(autoid.AutoRandomType) == nil { @@ -691,7 +770,7 @@ func (b *Builder) applyCreateTable(m *meta.Meta, dbInfo *model.DBInfo, tableID i return a.GetType() != autoid.AutoIncrementType && a.GetType() != autoid.RowIDAllocType }) newAlloc := autoid.NewAllocator(b.store, dbInfo.ID, tblInfo.ID, tblInfo.IsAutoRandomBitColUnsigned(), autoid.AutoRandomType, tblVer) - allocs = append(allocs, newAlloc) + allocs = allocs.Append(newAlloc) } } } @@ -802,6 +881,7 @@ func (b *Builder) InitWithOldInfoSchema(oldSchema InfoSchema) *Builder { b.copySchemasMap(oldIS) b.copyBundlesMap(oldIS) b.copyPoliciesMap(oldIS) + b.copyResourceGroupMap(oldIS) b.copyTemporaryTableIDsMap(oldIS) b.copyReferredForeignKeyMap(oldIS) @@ -829,6 +909,13 @@ func (b *Builder) copyPoliciesMap(oldIS *infoSchema) { } } +func (b *Builder) copyResourceGroupMap(oldIS *infoSchema) { + is := b.is + for _, v := range oldIS.AllResourceGroups() { + is.resourceGroupMap[v.Name.L] = v + } +} + func (b *Builder) copyTemporaryTableIDsMap(oldIS *infoSchema) { is := b.is if len(oldIS.temporaryTableIDs) == 0 { @@ -870,7 +957,7 @@ func (b *Builder) getSchemaAndCopyIfNecessary(dbName string) *model.DBInfo { } // InitWithDBInfos initializes an empty new InfoSchema with a slice of DBInfo, all placement rules, and schema version. -func (b *Builder) InitWithDBInfos(dbInfos []*model.DBInfo, policies []*model.PolicyInfo, schemaVersion int64) (*Builder, error) { +func (b *Builder) InitWithDBInfos(dbInfos []*model.DBInfo, policies []*model.PolicyInfo, resourceGroups []*model.ResourceGroupInfo, schemaVersion int64) (*Builder, error) { info := b.is info.schemaMetaVersion = schemaVersion // build the policies. @@ -878,6 +965,11 @@ func (b *Builder) InitWithDBInfos(dbInfos []*model.DBInfo, policies []*model.Pol info.setPolicy(policy) } + // build the groups. + for _, group := range resourceGroups { + info.setResourceGroup(group) + } + // Maintain foreign key reference information. for _, di := range dbInfos { for _, t := range di.Tables { @@ -981,6 +1073,7 @@ func NewBuilder(store kv.Storage, factory func() (pools.Resource, error)) *Build is: &infoSchema{ schemaMap: map[string]*schemaTables{}, policyMap: map[string]*model.PolicyInfo{}, + resourceGroupMap: map[string]*model.ResourceGroupInfo{}, ruleBundleMap: map[int64]*placement.Bundle{}, sortedTablesBuckets: make([]sortedTables, bucketCount), referredForeignKeyMap: make(map[SchemaAndTableName][]*model.ReferredFKInfo), diff --git a/infoschema/cache.go b/infoschema/cache.go index 22ea012a9be28..34cc08eca2231 100644 --- a/infoschema/cache.go +++ b/infoschema/cache.go @@ -43,8 +43,15 @@ type InfoCache struct { } // NewCache creates a new InfoCache. -func NewCache(capcity int) *InfoCache { - return &InfoCache{cache: make([]InfoSchema, 0, capcity)} +func NewCache(capacity int) *InfoCache { + return &InfoCache{cache: make([]InfoSchema, 0, capacity)} +} + +// Reset resets the cache. +func (h *InfoCache) Reset(capacity int) { + h.mu.Lock() + defer h.mu.Unlock() + h.cache = make([]InfoSchema, 0, capacity) } // GetLatest gets the newest information schema. diff --git a/infoschema/cluster.go b/infoschema/cluster.go index 47bb7db4c3434..2977c1c770144 100644 --- a/infoschema/cluster.go +++ b/infoschema/cluster.go @@ -27,9 +27,10 @@ import ( "github.com/pingcap/tidb/util/sem" ) +// Cluster table indicates that these tables need to get data from other tidb nodes, which may get from all other nodes, or may get from the ddl owner. // Cluster table list, attention: // 1. the table name should be upper case. -// 2. clusterTableName should equal to "CLUSTER_" + memTableTableName. +// 2. For tables that need to get data from all other TiDB nodes, clusterTableName should equal to "CLUSTER_" + memTableTableName. const ( // ClusterTableSlowLog is the string constant of cluster slow query memory table. ClusterTableSlowLog = "CLUSTER_SLOW_QUERY" @@ -46,10 +47,14 @@ const ( ClusterTableDeadlocks = "CLUSTER_DEADLOCKS" // ClusterTableDeadlocks is the string constant of cluster transaction summary table. ClusterTableTrxSummary = "CLUSTER_TRX_SUMMARY" + // ClusterTableMemoryUsage is the memory usage status of tidb cluster. + ClusterTableMemoryUsage = "CLUSTER_MEMORY_USAGE" + // ClusterTableMemoryUsageOpsHistory is the memory control operators history of tidb cluster. + ClusterTableMemoryUsageOpsHistory = "CLUSTER_MEMORY_USAGE_OPS_HISTORY" ) -// memTableToClusterTables means add memory table to cluster table. -var memTableToClusterTables = map[string]string{ +// memTableToAllTiDBClusterTables means add memory table to cluster table that will send cop request to all TiDB nodes. +var memTableToAllTiDBClusterTables = map[string]string{ TableSlowQuery: ClusterTableSlowLog, TableProcesslist: ClusterTableProcesslist, TableStatementsSummary: ClusterTableStatementsSummary, @@ -58,11 +63,36 @@ var memTableToClusterTables = map[string]string{ TableTiDBTrx: ClusterTableTiDBTrx, TableDeadlocks: ClusterTableDeadlocks, TableTrxSummary: ClusterTableTrxSummary, + TableMemoryUsage: ClusterTableMemoryUsage, + TableMemoryUsageOpsHistory: ClusterTableMemoryUsageOpsHistory, +} + +// memTableToDDLOwnerClusterTables means add memory table to cluster table that will send cop request to DDL owner node. +var memTableToDDLOwnerClusterTables = map[string]string{ + TableTiFlashReplica: TableTiFlashReplica, +} + +// ClusterTableCopDestination means the destination that cluster tables will send cop requests to. +type ClusterTableCopDestination int + +const ( + // AllTiDB is uese by CLUSTER_* table, means that these tables will send cop request to all TiDB nodes. + AllTiDB ClusterTableCopDestination = iota + // DDLOwner is uese by tiflash_replica currently, means that this table will send cop request to DDL owner node. + DDLOwner +) + +// GetClusterTableCopDestination gets cluster table cop request destination. +func GetClusterTableCopDestination(tableName string) ClusterTableCopDestination { + if _, exist := memTableToDDLOwnerClusterTables[strings.ToUpper(tableName)]; exist { + return DDLOwner + } + return AllTiDB } func init() { var addrCol = columnInfo{name: util.ClusterTableInstanceColumnName, tp: mysql.TypeVarchar, size: 64} - for memTableName, clusterMemTableName := range memTableToClusterTables { + for memTableName, clusterMemTableName := range memTableToAllTiDBClusterTables { memTableCols := tableNameToColumns[memTableName] if len(memTableCols) == 0 { continue @@ -80,7 +110,13 @@ func isClusterTableByName(dbName, tableName string) bool { switch dbName { case util.InformationSchemaName.O, util.PerformanceSchemaName.O: tableName = strings.ToUpper(tableName) - for _, name := range memTableToClusterTables { + for _, name := range memTableToAllTiDBClusterTables { + name = strings.ToUpper(name) + if name == tableName { + return true + } + } + for _, name := range memTableToDDLOwnerClusterTables { name = strings.ToUpper(name) if name == tableName { return true diff --git a/infoschema/cluster_tables_test.go b/infoschema/cluster_tables_test.go index 5e323b2adc88a..781f52bebe519 100644 --- a/infoschema/cluster_tables_test.go +++ b/infoschema/cluster_tables_test.go @@ -31,6 +31,7 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/fn" "github.com/pingcap/kvproto/pkg/deadlock" + "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" @@ -40,16 +41,20 @@ import ( "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/server" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/store/helper" + "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/store/mockstore/mockstorage" + "github.com/pingcap/tidb/store/mockstore/unistore" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/testkit/external" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/pdapi" "github.com/pingcap/tidb/util/resourcegrouptag" "github.com/pingcap/tidb/util/set" + "github.com/pingcap/tidb/util/stmtsummary" "github.com/pingcap/tipb/go-tipb" "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/testutils" "google.golang.org/grpc" ) @@ -811,10 +816,6 @@ func (s *clusterTablesSuite) newTestKitWithRoot(t *testing.T) *testkit.TestKit { } func TestMDLView(t *testing.T) { - if !variable.EnableConcurrentDDL.Load() { - t.Skipf("test requires concurrent ddl") - } - // setup suite s := new(clusterTablesSuite) s.store, s.dom = testkit.CreateMockStoreAndDomain(t) @@ -852,3 +853,392 @@ func TestMDLView(t *testing.T) { wg.Wait() } + +func TestCreateBindingFromHistory(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t1(id int primary key, a int, b int, key(a))") + tk.MustExec("create table t2(id int primary key, a int, b int, key(a))") + + var testCases = []struct { + sqls []string + hint string + }{ + { + sqls: []string{ + "select %s * from t1, t2 where t1.id = t2.id", + "select %s * from test.t1, t2 where t1.id = t2.id", + "select %s * from test.t1, test.t2 where t1.id = t2.id", + "select %s * from t1, test.t2 where t1.id = t2.id", + }, + hint: "/*+ merge_join(t1, t2) */", + }, + { + sqls: []string{ + "select %s * from t1 where a = 1", + "select %s * from test.t1 where a = 1", + }, + hint: "/*+ ignore_index(t, a) */", + }, + } + + for _, testCase := range testCases { + for _, bind := range testCase.sqls { + stmtsummary.StmtSummaryByDigestMap.Clear() + bindSQL := fmt.Sprintf(bind, testCase.hint) + tk.MustExec(bindSQL) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", bindSQL)).Rows() + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + showRes := tk.MustQuery("show bindings").Rows() + require.Equal(t, len(showRes), 1) + require.Equal(t, planDigest[0][0], showRes[0][10]) + for _, sql := range testCase.sqls { + tk.MustExec(fmt.Sprintf(sql, "")) + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + } + } + showRes := tk.MustQuery("show bindings").Rows() + require.Equal(t, len(showRes), 1) + tk.MustExec(fmt.Sprintf("drop binding for sql digest '%s'", showRes[0][9])) + } + + // exception cases + tk.MustGetErrMsg(fmt.Sprintf("create binding from history using plan digest '%s'", "1"), "can't find any plans for '1'") + tk.MustGetErrMsg(fmt.Sprintf("create binding from history using plan digest '%s'", ""), "plan digest is empty") + tk.MustExec("create binding for select * from t1, t2 where t1.id = t2.id using select /*+ merge_join(t1, t2) */ * from t1, t2 where t1.id = t2.id") + showRes := tk.MustQuery("show bindings").Rows() + require.Equal(t, showRes[0][10], "") // plan digest should be nil by create for +} + +func TestCreateBindingForPrepareFromHistory(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int primary key, a int, key(a))") + + tk.MustExec("prepare stmt from 'select /*+ ignore_index(t,a) */ * from t where a = ?'") + tk.MustExec("set @a = 1") + tk.MustExec("execute stmt using @a") + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", "select /*+ ignore_index(t,a) */ * from t where a = ? [arguments: 1]")).Rows() + showRes := tk.MustQuery("show bindings").Rows() + require.Equal(t, len(showRes), 0) + tk.MustExec(fmt.Sprintf("create binding from history using plan digest '%s'", planDigest[0][0])) + showRes = tk.MustQuery("show bindings").Rows() + require.Equal(t, len(showRes), 1) + require.Equal(t, planDigest[0][0], showRes[0][10]) + tk.MustExec("execute stmt using @a") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) +} + +func TestErrorCasesCreateBindingFromHistory(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2, t3") + tk.MustExec("create table t1(id int)") + tk.MustExec("create table t2(id int)") + tk.MustExec("create table t3(id int)") + + sql := "select * from t1 where t1.id in (select id from t2)" + tk.MustExec(sql) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustGetErrMsg(fmt.Sprintf("create binding from history using plan digest '%s'", planDigest[0][0]), "can't create binding for query with sub query") + + sql = "select * from t1, t2, t3 where t1.id = t2.id and t2.id = t3.id" + tk.MustExec(sql) + planDigest = tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustGetErrMsg(fmt.Sprintf("create binding from history using plan digest '%s'", planDigest[0][0]), "can't create binding for query with more than two table join") +} + +// withMockTiFlash sets the mockStore to have N TiFlash stores (naming as tiflash0, tiflash1, ...). +func withMockTiFlash(nodes int) mockstore.MockTiKVStoreOption { + return mockstore.WithMultipleOptions( + mockstore.WithClusterInspector(func(c testutils.Cluster) { + mockCluster := c.(*unistore.Cluster) + _, _, region1 := mockstore.BootstrapWithSingleStore(c) + tiflashIdx := 0 + for tiflashIdx < nodes { + store2 := c.AllocID() + peer2 := c.AllocID() + addr2 := fmt.Sprintf("tiflash%d", tiflashIdx) + mockCluster.AddStore(store2, addr2, &metapb.StoreLabel{Key: "engine", Value: "tiflash"}) + mockCluster.AddPeer(region1, store2, peer2) + tiflashIdx++ + } + }), + mockstore.WithStoreType(mockstore.EmbedUnistore), + ) +} + +func TestBindingFromHistoryWithTiFlashBindable(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.store = testkit.CreateMockStore(t, withMockTiFlash(2)) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test;") + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t(a int);") + tk.MustExec("alter table test.t set tiflash replica 1") + tb := external.GetTableByName(t, tk, "test", "t") + err := domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + tk.MustExec("set @@session.tidb_isolation_read_engines = 'tiflash'") + + sql := "select * from t" + tk.MustExec(sql) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustGetErrMsg(fmt.Sprintf("create binding from history using plan digest '%s'", planDigest[0][0]), "can't create binding for query with tiflash engine") +} + +func TestSetBindingStatusBySQLDigest(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int, a int, key(a))") + sql := "select /*+ ignore_index(t, a) */ * from t where t.a = 1" + tk.MustExec(sql) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.cluster_statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustExec(fmt.Sprintf("create global binding from history using plan digest '%s'", planDigest[0][0])) + sql = "select * from t where t.a = 1" + tk.MustExec(sql) + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + + sqlDigest := tk.MustQuery("show global bindings").Rows() + tk.MustExec(fmt.Sprintf("set binding disabled for sql digest '%s'", sqlDigest[0][9])) + tk.MustExec(sql) + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + tk.MustExec(fmt.Sprintf("set binding enabled for sql digest '%s'", sqlDigest[0][9])) + tk.MustExec(sql) + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + tk.MustGetErrMsg("set binding enabled for sql digest '2'", "can't find any binding for '2'") +} + +func TestCreateBindingWhenCloseStmtSummaryTable(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int primary key, a int, key(a))") + tk.MustExec("set global tidb_enable_stmt_summary = 0") + tk.MustExec("select /*+ ignore_index(t, a) */ * from t where a = 1") + + tk.MustGetErrMsg("create binding from history using plan digest '4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb'", + "can't find any plans for '4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb'") +} + +func TestCreateBindingForNotSupportedStmt(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int primary key, a int, key(a))") + + sql := "admin show ddl jobs" + tk.MustExec(sql) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustGetErrMsg(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0]), fmt.Sprintf("can't find any plans for '%s'", planDigest[0][0])) + + sql = "show tables" + tk.MustExec(sql) + planDigest = tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustGetErrMsg(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0]), fmt.Sprintf("can't find any plans for '%s'", planDigest[0][0])) + + sql = "explain select /*+ ignore_index(t, a) */ * from t where a = 1" + tk.MustExec(sql) + planDigest = tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustGetErrMsg(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0]), fmt.Sprintf("can't find any plans for '%s'", planDigest[0][0])) +} + +func TestCreateBindingRepeatedly(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int primary key, a int, key(a))") + + sql := "select /*+ ignore_index(t, a) */ * from t where a = 1" + tk.MustExec(sql) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + binding := tk.MustQuery("show bindings").Rows() + loc, _ := time.LoadLocation("Asia/Shanghai") + createTime, _ := time.ParseInLocation("2006-01-02 15:04:05", binding[0][4].(string), loc) + updateTime, _ := time.ParseInLocation("2006-01-02 15:04:05", binding[0][5].(string), loc) + + // binding from history cover binding from history + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + binding1 := tk.MustQuery("show bindings").Rows() + createTime1, _ := time.ParseInLocation("2006-01-02 15:04:05", binding1[0][4].(string), loc) + updateTime1, _ := time.ParseInLocation("2006-01-02 15:04:05", binding1[0][5].(string), loc) + require.Greater(t, createTime1.UnixNano(), createTime.UnixNano()) + require.Greater(t, updateTime1.UnixNano(), updateTime.UnixNano()) + for i := range binding1[0] { + if i != 4 && i != 5 { + require.Equal(t, binding[0][i], binding1[0][i]) + } + } + // binding from sql cover binding from history + tk.MustExec("create binding for select * from t where a = 1 using select /*+ ignore_index(t, a) */ * from t where a = 1") + binding2 := tk.MustQuery("show bindings").Rows() + createTime2, _ := time.ParseInLocation("2006-01-02 15:04:05", binding2[0][4].(string), loc) + updateTime2, _ := time.ParseInLocation("2006-01-02 15:04:05", binding2[0][5].(string), loc) + require.Greater(t, createTime2.UnixNano(), createTime1.UnixNano()) + require.Greater(t, updateTime2.UnixNano(), updateTime1.UnixNano()) + require.Equal(t, binding2[0][8], "manual") + require.Equal(t, binding2[0][10], "") + for i := range binding2[0] { + if i != 1 && i != 4 && i != 5 && i != 8 && i != 10 { + // bind_sql, create_time, update_time, source, plan_digest may be different + require.Equal(t, binding1[0][i], binding2[0][i]) + } + } + // binding from history cover binding from sql + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + binding3 := tk.MustQuery("show bindings").Rows() + createTime3, _ := time.ParseInLocation("2006-01-02 15:04:05", binding3[0][4].(string), loc) + updateTime3, _ := time.ParseInLocation("2006-01-02 15:04:05", binding3[0][5].(string), loc) + require.Greater(t, createTime3.UnixNano(), createTime2.UnixNano()) + require.Greater(t, updateTime3.UnixNano(), updateTime2.UnixNano()) + require.Equal(t, binding3[0][8], "history") + require.Equal(t, binding3[0][10], planDigest[0][0]) + for i := range binding3[0] { + if i != 1 && i != 4 && i != 5 && i != 8 && i != 10 { + // bind_sql, create_time, update_time, source, plan_digest may be different + require.Equal(t, binding2[0][i], binding3[0][i]) + } + } +} + +func TestCreateBindingWithUsingKeyword(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1, t2") + tk.MustExec("create table t(id int primary key, a int, key(a))") + tk.MustExec("create table t1(id int primary key, a int, key(a))") + tk.MustExec("create table t2(id int primary key, a int, key(a))") + + // `JOIN` keyword and not specifying the associated columns with the `USING` keyword. + tk.MustGetErrMsg("CREATE GLOBAL BINDING for SELECT * FROM t t1 JOIN t t2 USING SELECT * FROM t t1 JOIN t t2;", + "[parser:1064]You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 67 near \"SELECT * FROM t t1 JOIN t t2;\" ") + sql := "SELECT * FROM t t1 JOIN t t2;" + tk.MustExec(sql) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + tk.MustExec(sql) + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + + // `DELETE` statements that contain the `USING` keyword. + tk.MustGetErrMsg("`CREATE GLOBAL BINDING for DELETE FROM t1 USING t1 JOIN t2 ON t1.a = t2.a USING DELETE FROM t1 USING t1 JOIN t2 ON t1.a = t2.a;", + "[parser:1064]You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 127 near \"`CREATE GLOBAL BINDING for DELETE FROM t1 USING t1 JOIN t2 ON t1.a = t2.a USING DELETE FROM t1 USING t1 JOIN t2 ON t1.a = t2.a;\" ") + sql = "DELETE FROM t1 USING t1 JOIN t2 ON t1.a = t2.a;" + tk.MustExec(sql) + planDigest = tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + tk.MustExec(sql) + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) +} + +func TestNewCreatedBindingCanWorkWithPlanCache(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1, t2") + tk.MustExec("create table t(id int primary key, a int, key(a))") + + tk.MustExec("prepare stmt from 'select * from t where a = ?'") + tk.MustExec("set @a = 0") + tk.MustExec("execute stmt using @a") + tk.MustExec("execute stmt using @a") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + sql := "select /*+ ignore_index(t, a) */ * from t where a = 1" + tk.MustExec(sql) + planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows() + tk.MustExec(fmt.Sprintf("create session binding from history using plan digest '%s'", planDigest[0][0])) + tk.MustExec("execute stmt using @a") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) +} diff --git a/infoschema/error.go b/infoschema/error.go index a7e4929a35bcc..2e1a45c7ae113 100644 --- a/infoschema/error.go +++ b/infoschema/error.go @@ -32,7 +32,11 @@ var ( ErrPlacementPolicyExists = dbterror.ClassSchema.NewStd(mysql.ErrPlacementPolicyExists) // ErrPlacementPolicyNotExists return for placement_policy policy not exists. ErrPlacementPolicyNotExists = dbterror.ClassSchema.NewStd(mysql.ErrPlacementPolicyNotExists) - // ErrReservedSyntax for internal syntax. + // ErrResourceGroupExists return for resource group already exists. + ErrResourceGroupExists = dbterror.ClassSchema.NewStd(mysql.ErrResourceGroupExists) + // ErrResourceGroupNotExists return for resource group not exists. + ErrResourceGroupNotExists = dbterror.ClassSchema.NewStd(mysql.ErrResourceGroupNotExists) + // ErrReservedSyntax for internal syntax. ErrReservedSyntax = dbterror.ClassSchema.NewStd(mysql.ErrReservedSyntax) // ErrTableExists returns for table already exists. ErrTableExists = dbterror.ClassSchema.NewStd(mysql.ErrTableExists) @@ -64,6 +68,8 @@ var ( ErrKeyNotExists = dbterror.ClassSchema.NewStd(mysql.ErrKeyDoesNotExist) // ErrCannotAddForeign returns for foreign key exists. ErrCannotAddForeign = dbterror.ClassSchema.NewStd(mysql.ErrCannotAddForeign) + // ErrForeignKeyOnPartitioned returns for foreign key on partition table. + ErrForeignKeyOnPartitioned = dbterror.ClassSchema.NewStd(mysql.ErrForeignKeyOnPartitioned) // ErrForeignKeyNotMatch returns for foreign key not match. ErrForeignKeyNotMatch = dbterror.ClassSchema.NewStd(mysql.ErrWrongFkDef) // ErrIndexExists returns for index already exists. @@ -94,4 +100,6 @@ var ( ErrForeignKeyNoIndexInParent = dbterror.ClassSchema.NewStd(mysql.ErrForeignKeyNoIndexInParent) // ErrForeignKeyColumnNotNull returns when foreign key with SET NULL constrain and the related column has not null. ErrForeignKeyColumnNotNull = dbterror.ClassSchema.NewStd(mysql.ErrForeignKeyColumnNotNull) + // ErrResourceGroupSupportDisabled returns for resource group feature is disabled + ErrResourceGroupSupportDisabled = dbterror.ClassSchema.NewStd(mysql.ErrResourceGroupSupportDisabled) ) diff --git a/infoschema/infoschema.go b/infoschema/infoschema.go index 085c5f1d3e3e2..f46f7d082a66e 100644 --- a/infoschema/infoschema.go +++ b/infoschema/infoschema.go @@ -42,6 +42,7 @@ type InfoSchema interface { SchemaByID(id int64) (*model.DBInfo, bool) SchemaByTable(tableInfo *model.TableInfo) (*model.DBInfo, bool) PolicyByName(name model.CIStr) (*model.PolicyInfo, bool) + ResourceGroupByName(name model.CIStr) (*model.ResourceGroupInfo, bool) TableByID(id int64) (table.Table, bool) AllocByID(id int64) (autoid.Allocators, bool) AllSchemaNames() []string @@ -60,6 +61,8 @@ type InfoSchema interface { AllPlacementBundles() []*placement.Bundle // AllPlacementPolicies returns all placement policies AllPlacementPolicies() []*model.PolicyInfo + // AllResourceGroups returns all resource groups + AllResourceGroups() []*model.ResourceGroupInfo // HasTemporaryTable returns whether information schema has temporary table HasTemporaryTable() bool // GetTableReferredForeignKeys gets the table's ReferredFKInfo by lowercase schema and table name. @@ -93,6 +96,10 @@ type infoSchema struct { policyMutex sync.RWMutex policyMap map[string]*model.PolicyInfo + // resourceGroupMap stores all resource groups. + resourceGroupMutex sync.RWMutex + resourceGroupMap map[string]*model.ResourceGroupInfo + schemaMap map[string]*schemaTables // sortedTablesBuckets is a slice of sortedTables, a table's bucket index is (tableID % bucketCount). @@ -120,6 +127,7 @@ func MockInfoSchema(tbList []*model.TableInfo) InfoSchema { result := &infoSchema{} result.schemaMap = make(map[string]*schemaTables) result.policyMap = make(map[string]*model.PolicyInfo) + result.resourceGroupMap = make(map[string]*model.ResourceGroupInfo) result.ruleBundleMap = make(map[int64]*placement.Bundle) result.sortedTablesBuckets = make([]sortedTables, bucketCount) dbInfo := &model.DBInfo{ID: 0, Name: model.NewCIStr("test"), Tables: tbList} @@ -147,6 +155,7 @@ func MockInfoSchemaWithSchemaVer(tbList []*model.TableInfo, schemaVer int64) Inf result := &infoSchema{} result.schemaMap = make(map[string]*schemaTables) result.policyMap = make(map[string]*model.PolicyInfo) + result.resourceGroupMap = make(map[string]*model.ResourceGroupInfo) result.ruleBundleMap = make(map[int64]*placement.Bundle) result.sortedTablesBuckets = make([]sortedTables, bucketCount) dbInfo := &model.DBInfo{ID: 0, Name: model.NewCIStr("test"), Tables: tbList} @@ -235,6 +244,17 @@ func (is *infoSchema) PolicyByID(id int64) (val *model.PolicyInfo, ok bool) { return nil, false } +func (is *infoSchema) ResourceGroupByID(id int64) (val *model.ResourceGroupInfo, ok bool) { + is.resourceGroupMutex.RLock() + defer is.resourceGroupMutex.RUnlock() + for _, v := range is.resourceGroupMap { + if v.ID == id { + return v, true + } + } + return nil, false +} + func (is *infoSchema) SchemaByID(id int64) (val *model.DBInfo, ok bool) { for _, v := range is.schemaMap { if v.dbInfo.ID == id { @@ -270,7 +290,7 @@ func (is *infoSchema) TableByID(id int64) (val table.Table, ok bool) { func (is *infoSchema) AllocByID(id int64) (autoid.Allocators, bool) { tbl, ok := is.TableByID(id) if !ok { - return nil, false + return autoid.Allocators{}, false } return tbl.Allocators(nil), true } @@ -393,6 +413,25 @@ func (is *infoSchema) PolicyByName(name model.CIStr) (*model.PolicyInfo, bool) { return t, r } +// ResourceGroupByName is used to find the resource group. +func (is *infoSchema) ResourceGroupByName(name model.CIStr) (*model.ResourceGroupInfo, bool) { + is.resourceGroupMutex.RLock() + defer is.resourceGroupMutex.RUnlock() + t, r := is.resourceGroupMap[name.L] + return t, r +} + +// AllResourceGroups returns all resource groups. +func (is *infoSchema) AllResourceGroups() []*model.ResourceGroupInfo { + is.resourceGroupMutex.RLock() + defer is.resourceGroupMutex.RUnlock() + groups := make([]*model.ResourceGroupInfo, 0, len(is.resourceGroupMap)) + for _, group := range is.resourceGroupMap { + groups = append(groups, group) + } + return groups +} + // AllPlacementPolicies returns all placement policies func (is *infoSchema) AllPlacementPolicies() []*model.PolicyInfo { is.policyMutex.RLock() @@ -417,6 +456,18 @@ func (is *infoSchema) AllPlacementBundles() []*placement.Bundle { return bundles } +func (is *infoSchema) setResourceGroup(resourceGroup *model.ResourceGroupInfo) { + is.resourceGroupMutex.Lock() + defer is.resourceGroupMutex.Unlock() + is.resourceGroupMap[resourceGroup.Name.L] = resourceGroup +} + +func (is *infoSchema) deleteResourceGroup(name string) { + is.resourceGroupMutex.Lock() + defer is.resourceGroupMutex.Unlock() + delete(is.resourceGroupMap, name) +} + func (is *infoSchema) setPolicy(policy *model.PolicyInfo) { is.policyMutex.Lock() defer is.policyMutex.Unlock() @@ -463,7 +514,7 @@ func (is *infoSchema) addReferredForeignKeys(schema model.CIStr, tbInfo *model.T if newReferredFKList[i].ChildTable.L != newReferredFKList[j].ChildTable.L { return newReferredFKList[i].ChildTable.L < newReferredFKList[j].ChildTable.L } - return newReferredFKList[i].ChildFKName.L != newReferredFKList[j].ChildFKName.L + return newReferredFKList[i].ChildFKName.L < newReferredFKList[j].ChildFKName.L }) is.referredForeignKeyMap[refer] = newReferredFKList } @@ -674,6 +725,12 @@ func (ts *SessionExtendedInfoSchema) SchemaByTable(tableInfo *model.TableInfo) ( } } + if ts.MdlTables != nil { + if tbl, ok := ts.MdlTables.SchemaByTable(tableInfo); ok { + return tbl, true + } + } + return ts.InfoSchema.SchemaByTable(tableInfo) } diff --git a/infoschema/infoschema_test.go b/infoschema/infoschema_test.go index 8f92eb3c16ddb..513dbfb6f7223 100644 --- a/infoschema/infoschema_test.go +++ b/infoschema/infoschema_test.go @@ -110,7 +110,7 @@ func TestBasic(t *testing.T) { }) require.NoError(t, err) - builder, err := infoschema.NewBuilder(dom.Store(), nil).InitWithDBInfos(dbInfos, nil, 1) + builder, err := infoschema.NewBuilder(dom.Store(), nil).InitWithDBInfos(dbInfos, nil, nil, 1) require.NoError(t, err) txn, err := store.Begin() @@ -256,7 +256,7 @@ func TestInfoTables(t *testing.T) { require.NoError(t, err) }() - builder, err := infoschema.NewBuilder(store, nil).InitWithDBInfos(nil, nil, 0) + builder, err := infoschema.NewBuilder(store, nil).InitWithDBInfos(nil, nil, nil, 0) require.NoError(t, err) is := builder.Build() @@ -296,6 +296,7 @@ func TestInfoTables(t *testing.T) { "DEADLOCKS", "PLACEMENT_POLICIES", "TRX_SUMMARY", + "RESOURCE_GROUPS", } for _, tbl := range infoTables { tb, err1 := is.TableByName(util.InformationSchemaName, model.NewCIStr(tbl)) @@ -316,12 +317,12 @@ func genGlobalID(store kv.Storage) (int64, error) { } func TestBuildSchemaWithGlobalTemporaryTable(t *testing.T) { - store := testkit.CreateMockStore(t) + store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - is := tk.Session().GetDomainInfoSchema().(infoschema.InfoSchema) + is := dom.InfoSchema() require.False(t, is.HasTemporaryTable()) db, ok := is.SchemaByName(model.NewCIStr("test")) require.True(t, ok) @@ -410,7 +411,7 @@ func TestBuildSchemaWithGlobalTemporaryTable(t *testing.T) { // full load newDB, ok := newIS.SchemaByName(model.NewCIStr("test")) require.True(t, ok) - builder, err := infoschema.NewBuilder(store, nil).InitWithDBInfos([]*model.DBInfo{newDB}, newIS.AllPlacementPolicies(), newIS.SchemaMetaVersion()) + builder, err := infoschema.NewBuilder(store, nil).InitWithDBInfos([]*model.DBInfo{newDB}, newIS.AllPlacementPolicies(), newIS.AllResourceGroups(), newIS.SchemaMetaVersion()) require.NoError(t, err) require.True(t, builder.Build().HasTemporaryTable()) @@ -535,7 +536,7 @@ func TestBuildBundle(t *testing.T) { assertBundle(is, tbl2.Meta().ID, nil) assertBundle(is, p1.ID, p1Bundle) - builder, err := infoschema.NewBuilder(store, nil).InitWithDBInfos([]*model.DBInfo{db}, is.AllPlacementPolicies(), is.SchemaMetaVersion()) + builder, err := infoschema.NewBuilder(store, nil).InitWithDBInfos([]*model.DBInfo{db}, is.AllPlacementPolicies(), is.AllResourceGroups(), is.SchemaMetaVersion()) require.NoError(t, err) is2 := builder.Build() assertBundle(is2, tbl1.Meta().ID, tb1Bundle) diff --git a/infoschema/main_test.go b/infoschema/main_test.go index 9330b22b360ca..09a412679f664 100644 --- a/infoschema/main_test.go +++ b/infoschema/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/infoschema/perfschema/main_test.go b/infoschema/perfschema/main_test.go index 43012b2c4dbde..950b95993b536 100644 --- a/infoschema/perfschema/main_test.go +++ b/infoschema/perfschema/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/infoschema/perfschema/tables.go b/infoschema/perfschema/tables.go index 5046dd318ec19..6889d61c3be85 100644 --- a/infoschema/perfschema/tables.go +++ b/infoschema/perfschema/tables.go @@ -15,6 +15,7 @@ package perfschema import ( + "context" "fmt" "net/http" "strings" @@ -206,6 +207,11 @@ func (vt *perfSchemaTable) Indices() []table.Index { return vt.indices } +// GetPartitionedTable implements table.Table GetPartitionedTable interface. +func (vt *perfSchemaTable) GetPartitionedTable() table.PartitionedTable { + return nil +} + // initTableIndices initializes the indices of the perfSchemaTable. func initTableIndices(t *perfSchemaTable) error { tblInfo := t.meta @@ -219,7 +225,7 @@ func initTableIndices(t *perfSchemaTable) error { return nil } -func (vt *perfSchemaTable) getRows(ctx sessionctx.Context, cols []*table.Column) (fullRows [][]types.Datum, err error) { +func (vt *perfSchemaTable) getRows(ctx context.Context, sctx sessionctx.Context, cols []*table.Column) (fullRows [][]types.Datum, err error) { switch vt.meta.Name.O { case tableNameTiDBProfileCPU: fullRows, err = (&profile.Collector{}).ProfileGraph("cpu") @@ -235,22 +241,22 @@ func (vt *perfSchemaTable) getRows(ctx sessionctx.Context, cols []*table.Column) fullRows, err = (&profile.Collector{}).ProfileGraph("goroutine") case tableNameTiKVProfileCPU: interval := fmt.Sprintf("%d", profile.CPUProfileInterval/time.Second) - fullRows, err = dataForRemoteProfile(ctx, "tikv", "/debug/pprof/profile?seconds="+interval, false) + fullRows, err = dataForRemoteProfile(sctx, "tikv", "/debug/pprof/profile?seconds="+interval, false) case tableNamePDProfileCPU: interval := fmt.Sprintf("%d", profile.CPUProfileInterval/time.Second) - fullRows, err = dataForRemoteProfile(ctx, "pd", "/pd/api/v1/debug/pprof/profile?seconds="+interval, false) + fullRows, err = dataForRemoteProfile(sctx, "pd", "/pd/api/v1/debug/pprof/profile?seconds="+interval, false) case tableNamePDProfileMemory: - fullRows, err = dataForRemoteProfile(ctx, "pd", "/pd/api/v1/debug/pprof/heap", false) + fullRows, err = dataForRemoteProfile(sctx, "pd", "/pd/api/v1/debug/pprof/heap", false) case tableNamePDProfileMutex: - fullRows, err = dataForRemoteProfile(ctx, "pd", "/pd/api/v1/debug/pprof/mutex", false) + fullRows, err = dataForRemoteProfile(sctx, "pd", "/pd/api/v1/debug/pprof/mutex", false) case tableNamePDProfileAllocs: - fullRows, err = dataForRemoteProfile(ctx, "pd", "/pd/api/v1/debug/pprof/allocs", false) + fullRows, err = dataForRemoteProfile(sctx, "pd", "/pd/api/v1/debug/pprof/allocs", false) case tableNamePDProfileBlock: - fullRows, err = dataForRemoteProfile(ctx, "pd", "/pd/api/v1/debug/pprof/block", false) + fullRows, err = dataForRemoteProfile(sctx, "pd", "/pd/api/v1/debug/pprof/block", false) case tableNamePDProfileGoroutines: - fullRows, err = dataForRemoteProfile(ctx, "pd", "/pd/api/v1/debug/pprof/goroutine?debug=2", true) + fullRows, err = dataForRemoteProfile(sctx, "pd", "/pd/api/v1/debug/pprof/goroutine?debug=2", true) case tableNameSessionVariables: - fullRows, err = infoschema.GetDataFromSessionVariables(ctx) + fullRows, err = infoschema.GetDataFromSessionVariables(ctx, sctx) } if err != nil { return @@ -270,9 +276,8 @@ func (vt *perfSchemaTable) getRows(ctx sessionctx.Context, cols []*table.Column) } // IterRecords implements table.Table IterRecords interface. -func (vt *perfSchemaTable) IterRecords(ctx sessionctx.Context, cols []*table.Column, - fn table.RecordIterFunc) error { - rows, err := vt.getRows(ctx, cols) +func (vt *perfSchemaTable) IterRecords(ctx context.Context, sctx sessionctx.Context, cols []*table.Column, fn table.RecordIterFunc) error { + rows, err := vt.getRows(ctx, sctx, cols) if err != nil { return err } diff --git a/infoschema/tables.go b/infoschema/tables.go index 74d064b55759a..35b199be043cd 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -22,10 +22,14 @@ import ( "net/http" "strconv" "strings" + "sync" + "time" "github.com/pingcap/errors" "github.com/pingcap/failpoint" + "github.com/pingcap/kvproto/pkg/diagnosticspb" "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/log" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl/placement" "github.com/pingcap/tidb/domain/infosync" @@ -47,9 +51,13 @@ import ( "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/pdapi" "github.com/pingcap/tidb/util/sem" + "github.com/pingcap/tidb/util/set" "github.com/pingcap/tidb/util/stmtsummary" "github.com/tikv/client-go/v2/tikv" "go.uber.org/zap" + "golang.org/x/exp/slices" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" ) const ( @@ -184,6 +192,14 @@ const ( TableTrxSummary = "TRX_SUMMARY" // TableVariablesInfo is the string constant of variables_info table. TableVariablesInfo = "VARIABLES_INFO" + // TableUserAttributes is the string constant of user_attributes view. + TableUserAttributes = "USER_ATTRIBUTES" + // TableMemoryUsage is the memory usage status of tidb instance. + TableMemoryUsage = "MEMORY_USAGE" + // TableMemoryUsageOpsHistory is the memory control operators history. + TableMemoryUsageOpsHistory = "MEMORY_USAGE_OPS_HISTORY" + // TableResourceGroups is the metadata of resource groups. + TableResourceGroups = "RESOURCE_GROUPS" ) const ( @@ -285,6 +301,12 @@ var tableIDMap = map[string]int64{ TableTrxSummary: autoid.InformationSchemaDBID + 80, ClusterTableTrxSummary: autoid.InformationSchemaDBID + 81, TableVariablesInfo: autoid.InformationSchemaDBID + 82, + TableUserAttributes: autoid.InformationSchemaDBID + 83, + TableMemoryUsage: autoid.InformationSchemaDBID + 84, + TableMemoryUsageOpsHistory: autoid.InformationSchemaDBID + 85, + ClusterTableMemoryUsage: autoid.InformationSchemaDBID + 86, + ClusterTableMemoryUsageOpsHistory: autoid.InformationSchemaDBID + 87, + TableResourceGroups: autoid.InformationSchemaDBID + 88, } // columnInfo represents the basic column information of all kinds of INFORMATION_SCHEMA tables @@ -879,6 +901,7 @@ var slowQueryCols = []columnInfo{ {name: variable.SlowLogBackoffTotal, tp: mysql.TypeDouble, size: 22}, {name: variable.SlowLogWriteSQLRespTotal, tp: mysql.TypeDouble, size: 22}, {name: variable.SlowLogResultRows, tp: mysql.TypeLonglong, size: 22}, + {name: variable.SlowLogWarnings, tp: mysql.TypeLongBlob, size: types.UnspecifiedLength}, {name: variable.SlowLogBackoffDetail, tp: mysql.TypeVarchar, size: 4096}, {name: variable.SlowLogPrepared, tp: mysql.TypeTiny, size: 1}, {name: variable.SlowLogSucc, tp: mysql.TypeTiny, size: 1}, @@ -1312,6 +1335,9 @@ var tableStatementsSummaryCols = []columnInfo{ {name: stmtsummary.PlanDigestStr, tp: mysql.TypeVarchar, size: 64, comment: "Digest of its execution plan"}, {name: stmtsummary.PlanStr, tp: mysql.TypeBlob, size: types.UnspecifiedLength, comment: "Sampled execution plan"}, {name: stmtsummary.BinaryPlan, tp: mysql.TypeBlob, size: types.UnspecifiedLength, comment: "Sampled binary plan"}, + {name: stmtsummary.Charset, tp: mysql.TypeVarchar, size: 64, comment: "Sampled charset"}, + {name: stmtsummary.Collation, tp: mysql.TypeVarchar, size: 64, comment: "Sampled collation"}, + {name: stmtsummary.PlanHint, tp: mysql.TypeVarchar, size: 64, comment: "Sampled plan hint"}, } var tableStorageStatsCols = []columnInfo{ @@ -1358,6 +1384,7 @@ var tableTableTiFlashTablesCols = []columnInfo{ {name: "AVG_STABLE_ROWS", tp: mysql.TypeDouble, size: 64}, {name: "AVG_STABLE_SIZE", tp: mysql.TypeDouble, size: 64}, {name: "TOTAL_PACK_COUNT_IN_DELTA", tp: mysql.TypeLonglong, size: 64}, + {name: "MAX_PACK_COUNT_IN_DELTA", tp: mysql.TypeLonglong, size: 64}, {name: "AVG_PACK_COUNT_IN_DELTA", tp: mysql.TypeDouble, size: 64}, {name: "AVG_PACK_ROWS_IN_DELTA", tp: mysql.TypeDouble, size: 64}, {name: "AVG_PACK_SIZE_IN_DELTA", tp: mysql.TypeDouble, size: 64}, @@ -1369,23 +1396,14 @@ var tableTableTiFlashTablesCols = []columnInfo{ {name: "STORAGE_STABLE_OLDEST_SNAPSHOT_LIFETIME", tp: mysql.TypeDouble, size: 64}, {name: "STORAGE_STABLE_OLDEST_SNAPSHOT_THREAD_ID", tp: mysql.TypeLonglong, size: 64}, {name: "STORAGE_STABLE_OLDEST_SNAPSHOT_TRACING_ID", tp: mysql.TypeVarchar, size: 128}, - {name: "STORAGE_STABLE_NUM_PAGES", tp: mysql.TypeLonglong, size: 64}, - {name: "STORAGE_STABLE_NUM_NORMAL_PAGES", tp: mysql.TypeLonglong, size: 64}, - {name: "STORAGE_STABLE_MAX_PAGE_ID", tp: mysql.TypeLonglong, size: 64}, {name: "STORAGE_DELTA_NUM_SNAPSHOTS", tp: mysql.TypeLonglong, size: 64}, {name: "STORAGE_DELTA_OLDEST_SNAPSHOT_LIFETIME", tp: mysql.TypeDouble, size: 64}, {name: "STORAGE_DELTA_OLDEST_SNAPSHOT_THREAD_ID", tp: mysql.TypeLonglong, size: 64}, {name: "STORAGE_DELTA_OLDEST_SNAPSHOT_TRACING_ID", tp: mysql.TypeVarchar, size: 128}, - {name: "STORAGE_DELTA_NUM_PAGES", tp: mysql.TypeLonglong, size: 64}, - {name: "STORAGE_DELTA_NUM_NORMAL_PAGES", tp: mysql.TypeLonglong, size: 64}, - {name: "STORAGE_DELTA_MAX_PAGE_ID", tp: mysql.TypeLonglong, size: 64}, {name: "STORAGE_META_NUM_SNAPSHOTS", tp: mysql.TypeLonglong, size: 64}, {name: "STORAGE_META_OLDEST_SNAPSHOT_LIFETIME", tp: mysql.TypeDouble, size: 64}, {name: "STORAGE_META_OLDEST_SNAPSHOT_THREAD_ID", tp: mysql.TypeLonglong, size: 64}, {name: "STORAGE_META_OLDEST_SNAPSHOT_TRACING_ID", tp: mysql.TypeVarchar, size: 128}, - {name: "STORAGE_META_NUM_PAGES", tp: mysql.TypeLonglong, size: 64}, - {name: "STORAGE_META_NUM_NORMAL_PAGES", tp: mysql.TypeLonglong, size: 64}, - {name: "STORAGE_META_MAX_PAGE_ID", tp: mysql.TypeLonglong, size: 64}, {name: "BACKGROUND_TASKS_LENGTH", tp: mysql.TypeLonglong, size: 64}, {name: "TIFLASH_INSTANCE", tp: mysql.TypeVarchar, size: 64}, } @@ -1536,6 +1554,49 @@ var tableVariablesInfoCols = []columnInfo{ {name: "IS_NOOP", tp: mysql.TypeVarchar, size: 64, flag: mysql.NotNullFlag}, } +var tableUserAttributesCols = []columnInfo{ + {name: "USER", tp: mysql.TypeVarchar, size: 32, flag: mysql.NotNullFlag}, + {name: "HOST", tp: mysql.TypeVarchar, size: 255, flag: mysql.NotNullFlag}, + {name: "ATTRIBUTE", tp: mysql.TypeLongBlob, size: types.UnspecifiedLength}, +} + +var tableMemoryUsageCols = []columnInfo{ + {name: "MEMORY_TOTAL", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "MEMORY_LIMIT", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "MEMORY_CURRENT", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "MEMORY_MAX_USED", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "CURRENT_OPS", tp: mysql.TypeVarchar, size: 50}, + {name: "SESSION_KILL_LAST", tp: mysql.TypeDatetime}, + {name: "SESSION_KILL_TOTAL", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "GC_LAST", tp: mysql.TypeDatetime}, + {name: "GC_TOTAL", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "DISK_USAGE", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "QUERY_FORCE_DISK", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, +} + +var tableMemoryUsageOpsHistoryCols = []columnInfo{ + {name: "TIME", tp: mysql.TypeDatetime, size: 64, flag: mysql.NotNullFlag}, + {name: "OPS", tp: mysql.TypeVarchar, size: 20, flag: mysql.NotNullFlag}, + {name: "MEMORY_LIMIT", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "MEMORY_CURRENT", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag}, + {name: "PROCESSID", tp: mysql.TypeLonglong, size: 21, flag: mysql.UnsignedFlag}, + {name: "MEM", tp: mysql.TypeLonglong, size: 21, flag: mysql.UnsignedFlag}, + {name: "DISK", tp: mysql.TypeLonglong, size: 21, flag: mysql.UnsignedFlag}, + {name: "CLIENT", tp: mysql.TypeVarchar, size: 64}, + {name: "DB", tp: mysql.TypeVarchar, size: 64}, + {name: "USER", tp: mysql.TypeVarchar, size: 16}, + {name: "SQL_DIGEST", tp: mysql.TypeVarchar, size: 64}, + {name: "SQL_TEXT", tp: mysql.TypeVarchar, size: 256}, +} + +var tableResourceGroupsCols = []columnInfo{ + {name: "GROUP_ID", tp: mysql.TypeLonglong, size: 64, flag: mysql.NotNullFlag}, + {name: "GROUP_NAME", tp: mysql.TypeVarchar, size: 512, flag: mysql.NotNullFlag}, + {name: "RRU_PER_SECOND", tp: mysql.TypeLonglong, size: 64}, + {name: "WRU_PER_SECOND", tp: mysql.TypeLonglong, size: 64}, + // {name: "BURSTABLE", tp: mysql.TypeVarchar, size: 10}, +} + // GetShardingInfo returns a nil or description string for the sharding information of given TableInfo. // The returned description string may be: // - "NOT_SHARDED": for tables that SHARD_ROW_ID_BITS is not specified. @@ -1691,8 +1752,8 @@ func FormatTiDBVersion(TiDBVersion string, isDefaultVersion bool) string { // The user hasn't set the config 'ServerVersion'. if isDefaultVersion { - nodeVersion = TiDBVersion[strings.LastIndex(TiDBVersion, "TiDB-")+len("TiDB-"):] - if nodeVersion[0] == 'v' { + nodeVersion = TiDBVersion[strings.Index(TiDBVersion, "TiDB-")+len("TiDB-"):] + if len(nodeVersion) > 0 && nodeVersion[0] == 'v' { nodeVersion = nodeVersion[1:] } nodeVersions := strings.Split(nodeVersion, "-") @@ -1903,16 +1964,16 @@ func SysVarHiddenForSem(ctx sessionctx.Context, sysVarNameInLower string) bool { } // GetDataFromSessionVariables return the [name, value] of all session variables -func GetDataFromSessionVariables(ctx sessionctx.Context) ([][]types.Datum, error) { - sessionVars := ctx.GetSessionVars() +func GetDataFromSessionVariables(ctx context.Context, sctx sessionctx.Context) ([][]types.Datum, error) { + sessionVars := sctx.GetSessionVars() sysVars := variable.GetSysVars() rows := make([][]types.Datum, 0, len(sysVars)) for _, v := range sysVars { - if SysVarHiddenForSem(ctx, v.Name) { + if SysVarHiddenForSem(sctx, v.Name) { continue } var value string - value, err := sessionVars.GetSessionOrGlobalSystemVar(v.Name) + value, err := sessionVars.GetSessionOrGlobalSystemVar(ctx, v.Name) if err != nil { return nil, err } @@ -1995,6 +2056,10 @@ var tableNameToColumns = map[string][]columnInfo{ TablePlacementPolicies: tablePlacementPoliciesCols, TableTrxSummary: tableTrxSummaryCols, TableVariablesInfo: tableVariablesInfoCols, + TableUserAttributes: tableUserAttributesCols, + TableMemoryUsage: tableMemoryUsageCols, + TableMemoryUsageOpsHistory: tableMemoryUsageOpsHistoryCols, + TableResourceGroups: tableResourceGroupsCols, } func createInfoSchemaTable(_ autoid.Allocators, meta *model.TableInfo) (table.Table, error) { @@ -2016,8 +2081,7 @@ type infoschemaTable struct { } // IterRecords implements table.Table IterRecords interface. -func (*infoschemaTable) IterRecords(_ sessionctx.Context, _ []*table.Column, - _ table.RecordIterFunc) error { +func (*infoschemaTable) IterRecords(ctx context.Context, sctx sessionctx.Context, cols []*table.Column, fn table.RecordIterFunc) error { return nil } @@ -2083,7 +2147,7 @@ func (it *infoschemaTable) UpdateRecord(gctx context.Context, ctx sessionctx.Con // Allocators implements table.Table Allocators interface. func (it *infoschemaTable) Allocators(_ sessionctx.Context) autoid.Allocators { - return nil + return autoid.Allocators{} } // Meta implements table.Table Meta interface. @@ -2101,6 +2165,11 @@ func (it *infoschemaTable) Type() table.Type { return it.tp } +// GetPartitionedTable implements table.Table GetPartitionedTable interface. +func (it *infoschemaTable) GetPartitionedTable() table.PartitionedTable { + return nil +} + // VirtualTable is a dummy table.Table implementation. type VirtualTable struct{} @@ -2166,7 +2235,7 @@ func (vt *VirtualTable) UpdateRecord(ctx context.Context, sctx sessionctx.Contex // Allocators implements table.Table Allocators interface. func (vt *VirtualTable) Allocators(_ sessionctx.Context) autoid.Allocators { - return nil + return autoid.Allocators{} } // Meta implements table.Table Meta interface. @@ -2183,3 +2252,142 @@ func (vt *VirtualTable) GetPhysicalID() int64 { func (vt *VirtualTable) Type() table.Type { return table.VirtualTable } + +// GetTiFlashServerInfo returns all TiFlash server infos +func GetTiFlashServerInfo(sctx sessionctx.Context) ([]ServerInfo, error) { + if config.GetGlobalConfig().DisaggregatedTiFlash { + return nil, table.ErrUnsupportedOp + } + serversInfo, err := GetStoreServerInfo(sctx) + if err != nil { + return nil, err + } + serversInfo = FilterClusterServerInfo(serversInfo, set.NewStringSet(kv.TiFlash.Name()), set.NewStringSet()) + return serversInfo, nil +} + +// FetchClusterServerInfoWithoutPrivilegeCheck fetches cluster server information +func FetchClusterServerInfoWithoutPrivilegeCheck(ctx context.Context, sctx sessionctx.Context, serversInfo []ServerInfo, serverInfoType diagnosticspb.ServerInfoType, recordWarningInStmtCtx bool) ([][]types.Datum, error) { + type result struct { + idx int + rows [][]types.Datum + err error + } + wg := sync.WaitGroup{} + ch := make(chan result, len(serversInfo)) + infoTp := serverInfoType + finalRows := make([][]types.Datum, 0, len(serversInfo)*10) + for i, srv := range serversInfo { + address := srv.Address + remote := address + if srv.ServerType == "tidb" { + remote = srv.StatusAddr + } + wg.Add(1) + go func(index int, remote, address, serverTP string) { + util.WithRecovery(func() { + defer wg.Done() + items, err := getServerInfoByGRPC(ctx, remote, infoTp) + if err != nil { + ch <- result{idx: index, err: err} + return + } + partRows := serverInfoItemToRows(items, serverTP, address) + ch <- result{idx: index, rows: partRows} + }, nil) + }(i, remote, address, srv.ServerType) + } + wg.Wait() + close(ch) + // Keep the original order to make the result more stable + var results []result //nolint: prealloc + for result := range ch { + if result.err != nil { + if recordWarningInStmtCtx { + sctx.GetSessionVars().StmtCtx.AppendWarning(result.err) + } else { + log.Warn(result.err.Error()) + } + continue + } + results = append(results, result) + } + slices.SortFunc(results, func(i, j result) bool { return i.idx < j.idx }) + for _, result := range results { + finalRows = append(finalRows, result.rows...) + } + return finalRows, nil +} + +func serverInfoItemToRows(items []*diagnosticspb.ServerInfoItem, tp, addr string) [][]types.Datum { + rows := make([][]types.Datum, 0, len(items)) + for _, v := range items { + for _, item := range v.Pairs { + row := types.MakeDatums( + tp, + addr, + v.Tp, + v.Name, + item.Key, + item.Value, + ) + rows = append(rows, row) + } + } + return rows +} + +func getServerInfoByGRPC(ctx context.Context, address string, tp diagnosticspb.ServerInfoType) ([]*diagnosticspb.ServerInfoItem, error) { + opt := grpc.WithInsecure() + security := config.GetGlobalConfig().Security + if len(security.ClusterSSLCA) != 0 { + clusterSecurity := security.ClusterSecurity() + tlsConfig, err := clusterSecurity.ToTLSConfig() + if err != nil { + return nil, errors.Trace(err) + } + opt = grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)) + } + conn, err := grpc.Dial(address, opt) + if err != nil { + return nil, err + } + defer func() { + err := conn.Close() + if err != nil { + log.Error("close grpc connection error", zap.Error(err)) + } + }() + + cli := diagnosticspb.NewDiagnosticsClient(conn) + ctx, cancel := context.WithTimeout(ctx, time.Second*10) + defer cancel() + r, err := cli.ServerInfo(ctx, &diagnosticspb.ServerInfoRequest{Tp: tp}) + if err != nil { + return nil, err + } + return r.Items, nil +} + +// FilterClusterServerInfo filters serversInfo by nodeTypes and addresses +func FilterClusterServerInfo(serversInfo []ServerInfo, nodeTypes, addresses set.StringSet) []ServerInfo { + if len(nodeTypes) == 0 && len(addresses) == 0 { + return serversInfo + } + + filterServers := make([]ServerInfo, 0, len(serversInfo)) + for _, srv := range serversInfo { + // Skip some node type which has been filtered in WHERE clause + // e.g: SELECT * FROM cluster_config WHERE type='tikv' + if len(nodeTypes) > 0 && !nodeTypes.Exist(srv.ServerType) { + continue + } + // Skip some node address which has been filtered in WHERE clause + // e.g: SELECT * FROM cluster_config WHERE address='192.16.8.12:2379' + if len(addresses) > 0 && !addresses.Exist(srv.Address) { + continue + } + filterServers = append(filterServers, srv) + } + return filterServers +} diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 15cb2026ba737..e2f04758dda6e 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -18,6 +18,7 @@ import ( "fmt" "math" "os" + "strconv" "strings" "testing" "time" @@ -39,7 +40,10 @@ import ( "github.com/pingcap/tidb/session/txninfo" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/gctuner" + "github.com/pingcap/tidb/util/memory" "github.com/stretchr/testify/require" ) @@ -53,7 +57,7 @@ func newTestKitWithRoot(t *testing.T, store kv.Storage) *testkit.TestKit { func newTestKitWithPlanCache(t *testing.T, store kv.Storage) *testkit.TestKit { tk := testkit.NewTestKit(t, store) se, err := session.CreateSession4TestWithOpt(store, &session.Opt{PreparedPlanCache: plannercore.NewLRUPlanCache(100, - 0.1, math.MaxUint64, plannercore.PickPlanFromBucket)}) + 0.1, math.MaxUint64, plannercore.PickPlanFromBucket, tk.Session())}) require.NoError(t, err) tk.SetSession(se) tk.RefreshConnectionID() @@ -260,6 +264,8 @@ func TestCurrentTimestampAsDefault(t *testing.T) { c_timestamp timestamp, c_timestamp_default timestamp default current_timestamp, c_timestamp_default_3 timestamp(3) default current_timestamp(3), + c_date_default date default current_date, + c_date_default_2 date default curdate(), c_varchar_default varchar(20) default "current_timestamp", c_varchar_default_3 varchar(20) default "current_timestamp(3)", c_varchar_default_on_update datetime default current_timestamp on update current_timestamp, @@ -272,6 +278,8 @@ func TestCurrentTimestampAsDefault(t *testing.T) { WHERE table_schema = "default_time_test" AND table_name = "default_time_table" ORDER BY column_name`, ).Check(testkit.Rows( + "c_date_default CURRENT_DATE ", + "c_date_default_2 CURRENT_DATE ", "c_datetime ", "c_datetime_default CURRENT_TIMESTAMP ", "c_datetime_default_2 CURRENT_TIMESTAMP(2) ", @@ -527,18 +535,168 @@ func TestSlowQuery(t *testing.T) { slowLogFileName := "tidb_slow.log" prepareSlowLogfile(t, slowLogFileName) defer func() { require.NoError(t, os.Remove(slowLogFileName)) }() + expectedRes := [][]interface{}{ + {"2019-02-12 19:33:56.571953", + "406315658548871171", + "root", + "localhost", + "6", + "57", + "0.12", + "4.895492", + "0.4", + "0.2", + "0.000000003", + "2", + "0.000000002", + "0.00000001", + "0.000000003", + "0.19", + "0.21", + "0.01", + "0", + "0.18", + "[txnLock]", + "0.03", + "0", + "15", + "480", + "1", + "8", + "0.3824278", + "0.161", + "0.101", + "0.092", + "1.71", + "1", + "100001", + "100000", + "100", + "10", + "10", + "10", + "100", + "test", + "", + "0", + "42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772", + "t1:1,t2:2", + "0.1", + "0.2", + "0.03", + "127.0.0.1:20160", + "0.05", + "0.6", + "0.8", + "0.0.0.0:20160", + "70724", + "65536", + "0", + "0", + "0", + "0", + "10", + "", + "", + "0", + "1", + "0", + "0", + "1", + "0", + "0", + "abcd", + "60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4", + "", + "update t set i = 2;", + "select * from t_slim;"}, + {"2021-09-08 14:39:54.506967", + "427578666238083075", + "root", + "172.16.0.0", + "40507", + "0", + "0", + "25.571605962", + "0.002923536", + "0.006800973", + "0.002100764", + "0", + "0", + "0", + "0.000015801", + "25.542014572", + "0", + "0.002294647", + "0.000605473", + "12.483", + "[tikvRPC regionMiss tikvRPC regionMiss regionMiss]", + "0", + "0", + "624", + "172064", + "60", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "rtdb", + "", + "0", + "124acb3a0bec903176baca5f9da00b4e7512a41c93b417923f26502edeb324cc", + "", + "0", + "0", + "0", + "", + "0", + "0", + "0", + "", + "856544", + "0", + "86.635049185", + "0.015486658", + "100.054", + "0", + "0", + "", + "", + "0", + "1", + "0", + "0", + "0", + "0", + "0", + "", + "", + "", + "", + "INSERT INTO ...;", + }, + } tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", slowLogFileName)) tk.MustExec("set time_zone = '+08:00';") re := tk.MustQuery("select * from information_schema.slow_query") - re.Check(testkit.RowsWithSep("|", "2019-02-12 19:33:56.571953|406315658548871171|root|localhost|6|57|0.12|4.895492|0.4|0.2|0.000000003|2|0.000000002|0.00000001|0.000000003|0.19|0.21|0.01|0|0.18|[txnLock]|0.03|0|15|480|1|8|0.3824278|0.161|0.101|0.092|1.71|1|100001|100000|100|10|10|10|100|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|65536|0|0|0|0|10||0|1|0|0|1|0|0|abcd|60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4||update t set i = 2;|select * from t_slim;", - "2021-09-08|14:39:54.506967|427578666238083075|root|172.16.0.0|40507|0|0|25.571605962|0.002923536|0.006800973|0.002100764|0|0|0|0.000015801|25.542014572|0|0.002294647|0.000605473|12.483|[tikvRPC regionMiss tikvRPC regionMiss regionMiss]|0|0|624|172064|60|0|0|0|0|0|0|0|0|0|0|0|0|0|0|rtdb||0|124acb3a0bec903176baca5f9da00b4e7512a41c93b417923f26502edeb324cc||0|0|0||0|0|0||856544|0|86.635049185|0.015486658|100.054|0|0||0|1|0|0|0|0|0|||||INSERT INTO ...;", - )) + re.Check(expectedRes) + tk.MustExec("set time_zone = '+00:00';") re = tk.MustQuery("select * from information_schema.slow_query") - re.Check(testkit.RowsWithSep("|", "2019-02-12 11:33:56.571953|406315658548871171|root|localhost|6|57|0.12|4.895492|0.4|0.2|0.000000003|2|0.000000002|0.00000001|0.000000003|0.19|0.21|0.01|0|0.18|[txnLock]|0.03|0|15|480|1|8|0.3824278|0.161|0.101|0.092|1.71|1|100001|100000|100|10|10|10|100|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|65536|0|0|0|0|10||0|1|0|0|1|0|0|abcd|60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4||update t set i = 2;|select * from t_slim;", - "2021-09-08|06:39:54.506967|427578666238083075|root|172.16.0.0|40507|0|0|25.571605962|0.002923536|0.006800973|0.002100764|0|0|0|0.000015801|25.542014572|0|0.002294647|0.000605473|12.483|[tikvRPC regionMiss tikvRPC regionMiss regionMiss]|0|0|624|172064|60|0|0|0|0|0|0|0|0|0|0|0|0|0|0|rtdb||0|124acb3a0bec903176baca5f9da00b4e7512a41c93b417923f26502edeb324cc||0|0|0||0|0|0||856544|0|86.635049185|0.015486658|100.054|0|0||0|1|0|0|0|0|0|||||INSERT INTO ...;", - )) + expectedRes[0][0] = "2019-02-12 11:33:56.571953" + expectedRes[1][0] = "2021-09-08 06:39:54.506967" + re.Check(expectedRes) // Test for long query. f, err := os.OpenFile(slowLogFileName, os.O_CREATE|os.O_WRONLY, 0644) @@ -584,12 +742,12 @@ INSERT INTO ...; defer func() { require.NoError(t, os.Remove(slowLogFileName)) }() tk := testkit.NewTestKit(t, store) - //check schema + // check schema tk.MustQuery(`select COUNT(*) from information_schema.columns WHERE table_name = 'slow_query' and column_name = '` + columnName + `'`). Check(testkit.Rows("1")) - //check select + // check select tk.MustQuery(`select ` + columnName + ` from information_schema.slow_query`).Check(testkit.Rows("1")) } @@ -672,8 +830,14 @@ func TestSelectHiddenColumn(t *testing.T) { func TestFormatVersion(t *testing.T) { // Test for defaultVersions. - defaultVersions := []string{"5.7.25-TiDB-None", "5.7.25-TiDB-8.0.18", "5.7.25-TiDB-8.0.18-beta.1", "5.7.25-TiDB-v4.0.0-beta-446-g5268094af"} - defaultRes := []string{"None", "8.0.18", "8.0.18-beta.1", "4.0.0-beta"} + defaultVersions := []string{ + "5.7.25-TiDB-None", + "5.7.25-TiDB-8.0.18", + "5.7.25-TiDB-8.0.18-beta.1", + "5.7.25-TiDB-v4.0.0-beta-446-g5268094af", + "5.7.25-TiDB-", + "5.7.25-TiDB-v4.0.0-TiDB-446"} + defaultRes := []string{"None", "8.0.18", "8.0.18-beta.1", "4.0.0-beta", "", "4.0.0-TiDB"} for i, v := range defaultVersions { version := infoschema.FormatTiDBVersion(v, true) require.Equal(t, defaultRes[i], version) @@ -1048,7 +1212,7 @@ func TestStmtSummaryInternalQuery(t *testing.T) { "where digest_text like \"select `original_sql` , `bind_sql` , `default_db` , status%\"" tk.MustQuery(sql).Check(testkit.Rows( "select `original_sql` , `bind_sql` , `default_db` , status , `create_time` , `update_time` , charset , " + - "collation , source from `mysql` . `bind_info` where `update_time` > ? order by `update_time` , `create_time`")) + "collation , source , `sql_digest` , `plan_digest` from `mysql` . `bind_info` where `update_time` > ? order by `update_time` , `create_time`")) // Test for issue #21642. tk.MustQuery(`select tidb_version()`) @@ -1383,16 +1547,19 @@ func TestTiDBTrx(t *testing.T) { tk.MustExec("update test_tidb_trx set i = i + 1") _, digest := parser.NormalizeDigest("update test_tidb_trx set i = i + 1") sm := &testkit.MockSessionManager{TxnInfo: make([]*txninfo.TxnInfo, 2)} + memDBTracker := memory.NewTracker(memory.LabelForMemDB, -1) + memDBTracker.Consume(19) + tk.Session().GetSessionVars().MemDBFootprint = memDBTracker sm.TxnInfo[0] = &txninfo.TxnInfo{ StartTS: 424768545227014155, CurrentSQLDigest: digest.String(), State: txninfo.TxnIdle, EntriesCount: 1, - EntriesSize: 19, ConnectionID: 2, Username: "root", CurrentDB: "test", } + blockTime2 := time.Date(2021, 05, 20, 13, 18, 30, 123456000, time.Local) sm.TxnInfo[1] = &txninfo.TxnInfo{ StartTS: 425070846483628033, @@ -1409,7 +1576,7 @@ func TestTiDBTrx(t *testing.T) { tk.MustQuery("select * from information_schema.TIDB_TRX;").Check(testkit.Rows( "424768545227014155 2021-05-07 12:56:48.001000 "+digest.String()+" update `test_tidb_trx` set `i` = `i` + ? Idle 1 19 2 root test [] ", - "425070846483628033 2021-05-20 21:16:35.778000 LockWaiting 2021-05-20 13:18:30.123456 0 0 10 user1 db1 [\"sql1\",\"sql2\",\""+digest.String()+"\"] ")) + "425070846483628033 2021-05-20 21:16:35.778000 LockWaiting 2021-05-20 13:18:30.123456 0 19 10 user1 db1 [\"sql1\",\"sql2\",\""+digest.String()+"\"] ")) // Test the all_sql_digests column can be directly passed to the tidb_decode_sql_digests function. require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/sqlDigestRetrieverSkipRetrieveGlobal", "return")) @@ -1539,6 +1706,7 @@ func TestVariablesInfo(t *testing.T) { // See session/bootstrap.go:doDMLWorks() for where the exceptions are defined. stmt := tk.MustQuery(`SELECT variable_name, default_value, current_value FROM information_schema.variables_info WHERE current_value != default_value and default_value != '' ORDER BY variable_name`) stmt.Check(testkit.Rows( + "last_sql_use_alloc OFF ON", // for test stability "tidb_enable_auto_analyze ON OFF", // always changed for tests "tidb_enable_collect_execution_info ON OFF", // for test stability "tidb_enable_mutation_checker OFF ON", // for new installs @@ -1560,3 +1728,116 @@ func TestTableConstraintsContainForeignKeys(t *testing.T) { tk.MustQuery("SELECT * FROM INFORMATION_SCHEMA.table_constraints WHERE constraint_schema = 'tableconstraints' AND table_name = 't2'").Sort().Check(testkit.Rows("def tableconstraints PRIMARY tableconstraints t2 PRIMARY KEY", "def tableconstraints fk_t2_t1 tableconstraints t2 FOREIGN KEY")) tk.MustQuery("SELECT * FROM INFORMATION_SCHEMA.table_constraints WHERE constraint_schema = 'tableconstraints' AND table_name = 't1'").Sort().Check(testkit.Rows("def tableconstraints PRIMARY tableconstraints t1 PRIMARY KEY")) } + +func TestMemoryUsageAndOpsHistory(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/util/gctuner/testMemoryLimitTuner", "return(true)")) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/util/gctuner/testMemoryLimitTuner")) + }() + gctuner.GlobalMemoryLimitTuner.Start() + defer func() { + time.Sleep(1 * time.Second) // Wait tuning finished. + }() + tk.MustExec("set global tidb_mem_oom_action = 'CANCEL'") + tk.MustExec("set global tidb_server_memory_limit=512<<20") + tk.MustExec("set global tidb_enable_tmp_storage_on_oom=off") + dom, err := session.GetDomain(store) + require.Nil(t, err) + go dom.ServerMemoryLimitHandle().SetSessionManager(tk.Session().GetSessionManager()).Run() + // OOM + tk.MustExec("use test") + tk.MustExec("create table t(a int)") + tk.MustExec("insert into t values(1)") + for i := 0; i < 9; i++ { + tk.MustExec("insert into t select * from t;") + } + + var tmp string + var ok bool + var beginTime = time.Now().Format(types.TimeFormat) + err = tk.QueryToErr("explain analyze select * from t t1 join t t2 join t t3 on t1.a=t2.a and t1.a=t3.a order by t1.a") + var endTime = time.Now().Format(types.TimeFormat) + require.NotNil(t, err) + // Check Memory Table + rows := tk.MustQuery("select * from INFORMATION_SCHEMA.MEMORY_USAGE").Rows() + require.Len(t, rows, 1) + row := rows[0] + require.Len(t, row, 11) + require.Equal(t, row[0], strconv.FormatUint(memory.GetMemTotalIgnoreErr(), 10)) // MEMORY_TOTAL + require.Equal(t, row[1], "536870912") // MEMORY_LIMIT + require.Greater(t, row[2], "0") // MEMORY_CURRENT + tmp, ok = row[3].(string) // MEMORY_MAX_USED + require.Equal(t, ok, true) + val, err := strconv.ParseUint(tmp, 10, 64) + require.Nil(t, err) + require.Greater(t, val, uint64(536870912)) + + tmp, ok = row[4].(string) // CURRENT_OPS + require.Equal(t, ok, true) + if tmp != "null" && tmp != "shrink" { + require.Fail(t, "CURRENT_OPS get wrong value") + } + require.GreaterOrEqual(t, row[5], beginTime) // SESSION_KILL_LAST + require.LessOrEqual(t, row[5], endTime) + require.Greater(t, row[6], "0") // SESSION_KILL_TOTAL + require.GreaterOrEqual(t, row[7], beginTime) // GC_LAST + require.LessOrEqual(t, row[7], endTime) + require.Greater(t, row[8], "0") // GC_TOTAL + require.Equal(t, row[9], "0") // DISK_USAGE + require.Equal(t, row[10], "0") // QUERY_FORCE_DISK + + rows = tk.MustQuery("select * from INFORMATION_SCHEMA.MEMORY_USAGE_OPS_HISTORY").Rows() + require.Greater(t, len(rows), 0) + row = rows[len(rows)-1] + require.Len(t, row, 12) + require.GreaterOrEqual(t, row[0], beginTime) // TIME + require.LessOrEqual(t, row[0], endTime) + require.Equal(t, row[1], "SessionKill") // OPS + require.Equal(t, row[2], "536870912") // MEMORY_LIMIT + tmp, ok = row[3].(string) // MEMORY_CURRENT + require.Equal(t, ok, true) + val, err = strconv.ParseUint(tmp, 10, 64) + require.Nil(t, err) + require.Greater(t, val, uint64(536870912)) + + require.Greater(t, row[4], "0") // PROCESSID + require.Greater(t, row[5], "0") // MEM + require.Equal(t, row[6], "0") // DISK + require.Equal(t, row[7], "") // CLIENT + require.Equal(t, row[8], "test") // DB + require.Equal(t, row[9], "") // USER + require.Equal(t, row[10], "e3237ec256015a3566757e0c2742507cd30ae04e4cac2fbc14d269eafe7b067b") // SQL_DIGEST + require.Equal(t, row[11], "explain analyze select * from t t1 join t t2 join t t3 on t1.a=t2.a and t1.a=t3.a order by t1.a") // SQL_TEXT +} + +func TestAddFieldsForBinding(t *testing.T) { + s := new(clusterTablesSuite) + s.store, s.dom = testkit.CreateMockStoreAndDomain(t) + s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil) + s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer() + s.startTime = time.Now() + defer s.httpServer.Close() + defer s.rpcserver.Stop() + tk := s.newTestKitWithRoot(t) + + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, key(a))") + tk.MustExec("select /*+ ignore_index(t, a)*/ * from t where a = 1") + planDigest := "4e3159169cc63c14b139a4e7d72eae1759875c9a9581f94bb2079aae961189cb" + rows := tk.MustQuery(fmt.Sprintf("select stmt_type, prepared, sample_user, schema_name, query_sample_text, charset, collation, plan_hint, digest_text "+ + "from information_schema.cluster_statements_summary where plan_digest = '%s'", planDigest)).Rows() + + require.Equal(t, rows[0][0], "Select") + require.Equal(t, rows[0][1], "0") + require.Equal(t, rows[0][2], "root") + require.Equal(t, rows[0][3], "test") + require.Equal(t, rows[0][4], "select /*+ ignore_index(t, a)*/ * from t where a = 1") + require.Equal(t, rows[0][5], "utf8mb4") + require.Equal(t, rows[0][6], "utf8mb4_bin") + require.Equal(t, rows[0][7], "use_index(@`sel_1` `test`.`t` ), ignore_index(`t` `a`)") + require.Equal(t, rows[0][8], "select * from `t` where `a` = ?") +} diff --git a/keyspace/BUILD.bazel b/keyspace/BUILD.bazel new file mode 100644 index 0000000000000..a536722a018d7 --- /dev/null +++ b/keyspace/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "keyspace", + srcs = ["keyspace.go"], + importpath = "github.com/pingcap/tidb/keyspace", + visibility = ["//visibility:public"], + deps = [ + "@com_github_pingcap_kvproto//pkg/kvrpcpb", + "@com_github_tikv_client_go_v2//tikv", + ], +) diff --git a/keyspace/keyspace.go b/keyspace/keyspace.go new file mode 100644 index 0000000000000..103d0f742cee7 --- /dev/null +++ b/keyspace/keyspace.go @@ -0,0 +1,38 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package keyspace + +import ( + "fmt" + + "github.com/pingcap/kvproto/pkg/kvrpcpb" + "github.com/tikv/client-go/v2/tikv" +) + +const ( + // tidbKeyspaceEtcdPathPrefix is the keyspace prefix for etcd namespace + tidbKeyspaceEtcdPathPrefix = "/keyspaces/tidb/" +) + +// CodecV1 represents api v1 codec. +var CodecV1 = tikv.NewCodecV1(tikv.ModeTxn) + +// MakeKeyspaceEtcdNamespace return the keyspace prefix path for etcd namespace +func MakeKeyspaceEtcdNamespace(c tikv.Codec) string { + if c.GetAPIVersion() == kvrpcpb.APIVersion_V1 { + return "" + } + return fmt.Sprintf(tidbKeyspaceEtcdPathPrefix+"%d", c.GetKeyspaceID()) +} diff --git a/kv/BUILD.bazel b/kv/BUILD.bazel index 32dd9f1474179..992d99d382e42 100644 --- a/kv/BUILD.bazel +++ b/kv/BUILD.bazel @@ -48,6 +48,7 @@ go_library( "@com_github_tikv_client_go_v2//tikvrpc", "@com_github_tikv_client_go_v2//util", "@com_github_tikv_pd_client//:client", + "@org_golang_x_exp//slices", "@org_uber_go_zap//:zap", ], ) diff --git a/kv/interface_mock_test.go b/kv/interface_mock_test.go index 8090463c84223..283eb0858b716 100644 --- a/kv/interface_mock_test.go +++ b/kv/interface_mock_test.go @@ -52,6 +52,13 @@ func (t *mockTxn) LockKeys(_ context.Context, _ *LockCtx, _ ...Key) error { return nil } +func (t *mockTxn) LockKeysFunc(_ context.Context, _ *LockCtx, fn func(), _ ...Key) error { + if fn != nil { + fn() + } + return nil +} + func (t *mockTxn) SetOption(opt int, val interface{}) { t.opts[opt] = val } @@ -161,6 +168,20 @@ func (t *mockTxn) UpdateMemBufferFlags(_ []byte, _ ...FlagsOp) { } +func (t *mockTxn) SetMemoryFootprintChangeHook(func(uint64)) { + +} + +func (t *mockTxn) Mem() uint64 { + return 0 +} + +func (t *mockTxn) StartAggressiveLocking() error { return nil } +func (t *mockTxn) RetryAggressiveLocking(_ context.Context) error { return nil } +func (t *mockTxn) CancelAggressiveLocking(_ context.Context) error { return nil } +func (t *mockTxn) DoneAggressiveLocking(_ context.Context) error { return nil } +func (t *mockTxn) IsInAggressiveLockingMode() bool { return false } + // newMockTxn new a mockTxn. func newMockTxn() Transaction { return &mockTxn{ @@ -172,6 +193,10 @@ func newMockTxn() Transaction { // mockStorage is used to start a must commit-failed txn. type mockStorage struct{} +func (s *mockStorage) GetCodec() tikv.Codec { + return nil +} + func (s *mockStorage) Begin(opts ...tikv.TxnOption) (Transaction, error) { return newMockTxn(), nil } diff --git a/kv/kv.go b/kv/kv.go index d39dc1ee5c862..9239cc514c7b2 100644 --- a/kv/kv.go +++ b/kv/kv.go @@ -15,6 +15,7 @@ package kv import ( + "bytes" "context" "crypto/tls" "time" @@ -33,6 +34,7 @@ import ( "github.com/tikv/client-go/v2/tikvrpc" "github.com/tikv/client-go/v2/util" pd "github.com/tikv/pd/client" + "golang.org/x/exp/slices" ) // UnCommitIndexKVFlag uses to indicate the index key/value is no need to commit. @@ -201,8 +203,13 @@ type LockCtx = tikvstore.LockCtx type Transaction interface { RetrieverMutator AssertionProto + AggressiveLockingController // Size returns sum of keys and values length. Size() int + // Mem returns the memory consumption of the transaction. + Mem() uint64 + // SetMemoryFootprintChangeHook sets the hook that will be called when the memory footprint changes. + SetMemoryFootprintChangeHook(func(uint64)) // Len returns the number of entries in the DB. Len() int // Reset reset the Transaction to initial states. @@ -216,6 +223,10 @@ type Transaction interface { // LockKeys tries to lock the entries with the keys in KV store. // Will block until all keys are locked successfully or an error occurs. LockKeys(ctx context.Context, lockCtx *LockCtx, keys ...Key) error + // LockKeysFunc tries to lock the entries with the keys in KV store. + // Will block until all keys are locked successfully or an error occurs. + // fn is called before LockKeys unlocks the keys. + LockKeysFunc(ctx context.Context, lockCtx *LockCtx, fn func(), keys ...Key) error // SetOption sets an option with a value, when val is nil, uses the default // value of this option. SetOption(opt int, val interface{}) @@ -271,6 +282,15 @@ type AssertionProto interface { SetAssertion(key []byte, assertion ...FlagsOp) error } +// AggressiveLockingController is the interface that defines aggressive locking related operations. +type AggressiveLockingController interface { + StartAggressiveLocking() error + RetryAggressiveLocking(ctx context.Context) error + CancelAggressiveLocking(ctx context.Context) error + DoneAggressiveLocking(ctx context.Context) error + IsInAggressiveLockingMode() bool +} + // Client is used to send request to KV layer. type Client interface { // Send sends request to KV layer, returns a Response. @@ -331,13 +351,168 @@ func (t StoreType) Name() string { return "unspecified" } +// KeyRanges wrap the ranges for partitioned table cases. +// We might send ranges from different in the one request. +type KeyRanges struct { + ranges [][]KeyRange + rowCountHints [][]int + + isPartitioned bool +} + +// NewPartitionedKeyRanges constructs a new RequestRange for partitioned table. +func NewPartitionedKeyRanges(ranges [][]KeyRange) *KeyRanges { + return NewPartitionedKeyRangesWithHints(ranges, nil) +} + +// NewNonParitionedKeyRanges constructs a new RequestRange for a non partitioned table. +func NewNonParitionedKeyRanges(ranges []KeyRange) *KeyRanges { + return NewNonParitionedKeyRangesWithHint(ranges, nil) +} + +// NewPartitionedKeyRangesWithHints constructs a new RequestRange for partitioned table with row count hint. +func NewPartitionedKeyRangesWithHints(ranges [][]KeyRange, hints [][]int) *KeyRanges { + return &KeyRanges{ + ranges: ranges, + rowCountHints: hints, + isPartitioned: true, + } +} + +// NewNonParitionedKeyRangesWithHint constructs a new RequestRange for a non partitioned table with rou count hint. +func NewNonParitionedKeyRangesWithHint(ranges []KeyRange, hints []int) *KeyRanges { + rr := &KeyRanges{ + ranges: [][]KeyRange{ranges}, + isPartitioned: false, + } + if hints != nil { + rr.rowCountHints = [][]int{hints} + } + return rr +} + +// FirstPartitionRange returns the the result of first range. +// We may use some func to generate ranges for both partitioned table and non partitioned table. +// This method provides a way to fallback to non-partitioned ranges. +func (rr *KeyRanges) FirstPartitionRange() []KeyRange { + if len(rr.ranges) == 0 { + return []KeyRange{} + } + return rr.ranges[0] +} + +// SetToNonPartitioned set the status to non-partitioned. +func (rr *KeyRanges) SetToNonPartitioned() error { + if len(rr.ranges) > 1 { + return errors.Errorf("you want to change the partitioned ranges to non-partitioned ranges") + } + rr.isPartitioned = false + return nil +} + +// AppendSelfTo appends itself to another slice. +func (rr *KeyRanges) AppendSelfTo(ranges []KeyRange) []KeyRange { + for _, r := range rr.ranges { + ranges = append(ranges, r...) + } + return ranges +} + +// SortByFunc sorts each partition's ranges. +// Since the ranges are sorted in most cases, we check it first. +func (rr *KeyRanges) SortByFunc(sortFunc func(i, j KeyRange) bool) { + if !slices.IsSortedFunc(rr.ranges, func(i, j []KeyRange) bool { + // A simple short-circuit since the empty range actually won't make anything wrong. + if len(i) == 0 || len(j) == 0 { + return true + } + return sortFunc(i[0], j[0]) + }) { + slices.SortFunc(rr.ranges, func(i, j []KeyRange) bool { + if len(i) == 0 { + return true + } + if len(j) == 0 { + return false + } + return sortFunc(i[0], j[0]) + }) + } + for i := range rr.ranges { + if !slices.IsSortedFunc(rr.ranges[i], sortFunc) { + slices.SortFunc(rr.ranges[i], sortFunc) + } + } +} + +// ForEachPartitionWithErr runs the func for each partition with an error check. +func (rr *KeyRanges) ForEachPartitionWithErr(theFunc func([]KeyRange, []int) error) (err error) { + for i := range rr.ranges { + var hints []int + if len(rr.rowCountHints) > i { + hints = rr.rowCountHints[i] + } + err = theFunc(rr.ranges[i], hints) + if err != nil { + return err + } + } + return nil +} + +// ForEachPartition runs the func for each partition without error check. +func (rr *KeyRanges) ForEachPartition(theFunc func([]KeyRange)) { + for i := range rr.ranges { + theFunc(rr.ranges[i]) + } +} + +// PartitionNum returns how many partition is involved in the ranges. +func (rr *KeyRanges) PartitionNum() int { + return len(rr.ranges) +} + +// IsFullySorted checks whether the ranges are sorted inside partition and each partition is also sorated. +func (rr *KeyRanges) IsFullySorted() bool { + sortedByPartition := slices.IsSortedFunc(rr.ranges, func(i, j []KeyRange) bool { + // A simple short-circuit since the empty range actually won't make anything wrong. + if len(i) == 0 || len(j) == 0 { + return true + } + return bytes.Compare(i[0].StartKey, j[0].StartKey) < 0 + }) + if !sortedByPartition { + return false + } + for _, ranges := range rr.ranges { + if !slices.IsSortedFunc(ranges, func(i, j KeyRange) bool { + return bytes.Compare(i.StartKey, j.StartKey) < 0 + }) { + return false + } + } + return true +} + +// TotalRangeNum returns how many ranges there are. +func (rr *KeyRanges) TotalRangeNum() int { + ret := 0 + for _, r := range rr.ranges { + ret += len(r) + } + return ret +} + // Request represents a kv request. type Request struct { // Tp is the request type. - Tp int64 - StartTs uint64 - Data []byte - KeyRanges []KeyRange + Tp int64 + StartTs uint64 + Data []byte + + // KeyRanges makes sure that the request is sent first by partition then by region. + // When the table is small, it's possible that multiple partitions are in the same region. + KeyRanges *KeyRanges // For PartitionTableScan used by tiflash. PartitionIDAndRanges []PartitionIDAndRanges @@ -394,6 +569,10 @@ type Request struct { } // RequestSource indicates whether the request is an internal request. RequestSource util.RequestSource + // StoreBatchSize indicates the batch size of coprocessor in the same store. + StoreBatchSize int + // ResourceGroupName is the name of the bind resource group. + ResourceGroupName string } // CoprRequestAdjuster is used to check and adjust a copr request according to specific rules. @@ -502,6 +681,8 @@ type Storage interface { GetMinSafeTS(txnScope string) uint64 // GetLockWaits return all lock wait information GetLockWaits() ([]*deadlockpb.WaitForEntry, error) + // GetCodec gets the codec of the storage. + GetCodec() tikv.Codec } // EtcdBackend is used for judging a storage is a real TiKV. diff --git a/kv/main_test.go b/kv/main_test.go index e0b772c63768d..3d161d7ce0704 100644 --- a/kv/main_test.go +++ b/kv/main_test.go @@ -26,6 +26,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/kv/mpp.go b/kv/mpp.go index b0752f8186deb..de0a8e8654528 100644 --- a/kv/mpp.go +++ b/kv/mpp.go @@ -16,7 +16,6 @@ package kv import ( "context" - "sync" "time" "github.com/pingcap/kvproto/pkg/mpp" @@ -28,21 +27,33 @@ type MPPTaskMeta interface { GetAddress() string } +// MPPQueryID means the global unique id of a mpp query. +type MPPQueryID struct { + QueryTs uint64 // timestamp of query execution, used for TiFlash minTSO schedule + LocalQueryID uint64 // unique mpp query id in local tidb memory. + ServerID uint64 +} + // MPPTask means the minimum execution unit of a mpp computation job. type MPPTask struct { - Meta MPPTaskMeta // on which store this task will execute - ID int64 // mppTaskID - StartTs uint64 - TableID int64 // physical table id + Meta MPPTaskMeta // on which store this task will execute + ID int64 // mppTaskID + StartTs uint64 + MppQueryID MPPQueryID + TableID int64 // physical table id - PartitionTableIDs []int64 + PartitionTableIDs []int64 + IsDisaggregatedTiFlashStaticPrune bool } // ToPB generates the pb structure. func (t *MPPTask) ToPB() *mpp.TaskMeta { meta := &mpp.TaskMeta{ - StartTs: t.StartTs, - TaskId: t.ID, + StartTs: t.StartTs, + QueryTs: t.MppQueryID.QueryTs, + LocalQueryId: t.MppQueryID.LocalQueryID, + ServerId: t.MppQueryID.ServerID, + TaskId: t.ID, } if t.ID != -1 { meta.Address = t.Meta.GetAddress() @@ -71,20 +82,21 @@ type MPPDispatchRequest struct { IsRoot bool // root task returns data to tidb directly. Timeout uint64 // If task is assigned but doesn't receive a connect request during timeout, the task should be destroyed. // SchemaVer is for any schema-ful storage (like tiflash) to validate schema correctness if necessary. - SchemaVar int64 - StartTs uint64 - ID int64 // identify a single task - State MppTaskStates + SchemaVar int64 + StartTs uint64 + MppQueryID MPPQueryID + ID int64 // identify a single task + State MppTaskStates } // MPPClient accepts and processes mpp requests. type MPPClient interface { // ConstructMPPTasks schedules task for a plan fragment. // TODO:: This interface will be refined after we support more executors. - ConstructMPPTasks(context.Context, *MPPBuildTasksRequest, *sync.Map, time.Duration) ([]MPPTaskMeta, error) + ConstructMPPTasks(context.Context, *MPPBuildTasksRequest, time.Duration) ([]MPPTaskMeta, error) // DispatchMPPTasks dispatches ALL mpp requests at once, and returns an iterator that transfers the data. - DispatchMPPTasks(ctx context.Context, vars interface{}, reqs []*MPPDispatchRequest, needTriggerFallback bool, startTs uint64) Response + DispatchMPPTasks(ctx context.Context, vars interface{}, reqs []*MPPDispatchRequest, needTriggerFallback bool, startTs uint64, mppQueryID MPPQueryID) Response } // MPPBuildTasksRequest request the stores allocation for a mpp plan fragment. diff --git a/kv/option.go b/kv/option.go index 888a1e24f0fa0..80d0f7792f172 100644 --- a/kv/option.go +++ b/kv/option.go @@ -93,6 +93,10 @@ const ( ReplicaReadAdjuster // ScanBatchSize set the iter scan batch size. ScanBatchSize + // TxnSource set the source of this transaction. + TxnSource + // ResourceGroupName set the bind resource group name. + ResourceGroupName ) // ReplicaReadType is the type of replica to read data from @@ -109,6 +113,8 @@ const ( ReplicaReadClosest // ReplicaReadClosestAdaptive stands for 'read from follower which locates in the same zone if the response size exceeds certain threshold' ReplicaReadClosestAdaptive + // ReplicaReadLearner stands for 'read from learner'. + ReplicaReadLearner ) // IsFollowerRead checks if follower is going to be used to read data. @@ -165,4 +171,6 @@ const ( InternalTxnBR = InternalTxnTools // InternalTxnTrace handles the trace statement. InternalTxnTrace = "Trace" + // InternalTxnTTL is the type of TTL usage + InternalTxnTTL = "TTL" ) diff --git a/kv/txn.go b/kv/txn.go index d7828c7fb3138..035f2aa662eca 100644 --- a/kv/txn.go +++ b/kv/txn.go @@ -195,20 +195,22 @@ func BackOff(attempts uint) int { func setRequestSourceForInnerTxn(ctx context.Context, txn Transaction) { if source := ctx.Value(RequestSourceKey); source != nil { requestSource := source.(RequestSource) - if !requestSource.RequestSourceInternal { - logutil.Logger(ctx).Warn("`RunInNewTxn` should be used by inner txn only") + if requestSource.RequestSourceType != "" { + if !requestSource.RequestSourceInternal { + logutil.Logger(ctx).Warn("`RunInNewTxn` should be used by inner txn only") + } + txn.SetOption(RequestSourceInternal, requestSource.RequestSourceInternal) + txn.SetOption(RequestSourceType, requestSource.RequestSourceType) + return } - txn.SetOption(RequestSourceInternal, requestSource.RequestSourceInternal) - txn.SetOption(RequestSourceType, requestSource.RequestSourceType) + } + // panic in test mode in case there are requests without source in the future. + // log warnings in production mode. + if flag.Lookup("test.v") != nil || flag.Lookup("check.v") != nil { + panic("unexpected no source type context, if you see this error, " + + "the `RequestSourceTypeKey` is missing in your context") } else { - // panic in test mode in case there are requests without source in the future. - // log warnings in production mode. - if flag.Lookup("test.v") != nil || flag.Lookup("check.v") != nil { - panic("unexpected no source type context, if you see this error, " + - "the `RequestSourceTypeKey` is missing in your context") - } else { - logutil.Logger(ctx).Warn("unexpected no source type context, if you see this warning, " + - "the `RequestSourceTypeKey` is missing in the context") - } + logutil.Logger(ctx).Warn("unexpected no source type context, if you see this warning, " + + "the `RequestSourceTypeKey` is missing in the context") } } diff --git a/meta/BUILD.bazel b/meta/BUILD.bazel index 791662be8c215..c6c796a9771c1 100644 --- a/meta/BUILD.bazel +++ b/meta/BUILD.bazel @@ -16,10 +16,8 @@ go_library( "//parser/mysql", "//structure", "//util/dbterror", - "//util/logutil", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_kvproto//pkg/kvrpcpb", - "@org_uber_go_zap//:zap", ], ) @@ -33,12 +31,10 @@ go_test( embed = [":meta"], flaky = True, deps = [ - "//ddl", "//kv", "//parser/model", "//store/mockstore", "//testkit/testsetup", - "//testkit/testutil", "//util", "@com_github_pingcap_errors//:errors", "@com_github_stretchr_testify//require", diff --git a/meta/autoid/BUILD.bazel b/meta/autoid/BUILD.bazel index f5bb574907665..b67f7f7c223c7 100644 --- a/meta/autoid/BUILD.bazel +++ b/meta/autoid/BUILD.bazel @@ -4,12 +4,14 @@ go_library( name = "autoid", srcs = [ "autoid.go", + "autoid_service.go", "errors.go", "memid.go", ], importpath = "github.com/pingcap/tidb/meta/autoid", visibility = ["//visibility:public"], deps = [ + "//config", "//errno", "//kv", "//meta", @@ -24,8 +26,12 @@ go_library( "@com_github_opentracing_opentracing_go//:opentracing-go", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_kvproto//pkg/autoid", "@com_github_tikv_client_go_v2//txnkv/txnsnapshot", "@com_github_tikv_client_go_v2//util", + "@io_etcd_go_etcd_client_v3//:client", + "@org_golang_google_grpc//:grpc", + "@org_golang_google_grpc//credentials", "@org_uber_go_zap//:zap", ], ) diff --git a/meta/autoid/autoid.go b/meta/autoid/autoid.go index e20c0ed898f13..8c5e1d7bc58d8 100644 --- a/meta/autoid/autoid.go +++ b/meta/autoid/autoid.go @@ -26,6 +26,7 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pingcap/errors" "github.com/pingcap/failpoint" + "github.com/pingcap/kvproto/pkg/autoid" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/metrics" @@ -38,6 +39,7 @@ import ( "github.com/pingcap/tidb/util/mathutil" "github.com/tikv/client-go/v2/txnkv/txnsnapshot" tikvutil "github.com/tikv/client-go/v2/util" + clientv3 "go.etcd.io/etcd/client/v3" "go.uber.org/zap" ) @@ -203,16 +205,36 @@ type Allocator interface { } // Allocators represents a set of `Allocator`s. -type Allocators []Allocator +type Allocators struct { + SepAutoInc bool + Allocs []Allocator +} // NewAllocators packs multiple `Allocator`s into Allocators. -func NewAllocators(allocators ...Allocator) Allocators { - return allocators +func NewAllocators(sepAutoInc bool, allocators ...Allocator) Allocators { + return Allocators{ + SepAutoInc: sepAutoInc, + Allocs: allocators, + } +} + +// Append add an allocator to the allocators. +func (all Allocators) Append(a Allocator) Allocators { + return Allocators{ + SepAutoInc: all.SepAutoInc, + Allocs: append(all.Allocs, a), + } } // Get returns the Allocator according to the AllocatorType. func (all Allocators) Get(allocType AllocatorType) Allocator { - for _, a := range all { + if !all.SepAutoInc { + if allocType == AutoIncrementType { + allocType = RowIDAllocType + } + } + + for _, a := range all.Allocs { if a.GetType() == allocType { return a } @@ -222,13 +244,16 @@ func (all Allocators) Get(allocType AllocatorType) Allocator { // Filter filters all the allocators that match pred. func (all Allocators) Filter(pred func(Allocator) bool) Allocators { - var ret Allocators - for _, a := range all { + var ret []Allocator + for _, a := range all.Allocs { if pred(a) { ret = append(ret, a) } } - return ret + return Allocators{ + SepAutoInc: all.SepAutoInc, + Allocs: ret, + } } type allocator struct { @@ -260,11 +285,15 @@ func SetStep(s int64) { // Base implements autoid.Allocator Base interface. func (alloc *allocator) Base() int64 { + alloc.mu.Lock() + defer alloc.mu.Unlock() return alloc.base } // End implements autoid.Allocator End interface. func (alloc *allocator) End() int64 { + alloc.mu.Lock() + defer alloc.mu.Unlock() return alloc.end } @@ -533,6 +562,52 @@ func NextStep(curStep int64, consumeDur time.Duration) int64 { return res } +// MockForTest is exported for testing. +// The actual implementation is in github.com/pingcap/tidb/autoid_service because of the +// package circle depending issue. +var MockForTest func(kv.Storage) autoid.AutoIDAllocClient + +func newSinglePointAlloc(store kv.Storage, dbID, tblID int64, isUnsigned bool) *singlePointAlloc { + ebd, ok := store.(kv.EtcdBackend) + if !ok { + // newSinglePointAlloc fail because not etcd background + // This could happen in the server package unit test + return nil + } + + addrs, err := ebd.EtcdAddrs() + if err != nil { + panic(err) + } + spa := &singlePointAlloc{ + dbID: dbID, + tblID: tblID, + isUnsigned: isUnsigned, + } + if len(addrs) > 0 { + etcdCli, err := clientv3.New(clientv3.Config{ + Endpoints: addrs, + TLS: ebd.TLSConfig(), + }) + if err != nil { + logutil.BgLogger().Error("[autoid client] fail to connect etcd, fallback to default", zap.Error(err)) + return nil + } + spa.clientDiscover = clientDiscover{etcdCli: etcdCli} + } else { + spa.clientDiscover = clientDiscover{} + spa.mu.AutoIDAllocClient = MockForTest(store) + } + + // mockAutoIDChange failpoint is not implemented in this allocator, so fallback to use the default one. + failpoint.Inject("mockAutoIDChange", func(val failpoint.Value) { + if val.(bool) { + spa = nil + } + }) + return spa +} + // NewAllocator returns a new auto increment id generator on the store. func NewAllocator(store kv.Storage, dbID, tbID int64, isUnsigned bool, allocType AllocatorType, opts ...AllocOption) Allocator { @@ -548,6 +623,22 @@ func NewAllocator(store kv.Storage, dbID, tbID int64, isUnsigned bool, for _, fn := range opts { fn.ApplyOn(alloc) } + + // Use the MySQL compatible AUTO_INCREMENT mode. + if alloc.customStep && alloc.step == 1 && alloc.tbVersion >= model.TableInfoVersion5 { + if allocType == AutoIncrementType { + alloc1 := newSinglePointAlloc(store, dbID, tbID, isUnsigned) + if alloc1 != nil { + return alloc1 + } + } else if allocType == RowIDAllocType { + // Now that the autoid and rowid allocator are separated, the AUTO_ID_CACHE 1 setting should not make + // the rowid allocator do not use cache. + alloc.customStep = false + alloc.step = step + } + } + return alloc } @@ -578,6 +669,10 @@ func NewAllocatorsFromTblInfo(store kv.Storage, schemaID int64, tblInfo *model.T alloc := NewAllocator(store, dbID, tblInfo.ID, tblInfo.IsAutoIncColUnsigned(), RowIDAllocType, idCacheOpt, tblVer) allocs = append(allocs, alloc) } + if hasAutoIncID { + alloc := NewAllocator(store, dbID, tblInfo.ID, tblInfo.IsAutoIncColUnsigned(), AutoIncrementType, idCacheOpt, tblVer) + allocs = append(allocs, alloc) + } hasAutoRandID := tblInfo.ContainsAutoRandomBits() if hasAutoRandID { alloc := NewAllocator(store, dbID, tblInfo.ID, tblInfo.IsAutoRandomBitColUnsigned(), AutoRandomType, idCacheOpt, tblVer) @@ -586,7 +681,7 @@ func NewAllocatorsFromTblInfo(store kv.Storage, schemaID int64, tblInfo *model.T if tblInfo.IsSequence() { allocs = append(allocs, NewSequenceAllocator(store, dbID, tblInfo.ID, tblInfo.Sequence)) } - return NewAllocators(allocs...) + return NewAllocators(tblInfo.SepAutoInc(), allocs...) } // Alloc implements autoid.Allocator Alloc interface. @@ -787,7 +882,7 @@ func (alloc *allocator) alloc4Signed(ctx context.Context, n uint64, increment, o var newBase, newEnd int64 startTime := time.Now() nextStep := alloc.step - if !alloc.customStep { + if !alloc.customStep && alloc.end > 0 { // Although it may skip a segment here, we still think it is consumed. consumeDur := startTime.Sub(alloc.lastAllocTime) nextStep = NextStep(alloc.step, consumeDur) @@ -893,6 +988,11 @@ func (alloc *allocator) alloc4Unsigned(ctx context.Context, n uint64, increment, }() } + if codeRun := ctx.Value("testIssue39528"); codeRun != nil { + *(codeRun.(*bool)) = true + return 0, 0, errors.New("mock error for test") + } + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta) err := kv.RunInNewTxn(ctx, alloc.store, true, func(ctx context.Context, txn kv.Transaction) error { if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { diff --git a/meta/autoid/autoid_service.go b/meta/autoid/autoid_service.go new file mode 100644 index 0000000000000..0b0f4946b3d0c --- /dev/null +++ b/meta/autoid/autoid_service.go @@ -0,0 +1,258 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package autoid + +import ( + "context" + "strings" + "sync" + "time" + + "github.com/opentracing/opentracing-go" + "github.com/pingcap/errors" + "github.com/pingcap/kvproto/pkg/autoid" + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/util/logutil" + clientv3 "go.etcd.io/etcd/client/v3" + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" +) + +var _ Allocator = &singlePointAlloc{} + +type singlePointAlloc struct { + dbID int64 + tblID int64 + lastAllocated int64 + isUnsigned bool + clientDiscover +} + +type clientDiscover struct { + // This the etcd client for service discover + etcdCli *clientv3.Client + // This is the real client for the AutoIDAlloc service + mu struct { + sync.RWMutex + autoid.AutoIDAllocClient + // Release the client conn to avoid resource leak! + // See https://github.com/grpc/grpc-go/issues/5321 + *grpc.ClientConn + } +} + +const ( + autoIDLeaderPath = "tidb/autoid/leader" +) + +func (d *clientDiscover) GetClient(ctx context.Context) (autoid.AutoIDAllocClient, error) { + d.mu.RLock() + cli := d.mu.AutoIDAllocClient + if cli != nil { + d.mu.RUnlock() + return cli, nil + } + d.mu.RUnlock() + + d.mu.Lock() + defer d.mu.Unlock() + if d.mu.AutoIDAllocClient != nil { + return d.mu.AutoIDAllocClient, nil + } + + resp, err := d.etcdCli.Get(ctx, autoIDLeaderPath, clientv3.WithFirstCreate()...) + if err != nil { + return nil, errors.Trace(err) + } + if len(resp.Kvs) == 0 { + return nil, errors.New("autoid service leader not found") + } + + addr := string(resp.Kvs[0].Value) + opt := grpc.WithInsecure() + security := config.GetGlobalConfig().Security + if len(security.ClusterSSLCA) != 0 { + clusterSecurity := security.ClusterSecurity() + tlsConfig, err := clusterSecurity.ToTLSConfig() + if err != nil { + return nil, errors.Trace(err) + } + opt = grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)) + } + logutil.BgLogger().Info("[autoid client] connect to leader", zap.String("addr", addr)) + grpcConn, err := grpc.Dial(addr, opt) + if err != nil { + return nil, errors.Trace(err) + } + cli = autoid.NewAutoIDAllocClient(grpcConn) + d.mu.AutoIDAllocClient = cli + d.mu.ClientConn = grpcConn + return cli, nil +} + +// Alloc allocs N consecutive autoID for table with tableID, returning (min, max] of the allocated autoID batch. +// The consecutive feature is used to insert multiple rows in a statement. +// increment & offset is used to validate the start position (the allocator's base is not always the last allocated id). +// The returned range is (min, max]: +// case increment=1 & offset=1: you can derive the ids like min+1, min+2... max. +// case increment=x & offset=y: you firstly need to seek to firstID by `SeekToFirstAutoIDXXX`, then derive the IDs like firstID, firstID + increment * 2... in the caller. +func (sp *singlePointAlloc) Alloc(ctx context.Context, n uint64, increment, offset int64) (min int64, max int64, _ error) { + if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { + span1 := span.Tracer().StartSpan("autoid.Alloc", opentracing.ChildOf(span.Context())) + defer span1.Finish() + ctx = opentracing.ContextWithSpan(ctx, span1) + } + + if !validIncrementAndOffset(increment, offset) { + return 0, 0, errInvalidIncrementAndOffset.GenWithStackByArgs(increment, offset) + } + +retry: + cli, err := sp.GetClient(ctx) + if err != nil { + return 0, 0, errors.Trace(err) + } + + start := time.Now() + resp, err := cli.AllocAutoID(ctx, &autoid.AutoIDRequest{ + DbID: sp.dbID, + TblID: sp.tblID, + N: n, + Increment: increment, + Offset: offset, + IsUnsigned: sp.isUnsigned, + }) + if err != nil { + if strings.Contains(err.Error(), "rpc error") { + time.Sleep(backoffDuration) + sp.resetConn(err) + goto retry + } + return 0, 0, errors.Trace(err) + } + if len(resp.Errmsg) != 0 { + return 0, 0, errors.Trace(errors.New(string(resp.Errmsg))) + } + + du := time.Since(start) + metrics.AutoIDReqDuration.Observe(du.Seconds()) + sp.lastAllocated = resp.Min + return resp.Min, resp.Max, err +} + +const backoffDuration = 200 * time.Millisecond + +func (sp *singlePointAlloc) resetConn(reason error) { + logutil.BgLogger().Info("[autoid client] reset grpc connection", + zap.String("reason", reason.Error())) + var grpcConn *grpc.ClientConn + sp.mu.Lock() + grpcConn = sp.mu.ClientConn + sp.mu.AutoIDAllocClient = nil + sp.mu.ClientConn = nil + sp.mu.Unlock() + // Close grpc.ClientConn to release resource. + if grpcConn != nil { + err := grpcConn.Close() + if err != nil { + logutil.BgLogger().Warn("[autoid client] close grpc connection error", zap.Error(err)) + } + } +} + +// AllocSeqCache allocs sequence batch value cached in table level(rather than in alloc), the returned range covering +// the size of sequence cache with it's increment. The returned round indicates the sequence cycle times if it is with +// cycle option. +func (*singlePointAlloc) AllocSeqCache() (a int64, b int64, c int64, err error) { + return 0, 0, 0, errors.New("AllocSeqCache not implemented") +} + +// Rebase rebases the autoID base for table with tableID and the new base value. +// If allocIDs is true, it will allocate some IDs and save to the cache. +// If allocIDs is false, it will not allocate IDs. +func (sp *singlePointAlloc) Rebase(ctx context.Context, newBase int64, _ bool) error { + if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { + span1 := span.Tracer().StartSpan("autoid.Rebase", opentracing.ChildOf(span.Context())) + defer span1.Finish() + ctx = opentracing.ContextWithSpan(ctx, span1) + } + + return sp.rebase(ctx, newBase, false) +} + +func (sp *singlePointAlloc) rebase(ctx context.Context, newBase int64, force bool) error { +retry: + cli, err := sp.GetClient(ctx) + if err != nil { + return errors.Trace(err) + } + var resp *autoid.RebaseResponse + resp, err = cli.Rebase(ctx, &autoid.RebaseRequest{ + DbID: sp.dbID, + TblID: sp.tblID, + Base: newBase, + Force: force, + IsUnsigned: sp.isUnsigned, + }) + if err != nil { + if strings.Contains(err.Error(), "rpc error") { + time.Sleep(backoffDuration) + sp.resetConn(err) + goto retry + } + return errors.Trace(err) + } + if len(resp.Errmsg) != 0 { + return errors.Trace(errors.New(string(resp.Errmsg))) + } + sp.lastAllocated = newBase + return nil +} + +// ForceRebase set the next global auto ID to newBase. +func (sp *singlePointAlloc) ForceRebase(newBase int64) error { + if newBase == -1 { + return ErrAutoincReadFailed.GenWithStack("Cannot force rebase the next global ID to '0'") + } + return sp.rebase(context.Background(), newBase, true) +} + +// RebaseSeq rebases the sequence value in number axis with tableID and the new base value. +func (*singlePointAlloc) RebaseSeq(_ int64) (int64, bool, error) { + return 0, false, errors.New("RebaseSeq not implemented") +} + +// Base return the current base of Allocator. +func (sp *singlePointAlloc) Base() int64 { + return sp.lastAllocated +} + +// End is only used for test. +func (sp *singlePointAlloc) End() int64 { + return sp.lastAllocated +} + +// NextGlobalAutoID returns the next global autoID. +// Used by 'show create table', 'alter table auto_increment = xxx' +func (sp *singlePointAlloc) NextGlobalAutoID() (int64, error) { + _, max, err := sp.Alloc(context.Background(), 0, 1, 1) + return max + 1, err +} + +func (*singlePointAlloc) GetType() AllocatorType { + return AutoIncrementType +} diff --git a/meta/autoid/autoid_test.go b/meta/autoid/autoid_test.go index 0b8cd60257cf4..912b1e173bc8c 100644 --- a/meta/autoid/autoid_test.go +++ b/meta/autoid/autoid_test.go @@ -20,6 +20,7 @@ import ( "math" "math/rand" "sync" + "sync/atomic" "testing" "time" @@ -594,3 +595,57 @@ func TestAllocComputationIssue(t *testing.T) { require.Equal(t, int64(7), min) require.Equal(t, int64(13), max) } + +func TestIssue40584(t *testing.T) { + store, err := mockstore.NewMockStore() + require.NoError(t, err) + defer func() { + err := store.Close() + require.NoError(t, err) + }() + + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnMeta) + err = kv.RunInNewTxn(ctx, store, false, func(ctx context.Context, txn kv.Transaction) error { + m := meta.NewMeta(txn) + err = m.CreateDatabase(&model.DBInfo{ID: 1, Name: model.NewCIStr("a")}) + require.NoError(t, err) + err = m.CreateTableOrView(1, &model.TableInfo{ID: 1, Name: model.NewCIStr("t")}) + require.NoError(t, err) + return nil + }) + require.NoError(t, err) + + alloc := autoid.NewAllocator(store, 1, 1, false, autoid.RowIDAllocType) + require.NotNil(t, alloc) + + finishAlloc := make(chan bool) + finishBase := make(chan bool) + var done int32 = 0 + + // call allocator.Alloc and allocator.Base in parallel for 3 seconds to detect data race + go func() { + for { + alloc.Alloc(ctx, 1, 1, 1) + if atomic.LoadInt32(&done) > 0 { + break + } + } + finishAlloc <- true + }() + + go func() { + for { + alloc.Base() + if atomic.LoadInt32(&done) > 0 { + break + } + } + finishBase <- true + }() + + runTime := time.NewTimer(time.Second * 3) + <-runTime.C + atomic.AddInt32(&done, 1) + <-finishAlloc + <-finishBase +} diff --git a/meta/autoid/errors.go b/meta/autoid/errors.go index aef8bb4cc6fe8..6d76e2dbe3808 100644 --- a/meta/autoid/errors.go +++ b/meta/autoid/errors.go @@ -31,8 +31,10 @@ var ( ) const ( - // AutoRandomPKisNotHandleErrMsg indicates the auto_random column attribute is defined on a non-primary key column, or the primary key is nonclustered. - AutoRandomPKisNotHandleErrMsg = "column %s is not the integer primary key, or the primary key is nonclustered" + // AutoRandomMustFirstColumnInPK is reported when auto_random is not the first column in primary key. + AutoRandomMustFirstColumnInPK = "column '%s' must be the first column in primary key" + // AutoRandomNoClusteredPKErrMsg indicates the primary key is not clustered. + AutoRandomNoClusteredPKErrMsg = "auto_random is only supported on the tables with clustered primary key" // AutoRandomIncompatibleWithAutoIncErrMsg is reported when auto_random and auto_increment are specified on the same column. AutoRandomIncompatibleWithAutoIncErrMsg = "auto_random is incompatible with auto_increment" // AutoRandomIncompatibleWithDefaultValueErrMsg is reported when auto_random and default are specified on the same column. diff --git a/meta/autoid/main_test.go b/meta/autoid/main_test.go index c5dad759b65b1..7eb312e043e3a 100644 --- a/meta/autoid/main_test.go +++ b/meta/autoid/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/meta/main_test.go b/meta/main_test.go index 1cfa29527043e..3e4abdaa12624 100644 --- a/meta/main_test.go +++ b/meta/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } diff --git a/meta/meta.go b/meta/meta.go index f132d0597d1da..41a8231130be0 100644 --- a/meta/meta.go +++ b/meta/meta.go @@ -19,7 +19,6 @@ import ( "encoding/binary" "encoding/json" "fmt" - "math" "strconv" "strings" "sync" @@ -34,8 +33,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/structure" "github.com/pingcap/tidb/util/dbterror" - "github.com/pingcap/tidb/util/logutil" - "go.uber.org/zap" ) var ( @@ -59,26 +56,27 @@ var ( // var ( - mMetaPrefix = []byte("m") - mNextGlobalIDKey = []byte("NextGlobalID") - mSchemaVersionKey = []byte("SchemaVersionKey") - mDBs = []byte("DBs") - mDBPrefix = "DB" - mTablePrefix = "Table" - mSequencePrefix = "SID" - mSeqCyclePrefix = "SequenceCycle" - mTableIDPrefix = "TID" - mIncIDPrefix = "IID" - mRandomIDPrefix = "TARID" - mBootstrapKey = []byte("BootstrapKey") - mSchemaDiffPrefix = "Diff" - mPolicies = []byte("Policies") - mPolicyPrefix = "Policy" - mPolicyGlobalID = []byte("PolicyGlobalID") - mPolicyMagicByte = CurrentMagicByteVer - mDDLTableVersion = []byte("DDLTableVersion") - mConcurrentDDL = []byte("concurrentDDL") - mFlashbackHistoryTSRange = []byte("FlashbackHistoryTSRange") + mMetaPrefix = []byte("m") + mNextGlobalIDKey = []byte("NextGlobalID") + mSchemaVersionKey = []byte("SchemaVersionKey") + mDBs = []byte("DBs") + mDBPrefix = "DB" + mTablePrefix = "Table" + mSequencePrefix = "SID" + mSeqCyclePrefix = "SequenceCycle" + mTableIDPrefix = "TID" + mIncIDPrefix = "IID" + mRandomIDPrefix = "TARID" + mBootstrapKey = []byte("BootstrapKey") + mSchemaDiffPrefix = "Diff" + mPolicies = []byte("Policies") + mPolicyPrefix = "Policy" + mResourceGroups = []byte("ResourceGroups") + mResourceGroupPrefix = "RG" + mPolicyGlobalID = []byte("PolicyGlobalID") + mPolicyMagicByte = CurrentMagicByteVer + mDDLTableVersion = []byte("DDLTableVersion") + mMetaDataLock = []byte("metadataLock") ) const ( @@ -110,6 +108,10 @@ var ( ErrPolicyExists = dbterror.ClassMeta.NewStd(errno.ErrPlacementPolicyExists) // ErrPolicyNotExists is the error for policy not exists. ErrPolicyNotExists = dbterror.ClassMeta.NewStd(errno.ErrPlacementPolicyNotExists) + // ErrResourceGroupExists is the error for resource group exists. + ErrResourceGroupExists = dbterror.ClassMeta.NewStd(errno.ErrResourceGroupExists) + // ErrResourceGroupNotExists is the error for resource group not exists. + ErrResourceGroupNotExists = dbterror.ClassMeta.NewStd(errno.ErrResourceGroupNotExists) // ErrTableExists is the error for table exists. ErrTableExists = dbterror.ClassMeta.NewStd(mysql.ErrTableExists) // ErrTableNotExists is the error for table not exists. @@ -129,17 +131,13 @@ type Meta struct { // NewMeta creates a Meta in transaction txn. // If the current Meta needs to handle a job, jobListKey is the type of the job's list. -func NewMeta(txn kv.Transaction, jobListKeys ...JobListKeyType) *Meta { +func NewMeta(txn kv.Transaction) *Meta { txn.SetOption(kv.Priority, kv.PriorityHigh) txn.SetDiskFullOpt(kvrpcpb.DiskFullOpt_AllowedOnAlmostFull) t := structure.NewStructure(txn, txn, mMetaPrefix) - listKey := DefaultJobListKey - if len(jobListKeys) != 0 { - listKey = jobListKeys[0] - } return &Meta{txn: t, StartTS: txn.StartTS(), - jobListKey: listKey, + jobListKey: DefaultJobListKey, } } @@ -166,6 +164,23 @@ func (m *Meta) GenGlobalID() (int64, error) { return newID, err } +// AdvanceGlobalIDs advances the global ID by n. +// return the old global ID. +func (m *Meta) AdvanceGlobalIDs(n int) (int64, error) { + globalIDMutex.Lock() + defer globalIDMutex.Unlock() + + newID, err := m.txn.Inc(mNextGlobalIDKey, int64(n)) + if err != nil { + return 0, err + } + if newID > MaxGlobalID { + return 0, errors.Errorf("global id:%d exceeds the limit:%d", newID, MaxGlobalID) + } + origID := newID - int64(n) + return origID, nil +} + // GenGlobalIDs generates the next n global IDs. func (m *Meta) GenGlobalIDs(n int) ([]int64, error) { globalIDMutex.Lock() @@ -208,6 +223,10 @@ func (*Meta) policyKey(policyID int64) []byte { return []byte(fmt.Sprintf("%s:%d", mPolicyPrefix, policyID)) } +func (*Meta) resourceGroupKey(groupID int64) []byte { + return []byte(fmt.Sprintf("%s:%d", mResourceGroupPrefix, groupID)) +} + func (*Meta) dbKey(dbID int64) []byte { return DBkey(dbID) } @@ -420,6 +439,22 @@ func (m *Meta) checkPolicyNotExists(policyKey []byte) error { return errors.Trace(err) } +func (m *Meta) checkResourceGroupNotExists(groupKey []byte) error { + v, err := m.txn.HGet(mResourceGroups, groupKey) + if err == nil && v != nil { + err = ErrResourceGroupExists.GenWithStack("group already exists") + } + return errors.Trace(err) +} + +func (m *Meta) checkResourceGroupExists(groupKey []byte) error { + v, err := m.txn.HGet(mResourceGroups, groupKey) + if err == nil && v == nil { + err = ErrResourceGroupNotExists.GenWithStack("group doesn't exist") + } + return errors.Trace(err) +} + func (m *Meta) checkDBExists(dbKey []byte) error { v, err := m.txn.HGet(mDBs, dbKey) if err == nil && v == nil { @@ -485,6 +520,50 @@ func (m *Meta) UpdatePolicy(policy *model.PolicyInfo) error { return m.txn.HSet(mPolicies, policyKey, attachMagicByte(data)) } +// CreateResourceGroup creates a resource group. +func (m *Meta) CreateResourceGroup(group *model.ResourceGroupInfo) error { + if group.ID == 0 { + return errors.New("group.ID is invalid") + } + groupKey := m.resourceGroupKey(group.ID) + if err := m.checkResourceGroupNotExists(groupKey); err != nil { + return errors.Trace(err) + } + + data, err := json.Marshal(group) + if err != nil { + return errors.Trace(err) + } + return m.txn.HSet(mResourceGroups, groupKey, attachMagicByte(data)) +} + +// UpdateResourceGroup updates a resource group. +func (m *Meta) UpdateResourceGroup(group *model.ResourceGroupInfo) error { + groupKey := m.resourceGroupKey(group.ID) + if err := m.checkResourceGroupExists(groupKey); err != nil { + return errors.Trace(err) + } + + data, err := json.Marshal(group) + if err != nil { + return errors.Trace(err) + } + return m.txn.HSet(mResourceGroups, groupKey, attachMagicByte(data)) +} + +// DropResourceGroup drops a resource group. +func (m *Meta) DropResourceGroup(groupID int64) error { + // Check if group exists. + groupKey := m.resourceGroupKey(groupID) + if err := m.txn.HClear(groupKey); err != nil { + return errors.Trace(err) + } + if err := m.txn.HDel(mPolicies, groupKey); err != nil { + return errors.Trace(err) + } + return nil +} + // CreateDatabase creates a database with db info. func (m *Meta) CreateDatabase(dbInfo *model.DBInfo) error { dbKey := m.dbKey(dbInfo.ID) @@ -605,56 +684,27 @@ func (m *Meta) CheckMDLTableExists() (bool, error) { return bytes.Equal(v, []byte("2")), nil } -// TSRange store a range time -type TSRange struct { - StartTS uint64 - EndTS uint64 -} - -// SetFlashbackHistoryTSRange store flashback time range to TiKV -func (m *Meta) SetFlashbackHistoryTSRange(timeRange []TSRange) error { - timeRangeByte, err := json.Marshal(timeRange) - if err != nil { - return err - } - return errors.Trace(m.txn.Set(mFlashbackHistoryTSRange, timeRangeByte)) -} - -// GetFlashbackHistoryTSRange get flashback time range from TiKV -func (m *Meta) GetFlashbackHistoryTSRange() (timeRange []TSRange, err error) { - timeRangeByte, err := m.txn.Get(mFlashbackHistoryTSRange) - if err != nil { - return nil, err - } - if len(timeRangeByte) == 0 { - return []TSRange{}, nil - } - err = json.Unmarshal(timeRangeByte, &timeRange) - if err != nil { - return nil, err - } - return timeRange, nil -} - -// SetConcurrentDDL set the concurrent DDL flag. -func (m *Meta) SetConcurrentDDL(b bool) error { +// SetMetadataLock sets the metadata lock. +func (m *Meta) SetMetadataLock(b bool) error { var data []byte if b { data = []byte("1") } else { data = []byte("0") } - return errors.Trace(m.txn.Set(mConcurrentDDL, data)) + return errors.Trace(m.txn.Set(mMetaDataLock, data)) } -// IsConcurrentDDL returns true if the concurrent DDL flag is set. -func (m *Meta) IsConcurrentDDL() (bool, error) { - val, err := m.txn.Get(mConcurrentDDL) +// GetMetadataLock gets the metadata lock. +func (m *Meta) GetMetadataLock() (enable bool, isNull bool, err error) { + val, err := m.txn.Get(mMetaDataLock) if err != nil { - return false, errors.Trace(err) + return false, false, errors.Trace(err) } - - return len(val) == 0 || bytes.Equal(val, []byte("1")), nil + if len(val) == 0 { + return false, true, nil + } + return bytes.Equal(val, []byte("1")), false, nil } // CreateTableAndSetAutoID creates a table with tableInfo in database, @@ -899,6 +949,50 @@ func (m *Meta) GetPolicy(policyID int64) (*model.PolicyInfo, error) { return policy, errors.Trace(err) } +// ListResourceGroups shows all resource groups. +func (m *Meta) ListResourceGroups() ([]*model.ResourceGroupInfo, error) { + res, err := m.txn.HGetAll(mResourceGroups) + if err != nil { + return nil, errors.Trace(err) + } + + groups := make([]*model.ResourceGroupInfo, 0, len(res)) + for _, r := range res { + value, err := detachMagicByte(r.Value) + if err != nil { + return nil, errors.Trace(err) + } + group := &model.ResourceGroupInfo{} + err = json.Unmarshal(value, group) + if err != nil { + return nil, errors.Trace(err) + } + groups = append(groups, group) + } + return groups, nil +} + +// GetResourceGroup gets the database value with ID. +func (m *Meta) GetResourceGroup(groupID int64) (*model.ResourceGroupInfo, error) { + groupKey := m.resourceGroupKey(groupID) + value, err := m.txn.HGet(mResourceGroups, groupKey) + if err != nil { + return nil, errors.Trace(err) + } + if value == nil { + return nil, ErrResourceGroupNotExists.GenWithStack("resource group id : %d doesn't exist", groupID) + } + + value, err = detachMagicByte(value) + if err != nil { + return nil, errors.Trace(err) + } + + group := &model.ResourceGroupInfo{} + err = json.Unmarshal(value, group) + return group, errors.Trace(err) +} + func attachMagicByte(data []byte) []byte { data = append(data, 0) copy(data[1:], data) @@ -945,6 +1039,27 @@ func (m *Meta) GetTable(dbID int64, tableID int64) (*model.TableInfo, error) { return tableInfo, errors.Trace(err) } +// CheckTableExists checks if the table is existed with dbID and tableID. +func (m *Meta) CheckTableExists(dbID int64, tableID int64) (bool, error) { + // Check if db exists. + dbKey := m.dbKey(dbID) + if err := m.checkDBExists(dbKey); err != nil { + return false, errors.Trace(err) + } + + // Check if table exists. + tableKey := m.tableKey(tableID) + v, err := m.txn.HGet(dbKey, tableKey) + if err != nil { + return false, errors.Trace(err) + } + if v != nil { + return true, nil + } + + return false, nil +} + // DDL job structure // DDLJobList: list jobs // DDLJobHistory: hash @@ -957,12 +1072,8 @@ var ( mDDLJobListKey = []byte("DDLJobList") mDDLJobAddIdxList = []byte("DDLJobAddIdxList") mDDLJobHistoryKey = []byte("DDLJobHistory") - mDDLJobReorgKey = []byte("DDLJobReorg") ) -// JobListKeyType is a key type of the DDL job queue. -type JobListKeyType []byte - var ( // DefaultJobListKey keeps all actions of DDL jobs except "add index". DefaultJobListKey JobListKeyType = mDDLJobListKey @@ -988,31 +1099,8 @@ func (m *Meta) EnQueueDDLJob(job *model.Job, jobListKeys ...JobListKeyType) erro return m.enQueueDDLJob(listKey, job, true) } -// EnQueueDDLJobNoUpdate adds a DDL job to the list without update raw args. -func (m *Meta) EnQueueDDLJobNoUpdate(job *model.Job, jobListKeys ...JobListKeyType) error { - listKey := m.jobListKey - if len(jobListKeys) != 0 { - listKey = jobListKeys[0] - } - - return m.enQueueDDLJob(listKey, job, false) -} - -func (m *Meta) deQueueDDLJob(key []byte) (*model.Job, error) { - value, err := m.txn.LPop(key) - if err != nil || value == nil { - return nil, errors.Trace(err) - } - - job := &model.Job{} - err = job.Decode(value) - return job, errors.Trace(err) -} - -// DeQueueDDLJob pops a DDL job from the list. -func (m *Meta) DeQueueDDLJob() (*model.Job, error) { - return m.deQueueDDLJob(m.jobListKey) -} +// JobListKeyType is a key type of the DDL job queue. +type JobListKeyType []byte func (m *Meta) getDDLJob(key []byte, index int64) (*model.Job, error) { value, err := m.txn.LIndex(key, index) @@ -1033,61 +1121,6 @@ func (m *Meta) getDDLJob(key []byte, index int64) (*model.Job, error) { return job, errors.Trace(err) } -// GetDDLJobByIdx returns the corresponding DDL job by the index. -// The length of jobListKeys can only be 1 or 0. -// If its length is 1, we need to replace m.jobListKey with jobListKeys[0]. -// Otherwise, we use m.jobListKey directly. -func (m *Meta) GetDDLJobByIdx(index int64, jobListKeys ...JobListKeyType) (*model.Job, error) { - listKey := m.jobListKey - if len(jobListKeys) != 0 { - listKey = jobListKeys[0] - } - - startTime := time.Now() - job, err := m.getDDLJob(listKey, index) - metrics.MetaHistogram.WithLabelValues(metrics.GetDDLJobByIdx, metrics.RetLabel(err)).Observe(time.Since(startTime).Seconds()) - return job, errors.Trace(err) -} - -// updateDDLJob updates the DDL job with index and key. -// updateRawArgs is used to determine whether to update the raw args when encode the job. -func (m *Meta) updateDDLJob(index int64, job *model.Job, key []byte, updateRawArgs bool) error { - b, err := job.Encode(updateRawArgs) - if err == nil { - err = m.txn.LSet(key, index, b) - } - return errors.Trace(err) -} - -// UpdateDDLJob updates the DDL job with index. -// updateRawArgs is used to determine whether to update the raw args when encode the job. -// The length of jobListKeys can only be 1 or 0. -// If its length is 1, we need to replace m.jobListKey with jobListKeys[0]. -// Otherwise, we use m.jobListKey directly. -func (m *Meta) UpdateDDLJob(index int64, job *model.Job, updateRawArgs bool, jobListKeys ...JobListKeyType) error { - listKey := m.jobListKey - if len(jobListKeys) != 0 { - listKey = jobListKeys[0] - } - - startTime := time.Now() - err := m.updateDDLJob(index, job, listKey, updateRawArgs) - metrics.MetaHistogram.WithLabelValues(metrics.UpdateDDLJob, metrics.RetLabel(err)).Observe(time.Since(startTime).Seconds()) - return errors.Trace(err) -} - -// DDLJobQueueLen returns the DDL job queue length. -// The length of jobListKeys can only be 1 or 0. -// If its length is 1, we need to replace m.jobListKey with jobListKeys[0]. -// Otherwise, we use m.jobListKey directly. -func (m *Meta) DDLJobQueueLen(jobListKeys ...JobListKeyType) (int64, error) { - listKey := m.jobListKey - if len(jobListKeys) != 0 { - listKey = jobListKeys[0] - } - return m.txn.LLen(listKey) -} - // GetAllDDLJobsInQueue gets all DDL Jobs in the current queue. // The length of jobListKeys can only be 1 or 0. // If its length is 1, we need to replace m.jobListKey with jobListKeys[0]. @@ -1122,45 +1155,6 @@ func (*Meta) jobIDKey(id int64) []byte { return b } -func (m *Meta) reorgJobCurrentElement(id int64) []byte { - b := make([]byte, 0, 12) - b = append(b, m.jobIDKey(id)...) - b = append(b, "_ele"...) - return b -} - -func (m *Meta) reorgJobStartHandle(id int64, element *Element) []byte { - b := make([]byte, 0, 16+len(element.TypeKey)) - b = append(b, m.jobIDKey(id)...) - b = append(b, element.TypeKey...) - eID := make([]byte, 8) - binary.BigEndian.PutUint64(eID, uint64(element.ID)) - b = append(b, eID...) - return b -} - -func (*Meta) reorgJobEndHandle(id int64, element *Element) []byte { - b := make([]byte, 8, 25) - binary.BigEndian.PutUint64(b, uint64(id)) - b = append(b, element.TypeKey...) - eID := make([]byte, 8) - binary.BigEndian.PutUint64(eID, uint64(element.ID)) - b = append(b, eID...) - b = append(b, "_end"...) - return b -} - -func (*Meta) reorgJobPhysicalTableID(id int64, element *Element) []byte { - b := make([]byte, 8, 25) - binary.BigEndian.PutUint64(b, uint64(id)) - b = append(b, element.TypeKey...) - eID := make([]byte, 8) - binary.BigEndian.PutUint64(eID, uint64(element.ID)) - b = append(b, eID...) - b = append(b, "_pid"...) - return b -} - func (m *Meta) addHistoryDDLJob(key []byte, job *model.Job, updateRawArgs bool) error { b, err := job.Encode(updateRawArgs) if err == nil { @@ -1322,160 +1316,6 @@ func DecodeElement(b []byte) (*Element, error) { return &Element{ID: int64(id), TypeKey: tp}, nil } -// UpdateDDLReorgStartHandle saves the job reorganization latest processed element and start handle for later resuming. -func (m *Meta) UpdateDDLReorgStartHandle(job *model.Job, element *Element, startKey kv.Key) error { - err := m.txn.HSet(mDDLJobReorgKey, m.reorgJobCurrentElement(job.ID), element.EncodeElement()) - if err != nil { - return errors.Trace(err) - } - if startKey != nil { - err = m.txn.HSet(mDDLJobReorgKey, m.reorgJobStartHandle(job.ID, element), startKey) - if err != nil { - return errors.Trace(err) - } - } - return nil -} - -// UpdateDDLReorgHandle saves the job reorganization latest processed information for later resuming. -func (m *Meta) UpdateDDLReorgHandle(jobID int64, startKey, endKey kv.Key, physicalTableID int64, element *Element) error { - err := m.txn.HSet(mDDLJobReorgKey, m.reorgJobCurrentElement(jobID), element.EncodeElement()) - if err != nil { - return errors.Trace(err) - } - if startKey != nil { - err = m.txn.HSet(mDDLJobReorgKey, m.reorgJobStartHandle(jobID, element), startKey) - if err != nil { - return errors.Trace(err) - } - } - if endKey != nil { - err = m.txn.HSet(mDDLJobReorgKey, m.reorgJobEndHandle(jobID, element), endKey) - if err != nil { - return errors.Trace(err) - } - } - err = m.txn.HSet(mDDLJobReorgKey, m.reorgJobPhysicalTableID(jobID, element), []byte(strconv.FormatInt(physicalTableID, 10))) - return errors.Trace(err) -} - -// ClearAllDDLReorgHandle clears all reorganization related handles. -func (m *Meta) ClearAllDDLReorgHandle() error { - return m.txn.HClear(mDDLJobReorgKey) -} - -// ClearALLDDLJob clears all DDL jobs. -func (m *Meta) ClearALLDDLJob() error { - if err := m.txn.LClear(mDDLJobAddIdxList); err != nil { - return errors.Trace(err) - } - if err := m.txn.LClear(mDDLJobListKey); err != nil { - return errors.Trace(err) - } - return nil -} - -// ClearAllHistoryJob clears all history jobs. **IT IS VERY DANGEROUS** -func (m *Meta) ClearAllHistoryJob() error { - if err := m.txn.HClear(mDDLJobHistoryKey); err != nil { - return errors.Trace(err) - } - return nil -} - -// RemoveReorgElement removes the element of the reorganization information. -func (m *Meta) RemoveReorgElement(job *model.Job) error { - err := m.txn.HDel(mDDLJobReorgKey, m.reorgJobCurrentElement(job.ID)) - if err != nil { - return errors.Trace(err) - } - return nil -} - -// RemoveDDLReorgHandle removes the job reorganization related handles. -func (m *Meta) RemoveDDLReorgHandle(job *model.Job, elements []*Element) error { - if len(elements) == 0 { - return nil - } - - err := m.txn.HDel(mDDLJobReorgKey, m.reorgJobCurrentElement(job.ID)) - if err != nil { - return errors.Trace(err) - } - - for _, element := range elements { - err = m.txn.HDel(mDDLJobReorgKey, m.reorgJobStartHandle(job.ID, element)) - if err != nil { - return errors.Trace(err) - } - if err = m.txn.HDel(mDDLJobReorgKey, m.reorgJobEndHandle(job.ID, element)); err != nil { - logutil.BgLogger().Warn("remove DDL reorg end handle", zap.Error(err)) - } - if err = m.txn.HDel(mDDLJobReorgKey, m.reorgJobPhysicalTableID(job.ID, element)); err != nil { - logutil.BgLogger().Warn("remove DDL reorg physical ID", zap.Error(err)) - } - } - return nil -} - -// GetDDLReorgHandle gets the latest processed DDL reorganize position. -func (m *Meta) GetDDLReorgHandle(job *model.Job) (element *Element, startKey, endKey kv.Key, physicalTableID int64, err error) { - elementBytes, err := m.txn.HGet(mDDLJobReorgKey, m.reorgJobCurrentElement(job.ID)) - if err != nil { - return nil, nil, nil, 0, errors.Trace(err) - } - if elementBytes == nil { - return nil, nil, nil, 0, ErrDDLReorgElementNotExist - } - element, err = DecodeElement(elementBytes) - if err != nil { - return nil, nil, nil, 0, errors.Trace(err) - } - - startKey, err = getReorgJobFieldHandle(m.txn, m.reorgJobStartHandle(job.ID, element)) - if err != nil { - return nil, nil, nil, 0, errors.Trace(err) - } - endKey, err = getReorgJobFieldHandle(m.txn, m.reorgJobEndHandle(job.ID, element)) - if err != nil { - return nil, nil, nil, 0, errors.Trace(err) - } - - physicalTableID, err = m.txn.HGetInt64(mDDLJobReorgKey, m.reorgJobPhysicalTableID(job.ID, element)) - if err != nil { - err = errors.Trace(err) - return - } - - // physicalTableID may be 0, because older version TiDB (without table partition) doesn't store them. - // update them to table's in this case. - if physicalTableID == 0 { - if job.ReorgMeta != nil { - endKey = kv.IntHandle(job.ReorgMeta.EndHandle).Encoded() - } else { - endKey = kv.IntHandle(math.MaxInt64).Encoded() - } - physicalTableID = job.TableID - logutil.BgLogger().Warn("new TiDB binary running on old TiDB DDL reorg data", - zap.Int64("partition ID", physicalTableID), - zap.Stringer("startHandle", startKey), - zap.Stringer("endHandle", endKey)) - } - return -} - -func getReorgJobFieldHandle(t *structure.TxStructure, reorgJobField []byte) (kv.Key, error) { - bs, err := t.HGet(mDDLJobReorgKey, reorgJobField) - if err != nil { - return nil, errors.Trace(err) - } - keyNotFound := bs == nil - if keyNotFound { - return nil, nil - } - return bs, nil -} - func (*Meta) schemaDiffKey(schemaVersion int64) []byte { return []byte(fmt.Sprintf("%s:%d", mSchemaDiffPrefix, schemaVersion)) } diff --git a/meta/meta_autoid.go b/meta/meta_autoid.go index 18d384b2b25a7..5763aa268051a 100644 --- a/meta/meta_autoid.go +++ b/meta/meta_autoid.go @@ -102,7 +102,7 @@ type autoIDAccessors struct { access autoIDAccessor } -const sepAutoIncVer = model.TableInfoVersion4 + 1 +const sepAutoIncVer = model.TableInfoVersion5 // Get implements the interface AutoIDAccessors. func (a *autoIDAccessors) Get() (autoIDs AutoIDGroup, err error) { diff --git a/meta/meta_test.go b/meta/meta_test.go index 0529fdbcc5eda..d1d932821bce3 100644 --- a/meta/meta_test.go +++ b/meta/meta_test.go @@ -17,18 +17,15 @@ package meta_test import ( "context" "fmt" - "math" "strconv" "testing" "time" "github.com/pingcap/errors" - "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/store/mockstore" - "github.com/pingcap/tidb/testkit/testutil" "github.com/pingcap/tidb/util" "github.com/stretchr/testify/require" ) @@ -252,10 +249,16 @@ func TestMeta(t *testing.T) { table, err := m.GetTable(1, 1) require.NoError(t, err) require.Equal(t, tbInfo, table) + tblExist, err := m.CheckTableExists(1, 1) + require.NoError(t, err) + require.Equal(t, true, tblExist) table, err = m.GetTable(1, 2) require.NoError(t, err) require.Nil(t, table) + tblExist, err = m.CheckTableExists(1, 2) + require.NoError(t, err) + require.Equal(t, false, tblExist) tbInfo2 := &model.TableInfo{ ID: 2, @@ -442,202 +445,6 @@ func TestElement(t *testing.T) { require.EqualError(t, err, `invalid encoded element "_col_" length 5`) } -func TestDDL(t *testing.T) { - testCases := []struct { - desc string - startHandle kv.Handle - endHandle kv.Handle - }{ - { - "kv.IntHandle", - kv.IntHandle(1), - kv.IntHandle(2), - }, - { - "kv.CommonHandle", - testutil.MustNewCommonHandle(t, "abc", 1222, "string"), - testutil.MustNewCommonHandle(t, "dddd", 1222, "string"), - }, - } - - for _, tc := range testCases { - // copy iterator variable into a new variable, see issue #27779 - tc := tc - t.Run(tc.desc, func(t *testing.T) { - store, err := mockstore.NewMockStore() - require.NoError(t, err) - defer func() { - err := store.Close() - require.NoError(t, err) - }() - - txn, err := store.Begin() - require.NoError(t, err) - - m := meta.NewMeta(txn) - - job := &model.Job{ID: 1} - err = m.EnQueueDDLJob(job) - require.NoError(t, err) - n, err := m.DDLJobQueueLen() - require.NoError(t, err) - require.Equal(t, int64(1), n) - - v, err := m.GetDDLJobByIdx(0) - require.NoError(t, err) - require.Equal(t, job, v) - v, err = m.GetDDLJobByIdx(1) - require.NoError(t, err) - require.Nil(t, v) - - job.ID = 2 - err = m.UpdateDDLJob(0, job, true) - require.NoError(t, err) - - element := &meta.Element{ID: 123, TypeKey: meta.IndexElementKey} - // There are 3 meta key relate to index reorganization: - // start_handle, end_handle and physical_table_id. - // Only start_handle is initialized. - err = m.UpdateDDLReorgStartHandle(job, element, kv.IntHandle(1).Encoded()) - require.NoError(t, err) - - // Since physical_table_id is uninitialized, we simulate older TiDB version that doesn't store them. - // In this case GetDDLReorgHandle always return maxInt64 as end_handle. - e, i, j, k, err := m.GetDDLReorgHandle(job) - require.NoError(t, err) - require.Equal(t, element, e) - require.Equal(t, kv.Key(kv.IntHandle(1).Encoded()), i) - require.Equal(t, kv.Key(kv.IntHandle(math.MaxInt64).Encoded()), j) - require.Equal(t, int64(0), k) - - element = &meta.Element{ID: 222, TypeKey: meta.ColumnElementKey} - err = m.UpdateDDLReorgHandle(job.ID, tc.startHandle.Encoded(), tc.endHandle.Encoded(), 3, element) - require.NoError(t, err) - element1 := &meta.Element{ID: 223, TypeKey: meta.IndexElementKey} - err = m.UpdateDDLReorgHandle(job.ID, tc.startHandle.Encoded(), tc.endHandle.Encoded(), 3, element1) - require.NoError(t, err) - - e, i, j, k, err = m.GetDDLReorgHandle(job) - require.NoError(t, err) - require.Equal(t, element1, e) - require.Equal(t, kv.Key(tc.startHandle.Encoded()), i) - require.Equal(t, kv.Key(tc.endHandle.Encoded()), j) - require.Equal(t, int64(3), k) - - err = m.RemoveDDLReorgHandle(job, []*meta.Element{element, element1}) - require.NoError(t, err) - e, i, j, k, err = m.GetDDLReorgHandle(job) - require.True(t, meta.ErrDDLReorgElementNotExist.Equal(err)) - require.Nil(t, e) - require.Nil(t, i) - require.Nil(t, j) - require.Equal(t, k, int64(0)) - - // new TiDB binary running on old TiDB DDL reorg data. - e, i, j, k, err = m.GetDDLReorgHandle(job) - require.True(t, meta.ErrDDLReorgElementNotExist.Equal(err)) - require.Nil(t, e) - require.Nil(t, i) - require.Nil(t, j) - require.Equal(t, k, int64(0)) - - // Test GetDDLReorgHandle failed. - _, _, _, _, err = m.GetDDLReorgHandle(job) - require.True(t, meta.ErrDDLReorgElementNotExist.Equal(err)) - - v, err = m.DeQueueDDLJob() - require.NoError(t, err) - require.Equal(t, job, v) - - err = m.AddHistoryDDLJob(job, true) - require.NoError(t, err) - v, err = m.GetHistoryDDLJob(2) - require.NoError(t, err) - require.Equal(t, job, v) - - // Add multiple history jobs. - arg := "test arg" - historyJob1 := &model.Job{ID: 1234} - historyJob1.Args = append(job.Args, arg) - err = m.AddHistoryDDLJob(historyJob1, true) - require.NoError(t, err) - historyJob2 := &model.Job{ID: 123} - historyJob2.Args = append(job.Args, arg) - err = m.AddHistoryDDLJob(historyJob2, false) - require.NoError(t, err) - all, err := ddl.GetAllHistoryDDLJobs(m) - require.NoError(t, err) - var lastID int64 - for _, job := range all { - require.Greater(t, job.ID, lastID) - lastID = job.ID - arg1 := "" - err := job.DecodeArgs(&arg1) - require.NoError(t, err) - if job.ID == historyJob1.ID { - require.Equal(t, historyJob1.Args[0], *(job.Args[0].(*string))) - } else { - require.Len(t, job.Args, 0) - } - } - - // Test for get last N history ddl jobs. - historyJobs, err := ddl.GetLastNHistoryDDLJobs(m, 2) - require.NoError(t, err) - require.Len(t, historyJobs, 2) - require.Equal(t, int64(1234), historyJobs[0].ID) - require.Equal(t, int64(123), historyJobs[1].ID) - - // Test GetAllDDLJobsInQueue. - err = m.EnQueueDDLJob(job) - require.NoError(t, err) - job1 := &model.Job{ID: 2} - err = m.EnQueueDDLJob(job1) - require.NoError(t, err) - jobs, err := m.GetAllDDLJobsInQueue() - require.NoError(t, err) - expectJobs := []*model.Job{job, job1} - require.Equal(t, expectJobs, jobs) - - err = txn.Commit(context.Background()) - require.NoError(t, err) - }) - } -} - -func TestAddIndexJob(t *testing.T) { - store, err := mockstore.NewMockStore() - require.NoError(t, err) - defer func() { - err := store.Close() - require.NoError(t, err) - }() - - txn1, err := store.Begin() - require.NoError(t, err) - - m := meta.NewMeta(txn1, meta.AddIndexJobListKey) - job := &model.Job{ID: 1} - err = m.EnQueueDDLJob(job) - require.NoError(t, err) - job.ID = 123 - err = m.UpdateDDLJob(0, job, true, meta.AddIndexJobListKey) - require.NoError(t, err) - v, err := m.GetDDLJobByIdx(0, meta.AddIndexJobListKey) - require.NoError(t, err) - require.Equal(t, job, v) - l, err := m.DDLJobQueueLen(meta.AddIndexJobListKey) - require.NoError(t, err) - require.Equal(t, int64(1), l) - jobs, err := m.GetAllDDLJobsInQueue(meta.AddIndexJobListKey) - require.NoError(t, err) - expectJobs := []*model.Job{job} - require.Equal(t, expectJobs, jobs) - - err = txn1.Commit(context.Background()) - require.NoError(t, err) -} - func BenchmarkGenGlobalIDs(b *testing.B) { store, err := mockstore.NewMockStore() require.NoError(b, err) @@ -767,45 +574,6 @@ func TestSequenceKey(b *testing.T) { require.Equal(b, tableID, id) } -func TestClearJob(t *testing.T) { - store, err := mockstore.NewMockStore() - require.NoError(t, err) - defer func() { - require.NoError(t, store.Close()) - }() - - txn, err := store.Begin() - require.NoError(t, err) - - job1 := &model.Job{ID: 1, TableID: 1, Type: model.ActionAddColumn} - job2 := &model.Job{ID: 2, TableID: 1, Type: model.ActionCreateTable} - job3 := &model.Job{ID: 3, TableID: 2, Type: model.ActionDropColumn} - - m := meta.NewMeta(txn) - - require.NoError(t, m.EnQueueDDLJob(job1)) - require.NoError(t, m.EnQueueDDLJob(job2)) - require.NoError(t, m.EnQueueDDLJob(job3)) - - require.NoError(t, m.AddHistoryDDLJob(job1, false)) - require.NoError(t, m.AddHistoryDDLJob(job2, false)) - - jobs, err := m.GetAllDDLJobsInQueue() - require.NoError(t, err) - require.Len(t, jobs, 3) - require.NoError(t, m.ClearALLDDLJob()) - jobs, err = m.GetAllDDLJobsInQueue() - require.NoError(t, err) - require.Len(t, jobs, 0) - - count, err := m.GetHistoryDDLCount() - require.NoError(t, err) - require.Equal(t, count, uint64(2)) - - err = txn.Rollback() - require.NoError(t, err) -} - func TestCreateMySQLDatabase(t *testing.T) { store, err := mockstore.NewMockStore() require.NoError(t, err) @@ -829,41 +597,3 @@ func TestCreateMySQLDatabase(t *testing.T) { err = txn.Rollback() require.NoError(t, err) } - -func TestDDLTable(t *testing.T) { - store, err := mockstore.NewMockStore() - require.NoError(t, err) - defer func() { - require.NoError(t, store.Close()) - }() - - txn, err := store.Begin() - require.NoError(t, err) - - m := meta.NewMeta(txn) - - exists, err := m.CheckDDLTableExists() - require.NoError(t, err) - require.False(t, exists) - - err = m.SetDDLTables() - require.NoError(t, err) - - exists, err = m.CheckDDLTableExists() - require.NoError(t, err) - require.True(t, exists) - - err = m.SetConcurrentDDL(true) - require.NoError(t, err) - b, err := m.IsConcurrentDDL() - require.NoError(t, err) - require.True(t, b) - err = m.SetConcurrentDDL(false) - require.NoError(t, err) - b, err = m.IsConcurrentDDL() - require.NoError(t, err) - require.False(t, b) - - err = txn.Rollback() - require.NoError(t, err) -} diff --git a/metrics/BUILD.bazel b/metrics/BUILD.bazel index ff37513801ede..c414e04d9c907 100644 --- a/metrics/BUILD.bazel +++ b/metrics/BUILD.bazel @@ -13,12 +13,14 @@ go_library( "meta.go", "metrics.go", "owner.go", + "resourcemanager.go", "server.go", "session.go", "sli.go", "stats.go", "telemetry.go", "topsql.go", + "ttl.go", ], importpath = "github.com/pingcap/tidb/metrics", visibility = ["//visibility:public"], diff --git a/metrics/ddl.go b/metrics/ddl.go index 5efe636c8a038..c97077ed0aea0 100644 --- a/metrics/ddl.go +++ b/metrics/ddl.go @@ -147,6 +147,8 @@ const ( LblAddIndex = "add_index" LblAddIndexMerge = "add_index_merge_tmp" LblModifyColumn = "modify_column" + + LblReorgPartition = "reorganize_partition" ) // GenerateReorgLabel returns the label with schema name and table name. diff --git a/metrics/grafana/performance_overview.json b/metrics/grafana/performance_overview.json index 01dbc77ee5553..5ee670584f99e 100644 --- a/metrics/grafana/performance_overview.json +++ b/metrics/grafana/performance_overview.json @@ -57,8 +57,8 @@ "editable": true, "gnetId": null, "graphTooltip": 1, - "id": null, - "iteration": 1577357354898, + "id": 31, + "iteration": 1669018858346, "links": [], "panels": [ { @@ -162,7 +162,7 @@ "targets": [ { "exemplar": true, - "expr": "sum(rate(tidb_server_handle_query_duration_seconds_sum{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", sql_type!=\"internal\"}[1m]))", + "expr": "sum(tidb_server_tokens{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"})", "hide": false, "interval": "", "legendFormat": "database time", @@ -302,7 +302,7 @@ "targets": [ { "exemplar": true, - "expr": "sum(rate(tidb_server_handle_query_duration_seconds_sum{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", sql_type!=\"internal\"}[1m]))", + "expr": "sum(tidb_server_tokens{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"})", "hide": false, "interval": "", "legendFormat": "database time", @@ -479,6 +479,11 @@ "lines": true, "linewidth": 2, "stack": false + }, + { + "$$hashKey": "object:321", + "alias": "tiflash_mpp", + "color": "#8F3BB8" } ], "spaceLength": 10, @@ -508,6 +513,14 @@ "interval": "", "legendFormat": "execute time", "refId": "F" + }, + { + "exemplar": true, + "expr": "sum(rate(tiflash_coprocessor_request_duration_seconds_sum{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}[1m])) ", + "hide": false, + "interval": "", + "legendFormat": "tiflash_mpp", + "refId": "A" } ], "thresholds": [], @@ -850,13 +863,24 @@ "targets": [ { "exemplar": true, - "expr": "sum(rate(tidb_server_plan_cache_total{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}[1m])) by (type)", + "expr": "sum(rate(tidb_server_plan_cache_total{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}[1m]))", "format": "time_series", "interval": "", "intervalFactor": 2, - "legendFormat": "avg", + "legendFormat": "avg-hit", "refId": "A", "step": 30 + }, + { + "exemplar": true, + "expr": "sum(rate(tidb_server_plan_cache_miss_total{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "avg-miss", + "refId": "B", + "step": 30 } ], "thresholds": [], @@ -1037,12 +1061,12 @@ }, { "aliasColors": {}, - "bars": false, + "bars": true, "dashLength": 10, "dashes": false, "datasource": "${DS_TEST-CLUSTER}", "decimals": null, - "description": "TiDB current connection counts", + "description": "kv request time by command source", "editable": true, "error": false, "fill": 1, @@ -1055,7 +1079,7 @@ "y": 15 }, "hiddenSeries": false, - "id": 188, + "id": 23763571995, "legend": { "alignAsTable": true, "avg": true, @@ -1071,7 +1095,7 @@ "total": false, "values": true }, - "lines": true, + "lines": false, "linewidth": 1, "links": [], "nullPointMode": "null as zero", @@ -1083,49 +1107,49 @@ "pointradius": 5, "points": false, "renderer": "flot", - "seriesOverrides": [], + "seriesOverrides": [ + { + "$$hashKey": "object:243", + "alias": "kv request total time", + "bars": false, + "color": "#FADE2A", + "lines": true, + "stack": false + } + ], "spaceLength": 10, - "stack": false, + "stack": true, "steppedLine": false, "targets": [ { "exemplar": true, - "expr": "tidb_server_connections{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}", + "expr": "sum(rate(tidb_tikvclient_request_time_counter{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (type, source)", "format": "time_series", "interval": "", "intervalFactor": 2, - "legendFormat": "{{instance}}", + "legendFormat": "{{type}}-{{source}}", "refId": "A", "step": 30 }, { "exemplar": true, - "expr": "sum(tidb_server_connections{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"})", + "expr": "sum(rate(tidb_tikvclient_request_time_counter{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", "hide": false, "interval": "", - "intervalFactor": 2, - "legendFormat": "total", + "legendFormat": "kv request total time", "refId": "B" - }, - { - "exemplar": true, - "expr": "sum(rate(tidb_server_handle_query_duration_seconds_sum{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", sql_type!=\"internal\"}[1m]))", - "hide": false, - "interval": "", - "legendFormat": "active connections", - "refId": "C" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, - "title": "Connection Count", + "title": "KV Request Time By Source", "tooltip": { "msResolution": false, "shared": true, "sort": 0, - "value_type": "individual" + "value_type": "cumulative" }, "type": "graph", "xaxis": { @@ -1137,9 +1161,9 @@ }, "yaxes": [ { - "$$hashKey": "object:3472", + "$$hashKey": "object:178", "decimals": 0, - "format": "short", + "format": "s", "label": null, "logBase": 1, "max": null, @@ -1147,7 +1171,7 @@ "show": true }, { - "$$hashKey": "object:3473", + "$$hashKey": "object:179", "format": "short", "label": null, "logBase": 1, @@ -1461,8 +1485,8 @@ "fill": 1, "fillGradient": 0, "gridPos": { - "h": 7, - "w": 12, + "h": 6, + "w": 8, "x": 0, "y": 29 }, @@ -1582,9 +1606,9 @@ "fillGradient": 0, "grid": {}, "gridPos": { - "h": 7, - "w": 12, - "x": 12, + "h": 6, + "w": 8, + "x": 8, "y": 29 }, "hiddenSeries": false, @@ -1701,6 +1725,148 @@ "alignLevel": null } }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "decimals": null, + "description": "TiDB current connection counts", + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 29 + }, + "hiddenSeries": false, + "id": 188, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:113", + "alias": "disconnection/s", + "color": "#C4162A", + "linewidth": 2, + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "tidb_server_connections{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 30 + }, + { + "exemplar": true, + "expr": "sum(tidb_server_connections{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"})", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "total", + "refId": "B" + }, + { + "exemplar": true, + "expr": "sum(tidb_server_tokens{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"})", + "hide": false, + "interval": "", + "legendFormat": "active connections", + "refId": "D" + }, + { + "exemplar": true, + "expr": "sum(rate(tidb_server_disconnection_total{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", result=\"ok\"}[1m]))", + "hide": false, + "interval": "", + "legendFormat": "disconnection/s", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Connection Count", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:3472", + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:3473", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, { "aliasColors": {}, "bars": false, @@ -1718,7 +1884,7 @@ "h": 8, "w": 8, "x": 0, - "y": 36 + "y": 35 }, "hiddenSeries": false, "id": 156, @@ -1842,7 +2008,7 @@ "h": 8, "w": 8, "x": 8, - "y": 36 + "y": 35 }, "hiddenSeries": false, "id": 170, @@ -1953,7 +2119,7 @@ "h": 8, "w": 8, "x": 16, - "y": 36 + "y": 35 }, "hiddenSeries": false, "id": 169, @@ -2078,7 +2244,7 @@ "h": 8, "w": 8, "x": 0, - "y": 44 + "y": 43 }, "hiddenSeries": false, "id": 172, @@ -2186,7 +2352,7 @@ "h": 8, "w": 8, "x": 8, - "y": 44 + "y": 43 }, "hiddenSeries": false, "id": 173, @@ -2283,7 +2449,7 @@ "dashLength": 10, "dashes": false, "datasource": "${DS_TEST-CLUSTER}", - "description": "- TSO Wait Duration: The duration of a client starting to wait for the TS until received the TS result.\n- TSO RPC Duration: The duration of a client sending TSO request until received the response.", + "description": "- TSO Wait Duration: The duration of a client starting to wait for the TS until received the TS result.\n- TSO RPC Duration: The duration of a client sending TSO request until received the response.\n- PD Server Handle Time: The time consumed by handling TiDB requests.", "editable": true, "error": false, "fill": 1, @@ -2293,7 +2459,7 @@ "h": 8, "w": 8, "x": 16, - "y": 44 + "y": 43 }, "hiddenSeries": false, "id": 77, @@ -2341,6 +2507,14 @@ "legendFormat": "rpc - avg", "refId": "A" }, + { + "exemplar": true, + "expr": "(sum(rate(pd_server_handle_tso_duration_seconds_sum{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}[1m])) / sum(rate(pd_server_handle_tso_duration_seconds_count{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\"}[1m])))", + "hide": false, + "interval": "", + "legendFormat": "handle - avg", + "refId": "F" + }, { "exemplar": true, "expr": "histogram_quantile(0.99, sum(rate(pd_client_cmd_handle_cmds_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", type=\"wait\"}[1m])) by (le))", @@ -2359,6 +2533,16 @@ "intervalFactor": 2, "legendFormat": "rpc - 99", "refId": "E" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(pd_server_handle_tso_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[30s])) by (type, le))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "handle - 99", + "refId": "C" } ], "thresholds": [], @@ -2422,7 +2606,7 @@ "h": 8, "w": 8, "x": 0, - "y": 52 + "y": 51 }, "hiddenSeries": false, "id": 185, @@ -2536,7 +2720,7 @@ "h": 8, "w": 8, "x": 8, - "y": 52 + "y": 51 }, "hiddenSeries": false, "id": 183, @@ -2652,7 +2836,7 @@ "h": 8, "w": 8, "x": 16, - "y": 52 + "y": 51 }, "hiddenSeries": false, "id": 174, @@ -2768,7 +2952,7 @@ "h": 9, "w": 8, "x": 0, - "y": 60 + "y": 59 }, "hiddenSeries": false, "id": 176, @@ -2884,7 +3068,7 @@ "h": 9, "w": 8, "x": 8, - "y": 60 + "y": 59 }, "hiddenSeries": false, "id": 177, @@ -3000,7 +3184,7 @@ "h": 9, "w": 8, "x": 16, - "y": 60 + "y": 59 }, "hiddenSeries": false, "id": 186, @@ -3098,27 +3282,3153 @@ "align": false, "alignLevel": null } + }, + { + "collapsed": true, + "datasource": "${DS_TEST-CLUSTER}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 68 + }, + "id": 159, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "decimals": 1, + "description": "The CPU usage of each TiFlash instance", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 2 + }, + "hiddenSeries": false, + "id": 161, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "rate(tiflash_proxy_process_cpu_seconds_total{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", job=\"tiflash\"}[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "CPU", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "decimals": 1, + "description": "The memory usage per TiFlash instance", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 2 + }, + "hiddenSeries": false, + "id": 1709, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "avg(tiflash_proxy_process_resident_memory_bytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}) by (instance)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Memory", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "decimals": 1, + "description": "The I/O utilization per TiFlash instance", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 2 + }, + "hiddenSeries": false, + "id": 165, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "rate(node_disk_io_time_seconds_total{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"tiflash.*\"}[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{instance}} - {{device}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "IO utilization", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The MPP query count in TiFlash", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 9 + }, + "hiddenSeries": false, + "id": 157, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "max(tiflash_mpp_task_manager{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}) by (instance, type)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}-{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "MPP Query count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of coprocessor requests received by all TiFlash instances. batch is the number of batch requests. batch_cop is the number of coprocessor requests in the batch requests. cop is the number of coprocessor requests that are sent directly via the coprocessor interface. cop_dag is the number of dag requests in all coprocessor requests. super_batch is the number of requests to enable the Super Batch feature.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 9 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(tiflash_coprocessor_request_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (type)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Request QPS", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of each type of dag executors in the requests received by all TiFlash instances. table_scan is the table scan executor. selection is the selection executor. aggregation is the aggregation executor. top_n is the TopN executor. limit is the limit executor.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 9 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tiflash_coprocessor_executor_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (type)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Executor QPS", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The overview of the total duration of all TiFlash instances processing coprocessor requests.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 166, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tiflash_coprocessor_request_duration_seconds_sum[1m])) by (type)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{type}}", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Request Duration Overview", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": " The total duration of all TiFlash instances processing coprocessor requests.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 16 + }, + "hiddenSeries": false, + "id": 11, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.999, sum(rate(tiflash_coprocessor_request_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le))", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "999", + "refId": "A" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(tiflash_coprocessor_request_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le,type))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "99-{{type}}", + "refId": "B" + }, + { + "exemplar": true, + "expr": "sum(rate(tiflash_coprocessor_request_duration_seconds_sum{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (type) /sum(rate(tiflash_coprocessor_request_duration_seconds_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (type)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "avg-{{type}}", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Request Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The duration of all TiFlash instances processing coprocessor requests. The processing time is from starting to execute the coprocessor request to completing the execution.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 16 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.999, sum(rate(tiflash_coprocessor_request_handle_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le))", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "999", + "refId": "A" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(tiflash_coprocessor_request_handle_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le,type))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "99-{{type}}", + "refId": "B" + }, + { + "exemplar": true, + "expr": "sum(rate(tiflash_coprocessor_request_handle_seconds_sum[1m])) by (type) /sum(rate(tiflash_coprocessor_request_handle_seconds_count[1m])) by (type)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "avg-{{type}}", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Request Handle Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The time used by wait_index for all TiFlash instances, namely the time used to wait until local index >= read_index after the read_index request is received.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 37, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/timeout/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(1.00, sum(rate(tiflash_raft_wait_index_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le))", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "max", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(tiflash_raft_wait_index_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "99", + "refId": "B" + }, + { + "exemplar": true, + "expr": "sum(rate(tiflash_raft_wait_index_duration_seconds_sum[1m]))/sum(rate(tiflash_raft_wait_index_duration_seconds_count[1m]))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "avg", + "refId": "D" + }, + { + "expr": "sum(increase(tiflash_system_profile_event_RaftWaitIndexTimeout{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (instance)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}-timeout", + "refId": "E" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Raft Wait Index Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "decimals": 2, + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of times that each TiFlash instance triggers the read_index request per second, which equals to the number of Regions triggered.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 22 + }, + "hiddenSeries": false, + "id": 23763571994, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/timeout/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(1.00, sum(rate(tiflash_raft_wait_index_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le))", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "max", + "refId": "A" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(tiflash_raft_read_index_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "99", + "refId": "B" + }, + { + "exemplar": true, + "expr": "sum(rate(tiflash_raft_read_index_duration_seconds_sum[1m]))/sum(rate(tiflash_raft_read_index_duration_seconds_count[1m]))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "avg", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Raft Batch Read Index Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "decimals": 2, + "format": "opm", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "decimals": 1, + "description": "The throughput of write by instance", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 28 + }, + "height": "", + "hiddenSeries": false, + "id": 89, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 250, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeatedByRow": true, + "seriesOverrides": [ + { + "alias": "/total/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tiflash_storage_throughput_bytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", type=~\"write\"}[1m])) by (instance)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "write-{{instance}}", + "refId": "A", + "step": 10 + }, + { + "exemplar": true, + "expr": "sum(rate(tiflash_storage_throughput_bytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", type=~\"ingest\"}[1m])) by (instance)", + "hide": false, + "interval": "", + "legendFormat": "ingest-{{instance}}", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Write Throughput By Instance", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "binBps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "decimals": 1, + "description": "The flow of different kinds of write operations", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 34 + }, + "height": "", + "hiddenSeries": false, + "id": 60, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeatedByRow": true, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(tiflash_system_profile_event_WriteBufferFromFileDescriptorWriteBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "File Descriptor", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(rate(tiflash_system_profile_event_PSMWriteBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Page", + "refId": "B" + }, + { + "expr": "sum(rate(tiflash_system_profile_event_PSMBackgroundWriteBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "PageBackGround", + "refId": "C" + }, + { + "expr": "sum(rate(tiflash_system_profile_event_WriteBufferAIOWriteBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "AIO", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Write flow", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "binBps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "decimals": 1, + "description": "The flow of different kinds of read operations", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 34 + }, + "height": "", + "hiddenSeries": false, + "id": 59, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeatedByRow": true, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(tiflash_system_profile_event_ReadBufferFromFileDescriptorReadBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "File Descriptor", + "refId": "A", + "step": 10 + }, + { + "expr": "sum(rate(tiflash_system_profile_event_PSMReadBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Page", + "refId": "B" + }, + { + "expr": "sum(rate(tiflash_system_profile_event_PSMBackgroundReadBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "PageBackGround", + "refId": "C" + }, + { + "expr": "sum(rate(tiflash_system_profile_event_ReadBufferAIOReadBytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m]))", + "format": "time_series", + "hide": true, + "intervalFactor": 1, + "legendFormat": "AIO", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Read flow", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "binBps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "TiFlash", + "type": "row" + }, + { + "collapsed": true, + "datasource": "${DS_TEST-CLUSTER}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 69 + }, + "id": 515, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "CPU usage of TiCDC", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 71 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": false, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:284", + "alias": "/.*MaxProcs/", + "fill": 0, + "linewidth": 2, + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", job=\"ticdc\"}[1m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + }, + { + "expr": "ticdc_server_go_max_procs{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", job=\"ticdc\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}-MaxProcs", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "CPU usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:295", + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:296", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "Memory usage of TiCDC", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 71 + }, + "hiddenSeries": false, + "id": 23, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", job=\"ticdc\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "process-{{instance}}", + "refId": "A" + }, + { + "expr": "go_memstats_heap_alloc_bytes{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", job=\"ticdc\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "heap-{{instance}}", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Memory usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "Goroutine count of TiCDC", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 71 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": " go_goroutines{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", job=\"ticdc\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + }, + { + "expr": "go_threads{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", job=\"ticdc\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 1, + "legendFormat": "threads-{{instance}}", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Goroutine count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The lag between changefeed checkpoint ts and the latest ts of upstream TiDB.", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 78 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "max(ticdc_owner_checkpoint_ts_lag{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}) by (changefeed)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}", + "refId": "A" + }, + { + "exemplar": true, + "expr": "max(ticdc_processor_checkpoint_ts_lag{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}) by (instance,changefeed)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}-{{changefeed}}", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Changefeed checkpoint lag", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:79", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:80", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The lag between changefeed resolved ts and the latest ts of upstream TiDB.", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 78 + }, + "hiddenSeries": false, + "id": 513, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "max(ticdc_owner_resolved_ts_lag{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}) by (changefeed)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}", + "refId": "C" + }, + { + "exemplar": true, + "expr": "max(ticdc_processor_resolved_ts_lag{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}) by (instance,changefeed)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}-{{chanefeed}}", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Changefeed resolved ts lag", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The status of each changefeed.\n\n0: Normal\n\n1: Error\n\n2: Failed\n\n3: Stopped\n\n4: Finished\n\n-1: Unknown", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 78 + }, + "hiddenSeries": false, + "id": 163, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "max(ticdc_owner_status{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}) by (changefeed)", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "The status of changefeeds", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of events that puller outputs to sorter \n per second", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 85 + }, + "hiddenSeries": false, + "id": 218, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum (rate(ticdc_puller_txn_collect_event_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", type!=\"resolved\"}[1m])) by (changefeed, instance, type)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}-{{instance}}-{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Puller output events/s", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of events that sorter outputs to puller \n per second", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 85 + }, + "hiddenSeries": false, + "id": 228, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(ticdc_sorter_output_event_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (changefeed, instance, type)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}-{{instance}}-{{type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Sorter output events/s", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of events that mounter outputs to sink per second", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 92 + }, + "hiddenSeries": false, + "id": 219, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(ticdc_mounter_total_rows_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (instance,changefeed)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}-{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Mounter output events/s", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:196", + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:197", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of events that table sorter outputs to sink per second", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 92 + }, + "hiddenSeries": false, + "id": 108, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(ticdc_sink_table_sink_total_rows_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\"}[1m])) by (changefeed, instance)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}-{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Table sink output events/s", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of rows that sink flushes to downstream per second.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 99 + }, + "hiddenSeries": false, + "id": 654, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(ticdc_sinkv2_batch_row_count_sum{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}[1m])) by (changefeed, instance)", + "interval": "", + "legendFormat": "{{changefeed}}-{{instance}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "SinkV2 - Sink flush rows/s", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:258", + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:259", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "Full flush (backend flush + callback + conflict detector notify) duration", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 99 + }, + "hiddenSeries": false, + "id": 620, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.999, sum(rate(ticdc_sinkv2_txn_worker_flush_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}[1m])) by (le,changefeed,instance))", + "interval": "", + "legendFormat": "99.9-{{changefeed}}-{{instance}}", + "queryType": "randomWalk", + "refId": "A" + }, + { + "exemplar": true, + "expr": "sum(rate(ticdc_sinkv2_txn_worker_flush_duration_sum{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}[1m])) by (changefeed,instance) / \nsum(rate(ticdc_sinkv2_txn_worker_flush_duration_count{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}[1m])) by (changefeed,instance)", + "hide": false, + "interval": "", + "legendFormat": "avg-{{changefeed}}-{{instance}}", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Transaction Sink Full Flush Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:332", + "format": "s", + "label": null, + "logBase": 2, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:333", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "MQ worker send messages to Kafka, this metric record the time cost on send every message.", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 106 + }, + "hiddenSeries": false, + "id": 653, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.999, sum(rate(ticdc_sinkv2_mq_worker_send_message_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}[1m])) by (le,changefeed,instance))", + "interval": "", + "legendFormat": "{{changefeed}}-{{instance}}-P999", + "queryType": "randomWalk", + "refId": "A" + }, + { + "exemplar": true, + "expr": "sum(rate(ticdc_sinkv2_mq_worker_send_message_duration_sum{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}[1m])) by (changefeed,instance) / \nsum(rate(ticdc_sinkv2_mq_worker_send_message_duration_count{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}[1m])) by (changefeed,instance)", + "hide": false, + "interval": "", + "legendFormat": "{{changefeed}}-{{instance}}-avg", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "MQ Worker Send Message Duration Percentile", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:406", + "format": "s", + "label": null, + "logBase": 2, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:407", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "Bytes/second written off all brokers.\nvalue = one-minute moving average rate of Bytes per second", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 106 + }, + "hiddenSeries": false, + "id": 628, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "paceLength": 10, + "percentage": false, + "pluginVersion": "8.0.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(ticdc_sinkv2_kafka_producer_outgoing_byte_rate{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", changefeed!=\"\"}) by (changefeed, instance, broker)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{changefeed}}-{{instance}}-{{broker}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Kafka Outgoing Bytes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:480", + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:481", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "CDC", + "type": "row" } ], "refresh": "30s", - "schemaVersion": 18, + "schemaVersion": 27, "style": "dark", "tags": [], "templating": { "list": [ { "allValue": null, - "current": {}, + "current": { + "isNone": true, + "selected": false, + "text": "None", + "value": "" + }, "datasource": "${DS_TEST-CLUSTER}", + "definition": "", + "description": null, + "error": null, "hide": 2, "includeAll": false, "label": "K8s-cluster", "multi": false, "name": "k8s_cluster", "options": [], - "query": "label_values(pd_cluster_status, k8s_cluster)", + "query": { + "query": "label_values(pd_cluster_status, k8s_cluster)", + "refId": "${DS_TEST-CLUSTER}-k8s_cluster-Variable-Query" + }, "refresh": 2, "regex": "", + "skipUrlSync": false, "sort": 1, "tagValuesQuery": "", "tags": [], @@ -3128,17 +6438,29 @@ }, { "allValue": null, - "current": {}, + "current": { + "isNone": true, + "selected": false, + "text": "None", + "value": "" + }, "datasource": "${DS_TEST-CLUSTER}", + "definition": "", + "description": null, + "error": null, "hide": 2, "includeAll": false, "label": "tidb_cluster", "multi": false, "name": "tidb_cluster", "options": [], - "query": "label_values(pd_cluster_status{k8s_cluster=\"$k8s_cluster\"}, tidb_cluster)", + "query": { + "query": "label_values(pd_cluster_status{k8s_cluster=\"$k8s_cluster\"}, tidb_cluster)", + "refId": "${DS_TEST-CLUSTER}-tidb_cluster-Variable-Query" + }, "refresh": 2, "regex": "", + "skipUrlSync": false, "sort": 1, "tagValuesQuery": "", "tags": [], @@ -3181,4 +6503,4 @@ "title": "Test-Cluster-Performance-Overview", "uid": "eDbRZpnWa", "version": 2 -} +} \ No newline at end of file diff --git a/metrics/grafana/tidb.json b/metrics/grafana/tidb.json index 0684067314075..25042b63a8bab 100644 --- a/metrics/grafana/tidb.json +++ b/metrics/grafana/tidb.json @@ -1979,6 +1979,117 @@ "align": false, "alignLevel": null } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The number of queries contained in a multi-query statement per second.", + "editable": true, + "error": false, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 23 + }, + "hiddenSeries": false, + "id": 272, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.11", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tidb_server_multi_query_num_sum{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[30s]))/sum(rate(tidb_server_multi_query_num_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[30s]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "avg", + "refId": "A", + "step": 10 + }, + { + "exemplar": true, + "expr": "sum(rate(tidb_server_multi_query_num_sum{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[30s]))", + "hide": false, + "interval": "", + "legendFormat": "sum", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Queries in Multi-Statement", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } } ], "repeat": null, @@ -7473,62 +7584,49 @@ "align": false, "alignLevel": null } - } - ], - "repeat": null, - "title": "Executor", - "type": "row" - }, - { - "collapsed": true, - "datasource": null, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 5 - }, - "id": 143, - "panels": [ + }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_TEST-CLUSTER}", - "description": "durations of distsql execution by type", - "editable": true, - "error": false, + "description": "Total memory usage of all prepared plan cache in a instance", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "fill": 1, - "grid": {}, + "fillGradient": 0, "gridPos": { - "h": 7, + "h": 8, "w": 12, - "x": 0, - "y": 122 + "x": 12, + "y": 29 }, - "id": 12, + "hiddenSeries": false, + "id": 269, "legend": { "alignAsTable": true, "avg": false, - "current": false, - "max": false, + "current": true, + "hideEmpty": true, + "max": true, "min": false, "rightSide": true, "show": true, "total": false, - "values": false + "values": true }, "lines": true, - "linewidth": 2, - "links": [ - { - "url": "/" - } - ], + "linewidth": 1, "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, "percentage": false, - "pointradius": 5, + "pluginVersion": "7.5.11", + "pointradius": 2, "points": false, "renderer": "flot", "seriesOverrides": [], @@ -7537,48 +7635,23 @@ "steppedLine": false, "targets": [ { - "expr": "histogram_quantile(0.999, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "999-{{type}}", - "refId": "D" - }, - { - "expr": "histogram_quantile(0.99, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", - "format": "time_series", + "exemplar": true, + "expr": "tidb_server_plan_cache_instance_memory_usage{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}", "hide": false, - "intervalFactor": 2, - "legendFormat": "99-{{type}}", - "metric": "tidb_distsql_handle_query_duration_seconds_bucket{}", - "refId": "A", - "step": 4 - }, - { - "expr": "histogram_quantile(0.90, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "90-{{type}}", - "refId": "B" - }, - { - "expr": "histogram_quantile(0.50, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", - "format": "time_series", "interval": "", - "intervalFactor": 2, - "legendFormat": "50-{{type}}", - "refId": "C" + "legendFormat": "{{instance}}", + "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, - "title": "Distsql Duration", + "title": "Plan Cache Memory Usage", "tooltip": { - "msResolution": false, "shared": true, "sort": 0, - "value_type": "cumulative" + "value_type": "individual" }, "type": "graph", "xaxis": { @@ -7590,14 +7663,16 @@ }, "yaxes": [ { - "format": "s", + "$$hashKey": "object:122", + "format": "bytes", "label": null, - "logBase": 2, + "logBase": 1, "max": null, - "min": "0.0005", + "min": "0", "show": true }, { + "$$hashKey": "object:123", "format": "short", "label": null, "logBase": 1, @@ -7617,33 +7692,49 @@ "dashLength": 10, "dashes": false, "datasource": "${DS_TEST-CLUSTER}", - "description": "distsql query handling durations per second", + "decimals": null, + "description": "TiDB prepared plan cache plan num\n", "editable": true, "error": false, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "fill": 1, + "fillGradient": 0, "grid": {}, "gridPos": { - "h": 7, + "h": 8, "w": 12, - "x": 12, - "y": 122 + "x": 0, + "y": 37 }, - "id": 14, + "hiddenSeries": false, + "id": 271, "legend": { + "alignAsTable": true, "avg": false, - "current": false, - "max": false, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, "min": false, - "rightSide": false, - "show": false, + "rightSide": true, + "show": true, + "sort": null, + "sortDesc": null, "total": false, - "values": false + "values": true }, "lines": true, - "linewidth": 2, + "linewidth": 1, "links": [], "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, "percentage": false, + "pluginVersion": "7.5.11", "pointradius": 5, "points": false, "renderer": "flot", @@ -7653,20 +7744,21 @@ "steppedLine": false, "targets": [ { - "expr": "sum(rate(tidb_distsql_handle_query_duration_seconds_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (copr_type)", + "exemplar": true, + "expr": "tidb_server_plan_cache_instance_plan_num_total{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}\n", "format": "time_series", + "interval": "", "intervalFactor": 2, - "legendFormat": "{{copr_type}}", - "metric": "tidb_distsql_query_total", + "legendFormat": "{{instance}}", "refId": "A", - "step": 4 + "step": 30 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, - "title": "Distsql QPS", + "title": "Plan Cache Plan Num", "tooltip": { "msResolution": false, "shared": true, @@ -7687,7 +7779,7 @@ "label": null, "logBase": 1, "max": null, - "min": 0, + "min": "0", "show": true }, { @@ -7703,15 +7795,245 @@ "align": false, "alignLevel": null } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_TEST-CLUSTER}", - "description": "the numebr of distsql partial scan numbers", - "editable": true, + } + ], + "repeat": null, + "title": "Executor", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 143, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "durations of distsql execution by type", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 122 + }, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [ + { + "url": "/" + } + ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.999, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "999-{{type}}", + "refId": "D" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "99-{{type}}", + "metric": "tidb_distsql_handle_query_duration_seconds_bucket{}", + "refId": "A", + "step": 4 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "90-{{type}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.50, sum(rate(tidb_distsql_handle_query_duration_seconds_bucket{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (le, type))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "50-{{type}}", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Distsql Duration", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 2, + "max": null, + "min": "0.0005", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "distsql query handling durations per second", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 122 + }, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(tidb_distsql_handle_query_duration_seconds_count{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (copr_type)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{copr_type}}", + "metric": "tidb_distsql_query_total", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Distsql QPS", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "the numebr of distsql partial scan numbers", + "editable": true, "error": false, "fill": 1, "grid": {}, @@ -14015,23 +14337,252 @@ "align": false, "alignLevel": null } - } - ], - "repeat": null, - "title": "Statistics", - "type": "row" - }, - { - "collapsed": true, - "datasource": null, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 12 - }, - "id": 161, - "panels": [ + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 184 + }, + "hiddenSeries": false, + "id": 236, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.11", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tidb_plan_replayer_task{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", type=~\"dump\"}[1m])) by (result)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "dump-task-{{result}}", + "refId": "A", + "step": 30 + }, + { + "exemplar": true, + "expr": "sum(rate(tidb_plan_replayer_task{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", type=~\"capture\"}[1m])) by (result)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "capture-task-{{result}}", + "refId": "B", + "step": 30 + }, + { + "exemplar": true, + "expr": "avg(tidb_plan_replayer_register_task{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"})", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "register-task", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Plan Replayer Task OPM", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 184 + }, + "hiddenSeries": false, + "id": 237, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.11", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tidb_statistics_historical_stats{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", type=~\"generate\"}[1m])) by (result)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "generate-{{result}}", + "refId": "A", + "step": 30 + }, + { + "exemplar": true, + "expr": "sum(rate(tidb_statistics_historical_stats{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", type=~\"dump\"}[1m])) by (result)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "dump-{{result}}", + "refId": "B", + "step": 30 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Historical Stats OPM", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "repeat": null, + "title": "Statistics", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 161, + "panels": [ { "aliasColors": {}, "bars": false, @@ -16663,6 +17214,1051 @@ ], "title": "SourceSQL", "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 75 + }, + "id": 274, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The query count per second for each type of query in TTL jobs", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 76 + }, + "hiddenSeries": false, + "id": 279, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.10", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "delete ok", + "color": "#73BF69" + }, + { + "alias": "select ok", + "color": "#5794F2" + }, + { + "alias": "delete error", + "color": "#F2495C" + }, + { + "alias": "select error", + "color": "#FF7383" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tidb_server_ttl_query_duration_count{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (sql_type, result)", + "interval": "", + "legendFormat": "{{sql_type}} {{result}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TTL QPS By Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The processed rows per second by TTL jobs", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 76 + }, + "hiddenSeries": false, + "id": 287, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.10", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "delete error", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tidb_server_ttl_processed_expired_rows{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}[1m])) by (sql_type, result)", + "interval": "", + "legendFormat": "{{sql_type}} {{result}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TTL Processed Rows Per Second", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The duration of the TTL scan queries", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 84 + }, + "hiddenSeries": false, + "id": 284, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.10", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.50, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"select\", result=\"ok\"}[1m])) by (le))", + "interval": "", + "legendFormat": "50", + "queryType": "randomWalk", + "refId": "A" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.80, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"select\", result=\"ok\"}[1m])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "80", + "refId": "B" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.90, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"select\", result=\"ok\"}[1m])) by (le))\n", + "hide": false, + "interval": "", + "legendFormat": "90", + "refId": "C" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"select\", result=\"ok\"}[1m])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "99", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TTL Scan Query Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The duration of the TTL delete queries", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 84 + }, + "hiddenSeries": false, + "id": 285, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.10", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.50, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"delete\", result=\"ok\"}[1m])) by (le))", + "interval": "", + "legendFormat": "50", + "queryType": "randomWalk", + "refId": "A" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.80, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"delete\", result=\"ok\"}[1m])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "80", + "refId": "B" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.90, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"delete\", result=\"ok\"}[1m])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "90", + "refId": "C" + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(tidb_server_ttl_query_duration_bucket{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", sql_type=\"delete\", result=\"ok\"}[1m])) by (le))", + "hide": false, + "interval": "", + "legendFormat": "99", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TTL Delete Query Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The time spent on each phase for scan workers", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 92 + }, + "hiddenSeries": false, + "id": 276, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.10", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "idle", + "color": "#73BF69" + }, + { + "alias": "query", + "color": "#FADE2A" + }, + { + "alias": "begin_txn", + "color": "#FFA6B0" + }, + { + "alias": "commit_txn", + "color": "#FF7383" + }, + { + "alias": "wait_retry", + "color": "#FF9830" + }, + { + "alias": "check_ttl", + "color": "#C4162A" + }, + { + "alias": "dispatch", + "color": "#8F3BB8" + }, + { + "alias": "wait_token", + "color": "#8AB8FF" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tidb_server_ttl_phase_time{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", type=\"scan_worker\"}[1m])) by (phase)", + "interval": "", + "legendFormat": "{{phase}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Scan Worker Time By Phase", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The time spent on each phase for delete workers", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 92 + }, + "hiddenSeries": false, + "id": 282, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.10", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "idle", + "color": "#73BF69" + }, + { + "alias": "query", + "color": "#FADE2A" + }, + { + "alias": "begin_txn", + "color": "#FFA6B0" + }, + { + "alias": "commit_txn", + "color": "#FF7383" + }, + { + "alias": "wait_retry", + "color": "#FF9830" + }, + { + "alias": "check_ttl", + "color": "#C4162A" + }, + { + "alias": "dispatch", + "color": "#8F3BB8" + }, + { + "alias": "wait_token", + "color": "#8AB8FF" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(tidb_server_ttl_phase_time{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\", type=\"delete_worker\"}[1m])) by (phase)\n", + "interval": "", + "legendFormat": "{{phase}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Delete Worker Time By Phase", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "The TTL job statuses in each worker", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 100 + }, + "hiddenSeries": false, + "id": 281, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.10", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "running", + "color": "#5794F2" + }, + { + "alias": "cancelling", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(tidb_server_ttl_job_status{k8s_cluster=\"$k8s_cluster\",tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}) by (type, instance)", + "interval": "", + "legendFormat": "{{ instance }} {{ type }}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TTL Job Count By Status", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "TTL", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 291, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "hiddenSeries": false, + "id": 289, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.11", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "tidb_server_gogc{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}", + "interval": "", + "legendFormat": "{{instance}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "GOGC", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_TEST-CLUSTER}", + "description": "exponential moving average of CPU Usage", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "hiddenSeries": false, + "id": 293, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.11", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "tidb_rm_ema_cpu_usage{k8s_cluster=\"$k8s_cluster\", tidb_cluster=\"$tidb_cluster\", instance=~\"$instance\"}", + "interval": "", + "legendFormat": "{{instance}}", + "queryType": "randomWalk", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "EMA CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Resource Manager", + "type": "row" } ], "refresh": "30s", diff --git a/metrics/log_backup.go b/metrics/log_backup.go index 6c706b8027a79..767fe2e251d8a 100644 --- a/metrics/log_backup.go +++ b/metrics/log_backup.go @@ -60,4 +60,10 @@ var ( Name: "region_request_failure", Help: "The failure reasons of requesting region checkpoints.", }, []string{"reason"}) + RegionCheckpointSubscriptionEvent = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "log_backup", + Name: "region_checkpoint_event", + Help: "The region flush event count.", + }, []string{"store"}) ) diff --git a/metrics/main_test.go b/metrics/main_test.go index 998921fbc3192..887847a12ba86 100644 --- a/metrics/main_test.go +++ b/metrics/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/metrics/meta.go b/metrics/meta.go index 519ba6a0924a1..af967fe48a3bb 100644 --- a/metrics/meta.go +++ b/metrics/meta.go @@ -34,8 +34,6 @@ var ( GetSchemaDiff = "get_schema_diff" SetSchemaDiff = "set_schema_diff" - GetDDLJobByIdx = "get_ddl_job" - UpdateDDLJob = "update_ddl_job" GetHistoryDDLJob = "get_history_ddl_job" MetaHistogram = prometheus.NewHistogramVec( diff --git a/metrics/metrics.go b/metrics/metrics.go index 3d6ba83979f45..633aa551564bc 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -114,6 +114,7 @@ func RegisterMetrics() { prometheus.MustRegister(ExecuteErrorCounter) prometheus.MustRegister(ExecutorCounter) prometheus.MustRegister(GetTokenDurationHistogram) + prometheus.MustRegister(NumOfMultiQueryHistogram) prometheus.MustRegister(HandShakeErrorCounter) prometheus.MustRegister(HandleJobHistogram) prometheus.MustRegister(SignificantFeedbackCounter) @@ -123,7 +124,6 @@ func RegisterMetrics() { prometheus.MustRegister(SyncLoadHistogram) prometheus.MustRegister(ReadStatsHistogram) prometheus.MustRegister(JobsGauge) - prometheus.MustRegister(KeepAliveCounter) prometheus.MustRegister(LoadPrivilegeCounter) prometheus.MustRegister(InfoCacheCounters) prometheus.MustRegister(LoadSchemaCounter) @@ -134,6 +134,8 @@ func RegisterMetrics() { prometheus.MustRegister(PanicCounter) prometheus.MustRegister(PlanCacheCounter) prometheus.MustRegister(PlanCacheMissCounter) + prometheus.MustRegister(PlanCacheInstanceMemoryUsage) + prometheus.MustRegister(PlanCacheInstancePlanNumCounter) prometheus.MustRegister(PseudoEstimation) prometheus.MustRegister(PacketIOCounter) prometheus.MustRegister(QueryDurationHistogram) @@ -179,6 +181,7 @@ func RegisterMetrics() { prometheus.MustRegister(TokenGauge) prometheus.MustRegister(ConfigStatus) prometheus.MustRegister(TiFlashQueryTotalCounter) + prometheus.MustRegister(TiFlashFailedMPPStoreState) prometheus.MustRegister(SmallTxnWriteDuration) prometheus.MustRegister(TxnWriteThroughput) prometheus.MustRegister(LoadSysVarCacheCounter) @@ -190,7 +193,8 @@ func RegisterMetrics() { prometheus.MustRegister(CPUProfileCounter) prometheus.MustRegister(ReadFromTableCacheCounter) prometheus.MustRegister(LoadTableCacheDurationHistogram) - prometheus.MustRegister(NonTransactionalDeleteCount) + prometheus.MustRegister(NonTransactionalDMLCount) + prometheus.MustRegister(PessimisticDMLDurationByAttempt) prometheus.MustRegister(MemoryUsage) prometheus.MustRegister(StatsCacheLRUCounter) prometheus.MustRegister(StatsCacheLRUGauge) @@ -203,8 +207,21 @@ func RegisterMetrics() { prometheus.MustRegister(GetCheckpointBatchSize) prometheus.MustRegister(RegionCheckpointRequest) prometheus.MustRegister(RegionCheckpointFailure) + prometheus.MustRegister(AutoIDReqDuration) + prometheus.MustRegister(RegionCheckpointSubscriptionEvent) prometheus.MustRegister(RCCheckTSWriteConfilictCounter) + prometheus.MustRegister(TTLQueryDuration) + prometheus.MustRegister(TTLProcessedExpiredRowsCounter) + prometheus.MustRegister(TTLJobStatus) + prometheus.MustRegister(TTLPhaseTime) + + prometheus.MustRegister(EMACPUUsageGauge) + + prometheus.MustRegister(HistoricalStatsCounter) + prometheus.MustRegister(PlanReplayerTaskCounter) + prometheus.MustRegister(PlanReplayerRegisterTaskGauge) + tikvmetrics.InitMetrics(TiDB, TiKVClient) tikvmetrics.RegisterMetrics() tikvmetrics.TiKVPanicCounter = PanicCounter // reset tidb metrics for tikv metrics @@ -226,8 +243,9 @@ func ToggleSimplifiedMode(simplified bool) { InfoCacheCounters, ReadFromTableCacheCounter, TiFlashQueryTotalCounter, + TiFlashFailedMPPStoreState, CampaignOwnerCounter, - NonTransactionalDeleteCount, + NonTransactionalDMLCount, MemoryUsage, TokenGauge, tikvmetrics.TiKVRawkvSizeHistogram, diff --git a/metrics/resourcemanager.go b/metrics/resourcemanager.go new file mode 100644 index 0000000000000..d45b8833e1225 --- /dev/null +++ b/metrics/resourcemanager.go @@ -0,0 +1,27 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metrics + +import "github.com/prometheus/client_golang/prometheus" + +var ( + // EMACPUUsageGauge means exponential moving average of CPU usage + EMACPUUsageGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "tidb", + Subsystem: "rm", + Name: "ema_cpu_usage", + Help: "exponential moving average of CPU usage", + }) +) diff --git a/metrics/server.go b/metrics/server.go index d88c84a254581..830e03b28e986 100644 --- a/metrics/server.go +++ b/metrics/server.go @@ -120,14 +120,6 @@ var ( Help: "Counter of system time jumps backward.", }) - KeepAliveCounter = prometheus.NewCounter( - prometheus.CounterOpts{ - Namespace: "tidb", - Subsystem: "monitor", - Name: "keep_alive_total", - Help: "Counter of TiDB keep alive.", - }) - PlanCacheCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: "tidb", @@ -144,6 +136,22 @@ var ( Help: "Counter of plan cache miss.", }, []string{LblType}) + PlanCacheInstanceMemoryUsage = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "plan_cache_instance_memory_usage", + Help: "Total plan cache memory usage of all sessions in a instance", + }, []string{LblType}) + + PlanCacheInstancePlanNumCounter = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "plan_cache_instance_plan_num_total", + Help: "Counter of plan of all prepared plan cache in a instance", + }, []string{LblType}) + ReadFromTableCacheCounter = prometheus.NewCounter( prometheus.CounterOpts{ Namespace: "tidb", @@ -171,6 +179,15 @@ var ( Buckets: prometheus.ExponentialBuckets(1, 2, 30), // 1us ~ 528s }) + NumOfMultiQueryHistogram = prometheus.NewHistogram( + prometheus.HistogramOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "multi_query_num", + Help: "The number of queries contained in a multi-query statement.", + Buckets: prometheus.ExponentialBuckets(1, 2, 20), // 1 ~ 1048576 + }) + TotalQueryProcHistogram = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Namespace: "tidb", @@ -254,6 +271,14 @@ var ( Help: "Counter of TiFlash queries.", }, []string{LblType, LblResult}) + TiFlashFailedMPPStoreState = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "tiflash_failed_store", + Help: "Statues of failed tiflash mpp store,-1 means detector heartbeat,0 means reachable,1 means abnormal.", + }, []string{LblAddress}) + PDAPIExecutionHistogram = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Namespace: "tidb", diff --git a/metrics/session.go b/metrics/session.go index a54ab8e4cb8d4..170e7b5d178f5 100644 --- a/metrics/session.go +++ b/metrics/session.go @@ -18,6 +18,15 @@ import "github.com/prometheus/client_golang/prometheus" // Session metrics. var ( + AutoIDReqDuration = prometheus.NewHistogram( + prometheus.HistogramOpts{ + Namespace: "tidb", + Subsystem: "meta", + Name: "autoid_duration_seconds", + Help: "Bucketed histogram of processing time (s) in parse SQL.", + Buckets: prometheus.ExponentialBuckets(0.00004, 2, 28), // 40us ~ 1.5h + }) + SessionExecuteParseDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Namespace: "tidb", @@ -128,13 +137,14 @@ var ( Help: "Counter of validating read ts by getting a timestamp from PD", }) - NonTransactionalDeleteCount = prometheus.NewCounter( + NonTransactionalDMLCount = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: "tidb", Subsystem: "session", - Name: "non_transactional_delete_count", + Name: "non_transactional_dml_count", Help: "Counter of non-transactional delete", - }) + }, []string{LblType}, + ) TxnStatusEnteringCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: "tidb", @@ -156,9 +166,18 @@ var ( Namespace: "tidb", Subsystem: "session", Name: "lazy_pessimistic_unique_check_set_count", - Help: "Counter of setting tidb_constraint_check_in_place to false", + Help: "Counter of setting tidb_constraint_check_in_place to false, note that it doesn't count the default value set by tidb config", }, ) + + PessimisticDMLDurationByAttempt = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: "tidb", + Subsystem: "session", + Name: "transaction_pessimistic_dml_duration_by_attempt", + Help: "Bucketed histogram of duration of pessimistic DMLs, distinguished by first attempt and retries", + Buckets: prometheus.ExponentialBuckets(0.001, 2, 28), // 1ms ~ 1.5days + }, []string{LblType, LblPhase}) ) // Label constants. diff --git a/metrics/stats.go b/metrics/stats.go index 76bd1ec7a936b..5d73753f5669c 100644 --- a/metrics/stats.go +++ b/metrics/stats.go @@ -150,4 +150,25 @@ var ( Name: "stats_healthy", Help: "Gauge of stats healthy", }, []string{LblType}) + + HistoricalStatsCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "statistics", + Name: "historical_stats", + Help: "counter of the historical stats operation", + }, []string{LblType, LblResult}) + + PlanReplayerTaskCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "plan_replayer", + Name: "task", + Help: "counter of plan replayer captured task", + }, []string{LblType, LblResult}) + + PlanReplayerRegisterTaskGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "tidb", + Subsystem: "plan_replayer", + Name: "register_task", + Help: "gauge of plan replayer registered task", + }) ) diff --git a/metrics/telemetry.go b/metrics/telemetry.go index 222d723fb9b4f..6b7dbef4e8d5d 100644 --- a/metrics/telemetry.go +++ b/metrics/telemetry.go @@ -148,6 +148,34 @@ var ( Name: "add_index_ingest_usage", Help: "Counter of usage of add index acceleration solution", }) + TelemetryFlashbackClusterCnt = prometheus.NewCounter( + prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "telemetry", + Name: "flashback_cluster_usage", + Help: "Counter of usage of flashback cluster", + }) + TelemetryIndexMergeUsage = prometheus.NewCounter( + prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "telemetry", + Name: "index_merge_usage", + Help: "Counter of usage of index merge", + }) + TelemetryCompactPartitionCnt = prometheus.NewCounter( + prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "telemetry", + Name: "compact_partition_usage", + Help: "Counter of compact table partition", + }) + TelemetryReorganizePartitionCnt = prometheus.NewCounter( + prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "telemetry", + Name: "reorganize_partition_usage", + Help: "Counter of alter table reorganize partition", + }) ) // readCounter reads the value of a prometheus.Counter. @@ -247,6 +275,8 @@ type TablePartitionUsageCounter struct { TablePartitionCreateIntervalPartitionsCnt int64 `json:"table_partition_create_interval_partitions_cnt"` TablePartitionAddIntervalPartitionsCnt int64 `json:"table_partition_add_interval_partitions_cnt"` TablePartitionDropIntervalPartitionsCnt int64 `json:"table_partition_drop_interval_partitions_cnt"` + TablePartitionComactCnt int64 `json:"table_TablePartitionComactCnt"` + TablePartitionReorganizePartitionCnt int64 `json:"table_reorganize_partition_cnt"` } // ExchangePartitionUsageCounter records the usages of exchange partition. @@ -284,22 +314,25 @@ func (c TablePartitionUsageCounter) Cal(rhs TablePartitionUsageCounter) TablePar TablePartitionCreateIntervalPartitionsCnt: c.TablePartitionCreateIntervalPartitionsCnt - rhs.TablePartitionCreateIntervalPartitionsCnt, TablePartitionAddIntervalPartitionsCnt: c.TablePartitionAddIntervalPartitionsCnt - rhs.TablePartitionAddIntervalPartitionsCnt, TablePartitionDropIntervalPartitionsCnt: c.TablePartitionDropIntervalPartitionsCnt - rhs.TablePartitionDropIntervalPartitionsCnt, + TablePartitionComactCnt: c.TablePartitionComactCnt - rhs.TablePartitionComactCnt, + TablePartitionReorganizePartitionCnt: c.TablePartitionReorganizePartitionCnt - rhs.TablePartitionReorganizePartitionCnt, } } // ResetTablePartitionCounter gets the TxnCommitCounter. func ResetTablePartitionCounter(pre TablePartitionUsageCounter) TablePartitionUsageCounter { return TablePartitionUsageCounter{ - TablePartitionCnt: readCounter(TelemetryTablePartitionCnt), - TablePartitionListCnt: readCounter(TelemetryTablePartitionListCnt), - TablePartitionRangeCnt: readCounter(TelemetryTablePartitionRangeCnt), - TablePartitionHashCnt: readCounter(TelemetryTablePartitionHashCnt), - TablePartitionRangeColumnsCnt: readCounter(TelemetryTablePartitionRangeColumnsCnt), - TablePartitionRangeColumnsGt1Cnt: readCounter(TelemetryTablePartitionRangeColumnsGt1Cnt), - TablePartitionRangeColumnsGt2Cnt: readCounter(TelemetryTablePartitionRangeColumnsGt2Cnt), - TablePartitionRangeColumnsGt3Cnt: readCounter(TelemetryTablePartitionRangeColumnsGt3Cnt), - TablePartitionListColumnsCnt: readCounter(TelemetryTablePartitionListColumnsCnt), - TablePartitionMaxPartitionsCnt: mathutil.Max(readCounter(TelemetryTablePartitionMaxPartitionsCnt)-pre.TablePartitionMaxPartitionsCnt, pre.TablePartitionMaxPartitionsCnt), + TablePartitionCnt: readCounter(TelemetryTablePartitionCnt), + TablePartitionListCnt: readCounter(TelemetryTablePartitionListCnt), + TablePartitionRangeCnt: readCounter(TelemetryTablePartitionRangeCnt), + TablePartitionHashCnt: readCounter(TelemetryTablePartitionHashCnt), + TablePartitionRangeColumnsCnt: readCounter(TelemetryTablePartitionRangeColumnsCnt), + TablePartitionRangeColumnsGt1Cnt: readCounter(TelemetryTablePartitionRangeColumnsGt1Cnt), + TablePartitionRangeColumnsGt2Cnt: readCounter(TelemetryTablePartitionRangeColumnsGt2Cnt), + TablePartitionRangeColumnsGt3Cnt: readCounter(TelemetryTablePartitionRangeColumnsGt3Cnt), + TablePartitionListColumnsCnt: readCounter(TelemetryTablePartitionListColumnsCnt), + TablePartitionMaxPartitionsCnt: mathutil.Max(readCounter(TelemetryTablePartitionMaxPartitionsCnt)-pre.TablePartitionMaxPartitionsCnt, pre.TablePartitionMaxPartitionsCnt), + TablePartitionReorganizePartitionCnt: readCounter(TelemetryReorganizePartitionCnt), } } @@ -319,25 +352,33 @@ func GetTablePartitionCounter() TablePartitionUsageCounter { TablePartitionCreateIntervalPartitionsCnt: readCounter(TelemetryTablePartitionCreateIntervalPartitionsCnt), TablePartitionAddIntervalPartitionsCnt: readCounter(TelemetryTablePartitionAddIntervalPartitionsCnt), TablePartitionDropIntervalPartitionsCnt: readCounter(TelemetryTablePartitionDropIntervalPartitionsCnt), + TablePartitionComactCnt: readCounter(TelemetryCompactPartitionCnt), + TablePartitionReorganizePartitionCnt: readCounter(TelemetryReorganizePartitionCnt), } } // NonTransactionalStmtCounter records the usages of non-transactional statements. type NonTransactionalStmtCounter struct { DeleteCount int64 `json:"delete"` + UpdateCount int64 `json:"update"` + InsertCount int64 `json:"insert"` } // Sub returns the difference of two counters. func (n NonTransactionalStmtCounter) Sub(rhs NonTransactionalStmtCounter) NonTransactionalStmtCounter { return NonTransactionalStmtCounter{ DeleteCount: n.DeleteCount - rhs.DeleteCount, + UpdateCount: n.UpdateCount - rhs.UpdateCount, + InsertCount: n.InsertCount - rhs.InsertCount, } } // GetNonTransactionalStmtCounter gets the NonTransactionalStmtCounter. func GetNonTransactionalStmtCounter() NonTransactionalStmtCounter { return NonTransactionalStmtCounter{ - DeleteCount: readCounter(NonTransactionalDeleteCount), + DeleteCount: readCounter(NonTransactionalDMLCount.With(prometheus.Labels{LblType: "delete"})), + UpdateCount: readCounter(NonTransactionalDMLCount.With(prometheus.Labels{LblType: "update"})), + InsertCount: readCounter(NonTransactionalDMLCount.With(prometheus.Labels{LblType: "insert"})), } } @@ -351,22 +392,44 @@ func GetLazyPessimisticUniqueCheckSetCounter() int64 { return readCounter(LazyPessimisticUniqueCheckSetCount) } -// DDLUsageCounter records the usages of Add Index with acceleration solution. +// DDLUsageCounter records the usages of DDL related features. type DDLUsageCounter struct { - AddIndexIngestUsed int64 `json:"add_index_ingest_used"` - MetadataLockUsed bool `json:"metadata_lock_used"` + AddIndexIngestUsed int64 `json:"add_index_ingest_used"` + MetadataLockUsed bool `json:"metadata_lock_used"` + FlashbackClusterUsed int64 `json:"flashback_cluster_used"` } // Sub returns the difference of two counters. func (a DDLUsageCounter) Sub(rhs DDLUsageCounter) DDLUsageCounter { return DDLUsageCounter{ - AddIndexIngestUsed: a.AddIndexIngestUsed - rhs.AddIndexIngestUsed, + AddIndexIngestUsed: a.AddIndexIngestUsed - rhs.AddIndexIngestUsed, + FlashbackClusterUsed: a.FlashbackClusterUsed - rhs.FlashbackClusterUsed, } } // GetDDLUsageCounter gets the add index acceleration solution counts. func GetDDLUsageCounter() DDLUsageCounter { return DDLUsageCounter{ - AddIndexIngestUsed: readCounter(TelemetryAddIndexIngestCnt), + AddIndexIngestUsed: readCounter(TelemetryAddIndexIngestCnt), + FlashbackClusterUsed: readCounter(TelemetryFlashbackClusterCnt), + } +} + +// IndexMergeUsageCounter records the usages of IndexMerge feature. +type IndexMergeUsageCounter struct { + IndexMergeUsed int64 `json:"index_merge_used"` +} + +// Sub returns the difference of two counters. +func (i IndexMergeUsageCounter) Sub(rhs IndexMergeUsageCounter) IndexMergeUsageCounter { + return IndexMergeUsageCounter{ + IndexMergeUsed: i.IndexMergeUsed - rhs.IndexMergeUsed, + } +} + +// GetIndexMergeCounter gets the IndexMerge usage counter. +func GetIndexMergeCounter() IndexMergeUsageCounter { + return IndexMergeUsageCounter{ + IndexMergeUsed: readCounter(TelemetryIndexMergeUsage), } } diff --git a/metrics/ttl.go b/metrics/ttl.go new file mode 100644 index 0000000000000..ab7e47e615e28 --- /dev/null +++ b/metrics/ttl.go @@ -0,0 +1,53 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metrics + +import "github.com/prometheus/client_golang/prometheus" + +// TTL metrics +var ( + TTLQueryDuration = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "ttl_query_duration", + Help: "Bucketed histogram of processing time (s) of handled TTL queries.", + Buckets: prometheus.ExponentialBuckets(0.01, 2, 20), // 10ms ~ 1.45hour + }, []string{LblSQLType, LblResult}) + + TTLProcessedExpiredRowsCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "ttl_processed_expired_rows", + Help: "The count of expired rows processed in TTL jobs", + }, []string{LblSQLType, LblResult}) + + TTLJobStatus = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "ttl_job_status", + Help: "The jobs count in the specified status", + }, []string{LblType}) + + TTLPhaseTime = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "server", + Name: "ttl_phase_time", + Help: "The time spent in each phase", + }, []string{LblType, LblPhase}) +) diff --git a/owner/main_test.go b/owner/main_test.go index 57bc7021c5ca9..b1e1355258582 100644 --- a/owner/main_test.go +++ b/owner/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } diff --git a/parser/BUILD.bazel b/parser/BUILD.bazel index f52b1fc9ac4f3..ec67a5c141849 100644 --- a/parser/BUILD.bazel +++ b/parser/BUILD.bazel @@ -17,6 +17,7 @@ go_library( "//parser/ast", "//parser/auth", "//parser/charset", + "//parser/duration", "//parser/model", "//parser/mysql", "//parser/opcode", diff --git a/parser/ast/ddl.go b/parser/ast/ddl.go index 0bf00b7c151b6..c2649b8f3fb6f 100644 --- a/parser/ast/ddl.go +++ b/parser/ast/ddl.go @@ -28,17 +28,21 @@ var ( _ DDLNode = &AlterTableStmt{} _ DDLNode = &AlterSequenceStmt{} _ DDLNode = &AlterPlacementPolicyStmt{} + _ DDLNode = &AlterResourceGroupStmt{} _ DDLNode = &CreateDatabaseStmt{} _ DDLNode = &CreateIndexStmt{} _ DDLNode = &CreateTableStmt{} _ DDLNode = &CreateViewStmt{} _ DDLNode = &CreateSequenceStmt{} _ DDLNode = &CreatePlacementPolicyStmt{} + _ DDLNode = &CreateResourceGroupStmt{} _ DDLNode = &DropDatabaseStmt{} + _ DDLNode = &FlashBackDatabaseStmt{} _ DDLNode = &DropIndexStmt{} _ DDLNode = &DropTableStmt{} _ DDLNode = &DropSequenceStmt{} _ DDLNode = &DropPlacementPolicyStmt{} + _ DDLNode = &DropResourceGroupStmt{} _ DDLNode = &RenameTableStmt{} _ DDLNode = &TruncateTableStmt{} _ DDLNode = &RepairTableStmt{} @@ -253,6 +257,35 @@ func (n *DropDatabaseStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } +// FlashBackDatabaseStmt is a statement to restore a database and all tables in the database. +type FlashBackDatabaseStmt struct { + ddlNode + + DBName model.CIStr + NewName string +} + +// Restore implements Node interface. +func (n *FlashBackDatabaseStmt) Restore(ctx *format.RestoreCtx) error { + ctx.WriteKeyWord("FLASHBACK DATABASE ") + ctx.WriteName(n.DBName.O) + if len(n.NewName) > 0 { + ctx.WriteKeyWord(" TO ") + ctx.WriteName(n.NewName) + } + return nil +} + +// Accept implements Node Accept interface. +func (n *FlashBackDatabaseStmt) Accept(v Visitor) (Node, bool) { + newNode, skipChildren := v.Enter(n) + if skipChildren { + return v.Leave(newNode) + } + n = newNode.(*FlashBackDatabaseStmt) + return v.Leave(n) +} + // IndexPartSpecifications is used for parsing index column name or index expression from SQL. type IndexPartSpecification struct { node @@ -1063,7 +1096,8 @@ func (n *CreateTableStmt) Restore(ctx *format.RestoreCtx) error { ctx.WritePlain(")") } - for i, option := range n.Options { + options := tableOptionsWithRestoreTTLFlag(ctx.Flags, n.Options) + for i, option := range options { ctx.WritePlain(" ") if err := option.Restore(ctx); err != nil { return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt TableOption: [%v]", i) @@ -1150,6 +1184,13 @@ func (n *CreateTableStmt) Accept(v Visitor) (Node, bool) { } n.Partition = node.(*PartitionOptions) } + for i, option := range n.Options { + node, ok = option.Accept(v) + if !ok { + return n, false + } + n.Options[i] = node.(*TableOption) + } return v.Leave(n) } @@ -1243,6 +1284,32 @@ func (n *DropPlacementPolicyStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } +type DropResourceGroupStmt struct { + ddlNode + + IfExists bool + ResourceGroupName model.CIStr +} + +// Restore implements Restore interface. +func (n *DropResourceGroupStmt) Restore(ctx *format.RestoreCtx) error { + ctx.WriteKeyWord("DROP RESOURCE GROUP ") + if n.IfExists { + ctx.WriteKeyWord("IF EXISTS ") + } + ctx.WriteName(n.ResourceGroupName.O) + return nil +} + +func (n *DropResourceGroupStmt) Accept(v Visitor) (Node, bool) { + newNode, skipChildren := v.Enter(n) + if skipChildren { + return v.Leave(newNode) + } + n = newNode.(*DropResourceGroupStmt) + return v.Leave(n) +} + // DropSequenceStmt is a statement to drop a Sequence. type DropSequenceStmt struct { ddlNode @@ -1503,6 +1570,43 @@ func (n *CreatePlacementPolicyStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } +// CreateResourceGroupStmt is a statement to create a policy. +type CreateResourceGroupStmt struct { + ddlNode + + IfNotExists bool + ResourceGroupName model.CIStr + ResourceGroupOptionList []*ResourceGroupOption +} + +// Restore implements Node interface. +func (n *CreateResourceGroupStmt) Restore(ctx *format.RestoreCtx) error { + ctx.WriteKeyWord("CREATE ") + + ctx.WriteKeyWord("RESOURCE GROUP ") + if n.IfNotExists { + ctx.WriteKeyWord("IF NOT EXISTS ") + } + ctx.WriteName(n.ResourceGroupName.O) + for i, option := range n.ResourceGroupOptionList { + ctx.WritePlain(" ") + if err := option.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing CreatePlacementPolicy TableOption: [%v]", i) + } + } + return nil +} + +// Accept implements Node Accept interface. +func (n *CreateResourceGroupStmt) Accept(v Visitor) (Node, bool) { + newNode, skipChildren := v.Enter(n) + if skipChildren { + return v.Leave(newNode) + } + n = newNode.(*CreateResourceGroupStmt) + return v.Leave(n) +} + // CreateSequenceStmt is a statement to create a Sequence. type CreateSequenceStmt struct { ddlNode @@ -1994,6 +2098,59 @@ func (n *PlacementOption) Restore(ctx *format.RestoreCtx) error { return ctx.WriteWithSpecialComments(tidb.FeatureIDPlacement, fn) } +// ResourceGroupOption is used for parsing resource group option. +type ResourceGroupOption struct { + Tp ResourceUnitType + StrValue string + UintValue uint64 +} + +type ResourceUnitType int + +const ( + ResourceRRURate ResourceUnitType = iota + ResourceWRURate + // Native mode + ResourceUnitCPU + ResourceUnitIOReadBandwidth + ResourceUnitIOWriteBandwidth +) + +func (n *ResourceGroupOption) Restore(ctx *format.RestoreCtx) error { + if ctx.Flags.HasSkipPlacementRuleForRestoreFlag() { + return nil + } + fn := func() error { + switch n.Tp { + case ResourceRRURate: + ctx.WriteKeyWord("RRU_PER_SEC ") + ctx.WritePlain("= ") + ctx.WritePlainf("%d", n.UintValue) + case ResourceWRURate: + ctx.WriteKeyWord("WRU_PER_SEC ") + ctx.WritePlain("= ") + ctx.WritePlainf("%d", n.UintValue) + case ResourceUnitCPU: + ctx.WriteKeyWord("CPU ") + ctx.WritePlain("= ") + ctx.WriteString(n.StrValue) + case ResourceUnitIOReadBandwidth: + ctx.WriteKeyWord("IO_READ_BANDWIDTH ") + ctx.WritePlain("= ") + ctx.WriteString(n.StrValue) + case ResourceUnitIOWriteBandwidth: + ctx.WriteKeyWord("IO_WRITE_BANDWIDTH ") + ctx.WritePlain("= ") + ctx.WriteString(n.StrValue) + default: + return errors.Errorf("invalid PlacementOption: %d", n.Tp) + } + return nil + } + // WriteSpecialComment + return ctx.WriteWithSpecialComments(tidb.FeatureIDResourceGroup, fn) +} + type StatsOptionType int const ( @@ -2044,6 +2201,9 @@ const ( TableOptionTableCheckSum TableOptionUnion TableOptionEncryption + TableOptionTTL + TableOptionTTLEnable + TableOptionTTLJobInterval TableOptionPlacementPolicy = TableOptionType(PlacementOptionPolicy) TableOptionStatsBuckets = TableOptionType(StatsOptionBuckets) TableOptionStatsTopN = TableOptionType(StatsOptionTopN) @@ -2090,13 +2250,16 @@ const ( // TableOption is used for parsing table option from SQL. type TableOption struct { - Tp TableOptionType - Default bool - StrValue string - UintValue uint64 - BoolValue bool - Value ValueExpr - TableNames []*TableName + node + Tp TableOptionType + Default bool + StrValue string + UintValue uint64 + BoolValue bool + TimeUnitValue *TimeUnitExpr + Value ValueExpr + TableNames []*TableName + ColumnName *ColumnName } func (n *TableOption) Restore(ctx *format.RestoreCtx) error { @@ -2375,12 +2538,67 @@ func (n *TableOption) Restore(ctx *format.RestoreCtx) error { } else { ctx.WriteString(n.StrValue) } + case TableOptionTTL: + _ = ctx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error { + ctx.WriteKeyWord("TTL ") + ctx.WritePlain("= ") + ctx.WriteName(n.ColumnName.Name.String()) + ctx.WritePlain(" + INTERVAL ") + err := n.Value.Restore(ctx) + ctx.WritePlain(" ") + if err != nil { + return err + } + return n.TimeUnitValue.Restore(ctx) + }) + case TableOptionTTLEnable: + _ = ctx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error { + ctx.WriteKeyWord("TTL_ENABLE ") + ctx.WritePlain("= ") + if n.BoolValue { + ctx.WriteString("ON") + } else { + ctx.WriteString("OFF") + } + return nil + }) + case TableOptionTTLJobInterval: + _ = ctx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error { + ctx.WriteKeyWord("TTL_JOB_INTERVAL ") + ctx.WritePlain("= ") + ctx.WriteString(n.StrValue) + return nil + }) default: return errors.Errorf("invalid TableOption: %d", n.Tp) } return nil } +// Accept implements Node Accept interface. +func (n *TableOption) Accept(v Visitor) (Node, bool) { + newNode, skipChildren := v.Enter(n) + if skipChildren { + return v.Leave(newNode) + } + n = newNode.(*TableOption) + if n.Value != nil { + node, ok := n.Value.Accept(v) + if !ok { + return n, false + } + n.Value = node.(ValueExpr) + } + if n.TimeUnitValue != nil { + node, ok := n.TimeUnitValue.Accept(v) + if !ok { + return n, false + } + n.TimeUnitValue = node.(*TimeUnitExpr) + } + return v.Leave(n) +} + // SequenceOptionType is the type for SequenceOption type SequenceOptionType int @@ -2569,6 +2787,7 @@ const ( AlterTableAddLastPartition AlterTableReorganizeLastPartition AlterTableReorganizeFirstPartition + AlterTableRemoveTTL ) // LockType is the type for AlterTableSpec. @@ -3250,7 +3469,11 @@ func (n *AlterTableSpec) Restore(ctx *format.RestoreCtx) error { if err := spec.Restore(ctx); err != nil { return errors.Annotatef(err, "An error occurred while restore AlterTableSpec.StatsOptionsSpec") } - + case AlterTableRemoveTTL: + _ = ctx.WriteWithSpecialComments(tidb.FeatureIDTTL, func() error { + ctx.WriteKeyWord("REMOVE TTL") + return nil + }) default: // TODO: not support ctx.WritePlainf(" /* AlterTableType(%d) is not supported */ ", n.Tp) @@ -3314,6 +3537,13 @@ func (n *AlterTableSpec) Accept(v Visitor) (Node, bool) { } n.Partition = node.(*PartitionOptions) } + for i, option := range n.Options { + node, ok := option.Accept(v) + if !ok { + return n, false + } + n.Options[i] = node.(*TableOption) + } for _, def := range n.PartDefinitions { if !def.acceptInPlace(v) { return n, false @@ -3352,11 +3582,21 @@ func (n *AlterTableStmt) Restore(ctx *format.RestoreCtx) error { if err := n.Table.Restore(ctx); err != nil { return errors.Annotate(err, "An error occurred while restore AlterTableStmt.Table") } - var specs []*AlterTableSpec + specs := make([]*AlterTableSpec, 0, len(n.Specs)) for _, spec := range n.Specs { - if !(spec.IsAllPlacementRule() && ctx.Flags.HasSkipPlacementRuleForRestoreFlag()) { - specs = append(specs, spec) + if spec.IsAllPlacementRule() && ctx.Flags.HasSkipPlacementRuleForRestoreFlag() { + continue } + if spec.Tp == AlterTableOption { + newOptions := tableOptionsWithRestoreTTLFlag(ctx.Flags, spec.Options) + if len(newOptions) == 0 { + continue + } + newSpec := *spec + newSpec.Options = newOptions + spec = &newSpec + } + specs = append(specs, spec) } for i, spec := range specs { if i == 0 || spec.Tp == AlterTablePartition || spec.Tp == AlterTableRemovePartitioning || spec.Tp == AlterTableImportTablespace || spec.Tp == AlterTableDiscardTablespace { @@ -4010,29 +4250,57 @@ func (n *RecoverTableStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } -// FlashBackClusterStmt is a statement to restore the cluster to the specified timestamp -type FlashBackClusterStmt struct { +// FlashBackToTimestampStmt is a statement to restore the cluster to the specified timestamp +type FlashBackToTimestampStmt struct { ddlNode FlashbackTS ExprNode + Tables []*TableName + DBName model.CIStr } // Restore implements Node interface -func (n *FlashBackClusterStmt) Restore(ctx *format.RestoreCtx) error { - ctx.WriteKeyWord("FLASHBACK CLUSTER TO TIMESTAMP ") +func (n *FlashBackToTimestampStmt) Restore(ctx *format.RestoreCtx) error { + ctx.WriteKeyWord("FLASHBACK ") + if len(n.Tables) != 0 { + ctx.WriteKeyWord("TABLE ") + for index, table := range n.Tables { + if index != 0 { + ctx.WritePlain(", ") + } + if err := table.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore DropTableStmt.Tables[%d]", index) + } + } + } else if n.DBName.O != "" { + ctx.WriteKeyWord("DATABASE ") + ctx.WriteName(n.DBName.O) + } else { + ctx.WriteKeyWord("CLUSTER") + } + ctx.WriteKeyWord(" TO TIMESTAMP ") if err := n.FlashbackTS.Restore(ctx); err != nil { - return errors.Annotate(err, "An error occurred while splicing FlashBackClusterStmt.FlashbackTS") + return errors.Annotate(err, "An error occurred while splicing FlashBackToTimestampStmt.FlashbackTS") } return nil } // Accept implements Node Accept interface. -func (n *FlashBackClusterStmt) Accept(v Visitor) (Node, bool) { +func (n *FlashBackToTimestampStmt) Accept(v Visitor) (Node, bool) { newNode, skipChildren := v.Enter(n) if skipChildren { return v.Leave(newNode) } - n = newNode.(*FlashBackClusterStmt) + n = newNode.(*FlashBackToTimestampStmt) + if len(n.Tables) != 0 { + for i, val := range n.Tables { + node, ok := val.Accept(v) + if !ok { + return n, false + } + n.Tables[i] = node.(*TableName) + } + } node, ok := n.FlashbackTS.Accept(v) if !ok { return n, false @@ -4174,6 +4442,39 @@ func (n *AlterPlacementPolicyStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } +// AlterResourceGroupStmt is a statement to alter placement policy option. +type AlterResourceGroupStmt struct { + ddlNode + + ResourceGroupName model.CIStr + IfExists bool + ResourceGroupOptionList []*ResourceGroupOption +} + +func (n *AlterResourceGroupStmt) Restore(ctx *format.RestoreCtx) error { + ctx.WriteKeyWord("ALTER RESOURCE GROUP ") + if n.IfExists { + ctx.WriteKeyWord("IF EXISTS ") + } + ctx.WriteName(n.ResourceGroupName.O) + for i, option := range n.ResourceGroupOptionList { + ctx.WritePlain(" ") + if err := option.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing AlterResourceStmt Options: [%v]", i) + } + } + return nil +} + +func (n *AlterResourceGroupStmt) Accept(v Visitor) (Node, bool) { + newNode, skipChildren := v.Enter(n) + if skipChildren { + return v.Leave(newNode) + } + n = newNode.(*AlterResourceGroupStmt) + return v.Leave(n) +} + // AlterSequenceStmt is a statement to alter sequence option. type AlterSequenceStmt struct { ddlNode @@ -4228,3 +4529,25 @@ func restorePlacementStmtInSpecialComment(ctx *format.RestoreCtx, n DDLNode) err return n.Restore(ctx) }) } + +func tableOptionsWithRestoreTTLFlag(flags format.RestoreFlags, options []*TableOption) []*TableOption { + if !flags.HasRestoreWithTTLEnableOff() { + return options + } + + newOptions := make([]*TableOption, 0, len(options)) + for _, opt := range options { + if opt.Tp == TableOptionTTLEnable { + continue + } + + newOptions = append(newOptions, opt) + if opt.Tp == TableOptionTTL { + newOptions = append(newOptions, &TableOption{ + Tp: TableOptionTTLEnable, + BoolValue: false, + }) + } + } + return newOptions +} diff --git a/parser/ast/ddl_test.go b/parser/ast/ddl_test.go index 44059151db3b6..dbbb212037db8 100644 --- a/parser/ast/ddl_test.go +++ b/parser/ast/ddl_test.go @@ -248,6 +248,21 @@ func TestDDLColumnOptionRestore(t *testing.T) { runNodeRestoreTest(t, testCases, "CREATE TABLE child (id INT %s)", extractNodeFunc) } +func TestGeneratedRestore(t *testing.T) { + testCases := []NodeRestoreTestCase{ + {"generated always as(id + 1)", "GENERATED ALWAYS AS(`id`+1) VIRTUAL"}, + {"generated always as(id + 1) virtual", "GENERATED ALWAYS AS(`id`+1) VIRTUAL"}, + {"generated always as(id + 1) stored", "GENERATED ALWAYS AS(`id`+1) STORED"}, + {"generated always as(lower(id)) stored", "GENERATED ALWAYS AS(LOWER(`id`)) STORED"}, + {"generated always as(lower(child.id)) stored", "GENERATED ALWAYS AS(LOWER(`id`)) STORED"}, + } + extractNodeFunc := func(node Node) Node { + return node.(*CreateTableStmt).Cols[0].Options[0] + } + runNodeRestoreTestWithFlagsStmtChange(t, testCases, "CREATE TABLE child (id INT %s)", extractNodeFunc, + format.DefaultRestoreFlags|format.RestoreWithoutSchemaName|format.RestoreWithoutTableName) +} + func TestDDLColumnDefRestore(t *testing.T) { testCases := []NodeRestoreTestCase{ // for type @@ -827,3 +842,79 @@ func TestRemovePlacementRestore(t *testing.T) { runNodeRestoreTestWithFlagsStmtChange(t, testCases, "%s", extractNodeFunc, f) } } + +func TestFlashBackDatabaseRestore(t *testing.T) { + testCases := []NodeRestoreTestCase{ + {"flashback database M", "FLASHBACK DATABASE `M`"}, + {"flashback schema M", "FLASHBACK DATABASE `M`"}, + {"flashback database M to n", "FLASHBACK DATABASE `M` TO `n`"}, + {"flashback schema M to N", "FLASHBACK DATABASE `M` TO `N`"}, + } + extractNodeFunc := func(node Node) Node { + return node + } + runNodeRestoreTest(t, testCases, "%s", extractNodeFunc) +} + +func TestTableOptionTTLRestore(t *testing.T) { + sourceSQL1 := "create table t (created_at datetime) ttl = created_at + INTERVAL 1 YEAR" + sourceSQL2 := "alter table t ttl_enable = 'OFF'" + sourceSQL3 := "alter table t remove ttl" + cases := []struct { + sourceSQL string + flags format.RestoreFlags + expectSQL string + }{ + {sourceSQL1, format.DefaultRestoreFlags, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR"}, + {sourceSQL1, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment, "CREATE TABLE `t` (`created_at` DATETIME) /*T![ttl] TTL = `created_at` + INTERVAL 1 YEAR */"}, + {sourceSQL2, format.DefaultRestoreFlags, "ALTER TABLE `t` TTL_ENABLE = 'OFF'"}, + {sourceSQL2, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment, "ALTER TABLE `t` /*T![ttl] TTL_ENABLE = 'OFF' */"}, + {sourceSQL3, format.DefaultRestoreFlags, "ALTER TABLE `t` REMOVE TTL"}, + {sourceSQL3, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment, "ALTER TABLE `t` /*T![ttl] REMOVE TTL */"}, + } + + extractNodeFunc := func(node Node) Node { + return node + } + + for _, ca := range cases { + testCases := []NodeRestoreTestCase{ + {ca.sourceSQL, ca.expectSQL}, + } + runNodeRestoreTestWithFlags(t, testCases, "%s", extractNodeFunc, ca.flags) + } +} + +func TestTableOptionTTLRestoreWithTTLEnableOffFlag(t *testing.T) { + sourceSQL1 := "create table t (created_at datetime) ttl = created_at + INTERVAL 1 YEAR" + sourceSQL2 := "alter table t ttl_enable = 'ON'" + sourceSQL3 := "alter table t remove ttl" + sourceSQL4 := "create table t (created_at datetime) ttl = created_at + INTERVAL 1 YEAR ttl_enable = 'ON'" + sourceSQL5 := "alter table t ttl_enable = 'ON' placement policy p1" + cases := []struct { + sourceSQL string + flags format.RestoreFlags + expectSQL string + }{ + {sourceSQL1, format.DefaultRestoreFlags | format.RestoreWithTTLEnableOff, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'OFF'"}, + {sourceSQL1, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment | format.RestoreWithTTLEnableOff, "CREATE TABLE `t` (`created_at` DATETIME) /*T![ttl] TTL = `created_at` + INTERVAL 1 YEAR */ /*T![ttl] TTL_ENABLE = 'OFF' */"}, + {sourceSQL2, format.DefaultRestoreFlags | format.RestoreWithTTLEnableOff, "ALTER TABLE `t`"}, + {sourceSQL2, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment | format.RestoreWithTTLEnableOff, "ALTER TABLE `t`"}, + {sourceSQL3, format.DefaultRestoreFlags | format.RestoreWithTTLEnableOff, "ALTER TABLE `t` REMOVE TTL"}, + {sourceSQL3, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment | format.RestoreWithTTLEnableOff, "ALTER TABLE `t` /*T![ttl] REMOVE TTL */"}, + {sourceSQL4, format.DefaultRestoreFlags | format.RestoreWithTTLEnableOff, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'OFF'"}, + {sourceSQL4, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment | format.RestoreWithTTLEnableOff, "CREATE TABLE `t` (`created_at` DATETIME) /*T![ttl] TTL = `created_at` + INTERVAL 1 YEAR */ /*T![ttl] TTL_ENABLE = 'OFF' */"}, + {sourceSQL5, format.DefaultRestoreFlags | format.RestoreTiDBSpecialComment | format.RestoreWithTTLEnableOff, "ALTER TABLE `t` /*T![placement] PLACEMENT POLICY = `p1` */"}, + } + + extractNodeFunc := func(node Node) Node { + return node + } + + for _, ca := range cases { + testCases := []NodeRestoreTestCase{ + {ca.sourceSQL, ca.expectSQL}, + } + runNodeRestoreTestWithFlagsStmtChange(t, testCases, "%s", extractNodeFunc, ca.flags) + } +} diff --git a/parser/ast/dml.go b/parser/ast/dml.go index 4b5ddbae45d8d..4b14bdc1fbc69 100644 --- a/parser/ast/dml.go +++ b/parser/ast/dml.go @@ -31,7 +31,7 @@ var ( _ DMLNode = &ShowStmt{} _ DMLNode = &LoadDataStmt{} _ DMLNode = &SplitRegionStmt{} - _ DMLNode = &NonTransactionalDeleteStmt{} + _ DMLNode = &NonTransactionalDMLStmt{} _ Node = &Assignment{} _ Node = &ByItem{} @@ -288,15 +288,17 @@ func (*TableName) resultSet() {} // Restore implements Node interface. func (n *TableName) restoreName(ctx *format.RestoreCtx) { - // restore db name - if n.Schema.String() != "" { - ctx.WriteName(n.Schema.String()) - ctx.WritePlain(".") - } else if ctx.DefaultDB != "" { - // Try CTE, for a CTE table name, we shouldn't write the database name. - if !ctx.IsCTETableName(n.Name.L) { - ctx.WriteName(ctx.DefaultDB) + if !ctx.Flags.HasWithoutSchemaNameFlag() { + // restore db name + if n.Schema.String() != "" { + ctx.WriteName(n.Schema.String()) ctx.WritePlain(".") + } else if ctx.DefaultDB != "" { + // Try CTE, for a CTE table name, we shouldn't write the database name. + if !ctx.IsCTETableName(n.Name.L) { + ctx.WriteName(ctx.DefaultDB) + ctx.WritePlain(".") + } } } // restore table name @@ -356,6 +358,8 @@ const ( HintUse IndexHintType = iota + 1 HintIgnore HintForce + HintKeepOrder + HintNoKeepOrder ) // IndexHintScope is the type for index hint for join, order by or group by. @@ -386,6 +390,10 @@ func (n *IndexHint) Restore(ctx *format.RestoreCtx) error { indexHintType = "IGNORE INDEX" case HintForce: indexHintType = "FORCE INDEX" + case HintKeepOrder: + indexHintType = "KEEP ORDER" + case HintNoKeepOrder: + indexHintType = "NO KEEP ORDER" default: // Prevent accidents return errors.New("IndexHintType has an error while matching") } @@ -1642,7 +1650,7 @@ func (n *SetOprStmt) Restore(ctx *format.RestoreCtx) error { if n.With != nil { defer ctx.RestoreCTEFunc()() //nolint: all_revive if err := n.With.Restore(ctx); err != nil { - return errors.Annotate(err, "An error occurred while restore UnionStmt.With") + return errors.Annotate(err, "An error occurred while restore SetOprStmt.With") } } if n.IsInBraces { @@ -1793,12 +1801,26 @@ func (n *ColumnNameOrUserVar) Accept(v Visitor) (node Node, ok bool) { return v.Leave(n) } +type FileLocRefTp int + +const ( + // FileLocServer is used when there's no keywords in SQL, which means the data file should be located on the tidb-server. + FileLocServer FileLocRefTp = iota + // FileLocClient is used when there's LOCAL keyword in SQL, which means the data file should be located on the MySQL + // client. + FileLocClient + // FileLocRemote is used when there's REMOTE keyword in SQL, which means the data file should be located on a remote + // server, such as a cloud storage. + FileLocRemote +) + // LoadDataStmt is a statement to load data from a specified file, then insert this rows into an existing table. // See https://dev.mysql.com/doc/refman/5.7/en/load-data.html +// in TiDB we extend the syntax to use LOAD DATA as a more general way to import data. type LoadDataStmt struct { dmlNode - IsLocal bool + FileLocRef FileLocRefTp Path string OnDuplicate OnDuplicateKeyHandlingType Table *TableName @@ -1814,8 +1836,12 @@ type LoadDataStmt struct { // Restore implements Node interface. func (n *LoadDataStmt) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord("LOAD DATA ") - if n.IsLocal { + switch n.FileLocRef { + case FileLocServer: + case FileLocClient: ctx.WriteKeyWord("LOCAL ") + case FileLocRemote: + ctx.WriteKeyWord("REMOTE ") } ctx.WriteKeyWord("INFILE ") ctx.WriteString(n.Path) @@ -2197,6 +2223,42 @@ func (n *InsertStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } +// WhereExpr implements ShardableDMLStmt interface. +func (n *InsertStmt) WhereExpr() ExprNode { + if n.Select == nil { + return nil + } + s, ok := n.Select.(*SelectStmt) + if !ok { + return nil + } + return s.Where +} + +// SetWhereExpr implements ShardableDMLStmt interface. +func (n *InsertStmt) SetWhereExpr(e ExprNode) { + if n.Select == nil { + return + } + s, ok := n.Select.(*SelectStmt) + if !ok { + return + } + s.Where = e +} + +// TableRefsJoin implements ShardableDMLStmt interface. +func (n *InsertStmt) TableRefsJoin() (*Join, bool) { + if n.Select == nil { + return nil, false + } + s, ok := n.Select.(*SelectStmt) + if !ok { + return nil, false + } + return s.From.TableRefs, true +} + // DeleteStmt is a statement to delete rows from table. // See https://dev.mysql.com/doc/refman/5.7/en/delete.html type DeleteStmt struct { @@ -2363,23 +2425,50 @@ func (n *DeleteStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } +// WhereExpr implements ShardableDMLStmt interface. +func (n *DeleteStmt) WhereExpr() ExprNode { + return n.Where +} + +// SetWhereExpr implements ShardableDMLStmt interface. +func (n *DeleteStmt) SetWhereExpr(e ExprNode) { + n.Where = e +} + +// TableRefsJoin implements ShardableDMLStmt interface. +func (n *DeleteStmt) TableRefsJoin() (*Join, bool) { + return n.TableRefs.TableRefs, true +} + const ( NoDryRun = iota DryRunQuery DryRunSplitDml ) -type NonTransactionalDeleteStmt struct { +type ShardableDMLStmt = interface { + StmtNode + WhereExpr() ExprNode + SetWhereExpr(ExprNode) + // TableRefsJoin returns the table refs in the statement. + TableRefsJoin() (refs *Join, ok bool) +} + +var _ ShardableDMLStmt = &DeleteStmt{} +var _ ShardableDMLStmt = &UpdateStmt{} +var _ ShardableDMLStmt = &InsertStmt{} + +type NonTransactionalDMLStmt struct { dmlNode DryRun int // 0: no dry run, 1: dry run the query, 2: dry run split DMLs ShardColumn *ColumnName // if it's nil, the handle column is automatically chosen for it Limit uint64 - DeleteStmt *DeleteStmt + DMLStmt ShardableDMLStmt } // Restore implements Node interface. -func (n *NonTransactionalDeleteStmt) Restore(ctx *format.RestoreCtx) error { +func (n *NonTransactionalDMLStmt) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord("BATCH ") if n.ShardColumn != nil { ctx.WriteKeyWord("ON ") @@ -2396,20 +2485,20 @@ func (n *NonTransactionalDeleteStmt) Restore(ctx *format.RestoreCtx) error { if n.DryRun == DryRunQuery { ctx.WriteKeyWord("DRY RUN QUERY ") } - if err := n.DeleteStmt.Restore(ctx); err != nil { + if err := n.DMLStmt.Restore(ctx); err != nil { return errors.Trace(err) } return nil } // Accept implements Node Accept interface. -func (n *NonTransactionalDeleteStmt) Accept(v Visitor) (Node, bool) { +func (n *NonTransactionalDMLStmt) Accept(v Visitor) (Node, bool) { newNode, skipChildren := v.Enter(n) if skipChildren { return v.Leave(newNode) } - n = newNode.(*NonTransactionalDeleteStmt) + n = newNode.(*NonTransactionalDMLStmt) if n.ShardColumn != nil { node, ok := n.ShardColumn.Accept(v) if !ok { @@ -2417,12 +2506,12 @@ func (n *NonTransactionalDeleteStmt) Accept(v Visitor) (Node, bool) { } n.ShardColumn = node.(*ColumnName) } - if n.DeleteStmt != nil { - node, ok := n.DeleteStmt.Accept(v) + if n.DMLStmt != nil { + node, ok := n.DMLStmt.Accept(v) if !ok { return n, false } - n.DeleteStmt = node.(*DeleteStmt) + n.DMLStmt = node.(ShardableDMLStmt) } return v.Leave(n) } @@ -2574,6 +2663,21 @@ func (n *UpdateStmt) Accept(v Visitor) (Node, bool) { return v.Leave(n) } +// WhereExpr implements ShardableDMLStmt interface. +func (n *UpdateStmt) WhereExpr() ExprNode { + return n.Where +} + +// SetWhereExpr implements ShardableDMLStmt interface. +func (n *UpdateStmt) SetWhereExpr(e ExprNode) { + n.Where = e +} + +// TableRefsJoin implements ShardableDMLStmt interface. +func (n *UpdateStmt) TableRefsJoin() (*Join, bool) { + return n.TableRefs.TableRefs, true +} + // Limit is the limit clause. type Limit struct { node @@ -2657,6 +2761,7 @@ const ( ShowStatsTopN ShowStatsBuckets ShowStatsHealthy + ShowStatsLocked ShowHistogramsInFlight ShowColumnStatsUsage ShowPlugins @@ -2684,6 +2789,7 @@ const ( ShowPlacementForPartition ShowPlacementLabels ShowSessionStates + ShowCreateResourceGroup ) const ( @@ -2704,19 +2810,20 @@ const ( type ShowStmt struct { dmlNode - Tp ShowStmtType // Databases/Tables/Columns/.... - DBName string - Table *TableName // Used for showing columns. - Partition model.CIStr // Used for showing partition. - Column *ColumnName // Used for `desc table column`. - IndexName model.CIStr - Flag int // Some flag parsed from sql, such as FULL. - Full bool - User *auth.UserIdentity // Used for show grants/create user. - Roles []*auth.RoleIdentity // Used for show grants .. using - IfNotExists bool // Used for `show create database if not exists` - Extended bool // Used for `show extended columns from ...` - Limit *Limit // Used for partial Show STMTs to limit Result Set row numbers. + Tp ShowStmtType // Databases/Tables/Columns/.... + DBName string + Table *TableName // Used for showing columns. + Partition model.CIStr // Used for showing partition. + Column *ColumnName // Used for `desc table column`. + IndexName model.CIStr + ResourceGroupName string // used for showing resource group + Flag int // Some flag parsed from sql, such as FULL. + Full bool + User *auth.UserIdentity // Used for show grants/create user. + Roles []*auth.RoleIdentity // Used for show grants .. using + IfNotExists bool // Used for `show create database if not exists` + Extended bool // Used for `show extended columns from ...` + Limit *Limit // Used for partial Show STMTs to limit Result Set row numbers. CountWarningsOrErrors bool // Used for showing count(*) warnings | errors @@ -2792,6 +2899,9 @@ func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error { case ShowCreatePlacementPolicy: ctx.WriteKeyWord("CREATE PLACEMENT POLICY ") ctx.WriteName(n.DBName) + case ShowCreateResourceGroup: + ctx.WriteKeyWord("CREATE RESOURCE GROUP ") + ctx.WriteName(n.ResourceGroupName) case ShowCreateUser: ctx.WriteKeyWord("CREATE USER ") if err := n.User.Restore(ctx); err != nil { @@ -2831,6 +2941,11 @@ func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error { if err := restoreShowLikeOrWhereOpt(); err != nil { return err } + case ShowStatsLocked: + ctx.WriteKeyWord("STATS_LOCKED") + if err := restoreShowLikeOrWhereOpt(); err != nil { + return err + } case ShowStatsHistograms: ctx.WriteKeyWord("STATS_HISTOGRAMS") if err := restoreShowLikeOrWhereOpt(); err != nil { diff --git a/parser/ast/expressions.go b/parser/ast/expressions.go index 270c46218af61..6bca49f4d2a7d 100644 --- a/parser/ast/expressions.go +++ b/parser/ast/expressions.go @@ -512,11 +512,11 @@ type ColumnName struct { // Restore implements Node interface. func (n *ColumnName) Restore(ctx *format.RestoreCtx) error { - if n.Schema.O != "" && !ctx.IsCTETableName(n.Table.L) { + if n.Schema.O != "" && !ctx.IsCTETableName(n.Table.L) && !ctx.Flags.HasWithoutSchemaNameFlag() { ctx.WriteName(n.Schema.O) ctx.WritePlain(".") } - if n.Table.O != "" { + if n.Table.O != "" && !ctx.Flags.HasWithoutTableNameFlag() { ctx.WriteName(n.Table.O) ctx.WritePlain(".") } diff --git a/parser/ast/functions.go b/parser/ast/functions.go index 5da3d4ad394c4..fdedf53b701cf 100644 --- a/parser/ast/functions.go +++ b/parser/ast/functions.go @@ -331,7 +331,9 @@ const ( JSONInsert = "json_insert" JSONReplace = "json_replace" JSONRemove = "json_remove" + JSONOverlaps = "json_overlaps" JSONContains = "json_contains" + JSONMemberOf = "json_memberof" JSONContainsPath = "json_contains_path" JSONValid = "json_valid" JSONArrayAppend = "json_array_append" @@ -341,6 +343,7 @@ const ( JSONPretty = "json_pretty" JSONQuote = "json_quote" JSONSearch = "json_search" + JSONStorageFree = "json_storage_free" JSONStorageSize = "json_storage_size" JSONDepth = "json_depth" JSONKeys = "json_keys" @@ -379,21 +382,9 @@ type FuncCallExpr struct { // Restore implements Node interface. func (n *FuncCallExpr) Restore(ctx *format.RestoreCtx) error { - var specialLiteral string - switch n.FnName.L { - case DateLiteral: - specialLiteral = "DATE " - case TimeLiteral: - specialLiteral = "TIME " - case TimestampLiteral: - specialLiteral = "TIMESTAMP " - } - if specialLiteral != "" { - ctx.WritePlain(specialLiteral) - if err := n.Args[0].Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore FuncCastExpr.Expr") - } - return nil + done, err := n.customRestore(ctx) + if done { + return err } if len(n.Schema.String()) != 0 { @@ -494,29 +485,70 @@ func (n *FuncCallExpr) Restore(ctx *format.RestoreCtx) error { return nil } +func (n *FuncCallExpr) customRestore(ctx *format.RestoreCtx) (bool, error) { + var specialLiteral string + switch n.FnName.L { + case DateLiteral: + specialLiteral = "DATE " + case TimeLiteral: + specialLiteral = "TIME " + case TimestampLiteral: + specialLiteral = "TIMESTAMP " + } + if specialLiteral != "" { + ctx.WritePlain(specialLiteral) + if err := n.Args[0].Restore(ctx); err != nil { + return true, errors.Annotatef(err, "An error occurred while restore FuncCallExpr.Expr") + } + return true, nil + } + if n.FnName.L == JSONMemberOf { + if err := n.Args[0].Restore(ctx); err != nil { + return true, errors.Annotatef(err, "An error occurred while restore FuncCallExpr.(MEMBER OF).Args[0]") + } + ctx.WriteKeyWord(" MEMBER OF ") + ctx.WritePlain("(") + if err := n.Args[1].Restore(ctx); err != nil { + return true, errors.Annotatef(err, "An error occurred while restore FuncCallExpr.(MEMBER OF).Args[1]") + } + ctx.WritePlain(")") + return true, nil + } + return false, nil +} + // Format the ExprNode into a Writer. func (n *FuncCallExpr) Format(w io.Writer) { - fmt.Fprintf(w, "%s(", n.FnName.L) if !n.specialFormatArgs(w) { + fmt.Fprintf(w, "%s(", n.FnName.L) for i, arg := range n.Args { arg.Format(w) if i != len(n.Args)-1 { fmt.Fprint(w, ", ") } } + fmt.Fprint(w, ")") } - fmt.Fprint(w, ")") } // specialFormatArgs formats argument list for some special functions. func (n *FuncCallExpr) specialFormatArgs(w io.Writer) bool { switch n.FnName.L { case DateAdd, DateSub, AddDate, SubDate: + fmt.Fprintf(w, "%s(", n.FnName.L) n.Args[0].Format(w) fmt.Fprint(w, ", INTERVAL ") n.Args[1].Format(w) fmt.Fprint(w, " ") n.Args[2].Format(w) + fmt.Fprint(w, ")") + return true + case JSONMemberOf: + n.Args[0].Format(w) + fmt.Fprint(w, " MEMBER OF ") + fmt.Fprint(w, " (") + n.Args[1].Format(w) + fmt.Fprint(w, ")") return true } return false diff --git a/parser/ast/misc.go b/parser/ast/misc.go index c7d23ddcfddac..453da4f6dc34a 100644 --- a/parser/ast/misc.go +++ b/parser/ast/misc.go @@ -98,6 +98,7 @@ type AuthOption struct { // ByAuthString set as true, if AuthString is used for authorization. Otherwise, authorization is done by HashString. ByAuthString bool AuthString string + ByHashString bool HashString string AuthPlugin string } @@ -112,7 +113,7 @@ func (n *AuthOption) Restore(ctx *format.RestoreCtx) error { if n.ByAuthString { ctx.WriteKeyWord(" BY ") ctx.WriteString(n.AuthString) - } else if n.HashString != "" { + } else if n.ByHashString { ctx.WriteKeyWord(" AS ") ctx.WriteString(n.HashString) } @@ -265,6 +266,12 @@ type PlanReplayerStmt struct { Stmt StmtNode Analyze bool Load bool + + // Capture indicates 'plan replayer capture ' + Capture bool + SQLDigest string + PlanDigest string + // File is used to store 2 cases: // 1. plan replayer load 'file'; // 2. plan replayer dump explain 'file' @@ -284,6 +291,13 @@ func (n *PlanReplayerStmt) Restore(ctx *format.RestoreCtx) error { ctx.WriteString(n.File) return nil } + if n.Capture { + ctx.WriteKeyWord("PLAN REPLAYER CAPTURE ") + ctx.WriteString(n.SQLDigest) + ctx.WriteKeyWord(" ") + ctx.WriteString(n.PlanDigest) + return nil + } ctx.WriteKeyWord("PLAN REPLAYER DUMP EXPLAIN ") if n.Analyze { ctx.WriteKeyWord("ANALYZE ") @@ -506,7 +520,6 @@ type Prepared struct { StmtType string Params []ParamMarkerExpr SchemaVersion int64 - UseCache bool CachedPlan interface{} CachedNames interface{} } @@ -937,6 +950,8 @@ type KillStmt struct { // So, "KILL TIDB" grammar is introduced, and it REQUIRES DIRECT client -> TiDB TOPOLOGY. // TODO: The standard KILL grammar will be supported once we have global connectionID. TiDBExtension bool + + Expr ExprNode } // Restore implements Node interface. @@ -948,7 +963,14 @@ func (n *KillStmt) Restore(ctx *format.RestoreCtx) error { if n.Query { ctx.WriteKeyWord(" QUERY") } - ctx.WritePlainf(" %d", n.ConnectionID) + if n.Expr != nil { + ctx.WriteKeyWord(" ") + if err := n.Expr.Restore(ctx); err != nil { + return errors.Trace(err) + } + } else { + ctx.WritePlainf(" %d", n.ConnectionID) + } return nil } @@ -1380,22 +1402,12 @@ func (n *UserSpec) EncodedPassword() (string, bool) { return opt.HashString, true } -const ( - TlsNone = iota - Ssl - X509 - Cipher - Issuer - Subject - SAN -) - -type TLSOption struct { - Type int +type AuthTokenOrTLSOption struct { + Type AuthTokenOrTLSOptionType Value string } -func (t *TLSOption) Restore(ctx *format.RestoreCtx) error { +func (t *AuthTokenOrTLSOption) Restore(ctx *format.RestoreCtx) error { switch t.Type { case TlsNone: ctx.WriteKeyWord("NONE") @@ -1415,12 +1427,51 @@ func (t *TLSOption) Restore(ctx *format.RestoreCtx) error { case SAN: ctx.WriteKeyWord("SAN ") ctx.WriteString(t.Value) + case TokenIssuer: + ctx.WriteKeyWord("TOKEN_ISSUER ") + ctx.WriteString(t.Value) default: - return errors.Errorf("Unsupported TLSOption.Type %d", t.Type) + return errors.Errorf("Unsupported AuthTokenOrTLSOption.Type %d", t.Type) } return nil } +type AuthTokenOrTLSOptionType int + +const ( + TlsNone AuthTokenOrTLSOptionType = iota + Ssl + X509 + Cipher + Issuer + Subject + SAN + TokenIssuer +) + +func (t AuthTokenOrTLSOptionType) String() string { + switch t { + case TlsNone: + return "NONE" + case Ssl: + return "SSL" + case X509: + return "X509" + case Cipher: + return "CIPHER" + case Issuer: + return "ISSUER" + case Subject: + return "SUBJECT" + case SAN: + return "SAN" + case TokenIssuer: + return "TOKEN_ISSUER" + default: + return "UNKNOWN" + } +} + const ( MaxQueriesPerHour = iota + 1 MaxUpdatesPerHour @@ -1455,8 +1506,19 @@ const ( PasswordExpireDefault PasswordExpireNever PasswordExpireInterval + PasswordHistory + PasswordHistoryDefault + PasswordReuseInterval + PasswordReuseDefault Lock Unlock + FailedLoginAttempts + PasswordLockTime + PasswordLockTimeUnbounded + UserCommentType + UserAttributeType + + UserResourceGroupName ) type PasswordOrLockOption struct { @@ -1480,23 +1542,73 @@ func (p *PasswordOrLockOption) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord("ACCOUNT LOCK") case Unlock: ctx.WriteKeyWord("ACCOUNT UNLOCK") + case FailedLoginAttempts: + ctx.WriteKeyWord("FAILED_LOGIN_ATTEMPTS") + ctx.WritePlainf(" %d", p.Count) + case PasswordLockTime: + ctx.WriteKeyWord("PASSWORD_LOCK_TIME") + ctx.WritePlainf(" %d", p.Count) + case PasswordLockTimeUnbounded: + ctx.WriteKeyWord("PASSWORD_LOCK_TIME UNBOUNDED") + case PasswordHistory: + ctx.WriteKeyWord("PASSWORD HISTORY") + ctx.WritePlainf(" %d", p.Count) + case PasswordHistoryDefault: + ctx.WriteKeyWord("PASSWORD HISTORY DEFAULT") + case PasswordReuseInterval: + ctx.WriteKeyWord("PASSWORD REUSE INTERVAL") + ctx.WritePlainf(" %d", p.Count) + ctx.WriteKeyWord(" DAY") + case PasswordReuseDefault: + ctx.WriteKeyWord("PASSWORD REUSE INTERVAL DEFAULT") default: return errors.Errorf("Unsupported PasswordOrLockOption.Type %d", p.Type) } return nil } +type CommentOrAttributeOption struct { + Type int + Value string +} + +func (c *CommentOrAttributeOption) Restore(ctx *format.RestoreCtx) error { + if c.Type == UserCommentType { + ctx.WriteKeyWord(" COMMENT ") + ctx.WriteString(c.Value) + } else if c.Type == UserAttributeType { + ctx.WriteKeyWord(" ATTRIBUTE ") + ctx.WriteString(c.Value) + } + return nil +} + +type ResourceGroupNameOption struct { + Type int + Value string +} + +func (c *ResourceGroupNameOption) Restore(ctx *format.RestoreCtx) error { + if c.Type == UserResourceGroupName { + ctx.WriteKeyWord(" RESOURCE GROUP ") + ctx.WriteName(c.Value) + } + return nil +} + // CreateUserStmt creates user account. -// See https://dev.mysql.com/doc/refman/5.7/en/create-user.html +// See https://dev.mysql.com/doc/refman/8.0/en/create-user.html type CreateUserStmt struct { stmtNode - IsCreateRole bool - IfNotExists bool - Specs []*UserSpec - TLSOptions []*TLSOption - ResourceOptions []*ResourceOption - PasswordOrLockOptions []*PasswordOrLockOption + IsCreateRole bool + IfNotExists bool + Specs []*UserSpec + AuthTokenOrTLSOptions []*AuthTokenOrTLSOption + ResourceOptions []*ResourceOption + PasswordOrLockOptions []*PasswordOrLockOption + CommentOrAttributeOption *CommentOrAttributeOption + ResourceGroupNameOption *ResourceGroupNameOption } // Restore implements Node interface. @@ -1518,16 +1630,16 @@ func (n *CreateUserStmt) Restore(ctx *format.RestoreCtx) error { } } - if len(n.TLSOptions) != 0 { + if len(n.AuthTokenOrTLSOptions) != 0 { ctx.WriteKeyWord(" REQUIRE ") } - for i, option := range n.TLSOptions { + for i, option := range n.AuthTokenOrTLSOptions { if i != 0 { ctx.WriteKeyWord(" AND ") } if err := option.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.TLSOptions[%d]", i) + return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.AuthTokenOrTLSOptions[%d]", i) } } @@ -1548,6 +1660,19 @@ func (n *CreateUserStmt) Restore(ctx *format.RestoreCtx) error { return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.PasswordOrLockOptions[%d]", i) } } + + if n.CommentOrAttributeOption != nil { + if err := n.CommentOrAttributeOption.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.CommentOrAttributeOption") + } + } + + if n.ResourceGroupNameOption != nil { + if err := n.ResourceGroupNameOption.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.ResourceGroupNameOption") + } + } + return nil } @@ -1573,16 +1698,18 @@ func (n *CreateUserStmt) SecureText() string { } // AlterUserStmt modifies user account. -// See https://dev.mysql.com/doc/refman/5.7/en/alter-user.html +// See https://dev.mysql.com/doc/refman/8.0/en/alter-user.html type AlterUserStmt struct { stmtNode - IfExists bool - CurrentAuth *AuthOption - Specs []*UserSpec - TLSOptions []*TLSOption - ResourceOptions []*ResourceOption - PasswordOrLockOptions []*PasswordOrLockOption + IfExists bool + CurrentAuth *AuthOption + Specs []*UserSpec + AuthTokenOrTLSOptions []*AuthTokenOrTLSOption + ResourceOptions []*ResourceOption + PasswordOrLockOptions []*PasswordOrLockOption + CommentOrAttributeOption *CommentOrAttributeOption + ResourceGroupNameOption *ResourceGroupNameOption } // Restore implements Node interface. @@ -1607,16 +1734,16 @@ func (n *AlterUserStmt) Restore(ctx *format.RestoreCtx) error { } } - if len(n.TLSOptions) != 0 { + if len(n.AuthTokenOrTLSOptions) != 0 { ctx.WriteKeyWord(" REQUIRE ") } - for i, option := range n.TLSOptions { + for i, option := range n.AuthTokenOrTLSOptions { if i != 0 { ctx.WriteKeyWord(" AND ") } if err := option.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.TLSOptions[%d]", i) + return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.AuthTokenOrTLSOptions[%d]", i) } } @@ -1637,6 +1764,19 @@ func (n *AlterUserStmt) Restore(ctx *format.RestoreCtx) error { return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.PasswordOrLockOptions[%d]", i) } } + + if n.CommentOrAttributeOption != nil { + if err := n.CommentOrAttributeOption.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.CommentOrAttributeOption") + } + } + + if n.ResourceGroupNameOption != nil { + if err := n.ResourceGroupNameOption.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.ResourceGroupNameOption") + } + } + return nil } @@ -1740,6 +1880,7 @@ type CreateBindingStmt struct { GlobalScope bool OriginNode StmtNode HintedNode StmtNode + PlanDigest string } func (n *CreateBindingStmt) Restore(ctx *format.RestoreCtx) error { @@ -1749,13 +1890,18 @@ func (n *CreateBindingStmt) Restore(ctx *format.RestoreCtx) error { } else { ctx.WriteKeyWord("SESSION ") } - ctx.WriteKeyWord("BINDING FOR ") - if err := n.OriginNode.Restore(ctx); err != nil { - return errors.Trace(err) - } - ctx.WriteKeyWord(" USING ") - if err := n.HintedNode.Restore(ctx); err != nil { - return errors.Trace(err) + if n.OriginNode == nil { + ctx.WriteKeyWord("BINDING FROM HISTORY USING PLAN DIGEST ") + ctx.WriteString(n.PlanDigest) + } else { + ctx.WriteKeyWord("BINDING FOR ") + if err := n.OriginNode.Restore(ctx); err != nil { + return errors.Trace(err) + } + ctx.WriteKeyWord(" USING ") + if err := n.HintedNode.Restore(ctx); err != nil { + return errors.Trace(err) + } } return nil } @@ -1766,16 +1912,18 @@ func (n *CreateBindingStmt) Accept(v Visitor) (Node, bool) { return v.Leave(newNode) } n = newNode.(*CreateBindingStmt) - origNode, ok := n.OriginNode.Accept(v) - if !ok { - return n, false - } - n.OriginNode = origNode.(StmtNode) - hintedNode, ok := n.HintedNode.Accept(v) - if !ok { - return n, false + if n.OriginNode != nil { + origNode, ok := n.OriginNode.Accept(v) + if !ok { + return n, false + } + n.OriginNode = origNode.(StmtNode) + hintedNode, ok := n.HintedNode.Accept(v) + if !ok { + return n, false + } + n.HintedNode = hintedNode.(StmtNode) } - n.HintedNode = hintedNode.(StmtNode) return v.Leave(n) } @@ -1786,6 +1934,7 @@ type DropBindingStmt struct { GlobalScope bool OriginNode StmtNode HintedNode StmtNode + SQLDigest string } func (n *DropBindingStmt) Restore(ctx *format.RestoreCtx) error { @@ -1796,14 +1945,19 @@ func (n *DropBindingStmt) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord("SESSION ") } ctx.WriteKeyWord("BINDING FOR ") - if err := n.OriginNode.Restore(ctx); err != nil { - return errors.Trace(err) - } - if n.HintedNode != nil { - ctx.WriteKeyWord(" USING ") - if err := n.HintedNode.Restore(ctx); err != nil { + if n.OriginNode == nil { + ctx.WriteKeyWord("SQL DIGEST ") + ctx.WriteString(n.SQLDigest) + } else { + if err := n.OriginNode.Restore(ctx); err != nil { return errors.Trace(err) } + if n.HintedNode != nil { + ctx.WriteKeyWord(" USING ") + if err := n.HintedNode.Restore(ctx); err != nil { + return errors.Trace(err) + } + } } return nil } @@ -1814,17 +1968,20 @@ func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) { return v.Leave(newNode) } n = newNode.(*DropBindingStmt) - origNode, ok := n.OriginNode.Accept(v) - if !ok { - return n, false - } - n.OriginNode = origNode.(StmtNode) - if n.HintedNode != nil { - hintedNode, ok := n.HintedNode.Accept(v) + if n.OriginNode != nil { + // OriginNode is nil means we build drop binding by sql digest + origNode, ok := n.OriginNode.Accept(v) if !ok { return n, false } - n.HintedNode = hintedNode.(StmtNode) + n.OriginNode = origNode.(StmtNode) + if n.HintedNode != nil { + hintedNode, ok := n.HintedNode.Accept(v) + if !ok { + return n, false + } + n.HintedNode = hintedNode.(StmtNode) + } } return v.Leave(n) } @@ -1845,6 +2002,7 @@ type SetBindingStmt struct { BindingStatusType BindingStatusType OriginNode StmtNode HintedNode StmtNode + SQLDigest string } func (n *SetBindingStmt) Restore(ctx *format.RestoreCtx) error { @@ -1857,14 +2015,19 @@ func (n *SetBindingStmt) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord("DISABLED ") } ctx.WriteKeyWord("FOR ") - if err := n.OriginNode.Restore(ctx); err != nil { - return errors.Trace(err) - } - if n.HintedNode != nil { - ctx.WriteKeyWord(" USING ") - if err := n.HintedNode.Restore(ctx); err != nil { + if n.OriginNode == nil { + ctx.WriteKeyWord("SQL DIGEST ") + ctx.WriteString(n.SQLDigest) + } else { + if err := n.OriginNode.Restore(ctx); err != nil { return errors.Trace(err) } + if n.HintedNode != nil { + ctx.WriteKeyWord(" USING ") + if err := n.HintedNode.Restore(ctx); err != nil { + return errors.Trace(err) + } + } } return nil } @@ -1875,17 +2038,20 @@ func (n *SetBindingStmt) Accept(v Visitor) (Node, bool) { return v.Leave(newNode) } n = newNode.(*SetBindingStmt) - origNode, ok := n.OriginNode.Accept(v) - if !ok { - return n, false - } - n.OriginNode = origNode.(StmtNode) - if n.HintedNode != nil { - hintedNode, ok := n.HintedNode.Accept(v) + if n.OriginNode != nil { + // OriginNode is nil means we set binding stmt by sql digest + origNode, ok := n.OriginNode.Accept(v) if !ok { return n, false } - n.HintedNode = hintedNode.(StmtNode) + n.OriginNode = origNode.(StmtNode) + if n.HintedNode != nil { + hintedNode, ok := n.HintedNode.Accept(v) + if !ok { + return n, false + } + n.HintedNode = hintedNode.(StmtNode) + } } return v.Leave(n) } @@ -2608,12 +2774,12 @@ func (n *RevokeRoleStmt) Accept(v Visitor) (Node, bool) { type GrantStmt struct { stmtNode - Privs []*PrivElem - ObjectType ObjectTypeType - Level *GrantLevel - Users []*UserSpec - TLSOptions []*TLSOption - WithGrant bool + Privs []*PrivElem + ObjectType ObjectTypeType + Level *GrantLevel + Users []*UserSpec + AuthTokenOrTLSOptions []*AuthTokenOrTLSOption + WithGrant bool } // Restore implements Node interface. @@ -2648,16 +2814,16 @@ func (n *GrantStmt) Restore(ctx *format.RestoreCtx) error { return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i) } } - if n.TLSOptions != nil { - if len(n.TLSOptions) != 0 { + if n.AuthTokenOrTLSOptions != nil { + if len(n.AuthTokenOrTLSOptions) != 0 { ctx.WriteKeyWord(" REQUIRE ") } - for i, option := range n.TLSOptions { + for i, option := range n.AuthTokenOrTLSOptions { if i != 0 { ctx.WriteKeyWord(" AND ") } if err := option.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore GrantStmt.TLSOptions[%d]", i) + return errors.Annotatef(err, "An error occurred while restore GrantStmt.AuthTokenOrTLSOptions[%d]", i) } } } @@ -3575,9 +3741,13 @@ func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error { } ctx.WriteName(n.QBName.String()) } + if n.HintName.L == "qb_name" && len(n.Tables) == 0 { + ctx.WritePlain(")") + return nil + } // Hints without args except query block. switch n.HintName.L { - case "hash_agg", "stream_agg", "agg_to_cop", "read_consistent_replica", "no_index_merge", "qb_name", "ignore_plan_cache", "limit_to_cop", "straight_join", "merge", "no_decorrelate": + case "mpp_1phase_agg", "mpp_2phase_agg", "hash_agg", "stream_agg", "agg_to_cop", "read_consistent_replica", "no_index_merge", "ignore_plan_cache", "limit_to_cop", "straight_join", "merge", "no_decorrelate": ctx.WritePlain(")") return nil } @@ -3590,14 +3760,14 @@ func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error { ctx.WritePlainf("%d", n.HintData.(uint64)) case "nth_plan": ctx.WritePlainf("%d", n.HintData.(int64)) - case "tidb_hj", "tidb_smj", "tidb_inlj", "hash_join", "hash_join_build", "hash_join_probe", "merge_join", "inl_join", "broadcast_join", "inl_hash_join", "inl_merge_join", "leading": + case "tidb_hj", "tidb_smj", "tidb_inlj", "hash_join", "hash_join_build", "hash_join_probe", "merge_join", "inl_join", "broadcast_join", "shuffle_join", "inl_hash_join", "inl_merge_join", "leading": for i, table := range n.Tables { if i != 0 { ctx.WritePlain(", ") } table.Restore(ctx) } - case "use_index", "ignore_index", "use_index_merge", "force_index": + case "use_index", "ignore_index", "use_index_merge", "force_index", "keep_order", "no_keep_order": n.Tables[0].Restore(ctx) ctx.WritePlain(" ") for i, index := range n.Indexes { @@ -3606,6 +3776,16 @@ func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error { } ctx.WriteName(index.String()) } + case "qb_name": + if len(n.Tables) > 0 { + ctx.WritePlain(", ") + for i, table := range n.Tables { + if i != 0 { + ctx.WritePlain(". ") + } + table.Restore(ctx) + } + } case "use_toja", "use_cascades": if n.HintData.(bool) { ctx.WritePlain("TRUE") @@ -3636,9 +3816,9 @@ func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error { ctx.WriteString(hintData.To) case "set_var": hintData := n.HintData.(HintSetVar) - ctx.WriteString(hintData.VarName) - ctx.WritePlain(", ") - ctx.WriteString(hintData.Value) + ctx.WritePlain(hintData.VarName) + ctx.WritePlain(" = ") + ctx.WritePlain(hintData.Value) } ctx.WritePlain(")") return nil diff --git a/parser/ast/misc_test.go b/parser/ast/misc_test.go index 5355d81ae266b..36e8cb1ef002f 100644 --- a/parser/ast/misc_test.go +++ b/parser/ast/misc_test.go @@ -75,7 +75,11 @@ func TestMiscVisitorCover(t *testing.T) { &ast.PrivElem{}, &ast.VariableAssignment{Value: valueExpr}, &ast.KillStmt{}, - &ast.DropStatsStmt{Table: &ast.TableName{}}, + &ast.DropStatsStmt{ + Tables: []*ast.TableName{ + {}, + }, + }, &ast.ShutdownStmt{}, } @@ -224,6 +228,18 @@ func TestTableOptimizerHintRestore(t *testing.T) { {"IGNORE_INDEX(@sel_1 t1 c1)", "IGNORE_INDEX(@`sel_1` `t1` `c1`)"}, {"IGNORE_INDEX(t1@sel_1 c1)", "IGNORE_INDEX(`t1`@`sel_1` `c1`)"}, {"IGNORE_INDEX(t1@sel_1 partition(p0, p1) c1)", "IGNORE_INDEX(`t1`@`sel_1` PARTITION(`p0`, `p1`) `c1`)"}, + {"KEEP_ORDER(t1 c1)", "KEEP_ORDER(`t1` `c1`)"}, + {"KEEP_ORDER(test.t1 c1)", "KEEP_ORDER(`test`.`t1` `c1`)"}, + {"KEEP_ORDER(@sel_1 t1 c1)", "KEEP_ORDER(@`sel_1` `t1` `c1`)"}, + {"KEEP_ORDER(t1@sel_1 c1)", "KEEP_ORDER(`t1`@`sel_1` `c1`)"}, + {"KEEP_ORDER(test.t1@sel_1 c1)", "KEEP_ORDER(`test`.`t1`@`sel_1` `c1`)"}, + {"KEEP_ORDER(test.t1@sel_1 partition(p0) c1)", "KEEP_ORDER(`test`.`t1`@`sel_1` PARTITION(`p0`) `c1`)"}, + {"NO_KEEP_ORDER(t1 c1)", "NO_KEEP_ORDER(`t1` `c1`)"}, + {"NO_KEEP_ORDER(test.t1 c1)", "NO_KEEP_ORDER(`test`.`t1` `c1`)"}, + {"NO_KEEP_ORDER(@sel_1 t1 c1)", "NO_KEEP_ORDER(@`sel_1` `t1` `c1`)"}, + {"NO_KEEP_ORDER(t1@sel_1 c1)", "NO_KEEP_ORDER(`t1`@`sel_1` `c1`)"}, + {"NO_KEEP_ORDER(test.t1@sel_1 c1)", "NO_KEEP_ORDER(`test`.`t1`@`sel_1` `c1`)"}, + {"NO_KEEP_ORDER(test.t1@sel_1 partition(p0) c1)", "NO_KEEP_ORDER(`test`.`t1`@`sel_1` PARTITION(`p0`) `c1`)"}, {"TIDB_SMJ(`t1`)", "TIDB_SMJ(`t1`)"}, {"TIDB_SMJ(t1)", "TIDB_SMJ(`t1`)"}, {"TIDB_SMJ(t1,t2)", "TIDB_SMJ(`t1`, `t2`)"}, diff --git a/parser/ast/stats.go b/parser/ast/stats.go index 55bb1f7abbdd8..f7e23a404cf0c 100644 --- a/parser/ast/stats.go +++ b/parser/ast/stats.go @@ -189,10 +189,11 @@ func (n *AnalyzeTableStmt) Accept(v Visitor) (Node, bool) { } // DropStatsStmt is used to drop table statistics. +// if the PartitionNames is not empty, or IsGlobalStats is true, it will contain exactly one table type DropStatsStmt struct { stmtNode - Table *TableName + Tables []*TableName PartitionNames []model.CIStr IsGlobalStats bool } @@ -200,8 +201,14 @@ type DropStatsStmt struct { // Restore implements Node interface. func (n *DropStatsStmt) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord("DROP STATS ") - if err := n.Table.Restore(ctx); err != nil { - return errors.Annotate(err, "An error occurred while add table") + + for index, table := range n.Tables { + if index != 0 { + ctx.WritePlain(", ") + } + if err := table.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore DropStatsStmt.Tables[%d]", index) + } } if n.IsGlobalStats { @@ -228,11 +235,13 @@ func (n *DropStatsStmt) Accept(v Visitor) (Node, bool) { return v.Leave(newNode) } n = newNode.(*DropStatsStmt) - node, ok := n.Table.Accept(v) - if !ok { - return n, false + for i, val := range n.Tables { + node, ok := val.Accept(v) + if !ok { + return n, false + } + n.Tables[i] = node.(*TableName) } - n.Table = node.(*TableName) return v.Leave(n) } @@ -259,3 +268,79 @@ func (n *LoadStatsStmt) Accept(v Visitor) (Node, bool) { n = newNode.(*LoadStatsStmt) return v.Leave(n) } + +// LockStatsStmt is the statement node for lock table statistic +type LockStatsStmt struct { + stmtNode + + Tables []*TableName +} + +// Restore implements Node interface. +func (n *LockStatsStmt) Restore(ctx *format.RestoreCtx) error { + ctx.WriteKeyWord("LOCK STATS ") + for index, table := range n.Tables { + if index != 0 { + ctx.WritePlain(", ") + } + if err := table.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore LockStatsStmt.Tables[%d]", index) + } + } + return nil +} + +// Accept implements Node Accept interface. +func (n *LockStatsStmt) Accept(v Visitor) (Node, bool) { + newNode, skipChildren := v.Enter(n) + if skipChildren { + return v.Leave(newNode) + } + n = newNode.(*LockStatsStmt) + for i, val := range n.Tables { + node, ok := val.Accept(v) + if !ok { + return n, false + } + n.Tables[i] = node.(*TableName) + } + return v.Leave(n) +} + +// UnlockStatsStmt is the statement node for unlock table statistic +type UnlockStatsStmt struct { + stmtNode + + Tables []*TableName +} + +// Restore implements Node interface. +func (n *UnlockStatsStmt) Restore(ctx *format.RestoreCtx) error { + ctx.WriteKeyWord("UNLOCK STATS ") + for index, table := range n.Tables { + if index != 0 { + ctx.WritePlain(", ") + } + if err := table.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore UnlockStatsStmt.Tables[%d]", index) + } + } + return nil +} + +// Accept implements Node Accept interface. +func (n *UnlockStatsStmt) Accept(v Visitor) (Node, bool) { + newNode, skipChildren := v.Enter(n) + if skipChildren { + return v.Leave(newNode) + } + n = newNode.(*UnlockStatsStmt) + for i, val := range n.Tables { + node, ok := val.Accept(v) + if !ok { + return n, false + } + n.Tables[i] = node.(*TableName) + } + return v.Leave(n) +} diff --git a/parser/auth/auth.go b/parser/auth/auth.go index 109fdda04b644..cb9abb883a33d 100644 --- a/parser/auth/auth.go +++ b/parser/auth/auth.go @@ -33,6 +33,7 @@ type UserIdentity struct { CurrentUser bool AuthUsername string // Username matched in privileges system AuthHostname string // Match in privs system (i.e. could be a wildcard) + AuthPlugin string // The plugin specified in handshake, only used during authentication. } // Restore implements Node interface. diff --git a/parser/consistent_test.go b/parser/consistent_test.go index e78b7f31ddddd..1acc1a58bc850 100644 --- a/parser/consistent_test.go +++ b/parser/consistent_test.go @@ -14,7 +14,7 @@ package parser import ( - "io/ioutil" + gio "io" "os" "sort" "strings" @@ -27,7 +27,7 @@ func TestKeywordConsistent(t *testing.T) { parserFilename := "parser.y" parserFile, err := os.Open(parserFilename) requires.NoError(t, err) - data, err := ioutil.ReadAll(parserFile) + data, err := gio.ReadAll(parserFile) requires.NoError(t, err) content := string(data) diff --git a/parser/duration/BUILD.bazel b/parser/duration/BUILD.bazel new file mode 100644 index 0000000000000..0e676c8d58566 --- /dev/null +++ b/parser/duration/BUILD.bazel @@ -0,0 +1,16 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "duration", + srcs = ["duration.go"], + importpath = "github.com/pingcap/tidb/parser/duration", + visibility = ["//visibility:public"], + deps = ["@com_github_pingcap_errors//:errors"], +) + +go_test( + name = "duration_test", + srcs = ["duration_test.go"], + embed = [":duration"], + deps = ["@com_github_stretchr_testify//require"], +) diff --git a/parser/duration/duration.go b/parser/duration/duration.go new file mode 100644 index 0000000000000..6eb13111b0424 --- /dev/null +++ b/parser/duration/duration.go @@ -0,0 +1,73 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package duration provides a customized duration, which supports unit 'd', 'h' and 'm' +package duration + +import ( + "strconv" + "time" + "unicode" + + "github.com/pingcap/errors" +) + +func readFloat(s string) (float64, string, error) { + numbers := "" + for pos, ch := range s { + if !unicode.IsDigit(ch) && ch != '.' { + numbers = s[:pos] + break + } + } + if len(numbers) > 0 { + i, err := strconv.ParseFloat(numbers, 64) + if err != nil { + return 0, s, err + } + return i, s[len(numbers):], nil + } + return 0, s, errors.New("fail to read an integer") +} + +// ParseDuration parses the duration which contains 'd', 'h' and 'm' +func ParseDuration(s string) (time.Duration, error) { + duration := time.Duration(0) + + if s == "0" { + return 0, nil + } + + var err error + var i float64 + for len(s) > 0 { + i, s, err = readFloat(s) + if err != nil { + return 0, err + } + switch s[0] { + case 'd': + duration += time.Duration(i * float64(time.Hour*24)) + case 'h': + duration += time.Duration(i * float64(time.Hour)) + case 'm': + duration += time.Duration(i * float64(time.Minute)) + default: + return 0, errors.Errorf("unknown unit %c", s[0]) + } + + s = s[1:] + } + + return duration, nil +} diff --git a/parser/duration/duration_test.go b/parser/duration/duration_test.go new file mode 100644 index 0000000000000..4a1555db69e41 --- /dev/null +++ b/parser/duration/duration_test.go @@ -0,0 +1,65 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package duration + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestParseDuration(t *testing.T) { + cases := []struct { + str string + duration time.Duration + }{ + { + "1h", + time.Hour, + }, + { + "1h100m", + time.Hour + 100*time.Minute, + }, + { + "1d10000m", + 24*time.Hour + 10000*time.Minute, + }, + { + "1d100h", + 24*time.Hour + 100*time.Hour, + }, + { + "1.5d", + 36 * time.Hour, + }, + { + "1d1.5h", + 24*time.Hour + time.Hour + 30*time.Minute, + }, + { + "1d3.555h", + 24*time.Hour + time.Duration(3.555*float64(time.Hour)), + }, + } + + for _, c := range cases { + t.Run(c.str, func(t *testing.T) { + d, err := ParseDuration(c.str) + require.NoError(t, err) + require.Equal(t, c.duration, d) + }) + } +} diff --git a/parser/format/format.go b/parser/format/format.go index adada122e255e..a60c8d7b6589d 100644 --- a/parser/format/format.go +++ b/parser/format/format.go @@ -235,6 +235,9 @@ const ( RestoreTiDBSpecialComment SkipPlacementRuleForRestore + RestoreWithTTLEnableOff + RestoreWithoutSchemaName + RestoreWithoutTableName ) const ( @@ -246,6 +249,16 @@ func (rf RestoreFlags) has(flag RestoreFlags) bool { return rf&flag != 0 } +// HasWithoutSchemaNameFlag returns a boolean indicating when `rf` has `RestoreWithoutSchemaName` flag. +func (rf RestoreFlags) HasWithoutSchemaNameFlag() bool { + return rf.has(RestoreWithoutSchemaName) +} + +// HasWithoutTableNameFlag returns a boolean indicating when `rf` has `RestoreWithoutTableName` flag. +func (rf RestoreFlags) HasWithoutTableNameFlag() bool { + return rf.has(RestoreWithoutTableName) +} + // HasStringSingleQuotesFlag returns a boolean indicating when `rf` has `RestoreStringSingleQuotes` flag. func (rf RestoreFlags) HasStringSingleQuotesFlag() bool { return rf.has(RestoreStringSingleQuotes) @@ -321,6 +334,11 @@ func (rf RestoreFlags) HasSkipPlacementRuleForRestoreFlag() bool { return rf.has(SkipPlacementRuleForRestore) } +// HasRestoreWithTTLEnableOff returns a boolean indicating whether to force set TTL_ENABLE='OFF' when restoring a TTL table +func (rf RestoreFlags) HasRestoreWithTTLEnableOff() bool { + return rf.has(RestoreWithTTLEnableOff) +} + // RestoreCtx is `Restore` context to hold flags and writer. type RestoreCtx struct { Flags RestoreFlags diff --git a/parser/format/format_test.go b/parser/format/format_test.go index 429c2c27c19d1..bc04033214cdd 100644 --- a/parser/format/format_test.go +++ b/parser/format/format_test.go @@ -15,7 +15,7 @@ package format import ( "bytes" - "io/ioutil" + "io" "strings" "testing" @@ -26,7 +26,7 @@ import ( func checkFormat(t *testing.T, f Formatter, buf *bytes.Buffer, str, expect string) { _, err := f.Format(str, 3) require.NoError(t, err) - b, err := ioutil.ReadAll(buf) + b, err := io.ReadAll(buf) require.NoError(t, err) require.Equal(t, expect, string(b)) } diff --git a/parser/hintparser.go b/parser/hintparser.go index 6b7b5819d5bf8..a619d2a1c74f2 100644 --- a/parser/hintparser.go +++ b/parser/hintparser.go @@ -41,209 +41,221 @@ type yyhintXError struct { } const ( - yyhintDefault = 57421 + yyhintDefault = 57426 yyhintEOFCode = 57344 yyhintErrCode = 57345 hintAggToCop = 57379 - hintBCJoin = 57392 + hintBCJoin = 57394 hintBKA = 57355 hintBNL = 57357 - hintDupsWeedOut = 57417 - hintFalse = 57413 - hintFirstMatch = 57418 - hintForceIndex = 57403 - hintGB = 57416 + hintDupsWeedOut = 57422 + hintFalse = 57418 + hintFirstMatch = 57423 + hintForceIndex = 57408 + hintGB = 57421 hintHashAgg = 57381 hintHashJoin = 57359 hintHashJoinBuild = 57360 hintHashJoinProbe = 57361 hintIdentifier = 57347 - hintIgnoreIndex = 57382 + hintIgnoreIndex = 57384 hintIgnorePlanCache = 57380 hintIndexMerge = 57365 - hintInlHashJoin = 57383 - hintInlJoin = 57384 - hintInlMergeJoin = 57385 + hintInlHashJoin = 57385 + hintInlJoin = 57386 + hintInlMergeJoin = 57387 hintIntLit = 57346 hintInvalid = 57348 hintJoinFixedOrder = 57351 hintJoinOrder = 57352 hintJoinPrefix = 57353 hintJoinSuffix = 57354 - hintLeading = 57405 - hintLimitToCop = 57402 - hintLooseScan = 57419 - hintMB = 57415 + hintKeepOrder = 57400 + hintLeading = 57410 + hintLimitToCop = 57407 + hintLooseScan = 57424 + hintMB = 57420 hintMRR = 57367 - hintMaterialization = 57420 + hintMaterialization = 57425 hintMaxExecutionTime = 57375 - hintMemoryQuota = 57386 + hintMemoryQuota = 57388 hintMerge = 57363 + hintMpp1PhaseAgg = 57382 + hintMpp2PhaseAgg = 57383 hintNoBKA = 57356 hintNoBNL = 57358 - hintNoDecorrelate = 57407 + hintNoDecorrelate = 57412 hintNoHashJoin = 57362 hintNoICP = 57369 hintNoIndexMerge = 57366 + hintNoKeepOrder = 57401 hintNoMRR = 57368 hintNoMerge = 57364 hintNoRangeOptimization = 57370 hintNoSemijoin = 57374 hintNoSkipScan = 57372 - hintNoSwapJoinInputs = 57387 - hintNthPlan = 57401 - hintOLAP = 57408 - hintOLTP = 57409 - hintPartition = 57410 + hintNoSwapJoinInputs = 57389 + hintNthPlan = 57406 + hintOLAP = 57413 + hintOLTP = 57414 + hintPartition = 57415 hintQBName = 57378 - hintQueryType = 57388 - hintReadConsistentReplica = 57389 - hintReadFromStorage = 57390 + hintQueryType = 57390 + hintReadConsistentReplica = 57391 + hintReadFromStorage = 57392 hintResourceGroup = 57377 - hintSMJoin = 57391 - hintSemiJoinRewrite = 57406 + hintSMJoin = 57393 + hintSemiJoinRewrite = 57411 hintSemijoin = 57373 hintSetVar = 57376 + hintShuffleJoin = 57395 hintSingleAtIdentifier = 57349 hintSkipScan = 57371 - hintStraightJoin = 57404 - hintStreamAgg = 57393 + hintStraightJoin = 57409 + hintStreamAgg = 57396 hintStringLit = 57350 - hintSwapJoinInputs = 57394 - hintTiFlash = 57412 - hintTiKV = 57411 - hintTimeRange = 57399 - hintTrue = 57414 - hintUseCascades = 57400 - hintUseIndex = 57396 - hintUseIndexMerge = 57395 - hintUsePlanCache = 57397 - hintUseToja = 57398 + hintSwapJoinInputs = 57397 + hintTiFlash = 57417 + hintTiKV = 57416 + hintTimeRange = 57404 + hintTrue = 57419 + hintUseCascades = 57405 + hintUseIndex = 57399 + hintUseIndexMerge = 57398 + hintUsePlanCache = 57402 + hintUseToja = 57403 yyhintMaxDepth = 200 - yyhintTabOfs = -182 + yyhintTabOfs = -197 ) var ( yyhintXLAT = map[int]int{ - 41: 0, // ')' (135x) - 57379: 1, // hintAggToCop (127x) - 57392: 2, // hintBCJoin (127x) - 57355: 3, // hintBKA (127x) - 57357: 4, // hintBNL (127x) - 57403: 5, // hintForceIndex (127x) - 57381: 6, // hintHashAgg (127x) - 57359: 7, // hintHashJoin (127x) - 57360: 8, // hintHashJoinBuild (127x) - 57361: 9, // hintHashJoinProbe (127x) - 57382: 10, // hintIgnoreIndex (127x) - 57380: 11, // hintIgnorePlanCache (127x) - 57365: 12, // hintIndexMerge (127x) - 57383: 13, // hintInlHashJoin (127x) - 57384: 14, // hintInlJoin (127x) - 57385: 15, // hintInlMergeJoin (127x) - 57351: 16, // hintJoinFixedOrder (127x) - 57352: 17, // hintJoinOrder (127x) - 57353: 18, // hintJoinPrefix (127x) - 57354: 19, // hintJoinSuffix (127x) - 57405: 20, // hintLeading (127x) - 57402: 21, // hintLimitToCop (127x) - 57375: 22, // hintMaxExecutionTime (127x) - 57386: 23, // hintMemoryQuota (127x) - 57363: 24, // hintMerge (127x) - 57367: 25, // hintMRR (127x) - 57356: 26, // hintNoBKA (127x) - 57358: 27, // hintNoBNL (127x) - 57407: 28, // hintNoDecorrelate (127x) - 57362: 29, // hintNoHashJoin (127x) - 57369: 30, // hintNoICP (127x) - 57366: 31, // hintNoIndexMerge (127x) - 57364: 32, // hintNoMerge (127x) - 57368: 33, // hintNoMRR (127x) - 57370: 34, // hintNoRangeOptimization (127x) - 57374: 35, // hintNoSemijoin (127x) - 57372: 36, // hintNoSkipScan (127x) - 57387: 37, // hintNoSwapJoinInputs (127x) - 57401: 38, // hintNthPlan (127x) - 57378: 39, // hintQBName (127x) - 57388: 40, // hintQueryType (127x) - 57389: 41, // hintReadConsistentReplica (127x) - 57390: 42, // hintReadFromStorage (127x) - 57377: 43, // hintResourceGroup (127x) - 57373: 44, // hintSemijoin (127x) - 57406: 45, // hintSemiJoinRewrite (127x) - 57376: 46, // hintSetVar (127x) - 57371: 47, // hintSkipScan (127x) - 57391: 48, // hintSMJoin (127x) - 57404: 49, // hintStraightJoin (127x) - 57393: 50, // hintStreamAgg (127x) - 57394: 51, // hintSwapJoinInputs (127x) - 57399: 52, // hintTimeRange (127x) - 57400: 53, // hintUseCascades (127x) - 57396: 54, // hintUseIndex (127x) - 57395: 55, // hintUseIndexMerge (127x) - 57397: 56, // hintUsePlanCache (127x) - 57398: 57, // hintUseToja (127x) - 44: 58, // ',' (125x) - 57417: 59, // hintDupsWeedOut (105x) - 57418: 60, // hintFirstMatch (105x) - 57419: 61, // hintLooseScan (105x) - 57420: 62, // hintMaterialization (105x) - 57412: 63, // hintTiFlash (105x) - 57411: 64, // hintTiKV (105x) - 57413: 65, // hintFalse (104x) - 57408: 66, // hintOLAP (104x) - 57409: 67, // hintOLTP (104x) - 57414: 68, // hintTrue (104x) - 57416: 69, // hintGB (103x) - 57415: 70, // hintMB (103x) - 57347: 71, // hintIdentifier (102x) - 57349: 72, // hintSingleAtIdentifier (87x) - 93: 73, // ']' (81x) - 57410: 74, // hintPartition (75x) - 46: 75, // '.' (71x) - 61: 76, // '=' (71x) - 40: 77, // '(' (66x) - 57344: 78, // $end (24x) - 57441: 79, // QueryBlockOpt (17x) - 57433: 80, // Identifier (13x) - 57346: 81, // hintIntLit (8x) - 57350: 82, // hintStringLit (5x) - 57423: 83, // CommaOpt (4x) - 57429: 84, // HintTable (4x) - 57430: 85, // HintTableList (4x) - 91: 86, // '[' (3x) - 57422: 87, // BooleanHintName (2x) - 57424: 88, // HintIndexList (2x) - 57426: 89, // HintStorageType (2x) - 57427: 90, // HintStorageTypeAndTable (2x) - 57431: 91, // HintTableListOpt (2x) - 57436: 92, // JoinOrderOptimizerHintName (2x) - 57437: 93, // NullaryHintName (2x) - 57440: 94, // PartitionListOpt (2x) - 57443: 95, // StorageOptimizerHintOpt (2x) - 57444: 96, // SubqueryOptimizerHintName (2x) - 57447: 97, // SubqueryStrategy (2x) - 57448: 98, // SupportedIndexLevelOptimizerHintName (2x) - 57449: 99, // SupportedTableLevelOptimizerHintName (2x) - 57450: 100, // TableOptimizerHintOpt (2x) - 57452: 101, // UnsupportedIndexLevelOptimizerHintName (2x) - 57453: 102, // UnsupportedTableLevelOptimizerHintName (2x) - 57425: 103, // HintQueryType (1x) - 57428: 104, // HintStorageTypeAndTableList (1x) - 57432: 105, // HintTrueOrFalse (1x) - 57434: 106, // IndexNameList (1x) - 57435: 107, // IndexNameListOpt (1x) - 57438: 108, // OptimizerHintList (1x) - 57439: 109, // PartitionList (1x) - 57442: 110, // Start (1x) - 57445: 111, // SubqueryStrategies (1x) - 57446: 112, // SubqueryStrategiesOpt (1x) - 57451: 113, // UnitOfBytes (1x) - 57454: 114, // Value (1x) - 57421: 115, // $default (0x) - 57345: 116, // error (0x) - 57348: 117, // hintInvalid (0x) + 41: 0, // ')' (148x) + 57379: 1, // hintAggToCop (135x) + 57394: 2, // hintBCJoin (135x) + 57355: 3, // hintBKA (135x) + 57357: 4, // hintBNL (135x) + 57408: 5, // hintForceIndex (135x) + 57381: 6, // hintHashAgg (135x) + 57359: 7, // hintHashJoin (135x) + 57360: 8, // hintHashJoinBuild (135x) + 57361: 9, // hintHashJoinProbe (135x) + 57384: 10, // hintIgnoreIndex (135x) + 57380: 11, // hintIgnorePlanCache (135x) + 57365: 12, // hintIndexMerge (135x) + 57385: 13, // hintInlHashJoin (135x) + 57386: 14, // hintInlJoin (135x) + 57387: 15, // hintInlMergeJoin (135x) + 57351: 16, // hintJoinFixedOrder (135x) + 57352: 17, // hintJoinOrder (135x) + 57353: 18, // hintJoinPrefix (135x) + 57354: 19, // hintJoinSuffix (135x) + 57400: 20, // hintKeepOrder (135x) + 57410: 21, // hintLeading (135x) + 57407: 22, // hintLimitToCop (135x) + 57375: 23, // hintMaxExecutionTime (135x) + 57388: 24, // hintMemoryQuota (135x) + 57363: 25, // hintMerge (135x) + 57382: 26, // hintMpp1PhaseAgg (135x) + 57383: 27, // hintMpp2PhaseAgg (135x) + 57367: 28, // hintMRR (135x) + 57356: 29, // hintNoBKA (135x) + 57358: 30, // hintNoBNL (135x) + 57412: 31, // hintNoDecorrelate (135x) + 57362: 32, // hintNoHashJoin (135x) + 57369: 33, // hintNoICP (135x) + 57366: 34, // hintNoIndexMerge (135x) + 57401: 35, // hintNoKeepOrder (135x) + 57364: 36, // hintNoMerge (135x) + 57368: 37, // hintNoMRR (135x) + 57370: 38, // hintNoRangeOptimization (135x) + 57374: 39, // hintNoSemijoin (135x) + 57372: 40, // hintNoSkipScan (135x) + 57389: 41, // hintNoSwapJoinInputs (135x) + 57406: 42, // hintNthPlan (135x) + 57378: 43, // hintQBName (135x) + 57390: 44, // hintQueryType (135x) + 57391: 45, // hintReadConsistentReplica (135x) + 57392: 46, // hintReadFromStorage (135x) + 57377: 47, // hintResourceGroup (135x) + 57373: 48, // hintSemijoin (135x) + 57411: 49, // hintSemiJoinRewrite (135x) + 57376: 50, // hintSetVar (135x) + 57395: 51, // hintShuffleJoin (135x) + 57371: 52, // hintSkipScan (135x) + 57393: 53, // hintSMJoin (135x) + 57409: 54, // hintStraightJoin (135x) + 57396: 55, // hintStreamAgg (135x) + 57397: 56, // hintSwapJoinInputs (135x) + 57404: 57, // hintTimeRange (135x) + 57405: 58, // hintUseCascades (135x) + 57399: 59, // hintUseIndex (135x) + 57398: 60, // hintUseIndexMerge (135x) + 57402: 61, // hintUsePlanCache (135x) + 57403: 62, // hintUseToja (135x) + 44: 63, // ',' (132x) + 57422: 64, // hintDupsWeedOut (112x) + 57423: 65, // hintFirstMatch (112x) + 57424: 66, // hintLooseScan (112x) + 57425: 67, // hintMaterialization (112x) + 57417: 68, // hintTiFlash (112x) + 57416: 69, // hintTiKV (112x) + 57418: 70, // hintFalse (111x) + 57413: 71, // hintOLAP (111x) + 57414: 72, // hintOLTP (111x) + 57419: 73, // hintTrue (111x) + 57421: 74, // hintGB (110x) + 57420: 75, // hintMB (110x) + 57347: 76, // hintIdentifier (109x) + 57349: 77, // hintSingleAtIdentifier (95x) + 93: 78, // ']' (86x) + 46: 79, // '.' (85x) + 57415: 80, // hintPartition (80x) + 61: 81, // '=' (76x) + 40: 82, // '(' (71x) + 57344: 83, // $end (25x) + 57446: 84, // QueryBlockOpt (20x) + 57438: 85, // Identifier (15x) + 57346: 86, // hintIntLit (8x) + 57350: 87, // hintStringLit (5x) + 57428: 88, // CommaOpt (4x) + 57434: 89, // HintTable (4x) + 57435: 90, // HintTableList (4x) + 91: 91, // '[' (3x) + 57427: 92, // BooleanHintName (2x) + 57429: 93, // HintIndexList (2x) + 57431: 94, // HintStorageType (2x) + 57432: 95, // HintStorageTypeAndTable (2x) + 57436: 96, // HintTableListOpt (2x) + 57441: 97, // JoinOrderOptimizerHintName (2x) + 57442: 98, // NullaryHintName (2x) + 57445: 99, // PartitionListOpt (2x) + 57448: 100, // StorageOptimizerHintOpt (2x) + 57449: 101, // SubqueryOptimizerHintName (2x) + 57452: 102, // SubqueryStrategy (2x) + 57453: 103, // SupportedIndexLevelOptimizerHintName (2x) + 57454: 104, // SupportedTableLevelOptimizerHintName (2x) + 57455: 105, // TableOptimizerHintOpt (2x) + 57457: 106, // UnsupportedIndexLevelOptimizerHintName (2x) + 57458: 107, // UnsupportedTableLevelOptimizerHintName (2x) + 57460: 108, // ViewName (2x) + 57430: 109, // HintQueryType (1x) + 57433: 110, // HintStorageTypeAndTableList (1x) + 57437: 111, // HintTrueOrFalse (1x) + 57439: 112, // IndexNameList (1x) + 57440: 113, // IndexNameListOpt (1x) + 57443: 114, // OptimizerHintList (1x) + 57444: 115, // PartitionList (1x) + 57447: 116, // Start (1x) + 57450: 117, // SubqueryStrategies (1x) + 57451: 118, // SubqueryStrategiesOpt (1x) + 57456: 119, // UnitOfBytes (1x) + 57459: 120, // Value (1x) + 57461: 121, // ViewNameList (1x) + 57426: 122, // $default (0x) + 57345: 123, // error (0x) + 57348: 124, // hintInvalid (0x) } yyhintSymNames = []string{ @@ -267,11 +279,14 @@ var ( "hintJoinOrder", "hintJoinPrefix", "hintJoinSuffix", + "hintKeepOrder", "hintLeading", "hintLimitToCop", "hintMaxExecutionTime", "hintMemoryQuota", "hintMerge", + "hintMpp1PhaseAgg", + "hintMpp2PhaseAgg", "hintMRR", "hintNoBKA", "hintNoBNL", @@ -279,6 +294,7 @@ var ( "hintNoHashJoin", "hintNoICP", "hintNoIndexMerge", + "hintNoKeepOrder", "hintNoMerge", "hintNoMRR", "hintNoRangeOptimization", @@ -294,6 +310,7 @@ var ( "hintSemijoin", "hintSemiJoinRewrite", "hintSetVar", + "hintShuffleJoin", "hintSkipScan", "hintSMJoin", "hintStraightJoin", @@ -321,8 +338,8 @@ var ( "hintIdentifier", "hintSingleAtIdentifier", "']'", - "hintPartition", "'.'", + "hintPartition", "'='", "'('", "$end", @@ -350,6 +367,7 @@ var ( "TableOptimizerHintOpt", "UnsupportedIndexLevelOptimizerHintName", "UnsupportedTableLevelOptimizerHintName", + "ViewName", "HintQueryType", "HintStorageTypeAndTableList", "HintTrueOrFalse", @@ -362,6 +380,7 @@ var ( "SubqueryStrategiesOpt", "UnitOfBytes", "Value", + "ViewNameList", "$default", "error", "hintInvalid", @@ -369,510 +388,548 @@ var ( yyhintReductions = []struct{ xsym, components int }{ {0, 1}, + {116, 1}, + {114, 1}, + {114, 3}, + {114, 1}, + {114, 3}, + {105, 4}, + {105, 4}, + {105, 4}, + {105, 4}, + {105, 4}, + {105, 4}, + {105, 5}, + {105, 5}, + {105, 5}, + {105, 6}, + {105, 4}, + {105, 4}, + {105, 6}, + {105, 6}, + {105, 6}, + {105, 5}, + {105, 4}, + {105, 5}, + {100, 5}, {110, 1}, + {110, 3}, + {95, 4}, + {84, 0}, + {84, 1}, + {88, 0}, + {88, 1}, + {99, 0}, + {99, 4}, + {115, 1}, + {115, 3}, + {96, 1}, + {96, 1}, + {90, 2}, + {90, 3}, + {89, 3}, + {89, 5}, + {121, 3}, + {121, 1}, + {108, 2}, {108, 1}, - {108, 3}, - {108, 1}, - {108, 3}, - {100, 4}, - {100, 4}, - {100, 4}, - {100, 4}, - {100, 4}, - {100, 4}, - {100, 5}, - {100, 5}, - {100, 5}, - {100, 6}, - {100, 4}, - {100, 4}, - {100, 6}, - {100, 6}, - {100, 5}, - {100, 4}, - {100, 5}, - {95, 5}, - {104, 1}, - {104, 3}, - {90, 4}, - {79, 0}, - {79, 1}, - {83, 0}, - {83, 1}, - {94, 0}, - {94, 4}, - {109, 1}, - {109, 3}, - {91, 1}, - {91, 1}, - {85, 2}, - {85, 3}, - {84, 3}, - {84, 5}, - {88, 4}, - {107, 0}, - {107, 1}, - {106, 1}, - {106, 3}, - {112, 0}, + {93, 4}, + {113, 0}, + {113, 1}, {112, 1}, + {112, 3}, + {118, 0}, + {118, 1}, + {117, 1}, + {117, 3}, + {120, 1}, + {120, 1}, + {120, 1}, + {119, 1}, + {119, 1}, {111, 1}, - {111, 3}, - {114, 1}, - {114, 1}, - {114, 1}, - {113, 1}, - {113, 1}, - {105, 1}, - {105, 1}, - {92, 1}, - {92, 1}, - {92, 1}, - {102, 1}, - {102, 1}, + {111, 1}, + {97, 1}, + {97, 1}, + {97, 1}, + {107, 1}, + {107, 1}, + {107, 1}, + {107, 1}, + {107, 1}, + {107, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {104, 1}, + {106, 1}, + {106, 1}, + {106, 1}, + {106, 1}, + {106, 1}, + {106, 1}, + {106, 1}, + {103, 1}, + {103, 1}, + {103, 1}, + {103, 1}, + {103, 1}, + {103, 1}, + {101, 1}, + {101, 1}, {102, 1}, {102, 1}, {102, 1}, {102, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {99, 1}, - {101, 1}, - {101, 1}, - {101, 1}, - {101, 1}, - {101, 1}, - {101, 1}, - {101, 1}, + {92, 1}, + {92, 1}, {98, 1}, {98, 1}, {98, 1}, {98, 1}, - {96, 1}, - {96, 1}, - {97, 1}, - {97, 1}, - {97, 1}, - {97, 1}, - {87, 1}, - {87, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {93, 1}, - {103, 1}, - {103, 1}, - {89, 1}, - {89, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, - {80, 1}, + {98, 1}, + {98, 1}, + {98, 1}, + {98, 1}, + {98, 1}, + {98, 1}, + {98, 1}, + {98, 1}, + {98, 1}, + {109, 1}, + {109, 1}, + {94, 1}, + {94, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, + {85, 1}, } yyhintXErrors = map[yyhintXError]string{} - yyhintParseTab = [265][]uint16{ + yyhintParseTab = [284][]uint16{ // 0 - {1: 244, 215, 208, 210, 236, 242, 222, 223, 224, 234, 248, 226, 218, 216, 221, 187, 205, 206, 207, 225, 245, 194, 199, 217, 227, 209, 211, 251, 212, 229, 246, 213, 228, 230, 238, 232, 220, 195, 198, 203, 247, 204, 197, 237, 250, 196, 231, 214, 249, 243, 219, 200, 240, 233, 235, 241, 239, 87: 201, 92: 188, 202, 95: 186, 193, 98: 192, 190, 185, 191, 189, 108: 184, 110: 183}, - {78: 182}, - {1: 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 344, 78: 181, 83: 444}, - {1: 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 78: 180}, - {1: 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 78: 178}, + {1: 264, 230, 223, 225, 252, 260, 238, 239, 240, 250, 268, 242, 234, 232, 237, 202, 220, 221, 222, 253, 241, 265, 209, 214, 233, 261, 262, 243, 224, 226, 271, 227, 245, 266, 254, 228, 244, 246, 256, 248, 236, 210, 213, 218, 267, 219, 212, 255, 270, 211, 231, 247, 229, 269, 263, 235, 215, 258, 249, 251, 259, 257, 92: 216, 97: 203, 217, 100: 201, 208, 103: 207, 205, 200, 206, 204, 114: 199, 116: 198}, + {83: 197}, + {1: 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 369, 83: 196, 88: 478}, + {1: 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 83: 195}, + {1: 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 83: 193}, // 5 - {77: 441}, - {77: 438}, - {77: 435}, - {77: 430}, - {77: 427}, + {82: 475}, + {82: 472}, + {82: 469}, + {82: 464}, + {82: 461}, // 10 - {77: 416}, - {77: 404}, - {77: 400}, - {77: 396}, - {77: 388}, + {82: 450}, + {82: 438}, + {82: 434}, + {82: 430}, + {82: 422}, // 15 - {77: 385}, - {77: 382}, - {77: 375}, - {77: 370}, - {77: 364}, + {82: 419}, + {82: 407}, + {82: 400}, + {82: 395}, + {82: 389}, // 20 - {77: 361}, - {77: 355}, - {77: 252}, - {77: 125}, - {77: 124}, + {82: 386}, + {82: 380}, + {82: 272}, + {82: 135}, + {82: 134}, // 25 - {77: 123}, - {77: 122}, - {77: 121}, - {77: 120}, - {77: 119}, + {82: 133}, + {82: 132}, + {82: 131}, + {82: 130}, + {82: 129}, // 30 - {77: 118}, - {77: 117}, - {77: 116}, - {77: 115}, - {77: 114}, + {82: 128}, + {82: 127}, + {82: 126}, + {82: 125}, + {82: 124}, // 35 - {77: 113}, - {77: 112}, - {77: 111}, - {77: 110}, - {77: 109}, + {82: 123}, + {82: 122}, + {82: 121}, + {82: 120}, + {82: 119}, // 40 - {77: 108}, - {77: 107}, - {77: 106}, - {77: 105}, - {77: 104}, + {82: 118}, + {82: 117}, + {82: 116}, + {82: 115}, + {82: 114}, // 45 - {77: 103}, - {77: 102}, - {77: 101}, - {77: 100}, - {77: 99}, + {82: 113}, + {82: 112}, + {82: 111}, + {82: 110}, + {82: 109}, // 50 - {77: 98}, - {77: 97}, - {77: 96}, - {77: 95}, - {77: 94}, + {82: 108}, + {82: 107}, + {82: 106}, + {82: 105}, + {82: 104}, // 55 - {77: 93}, - {77: 92}, - {77: 87}, - {77: 86}, - {77: 85}, + {82: 103}, + {82: 102}, + {82: 101}, + {82: 100}, + {82: 99}, // 60 - {77: 84}, - {77: 83}, - {77: 82}, - {77: 81}, - {77: 80}, + {82: 94}, + {82: 93}, + {82: 92}, + {82: 91}, + {82: 90}, // 65 - {77: 79}, - {77: 78}, - {77: 77}, - {77: 76}, - {77: 75}, + {82: 89}, + {82: 88}, + {82: 87}, + {82: 86}, + {82: 85}, // 70 - {63: 155, 155, 72: 254, 79: 253}, - {63: 259, 258, 89: 257, 256, 104: 255}, - {154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 73: 154, 154, 81: 154}, - {352, 58: 353}, - {158, 58: 158}, + {82: 84}, + {82: 83}, + {82: 82}, + {82: 81}, + {82: 80}, // 75 - {86: 260}, - {86: 72}, - {86: 71}, - {1: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 59: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 79: 262, 85: 261}, - {58: 350, 73: 349}, + {68: 169, 169, 77: 274, 84: 273}, + {68: 279, 278, 94: 277, 276, 110: 275}, + {168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 78: 168, 168, 168, 86: 168}, + {377, 63: 378}, + {172, 63: 172}, // 80 - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 264, 84: 263}, - {145, 58: 145, 73: 145}, - {155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 155, 155, 336, 79: 335}, - {70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70}, - {69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69}, + {91: 280}, + {91: 77}, + {91: 76}, + {1: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 64: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 84: 282, 90: 281}, + {63: 375, 78: 374}, // 85 - {68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68}, - {67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67}, - {66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66}, - {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65}, - {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 284, 89: 283}, + {159, 63: 159, 78: 159}, + {169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 169, 361, 169, 84: 360}, + {75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75}, + {74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74}, // 90 - {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}, - {62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62}, - {61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61}, - {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60}, - {59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59}, + {73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73}, + {72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72}, + {71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71}, + {70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70}, + {69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69}, // 95 - {58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58}, - {57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57}, - {56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56}, - {55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55}, - {54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54}, + {68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68}, + {67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67}, + {66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66}, + {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, // 100 - {53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53}, - {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52}, - {51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51}, - {50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50}, - {49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49}, + {63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}, + {62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62}, + {61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61}, + {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60}, + {59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59}, // 105 - {48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48}, - {47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47}, - {46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46}, - {45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45}, - {44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44}, + {58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58}, + {57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57}, + {56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56}, + {55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55}, + {54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54}, // 110 - {43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43}, - {42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42}, - {41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41}, - {40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}, - {39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39}, + {53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53}, + {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52}, + {51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51}, + {50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50}, + {49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49}, // 115 - {38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38}, - {37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37}, - {36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36}, - {35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35}, - {34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34}, + {48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48}, + {47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47}, + {46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46}, + {45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45}, + {44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44}, // 120 - {33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33}, - {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}, - {31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31}, - {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, - {29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29}, + {43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43}, + {42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42}, + {41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41}, + {40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}, + {39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39}, // 125 - {28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, - {27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27}, - {26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26}, - {25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25}, - {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24}, + {38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38}, + {37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37}, + {36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36}, + {35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35}, + {34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34}, // 130 - {23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23}, - {22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22}, - {21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21}, - {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20}, - {19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19}, + {33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33}, + {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}, + {31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31}, + {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, + {29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29}, // 135 - {18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}, - {17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17}, - {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}, - {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, - {14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, + {27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27}, + {26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26}, + {25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25}, + {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24}, // 140 - {13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, - {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, - {11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, - {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, - {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}, + {23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23}, + {22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22}, + {21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21}, + {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20}, + {19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19}, // 145 - {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, - {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}, - {6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}, - {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, - {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + {18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}, + {17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17}, + {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}, + {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, // 150 - {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, - {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 73: 151, 339, 94: 348}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 337}, + {13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, + {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}, // 155 - {155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 155, 155, 79: 338}, - {151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 73: 151, 339, 94: 340}, - {77: 341}, - {142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 73: 142}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 343, 109: 342}, + {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, + {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}, + {6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}, + {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, // 160 - {345, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 344, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 83: 346}, - {149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149}, - {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 59: 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 82: 152}, - {150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 73: 150}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 347}, + {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 78: 165, 80: 364, 99: 373}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 362}, // 165 - {148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148}, - {143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 73: 143}, - {156, 58: 156}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 264, 84: 351}, - {144, 58: 144, 73: 144}, + {169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 169, 80: 169, 84: 363}, + {165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 78: 165, 80: 364, 99: 365}, + {82: 366}, + {156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 78: 156}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 368, 115: 367}, // 170 - {1: 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 78: 159}, - {63: 259, 258, 89: 257, 354}, - {157, 58: 157}, - {66: 155, 155, 72: 254, 79: 356}, - {66: 358, 359, 103: 357}, + {370, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 369, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 88: 371}, + {163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163}, + {166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 64: 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 87: 166}, + {164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 78: 164}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 372}, // 175 - {360}, - {74}, - {73}, - {1: 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 78: 160}, - {155, 72: 254, 79: 362}, + {162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162}, + {157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 78: 157}, + {170, 63: 170}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 284, 89: 376}, + {158, 63: 158, 78: 158}, // 180 - {363}, - {1: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 78: 161}, - {65: 155, 68: 155, 72: 254, 79: 365}, - {65: 368, 68: 367, 105: 366}, - {369}, + {1: 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 83: 173}, + {68: 279, 278, 94: 277, 379}, + {171, 63: 171}, + {71: 169, 169, 77: 274, 84: 381}, + {71: 383, 384, 109: 382}, // 185 - {127}, - {126}, - {1: 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 78: 162}, - {82: 371}, - {58: 344, 82: 153, 372}, + {385}, + {79}, + {78}, + {1: 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 83: 174}, + {169, 77: 274, 84: 387}, // 190 - {82: 373}, - {374}, - {1: 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 78: 163}, - {72: 254, 79: 376, 81: 155}, - {81: 377}, + {388}, + {1: 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 83: 175}, + {70: 169, 73: 169, 77: 274, 84: 390}, + {70: 393, 73: 392, 111: 391}, + {394}, // 195 - {69: 380, 379, 113: 378}, - {381}, - {129}, - {128}, - {1: 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 78: 164}, + {137}, + {136}, + {1: 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 83: 176}, + {87: 396}, + {63: 369, 87: 167, 397}, // 200 - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 383}, - {384}, - {1: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 78: 165}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 386}, - {387}, + {87: 398}, + {399}, + {1: 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 83: 177}, + {77: 274, 84: 401, 86: 169}, + {86: 402}, // 205 - {1: 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 78: 166}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 389}, - {76: 390}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 393, 394, 392, 114: 391}, - {395}, + {74: 405, 404, 119: 403}, + {406}, + {139}, + {138}, + {1: 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 83: 178}, // 210 - {132}, - {131}, - {130}, - {1: 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 78: 167}, - {72: 254, 79: 397, 81: 155}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 408}, + {409, 63: 410}, + {1: 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 83: 180}, + {169, 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 274, 79: 169, 84: 414, 413, 108: 412, 121: 411}, + {416, 79: 417}, // 215 - {81: 398}, - {399}, - {1: 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 78: 168}, - {72: 254, 79: 401, 81: 155}, - {81: 402}, + {154, 79: 154}, + {169, 77: 274, 79: 169, 84: 415}, + {152, 79: 152}, + {153, 79: 153}, + {1: 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 83: 179}, // 220 - {403}, - {1: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 78: 169}, - {155, 59: 155, 155, 155, 155, 72: 254, 79: 405}, - {136, 59: 409, 410, 411, 412, 97: 408, 111: 407, 406}, - {415}, + {169, 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 274, 79: 169, 84: 414, 413, 108: 418}, + {155, 79: 155}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 420}, + {421}, + {1: 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 83: 181}, // 225 - {135, 58: 413}, - {134, 58: 134}, - {91, 58: 91}, - {90, 58: 90}, - {89, 58: 89}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 423}, + {81: 424}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 427, 428, 426, 120: 425}, + {429}, + {142}, // 230 - {88, 58: 88}, - {59: 409, 410, 411, 412, 97: 414}, - {133, 58: 133}, - {1: 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 78: 170}, - {1: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 59: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 79: 418, 88: 417}, - // 235 - {426}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 264, 84: 419}, - {153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 344, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 83: 420}, - {140, 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 423, 106: 422, 421}, {141}, + {140}, + {1: 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 83: 182}, + {77: 274, 84: 431, 86: 169}, + {86: 432}, + // 235 + {433}, + {1: 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 83: 183}, + {77: 274, 84: 435, 86: 169}, + {86: 436}, + {437}, // 240 - {139, 58: 424}, - {138, 58: 138}, - {1: 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 425}, - {137, 58: 137}, - {1: 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 78: 171}, + {1: 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 83: 184}, + {169, 64: 169, 169, 169, 169, 77: 274, 84: 439}, + {146, 64: 443, 444, 445, 446, 102: 442, 117: 441, 440}, + {449}, + {145, 63: 447}, // 245 - {1: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 59: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 79: 418, 88: 428}, - {429}, - {1: 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 78: 172}, - {155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 59: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 79: 433, 85: 432, 91: 431}, - {434}, + {144, 63: 144}, + {98, 63: 98}, + {97, 63: 97}, + {96, 63: 96}, + {95, 63: 95}, // 250 - {147, 58: 350}, - {146, 294, 308, 270, 272, 318, 297, 274, 275, 276, 298, 296, 280, 299, 300, 301, 266, 267, 268, 269, 320, 295, 290, 302, 278, 282, 271, 273, 322, 277, 284, 281, 279, 283, 285, 289, 287, 303, 317, 293, 304, 305, 306, 292, 288, 321, 291, 286, 307, 319, 309, 310, 315, 316, 312, 311, 313, 314, 59: 331, 332, 333, 334, 326, 325, 327, 323, 324, 328, 330, 329, 265, 80: 264, 84: 263}, - {1: 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 78: 173}, - {155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 59: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 79: 433, 85: 432, 91: 436}, - {437}, + {64: 443, 444, 445, 446, 102: 448}, + {143, 63: 143}, + {1: 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 83: 185}, + {1: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 64: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 84: 452, 93: 451}, + {460}, // 255 - {1: 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 78: 174}, - {1: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 59: 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 254, 79: 262, 85: 439}, - {440, 58: 350}, - {1: 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 78: 175}, - {155, 72: 254, 79: 442}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 284, 89: 453}, + {167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 369, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 88: 454}, + {150, 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 457, 112: 456, 455}, + {151}, + {149, 63: 458}, // 260 - {443}, - {1: 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 78: 176}, - {1: 244, 215, 208, 210, 236, 242, 222, 223, 224, 234, 248, 226, 218, 216, 221, 187, 205, 206, 207, 225, 245, 194, 199, 217, 227, 209, 211, 251, 212, 229, 246, 213, 228, 230, 238, 232, 220, 195, 198, 203, 247, 204, 197, 237, 250, 196, 231, 214, 249, 243, 219, 200, 240, 233, 235, 241, 239, 87: 201, 92: 188, 202, 95: 446, 193, 98: 192, 190, 445, 191, 189}, - {1: 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 78: 179}, - {1: 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 78: 177}, + {148, 63: 148}, + {1: 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 459}, + {147, 63: 147}, + {1: 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 83: 186}, + {1: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 64: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 84: 452, 93: 462}, + // 265 + {463}, + {1: 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 83: 187}, + {169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 64: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 84: 467, 90: 466, 96: 465}, + {468}, + {161, 63: 375}, + // 270 + {160, 314, 330, 290, 292, 343, 317, 294, 295, 296, 320, 316, 300, 321, 322, 323, 286, 287, 288, 289, 336, 345, 315, 310, 324, 298, 318, 319, 302, 291, 293, 347, 297, 304, 301, 337, 299, 303, 305, 309, 307, 325, 342, 313, 326, 327, 328, 312, 308, 346, 311, 331, 306, 329, 344, 332, 333, 340, 341, 335, 334, 338, 339, 64: 356, 357, 358, 359, 351, 350, 352, 348, 349, 353, 355, 354, 285, 85: 284, 89: 283}, + {1: 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 83: 188}, + {169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 64: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 84: 467, 90: 466, 96: 470}, + {471}, + {1: 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 83: 189}, + // 275 + {1: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 64: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 274, 84: 282, 90: 473}, + {474, 63: 375}, + {1: 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 83: 190}, + {169, 77: 274, 84: 476}, + {477}, + // 280 + {1: 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 83: 191}, + {1: 264, 230, 223, 225, 252, 260, 238, 239, 240, 250, 268, 242, 234, 232, 237, 202, 220, 221, 222, 253, 241, 265, 209, 214, 233, 261, 262, 243, 224, 226, 271, 227, 245, 266, 254, 228, 244, 246, 256, 248, 236, 210, 213, 218, 267, 219, 212, 255, 270, 211, 231, 247, 229, 269, 263, 235, 215, 258, 249, 251, 259, 257, 92: 216, 97: 203, 217, 100: 480, 208, 103: 207, 205, 479, 206, 204}, + {1: 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 83: 194}, + {1: 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 83: 192}, } ) @@ -912,7 +969,7 @@ func yyhintlex1(yylex yyhintLexer, lval *yyhintSymType) (n int) { } func yyhintParse(yylex yyhintLexer, parser *hintParser) int { - const yyError = 116 + const yyError = 123 yyEx, _ := yylex.(yyhintLexerEx) var yyn int @@ -1189,6 +1246,14 @@ yynewstate: } } case 18: + { + parser.yyVAL.hint = &ast.TableOptimizerHint{ + HintName: model.NewCIStr(yyS[yypt-5].ident), + QBName: model.NewCIStr(yyS[yypt-3].ident), + Tables: yyS[yypt-1].hint.Tables, + } + } + case 19: { maxValue := uint64(math.MaxInt64) / yyS[yypt-1].number if yyS[yypt-2].number <= maxValue { @@ -1203,7 +1268,7 @@ yynewstate: parser.yyVAL.hint = nil } } - case 19: + case 20: { parser.yyVAL.hint = &ast.TableOptimizerHint{ HintName: model.NewCIStr(yyS[yypt-5].ident), @@ -1213,21 +1278,21 @@ yynewstate: }, } } - case 20: + case 21: { h := yyS[yypt-1].hint h.HintName = model.NewCIStr(yyS[yypt-4].ident) h.QBName = model.NewCIStr(yyS[yypt-2].ident) parser.yyVAL.hint = h } - case 21: + case 22: { parser.yyVAL.hint = &ast.TableOptimizerHint{ HintName: model.NewCIStr(yyS[yypt-3].ident), QBName: model.NewCIStr(yyS[yypt-1].ident), } } - case 22: + case 23: { parser.yyVAL.hint = &ast.TableOptimizerHint{ HintName: model.NewCIStr(yyS[yypt-4].ident), @@ -1235,7 +1300,7 @@ yynewstate: HintData: model.NewCIStr(yyS[yypt-1].ident), } } - case 23: + case 24: { hs := yyS[yypt-1].hints name := model.NewCIStr(yyS[yypt-4].ident) @@ -1246,60 +1311,60 @@ yynewstate: } parser.yyVAL.hints = hs } - case 24: + case 25: { parser.yyVAL.hints = []*ast.TableOptimizerHint{yyS[yypt-0].hint} } - case 25: + case 26: { parser.yyVAL.hints = append(yyS[yypt-2].hints, yyS[yypt-0].hint) } - case 26: + case 27: { h := yyS[yypt-1].hint h.HintData = model.NewCIStr(yyS[yypt-3].ident) parser.yyVAL.hint = h } - case 27: + case 28: { parser.yyVAL.ident = "" } - case 31: + case 32: { parser.yyVAL.modelIdents = nil } - case 32: + case 33: { parser.yyVAL.modelIdents = yyS[yypt-1].modelIdents } - case 33: + case 34: { parser.yyVAL.modelIdents = []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)} } - case 34: + case 35: { parser.yyVAL.modelIdents = append(yyS[yypt-2].modelIdents, model.NewCIStr(yyS[yypt-0].ident)) } - case 36: + case 37: { parser.yyVAL.hint = &ast.TableOptimizerHint{ QBName: model.NewCIStr(yyS[yypt-0].ident), } } - case 37: + case 38: { parser.yyVAL.hint = &ast.TableOptimizerHint{ Tables: []ast.HintTable{yyS[yypt-0].table}, QBName: model.NewCIStr(yyS[yypt-1].ident), } } - case 38: + case 39: { h := yyS[yypt-2].hint h.Tables = append(h.Tables, yyS[yypt-0].table) parser.yyVAL.hint = h } - case 39: + case 40: { parser.yyVAL.table = ast.HintTable{ TableName: model.NewCIStr(yyS[yypt-2].ident), @@ -1307,7 +1372,7 @@ yynewstate: PartitionList: yyS[yypt-0].modelIdents, } } - case 40: + case 41: { parser.yyVAL.table = ast.HintTable{ DBName: model.NewCIStr(yyS[yypt-4].ident), @@ -1316,46 +1381,71 @@ yynewstate: PartitionList: yyS[yypt-0].modelIdents, } } - case 41: + case 42: + { + h := yyS[yypt-2].hint + h.Tables = append(h.Tables, yyS[yypt-0].table) + parser.yyVAL.hint = h + } + case 43: + { + parser.yyVAL.hint = &ast.TableOptimizerHint{ + Tables: []ast.HintTable{yyS[yypt-0].table}, + } + } + case 44: + { + parser.yyVAL.table = ast.HintTable{ + TableName: model.NewCIStr(yyS[yypt-1].ident), + QBName: model.NewCIStr(yyS[yypt-0].ident), + } + } + case 45: + { + parser.yyVAL.table = ast.HintTable{ + QBName: model.NewCIStr(yyS[yypt-0].ident), + } + } + case 46: { h := yyS[yypt-0].hint h.Tables = []ast.HintTable{yyS[yypt-2].table} h.QBName = model.NewCIStr(yyS[yypt-3].ident) parser.yyVAL.hint = h } - case 42: + case 47: { parser.yyVAL.hint = &ast.TableOptimizerHint{} } - case 44: + case 49: { parser.yyVAL.hint = &ast.TableOptimizerHint{ Indexes: []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)}, } } - case 45: + case 50: { h := yyS[yypt-2].hint h.Indexes = append(h.Indexes, model.NewCIStr(yyS[yypt-0].ident)) parser.yyVAL.hint = h } - case 52: + case 57: { parser.yyVAL.ident = strconv.FormatUint(yyS[yypt-0].number, 10) } - case 53: + case 58: { parser.yyVAL.number = 1024 * 1024 } - case 54: + case 59: { parser.yyVAL.number = 1024 * 1024 * 1024 } - case 55: + case 60: { parser.yyVAL.hint = &ast.TableOptimizerHint{HintData: true} } - case 56: + case 61: { parser.yyVAL.hint = &ast.TableOptimizerHint{HintData: false} } diff --git a/parser/hintparser.y b/parser/hintparser.y index 85d7fdba2dd3f..0d92905bb86f3 100644 --- a/parser/hintparser.y +++ b/parser/hintparser.y @@ -85,6 +85,8 @@ import ( hintAggToCop "AGG_TO_COP" hintIgnorePlanCache "IGNORE_PLAN_CACHE" hintHashAgg "HASH_AGG" + hintMpp1PhaseAgg "MPP_1PHASE_AGG" + hintMpp2PhaseAgg "MPP_2PHASE_AGG" hintIgnoreIndex "IGNORE_INDEX" hintInlHashJoin "INL_HASH_JOIN" hintInlJoin "INL_JOIN" @@ -96,10 +98,13 @@ import ( hintReadFromStorage "READ_FROM_STORAGE" hintSMJoin "MERGE_JOIN" hintBCJoin "BROADCAST_JOIN" + hintShuffleJoin "SHUFFLE_JOIN" hintStreamAgg "STREAM_AGG" hintSwapJoinInputs "SWAP_JOIN_INPUTS" hintUseIndexMerge "USE_INDEX_MERGE" hintUseIndex "USE_INDEX" + hintKeepOrder "KEEP_ORDER" + hintNoKeepOrder "NO_KEEP_ORDER" hintUsePlanCache "USE_PLAN_CACHE" hintUseToja "USE_TOJA" hintTimeRange "TIME_RANGE" @@ -159,6 +164,7 @@ import ( HintIndexList "table name with index list in optimizer hint" IndexNameList "index list in optimizer hint" IndexNameListOpt "optional index list in optimizer hint" + ViewNameList "view name list in optimizer hint" SubqueryStrategies "subquery strategies" SubqueryStrategiesOpt "optional subquery strategies" HintTrueOrFalse "true or false in optimizer hint" @@ -166,6 +172,7 @@ import ( %type HintTable "Table in optimizer hint" + ViewName "View name in optimizer hint" %type PartitionList "partition name list in optimizer hint" @@ -282,6 +289,14 @@ TableOptimizerHintOpt: QBName: model.NewCIStr($3), } } +| "QB_NAME" '(' Identifier ',' ViewNameList ')' + { + $$ = &ast.TableOptimizerHint{ + HintName: model.NewCIStr($1), + QBName: model.NewCIStr($3), + Tables: $5.Tables, + } + } | "MEMORY_QUOTA" '(' QueryBlockOpt hintIntLit UnitOfBytes ')' { maxValue := uint64(math.MaxInt64) / $5 @@ -444,6 +459,35 @@ HintTable: } } +ViewNameList: + ViewNameList '.' ViewName + { + h := $1 + h.Tables = append(h.Tables, $3) + $$ = h + } +| ViewName + { + $$ = &ast.TableOptimizerHint{ + Tables: []ast.HintTable{$1}, + } + } + +ViewName: + Identifier QueryBlockOpt + { + $$ = ast.HintTable{ + TableName: model.NewCIStr($1), + QBName: model.NewCIStr($2), + } + } +| QueryBlockOpt + { + $$ = ast.HintTable{ + QBName: model.NewCIStr($1), + } + } + /** * HintIndexList: * @@ -538,6 +582,7 @@ UnsupportedTableLevelOptimizerHintName: SupportedTableLevelOptimizerHintName: "MERGE_JOIN" | "BROADCAST_JOIN" +| "SHUFFLE_JOIN" | "INL_JOIN" | "MERGE" | "INL_HASH_JOIN" @@ -564,6 +609,8 @@ SupportedIndexLevelOptimizerHintName: | "IGNORE_INDEX" | "USE_INDEX_MERGE" | "FORCE_INDEX" +| "KEEP_ORDER" +| "NO_KEEP_ORDER" SubqueryOptimizerHintName: "SEMIJOIN" @@ -582,6 +629,8 @@ BooleanHintName: NullaryHintName: "USE_PLAN_CACHE" | "HASH_AGG" +| "MPP_1PHASE_AGG" +| "MPP_2PHASE_AGG" | "STREAM_AGG" | "AGG_TO_COP" | "LIMIT_TO_COP" @@ -636,6 +685,8 @@ Identifier: | "LIMIT_TO_COP" | "IGNORE_PLAN_CACHE" | "HASH_AGG" +| "MPP_1PHASE_AGG" +| "MPP_2PHASE_AGG" | "IGNORE_INDEX" | "INL_HASH_JOIN" | "INL_JOIN" @@ -647,10 +698,13 @@ Identifier: | "READ_FROM_STORAGE" | "MERGE_JOIN" | "BROADCAST_JOIN" +| "SHUFFLE_JOIN" | "STREAM_AGG" | "SWAP_JOIN_INPUTS" | "USE_INDEX_MERGE" | "USE_INDEX" +| "KEEP_ORDER" +| "NO_KEEP_ORDER" | "USE_PLAN_CACHE" | "USE_TOJA" | "TIME_RANGE" diff --git a/parser/lexer.go b/parser/lexer.go index 039dfe224e34a..01f1ef035914a 100644 --- a/parser/lexer.go +++ b/parser/lexer.go @@ -193,6 +193,30 @@ func (s *Scanner) getNextToken() int { return tok } +func (s *Scanner) getNextTwoTokens() (tok1 int, tok2 int) { + r := s.r + tok1, pos, lit := s.scan() + if tok1 == identifier { + tok1 = s.handleIdent(&yySymType{}) + } + if tok1 == identifier { + if tmpToken := s.isTokenIdentifier(lit, pos.Offset); tmpToken != 0 { + tok1 = tmpToken + } + } + tok2, pos, lit = s.scan() + if tok2 == identifier { + tok2 = s.handleIdent(&yySymType{}) + } + if tok2 == identifier { + if tmpToken := s.isTokenIdentifier(lit, pos.Offset); tmpToken != 0 { + tok2 = tmpToken + } + } + s.r = r + return tok1, tok2 +} + // Lex returns a token and store the token value in v. // Scanner satisfies yyLexer interface. // 0 and invalid are special token id this function would return: @@ -228,13 +252,28 @@ func (s *Scanner) Lex(v *yySymType) int { if tok == not && s.sqlMode.HasHighNotPrecedenceMode() { return not2 } - if tok == as && s.getNextToken() == of { + if (tok == as || tok == member) && s.getNextToken() == of { _, pos, lit = s.scan() v.ident = fmt.Sprintf("%s %s", v.ident, lit) - s.lastKeyword = asof s.lastScanOffset = pos.Offset v.offset = pos.Offset - return asof + if tok == as { + s.lastKeyword = asof + return asof + } + s.lastKeyword = memberof + return memberof + } + if tok == to { + tok1, tok2 := s.getNextTwoTokens() + if tok1 == timestampType && tok2 == stringLit { + _, pos, lit = s.scan() + v.ident = fmt.Sprintf("%s %s", v.ident, lit) + s.lastKeyword = toTimestamp + s.lastScanOffset = pos.Offset + v.offset = pos.Offset + return toTimestamp + } } switch tok { diff --git a/parser/misc.go b/parser/misc.go index edc8480cdbf14..5e481c24562af 100644 --- a/parser/misc.go +++ b/parser/misc.go @@ -153,9 +153,11 @@ var tokenMap = map[string]int{ "ANY": any, "APPROX_COUNT_DISTINCT": approxCountDistinct, "APPROX_PERCENTILE": approxPercentile, + "ARRAY": array, "AS": as, "ASC": asc, "ASCII": ascii, + "ATTRIBUTE": attribute, "ATTRIBUTES": attributes, "BATCH": batch, "STATS_OPTIONS": statsOptions, @@ -255,6 +257,7 @@ var tokenMap = map[string]int{ "CSV_NULL": csvNull, "CSV_SEPARATOR": csvSeparator, "CSV_TRIM_LAST_SEPARATORS": csvTrimLastSeparators, + "CURDATE": curDate, "CURRENT_DATE": currentDate, "CURRENT_ROLE": currentRole, "CURRENT_TIME": currentTime, @@ -288,6 +291,7 @@ var tokenMap = map[string]int{ "DEPTH": depth, "DESC": desc, "DESCRIBE": describe, + "DIGEST": digest, "DIRECTORY": directory, "DISABLE": disable, "DISABLED": disabled, @@ -407,6 +411,10 @@ var tokenMap = map[string]int{ "INVISIBLE": invisible, "INVOKER": invoker, "IO": io, + "RRU_PER_SEC": rruRate, + "WRU_PER_SEC": wruRate, + "IO_READ_BANDWIDTH": ioReadBandwidth, + "IO_WRITE_BANDWIDTH": ioWriteBandwidth, "IPC": ipc, "IS": is, "ISOLATION": isolation, @@ -468,6 +476,7 @@ var tokenMap = map[string]int{ "MEDIUMINT": mediumIntType, "MEDIUMTEXT": mediumtextType, "MEMORY": memory, + "MEMBER": member, "MERGE": merge, "MICROSECOND": microsecond, "MIN_ROWS": minRows, @@ -579,6 +588,7 @@ var tokenMap = map[string]int{ "RELEASE": release, "RELOAD": reload, "REMOVE": remove, + "REMOTE": remote, "RENAME": rename, "REORGANIZE": reorganize, "REPAIR": repair, @@ -592,6 +602,7 @@ var tokenMap = map[string]int{ "REQUIRE": require, "REQUIRED": required, "RESET": reset, + "RESOURCE": resource, "RESPECT": respect, "RESTART": restart, "RESTORE": restore, @@ -680,6 +691,7 @@ var tokenMap = map[string]int{ "STATS_HISTOGRAMS": statsHistograms, "STATS_TOPN": statsTopN, "STATS_META": statsMeta, + "STATS_LOCKED": statsLocked, "HISTOGRAMS_IN_FLIGHT": histogramsInFlight, "STATS_PERSISTENT": statsPersistent, "STATS_SAMPLE_PAGES": statsSamplePages, @@ -724,6 +736,7 @@ var tokenMap = map[string]int{ "THEN": then, "TIDB": tidb, "TIDB_CURRENT_TSO": tidbCurrentTSO, + "TIDB_JSON": tidbJson, "TIFLASH": tiFlash, "TIKV_IMPORTER": tikvImporter, "TIME": timeType, @@ -735,6 +748,7 @@ var tokenMap = map[string]int{ "TINYTEXT": tinytextType, "TLS": tls, "TO": to, + "TOKEN_ISSUER": tokenIssuer, "TOKUDB_DEFAULT": tokudbDefault, "TOKUDB_FAST": tokudbFast, "TOKUDB_LZMA": tokudbLzma, @@ -756,6 +770,9 @@ var tokenMap = map[string]int{ "TRUE": trueKwd, "TRUNCATE": truncate, "TRUE_CARD_COST": trueCardCost, + "TTL": ttl, + "TTL_ENABLE": ttlEnable, + "TTL_JOB_INTERVAL": ttlJobInterval, "TYPE": tp, "UNBOUNDED": unbounded, "UNCOMMITTED": uncommitted, @@ -807,6 +824,9 @@ var tokenMap = map[string]int{ "YEAR": yearType, "ZEROFILL": zerofill, "WAIT": wait, + "FAILED_LOGIN_ATTEMPTS": failedLoginAttempts, + "PASSWORD_LOCK_TIME": passwordLockTime, + "REUSE": reuse, } // See https://dev.mysql.com/doc/refman/5.7/en/function-resolution.html for details. @@ -921,6 +941,8 @@ var hintTokenMap = map[string]int{ "LIMIT_TO_COP": hintLimitToCop, "IGNORE_PLAN_CACHE": hintIgnorePlanCache, "HASH_AGG": hintHashAgg, + "MPP_1PHASE_AGG": hintMpp1PhaseAgg, + "MPP_2PHASE_AGG": hintMpp2PhaseAgg, "IGNORE_INDEX": hintIgnoreIndex, "INL_HASH_JOIN": hintInlHashJoin, "INL_JOIN": hintInlJoin, @@ -931,11 +953,14 @@ var hintTokenMap = map[string]int{ "READ_CONSISTENT_REPLICA": hintReadConsistentReplica, "READ_FROM_STORAGE": hintReadFromStorage, "BROADCAST_JOIN": hintBCJoin, + "SHUFFLE_JOIN": hintShuffleJoin, "MERGE_JOIN": hintSMJoin, "STREAM_AGG": hintStreamAgg, "SWAP_JOIN_INPUTS": hintSwapJoinInputs, "USE_INDEX_MERGE": hintUseIndexMerge, "USE_INDEX": hintUseIndex, + "KEEP_ORDER": hintKeepOrder, + "NO_KEEP_ORDER": hintNoKeepOrder, "USE_PLAN_CACHE": hintUsePlanCache, "USE_TOJA": hintUseToja, "TIME_RANGE": hintTimeRange, diff --git a/parser/model/ddl.go b/parser/model/ddl.go index 19164959815a3..8eb26ca238d3f 100644 --- a/parser/model/ddl.go +++ b/parser/model/ddl.go @@ -97,6 +97,13 @@ const ( ActionCreateTables ActionType = 60 ActionMultiSchemaChange ActionType = 61 ActionFlashbackCluster ActionType = 62 + ActionRecoverSchema ActionType = 63 + ActionReorganizePartition ActionType = 64 + ActionAlterTTLInfo ActionType = 65 + ActionAlterTTLRemove ActionType = 67 + ActionCreateResourceGroup ActionType = 68 + ActionAlterResourceGroup ActionType = 69 + ActionDropResourceGroup ActionType = 70 ) var actionMap = map[ActionType]string{ @@ -158,6 +165,13 @@ var actionMap = map[ActionType]string{ ActionAlterTableStatsOptions: "alter table statistics options", ActionMultiSchemaChange: "alter table multi-schema change", ActionFlashbackCluster: "flashback cluster", + ActionRecoverSchema: "flashback schema", + ActionReorganizePartition: "alter table reorganize partition", + ActionAlterTTLInfo: "alter table ttl", + ActionAlterTTLRemove: "alter table no_ttl", + ActionCreateResourceGroup: "create resource group", + ActionAlterResourceGroup: "alter resource group", + ActionDropResourceGroup: "drop resource group", // `ActionAlterTableAlterPartition` is removed and will never be used. // Just left a tombstone here for compatibility. @@ -252,6 +266,19 @@ func (tp ReorgType) NeedMergeProcess() bool { return tp == ReorgTypeLitMerge || tp == ReorgTypeTxnMerge } +// String implements fmt.Stringer interface. +func (tp ReorgType) String() string { + switch tp { + case ReorgTypeTxn: + return "txn" + case ReorgTypeLitMerge: + return "ingest" + case ReorgTypeTxnMerge: + return "txn-merge" + } + return "" +} + // TimeZoneLocation represents a single time zone. type TimeZoneLocation struct { Name string `json:"name"` @@ -296,10 +323,18 @@ type MultiSchemaInfo struct { DropIndexes []CIStr `json:"-"` AlterIndexes []CIStr `json:"-"` + AddForeignKeys []AddForeignKeyInfo `json:"-"` + RelativeColumns []CIStr `json:"-"` PositionColumns []CIStr `json:"-"` } +// AddForeignKeyInfo contains foreign key information. +type AddForeignKeyInfo struct { + Name CIStr + Cols []CIStr +} + // NewMultiSchemaInfo new a MultiSchemaInfo. func NewMultiSchemaInfo() *MultiSchemaInfo { return &MultiSchemaInfo{ @@ -321,6 +356,7 @@ type SubJob struct { Warning *terror.Error `json:"warning"` CtxVars []interface{} `json:"-"` SchemaVer int64 `json:"schema_version"` + ReorgTp ReorgType `json:"reorg_tp"` } // IsNormal returns true if the sub-job is normally running. @@ -383,6 +419,45 @@ func (sub *SubJob) FromProxyJob(proxyJob *Job, ver int64) { sub.Warning = proxyJob.Warning sub.RowCount = proxyJob.RowCount sub.SchemaVer = ver + sub.ReorgTp = proxyJob.ReorgMeta.ReorgTp +} + +// JobMeta is meta info of Job. +type JobMeta struct { + SchemaID int64 `json:"schema_id"` + TableID int64 `json:"table_id"` + // Query string of the ddl job. + Query string `json:"query"` + // Priority is only used to set the operation priority of adding indices. + Priority int `json:"priority"` +} + +// BackfillMeta is meta info of the backfill job. +type BackfillMeta struct { + PhysicalTableID int64 `json:"physical_table_id"` + IsUnique bool `json:"is_unique"` + EndInclude bool `json:"end_include"` + ErrMsg string `json:"err_msg"` + + SQLMode mysql.SQLMode `json:"sql_mode"` + Warnings map[errors.ErrorID]*terror.Error `json:"warnings"` + WarningsCount map[errors.ErrorID]int64 `json:"warnings_count"` + Location *TimeZoneLocation `json:"location"` + ReorgTp ReorgType `json:"reorg_tp"` + + *JobMeta `json:"job_meta"` +} + +// Encode encodes BackfillMeta with json format. +func (bm *BackfillMeta) Encode() ([]byte, error) { + b, err := json.Marshal(bm) + return b, errors.Trace(err) +} + +// Decode decodes BackfillMeta from the json buffer. +func (bm *BackfillMeta) Decode(b []byte) error { + err := json.Unmarshal(b, bm) + return errors.Trace(err) } // Job is for a DDL operation. @@ -593,6 +668,9 @@ func (job *Job) String() string { rowCount := job.GetRowCount() ret := fmt.Sprintf("ID:%d, Type:%s, State:%s, SchemaState:%s, SchemaID:%d, TableID:%d, RowCount:%d, ArgLen:%d, start time: %v, Err:%v, ErrCount:%d, SnapshotVersion:%v", job.ID, job.Type, job.State, job.SchemaState, job.SchemaID, job.TableID, rowCount, len(job.Args), TSConvert2Time(job.StartTS), job.Error, job.ErrorCount, job.SnapshotVer) + if job.ReorgMeta != nil { + ret += fmt.Sprintf(", UniqueWarnings:%d", len(job.ReorgMeta.Warnings)) + } if job.Type != ActionMultiSchemaChange && job.MultiSchemaInfo != nil { ret += fmt.Sprintf(", Multi-Schema Change:true, Revertible:%v", job.MultiSchemaInfo.Revertible) } @@ -811,7 +889,8 @@ func (job *Job) IsRollbackable() bool { case ActionMultiSchemaChange: return job.MultiSchemaInfo.Revertible case ActionFlashbackCluster: - if job.SchemaState == StateWriteReorganization { + if job.SchemaState == StateWriteReorganization || + job.SchemaState == StateWriteOnly { return false } } @@ -877,6 +956,8 @@ type SchemaDiff struct { OldTableID int64 `json:"old_table_id"` // OldSchemaID is the schema ID before rename table, only used by rename table DDL. OldSchemaID int64 `json:"old_schema_id"` + // RegenerateSchemaMap means whether to rebuild the schema map when applying to the schema diff. + RegenerateSchemaMap bool `json:"regenerate_schema_map"` AffectedOpts []*AffectedOption `json:"affected_options"` } diff --git a/parser/model/ddl_test.go b/parser/model/ddl_test.go index 7fddcca54e351..d67b6ac91175a 100644 --- a/parser/model/ddl_test.go +++ b/parser/model/ddl_test.go @@ -51,3 +51,22 @@ func TestJobSize(t *testing.T) { job := model.Job{} require.Equal(t, 288, int(unsafe.Sizeof(job)), msg) } + +func TestBackfillMetaCodec(t *testing.T) { + jm := &model.JobMeta{ + SchemaID: 1, + TableID: 2, + Query: "alter table t add index idx(a)", + Priority: 1, + } + bm := &model.BackfillMeta{ + EndInclude: true, + ErrMsg: "has a err", + JobMeta: jm, + } + bmBytes, err := bm.Encode() + require.NoError(t, err) + bmRet := &model.BackfillMeta{} + bmRet.Decode(bmBytes) + require.Equal(t, bm, bmRet) +} diff --git a/parser/model/model.go b/parser/model/model.go index 34f16a72a6edc..70dcccf013141 100644 --- a/parser/model/model.go +++ b/parser/model/model.go @@ -164,6 +164,9 @@ type ColumnInfo struct { // Clone clones ColumnInfo. func (c *ColumnInfo) Clone() *ColumnInfo { + if c == nil { + return nil + } nc := *c return &nc } @@ -333,6 +336,9 @@ func (c *ColumnInfo) GetTypeDesc() string { return desc } +// EmptyColumnInfoSize is the memory usage of ColumnInfoSize +const EmptyColumnInfoSize = int64(unsafe.Sizeof(ColumnInfo{})) + // FindColumnInfo finds ColumnInfo in cols by name. func FindColumnInfo(cols []*ColumnInfo, name string) *ColumnInfo { name = strings.ToLower(name) @@ -375,8 +381,8 @@ func FindFKInfoByName(fks []*FKInfo, name string) *FKInfo { } // FindIndexByColumns find IndexInfo in indices which is cover the specified columns. -func FindIndexByColumns(tbInfo *TableInfo, cols ...CIStr) *IndexInfo { - for _, index := range tbInfo.Indices { +func FindIndexByColumns(tbInfo *TableInfo, indices []*IndexInfo, cols ...CIStr) *IndexInfo { + for _, index := range indices { if IsIndexPrefixCovered(tbInfo, index, cols...) { return index } @@ -440,14 +446,16 @@ const ( // However, the convert is missed in some scenarios before v2.1.9, so for all those tables prior to TableInfoVersion3, their // charsets / collations will be converted to lower-case while loading from the storage. TableInfoVersion3 = uint16(3) - // TableInfoVersion4 indicates that the auto_increment allocator in TiDB has been separated from - // _tidb_rowid allocator. This version is introduced to preserve the compatibility of old tables: - // the tables with version < TableInfoVersion4 still use a single allocator for auto_increment and _tidb_rowid. - // Also see https://github.com/pingcap/tidb/issues/982. + // TableInfoVersion4 is not used. TableInfoVersion4 = uint16(4) + // TableInfoVersion5 indicates that the auto_increment allocator in TiDB has been separated from + // _tidb_rowid allocator when AUTO_ID_CACHE is 1. This version is introduced to preserve the compatibility of old tables: + // the tables with version <= TableInfoVersion4 still use a single allocator for auto_increment and _tidb_rowid. + // Also see https://github.com/pingcap/tidb/issues/982. + TableInfoVersion5 = uint16(5) // CurrLatestTableInfoVersion means the latest table info in the current TiDB. - CurrLatestTableInfoVersion = TableInfoVersion4 + CurrLatestTableInfoVersion = TableInfoVersion5 ) // ExtraHandleName is the name of ExtraHandle Column. @@ -542,6 +550,13 @@ type TableInfo struct { StatsOptions *StatsOptions `json:"stats_options"` ExchangePartitionInfo *ExchangePartitionInfo `json:"exchange_partition_info"` + + TTLInfo *TTLInfo `json:"ttl_info"` +} + +// SepAutoInc decides whether _rowid and auto_increment id use separate allocator. +func (t *TableInfo) SepAutoInc() bool { + return t.Version >= TableInfoVersion5 && t.AutoIdCache == 1 } // TableCacheStatusType is the type of the table cache status @@ -742,6 +757,13 @@ func (t *TableInfo) Clone() *TableInfo { nt.ForeignKeys[i] = t.ForeignKeys[i].Clone() } + if t.Partition != nil { + nt.Partition = t.Partition.Clone() + } + if t.TTLInfo != nil { + nt.TTLInfo = t.TTLInfo.Clone() + } + return &nt } @@ -1174,6 +1196,8 @@ type PartitionInfo struct { DroppingDefinitions []PartitionDefinition `json:"dropping_definitions"` States []PartitionState `json:"states"` Num uint64 `json:"num"` + // Only used during ReorganizePartition so far + DDLState SchemaState `json:"ddl_state"` } // Clone clones itself. @@ -1308,15 +1332,15 @@ func (ci *PartitionDefinition) MemoryUsage() (sum int64) { } // FindPartitionDefinitionByName finds PartitionDefinition by name. -func (t *TableInfo) FindPartitionDefinitionByName(partitionDefinitionName string) *PartitionDefinition { +func (pi *PartitionInfo) FindPartitionDefinitionByName(partitionDefinitionName string) int { lowConstrName := strings.ToLower(partitionDefinitionName) - definitions := t.Partition.Definitions + definitions := pi.Definitions for i := range definitions { if definitions[i].Name.L == lowConstrName { - return &t.Partition.Definitions[i] + return i } } - return nil + return -1 } // IndexColumn provides index column info. @@ -1400,10 +1424,14 @@ type IndexInfo struct { Primary bool `json:"is_primary"` // Whether the index is primary key. Invisible bool `json:"is_invisible"` // Whether the index is invisible. Global bool `json:"is_global"` // Whether the index is global. + MVIndex bool `json:"mv_index"` // Whether the index is multivalued index. } // Clone clones IndexInfo. func (index *IndexInfo) Clone() *IndexInfo { + if index == nil { + return nil + } ni := *index ni.Columns = make([]*IndexColumn, len(index.Columns)) for i := range index.Columns { @@ -1730,6 +1758,23 @@ func (p *PolicyInfo) Clone() *PolicyInfo { return &cloned } +// TTLInfo records the TTL config +type TTLInfo struct { + ColumnName CIStr `json:"column"` + IntervalExprStr string `json:"interval_expr"` + // `IntervalTimeUnit` is actually ast.TimeUnitType. Use `int` to avoid cycle dependency + IntervalTimeUnit int `json:"interval_time_unit"` + Enable bool `json:"enable"` + // JobInterval is the interval between two TTL scan jobs. + JobInterval string `json:"job_interval"` +} + +// Clone clones TTLInfo +func (t *TTLInfo) Clone() *TTLInfo { + cloned := *t + return &cloned +} + func writeSettingItemToBuilder(sb *strings.Builder, item string) { if sb.Len() != 0 { sb.WriteString(" ") @@ -1798,6 +1843,62 @@ func (p *PlacementSettings) Clone() *PlacementSettings { return &cloned } +// ResourceGroupRefInfo is the struct to refer the resource group. +type ResourceGroupRefInfo struct { + ID int64 `json:"id"` + Name CIStr `json:"name"` +} + +// ResourceGroupSettings is the settings of the resource group +type ResourceGroupSettings struct { + RRURate uint64 `json:"rru_per_sec"` + WRURate uint64 `json:"wru_per_sec"` + CPULimiter string `json:"cpu_limit"` + IOReadBandwidth string `json:"io_read_bandwidth"` + IOWriteBandwidth string `json:"io_write_bandwidth"` +} + +func (p *ResourceGroupSettings) String() string { + sb := new(strings.Builder) + if p.RRURate != 0 { + writeSettingIntegerToBuilder(sb, "RRU_PER_SEC", p.RRURate) + } + if p.WRURate != 0 { + writeSettingIntegerToBuilder(sb, "WRU_PER_SEC", p.WRURate) + } + if len(p.CPULimiter) > 0 { + writeSettingStringToBuilder(sb, "CPU", p.CPULimiter) + } + if len(p.IOReadBandwidth) > 0 { + writeSettingStringToBuilder(sb, "IO_READ_BANDWIDTH", p.IOReadBandwidth) + } + if len(p.IOWriteBandwidth) > 0 { + writeSettingStringToBuilder(sb, "IO_WRITE_BANDWIDTH", p.IOWriteBandwidth) + } + return sb.String() +} + +// Clone clones the resource group settings. +func (p *ResourceGroupSettings) Clone() *ResourceGroupSettings { + cloned := *p + return &cloned +} + +// ResourceGroupInfo is the struct to store the placement policy. +type ResourceGroupInfo struct { + *ResourceGroupSettings + ID int64 `json:"id"` + Name CIStr `json:"name"` + State SchemaState `json:"state"` +} + +// Clone clones the ResourceGroupInfo. +func (p *ResourceGroupInfo) Clone() *ResourceGroupInfo { + cloned := *p + cloned.ResourceGroupSettings = p.ResourceGroupSettings.Clone() + return &cloned +} + // StatsOptions is the struct to store the stats options. type StatsOptions struct { *StatsWindowSettings diff --git a/parser/model/model_test.go b/parser/model/model_test.go index 47a8ecad6e4a4..6062df58aabec 100644 --- a/parser/model/model_test.go +++ b/parser/model/model_test.go @@ -785,3 +785,23 @@ func TestIsIndexPrefixCovered(t *testing.T) { require.Equal(t, true, IsIndexPrefixCovered(tbl, i1, NewCIStr("c_4"), NewCIStr("c_2"))) require.Equal(t, false, IsIndexPrefixCovered(tbl, i0, NewCIStr("c_2"))) } + +func TestTTLInfoClone(t *testing.T) { + ttlInfo := &TTLInfo{ + ColumnName: NewCIStr("test"), + IntervalExprStr: "test_expr", + IntervalTimeUnit: 5, + Enable: true, + } + + clonedTTLInfo := ttlInfo.Clone() + clonedTTLInfo.ColumnName = NewCIStr("test_2") + clonedTTLInfo.IntervalExprStr = "test_expr_2" + clonedTTLInfo.IntervalTimeUnit = 9 + clonedTTLInfo.Enable = false + + require.Equal(t, "test", ttlInfo.ColumnName.O) + require.Equal(t, "test_expr", ttlInfo.IntervalExprStr) + require.Equal(t, 5, ttlInfo.IntervalTimeUnit) + require.Equal(t, true, ttlInfo.Enable) +} diff --git a/parser/mysql/const.go b/parser/mysql/const.go index 056be1934265a..f836cc05e4286 100644 --- a/parser/mysql/const.go +++ b/parser/mysql/const.go @@ -81,6 +81,8 @@ const ( MaxKeyParts = 16 // MaxIndexIdentifierLen is max length of index identifier. MaxIndexIdentifierLen = 64 + // MaxForeignKeyIdentifierLen is max length of foreign key identifier. + MaxForeignKeyIdentifierLen = 64 // MaxConstraintIdentifierLen is max length of constrain identifier. MaxConstraintIdentifierLen = 64 // MaxViewIdentifierLen is max length of view identifier. @@ -177,8 +179,10 @@ const ( AuthNativePassword = "mysql_native_password" // #nosec G101 AuthCachingSha2Password = "caching_sha2_password" // #nosec G101 AuthTiDBSM3Password = "tidb_sm3_password" // #nosec G101 + AuthMySQLClearPassword = "mysql_clear_password" AuthSocket = "auth_socket" AuthTiDBSessionToken = "tidb_session_token" + AuthTiDBAuthToken = "tidb_auth_token" ) // MySQL database and tables. @@ -205,6 +209,8 @@ const ( RoleEdgeTable = "role_edges" // DefaultRoleTable is the table contain default active role info DefaultRoleTable = "default_roles" + // PasswordHistoryTable is the table in system db contains password history. + PasswordHistoryTable = "password_history" ) // MySQL type maximum length. diff --git a/parser/mysql/errcode.go b/parser/mysql/errcode.go index f82bbb1e0978f..0ea2134f88d75 100644 --- a/parser/mysql/errcode.go +++ b/parser/mysql/errcode.go @@ -884,6 +884,7 @@ const ( ErrErrorLast = 1863 ErrMaxExecTimeExceeded = 1907 ErrInvalidFieldSize = 3013 + ErrPasswordExpireAnonymousUser = 3016 ErrIncorrectType = 3064 ErrInvalidJSONData = 3069 ErrGeneratedColumnFunctionIsNotAllowed = 3102 diff --git a/parser/mysql/errname.go b/parser/mysql/errname.go index eef4defcb2465..3066d9f6fb6b0 100644 --- a/parser/mysql/errname.go +++ b/parser/mysql/errname.go @@ -899,6 +899,7 @@ var MySQLErrName = map[uint16]*ErrMessage{ ErrDependentByGeneratedColumn: Message("Column '%s' has a generated column dependency.", nil), ErrGeneratedColumnRefAutoInc: Message("Generated column '%s' cannot refer to auto-increment column.", nil), ErrInvalidFieldSize: Message("Invalid size for column '%s'.", nil), + ErrPasswordExpireAnonymousUser: Message("The password for anonymous user cannot be expired.", nil), ErrIncorrectType: Message("Incorrect type for argument %s in function %s.", nil), ErrInvalidJSONData: Message("Invalid JSON data provided to function %s: %s", nil), ErrInvalidJSONText: Message("Invalid JSON text: %-.192s", nil), diff --git a/parser/mysql/type.go b/parser/mysql/type.go index c54d0f8984b63..f79be8ab30d96 100644 --- a/parser/mysql/type.go +++ b/parser/mysql/type.go @@ -43,7 +43,7 @@ const ( TypeLongBlob byte = 0xfb TypeBlob byte = 0xfc TypeVarString byte = 0xfd - TypeString byte = 0xfe + TypeString byte = 0xfe /* TypeString is char type */ TypeGeometry byte = 0xff ) diff --git a/parser/mysql/util.go b/parser/mysql/util.go index 367839b2ce3af..c69e290369598 100644 --- a/parser/mysql/util.go +++ b/parser/mysql/util.go @@ -93,3 +93,10 @@ func GetDefaultFieldLengthAndDecimalForCast(tp byte) (flen int, decimal int) { } return -1, -1 } + +// IsAuthPluginClearText is used to indicated that the plugin need clear-text password. +func IsAuthPluginClearText(authPlugin string) bool { + return authPlugin == AuthNativePassword || + authPlugin == AuthTiDBSM3Password || + authPlugin == AuthCachingSha2Password +} diff --git a/parser/parser.go b/parser/parser.go index 6eafe157e0a77..0412b37bce71c 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -34,6 +34,7 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/charset" + "github.com/pingcap/tidb/parser/duration" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/opcode" @@ -54,2174 +55,2231 @@ type yyXError struct { } const ( - yyDefault = 58113 + yyDefault = 58135 yyEOFCode = 57344 - account = 57574 - action = 57575 - add = 57359 - addDate = 57914 - admin = 57999 - advise = 57576 - after = 57577 - against = 57578 - ago = 57579 - algorithm = 57580 - all = 57360 - alter = 57361 - always = 57581 - analyze = 57362 - and = 57363 - andand = 57354 - andnot = 58074 - any = 57582 - approxCountDistinct = 57915 - approxPercentile = 57916 - as = 57364 - asc = 57365 - ascii = 57583 + account = 57577 + action = 57578 + add = 57361 + addDate = 57929 + admin = 58020 + advise = 57579 + after = 57580 + against = 57581 + ago = 57582 + algorithm = 57583 + all = 57362 + alter = 57363 + always = 57584 + analyze = 57364 + and = 57365 + andand = 57356 + andnot = 58096 + any = 57585 + approxCountDistinct = 57930 + approxPercentile = 57931 + array = 57366 + as = 57367 + asc = 57368 + ascii = 57586 asof = 57347 - assignmentEq = 58075 - attributes = 57584 - autoIdCache = 57589 - autoIncrement = 57590 - autoRandom = 57591 - autoRandomBase = 57592 - avg = 57593 - avgRowLength = 57594 - backend = 57595 - backup = 57596 - backups = 57597 - batch = 58000 - begin = 57598 - bernoulli = 57599 - between = 57366 - bigIntType = 57367 - binaryType = 57368 - binding = 57600 - bindingCache = 57601 - bindings = 57602 - binlog = 57603 - bitAnd = 57917 - bitLit = 58073 - bitOr = 57918 - bitType = 57604 - bitXor = 57919 - blobType = 57369 - block = 57605 - boolType = 57607 - booleanType = 57606 - both = 57370 - bound = 57920 - briefType = 57921 - btree = 57608 - buckets = 58001 - builtinApproxCountDistinct = 58047 - builtinApproxPercentile = 58048 - builtinBitAnd = 58042 - builtinBitOr = 58043 - builtinBitXor = 58044 - builtinCast = 58045 - builtinCount = 58046 - builtinCurDate = 58049 - builtinCurTime = 58050 - builtinDateAdd = 58051 - builtinDateSub = 58052 - builtinExtract = 58053 - builtinGroupConcat = 58054 - builtinMax = 58055 - builtinMin = 58056 - builtinNow = 58057 - builtinPosition = 58058 - builtinStddevPop = 58062 - builtinStddevSamp = 58063 - builtinSubstring = 58059 - builtinSum = 58060 - builtinSysDate = 58061 - builtinTranslate = 58064 - builtinTrim = 58065 - builtinUser = 58066 - builtinVarPop = 58067 - builtinVarSamp = 58068 - builtins = 58002 - by = 57371 - byteType = 57609 - cache = 57610 - call = 57372 - cancel = 58003 - capture = 57611 - cardinality = 58004 - cascade = 57373 - cascaded = 57612 - caseKwd = 57374 - cast = 57922 - causal = 57613 - chain = 57614 - change = 57375 - charType = 57377 - character = 57376 - charsetKwd = 57615 - check = 57378 - checkpoint = 57616 - checksum = 57617 - cipher = 57618 - cleanup = 57619 - client = 57620 - clientErrorsSummary = 57621 - cluster = 57647 - clustered = 57648 - cmSketch = 58005 - coalesce = 57622 - collate = 57379 - collation = 57623 - column = 57380 - columnFormat = 57624 - columnStatsUsage = 58006 - columns = 57625 - comment = 57627 - commit = 57628 - committed = 57629 - compact = 57630 - compressed = 57631 - compression = 57632 - concurrency = 57633 - config = 57626 - connection = 57634 - consistency = 57635 - consistent = 57636 - constraint = 57381 - constraints = 57924 - context = 57637 - convert = 57382 - copyKwd = 57923 - correlation = 58007 - cpu = 57638 - create = 57383 - createTableSelect = 58097 - cross = 57384 - csvBackslashEscape = 57639 - csvDelimiter = 57640 - csvHeader = 57641 - csvNotNull = 57642 - csvNull = 57643 - csvSeparator = 57644 - csvTrimLastSeparators = 57645 - cumeDist = 57385 - curTime = 57925 - current = 57646 - currentDate = 57386 - currentRole = 57390 - currentTime = 57387 - currentTs = 57388 - currentUser = 57389 - cycle = 57649 - data = 57650 - database = 57391 - databases = 57392 - dateAdd = 57926 - dateSub = 57927 - dateType = 57652 - datetimeType = 57651 - day = 57653 - dayHour = 57393 - dayMicrosecond = 57394 - dayMinute = 57395 - daySecond = 57396 - ddl = 58008 - deallocate = 57654 - decLit = 58070 - decimalType = 57397 - defaultKwd = 57398 - definer = 57655 - delayKeyWrite = 57656 - delayed = 57399 - deleteKwd = 57400 - denseRank = 57401 - dependency = 58009 - depth = 58010 - desc = 57402 - describe = 57403 - directory = 57657 - disable = 57658 - disabled = 57659 - discard = 57660 - disk = 57661 - distinct = 57404 - distinctRow = 57405 - div = 57406 - do = 57662 - dotType = 57928 - doubleAtIdentifier = 57351 - doubleType = 57407 - drainer = 58011 - drop = 57408 - dry = 58012 - dual = 57409 - dump = 57929 - duplicate = 57663 - dynamic = 57664 - elseKwd = 57410 - empty = 58088 - enable = 57665 - enabled = 57666 - enclosed = 57411 - encryption = 57667 - end = 57668 - enforced = 57669 - engine = 57670 - engines = 57671 - enum = 57672 - eq = 58076 + assignmentEq = 58097 + attribute = 57587 + attributes = 57588 + autoIdCache = 57593 + autoIncrement = 57594 + autoRandom = 57595 + autoRandomBase = 57596 + avg = 57597 + avgRowLength = 57598 + backend = 57599 + backup = 57600 + backups = 57601 + batch = 58021 + begin = 57602 + bernoulli = 57603 + between = 57369 + bigIntType = 57370 + binaryType = 57371 + binding = 57604 + bindingCache = 57605 + bindings = 57606 + binlog = 57607 + bitAnd = 57932 + bitLit = 58095 + bitOr = 57933 + bitType = 57608 + bitXor = 57934 + blobType = 57372 + block = 57609 + boolType = 57611 + booleanType = 57610 + both = 57373 + bound = 57935 + briefType = 57936 + btree = 57612 + buckets = 58022 + builtinApproxCountDistinct = 58069 + builtinApproxPercentile = 58070 + builtinBitAnd = 58064 + builtinBitOr = 58065 + builtinBitXor = 58066 + builtinCast = 58067 + builtinCount = 58068 + builtinCurDate = 58071 + builtinCurTime = 58072 + builtinDateAdd = 58073 + builtinDateSub = 58074 + builtinExtract = 58075 + builtinGroupConcat = 58076 + builtinMax = 58077 + builtinMin = 58078 + builtinNow = 58079 + builtinPosition = 58080 + builtinStddevPop = 58084 + builtinStddevSamp = 58085 + builtinSubstring = 58081 + builtinSum = 58082 + builtinSysDate = 58083 + builtinTranslate = 58086 + builtinTrim = 58087 + builtinUser = 58088 + builtinVarPop = 58089 + builtinVarSamp = 58090 + builtins = 58023 + by = 57374 + byteType = 57613 + cache = 57614 + call = 57375 + cancel = 58024 + capture = 57615 + cardinality = 58025 + cascade = 57376 + cascaded = 57616 + caseKwd = 57377 + cast = 57937 + causal = 57617 + chain = 57618 + change = 57378 + charType = 57380 + character = 57379 + charsetKwd = 57619 + check = 57381 + checkpoint = 57620 + checksum = 57621 + cipher = 57622 + cleanup = 57623 + client = 57624 + clientErrorsSummary = 57625 + cluster = 57651 + clustered = 57652 + cmSketch = 58026 + coalesce = 57626 + collate = 57382 + collation = 57627 + column = 57383 + columnFormat = 57628 + columnStatsUsage = 58027 + columns = 57629 + comment = 57631 + commit = 57632 + committed = 57633 + compact = 57634 + compressed = 57635 + compression = 57636 + concurrency = 57637 + config = 57630 + connection = 57638 + consistency = 57639 + consistent = 57640 + constraint = 57384 + constraints = 57939 + context = 57641 + convert = 57385 + copyKwd = 57938 + correlation = 58028 + cpu = 57642 + create = 57386 + createTableSelect = 58119 + cross = 57387 + csvBackslashEscape = 57643 + csvDelimiter = 57644 + csvHeader = 57645 + csvNotNull = 57646 + csvNull = 57647 + csvSeparator = 57648 + csvTrimLastSeparators = 57649 + cumeDist = 57388 + curDate = 57941 + curTime = 57940 + current = 57650 + currentDate = 57389 + currentRole = 57393 + currentTime = 57390 + currentTs = 57391 + currentUser = 57392 + cycle = 57653 + data = 57654 + database = 57394 + databases = 57395 + dateAdd = 57942 + dateSub = 57943 + dateType = 57656 + datetimeType = 57655 + day = 57657 + dayHour = 57396 + dayMicrosecond = 57397 + dayMinute = 57398 + daySecond = 57399 + ddl = 58029 + deallocate = 57658 + decLit = 58092 + decimalType = 57400 + defaultKwd = 57401 + definer = 57659 + delayKeyWrite = 57660 + delayed = 57402 + deleteKwd = 57403 + denseRank = 57404 + dependency = 58030 + depth = 58031 + desc = 57405 + describe = 57406 + digest = 57661 + directory = 57662 + disable = 57663 + disabled = 57664 + discard = 57665 + disk = 57666 + distinct = 57407 + distinctRow = 57408 + div = 57409 + do = 57667 + dotType = 57944 + doubleAtIdentifier = 57353 + doubleType = 57410 + drainer = 58032 + drop = 57411 + dry = 58033 + dual = 57412 + dump = 57945 + duplicate = 57668 + dynamic = 57669 + elseKwd = 57413 + empty = 58110 + enable = 57670 + enabled = 57671 + enclosed = 57414 + encryption = 57672 + end = 57673 + enforced = 57674 + engine = 57675 + engines = 57676 + enum = 57677 + eq = 58098 yyErrCode = 57345 - errorKwd = 57673 - escape = 57674 - escaped = 57412 - event = 57675 - events = 57676 - evolve = 57677 - exact = 57930 - except = 57415 - exchange = 57678 - exclusive = 57679 - execute = 57680 - exists = 57413 - expansion = 57681 - expire = 57682 - explain = 57414 - exprPushdownBlacklist = 57931 - extended = 57683 - extract = 57932 - falseKwd = 57416 - faultsSym = 57684 - fetch = 57417 - fields = 57685 - file = 57686 - first = 57687 - firstValue = 57418 - fixed = 57688 - flashback = 57933 - floatLit = 58069 - floatType = 57419 - flush = 57689 - follower = 57934 - followerConstraints = 57935 - followers = 57936 - following = 57690 - forKwd = 57420 - force = 57421 - foreign = 57422 - format = 57691 - from = 57423 - full = 57692 - fulltext = 57424 - function = 57693 - ge = 58077 - general = 57694 - generated = 57425 - getFormat = 57937 - global = 57695 - grant = 57426 - grants = 57696 - group = 57427 - groupConcat = 57938 - groups = 57428 - hash = 57697 - having = 57429 - help = 57698 - hexLit = 58072 - highPriority = 57430 - higherThanComma = 58112 - higherThanParenthese = 58106 - hintComment = 57353 - histogram = 57699 - histogramsInFlight = 58031 - history = 57700 - hosts = 57701 - hour = 57702 - hourMicrosecond = 57431 - hourMinute = 57432 - hourSecond = 57433 - identSQLErrors = 57704 - identified = 57703 + errorKwd = 57678 + escape = 57679 + escaped = 57415 + event = 57680 + events = 57681 + evolve = 57682 + exact = 57946 + except = 57418 + exchange = 57683 + exclusive = 57684 + execute = 57685 + exists = 57416 + expansion = 57686 + expire = 57687 + explain = 57417 + exprPushdownBlacklist = 57947 + extended = 57688 + extract = 57948 + failedLoginAttempts = 57927 + falseKwd = 57419 + faultsSym = 57689 + fetch = 57420 + fields = 57690 + file = 57691 + first = 57692 + firstValue = 57421 + fixed = 57693 + flashback = 57949 + floatLit = 58091 + floatType = 57422 + flush = 57694 + follower = 57950 + followerConstraints = 57951 + followers = 57952 + following = 57695 + forKwd = 57423 + force = 57424 + foreign = 57425 + format = 57696 + from = 57426 + full = 57697 + fulltext = 57427 + function = 57698 + ge = 58099 + general = 57699 + generated = 57428 + getFormat = 57953 + global = 57700 + grant = 57429 + grants = 57701 + group = 57430 + groupConcat = 57954 + groups = 57431 + hash = 57702 + having = 57432 + help = 57703 + hexLit = 58094 + highPriority = 57433 + higherThanComma = 58134 + higherThanParenthese = 58128 + hintComment = 57355 + histogram = 57704 + histogramsInFlight = 58053 + history = 57705 + hosts = 57706 + hour = 57707 + hourMicrosecond = 57434 + hourMinute = 57435 + hourSecond = 57436 + identSQLErrors = 57709 + identified = 57708 identifier = 57346 - ifKwd = 57434 - ignore = 57435 - importKwd = 57705 - imports = 57706 - in = 57436 - increment = 57707 - incremental = 57708 - index = 57437 - indexes = 57709 - infile = 57438 - inner = 57439 - inplace = 57940 - insert = 57446 - insertMethod = 57710 - insertValues = 58095 - instance = 57711 - instant = 57941 - int1Type = 57448 - int2Type = 57449 - int3Type = 57450 - int4Type = 57451 - int8Type = 57452 - intLit = 58071 - intType = 57447 - integerType = 57440 - internal = 57942 - intersect = 57441 - interval = 57442 - into = 57443 - invalid = 57352 - invisible = 57712 - invoker = 57713 - io = 57714 - ipc = 57715 - is = 57445 - isolation = 57716 - issuer = 57717 - job = 58014 - jobs = 58013 - join = 57453 - jsonArrayagg = 57943 - jsonObjectAgg = 57944 - jsonType = 57718 - jss = 58079 - juss = 58080 - key = 57454 - keyBlockSize = 57719 - keys = 57455 - kill = 57456 - labels = 57720 - lag = 57457 - language = 57721 - last = 57722 - lastBackup = 57723 - lastValue = 57458 - lastval = 57724 - le = 58078 - lead = 57459 - leader = 57945 - leaderConstraints = 57946 - leading = 57460 - learner = 57947 - learnerConstraints = 57948 - learners = 57949 - left = 57461 - less = 57725 - level = 57726 - like = 57462 - limit = 57463 - linear = 57465 - lines = 57464 - list = 57727 - load = 57466 - local = 57728 - localTime = 57467 - localTs = 57468 - location = 57730 - lock = 57469 - locked = 57729 - logs = 57731 - long = 57559 - longblobType = 57470 - longtextType = 57471 - lowPriority = 57472 - lowerThanCharsetKwd = 58098 - lowerThanComma = 58111 - lowerThanCreateTableSelect = 58096 - lowerThanEq = 58108 - lowerThanFunction = 58103 - lowerThanInsertValues = 58094 - lowerThanKey = 58099 - lowerThanLocal = 58100 - lowerThanNot = 58110 - lowerThanOn = 58107 - lowerThanParenthese = 58105 - lowerThanRemove = 58101 - lowerThanSelectOpt = 58089 - lowerThanSelectStmt = 58093 - lowerThanSetKeyword = 58092 - lowerThanStringLitToken = 58091 - lowerThanValueKeyword = 58090 - lowerThenOrder = 58102 - lsh = 58081 - master = 57732 - match = 57473 - max = 57951 - maxConnectionsPerHour = 57735 - maxQueriesPerHour = 57736 - maxRows = 57737 - maxUpdatesPerHour = 57738 - maxUserConnections = 57739 - maxValue = 57474 - max_idxnum = 57733 - max_minutes = 57734 - mb = 57740 - mediumIntType = 57476 - mediumblobType = 57475 - mediumtextType = 57477 - memory = 57741 - merge = 57742 - microsecond = 57743 - min = 57950 - minRows = 57744 - minValue = 57746 - minute = 57745 - minuteMicrosecond = 57478 - minuteSecond = 57479 - mod = 57480 - mode = 57747 - modify = 57748 - month = 57749 - names = 57750 - national = 57751 - natural = 57573 - ncharType = 57752 - neg = 58109 - neq = 58082 - neqSynonym = 58083 - never = 57753 - next = 57754 - next_row_id = 57939 - nextval = 57755 - no = 57756 - noWriteToBinLog = 57482 - nocache = 57757 - nocycle = 57758 - nodeID = 58015 - nodeState = 58016 - nodegroup = 57759 - nomaxvalue = 57760 - nominvalue = 57761 - nonclustered = 57762 - none = 57763 - not = 57481 - not2 = 58087 - now = 57952 - nowait = 57764 - nthValue = 57483 - ntile = 57484 - null = 57485 - nulleq = 58084 - nulls = 57766 - numericType = 57486 - nvarcharType = 57765 - odbcDateType = 57356 - odbcTimeType = 57357 - odbcTimestampType = 57358 - of = 57487 - off = 57767 - offset = 57768 - on = 57488 - onDuplicate = 57769 - online = 57770 - only = 57771 - open = 57772 - optRuleBlacklist = 57953 - optimistic = 58017 - optimize = 57489 - option = 57490 - optional = 57773 - optionally = 57491 - or = 57492 - order = 57493 - outer = 57494 - outfile = 57444 - over = 57495 - packKeys = 57774 - pageSym = 57775 - paramMarker = 58085 - parser = 57776 - partial = 57777 - partition = 57496 - partitioning = 57778 - partitions = 57779 - password = 57780 - per_db = 57782 - per_table = 57783 - percent = 57781 - percentRank = 57497 - pessimistic = 58018 - pipes = 57355 - pipesAsOr = 57784 - placement = 57954 - plan = 57955 - planCache = 57956 - plugins = 57785 - policy = 57786 - position = 57957 - preSplitRegions = 57787 - preceding = 57788 - precisionType = 57498 - predicate = 57958 - prepare = 57789 - preserve = 57790 - primary = 57499 - primaryRegion = 57959 - privileges = 57791 - procedure = 57500 - process = 57792 - processlist = 57793 - profile = 57794 - profiles = 57795 - proxy = 57796 - pump = 58019 - purge = 57797 - quarter = 57798 - queries = 57799 - query = 57800 - quick = 57801 - rangeKwd = 57501 - rank = 57502 - rateLimit = 57802 - read = 57503 - realType = 57504 - rebuild = 57803 - recent = 57960 - recover = 57804 - recursive = 57505 - redundant = 57805 - references = 57506 - regexpKwd = 57507 - region = 58041 - regions = 58040 - release = 57508 - reload = 57806 - remove = 57807 - rename = 57509 - reorganize = 57808 - repair = 57809 - repeat = 57510 - repeatable = 57810 - replace = 57511 - replayer = 57961 - replica = 57811 - replicas = 57812 - replication = 57813 - require = 57512 - required = 57814 - reset = 58039 - respect = 57815 - restart = 57816 - restore = 57817 - restores = 57818 - restrict = 57513 - resume = 57819 - reverse = 57820 - revoke = 57514 - right = 57515 - rlike = 57516 - role = 57821 - rollback = 57822 - routine = 57823 - row = 57517 - rowCount = 57824 - rowFormat = 57825 - rowNumber = 57519 - rows = 57518 - rsh = 58086 - rtree = 57826 - run = 58020 - running = 57962 - s3 = 57963 - sampleRate = 58022 - samples = 58021 - san = 57827 - savepoint = 57828 - schedule = 57964 - second = 57829 - secondMicrosecond = 57520 - secondaryEngine = 57830 - secondaryLoad = 57831 - secondaryUnload = 57832 - security = 57833 - selectKwd = 57521 - sendCredentialsToTiKV = 57834 - separator = 57835 - sequence = 57836 - serial = 57837 - serializable = 57838 - session = 57839 - sessionStates = 58023 - set = 57522 - setval = 57840 - shardRowIDBits = 57841 - share = 57842 - shared = 57843 - show = 57523 - shutdown = 57844 - signed = 57845 - simple = 57846 - singleAtIdentifier = 57350 - skip = 57847 - skipSchemaFiles = 57848 - slave = 57849 - slow = 57850 - smallIntType = 57524 - snapshot = 57851 - some = 57852 - source = 57853 - spatial = 57525 - split = 58037 - sql = 57526 - sqlBigResult = 57527 - sqlBufferResult = 57854 - sqlCache = 57855 - sqlCalcFoundRows = 57528 - sqlNoCache = 57856 - sqlSmallResult = 57529 - sqlTsiDay = 57857 - sqlTsiHour = 57858 - sqlTsiMinute = 57859 - sqlTsiMonth = 57860 - sqlTsiQuarter = 57861 - sqlTsiSecond = 57862 - sqlTsiWeek = 57863 - sqlTsiYear = 57864 - ssl = 57530 - staleness = 57965 - start = 57865 - starting = 57531 - statistics = 58024 - stats = 58025 - statsAutoRecalc = 57866 - statsBuckets = 58028 - statsColChoice = 57587 - statsColList = 57588 - statsExtended = 57532 - statsHealthy = 58029 - statsHistograms = 58027 - statsMeta = 58026 - statsOptions = 57585 - statsPersistent = 57867 - statsSamplePages = 57868 - statsSampleRate = 57586 - statsTopN = 58030 - status = 57869 - std = 57966 - stddev = 57967 - stddevPop = 57968 - stddevSamp = 57969 - stop = 57970 - storage = 57870 - stored = 57537 - straightJoin = 57533 - strict = 57971 - strictFormat = 57871 - stringLit = 57349 - strong = 57972 - subDate = 57973 - subject = 57872 - subpartition = 57873 - subpartitions = 57874 - substring = 57975 - sum = 57974 - super = 57875 - swaps = 57876 - switchesSym = 57877 - system = 57878 - systemTime = 57879 - tableChecksum = 57880 - tableKwd = 57535 - tableRefPriority = 58104 - tableSample = 57536 - tables = 57881 - tablespace = 57882 - target = 57976 - telemetry = 58032 - telemetryID = 58033 - temporary = 57883 - temptable = 57884 - terminated = 57538 - textType = 57885 - than = 57886 - then = 57539 - tiFlash = 58035 - tidb = 58034 - tidbCurrentTSO = 57534 - tikvImporter = 57887 - timeType = 57889 - timestampAdd = 57977 - timestampDiff = 57978 - timestampType = 57888 - tinyIntType = 57541 - tinyblobType = 57540 - tinytextType = 57542 - tls = 57979 - to = 57543 - tokudbDefault = 57980 - tokudbFast = 57981 - tokudbLzma = 57982 - tokudbQuickLZ = 57983 - tokudbSmall = 57985 - tokudbSnappy = 57984 - tokudbUncompressed = 57986 - tokudbZlib = 57987 - tokudbZstd = 57988 - top = 57989 - topn = 58036 - tp = 57890 - trace = 57891 - traditional = 57892 - trailing = 57544 - transaction = 57893 - trigger = 57545 - triggers = 57894 - trim = 57990 - trueCardCost = 57995 - trueKwd = 57546 - truncate = 57895 - unbounded = 57896 - uncommitted = 57897 - undefined = 57898 - underscoreCS = 57348 - unicodeSym = 57899 - union = 57548 - unique = 57547 - unknown = 57900 - unlock = 57549 - unsigned = 57550 - update = 57551 - usage = 57552 - use = 57553 - user = 57901 - using = 57554 - utcDate = 57555 - utcTime = 57557 - utcTimestamp = 57556 - validation = 57902 - value = 57903 - values = 57558 - varPop = 57992 - varSamp = 57993 - varbinaryType = 57562 - varcharType = 57560 - varcharacter = 57561 - variables = 57904 - variance = 57991 - varying = 57563 - verboseType = 57994 - view = 57905 - virtual = 57564 - visible = 57906 - voter = 57996 - voterConstraints = 57997 - voters = 57998 - wait = 57913 - warnings = 57907 - week = 57908 - weightString = 57909 - when = 57565 - where = 57566 - width = 58038 - window = 57568 - with = 57569 - without = 57910 - write = 57567 - x509 = 57911 - xor = 57570 - yearMonth = 57571 - yearType = 57912 - zerofill = 57572 + ifKwd = 57437 + ignore = 57438 + importKwd = 57710 + imports = 57711 + in = 57439 + increment = 57712 + incremental = 57713 + index = 57440 + indexes = 57714 + infile = 57441 + inner = 57442 + inplace = 57956 + insert = 57449 + insertMethod = 57715 + insertValues = 58117 + instance = 57716 + instant = 57957 + int1Type = 57451 + int2Type = 57452 + int3Type = 57453 + int4Type = 57454 + int8Type = 57455 + intLit = 58093 + intType = 57450 + integerType = 57443 + internal = 57958 + intersect = 57444 + interval = 57445 + into = 57446 + invalid = 57354 + invisible = 57717 + invoker = 57718 + io = 57719 + ioReadBandwidth = 58018 + ioWriteBandwidth = 58019 + ipc = 57720 + is = 57448 + isolation = 57721 + issuer = 57722 + job = 58035 + jobs = 58034 + join = 57456 + jsonArrayagg = 57959 + jsonObjectAgg = 57960 + jsonType = 57723 + jss = 58101 + juss = 58102 + key = 57457 + keyBlockSize = 57724 + keys = 57458 + kill = 57459 + labels = 57725 + lag = 57460 + language = 57726 + last = 57727 + lastBackup = 57728 + lastValue = 57461 + lastval = 57729 + le = 58100 + lead = 57462 + leader = 57961 + leaderConstraints = 57962 + leading = 57463 + learner = 57963 + learnerConstraints = 57964 + learners = 57965 + left = 57464 + less = 57730 + level = 57731 + like = 57465 + limit = 57466 + linear = 57468 + lines = 57467 + list = 57732 + load = 57469 + local = 57733 + localTime = 57470 + localTs = 57471 + location = 57735 + lock = 57472 + locked = 57734 + logs = 57736 + long = 57562 + longblobType = 57473 + longtextType = 57474 + lowPriority = 57475 + lowerThanCharsetKwd = 58120 + lowerThanComma = 58133 + lowerThanCreateTableSelect = 58118 + lowerThanEq = 58130 + lowerThanFunction = 58125 + lowerThanInsertValues = 58116 + lowerThanKey = 58121 + lowerThanLocal = 58122 + lowerThanNot = 58132 + lowerThanOn = 58129 + lowerThanParenthese = 58127 + lowerThanRemove = 58123 + lowerThanSelectOpt = 58111 + lowerThanSelectStmt = 58115 + lowerThanSetKeyword = 58114 + lowerThanStringLitToken = 58113 + lowerThanValueKeyword = 58112 + lowerThenOrder = 58124 + lsh = 58103 + master = 57737 + match = 57476 + max = 57967 + maxConnectionsPerHour = 57740 + maxQueriesPerHour = 57741 + maxRows = 57742 + maxUpdatesPerHour = 57743 + maxUserConnections = 57744 + maxValue = 57477 + max_idxnum = 57738 + max_minutes = 57739 + mb = 57745 + mediumIntType = 57479 + mediumblobType = 57478 + mediumtextType = 57480 + member = 57746 + memberof = 57349 + memory = 57747 + merge = 57748 + microsecond = 57749 + min = 57966 + minRows = 57750 + minValue = 57752 + minute = 57751 + minuteMicrosecond = 57481 + minuteSecond = 57482 + mod = 57483 + mode = 57753 + modify = 57754 + month = 57755 + names = 57756 + national = 57757 + natural = 57576 + ncharType = 57758 + neg = 58131 + neq = 58104 + neqSynonym = 58105 + never = 57759 + next = 57760 + next_row_id = 57955 + nextval = 57761 + no = 57762 + noWriteToBinLog = 57485 + nocache = 57763 + nocycle = 57764 + nodeID = 58036 + nodeState = 58037 + nodegroup = 57765 + nomaxvalue = 57766 + nominvalue = 57767 + nonclustered = 57768 + none = 57769 + not = 57484 + not2 = 58109 + now = 57968 + nowait = 57770 + nthValue = 57486 + ntile = 57487 + null = 57488 + nulleq = 58106 + nulls = 57772 + numericType = 57489 + nvarcharType = 57771 + odbcDateType = 57358 + odbcTimeType = 57359 + odbcTimestampType = 57360 + of = 57490 + off = 57773 + offset = 57774 + on = 57491 + onDuplicate = 57775 + online = 57776 + only = 57777 + open = 57778 + optRuleBlacklist = 57969 + optimistic = 58038 + optimize = 57492 + option = 57493 + optional = 57779 + optionally = 57494 + or = 57495 + order = 57496 + outer = 57497 + outfile = 57447 + over = 57498 + packKeys = 57780 + pageSym = 57781 + paramMarker = 58107 + parser = 57782 + partial = 57783 + partition = 57499 + partitioning = 57784 + partitions = 57785 + password = 57786 + passwordLockTime = 57928 + per_db = 57788 + per_table = 57789 + percent = 57787 + percentRank = 57500 + pessimistic = 58039 + pipes = 57357 + pipesAsOr = 57790 + placement = 57970 + plan = 57971 + planCache = 57972 + plugins = 57791 + policy = 57792 + position = 57973 + preSplitRegions = 57793 + preceding = 57794 + precisionType = 57501 + predicate = 57974 + prepare = 57795 + preserve = 57796 + primary = 57502 + primaryRegion = 57975 + privileges = 57797 + procedure = 57503 + process = 57798 + processlist = 57799 + profile = 57800 + profiles = 57801 + proxy = 57802 + pump = 58040 + purge = 57803 + quarter = 57804 + queries = 57805 + query = 57806 + quick = 57807 + rangeKwd = 57504 + rank = 57505 + rateLimit = 57808 + read = 57506 + realType = 57507 + rebuild = 57809 + recent = 57976 + recover = 57810 + recursive = 57508 + redundant = 57811 + references = 57509 + regexpKwd = 57510 + region = 58063 + regions = 58062 + release = 57511 + reload = 57812 + remote = 57813 + remove = 57814 + rename = 57512 + reorganize = 57815 + repair = 57816 + repeat = 57513 + repeatable = 57817 + replace = 57514 + replayer = 57977 + replica = 57818 + replicas = 57819 + replication = 57820 + require = 57515 + required = 57821 + reset = 58061 + resource = 57822 + respect = 57823 + restart = 57824 + restore = 57825 + restores = 57826 + restrict = 57516 + resume = 57827 + reuse = 57828 + reverse = 57829 + revoke = 57517 + right = 57518 + rlike = 57519 + role = 57830 + rollback = 57831 + routine = 57832 + row = 57520 + rowCount = 57833 + rowFormat = 57834 + rowNumber = 57522 + rows = 57521 + rruRate = 58016 + rsh = 58108 + rtree = 57835 + run = 58041 + running = 57978 + s3 = 57979 + sampleRate = 58043 + samples = 58042 + san = 57836 + savepoint = 57837 + schedule = 57980 + second = 57838 + secondMicrosecond = 57523 + secondaryEngine = 57839 + secondaryLoad = 57840 + secondaryUnload = 57841 + security = 57842 + selectKwd = 57524 + sendCredentialsToTiKV = 57843 + separator = 57844 + sequence = 57845 + serial = 57846 + serializable = 57847 + session = 57848 + sessionStates = 58044 + set = 57525 + setval = 57849 + shardRowIDBits = 57850 + share = 57851 + shared = 57852 + show = 57526 + shutdown = 57853 + signed = 57854 + simple = 57855 + singleAtIdentifier = 57352 + skip = 57856 + skipSchemaFiles = 57857 + slave = 57858 + slow = 57859 + smallIntType = 57527 + snapshot = 57860 + some = 57861 + source = 57862 + spatial = 57528 + split = 58059 + sql = 57529 + sqlBigResult = 57530 + sqlBufferResult = 57863 + sqlCache = 57864 + sqlCalcFoundRows = 57531 + sqlNoCache = 57865 + sqlSmallResult = 57532 + sqlTsiDay = 57866 + sqlTsiHour = 57867 + sqlTsiMinute = 57868 + sqlTsiMonth = 57869 + sqlTsiQuarter = 57870 + sqlTsiSecond = 57871 + sqlTsiWeek = 57872 + sqlTsiYear = 57873 + ssl = 57533 + staleness = 57981 + start = 57874 + starting = 57534 + statistics = 58045 + stats = 58046 + statsAutoRecalc = 57875 + statsBuckets = 58049 + statsColChoice = 57591 + statsColList = 57592 + statsExtended = 57535 + statsHealthy = 58050 + statsHistograms = 58048 + statsLocked = 58052 + statsMeta = 58047 + statsOptions = 57589 + statsPersistent = 57876 + statsSamplePages = 57877 + statsSampleRate = 57590 + statsTopN = 58051 + status = 57878 + std = 57982 + stddev = 57983 + stddevPop = 57984 + stddevSamp = 57985 + stop = 57986 + storage = 57879 + stored = 57540 + straightJoin = 57536 + strict = 57987 + strictFormat = 57880 + stringLit = 57351 + strong = 57988 + subDate = 57989 + subject = 57881 + subpartition = 57882 + subpartitions = 57883 + substring = 57991 + sum = 57990 + super = 57884 + swaps = 57885 + switchesSym = 57886 + system = 57887 + systemTime = 57888 + tableChecksum = 57889 + tableKwd = 57538 + tableRefPriority = 58126 + tableSample = 57539 + tables = 57890 + tablespace = 57891 + target = 57992 + telemetry = 58054 + telemetryID = 58055 + temporary = 57892 + temptable = 57893 + terminated = 57541 + textType = 57894 + than = 57895 + then = 57542 + tiFlash = 58057 + tidb = 58056 + tidbCurrentTSO = 57537 + tidbJson = 57993 + tikvImporter = 57896 + timeType = 57898 + timestampAdd = 57994 + timestampDiff = 57995 + timestampType = 57897 + tinyIntType = 57544 + tinyblobType = 57543 + tinytextType = 57545 + tls = 57996 + to = 57546 + toTimestamp = 57348 + tokenIssuer = 57899 + tokudbDefault = 57997 + tokudbFast = 57998 + tokudbLzma = 57999 + tokudbQuickLZ = 58000 + tokudbSmall = 58002 + tokudbSnappy = 58001 + tokudbUncompressed = 58003 + tokudbZlib = 58004 + tokudbZstd = 58005 + top = 58006 + topn = 58058 + tp = 57900 + trace = 57901 + traditional = 57902 + trailing = 57547 + transaction = 57903 + trigger = 57548 + triggers = 57904 + trim = 58007 + trueCardCost = 58012 + trueKwd = 57549 + truncate = 57905 + ttl = 57906 + ttlEnable = 57907 + ttlJobInterval = 57908 + unbounded = 57909 + uncommitted = 57910 + undefined = 57911 + underscoreCS = 57350 + unicodeSym = 57912 + union = 57551 + unique = 57550 + unknown = 57913 + unlock = 57552 + unsigned = 57553 + update = 57554 + usage = 57555 + use = 57556 + user = 57914 + using = 57557 + utcDate = 57558 + utcTime = 57560 + utcTimestamp = 57559 + validation = 57915 + value = 57916 + values = 57561 + varPop = 58009 + varSamp = 58010 + varbinaryType = 57565 + varcharType = 57563 + varcharacter = 57564 + variables = 57917 + variance = 58008 + varying = 57566 + verboseType = 58011 + view = 57918 + virtual = 57567 + visible = 57919 + voter = 58013 + voterConstraints = 58014 + voters = 58015 + wait = 57926 + warnings = 57920 + week = 57921 + weightString = 57922 + when = 57568 + where = 57569 + width = 58060 + window = 57571 + with = 57572 + without = 57923 + write = 57570 + wruRate = 58017 + x509 = 57924 + xor = 57573 + yearMonth = 57574 + yearType = 57925 + zerofill = 57575 yyMaxDepth = 200 - yyTabOfs = -2537 + yyTabOfs = -2616 ) var ( yyXLAT = map[int]int{ - 57344: 0, // $end (2243x) - 59: 1, // ';' (2242x) - 58037: 2, // split (1872x) - 57742: 3, // merge (1871x) - 57807: 4, // remove (1870x) - 57808: 5, // reorganize (1870x) - 57627: 6, // comment (1802x) - 57870: 7, // storage (1778x) - 57590: 8, // autoIncrement (1767x) - 44: 9, // ',' (1679x) - 57687: 10, // first (1669x) - 57577: 11, // after (1663x) - 57837: 12, // serial (1659x) - 57591: 13, // autoRandom (1658x) - 57624: 14, // columnFormat (1658x) - 57780: 15, // password (1626x) - 57615: 16, // charsetKwd (1624x) - 57617: 17, // checksum (1612x) - 57954: 18, // placement (1610x) - 57719: 19, // keyBlockSize (1594x) - 57882: 20, // tablespace (1591x) - 57667: 21, // encryption (1589x) - 57670: 22, // engine (1586x) - 57650: 23, // data (1584x) - 57710: 24, // insertMethod (1582x) - 57737: 25, // maxRows (1582x) - 57744: 26, // minRows (1582x) - 57759: 27, // nodegroup (1582x) - 57634: 28, // connection (1574x) - 57592: 29, // autoRandomBase (1571x) - 58028: 30, // statsBuckets (1569x) - 58030: 31, // statsTopN (1569x) - 57589: 32, // autoIdCache (1568x) - 57594: 33, // avgRowLength (1568x) - 57632: 34, // compression (1568x) - 57656: 35, // delayKeyWrite (1568x) - 57774: 36, // packKeys (1568x) - 57787: 37, // preSplitRegions (1568x) - 57825: 38, // rowFormat (1568x) - 57830: 39, // secondaryEngine (1568x) - 57841: 40, // shardRowIDBits (1568x) - 57866: 41, // statsAutoRecalc (1568x) - 57587: 42, // statsColChoice (1568x) - 57588: 43, // statsColList (1568x) - 57867: 44, // statsPersistent (1568x) - 57868: 45, // statsSamplePages (1568x) - 57586: 46, // statsSampleRate (1568x) - 57880: 47, // tableChecksum (1568x) - 57574: 48, // account (1514x) - 41: 49, // ')' (1511x) - 57819: 50, // resume (1504x) - 57845: 51, // signed (1504x) - 57851: 52, // snapshot (1503x) - 57595: 53, // backend (1502x) - 57616: 54, // checkpoint (1502x) - 57633: 55, // concurrency (1502x) - 57639: 56, // csvBackslashEscape (1502x) - 57640: 57, // csvDelimiter (1502x) - 57641: 58, // csvHeader (1502x) - 57642: 59, // csvNotNull (1502x) - 57643: 60, // csvNull (1502x) - 57644: 61, // csvSeparator (1502x) - 57645: 62, // csvTrimLastSeparators (1502x) - 57723: 63, // lastBackup (1502x) - 57769: 64, // onDuplicate (1502x) - 57770: 65, // online (1502x) - 57802: 66, // rateLimit (1502x) - 57834: 67, // sendCredentialsToTiKV (1502x) - 57848: 68, // skipSchemaFiles (1502x) - 57871: 69, // strictFormat (1502x) - 57887: 70, // tikvImporter (1502x) - 57895: 71, // truncate (1499x) - 57756: 72, // no (1498x) - 57865: 73, // start (1496x) - 57610: 74, // cache (1493x) - 57757: 75, // nocache (1492x) - 57649: 76, // cycle (1491x) - 57746: 77, // minValue (1491x) - 57707: 78, // increment (1490x) - 57758: 79, // nocycle (1490x) - 57760: 80, // nomaxvalue (1490x) - 57761: 81, // nominvalue (1490x) - 57816: 82, // restart (1488x) - 57580: 83, // algorithm (1487x) - 57890: 84, // tp (1487x) - 57648: 85, // clustered (1486x) - 57712: 86, // invisible (1486x) - 57762: 87, // nonclustered (1486x) - 58040: 88, // regions (1486x) - 57906: 89, // visible (1486x) - 57873: 90, // subpartition (1483x) - 57779: 91, // partitions (1482x) - 57924: 92, // constraints (1479x) - 57935: 93, // followerConstraints (1479x) - 57936: 94, // followers (1479x) - 57946: 95, // leaderConstraints (1479x) - 57948: 96, // learnerConstraints (1479x) - 57949: 97, // learners (1479x) - 57959: 98, // primaryRegion (1479x) - 57964: 99, // schedule (1479x) - 57997: 100, // voterConstraints (1479x) - 57998: 101, // voters (1479x) - 57625: 102, // columns (1478x) - 57905: 103, // view (1478x) - 57912: 104, // yearType (1475x) - 57653: 105, // day (1474x) - 57583: 106, // ascii (1473x) - 57609: 107, // byteType (1473x) - 57829: 108, // second (1473x) - 57864: 109, // sqlTsiYear (1473x) - 57899: 110, // unicodeSym (1473x) - 57685: 111, // fields (1472x) - 57702: 112, // hour (1472x) - 57743: 113, // microsecond (1472x) - 57745: 114, // minute (1472x) - 57749: 115, // month (1472x) - 57798: 116, // quarter (1472x) - 57857: 117, // sqlTsiDay (1472x) - 57858: 118, // sqlTsiHour (1472x) - 57859: 119, // sqlTsiMinute (1472x) - 57860: 120, // sqlTsiMonth (1472x) - 57861: 121, // sqlTsiQuarter (1472x) - 57862: 122, // sqlTsiSecond (1472x) - 57863: 123, // sqlTsiWeek (1472x) - 57908: 124, // week (1472x) - 57881: 125, // tables (1471x) - 57869: 126, // status (1470x) - 57835: 127, // separator (1469x) - 57735: 128, // maxConnectionsPerHour (1468x) - 57736: 129, // maxQueriesPerHour (1468x) - 57738: 130, // maxUpdatesPerHour (1468x) - 57739: 131, // maxUserConnections (1468x) - 57788: 132, // preceding (1468x) - 57618: 133, // cipher (1467x) - 57705: 134, // importKwd (1467x) - 57717: 135, // issuer (1467x) - 57728: 136, // local (1467x) - 57827: 137, // san (1467x) - 57872: 138, // subject (1467x) - 57800: 139, // query (1466x) - 57847: 140, // skip (1466x) - 57602: 141, // bindings (1465x) - 57655: 142, // definer (1465x) - 57697: 143, // hash (1465x) - 57703: 144, // identified (1465x) - 57731: 145, // logs (1465x) - 57815: 146, // respect (1465x) - 57628: 147, // commit (1464x) - 57646: 148, // current (1464x) - 57669: 149, // enforced (1464x) - 57690: 150, // following (1464x) - 57346: 151, // identifier (1464x) - 57725: 152, // less (1464x) - 57764: 153, // nowait (1464x) - 57771: 154, // only (1464x) - 57822: 155, // rollback (1464x) - 57828: 156, // savepoint (1464x) - 57886: 157, // than (1464x) - 57903: 158, // value (1464x) - 57598: 159, // begin (1463x) - 57600: 160, // binding (1463x) - 57668: 161, // end (1463x) - 57695: 162, // global (1463x) - 57939: 163, // next_row_id (1463x) - 57768: 164, // offset (1463x) - 57786: 165, // policy (1463x) - 57958: 166, // predicate (1463x) - 57883: 167, // temporary (1463x) - 58035: 168, // tiFlash (1463x) - 57896: 169, // unbounded (1463x) - 57901: 170, // user (1463x) - 57718: 171, // jsonType (1462x) - 57956: 172, // planCache (1462x) - 57789: 173, // prepare (1462x) - 57821: 174, // role (1462x) - 57900: 175, // unknown (1462x) - 57913: 176, // wait (1462x) - 57608: 177, // btree (1461x) - 57651: 178, // datetimeType (1461x) - 57652: 179, // dateType (1461x) - 57688: 180, // fixed (1461x) - 57704: 181, // identSQLErrors (1461x) - 57716: 182, // isolation (1461x) - 57722: 183, // last (1461x) - 57730: 184, // location (1461x) - 57733: 185, // max_idxnum (1461x) - 57741: 186, // memory (1461x) - 57767: 187, // off (1461x) - 57773: 188, // optional (1461x) - 57782: 189, // per_db (1461x) - 57791: 190, // privileges (1461x) - 57811: 191, // replica (1461x) - 57814: 192, // required (1461x) - 57826: 193, // rtree (1461x) - 57962: 194, // running (1461x) - 58022: 195, // sampleRate (1461x) - 57836: 196, // sequence (1461x) - 57839: 197, // session (1461x) - 57850: 198, // slow (1461x) - 57888: 199, // timestampType (1461x) - 57889: 200, // timeType (1461x) - 57902: 201, // validation (1461x) - 57904: 202, // variables (1461x) - 57584: 203, // attributes (1460x) - 57630: 204, // compact (1460x) - 57658: 205, // disable (1460x) - 57663: 206, // duplicate (1460x) - 57664: 207, // dynamic (1460x) - 57665: 208, // enable (1460x) - 57673: 209, // errorKwd (1460x) - 57689: 210, // flush (1460x) - 57692: 211, // full (1460x) - 57740: 212, // mb (1460x) - 57747: 213, // mode (1460x) - 57753: 214, // never (1460x) - 57955: 215, // plan (1460x) - 57785: 216, // plugins (1460x) - 57793: 217, // processlist (1460x) - 57804: 218, // recover (1460x) - 57809: 219, // repair (1460x) - 57810: 220, // repeatable (1460x) - 58024: 221, // statistics (1460x) - 57874: 222, // subpartitions (1460x) - 58034: 223, // tidb (1460x) - 57910: 224, // without (1460x) - 57999: 225, // admin (1459x) - 57596: 226, // backup (1459x) - 58000: 227, // batch (1459x) - 57603: 228, // binlog (1459x) - 57605: 229, // block (1459x) - 57606: 230, // booleanType (1459x) - 57921: 231, // briefType (1459x) - 58001: 232, // buckets (1459x) - 58004: 233, // cardinality (1459x) - 57614: 234, // chain (1459x) - 57621: 235, // clientErrorsSummary (1459x) - 58005: 236, // cmSketch (1459x) - 57622: 237, // coalesce (1459x) - 57631: 238, // compressed (1459x) - 57637: 239, // context (1459x) - 57923: 240, // copyKwd (1459x) - 58007: 241, // correlation (1459x) - 57638: 242, // cpu (1459x) - 57654: 243, // deallocate (1459x) - 58009: 244, // dependency (1459x) - 57657: 245, // directory (1459x) - 57660: 246, // discard (1459x) - 57661: 247, // disk (1459x) - 57662: 248, // do (1459x) - 57928: 249, // dotType (1459x) - 58011: 250, // drainer (1459x) - 58012: 251, // dry (1459x) - 57678: 252, // exchange (1459x) - 57680: 253, // execute (1459x) - 57681: 254, // expansion (1459x) - 57933: 255, // flashback (1459x) - 57691: 256, // format (1459x) - 57694: 257, // general (1459x) - 57698: 258, // help (1459x) - 57699: 259, // histogram (1459x) - 57701: 260, // hosts (1459x) - 57940: 261, // inplace (1459x) - 57711: 262, // instance (1459x) - 57941: 263, // instant (1459x) - 57715: 264, // ipc (1459x) - 58014: 265, // job (1459x) - 58013: 266, // jobs (1459x) - 57720: 267, // labels (1459x) - 57729: 268, // locked (1459x) - 57748: 269, // modify (1459x) - 57754: 270, // next (1459x) - 58015: 271, // nodeID (1459x) - 58016: 272, // nodeState (1459x) - 57766: 273, // nulls (1459x) - 57775: 274, // pageSym (1459x) - 58019: 275, // pump (1459x) - 57797: 276, // purge (1459x) - 57803: 277, // rebuild (1459x) - 57805: 278, // redundant (1459x) - 57806: 279, // reload (1459x) - 57817: 280, // restore (1459x) - 57823: 281, // routine (1459x) - 57963: 282, // s3 (1459x) - 58021: 283, // samples (1459x) - 57831: 284, // secondaryLoad (1459x) - 57832: 285, // secondaryUnload (1459x) - 57842: 286, // share (1459x) - 57844: 287, // shutdown (1459x) - 57853: 288, // source (1459x) - 58025: 289, // stats (1459x) - 57585: 290, // statsOptions (1459x) - 57970: 291, // stop (1459x) - 57876: 292, // swaps (1459x) - 57980: 293, // tokudbDefault (1459x) - 57981: 294, // tokudbFast (1459x) - 57982: 295, // tokudbLzma (1459x) - 57983: 296, // tokudbQuickLZ (1459x) - 57985: 297, // tokudbSmall (1459x) - 57984: 298, // tokudbSnappy (1459x) - 57986: 299, // tokudbUncompressed (1459x) - 57987: 300, // tokudbZlib (1459x) - 57988: 301, // tokudbZstd (1459x) - 58036: 302, // topn (1459x) - 57891: 303, // trace (1459x) - 57892: 304, // traditional (1459x) - 57995: 305, // trueCardCost (1459x) - 57994: 306, // verboseType (1459x) - 57907: 307, // warnings (1459x) - 57575: 308, // action (1458x) - 57576: 309, // advise (1458x) - 57578: 310, // against (1458x) - 57579: 311, // ago (1458x) - 57581: 312, // always (1458x) - 57597: 313, // backups (1458x) - 57599: 314, // bernoulli (1458x) - 57601: 315, // bindingCache (1458x) - 57604: 316, // bitType (1458x) - 57607: 317, // boolType (1458x) - 58002: 318, // builtins (1458x) - 58003: 319, // cancel (1458x) - 57611: 320, // capture (1458x) - 57612: 321, // cascaded (1458x) - 57613: 322, // causal (1458x) - 57619: 323, // cleanup (1458x) - 57620: 324, // client (1458x) - 57647: 325, // cluster (1458x) - 57623: 326, // collation (1458x) - 58006: 327, // columnStatsUsage (1458x) - 57629: 328, // committed (1458x) - 57626: 329, // config (1458x) - 57635: 330, // consistency (1458x) - 57636: 331, // consistent (1458x) - 58008: 332, // ddl (1458x) - 58010: 333, // depth (1458x) - 57659: 334, // disabled (1458x) - 57929: 335, // dump (1458x) - 57666: 336, // enabled (1458x) - 57671: 337, // engines (1458x) - 57672: 338, // enum (1458x) - 57676: 339, // events (1458x) - 57677: 340, // evolve (1458x) - 57682: 341, // expire (1458x) - 57931: 342, // exprPushdownBlacklist (1458x) - 57683: 343, // extended (1458x) - 57684: 344, // faultsSym (1458x) - 57693: 345, // function (1458x) - 57696: 346, // grants (1458x) - 58031: 347, // histogramsInFlight (1458x) - 57700: 348, // history (1458x) - 57706: 349, // imports (1458x) - 57708: 350, // incremental (1458x) - 57709: 351, // indexes (1458x) - 57942: 352, // internal (1458x) - 57713: 353, // invoker (1458x) - 57714: 354, // io (1458x) - 57721: 355, // language (1458x) - 57726: 356, // level (1458x) - 57727: 357, // list (1458x) - 57732: 358, // master (1458x) - 57734: 359, // max_minutes (1458x) - 57751: 360, // national (1458x) - 57752: 361, // ncharType (1458x) - 57755: 362, // nextval (1458x) - 57763: 363, // none (1458x) - 57765: 364, // nvarcharType (1458x) - 57772: 365, // open (1458x) - 58017: 366, // optimistic (1458x) - 57953: 367, // optRuleBlacklist (1458x) - 57776: 368, // parser (1458x) - 57777: 369, // partial (1458x) - 57778: 370, // partitioning (1458x) - 57783: 371, // per_table (1458x) - 57781: 372, // percent (1458x) - 58018: 373, // pessimistic (1458x) - 57790: 374, // preserve (1458x) - 57794: 375, // profile (1458x) - 57795: 376, // profiles (1458x) - 57799: 377, // queries (1458x) - 57960: 378, // recent (1458x) - 58041: 379, // region (1458x) - 57961: 380, // replayer (1458x) - 58039: 381, // reset (1458x) - 57818: 382, // restores (1458x) - 58020: 383, // run (1458x) - 57833: 384, // security (1458x) - 57838: 385, // serializable (1458x) - 58023: 386, // sessionStates (1458x) - 57846: 387, // simple (1458x) - 57849: 388, // slave (1458x) - 58029: 389, // statsHealthy (1458x) - 58027: 390, // statsHistograms (1458x) - 58026: 391, // statsMeta (1458x) - 57971: 392, // strict (1458x) - 57877: 393, // switchesSym (1458x) - 57878: 394, // system (1458x) - 57879: 395, // systemTime (1458x) - 57976: 396, // target (1458x) - 58033: 397, // telemetryID (1458x) - 57884: 398, // temptable (1458x) - 57885: 399, // textType (1458x) - 57979: 400, // tls (1458x) - 57989: 401, // top (1458x) - 57893: 402, // transaction (1458x) - 57894: 403, // triggers (1458x) - 57897: 404, // uncommitted (1458x) - 57898: 405, // undefined (1458x) - 58038: 406, // width (1458x) - 57911: 407, // x509 (1458x) - 57914: 408, // addDate (1457x) - 57582: 409, // any (1457x) - 57915: 410, // approxCountDistinct (1457x) - 57916: 411, // approxPercentile (1457x) - 57593: 412, // avg (1457x) - 57917: 413, // bitAnd (1457x) - 57918: 414, // bitOr (1457x) - 57919: 415, // bitXor (1457x) - 57920: 416, // bound (1457x) - 57922: 417, // cast (1457x) - 57925: 418, // curTime (1457x) - 57926: 419, // dateAdd (1457x) - 57927: 420, // dateSub (1457x) - 57674: 421, // escape (1457x) - 57675: 422, // event (1457x) - 57930: 423, // exact (1457x) - 57679: 424, // exclusive (1457x) - 57932: 425, // extract (1457x) - 57686: 426, // file (1457x) - 57934: 427, // follower (1457x) - 57937: 428, // getFormat (1457x) - 57938: 429, // groupConcat (1457x) - 57943: 430, // jsonArrayagg (1457x) - 57944: 431, // jsonObjectAgg (1457x) - 57724: 432, // lastval (1457x) - 57945: 433, // leader (1457x) - 57947: 434, // learner (1457x) - 57951: 435, // max (1457x) - 57950: 436, // min (1457x) - 57750: 437, // names (1457x) - 57952: 438, // now (1457x) - 57957: 439, // position (1457x) - 57792: 440, // process (1457x) - 57796: 441, // proxy (1457x) - 57801: 442, // quick (1457x) - 57812: 443, // replicas (1457x) - 57813: 444, // replication (1457x) - 57820: 445, // reverse (1457x) - 57824: 446, // rowCount (1457x) - 57840: 447, // setval (1457x) - 57843: 448, // shared (1457x) - 57852: 449, // some (1457x) - 57854: 450, // sqlBufferResult (1457x) - 57855: 451, // sqlCache (1457x) - 57856: 452, // sqlNoCache (1457x) - 57965: 453, // staleness (1457x) - 57966: 454, // std (1457x) - 57967: 455, // stddev (1457x) - 57968: 456, // stddevPop (1457x) - 57969: 457, // stddevSamp (1457x) - 57972: 458, // strong (1457x) - 57973: 459, // subDate (1457x) - 57975: 460, // substring (1457x) - 57974: 461, // sum (1457x) - 57875: 462, // super (1457x) - 58032: 463, // telemetry (1457x) - 57977: 464, // timestampAdd (1457x) - 57978: 465, // timestampDiff (1457x) - 57990: 466, // trim (1457x) - 57991: 467, // variance (1457x) - 57992: 468, // varPop (1457x) - 57993: 469, // varSamp (1457x) - 57996: 470, // voter (1457x) - 57909: 471, // weightString (1457x) - 57488: 472, // on (1395x) - 40: 473, // '(' (1324x) - 57569: 474, // with (1211x) - 57349: 475, // stringLit (1195x) - 58087: 476, // not2 (1192x) - 57481: 477, // not (1129x) - 57364: 478, // as (1106x) - 57398: 479, // defaultKwd (1100x) - 57548: 480, // union (1058x) - 57554: 481, // using (1051x) - 57461: 482, // left (1046x) - 57515: 483, // right (1046x) - 57379: 484, // collate (1043x) - 43: 485, // '+' (1023x) - 45: 486, // '-' (1022x) - 57480: 487, // mod (1002x) - 57496: 488, // partition (962x) - 57435: 489, // ignore (957x) - 57415: 490, // except (950x) - 57441: 491, // intersect (949x) - 57485: 492, // null (947x) - 57463: 493, // limit (930x) - 57420: 494, // forKwd (927x) - 57558: 495, // values (922x) - 57443: 496, // into (920x) - 57469: 497, // lock (916x) - 57566: 498, // where (910x) - 58076: 499, // eq (908x) - 57423: 500, // from (908x) - 57417: 501, // fetch (906x) - 57493: 502, // order (902x) - 57421: 503, // force (898x) - 57511: 504, // replace (895x) - 57377: 505, // charType (894x) - 57522: 506, // set (889x) - 57363: 507, // and (887x) - 58071: 508, // intLit (884x) - 57492: 509, // or (864x) - 57354: 510, // andand (863x) - 57784: 511, // pipesAsOr (863x) - 57570: 512, // xor (863x) - 57427: 513, // group (837x) - 57429: 514, // having (837x) - 57533: 515, // straightJoin (831x) - 57568: 516, // window (823x) - 57453: 517, // join (819x) - 57462: 518, // like (811x) - 57573: 519, // natural (809x) - 42: 520, // '*' (808x) - 57384: 521, // cross (808x) - 57439: 522, // inner (808x) - 125: 523, // '}' (805x) - 57518: 524, // rows (793x) - 57553: 525, // use (789x) - 57536: 526, // tableSample (783x) - 57501: 527, // rangeKwd (782x) - 57428: 528, // groups (781x) - 57402: 529, // desc (780x) - 57368: 530, // binaryType (779x) - 57365: 531, // asc (778x) - 57393: 532, // dayHour (778x) - 57394: 533, // dayMicrosecond (778x) - 57395: 534, // dayMinute (778x) - 57396: 535, // daySecond (778x) - 57431: 536, // hourMicrosecond (778x) - 57432: 537, // hourMinute (778x) - 57433: 538, // hourSecond (778x) - 57478: 539, // minuteMicrosecond (778x) - 57479: 540, // minuteSecond (778x) - 57520: 541, // secondMicrosecond (778x) - 57571: 542, // yearMonth (778x) - 57565: 543, // when (775x) - 57436: 544, // in (773x) - 57410: 545, // elseKwd (772x) - 57539: 546, // then (769x) - 47: 547, // '/' (766x) - 37: 548, // '%' (765x) - 38: 549, // '&' (765x) - 94: 550, // '^' (765x) - 124: 551, // '|' (765x) - 57406: 552, // div (765x) - 58081: 553, // lsh (765x) - 58086: 554, // rsh (765x) - 60: 555, // '<' (762x) - 62: 556, // '>' (762x) - 58077: 557, // ge (762x) - 57445: 558, // is (762x) - 58078: 559, // le (762x) - 58082: 560, // neq (762x) - 58083: 561, // neqSynonym (762x) - 58084: 562, // nulleq (762x) - 57366: 563, // between (760x) - 57434: 564, // ifKwd (755x) - 57507: 565, // regexpKwd (752x) - 57516: 566, // rlike (752x) - 57446: 567, // insert (741x) - 57350: 568, // singleAtIdentifier (736x) - 57535: 569, // tableKwd (736x) - 57389: 570, // currentUser (732x) - 57416: 571, // falseKwd (730x) - 57546: 572, // trueKwd (730x) - 58070: 573, // decLit (724x) - 58069: 574, // floatLit (724x) - 57517: 575, // row (724x) - 58072: 576, // hexLit (722x) - 58085: 577, // paramMarker (722x) - 57442: 578, // interval (721x) - 123: 579, // '{' (720x) - 58073: 580, // bitLit (720x) - 57454: 581, // key (720x) - 57391: 582, // database (715x) - 57413: 583, // exists (715x) - 57382: 584, // convert (712x) - 58057: 585, // builtinNow (711x) - 57388: 586, // currentTs (711x) - 57351: 587, // doubleAtIdentifier (711x) - 57467: 588, // localTime (711x) - 57468: 589, // localTs (711x) - 57378: 590, // check (710x) - 57499: 591, // primary (710x) - 57348: 592, // underscoreCS (710x) - 58046: 593, // builtinCount (709x) - 57355: 594, // pipes (709x) - 33: 595, // '!' (708x) - 126: 596, // '~' (708x) - 58047: 597, // builtinApproxCountDistinct (708x) - 58048: 598, // builtinApproxPercentile (708x) - 58042: 599, // builtinBitAnd (708x) - 58043: 600, // builtinBitOr (708x) - 58044: 601, // builtinBitXor (708x) - 58045: 602, // builtinCast (708x) - 58049: 603, // builtinCurDate (708x) - 58050: 604, // builtinCurTime (708x) - 58051: 605, // builtinDateAdd (708x) - 58052: 606, // builtinDateSub (708x) - 58053: 607, // builtinExtract (708x) - 58054: 608, // builtinGroupConcat (708x) - 58055: 609, // builtinMax (708x) - 58056: 610, // builtinMin (708x) - 58058: 611, // builtinPosition (708x) - 58062: 612, // builtinStddevPop (708x) - 58063: 613, // builtinStddevSamp (708x) - 58059: 614, // builtinSubstring (708x) - 58060: 615, // builtinSum (708x) - 58061: 616, // builtinSysDate (708x) - 58064: 617, // builtinTranslate (708x) - 58065: 618, // builtinTrim (708x) - 58066: 619, // builtinUser (708x) - 58067: 620, // builtinVarPop (708x) - 58068: 621, // builtinVarSamp (708x) - 57374: 622, // caseKwd (708x) - 57385: 623, // cumeDist (708x) - 57386: 624, // currentDate (708x) - 57390: 625, // currentRole (708x) - 57387: 626, // currentTime (708x) - 57401: 627, // denseRank (708x) - 57418: 628, // firstValue (708x) - 57457: 629, // lag (708x) - 57458: 630, // lastValue (708x) - 57459: 631, // lead (708x) - 57483: 632, // nthValue (708x) - 57484: 633, // ntile (708x) - 57497: 634, // percentRank (708x) - 57502: 635, // rank (708x) - 57510: 636, // repeat (708x) - 57519: 637, // rowNumber (708x) - 57534: 638, // tidbCurrentTSO (708x) - 57555: 639, // utcDate (708x) - 57557: 640, // utcTime (708x) - 57556: 641, // utcTimestamp (708x) - 57547: 642, // unique (703x) - 57381: 643, // constraint (701x) - 57506: 644, // references (698x) - 57425: 645, // generated (694x) - 57521: 646, // selectKwd (693x) - 57376: 647, // character (658x) - 57473: 648, // match (650x) - 57437: 649, // index (646x) - 57543: 650, // to (569x) - 57360: 651, // all (554x) - 46: 652, // '.' (549x) - 57362: 653, // analyze (533x) - 57551: 654, // update (523x) - 57474: 655, // maxValue (517x) - 58079: 656, // jss (515x) - 58080: 657, // juss (515x) - 57464: 658, // lines (504x) - 58075: 659, // assignmentEq (501x) - 57371: 660, // by (501x) - 58339: 661, // Identifier (499x) - 58417: 662, // NotKeywordToken (499x) - 58645: 663, // TiDBKeyword (499x) - 58655: 664, // UnReservedKeyword (499x) - 57361: 665, // alter (498x) - 57512: 666, // require (496x) - 64: 667, // '@' (491x) - 57526: 668, // sql (488x) - 57408: 669, // drop (485x) - 57373: 670, // cascade (484x) - 57503: 671, // read (484x) - 57513: 672, // restrict (484x) - 57347: 673, // asof (482x) - 57383: 674, // create (480x) - 57422: 675, // foreign (480x) - 57424: 676, // fulltext (480x) - 57561: 677, // varcharacter (478x) - 57560: 678, // varcharType (478x) - 57375: 679, // change (477x) - 57397: 680, // decimalType (477x) - 57407: 681, // doubleType (477x) - 57419: 682, // floatType (477x) - 57440: 683, // integerType (477x) - 57447: 684, // intType (477x) - 57504: 685, // realType (477x) - 57509: 686, // rename (477x) - 57567: 687, // write (477x) - 57562: 688, // varbinaryType (476x) - 57359: 689, // add (475x) - 57367: 690, // bigIntType (475x) - 57369: 691, // blobType (475x) - 57448: 692, // int1Type (475x) - 57449: 693, // int2Type (475x) - 57450: 694, // int3Type (475x) - 57451: 695, // int4Type (475x) - 57452: 696, // int8Type (475x) - 57559: 697, // long (475x) - 57470: 698, // longblobType (475x) - 57471: 699, // longtextType (475x) - 57475: 700, // mediumblobType (475x) - 57476: 701, // mediumIntType (475x) - 57477: 702, // mediumtextType (475x) - 57486: 703, // numericType (475x) - 57489: 704, // optimize (475x) - 57524: 705, // smallIntType (475x) - 57540: 706, // tinyblobType (475x) - 57541: 707, // tinyIntType (475x) - 57542: 708, // tinytextType (475x) - 58610: 709, // SubSelect (223x) - 58664: 710, // UserVariable (181x) - 58585: 711, // SimpleIdent (180x) - 58392: 712, // Literal (178x) - 58600: 713, // StringLiteral (178x) - 58414: 714, // NextValueForSequence (177x) - 58316: 715, // FunctionCallGeneric (176x) - 58317: 716, // FunctionCallKeyword (176x) - 58318: 717, // FunctionCallNonKeyword (176x) - 58319: 718, // FunctionNameConflict (176x) - 58320: 719, // FunctionNameDateArith (176x) - 58321: 720, // FunctionNameDateArithMultiForms (176x) - 58322: 721, // FunctionNameDatetimePrecision (176x) - 58323: 722, // FunctionNameOptionalBraces (176x) - 58324: 723, // FunctionNameSequence (176x) - 58584: 724, // SimpleExpr (176x) - 58611: 725, // SumExpr (176x) - 58613: 726, // SystemVariable (176x) - 58675: 727, // Variable (176x) - 58698: 728, // WindowFuncCall (176x) - 58164: 729, // BitExpr (163x) - 58491: 730, // PredicateExpr (132x) - 58167: 731, // BoolPri (129x) - 58281: 732, // Expression (129x) - 58412: 733, // NUM (103x) - 58713: 734, // logAnd (97x) - 58714: 735, // logOr (97x) - 58271: 736, // EqOpt (75x) - 58623: 737, // TableName (75x) - 58601: 738, // StringName (56x) - 57400: 739, // deleteKwd (52x) - 57550: 740, // unsigned (47x) - 58383: 741, // LengthNum (46x) - 57495: 742, // over (45x) - 57572: 743, // zerofill (45x) - 58190: 744, // ColumnName (41x) - 57404: 745, // distinct (36x) - 57405: 746, // distinctRow (36x) - 58703: 747, // WindowingClause (35x) - 58539: 748, // SelectStmt (34x) - 58540: 749, // SelectStmtBasic (34x) - 58542: 750, // SelectStmtFromDualTable (34x) - 58543: 751, // SelectStmtFromTable (34x) - 58560: 752, // SetOprClause (34x) - 57399: 753, // delayed (33x) - 57430: 754, // highPriority (33x) - 57472: 755, // lowPriority (33x) - 58561: 756, // SetOprClauseList (33x) - 58564: 757, // SetOprStmtWithLimitOrderBy (33x) - 58565: 758, // SetOprStmtWoutLimitOrderBy (33x) - 58704: 759, // WithClause (31x) - 58552: 760, // SelectStmtWithClause (30x) - 58563: 761, // SetOprStmt (30x) - 57353: 762, // hintComment (27x) - 58371: 763, // Int64Num (26x) - 58292: 764, // FieldLen (25x) - 58456: 765, // OptWindowingClause (24x) - 58246: 766, // DeleteWithoutUsingStmt (23x) - 58462: 767, // OrderBy (23x) - 58546: 768, // SelectStmtLimit (23x) - 57527: 769, // sqlBigResult (23x) - 57528: 770, // sqlCalcFoundRows (23x) - 57529: 771, // sqlSmallResult (23x) - 58658: 772, // UpdateStmtNoWith (22x) - 58178: 773, // CharsetKw (20x) - 58368: 774, // InsertIntoStmt (20x) - 58513: 775, // ReplaceIntoStmt (20x) - 58657: 776, // UpdateStmt (20x) - 58666: 777, // Username (20x) - 58282: 778, // ExpressionList (18x) - 58245: 779, // DeleteWithUsingStmt (17x) - 58340: 780, // IfExists (17x) - 58486: 781, // PlacementPolicyOption (17x) - 57538: 782, // terminated (16x) - 58244: 783, // DeleteFromStmt (15x) - 58248: 784, // DistinctKwd (15x) - 58341: 785, // IfNotExists (15x) - 58474: 786, // PartitionNameList (15x) - 58249: 787, // DistinctOpt (14x) - 57411: 788, // enclosed (14x) - 58441: 789, // OptFieldLen (14x) - 58688: 790, // WhereClause (14x) - 58689: 791, // WhereClauseOptional (14x) - 58241: 792, // DefaultKwdOpt (13x) - 57412: 793, // escaped (13x) - 57491: 794, // optionally (13x) - 58624: 795, // TableNameList (13x) - 58647: 796, // TimestampUnit (13x) - 58280: 797, // ExprOrDefault (12x) - 58377: 798, // JoinTable (12x) - 58435: 799, // OptBinary (12x) - 57508: 800, // release (12x) - 58529: 801, // RolenameComposed (12x) - 58620: 802, // TableFactor (12x) - 58633: 803, // TableRef (12x) - 58137: 804, // AnalyzeOptionListOpt (11x) - 58311: 805, // FromOrIn (11x) - 58133: 806, // AlterTableStmt (10x) - 58179: 807, // CharsetName (10x) - 58191: 808, // ColumnNameList (10x) - 57466: 809, // load (10x) - 58418: 810, // NotSym (10x) - 57482: 811, // noWriteToBinLog (10x) - 58463: 812, // OrderByOptional (10x) - 58465: 813, // PartDefOption (10x) - 58583: 814, // SignedNum (10x) - 58646: 815, // TimeUnit (10x) - 58170: 816, // BuggyDefaultFalseDistinctOpt (9x) - 58231: 817, // DBName (9x) - 58240: 818, // DefaultFalseDistinctOpt (9x) - 58378: 819, // JoinType (9x) - 58425: 820, // NumLiteral (9x) - 58528: 821, // Rolename (9x) - 58523: 822, // RoleNameString (9x) - 58230: 823, // CrossOpt (8x) - 58272: 824, // EqOrAssignmentEq (8x) - 58279: 825, // ExplainableStmt (8x) - 58283: 826, // ExpressionListOpt (8x) - 58362: 827, // IndexPartSpecification (8x) - 58379: 828, // KeyOrIndex (8x) - 58415: 829, // NoWriteToBinLogAliasOpt (8x) - 58547: 830, // SelectStmtLimitOpt (8x) - 58678: 831, // VariableName (8x) - 58119: 832, // AllOrPartitionNameList (7x) - 58214: 833, // ConstraintKeywordOpt (7x) - 58298: 834, // FieldsOrColumns (7x) - 58309: 835, // ForceOpt (7x) - 58363: 836, // IndexPartSpecificationList (7x) - 58495: 837, // Priority (7x) - 58533: 838, // RowFormat (7x) - 58536: 839, // RowValue (7x) - 58558: 840, // SetExpr (7x) - 58569: 841, // ShowDatabaseNameOpt (7x) - 58630: 842, // TableOption (7x) - 57563: 843, // varying (7x) - 58138: 844, // AnalyzeTableStmt (6x) - 58159: 845, // BeginTransactionStmt (6x) - 58161: 846, // BindableStmt (6x) - 57380: 847, // column (6x) - 58185: 848, // ColumnDef (6x) - 58204: 849, // CommitStmt (6x) - 58233: 850, // DatabaseOption (6x) - 58236: 851, // DatabaseSym (6x) - 58274: 852, // EscapedTableRef (6x) - 58296: 853, // FieldTerminator (6x) - 57426: 854, // grant (6x) - 58345: 855, // IgnoreOptional (6x) - 58354: 856, // IndexInvisible (6x) - 58359: 857, // IndexNameList (6x) - 58365: 858, // IndexType (6x) - 58396: 859, // LoadDataStmt (6x) - 58475: 860, // PartitionNameListOpt (6x) - 58508: 861, // ReleaseSavepointStmt (6x) - 58530: 862, // RolenameList (6x) - 58532: 863, // RollbackStmt (6x) - 58537: 864, // SavepointStmt (6x) - 58568: 865, // SetStmt (6x) - 57523: 866, // show (6x) - 58628: 867, // TableOptimizerHints (6x) - 58667: 868, // UsernameList (6x) - 58705: 869, // WithClustered (6x) - 58117: 870, // AlgorithmClause (5x) - 58172: 871, // ByItem (5x) - 58184: 872, // CollationName (5x) - 58188: 873, // ColumnKeywordOpt (5x) - 58247: 874, // DirectPlacementOption (5x) - 58294: 875, // FieldOpt (5x) - 58295: 876, // FieldOpts (5x) - 58337: 877, // IdentList (5x) - 58357: 878, // IndexName (5x) - 58360: 879, // IndexOption (5x) - 58361: 880, // IndexOptionList (5x) - 57438: 881, // infile (5x) - 58388: 882, // LimitOption (5x) - 58400: 883, // LockClause (5x) - 58437: 884, // OptCharsetWithOptBinary (5x) - 58448: 885, // OptNullTreatment (5x) - 58489: 886, // PolicyName (5x) - 58496: 887, // PriorityOpt (5x) - 58538: 888, // SelectLockOpt (5x) - 58545: 889, // SelectStmtIntoOption (5x) - 58634: 890, // TableRefs (5x) - 58660: 891, // UserSpec (5x) - 58143: 892, // Assignment (4x) - 58149: 893, // AuthString (4x) - 58151: 894, // BRIEBooleanOptionName (4x) - 58152: 895, // BRIEIntegerOptionName (4x) - 58153: 896, // BRIEKeywordOptionName (4x) - 58154: 897, // BRIEOption (4x) - 58155: 898, // BRIEOptions (4x) - 58157: 899, // BRIEStringOptionName (4x) - 58173: 900, // ByList (4x) - 58177: 901, // Char (4x) - 58208: 902, // ConfigItemName (4x) - 58212: 903, // Constraint (4x) - 58305: 904, // FloatOpt (4x) - 58366: 905, // IndexTypeName (4x) - 57490: 906, // option (4x) - 58453: 907, // OptWild (4x) - 57494: 908, // outer (4x) - 58490: 909, // Precision (4x) - 58504: 910, // ReferDef (4x) - 58519: 911, // RestrictOrCascadeOpt (4x) - 58535: 912, // RowStmt (4x) - 58553: 913, // SequenceOption (4x) - 57532: 914, // statsExtended (4x) - 58615: 915, // TableAsName (4x) - 58616: 916, // TableAsNameOpt (4x) - 58627: 917, // TableNameOptWild (4x) - 58629: 918, // TableOptimizerHintsOpt (4x) - 58631: 919, // TableOptionList (4x) - 58649: 920, // TraceableStmt (4x) - 58650: 921, // TransactionChar (4x) - 58661: 922, // UserSpecList (4x) - 58699: 923, // WindowName (4x) - 58140: 924, // AsOfClause (3x) - 58144: 925, // AssignmentList (3x) - 58146: 926, // AttributesOpt (3x) - 58168: 927, // Boolean (3x) - 58197: 928, // ColumnOption (3x) - 58200: 929, // ColumnPosition (3x) - 58205: 930, // CommonTableExpr (3x) - 58226: 931, // CreateTableStmt (3x) - 58234: 932, // DatabaseOptionList (3x) - 58242: 933, // DefaultTrueDistinctOpt (3x) - 58268: 934, // EnforcedOrNot (3x) - 57414: 935, // explain (3x) - 58285: 936, // ExtendedPriv (3x) - 58325: 937, // GeneratedAlways (3x) - 58327: 938, // GlobalScope (3x) - 58331: 939, // GroupByClause (3x) - 58349: 940, // IndexHint (3x) - 58353: 941, // IndexHintType (3x) - 58358: 942, // IndexNameAndTypeOpt (3x) - 57455: 943, // keys (3x) - 58390: 944, // Lines (3x) - 58409: 945, // MaxValueOrExpression (3x) - 58419: 946, // NowSym (3x) - 58420: 947, // NowSymFunc (3x) - 58421: 948, // NowSymOptionFraction (3x) - 58449: 949, // OptOrder (3x) - 58452: 950, // OptTemporary (3x) - 58466: 951, // PartDefOptionList (3x) - 58468: 952, // PartitionDefinition (3x) - 58478: 953, // PasswordExpire (3x) - 58480: 954, // PasswordOrLockOption (3x) - 58488: 955, // PluginNameList (3x) - 58494: 956, // PrimaryOpt (3x) - 58497: 957, // PrivElem (3x) - 58499: 958, // PrivType (3x) - 57500: 959, // procedure (3x) - 58514: 960, // RequireClause (3x) - 58515: 961, // RequireClauseOpt (3x) - 58517: 962, // RequireListElement (3x) - 58531: 963, // RolenameWithoutIdent (3x) - 58524: 964, // RoleOrPrivElem (3x) - 58544: 965, // SelectStmtGroup (3x) - 58562: 966, // SetOprOpt (3x) - 58614: 967, // TableAliasRefList (3x) - 58617: 968, // TableElement (3x) - 58626: 969, // TableNameListOpt2 (3x) - 58642: 970, // TextString (3x) - 58651: 971, // TransactionChars (3x) - 57545: 972, // trigger (3x) - 57549: 973, // unlock (3x) - 57552: 974, // usage (3x) - 58671: 975, // ValuesList (3x) - 58673: 976, // ValuesStmtList (3x) - 58669: 977, // ValueSym (3x) - 58676: 978, // VariableAssignment (3x) - 58696: 979, // WindowFrameStart (3x) - 58115: 980, // AdminStmt (2x) - 58118: 981, // AllColumnsOrPredicateColumnsOpt (2x) - 58120: 982, // AlterDatabaseStmt (2x) - 58121: 983, // AlterImportStmt (2x) - 58122: 984, // AlterInstanceStmt (2x) - 58123: 985, // AlterOrderItem (2x) - 58125: 986, // AlterPolicyStmt (2x) - 58126: 987, // AlterSequenceOption (2x) - 58128: 988, // AlterSequenceStmt (2x) - 58130: 989, // AlterTableSpec (2x) - 58134: 990, // AlterUserStmt (2x) - 58135: 991, // AnalyzeOption (2x) - 58163: 992, // BinlogStmt (2x) - 58156: 993, // BRIEStmt (2x) - 58158: 994, // BRIETables (2x) - 58171: 995, // BuiltinFunction (2x) - 57372: 996, // call (2x) - 58174: 997, // CallStmt (2x) - 58175: 998, // CastType (2x) - 58176: 999, // ChangeStmt (2x) - 58182: 1000, // CheckConstraintKeyword (2x) - 58192: 1001, // ColumnNameListOpt (2x) - 58195: 1002, // ColumnNameOrUserVariable (2x) - 58198: 1003, // ColumnOptionList (2x) - 58199: 1004, // ColumnOptionListOpt (2x) - 58201: 1005, // ColumnSetValue (2x) - 58207: 1006, // CompletionTypeWithinTransaction (2x) - 58209: 1007, // ConnectionOption (2x) - 58211: 1008, // ConnectionOptions (2x) - 58215: 1009, // CreateBindingStmt (2x) - 58216: 1010, // CreateDatabaseStmt (2x) - 58217: 1011, // CreateImportStmt (2x) - 58218: 1012, // CreateIndexStmt (2x) - 58219: 1013, // CreatePolicyStmt (2x) - 58220: 1014, // CreateRoleStmt (2x) - 58222: 1015, // CreateSequenceStmt (2x) - 58223: 1016, // CreateStatisticsStmt (2x) - 58224: 1017, // CreateTableOptionListOpt (2x) - 58227: 1018, // CreateUserStmt (2x) - 58229: 1019, // CreateViewStmt (2x) - 57392: 1020, // databases (2x) - 58238: 1021, // DeallocateStmt (2x) - 58239: 1022, // DeallocateSym (2x) - 57403: 1023, // describe (2x) - 58250: 1024, // DoStmt (2x) - 58251: 1025, // DropBindingStmt (2x) - 58252: 1026, // DropDatabaseStmt (2x) - 58253: 1027, // DropImportStmt (2x) - 58254: 1028, // DropIndexStmt (2x) - 58255: 1029, // DropPolicyStmt (2x) - 58256: 1030, // DropRoleStmt (2x) - 58257: 1031, // DropSequenceStmt (2x) - 58258: 1032, // DropStatisticsStmt (2x) - 58259: 1033, // DropStatsStmt (2x) - 58260: 1034, // DropTableStmt (2x) - 58261: 1035, // DropUserStmt (2x) - 58262: 1036, // DropViewStmt (2x) - 58264: 1037, // DuplicateOpt (2x) - 58266: 1038, // EmptyStmt (2x) - 58267: 1039, // EncryptionOpt (2x) - 58269: 1040, // EnforcedOrNotOpt (2x) - 58273: 1041, // ErrorHandling (2x) - 58275: 1042, // ExecuteStmt (2x) - 58276: 1043, // ExplainFormatType (2x) - 58277: 1044, // ExplainStmt (2x) - 58278: 1045, // ExplainSym (2x) - 58287: 1046, // Field (2x) - 58290: 1047, // FieldItem (2x) - 58297: 1048, // Fields (2x) - 58302: 1049, // FlashbackClusterStmt (2x) - 58303: 1050, // FlashbackTableStmt (2x) - 58308: 1051, // FlushStmt (2x) - 58314: 1052, // FuncDatetimePrecList (2x) - 58315: 1053, // FuncDatetimePrecListOpt (2x) - 58328: 1054, // GrantProxyStmt (2x) - 58329: 1055, // GrantRoleStmt (2x) - 58330: 1056, // GrantStmt (2x) - 58332: 1057, // HandleRange (2x) - 58334: 1058, // HashString (2x) - 58335: 1059, // HavingClause (2x) - 58336: 1060, // HelpStmt (2x) - 58348: 1061, // IndexAdviseStmt (2x) - 58350: 1062, // IndexHintList (2x) - 58351: 1063, // IndexHintListOpt (2x) - 58356: 1064, // IndexLockAndAlgorithmOpt (2x) - 58369: 1065, // InsertValues (2x) - 58374: 1066, // IntoOpt (2x) - 58380: 1067, // KeyOrIndexOpt (2x) - 57456: 1068, // kill (2x) - 58381: 1069, // KillOrKillTiDB (2x) - 58382: 1070, // KillStmt (2x) - 58387: 1071, // LimitClause (2x) - 57465: 1072, // linear (2x) - 58389: 1073, // LinearOpt (2x) - 58393: 1074, // LoadDataSetItem (2x) - 58397: 1075, // LoadStatsStmt (2x) - 58398: 1076, // LocalOpt (2x) - 58399: 1077, // LocationLabelList (2x) - 58401: 1078, // LockTablesStmt (2x) - 58410: 1079, // MaxValueOrExpressionList (2x) - 58416: 1080, // NonTransactionalDeleteStmt (2x) - 58422: 1081, // NowSymOptionFractionParentheses (2x) - 58424: 1082, // NumList (2x) - 58427: 1083, // ObjectType (2x) - 57487: 1084, // of (2x) - 58428: 1085, // OfTablesOpt (2x) - 58429: 1086, // OnCommitOpt (2x) - 58430: 1087, // OnDelete (2x) - 58433: 1088, // OnUpdate (2x) - 58438: 1089, // OptCollate (2x) - 58443: 1090, // OptFull (2x) - 58445: 1091, // OptInteger (2x) - 58458: 1092, // OptionalBraces (2x) - 58457: 1093, // OptionLevel (2x) - 58447: 1094, // OptLeadLagInfo (2x) - 58446: 1095, // OptLLDefault (2x) - 58464: 1096, // OuterOpt (2x) - 58469: 1097, // PartitionDefinitionList (2x) - 58470: 1098, // PartitionDefinitionListOpt (2x) - 58471: 1099, // PartitionIntervalOpt (2x) - 58477: 1100, // PartitionOpt (2x) - 58479: 1101, // PasswordOpt (2x) - 58481: 1102, // PasswordOrLockOptionList (2x) - 58482: 1103, // PasswordOrLockOptions (2x) - 58485: 1104, // PlacementOptionList (2x) - 58487: 1105, // PlanReplayerStmt (2x) - 58493: 1106, // PreparedStmt (2x) - 58498: 1107, // PrivLevel (2x) - 58501: 1108, // PurgeImportStmt (2x) - 58502: 1109, // QuickOptional (2x) - 58503: 1110, // RecoverTableStmt (2x) - 58505: 1111, // ReferOpt (2x) - 58507: 1112, // RegexpSym (2x) - 58509: 1113, // RenameTableStmt (2x) - 58510: 1114, // RenameUserStmt (2x) - 58512: 1115, // RepeatableOpt (2x) - 58518: 1116, // RestartStmt (2x) - 58520: 1117, // ResumeImportStmt (2x) - 57514: 1118, // revoke (2x) - 58521: 1119, // RevokeRoleStmt (2x) - 58522: 1120, // RevokeStmt (2x) - 58525: 1121, // RoleOrPrivElemList (2x) - 58526: 1122, // RoleSpec (2x) - 58548: 1123, // SelectStmtOpt (2x) - 58551: 1124, // SelectStmtSQLCache (2x) - 58555: 1125, // SetBindingStmt (2x) - 58556: 1126, // SetDefaultRoleOpt (2x) - 58557: 1127, // SetDefaultRoleStmt (2x) - 58567: 1128, // SetRoleStmt (2x) - 58570: 1129, // ShowImportStmt (2x) - 58575: 1130, // ShowProfileType (2x) - 58578: 1131, // ShowStmt (2x) - 58579: 1132, // ShowTableAliasOpt (2x) - 58581: 1133, // ShutdownStmt (2x) - 58582: 1134, // SignedLiteral (2x) - 58586: 1135, // SplitOption (2x) - 58587: 1136, // SplitRegionStmt (2x) - 58591: 1137, // Statement (2x) - 58594: 1138, // StatsOptionsOpt (2x) - 58595: 1139, // StatsPersistentVal (2x) - 58596: 1140, // StatsType (2x) - 58597: 1141, // StopImportStmt (2x) - 58604: 1142, // SubPartDefinition (2x) - 58607: 1143, // SubPartitionMethod (2x) - 58612: 1144, // Symbol (2x) - 58618: 1145, // TableElementList (2x) - 58621: 1146, // TableLock (2x) - 58625: 1147, // TableNameListOpt (2x) - 58632: 1148, // TableOrTables (2x) - 58641: 1149, // TablesTerminalSym (2x) - 58639: 1150, // TableToTable (2x) - 58643: 1151, // TextStringList (2x) - 58648: 1152, // TraceStmt (2x) - 58653: 1153, // TruncateTableStmt (2x) - 58656: 1154, // UnlockTablesStmt (2x) - 58662: 1155, // UserToUser (2x) - 58659: 1156, // UseStmt (2x) - 58674: 1157, // Varchar (2x) - 58677: 1158, // VariableAssignmentList (2x) - 58686: 1159, // WhenClause (2x) - 58691: 1160, // WindowDefinition (2x) - 58694: 1161, // WindowFrameBound (2x) - 58701: 1162, // WindowSpec (2x) - 58706: 1163, // WithGrantOptionOpt (2x) - 58707: 1164, // WithList (2x) - 58711: 1165, // Writeable (2x) - 58114: 1166, // AdminShowSlow (1x) - 58116: 1167, // AdminStmtLimitOpt (1x) - 58124: 1168, // AlterOrderList (1x) - 58127: 1169, // AlterSequenceOptionList (1x) - 58129: 1170, // AlterTablePartitionOpt (1x) - 58131: 1171, // AlterTableSpecList (1x) - 58132: 1172, // AlterTableSpecListOpt (1x) - 58136: 1173, // AnalyzeOptionList (1x) - 58139: 1174, // AnyOrAll (1x) - 58141: 1175, // AsOfClauseOpt (1x) - 58142: 1176, // AsOpt (1x) - 58147: 1177, // AuthOption (1x) - 58148: 1178, // AuthPlugin (1x) - 58150: 1179, // AutoRandomOpt (1x) - 58160: 1180, // BetweenOrNotOp (1x) - 58162: 1181, // BindingStatusType (1x) - 58165: 1182, // BitValueType (1x) - 58166: 1183, // BlobType (1x) - 58169: 1184, // BooleanType (1x) - 57370: 1185, // both (1x) - 58180: 1186, // CharsetNameOrDefault (1x) - 58181: 1187, // CharsetOpt (1x) - 58183: 1188, // ClearPasswordExpireOptions (1x) - 58187: 1189, // ColumnFormat (1x) - 58189: 1190, // ColumnList (1x) - 58196: 1191, // ColumnNameOrUserVariableList (1x) - 58193: 1192, // ColumnNameOrUserVarListOpt (1x) - 58194: 1193, // ColumnNameOrUserVarListOptWithBrackets (1x) - 58202: 1194, // ColumnSetValueList (1x) - 58206: 1195, // CompareOp (1x) - 58210: 1196, // ConnectionOptionList (1x) - 58213: 1197, // ConstraintElem (1x) - 58221: 1198, // CreateSequenceOptionListOpt (1x) - 58225: 1199, // CreateTableSelectOpt (1x) - 58228: 1200, // CreateViewSelectOpt (1x) - 58235: 1201, // DatabaseOptionListOpt (1x) - 58237: 1202, // DateAndTimeType (1x) - 58232: 1203, // DBNameList (1x) - 58243: 1204, // DefaultValueExpr (1x) - 58263: 1205, // DryRunOptions (1x) - 57409: 1206, // dual (1x) - 58265: 1207, // ElseOpt (1x) - 58270: 1208, // EnforcedOrNotOrNotNullOpt (1x) - 58284: 1209, // ExpressionOpt (1x) - 58286: 1210, // FetchFirstOpt (1x) - 58288: 1211, // FieldAsName (1x) - 58289: 1212, // FieldAsNameOpt (1x) - 58291: 1213, // FieldItemList (1x) - 58293: 1214, // FieldList (1x) - 58299: 1215, // FirstAndLastPartOpt (1x) - 58300: 1216, // FirstOrNext (1x) - 58301: 1217, // FixedPointType (1x) - 58304: 1218, // FlashbackToNewName (1x) - 58306: 1219, // FloatingPointType (1x) - 58307: 1220, // FlushOption (1x) - 58310: 1221, // FromDual (1x) - 58312: 1222, // FulltextSearchModifierOpt (1x) - 58313: 1223, // FuncDatetimePrec (1x) - 58326: 1224, // GetFormatSelector (1x) - 58333: 1225, // HandleRangeList (1x) - 58338: 1226, // IdentListWithParenOpt (1x) - 58342: 1227, // IfNotRunning (1x) - 58343: 1228, // IfRunning (1x) - 58344: 1229, // IgnoreLines (1x) - 58346: 1230, // ImportTruncate (1x) - 58352: 1231, // IndexHintScope (1x) - 58355: 1232, // IndexKeyTypeOpt (1x) - 58364: 1233, // IndexPartSpecificationListOpt (1x) - 58367: 1234, // IndexTypeOpt (1x) - 58347: 1235, // InOrNotOp (1x) - 58370: 1236, // InstanceOption (1x) - 58372: 1237, // IntegerType (1x) - 58373: 1238, // IntervalExpr (1x) - 58376: 1239, // IsolationLevel (1x) - 58375: 1240, // IsOrNotOp (1x) - 57460: 1241, // leading (1x) - 58384: 1242, // LikeEscapeOpt (1x) - 58385: 1243, // LikeOrNotOp (1x) - 58386: 1244, // LikeTableWithOrWithoutParen (1x) - 58391: 1245, // LinesTerminated (1x) - 58394: 1246, // LoadDataSetList (1x) - 58395: 1247, // LoadDataSetSpecOpt (1x) - 58402: 1248, // LockType (1x) - 58403: 1249, // LogTypeOpt (1x) - 58404: 1250, // Match (1x) - 58405: 1251, // MatchOpt (1x) - 58406: 1252, // MaxIndexNumOpt (1x) - 58407: 1253, // MaxMinutesOpt (1x) - 58408: 1254, // MaxValPartOpt (1x) - 58411: 1255, // NChar (1x) - 58423: 1256, // NullPartOpt (1x) - 58426: 1257, // NumericType (1x) - 58413: 1258, // NVarchar (1x) - 58431: 1259, // OnDeleteUpdateOpt (1x) - 58432: 1260, // OnDuplicateKeyUpdate (1x) - 58434: 1261, // OptBinMod (1x) - 58436: 1262, // OptCharset (1x) - 58439: 1263, // OptErrors (1x) - 58440: 1264, // OptExistingWindowName (1x) - 58442: 1265, // OptFromFirstLast (1x) - 58444: 1266, // OptGConcatSeparator (1x) - 58459: 1267, // OptionalShardColumn (1x) - 58450: 1268, // OptPartitionClause (1x) - 58451: 1269, // OptTable (1x) - 58454: 1270, // OptWindowFrameClause (1x) - 58455: 1271, // OptWindowOrderByClause (1x) - 58461: 1272, // Order (1x) - 58460: 1273, // OrReplace (1x) - 57444: 1274, // outfile (1x) - 58467: 1275, // PartDefValuesOpt (1x) - 58472: 1276, // PartitionKeyAlgorithmOpt (1x) - 58473: 1277, // PartitionMethod (1x) - 58476: 1278, // PartitionNumOpt (1x) - 58483: 1279, // PerDB (1x) - 58484: 1280, // PerTable (1x) - 57498: 1281, // precisionType (1x) - 58492: 1282, // PrepareSQL (1x) - 58500: 1283, // ProcedureCall (1x) - 57505: 1284, // recursive (1x) - 58506: 1285, // RegexpOrNotOp (1x) - 58511: 1286, // ReorganizePartitionRuleOpt (1x) - 58516: 1287, // RequireList (1x) - 58527: 1288, // RoleSpecList (1x) - 58534: 1289, // RowOrRows (1x) - 58541: 1290, // SelectStmtFieldList (1x) - 58549: 1291, // SelectStmtOpts (1x) - 58550: 1292, // SelectStmtOptsList (1x) - 58554: 1293, // SequenceOptionList (1x) - 58559: 1294, // SetOpr (1x) - 58566: 1295, // SetRoleOpt (1x) - 58571: 1296, // ShowIndexKwd (1x) - 58572: 1297, // ShowLikeOrWhereOpt (1x) - 58573: 1298, // ShowPlacementTarget (1x) - 58574: 1299, // ShowProfileArgsOpt (1x) - 58576: 1300, // ShowProfileTypes (1x) - 58577: 1301, // ShowProfileTypesOpt (1x) - 58580: 1302, // ShowTargetFilterable (1x) - 57525: 1303, // spatial (1x) - 58588: 1304, // SplitSyntaxOption (1x) - 57530: 1305, // ssl (1x) - 58589: 1306, // Start (1x) - 58590: 1307, // Starting (1x) - 57531: 1308, // starting (1x) - 58592: 1309, // StatementList (1x) - 58593: 1310, // StatementScope (1x) - 58598: 1311, // StorageMedia (1x) - 57537: 1312, // stored (1x) - 58599: 1313, // StringList (1x) - 58602: 1314, // StringNameOrBRIEOptionKeyword (1x) - 58603: 1315, // StringType (1x) - 58605: 1316, // SubPartDefinitionList (1x) - 58606: 1317, // SubPartDefinitionListOpt (1x) - 58608: 1318, // SubPartitionNumOpt (1x) - 58609: 1319, // SubPartitionOpt (1x) - 58619: 1320, // TableElementListOpt (1x) - 58622: 1321, // TableLockList (1x) - 58635: 1322, // TableRefsClause (1x) - 58636: 1323, // TableSampleMethodOpt (1x) - 58637: 1324, // TableSampleOpt (1x) - 58638: 1325, // TableSampleUnitOpt (1x) - 58640: 1326, // TableToTableList (1x) - 58644: 1327, // TextType (1x) - 57544: 1328, // trailing (1x) - 58652: 1329, // TrimDirection (1x) - 58654: 1330, // Type (1x) - 58663: 1331, // UserToUserList (1x) - 58665: 1332, // UserVariableList (1x) - 58668: 1333, // UsingRoles (1x) - 58670: 1334, // Values (1x) - 58672: 1335, // ValuesOpt (1x) - 58679: 1336, // ViewAlgorithm (1x) - 58680: 1337, // ViewCheckOption (1x) - 58681: 1338, // ViewDefiner (1x) - 58682: 1339, // ViewFieldList (1x) - 58683: 1340, // ViewName (1x) - 58684: 1341, // ViewSQLSecurity (1x) - 57564: 1342, // virtual (1x) - 58685: 1343, // VirtualOrStored (1x) - 58687: 1344, // WhenClauseList (1x) - 58690: 1345, // WindowClauseOptional (1x) - 58692: 1346, // WindowDefinitionList (1x) - 58693: 1347, // WindowFrameBetween (1x) - 58695: 1348, // WindowFrameExtent (1x) - 58697: 1349, // WindowFrameUnits (1x) - 58700: 1350, // WindowNameOrSpec (1x) - 58702: 1351, // WindowSpecDetails (1x) - 58708: 1352, // WithReadLockOpt (1x) - 58709: 1353, // WithValidation (1x) - 58710: 1354, // WithValidationOpt (1x) - 58712: 1355, // Year (1x) - 58113: 1356, // $default (0x) - 58074: 1357, // andnot (0x) - 58145: 1358, // AssignmentListOpt (0x) - 58186: 1359, // ColumnDefList (0x) - 58203: 1360, // CommaOpt (0x) - 58097: 1361, // createTableSelect (0x) - 58088: 1362, // empty (0x) - 57345: 1363, // error (0x) - 58112: 1364, // higherThanComma (0x) - 58106: 1365, // higherThanParenthese (0x) - 58095: 1366, // insertValues (0x) - 57352: 1367, // invalid (0x) - 58098: 1368, // lowerThanCharsetKwd (0x) - 58111: 1369, // lowerThanComma (0x) - 58096: 1370, // lowerThanCreateTableSelect (0x) - 58108: 1371, // lowerThanEq (0x) - 58103: 1372, // lowerThanFunction (0x) - 58094: 1373, // lowerThanInsertValues (0x) - 58099: 1374, // lowerThanKey (0x) - 58100: 1375, // lowerThanLocal (0x) - 58110: 1376, // lowerThanNot (0x) - 58107: 1377, // lowerThanOn (0x) - 58105: 1378, // lowerThanParenthese (0x) - 58101: 1379, // lowerThanRemove (0x) - 58089: 1380, // lowerThanSelectOpt (0x) - 58093: 1381, // lowerThanSelectStmt (0x) - 58092: 1382, // lowerThanSetKeyword (0x) - 58091: 1383, // lowerThanStringLitToken (0x) - 58090: 1384, // lowerThanValueKeyword (0x) - 58102: 1385, // lowerThenOrder (0x) - 58109: 1386, // neg (0x) - 57356: 1387, // odbcDateType (0x) - 57358: 1388, // odbcTimestampType (0x) - 57357: 1389, // odbcTimeType (0x) - 58104: 1390, // tableRefPriority (0x) + 57344: 0, // $end (2318x) + 59: 1, // ';' (2317x) + 58059: 2, // split (1911x) + 57748: 3, // merge (1910x) + 57814: 4, // remove (1909x) + 57815: 5, // reorganize (1909x) + 57631: 6, // comment (1904x) + 57879: 7, // storage (1817x) + 57594: 8, // autoIncrement (1806x) + 44: 9, // ',' (1720x) + 57692: 10, // first (1705x) + 57580: 11, // after (1699x) + 57846: 12, // serial (1695x) + 57595: 13, // autoRandom (1694x) + 57628: 14, // columnFormat (1694x) + 57786: 15, // password (1669x) + 57619: 16, // charsetKwd (1661x) + 57621: 17, // checksum (1649x) + 57970: 18, // placement (1647x) + 57724: 19, // keyBlockSize (1631x) + 57891: 20, // tablespace (1628x) + 57672: 21, // encryption (1626x) + 57675: 22, // engine (1623x) + 57654: 23, // data (1621x) + 57715: 24, // insertMethod (1619x) + 57742: 25, // maxRows (1619x) + 57750: 26, // minRows (1619x) + 57765: 27, // nodegroup (1619x) + 57638: 28, // connection (1611x) + 57596: 29, // autoRandomBase (1608x) + 58049: 30, // statsBuckets (1606x) + 58051: 31, // statsTopN (1606x) + 57906: 32, // ttl (1606x) + 57593: 33, // autoIdCache (1605x) + 57598: 34, // avgRowLength (1605x) + 57636: 35, // compression (1605x) + 57660: 36, // delayKeyWrite (1605x) + 57780: 37, // packKeys (1605x) + 57793: 38, // preSplitRegions (1605x) + 57834: 39, // rowFormat (1605x) + 57839: 40, // secondaryEngine (1605x) + 57850: 41, // shardRowIDBits (1605x) + 57875: 42, // statsAutoRecalc (1605x) + 57591: 43, // statsColChoice (1605x) + 57592: 44, // statsColList (1605x) + 57876: 45, // statsPersistent (1605x) + 57877: 46, // statsSamplePages (1605x) + 57590: 47, // statsSampleRate (1605x) + 57889: 48, // tableChecksum (1605x) + 57907: 49, // ttlEnable (1605x) + 57908: 50, // ttlJobInterval (1605x) + 57822: 51, // resource (1564x) + 57587: 52, // attribute (1556x) + 57577: 53, // account (1554x) + 57927: 54, // failedLoginAttempts (1554x) + 57928: 55, // passwordLockTime (1554x) + 57827: 56, // resume (1538x) + 57854: 57, // signed (1538x) + 41: 58, // ')' (1537x) + 57860: 59, // snapshot (1537x) + 57599: 60, // backend (1536x) + 57620: 61, // checkpoint (1536x) + 57637: 62, // concurrency (1536x) + 57643: 63, // csvBackslashEscape (1536x) + 57644: 64, // csvDelimiter (1536x) + 57645: 65, // csvHeader (1536x) + 57646: 66, // csvNotNull (1536x) + 57647: 67, // csvNull (1536x) + 57648: 68, // csvSeparator (1536x) + 57649: 69, // csvTrimLastSeparators (1536x) + 57728: 70, // lastBackup (1536x) + 57775: 71, // onDuplicate (1536x) + 57776: 72, // online (1536x) + 57808: 73, // rateLimit (1536x) + 57843: 74, // sendCredentialsToTiKV (1536x) + 57857: 75, // skipSchemaFiles (1536x) + 57880: 76, // strictFormat (1536x) + 57896: 77, // tikvImporter (1536x) + 57905: 78, // truncate (1533x) + 57762: 79, // no (1532x) + 57874: 80, // start (1530x) + 57614: 81, // cache (1527x) + 57763: 82, // nocache (1526x) + 57653: 83, // cycle (1525x) + 57752: 84, // minValue (1525x) + 57712: 85, // increment (1524x) + 57764: 86, // nocycle (1524x) + 57766: 87, // nomaxvalue (1524x) + 57767: 88, // nominvalue (1524x) + 57824: 89, // restart (1522x) + 57583: 90, // algorithm (1521x) + 57900: 91, // tp (1521x) + 57652: 92, // clustered (1520x) + 57717: 93, // invisible (1520x) + 57768: 94, // nonclustered (1520x) + 58062: 95, // regions (1520x) + 57919: 96, // visible (1520x) + 57882: 97, // subpartition (1517x) + 57785: 98, // partitions (1516x) + 57939: 99, // constraints (1513x) + 57951: 100, // followerConstraints (1513x) + 57952: 101, // followers (1513x) + 57962: 102, // leaderConstraints (1513x) + 57964: 103, // learnerConstraints (1513x) + 57965: 104, // learners (1513x) + 57975: 105, // primaryRegion (1513x) + 57980: 106, // schedule (1513x) + 58014: 107, // voterConstraints (1513x) + 58015: 108, // voters (1513x) + 57629: 109, // columns (1512x) + 57918: 110, // view (1512x) + 57657: 111, // day (1510x) + 57925: 112, // yearType (1510x) + 57642: 113, // cpu (1509x) + 57838: 114, // second (1508x) + 57873: 115, // sqlTsiYear (1508x) + 57586: 116, // ascii (1507x) + 57613: 117, // byteType (1507x) + 57707: 118, // hour (1507x) + 58018: 119, // ioReadBandwidth (1507x) + 58019: 120, // ioWriteBandwidth (1507x) + 57749: 121, // microsecond (1507x) + 57751: 122, // minute (1507x) + 57755: 123, // month (1507x) + 57804: 124, // quarter (1507x) + 58016: 125, // rruRate (1507x) + 57866: 126, // sqlTsiDay (1507x) + 57867: 127, // sqlTsiHour (1507x) + 57868: 128, // sqlTsiMinute (1507x) + 57869: 129, // sqlTsiMonth (1507x) + 57870: 130, // sqlTsiQuarter (1507x) + 57871: 131, // sqlTsiSecond (1507x) + 57872: 132, // sqlTsiWeek (1507x) + 57912: 133, // unicodeSym (1507x) + 57921: 134, // week (1507x) + 58017: 135, // wruRate (1507x) + 57690: 136, // fields (1506x) + 57890: 137, // tables (1505x) + 57878: 138, // status (1504x) + 57844: 139, // separator (1503x) + 57622: 140, // cipher (1502x) + 57346: 141, // identifier (1502x) + 57722: 142, // issuer (1502x) + 57740: 143, // maxConnectionsPerHour (1502x) + 57741: 144, // maxQueriesPerHour (1502x) + 57743: 145, // maxUpdatesPerHour (1502x) + 57744: 146, // maxUserConnections (1502x) + 57794: 147, // preceding (1502x) + 57836: 148, // san (1502x) + 57881: 149, // subject (1502x) + 57899: 150, // tokenIssuer (1502x) + 57710: 151, // importKwd (1501x) + 57733: 152, // local (1501x) + 57806: 153, // query (1500x) + 57856: 154, // skip (1500x) + 57606: 155, // bindings (1499x) + 57659: 156, // definer (1499x) + 57702: 157, // hash (1499x) + 57708: 158, // identified (1499x) + 57736: 159, // logs (1499x) + 57823: 160, // respect (1499x) + 57632: 161, // commit (1498x) + 57650: 162, // current (1498x) + 57674: 163, // enforced (1498x) + 57695: 164, // following (1498x) + 57730: 165, // less (1498x) + 57770: 166, // nowait (1498x) + 57777: 167, // only (1498x) + 57831: 168, // rollback (1498x) + 57837: 169, // savepoint (1498x) + 57895: 170, // than (1498x) + 57909: 171, // unbounded (1498x) + 57916: 172, // value (1498x) + 57602: 173, // begin (1497x) + 57604: 174, // binding (1497x) + 57673: 175, // end (1497x) + 57700: 176, // global (1497x) + 57955: 177, // next_row_id (1497x) + 57774: 178, // offset (1497x) + 57792: 179, // policy (1497x) + 57974: 180, // predicate (1497x) + 57892: 181, // temporary (1497x) + 58057: 182, // tiFlash (1497x) + 57914: 183, // user (1497x) + 57723: 184, // jsonType (1496x) + 57972: 185, // planCache (1496x) + 57795: 186, // prepare (1496x) + 57830: 187, // role (1496x) + 57913: 188, // unknown (1496x) + 57926: 189, // wait (1496x) + 57612: 190, // btree (1495x) + 57655: 191, // datetimeType (1495x) + 57656: 192, // dateType (1495x) + 57693: 193, // fixed (1495x) + 57709: 194, // identSQLErrors (1495x) + 57721: 195, // isolation (1495x) + 57727: 196, // last (1495x) + 57735: 197, // location (1495x) + 57738: 198, // max_idxnum (1495x) + 57747: 199, // memory (1495x) + 57773: 200, // off (1495x) + 57779: 201, // optional (1495x) + 57788: 202, // per_db (1495x) + 57971: 203, // plan (1495x) + 57797: 204, // privileges (1495x) + 57818: 205, // replica (1495x) + 57821: 206, // required (1495x) + 57835: 207, // rtree (1495x) + 57978: 208, // running (1495x) + 58043: 209, // sampleRate (1495x) + 57845: 210, // sequence (1495x) + 57848: 211, // session (1495x) + 57859: 212, // slow (1495x) + 58046: 213, // stats (1495x) + 57898: 214, // timeType (1495x) + 57915: 215, // validation (1495x) + 57917: 216, // variables (1495x) + 57588: 217, // attributes (1494x) + 57634: 218, // compact (1494x) + 57661: 219, // digest (1494x) + 57663: 220, // disable (1494x) + 57668: 221, // duplicate (1494x) + 57669: 222, // dynamic (1494x) + 57670: 223, // enable (1494x) + 57678: 224, // errorKwd (1494x) + 57694: 225, // flush (1494x) + 57697: 226, // full (1494x) + 57705: 227, // history (1494x) + 57745: 228, // mb (1494x) + 57753: 229, // mode (1494x) + 57791: 230, // plugins (1494x) + 57799: 231, // processlist (1494x) + 57810: 232, // recover (1494x) + 57816: 233, // repair (1494x) + 57817: 234, // repeatable (1494x) + 58045: 235, // statistics (1494x) + 57883: 236, // subpartitions (1494x) + 58056: 237, // tidb (1494x) + 57897: 238, // timestampType (1494x) + 57923: 239, // without (1494x) + 58020: 240, // admin (1493x) + 57600: 241, // backup (1493x) + 58021: 242, // batch (1493x) + 57607: 243, // binlog (1493x) + 57609: 244, // block (1493x) + 57610: 245, // booleanType (1493x) + 57936: 246, // briefType (1493x) + 58022: 247, // buckets (1493x) + 57615: 248, // capture (1493x) + 58025: 249, // cardinality (1493x) + 57618: 250, // chain (1493x) + 57625: 251, // clientErrorsSummary (1493x) + 58026: 252, // cmSketch (1493x) + 57626: 253, // coalesce (1493x) + 57635: 254, // compressed (1493x) + 57641: 255, // context (1493x) + 57938: 256, // copyKwd (1493x) + 58028: 257, // correlation (1493x) + 57658: 258, // deallocate (1493x) + 58030: 259, // dependency (1493x) + 57662: 260, // directory (1493x) + 57665: 261, // discard (1493x) + 57666: 262, // disk (1493x) + 57667: 263, // do (1493x) + 57944: 264, // dotType (1493x) + 58032: 265, // drainer (1493x) + 58033: 266, // dry (1493x) + 57683: 267, // exchange (1493x) + 57685: 268, // execute (1493x) + 57686: 269, // expansion (1493x) + 57949: 270, // flashback (1493x) + 57696: 271, // format (1493x) + 57699: 272, // general (1493x) + 57703: 273, // help (1493x) + 57704: 274, // histogram (1493x) + 57706: 275, // hosts (1493x) + 57956: 276, // inplace (1493x) + 57716: 277, // instance (1493x) + 57957: 278, // instant (1493x) + 57720: 279, // ipc (1493x) + 58035: 280, // job (1493x) + 58034: 281, // jobs (1493x) + 57725: 282, // labels (1493x) + 57734: 283, // locked (1493x) + 57754: 284, // modify (1493x) + 57760: 285, // next (1493x) + 58036: 286, // nodeID (1493x) + 58037: 287, // nodeState (1493x) + 57772: 288, // nulls (1493x) + 57781: 289, // pageSym (1493x) + 58040: 290, // pump (1493x) + 57803: 291, // purge (1493x) + 57809: 292, // rebuild (1493x) + 57811: 293, // redundant (1493x) + 57812: 294, // reload (1493x) + 57825: 295, // restore (1493x) + 57832: 296, // routine (1493x) + 57979: 297, // s3 (1493x) + 58042: 298, // samples (1493x) + 57840: 299, // secondaryLoad (1493x) + 57841: 300, // secondaryUnload (1493x) + 57851: 301, // share (1493x) + 57853: 302, // shutdown (1493x) + 57862: 303, // source (1493x) + 57589: 304, // statsOptions (1493x) + 57986: 305, // stop (1493x) + 57885: 306, // swaps (1493x) + 57993: 307, // tidbJson (1493x) + 57997: 308, // tokudbDefault (1493x) + 57998: 309, // tokudbFast (1493x) + 57999: 310, // tokudbLzma (1493x) + 58000: 311, // tokudbQuickLZ (1493x) + 58002: 312, // tokudbSmall (1493x) + 58001: 313, // tokudbSnappy (1493x) + 58003: 314, // tokudbUncompressed (1493x) + 58004: 315, // tokudbZlib (1493x) + 58005: 316, // tokudbZstd (1493x) + 58058: 317, // topn (1493x) + 57901: 318, // trace (1493x) + 57902: 319, // traditional (1493x) + 58012: 320, // trueCardCost (1493x) + 58011: 321, // verboseType (1493x) + 57920: 322, // warnings (1493x) + 57578: 323, // action (1492x) + 57579: 324, // advise (1492x) + 57581: 325, // against (1492x) + 57582: 326, // ago (1492x) + 57584: 327, // always (1492x) + 57601: 328, // backups (1492x) + 57603: 329, // bernoulli (1492x) + 57605: 330, // bindingCache (1492x) + 57608: 331, // bitType (1492x) + 57611: 332, // boolType (1492x) + 58023: 333, // builtins (1492x) + 58024: 334, // cancel (1492x) + 57616: 335, // cascaded (1492x) + 57617: 336, // causal (1492x) + 57623: 337, // cleanup (1492x) + 57624: 338, // client (1492x) + 57651: 339, // cluster (1492x) + 57627: 340, // collation (1492x) + 58027: 341, // columnStatsUsage (1492x) + 57633: 342, // committed (1492x) + 57630: 343, // config (1492x) + 57639: 344, // consistency (1492x) + 57640: 345, // consistent (1492x) + 58029: 346, // ddl (1492x) + 58031: 347, // depth (1492x) + 57664: 348, // disabled (1492x) + 57945: 349, // dump (1492x) + 57671: 350, // enabled (1492x) + 57676: 351, // engines (1492x) + 57677: 352, // enum (1492x) + 57681: 353, // events (1492x) + 57682: 354, // evolve (1492x) + 57687: 355, // expire (1492x) + 57947: 356, // exprPushdownBlacklist (1492x) + 57688: 357, // extended (1492x) + 57689: 358, // faultsSym (1492x) + 57698: 359, // function (1492x) + 57701: 360, // grants (1492x) + 58053: 361, // histogramsInFlight (1492x) + 57711: 362, // imports (1492x) + 57713: 363, // incremental (1492x) + 57714: 364, // indexes (1492x) + 57958: 365, // internal (1492x) + 57718: 366, // invoker (1492x) + 57719: 367, // io (1492x) + 57726: 368, // language (1492x) + 57731: 369, // level (1492x) + 57732: 370, // list (1492x) + 57737: 371, // master (1492x) + 57739: 372, // max_minutes (1492x) + 57757: 373, // national (1492x) + 57758: 374, // ncharType (1492x) + 57759: 375, // never (1492x) + 57761: 376, // nextval (1492x) + 57769: 377, // none (1492x) + 57771: 378, // nvarcharType (1492x) + 57778: 379, // open (1492x) + 58038: 380, // optimistic (1492x) + 57969: 381, // optRuleBlacklist (1492x) + 57782: 382, // parser (1492x) + 57783: 383, // partial (1492x) + 57784: 384, // partitioning (1492x) + 57789: 385, // per_table (1492x) + 57787: 386, // percent (1492x) + 58039: 387, // pessimistic (1492x) + 57796: 388, // preserve (1492x) + 57800: 389, // profile (1492x) + 57801: 390, // profiles (1492x) + 57805: 391, // queries (1492x) + 57976: 392, // recent (1492x) + 58063: 393, // region (1492x) + 57813: 394, // remote (1492x) + 57977: 395, // replayer (1492x) + 58061: 396, // reset (1492x) + 57826: 397, // restores (1492x) + 57828: 398, // reuse (1492x) + 58041: 399, // run (1492x) + 57842: 400, // security (1492x) + 57847: 401, // serializable (1492x) + 58044: 402, // sessionStates (1492x) + 57855: 403, // simple (1492x) + 57858: 404, // slave (1492x) + 58050: 405, // statsHealthy (1492x) + 58048: 406, // statsHistograms (1492x) + 58052: 407, // statsLocked (1492x) + 58047: 408, // statsMeta (1492x) + 57987: 409, // strict (1492x) + 57886: 410, // switchesSym (1492x) + 57887: 411, // system (1492x) + 57888: 412, // systemTime (1492x) + 57992: 413, // target (1492x) + 58055: 414, // telemetryID (1492x) + 57893: 415, // temptable (1492x) + 57894: 416, // textType (1492x) + 57996: 417, // tls (1492x) + 58006: 418, // top (1492x) + 57903: 419, // transaction (1492x) + 57904: 420, // triggers (1492x) + 57910: 421, // uncommitted (1492x) + 57911: 422, // undefined (1492x) + 58060: 423, // width (1492x) + 57924: 424, // x509 (1492x) + 57929: 425, // addDate (1491x) + 57585: 426, // any (1491x) + 57930: 427, // approxCountDistinct (1491x) + 57931: 428, // approxPercentile (1491x) + 57597: 429, // avg (1491x) + 57932: 430, // bitAnd (1491x) + 57933: 431, // bitOr (1491x) + 57934: 432, // bitXor (1491x) + 57935: 433, // bound (1491x) + 57937: 434, // cast (1491x) + 57941: 435, // curDate (1491x) + 57940: 436, // curTime (1491x) + 57942: 437, // dateAdd (1491x) + 57943: 438, // dateSub (1491x) + 57679: 439, // escape (1491x) + 57680: 440, // event (1491x) + 57946: 441, // exact (1491x) + 57684: 442, // exclusive (1491x) + 57948: 443, // extract (1491x) + 57691: 444, // file (1491x) + 57950: 445, // follower (1491x) + 57953: 446, // getFormat (1491x) + 57954: 447, // groupConcat (1491x) + 57959: 448, // jsonArrayagg (1491x) + 57960: 449, // jsonObjectAgg (1491x) + 57729: 450, // lastval (1491x) + 57961: 451, // leader (1491x) + 57963: 452, // learner (1491x) + 57967: 453, // max (1491x) + 57746: 454, // member (1491x) + 57966: 455, // min (1491x) + 57756: 456, // names (1491x) + 57968: 457, // now (1491x) + 57973: 458, // position (1491x) + 57798: 459, // process (1491x) + 57802: 460, // proxy (1491x) + 57807: 461, // quick (1491x) + 57819: 462, // replicas (1491x) + 57820: 463, // replication (1491x) + 57829: 464, // reverse (1491x) + 57833: 465, // rowCount (1491x) + 57849: 466, // setval (1491x) + 57852: 467, // shared (1491x) + 57861: 468, // some (1491x) + 57863: 469, // sqlBufferResult (1491x) + 57864: 470, // sqlCache (1491x) + 57865: 471, // sqlNoCache (1491x) + 57981: 472, // staleness (1491x) + 57982: 473, // std (1491x) + 57983: 474, // stddev (1491x) + 57984: 475, // stddevPop (1491x) + 57985: 476, // stddevSamp (1491x) + 57988: 477, // strong (1491x) + 57989: 478, // subDate (1491x) + 57991: 479, // substring (1491x) + 57990: 480, // sum (1491x) + 57884: 481, // super (1491x) + 58054: 482, // telemetry (1491x) + 57994: 483, // timestampAdd (1491x) + 57995: 484, // timestampDiff (1491x) + 58007: 485, // trim (1491x) + 58008: 486, // variance (1491x) + 58009: 487, // varPop (1491x) + 58010: 488, // varSamp (1491x) + 58013: 489, // voter (1491x) + 57922: 490, // weightString (1491x) + 57491: 491, // on (1420x) + 40: 492, // '(' (1356x) + 57351: 493, // stringLit (1237x) + 57572: 494, // with (1236x) + 58109: 495, // not2 (1214x) + 57401: 496, // defaultKwd (1154x) + 57484: 497, // not (1150x) + 57367: 498, // as (1131x) + 57382: 499, // collate (1097x) + 57551: 500, // union (1081x) + 57557: 501, // using (1072x) + 57464: 502, // left (1067x) + 57518: 503, // right (1067x) + 43: 504, // '+' (1044x) + 45: 505, // '-' (1042x) + 57483: 506, // mod (1022x) + 57499: 507, // partition (1015x) + 57438: 508, // ignore (980x) + 57418: 509, // except (970x) + 57488: 510, // null (970x) + 57444: 511, // intersect (969x) + 57466: 512, // limit (950x) + 57423: 513, // forKwd (948x) + 57380: 514, // charType (946x) + 57561: 515, // values (946x) + 57446: 516, // into (940x) + 58098: 517, // eq (936x) + 57472: 518, // lock (936x) + 57569: 519, // where (931x) + 57426: 520, // from (929x) + 57420: 521, // fetch (926x) + 57514: 522, // replace (923x) + 57496: 523, // order (922x) + 57424: 524, // force (921x) + 58093: 525, // intLit (913x) + 57525: 526, // set (909x) + 57365: 527, // and (908x) + 57495: 528, // or (884x) + 57356: 529, // andand (883x) + 57790: 530, // pipesAsOr (883x) + 57573: 531, // xor (883x) + 57430: 532, // group (862x) + 57432: 533, // having (857x) + 57536: 534, // straightJoin (851x) + 57571: 535, // window (843x) + 57456: 536, // join (839x) + 57465: 537, // like (831x) + 57576: 538, // natural (829x) + 57387: 539, // cross (828x) + 57442: 540, // inner (828x) + 42: 541, // '*' (827x) + 125: 542, // '}' (825x) + 57521: 543, // rows (813x) + 57556: 544, // use (809x) + 57539: 545, // tableSample (803x) + 57504: 546, // rangeKwd (802x) + 57431: 547, // groups (801x) + 57405: 548, // desc (800x) + 57371: 549, // binaryType (799x) + 57396: 550, // dayHour (799x) + 57397: 551, // dayMicrosecond (799x) + 57398: 552, // dayMinute (799x) + 57399: 553, // daySecond (799x) + 57434: 554, // hourMicrosecond (799x) + 57435: 555, // hourMinute (799x) + 57436: 556, // hourSecond (799x) + 57481: 557, // minuteMicrosecond (799x) + 57482: 558, // minuteSecond (799x) + 57523: 559, // secondMicrosecond (799x) + 57574: 560, // yearMonth (799x) + 57368: 561, // asc (798x) + 57568: 562, // when (795x) + 57413: 563, // elseKwd (792x) + 57439: 564, // in (792x) + 57542: 565, // then (789x) + 47: 566, // '/' (785x) + 37: 567, // '%' (784x) + 38: 568, // '&' (784x) + 94: 569, // '^' (784x) + 124: 570, // '|' (784x) + 57409: 571, // div (784x) + 58103: 572, // lsh (784x) + 58108: 573, // rsh (784x) + 60: 574, // '<' (782x) + 62: 575, // '>' (782x) + 58099: 576, // ge (782x) + 57448: 577, // is (782x) + 58100: 578, // le (782x) + 58104: 579, // neq (782x) + 58105: 580, // neqSynonym (782x) + 58106: 581, // nulleq (782x) + 57369: 582, // between (779x) + 57437: 583, // ifKwd (778x) + 57510: 584, // regexpKwd (771x) + 57519: 585, // rlike (771x) + 57349: 586, // memberof (768x) + 57449: 587, // insert (767x) + 57538: 588, // tableKwd (759x) + 57352: 589, // singleAtIdentifier (756x) + 57392: 590, // currentUser (752x) + 57419: 591, // falseKwd (751x) + 57549: 592, // trueKwd (751x) + 58092: 593, // decLit (745x) + 58091: 594, // floatLit (745x) + 57520: 595, // row (744x) + 58094: 596, // hexLit (743x) + 58107: 597, // paramMarker (742x) + 58095: 598, // bitLit (741x) + 57445: 599, // interval (741x) + 57457: 600, // key (741x) + 123: 601, // '{' (740x) + 57394: 602, // database (736x) + 57416: 603, // exists (735x) + 57385: 604, // convert (732x) + 58071: 605, // builtinCurDate (731x) + 58079: 606, // builtinNow (731x) + 57381: 607, // check (731x) + 57389: 608, // currentDate (731x) + 57391: 609, // currentTs (731x) + 57353: 610, // doubleAtIdentifier (731x) + 57470: 611, // localTime (731x) + 57471: 612, // localTs (731x) + 57502: 613, // primary (731x) + 57350: 614, // underscoreCS (731x) + 58068: 615, // builtinCount (729x) + 57357: 616, // pipes (729x) + 33: 617, // '!' (728x) + 126: 618, // '~' (728x) + 58069: 619, // builtinApproxCountDistinct (728x) + 58070: 620, // builtinApproxPercentile (728x) + 58064: 621, // builtinBitAnd (728x) + 58065: 622, // builtinBitOr (728x) + 58066: 623, // builtinBitXor (728x) + 58067: 624, // builtinCast (728x) + 58072: 625, // builtinCurTime (728x) + 58073: 626, // builtinDateAdd (728x) + 58074: 627, // builtinDateSub (728x) + 58075: 628, // builtinExtract (728x) + 58076: 629, // builtinGroupConcat (728x) + 58077: 630, // builtinMax (728x) + 58078: 631, // builtinMin (728x) + 58080: 632, // builtinPosition (728x) + 58084: 633, // builtinStddevPop (728x) + 58085: 634, // builtinStddevSamp (728x) + 58081: 635, // builtinSubstring (728x) + 58082: 636, // builtinSum (728x) + 58083: 637, // builtinSysDate (728x) + 58086: 638, // builtinTranslate (728x) + 58087: 639, // builtinTrim (728x) + 58088: 640, // builtinUser (728x) + 58089: 641, // builtinVarPop (728x) + 58090: 642, // builtinVarSamp (728x) + 57377: 643, // caseKwd (728x) + 57388: 644, // cumeDist (728x) + 57393: 645, // currentRole (728x) + 57390: 646, // currentTime (728x) + 57404: 647, // denseRank (728x) + 57421: 648, // firstValue (728x) + 57460: 649, // lag (728x) + 57461: 650, // lastValue (728x) + 57462: 651, // lead (728x) + 57486: 652, // nthValue (728x) + 57487: 653, // ntile (728x) + 57500: 654, // percentRank (728x) + 57505: 655, // rank (728x) + 57513: 656, // repeat (728x) + 57522: 657, // rowNumber (728x) + 57537: 658, // tidbCurrentTSO (728x) + 57558: 659, // utcDate (728x) + 57560: 660, // utcTime (728x) + 57559: 661, // utcTimestamp (728x) + 57550: 662, // unique (724x) + 57384: 663, // constraint (722x) + 57509: 664, // references (719x) + 57524: 665, // selectKwd (716x) + 57428: 666, // generated (715x) + 57379: 667, // character (709x) + 57440: 668, // index (697x) + 57476: 669, // match (669x) + 57546: 670, // to (588x) + 57362: 671, // all (573x) + 46: 672, // '.' (568x) + 57364: 673, // analyze (552x) + 57554: 674, // update (549x) + 57477: 675, // maxValue (536x) + 58101: 676, // jss (534x) + 58102: 677, // juss (534x) + 57366: 678, // array (532x) + 57467: 679, // lines (523x) + 58097: 680, // assignmentEq (520x) + 57374: 681, // by (520x) + 57363: 682, // alter (518x) + 57515: 683, // require (515x) + 64: 684, // '@' (510x) + 58368: 685, // Identifier (509x) + 58448: 686, // NotKeywordToken (509x) + 57529: 687, // sql (509x) + 58679: 688, // TiDBKeyword (509x) + 58689: 689, // UnReservedKeyword (509x) + 57411: 690, // drop (504x) + 57376: 691, // cascade (503x) + 57506: 692, // read (503x) + 57516: 693, // restrict (503x) + 57347: 694, // asof (501x) + 57386: 695, // create (499x) + 57425: 696, // foreign (499x) + 57427: 697, // fulltext (499x) + 57348: 698, // toTimestamp (498x) + 57564: 699, // varcharacter (497x) + 57563: 700, // varcharType (497x) + 57378: 701, // change (496x) + 57400: 702, // decimalType (496x) + 57410: 703, // doubleType (496x) + 57422: 704, // floatType (496x) + 57443: 705, // integerType (496x) + 57450: 706, // intType (496x) + 57507: 707, // realType (496x) + 57512: 708, // rename (496x) + 57570: 709, // write (496x) + 57565: 710, // varbinaryType (495x) + 57361: 711, // add (494x) + 57370: 712, // bigIntType (494x) + 57372: 713, // blobType (494x) + 57451: 714, // int1Type (494x) + 57452: 715, // int2Type (494x) + 57453: 716, // int3Type (494x) + 57454: 717, // int4Type (494x) + 57455: 718, // int8Type (494x) + 57562: 719, // long (494x) + 57473: 720, // longblobType (494x) + 57474: 721, // longtextType (494x) + 57478: 722, // mediumblobType (494x) + 57479: 723, // mediumIntType (494x) + 57480: 724, // mediumtextType (494x) + 57489: 725, // numericType (494x) + 57492: 726, // optimize (494x) + 57527: 727, // smallIntType (494x) + 57543: 728, // tinyblobType (494x) + 57544: 729, // tinyIntType (494x) + 57545: 730, // tinytextType (494x) + 58644: 731, // SubSelect (224x) + 58699: 732, // UserVariable (182x) + 58619: 733, // SimpleIdent (181x) + 58421: 734, // Literal (180x) + 58634: 735, // StringLiteral (180x) + 58445: 736, // NextValueForSequence (178x) + 58345: 737, // FunctionCallGeneric (177x) + 58346: 738, // FunctionCallKeyword (177x) + 58347: 739, // FunctionCallNonKeyword (177x) + 58348: 740, // FunctionNameConflict (177x) + 58349: 741, // FunctionNameDateArith (177x) + 58350: 742, // FunctionNameDateArithMultiForms (177x) + 58351: 743, // FunctionNameDatetimePrecision (177x) + 58352: 744, // FunctionNameOptionalBraces (177x) + 58353: 745, // FunctionNameSequence (177x) + 58618: 746, // SimpleExpr (177x) + 58645: 747, // SumExpr (177x) + 58647: 748, // SystemVariable (177x) + 58710: 749, // Variable (177x) + 58733: 750, // WindowFuncCall (177x) + 58188: 751, // BitExpr (163x) + 58521: 752, // PredicateExpr (132x) + 58191: 753, // BoolPri (129x) + 58309: 754, // Expression (129x) + 58443: 755, // NUM (109x) + 58748: 756, // logAnd (97x) + 58749: 757, // logOr (97x) + 58299: 758, // EqOpt (83x) + 58657: 759, // TableName (77x) + 58635: 760, // StringName (56x) + 57403: 761, // deleteKwd (53x) + 58412: 762, // LengthNum (48x) + 57553: 763, // unsigned (47x) + 57498: 764, // over (45x) + 57575: 765, // zerofill (45x) + 58213: 766, // ColumnName (41x) + 57407: 767, // distinct (36x) + 57408: 768, // distinctRow (36x) + 58738: 769, // WindowingClause (35x) + 58572: 770, // SelectStmt (34x) + 58573: 771, // SelectStmtBasic (34x) + 58575: 772, // SelectStmtFromDualTable (34x) + 58576: 773, // SelectStmtFromTable (34x) + 58593: 774, // SetOprClause (34x) + 57402: 775, // delayed (33x) + 57433: 776, // highPriority (33x) + 57475: 777, // lowPriority (33x) + 58594: 778, // SetOprClauseList (33x) + 58597: 779, // SetOprStmtWithLimitOrderBy (33x) + 58598: 780, // SetOprStmtWoutLimitOrderBy (33x) + 58739: 781, // WithClause (31x) + 58585: 782, // SelectStmtWithClause (30x) + 58596: 783, // SetOprStmt (30x) + 58400: 784, // Int64Num (28x) + 57355: 785, // hintComment (27x) + 58320: 786, // FieldLen (25x) + 58487: 787, // OptWindowingClause (24x) + 58693: 788, // UpdateStmtNoWith (24x) + 58272: 789, // DeleteWithoutUsingStmt (23x) + 58493: 790, // OrderBy (23x) + 58579: 791, // SelectStmtLimit (23x) + 57530: 792, // sqlBigResult (23x) + 57531: 793, // sqlCalcFoundRows (23x) + 57532: 794, // sqlSmallResult (23x) + 58397: 795, // InsertIntoStmt (21x) + 58543: 796, // ReplaceIntoStmt (21x) + 58692: 797, // UpdateStmt (21x) + 58202: 798, // CharsetKw (20x) + 58701: 799, // Username (20x) + 58369: 800, // IfExists (19x) + 58310: 801, // ExpressionList (18x) + 58271: 802, // DeleteWithUsingStmt (17x) + 58516: 803, // PlacementPolicyOption (17x) + 58658: 804, // TableNameList (17x) + 58370: 805, // IfNotExists (16x) + 57541: 806, // terminated (16x) + 58270: 807, // DeleteFromStmt (15x) + 58275: 808, // DistinctKwd (15x) + 58505: 809, // PartitionNameList (15x) + 58276: 810, // DistinctOpt (14x) + 57414: 811, // enclosed (14x) + 58472: 812, // OptFieldLen (14x) + 58681: 813, // TimestampUnit (14x) + 58723: 814, // WhereClause (14x) + 58724: 815, // WhereClauseOptional (14x) + 58267: 816, // DefaultKwdOpt (13x) + 57415: 817, // escaped (13x) + 57494: 818, // optionally (13x) + 58308: 819, // ExprOrDefault (12x) + 58406: 820, // JoinTable (12x) + 58466: 821, // OptBinary (12x) + 57511: 822, // release (12x) + 58562: 823, // RolenameComposed (12x) + 58654: 824, // TableFactor (12x) + 58667: 825, // TableRef (12x) + 58160: 826, // AnalyzeOptionListOpt (11x) + 58340: 827, // FromOrIn (11x) + 58680: 828, // TimeUnit (11x) + 58156: 829, // AlterTableStmt (10x) + 58203: 830, // CharsetName (10x) + 58214: 831, // ColumnNameList (10x) + 58257: 832, // DBName (10x) + 57469: 833, // load (10x) + 58449: 834, // NotSym (10x) + 57485: 835, // noWriteToBinLog (10x) + 58494: 836, // OrderByOptional (10x) + 58496: 837, // PartDefOption (10x) + 58617: 838, // SignedNum (10x) + 58194: 839, // BuggyDefaultFalseDistinctOpt (9x) + 58266: 840, // DefaultFalseDistinctOpt (9x) + 58407: 841, // JoinType (9x) + 58456: 842, // NumLiteral (9x) + 58561: 843, // Rolename (9x) + 58556: 844, // RoleNameString (9x) + 58255: 845, // CrossOpt (8x) + 58300: 846, // EqOrAssignmentEq (8x) + 58307: 847, // ExplainableStmt (8x) + 58311: 848, // ExpressionListOpt (8x) + 58391: 849, // IndexPartSpecification (8x) + 58408: 850, // KeyOrIndex (8x) + 58446: 851, // NoWriteToBinLogAliasOpt (8x) + 58580: 852, // SelectStmtLimitOpt (8x) + 58713: 853, // VariableName (8x) + 58141: 854, // AllOrPartitionNameList (7x) + 58238: 855, // ConstraintKeywordOpt (7x) + 58262: 856, // DatabaseSym (7x) + 58326: 857, // FieldsOrColumns (7x) + 58338: 858, // ForceOpt (7x) + 58392: 859, // IndexPartSpecificationList (7x) + 57441: 860, // infile (7x) + 58525: 861, // Priority (7x) + 58566: 862, // RowFormat (7x) + 58569: 863, // RowValue (7x) + 58591: 864, // SetExpr (7x) + 58603: 865, // ShowDatabaseNameOpt (7x) + 58664: 866, // TableOption (7x) + 57566: 867, // varying (7x) + 58161: 868, // AnalyzeTableStmt (6x) + 58183: 869, // BeginTransactionStmt (6x) + 58185: 870, // BindableStmt (6x) + 57383: 871, // column (6x) + 58208: 872, // ColumnDef (6x) + 58228: 873, // CommitStmt (6x) + 58259: 874, // DatabaseOption (6x) + 58302: 875, // EscapedTableRef (6x) + 58324: 876, // FieldTerminator (6x) + 57429: 877, // grant (6x) + 58374: 878, // IgnoreOptional (6x) + 58383: 879, // IndexInvisible (6x) + 58388: 880, // IndexNameList (6x) + 58394: 881, // IndexType (6x) + 58425: 882, // LoadDataStmt (6x) + 58506: 883, // PartitionNameListOpt (6x) + 58538: 884, // ReleaseSavepointStmt (6x) + 58563: 885, // RolenameList (6x) + 58565: 886, // RollbackStmt (6x) + 58570: 887, // SavepointStmt (6x) + 58601: 888, // SetStmt (6x) + 57526: 889, // show (6x) + 58662: 890, // TableOptimizerHints (6x) + 58702: 891, // UsernameList (6x) + 58740: 892, // WithClustered (6x) + 58139: 893, // AlgorithmClause (5x) + 58196: 894, // ByItem (5x) + 58207: 895, // CollationName (5x) + 58211: 896, // ColumnKeywordOpt (5x) + 58273: 897, // DirectPlacementOption (5x) + 58274: 898, // DirectResourceGroupOption (5x) + 58322: 899, // FieldOpt (5x) + 58323: 900, // FieldOpts (5x) + 58366: 901, // IdentList (5x) + 58386: 902, // IndexName (5x) + 58389: 903, // IndexOption (5x) + 58390: 904, // IndexOptionList (5x) + 58417: 905, // LimitOption (5x) + 58430: 906, // LockClause (5x) + 58468: 907, // OptCharsetWithOptBinary (5x) + 58479: 908, // OptNullTreatment (5x) + 58519: 909, // PolicyName (5x) + 58526: 910, // PriorityOpt (5x) + 58548: 911, // ResourceGroupName (5x) + 58571: 912, // SelectLockOpt (5x) + 58578: 913, // SelectStmtIntoOption (5x) + 58668: 914, // TableRefs (5x) + 58695: 915, // UserSpec (5x) + 58167: 916, // Assignment (4x) + 58173: 917, // AuthString (4x) + 58175: 918, // BRIEBooleanOptionName (4x) + 58176: 919, // BRIEIntegerOptionName (4x) + 58177: 920, // BRIEKeywordOptionName (4x) + 58178: 921, // BRIEOption (4x) + 58179: 922, // BRIEOptions (4x) + 58181: 923, // BRIEStringOptionName (4x) + 58195: 924, // BuiltinFunction (4x) + 58197: 925, // ByList (4x) + 58201: 926, // Char (4x) + 58232: 927, // ConfigItemName (4x) + 58236: 928, // Constraint (4x) + 58334: 929, // FloatOpt (4x) + 58395: 930, // IndexTypeName (4x) + 57493: 931, // option (4x) + 58484: 932, // OptWild (4x) + 57497: 933, // outer (4x) + 58520: 934, // Precision (4x) + 58534: 935, // ReferDef (4x) + 58552: 936, // RestrictOrCascadeOpt (4x) + 58568: 937, // RowStmt (4x) + 58586: 938, // SequenceOption (4x) + 57535: 939, // statsExtended (4x) + 58649: 940, // TableAsName (4x) + 58650: 941, // TableAsNameOpt (4x) + 58661: 942, // TableNameOptWild (4x) + 58663: 943, // TableOptimizerHintsOpt (4x) + 58665: 944, // TableOptionList (4x) + 58683: 945, // TraceableStmt (4x) + 58684: 946, // TransactionChar (4x) + 58696: 947, // UserSpecList (4x) + 58734: 948, // WindowName (4x) + 58164: 949, // AsOfClause (3x) + 58168: 950, // AssignmentList (3x) + 58170: 951, // AttributesOpt (3x) + 58192: 952, // Boolean (3x) + 58220: 953, // ColumnOption (3x) + 58223: 954, // ColumnPosition (3x) + 58229: 955, // CommonTableExpr (3x) + 58251: 956, // CreateTableStmt (3x) + 58256: 957, // CurdateSym (3x) + 58260: 958, // DatabaseOptionList (3x) + 58268: 959, // DefaultTrueDistinctOpt (3x) + 58296: 960, // EnforcedOrNot (3x) + 57417: 961, // explain (3x) + 58313: 962, // ExtendedPriv (3x) + 58354: 963, // GeneratedAlways (3x) + 58356: 964, // GlobalScope (3x) + 58360: 965, // GroupByClause (3x) + 58378: 966, // IndexHint (3x) + 58382: 967, // IndexHintType (3x) + 58387: 968, // IndexNameAndTypeOpt (3x) + 57458: 969, // keys (3x) + 58419: 970, // Lines (3x) + 58440: 971, // MaxValueOrExpression (3x) + 58450: 972, // NowSym (3x) + 58451: 973, // NowSymFunc (3x) + 58452: 974, // NowSymOptionFraction (3x) + 58480: 975, // OptOrder (3x) + 58483: 976, // OptTemporary (3x) + 58497: 977, // PartDefOptionList (3x) + 58499: 978, // PartitionDefinition (3x) + 58510: 979, // PasswordOrLockOption (3x) + 58518: 980, // PluginNameList (3x) + 58524: 981, // PrimaryOpt (3x) + 58527: 982, // PrivElem (3x) + 58529: 983, // PrivType (3x) + 57503: 984, // procedure (3x) + 58544: 985, // RequireClause (3x) + 58545: 986, // RequireClauseOpt (3x) + 58547: 987, // RequireListElement (3x) + 58564: 988, // RolenameWithoutIdent (3x) + 58557: 989, // RoleOrPrivElem (3x) + 58577: 990, // SelectStmtGroup (3x) + 58595: 991, // SetOprOpt (3x) + 58648: 992, // TableAliasRefList (3x) + 58651: 993, // TableElement (3x) + 58660: 994, // TableNameListOpt2 (3x) + 58676: 995, // TextString (3x) + 58685: 996, // TransactionChars (3x) + 57548: 997, // trigger (3x) + 57552: 998, // unlock (3x) + 57555: 999, // usage (3x) + 58706: 1000, // ValuesList (3x) + 58708: 1001, // ValuesStmtList (3x) + 58704: 1002, // ValueSym (3x) + 58711: 1003, // VariableAssignment (3x) + 58731: 1004, // WindowFrameStart (3x) + 58137: 1005, // AdminStmt (2x) + 58140: 1006, // AllColumnsOrPredicateColumnsOpt (2x) + 58142: 1007, // AlterDatabaseStmt (2x) + 58143: 1008, // AlterImportStmt (2x) + 58144: 1009, // AlterInstanceStmt (2x) + 58145: 1010, // AlterOrderItem (2x) + 58147: 1011, // AlterPolicyStmt (2x) + 58148: 1012, // AlterResourceGroupStmt (2x) + 58149: 1013, // AlterSequenceOption (2x) + 58151: 1014, // AlterSequenceStmt (2x) + 58152: 1015, // AlterTableSpec (2x) + 58157: 1016, // AlterUserStmt (2x) + 58158: 1017, // AnalyzeOption (2x) + 58187: 1018, // BinlogStmt (2x) + 58180: 1019, // BRIEStmt (2x) + 58182: 1020, // BRIETables (2x) + 57375: 1021, // call (2x) + 58198: 1022, // CallStmt (2x) + 58199: 1023, // CastType (2x) + 58200: 1024, // ChangeStmt (2x) + 58206: 1025, // CheckConstraintKeyword (2x) + 58215: 1026, // ColumnNameListOpt (2x) + 58218: 1027, // ColumnNameOrUserVariable (2x) + 58221: 1028, // ColumnOptionList (2x) + 58222: 1029, // ColumnOptionListOpt (2x) + 58224: 1030, // ColumnSetValue (2x) + 58227: 1031, // CommentOrAttributeOption (2x) + 58231: 1032, // CompletionTypeWithinTransaction (2x) + 58233: 1033, // ConnectionOption (2x) + 58235: 1034, // ConnectionOptions (2x) + 58239: 1035, // CreateBindingStmt (2x) + 58240: 1036, // CreateDatabaseStmt (2x) + 58241: 1037, // CreateImportStmt (2x) + 58242: 1038, // CreateIndexStmt (2x) + 58243: 1039, // CreatePolicyStmt (2x) + 58244: 1040, // CreateResourceGroupStmt (2x) + 58245: 1041, // CreateRoleStmt (2x) + 58247: 1042, // CreateSequenceStmt (2x) + 58248: 1043, // CreateStatisticsStmt (2x) + 58249: 1044, // CreateTableOptionListOpt (2x) + 58252: 1045, // CreateUserStmt (2x) + 58254: 1046, // CreateViewStmt (2x) + 57395: 1047, // databases (2x) + 58264: 1048, // DeallocateStmt (2x) + 58265: 1049, // DeallocateSym (2x) + 57406: 1050, // describe (2x) + 58277: 1051, // DoStmt (2x) + 58278: 1052, // DropBindingStmt (2x) + 58279: 1053, // DropDatabaseStmt (2x) + 58280: 1054, // DropImportStmt (2x) + 58281: 1055, // DropIndexStmt (2x) + 58282: 1056, // DropPolicyStmt (2x) + 58283: 1057, // DropResourceGroupStmt (2x) + 58284: 1058, // DropRoleStmt (2x) + 58285: 1059, // DropSequenceStmt (2x) + 58286: 1060, // DropStatisticsStmt (2x) + 58287: 1061, // DropStatsStmt (2x) + 58288: 1062, // DropTableStmt (2x) + 58289: 1063, // DropUserStmt (2x) + 58290: 1064, // DropViewStmt (2x) + 58292: 1065, // DuplicateOpt (2x) + 58294: 1066, // EmptyStmt (2x) + 58295: 1067, // EncryptionOpt (2x) + 58297: 1068, // EnforcedOrNotOpt (2x) + 58301: 1069, // ErrorHandling (2x) + 58303: 1070, // ExecuteStmt (2x) + 58304: 1071, // ExplainFormatType (2x) + 58305: 1072, // ExplainStmt (2x) + 58306: 1073, // ExplainSym (2x) + 58315: 1074, // Field (2x) + 58318: 1075, // FieldItem (2x) + 58325: 1076, // Fields (2x) + 58330: 1077, // FlashbackDatabaseStmt (2x) + 58331: 1078, // FlashbackTableStmt (2x) + 58332: 1079, // FlashbackToNewName (2x) + 58333: 1080, // FlashbackToTimestampStmt (2x) + 58337: 1081, // FlushStmt (2x) + 58343: 1082, // FuncDatetimePrecList (2x) + 58344: 1083, // FuncDatetimePrecListOpt (2x) + 58357: 1084, // GrantProxyStmt (2x) + 58358: 1085, // GrantRoleStmt (2x) + 58359: 1086, // GrantStmt (2x) + 58361: 1087, // HandleRange (2x) + 58363: 1088, // HashString (2x) + 58364: 1089, // HavingClause (2x) + 58365: 1090, // HelpStmt (2x) + 58377: 1091, // IndexAdviseStmt (2x) + 58379: 1092, // IndexHintList (2x) + 58380: 1093, // IndexHintListOpt (2x) + 58385: 1094, // IndexLockAndAlgorithmOpt (2x) + 58398: 1095, // InsertValues (2x) + 58403: 1096, // IntoOpt (2x) + 58409: 1097, // KeyOrIndexOpt (2x) + 57459: 1098, // kill (2x) + 58410: 1099, // KillOrKillTiDB (2x) + 58411: 1100, // KillStmt (2x) + 58416: 1101, // LimitClause (2x) + 57468: 1102, // linear (2x) + 58418: 1103, // LinearOpt (2x) + 58422: 1104, // LoadDataSetItem (2x) + 58426: 1105, // LoadStatsStmt (2x) + 58428: 1106, // LocationLabelList (2x) + 58431: 1107, // LockStatsStmt (2x) + 58432: 1108, // LockTablesStmt (2x) + 58441: 1109, // MaxValueOrExpressionList (2x) + 58447: 1110, // NonTransactionalDMLStmt (2x) + 58453: 1111, // NowSymOptionFractionParentheses (2x) + 58455: 1112, // NumList (2x) + 58458: 1113, // ObjectType (2x) + 57490: 1114, // of (2x) + 58459: 1115, // OfTablesOpt (2x) + 58460: 1116, // OnCommitOpt (2x) + 58461: 1117, // OnDelete (2x) + 58464: 1118, // OnUpdate (2x) + 58469: 1119, // OptCollate (2x) + 58474: 1120, // OptFull (2x) + 58476: 1121, // OptInteger (2x) + 58489: 1122, // OptionalBraces (2x) + 58488: 1123, // OptionLevel (2x) + 58478: 1124, // OptLeadLagInfo (2x) + 58477: 1125, // OptLLDefault (2x) + 58495: 1126, // OuterOpt (2x) + 58500: 1127, // PartitionDefinitionList (2x) + 58501: 1128, // PartitionDefinitionListOpt (2x) + 58502: 1129, // PartitionIntervalOpt (2x) + 58508: 1130, // PartitionOpt (2x) + 58509: 1131, // PasswordOpt (2x) + 58511: 1132, // PasswordOrLockOptionList (2x) + 58512: 1133, // PasswordOrLockOptions (2x) + 58515: 1134, // PlacementOptionList (2x) + 58517: 1135, // PlanReplayerStmt (2x) + 58523: 1136, // PreparedStmt (2x) + 58528: 1137, // PrivLevel (2x) + 58531: 1138, // PurgeImportStmt (2x) + 58532: 1139, // QuickOptional (2x) + 58533: 1140, // RecoverTableStmt (2x) + 58535: 1141, // ReferOpt (2x) + 58537: 1142, // RegexpSym (2x) + 58539: 1143, // RenameTableStmt (2x) + 58540: 1144, // RenameUserStmt (2x) + 58542: 1145, // RepeatableOpt (2x) + 58549: 1146, // ResourceGroupNameOption (2x) + 58550: 1147, // ResourceGroupOptionList (2x) + 58551: 1148, // RestartStmt (2x) + 58553: 1149, // ResumeImportStmt (2x) + 57517: 1150, // revoke (2x) + 58554: 1151, // RevokeRoleStmt (2x) + 58555: 1152, // RevokeStmt (2x) + 58558: 1153, // RoleOrPrivElemList (2x) + 58559: 1154, // RoleSpec (2x) + 58581: 1155, // SelectStmtOpt (2x) + 58584: 1156, // SelectStmtSQLCache (2x) + 58588: 1157, // SetBindingStmt (2x) + 58589: 1158, // SetDefaultRoleOpt (2x) + 58590: 1159, // SetDefaultRoleStmt (2x) + 58600: 1160, // SetRoleStmt (2x) + 58604: 1161, // ShowImportStmt (2x) + 58609: 1162, // ShowProfileType (2x) + 58612: 1163, // ShowStmt (2x) + 58613: 1164, // ShowTableAliasOpt (2x) + 58615: 1165, // ShutdownStmt (2x) + 58616: 1166, // SignedLiteral (2x) + 58620: 1167, // SplitOption (2x) + 58621: 1168, // SplitRegionStmt (2x) + 58625: 1169, // Statement (2x) + 58628: 1170, // StatsOptionsOpt (2x) + 58629: 1171, // StatsPersistentVal (2x) + 58630: 1172, // StatsType (2x) + 58631: 1173, // StopImportStmt (2x) + 58638: 1174, // SubPartDefinition (2x) + 58641: 1175, // SubPartitionMethod (2x) + 58646: 1176, // Symbol (2x) + 58652: 1177, // TableElementList (2x) + 58655: 1178, // TableLock (2x) + 58659: 1179, // TableNameListOpt (2x) + 58666: 1180, // TableOrTables (2x) + 58675: 1181, // TablesTerminalSym (2x) + 58673: 1182, // TableToTable (2x) + 58677: 1183, // TextStringList (2x) + 58682: 1184, // TraceStmt (2x) + 58687: 1185, // TruncateTableStmt (2x) + 58690: 1186, // UnlockStatsStmt (2x) + 58691: 1187, // UnlockTablesStmt (2x) + 58697: 1188, // UserToUser (2x) + 58694: 1189, // UseStmt (2x) + 58709: 1190, // Varchar (2x) + 58712: 1191, // VariableAssignmentList (2x) + 58721: 1192, // WhenClause (2x) + 58726: 1193, // WindowDefinition (2x) + 58729: 1194, // WindowFrameBound (2x) + 58736: 1195, // WindowSpec (2x) + 58741: 1196, // WithGrantOptionOpt (2x) + 58742: 1197, // WithList (2x) + 58746: 1198, // Writeable (2x) + 58136: 1199, // AdminShowSlow (1x) + 58138: 1200, // AdminStmtLimitOpt (1x) + 58146: 1201, // AlterOrderList (1x) + 58150: 1202, // AlterSequenceOptionList (1x) + 58153: 1203, // AlterTableSpecList (1x) + 58154: 1204, // AlterTableSpecListOpt (1x) + 58155: 1205, // AlterTableSpecSingleOpt (1x) + 58159: 1206, // AnalyzeOptionList (1x) + 58162: 1207, // AnyOrAll (1x) + 58163: 1208, // ArrayKwdOpt (1x) + 58165: 1209, // AsOfClauseOpt (1x) + 58166: 1210, // AsOpt (1x) + 58171: 1211, // AuthOption (1x) + 58172: 1212, // AuthPlugin (1x) + 58174: 1213, // AutoRandomOpt (1x) + 58184: 1214, // BetweenOrNotOp (1x) + 58186: 1215, // BindingStatusType (1x) + 58189: 1216, // BitValueType (1x) + 58190: 1217, // BlobType (1x) + 58193: 1218, // BooleanType (1x) + 57373: 1219, // both (1x) + 58204: 1220, // CharsetNameOrDefault (1x) + 58205: 1221, // CharsetOpt (1x) + 58210: 1222, // ColumnFormat (1x) + 58212: 1223, // ColumnList (1x) + 58219: 1224, // ColumnNameOrUserVariableList (1x) + 58216: 1225, // ColumnNameOrUserVarListOpt (1x) + 58217: 1226, // ColumnNameOrUserVarListOptWithBrackets (1x) + 58225: 1227, // ColumnSetValueList (1x) + 58230: 1228, // CompareOp (1x) + 58234: 1229, // ConnectionOptionList (1x) + 58237: 1230, // ConstraintElem (1x) + 58246: 1231, // CreateSequenceOptionListOpt (1x) + 58250: 1232, // CreateTableSelectOpt (1x) + 58253: 1233, // CreateViewSelectOpt (1x) + 58261: 1234, // DatabaseOptionListOpt (1x) + 58263: 1235, // DateAndTimeType (1x) + 58258: 1236, // DBNameList (1x) + 58269: 1237, // DefaultValueExpr (1x) + 58291: 1238, // DryRunOptions (1x) + 57412: 1239, // dual (1x) + 58293: 1240, // ElseOpt (1x) + 58298: 1241, // EnforcedOrNotOrNotNullOpt (1x) + 58312: 1242, // ExpressionOpt (1x) + 58314: 1243, // FetchFirstOpt (1x) + 58316: 1244, // FieldAsName (1x) + 58317: 1245, // FieldAsNameOpt (1x) + 58319: 1246, // FieldItemList (1x) + 58321: 1247, // FieldList (1x) + 58327: 1248, // FirstAndLastPartOpt (1x) + 58328: 1249, // FirstOrNext (1x) + 58329: 1250, // FixedPointType (1x) + 58335: 1251, // FloatingPointType (1x) + 58336: 1252, // FlushOption (1x) + 58339: 1253, // FromDual (1x) + 58341: 1254, // FulltextSearchModifierOpt (1x) + 58342: 1255, // FuncDatetimePrec (1x) + 58355: 1256, // GetFormatSelector (1x) + 58362: 1257, // HandleRangeList (1x) + 58367: 1258, // IdentListWithParenOpt (1x) + 58371: 1259, // IfNotRunning (1x) + 58372: 1260, // IfRunning (1x) + 58373: 1261, // IgnoreLines (1x) + 58375: 1262, // ImportTruncate (1x) + 58381: 1263, // IndexHintScope (1x) + 58384: 1264, // IndexKeyTypeOpt (1x) + 58393: 1265, // IndexPartSpecificationListOpt (1x) + 58396: 1266, // IndexTypeOpt (1x) + 58376: 1267, // InOrNotOp (1x) + 58399: 1268, // InstanceOption (1x) + 58401: 1269, // IntegerType (1x) + 58402: 1270, // IntervalExpr (1x) + 58405: 1271, // IsolationLevel (1x) + 58404: 1272, // IsOrNotOp (1x) + 57463: 1273, // leading (1x) + 58413: 1274, // LikeEscapeOpt (1x) + 58414: 1275, // LikeOrNotOp (1x) + 58415: 1276, // LikeTableWithOrWithoutParen (1x) + 58420: 1277, // LinesTerminated (1x) + 58423: 1278, // LoadDataSetList (1x) + 58424: 1279, // LoadDataSetSpecOpt (1x) + 58427: 1280, // LocalOpt (1x) + 58429: 1281, // LocationOpt (1x) + 58433: 1282, // LockType (1x) + 58434: 1283, // LogTypeOpt (1x) + 58435: 1284, // Match (1x) + 58436: 1285, // MatchOpt (1x) + 58437: 1286, // MaxIndexNumOpt (1x) + 58438: 1287, // MaxMinutesOpt (1x) + 58439: 1288, // MaxValPartOpt (1x) + 58442: 1289, // NChar (1x) + 58454: 1290, // NullPartOpt (1x) + 58457: 1291, // NumericType (1x) + 58444: 1292, // NVarchar (1x) + 58462: 1293, // OnDeleteUpdateOpt (1x) + 58463: 1294, // OnDuplicateKeyUpdate (1x) + 58465: 1295, // OptBinMod (1x) + 58467: 1296, // OptCharset (1x) + 58470: 1297, // OptErrors (1x) + 58471: 1298, // OptExistingWindowName (1x) + 58473: 1299, // OptFromFirstLast (1x) + 58475: 1300, // OptGConcatSeparator (1x) + 58490: 1301, // OptionalShardColumn (1x) + 58481: 1302, // OptPartitionClause (1x) + 58482: 1303, // OptTable (1x) + 58485: 1304, // OptWindowFrameClause (1x) + 58486: 1305, // OptWindowOrderByClause (1x) + 58492: 1306, // Order (1x) + 58491: 1307, // OrReplace (1x) + 57447: 1308, // outfile (1x) + 58498: 1309, // PartDefValuesOpt (1x) + 58503: 1310, // PartitionKeyAlgorithmOpt (1x) + 58504: 1311, // PartitionMethod (1x) + 58507: 1312, // PartitionNumOpt (1x) + 58513: 1313, // PerDB (1x) + 58514: 1314, // PerTable (1x) + 57501: 1315, // precisionType (1x) + 58522: 1316, // PrepareSQL (1x) + 58530: 1317, // ProcedureCall (1x) + 57508: 1318, // recursive (1x) + 58536: 1319, // RegexpOrNotOp (1x) + 58541: 1320, // ReorganizePartitionRuleOpt (1x) + 58546: 1321, // RequireList (1x) + 58560: 1322, // RoleSpecList (1x) + 58567: 1323, // RowOrRows (1x) + 58574: 1324, // SelectStmtFieldList (1x) + 58582: 1325, // SelectStmtOpts (1x) + 58583: 1326, // SelectStmtOptsList (1x) + 58587: 1327, // SequenceOptionList (1x) + 58592: 1328, // SetOpr (1x) + 58599: 1329, // SetRoleOpt (1x) + 58602: 1330, // ShardableStmt (1x) + 58605: 1331, // ShowIndexKwd (1x) + 58606: 1332, // ShowLikeOrWhereOpt (1x) + 58607: 1333, // ShowPlacementTarget (1x) + 58608: 1334, // ShowProfileArgsOpt (1x) + 58610: 1335, // ShowProfileTypes (1x) + 58611: 1336, // ShowProfileTypesOpt (1x) + 58614: 1337, // ShowTargetFilterable (1x) + 57528: 1338, // spatial (1x) + 58622: 1339, // SplitSyntaxOption (1x) + 57533: 1340, // ssl (1x) + 58623: 1341, // Start (1x) + 58624: 1342, // Starting (1x) + 57534: 1343, // starting (1x) + 58626: 1344, // StatementList (1x) + 58627: 1345, // StatementScope (1x) + 58632: 1346, // StorageMedia (1x) + 57540: 1347, // stored (1x) + 58633: 1348, // StringList (1x) + 58636: 1349, // StringNameOrBRIEOptionKeyword (1x) + 58637: 1350, // StringType (1x) + 58639: 1351, // SubPartDefinitionList (1x) + 58640: 1352, // SubPartDefinitionListOpt (1x) + 58642: 1353, // SubPartitionNumOpt (1x) + 58643: 1354, // SubPartitionOpt (1x) + 58653: 1355, // TableElementListOpt (1x) + 58656: 1356, // TableLockList (1x) + 58669: 1357, // TableRefsClause (1x) + 58670: 1358, // TableSampleMethodOpt (1x) + 58671: 1359, // TableSampleOpt (1x) + 58672: 1360, // TableSampleUnitOpt (1x) + 58674: 1361, // TableToTableList (1x) + 58678: 1362, // TextType (1x) + 57547: 1363, // trailing (1x) + 58686: 1364, // TrimDirection (1x) + 58688: 1365, // Type (1x) + 58698: 1366, // UserToUserList (1x) + 58700: 1367, // UserVariableList (1x) + 58703: 1368, // UsingRoles (1x) + 58705: 1369, // Values (1x) + 58707: 1370, // ValuesOpt (1x) + 58714: 1371, // ViewAlgorithm (1x) + 58715: 1372, // ViewCheckOption (1x) + 58716: 1373, // ViewDefiner (1x) + 58717: 1374, // ViewFieldList (1x) + 58718: 1375, // ViewName (1x) + 58719: 1376, // ViewSQLSecurity (1x) + 57567: 1377, // virtual (1x) + 58720: 1378, // VirtualOrStored (1x) + 58722: 1379, // WhenClauseList (1x) + 58725: 1380, // WindowClauseOptional (1x) + 58727: 1381, // WindowDefinitionList (1x) + 58728: 1382, // WindowFrameBetween (1x) + 58730: 1383, // WindowFrameExtent (1x) + 58732: 1384, // WindowFrameUnits (1x) + 58735: 1385, // WindowNameOrSpec (1x) + 58737: 1386, // WindowSpecDetails (1x) + 58743: 1387, // WithReadLockOpt (1x) + 58744: 1388, // WithValidation (1x) + 58745: 1389, // WithValidationOpt (1x) + 58747: 1390, // Year (1x) + 58135: 1391, // $default (0x) + 58096: 1392, // andnot (0x) + 58169: 1393, // AssignmentListOpt (0x) + 58209: 1394, // ColumnDefList (0x) + 58226: 1395, // CommaOpt (0x) + 58119: 1396, // createTableSelect (0x) + 58110: 1397, // empty (0x) + 57345: 1398, // error (0x) + 58134: 1399, // higherThanComma (0x) + 58128: 1400, // higherThanParenthese (0x) + 58117: 1401, // insertValues (0x) + 57354: 1402, // invalid (0x) + 58120: 1403, // lowerThanCharsetKwd (0x) + 58133: 1404, // lowerThanComma (0x) + 58118: 1405, // lowerThanCreateTableSelect (0x) + 58130: 1406, // lowerThanEq (0x) + 58125: 1407, // lowerThanFunction (0x) + 58116: 1408, // lowerThanInsertValues (0x) + 58121: 1409, // lowerThanKey (0x) + 58122: 1410, // lowerThanLocal (0x) + 58132: 1411, // lowerThanNot (0x) + 58129: 1412, // lowerThanOn (0x) + 58127: 1413, // lowerThanParenthese (0x) + 58123: 1414, // lowerThanRemove (0x) + 58111: 1415, // lowerThanSelectOpt (0x) + 58115: 1416, // lowerThanSelectStmt (0x) + 58114: 1417, // lowerThanSetKeyword (0x) + 58113: 1418, // lowerThanStringLitToken (0x) + 58112: 1419, // lowerThanValueKeyword (0x) + 58124: 1420, // lowerThenOrder (0x) + 58131: 1421, // neg (0x) + 57358: 1422, // odbcDateType (0x) + 57360: 1423, // odbcTimestampType (0x) + 57359: 1424, // odbcTimeType (0x) + 58126: 1425, // tableRefPriority (0x) } yySymNames = []string{ @@ -2257,6 +2315,7 @@ var ( "autoRandomBase", "statsBuckets", "statsTopN", + "ttl", "autoIdCache", "avgRowLength", "compression", @@ -2273,10 +2332,16 @@ var ( "statsSamplePages", "statsSampleRate", "tableChecksum", + "ttlEnable", + "ttlJobInterval", + "resource", + "attribute", "account", - "')'", + "failedLoginAttempts", + "passwordLockTime", "resume", "signed", + "')'", "snapshot", "backend", "checkpoint", @@ -2329,19 +2394,21 @@ var ( "voters", "columns", "view", - "yearType", "day", - "ascii", - "byteType", + "yearType", + "cpu", "second", "sqlTsiYear", - "unicodeSym", - "fields", + "ascii", + "byteType", "hour", + "ioReadBandwidth", + "ioWriteBandwidth", "microsecond", "minute", "month", "quarter", + "rruRate", "sqlTsiDay", "sqlTsiHour", "sqlTsiMinute", @@ -2349,21 +2416,26 @@ var ( "sqlTsiQuarter", "sqlTsiSecond", "sqlTsiWeek", + "unicodeSym", "week", + "wruRate", + "fields", "tables", "status", "separator", + "cipher", + "identifier", + "issuer", "maxConnectionsPerHour", "maxQueriesPerHour", "maxUpdatesPerHour", "maxUserConnections", "preceding", - "cipher", - "importKwd", - "issuer", - "local", "san", "subject", + "tokenIssuer", + "importKwd", + "local", "query", "skip", "bindings", @@ -2376,13 +2448,13 @@ var ( "current", "enforced", "following", - "identifier", "less", "nowait", "only", "rollback", "savepoint", "than", + "unbounded", "value", "begin", "binding", @@ -2394,7 +2466,6 @@ var ( "predicate", "temporary", "tiFlash", - "unbounded", "user", "jsonType", "planCache", @@ -2415,6 +2486,7 @@ var ( "off", "optional", "per_db", + "plan", "privileges", "replica", "required", @@ -2424,12 +2496,13 @@ var ( "sequence", "session", "slow", - "timestampType", + "stats", "timeType", "validation", "variables", "attributes", "compact", + "digest", "disable", "duplicate", "dynamic", @@ -2437,10 +2510,9 @@ var ( "errorKwd", "flush", "full", + "history", "mb", "mode", - "never", - "plan", "plugins", "processlist", "recover", @@ -2449,6 +2521,7 @@ var ( "statistics", "subpartitions", "tidb", + "timestampType", "without", "admin", "backup", @@ -2458,6 +2531,7 @@ var ( "booleanType", "briefType", "buckets", + "capture", "cardinality", "chain", "clientErrorsSummary", @@ -2467,7 +2541,6 @@ var ( "context", "copyKwd", "correlation", - "cpu", "deallocate", "dependency", "directory", @@ -2514,10 +2587,10 @@ var ( "share", "shutdown", "source", - "stats", "statsOptions", "stop", "swaps", + "tidbJson", "tokudbDefault", "tokudbFast", "tokudbLzma", @@ -2545,7 +2618,6 @@ var ( "boolType", "builtins", "cancel", - "capture", "cascaded", "causal", "cleanup", @@ -2573,7 +2645,6 @@ var ( "function", "grants", "histogramsInFlight", - "history", "imports", "incremental", "indexes", @@ -2587,6 +2658,7 @@ var ( "max_minutes", "national", "ncharType", + "never", "nextval", "none", "nvarcharType", @@ -2605,9 +2677,11 @@ var ( "queries", "recent", "region", + "remote", "replayer", "reset", "restores", + "reuse", "run", "security", "serializable", @@ -2616,6 +2690,7 @@ var ( "slave", "statsHealthy", "statsHistograms", + "statsLocked", "statsMeta", "strict", "switchesSym", @@ -2643,6 +2718,7 @@ var ( "bitXor", "bound", "cast", + "curDate", "curTime", "dateAdd", "dateSub", @@ -2661,6 +2737,7 @@ var ( "leader", "learner", "max", + "member", "min", "names", "now", @@ -2699,41 +2776,41 @@ var ( "weightString", "on", "'('", - "with", "stringLit", + "with", "not2", + "defaultKwd", "not", "as", - "defaultKwd", + "collate", "union", "using", "left", "right", - "collate", "'+'", "'-'", "mod", "partition", "ignore", "except", - "intersect", "null", + "intersect", "limit", "forKwd", + "charType", "values", "into", + "eq", "lock", "where", - "eq", "from", "fetch", + "replace", "order", "force", - "replace", - "charType", + "intLit", "set", "and", - "intLit", "or", "andand", "pipesAsOr", @@ -2745,9 +2822,9 @@ var ( "join", "like", "natural", - "'*'", "cross", "inner", + "'*'", "'}'", "rows", "use", @@ -2756,7 +2833,6 @@ var ( "groups", "desc", "binaryType", - "asc", "dayHour", "dayMicrosecond", "dayMinute", @@ -2768,9 +2844,10 @@ var ( "minuteSecond", "secondMicrosecond", "yearMonth", + "asc", "when", - "in", "elseKwd", + "in", "then", "'/'", "'%'", @@ -2792,9 +2869,10 @@ var ( "ifKwd", "regexpKwd", "rlike", + "memberof", "insert", - "singleAtIdentifier", "tableKwd", + "singleAtIdentifier", "currentUser", "falseKwd", "trueKwd", @@ -2803,19 +2881,21 @@ var ( "row", "hexLit", "paramMarker", - "interval", - "'{'", "bitLit", + "interval", "key", + "'{'", "database", "exists", "convert", + "builtinCurDate", "builtinNow", + "check", + "currentDate", "currentTs", "doubleAtIdentifier", "localTime", "localTs", - "check", "primary", "underscoreCS", "builtinCount", @@ -2828,7 +2908,6 @@ var ( "builtinBitOr", "builtinBitXor", "builtinCast", - "builtinCurDate", "builtinCurTime", "builtinDateAdd", "builtinDateSub", @@ -2849,7 +2928,6 @@ var ( "builtinVarSamp", "caseKwd", "cumeDist", - "currentDate", "currentRole", "currentTime", "denseRank", @@ -2870,11 +2948,11 @@ var ( "unique", "constraint", "references", - "generated", "selectKwd", + "generated", "character", - "match", "index", + "match", "to", "all", "'.'", @@ -2883,17 +2961,18 @@ var ( "maxValue", "jss", "juss", + "array", "lines", "assignmentEq", "by", - "Identifier", - "NotKeywordToken", - "TiDBKeyword", - "UnReservedKeyword", "alter", "require", "'@'", + "Identifier", + "NotKeywordToken", "sql", + "TiDBKeyword", + "UnReservedKeyword", "drop", "cascade", "read", @@ -2902,6 +2981,7 @@ var ( "create", "foreign", "fulltext", + "toTimestamp", "varcharacter", "varcharType", "change", @@ -2965,8 +3045,8 @@ var ( "TableName", "StringName", "deleteKwd", - "unsigned", "LengthNum", + "unsigned", "over", "zerofill", "ColumnName", @@ -2987,41 +3067,41 @@ var ( "WithClause", "SelectStmtWithClause", "SetOprStmt", - "hintComment", "Int64Num", + "hintComment", "FieldLen", "OptWindowingClause", + "UpdateStmtNoWith", "DeleteWithoutUsingStmt", "OrderBy", "SelectStmtLimit", "sqlBigResult", "sqlCalcFoundRows", "sqlSmallResult", - "UpdateStmtNoWith", - "CharsetKw", "InsertIntoStmt", "ReplaceIntoStmt", "UpdateStmt", + "CharsetKw", "Username", + "IfExists", "ExpressionList", "DeleteWithUsingStmt", - "IfExists", "PlacementPolicyOption", + "TableNameList", + "IfNotExists", "terminated", "DeleteFromStmt", "DistinctKwd", - "IfNotExists", "PartitionNameList", "DistinctOpt", "enclosed", "OptFieldLen", + "TimestampUnit", "WhereClause", "WhereClauseOptional", "DefaultKwdOpt", "escaped", "optionally", - "TableNameList", - "TimestampUnit", "ExprOrDefault", "JoinTable", "OptBinary", @@ -3031,18 +3111,18 @@ var ( "TableRef", "AnalyzeOptionListOpt", "FromOrIn", + "TimeUnit", "AlterTableStmt", "CharsetName", "ColumnNameList", + "DBName", "load", "NotSym", "noWriteToBinLog", "OrderByOptional", "PartDefOption", "SignedNum", - "TimeUnit", "BuggyDefaultFalseDistinctOpt", - "DBName", "DefaultFalseDistinctOpt", "JoinType", "NumLiteral", @@ -3059,9 +3139,11 @@ var ( "VariableName", "AllOrPartitionNameList", "ConstraintKeywordOpt", + "DatabaseSym", "FieldsOrColumns", "ForceOpt", "IndexPartSpecificationList", + "infile", "Priority", "RowFormat", "RowValue", @@ -3076,7 +3158,6 @@ var ( "ColumnDef", "CommitStmt", "DatabaseOption", - "DatabaseSym", "EscapedTableRef", "FieldTerminator", "grant", @@ -3100,19 +3181,20 @@ var ( "CollationName", "ColumnKeywordOpt", "DirectPlacementOption", + "DirectResourceGroupOption", "FieldOpt", "FieldOpts", "IdentList", "IndexName", "IndexOption", "IndexOptionList", - "infile", "LimitOption", "LockClause", "OptCharsetWithOptBinary", "OptNullTreatment", "PolicyName", "PriorityOpt", + "ResourceGroupName", "SelectLockOpt", "SelectStmtIntoOption", "TableRefs", @@ -3125,6 +3207,7 @@ var ( "BRIEOption", "BRIEOptions", "BRIEStringOptionName", + "BuiltinFunction", "ByList", "Char", "ConfigItemName", @@ -3157,6 +3240,7 @@ var ( "ColumnPosition", "CommonTableExpr", "CreateTableStmt", + "CurdateSym", "DatabaseOptionList", "DefaultTrueDistinctOpt", "EnforcedOrNot", @@ -3178,7 +3262,6 @@ var ( "OptTemporary", "PartDefOptionList", "PartitionDefinition", - "PasswordExpire", "PasswordOrLockOption", "PluginNameList", "PrimaryOpt", @@ -3212,6 +3295,7 @@ var ( "AlterInstanceStmt", "AlterOrderItem", "AlterPolicyStmt", + "AlterResourceGroupStmt", "AlterSequenceOption", "AlterSequenceStmt", "AlterTableSpec", @@ -3220,7 +3304,6 @@ var ( "BinlogStmt", "BRIEStmt", "BRIETables", - "BuiltinFunction", "call", "CallStmt", "CastType", @@ -3231,6 +3314,7 @@ var ( "ColumnOptionList", "ColumnOptionListOpt", "ColumnSetValue", + "CommentOrAttributeOption", "CompletionTypeWithinTransaction", "ConnectionOption", "ConnectionOptions", @@ -3239,6 +3323,7 @@ var ( "CreateImportStmt", "CreateIndexStmt", "CreatePolicyStmt", + "CreateResourceGroupStmt", "CreateRoleStmt", "CreateSequenceStmt", "CreateStatisticsStmt", @@ -3255,6 +3340,7 @@ var ( "DropImportStmt", "DropIndexStmt", "DropPolicyStmt", + "DropResourceGroupStmt", "DropRoleStmt", "DropSequenceStmt", "DropStatisticsStmt", @@ -3274,8 +3360,10 @@ var ( "Field", "FieldItem", "Fields", - "FlashbackClusterStmt", + "FlashbackDatabaseStmt", "FlashbackTableStmt", + "FlashbackToNewName", + "FlashbackToTimestampStmt", "FlushStmt", "FuncDatetimePrecList", "FuncDatetimePrecListOpt", @@ -3301,11 +3389,11 @@ var ( "LinearOpt", "LoadDataSetItem", "LoadStatsStmt", - "LocalOpt", "LocationLabelList", + "LockStatsStmt", "LockTablesStmt", "MaxValueOrExpressionList", - "NonTransactionalDeleteStmt", + "NonTransactionalDMLStmt", "NowSymOptionFractionParentheses", "NumList", "ObjectType", @@ -3341,6 +3429,8 @@ var ( "RenameTableStmt", "RenameUserStmt", "RepeatableOpt", + "ResourceGroupNameOption", + "ResourceGroupOptionList", "RestartStmt", "ResumeImportStmt", "revoke", @@ -3379,6 +3469,7 @@ var ( "TextStringList", "TraceStmt", "TruncateTableStmt", + "UnlockStatsStmt", "UnlockTablesStmt", "UserToUser", "UseStmt", @@ -3395,11 +3486,12 @@ var ( "AdminStmtLimitOpt", "AlterOrderList", "AlterSequenceOptionList", - "AlterTablePartitionOpt", "AlterTableSpecList", "AlterTableSpecListOpt", + "AlterTableSpecSingleOpt", "AnalyzeOptionList", "AnyOrAll", + "ArrayKwdOpt", "AsOfClauseOpt", "AsOpt", "AuthOption", @@ -3413,7 +3505,6 @@ var ( "both", "CharsetNameOrDefault", "CharsetOpt", - "ClearPasswordExpireOptions", "ColumnFormat", "ColumnList", "ColumnNameOrUserVariableList", @@ -3443,7 +3534,6 @@ var ( "FirstAndLastPartOpt", "FirstOrNext", "FixedPointType", - "FlashbackToNewName", "FloatingPointType", "FlushOption", "FromDual", @@ -3473,6 +3563,8 @@ var ( "LinesTerminated", "LoadDataSetList", "LoadDataSetSpecOpt", + "LocalOpt", + "LocationOpt", "LockType", "LogTypeOpt", "Match", @@ -3521,6 +3613,7 @@ var ( "SequenceOptionList", "SetOpr", "SetRoleOpt", + "ShardableStmt", "ShowIndexKwd", "ShowLikeOrWhereOpt", "ShowPlacementTarget", @@ -3620,7751 +3713,8007 @@ var ( yyReductions = []struct{ xsym, components int }{ {0, 1}, - {1306, 1}, - {806, 6}, - {806, 8}, - {806, 10}, - {806, 5}, - {806, 7}, - {806, 7}, - {806, 9}, - {1104, 1}, - {1104, 2}, - {1104, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {874, 3}, - {781, 4}, - {781, 4}, - {781, 4}, - {781, 4}, - {926, 3}, - {926, 3}, - {1138, 3}, - {1138, 3}, - {1170, 1}, - {1170, 2}, - {1170, 4}, - {1170, 8}, - {1170, 8}, + {1341, 1}, + {829, 6}, + {829, 8}, + {829, 10}, + {829, 5}, + {829, 7}, + {829, 7}, + {829, 9}, + {1147, 1}, + {1147, 2}, + {1147, 3}, + {898, 3}, + {898, 3}, + {898, 3}, + {898, 3}, + {898, 3}, + {1134, 1}, + {1134, 2}, + {1134, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {897, 3}, + {803, 4}, + {803, 4}, + {803, 4}, + {803, 4}, + {951, 3}, + {951, 3}, {1170, 3}, {1170, 3}, - {1077, 0}, - {1077, 3}, - {989, 1}, - {989, 5}, - {989, 5}, - {989, 5}, - {989, 5}, - {989, 6}, - {989, 2}, - {989, 5}, - {989, 6}, - {989, 8}, - {989, 8}, - {989, 1}, - {989, 1}, - {989, 3}, - {989, 4}, - {989, 5}, - {989, 3}, - {989, 4}, - {989, 8}, - {989, 4}, - {989, 7}, - {989, 3}, - {989, 4}, - {989, 4}, - {989, 4}, - {989, 4}, - {989, 2}, - {989, 2}, - {989, 4}, - {989, 4}, - {989, 5}, - {989, 3}, - {989, 2}, - {989, 2}, - {989, 5}, - {989, 6}, - {989, 6}, - {989, 8}, - {989, 5}, - {989, 5}, - {989, 3}, - {989, 3}, - {989, 3}, - {989, 5}, - {989, 1}, - {989, 1}, - {989, 1}, - {989, 1}, - {989, 2}, - {989, 2}, - {989, 1}, - {989, 1}, - {989, 4}, - {989, 3}, - {989, 4}, - {989, 1}, - {989, 1}, - {1286, 0}, - {1286, 5}, - {832, 1}, - {832, 1}, - {1354, 0}, - {1354, 1}, - {1353, 2}, - {1353, 2}, - {869, 1}, + {1205, 1}, + {1205, 2}, + {1205, 4}, + {1205, 8}, + {1205, 8}, + {1205, 3}, + {1205, 3}, + {1205, 2}, + {1106, 0}, + {1106, 3}, + {1015, 1}, + {1015, 5}, + {1015, 5}, + {1015, 5}, + {1015, 5}, + {1015, 6}, + {1015, 2}, + {1015, 5}, + {1015, 6}, + {1015, 8}, + {1015, 8}, + {1015, 1}, + {1015, 1}, + {1015, 3}, + {1015, 4}, + {1015, 5}, + {1015, 3}, + {1015, 4}, + {1015, 8}, + {1015, 4}, + {1015, 7}, + {1015, 3}, + {1015, 4}, + {1015, 4}, + {1015, 4}, + {1015, 4}, + {1015, 2}, + {1015, 2}, + {1015, 4}, + {1015, 4}, + {1015, 5}, + {1015, 3}, + {1015, 2}, + {1015, 2}, + {1015, 5}, + {1015, 6}, + {1015, 6}, + {1015, 8}, + {1015, 5}, + {1015, 5}, + {1015, 3}, + {1015, 3}, + {1015, 3}, + {1015, 5}, + {1015, 1}, + {1015, 1}, + {1015, 1}, + {1015, 1}, + {1015, 2}, + {1015, 2}, + {1015, 1}, + {1015, 1}, + {1015, 4}, + {1015, 3}, + {1015, 4}, + {1015, 1}, + {1015, 1}, + {1320, 0}, + {1320, 5}, + {854, 1}, + {854, 1}, + {1389, 0}, + {1389, 1}, + {1388, 2}, + {1388, 2}, + {892, 1}, + {892, 1}, + {893, 3}, + {893, 3}, + {893, 3}, + {893, 3}, + {893, 3}, + {906, 3}, + {906, 3}, + {1198, 2}, + {1198, 2}, + {850, 1}, + {850, 1}, + {1097, 0}, + {1097, 1}, + {896, 0}, + {896, 1}, + {954, 0}, + {954, 1}, + {954, 2}, + {1204, 0}, + {1204, 1}, + {1203, 1}, + {1203, 3}, + {809, 1}, + {809, 3}, + {855, 0}, + {855, 1}, + {855, 2}, + {1176, 1}, + {1143, 3}, + {1361, 1}, + {1361, 3}, + {1182, 3}, + {1144, 3}, + {1366, 1}, + {1366, 3}, + {1188, 3}, + {1140, 5}, + {1140, 3}, + {1140, 4}, + {1080, 4}, + {1080, 5}, + {1080, 5}, + {1078, 4}, + {1079, 0}, + {1079, 2}, + {1077, 4}, + {1168, 6}, + {1168, 8}, + {1167, 6}, + {1167, 2}, + {1339, 0}, + {1339, 2}, + {1339, 1}, + {1339, 3}, + {868, 5}, + {868, 6}, + {868, 7}, + {868, 7}, + {868, 8}, + {868, 9}, + {868, 8}, + {868, 7}, + {868, 6}, + {868, 8}, + {1006, 0}, + {1006, 2}, + {1006, 2}, + {826, 0}, + {826, 2}, + {1206, 1}, + {1206, 3}, + {1017, 2}, + {1017, 2}, + {1017, 3}, + {1017, 3}, + {1017, 2}, + {1017, 2}, + {916, 3}, + {950, 1}, + {950, 3}, + {1393, 0}, + {1393, 1}, {869, 1}, - {870, 3}, - {870, 3}, - {870, 3}, - {870, 3}, - {870, 3}, - {883, 3}, - {883, 3}, - {1165, 2}, - {1165, 2}, - {828, 1}, - {828, 1}, - {1067, 0}, - {1067, 1}, - {873, 0}, - {873, 1}, - {929, 0}, - {929, 1}, - {929, 2}, - {1172, 0}, - {1172, 1}, - {1171, 1}, - {1171, 3}, - {786, 1}, - {786, 3}, - {833, 0}, - {833, 1}, - {833, 2}, - {1144, 1}, - {1113, 3}, - {1326, 1}, - {1326, 3}, - {1150, 3}, - {1114, 3}, - {1331, 1}, - {1331, 3}, - {1155, 3}, - {1110, 5}, - {1110, 3}, - {1110, 4}, - {1049, 5}, - {1050, 4}, - {1218, 0}, - {1218, 2}, - {1136, 6}, - {1136, 8}, - {1135, 6}, - {1135, 2}, - {1304, 0}, - {1304, 2}, - {1304, 1}, - {1304, 3}, - {844, 5}, - {844, 6}, - {844, 7}, - {844, 7}, - {844, 8}, - {844, 9}, - {844, 8}, - {844, 7}, - {844, 6}, - {844, 8}, - {981, 0}, - {981, 2}, - {981, 2}, - {804, 0}, - {804, 2}, - {1173, 1}, - {1173, 3}, - {991, 2}, - {991, 2}, - {991, 3}, - {991, 3}, - {991, 2}, - {991, 2}, - {892, 3}, - {925, 1}, - {925, 3}, - {1358, 0}, - {1358, 1}, - {845, 1}, - {845, 2}, - {845, 2}, - {845, 2}, - {845, 4}, - {845, 5}, - {845, 6}, - {845, 4}, - {845, 5}, - {992, 2}, - {1359, 1}, - {1359, 3}, - {848, 3}, - {848, 3}, - {744, 1}, - {744, 3}, - {744, 5}, - {808, 1}, - {808, 3}, - {1001, 0}, - {1001, 1}, + {869, 2}, + {869, 2}, + {869, 2}, + {869, 4}, + {869, 5}, + {869, 6}, + {869, 4}, + {869, 5}, + {1018, 2}, + {1394, 1}, + {1394, 3}, + {872, 3}, + {872, 3}, + {766, 1}, + {766, 3}, + {766, 5}, + {831, 1}, + {831, 3}, + {1026, 0}, + {1026, 1}, + {1258, 0}, + {1258, 3}, + {901, 1}, + {901, 3}, + {1225, 0}, + {1225, 1}, + {1224, 1}, + {1224, 3}, + {1027, 1}, + {1027, 1}, {1226, 0}, {1226, 3}, - {877, 1}, - {877, 3}, - {1192, 0}, - {1192, 1}, - {1191, 1}, - {1191, 3}, - {1002, 1}, - {1002, 1}, - {1193, 0}, - {1193, 3}, - {849, 1}, - {849, 2}, - {956, 0}, - {956, 1}, - {810, 1}, - {810, 1}, - {934, 1}, - {934, 2}, - {1040, 0}, - {1040, 1}, - {1208, 2}, - {1208, 1}, - {928, 2}, - {928, 1}, - {928, 1}, - {928, 2}, - {928, 3}, - {928, 1}, - {928, 2}, - {928, 2}, - {928, 3}, - {928, 3}, - {928, 2}, - {928, 6}, - {928, 6}, - {928, 1}, - {928, 2}, - {928, 2}, - {928, 2}, - {928, 2}, - {1179, 0}, - {1179, 3}, - {1179, 5}, - {1311, 1}, - {1311, 1}, - {1311, 1}, - {1189, 1}, - {1189, 1}, - {1189, 1}, - {937, 0}, - {937, 2}, - {1343, 0}, - {1343, 1}, - {1343, 1}, - {1003, 1}, - {1003, 2}, - {1004, 0}, - {1004, 1}, - {1197, 7}, - {1197, 7}, - {1197, 7}, - {1197, 7}, - {1197, 8}, - {1197, 5}, - {1250, 2}, - {1250, 2}, - {1250, 2}, - {1251, 0}, - {1251, 1}, - {910, 5}, - {1087, 3}, - {1088, 3}, - {1259, 0}, - {1259, 1}, - {1259, 1}, - {1259, 2}, - {1259, 2}, - {1111, 1}, - {1111, 1}, - {1111, 2}, - {1111, 2}, - {1111, 2}, - {1204, 1}, - {1204, 1}, - {1204, 1}, - {1204, 1}, - {995, 3}, - {995, 3}, - {995, 4}, - {1081, 3}, - {1081, 1}, - {948, 1}, - {948, 3}, - {948, 4}, - {714, 4}, - {714, 4}, - {947, 1}, - {947, 1}, - {947, 1}, - {947, 1}, - {946, 1}, - {946, 1}, - {946, 1}, - {1134, 1}, - {1134, 2}, - {1134, 2}, - {820, 1}, - {820, 1}, - {820, 1}, - {1140, 1}, - {1140, 1}, - {1140, 1}, - {1181, 1}, - {1181, 1}, - {1016, 12}, - {1032, 3}, - {1012, 13}, - {1233, 0}, - {1233, 3}, - {836, 1}, - {836, 3}, - {827, 3}, - {827, 4}, - {1064, 0}, - {1064, 1}, - {1064, 1}, - {1064, 2}, - {1064, 2}, + {873, 1}, + {873, 2}, + {981, 0}, + {981, 1}, + {834, 1}, + {834, 1}, + {960, 1}, + {960, 2}, + {1068, 0}, + {1068, 1}, + {1241, 2}, + {1241, 1}, + {953, 2}, + {953, 1}, + {953, 1}, + {953, 2}, + {953, 3}, + {953, 1}, + {953, 2}, + {953, 2}, + {953, 3}, + {953, 3}, + {953, 2}, + {953, 6}, + {953, 6}, + {953, 1}, + {953, 2}, + {953, 2}, + {953, 2}, + {953, 2}, + {1213, 0}, + {1213, 3}, + {1213, 5}, + {1346, 1}, + {1346, 1}, + {1346, 1}, + {1222, 1}, + {1222, 1}, + {1222, 1}, + {963, 0}, + {963, 2}, + {1378, 0}, + {1378, 1}, + {1378, 1}, + {1028, 1}, + {1028, 2}, + {1029, 0}, + {1029, 1}, + {1230, 7}, + {1230, 7}, + {1230, 7}, + {1230, 7}, + {1230, 8}, + {1230, 5}, + {1284, 2}, + {1284, 2}, + {1284, 2}, + {1285, 0}, + {1285, 1}, + {935, 5}, + {1117, 3}, + {1118, 3}, + {1293, 0}, + {1293, 1}, + {1293, 1}, + {1293, 2}, + {1293, 2}, + {1141, 1}, + {1141, 1}, + {1141, 2}, + {1141, 2}, + {1141, 2}, + {1237, 1}, + {1237, 1}, + {1237, 1}, + {1237, 1}, + {924, 3}, + {924, 3}, + {924, 4}, + {1111, 3}, + {1111, 1}, + {974, 1}, + {974, 3}, + {974, 4}, + {974, 3}, + {974, 1}, + {736, 4}, + {736, 4}, + {973, 1}, + {973, 1}, + {973, 1}, + {973, 1}, + {972, 1}, + {972, 1}, + {972, 1}, + {957, 1}, + {957, 1}, + {1166, 1}, + {1166, 2}, + {1166, 2}, + {842, 1}, + {842, 1}, + {842, 1}, + {1172, 1}, + {1172, 1}, + {1172, 1}, + {1215, 1}, + {1215, 1}, + {1043, 12}, + {1060, 3}, + {1038, 13}, + {1265, 0}, + {1265, 3}, + {859, 1}, + {859, 3}, + {849, 3}, + {849, 4}, + {1094, 0}, + {1094, 1}, + {1094, 1}, + {1094, 2}, + {1094, 2}, + {1264, 0}, + {1264, 1}, + {1264, 1}, + {1264, 1}, + {1007, 4}, + {1007, 3}, + {1036, 5}, + {832, 1}, + {909, 1}, + {911, 1}, + {874, 4}, + {874, 4}, + {874, 4}, + {874, 2}, + {874, 1}, + {874, 5}, + {1234, 0}, + {1234, 1}, + {958, 1}, + {958, 2}, + {956, 12}, + {956, 7}, + {1116, 0}, + {1116, 4}, + {1116, 4}, + {816, 0}, + {816, 1}, + {1130, 0}, + {1130, 6}, + {1175, 6}, + {1175, 5}, + {1310, 0}, + {1310, 3}, + {1311, 1}, + {1311, 5}, + {1311, 6}, + {1311, 4}, + {1311, 5}, + {1311, 4}, + {1311, 3}, + {1311, 1}, + {1129, 0}, + {1129, 7}, + {1270, 1}, + {1270, 2}, + {1290, 0}, + {1290, 2}, + {1288, 0}, + {1288, 2}, + {1248, 0}, + {1248, 14}, + {1103, 0}, + {1103, 1}, + {1354, 0}, + {1354, 4}, + {1353, 0}, + {1353, 2}, + {1312, 0}, + {1312, 2}, + {1128, 0}, + {1128, 3}, + {1127, 1}, + {1127, 3}, + {978, 5}, + {1352, 0}, + {1352, 3}, + {1351, 1}, + {1351, 3}, + {1174, 3}, + {977, 0}, + {977, 2}, + {837, 3}, + {837, 3}, + {837, 4}, + {837, 3}, + {837, 4}, + {837, 4}, + {837, 3}, + {837, 3}, + {837, 3}, + {837, 3}, + {837, 1}, + {1309, 0}, + {1309, 4}, + {1309, 6}, + {1309, 1}, + {1309, 5}, + {1309, 1}, + {1309, 1}, + {1065, 0}, + {1065, 1}, + {1065, 1}, + {1210, 0}, + {1210, 1}, {1232, 0}, {1232, 1}, {1232, 1}, {1232, 1}, - {982, 4}, - {982, 3}, - {1010, 5}, - {817, 1}, - {886, 1}, - {850, 4}, - {850, 4}, - {850, 4}, - {850, 2}, - {850, 1}, - {850, 5}, - {1201, 0}, - {1201, 1}, - {932, 1}, - {932, 2}, - {931, 12}, - {931, 7}, - {1086, 0}, - {1086, 4}, - {1086, 4}, - {792, 0}, - {792, 1}, - {1100, 0}, - {1100, 6}, - {1143, 6}, - {1143, 5}, - {1276, 0}, - {1276, 3}, - {1277, 1}, - {1277, 5}, - {1277, 6}, - {1277, 4}, - {1277, 5}, - {1277, 4}, - {1277, 3}, - {1277, 1}, - {1099, 0}, - {1099, 7}, - {1238, 1}, - {1238, 2}, - {1256, 0}, - {1256, 2}, - {1254, 0}, - {1254, 2}, - {1215, 0}, - {1215, 14}, - {1073, 0}, + {1232, 1}, + {1233, 1}, + {1233, 1}, + {1233, 1}, + {1233, 1}, + {1276, 2}, + {1276, 4}, + {1046, 11}, + {1307, 0}, + {1307, 2}, + {1371, 0}, + {1371, 3}, + {1371, 3}, + {1371, 3}, + {1373, 0}, + {1373, 3}, + {1376, 0}, + {1376, 3}, + {1376, 3}, + {1375, 1}, + {1374, 0}, + {1374, 3}, + {1223, 1}, + {1223, 3}, + {1372, 0}, + {1372, 4}, + {1372, 4}, + {1051, 2}, + {789, 13}, + {789, 9}, + {802, 10}, + {807, 1}, + {807, 1}, + {807, 2}, + {807, 2}, + {856, 1}, + {1053, 4}, + {1055, 7}, + {1062, 6}, + {976, 0}, + {976, 1}, + {976, 2}, + {1064, 4}, + {1064, 6}, + {1063, 3}, + {1063, 5}, + {1058, 3}, + {1058, 5}, + {1061, 3}, + {1061, 5}, + {1061, 4}, + {936, 0}, + {936, 1}, + {936, 1}, + {1180, 1}, + {1180, 1}, + {758, 0}, + {758, 1}, + {1066, 0}, + {1184, 2}, + {1184, 5}, + {1184, 3}, + {1184, 6}, {1073, 1}, - {1319, 0}, - {1319, 4}, - {1318, 0}, - {1318, 2}, - {1278, 0}, - {1278, 2}, - {1098, 0}, - {1098, 3}, - {1097, 1}, - {1097, 3}, - {952, 5}, - {1317, 0}, - {1317, 3}, - {1316, 1}, - {1316, 3}, - {1142, 3}, - {951, 0}, - {951, 2}, - {813, 3}, - {813, 3}, - {813, 4}, - {813, 3}, - {813, 4}, - {813, 4}, - {813, 3}, - {813, 3}, - {813, 3}, - {813, 3}, - {813, 1}, - {1275, 0}, - {1275, 4}, - {1275, 6}, - {1275, 1}, - {1275, 5}, - {1275, 1}, + {1073, 1}, + {1073, 1}, + {1072, 2}, + {1072, 3}, + {1072, 2}, + {1072, 4}, + {1072, 7}, + {1072, 5}, + {1072, 7}, + {1072, 5}, + {1072, 3}, + {1072, 6}, + {1072, 6}, + {1071, 1}, + {1071, 1}, + {1071, 1}, + {1071, 1}, + {1071, 1}, + {1071, 1}, + {1071, 1}, + {1071, 1}, + {887, 2}, + {884, 3}, + {1019, 5}, + {1019, 5}, + {1020, 2}, + {1020, 2}, + {1020, 2}, + {1236, 1}, + {1236, 3}, + {922, 0}, + {922, 2}, + {919, 1}, + {919, 1}, + {918, 1}, + {918, 1}, + {918, 1}, + {918, 1}, + {918, 1}, + {918, 1}, + {918, 1}, + {918, 1}, + {923, 1}, + {923, 1}, + {923, 1}, + {923, 1}, + {920, 1}, + {920, 1}, + {920, 2}, + {921, 3}, + {921, 3}, + {921, 3}, + {921, 3}, + {921, 5}, + {921, 3}, + {921, 3}, + {921, 3}, + {921, 3}, + {921, 6}, + {921, 3}, + {921, 3}, + {921, 3}, + {921, 3}, + {921, 3}, + {921, 3}, + {762, 1}, + {784, 1}, + {755, 1}, + {952, 1}, + {952, 1}, + {952, 1}, + {1123, 1}, + {1123, 1}, + {1123, 1}, + {1138, 3}, + {1037, 8}, + {1173, 4}, + {1149, 4}, + {1008, 6}, + {1054, 4}, + {1161, 5}, + {1260, 0}, + {1260, 2}, + {1259, 0}, + {1259, 3}, + {1297, 0}, + {1297, 1}, + {1069, 0}, + {1069, 1}, + {1069, 2}, + {1069, 2}, + {1069, 2}, + {1069, 2}, + {1262, 0}, + {1262, 3}, + {1262, 3}, + {754, 3}, + {754, 3}, + {754, 3}, + {754, 3}, + {754, 2}, + {754, 9}, + {754, 3}, + {754, 3}, + {754, 3}, + {754, 1}, + {971, 1}, + {971, 1}, + {1254, 0}, + {1254, 4}, + {1254, 7}, + {1254, 3}, + {1254, 3}, + {757, 1}, + {757, 1}, + {756, 1}, + {756, 1}, + {801, 1}, + {801, 3}, + {1109, 1}, + {1109, 3}, + {848, 0}, + {848, 1}, + {1083, 0}, + {1083, 1}, + {1082, 1}, + {753, 3}, + {753, 3}, + {753, 4}, + {753, 5}, + {753, 1}, + {1228, 1}, + {1228, 1}, + {1228, 1}, + {1228, 1}, + {1228, 1}, + {1228, 1}, + {1228, 1}, + {1228, 1}, + {1214, 1}, + {1214, 2}, + {1272, 1}, + {1272, 2}, + {1267, 1}, + {1267, 2}, {1275, 1}, - {1037, 0}, - {1037, 1}, - {1037, 1}, - {1176, 0}, - {1176, 1}, - {1199, 0}, - {1199, 1}, - {1199, 1}, - {1199, 1}, - {1199, 1}, - {1200, 1}, - {1200, 1}, - {1200, 1}, - {1200, 1}, + {1275, 2}, + {1319, 1}, + {1319, 2}, + {1207, 1}, + {1207, 1}, + {1207, 1}, + {752, 5}, + {752, 3}, + {752, 5}, + {752, 4}, + {752, 3}, + {752, 5}, + {752, 1}, + {1142, 1}, + {1142, 1}, + {1274, 0}, + {1274, 2}, + {1074, 1}, + {1074, 3}, + {1074, 5}, + {1074, 2}, + {1245, 0}, + {1245, 1}, + {1244, 1}, {1244, 2}, - {1244, 4}, - {1019, 11}, - {1273, 0}, - {1273, 2}, - {1336, 0}, - {1336, 3}, - {1336, 3}, - {1336, 3}, - {1338, 0}, - {1338, 3}, - {1341, 0}, - {1341, 3}, - {1341, 3}, - {1340, 1}, - {1339, 0}, - {1339, 3}, - {1190, 1}, - {1190, 3}, - {1337, 0}, - {1337, 4}, - {1337, 4}, - {1024, 2}, - {766, 13}, - {766, 9}, - {779, 10}, - {783, 1}, - {783, 1}, - {783, 2}, - {783, 2}, - {851, 1}, - {1026, 4}, - {1028, 7}, - {1034, 6}, - {950, 0}, - {950, 1}, - {950, 2}, - {1036, 4}, - {1036, 6}, - {1035, 3}, - {1035, 5}, + {1244, 1}, + {1244, 2}, + {1247, 1}, + {1247, 3}, + {965, 3}, + {1089, 0}, + {1089, 2}, + {1209, 0}, + {1209, 1}, + {949, 3}, + {800, 0}, + {800, 2}, + {805, 0}, + {805, 3}, + {878, 0}, + {878, 1}, + {902, 0}, + {902, 1}, + {904, 0}, + {904, 2}, + {903, 3}, + {903, 1}, + {903, 3}, + {903, 2}, + {903, 1}, + {903, 1}, + {968, 1}, + {968, 3}, + {968, 3}, + {1266, 0}, + {1266, 1}, + {881, 2}, + {881, 2}, + {930, 1}, + {930, 1}, + {930, 1}, + {879, 1}, + {879, 1}, + {685, 1}, + {685, 1}, + {685, 1}, + {685, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {689, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {688, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {686, 1}, + {1022, 2}, + {1317, 1}, + {1317, 3}, + {1317, 4}, + {1317, 6}, + {795, 9}, + {1096, 0}, + {1096, 1}, + {1095, 5}, + {1095, 4}, + {1095, 4}, + {1095, 4}, + {1095, 4}, + {1095, 2}, + {1095, 1}, + {1095, 1}, + {1095, 1}, + {1095, 1}, + {1095, 2}, + {1002, 1}, + {1002, 1}, + {1000, 1}, + {1000, 3}, + {863, 3}, + {1370, 0}, + {1370, 1}, + {1369, 3}, + {1369, 1}, + {819, 1}, + {819, 1}, {1030, 3}, - {1030, 5}, - {1033, 3}, - {1033, 5}, - {1033, 4}, - {911, 0}, - {911, 1}, - {911, 1}, - {1148, 1}, - {1148, 1}, - {736, 0}, - {736, 1}, - {1038, 0}, - {1152, 2}, - {1152, 5}, - {1152, 3}, - {1152, 6}, - {1045, 1}, - {1045, 1}, - {1045, 1}, - {1044, 2}, - {1044, 3}, - {1044, 2}, - {1044, 4}, - {1044, 7}, - {1044, 5}, - {1044, 7}, - {1044, 5}, - {1044, 3}, - {1044, 6}, - {1044, 6}, - {1043, 1}, - {1043, 1}, - {1043, 1}, - {1043, 1}, - {1043, 1}, - {1043, 1}, - {1043, 1}, - {864, 2}, - {861, 3}, - {993, 5}, - {993, 5}, - {994, 2}, - {994, 2}, - {994, 2}, - {1203, 1}, - {1203, 3}, - {898, 0}, - {898, 2}, - {895, 1}, - {895, 1}, - {894, 1}, - {894, 1}, - {894, 1}, - {894, 1}, - {894, 1}, - {894, 1}, - {894, 1}, - {894, 1}, - {899, 1}, - {899, 1}, - {899, 1}, - {899, 1}, - {896, 1}, - {896, 1}, - {896, 2}, - {897, 3}, - {897, 3}, - {897, 3}, - {897, 3}, - {897, 5}, - {897, 3}, - {897, 3}, - {897, 3}, - {897, 3}, - {897, 6}, - {897, 3}, - {897, 3}, - {897, 3}, - {897, 3}, - {897, 3}, - {897, 3}, - {741, 1}, - {763, 1}, - {733, 1}, - {927, 1}, - {927, 1}, - {927, 1}, - {1093, 1}, - {1093, 1}, - {1093, 1}, - {1108, 3}, - {1011, 8}, - {1141, 4}, - {1117, 4}, - {983, 6}, - {1027, 4}, - {1129, 5}, - {1228, 0}, - {1228, 2}, {1227, 0}, + {1227, 1}, {1227, 3}, - {1263, 0}, - {1263, 1}, - {1041, 0}, - {1041, 1}, - {1041, 2}, - {1041, 2}, - {1041, 2}, - {1041, 2}, - {1230, 0}, - {1230, 3}, - {1230, 3}, - {732, 3}, - {732, 3}, - {732, 3}, - {732, 3}, - {732, 2}, - {732, 9}, - {732, 3}, - {732, 3}, - {732, 3}, - {732, 1}, - {945, 1}, - {945, 1}, - {1222, 0}, - {1222, 4}, - {1222, 7}, - {1222, 3}, - {1222, 3}, - {735, 1}, - {735, 1}, + {1294, 0}, + {1294, 5}, + {796, 6}, {734, 1}, {734, 1}, - {778, 1}, - {778, 3}, - {1079, 1}, - {1079, 3}, - {826, 0}, - {826, 1}, - {1053, 0}, - {1053, 1}, - {1052, 1}, - {731, 3}, - {731, 3}, - {731, 4}, - {731, 5}, - {731, 1}, - {1195, 1}, - {1195, 1}, - {1195, 1}, - {1195, 1}, - {1195, 1}, - {1195, 1}, - {1195, 1}, - {1195, 1}, - {1180, 1}, - {1180, 2}, - {1240, 1}, - {1240, 2}, - {1235, 1}, - {1235, 2}, - {1243, 1}, - {1243, 2}, - {1285, 1}, - {1285, 2}, - {1174, 1}, - {1174, 1}, - {1174, 1}, - {730, 5}, - {730, 3}, - {730, 5}, - {730, 4}, - {730, 3}, - {730, 1}, - {1112, 1}, - {1112, 1}, - {1242, 0}, - {1242, 2}, - {1046, 1}, - {1046, 3}, - {1046, 5}, - {1046, 2}, - {1212, 0}, - {1212, 1}, - {1211, 1}, - {1211, 2}, - {1211, 1}, - {1211, 2}, - {1214, 1}, - {1214, 3}, - {939, 3}, - {1059, 0}, - {1059, 2}, - {1175, 0}, - {1175, 1}, - {924, 3}, - {780, 0}, - {780, 2}, - {785, 0}, - {785, 3}, - {855, 0}, - {855, 1}, - {878, 0}, - {878, 1}, - {880, 0}, - {880, 2}, - {879, 3}, - {879, 1}, - {879, 3}, - {879, 2}, - {879, 1}, - {879, 1}, - {942, 1}, - {942, 3}, - {942, 3}, - {1234, 0}, - {1234, 1}, - {858, 2}, - {858, 2}, - {905, 1}, - {905, 1}, - {905, 1}, - {856, 1}, - {856, 1}, - {661, 1}, - {661, 1}, - {661, 1}, - {661, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {664, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {663, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {662, 1}, - {997, 2}, - {1283, 1}, - {1283, 3}, - {1283, 4}, - {1283, 6}, - {774, 9}, - {1066, 0}, - {1066, 1}, - {1065, 5}, - {1065, 4}, - {1065, 4}, - {1065, 4}, - {1065, 4}, - {1065, 2}, - {1065, 1}, - {1065, 1}, - {1065, 1}, - {1065, 1}, - {1065, 2}, - {977, 1}, - {977, 1}, + {734, 1}, + {734, 1}, + {734, 1}, + {734, 1}, + {734, 1}, + {734, 2}, + {734, 1}, + {734, 1}, + {734, 2}, + {734, 2}, + {735, 1}, + {735, 2}, + {1201, 1}, + {1201, 3}, + {1010, 2}, + {790, 3}, + {925, 1}, + {925, 3}, + {894, 1}, + {894, 2}, + {1306, 1}, + {1306, 1}, + {975, 0}, {975, 1}, - {975, 3}, - {839, 3}, - {1335, 0}, - {1335, 1}, - {1334, 3}, - {1334, 1}, - {797, 1}, - {797, 1}, - {1005, 3}, - {1194, 0}, + {975, 1}, + {836, 0}, + {836, 1}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 5}, + {751, 5}, + {751, 5}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 3}, + {751, 1}, + {733, 1}, + {733, 3}, + {733, 5}, + {746, 1}, + {746, 1}, + {746, 1}, + {746, 1}, + {746, 3}, + {746, 1}, + {746, 1}, + {746, 1}, + {746, 1}, + {746, 1}, + {746, 2}, + {746, 2}, + {746, 2}, + {746, 2}, + {746, 3}, + {746, 2}, + {746, 1}, + {746, 3}, + {746, 5}, + {746, 6}, + {746, 2}, + {746, 4}, + {746, 2}, + {746, 7}, + {746, 5}, + {746, 6}, + {746, 6}, + {746, 4}, + {746, 4}, + {746, 3}, + {746, 3}, + {1208, 0}, + {1208, 1}, + {808, 1}, + {808, 1}, + {810, 1}, + {810, 1}, + {840, 0}, + {840, 1}, + {959, 0}, + {959, 1}, + {839, 1}, + {839, 2}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {740, 1}, + {1122, 0}, + {1122, 2}, + {744, 1}, + {744, 1}, + {744, 1}, + {744, 1}, + {744, 1}, + {743, 1}, + {743, 1}, + {743, 1}, + {743, 1}, + {743, 1}, + {743, 1}, + {738, 4}, + {738, 4}, + {738, 2}, + {738, 3}, + {738, 2}, + {738, 4}, + {738, 6}, + {738, 2}, + {738, 2}, + {738, 2}, + {738, 4}, + {738, 6}, + {738, 4}, + {739, 4}, + {739, 4}, + {739, 6}, + {739, 8}, + {739, 8}, + {739, 6}, + {739, 6}, + {739, 6}, + {739, 6}, + {739, 6}, + {739, 8}, + {739, 8}, + {739, 8}, + {739, 8}, + {739, 4}, + {739, 6}, + {739, 6}, + {739, 7}, + {739, 4}, + {739, 7}, + {739, 7}, + {739, 1}, + {739, 8}, + {1256, 1}, + {1256, 1}, + {1256, 1}, + {1256, 1}, + {741, 1}, + {741, 1}, + {742, 1}, + {742, 1}, + {1364, 1}, + {1364, 1}, + {1364, 1}, + {745, 4}, + {745, 6}, + {745, 1}, + {747, 6}, + {747, 4}, + {747, 4}, + {747, 5}, + {747, 6}, + {747, 5}, + {747, 6}, + {747, 5}, + {747, 6}, + {747, 5}, + {747, 6}, + {747, 5}, + {747, 5}, + {747, 8}, + {747, 6}, + {747, 6}, + {747, 6}, + {747, 6}, + {747, 6}, + {747, 6}, + {747, 6}, + {747, 5}, + {747, 6}, + {747, 7}, + {747, 8}, + {747, 8}, + {747, 9}, + {1300, 0}, + {1300, 2}, + {737, 4}, + {737, 6}, + {1255, 0}, + {1255, 2}, + {1255, 3}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {828, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {813, 1}, + {1242, 0}, + {1242, 1}, + {1379, 1}, + {1379, 2}, + {1192, 4}, + {1240, 0}, + {1240, 2}, + {1023, 2}, + {1023, 3}, + {1023, 1}, + {1023, 1}, + {1023, 2}, + {1023, 2}, + {1023, 2}, + {1023, 2}, + {1023, 2}, + {1023, 1}, + {1023, 1}, + {1023, 2}, + {1023, 1}, + {861, 1}, + {861, 1}, + {861, 1}, + {910, 0}, + {910, 1}, + {759, 1}, + {759, 3}, + {804, 1}, + {804, 3}, + {942, 2}, + {942, 4}, + {992, 1}, + {992, 3}, + {932, 0}, + {932, 2}, + {1139, 0}, + {1139, 1}, + {1136, 4}, + {1316, 1}, + {1316, 1}, + {1070, 2}, + {1070, 4}, + {1367, 1}, + {1367, 3}, + {1048, 3}, + {1049, 1}, + {1049, 1}, + {886, 1}, + {886, 2}, + {886, 3}, + {886, 4}, + {1032, 4}, + {1032, 4}, + {1032, 5}, + {1032, 2}, + {1032, 3}, + {1032, 1}, + {1032, 2}, + {1165, 1}, + {1148, 1}, + {1090, 2}, + {771, 4}, + {772, 3}, + {773, 7}, + {1359, 0}, + {1359, 7}, + {1359, 5}, + {1358, 0}, + {1358, 1}, + {1358, 1}, + {1358, 1}, + {1360, 0}, + {1360, 1}, + {1360, 1}, + {1145, 0}, + {1145, 4}, + {770, 7}, + {770, 6}, + {770, 5}, + {770, 6}, + {770, 6}, + {782, 2}, + {782, 2}, + {781, 2}, + {781, 3}, + {1197, 3}, + {1197, 1}, + {955, 4}, + {1253, 2}, + {1380, 0}, + {1380, 2}, + {1381, 1}, + {1381, 3}, + {1193, 3}, + {948, 1}, + {1195, 3}, + {1386, 4}, + {1298, 0}, + {1298, 1}, + {1302, 0}, + {1302, 3}, + {1305, 0}, + {1305, 3}, + {1304, 0}, + {1304, 2}, + {1384, 1}, + {1384, 1}, + {1384, 1}, + {1383, 1}, + {1383, 1}, + {1004, 2}, + {1004, 2}, + {1004, 2}, + {1004, 4}, + {1004, 2}, + {1382, 4}, {1194, 1}, - {1194, 3}, - {1260, 0}, - {1260, 5}, - {775, 6}, - {712, 1}, - {712, 1}, - {712, 1}, - {712, 1}, - {712, 1}, - {712, 1}, - {712, 1}, - {712, 2}, - {712, 1}, - {712, 1}, - {712, 2}, - {712, 2}, - {713, 1}, - {713, 2}, - {1168, 1}, - {1168, 3}, - {985, 2}, - {767, 3}, - {900, 1}, - {900, 3}, - {871, 1}, - {871, 2}, - {1272, 1}, - {1272, 1}, - {949, 0}, - {949, 1}, - {949, 1}, - {812, 0}, - {812, 1}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 5}, - {729, 5}, - {729, 5}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 3}, - {729, 1}, - {711, 1}, - {711, 3}, - {711, 5}, - {724, 1}, - {724, 1}, - {724, 1}, - {724, 1}, - {724, 3}, - {724, 1}, - {724, 1}, - {724, 1}, - {724, 1}, - {724, 1}, - {724, 2}, - {724, 2}, - {724, 2}, - {724, 2}, - {724, 3}, - {724, 2}, - {724, 1}, - {724, 3}, - {724, 5}, - {724, 6}, - {724, 2}, - {724, 4}, - {724, 2}, - {724, 6}, - {724, 5}, - {724, 6}, - {724, 6}, - {724, 4}, - {724, 4}, - {724, 3}, - {724, 3}, - {784, 1}, - {784, 1}, + {1194, 2}, + {1194, 2}, + {1194, 2}, + {1194, 4}, + {787, 0}, {787, 1}, - {787, 1}, - {818, 0}, - {818, 1}, - {933, 0}, - {933, 1}, - {816, 1}, - {816, 2}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {718, 1}, - {1092, 0}, + {769, 2}, + {1385, 1}, + {1385, 1}, + {750, 4}, + {750, 4}, + {750, 4}, + {750, 4}, + {750, 4}, + {750, 5}, + {750, 7}, + {750, 7}, + {750, 6}, + {750, 6}, + {750, 9}, + {1124, 0}, + {1124, 3}, + {1124, 3}, + {1125, 0}, + {1125, 2}, + {908, 0}, + {908, 2}, + {908, 2}, + {1299, 0}, + {1299, 2}, + {1299, 2}, + {1357, 1}, + {914, 1}, + {914, 3}, + {875, 1}, + {875, 4}, + {825, 1}, + {825, 1}, + {824, 6}, + {824, 2}, + {824, 3}, + {883, 0}, + {883, 4}, + {941, 0}, + {941, 1}, + {940, 1}, + {940, 2}, + {967, 2}, + {967, 2}, + {967, 2}, + {1263, 0}, + {1263, 2}, + {1263, 3}, + {1263, 3}, + {966, 5}, + {880, 0}, + {880, 1}, + {880, 3}, + {880, 1}, + {880, 3}, + {1092, 1}, {1092, 2}, - {722, 1}, - {722, 1}, - {722, 1}, - {722, 1}, - {722, 1}, - {721, 1}, - {721, 1}, - {721, 1}, - {721, 1}, - {721, 1}, - {721, 1}, - {716, 4}, - {716, 4}, - {716, 2}, - {716, 3}, - {716, 2}, - {716, 4}, - {716, 6}, - {716, 2}, - {716, 2}, - {716, 2}, - {716, 4}, - {716, 6}, - {716, 4}, - {717, 4}, - {717, 4}, - {717, 6}, - {717, 8}, - {717, 8}, - {717, 6}, - {717, 6}, - {717, 6}, - {717, 6}, - {717, 6}, - {717, 8}, - {717, 8}, - {717, 8}, - {717, 8}, - {717, 4}, - {717, 6}, - {717, 6}, - {717, 7}, - {717, 4}, - {717, 7}, - {717, 7}, - {717, 1}, - {717, 8}, - {1224, 1}, - {1224, 1}, - {1224, 1}, - {1224, 1}, - {719, 1}, - {719, 1}, - {720, 1}, - {720, 1}, - {1329, 1}, - {1329, 1}, - {1329, 1}, - {723, 4}, - {723, 6}, - {723, 1}, - {725, 6}, - {725, 4}, - {725, 4}, - {725, 5}, - {725, 6}, - {725, 5}, - {725, 6}, - {725, 5}, - {725, 6}, - {725, 5}, - {725, 6}, - {725, 5}, - {725, 5}, - {725, 8}, - {725, 6}, - {725, 6}, - {725, 6}, - {725, 6}, - {725, 6}, - {725, 6}, - {725, 6}, - {725, 5}, - {725, 6}, - {725, 7}, - {725, 8}, - {725, 8}, - {725, 9}, - {1266, 0}, - {1266, 2}, - {715, 4}, - {715, 6}, - {1223, 0}, - {1223, 2}, - {1223, 3}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {815, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {796, 1}, - {1209, 0}, - {1209, 1}, - {1344, 1}, - {1344, 2}, - {1159, 4}, - {1207, 0}, - {1207, 2}, - {998, 2}, - {998, 3}, - {998, 1}, - {998, 1}, - {998, 2}, - {998, 2}, - {998, 2}, - {998, 2}, - {998, 2}, - {998, 1}, - {998, 1}, - {998, 2}, - {998, 1}, - {837, 1}, - {837, 1}, - {837, 1}, - {887, 0}, - {887, 1}, - {737, 1}, - {737, 3}, - {795, 1}, - {795, 3}, - {917, 2}, - {917, 4}, - {967, 1}, - {967, 3}, - {907, 0}, - {907, 2}, - {1109, 0}, - {1109, 1}, - {1106, 4}, - {1282, 1}, - {1282, 1}, - {1042, 2}, - {1042, 4}, - {1332, 1}, - {1332, 3}, - {1021, 3}, - {1022, 1}, - {1022, 1}, - {863, 1}, - {863, 2}, - {863, 3}, - {863, 4}, - {1006, 4}, - {1006, 4}, - {1006, 5}, - {1006, 2}, - {1006, 3}, - {1006, 1}, - {1006, 2}, - {1133, 1}, - {1116, 1}, - {1060, 2}, - {749, 4}, - {750, 3}, - {751, 7}, - {1324, 0}, - {1324, 7}, - {1324, 5}, - {1323, 0}, - {1323, 1}, + {1093, 0}, + {1093, 1}, + {820, 3}, + {820, 5}, + {820, 7}, + {820, 7}, + {820, 9}, + {820, 4}, + {820, 6}, + {820, 3}, + {820, 5}, + {841, 1}, + {841, 1}, + {1126, 0}, + {1126, 1}, + {845, 1}, + {845, 2}, + {845, 2}, + {1101, 0}, + {1101, 2}, + {905, 1}, + {905, 1}, {1323, 1}, {1323, 1}, + {1249, 1}, + {1249, 1}, + {1243, 0}, + {1243, 1}, + {791, 2}, + {791, 4}, + {791, 4}, + {791, 5}, + {852, 0}, + {852, 1}, + {1155, 1}, + {1155, 1}, + {1155, 1}, + {1155, 1}, + {1155, 1}, + {1155, 1}, + {1155, 1}, + {1155, 1}, + {1155, 1}, {1325, 0}, {1325, 1}, - {1325, 1}, - {1115, 0}, - {1115, 4}, - {748, 7}, - {748, 6}, - {748, 5}, - {748, 6}, - {748, 6}, - {760, 2}, - {760, 2}, - {759, 2}, - {759, 3}, - {1164, 3}, - {1164, 1}, - {930, 4}, - {1221, 2}, - {1345, 0}, - {1345, 2}, - {1346, 1}, - {1346, 3}, - {1160, 3}, - {923, 1}, - {1162, 3}, - {1351, 4}, - {1264, 0}, - {1264, 1}, - {1268, 0}, - {1268, 3}, - {1271, 0}, - {1271, 3}, - {1270, 0}, - {1270, 2}, - {1349, 1}, - {1349, 1}, - {1349, 1}, - {1348, 1}, - {1348, 1}, - {979, 2}, - {979, 2}, - {979, 2}, - {979, 4}, - {979, 2}, - {1347, 4}, - {1161, 1}, - {1161, 2}, - {1161, 2}, - {1161, 2}, - {1161, 4}, - {765, 0}, - {765, 1}, - {747, 2}, - {1350, 1}, - {1350, 1}, - {728, 4}, - {728, 4}, - {728, 4}, - {728, 4}, - {728, 4}, - {728, 5}, - {728, 7}, - {728, 7}, - {728, 6}, - {728, 6}, - {728, 9}, - {1094, 0}, - {1094, 3}, - {1094, 3}, - {1095, 0}, - {1095, 2}, - {885, 0}, - {885, 2}, - {885, 2}, - {1265, 0}, - {1265, 2}, - {1265, 2}, - {1322, 1}, + {1326, 2}, + {1326, 1}, {890, 1}, - {890, 3}, - {852, 1}, - {852, 4}, - {803, 1}, - {803, 1}, - {802, 6}, - {802, 2}, - {802, 3}, - {860, 0}, - {860, 4}, - {916, 0}, - {916, 1}, - {915, 1}, - {915, 2}, - {941, 2}, - {941, 2}, - {941, 2}, - {1231, 0}, - {1231, 2}, - {1231, 3}, - {1231, 3}, - {940, 5}, - {857, 0}, - {857, 1}, - {857, 3}, - {857, 1}, - {857, 3}, - {1062, 1}, - {1062, 2}, - {1063, 0}, - {1063, 1}, - {798, 3}, - {798, 5}, - {798, 7}, - {798, 7}, - {798, 9}, - {798, 4}, - {798, 6}, - {798, 3}, - {798, 5}, - {819, 1}, - {819, 1}, - {1096, 0}, - {1096, 1}, - {823, 1}, - {823, 2}, - {823, 2}, - {1071, 0}, - {1071, 2}, - {882, 1}, - {882, 1}, - {1289, 1}, - {1289, 1}, - {1216, 1}, - {1216, 1}, - {1210, 0}, - {1210, 1}, - {768, 2}, - {768, 4}, - {768, 4}, - {768, 5}, - {830, 0}, - {830, 1}, - {1123, 1}, - {1123, 1}, - {1123, 1}, - {1123, 1}, - {1123, 1}, - {1123, 1}, - {1123, 1}, - {1123, 1}, - {1123, 1}, - {1291, 0}, - {1291, 1}, - {1292, 2}, - {1292, 1}, - {867, 1}, - {918, 0}, - {918, 1}, - {1124, 1}, - {1124, 1}, - {1290, 1}, - {965, 0}, - {965, 1}, - {889, 0}, - {889, 5}, - {709, 3}, - {709, 3}, - {709, 3}, - {709, 3}, - {888, 0}, - {888, 3}, - {888, 3}, + {943, 0}, + {943, 1}, + {1156, 1}, + {1156, 1}, + {1324, 1}, + {990, 0}, + {990, 1}, + {913, 0}, + {913, 5}, + {731, 3}, + {731, 3}, + {731, 3}, + {731, 3}, + {912, 0}, + {912, 3}, + {912, 3}, + {912, 4}, + {912, 5}, + {912, 4}, + {912, 5}, + {912, 5}, + {912, 4}, + {1115, 0}, + {1115, 2}, + {783, 1}, + {783, 1}, + {783, 2}, + {783, 2}, + {780, 3}, + {780, 3}, + {779, 4}, + {779, 4}, + {779, 5}, + {779, 2}, + {779, 2}, + {779, 3}, + {778, 1}, + {778, 3}, + {774, 1}, + {774, 1}, + {1328, 2}, + {1328, 2}, + {1328, 2}, + {991, 1}, + {1024, 9}, + {1024, 9}, + {888, 2}, {888, 4}, - {888, 5}, + {888, 6}, {888, 4}, - {888, 5}, - {888, 5}, {888, 4}, - {1085, 0}, - {1085, 2}, - {761, 1}, - {761, 1}, - {761, 2}, - {761, 2}, - {758, 3}, - {758, 3}, - {757, 4}, - {757, 4}, - {757, 5}, - {757, 2}, - {757, 2}, - {757, 3}, - {756, 1}, - {756, 3}, - {752, 1}, - {752, 1}, - {1294, 2}, - {1294, 2}, - {1294, 2}, - {966, 1}, - {999, 9}, - {999, 9}, - {865, 2}, - {865, 4}, - {865, 6}, - {865, 4}, - {865, 4}, - {865, 3}, - {865, 6}, - {865, 6}, - {865, 3}, - {1128, 3}, - {1127, 6}, - {1126, 1}, - {1126, 1}, - {1126, 1}, - {1295, 3}, - {1295, 1}, - {1295, 1}, - {971, 1}, - {971, 3}, - {921, 3}, - {921, 2}, - {921, 2}, - {921, 3}, - {1239, 2}, - {1239, 2}, - {1239, 2}, - {1239, 1}, - {840, 1}, - {840, 1}, - {840, 1}, - {824, 1}, - {824, 1}, - {831, 1}, - {831, 3}, - {902, 1}, - {902, 3}, - {902, 3}, - {978, 3}, - {978, 4}, - {978, 4}, - {978, 4}, - {978, 3}, - {978, 3}, - {978, 2}, - {978, 4}, - {978, 4}, - {978, 2}, - {978, 2}, - {1186, 1}, - {1186, 1}, - {807, 1}, - {807, 1}, - {872, 1}, - {872, 1}, + {888, 3}, + {888, 6}, + {888, 6}, + {888, 3}, + {1160, 3}, + {1159, 6}, {1158, 1}, - {1158, 3}, - {727, 1}, - {727, 1}, - {726, 1}, - {710, 1}, - {777, 1}, - {777, 3}, - {777, 2}, - {777, 2}, - {868, 1}, - {868, 3}, - {1101, 1}, - {1101, 4}, - {893, 1}, - {822, 1}, - {822, 1}, - {801, 3}, - {801, 2}, - {963, 1}, - {963, 1}, - {821, 1}, - {821, 1}, - {862, 1}, - {862, 3}, - {1167, 2}, - {1167, 4}, - {1167, 4}, - {980, 3}, - {980, 5}, - {980, 6}, - {980, 4}, - {980, 4}, - {980, 5}, - {980, 5}, - {980, 5}, - {980, 6}, - {980, 4}, - {980, 5}, - {980, 6}, - {980, 6}, - {980, 4}, - {980, 3}, - {980, 3}, - {980, 4}, - {980, 4}, - {980, 5}, - {980, 5}, - {980, 3}, - {980, 3}, - {980, 3}, - {980, 3}, - {980, 3}, - {980, 3}, - {980, 3}, - {980, 3}, - {980, 4}, - {1166, 2}, - {1166, 2}, - {1166, 3}, - {1166, 3}, - {1225, 1}, - {1225, 3}, - {1057, 5}, - {1082, 1}, - {1082, 3}, - {1131, 3}, - {1131, 4}, - {1131, 4}, - {1131, 5}, - {1131, 4}, - {1131, 5}, - {1131, 4}, - {1131, 4}, - {1131, 6}, - {1131, 4}, - {1131, 8}, - {1131, 2}, - {1131, 5}, - {1131, 3}, - {1131, 3}, - {1131, 2}, - {1131, 5}, - {1131, 2}, - {1131, 2}, - {1131, 4}, - {1298, 2}, - {1298, 2}, - {1298, 4}, - {1301, 0}, - {1301, 1}, - {1300, 1}, - {1300, 3}, - {1130, 1}, - {1130, 1}, - {1130, 2}, - {1130, 2}, - {1130, 2}, - {1130, 1}, - {1130, 1}, - {1130, 1}, - {1130, 1}, - {1299, 0}, - {1299, 3}, - {1333, 0}, - {1333, 2}, - {1296, 1}, - {1296, 1}, - {1296, 1}, - {805, 1}, - {805, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 3}, - {1302, 3}, - {1302, 3}, - {1302, 3}, - {1302, 5}, - {1302, 4}, - {1302, 5}, - {1302, 5}, - {1302, 1}, - {1302, 5}, - {1302, 1}, - {1302, 2}, - {1302, 2}, - {1302, 2}, - {1302, 1}, - {1302, 2}, - {1302, 2}, - {1302, 2}, - {1302, 2}, - {1302, 2}, - {1302, 2}, - {1302, 2}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 2}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 1}, - {1302, 2}, - {1297, 0}, - {1297, 2}, - {1297, 2}, - {938, 0}, - {938, 1}, - {938, 1}, - {1310, 0}, - {1310, 1}, - {1310, 1}, - {1310, 1}, - {1090, 0}, - {1090, 1}, - {841, 0}, - {841, 2}, - {1132, 2}, - {1051, 3}, - {955, 1}, - {955, 3}, - {1220, 1}, - {1220, 1}, - {1220, 3}, + {1158, 1}, + {1158, 1}, + {1329, 3}, + {1329, 1}, + {1329, 1}, + {996, 1}, + {996, 3}, + {946, 3}, + {946, 2}, + {946, 2}, + {946, 3}, + {1271, 2}, + {1271, 2}, + {1271, 2}, + {1271, 1}, + {864, 1}, + {864, 1}, + {864, 1}, + {846, 1}, + {846, 1}, + {853, 1}, + {853, 3}, + {927, 1}, + {927, 3}, + {927, 3}, + {1003, 3}, + {1003, 4}, + {1003, 4}, + {1003, 4}, + {1003, 3}, + {1003, 3}, + {1003, 2}, + {1003, 4}, + {1003, 4}, + {1003, 2}, + {1003, 2}, {1220, 1}, - {1220, 2}, - {1220, 3}, {1220, 1}, - {1249, 0}, - {1249, 1}, - {1249, 1}, - {1249, 1}, - {1249, 1}, - {1249, 1}, - {829, 0}, - {829, 1}, - {829, 1}, - {1147, 0}, - {1147, 1}, - {969, 0}, - {969, 2}, - {1352, 0}, - {1352, 3}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {1137, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {920, 1}, - {825, 1}, - {825, 1}, - {825, 1}, - {825, 1}, - {825, 1}, - {825, 1}, - {825, 1}, - {825, 1}, - {825, 1}, - {1309, 1}, - {1309, 3}, - {903, 2}, - {1000, 1}, - {1000, 1}, - {968, 1}, - {968, 1}, - {1145, 1}, - {1145, 3}, - {1320, 0}, - {1320, 3}, - {842, 1}, - {842, 4}, - {842, 4}, - {842, 4}, - {842, 3}, - {842, 4}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 1}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 3}, - {842, 2}, - {842, 2}, - {842, 3}, - {842, 3}, - {842, 5}, - {842, 3}, - {835, 0}, - {835, 1}, - {1139, 1}, - {1139, 1}, - {1017, 0}, - {1017, 1}, - {919, 1}, - {919, 2}, - {919, 3}, - {1269, 0}, + {830, 1}, + {830, 1}, + {895, 1}, + {895, 1}, + {1191, 1}, + {1191, 3}, + {749, 1}, + {749, 1}, + {748, 1}, + {732, 1}, + {799, 1}, + {799, 3}, + {799, 2}, + {799, 2}, + {891, 1}, + {891, 3}, + {1131, 1}, + {1131, 4}, + {917, 1}, + {844, 1}, + {844, 1}, + {823, 3}, + {823, 2}, + {988, 1}, + {988, 1}, + {843, 1}, + {843, 1}, + {885, 1}, + {885, 3}, + {1200, 2}, + {1200, 4}, + {1200, 4}, + {1005, 3}, + {1005, 5}, + {1005, 6}, + {1005, 4}, + {1005, 4}, + {1005, 5}, + {1005, 5}, + {1005, 5}, + {1005, 6}, + {1005, 4}, + {1005, 5}, + {1005, 6}, + {1005, 6}, + {1005, 4}, + {1005, 3}, + {1005, 3}, + {1005, 4}, + {1005, 4}, + {1005, 5}, + {1005, 5}, + {1005, 3}, + {1005, 3}, + {1005, 3}, + {1005, 3}, + {1005, 3}, + {1005, 3}, + {1005, 3}, + {1005, 3}, + {1005, 4}, + {1199, 2}, + {1199, 2}, + {1199, 3}, + {1199, 3}, + {1257, 1}, + {1257, 3}, + {1087, 5}, + {1112, 1}, + {1112, 3}, + {1163, 3}, + {1163, 4}, + {1163, 4}, + {1163, 5}, + {1163, 4}, + {1163, 5}, + {1163, 5}, + {1163, 4}, + {1163, 4}, + {1163, 6}, + {1163, 4}, + {1163, 8}, + {1163, 2}, + {1163, 5}, + {1163, 3}, + {1163, 3}, + {1163, 2}, + {1163, 5}, + {1163, 2}, + {1163, 2}, + {1163, 4}, + {1333, 2}, + {1333, 2}, + {1333, 4}, + {1336, 0}, + {1336, 1}, + {1335, 1}, + {1335, 3}, + {1162, 1}, + {1162, 1}, + {1162, 2}, + {1162, 2}, + {1162, 2}, + {1162, 1}, + {1162, 1}, + {1162, 1}, + {1162, 1}, + {1334, 0}, + {1334, 3}, + {1368, 0}, + {1368, 2}, + {1331, 1}, + {1331, 1}, + {1331, 1}, + {827, 1}, + {827, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 3}, + {1337, 3}, + {1337, 3}, + {1337, 3}, + {1337, 5}, + {1337, 4}, + {1337, 5}, + {1337, 5}, + {1337, 1}, + {1337, 5}, + {1337, 1}, + {1337, 2}, + {1337, 2}, + {1337, 2}, + {1337, 1}, + {1337, 2}, + {1337, 2}, + {1337, 2}, + {1337, 2}, + {1337, 2}, + {1337, 2}, + {1337, 2}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 2}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 1}, + {1337, 2}, + {1332, 0}, + {1332, 2}, + {1332, 2}, + {964, 0}, + {964, 1}, + {964, 1}, + {1345, 0}, + {1345, 1}, + {1345, 1}, + {1345, 1}, + {1120, 0}, + {1120, 1}, + {865, 0}, + {865, 2}, + {1164, 2}, + {1081, 3}, + {980, 1}, + {980, 3}, + {1252, 1}, + {1252, 1}, + {1252, 3}, + {1252, 1}, + {1252, 2}, + {1252, 3}, + {1252, 1}, + {1283, 0}, + {1283, 1}, + {1283, 1}, + {1283, 1}, + {1283, 1}, + {1283, 1}, + {851, 0}, + {851, 1}, + {851, 1}, + {1179, 0}, + {1179, 1}, + {994, 0}, + {994, 2}, + {1387, 0}, + {1387, 3}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {1169, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {945, 1}, + {847, 1}, + {847, 1}, + {847, 1}, + {847, 1}, + {847, 1}, + {847, 1}, + {847, 1}, + {847, 1}, + {847, 1}, + {1344, 1}, + {1344, 3}, + {928, 2}, + {1025, 1}, + {1025, 1}, + {993, 1}, + {993, 1}, + {1177, 1}, + {1177, 3}, + {1355, 0}, + {1355, 3}, + {866, 1}, + {866, 4}, + {866, 4}, + {866, 4}, + {866, 3}, + {866, 4}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 1}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 3}, + {866, 2}, + {866, 2}, + {866, 3}, + {866, 3}, + {866, 5}, + {866, 3}, + {866, 7}, + {866, 3}, + {866, 3}, + {858, 0}, + {858, 1}, + {1171, 1}, + {1171, 1}, + {1044, 0}, + {1044, 1}, + {944, 1}, + {944, 2}, + {944, 3}, + {1303, 0}, + {1303, 1}, + {1185, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {862, 3}, + {1365, 1}, + {1365, 1}, + {1365, 1}, + {1291, 3}, + {1291, 2}, + {1291, 3}, + {1291, 3}, + {1291, 2}, {1269, 1}, - {1153, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {838, 3}, - {1330, 1}, - {1330, 1}, - {1330, 1}, - {1257, 3}, - {1257, 2}, - {1257, 3}, - {1257, 3}, - {1257, 2}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1237, 1}, - {1184, 1}, - {1184, 1}, - {1091, 0}, - {1091, 1}, - {1091, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1269, 1}, + {1218, 1}, + {1218, 1}, + {1121, 0}, + {1121, 1}, + {1121, 1}, + {1250, 1}, + {1250, 1}, + {1250, 1}, + {1251, 1}, + {1251, 1}, + {1251, 1}, + {1251, 2}, + {1216, 1}, + {1350, 3}, + {1350, 2}, + {1350, 3}, + {1350, 2}, + {1350, 3}, + {1350, 3}, + {1350, 2}, + {1350, 2}, + {1350, 1}, + {1350, 2}, + {1350, 5}, + {1350, 5}, + {1350, 1}, + {1350, 3}, + {1350, 2}, + {926, 1}, + {926, 1}, + {1289, 1}, + {1289, 2}, + {1289, 2}, + {1190, 2}, + {1190, 2}, + {1190, 1}, + {1190, 1}, + {1292, 2}, + {1292, 2}, + {1292, 1}, + {1292, 2}, + {1292, 2}, + {1292, 3}, + {1292, 3}, + {1292, 2}, + {1390, 1}, + {1390, 1}, {1217, 1}, + {1217, 2}, {1217, 1}, {1217, 1}, - {1219, 1}, - {1219, 1}, - {1219, 1}, - {1219, 2}, - {1182, 1}, - {1315, 3}, - {1315, 2}, - {1315, 3}, - {1315, 2}, - {1315, 3}, - {1315, 3}, - {1315, 2}, - {1315, 2}, - {1315, 1}, - {1315, 2}, - {1315, 5}, - {1315, 5}, - {1315, 1}, - {1315, 3}, - {1315, 2}, - {901, 1}, - {901, 1}, - {1255, 1}, - {1255, 2}, - {1255, 2}, - {1157, 2}, - {1157, 2}, - {1157, 1}, - {1157, 1}, - {1258, 2}, - {1258, 2}, - {1258, 1}, - {1258, 2}, - {1258, 2}, - {1258, 3}, - {1258, 3}, - {1258, 2}, - {1355, 1}, - {1355, 1}, - {1183, 1}, - {1183, 2}, - {1183, 1}, + {1217, 2}, + {1362, 1}, + {1362, 2}, + {1362, 1}, + {1362, 1}, + {907, 1}, + {907, 1}, + {907, 1}, + {907, 1}, + {1235, 1}, + {1235, 2}, + {1235, 2}, + {1235, 2}, + {1235, 3}, + {786, 3}, + {812, 0}, + {812, 1}, + {899, 1}, + {899, 1}, + {899, 1}, + {900, 0}, + {900, 2}, + {929, 0}, + {929, 1}, + {929, 1}, + {934, 5}, + {1295, 0}, + {1295, 1}, + {821, 0}, + {821, 2}, + {821, 3}, + {1296, 0}, + {1296, 2}, + {798, 2}, + {798, 1}, + {798, 2}, + {1119, 0}, + {1119, 2}, + {1348, 1}, + {1348, 3}, + {995, 1}, + {995, 1}, + {995, 1}, {1183, 1}, - {1183, 2}, - {1327, 1}, - {1327, 2}, - {1327, 1}, - {1327, 1}, - {884, 1}, - {884, 1}, - {884, 1}, - {884, 1}, - {1202, 1}, - {1202, 2}, - {1202, 2}, - {1202, 2}, - {1202, 3}, - {764, 3}, - {789, 0}, - {789, 1}, - {875, 1}, - {875, 1}, - {875, 1}, - {876, 0}, - {876, 2}, - {904, 0}, - {904, 1}, - {904, 1}, - {909, 5}, - {1261, 0}, - {1261, 1}, - {799, 0}, - {799, 2}, - {799, 3}, - {1262, 0}, - {1262, 2}, - {773, 2}, - {773, 1}, - {773, 2}, - {1089, 0}, - {1089, 2}, - {1313, 1}, - {1313, 3}, - {970, 1}, - {970, 1}, - {970, 1}, - {1151, 1}, - {1151, 3}, - {738, 1}, - {738, 1}, - {1314, 1}, - {1314, 1}, - {1314, 1}, - {776, 1}, - {776, 2}, - {772, 10}, - {772, 8}, - {1156, 2}, - {790, 2}, - {791, 0}, - {791, 1}, - {1360, 0}, - {1360, 1}, - {1018, 7}, - {1014, 4}, - {990, 7}, - {990, 9}, - {984, 3}, - {1236, 2}, - {1236, 6}, - {891, 2}, - {922, 1}, - {922, 3}, - {1008, 0}, - {1008, 2}, - {1196, 1}, - {1196, 2}, - {1007, 2}, - {1007, 2}, - {1007, 2}, - {1007, 2}, - {961, 0}, - {961, 1}, - {960, 2}, - {960, 2}, - {960, 2}, - {960, 2}, - {1287, 1}, - {1287, 3}, - {1287, 2}, - {962, 2}, - {962, 2}, - {962, 2}, + {1183, 3}, + {760, 1}, + {760, 1}, + {1349, 1}, + {1349, 1}, + {1349, 1}, + {797, 1}, + {797, 2}, + {788, 10}, + {788, 8}, + {1189, 2}, + {814, 2}, + {815, 0}, + {815, 1}, + {1395, 0}, + {1395, 1}, + {1045, 9}, + {1041, 4}, + {1016, 9}, + {1016, 9}, + {1009, 3}, + {1268, 2}, + {1268, 6}, + {915, 2}, + {947, 1}, + {947, 3}, + {1034, 0}, + {1034, 2}, + {1229, 1}, + {1229, 2}, + {1033, 2}, + {1033, 2}, + {1033, 2}, + {1033, 2}, + {986, 0}, + {986, 1}, + {985, 2}, + {985, 2}, + {985, 2}, + {985, 2}, + {1321, 1}, + {1321, 3}, + {1321, 2}, + {987, 2}, + {987, 2}, + {987, 2}, + {987, 2}, + {987, 2}, + {1031, 0}, + {1031, 2}, + {1031, 2}, + {1146, 0}, + {1146, 3}, + {1133, 0}, + {1133, 1}, + {1132, 1}, + {1132, 2}, + {979, 2}, + {979, 2}, + {979, 3}, + {979, 3}, + {979, 4}, + {979, 5}, + {979, 2}, + {979, 5}, + {979, 3}, + {979, 3}, + {979, 2}, + {979, 2}, + {979, 2}, + {1211, 0}, + {1211, 3}, + {1211, 3}, + {1211, 5}, + {1211, 5}, + {1211, 4}, + {1212, 1}, + {1088, 1}, + {1088, 1}, + {1154, 1}, + {1322, 1}, + {1322, 3}, + {870, 1}, + {870, 1}, + {870, 1}, + {870, 1}, + {870, 1}, + {870, 1}, + {870, 1}, + {870, 1}, + {1035, 7}, + {1035, 9}, + {1052, 5}, + {1052, 7}, + {1052, 7}, + {1157, 5}, + {1157, 7}, + {1157, 7}, + {1086, 9}, + {1084, 7}, + {1085, 4}, + {1196, 0}, + {1196, 3}, + {1196, 3}, + {1196, 3}, + {1196, 3}, + {1196, 3}, + {962, 1}, {962, 2}, - {1103, 0}, - {1103, 1}, - {1102, 1}, - {1102, 2}, - {954, 2}, - {954, 2}, - {954, 1}, - {954, 4}, - {954, 2}, - {954, 2}, - {953, 3}, - {1188, 0}, - {1177, 0}, - {1177, 3}, - {1177, 3}, - {1177, 5}, - {1177, 5}, - {1177, 4}, - {1178, 1}, - {1058, 1}, - {1058, 1}, - {1122, 1}, - {1288, 1}, - {1288, 3}, - {846, 1}, - {846, 1}, - {846, 1}, - {846, 1}, - {846, 1}, - {846, 1}, - {846, 1}, - {846, 1}, - {1009, 7}, - {1025, 5}, - {1025, 7}, - {1125, 5}, - {1125, 7}, - {1056, 9}, - {1054, 7}, - {1055, 4}, - {1163, 0}, - {1163, 3}, - {1163, 3}, - {1163, 3}, - {1163, 3}, - {1163, 3}, - {936, 1}, - {936, 2}, - {964, 1}, - {964, 1}, - {964, 1}, - {964, 3}, - {964, 3}, - {1121, 1}, - {1121, 3}, - {957, 1}, - {957, 4}, - {958, 1}, - {958, 2}, - {958, 1}, - {958, 1}, - {958, 2}, - {958, 2}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 2}, - {958, 1}, - {958, 2}, - {958, 1}, - {958, 2}, - {958, 2}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 1}, - {958, 3}, - {958, 2}, - {958, 2}, - {958, 2}, - {958, 2}, - {958, 2}, - {958, 2}, - {958, 2}, - {958, 1}, - {958, 1}, - {1083, 0}, - {1083, 1}, - {1083, 1}, - {1083, 1}, - {1107, 1}, - {1107, 3}, - {1107, 3}, - {1107, 3}, - {1107, 1}, - {1120, 7}, - {1119, 4}, - {859, 15}, - {1229, 0}, - {1229, 3}, - {1187, 0}, - {1187, 3}, + {989, 1}, + {989, 1}, + {989, 1}, + {989, 3}, + {989, 3}, + {1153, 1}, + {1153, 3}, + {982, 1}, + {982, 4}, + {983, 1}, + {983, 2}, + {983, 1}, + {983, 1}, + {983, 2}, + {983, 2}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 2}, + {983, 1}, + {983, 2}, + {983, 1}, + {983, 2}, + {983, 2}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 1}, + {983, 3}, + {983, 2}, + {983, 2}, + {983, 2}, + {983, 2}, + {983, 2}, + {983, 2}, + {983, 2}, + {983, 1}, + {983, 1}, + {1113, 0}, + {1113, 1}, + {1113, 1}, + {1113, 1}, + {1137, 1}, + {1137, 3}, + {1137, 3}, + {1137, 3}, + {1137, 1}, + {1152, 7}, + {1151, 4}, + {882, 15}, + {1261, 0}, + {1261, 3}, + {1221, 0}, + {1221, 3}, + {1280, 0}, + {1280, 1}, + {1281, 0}, + {1281, 1}, + {1281, 1}, {1076, 0}, - {1076, 1}, - {1048, 0}, - {1048, 2}, - {834, 1}, - {834, 1}, - {1213, 2}, - {1213, 1}, - {1047, 3}, - {1047, 4}, - {1047, 3}, - {1047, 3}, - {853, 1}, - {853, 1}, - {853, 1}, - {944, 0}, - {944, 3}, - {1307, 0}, - {1307, 3}, - {1245, 0}, - {1245, 3}, - {1247, 0}, - {1247, 2}, - {1246, 3}, + {1076, 2}, + {857, 1}, + {857, 1}, + {1246, 2}, {1246, 1}, - {1074, 3}, - {1154, 2}, - {1078, 3}, - {1149, 1}, - {1149, 1}, - {1146, 2}, - {1248, 1}, - {1248, 2}, - {1248, 1}, - {1248, 2}, - {1321, 1}, - {1321, 3}, - {1080, 6}, - {1205, 0}, - {1205, 2}, - {1205, 3}, - {1267, 0}, - {1267, 2}, - {1070, 2}, - {1070, 3}, - {1070, 3}, - {1069, 1}, - {1069, 2}, {1075, 3}, - {1029, 5}, - {1013, 7}, - {986, 6}, - {1015, 6}, - {1198, 0}, - {1198, 1}, - {1293, 1}, - {1293, 2}, - {913, 3}, - {913, 3}, - {913, 3}, - {913, 3}, - {913, 3}, - {913, 1}, - {913, 2}, - {913, 3}, - {913, 1}, - {913, 2}, - {913, 3}, - {913, 1}, - {913, 2}, - {913, 1}, - {913, 1}, - {913, 2}, - {814, 1}, - {814, 2}, - {814, 2}, - {1031, 4}, - {988, 5}, - {1169, 1}, - {1169, 2}, - {987, 1}, - {987, 1}, - {987, 3}, - {987, 3}, - {1061, 8}, - {1253, 0}, - {1253, 2}, - {1252, 0}, - {1252, 3}, - {1280, 0}, - {1280, 2}, + {1075, 4}, + {1075, 3}, + {1075, 3}, + {876, 1}, + {876, 1}, + {876, 1}, + {970, 0}, + {970, 3}, + {1342, 0}, + {1342, 3}, + {1277, 0}, + {1277, 3}, {1279, 0}, {1279, 2}, - {1039, 1}, - {976, 1}, - {976, 3}, - {912, 2}, - {1105, 5}, - {1105, 6}, - {1105, 9}, - {1105, 10}, - {1105, 5}, - {1105, 6}, - {1105, 4}, + {1278, 3}, + {1278, 1}, + {1104, 3}, + {1187, 2}, + {1108, 3}, + {1181, 1}, + {1181, 1}, + {1178, 2}, + {1282, 1}, + {1282, 2}, + {1282, 1}, + {1282, 2}, + {1356, 1}, + {1356, 3}, + {1110, 6}, + {1330, 1}, + {1330, 1}, + {1330, 1}, + {1330, 1}, + {1238, 0}, + {1238, 2}, + {1238, 3}, + {1301, 0}, + {1301, 2}, + {1100, 2}, + {1100, 3}, + {1100, 3}, + {1100, 2}, + {1099, 1}, + {1099, 2}, + {1105, 3}, + {1107, 3}, + {1186, 3}, + {1056, 5}, + {1040, 6}, + {1012, 6}, + {1057, 5}, + {1039, 7}, + {1011, 6}, + {1042, 6}, + {1231, 0}, + {1231, 1}, + {1327, 1}, + {1327, 2}, + {938, 3}, + {938, 3}, + {938, 3}, + {938, 3}, + {938, 3}, + {938, 1}, + {938, 2}, + {938, 3}, + {938, 1}, + {938, 2}, + {938, 3}, + {938, 1}, + {938, 2}, + {938, 1}, + {938, 1}, + {938, 2}, + {838, 1}, + {838, 2}, + {838, 2}, + {1059, 4}, + {1014, 5}, + {1202, 1}, + {1202, 2}, + {1013, 1}, + {1013, 1}, + {1013, 3}, + {1013, 3}, + {1091, 8}, + {1287, 0}, + {1287, 2}, + {1286, 0}, + {1286, 3}, + {1314, 0}, + {1314, 2}, + {1313, 0}, + {1313, 2}, + {1067, 1}, + {1001, 1}, + {1001, 3}, + {937, 2}, + {1135, 5}, + {1135, 6}, + {1135, 9}, + {1135, 10}, + {1135, 5}, + {1135, 6}, + {1135, 4}, + {1135, 5}, } yyXErrors = map[yyXError]string{} - yyParseTab = [4336][]uint16{ + yyParseTab = [4484][]uint16{ // 0 - {2045, 2045, 2544, 50: 2568, 71: 2688, 73: 2547, 82: 2579, 147: 2549, 155: 2577, 2562, 159: 2546, 173: 2573, 210: 2598, 215: 2701, 218: 2542, 225: 2597, 2564, 2697, 2548, 243: 2576, 248: 2552, 253: 2574, 255: 2543, 258: 2580, 276: 2566, 280: 2565, 287: 2578, 291: 2567, 303: 2557, 473: 2588, 2587, 495: 2586, 497: 2696, 504: 2572, 506: 2596, 525: 2691, 529: 2560, 567: 2571, 569: 2585, 646: 2581, 649: 2700, 653: 2545, 2690, 665: 2540, 669: 2551, 674: 2550, 679: 2595, 686: 2541, 709: 2592, 739: 2553, 748: 2594, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2668, 2667, 766: 2554, 772: 2689, 774: 2649, 2660, 2679, 779: 2555, 783: 2614, 800: 2563, 806: 2602, 809: 2694, 844: 2608, 2609, 849: 2612, 854: 2692, 859: 2652, 861: 2662, 863: 2657, 2666, 2669, 2569, 931: 2621, 935: 2558, 973: 2695, 980: 2600, 982: 2601, 2604, 2605, 986: 2607, 988: 2606, 990: 2603, 992: 2610, 2611, 996: 2570, 2648, 999: 2617, 1009: 2625, 2618, 2619, 2620, 2626, 2624, 2627, 2628, 1018: 2623, 2622, 1021: 2613, 2575, 2559, 2629, 2641, 2630, 2631, 2632, 2634, 2638, 2635, 2639, 2640, 2633, 2637, 2636, 1038: 2599, 1042: 2615, 1044: 2616, 2561, 1049: 2643, 2644, 2642, 1054: 2646, 2647, 2645, 1060: 2685, 2650, 1068: 2699, 2698, 2651, 1075: 2653, 1078: 2682, 1080: 2686, 1105: 2654, 2655, 1108: 2656, 1110: 2661, 1113: 2658, 2659, 1116: 2684, 2663, 2693, 2665, 2664, 1125: 2670, 1127: 2672, 2671, 2675, 1131: 2676, 1133: 2683, 1136: 2673, 2687, 1141: 2674, 1152: 2677, 2678, 2681, 1156: 2680, 1306: 2538, 1309: 2539}, - {2537}, - {2536, 6871}, - {18: 6823, 134: 6820, 170: 6821, 196: 6824, 262: 6822, 489: 4191, 569: 1856, 582: 6163, 851: 6819, 855: 4190}, - {170: 6804, 569: 6803}, + {2107, 2107, 2623, 56: 2647, 78: 2773, 80: 2626, 89: 2658, 161: 2628, 168: 2656, 2641, 173: 2625, 186: 2652, 203: 2786, 225: 2677, 232: 2621, 240: 2676, 2643, 2782, 2627, 258: 2655, 263: 2631, 268: 2653, 270: 2622, 273: 2659, 291: 2645, 295: 2644, 302: 2657, 305: 2646, 318: 2636, 492: 2667, 494: 2666, 515: 2665, 518: 2781, 522: 2651, 526: 2675, 544: 2776, 548: 2639, 587: 2650, 2664, 665: 2660, 668: 2785, 673: 2624, 2775, 682: 2619, 690: 2630, 695: 2629, 701: 2674, 708: 2620, 731: 2671, 761: 2632, 770: 2673, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2753, 2752, 788: 2774, 2633, 795: 2732, 2745, 2764, 802: 2634, 807: 2694, 822: 2642, 829: 2681, 833: 2779, 868: 2688, 2689, 873: 2692, 877: 2777, 882: 2735, 884: 2747, 886: 2742, 2751, 2754, 2648, 956: 2701, 961: 2637, 998: 2780, 1005: 2679, 1007: 2680, 2683, 2684, 1011: 2686, 2687, 1014: 2685, 1016: 2682, 1018: 2690, 2691, 1021: 2649, 2731, 1024: 2697, 1035: 2705, 2698, 2699, 2700, 2706, 2707, 2704, 2708, 2709, 1045: 2703, 2702, 1048: 2693, 2654, 2638, 2710, 2723, 2711, 2712, 2713, 2715, 2719, 2720, 2716, 2721, 2722, 2714, 2718, 2717, 1066: 2678, 1070: 2695, 1072: 2696, 2640, 1077: 2727, 2725, 1080: 2726, 2724, 1084: 2729, 2730, 2728, 1090: 2770, 2733, 1098: 2784, 2783, 2734, 1105: 2736, 1107: 2737, 2767, 1110: 2771, 1135: 2739, 2740, 1138: 2741, 1140: 2746, 1143: 2743, 2744, 1148: 2769, 2748, 2778, 2750, 2749, 1157: 2755, 1159: 2757, 2756, 2760, 1163: 2761, 1165: 2768, 1168: 2758, 2772, 1173: 2759, 1184: 2762, 2763, 2738, 2766, 1189: 2765, 1341: 2617, 1344: 2618}, + {2616}, + {2615, 7098}, + {18: 7044, 51: 7043, 151: 7040, 183: 7041, 210: 7045, 277: 7042, 508: 4304, 588: 1916, 602: 6313, 856: 7039, 878: 4303}, + {183: 7024, 588: 7023}, // 5 - {569: 6797}, - {325: 6788, 569: 6789}, - {379: 6769, 488: 6770, 569: 2383, 1304: 6768}, - {350: 6724, 569: 6723}, - {2351, 2351, 366: 6722, 373: 6721}, + {588: 7017}, + {339: 7001, 588: 7002, 602: 6313, 856: 7003}, + {393: 6982, 507: 6983, 588: 2450, 1339: 6981}, + {363: 6937, 588: 6936}, + {2418, 2418, 380: 6935, 387: 6934}, // 10 - {402: 6710}, - {475: 6709}, - {2318, 2318, 72: 5993, 507: 5991, 800: 5992, 1006: 6708}, - {18: 2095, 83: 2095, 103: 2095, 134: 6485, 142: 2095, 160: 597, 162: 6422, 167: 5591, 170: 6486, 174: 6487, 196: 6489, 6126, 221: 6477, 509: 6484, 569: 2064, 582: 6163, 642: 6479, 649: 2200, 668: 2095, 676: 6481, 851: 6482, 938: 6488, 950: 5590, 1232: 6478, 1273: 6483, 1303: 6480}, - {18: 6429, 103: 6423, 125: 2064, 134: 6427, 160: 597, 162: 6422, 167: 5591, 170: 6424, 173: 1034, 6425, 196: 6430, 6126, 221: 6418, 289: 6426, 569: 2064, 582: 6163, 649: 6420, 851: 6419, 938: 6428, 950: 6421}, + {419: 6923}, + {493: 6922}, + {2385, 2385, 79: 6142, 527: 6140, 822: 6141, 1032: 6921}, + {18: 2157, 51: 6652, 90: 2157, 110: 2157, 151: 6648, 156: 2157, 174: 634, 176: 6577, 181: 5738, 183: 6649, 187: 6650, 210: 6653, 6276, 235: 6640, 528: 6647, 588: 2126, 602: 6313, 662: 6642, 668: 2263, 687: 2157, 697: 6644, 856: 6645, 964: 6651, 976: 5737, 1264: 6641, 1307: 6646, 1338: 6643}, + {18: 6584, 51: 6585, 110: 6578, 137: 2126, 151: 6582, 174: 634, 176: 6577, 181: 5738, 183: 6579, 186: 1073, 6580, 210: 6586, 6276, 213: 6581, 235: 6573, 588: 2126, 602: 6313, 668: 6575, 856: 6574, 964: 6583, 976: 6576}, // 15 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 6417}, - {2: 853, 853, 853, 853, 853, 853, 853, 10: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 50: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 489: 853, 500: 853, 753: 853, 853, 853, 762: 5398, 867: 5399, 918: 6405}, - {2072, 2072}, - {2071, 2071}, - {473: 2588, 495: 2586, 569: 2585, 646: 2581, 654: 2690, 709: 3888, 739: 2553, 748: 3887, 2582, 2583, 2584, 2593, 756: 2591, 3889, 3890, 766: 5184, 772: 5772, 779: 5185}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 6572}, + {2: 892, 892, 892, 892, 892, 892, 892, 10: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 59: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 508: 892, 520: 892, 775: 892, 892, 892, 785: 5545, 890: 5546, 943: 6560}, + {2134, 2134}, + {2133, 2133}, + {492: 2667, 515: 2665, 588: 2664, 665: 2660, 674: 2775, 731: 3997, 761: 2632, 770: 3996, 2661, 2662, 2663, 2672, 778: 2670, 3998, 3999, 788: 5324, 5322, 802: 5323}, // 20 - {73: 2547, 147: 2549, 155: 2577, 2562, 159: 2546, 215: 6378, 256: 6377, 473: 2588, 2587, 495: 2586, 504: 2572, 506: 6381, 567: 2571, 569: 2585, 646: 2581, 653: 2545, 2690, 709: 6379, 739: 2553, 748: 6380, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 6387, 6386, 766: 2554, 772: 2689, 774: 6384, 6385, 6383, 779: 2555, 783: 6382, 800: 2563, 809: 6396, 844: 6395, 6389, 849: 6390, 859: 6388, 861: 6392, 863: 6393, 6391, 6394, 920: 6376}, - {2: 2040, 2040, 2040, 2040, 2040, 2040, 2040, 10: 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 50: 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 473: 2040, 2040, 494: 2040, 2040, 504: 2040, 567: 2040, 569: 2040, 646: 2040, 653: 2040, 2040, 665: 2040, 739: 2040}, - {2: 2039, 2039, 2039, 2039, 2039, 2039, 2039, 10: 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 50: 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 473: 2039, 2039, 494: 2039, 2039, 504: 2039, 567: 2039, 569: 2039, 646: 2039, 653: 2039, 2039, 665: 2039, 739: 2039}, - {2: 2038, 2038, 2038, 2038, 2038, 2038, 2038, 10: 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 50: 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 473: 2038, 2038, 494: 2038, 2038, 504: 2038, 567: 2038, 569: 2038, 646: 2038, 653: 2038, 2038, 665: 2038, 739: 2038}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 6346, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 2588, 2587, 494: 6345, 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 653: 6347, 2690, 661: 3921, 2762, 2763, 2761, 2707, 709: 2708, 737: 6343, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 6344}, + {80: 2626, 161: 2628, 168: 2656, 2641, 173: 2625, 203: 6533, 271: 6532, 492: 2667, 494: 2666, 515: 2665, 522: 2651, 526: 6536, 587: 2650, 2664, 665: 2660, 673: 2624, 2775, 731: 6534, 761: 2632, 770: 6535, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 6542, 6541, 788: 2774, 2633, 795: 6539, 6540, 6538, 802: 2634, 807: 6537, 822: 2642, 833: 6551, 868: 6550, 6544, 873: 6545, 882: 6543, 884: 6547, 886: 6548, 6546, 6549, 945: 6531}, + {2: 2102, 2102, 2102, 2102, 2102, 2102, 2102, 10: 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 59: 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 2102, 492: 2102, 494: 2102, 513: 2102, 515: 2102, 522: 2102, 587: 2102, 2102, 665: 2102, 673: 2102, 2102, 682: 2102, 761: 2102}, + {2: 2101, 2101, 2101, 2101, 2101, 2101, 2101, 10: 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 59: 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 2101, 492: 2101, 494: 2101, 513: 2101, 515: 2101, 522: 2101, 587: 2101, 2101, 665: 2101, 673: 2101, 2101, 682: 2101, 761: 2101}, + {2: 2100, 2100, 2100, 2100, 2100, 2100, 2100, 10: 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 59: 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 492: 2100, 494: 2100, 513: 2100, 515: 2100, 522: 2100, 587: 2100, 2100, 665: 2100, 673: 2100, 2100, 682: 2100, 761: 2100}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 6500, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 2667, 494: 2666, 513: 6499, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 673: 6501, 2775, 682: 2795, 685: 4030, 2850, 688: 2851, 2849, 731: 2796, 759: 6497, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 6498}, // 25 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6342, 2762, 2763, 2761}, - {156: 6340}, - {569: 6258, 582: 6163, 851: 6257, 994: 6336}, - {569: 6258, 582: 6163, 851: 6257, 994: 6256}, - {134: 6254}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6496, 2850, 688: 2851, 2849}, + {169: 6494}, + {588: 6412, 602: 6313, 856: 6411, 1020: 6490}, + {588: 6412, 602: 6313, 856: 6411, 1020: 6410}, + {151: 6408}, // 30 - {134: 6249}, - {134: 6243}, - {16: 3836, 18: 6088, 30: 6117, 6116, 102: 590, 111: 590, 125: 590, 597, 134: 6077, 141: 597, 162: 6125, 181: 6101, 190: 6086, 197: 6126, 202: 597, 211: 6127, 216: 6111, 590, 250: 6108, 275: 6107, 307: 6100, 313: 6122, 315: 6105, 318: 6087, 326: 6103, 6120, 329: 6094, 337: 6092, 339: 6110, 343: 6098, 345: 6109, 6081, 6119, 349: 6124, 351: 6090, 358: 6082, 365: 6096, 375: 6085, 6084, 382: 6123, 386: 6112, 389: 6118, 6115, 6114, 403: 6104, 505: 3837, 569: 6080, 593: 6099, 647: 3835, 649: 6089, 653: 6121, 674: 6079, 773: 6095, 914: 6113, 938: 6102, 943: 6091, 959: 6106, 1020: 6093, 1090: 6083, 1296: 6097, 1302: 6078}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 6066, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6068, 2762, 2763, 2761, 1283: 6067}, - {2: 853, 853, 853, 853, 853, 853, 853, 10: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 50: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 489: 853, 496: 853, 753: 853, 853, 853, 762: 5398, 867: 5399, 918: 6053}, + {151: 6403}, + {151: 6397}, + {16: 3943, 18: 6237, 30: 6266, 6265, 109: 627, 136: 627, 627, 634, 151: 6226, 155: 634, 176: 6275, 194: 6250, 204: 6235, 211: 6276, 216: 634, 226: 6277, 230: 6260, 627, 265: 6257, 290: 6256, 322: 6249, 328: 6272, 330: 6254, 333: 6236, 340: 6252, 6270, 343: 6243, 351: 6241, 353: 6259, 357: 6247, 359: 6258, 6230, 6269, 6274, 364: 6239, 371: 6231, 379: 6245, 389: 6234, 6233, 397: 6273, 402: 6261, 405: 6267, 6264, 6268, 6263, 420: 6253, 514: 3944, 588: 6229, 615: 6248, 667: 3942, 6238, 673: 6271, 695: 6228, 798: 6244, 939: 6262, 964: 6251, 969: 6240, 984: 6255, 1047: 6242, 1120: 6232, 1331: 6246, 1337: 6227}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 6215, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6217, 2850, 688: 2851, 2849, 1317: 6216}, + {2: 892, 892, 892, 892, 892, 892, 892, 10: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 59: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 508: 892, 516: 892, 775: 892, 892, 892, 785: 5545, 890: 5546, 943: 6202}, // 35 - {2: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 10: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 50: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 496: 1057, 753: 5403, 5402, 5401, 837: 5404, 887: 6019}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6014, 2762, 2763, 2761}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6008, 2762, 2763, 2761}, - {173: 6006}, - {173: 1035}, + {2: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 10: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 59: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 516: 1096, 775: 5550, 5549, 5548, 861: 5551, 910: 6168}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6163, 2850, 688: 2851, 2849}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6157, 2850, 688: 2851, 2849}, + {186: 6155}, + {186: 1074}, // 40 - {1033, 1033, 72: 5993, 507: 5991, 650: 5990, 800: 5992, 1006: 5989}, - {1022, 1022}, - {1021, 1021}, - {475: 5988}, - {2: 858, 858, 858, 858, 858, 858, 858, 10: 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 50: 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 5958, 5964, 5965, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 473: 858, 475: 858, 858, 858, 479: 858, 482: 858, 858, 485: 858, 858, 858, 492: 858, 495: 858, 504: 858, 858, 508: 858, 515: 5961, 520: 858, 530: 858, 564: 858, 567: 858, 858, 570: 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 582: 858, 858, 858, 858, 858, 858, 858, 858, 592: 858, 858, 595: 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 648: 858, 651: 3546, 745: 3544, 3545, 753: 5403, 5402, 5401, 762: 5398, 769: 5957, 5960, 5956, 784: 5879, 787: 5954, 837: 5955, 867: 5953, 1123: 5963, 5959, 1291: 5952, 5962}, + {1072, 1072, 79: 6142, 527: 6140, 670: 6139, 822: 6141, 1032: 6138}, + {1061, 1061}, + {1060, 1060}, + {493: 6137}, + {2: 897, 897, 897, 897, 897, 897, 897, 10: 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 59: 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 6107, 6113, 6114, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 492: 897, 897, 495: 897, 897, 897, 502: 897, 897, 897, 897, 897, 510: 897, 514: 897, 897, 522: 897, 525: 897, 534: 6110, 541: 897, 549: 897, 583: 897, 587: 897, 589: 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 601: 897, 897, 897, 897, 897, 897, 608: 897, 897, 897, 897, 897, 614: 897, 897, 617: 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 669: 897, 671: 3653, 767: 3651, 3652, 775: 5550, 5549, 5548, 785: 5545, 792: 6106, 6109, 6105, 808: 6028, 810: 6103, 861: 6104, 890: 6102, 1155: 6112, 6108, 1325: 6101, 6111}, // 45 - {247, 247, 49: 247, 472: 247, 474: 247, 480: 247, 247, 490: 247, 247, 493: 247, 247, 496: 247, 247, 2722, 500: 5927, 247, 247, 513: 247, 790: 2723, 5928, 1221: 5926}, - {848, 848, 49: 848, 472: 848, 474: 848, 480: 848, 848, 490: 848, 848, 493: 848, 848, 496: 848, 848, 501: 848, 848, 513: 5917, 939: 5919, 965: 5918}, - {1297, 1297, 49: 1297, 472: 1297, 474: 1297, 480: 1297, 1297, 490: 1297, 1297, 493: 1297, 1297, 496: 1297, 1297, 501: 1297, 2725, 767: 2726, 812: 5913}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5908}, - {575: 3896, 912: 3895, 976: 3894}, + {275, 275, 58: 275, 491: 275, 494: 275, 500: 275, 275, 509: 275, 511: 275, 275, 275, 516: 275, 518: 275, 2810, 6076, 275, 523: 275, 532: 275, 814: 2811, 6077, 1253: 6075}, + {887, 887, 58: 887, 491: 887, 494: 887, 500: 887, 887, 509: 887, 511: 887, 887, 887, 516: 887, 518: 887, 521: 887, 523: 887, 532: 6066, 965: 6068, 990: 6067}, + {1338, 1338, 58: 1338, 491: 1338, 494: 1338, 500: 1338, 1338, 509: 1338, 511: 1338, 1338, 1338, 516: 1338, 518: 1338, 521: 1338, 523: 2813, 790: 2814, 836: 6062}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6057}, + {595: 4005, 937: 4004, 1001: 4003}, // 50 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5895, 2762, 2763, 2761, 930: 5894, 1164: 5892, 1284: 5893}, - {473: 2588, 2587, 495: 2586, 569: 2585, 646: 2581, 709: 5891, 748: 3881, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 3883, 3882}, - {829, 829, 49: 829, 472: 829, 474: 829, 481: 829}, - {828, 828, 49: 828, 472: 828, 474: 828, 481: 828}, - {480: 5876, 490: 5877, 5878, 1294: 5875}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6044, 2850, 688: 2851, 2849, 955: 6043, 1197: 6041, 1318: 6042}, + {492: 2667, 494: 2666, 515: 2665, 588: 2664, 665: 2660, 731: 6040, 770: 3990, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 3992, 3991}, + {868, 868, 58: 868, 491: 868, 494: 868, 501: 868}, + {867, 867, 58: 867, 491: 867, 494: 867, 501: 867}, + {500: 6025, 509: 6026, 511: 6027, 1328: 6024}, // 55 - {489, 489, 480: 814, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, - {480: 817, 490: 817, 817}, - {491, 491, 480: 815, 490: 815, 815}, - {250: 5860, 275: 5859}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 5700, 5695, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 5698, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 5704, 2807, 5697, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 5701, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 5702, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 5696, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 5705, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 5703, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 5699, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 479: 5707, 505: 3837, 568: 5711, 587: 5710, 647: 3835, 661: 5708, 2762, 2763, 2761, 773: 5712, 831: 5709, 978: 5713, 1158: 5706}, + {520, 520, 500: 853, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {500: 856, 509: 856, 511: 856}, + {522, 522, 500: 854, 509: 854, 511: 854}, + {265: 6009, 290: 6008}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 5847, 5842, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 5845, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 5851, 2896, 5844, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 5848, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 5849, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 5843, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 5852, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 5850, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 5846, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 496: 5854, 514: 3944, 589: 5858, 610: 5857, 667: 3942, 685: 5855, 2850, 688: 2851, 2849, 798: 5859, 853: 5856, 1003: 5860, 1191: 5853}, // 60 - {17: 5568, 210: 5573, 216: 5571, 218: 5566, 5572, 279: 5570, 319: 5569, 5574, 323: 5567, 340: 5575, 381: 5576, 590: 5565, 866: 5564}, - {22: 569, 125: 569, 569, 136: 4750, 145: 569, 190: 569, 198: 569, 209: 569, 223: 569, 235: 569, 257: 569, 260: 569, 530: 569, 569: 569, 811: 4749, 829: 5537}, + {17: 5715, 225: 5720, 230: 5718, 232: 5713, 5719, 248: 5721, 294: 5717, 334: 5716, 337: 5714, 354: 5722, 396: 5723, 607: 5712, 889: 5711}, + {22: 606, 137: 606, 606, 152: 4881, 159: 606, 204: 606, 212: 606, 224: 606, 237: 606, 251: 606, 272: 606, 275: 606, 549: 606, 588: 606, 835: 4880, 851: 5684}, + {597, 597}, + {596, 596}, + {595, 595}, + // 65 + {594, 594}, + {593, 593}, + {592, 592}, + {591, 591}, + {590, 590}, + // 70 + {589, 589}, + {588, 588}, + {587, 587}, + {586, 586}, + {585, 585}, + // 75 + {584, 584}, + {583, 583}, + {582, 582}, + {581, 581}, + {580, 580}, + // 80 + {579, 579}, + {578, 578}, + {577, 577}, + {576, 576}, + {575, 575}, + // 85 + {574, 574}, + {573, 573}, + {572, 572}, + {571, 571}, + {570, 570}, + // 90 + {569, 569}, + {568, 568}, + {567, 567}, + {566, 566}, + {565, 565}, + // 95 + {564, 564}, + {563, 563}, + {562, 562}, + {561, 561}, {560, 560}, + // 100 {559, 559}, {558, 558}, - // 65 {557, 557}, {556, 556}, {555, 555}, + // 105 {554, 554}, {553, 553}, - // 70 {552, 552}, {551, 551}, {550, 550}, + // 110 {549, 549}, {548, 548}, - // 75 {547, 547}, {546, 546}, {545, 545}, + // 115 {544, 544}, {543, 543}, - // 80 {542, 542}, {541, 541}, {540, 540}, + // 120 {539, 539}, {538, 538}, - // 85 {537, 537}, {536, 536}, {535, 535}, + // 125 {534, 534}, {533, 533}, - // 90 {532, 532}, {531, 531}, {530, 530}, + // 130 {529, 529}, {528, 528}, - // 95 {527, 527}, {526, 526}, {525, 525}, + // 135 {524, 524}, {523, 523}, - // 100 - {522, 522}, {521, 521}, - {520, 520}, {519, 519}, {518, 518}, - // 105 + // 140 {517, 517}, {516, 516}, {515, 515}, {514, 514}, {513, 513}, - // 110 + // 145 {512, 512}, {511, 511}, {510, 510}, {509, 509}, {508, 508}, - // 115 + // 150 {507, 507}, {506, 506}, {505, 505}, {504, 504}, {503, 503}, - // 120 + // 155 {502, 502}, - {501, 501}, - {500, 500}, - {499, 499}, - {498, 498}, - // 125 - {497, 497}, - {496, 496}, - {495, 495}, - {494, 494}, - {493, 493}, - // 130 - {492, 492}, - {490, 490}, - {488, 488}, - {487, 487}, - {486, 486}, - // 135 - {485, 485}, - {484, 484}, - {483, 483}, - {482, 482}, - {481, 481}, - // 140 - {480, 480}, - {479, 479}, - {478, 478}, - {477, 477}, {476, 476}, - // 145 - {475, 475}, - {474, 474}, - {473, 473}, - {472, 472}, - {471, 471}, - // 150 - {445, 445}, - {2: 391, 391, 391, 391, 391, 391, 391, 10: 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 50: 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 569: 5534, 1269: 5535}, - {253, 253, 481: 253}, - {2: 853, 853, 853, 853, 853, 853, 853, 10: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 50: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 473: 853, 489: 853, 579: 853, 753: 853, 853, 853, 762: 5398, 867: 5399, 918: 5400}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5396, 2762, 2763, 2761, 817: 5397}, - // 155 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5241, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 5243, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 5249, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 5245, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 5242, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 5250, 3206, 2932, 3158, 5244, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 5247, 5351, 2844, 3083, 5248, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 5246, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5252, 497: 5275, 567: 5269, 644: 5273, 646: 5258, 649: 5268, 651: 5262, 654: 5271, 661: 3491, 2762, 2763, 2761, 5263, 669: 5267, 674: 5264, 738: 5251, 5266, 801: 5253, 809: 5257, 854: 5272, 866: 5270, 936: 5254, 957: 5255, 5261, 963: 5256, 5259, 972: 5265, 974: 5274, 1121: 5352}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5241, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 5243, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 5249, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 5245, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 5242, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 5250, 3206, 2932, 3158, 5244, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 5247, 2843, 2844, 3083, 5248, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 5246, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5252, 497: 5275, 567: 5269, 644: 5273, 646: 5258, 649: 5268, 651: 5262, 654: 5271, 661: 3491, 2762, 2763, 2761, 5263, 669: 5267, 674: 5264, 738: 5251, 5266, 801: 5253, 809: 5257, 854: 5272, 866: 5270, 936: 5254, 957: 5255, 5261, 963: 5256, 5259, 972: 5265, 974: 5274, 1121: 5260}, - {23: 5200, 289: 5201}, - {125: 5187, 569: 5188, 1149: 5199}, - {125: 5187, 569: 5188, 1149: 5186}, + {2: 419, 419, 419, 419, 419, 419, 419, 10: 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 59: 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 588: 5681, 1303: 5682}, + {281, 281, 501: 281}, + {2: 892, 892, 892, 892, 892, 892, 892, 10: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 59: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 492: 892, 508: 892, 601: 892, 775: 892, 892, 892, 785: 5545, 890: 5546, 943: 5547}, // 160 - {472: 5174, 493: 63, 1267: 5173}, - {28: 5169, 139: 5170, 508: 2736, 733: 5168}, - {28: 58, 139: 58, 223: 5167, 508: 58}, - {309: 5150}, - {380: 2702}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 5544}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5386, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 5388, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 5394, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 5390, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 5387, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 5395, 3308, 3023, 3260, 5389, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 5392, 5496, 2933, 3175, 5393, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 5391, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5397, 518: 5420, 587: 5414, 664: 5418, 5403, 668: 5413, 671: 5407, 674: 5416, 682: 5408, 685: 3598, 2850, 688: 2851, 2849, 5412, 695: 5409, 760: 5396, 5411, 823: 5398, 833: 5402, 877: 5417, 889: 5415, 962: 5399, 982: 5400, 5406, 988: 5401, 5404, 997: 5410, 999: 5419, 1153: 5497}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5386, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 5388, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 5394, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 5390, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 5387, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 5395, 3308, 3023, 3260, 5389, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 5392, 2932, 2933, 3175, 5393, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 5391, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5397, 518: 5420, 587: 5414, 664: 5418, 5403, 668: 5413, 671: 5407, 674: 5416, 682: 5408, 685: 3598, 2850, 688: 2851, 2849, 5412, 695: 5409, 760: 5396, 5411, 823: 5398, 833: 5402, 877: 5417, 889: 5415, 962: 5399, 982: 5400, 5406, 988: 5401, 5404, 997: 5410, 999: 5419, 1153: 5405}, + {23: 5343, 213: 5344}, + {137: 5326, 213: 5341, 588: 5327, 1181: 5340}, // 165 - {335: 2703, 809: 2704}, - {935: 2706}, - {475: 2705}, - {1, 1}, - {198: 2719, 473: 2588, 2587, 2720, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 653: 2718, 2690, 665: 2707, 709: 2708, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 2717}, + {137: 5326, 213: 5328, 588: 5327, 1181: 5325}, + {491: 5308, 512: 70, 1301: 5307}, + {28: 5302, 141: 4840, 153: 5303, 492: 5300, 525: 2824, 755: 5301, 924: 5304}, + {28: 64, 141: 64, 153: 64, 237: 5299, 492: 64, 525: 64}, + {324: 5282}, // 170 - {489: 4191, 569: 1856, 855: 4190}, - {447, 447, 480: 814, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, - {449, 449, 480: 815, 490: 815, 815}, - {454, 454}, - {453, 453}, + {395: 2787}, + {248: 2790, 349: 2788, 833: 2789}, + {961: 2794}, + {493: 2793}, + {493: 2791}, // 175 - {452, 452}, - {451, 451}, - {450, 450}, - {448, 448}, - {446, 446}, + {493: 2792}, + {1, 1}, + {2, 2}, + {212: 2807, 492: 2667, 2808, 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 673: 2806, 2775, 682: 2795, 731: 2796, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 2805}, + {508: 4304, 588: 1916, 878: 4303}, // 180 - {7, 7}, - {198: 4184, 473: 2588, 2587, 4185, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 665: 2707, 709: 2708, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 4183}, - {139: 2721}, - {3, 3}, - {247, 247, 493: 247, 498: 2722, 501: 247, 247, 790: 2723, 2724}, + {478, 478, 500: 853, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {480, 480, 500: 854, 509: 854, 511: 854}, + {485, 485}, + {484, 484}, + {483, 483}, // 185 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4182}, - {246, 246, 49: 246, 472: 246, 474: 246, 480: 246, 246, 490: 246, 246, 493: 246, 246, 496: 246, 246, 501: 246, 246, 513: 246, 246, 516: 246}, - {1297, 1297, 493: 1297, 501: 1297, 2725, 767: 2726, 812: 2727}, - {660: 2750}, - {1296, 1296, 49: 1296, 127: 1296, 472: 1296, 474: 1296, 480: 1296, 1296, 490: 1296, 1296, 493: 1296, 1296, 496: 1296, 1296, 501: 1296}, + {482, 482}, + {481, 481}, + {479, 479}, + {477, 477}, + {8, 8}, // 190 - {869, 869, 493: 2728, 501: 2729, 768: 2730, 830: 2731}, - {508: 2736, 577: 2738, 733: 2735, 741: 2737, 882: 2745}, - {10: 2732, 270: 2733, 1216: 2734}, - {868, 868, 49: 868, 472: 868, 474: 868, 480: 868, 868, 490: 868, 868, 494: 868, 496: 868, 868}, - {5, 5}, + {212: 4297, 492: 2667, 4298, 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 682: 2795, 731: 2796, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 4296}, + {153: 2809}, + {4, 4}, + {275, 275, 512: 275, 519: 2810, 521: 275, 523: 275, 814: 2811, 2812}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4295}, // 195 - {508: 877, 524: 877, 575: 877, 577: 877}, - {508: 876, 524: 876, 575: 876, 577: 876}, - {508: 2736, 524: 875, 575: 875, 577: 2738, 733: 2735, 741: 2737, 882: 2739, 1210: 2740}, - {1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 15: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 49: 1975, 1975, 52: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 83: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 104: 1975, 1975, 108: 1975, 1975, 112: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 164: 1975, 184: 1975, 212: 1975, 472: 1975, 1975, 1975, 478: 1975, 1975, 1975, 1975, 484: 1975, 488: 1975, 1975, 1975, 1975, 494: 1975, 1975, 1975, 1975, 503: 1975, 1975, 1975, 1975, 524: 1975, 569: 1975, 575: 1975, 646: 1975, 1975, 649: 1975, 653: 1975}, - {1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 15: 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 52: 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 104: 1973, 1973, 108: 1973, 1973, 112: 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 128: 1973, 1973, 1973, 1973, 164: 1973, 184: 1973, 1973, 189: 1973, 212: 1973, 251: 1973, 472: 1973, 1973, 1973, 478: 1973, 1973, 1973, 1973, 484: 1973, 488: 1973, 1973, 1973, 1973, 493: 1973, 1973, 1973, 1973, 1973, 1973, 501: 1973, 503: 1973, 1973, 1973, 1973, 524: 1973, 569: 1973, 575: 1973, 646: 1973, 1973, 649: 1973, 653: 1973, 655: 1973, 658: 1973, 739: 1973}, + {274, 274, 58: 274, 491: 274, 494: 274, 500: 274, 274, 509: 274, 511: 274, 274, 274, 516: 274, 518: 274, 521: 274, 523: 274, 532: 274, 274, 535: 274}, + {1338, 1338, 512: 1338, 521: 1338, 523: 2813, 790: 2814, 836: 2815}, + {681: 2838}, + {1337, 1337, 58: 1337, 139: 1337, 491: 1337, 494: 1337, 500: 1337, 1337, 509: 1337, 511: 1337, 1337, 1337, 516: 1337, 518: 1337, 521: 1337}, + {908, 908, 512: 2816, 521: 2817, 791: 2818, 852: 2819}, // 200 - {881, 881, 9: 881, 49: 881, 164: 881, 472: 881, 474: 881, 480: 881, 881, 490: 881, 881, 494: 881, 496: 881, 881, 524: 881, 575: 881}, - {880, 880, 9: 880, 49: 880, 164: 880, 472: 880, 474: 880, 480: 880, 880, 490: 880, 880, 494: 880, 496: 880, 880, 524: 880, 575: 880}, - {524: 874, 575: 874}, - {524: 2742, 575: 2741, 1289: 2743}, - {154: 879}, + {525: 2824, 597: 2826, 755: 2823, 762: 2825, 905: 2833}, + {10: 2820, 285: 2821, 1249: 2822}, + {907, 907, 58: 907, 491: 907, 494: 907, 500: 907, 907, 509: 907, 511: 907, 513: 907, 516: 907, 518: 907}, + {6, 6}, + {525: 916, 543: 916, 595: 916, 597: 916}, // 205 - {154: 878}, - {154: 2744}, - {870, 870, 49: 870, 472: 870, 474: 870, 480: 870, 870, 490: 870, 870, 494: 870, 496: 870, 870}, - {873, 873, 9: 2746, 49: 873, 164: 2747, 472: 873, 474: 873, 480: 873, 873, 490: 873, 873, 494: 873, 496: 873, 873}, - {508: 2736, 577: 2738, 733: 2735, 741: 2737, 882: 2749}, + {525: 915, 543: 915, 595: 915, 597: 915}, + {525: 2824, 543: 914, 595: 914, 597: 2826, 755: 2823, 762: 2825, 905: 2827, 1243: 2828}, + {2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 15: 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 56: 2036, 58: 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 90: 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 111: 2036, 2036, 2036, 2036, 2036, 118: 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 2036, 134: 2036, 2036, 178: 2036, 197: 2036, 228: 2036, 491: 2036, 2036, 494: 2036, 496: 2036, 498: 2036, 2036, 2036, 2036, 507: 2036, 2036, 2036, 511: 2036, 513: 2036, 2036, 2036, 2036, 518: 2036, 522: 2036, 524: 2036, 526: 2036, 543: 2036, 588: 2036, 595: 2036, 665: 2036, 667: 2036, 2036, 673: 2036}, + {2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 15: 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 58: 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 111: 2034, 2034, 2034, 2034, 2034, 118: 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 2034, 134: 2034, 2034, 143: 2034, 2034, 2034, 2034, 178: 2034, 197: 2034, 2034, 202: 2034, 228: 2034, 266: 2034, 491: 2034, 2034, 494: 2034, 496: 2034, 498: 2034, 2034, 2034, 2034, 507: 2034, 2034, 2034, 511: 2034, 2034, 2034, 2034, 2034, 2034, 518: 2034, 2034, 521: 2034, 2034, 524: 2034, 526: 2034, 543: 2034, 587: 2034, 2034, 595: 2034, 665: 2034, 667: 2034, 2034, 673: 2034, 2034, 2034, 679: 2034, 761: 2034}, + {920, 920, 9: 920, 58: 920, 178: 920, 491: 920, 494: 920, 500: 920, 920, 509: 920, 511: 920, 513: 920, 516: 920, 518: 920, 543: 920, 595: 920}, // 210 - {508: 2736, 577: 2738, 733: 2735, 741: 2737, 882: 2748}, - {871, 871, 49: 871, 472: 871, 474: 871, 480: 871, 871, 490: 871, 871, 494: 871, 496: 871, 871}, - {872, 872, 49: 872, 472: 872, 474: 872, 480: 872, 872, 490: 872, 872, 494: 872, 496: 872, 872}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 2754, 871: 3241, 900: 3240}, - {1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 4179, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 474: 1535, 1535, 1535, 1535, 1535, 480: 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 489: 1535, 1535, 1535, 493: 1535, 1535, 496: 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 506: 1535, 1535, 509: 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 531: 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 565: 1535, 1535, 594: 1535, 652: 1535, 656: 1535, 1535}, + {919, 919, 9: 919, 58: 919, 178: 919, 491: 919, 494: 919, 500: 919, 919, 509: 919, 511: 919, 513: 919, 516: 919, 518: 919, 543: 919, 595: 919}, + {543: 913, 595: 913}, + {543: 2830, 595: 2829, 1323: 2831}, + {167: 918}, + {167: 917}, // 215 - {1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 4176, 1534, 1534, 1534, 1534, 1534, 480: 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 489: 1534, 1534, 1534, 493: 1534, 1534, 496: 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 506: 1534, 1534, 509: 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 531: 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 565: 1534, 1534, 594: 1534, 652: 1534, 656: 1534, 1534}, - {748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 474: 748, 748, 748, 748, 748, 480: 748, 748, 748, 748, 748, 748, 748, 748, 489: 748, 748, 748, 493: 748, 748, 496: 748, 748, 748, 748, 748, 748, 748, 748, 506: 748, 748, 509: 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 531: 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 565: 748, 748, 594: 748, 659: 4174}, - {1304, 1304, 9: 1304, 49: 1304, 127: 1304, 472: 1304, 474: 1304, 480: 1304, 1304, 490: 1304, 1304, 493: 1304, 1304, 496: 1304, 1304, 501: 1304, 1304, 507: 3345, 509: 3343, 3344, 3342, 3340, 514: 1304, 516: 1304, 524: 1304, 527: 1304, 1304, 4173, 531: 4172, 734: 3341, 3339, 1272: 4171}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4170}, - {473: 4142}, + {167: 2832}, + {909, 909, 58: 909, 491: 909, 494: 909, 500: 909, 909, 509: 909, 511: 909, 513: 909, 516: 909, 518: 909}, + {912, 912, 9: 2834, 58: 912, 178: 2835, 491: 912, 494: 912, 500: 912, 912, 509: 912, 511: 912, 513: 912, 516: 912, 518: 912}, + {525: 2824, 597: 2826, 755: 2823, 762: 2825, 905: 2837}, + {525: 2824, 597: 2826, 755: 2823, 762: 2825, 905: 2836}, // 220 - {1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 474: 1935, 1935, 478: 1935, 480: 1935, 1935, 1935, 1935, 489: 1935, 1935, 1935, 493: 1935, 1935, 496: 1935, 1935, 1935, 4125, 1935, 1935, 1935, 1935, 506: 1935, 1935, 509: 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 519: 1935, 521: 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 531: 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935, 545: 1935, 1935, 555: 4122, 4120, 4119, 4127, 4121, 4123, 4124, 4126, 1195: 4118, 1240: 4117}, - {1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 474: 1910, 1910, 478: 1910, 480: 1910, 1910, 1910, 1910, 489: 1910, 1910, 1910, 493: 1910, 1910, 496: 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 506: 1910, 1910, 509: 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 519: 1910, 521: 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 531: 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910, 545: 1910, 1910, 555: 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1910}, - {1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 474: 1883, 1883, 4089, 4088, 1883, 480: 1883, 1883, 1883, 1883, 485: 3686, 3687, 3692, 489: 1883, 1883, 1883, 493: 1883, 1883, 496: 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 506: 1883, 1883, 509: 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 4093, 1883, 3688, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 531: 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 4092, 1883, 1883, 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 4090, 565: 4099, 4100, 810: 4091, 1112: 4094, 1180: 4096, 1235: 4095, 1243: 4097, 1285: 4098}, - {1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 4085, 1832, 1832, 1832, 1832, 1832, 480: 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 489: 1832, 1832, 1832, 493: 1832, 1832, 496: 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 506: 1832, 1832, 509: 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 531: 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 565: 1832, 1832, 594: 1832, 652: 1832, 656: 1832, 1832}, - {1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 665: 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831}, + {910, 910, 58: 910, 491: 910, 494: 910, 500: 910, 910, 509: 910, 511: 910, 513: 910, 516: 910, 518: 910}, + {911, 911, 58: 911, 491: 911, 494: 911, 500: 911, 911, 509: 911, 511: 911, 513: 911, 516: 911, 518: 911}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 2842, 894: 3348, 925: 3347}, + {1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 4292, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 493: 1591, 1591, 1591, 497: 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 508: 1591, 1591, 511: 1591, 1591, 1591, 516: 1591, 1591, 1591, 1591, 1591, 1591, 523: 1591, 1591, 526: 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 550: 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 584: 1591, 1591, 1591, 616: 1591, 672: 1591, 676: 1591, 1591}, + {1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 4289, 1590, 1590, 1590, 497: 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 508: 1590, 1590, 511: 1590, 1590, 1590, 516: 1590, 1590, 1590, 1590, 1590, 1590, 523: 1590, 1590, 526: 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 550: 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 584: 1590, 1590, 1590, 616: 1590, 672: 1590, 676: 1590, 1590}, // 225 - {1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 665: 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830}, - {1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 665: 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829}, - {1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 665: 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828}, - {1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 665: 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827}, - {1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1235, 1826, 1826, 1826, 1826, 1826, 480: 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 489: 1826, 1826, 1826, 493: 1826, 1826, 496: 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 506: 1826, 1826, 509: 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 531: 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 565: 1826, 1826, 594: 1826, 652: 1826, 656: 1826, 1826}, + {787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 493: 787, 787, 787, 497: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 508: 787, 787, 511: 787, 787, 787, 516: 787, 787, 787, 787, 787, 787, 523: 787, 787, 526: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 550: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 584: 787, 787, 787, 616: 787, 680: 4287}, + {1345, 1345, 9: 1345, 58: 1345, 139: 1345, 491: 1345, 494: 1345, 500: 1345, 1345, 509: 1345, 511: 1345, 1345, 1345, 516: 1345, 518: 1345, 521: 1345, 523: 1345, 527: 3452, 3450, 3451, 3449, 3447, 533: 1345, 535: 1345, 543: 1345, 546: 1345, 1345, 4286, 561: 4285, 756: 3448, 3446, 1306: 4284}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4283}, + {492: 4255}, + {1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 493: 1996, 1996, 498: 1996, 500: 1996, 1996, 1996, 1996, 508: 1996, 1996, 511: 1996, 1996, 1996, 516: 1996, 4238, 1996, 1996, 1996, 1996, 523: 1996, 1996, 526: 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 538: 1996, 1996, 1996, 542: 1996, 1996, 1996, 1996, 1996, 1996, 1996, 550: 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 1996, 565: 1996, 574: 4235, 4233, 4232, 4240, 4234, 4236, 4237, 4239, 1228: 4231, 1272: 4230}, // 230 - {1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 665: 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825}, - {1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 665: 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824}, - {1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 665: 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823}, - {1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 665: 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822}, - {1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 665: 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821}, + {1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 493: 1971, 1971, 498: 1971, 500: 1971, 1971, 1971, 1971, 508: 1971, 1971, 511: 1971, 1971, 1971, 516: 1971, 1971, 1971, 1971, 1971, 1971, 523: 1971, 1971, 526: 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 538: 1971, 1971, 1971, 542: 1971, 1971, 1971, 1971, 1971, 1971, 1971, 550: 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 565: 1971, 574: 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971}, + {1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 493: 1943, 1943, 4198, 497: 4197, 1943, 500: 1943, 1943, 1943, 1943, 3793, 3794, 3799, 508: 1943, 1943, 511: 1943, 1943, 1943, 516: 1943, 1943, 1943, 1943, 1943, 1943, 523: 1943, 1943, 526: 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 4202, 1943, 1943, 1943, 3795, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 550: 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 4201, 1943, 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 4199, 584: 4209, 4210, 4208, 834: 4200, 1142: 4203, 1214: 4205, 1267: 4204, 1275: 4206, 1319: 4207}, + {1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 4194, 1892, 1892, 1892, 497: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 508: 1892, 1892, 511: 1892, 1892, 1892, 516: 1892, 1892, 1892, 1892, 1892, 1892, 523: 1892, 1892, 526: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 550: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 584: 1892, 1892, 1892, 616: 1892, 672: 1892, 676: 1892, 1892}, + {1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 687: 1891, 690: 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891, 1891}, + {1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 687: 1890, 690: 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890, 1890}, // 235 - {1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 665: 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820}, - {1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 665: 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819}, - {1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 665: 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818}, - {1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 665: 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817}, - {1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 665: 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816}, + {1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 687: 1889, 690: 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889, 1889}, + {1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 687: 1888, 690: 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888}, + {1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 687: 1887, 690: 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887}, + {1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1274, 1886, 1886, 1886, 497: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 508: 1886, 1886, 511: 1886, 1886, 1886, 516: 1886, 1886, 1886, 1886, 1886, 1886, 523: 1886, 1886, 526: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 550: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 584: 1886, 1886, 1886, 616: 1886, 672: 1886, 676: 1886, 1886}, + {1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 687: 1885, 690: 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885}, // 240 - {1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 4080, 1815, 1815, 1815, 1815, 1815, 480: 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 489: 1815, 1815, 1815, 493: 1815, 1815, 496: 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 506: 1815, 1815, 509: 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 531: 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 565: 1815, 1815, 594: 1815, 652: 1815, 656: 1815, 1815}, - {1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 665: 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814}, - {1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 665: 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813}, - {1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 665: 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812}, - {1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 665: 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811}, + {1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 687: 1884, 690: 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884}, + {1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 687: 1883, 690: 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883, 1883}, + {1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 687: 1882, 690: 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882}, + {1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 687: 1881, 690: 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881}, + {1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 687: 1880, 690: 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880}, // 245 - {1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 665: 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810}, - {1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 665: 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809}, - {1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 665: 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808}, - {1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 665: 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807}, - {1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 665: 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806}, + {1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 687: 1879, 690: 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879}, + {1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 687: 1878, 690: 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878, 1878}, + {1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 687: 1877, 690: 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877}, + {1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 687: 1876, 690: 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876, 1876}, + {1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 687: 1875, 690: 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875}, // 250 - {1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 665: 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805}, - {1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1234, 1804, 1804, 1804, 1804, 1804, 480: 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 489: 1804, 1804, 1804, 493: 1804, 1804, 496: 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 506: 1804, 1804, 509: 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 531: 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 565: 1804, 1804, 594: 1804, 652: 1804, 656: 1804, 1804}, - {1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 665: 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803}, - {1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 665: 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802}, - {1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 665: 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801}, + {1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 4189, 1874, 1874, 1874, 497: 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 508: 1874, 1874, 511: 1874, 1874, 1874, 516: 1874, 1874, 1874, 1874, 1874, 1874, 523: 1874, 1874, 526: 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 550: 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 584: 1874, 1874, 1874, 616: 1874, 672: 1874, 676: 1874, 1874}, + {1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 687: 1873, 690: 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873}, + {1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 687: 1872, 690: 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872}, + {1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 687: 1871, 690: 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871}, + {1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 687: 1870, 690: 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870, 1870}, // 255 - {1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 665: 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800}, - {1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 665: 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799}, - {1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 665: 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798}, - {1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 665: 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797}, - {1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 665: 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796}, + {1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 687: 1869, 690: 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869, 1869}, + {1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 687: 1868, 690: 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868}, + {1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 687: 1867, 690: 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867, 1867}, + {1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 687: 1866, 690: 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866, 1866}, + {1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 687: 1865, 690: 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865}, // 260 - {1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 665: 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795}, - {1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 665: 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794}, - {1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1231, 1793, 4079, 1793, 1793, 1793, 480: 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 489: 1793, 1793, 1793, 493: 1793, 1793, 496: 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 506: 1793, 1793, 509: 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 531: 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 565: 1793, 1793, 594: 1793, 652: 1793, 656: 1793, 1793}, - {1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 665: 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792}, - {1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1229, 1791, 1791, 1791, 1791, 1791, 480: 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 489: 1791, 1791, 1791, 493: 1791, 1791, 496: 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 506: 1791, 1791, 509: 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 531: 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 565: 1791, 1791, 594: 1791, 652: 1791, 656: 1791, 1791}, + {1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 687: 1864, 690: 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864, 1864}, + {1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1273, 1863, 1863, 1863, 497: 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 508: 1863, 1863, 511: 1863, 1863, 1863, 516: 1863, 1863, 1863, 1863, 1863, 1863, 523: 1863, 1863, 526: 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 550: 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 584: 1863, 1863, 1863, 616: 1863, 672: 1863, 676: 1863, 1863}, + {1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 687: 1862, 690: 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862}, + {1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 687: 1861, 690: 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861, 1861}, + {1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 687: 1860, 690: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860}, // 265 - {1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 665: 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790}, - {1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 665: 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789}, - {1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 665: 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788}, - {1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 665: 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787}, - {1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 665: 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786}, + {1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 687: 1859, 690: 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859}, + {1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 687: 1858, 690: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858}, + {1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 687: 1857, 690: 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857}, + {1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 687: 1856, 690: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856}, + {1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 687: 1855, 690: 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855}, // 270 - {1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 665: 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785}, - {1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 665: 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784}, - {1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 665: 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783}, - {1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 665: 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782}, - {1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 665: 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781}, + {1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 687: 1854, 690: 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854, 1854}, + {1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 687: 1853, 690: 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853}, + {1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1270, 4188, 1852, 1852, 497: 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 508: 1852, 1852, 511: 1852, 1852, 1852, 516: 1852, 1852, 1852, 1852, 1852, 1852, 523: 1852, 1852, 526: 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 550: 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 584: 1852, 1852, 1852, 616: 1852, 672: 1852, 676: 1852, 1852}, + {1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 687: 1851, 690: 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851, 1851}, + {1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1268, 1850, 1850, 1850, 497: 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 508: 1850, 1850, 511: 1850, 1850, 1850, 516: 1850, 1850, 1850, 1850, 1850, 1850, 523: 1850, 1850, 526: 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 550: 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 584: 1850, 1850, 1850, 616: 1850, 672: 1850, 676: 1850, 1850}, // 275 - {1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 665: 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780}, - {1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 665: 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779}, - {1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 665: 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778}, - {1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 665: 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777}, - {1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 665: 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776}, + {1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 687: 1849, 690: 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849}, + {1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 687: 1848, 690: 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848, 1848}, + {1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 687: 1847, 690: 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847}, + {1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 687: 1846, 690: 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846}, + {1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 687: 1845, 690: 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845}, // 280 - {1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 665: 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775}, - {1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 665: 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774}, - {1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 665: 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773}, - {1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 665: 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772}, - {1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 665: 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771}, + {1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 687: 1844, 690: 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844}, + {1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 687: 1843, 690: 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843}, + {1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 687: 1842, 690: 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842}, + {1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 687: 1841, 690: 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841}, + {1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 687: 1840, 690: 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840}, // 285 - {1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 665: 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770}, - {1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 665: 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769}, - {1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1225, 1768, 1768, 1768, 1768, 1768, 480: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 489: 1768, 1768, 1768, 493: 1768, 1768, 496: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 506: 1768, 1768, 509: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 531: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 565: 1768, 1768, 594: 1768, 652: 1768, 656: 1768, 1768}, - {1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 665: 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767}, - {1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 665: 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766}, + {1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 687: 1839, 690: 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839}, + {1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 687: 1838, 690: 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838}, + {1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 687: 1837, 690: 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837}, + {1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 687: 1836, 690: 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836}, + {1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 687: 1835, 690: 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835, 1835}, // 290 - {1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 665: 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765}, - {1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 665: 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764}, - {1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 665: 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763}, - {1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1228, 1762, 1762, 1762, 1762, 1762, 480: 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 489: 1762, 1762, 1762, 493: 1762, 1762, 496: 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 506: 1762, 1762, 509: 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 531: 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 565: 1762, 1762, 594: 1762, 652: 1762, 656: 1762, 1762}, - {1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 665: 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761}, + {1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 687: 1834, 690: 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834}, + {1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 687: 1833, 690: 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833}, + {1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 687: 1832, 690: 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832}, + {1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 687: 1831, 690: 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831}, + {1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 687: 1830, 690: 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830}, // 295 - {1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 665: 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760}, - {1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 665: 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759}, - {1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 665: 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758}, - {1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 665: 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757}, - {1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 665: 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756}, + {1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 687: 1829, 690: 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829}, + {1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 687: 1828, 690: 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828}, + {1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1264, 1827, 1827, 1827, 497: 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 508: 1827, 1827, 511: 1827, 1827, 1827, 516: 1827, 1827, 1827, 1827, 1827, 1827, 523: 1827, 1827, 526: 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 550: 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 584: 1827, 1827, 1827, 616: 1827, 672: 1827, 676: 1827, 1827}, + {1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 687: 1826, 690: 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826}, + {1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 687: 1825, 690: 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825}, // 300 - {1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 665: 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755}, - {1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 665: 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754}, - {1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 665: 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753}, - {1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 4076, 1752, 1752, 1752, 1752, 1752, 480: 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 489: 1752, 1752, 1752, 493: 1752, 1752, 496: 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 506: 1752, 1752, 509: 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 531: 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 565: 1752, 1752, 594: 1752, 652: 1752, 656: 1752, 1752}, - {1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 665: 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751}, + {1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 687: 1824, 690: 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824}, + {1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 687: 1823, 690: 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823}, + {1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 687: 1822, 690: 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822}, + {1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1267, 1821, 1821, 1821, 497: 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 508: 1821, 1821, 511: 1821, 1821, 1821, 516: 1821, 1821, 1821, 1821, 1821, 1821, 523: 1821, 1821, 526: 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 550: 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 584: 1821, 1821, 1821, 616: 1821, 672: 1821, 676: 1821, 1821}, + {1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 687: 1820, 690: 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820}, // 305 - {1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 665: 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750}, - {1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 665: 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749}, - {1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 665: 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748}, - {1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 665: 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747}, - {1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 665: 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746}, + {1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 687: 1819, 690: 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819}, + {1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 687: 1818, 690: 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818}, + {1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 687: 1817, 690: 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817}, + {1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 687: 1816, 690: 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816}, + {1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 687: 1815, 690: 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815}, // 310 - {1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 665: 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745}, - {1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 665: 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744}, - {1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 665: 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743}, - {1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 665: 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742}, - {1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 665: 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741}, + {1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 687: 1814, 690: 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814}, + {1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 687: 1813, 690: 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813}, + {1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 687: 1812, 690: 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812}, + {1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 4185, 1811, 1811, 1811, 497: 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 508: 1811, 1811, 511: 1811, 1811, 1811, 516: 1811, 1811, 1811, 1811, 1811, 1811, 523: 1811, 1811, 526: 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 550: 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 584: 1811, 1811, 1811, 616: 1811, 672: 1811, 676: 1811, 1811}, + {1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 687: 1810, 690: 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810}, // 315 - {1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 665: 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740}, - {1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 665: 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739}, - {1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 665: 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738}, - {1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 665: 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737}, - {1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 665: 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736}, + {1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 687: 1809, 690: 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809}, + {1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 687: 1808, 690: 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808, 1808}, + {1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 687: 1807, 690: 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807}, + {1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 687: 1806, 690: 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806}, + {1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 687: 1805, 690: 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805, 1805}, // 320 - {1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 665: 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735}, - {1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 665: 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734}, - {1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 665: 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733}, - {1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 665: 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732}, - {1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 665: 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731}, + {1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 687: 1804, 690: 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804}, + {1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 687: 1803, 690: 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803}, + {1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 687: 1802, 690: 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802}, + {1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 687: 1801, 690: 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801}, + {1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 687: 1800, 690: 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800}, // 325 - {1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 665: 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730}, - {1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 665: 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729}, - {1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 665: 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728}, - {1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1212, 1727, 4075, 1727, 1727, 1727, 480: 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 489: 1727, 1727, 1727, 493: 1727, 1727, 496: 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 506: 1727, 1727, 509: 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 531: 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 565: 1727, 1727, 594: 1727, 652: 1727, 656: 1727, 1727}, - {1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1211, 1726, 4074, 1726, 1726, 1726, 480: 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 489: 1726, 1726, 1726, 493: 1726, 1726, 496: 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 506: 1726, 1726, 509: 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 531: 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 565: 1726, 1726, 594: 1726, 652: 1726, 656: 1726, 1726}, + {1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 687: 1799, 690: 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799}, + {1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 687: 1798, 690: 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798, 1798}, + {1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 687: 1797, 690: 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797}, + {1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 687: 1796, 690: 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796}, + {1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 687: 1795, 690: 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795}, // 330 - {1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 665: 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725}, - {1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 665: 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724}, - {1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1210, 1723, 1723, 1723, 1723, 1723, 480: 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 489: 1723, 1723, 1723, 493: 1723, 1723, 496: 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 506: 1723, 1723, 509: 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 531: 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 565: 1723, 1723, 594: 1723, 652: 1723, 656: 1723, 1723}, - {1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 665: 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722}, - {1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 665: 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721}, + {1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 687: 1794, 690: 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794}, + {1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 687: 1793, 690: 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793}, + {1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 687: 1792, 690: 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792}, + {1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 687: 1791, 690: 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791}, + {1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 687: 1790, 690: 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790, 1790}, // 335 - {1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 665: 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720}, - {1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 665: 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719}, - {1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1207, 1718, 1718, 1718, 1718, 1718, 480: 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 489: 1718, 1718, 1718, 493: 1718, 1718, 496: 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 506: 1718, 1718, 509: 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 531: 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 565: 1718, 1718, 594: 1718, 652: 1718, 656: 1718, 1718}, - {1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 665: 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717}, - {1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1208, 1716, 1716, 1716, 1716, 1716, 480: 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 489: 1716, 1716, 1716, 493: 1716, 1716, 496: 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 506: 1716, 1716, 509: 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 531: 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 565: 1716, 1716, 594: 1716, 652: 1716, 656: 1716, 1716}, + {1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 687: 1789, 690: 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789}, + {1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 687: 1788, 690: 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788}, + {1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 687: 1787, 690: 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787}, + {1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 687: 1786, 690: 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786, 1786}, + {1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 687: 1785, 690: 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785}, // 340 - {1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 4064, 1715, 1715, 1715, 1715, 1715, 480: 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 489: 1715, 1715, 1715, 493: 1715, 1715, 496: 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 506: 1715, 1715, 509: 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 531: 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 565: 1715, 1715, 594: 1715, 652: 1715, 656: 1715, 1715}, - {1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 665: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714}, - {1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 665: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713}, - {1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1209, 1712, 1712, 1712, 1712, 1712, 480: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 489: 1712, 1712, 1712, 493: 1712, 1712, 496: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 506: 1712, 1712, 509: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 531: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 565: 1712, 1712, 594: 1712, 652: 1712, 656: 1712, 1712}, - {1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 665: 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711}, + {1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1251, 4184, 1784, 1784, 497: 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 508: 1784, 1784, 511: 1784, 1784, 1784, 516: 1784, 1784, 1784, 1784, 1784, 1784, 523: 1784, 1784, 526: 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 550: 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 584: 1784, 1784, 1784, 616: 1784, 672: 1784, 676: 1784, 1784}, + {1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1250, 4183, 1783, 1783, 497: 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 508: 1783, 1783, 511: 1783, 1783, 1783, 516: 1783, 1783, 1783, 1783, 1783, 1783, 523: 1783, 1783, 526: 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 550: 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 584: 1783, 1783, 1783, 616: 1783, 672: 1783, 676: 1783, 1783}, + {1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 687: 1782, 690: 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782}, + {1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 687: 1781, 690: 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781}, + {1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1249, 1780, 1780, 1780, 497: 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 508: 1780, 1780, 511: 1780, 1780, 1780, 516: 1780, 1780, 1780, 1780, 1780, 1780, 523: 1780, 1780, 526: 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 550: 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 584: 1780, 1780, 1780, 616: 1780, 672: 1780, 676: 1780, 1780}, // 345 - {1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1232, 1710, 1710, 1710, 1710, 1710, 480: 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 489: 1710, 1710, 1710, 493: 1710, 1710, 496: 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 506: 1710, 1710, 509: 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 531: 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 565: 1710, 1710, 594: 1710, 652: 1710, 656: 1710, 1710}, - {1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 665: 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709}, - {1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 665: 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708}, - {1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 665: 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707}, - {1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 665: 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706}, + {1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 687: 1779, 690: 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1779}, + {1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 687: 1778, 690: 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778}, + {1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 687: 1777, 690: 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777}, + {1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 687: 1776, 690: 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776}, + {1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1246, 1775, 1775, 1775, 497: 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 508: 1775, 1775, 511: 1775, 1775, 1775, 516: 1775, 1775, 1775, 1775, 1775, 1775, 523: 1775, 1775, 526: 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 550: 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 584: 1775, 1775, 1775, 616: 1775, 672: 1775, 676: 1775, 1775}, // 350 - {1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 665: 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705}, - {1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 665: 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704}, - {1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 665: 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703}, - {1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 665: 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702}, - {1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 665: 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701}, + {1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 687: 1774, 690: 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774}, + {1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1247, 1773, 1773, 1773, 497: 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 508: 1773, 1773, 511: 1773, 1773, 1773, 516: 1773, 1773, 1773, 1773, 1773, 1773, 523: 1773, 1773, 526: 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 550: 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 584: 1773, 1773, 1773, 616: 1773, 672: 1773, 676: 1773, 1773}, + {1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 4173, 1772, 1772, 1772, 497: 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 508: 1772, 1772, 511: 1772, 1772, 1772, 516: 1772, 1772, 1772, 1772, 1772, 1772, 523: 1772, 1772, 526: 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 550: 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 584: 1772, 1772, 1772, 616: 1772, 672: 1772, 676: 1772, 1772}, + {1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 687: 1771, 690: 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771}, + {1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 687: 1770, 690: 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770}, // 355 - {1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 665: 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700}, - {1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 665: 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699}, - {1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 665: 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698}, - {1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1219, 1697, 1697, 1697, 1697, 1697, 480: 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 489: 1697, 1697, 1697, 493: 1697, 1697, 496: 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 506: 1697, 1697, 509: 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 531: 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 565: 1697, 1697, 594: 1697, 652: 1697, 656: 1697, 1697}, - {1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 665: 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696}, + {1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1248, 1769, 1769, 1769, 497: 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 508: 1769, 1769, 511: 1769, 1769, 1769, 516: 1769, 1769, 1769, 1769, 1769, 1769, 523: 1769, 1769, 526: 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 550: 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 584: 1769, 1769, 1769, 616: 1769, 672: 1769, 676: 1769, 1769}, + {1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 687: 1768, 690: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768}, + {1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1271, 1767, 1767, 1767, 497: 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 508: 1767, 1767, 511: 1767, 1767, 1767, 516: 1767, 1767, 1767, 1767, 1767, 1767, 523: 1767, 1767, 526: 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 550: 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 584: 1767, 1767, 1767, 616: 1767, 672: 1767, 676: 1767, 1767}, + {1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 687: 1766, 690: 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766}, + {1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 687: 1765, 690: 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765}, // 360 - {1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 665: 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695}, - {1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 665: 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694}, - {1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 665: 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693}, - {1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 665: 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692}, - {1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 665: 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691}, + {1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 687: 1764, 690: 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764}, + {1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 687: 1763, 690: 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763}, + {1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 687: 1762, 690: 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762}, + {1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 687: 1761, 690: 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761}, + {1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 687: 1760, 690: 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760, 1760}, // 365 - {1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 665: 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690}, - {1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 665: 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689}, - {1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 665: 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688}, - {1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 665: 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687}, - {1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 665: 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686}, + {1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 687: 1759, 690: 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759}, + {1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 687: 1758, 690: 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758}, + {1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 687: 1757, 690: 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757}, + {1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 687: 1756, 690: 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756}, + {1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 687: 1755, 690: 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755}, // 370 - {1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 665: 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685}, - {1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 665: 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684}, - {1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 665: 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683}, - {1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 665: 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682}, - {1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 665: 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681}, + {1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1258, 1754, 1754, 1754, 497: 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 508: 1754, 1754, 511: 1754, 1754, 1754, 516: 1754, 1754, 1754, 1754, 1754, 1754, 523: 1754, 1754, 526: 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 550: 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 584: 1754, 1754, 1754, 616: 1754, 672: 1754, 676: 1754, 1754}, + {1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 687: 1753, 690: 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753}, + {1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 687: 1752, 690: 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752}, + {1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 687: 1751, 690: 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751}, + {1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 687: 1750, 690: 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750}, // 375 - {1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 665: 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680}, - {1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 665: 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679}, - {1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 665: 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678}, - {1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 665: 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677}, - {1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 665: 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676}, + {1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 687: 1749, 690: 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749}, + {1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 687: 1748, 690: 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748}, + {1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 687: 1747, 690: 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1747}, + {1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 687: 1746, 690: 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746}, + {1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 687: 1745, 690: 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745}, // 380 - {1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 665: 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675}, - {1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1216, 1674, 1674, 1674, 1674, 1674, 480: 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 489: 1674, 1674, 1674, 493: 1674, 1674, 496: 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 506: 1674, 1674, 509: 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 531: 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 565: 1674, 1674, 594: 1674, 652: 1674, 656: 1674, 1674}, - {1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 665: 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673}, - {1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 665: 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672}, - {1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 665: 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671}, + {1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 687: 1744, 690: 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744}, + {1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 687: 1743, 690: 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743}, + {1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 687: 1742, 690: 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742, 1742}, + {1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 687: 1741, 690: 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741}, + {1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 687: 1740, 690: 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740}, // 385 - {1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 665: 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670}, - {1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 665: 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669}, - {1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 665: 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668}, - {1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 665: 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667}, - {1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 665: 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666}, + {1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 687: 1739, 690: 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739}, + {1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 687: 1738, 690: 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738}, + {1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 687: 1737, 690: 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737, 1737}, + {1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 687: 1736, 690: 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736}, + {1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 687: 1735, 690: 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735, 1735}, // 390 - {1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 665: 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665}, - {1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 665: 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664}, - {1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 665: 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663}, - {1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 665: 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662}, - {1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 665: 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661}, + {1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 687: 1734, 690: 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734}, + {1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 687: 1733, 690: 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733, 1733}, + {1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 687: 1732, 690: 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732, 1732}, + {1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1255, 1731, 1731, 1731, 497: 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 508: 1731, 1731, 511: 1731, 1731, 1731, 516: 1731, 1731, 1731, 1731, 1731, 1731, 523: 1731, 1731, 526: 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 550: 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 584: 1731, 1731, 1731, 616: 1731, 672: 1731, 676: 1731, 1731}, + {1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 687: 1730, 690: 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730}, // 395 - {1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 665: 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660}, - {1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 665: 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659}, - {1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 665: 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658}, - {1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1214, 1657, 1657, 1657, 1657, 1657, 480: 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 489: 1657, 1657, 1657, 493: 1657, 1657, 496: 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 506: 1657, 1657, 509: 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 531: 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 565: 1657, 1657, 594: 1657, 652: 1657, 656: 1657, 1657}, - {1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1233, 1656, 1656, 1656, 1656, 1656, 480: 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 489: 1656, 1656, 1656, 493: 1656, 1656, 496: 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 506: 1656, 1656, 509: 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 531: 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 565: 1656, 1656, 594: 1656, 652: 1656, 656: 1656, 1656}, + {1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 687: 1729, 690: 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729}, + {1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 687: 1728, 690: 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728}, + {1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 687: 1727, 690: 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727}, + {1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 687: 1726, 690: 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726}, + {1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 687: 1725, 690: 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725}, // 400 - {1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1221, 1655, 1655, 1655, 1655, 1655, 480: 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 489: 1655, 1655, 1655, 493: 1655, 1655, 496: 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 506: 1655, 1655, 509: 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 531: 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 565: 1655, 1655, 594: 1655, 652: 1655, 656: 1655, 1655}, - {1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 665: 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654}, - {1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 665: 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653}, - {1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 665: 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652}, - {1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1223, 1651, 1651, 1651, 1651, 1651, 480: 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 489: 1651, 1651, 1651, 493: 1651, 1651, 496: 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 506: 1651, 1651, 509: 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 531: 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 565: 1651, 1651, 594: 1651, 652: 1651, 656: 1651, 1651}, + {1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 687: 1724, 690: 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724}, + {1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 687: 1723, 690: 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723}, + {1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 687: 1722, 690: 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1722}, + {1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 687: 1721, 690: 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721}, + {1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 687: 1720, 690: 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720}, // 405 - {1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1222, 1650, 1650, 1650, 1650, 1650, 480: 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 489: 1650, 1650, 1650, 493: 1650, 1650, 496: 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 506: 1650, 1650, 509: 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 531: 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 565: 1650, 1650, 594: 1650, 652: 1650, 656: 1650, 1650}, - {1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 665: 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649}, - {1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 665: 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648}, - {1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 665: 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647}, - {1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 665: 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646}, + {1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 687: 1719, 690: 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719}, + {1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 687: 1718, 690: 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718}, + {1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 687: 1717, 690: 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1717}, + {1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 687: 1716, 690: 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716}, + {1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 687: 1715, 690: 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715}, // 410 - {1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 665: 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645}, - {1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1213, 1644, 1644, 1644, 1644, 1644, 480: 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 489: 1644, 1644, 1644, 493: 1644, 1644, 496: 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 506: 1644, 1644, 509: 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 531: 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 565: 1644, 1644, 594: 1644, 652: 1644, 656: 1644, 1644}, - {1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 665: 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643}, - {1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 665: 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642}, - {1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 665: 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641}, + {1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1253, 1714, 1714, 1714, 497: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 508: 1714, 1714, 511: 1714, 1714, 1714, 516: 1714, 1714, 1714, 1714, 1714, 1714, 523: 1714, 1714, 526: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 550: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 584: 1714, 1714, 1714, 616: 1714, 672: 1714, 676: 1714, 1714}, + {1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1272, 1713, 1713, 1713, 497: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 508: 1713, 1713, 511: 1713, 1713, 1713, 516: 1713, 1713, 1713, 1713, 1713, 1713, 523: 1713, 1713, 526: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 550: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 584: 1713, 1713, 1713, 616: 1713, 672: 1713, 676: 1713, 1713}, + {1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1260, 1712, 1712, 1712, 497: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 508: 1712, 1712, 511: 1712, 1712, 1712, 516: 1712, 1712, 1712, 1712, 1712, 1712, 523: 1712, 1712, 526: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 550: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 584: 1712, 1712, 1712, 616: 1712, 672: 1712, 676: 1712, 1712}, + {1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 687: 1711, 690: 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711}, + {1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 687: 1710, 690: 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710}, // 415 - {1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 665: 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640}, - {1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 665: 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639}, - {1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 665: 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638}, - {1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 665: 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637}, - {1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 665: 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636}, + {1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 687: 1709, 690: 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709, 1709}, + {1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1262, 1708, 1708, 1708, 497: 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 508: 1708, 1708, 511: 1708, 1708, 1708, 516: 1708, 1708, 1708, 1708, 1708, 1708, 523: 1708, 1708, 526: 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 550: 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 584: 1708, 1708, 1708, 616: 1708, 672: 1708, 676: 1708, 1708}, + {1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1261, 1707, 1707, 1707, 497: 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 508: 1707, 1707, 511: 1707, 1707, 1707, 516: 1707, 1707, 1707, 1707, 1707, 1707, 523: 1707, 1707, 526: 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 550: 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 584: 1707, 1707, 1707, 616: 1707, 672: 1707, 676: 1707, 1707}, + {1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 687: 1706, 690: 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706, 1706}, + {1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 687: 1705, 690: 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705, 1705}, // 420 - {1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 665: 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635}, - {1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 665: 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634}, - {1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 665: 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633}, - {1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 665: 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632}, - {1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 665: 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631}, + {1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 687: 1704, 690: 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1704}, + {1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 687: 1703, 690: 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703}, + {1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 687: 1702, 690: 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702, 1702}, + {1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1252, 1701, 1701, 1701, 497: 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 508: 1701, 1701, 511: 1701, 1701, 1701, 516: 1701, 1701, 1701, 1701, 1701, 1701, 523: 1701, 1701, 526: 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 550: 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 584: 1701, 1701, 1701, 616: 1701, 672: 1701, 676: 1701, 1701}, + {1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 687: 1700, 690: 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700}, // 425 - {1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 665: 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630}, - {1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 665: 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629}, - {1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 665: 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628}, - {1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 665: 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627}, - {1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 665: 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626}, + {1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 687: 1699, 690: 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699}, + {1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 687: 1698, 690: 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698}, + {1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 687: 1697, 690: 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697}, + {1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 687: 1696, 690: 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696}, + {1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 687: 1695, 690: 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695, 1695}, // 430 - {1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 665: 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625}, - {1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 665: 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624}, - {1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 665: 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623}, - {1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 665: 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622}, - {1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 665: 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621}, + {1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 687: 1694, 690: 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694}, + {1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 687: 1693, 690: 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693}, + {1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 687: 1692, 690: 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692}, + {1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 687: 1691, 690: 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691, 1691}, + {1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 687: 1690, 690: 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690}, // 435 - {1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 665: 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620}, - {1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 665: 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619}, - {1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 665: 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618}, - {1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 665: 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617}, - {1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 665: 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616}, + {1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 687: 1689, 690: 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689}, + {1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 687: 1688, 690: 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688}, + {1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 687: 1687, 690: 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687}, + {1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 687: 1686, 690: 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686}, + {1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 687: 1685, 690: 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685}, // 440 - {1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 665: 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615}, - {1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 665: 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614}, - {1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 665: 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613}, - {1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 665: 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612}, - {1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 665: 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611}, + {1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 687: 1684, 690: 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684}, + {1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 687: 1683, 690: 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683}, + {1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 687: 1682, 690: 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682}, + {1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 687: 1681, 690: 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681}, + {1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 687: 1680, 690: 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680}, // 445 - {1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 665: 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610}, - {1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 665: 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609}, - {1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 665: 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608}, - {1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 665: 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607}, - {1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 665: 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606}, + {1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 687: 1679, 690: 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679}, + {1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 687: 1678, 690: 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678}, + {1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 687: 1677, 690: 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677}, + {1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 687: 1676, 690: 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676}, + {1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 687: 1675, 690: 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675}, // 450 - {1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 665: 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605}, - {1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 665: 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604}, - {1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 665: 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603}, - {1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 665: 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602}, - {1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 665: 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601}, + {1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 687: 1674, 690: 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674}, + {1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 687: 1673, 690: 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673}, + {1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 687: 1672, 690: 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672}, + {1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 687: 1671, 690: 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671, 1671}, + {1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 687: 1670, 690: 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670}, // 455 - {1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 665: 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600}, - {1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 665: 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599}, - {1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 665: 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598}, - {1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 665: 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597}, - {1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 665: 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596}, + {1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 687: 1669, 690: 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669}, + {1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 687: 1668, 690: 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1668}, + {1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 687: 1667, 690: 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667}, + {1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 687: 1666, 690: 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666, 1666}, + {1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 687: 1665, 690: 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665}, // 460 - {1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 665: 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595}, - {1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 665: 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594}, - {1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 665: 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593}, - {1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 665: 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592}, - {1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 665: 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591}, + {1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 687: 1664, 690: 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664}, + {1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 687: 1663, 690: 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663}, + {1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 687: 1662, 690: 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662}, + {1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 687: 1661, 690: 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661}, + {1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 687: 1660, 690: 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660}, // 465 - {1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 665: 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590}, - {1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 665: 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589}, - {1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 665: 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588}, - {1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 665: 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587}, - {1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 665: 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586}, + {1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 687: 1659, 690: 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659}, + {1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 687: 1658, 690: 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658}, + {1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 687: 1657, 690: 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657}, + {1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 687: 1656, 690: 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656}, + {1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 687: 1655, 690: 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655}, // 470 - {1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 665: 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585}, - {1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 665: 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584}, - {1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 665: 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583}, - {1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 665: 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582}, - {1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 665: 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581}, + {1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 687: 1654, 690: 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654}, + {1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 687: 1653, 690: 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653}, + {1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 687: 1652, 690: 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652}, + {1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 687: 1651, 690: 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651}, + {1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 687: 1650, 690: 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650}, // 475 - {1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 665: 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580}, - {1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 665: 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579}, - {1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 665: 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578}, - {1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 665: 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577}, - {1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 665: 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576}, + {1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 687: 1649, 690: 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649}, + {1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 687: 1648, 690: 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648, 1648}, + {1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 687: 1647, 690: 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647}, + {1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 687: 1646, 690: 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646}, + {1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 687: 1645, 690: 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645, 1645}, // 480 - {1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 665: 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575}, - {1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 665: 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574}, - {1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 665: 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573}, - {1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 665: 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572}, - {1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 665: 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571}, + {1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 687: 1644, 690: 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644}, + {1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 687: 1643, 690: 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643}, + {1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 687: 1642, 690: 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642}, + {1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 687: 1641, 690: 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641}, + {1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 687: 1640, 690: 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640, 1640}, // 485 - {1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 665: 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570}, - {1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 665: 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569}, - {1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 665: 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568}, - {1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 665: 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567}, - {1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 665: 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566}, + {1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 687: 1639, 690: 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639}, + {1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 687: 1638, 690: 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 1638}, + {1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 687: 1637, 690: 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637}, + {1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 687: 1636, 690: 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636, 1636}, + {1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 687: 1635, 690: 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635, 1635}, // 490 - {1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 665: 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565}, - {1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 665: 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564}, - {1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 665: 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563}, - {1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 665: 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562}, - {1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 665: 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561}, + {1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 687: 1634, 690: 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634}, + {1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 687: 1633, 690: 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633}, + {1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 687: 1632, 690: 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632}, + {1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 687: 1631, 690: 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631, 1631}, + {1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 687: 1630, 690: 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630, 1630}, // 495 - {1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 665: 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560}, - {1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 665: 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559}, - {1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 665: 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558}, - {1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 665: 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557}, - {1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 665: 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556}, + {1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 687: 1629, 690: 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629}, + {1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 687: 1628, 690: 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628, 1628}, + {1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 687: 1627, 690: 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627, 1627}, + {1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 687: 1626, 690: 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626}, + {1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 687: 1625, 690: 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625}, // 500 - {1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 665: 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555}, - {1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 665: 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554}, - {1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 665: 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553}, - {1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 665: 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552}, - {1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 665: 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551}, + {1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 687: 1624, 690: 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624}, + {1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 687: 1623, 690: 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623, 1623}, + {1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 687: 1622, 690: 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622}, + {1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 687: 1621, 690: 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621, 1621}, + {1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 687: 1620, 690: 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620, 1620}, // 505 - {1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 665: 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550}, - {1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 665: 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549}, - {1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 665: 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548}, - {1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 665: 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547}, - {1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 665: 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546}, + {1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 687: 1619, 690: 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1619}, + {1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 687: 1618, 690: 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618}, + {1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 687: 1617, 690: 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617, 1617}, + {1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 687: 1616, 690: 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616}, + {1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 687: 1615, 690: 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615}, // 510 - {1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 665: 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545}, - {1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 665: 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544}, - {1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 665: 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543}, - {1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 665: 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542}, - {1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 665: 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541}, + {1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 687: 1614, 690: 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614}, + {1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 687: 1613, 690: 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613, 1613}, + {1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 687: 1612, 690: 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612, 1612}, + {1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 687: 1611, 690: 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611}, + {1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 687: 1610, 690: 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610, 1610}, // 515 - {1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 665: 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540}, - {1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 665: 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539}, - {1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 665: 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538}, - {1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 665: 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537}, - {1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 665: 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536}, + {1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 687: 1609, 690: 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609}, + {1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 687: 1608, 690: 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608}, + {1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 687: 1607, 690: 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607, 1607}, + {1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 687: 1606, 690: 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606}, + {1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 687: 1605, 690: 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605, 1605}, // 520 - {1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 4061, 1533, 1533, 1533, 1533, 1533, 480: 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 489: 1533, 1533, 1533, 493: 1533, 1533, 496: 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 506: 1533, 1533, 509: 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 531: 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 565: 1533, 1533, 594: 1533, 652: 1533, 656: 1533, 1533}, - {1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 4050, 1532, 1532, 1532, 1532, 1532, 480: 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 489: 1532, 1532, 1532, 493: 1532, 1532, 496: 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 506: 1532, 1532, 509: 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 531: 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 565: 1532, 1532, 594: 1532, 652: 1532, 656: 1532, 1532}, - {1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 665: 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531}, - {1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 665: 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530}, - {1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 665: 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529}, + {1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 687: 1604, 690: 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604, 1604}, + {1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 687: 1603, 690: 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603}, + {1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 687: 1602, 690: 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602}, + {1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 687: 1601, 690: 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601, 1601}, + {1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 687: 1600, 690: 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600}, // 525 - {1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 665: 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528}, - {1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 665: 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527}, - {1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 665: 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526}, - {1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 665: 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525}, - {1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 665: 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524}, + {1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 687: 1599, 690: 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599, 1599}, + {1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 687: 1598, 690: 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598}, + {1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 687: 1597, 690: 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597}, + {1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 687: 1596, 690: 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596}, + {1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 687: 1595, 690: 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595}, // 530 - {1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 665: 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523}, - {1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 665: 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522}, - {1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 665: 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521}, - {1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 665: 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520}, - {1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 665: 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519}, + {1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 687: 1594, 690: 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594}, + {1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 687: 1593, 690: 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593, 1593}, + {1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 687: 1592, 690: 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592, 1592}, + {1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 4170, 1589, 1589, 1589, 497: 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 508: 1589, 1589, 511: 1589, 1589, 1589, 516: 1589, 1589, 1589, 1589, 1589, 1589, 523: 1589, 1589, 526: 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 550: 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 584: 1589, 1589, 1589, 616: 1589, 672: 1589, 676: 1589, 1589}, + {1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 4159, 1588, 1588, 1588, 497: 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 508: 1588, 1588, 511: 1588, 1588, 1588, 516: 1588, 1588, 1588, 1588, 1588, 1588, 523: 1588, 1588, 526: 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 550: 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 584: 1588, 1588, 1588, 616: 1588, 672: 1588, 676: 1588, 1588}, // 535 - {1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 665: 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518}, - {1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 665: 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517}, - {1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 665: 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516}, - {1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 665: 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515}, - {1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 665: 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514}, + {1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 687: 1587, 690: 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587}, + {1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 687: 1586, 690: 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586}, + {1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 687: 1585, 690: 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585}, + {1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 687: 1584, 690: 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584}, + {1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 687: 1583, 690: 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583, 1583}, // 540 - {1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 665: 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513}, - {1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 665: 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512}, - {1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 665: 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511}, - {1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 665: 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510}, - {1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 665: 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509}, + {1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 687: 1582, 690: 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582}, + {1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 687: 1581, 690: 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581}, + {1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 687: 1580, 690: 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580, 1580}, + {1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 687: 1579, 690: 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579}, + {1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 687: 1578, 690: 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578, 1578}, // 545 - {1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 665: 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508}, - {1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 665: 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507}, - {1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 665: 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506}, - {1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 665: 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505}, - {1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 665: 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504}, + {1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 687: 1577, 690: 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577}, + {1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 687: 1576, 690: 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576, 1576}, + {1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 687: 1575, 690: 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575, 1575}, + {1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 687: 1574, 690: 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574, 1574}, + {1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 687: 1573, 690: 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573, 1573}, // 550 - {1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 665: 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503}, - {1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 665: 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502}, - {1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 665: 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501}, - {1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 665: 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500}, - {1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 665: 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499}, + {1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 687: 1572, 690: 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572}, + {1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 687: 1571, 690: 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571}, + {1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 687: 1570, 690: 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570}, + {1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 687: 1569, 690: 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569}, + {1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 687: 1568, 690: 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568}, // 555 - {1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 665: 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498}, - {1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 665: 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497}, - {1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 665: 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496}, - {1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 665: 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495}, - {1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 665: 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494}, + {1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 687: 1567, 690: 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567}, + {1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 687: 1566, 690: 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566}, + {1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 687: 1565, 690: 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565}, + {1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 687: 1564, 690: 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564, 1564}, + {1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 687: 1563, 690: 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563}, // 560 - {1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 665: 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493}, - {1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 665: 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492}, - {1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 665: 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491}, - {1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 665: 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490}, - {1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 665: 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489}, + {1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 687: 1562, 690: 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1562}, + {1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 687: 1561, 690: 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561, 1561}, + {1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 687: 1560, 690: 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560}, + {1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 687: 1559, 690: 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559, 1559}, + {1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 687: 1558, 690: 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558, 1558}, // 565 - {1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 665: 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488}, - {1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 665: 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487}, - {1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 665: 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486}, - {1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 665: 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485}, - {1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 665: 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484}, + {1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 687: 1557, 690: 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557}, + {1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 687: 1556, 690: 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556}, + {1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 687: 1555, 690: 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555, 1555}, + {1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 687: 1554, 690: 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554, 1554}, + {1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 687: 1553, 690: 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553}, // 570 - {1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 665: 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483}, - {1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 665: 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482}, - {1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 665: 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481}, - {1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 665: 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480}, - {1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 665: 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479}, + {1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 687: 1552, 690: 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552}, + {1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 687: 1551, 690: 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551}, + {1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 687: 1550, 690: 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550}, + {1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 687: 1549, 690: 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549, 1549}, + {1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 687: 1548, 690: 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548}, // 575 - {1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 665: 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478}, - {1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 665: 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477}, - {1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 665: 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476}, - {1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 665: 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475}, - {1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 665: 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474}, + {1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 687: 1547, 690: 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547}, + {1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 687: 1546, 690: 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546}, + {1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 687: 1545, 690: 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545}, + {1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 687: 1544, 690: 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544}, + {1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 687: 1543, 690: 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543, 1543}, // 580 - {1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 665: 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473}, - {1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 665: 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472}, - {1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 665: 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471}, - {1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 665: 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470}, - {1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 665: 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469}, + {1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 687: 1542, 690: 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542}, + {1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 687: 1541, 690: 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541}, + {1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 687: 1540, 690: 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540}, + {1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 687: 1539, 690: 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539, 1539}, + {1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 687: 1538, 690: 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538, 1538}, // 585 - {1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 665: 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468}, - {1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 665: 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467}, - {1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 665: 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466}, - {1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 665: 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465}, - {1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 665: 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464}, + {1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 687: 1537, 690: 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537}, + {1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 687: 1536, 690: 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536}, + {1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 687: 1535, 690: 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535}, + {1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 687: 1534, 690: 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534}, + {1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 687: 1533, 690: 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533}, // 590 - {1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 665: 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463}, - {1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 665: 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462}, - {1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 665: 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461}, - {1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 665: 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460}, - {1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 665: 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459}, + {1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 687: 1532, 690: 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532}, + {1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 687: 1531, 690: 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531, 1531}, + {1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 687: 1530, 690: 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530}, + {1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 687: 1529, 690: 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529}, + {1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 687: 1528, 690: 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528}, // 595 - {1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 665: 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458}, - {1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 665: 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457}, - {1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 665: 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456}, - {1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 665: 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455}, - {1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 665: 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454}, + {1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 687: 1527, 690: 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527}, + {1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 687: 1526, 690: 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1526}, + {1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 687: 1525, 690: 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 1525}, + {1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 687: 1524, 690: 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1524}, + {1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 687: 1523, 690: 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523, 1523}, // 600 - {1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 665: 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453}, - {1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 665: 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452}, - {1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 665: 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451}, - {1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 665: 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450}, - {1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 665: 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449}, + {1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 687: 1522, 690: 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1522}, + {1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 687: 1521, 690: 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521, 1521}, + {1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 687: 1520, 690: 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520}, + {1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 687: 1519, 690: 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519}, + {1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 687: 1518, 690: 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518}, // 605 - {1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 665: 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448}, - {1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 665: 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447}, - {1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1151, 1446, 1446, 1446, 1446, 1446, 480: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 489: 1446, 1446, 1446, 493: 1446, 1446, 496: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 506: 1446, 1446, 509: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 531: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 565: 1446, 1446, 594: 1446, 652: 1446, 656: 1446, 1446}, - {1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 665: 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445}, - {1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 665: 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444}, + {1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 687: 1517, 690: 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517}, + {1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 687: 1516, 690: 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516}, + {1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 687: 1515, 690: 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515, 1515}, + {1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 687: 1514, 690: 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514}, + {1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 687: 1513, 690: 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513}, // 610 - {1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 665: 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443}, - {1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 665: 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442}, - {1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 665: 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441}, - {1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 665: 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440}, - {1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 665: 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439}, + {1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 687: 1512, 690: 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512}, + {1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 687: 1511, 690: 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511}, + {1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 687: 1510, 690: 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510}, + {1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 687: 1509, 690: 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509, 1509}, + {1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 687: 1508, 690: 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508}, // 615 - {1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 665: 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438}, - {1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 665: 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437}, - {1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 665: 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436}, - {1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 665: 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435}, - {1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 665: 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434}, + {1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 687: 1507, 690: 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507}, + {1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 687: 1506, 690: 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506}, + {1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 687: 1505, 690: 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505}, + {1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 687: 1504, 690: 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504}, + {1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 687: 1503, 690: 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503}, // 620 - {1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 665: 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433}, - {1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 665: 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432}, - {1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 4041, 1431, 1431, 1431, 1431, 1431, 480: 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 489: 1431, 1431, 1431, 493: 1431, 1431, 496: 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 506: 1431, 1431, 509: 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 531: 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 565: 1431, 1431, 594: 1431, 652: 1431, 656: 1431, 1431}, - {1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 665: 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430}, - {1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 665: 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429}, + {1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 687: 1502, 690: 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502}, + {1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 687: 1501, 690: 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501}, + {1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 687: 1500, 690: 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500}, + {1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 687: 1499, 690: 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499}, + {1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 687: 1498, 690: 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498, 1498}, // 625 - {1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 665: 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428}, - {1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 665: 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427}, - {1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 665: 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426}, - {1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 665: 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425}, - {1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 665: 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424}, + {1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 687: 1497, 690: 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497}, + {1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 687: 1496, 690: 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496}, + {1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 687: 1495, 690: 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495}, + {1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 687: 1494, 690: 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494}, + {1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1190, 1493, 1493, 1493, 497: 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 508: 1493, 1493, 511: 1493, 1493, 1493, 516: 1493, 1493, 1493, 1493, 1493, 1493, 523: 1493, 1493, 526: 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 550: 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 584: 1493, 1493, 1493, 616: 1493, 672: 1493, 676: 1493, 1493}, // 630 - {1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 665: 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423}, - {1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 665: 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422}, - {1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 665: 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421}, - {1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 665: 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420}, - {1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 665: 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419}, + {1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 687: 1492, 690: 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492}, + {1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 687: 1491, 690: 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491}, + {1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 687: 1490, 690: 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490}, + {1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 687: 1489, 690: 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489}, + {1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 687: 1488, 690: 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488}, // 635 - {1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 665: 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418}, - {1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 665: 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417}, - {1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 665: 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416}, - {1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 665: 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415}, - {1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 665: 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414}, + {1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 687: 1487, 690: 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487}, + {1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 687: 1486, 690: 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486}, + {1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 687: 1485, 690: 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485, 1485}, + {1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 687: 1484, 690: 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484}, + {1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 687: 1483, 690: 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483}, // 640 - {1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1150, 1413, 1413, 1413, 1413, 1413, 480: 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 489: 1413, 1413, 1413, 493: 1413, 1413, 496: 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 506: 1413, 1413, 509: 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 531: 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 565: 1413, 1413, 594: 1413, 652: 1413, 656: 1413, 1413}, - {1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 665: 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412}, - {1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 665: 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411}, - {1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 665: 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410}, - {1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 665: 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409}, + {1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 687: 1482, 690: 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482, 1482}, + {1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 687: 1481, 690: 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481}, + {1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 687: 1480, 690: 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480}, + {1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 687: 1479, 690: 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479}, + {1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 687: 1478, 690: 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478}, // 645 - {1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 665: 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408}, - {1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 665: 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407}, - {1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 665: 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406}, - {1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 665: 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405}, - {1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 665: 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404}, + {1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 4150, 1477, 1477, 1477, 497: 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 508: 1477, 1477, 511: 1477, 1477, 1477, 516: 1477, 1477, 1477, 1477, 1477, 1477, 523: 1477, 1477, 526: 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 550: 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 584: 1477, 1477, 1477, 616: 1477, 672: 1477, 676: 1477, 1477}, + {1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 687: 1476, 690: 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476}, + {1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 687: 1475, 690: 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475}, + {1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 687: 1474, 690: 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474}, + {1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 687: 1473, 690: 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473}, // 650 - {1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 665: 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403}, - {1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 665: 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402}, - {1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 4034, 1401, 1401, 1401, 1401, 1401, 480: 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 489: 1401, 1401, 1401, 493: 1401, 1401, 496: 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 506: 1401, 1401, 509: 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 531: 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 565: 1401, 1401, 594: 1401, 652: 1401, 656: 1401, 1401}, - {1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 4027, 1400, 1400, 1400, 1400, 1400, 480: 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 489: 1400, 1400, 1400, 493: 1400, 1400, 496: 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 506: 1400, 1400, 509: 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 531: 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 565: 1400, 1400, 594: 1400, 652: 1400, 656: 1400, 1400}, - {1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 665: 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399}, + {1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 687: 1472, 690: 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1472}, + {1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 687: 1471, 690: 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471, 1471}, + {1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 687: 1470, 690: 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470, 1470}, + {1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 687: 1469, 690: 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469, 1469}, + {1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 687: 1468, 690: 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468}, // 655 - {1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 665: 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398}, - {1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 665: 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1397}, - {1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 665: 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396}, - {1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 665: 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395}, - {1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 665: 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394}, + {1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 687: 1467, 690: 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467}, + {1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 687: 1466, 690: 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466, 1466}, + {1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 687: 1465, 690: 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465}, + {1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 687: 1464, 690: 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464}, + {1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 687: 1463, 690: 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463}, // 660 - {1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 665: 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393, 1393}, - {1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 665: 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392}, - {1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 665: 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391}, - {1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 665: 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390}, - {1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 665: 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1389}, + {1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 687: 1462, 690: 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462, 1462}, + {1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 687: 1461, 690: 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461}, + {1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 687: 1460, 690: 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460, 1460}, + {1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1189, 1459, 1459, 1459, 497: 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 508: 1459, 1459, 511: 1459, 1459, 1459, 516: 1459, 1459, 1459, 1459, 1459, 1459, 523: 1459, 1459, 526: 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 550: 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 584: 1459, 1459, 1459, 616: 1459, 672: 1459, 676: 1459, 1459}, + {1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 687: 1458, 690: 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458}, // 665 - {1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 665: 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388, 1388}, - {1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 665: 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387}, - {1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 665: 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386}, - {1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 665: 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385}, - {1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 665: 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384}, + {1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 687: 1457, 690: 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457}, + {1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 687: 1456, 690: 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456, 1456}, + {1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 687: 1455, 690: 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455}, + {1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 687: 1454, 690: 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454}, + {1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 687: 1453, 690: 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453}, // 670 - {1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 665: 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383, 1383}, - {1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 665: 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382, 1382}, - {1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 665: 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381}, - {1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 4007, 1380, 1380, 1380, 1380, 1380, 480: 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 489: 1380, 1380, 1380, 493: 1380, 1380, 496: 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 506: 1380, 1380, 509: 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 531: 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 565: 1380, 1380, 594: 1380, 652: 1380, 656: 1380, 1380}, - {1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 3999, 1379, 1379, 1379, 1379, 1379, 480: 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 489: 1379, 1379, 1379, 493: 1379, 1379, 496: 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 506: 1379, 1379, 509: 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 531: 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 565: 1379, 1379, 594: 1379, 652: 1379, 656: 1379, 1379}, + {1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 687: 1452, 690: 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452}, + {1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 687: 1451, 690: 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451, 1451}, + {1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 687: 1450, 690: 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 1450}, + {1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 687: 1449, 690: 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449}, + {1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 687: 1448, 690: 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448}, // 675 - {1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 665: 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378}, - {1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 665: 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377, 1377}, - {1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 665: 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376}, - {1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 665: 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375}, - {1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 665: 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374}, + {1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 4143, 1447, 1447, 1447, 497: 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 508: 1447, 1447, 511: 1447, 1447, 1447, 516: 1447, 1447, 1447, 1447, 1447, 1447, 523: 1447, 1447, 526: 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 550: 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 584: 1447, 1447, 1447, 616: 1447, 672: 1447, 676: 1447, 1447}, + {1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 4136, 1446, 1446, 1446, 497: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 508: 1446, 1446, 511: 1446, 1446, 1446, 516: 1446, 1446, 1446, 1446, 1446, 1446, 523: 1446, 1446, 526: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 550: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 584: 1446, 1446, 1446, 616: 1446, 672: 1446, 676: 1446, 1446}, + {1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 687: 1445, 690: 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445, 1445}, + {1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 687: 1444, 690: 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444}, + {1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 687: 1443, 690: 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443}, // 680 - {1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 665: 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373, 1373}, - {1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 665: 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372}, - {1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 665: 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371}, - {1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 665: 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1370}, - {1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 665: 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369}, + {1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 687: 1442, 690: 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442}, + {1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 687: 1441, 690: 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441}, + {1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 687: 1440, 690: 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440}, + {1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 687: 1439, 690: 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439, 1439}, + {1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 687: 1438, 690: 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438}, // 685 - {1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 665: 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368}, - {1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 665: 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367}, - {1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 665: 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1366}, - {1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 665: 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365}, - {1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 665: 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364}, + {1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 687: 1437, 690: 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437}, + {1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 687: 1436, 690: 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436}, + {1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 687: 1435, 690: 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435}, + {1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 687: 1434, 690: 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434}, + {1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 687: 1433, 690: 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1433}, // 690 - {1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 665: 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363}, - {1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 665: 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362}, - {1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 474: 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 496: 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 506: 1324, 1324, 509: 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 531: 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 565: 1324, 1324, 581: 1324, 590: 1324, 1324, 594: 1324, 642: 1324, 1324, 1324, 1324}, - {1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 474: 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 496: 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 506: 1323, 1323, 509: 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 531: 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 565: 1323, 1323, 581: 1323, 590: 1323, 1323, 594: 1323, 642: 1323, 1323, 1323, 1323}, - {1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 474: 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 496: 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 506: 1322, 1322, 509: 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 531: 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 565: 1322, 1322, 581: 1322, 590: 1322, 1322, 594: 1322, 642: 1322, 1322, 1322, 1322}, + {1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 687: 1432, 690: 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432, 1432}, + {1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 687: 1431, 690: 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431}, + {1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 687: 1430, 690: 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430, 1430}, + {1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 687: 1429, 690: 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429, 1429}, + {1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 687: 1428, 690: 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428}, // 695 - {1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 474: 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 496: 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 506: 1321, 1321, 509: 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 531: 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 565: 1321, 1321, 581: 1321, 590: 1321, 1321, 594: 1321, 642: 1321, 1321, 1321, 1321}, - {1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 474: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 496: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 506: 1320, 1320, 509: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 531: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 565: 1320, 1320, 581: 1320, 590: 1320, 1320, 594: 1320, 642: 1320, 1320, 1320, 1320}, - {1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 474: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 496: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 506: 1319, 1319, 509: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 531: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 565: 1319, 1319, 581: 1319, 590: 1319, 1319, 594: 1319, 642: 1319, 1319, 1319, 1319}, - {1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 474: 1318, 3998, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 496: 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 506: 1318, 1318, 509: 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 531: 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 565: 1318, 1318, 581: 1318, 590: 1318, 1318, 594: 1318, 642: 1318, 1318, 1318, 1318}, - {475: 3995, 576: 3996, 580: 3997}, + {1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 687: 1427, 690: 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427}, + {1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 4116, 1426, 1426, 1426, 497: 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 508: 1426, 1426, 511: 1426, 1426, 1426, 516: 1426, 1426, 1426, 1426, 1426, 1426, 523: 1426, 1426, 526: 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 550: 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 584: 1426, 1426, 1426, 616: 1426, 672: 1426, 676: 1426, 1426}, + {1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 4108, 1425, 1425, 1425, 497: 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 508: 1425, 1425, 511: 1425, 1425, 1425, 516: 1425, 1425, 1425, 1425, 1425, 1425, 523: 1425, 1425, 526: 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 550: 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 584: 1425, 1425, 1425, 616: 1425, 672: 1425, 676: 1425, 1425}, + {1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 687: 1424, 690: 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424}, + {1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 687: 1423, 690: 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423}, // 700 - {1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 474: 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 496: 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 506: 1316, 1316, 509: 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 531: 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 565: 1316, 1316, 581: 1316, 590: 1316, 1316, 594: 1316, 642: 1316, 1316, 1316, 1316}, - {1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 474: 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 496: 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 506: 1315, 1315, 509: 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 531: 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 565: 1315, 1315, 581: 1315, 590: 1315, 1315, 594: 1315, 642: 1315, 1315, 1315, 1315}, - {1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 474: 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 496: 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 506: 1312, 1312, 509: 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 531: 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 565: 1312, 1312, 581: 1312, 590: 1312, 1312, 594: 1312, 642: 1312, 1312, 1312, 1312}, - {1307, 1307, 9: 3412, 49: 1307, 127: 1307, 472: 1307, 474: 1307, 480: 1307, 1307, 490: 1307, 1307, 493: 1307, 1307, 496: 1307, 1307, 501: 1307}, - {1306, 1306, 9: 1306, 49: 1306, 127: 1306, 472: 1306, 474: 1306, 480: 1306, 1306, 490: 1306, 1306, 493: 1306, 1306, 496: 1306, 1306, 501: 1306, 1306, 514: 1306, 516: 1306, 524: 1306, 527: 1306, 1306}, + {1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 687: 1422, 690: 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422}, + {1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 687: 1421, 690: 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421, 1421}, + {1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 687: 1420, 690: 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420}, + {1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 687: 1419, 690: 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1419}, + {1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 687: 1418, 690: 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418}, // 705 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 1226, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3993}, - {1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 474: 1280, 1280, 1280, 1280, 1280, 480: 1280, 1280, 1280, 1280, 3350, 1280, 1280, 1280, 489: 1280, 1280, 1280, 493: 1280, 1280, 496: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 506: 1280, 1280, 509: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 531: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 565: 1280, 1280, 594: 3351}, - {1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 474: 1279, 1279, 1279, 1279, 1279, 480: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 489: 1279, 1279, 1279, 493: 1279, 1279, 496: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 506: 1279, 1279, 509: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 531: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 565: 1279, 1279, 594: 1279, 652: 3988, 656: 1279, 1279}, - {1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 474: 1276, 1276, 1276, 1276, 1276, 480: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 489: 1276, 1276, 1276, 493: 1276, 1276, 496: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 506: 1276, 1276, 509: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 531: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 565: 1276, 1276, 594: 1276, 656: 3984, 3985}, - {1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 474: 1275, 1275, 1275, 1275, 1275, 480: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 489: 1275, 1275, 1275, 493: 1275, 1275, 496: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 506: 1275, 1275, 509: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 531: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 565: 1275, 1275, 594: 1275}, + {1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 687: 1417, 690: 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417}, + {1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 687: 1416, 690: 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416}, + {1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 687: 1415, 690: 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1415}, + {1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 687: 1414, 690: 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414, 1414}, + {1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 687: 1413, 690: 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413}, // 710 - {1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 474: 1274, 1274, 1274, 1274, 1274, 480: 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 489: 1274, 1274, 1274, 493: 1274, 1274, 496: 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 506: 1274, 1274, 509: 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 531: 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 565: 1274, 1274, 594: 1274}, - {1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 474: 1273, 1273, 1273, 1273, 1273, 480: 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 489: 1273, 1273, 1273, 493: 1273, 1273, 496: 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 506: 1273, 1273, 509: 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 531: 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 565: 1273, 1273, 594: 1273}, - {1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 474: 1271, 1271, 1271, 1271, 1271, 480: 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 489: 1271, 1271, 1271, 493: 1271, 1271, 496: 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 506: 1271, 1271, 509: 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 531: 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 1271, 565: 1271, 1271, 594: 1271}, - {1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 474: 1270, 1270, 1270, 1270, 1270, 480: 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 489: 1270, 1270, 1270, 493: 1270, 1270, 496: 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 506: 1270, 1270, 509: 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 531: 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 565: 1270, 1270, 594: 1270}, - {1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 474: 1269, 1269, 1269, 1269, 1269, 480: 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 489: 1269, 1269, 1269, 493: 1269, 1269, 496: 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 506: 1269, 1269, 509: 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 531: 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 565: 1269, 1269, 594: 1269}, + {1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 687: 1412, 690: 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412, 1412}, + {1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 687: 1411, 690: 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411}, + {1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 687: 1410, 690: 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410}, + {1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 687: 1409, 690: 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409}, + {1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 687: 1408, 690: 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408, 1408}, // 715 - {1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 474: 1268, 1268, 1268, 1268, 1268, 480: 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 489: 1268, 1268, 1268, 493: 1268, 1268, 496: 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 506: 1268, 1268, 509: 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 531: 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 565: 1268, 1268, 594: 1268}, - {1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 474: 1267, 1267, 1267, 1267, 1267, 480: 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 489: 1267, 1267, 1267, 493: 1267, 1267, 496: 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 506: 1267, 1267, 509: 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 531: 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 565: 1267, 1267, 594: 1267}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3983, 3253, 3334, 3252, 3249}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3982, 3253, 3334, 3252, 3249}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3981, 3253, 3334, 3252, 3249}, + {1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 687: 1407, 690: 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407}, + {1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 687: 1406, 690: 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406}, + {1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 687: 1405, 690: 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405}, + {1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 687: 1404, 690: 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404}, + {1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 687: 1403, 690: 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403}, // 720 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3980, 3253, 3334, 3252, 3249}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3979, 3253, 3334, 3252, 3249}, - {1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 474: 1260, 1260, 1260, 1260, 1260, 480: 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 489: 1260, 1260, 1260, 493: 1260, 1260, 496: 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 506: 1260, 1260, 509: 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 531: 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 565: 1260, 1260, 594: 1260}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 2587, 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3879, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 2585, 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 646: 2581, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3878, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3876, 748: 3881, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 3883, 3882, 778: 3877}, - {473: 3871}, + {1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 493: 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 516: 1365, 1365, 1365, 1365, 1365, 1365, 523: 1365, 1365, 526: 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 550: 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 584: 1365, 1365, 1365, 600: 1365, 607: 1365, 613: 1365, 616: 1365, 662: 1365, 1365, 1365, 666: 1365}, + {1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 493: 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 516: 1364, 1364, 1364, 1364, 1364, 1364, 523: 1364, 1364, 526: 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 550: 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 584: 1364, 1364, 1364, 600: 1364, 607: 1364, 613: 1364, 616: 1364, 662: 1364, 1364, 1364, 666: 1364}, + {1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 493: 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 516: 1363, 1363, 1363, 1363, 1363, 1363, 523: 1363, 1363, 526: 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 550: 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 584: 1363, 1363, 1363, 600: 1363, 607: 1363, 613: 1363, 616: 1363, 662: 1363, 1363, 1363, 666: 1363}, + {1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 493: 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 516: 1362, 1362, 1362, 1362, 1362, 1362, 523: 1362, 1362, 526: 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 550: 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 584: 1362, 1362, 1362, 600: 1362, 607: 1362, 613: 1362, 616: 1362, 662: 1362, 1362, 1362, 666: 1362}, + {1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 493: 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 516: 1361, 1361, 1361, 1361, 1361, 1361, 523: 1361, 1361, 526: 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 550: 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 584: 1361, 1361, 1361, 600: 1361, 607: 1361, 613: 1361, 616: 1361, 662: 1361, 1361, 1361, 666: 1361}, // 725 - {473: 2588, 709: 3870}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3867, 2762, 2763, 2761}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3866, 3253, 3334, 3252, 3249}, - {473: 3861}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 543: 1080, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3848, 1209: 3849}, + {1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 493: 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 516: 1360, 1360, 1360, 1360, 1360, 1360, 523: 1360, 1360, 526: 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 550: 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 584: 1360, 1360, 1360, 600: 1360, 607: 1360, 613: 1360, 616: 1360, 662: 1360, 1360, 1360, 666: 1360}, + {1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 493: 4107, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 516: 1359, 1359, 1359, 1359, 1359, 1359, 523: 1359, 1359, 526: 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 550: 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 584: 1359, 1359, 1359, 600: 1359, 607: 1359, 613: 1359, 616: 1359, 662: 1359, 1359, 1359, 666: 1359}, + {493: 4104, 596: 4105, 598: 4106}, + {1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 493: 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 516: 1357, 1357, 1357, 1357, 1357, 1357, 523: 1357, 1357, 526: 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 550: 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357, 584: 1357, 1357, 1357, 600: 1357, 607: 1357, 613: 1357, 616: 1357, 662: 1357, 1357, 1357, 666: 1357}, + {1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 493: 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 516: 1356, 1356, 1356, 1356, 1356, 1356, 523: 1356, 1356, 526: 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 550: 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 584: 1356, 1356, 1356, 600: 1356, 607: 1356, 613: 1356, 616: 1356, 662: 1356, 1356, 1356, 666: 1356}, // 730 - {473: 3790}, - {473: 3787}, - {473: 3779}, - {473: 1230}, - {473: 1227}, + {1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 493: 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 516: 1353, 1353, 1353, 1353, 1353, 1353, 523: 1353, 1353, 526: 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 550: 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353, 584: 1353, 1353, 1353, 600: 1353, 607: 1353, 613: 1353, 616: 1353, 662: 1353, 1353, 1353, 666: 1353}, + {1348, 1348, 9: 3519, 58: 1348, 139: 1348, 491: 1348, 494: 1348, 500: 1348, 1348, 509: 1348, 511: 1348, 1348, 1348, 516: 1348, 518: 1348, 521: 1348}, + {1347, 1347, 9: 1347, 58: 1347, 139: 1347, 491: 1347, 494: 1347, 500: 1347, 1347, 509: 1347, 511: 1347, 1347, 1347, 516: 1347, 518: 1347, 521: 1347, 523: 1347, 533: 1347, 535: 1347, 543: 1347, 546: 1347, 1347}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 1265, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4102}, + {1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 493: 1321, 1321, 1321, 497: 1321, 1321, 3457, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 508: 1321, 1321, 511: 1321, 1321, 1321, 516: 1321, 1321, 1321, 1321, 1321, 1321, 523: 1321, 1321, 526: 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 550: 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 1321, 584: 1321, 1321, 1321, 616: 3458}, // 735 - {473: 1224}, - {473: 1220}, - {473: 1218}, - {473: 1217}, - {473: 1215}, + {1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 493: 1320, 1320, 1320, 497: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 508: 1320, 1320, 511: 1320, 1320, 1320, 516: 1320, 1320, 1320, 1320, 1320, 1320, 523: 1320, 1320, 526: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 550: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 584: 1320, 1320, 1320, 616: 1320, 672: 4097, 676: 1320, 1320}, + {1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 493: 1317, 1317, 1317, 497: 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 508: 1317, 1317, 511: 1317, 1317, 1317, 516: 1317, 1317, 1317, 1317, 1317, 1317, 523: 1317, 1317, 526: 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 550: 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 584: 1317, 1317, 1317, 616: 1317, 676: 4093, 4094}, + {1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 493: 1316, 1316, 1316, 497: 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 508: 1316, 1316, 511: 1316, 1316, 1316, 516: 1316, 1316, 1316, 1316, 1316, 1316, 523: 1316, 1316, 526: 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 550: 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 584: 1316, 1316, 1316, 616: 1316}, + {1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 493: 1315, 1315, 1315, 497: 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 508: 1315, 1315, 511: 1315, 1315, 1315, 516: 1315, 1315, 1315, 1315, 1315, 1315, 523: 1315, 1315, 526: 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 550: 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 1315, 584: 1315, 1315, 1315, 616: 1315}, + {1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 493: 1314, 1314, 1314, 497: 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 508: 1314, 1314, 511: 1314, 1314, 1314, 516: 1314, 1314, 1314, 1314, 1314, 1314, 523: 1314, 1314, 526: 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 550: 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 584: 1314, 1314, 1314, 616: 1314}, // 740 - {1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 480: 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 489: 1204, 1204, 1204, 493: 1204, 1204, 496: 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 506: 1204, 1204, 509: 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 531: 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 565: 1204, 1204, 594: 1204}, - {1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 480: 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 489: 1203, 1203, 1203, 493: 1203, 1203, 496: 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 506: 1203, 1203, 509: 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 531: 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 565: 1203, 1203, 594: 1203}, - {1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 480: 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 489: 1202, 1202, 1202, 493: 1202, 1202, 496: 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 506: 1202, 1202, 509: 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 531: 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 565: 1202, 1202, 594: 1202}, - {1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 480: 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 489: 1201, 1201, 1201, 493: 1201, 1201, 496: 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 506: 1201, 1201, 509: 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 531: 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 565: 1201, 1201, 594: 1201}, - {1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 480: 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 489: 1200, 1200, 1200, 493: 1200, 1200, 496: 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 506: 1200, 1200, 509: 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 531: 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 565: 1200, 1200, 594: 1200}, + {1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 493: 1312, 1312, 1312, 497: 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 508: 1312, 1312, 511: 1312, 1312, 1312, 516: 1312, 1312, 1312, 1312, 1312, 1312, 523: 1312, 1312, 526: 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 550: 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 584: 1312, 1312, 1312, 616: 1312}, + {1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 493: 1311, 1311, 1311, 497: 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 508: 1311, 1311, 511: 1311, 1311, 1311, 516: 1311, 1311, 1311, 1311, 1311, 1311, 523: 1311, 1311, 526: 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 550: 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 584: 1311, 1311, 1311, 616: 1311}, + {1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 493: 1310, 1310, 1310, 497: 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 508: 1310, 1310, 511: 1310, 1310, 1310, 516: 1310, 1310, 1310, 1310, 1310, 1310, 523: 1310, 1310, 526: 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 550: 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 584: 1310, 1310, 1310, 616: 1310}, + {1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 493: 1309, 1309, 1309, 497: 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 508: 1309, 1309, 511: 1309, 1309, 1309, 516: 1309, 1309, 1309, 1309, 1309, 1309, 523: 1309, 1309, 526: 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 550: 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 584: 1309, 1309, 1309, 616: 1309}, + {1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 493: 1308, 1308, 1308, 497: 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 508: 1308, 1308, 511: 1308, 1308, 1308, 516: 1308, 1308, 1308, 1308, 1308, 1308, 523: 1308, 1308, 526: 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 550: 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 584: 1308, 1308, 1308, 616: 1308}, // 745 - {1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 480: 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 489: 1199, 1199, 1199, 493: 1199, 1199, 496: 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 506: 1199, 1199, 509: 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 531: 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 565: 1199, 1199, 594: 1199}, - {1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 480: 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 489: 1198, 1198, 1198, 493: 1198, 1198, 496: 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 506: 1198, 1198, 509: 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 531: 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 565: 1198, 1198, 594: 1198}, - {1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 480: 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 489: 1197, 1197, 1197, 493: 1197, 1197, 496: 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 506: 1197, 1197, 509: 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 531: 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 565: 1197, 1197, 594: 1197}, - {1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 480: 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 489: 1196, 1196, 1196, 493: 1196, 1196, 496: 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 506: 1196, 1196, 509: 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 531: 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 565: 1196, 1196, 594: 1196}, - {1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 480: 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 489: 1195, 1195, 1195, 493: 1195, 1195, 496: 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 506: 1195, 1195, 509: 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 531: 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, 565: 1195, 1195, 594: 1195}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4092, 3360, 3441, 3359, 3356}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4091, 3360, 3441, 3359, 3356}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4090, 3360, 3441, 3359, 3356}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4089, 3360, 3441, 3359, 3356}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4088, 3360, 3441, 3359, 3356}, // 750 - {1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 480: 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 489: 1194, 1194, 1194, 493: 1194, 1194, 496: 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 506: 1194, 1194, 509: 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 531: 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 565: 1194, 1194, 594: 1194}, - {473: 3776}, - {473: 3773}, - {1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 3770, 1206, 1206, 1206, 1206, 1206, 480: 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 489: 1206, 1206, 1206, 493: 1206, 1206, 496: 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 506: 1206, 1206, 509: 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 531: 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 565: 1206, 1206, 594: 1206, 1092: 3771}, - {473: 3768}, + {1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 493: 1301, 1301, 1301, 497: 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 508: 1301, 1301, 511: 1301, 1301, 1301, 516: 1301, 1301, 1301, 1301, 1301, 1301, 523: 1301, 1301, 526: 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 550: 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 584: 1301, 1301, 1301, 616: 1301}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 2666, 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3988, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 2664, 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 665: 2660, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3987, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3985, 770: 3990, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 3992, 3991, 801: 3986}, + {492: 3980}, + {492: 2667, 731: 3979}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3976, 2850, 688: 2851, 2849}, // 755 - {1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 3764, 1112, 1112, 1112, 1112, 1112, 480: 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 489: 1112, 1112, 1112, 493: 1112, 1112, 496: 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 506: 1112, 1112, 509: 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 531: 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 565: 1112, 1112, 594: 1112, 1223: 3763}, - {473: 3755}, - {473: 3751}, - {473: 3746}, - {473: 3743}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3975, 3360, 3441, 3359, 3356}, + {492: 3968}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 562: 1119, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3955, 1242: 3956}, + {492: 3897}, + {492: 3894}, // 760 - {473: 3738}, - {473: 3729}, - {473: 3722}, - {473: 3717}, - {473: 3680}, + {492: 3886}, + {492: 1269}, + {492: 1266}, + {492: 1263}, + {492: 1259}, // 765 - {473: 3666}, - {473: 3649}, - {1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 474: 1159, 1159, 1159, 1159, 1159, 480: 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 489: 1159, 1159, 1159, 493: 1159, 1159, 496: 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 506: 1159, 1159, 509: 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 531: 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 565: 1159, 1159, 594: 1159}, - {473: 3642}, - {473: 1153}, + {492: 1257}, + {492: 1256}, + {492: 1254}, + {1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 497: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 508: 1243, 1243, 511: 1243, 1243, 1243, 516: 1243, 1243, 1243, 1243, 1243, 1243, 523: 1243, 1243, 526: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 550: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 584: 1243, 1243, 1243, 616: 1243}, + {1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 497: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 508: 1242, 1242, 511: 1242, 1242, 1242, 516: 1242, 1242, 1242, 1242, 1242, 1242, 523: 1242, 1242, 526: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 550: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 584: 1242, 1242, 1242, 616: 1242}, // 770 - {473: 1152}, - {1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 474: 1144, 1144, 1144, 1144, 1144, 480: 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 489: 1144, 1144, 1144, 493: 1144, 1144, 496: 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 506: 1144, 1144, 509: 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 531: 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 565: 1144, 1144, 594: 1144}, - {473: 3639}, - {473: 3636}, - {473: 3628}, + {1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 497: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 508: 1241, 1241, 511: 1241, 1241, 1241, 516: 1241, 1241, 1241, 1241, 1241, 1241, 523: 1241, 1241, 526: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 550: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 584: 1241, 1241, 1241, 616: 1241}, + {1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 497: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 508: 1240, 1240, 511: 1240, 1240, 1240, 516: 1240, 1240, 1240, 1240, 1240, 1240, 523: 1240, 1240, 526: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 550: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 584: 1240, 1240, 1240, 616: 1240}, + {1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 497: 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 508: 1239, 1239, 511: 1239, 1239, 1239, 516: 1239, 1239, 1239, 1239, 1239, 1239, 523: 1239, 1239, 526: 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 550: 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 1239, 584: 1239, 1239, 1239, 616: 1239}, + {1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 497: 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 508: 1238, 1238, 511: 1238, 1238, 1238, 516: 1238, 1238, 1238, 1238, 1238, 1238, 523: 1238, 1238, 526: 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 550: 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 584: 1238, 1238, 1238, 616: 1238}, + {1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 497: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 508: 1237, 1237, 511: 1237, 1237, 1237, 516: 1237, 1237, 1237, 1237, 1237, 1237, 523: 1237, 1237, 526: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 550: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 584: 1237, 1237, 1237, 616: 1237}, // 775 - {473: 3620}, - {473: 3612}, - {473: 3598}, - {473: 3586}, - {473: 3581}, + {1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 497: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 508: 1236, 1236, 511: 1236, 1236, 1236, 516: 1236, 1236, 1236, 1236, 1236, 1236, 523: 1236, 1236, 526: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 550: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 584: 1236, 1236, 1236, 616: 1236}, + {1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 497: 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 508: 1235, 1235, 511: 1235, 1235, 1235, 516: 1235, 1235, 1235, 1235, 1235, 1235, 523: 1235, 1235, 526: 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 550: 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 584: 1235, 1235, 1235, 616: 1235}, + {1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 497: 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 508: 1234, 1234, 511: 1234, 1234, 1234, 516: 1234, 1234, 1234, 1234, 1234, 1234, 523: 1234, 1234, 526: 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 550: 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 1234, 584: 1234, 1234, 1234, 616: 1234}, + {1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 497: 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 508: 1233, 1233, 511: 1233, 1233, 1233, 516: 1233, 1233, 1233, 1233, 1233, 1233, 523: 1233, 1233, 526: 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 550: 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 584: 1233, 1233, 1233, 616: 1233}, + {492: 3883}, // 780 - {473: 3576}, - {473: 3571}, - {473: 3566}, - {473: 3561}, - {473: 3556}, + {492: 3880}, + {1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 3877, 1245, 1245, 1245, 497: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 508: 1245, 1245, 511: 1245, 1245, 1245, 516: 1245, 1245, 1245, 1245, 1245, 1245, 523: 1245, 1245, 526: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 550: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 584: 1245, 1245, 1245, 616: 1245, 1122: 3878}, + {492: 3875}, + {1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 3871, 1151, 1151, 1151, 497: 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 508: 1151, 1151, 511: 1151, 1151, 1151, 516: 1151, 1151, 1151, 1151, 1151, 1151, 523: 1151, 1151, 526: 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 550: 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 584: 1151, 1151, 1151, 616: 1151, 1255: 3870}, + {492: 3862}, // 785 - {473: 3543}, - {473: 3540}, - {473: 3537}, - {473: 3534}, - {473: 3531}, + {492: 3858}, + {492: 3853}, + {492: 3850}, + {492: 3845}, + {492: 3836}, // 790 - {473: 3528}, - {473: 3524}, - {473: 3518}, - {473: 3505}, - {473: 3500}, + {492: 3829}, + {492: 3824}, + {492: 3787}, + {492: 3773}, + {492: 3756}, // 795 - {473: 3495}, - {473: 3337}, - {751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 474: 751, 751, 751, 751, 751, 480: 751, 751, 751, 751, 751, 751, 751, 751, 489: 751, 751, 751, 493: 751, 751, 496: 751, 751, 751, 751, 751, 751, 751, 751, 506: 751, 751, 509: 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 531: 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 565: 751, 751, 594: 751}, - {750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 474: 750, 750, 750, 750, 750, 480: 750, 750, 750, 750, 750, 750, 750, 750, 489: 750, 750, 750, 493: 750, 750, 496: 750, 750, 750, 750, 750, 750, 750, 750, 506: 750, 750, 509: 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 531: 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 565: 750, 750, 594: 750}, - {749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 474: 749, 749, 749, 749, 749, 480: 749, 749, 749, 749, 749, 749, 749, 749, 489: 749, 749, 749, 493: 749, 749, 496: 749, 749, 749, 749, 749, 749, 749, 749, 506: 749, 749, 509: 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 531: 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, 565: 749, 749, 594: 749}, + {1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 493: 1198, 1198, 1198, 497: 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 508: 1198, 1198, 511: 1198, 1198, 1198, 516: 1198, 1198, 1198, 1198, 1198, 1198, 523: 1198, 1198, 526: 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 550: 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 584: 1198, 1198, 1198, 616: 1198}, + {492: 3749}, + {492: 1192}, + {492: 1191}, + {1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 493: 1183, 1183, 1183, 497: 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 508: 1183, 1183, 511: 1183, 1183, 1183, 516: 1183, 1183, 1183, 1183, 1183, 1183, 523: 1183, 1183, 526: 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 550: 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 584: 1183, 1183, 1183, 616: 1183}, // 800 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3338}, - {9: 3346, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3494}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3493}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3492}, + {492: 3746}, + {492: 3743}, + {492: 3735}, + {492: 3727}, + {492: 3719}, // 805 - {2: 1927, 1927, 1927, 1927, 1927, 1927, 1927, 10: 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 50: 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 473: 1927, 475: 1927, 1927, 1927, 479: 1927, 482: 1927, 1927, 485: 1927, 1927, 1927, 492: 1927, 495: 1927, 504: 1927, 1927, 508: 1927, 530: 1927, 564: 1927, 567: 1927, 1927, 570: 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 582: 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 592: 1927, 1927, 595: 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927, 648: 1927}, - {2: 1926, 1926, 1926, 1926, 1926, 1926, 1926, 10: 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 50: 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 473: 1926, 475: 1926, 1926, 1926, 479: 1926, 482: 1926, 1926, 485: 1926, 1926, 1926, 492: 1926, 495: 1926, 504: 1926, 1926, 508: 1926, 530: 1926, 564: 1926, 567: 1926, 1926, 570: 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 582: 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 592: 1926, 1926, 595: 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 1926, 648: 1926}, - {2: 1925, 1925, 1925, 1925, 1925, 1925, 1925, 10: 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 50: 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 473: 1925, 475: 1925, 1925, 1925, 479: 1925, 482: 1925, 1925, 485: 1925, 1925, 1925, 492: 1925, 495: 1925, 504: 1925, 1925, 508: 1925, 530: 1925, 564: 1925, 567: 1925, 1925, 570: 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 582: 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 592: 1925, 1925, 595: 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 648: 1925}, - {2: 1924, 1924, 1924, 1924, 1924, 1924, 1924, 10: 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 50: 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 473: 1924, 475: 1924, 1924, 1924, 479: 1924, 482: 1924, 1924, 485: 1924, 1924, 1924, 492: 1924, 495: 1924, 504: 1924, 1924, 508: 1924, 530: 1924, 564: 1924, 567: 1924, 1924, 570: 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 582: 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 592: 1924, 1924, 595: 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 648: 1924}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3347, 3253, 3334, 3252, 3249}, + {492: 3705}, + {492: 3693}, + {492: 3688}, + {492: 3683}, + {492: 3678}, // 810 - {49: 3352, 484: 3350, 594: 3351}, - {473: 1226}, - {748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 474: 748, 748, 748, 748, 748, 480: 748, 748, 748, 748, 748, 748, 748, 748, 489: 748, 748, 748, 493: 748, 748, 496: 748, 748, 748, 748, 748, 748, 748, 748, 506: 748, 748, 509: 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 531: 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 565: 748, 748, 594: 748}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3489, 661: 3491, 2762, 2763, 2761, 738: 3488, 872: 3487}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3486, 3253, 3334, 3252, 3249}, + {492: 3673}, + {492: 3668}, + {492: 3663}, + {492: 3650}, + {492: 3647}, // 815 - {146: 935, 489: 935, 500: 3354, 742: 935, 1265: 3353}, - {146: 3358, 489: 3359, 742: 938, 885: 3357}, - {10: 3355, 183: 3356}, - {146: 934, 489: 934, 742: 934}, - {146: 933, 489: 933, 742: 933}, + {492: 3644}, + {492: 3641}, + {492: 3638}, + {492: 3635}, + {492: 3631}, // 820 - {742: 3362, 747: 3363}, - {273: 3361}, - {273: 3360}, - {742: 936}, - {742: 937}, + {492: 3625}, + {492: 3612}, + {492: 3607}, + {492: 3602}, + {492: 3444}, // 825 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 3401, 661: 3400, 2762, 2763, 2761, 923: 3403, 1162: 3404, 1350: 3402}, - {944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 474: 944, 944, 944, 944, 944, 480: 944, 944, 944, 944, 944, 944, 944, 944, 489: 944, 944, 944, 493: 944, 944, 496: 944, 944, 944, 944, 944, 944, 944, 944, 506: 944, 944, 509: 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 531: 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 565: 944, 944, 594: 944}, - {1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 665: 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832}, - {1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 665: 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826, 1826}, - {1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 665: 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815}, + {790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 493: 790, 790, 790, 497: 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 508: 790, 790, 511: 790, 790, 790, 516: 790, 790, 790, 790, 790, 790, 523: 790, 790, 526: 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 550: 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 584: 790, 790, 790, 616: 790}, + {789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 493: 789, 789, 789, 497: 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 508: 789, 789, 511: 789, 789, 789, 516: 789, 789, 789, 789, 789, 789, 523: 789, 789, 526: 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 550: 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 584: 789, 789, 789, 616: 789}, + {788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 493: 788, 788, 788, 497: 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 508: 788, 788, 511: 788, 788, 788, 516: 788, 788, 788, 788, 788, 788, 523: 788, 788, 526: 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 550: 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 584: 788, 788, 788, 616: 788}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3445}, + {9: 3453, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 830 - {1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 665: 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804}, - {1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 665: 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793, 1793}, - {1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 665: 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791}, - {1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 665: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768}, - {1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 665: 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762, 1762}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3601}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3600}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3599}, + {2: 1988, 1988, 1988, 1988, 1988, 1988, 1988, 10: 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 59: 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 492: 1988, 1988, 495: 1988, 1988, 1988, 502: 1988, 1988, 1988, 1988, 1988, 510: 1988, 514: 1988, 1988, 522: 1988, 525: 1988, 549: 1988, 583: 1988, 587: 1988, 589: 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 601: 1988, 1988, 1988, 1988, 1988, 1988, 608: 1988, 1988, 1988, 1988, 1988, 614: 1988, 1988, 617: 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 669: 1988}, + {2: 1987, 1987, 1987, 1987, 1987, 1987, 1987, 10: 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 59: 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 492: 1987, 1987, 495: 1987, 1987, 1987, 502: 1987, 1987, 1987, 1987, 1987, 510: 1987, 514: 1987, 1987, 522: 1987, 525: 1987, 549: 1987, 583: 1987, 587: 1987, 589: 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 601: 1987, 1987, 1987, 1987, 1987, 1987, 608: 1987, 1987, 1987, 1987, 1987, 614: 1987, 1987, 617: 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 669: 1987}, // 835 - {1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 665: 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752}, - {1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 665: 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727, 1727}, - {1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 665: 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726, 1726}, - {1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 665: 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723}, - {1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 665: 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718}, + {2: 1986, 1986, 1986, 1986, 1986, 1986, 1986, 10: 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 59: 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 492: 1986, 1986, 495: 1986, 1986, 1986, 502: 1986, 1986, 1986, 1986, 1986, 510: 1986, 514: 1986, 1986, 522: 1986, 525: 1986, 549: 1986, 583: 1986, 587: 1986, 589: 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 601: 1986, 1986, 1986, 1986, 1986, 1986, 608: 1986, 1986, 1986, 1986, 1986, 614: 1986, 1986, 617: 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 669: 1986}, + {2: 1985, 1985, 1985, 1985, 1985, 1985, 1985, 10: 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 59: 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 492: 1985, 1985, 495: 1985, 1985, 1985, 502: 1985, 1985, 1985, 1985, 1985, 510: 1985, 514: 1985, 1985, 522: 1985, 525: 1985, 549: 1985, 583: 1985, 587: 1985, 589: 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 601: 1985, 1985, 1985, 1985, 1985, 1985, 608: 1985, 1985, 1985, 1985, 1985, 614: 1985, 1985, 617: 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 669: 1985}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3454, 3360, 3441, 3359, 3356}, + {58: 3459, 499: 3457, 616: 3458}, + {492: 1265}, // 840 - {1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 665: 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716}, - {1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 665: 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715, 1715}, - {1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 665: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712}, - {1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 665: 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710}, - {1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 665: 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697}, + {787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 493: 787, 787, 787, 497: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 508: 787, 787, 511: 787, 787, 787, 516: 787, 787, 787, 787, 787, 787, 523: 787, 787, 526: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 550: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 584: 787, 787, 787, 616: 787}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3596, 685: 3598, 2850, 688: 2851, 2849, 760: 3595, 895: 3594}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3593, 3360, 3441, 3359, 3356}, + {160: 974, 508: 974, 520: 3461, 764: 974, 1299: 3460}, + {160: 3465, 508: 3466, 764: 977, 908: 3464}, // 845 - {1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 665: 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674}, - {1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 665: 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657}, - {1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 665: 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656}, - {1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 665: 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655}, - {1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 665: 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651}, + {10: 3462, 196: 3463}, + {160: 973, 508: 973, 764: 973}, + {160: 972, 508: 972, 764: 972}, + {764: 3469, 769: 3470}, + {288: 3468}, // 850 - {1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 665: 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650}, - {1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 665: 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644}, - {1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 665: 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535, 1535}, - {1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 665: 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534, 1534}, - {1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 665: 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533}, + {288: 3467}, + {764: 975}, + {764: 976}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 3508, 685: 3507, 2850, 688: 2851, 2849, 948: 3510, 1195: 3511, 1385: 3509}, + {983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 493: 983, 983, 983, 497: 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 508: 983, 983, 511: 983, 983, 983, 516: 983, 983, 983, 983, 983, 983, 523: 983, 983, 526: 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 550: 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 584: 983, 983, 983, 616: 983}, // 855 - {1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 665: 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532, 1532}, - {1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 665: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446}, - {1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 665: 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431, 1431}, - {1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 665: 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413}, - {1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 665: 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401}, + {1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 687: 1892, 690: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892}, + {1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 687: 1886, 690: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886}, + {1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 687: 1874, 690: 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874}, + {1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 687: 1863, 690: 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863}, + {1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 687: 1852, 690: 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852}, // 860 - {1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 665: 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400}, - {1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 665: 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380}, - {1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 665: 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1379}, - {986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 474: 986, 986, 986, 986, 986, 480: 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 493: 986, 986, 496: 986, 986, 986, 986, 986, 986, 986, 986, 506: 986, 986, 509: 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 531: 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 565: 986, 986, 594: 986}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 983, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 488: 983, 502: 983, 524: 983, 527: 983, 983, 661: 3400, 2762, 2763, 2761, 923: 3407, 1264: 3406, 1351: 3405}, + {1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 687: 1850, 690: 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850}, + {1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 687: 1827, 690: 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827}, + {1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 687: 1821, 690: 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821, 1821}, + {1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 687: 1811, 690: 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811}, + {1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 687: 1784, 690: 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784}, // 865 - {957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 474: 957, 957, 957, 957, 957, 480: 957, 957, 957, 957, 957, 957, 957, 957, 489: 957, 957, 957, 493: 957, 957, 496: 957, 957, 957, 957, 957, 957, 957, 957, 506: 957, 957, 509: 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 531: 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 565: 957, 957, 594: 957}, - {956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 474: 956, 956, 956, 956, 956, 480: 956, 956, 956, 956, 956, 956, 956, 956, 489: 956, 956, 956, 493: 956, 956, 496: 956, 956, 956, 956, 956, 956, 956, 956, 506: 956, 956, 509: 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 531: 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, 565: 956, 956, 594: 956}, - {955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 474: 955, 955, 955, 955, 955, 480: 955, 955, 955, 955, 955, 955, 955, 955, 489: 955, 955, 955, 493: 955, 955, 496: 955, 955, 955, 955, 955, 955, 955, 955, 506: 955, 955, 509: 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 531: 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 565: 955, 955, 594: 955}, - {49: 3485}, - {49: 981, 488: 3409, 502: 981, 524: 981, 527: 981, 981, 1268: 3408}, + {1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 687: 1783, 690: 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783}, + {1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 687: 1780, 690: 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780}, + {1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 687: 1775, 690: 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775}, + {1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 687: 1773, 690: 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773}, + {1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 687: 1772, 690: 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772}, // 870 - {49: 982, 488: 982, 502: 982, 524: 982, 527: 982, 982}, - {49: 979, 502: 3415, 524: 979, 527: 979, 979, 1271: 3414}, - {660: 3410}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 2754, 871: 3241, 900: 3411}, - {9: 3412, 49: 980, 502: 980, 524: 980, 527: 980, 980}, + {1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 687: 1769, 690: 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769}, + {1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 687: 1767, 690: 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767}, + {1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 687: 1754, 690: 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754}, + {1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 687: 1731, 690: 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731, 1731}, + {1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 687: 1714, 690: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714}, // 875 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 2754, 871: 3413}, - {1305, 1305, 9: 1305, 49: 1305, 127: 1305, 472: 1305, 474: 1305, 480: 1305, 1305, 490: 1305, 1305, 493: 1305, 1305, 496: 1305, 1305, 501: 1305, 1305, 514: 1305, 516: 1305, 524: 1305, 527: 1305, 1305}, - {49: 977, 524: 3420, 527: 3421, 3422, 1270: 3418, 1349: 3419}, - {660: 3416}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 2754, 871: 3241, 900: 3417}, + {1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 687: 1713, 690: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713}, + {1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 687: 1712, 690: 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712}, + {1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 687: 1708, 690: 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708, 1708}, + {1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 687: 1707, 690: 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707}, + {1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 687: 1701, 690: 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1701}, // 880 - {9: 3412, 49: 978, 524: 978, 527: 978, 978}, - {49: 984}, - {148: 3433, 169: 3429, 508: 3423, 563: 3434, 573: 3425, 3424, 577: 3431, 3432, 820: 3430, 979: 3427, 1347: 3428, 3426}, - {148: 975, 169: 975, 508: 975, 563: 975, 573: 975, 975, 577: 975, 975}, - {148: 974, 169: 974, 508: 974, 563: 974, 573: 974, 974, 577: 974, 974}, + {1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 687: 1591, 690: 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591, 1591}, + {1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 687: 1590, 690: 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590, 1590}, + {1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 687: 1589, 690: 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589}, + {1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 687: 1588, 690: 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588}, + {1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 687: 1493, 690: 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493}, // 885 - {148: 973, 169: 973, 508: 973, 563: 973, 573: 973, 973, 577: 973, 973}, - {2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 2222, 49: 2222, 132: 2222, 150: 2222, 472: 2222, 2222, 2222, 476: 2222, 2222, 2222, 2222, 2222, 484: 2222, 488: 2222, 2222, 492: 2222, 495: 2222, 503: 2222, 2222, 2222, 569: 2222, 581: 2222, 590: 2222, 2222, 642: 2222, 2222, 2222, 2222, 2222, 2222, 649: 2222}, - {2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 2221, 49: 2221, 132: 2221, 150: 2221, 195: 2221, 472: 2221, 2221, 2221, 476: 2221, 2221, 2221, 2221, 2221, 484: 2221, 488: 2221, 2221, 492: 2221, 495: 2221, 503: 2221, 2221, 2221, 569: 2221, 581: 2221, 590: 2221, 2221, 642: 2221, 2221, 2221, 2221, 2221, 2221, 649: 2221}, - {2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 2220, 49: 2220, 132: 2220, 150: 2220, 195: 2220, 472: 2220, 2220, 2220, 476: 2220, 2220, 2220, 2220, 2220, 484: 2220, 488: 2220, 2220, 492: 2220, 495: 2220, 503: 2220, 2220, 2220, 569: 2220, 581: 2220, 590: 2220, 2220, 642: 2220, 2220, 2220, 2220, 2220, 2220, 649: 2220}, - {49: 976}, + {1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 687: 1477, 690: 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477}, + {1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 687: 1459, 690: 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459}, + {1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 687: 1447, 690: 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447}, + {1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 687: 1446, 690: 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1446}, + {1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 687: 1426, 690: 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426}, // 890 - {49: 972}, - {49: 971}, - {132: 3480}, - {132: 3478}, - {132: 3476}, + {1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 687: 1425, 690: 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425}, + {1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 493: 1025, 1025, 1025, 497: 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 511: 1025, 1025, 1025, 516: 1025, 1025, 1025, 1025, 1025, 1025, 523: 1025, 1025, 526: 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 550: 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 584: 1025, 1025, 1025, 616: 1025}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1022, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 507: 1022, 523: 1022, 543: 1022, 546: 1022, 1022, 685: 3507, 2850, 688: 2851, 2849, 948: 3514, 1298: 3513, 1386: 3512}, + {996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 493: 996, 996, 996, 497: 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 508: 996, 996, 511: 996, 996, 996, 516: 996, 996, 996, 996, 996, 996, 523: 996, 996, 526: 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 550: 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 996, 584: 996, 996, 996, 616: 996}, + {995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 493: 995, 995, 995, 497: 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 508: 995, 995, 511: 995, 995, 995, 516: 995, 995, 995, 995, 995, 995, 523: 995, 995, 526: 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 550: 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 584: 995, 995, 995, 616: 995}, // 895 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3483}, - {575: 3482}, - {148: 3433, 169: 3435, 508: 3423, 573: 3425, 3424, 577: 3437, 3438, 820: 3436, 979: 3440, 1161: 3439}, - {132: 3480, 150: 3481}, - {132: 3478, 150: 3479}, + {994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 493: 994, 994, 994, 497: 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 508: 994, 994, 511: 994, 994, 994, 516: 994, 994, 994, 994, 994, 994, 523: 994, 994, 526: 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 550: 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 994, 584: 994, 994, 994, 616: 994}, + {58: 3592}, + {58: 1020, 507: 3516, 523: 1020, 543: 1020, 546: 1020, 1020, 1302: 3515}, + {58: 1021, 507: 1021, 523: 1021, 543: 1021, 546: 1021, 1021}, + {58: 1018, 523: 3522, 543: 1018, 546: 1018, 1018, 1305: 3521}, // 900 - {132: 3476, 150: 3477}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3443}, - {507: 3441}, - {49: 964, 507: 964}, - {148: 3433, 169: 3435, 508: 3423, 573: 3425, 3424, 577: 3437, 3438, 820: 3436, 979: 3440, 1161: 3442}, + {681: 3517}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 2842, 894: 3348, 925: 3518}, + {9: 3519, 58: 1019, 523: 1019, 543: 1019, 546: 1019, 1019}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 2842, 894: 3520}, + {1346, 1346, 9: 1346, 58: 1346, 139: 1346, 491: 1346, 494: 1346, 500: 1346, 1346, 509: 1346, 511: 1346, 1346, 1346, 516: 1346, 518: 1346, 521: 1346, 523: 1346, 533: 1346, 535: 1346, 543: 1346, 546: 1346, 1346}, // 905 - {49: 965}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 3473}, - {1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 480: 1109, 1109, 1109, 1109, 485: 1109, 1109, 1109, 489: 1109, 1109, 1109, 493: 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 506: 1109, 1109, 509: 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 531: 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 565: 1109, 1109, 569: 1109, 646: 1109}, - {1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 480: 1108, 1108, 1108, 1108, 485: 1108, 1108, 1108, 489: 1108, 1108, 1108, 493: 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 506: 1108, 1108, 509: 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 531: 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 565: 1108, 1108, 569: 1108, 646: 1108}, - {1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 480: 1107, 1107, 1107, 1107, 485: 1107, 1107, 1107, 489: 1107, 1107, 1107, 493: 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 506: 1107, 1107, 509: 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 531: 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 565: 1107, 1107, 569: 1107, 646: 1107}, + {58: 1016, 543: 3527, 546: 3528, 3529, 1304: 3525, 1384: 3526}, + {681: 3523}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 2842, 894: 3348, 925: 3524}, + {9: 3519, 58: 1017, 543: 1017, 546: 1017, 1017}, + {58: 1023}, // 910 - {1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 480: 1106, 1106, 1106, 1106, 485: 1106, 1106, 1106, 489: 1106, 1106, 1106, 493: 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 506: 1106, 1106, 509: 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 531: 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 565: 1106, 1106, 569: 1106, 646: 1106}, - {1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 480: 1105, 1105, 1105, 1105, 485: 1105, 1105, 1105, 489: 1105, 1105, 1105, 493: 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 506: 1105, 1105, 509: 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 531: 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 565: 1105, 1105, 569: 1105, 646: 1105}, - {1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 480: 1104, 1104, 1104, 1104, 485: 1104, 1104, 1104, 489: 1104, 1104, 1104, 493: 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 506: 1104, 1104, 509: 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 531: 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 565: 1104, 1104, 569: 1104, 646: 1104}, - {1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 480: 1103, 1103, 1103, 1103, 485: 1103, 1103, 1103, 489: 1103, 1103, 1103, 493: 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 506: 1103, 1103, 509: 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 531: 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 565: 1103, 1103, 569: 1103, 646: 1103}, - {1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 480: 1102, 1102, 1102, 1102, 485: 1102, 1102, 1102, 489: 1102, 1102, 1102, 493: 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 506: 1102, 1102, 509: 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 531: 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 565: 1102, 1102, 569: 1102, 646: 1102}, + {162: 3540, 171: 3536, 525: 3530, 582: 3541, 593: 3532, 3531, 597: 3538, 599: 3539, 842: 3537, 1004: 3534, 1382: 3535, 3533}, + {162: 1014, 171: 1014, 525: 1014, 582: 1014, 593: 1014, 1014, 597: 1014, 599: 1014}, + {162: 1013, 171: 1013, 525: 1013, 582: 1013, 593: 1013, 1013, 597: 1013, 599: 1013}, + {162: 1012, 171: 1012, 525: 1012, 582: 1012, 593: 1012, 1012, 597: 1012, 599: 1012}, + {2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 58: 2285, 147: 2285, 164: 2285, 491: 2285, 2285, 494: 2285, 2285, 2285, 2285, 2285, 2285, 2285, 507: 2285, 2285, 510: 2285, 514: 2285, 2285, 522: 2285, 524: 2285, 588: 2285, 600: 2285, 607: 2285, 613: 2285, 662: 2285, 2285, 2285, 2285, 2285, 2285, 2285}, // 915 - {1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 480: 1101, 1101, 1101, 1101, 485: 1101, 1101, 1101, 489: 1101, 1101, 1101, 493: 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 506: 1101, 1101, 509: 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 531: 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 565: 1101, 1101, 569: 1101, 646: 1101}, - {1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 480: 1100, 1100, 1100, 1100, 485: 1100, 1100, 1100, 489: 1100, 1100, 1100, 493: 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 506: 1100, 1100, 509: 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 531: 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 565: 1100, 1100, 569: 1100, 646: 1100}, - {1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 480: 1099, 1099, 1099, 1099, 485: 1099, 1099, 1099, 489: 1099, 1099, 1099, 493: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 506: 1099, 1099, 509: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 531: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 565: 1099, 1099, 569: 1099, 646: 1099}, - {1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 480: 1098, 1098, 1098, 1098, 485: 1098, 1098, 1098, 489: 1098, 1098, 1098, 493: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 506: 1098, 1098, 509: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 531: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 565: 1098, 1098, 569: 1098, 646: 1098}, - {1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 480: 1097, 1097, 1097, 1097, 485: 1097, 1097, 1097, 489: 1097, 1097, 1097, 493: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 506: 1097, 1097, 509: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 531: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 565: 1097, 1097, 569: 1097, 646: 1097}, + {2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 58: 2284, 147: 2284, 164: 2284, 209: 2284, 491: 2284, 2284, 494: 2284, 2284, 2284, 2284, 2284, 2284, 2284, 507: 2284, 2284, 510: 2284, 514: 2284, 2284, 522: 2284, 524: 2284, 588: 2284, 600: 2284, 607: 2284, 613: 2284, 662: 2284, 2284, 2284, 2284, 2284, 2284, 2284}, + {2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 58: 2283, 147: 2283, 164: 2283, 209: 2283, 491: 2283, 2283, 494: 2283, 2283, 2283, 2283, 2283, 2283, 2283, 507: 2283, 2283, 510: 2283, 514: 2283, 2283, 522: 2283, 524: 2283, 588: 2283, 600: 2283, 607: 2283, 613: 2283, 662: 2283, 2283, 2283, 2283, 2283, 2283, 2283}, + {58: 1015}, + {58: 1011}, + {58: 1010}, // 920 - {1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 480: 1096, 1096, 1096, 1096, 485: 1096, 1096, 1096, 489: 1096, 1096, 1096, 493: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 506: 1096, 1096, 509: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 531: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 565: 1096, 1096, 569: 1096, 646: 1096}, - {1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 480: 1095, 1095, 1095, 1095, 485: 1095, 1095, 1095, 489: 1095, 1095, 1095, 493: 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 506: 1095, 1095, 509: 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 531: 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 565: 1095, 1095, 569: 1095, 646: 1095}, - {1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 480: 1094, 1094, 1094, 1094, 485: 1094, 1094, 1094, 489: 1094, 1094, 1094, 493: 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 506: 1094, 1094, 509: 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 531: 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 565: 1094, 1094, 569: 1094, 646: 1094}, - {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 480: 1093, 1093, 1093, 1093, 485: 1093, 1093, 1093, 489: 1093, 1093, 1093, 493: 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 506: 1093, 1093, 509: 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 531: 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 565: 1093, 1093, 569: 1093, 646: 1093}, - {1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 480: 1092, 1092, 1092, 1092, 485: 1092, 1092, 1092, 489: 1092, 1092, 1092, 493: 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 506: 1092, 1092, 509: 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 531: 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 1092, 565: 1092, 1092, 569: 1092, 646: 1092}, + {147: 3587}, + {147: 3585}, + {147: 3583}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3590}, + {595: 3589}, // 925 - {1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 480: 1091, 1091, 1091, 1091, 485: 1091, 1091, 1091, 489: 1091, 1091, 1091, 493: 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 506: 1091, 1091, 509: 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 531: 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 565: 1091, 1091, 569: 1091, 646: 1091}, - {1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 480: 1090, 1090, 1090, 1090, 485: 1090, 1090, 1090, 489: 1090, 1090, 1090, 493: 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 506: 1090, 1090, 509: 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 531: 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 565: 1090, 1090, 569: 1090, 646: 1090}, - {1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 480: 1089, 1089, 1089, 1089, 485: 1089, 1089, 1089, 489: 1089, 1089, 1089, 493: 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 506: 1089, 1089, 509: 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 531: 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 565: 1089, 1089, 569: 1089, 646: 1089}, - {1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 480: 1088, 1088, 1088, 1088, 485: 1088, 1088, 1088, 489: 1088, 1088, 1088, 493: 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 506: 1088, 1088, 509: 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 531: 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 565: 1088, 1088, 569: 1088, 646: 1088}, - {1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 480: 1087, 1087, 1087, 1087, 485: 1087, 1087, 1087, 489: 1087, 1087, 1087, 493: 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 506: 1087, 1087, 509: 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 531: 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 565: 1087, 1087, 569: 1087, 646: 1087}, + {162: 3540, 171: 3542, 525: 3530, 593: 3532, 3531, 597: 3544, 599: 3545, 842: 3543, 1004: 3547, 1194: 3546}, + {147: 3587, 164: 3588}, + {147: 3585, 164: 3586}, + {147: 3583, 164: 3584}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3550}, // 930 - {1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 480: 1086, 1086, 1086, 1086, 485: 1086, 1086, 1086, 489: 1086, 1086, 1086, 493: 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 506: 1086, 1086, 509: 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 531: 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 565: 1086, 1086, 569: 1086, 646: 1086}, - {1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 480: 1085, 1085, 1085, 1085, 485: 1085, 1085, 1085, 489: 1085, 1085, 1085, 493: 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 506: 1085, 1085, 509: 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 531: 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 565: 1085, 1085, 569: 1085, 646: 1085}, - {1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 480: 1084, 1084, 1084, 1084, 485: 1084, 1084, 1084, 489: 1084, 1084, 1084, 493: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 506: 1084, 1084, 509: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 531: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 565: 1084, 1084, 569: 1084, 646: 1084}, - {1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 480: 1083, 1083, 1083, 1083, 485: 1083, 1083, 1083, 489: 1083, 1083, 1083, 493: 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 506: 1083, 1083, 509: 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 531: 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 565: 1083, 1083, 569: 1083, 646: 1083}, - {1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 480: 1082, 1082, 1082, 1082, 485: 1082, 1082, 1082, 489: 1082, 1082, 1082, 493: 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 506: 1082, 1082, 509: 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 531: 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 565: 1082, 1082, 569: 1082, 646: 1082}, + {527: 3548}, + {58: 1003, 527: 1003}, + {162: 3540, 171: 3542, 525: 3530, 593: 3532, 3531, 597: 3544, 599: 3545, 842: 3543, 1004: 3547, 1194: 3549}, + {58: 1004}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 3580}, // 935 - {1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 480: 1081, 1081, 1081, 1081, 485: 1081, 1081, 1081, 489: 1081, 1081, 1081, 493: 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 506: 1081, 1081, 509: 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 531: 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 565: 1081, 1081, 569: 1081, 646: 1081}, - {132: 3474, 150: 3475}, - {49: 967, 507: 967}, - {49: 960, 507: 960}, - {49: 968, 507: 968}, + {1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 511: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 526: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 550: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 584: 1148, 1148, 1148, 588: 1148, 665: 1148, 667: 1148, 1148}, + {1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 511: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 526: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 550: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 584: 1147, 1147, 1147, 588: 1147, 665: 1147, 667: 1147, 1147}, + {1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 511: 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 526: 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 550: 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 584: 1146, 1146, 1146, 588: 1146, 665: 1146, 667: 1146, 1146}, + {1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 511: 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 526: 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 550: 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 584: 1145, 1145, 1145, 588: 1145, 665: 1145, 667: 1145, 1145}, + {1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 511: 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 526: 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 550: 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 584: 1144, 1144, 1144, 588: 1144, 665: 1144, 667: 1144, 1144}, // 940 - {49: 961, 507: 961}, - {49: 969, 507: 969}, - {49: 962, 507: 962}, - {49: 970, 507: 970}, - {49: 963, 507: 963}, + {1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 511: 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 526: 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 550: 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 584: 1143, 1143, 1143, 588: 1143, 665: 1143, 667: 1143, 1143}, + {1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 511: 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 526: 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 550: 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 584: 1142, 1142, 1142, 588: 1142, 665: 1142, 667: 1142, 1142}, + {1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 511: 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 526: 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 550: 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 584: 1141, 1141, 1141, 588: 1141, 665: 1141, 667: 1141, 1141}, + {1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 511: 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 526: 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 550: 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 584: 1140, 1140, 1140, 588: 1140, 665: 1140, 667: 1140, 1140}, + {1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 511: 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 526: 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 550: 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 584: 1139, 1139, 1139, 588: 1139, 665: 1139, 667: 1139, 1139}, // 945 - {49: 966, 507: 966}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 3484}, - {132: 3474}, - {985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 474: 985, 985, 985, 985, 985, 480: 985, 985, 985, 985, 985, 985, 985, 985, 489: 985, 985, 985, 493: 985, 985, 496: 985, 985, 985, 985, 985, 985, 985, 985, 506: 985, 985, 509: 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 531: 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 565: 985, 985, 594: 985}, - {1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 474: 1262, 1262, 1262, 1262, 1262, 480: 1262, 1262, 1262, 1262, 3350, 1262, 1262, 1262, 489: 1262, 1262, 1262, 493: 1262, 1262, 496: 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 506: 1262, 1262, 509: 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 531: 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 565: 1262, 1262, 594: 1262}, + {1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 511: 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 526: 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 550: 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 584: 1138, 1138, 1138, 588: 1138, 665: 1138, 667: 1138, 1138}, + {1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 511: 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 526: 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 550: 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 584: 1137, 1137, 1137, 588: 1137, 665: 1137, 667: 1137, 1137}, + {1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 511: 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 526: 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 550: 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 584: 1136, 1136, 1136, 588: 1136, 665: 1136, 667: 1136, 1136}, + {1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 511: 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 526: 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 550: 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 584: 1135, 1135, 1135, 588: 1135, 665: 1135, 667: 1135, 1135}, + {1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 511: 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 526: 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 550: 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 584: 1134, 1134, 1134, 588: 1134, 665: 1134, 667: 1134, 1134}, // 950 - {1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 474: 1272, 1272, 1272, 1272, 1272, 480: 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 489: 1272, 1272, 1272, 493: 1272, 1272, 496: 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 506: 1272, 1272, 509: 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 531: 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 565: 1272, 1272, 594: 1272}, - {755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 509: 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 531: 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 565: 755, 755, 569: 755, 581: 755, 590: 755, 755, 594: 755, 642: 755, 755, 755, 755, 755, 755, 649: 755}, - {754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 509: 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 531: 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 565: 754, 754, 569: 754, 581: 754, 590: 754, 754, 594: 754, 642: 754, 754, 754, 754, 754, 754, 649: 754}, - {258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 509: 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 565: 258, 258, 568: 258, 258, 581: 258, 590: 258, 258, 594: 258, 642: 258, 258, 258, 258, 258, 258, 649: 258, 258, 653: 258, 658: 258, 660: 258, 666: 258, 258, 258}, - {257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 509: 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 565: 257, 257, 568: 257, 257, 581: 257, 590: 257, 257, 594: 257, 642: 257, 257, 257, 257, 257, 257, 649: 257, 257, 653: 257, 658: 257, 660: 257, 666: 257, 257, 257}, + {1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 511: 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 526: 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 550: 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 584: 1133, 1133, 1133, 588: 1133, 665: 1133, 667: 1133, 1133}, + {1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 511: 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 526: 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 550: 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 584: 1132, 1132, 1132, 588: 1132, 665: 1132, 667: 1132, 1132}, + {1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 511: 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 526: 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 550: 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 584: 1131, 1131, 1131, 588: 1131, 665: 1131, 667: 1131, 1131}, + {1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 511: 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 526: 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 550: 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 584: 1130, 1130, 1130, 588: 1130, 665: 1130, 667: 1130, 1130}, + {1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 511: 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 526: 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 550: 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 584: 1129, 1129, 1129, 588: 1129, 665: 1129, 667: 1129, 1129}, // 955 - {1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 474: 1941, 1941, 478: 1941, 480: 1941, 1941, 1941, 1941, 489: 1941, 1941, 1941, 493: 1941, 1941, 496: 1941, 1941, 1941, 500: 1941, 1941, 1941, 1941, 506: 1941, 1941, 509: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 519: 1941, 521: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 531: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 545: 1941, 1941, 734: 3341, 3339}, - {1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 474: 1942, 1942, 478: 1942, 480: 1942, 1942, 1942, 1942, 489: 1942, 1942, 1942, 493: 1942, 1942, 496: 1942, 1942, 1942, 500: 1942, 1942, 1942, 1942, 506: 1942, 3345, 509: 1942, 3344, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 519: 1942, 521: 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 531: 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 545: 1942, 1942, 734: 3341, 3339}, - {1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 474: 1943, 1943, 478: 1943, 480: 1943, 1943, 1943, 1943, 489: 1943, 1943, 1943, 493: 1943, 1943, 496: 1943, 1943, 1943, 500: 1943, 1943, 1943, 1943, 506: 1943, 3345, 509: 1943, 3344, 1943, 3340, 1943, 1943, 1943, 1943, 1943, 519: 1943, 521: 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 531: 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943, 545: 1943, 1943, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3496}, - {49: 3497, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 511: 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 526: 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 550: 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 584: 1128, 1128, 1128, 588: 1128, 665: 1128, 667: 1128, 1128}, + {1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 511: 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 526: 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 550: 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 584: 1127, 1127, 1127, 588: 1127, 665: 1127, 667: 1127, 1127}, + {1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 511: 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 526: 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 550: 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 584: 1126, 1126, 1126, 588: 1126, 665: 1126, 667: 1126, 1126}, + {1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 511: 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 526: 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 550: 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 584: 1125, 1125, 1125, 588: 1125, 665: 1125, 667: 1125, 1125}, + {1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 511: 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 526: 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 550: 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 584: 1124, 1124, 1124, 588: 1124, 665: 1124, 667: 1124, 1124}, // 960 - {146: 3358, 489: 3359, 742: 938, 885: 3498}, - {742: 3362, 747: 3499}, - {945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 474: 945, 945, 945, 945, 945, 480: 945, 945, 945, 945, 945, 945, 945, 945, 489: 945, 945, 945, 493: 945, 945, 496: 945, 945, 945, 945, 945, 945, 945, 945, 506: 945, 945, 509: 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 531: 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, 565: 945, 945, 594: 945}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3501}, - {49: 3502, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 511: 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 526: 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 550: 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 584: 1123, 1123, 1123, 588: 1123, 665: 1123, 667: 1123, 1123}, + {1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 511: 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 526: 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 550: 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 584: 1122, 1122, 1122, 588: 1122, 665: 1122, 667: 1122, 1122}, + {1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 511: 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 526: 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 550: 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 584: 1121, 1121, 1121, 588: 1121, 665: 1121, 667: 1121, 1121}, + {1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 511: 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 526: 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 550: 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 584: 1120, 1120, 1120, 588: 1120, 665: 1120, 667: 1120, 1120}, + {147: 3581, 164: 3582}, // 965 - {146: 3358, 489: 3359, 742: 938, 885: 3503}, - {742: 3362, 747: 3504}, - {946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 474: 946, 946, 946, 946, 946, 480: 946, 946, 946, 946, 946, 946, 946, 946, 489: 946, 946, 946, 493: 946, 946, 496: 946, 946, 946, 946, 946, 946, 946, 946, 506: 946, 946, 509: 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 531: 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 565: 946, 946, 594: 946}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3506}, - {9: 3508, 49: 943, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339, 1094: 3507}, + {58: 1006, 527: 1006}, + {58: 999, 527: 999}, + {58: 1007, 527: 1007}, + {58: 1000, 527: 1000}, + {58: 1008, 527: 1008}, // 970 - {49: 3515}, - {508: 3423, 573: 3425, 3424, 577: 3510, 820: 3509}, - {9: 3512, 49: 940, 1095: 3514}, - {9: 3512, 49: 940, 1095: 3511}, - {49: 941}, + {58: 1001, 527: 1001}, + {58: 1009, 527: 1009}, + {58: 1002, 527: 1002}, + {58: 1005, 527: 1005}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 3591}, // 975 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3513}, - {49: 939, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {49: 942}, - {146: 3358, 489: 3359, 742: 938, 885: 3516}, - {742: 3362, 747: 3517}, + {147: 3581}, + {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 493: 1024, 1024, 1024, 497: 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 508: 1024, 1024, 511: 1024, 1024, 1024, 516: 1024, 1024, 1024, 1024, 1024, 1024, 523: 1024, 1024, 526: 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 550: 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 584: 1024, 1024, 1024, 616: 1024}, + {1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 493: 1303, 1303, 1303, 497: 1303, 1303, 3457, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 508: 1303, 1303, 511: 1303, 1303, 1303, 516: 1303, 1303, 1303, 1303, 1303, 1303, 523: 1303, 1303, 526: 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 550: 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 584: 1303, 1303, 1303, 616: 1303}, + {1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 493: 1313, 1313, 1313, 497: 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 508: 1313, 1313, 511: 1313, 1313, 1313, 516: 1313, 1313, 1313, 1313, 1313, 1313, 523: 1313, 1313, 526: 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 550: 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 584: 1313, 1313, 1313, 616: 1313}, + {794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 526: 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 550: 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 584: 794, 794, 794, 588: 794, 600: 794, 607: 794, 613: 794, 616: 794, 662: 794, 794, 794, 794, 794, 794, 794}, // 980 - {947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 474: 947, 947, 947, 947, 947, 480: 947, 947, 947, 947, 947, 947, 947, 947, 489: 947, 947, 947, 493: 947, 947, 496: 947, 947, 947, 947, 947, 947, 947, 947, 506: 947, 947, 509: 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 531: 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, 565: 947, 947, 594: 947}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3519}, - {9: 3508, 49: 943, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339, 1094: 3520}, - {49: 3521}, - {146: 3358, 489: 3359, 742: 938, 885: 3522}, + {793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 526: 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 550: 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 584: 793, 793, 793, 588: 793, 600: 793, 607: 793, 613: 793, 616: 793, 662: 793, 793, 793, 793, 793, 793, 793}, + {286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 526: 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 584: 286, 286, 286, 588: 286, 286, 600: 286, 607: 286, 613: 286, 616: 286, 662: 286, 286, 286, 286, 286, 286, 286, 670: 286, 673: 286, 678: 286, 286, 681: 286, 683: 286, 286, 687: 286}, + {285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 526: 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 584: 285, 285, 285, 588: 285, 285, 600: 285, 607: 285, 613: 285, 616: 285, 662: 285, 285, 285, 285, 285, 285, 285, 670: 285, 673: 285, 678: 285, 285, 681: 285, 683: 285, 285, 687: 285}, + {2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 493: 2002, 2002, 498: 2002, 500: 2002, 2002, 2002, 2002, 508: 2002, 2002, 511: 2002, 2002, 2002, 516: 2002, 518: 2002, 2002, 2002, 2002, 523: 2002, 2002, 526: 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 538: 2002, 2002, 2002, 542: 2002, 2002, 2002, 2002, 2002, 2002, 2002, 550: 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 565: 2002, 756: 3448, 3446}, + {2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 493: 2003, 2003, 498: 2003, 500: 2003, 2003, 2003, 2003, 508: 2003, 2003, 511: 2003, 2003, 2003, 516: 2003, 518: 2003, 2003, 2003, 2003, 523: 2003, 2003, 526: 2003, 3452, 2003, 3451, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 538: 2003, 2003, 2003, 542: 2003, 2003, 2003, 2003, 2003, 2003, 2003, 550: 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 2003, 565: 2003, 756: 3448, 3446}, // 985 - {742: 3362, 747: 3523}, - {948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 474: 948, 948, 948, 948, 948, 480: 948, 948, 948, 948, 948, 948, 948, 948, 489: 948, 948, 948, 493: 948, 948, 496: 948, 948, 948, 948, 948, 948, 948, 948, 506: 948, 948, 509: 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 531: 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, 565: 948, 948, 594: 948}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3525, 3253, 3334, 3252, 3249}, - {49: 3526, 484: 3350, 594: 3351}, - {742: 3362, 747: 3527}, + {2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 493: 2004, 2004, 498: 2004, 500: 2004, 2004, 2004, 2004, 508: 2004, 2004, 511: 2004, 2004, 2004, 516: 2004, 518: 2004, 2004, 2004, 2004, 523: 2004, 2004, 526: 2004, 3452, 2004, 3451, 2004, 3447, 2004, 2004, 2004, 2004, 2004, 538: 2004, 2004, 2004, 542: 2004, 2004, 2004, 2004, 2004, 2004, 2004, 550: 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 2004, 565: 2004, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3603}, + {58: 3604, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {160: 3465, 508: 3466, 764: 977, 908: 3605}, + {764: 3469, 769: 3606}, // 990 - {949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 474: 949, 949, 949, 949, 949, 480: 949, 949, 949, 949, 949, 949, 949, 949, 489: 949, 949, 949, 493: 949, 949, 496: 949, 949, 949, 949, 949, 949, 949, 949, 506: 949, 949, 509: 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 531: 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 565: 949, 949, 594: 949}, - {49: 3529}, - {742: 3362, 747: 3530}, - {950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 474: 950, 950, 950, 950, 950, 480: 950, 950, 950, 950, 950, 950, 950, 950, 489: 950, 950, 950, 493: 950, 950, 496: 950, 950, 950, 950, 950, 950, 950, 950, 506: 950, 950, 509: 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 531: 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, 565: 950, 950, 594: 950}, - {49: 3532}, + {984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 493: 984, 984, 984, 497: 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 508: 984, 984, 511: 984, 984, 984, 516: 984, 984, 984, 984, 984, 984, 523: 984, 984, 526: 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 550: 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 584: 984, 984, 984, 616: 984}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3608}, + {58: 3609, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {160: 3465, 508: 3466, 764: 977, 908: 3610}, + {764: 3469, 769: 3611}, // 995 - {742: 3362, 747: 3533}, - {951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 474: 951, 951, 951, 951, 951, 480: 951, 951, 951, 951, 951, 951, 951, 951, 489: 951, 951, 951, 493: 951, 951, 496: 951, 951, 951, 951, 951, 951, 951, 951, 506: 951, 951, 509: 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 531: 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, 565: 951, 951, 594: 951}, - {49: 3535}, - {742: 3362, 747: 3536}, - {952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 474: 952, 952, 952, 952, 952, 480: 952, 952, 952, 952, 952, 952, 952, 952, 489: 952, 952, 952, 493: 952, 952, 496: 952, 952, 952, 952, 952, 952, 952, 952, 506: 952, 952, 509: 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 531: 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 565: 952, 952, 594: 952}, + {985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 493: 985, 985, 985, 497: 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 508: 985, 985, 511: 985, 985, 985, 516: 985, 985, 985, 985, 985, 985, 523: 985, 985, 526: 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 550: 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 584: 985, 985, 985, 616: 985}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3613}, + {9: 3615, 58: 982, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446, 1124: 3614}, + {58: 3622}, + {525: 3530, 593: 3532, 3531, 597: 3617, 842: 3616}, // 1000 - {49: 3538}, - {742: 3362, 747: 3539}, - {953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 474: 953, 953, 953, 953, 953, 480: 953, 953, 953, 953, 953, 953, 953, 953, 489: 953, 953, 953, 493: 953, 953, 496: 953, 953, 953, 953, 953, 953, 953, 953, 506: 953, 953, 509: 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 531: 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 565: 953, 953, 594: 953}, - {49: 3541}, - {742: 3362, 747: 3542}, + {9: 3619, 58: 979, 1125: 3621}, + {9: 3619, 58: 979, 1125: 3618}, + {58: 980}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3620}, + {58: 978, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1005 - {954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 474: 954, 954, 954, 954, 954, 480: 954, 954, 954, 954, 954, 954, 954, 954, 489: 954, 954, 954, 493: 954, 954, 496: 954, 954, 954, 954, 954, 954, 954, 954, 506: 954, 954, 509: 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 531: 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 565: 954, 954, 594: 954}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3550, 818: 3549}, - {2: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 10: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 50: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 473: 1245, 475: 1245, 1245, 1245, 479: 1245, 482: 1245, 1245, 485: 1245, 1245, 1245, 492: 1245, 495: 1245, 504: 1245, 1245, 508: 1245, 515: 1245, 520: 1245, 530: 1245, 564: 1245, 567: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 582: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 592: 1245, 1245, 595: 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 646: 1245, 648: 1245, 651: 1245, 745: 1245, 1245, 753: 1245, 1245, 1245, 762: 1245, 769: 1245, 1245, 1245}, - {2: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 10: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 50: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 473: 1244, 475: 1244, 1244, 1244, 479: 1244, 482: 1244, 1244, 485: 1244, 1244, 1244, 492: 1244, 495: 1244, 504: 1244, 1244, 508: 1244, 515: 1244, 520: 1244, 530: 1244, 564: 1244, 567: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 582: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 592: 1244, 1244, 595: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 646: 1244, 648: 1244, 651: 1244, 745: 1244, 1244, 753: 1244, 1244, 1244, 762: 1244, 769: 1244, 1244, 1244}, - {2: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 10: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 50: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 473: 1243, 475: 1243, 1243, 1243, 479: 1243, 482: 1243, 1243, 485: 1243, 1243, 1243, 492: 1243, 495: 1243, 504: 1243, 1243, 508: 1243, 515: 1243, 520: 1243, 530: 1243, 564: 1243, 567: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 582: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 592: 1243, 1243, 595: 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 646: 1243, 648: 1243, 651: 1243, 745: 1243, 1243, 753: 1243, 1243, 1243, 762: 1243, 769: 1243, 1243, 1243}, + {58: 981}, + {160: 3465, 508: 3466, 764: 977, 908: 3623}, + {764: 3469, 769: 3624}, + {986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 493: 986, 986, 986, 497: 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 508: 986, 986, 511: 986, 986, 986, 516: 986, 986, 986, 986, 986, 986, 523: 986, 986, 526: 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 550: 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 584: 986, 986, 986, 616: 986}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3626}, // 1010 - {2: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 10: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 50: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 473: 1242, 475: 1242, 1242, 1242, 479: 1242, 482: 1242, 1242, 485: 1242, 1242, 1242, 492: 1242, 495: 1242, 504: 1242, 1242, 508: 1242, 530: 1242, 564: 1242, 567: 1242, 1242, 570: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 582: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 592: 1242, 1242, 595: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 648: 1242, 651: 3555}, - {2: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 10: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 50: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 473: 1240, 475: 1240, 1240, 1240, 479: 1240, 482: 1240, 1240, 485: 1240, 1240, 1240, 492: 1240, 495: 1240, 504: 1240, 1240, 508: 1240, 530: 1240, 564: 1240, 567: 1240, 1240, 570: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 582: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 592: 1240, 1240, 595: 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 648: 1240}, - {2: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 10: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 50: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 473: 1237, 475: 1237, 1237, 1237, 479: 1237, 482: 1237, 1237, 485: 1237, 1237, 1237, 492: 1237, 495: 1237, 504: 1237, 1237, 508: 1237, 530: 1237, 564: 1237, 567: 1237, 1237, 570: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 582: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 592: 1237, 1237, 595: 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 648: 1237}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3551}, - {49: 3552, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {9: 3615, 58: 982, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446, 1124: 3627}, + {58: 3628}, + {160: 3465, 508: 3466, 764: 977, 908: 3629}, + {764: 3469, 769: 3630}, + {987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 493: 987, 987, 987, 497: 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 508: 987, 987, 511: 987, 987, 987, 516: 987, 987, 987, 987, 987, 987, 523: 987, 987, 526: 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 550: 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 584: 987, 987, 987, 616: 987}, // 1015 - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3553}, - {1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 474: 1123, 1123, 1123, 1123, 1123, 480: 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 489: 1123, 1123, 1123, 493: 1123, 1123, 496: 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 506: 1123, 1123, 509: 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 531: 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 565: 1123, 1123, 594: 1123}, - {958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 474: 958, 958, 958, 958, 958, 480: 958, 958, 958, 958, 958, 958, 958, 958, 489: 958, 958, 958, 493: 958, 958, 496: 958, 958, 958, 958, 958, 958, 958, 958, 506: 958, 958, 509: 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 531: 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 565: 958, 958, 594: 958}, - {2: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 10: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 50: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 473: 1236, 475: 1236, 1236, 1236, 479: 1236, 482: 1236, 1236, 485: 1236, 1236, 1236, 492: 1236, 495: 1236, 504: 1236, 1236, 508: 1236, 530: 1236, 564: 1236, 567: 1236, 1236, 570: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 582: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 592: 1236, 1236, 595: 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 648: 1236}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3557, 818: 3549}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3632, 3360, 3441, 3359, 3356}, + {58: 3633, 499: 3457, 616: 3458}, + {764: 3469, 769: 3634}, + {988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 493: 988, 988, 988, 497: 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 508: 988, 988, 511: 988, 988, 988, 516: 988, 988, 988, 988, 988, 988, 523: 988, 988, 526: 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 550: 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 988, 584: 988, 988, 988, 616: 988}, + {58: 3636}, // 1020 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3558}, - {49: 3559, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3560}, - {1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 474: 1124, 1124, 1124, 1124, 1124, 480: 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 489: 1124, 1124, 1124, 493: 1124, 1124, 496: 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 506: 1124, 1124, 509: 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 531: 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 565: 1124, 1124, 594: 1124}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3562, 818: 3549}, + {764: 3469, 769: 3637}, + {989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 493: 989, 989, 989, 497: 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 508: 989, 989, 511: 989, 989, 989, 516: 989, 989, 989, 989, 989, 989, 523: 989, 989, 526: 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 550: 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 989, 584: 989, 989, 989, 616: 989}, + {58: 3639}, + {764: 3469, 769: 3640}, + {990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 493: 990, 990, 990, 497: 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 508: 990, 990, 511: 990, 990, 990, 516: 990, 990, 990, 990, 990, 990, 523: 990, 990, 526: 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 550: 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 584: 990, 990, 990, 616: 990}, // 1025 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3563}, - {49: 3564, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3565}, - {1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 474: 1125, 1125, 1125, 1125, 1125, 480: 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 489: 1125, 1125, 1125, 493: 1125, 1125, 496: 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 506: 1125, 1125, 509: 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 531: 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 565: 1125, 1125, 594: 1125}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3567, 818: 3549}, + {58: 3642}, + {764: 3469, 769: 3643}, + {991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 493: 991, 991, 991, 497: 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 508: 991, 991, 511: 991, 991, 991, 516: 991, 991, 991, 991, 991, 991, 523: 991, 991, 526: 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 550: 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, 584: 991, 991, 991, 616: 991}, + {58: 3645}, + {764: 3469, 769: 3646}, // 1030 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3568}, - {49: 3569, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3570}, - {1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 474: 1126, 1126, 1126, 1126, 1126, 480: 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 489: 1126, 1126, 1126, 493: 1126, 1126, 496: 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 506: 1126, 1126, 509: 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 531: 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 565: 1126, 1126, 594: 1126}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3572, 818: 3549}, + {992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 493: 992, 992, 992, 497: 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 508: 992, 992, 511: 992, 992, 992, 516: 992, 992, 992, 992, 992, 992, 523: 992, 992, 526: 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 550: 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, 584: 992, 992, 992, 616: 992}, + {58: 3648}, + {764: 3469, 769: 3649}, + {993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 493: 993, 993, 993, 497: 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 508: 993, 993, 511: 993, 993, 993, 516: 993, 993, 993, 993, 993, 993, 523: 993, 993, 526: 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 550: 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 584: 993, 993, 993, 616: 993}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3657, 3656}, // 1035 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3573}, - {49: 3574, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3575}, - {1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 474: 1127, 1127, 1127, 1127, 1127, 480: 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 489: 1127, 1127, 1127, 493: 1127, 1127, 496: 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 506: 1127, 1127, 509: 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 531: 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 565: 1127, 1127, 594: 1127}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3577, 818: 3549}, + {2: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 10: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 59: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 492: 1284, 1284, 495: 1284, 1284, 1284, 502: 1284, 1284, 1284, 1284, 1284, 510: 1284, 514: 1284, 1284, 522: 1284, 525: 1284, 534: 1284, 541: 1284, 549: 1284, 583: 1284, 587: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 601: 1284, 1284, 1284, 1284, 1284, 1284, 608: 1284, 1284, 1284, 1284, 1284, 614: 1284, 1284, 617: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 665: 1284, 669: 1284, 671: 1284, 767: 1284, 1284, 775: 1284, 1284, 1284, 785: 1284, 792: 1284, 1284, 1284}, + {2: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 10: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 59: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 492: 1283, 1283, 495: 1283, 1283, 1283, 502: 1283, 1283, 1283, 1283, 1283, 510: 1283, 514: 1283, 1283, 522: 1283, 525: 1283, 534: 1283, 541: 1283, 549: 1283, 583: 1283, 587: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 601: 1283, 1283, 1283, 1283, 1283, 1283, 608: 1283, 1283, 1283, 1283, 1283, 614: 1283, 1283, 617: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 665: 1283, 669: 1283, 671: 1283, 767: 1283, 1283, 775: 1283, 1283, 1283, 785: 1283, 792: 1283, 1283, 1283}, + {2: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 10: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 59: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 492: 1282, 1282, 495: 1282, 1282, 1282, 502: 1282, 1282, 1282, 1282, 1282, 510: 1282, 514: 1282, 1282, 522: 1282, 525: 1282, 534: 1282, 541: 1282, 549: 1282, 583: 1282, 587: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 601: 1282, 1282, 1282, 1282, 1282, 1282, 608: 1282, 1282, 1282, 1282, 1282, 614: 1282, 1282, 617: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 665: 1282, 669: 1282, 671: 1282, 767: 1282, 1282, 775: 1282, 1282, 1282, 785: 1282, 792: 1282, 1282, 1282}, + {2: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 10: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 59: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 492: 1281, 1281, 495: 1281, 1281, 1281, 502: 1281, 1281, 1281, 1281, 1281, 510: 1281, 514: 1281, 1281, 522: 1281, 525: 1281, 549: 1281, 583: 1281, 587: 1281, 589: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 601: 1281, 1281, 1281, 1281, 1281, 1281, 608: 1281, 1281, 1281, 1281, 1281, 614: 1281, 1281, 617: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 669: 1281, 671: 3662}, + {2: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 10: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 59: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 492: 1279, 1279, 495: 1279, 1279, 1279, 502: 1279, 1279, 1279, 1279, 1279, 510: 1279, 514: 1279, 1279, 522: 1279, 525: 1279, 549: 1279, 583: 1279, 587: 1279, 589: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 601: 1279, 1279, 1279, 1279, 1279, 1279, 608: 1279, 1279, 1279, 1279, 1279, 614: 1279, 1279, 617: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 669: 1279}, // 1040 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3578}, - {49: 3579, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3580}, - {1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 474: 1128, 1128, 1128, 1128, 1128, 480: 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 489: 1128, 1128, 1128, 493: 1128, 1128, 496: 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 506: 1128, 1128, 509: 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 531: 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 565: 1128, 1128, 594: 1128}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3582, 818: 3549}, + {2: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 10: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 59: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 492: 1276, 1276, 495: 1276, 1276, 1276, 502: 1276, 1276, 1276, 1276, 1276, 510: 1276, 514: 1276, 1276, 522: 1276, 525: 1276, 549: 1276, 583: 1276, 587: 1276, 589: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 601: 1276, 1276, 1276, 1276, 1276, 1276, 608: 1276, 1276, 1276, 1276, 1276, 614: 1276, 1276, 617: 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 669: 1276}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3658}, + {58: 3659, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3660}, + {1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 493: 1162, 1162, 1162, 497: 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 508: 1162, 1162, 511: 1162, 1162, 1162, 516: 1162, 1162, 1162, 1162, 1162, 1162, 523: 1162, 1162, 526: 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 550: 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 584: 1162, 1162, 1162, 616: 1162}, // 1045 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3583}, - {49: 3584, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3585}, - {1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 474: 1129, 1129, 1129, 1129, 1129, 480: 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 489: 1129, 1129, 1129, 493: 1129, 1129, 496: 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 506: 1129, 1129, 509: 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 531: 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 565: 1129, 1129, 594: 1129}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 3587, 818: 3549}, + {997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 493: 997, 997, 997, 497: 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 508: 997, 997, 511: 997, 997, 997, 516: 997, 997, 997, 997, 997, 997, 523: 997, 997, 526: 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 550: 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 584: 997, 997, 997, 616: 997}, + {2: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 10: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 59: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 492: 1275, 1275, 495: 1275, 1275, 1275, 502: 1275, 1275, 1275, 1275, 1275, 510: 1275, 514: 1275, 1275, 522: 1275, 525: 1275, 549: 1275, 583: 1275, 587: 1275, 589: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 601: 1275, 1275, 1275, 1275, 1275, 1275, 608: 1275, 1275, 1275, 1275, 1275, 614: 1275, 1275, 617: 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 669: 1275}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3664, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3665}, + {58: 3666, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1050 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3589}, - {1923, 1923, 9: 1923, 49: 1923, 127: 1923, 481: 1923, 502: 1923, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {9: 3590, 49: 1297, 127: 1297, 502: 2725, 767: 2726, 812: 3591}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3597}, - {49: 1116, 127: 3593, 1266: 3592}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3667}, + {1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 493: 1163, 1163, 1163, 497: 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 508: 1163, 1163, 511: 1163, 1163, 1163, 516: 1163, 1163, 1163, 1163, 1163, 1163, 523: 1163, 1163, 526: 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 550: 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 584: 1163, 1163, 1163, 616: 1163}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3669, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3670}, + {58: 3671, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1055 - {49: 3595}, - {475: 3594}, - {49: 1115}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3596}, - {1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 474: 1130, 1130, 1130, 1130, 1130, 480: 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 489: 1130, 1130, 1130, 493: 1130, 1130, 496: 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 506: 1130, 1130, 509: 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 531: 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 565: 1130, 1130, 594: 1130}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3672}, + {1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 493: 1164, 1164, 1164, 497: 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 508: 1164, 1164, 511: 1164, 1164, 1164, 516: 1164, 1164, 1164, 1164, 1164, 1164, 523: 1164, 1164, 526: 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 550: 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 584: 1164, 1164, 1164, 616: 1164}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3674, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3675}, + {58: 3676, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1060 - {1922, 1922, 9: 1922, 49: 1922, 127: 1922, 481: 1922, 502: 1922, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 520: 3602, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 3601, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3599, 745: 3544, 3545, 784: 3600}, - {49: 3610, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3608}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3605}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3677}, + {1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 493: 1165, 1165, 1165, 497: 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 508: 1165, 1165, 511: 1165, 1165, 1165, 516: 1165, 1165, 1165, 1165, 1165, 1165, 523: 1165, 1165, 526: 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 550: 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 584: 1165, 1165, 1165, 616: 1165}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3679, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3680}, + {58: 3681, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1065 - {49: 3603}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3604}, - {1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 474: 1131, 1131, 1131, 1131, 1131, 480: 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 489: 1131, 1131, 1131, 493: 1131, 1131, 496: 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 506: 1131, 1131, 509: 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 531: 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 565: 1131, 1131, 594: 1131}, - {49: 3606, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3607}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3682}, + {1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 493: 1166, 1166, 1166, 497: 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 508: 1166, 1166, 511: 1166, 1166, 1166, 516: 1166, 1166, 1166, 1166, 1166, 1166, 523: 1166, 1166, 526: 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 550: 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 584: 1166, 1166, 1166, 616: 1166}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3684, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3685}, + {58: 3686, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1070 - {1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 474: 1133, 1133, 1133, 1133, 1133, 480: 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 489: 1133, 1133, 1133, 493: 1133, 1133, 496: 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 506: 1133, 1133, 509: 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 531: 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 565: 1133, 1133, 594: 1133}, - {9: 3590, 49: 3609}, - {1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 474: 1134, 1134, 1134, 1134, 1134, 480: 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 489: 1134, 1134, 1134, 493: 1134, 1134, 496: 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 506: 1134, 1134, 509: 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 531: 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 1134, 565: 1134, 1134, 594: 1134}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3611}, - {1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 474: 1132, 1132, 1132, 1132, 1132, 480: 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 489: 1132, 1132, 1132, 493: 1132, 1132, 496: 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 506: 1132, 1132, 509: 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 531: 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 1132, 565: 1132, 1132, 594: 1132}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3687}, + {1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 493: 1167, 1167, 1167, 497: 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 508: 1167, 1167, 511: 1167, 1167, 1167, 516: 1167, 1167, 1167, 1167, 1167, 1167, 523: 1167, 1167, 526: 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 550: 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 584: 1167, 1167, 1167, 616: 1167}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3689, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3690}, + {58: 3691, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1075 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 3614, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3613}, - {49: 3618, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3615}, - {49: 3616, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3617}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3692}, + {1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 493: 1168, 1168, 1168, 497: 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 508: 1168, 1168, 511: 1168, 1168, 1168, 516: 1168, 1168, 1168, 1168, 1168, 1168, 523: 1168, 1168, 526: 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 550: 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 584: 1168, 1168, 1168, 616: 1168}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 3694, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3696}, + {1984, 1984, 9: 1984, 58: 1984, 139: 1984, 501: 1984, 523: 1984, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1080 - {1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 474: 1135, 1135, 1135, 1135, 1135, 480: 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 489: 1135, 1135, 1135, 493: 1135, 1135, 496: 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 506: 1135, 1135, 509: 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 531: 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 565: 1135, 1135, 594: 1135}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3619}, - {1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 474: 1136, 1136, 1136, 1136, 1136, 480: 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 489: 1136, 1136, 1136, 493: 1136, 1136, 496: 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 506: 1136, 1136, 509: 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 531: 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 1136, 565: 1136, 1136, 594: 1136}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 3622, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3621}, - {49: 3626, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {9: 3697, 58: 1338, 139: 1338, 523: 2813, 790: 2814, 836: 3698}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3704}, + {58: 1155, 139: 3700, 1300: 3699}, + {58: 3702}, + {493: 3701}, // 1085 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3623}, - {49: 3624, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3625}, - {1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 474: 1137, 1137, 1137, 1137, 1137, 480: 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 489: 1137, 1137, 1137, 493: 1137, 1137, 496: 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 506: 1137, 1137, 509: 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 531: 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 565: 1137, 1137, 594: 1137}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3627}, + {58: 1154}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3703}, + {1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 493: 1169, 1169, 1169, 497: 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 508: 1169, 1169, 511: 1169, 1169, 1169, 516: 1169, 1169, 1169, 1169, 1169, 1169, 523: 1169, 1169, 526: 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 550: 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 584: 1169, 1169, 1169, 616: 1169}, + {1983, 1983, 9: 1983, 58: 1983, 139: 1983, 501: 1983, 523: 1983, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 541: 3709, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 3708, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3706, 767: 3651, 3652, 808: 3707}, // 1090 - {1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 474: 1138, 1138, 1138, 1138, 1138, 480: 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 489: 1138, 1138, 1138, 493: 1138, 1138, 496: 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 506: 1138, 1138, 509: 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 531: 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 1138, 565: 1138, 1138, 594: 1138}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 3630, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3629}, - {49: 3634, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3631}, - {49: 3632, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {58: 3717, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3715}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3712}, + {58: 3710}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3711}, // 1095 - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3633}, - {1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 474: 1139, 1139, 1139, 1139, 1139, 480: 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 489: 1139, 1139, 1139, 493: 1139, 1139, 496: 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 506: 1139, 1139, 509: 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 531: 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 565: 1139, 1139, 594: 1139}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 3635}, - {1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 474: 1140, 1140, 1140, 1140, 1140, 480: 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 489: 1140, 1140, 1140, 493: 1140, 1140, 496: 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 506: 1140, 1140, 509: 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 531: 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 1140, 565: 1140, 1140, 594: 1140}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3637}, + {1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 493: 1170, 1170, 1170, 497: 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 508: 1170, 1170, 511: 1170, 1170, 1170, 516: 1170, 1170, 1170, 1170, 1170, 1170, 523: 1170, 1170, 526: 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 550: 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 584: 1170, 1170, 1170, 616: 1170}, + {58: 3713, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3714}, + {1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 493: 1172, 1172, 1172, 497: 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 508: 1172, 1172, 511: 1172, 1172, 1172, 516: 1172, 1172, 1172, 1172, 1172, 1172, 523: 1172, 1172, 526: 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 550: 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 584: 1172, 1172, 1172, 616: 1172}, + {9: 3697, 58: 3716}, // 1100 - {9: 3590, 49: 3638}, - {1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 474: 1141, 1141, 1141, 1141, 1141, 480: 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 489: 1141, 1141, 1141, 493: 1141, 1141, 496: 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 506: 1141, 1141, 509: 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 531: 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 565: 1141, 1141, 594: 1141}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3640}, - {9: 3590, 49: 3641}, - {1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 474: 1142, 1142, 1142, 1142, 1142, 480: 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 489: 1142, 1142, 1142, 493: 1142, 1142, 496: 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 506: 1142, 1142, 509: 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 531: 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 565: 1142, 1142, 594: 1142}, + {1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 493: 1173, 1173, 1173, 497: 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 508: 1173, 1173, 511: 1173, 1173, 1173, 516: 1173, 1173, 1173, 1173, 1173, 1173, 523: 1173, 1173, 526: 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 550: 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 584: 1173, 1173, 1173, 616: 1173}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3718}, + {1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 493: 1171, 1171, 1171, 497: 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 508: 1171, 1171, 511: 1171, 1171, 1171, 516: 1171, 1171, 1171, 1171, 1171, 1171, 523: 1171, 1171, 526: 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 550: 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 584: 1171, 1171, 1171, 616: 1171}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 3721, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3720}, + {58: 3725, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1105 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3643}, - {9: 3644, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3645}, - {9: 3646, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3647}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3722}, + {58: 3723, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3724}, + {1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 493: 1174, 1174, 1174, 497: 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 508: 1174, 1174, 511: 1174, 1174, 1174, 516: 1174, 1174, 1174, 1174, 1174, 1174, 523: 1174, 1174, 526: 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 550: 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 584: 1174, 1174, 1174, 616: 1174}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3726}, // 1110 - {49: 3648, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 474: 1158, 1158, 1158, 1158, 1158, 480: 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 489: 1158, 1158, 1158, 493: 1158, 1158, 496: 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 506: 1158, 1158, 509: 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 531: 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 565: 1158, 1158, 594: 1158}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3650, 1185: 3652, 1241: 3653, 1328: 3654, 3651}, - {49: 3662, 500: 3663, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 500: 3656, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3655}, + {1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 493: 1175, 1175, 1175, 497: 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 508: 1175, 1175, 511: 1175, 1175, 1175, 516: 1175, 1175, 1175, 1175, 1175, 1175, 523: 1175, 1175, 526: 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 550: 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 584: 1175, 1175, 1175, 616: 1175}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 3729, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3728}, + {58: 3733, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3730}, + {58: 3731, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1115 - {2: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 10: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 50: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 473: 1149, 475: 1149, 1149, 1149, 479: 1149, 482: 1149, 1149, 485: 1149, 1149, 1149, 492: 1149, 495: 1149, 500: 1149, 504: 1149, 1149, 508: 1149, 530: 1149, 564: 1149, 567: 1149, 1149, 570: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 582: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 592: 1149, 1149, 595: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 648: 1149}, - {2: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 10: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 50: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 473: 1148, 475: 1148, 1148, 1148, 479: 1148, 482: 1148, 1148, 485: 1148, 1148, 1148, 492: 1148, 495: 1148, 500: 1148, 504: 1148, 1148, 508: 1148, 530: 1148, 564: 1148, 567: 1148, 1148, 570: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 582: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 592: 1148, 1148, 595: 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 648: 1148}, - {2: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 10: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 50: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 473: 1147, 475: 1147, 1147, 1147, 479: 1147, 482: 1147, 1147, 485: 1147, 1147, 1147, 492: 1147, 495: 1147, 500: 1147, 504: 1147, 1147, 508: 1147, 530: 1147, 564: 1147, 567: 1147, 1147, 570: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 582: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 592: 1147, 1147, 595: 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 648: 1147}, - {500: 3659, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3657}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3732}, + {1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 493: 1176, 1176, 1176, 497: 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 508: 1176, 1176, 511: 1176, 1176, 1176, 516: 1176, 1176, 1176, 1176, 1176, 1176, 523: 1176, 1176, 526: 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 550: 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 584: 1176, 1176, 1176, 616: 1176}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3734}, + {1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 493: 1177, 1177, 1177, 497: 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 508: 1177, 1177, 511: 1177, 1177, 1177, 516: 1177, 1177, 1177, 1177, 1177, 1177, 523: 1177, 1177, 526: 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 550: 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 584: 1177, 1177, 1177, 616: 1177}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 3737, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3736}, // 1120 - {49: 3658, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 474: 1164, 1164, 1164, 1164, 1164, 480: 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 489: 1164, 1164, 1164, 493: 1164, 1164, 496: 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 506: 1164, 1164, 509: 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 531: 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 565: 1164, 1164, 594: 1164}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3660}, - {49: 3661, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 474: 1163, 1163, 1163, 1163, 1163, 480: 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 489: 1163, 1163, 1163, 493: 1163, 1163, 496: 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 506: 1163, 1163, 509: 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 531: 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 565: 1163, 1163, 594: 1163}, + {58: 3741, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3738}, + {58: 3739, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3740}, + {1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 493: 1178, 1178, 1178, 497: 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 508: 1178, 1178, 511: 1178, 1178, 1178, 516: 1178, 1178, 1178, 1178, 1178, 1178, 523: 1178, 1178, 526: 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 550: 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 584: 1178, 1178, 1178, 616: 1178}, // 1125 - {1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 474: 1166, 1166, 1166, 1166, 1166, 480: 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 489: 1166, 1166, 1166, 493: 1166, 1166, 496: 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 506: 1166, 1166, 509: 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 531: 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 565: 1166, 1166, 594: 1166}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3664}, - {49: 3665, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 474: 1165, 1165, 1165, 1165, 1165, 480: 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 489: 1165, 1165, 1165, 493: 1165, 1165, 496: 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 506: 1165, 1165, 509: 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 531: 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 565: 1165, 1165, 594: 1165}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3667}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 3742}, + {1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 493: 1179, 1179, 1179, 497: 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 508: 1179, 1179, 511: 1179, 1179, 1179, 516: 1179, 1179, 1179, 1179, 1179, 1179, 523: 1179, 1179, 526: 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 550: 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 584: 1179, 1179, 1179, 616: 1179}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3744}, + {9: 3697, 58: 3745}, + {1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 493: 1180, 1180, 1180, 497: 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 508: 1180, 1180, 511: 1180, 1180, 1180, 516: 1180, 1180, 1180, 1180, 1180, 1180, 523: 1180, 1180, 526: 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 550: 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 584: 1180, 1180, 1180, 616: 1180}, // 1130 - {9: 3668, 500: 3669, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3675}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3670}, - {49: 3671, 494: 3672, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 474: 1171, 1171, 1171, 1171, 1171, 480: 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 489: 1171, 1171, 1171, 493: 1171, 1171, 496: 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 506: 1171, 1171, 509: 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 531: 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 565: 1171, 1171, 594: 1171}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3747}, + {9: 3697, 58: 3748}, + {1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 493: 1181, 1181, 1181, 497: 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 508: 1181, 1181, 511: 1181, 1181, 1181, 516: 1181, 1181, 1181, 1181, 1181, 1181, 523: 1181, 1181, 526: 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 550: 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 584: 1181, 1181, 1181, 616: 1181}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3750}, + {9: 3751, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1135 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3673}, - {49: 3674, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 474: 1169, 1169, 1169, 1169, 1169, 480: 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 489: 1169, 1169, 1169, 493: 1169, 1169, 496: 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 506: 1169, 1169, 509: 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 531: 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 565: 1169, 1169, 594: 1169}, - {9: 3677, 49: 3676, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 474: 1172, 1172, 1172, 1172, 1172, 480: 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 489: 1172, 1172, 1172, 493: 1172, 1172, 496: 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 506: 1172, 1172, 509: 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 531: 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 565: 1172, 1172, 594: 1172}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3752}, + {9: 3753, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3754}, + {58: 3755, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 493: 1197, 1197, 1197, 497: 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 508: 1197, 1197, 511: 1197, 1197, 1197, 516: 1197, 1197, 1197, 1197, 1197, 1197, 523: 1197, 1197, 526: 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 550: 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 584: 1197, 1197, 1197, 616: 1197}, // 1140 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3678}, - {49: 3679, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 474: 1170, 1170, 1170, 1170, 1170, 480: 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 489: 1170, 1170, 1170, 493: 1170, 1170, 496: 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 506: 1170, 1170, 509: 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 531: 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 565: 1170, 1170, 594: 1170}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3681}, - {485: 3686, 3687, 3692, 520: 3688, 544: 3694, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3757, 1219: 3759, 1273: 3760, 1363: 3761, 3758}, + {58: 3769, 520: 3770, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 520: 3763, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3762}, + {2: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 10: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 59: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 492: 1188, 1188, 495: 1188, 1188, 1188, 502: 1188, 1188, 1188, 1188, 1188, 510: 1188, 514: 1188, 1188, 520: 1188, 522: 1188, 525: 1188, 549: 1188, 583: 1188, 587: 1188, 589: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 601: 1188, 1188, 1188, 1188, 1188, 1188, 608: 1188, 1188, 1188, 1188, 1188, 614: 1188, 1188, 617: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 669: 1188}, + {2: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 10: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 59: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 492: 1187, 1187, 495: 1187, 1187, 1187, 502: 1187, 1187, 1187, 1187, 1187, 510: 1187, 514: 1187, 1187, 520: 1187, 522: 1187, 525: 1187, 549: 1187, 583: 1187, 587: 1187, 589: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 601: 1187, 1187, 1187, 1187, 1187, 1187, 608: 1187, 1187, 1187, 1187, 1187, 614: 1187, 1187, 617: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 669: 1187}, // 1145 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3716}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3715}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3714}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3713}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3710, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3709}, + {2: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 10: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 59: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 492: 1186, 1186, 495: 1186, 1186, 1186, 502: 1186, 1186, 1186, 1186, 1186, 510: 1186, 514: 1186, 1186, 520: 1186, 522: 1186, 525: 1186, 549: 1186, 583: 1186, 587: 1186, 589: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 601: 1186, 1186, 1186, 1186, 1186, 1186, 608: 1186, 1186, 1186, 1186, 1186, 614: 1186, 1186, 617: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 669: 1186}, + {520: 3766, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3764}, + {58: 3765, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 493: 1203, 1203, 1203, 497: 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 508: 1203, 1203, 511: 1203, 1203, 1203, 516: 1203, 1203, 1203, 1203, 1203, 1203, 523: 1203, 1203, 526: 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 550: 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 584: 1203, 1203, 1203, 616: 1203}, // 1150 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3704, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3703}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3702}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3701}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3700}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3699}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3767}, + {58: 3768, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 493: 1202, 1202, 1202, 497: 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 508: 1202, 1202, 511: 1202, 1202, 1202, 516: 1202, 1202, 1202, 1202, 1202, 1202, 523: 1202, 1202, 526: 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 550: 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, 584: 1202, 1202, 1202, 616: 1202}, + {1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 493: 1205, 1205, 1205, 497: 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 508: 1205, 1205, 511: 1205, 1205, 1205, 516: 1205, 1205, 1205, 1205, 1205, 1205, 523: 1205, 1205, 526: 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 550: 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 584: 1205, 1205, 1205, 616: 1205}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3771}, // 1155 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3698}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3697}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3695}, - {49: 3696, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 474: 1173, 1173, 1173, 1173, 1173, 480: 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 489: 1173, 1173, 1173, 493: 1173, 1173, 496: 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 506: 1173, 1173, 509: 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 531: 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 1173, 565: 1173, 1173, 594: 1173}, + {58: 3772, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 493: 1204, 1204, 1204, 497: 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 508: 1204, 1204, 511: 1204, 1204, 1204, 516: 1204, 1204, 1204, 1204, 1204, 1204, 523: 1204, 1204, 526: 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 550: 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 584: 1204, 1204, 1204, 616: 1204}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3774}, + {9: 3775, 520: 3776, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3782}, // 1160 - {1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 474: 1281, 1281, 1281, 1281, 1281, 480: 1281, 1281, 1281, 1281, 485: 1281, 1281, 1281, 489: 1281, 1281, 1281, 493: 1281, 1281, 496: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 506: 1281, 1281, 509: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 531: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 565: 1281, 1281}, - {1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 474: 1282, 1282, 1282, 1282, 1282, 480: 1282, 1282, 1282, 1282, 485: 1282, 1282, 1282, 489: 1282, 1282, 1282, 493: 1282, 1282, 496: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 506: 1282, 1282, 509: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 531: 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 3693, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 565: 1282, 1282}, - {1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 474: 1283, 1283, 1283, 1283, 1283, 480: 1283, 1283, 1283, 1283, 485: 1283, 1283, 1283, 489: 1283, 1283, 1283, 493: 1283, 1283, 496: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 506: 1283, 1283, 509: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 531: 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 3693, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 565: 1283, 1283}, - {1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 474: 1284, 1284, 1284, 1284, 1284, 480: 1284, 1284, 1284, 1284, 485: 1284, 1284, 1284, 489: 1284, 1284, 1284, 493: 1284, 1284, 496: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 506: 1284, 1284, 509: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 531: 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 3693, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 565: 1284, 1284}, - {1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 474: 1285, 1285, 1285, 1285, 1285, 480: 1285, 1285, 1285, 1285, 485: 1285, 1285, 1285, 489: 1285, 1285, 1285, 493: 1285, 1285, 496: 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 506: 1285, 1285, 509: 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 531: 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 3693, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 565: 1285, 1285}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3777}, + {58: 3778, 513: 3779, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 493: 1210, 1210, 1210, 497: 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 508: 1210, 1210, 511: 1210, 1210, 1210, 516: 1210, 1210, 1210, 1210, 1210, 1210, 523: 1210, 1210, 526: 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 550: 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 584: 1210, 1210, 1210, 616: 1210}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3780}, + {58: 3781, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1165 - {1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 474: 1286, 1286, 1286, 1286, 1286, 480: 1286, 1286, 1286, 1286, 485: 1286, 1286, 1286, 489: 1286, 1286, 1286, 493: 1286, 1286, 496: 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 506: 1286, 1286, 509: 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 531: 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 3693, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 565: 1286, 1286}, - {1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 474: 1290, 1290, 1290, 1290, 1290, 480: 1290, 1290, 1290, 1290, 485: 1290, 1290, 3692, 489: 1290, 1290, 1290, 493: 1290, 1290, 496: 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 506: 1290, 1290, 509: 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 3688, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 531: 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 3689, 3690, 1290, 3693, 1290, 3691, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 565: 1290, 1290}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 1226, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3705}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 3706}, - {1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 474: 1288, 1288, 1288, 1288, 1288, 480: 1288, 1288, 1288, 1288, 485: 1288, 1288, 1288, 489: 1288, 1288, 1288, 493: 1288, 1288, 496: 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 506: 1288, 1288, 509: 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 531: 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 565: 1288, 1288}, + {1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 493: 1208, 1208, 1208, 497: 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 508: 1208, 1208, 511: 1208, 1208, 1208, 516: 1208, 1208, 1208, 1208, 1208, 1208, 523: 1208, 1208, 526: 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 550: 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 1208, 584: 1208, 1208, 1208, 616: 1208}, + {9: 3784, 58: 3783, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 493: 1211, 1211, 1211, 497: 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 508: 1211, 1211, 511: 1211, 1211, 1211, 516: 1211, 1211, 1211, 1211, 1211, 1211, 523: 1211, 1211, 526: 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 550: 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 1211, 584: 1211, 1211, 1211, 616: 1211}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3785}, + {58: 3786, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1170 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3708}, - {1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 474: 1287, 1287, 1287, 1287, 1287, 480: 1287, 1287, 1287, 1287, 485: 1287, 1287, 3692, 489: 1287, 1287, 1287, 493: 1287, 1287, 496: 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 506: 1287, 1287, 509: 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 3688, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 531: 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 3689, 3690, 1287, 3693, 1287, 3691, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 565: 1287, 1287}, - {1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 474: 1291, 1291, 1291, 1291, 1291, 480: 1291, 1291, 1291, 1291, 485: 1291, 1291, 3692, 489: 1291, 1291, 1291, 493: 1291, 1291, 496: 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 506: 1291, 1291, 509: 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 3688, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 531: 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 3689, 3690, 1291, 3693, 1291, 3691, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 565: 1291, 1291}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 1226, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3711}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 3712}, + {1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 493: 1209, 1209, 1209, 497: 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 508: 1209, 1209, 511: 1209, 1209, 1209, 516: 1209, 1209, 1209, 1209, 1209, 1209, 523: 1209, 1209, 526: 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 550: 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 584: 1209, 1209, 1209, 616: 1209}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3788}, + {504: 3793, 3794, 3799, 541: 3795, 564: 3801, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3823}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3822}, // 1175 - {1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 474: 1289, 1289, 1289, 1289, 1289, 480: 1289, 1289, 1289, 1289, 485: 1289, 1289, 1289, 489: 1289, 1289, 1289, 493: 1289, 1289, 496: 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 506: 1289, 1289, 509: 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 531: 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 565: 1289, 1289}, - {1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 474: 1292, 1292, 1292, 1292, 1292, 480: 1292, 1292, 1292, 1292, 485: 3686, 3687, 3692, 489: 1292, 1292, 1292, 493: 1292, 1292, 496: 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 506: 1292, 1292, 509: 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 3688, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 531: 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 3689, 3690, 1292, 3693, 1292, 3691, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 565: 1292, 1292}, - {1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 474: 1293, 1293, 1293, 1293, 1293, 480: 1293, 1293, 1293, 1293, 485: 3686, 3687, 3692, 489: 1293, 1293, 1293, 493: 1293, 1293, 496: 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 506: 1293, 1293, 509: 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 3688, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 531: 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 3689, 3690, 1293, 3693, 1293, 3691, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 565: 1293, 1293}, - {1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 474: 1294, 1294, 1294, 1294, 1294, 480: 1294, 1294, 1294, 1294, 485: 3686, 3687, 3692, 489: 1294, 1294, 1294, 493: 1294, 1294, 496: 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 506: 1294, 1294, 509: 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 3688, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 531: 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 3689, 3690, 1294, 3693, 1294, 3691, 3684, 3685, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 565: 1294, 1294}, - {1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 474: 1295, 1295, 1295, 1295, 1295, 480: 1295, 1295, 1295, 1295, 485: 3686, 3687, 3692, 489: 1295, 1295, 1295, 493: 1295, 1295, 496: 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 506: 1295, 1295, 509: 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 3688, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 531: 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 3689, 3690, 3683, 3693, 1295, 3691, 3684, 3685, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 565: 1295, 1295}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3821}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3820}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3817, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3816}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3811, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3810}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3809}, // 1180 - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 796: 3444, 815: 3718}, - {500: 3719}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3720}, - {49: 3721, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 474: 1175, 1175, 1175, 1175, 1175, 480: 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 489: 1175, 1175, 1175, 493: 1175, 1175, 496: 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 506: 1175, 1175, 509: 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 531: 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 565: 1175, 1175, 594: 1175}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3808}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3807}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3806}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3805}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3804}, // 1185 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3723}, - {9: 3724, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {578: 3725}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3726}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 3727}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3802}, + {58: 3803, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 493: 1212, 1212, 1212, 497: 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 508: 1212, 1212, 511: 1212, 1212, 1212, 516: 1212, 1212, 1212, 1212, 1212, 1212, 523: 1212, 1212, 526: 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 550: 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 1212, 584: 1212, 1212, 1212, 616: 1212}, + {1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 493: 1322, 1322, 1322, 497: 1322, 1322, 500: 1322, 1322, 1322, 1322, 1322, 1322, 1322, 508: 1322, 1322, 511: 1322, 1322, 1322, 516: 1322, 1322, 1322, 1322, 1322, 1322, 523: 1322, 1322, 526: 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 550: 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 584: 1322, 1322, 1322}, + {1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 493: 1323, 1323, 1323, 497: 1323, 1323, 500: 1323, 1323, 1323, 1323, 1323, 1323, 1323, 508: 1323, 1323, 511: 1323, 1323, 1323, 516: 1323, 1323, 1323, 1323, 1323, 1323, 523: 1323, 1323, 526: 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 550: 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 3800, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 584: 1323, 1323, 1323}, // 1190 - {49: 3728}, - {1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 474: 1176, 1176, 1176, 1176, 1176, 480: 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 489: 1176, 1176, 1176, 493: 1176, 1176, 496: 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 506: 1176, 1176, 509: 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 531: 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 565: 1176, 1176, 594: 1176}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3730}, - {9: 3731, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3733, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3732}, + {1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 493: 1324, 1324, 1324, 497: 1324, 1324, 500: 1324, 1324, 1324, 1324, 1324, 1324, 1324, 508: 1324, 1324, 511: 1324, 1324, 1324, 516: 1324, 1324, 1324, 1324, 1324, 1324, 523: 1324, 1324, 526: 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 550: 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 3800, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324, 584: 1324, 1324, 1324}, + {1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 493: 1325, 1325, 1325, 497: 1325, 1325, 500: 1325, 1325, 1325, 1325, 1325, 1325, 1325, 508: 1325, 1325, 511: 1325, 1325, 1325, 516: 1325, 1325, 1325, 1325, 1325, 1325, 523: 1325, 1325, 526: 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 550: 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 3800, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 584: 1325, 1325, 1325}, + {1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 493: 1326, 1326, 1326, 497: 1326, 1326, 500: 1326, 1326, 1326, 1326, 1326, 1326, 1326, 508: 1326, 1326, 511: 1326, 1326, 1326, 516: 1326, 1326, 1326, 1326, 1326, 1326, 523: 1326, 1326, 526: 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 550: 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 3800, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 584: 1326, 1326, 1326}, + {1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 493: 1327, 1327, 1327, 497: 1327, 1327, 500: 1327, 1327, 1327, 1327, 1327, 1327, 1327, 508: 1327, 1327, 511: 1327, 1327, 1327, 516: 1327, 1327, 1327, 1327, 1327, 1327, 523: 1327, 1327, 526: 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 550: 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 3800, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 1327, 584: 1327, 1327, 1327}, + {1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 493: 1331, 1331, 1331, 497: 1331, 1331, 500: 1331, 1331, 1331, 1331, 1331, 1331, 3799, 508: 1331, 1331, 511: 1331, 1331, 1331, 516: 1331, 1331, 1331, 1331, 1331, 1331, 523: 1331, 1331, 526: 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 3795, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 550: 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 3796, 3797, 1331, 3800, 1331, 3798, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 1331, 584: 1331, 1331, 1331}, // 1195 - {49: 3737, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 1226, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3734}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 3735}, - {49: 3736, 485: 3707}, - {1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 474: 1177, 1177, 1177, 1177, 1177, 480: 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 489: 1177, 1177, 1177, 493: 1177, 1177, 496: 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 506: 1177, 1177, 509: 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 531: 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 565: 1177, 1177, 594: 1177}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 1265, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3812}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 3813}, + {1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 493: 1329, 1329, 1329, 497: 1329, 1329, 500: 1329, 1329, 1329, 1329, 1329, 1329, 1329, 508: 1329, 1329, 511: 1329, 1329, 1329, 516: 1329, 1329, 1329, 1329, 1329, 1329, 523: 1329, 1329, 526: 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 550: 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 584: 1329, 1329, 1329}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3815}, + {1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 493: 1328, 1328, 1328, 497: 1328, 1328, 500: 1328, 1328, 1328, 1328, 1328, 1328, 3799, 508: 1328, 1328, 511: 1328, 1328, 1328, 516: 1328, 1328, 1328, 1328, 1328, 1328, 523: 1328, 1328, 526: 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 3795, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 550: 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 3796, 3797, 1328, 3800, 1328, 3798, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 1328, 584: 1328, 1328, 1328}, // 1200 - {1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 474: 1178, 1178, 1178, 1178, 1178, 480: 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 489: 1178, 1178, 1178, 493: 1178, 1178, 496: 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 506: 1178, 1178, 509: 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 531: 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 565: 1178, 1178, 594: 1178}, - {49: 1917, 508: 3740, 1052: 3739, 3741}, - {49: 1916}, - {49: 1915}, - {49: 3742}, + {1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 493: 1332, 1332, 1332, 497: 1332, 1332, 500: 1332, 1332, 1332, 1332, 1332, 1332, 3799, 508: 1332, 1332, 511: 1332, 1332, 1332, 516: 1332, 1332, 1332, 1332, 1332, 1332, 523: 1332, 1332, 526: 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 3795, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 550: 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 3796, 3797, 1332, 3800, 1332, 3798, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 584: 1332, 1332, 1332}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 1265, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3818}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 3819}, + {1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 493: 1330, 1330, 1330, 497: 1330, 1330, 500: 1330, 1330, 1330, 1330, 1330, 1330, 1330, 508: 1330, 1330, 511: 1330, 1330, 1330, 516: 1330, 1330, 1330, 1330, 1330, 1330, 523: 1330, 1330, 526: 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 550: 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 1330, 584: 1330, 1330, 1330}, + {1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 493: 1333, 1333, 1333, 497: 1333, 1333, 500: 1333, 1333, 1333, 1333, 3793, 3794, 3799, 508: 1333, 1333, 511: 1333, 1333, 1333, 516: 1333, 1333, 1333, 1333, 1333, 1333, 523: 1333, 1333, 526: 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 3795, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 550: 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 3796, 3797, 1333, 3800, 1333, 3798, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 584: 1333, 1333, 1333}, // 1205 - {1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 474: 1179, 1179, 1179, 1179, 1179, 480: 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 489: 1179, 1179, 1179, 493: 1179, 1179, 496: 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 506: 1179, 1179, 509: 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 531: 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1179, 565: 1179, 1179, 594: 1179}, - {49: 1917, 508: 3740, 1052: 3739, 3744}, - {49: 3745}, - {1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 474: 1180, 1180, 1180, 1180, 1180, 480: 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 489: 1180, 1180, 1180, 493: 1180, 1180, 496: 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 506: 1180, 1180, 509: 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 531: 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 1180, 565: 1180, 1180, 594: 1180}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3747}, + {1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 493: 1334, 1334, 1334, 497: 1334, 1334, 500: 1334, 1334, 1334, 1334, 3793, 3794, 3799, 508: 1334, 1334, 511: 1334, 1334, 1334, 516: 1334, 1334, 1334, 1334, 1334, 1334, 523: 1334, 1334, 526: 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 3795, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 550: 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 3796, 3797, 1334, 3800, 1334, 3798, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 584: 1334, 1334, 1334}, + {1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 493: 1335, 1335, 1335, 497: 1335, 1335, 500: 1335, 1335, 1335, 1335, 3793, 3794, 3799, 508: 1335, 1335, 511: 1335, 1335, 1335, 516: 1335, 1335, 1335, 1335, 1335, 1335, 523: 1335, 1335, 526: 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 3795, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 550: 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 3796, 3797, 1335, 3800, 1335, 3798, 3791, 3792, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 584: 1335, 1335, 1335}, + {1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 493: 1336, 1336, 1336, 497: 1336, 1336, 500: 1336, 1336, 1336, 1336, 3793, 3794, 3799, 508: 1336, 1336, 511: 1336, 1336, 1336, 516: 1336, 1336, 1336, 1336, 1336, 1336, 523: 1336, 1336, 526: 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 3795, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 550: 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 3796, 3797, 3790, 3800, 1336, 3798, 3791, 3792, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 1336, 584: 1336, 1336, 1336}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 813: 3551, 828: 3825}, + {520: 3826}, // 1210 - {9: 3748, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 3749}, - {49: 3750, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 474: 1182, 1182, 1182, 1182, 1182, 480: 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 489: 1182, 1182, 1182, 493: 1182, 1182, 496: 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 506: 1182, 1182, 509: 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 531: 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 565: 1182, 1182, 594: 1182}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 3753}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3827}, + {58: 3828, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 493: 1214, 1214, 1214, 497: 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 508: 1214, 1214, 511: 1214, 1214, 1214, 516: 1214, 1214, 1214, 1214, 1214, 1214, 523: 1214, 1214, 526: 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 550: 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214, 584: 1214, 1214, 1214, 616: 1214}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3830}, + {9: 3831, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1215 - {9: 3590, 49: 1918}, - {49: 3754}, - {1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 474: 1183, 1183, 1183, 1183, 1183, 480: 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 489: 1183, 1183, 1183, 493: 1183, 1183, 496: 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 506: 1183, 1183, 509: 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 531: 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 1183, 565: 1183, 1183, 594: 1183}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3756}, - {9: 3590, 49: 3757, 481: 3758}, + {599: 3832}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3833}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 3834}, + {58: 3835}, + {1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 493: 1215, 1215, 1215, 497: 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 508: 1215, 1215, 511: 1215, 1215, 1215, 516: 1215, 1215, 1215, 1215, 1215, 1215, 523: 1215, 1215, 526: 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 550: 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 584: 1215, 1215, 1215, 616: 1215}, // 1220 - {1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 474: 1188, 1188, 1188, 1188, 1188, 480: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 489: 1188, 1188, 1188, 493: 1188, 1188, 496: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 506: 1188, 1188, 509: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 531: 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 565: 1188, 1188, 594: 1188}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 3759}, - {49: 3762}, - {757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 49: 757, 102: 757, 111: 757, 472: 757, 757, 757, 476: 757, 757, 757, 757, 757, 484: 757, 488: 757, 757, 492: 757, 495: 757, 503: 757, 757, 757, 757, 530: 757, 569: 757, 581: 757, 590: 757, 757, 642: 757, 757, 757, 757, 757, 757, 649: 757, 658: 757}, - {756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 49: 756, 102: 756, 111: 756, 472: 756, 756, 756, 476: 756, 756, 756, 756, 756, 484: 756, 488: 756, 756, 492: 756, 495: 756, 503: 756, 756, 756, 756, 530: 756, 569: 756, 581: 756, 590: 756, 756, 642: 756, 756, 756, 756, 756, 756, 649: 756, 658: 756}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3837}, + {9: 3838, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3840, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3839}, + {58: 3844, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 1265, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3841}, // 1225 - {1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 474: 1187, 1187, 1187, 1187, 1187, 480: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 489: 1187, 1187, 1187, 493: 1187, 1187, 496: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 506: 1187, 1187, 509: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 531: 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 565: 1187, 1187, 594: 1187}, - {1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 474: 1189, 1189, 1189, 1189, 1189, 480: 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 489: 1189, 1189, 1189, 493: 1189, 1189, 496: 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 506: 1189, 1189, 509: 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 531: 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 565: 1189, 1189, 594: 1189}, - {49: 3765, 508: 3766}, - {1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 474: 1111, 1111, 1111, 1111, 1111, 480: 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 489: 1111, 1111, 1111, 493: 1111, 1111, 496: 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 506: 1111, 1111, 509: 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 531: 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 565: 1111, 1111, 594: 1111}, - {49: 3767}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 3842}, + {58: 3843, 504: 3814}, + {1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 493: 1216, 1216, 1216, 497: 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 508: 1216, 1216, 511: 1216, 1216, 1216, 516: 1216, 1216, 1216, 1216, 1216, 1216, 523: 1216, 1216, 526: 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 550: 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 584: 1216, 1216, 1216, 616: 1216}, + {1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 493: 1217, 1217, 1217, 497: 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 508: 1217, 1217, 511: 1217, 1217, 1217, 516: 1217, 1217, 1217, 1217, 1217, 1217, 523: 1217, 1217, 526: 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 550: 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 584: 1217, 1217, 1217, 616: 1217}, + {58: 1978, 525: 3847, 1082: 3846, 3848}, // 1230 - {1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 474: 1110, 1110, 1110, 1110, 1110, 480: 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 489: 1110, 1110, 1110, 493: 1110, 1110, 496: 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 506: 1110, 1110, 509: 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 531: 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 565: 1110, 1110, 594: 1110}, - {49: 3769}, - {1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 474: 1190, 1190, 1190, 1190, 1190, 480: 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 489: 1190, 1190, 1190, 493: 1190, 1190, 496: 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 506: 1190, 1190, 509: 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 531: 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 565: 1190, 1190, 594: 1190}, - {49: 3772}, - {1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 474: 1191, 1191, 1191, 1191, 1191, 480: 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 489: 1191, 1191, 1191, 493: 1191, 1191, 496: 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 506: 1191, 1191, 509: 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 531: 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 565: 1191, 1191, 594: 1191}, + {58: 1977}, + {58: 1976}, + {58: 3849}, + {1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 493: 1218, 1218, 1218, 497: 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 508: 1218, 1218, 511: 1218, 1218, 1218, 516: 1218, 1218, 1218, 1218, 1218, 1218, 523: 1218, 1218, 526: 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 550: 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 584: 1218, 1218, 1218, 616: 1218}, + {58: 1978, 525: 3847, 1082: 3846, 3851}, // 1235 - {1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 474: 1205, 1205, 1205, 1205, 1205, 480: 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 489: 1205, 1205, 1205, 493: 1205, 1205, 496: 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 506: 1205, 1205, 509: 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 531: 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 565: 1205, 1205, 594: 1205, 650: 1205, 666: 1205, 668: 1205}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 3774}, - {49: 3775}, - {1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 474: 1192, 1192, 1192, 1192, 1192, 480: 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 489: 1192, 1192, 1192, 493: 1192, 1192, 496: 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 506: 1192, 1192, 509: 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 531: 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 1192, 565: 1192, 1192, 594: 1192}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 3777}, + {58: 3852}, + {1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 493: 1219, 1219, 1219, 497: 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 508: 1219, 1219, 511: 1219, 1219, 1219, 516: 1219, 1219, 1219, 1219, 1219, 1219, 523: 1219, 1219, 526: 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 550: 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 584: 1219, 1219, 1219, 616: 1219}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3854}, + {9: 3855, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 3856}, // 1240 - {49: 3778}, - {1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 474: 1193, 1193, 1193, 1193, 1193, 480: 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 489: 1193, 1193, 1193, 493: 1193, 1193, 496: 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 506: 1193, 1193, 509: 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 531: 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 1193, 565: 1193, 1193, 594: 1193}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3780, 2762, 2763, 2761, 711: 3781}, - {49: 1279, 499: 1279, 652: 3783}, - {49: 3782}, + {58: 3857, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 493: 1221, 1221, 1221, 497: 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 508: 1221, 1221, 511: 1221, 1221, 1221, 516: 1221, 1221, 1221, 1221, 1221, 1221, 523: 1221, 1221, 526: 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 550: 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 1221, 584: 1221, 1221, 1221, 616: 1221}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 3860}, + {9: 3697, 58: 1979}, + {58: 3861}, // 1245 - {1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 474: 1248, 1248, 1248, 1248, 1248, 480: 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 489: 1248, 1248, 1248, 493: 1248, 1248, 496: 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 506: 1248, 1248, 509: 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 531: 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 565: 1248, 1248, 594: 1248}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3784, 2762, 2763, 2761}, - {49: 1278, 499: 1278, 652: 3785}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3786, 2762, 2763, 2761}, - {1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 474: 1277, 1277, 1277, 1277, 1277, 480: 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 489: 1277, 1277, 1277, 493: 1277, 1277, 496: 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 506: 1277, 1277, 509: 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 531: 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 565: 1277, 1277, 594: 1277, 656: 1277, 1277}, + {1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 493: 1222, 1222, 1222, 497: 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 508: 1222, 1222, 511: 1222, 1222, 1222, 516: 1222, 1222, 1222, 1222, 1222, 1222, 523: 1222, 1222, 526: 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 550: 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 584: 1222, 1222, 1222, 616: 1222}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3863}, + {9: 3697, 58: 3864, 501: 3865}, + {1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 493: 1227, 1227, 1227, 497: 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 508: 1227, 1227, 511: 1227, 1227, 1227, 516: 1227, 1227, 1227, 1227, 1227, 1227, 523: 1227, 1227, 526: 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 550: 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 584: 1227, 1227, 1227, 616: 1227}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 3866}, // 1250 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3780, 2762, 2763, 2761, 711: 3788}, - {49: 3789}, - {1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 474: 1249, 1249, 1249, 1249, 1249, 480: 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 489: 1249, 1249, 1249, 493: 1249, 1249, 496: 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 506: 1249, 1249, 509: 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 531: 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 565: 1249, 1249, 594: 1249}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3791}, - {9: 3792, 481: 3793, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {58: 3869}, + {796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 58: 796, 109: 796, 136: 796, 491: 796, 796, 494: 796, 796, 796, 796, 796, 796, 796, 507: 796, 796, 510: 796, 514: 796, 796, 522: 796, 524: 796, 526: 796, 549: 796, 588: 796, 600: 796, 607: 796, 613: 796, 662: 796, 796, 796, 796, 796, 796, 796, 678: 796, 796}, + {795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 58: 795, 109: 795, 136: 795, 491: 795, 795, 494: 795, 795, 795, 795, 795, 795, 795, 507: 795, 795, 510: 795, 514: 795, 795, 522: 795, 524: 795, 526: 795, 549: 795, 588: 795, 600: 795, 607: 795, 613: 795, 662: 795, 795, 795, 795, 795, 795, 795, 678: 795, 795}, + {1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 493: 1226, 1226, 1226, 497: 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 508: 1226, 1226, 511: 1226, 1226, 1226, 516: 1226, 1226, 1226, 1226, 1226, 1226, 523: 1226, 1226, 526: 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 550: 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 584: 1226, 1226, 1226, 616: 1226}, + {1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 493: 1228, 1228, 1228, 497: 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 508: 1228, 1228, 511: 1228, 1228, 1228, 516: 1228, 1228, 1228, 1228, 1228, 1228, 523: 1228, 1228, 526: 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 550: 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 584: 1228, 1228, 1228, 616: 1228}, // 1255 - {51: 3804, 104: 3800, 171: 3806, 178: 3801, 3799, 200: 3803, 505: 3811, 530: 3797, 647: 3810, 680: 3802, 3807, 3808, 685: 3809, 740: 3805, 901: 3798, 998: 3796}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 3794}, - {49: 3795}, - {1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 474: 1250, 1250, 1250, 1250, 1250, 480: 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 489: 1250, 1250, 1250, 493: 1250, 1250, 496: 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 506: 1250, 1250, 509: 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 531: 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 565: 1250, 1250, 594: 1250}, - {49: 3847}, + {58: 3872, 525: 3873}, + {1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 493: 1150, 1150, 1150, 497: 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 508: 1150, 1150, 511: 1150, 1150, 1150, 516: 1150, 1150, 1150, 1150, 1150, 1150, 523: 1150, 1150, 526: 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 550: 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 584: 1150, 1150, 1150, 616: 1150}, + {58: 3874}, + {1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 493: 1149, 1149, 1149, 497: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 508: 1149, 1149, 511: 1149, 1149, 1149, 516: 1149, 1149, 1149, 1149, 1149, 1149, 523: 1149, 1149, 526: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 550: 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 584: 1149, 1149, 1149, 616: 1149}, + {58: 3876}, // 1260 - {49: 288, 473: 3826, 764: 3827, 789: 3846}, - {16: 288, 49: 288, 473: 3826, 505: 288, 530: 288, 647: 288, 764: 3827, 789: 3831}, - {49: 1071}, - {49: 1070}, - {49: 288, 473: 3826, 764: 3827, 789: 3830}, + {1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 493: 1229, 1229, 1229, 497: 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 508: 1229, 1229, 511: 1229, 1229, 1229, 516: 1229, 1229, 1229, 1229, 1229, 1229, 523: 1229, 1229, 526: 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 550: 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 584: 1229, 1229, 1229, 616: 1229}, + {58: 3879}, + {1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 493: 1230, 1230, 1230, 497: 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 508: 1230, 1230, 511: 1230, 1230, 1230, 516: 1230, 1230, 1230, 1230, 1230, 1230, 523: 1230, 1230, 526: 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 550: 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 584: 1230, 1230, 1230, 616: 1230}, + {1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 493: 1244, 1244, 1244, 497: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 508: 1244, 1244, 511: 1244, 1244, 1244, 516: 1244, 1244, 1244, 1244, 1244, 1244, 523: 1244, 1244, 526: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 550: 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 584: 1244, 1244, 1244, 616: 1244, 670: 1244, 683: 1244, 687: 1244}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 3881}, // 1265 - {49: 281, 473: 3813, 764: 3814, 904: 3829, 909: 3815}, - {49: 288, 473: 3826, 764: 3827, 789: 3825}, - {49: 352, 683: 3822, 3823, 1091: 3824}, - {49: 352, 683: 3822, 3823, 1091: 3821}, - {49: 1064}, + {58: 3882}, + {1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 493: 1231, 1231, 1231, 497: 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 508: 1231, 1231, 511: 1231, 1231, 1231, 516: 1231, 1231, 1231, 1231, 1231, 1231, 523: 1231, 1231, 526: 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 550: 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 584: 1231, 1231, 1231, 616: 1231}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 3884}, + {58: 3885}, + {1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 493: 1232, 1232, 1232, 497: 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 508: 1232, 1232, 511: 1232, 1232, 1232, 516: 1232, 1232, 1232, 1232, 1232, 1232, 523: 1232, 1232, 526: 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 550: 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 584: 1232, 1232, 1232, 616: 1232}, // 1270 - {49: 1063}, - {49: 281, 473: 3813, 764: 3814, 904: 3812, 909: 3815}, - {49: 1061}, - {16: 326, 49: 326, 473: 326, 505: 326, 530: 326, 647: 326}, - {16: 325, 49: 325, 473: 325, 505: 325, 530: 325, 647: 325}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3887, 2850, 688: 2851, 2849, 733: 3888}, + {58: 1320, 517: 1320, 672: 3890}, + {58: 3889}, + {1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 493: 1289, 1289, 1289, 497: 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 508: 1289, 1289, 511: 1289, 1289, 1289, 516: 1289, 1289, 1289, 1289, 1289, 1289, 523: 1289, 1289, 526: 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 550: 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 584: 1289, 1289, 1289, 616: 1289}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3891, 2850, 688: 2851, 2849}, // 1275 - {49: 1062}, - {508: 2736, 733: 2735, 741: 3816}, - {280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 49: 280, 51: 280, 472: 280, 476: 280, 280, 280, 280, 484: 280, 488: 280, 492: 280, 581: 280, 590: 280, 280, 642: 280, 280, 280, 280, 740: 280, 743: 280}, - {279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 49: 279, 51: 279, 472: 279, 476: 279, 279, 279, 279, 484: 279, 488: 279, 492: 279, 581: 279, 590: 279, 279, 642: 279, 279, 279, 279, 740: 279, 743: 279}, - {9: 3818, 49: 3817}, + {58: 1319, 517: 1319, 672: 3892}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3893, 2850, 688: 2851, 2849}, + {1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 493: 1318, 1318, 1318, 497: 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 508: 1318, 1318, 511: 1318, 1318, 1318, 516: 1318, 1318, 1318, 1318, 1318, 1318, 523: 1318, 1318, 526: 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 550: 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 584: 1318, 1318, 1318, 616: 1318, 676: 1318, 1318}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3887, 2850, 688: 2851, 2849, 733: 3895}, + {58: 3896}, // 1280 - {289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 16: 289, 49: 289, 51: 289, 106: 289, 289, 110: 289, 472: 289, 476: 289, 289, 289, 289, 484: 289, 488: 289, 492: 289, 505: 289, 529: 289, 289, 289, 581: 289, 590: 289, 289, 642: 289, 289, 289, 289, 647: 289, 740: 289, 743: 289}, - {508: 2736, 733: 2735, 741: 3819}, - {49: 3820}, - {278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 49: 278, 51: 278, 472: 278, 476: 278, 278, 278, 278, 484: 278, 488: 278, 492: 278, 581: 278, 590: 278, 278, 642: 278, 278, 278, 278, 740: 278, 743: 278}, - {49: 1065}, + {1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 493: 1290, 1290, 1290, 497: 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 508: 1290, 1290, 511: 1290, 1290, 1290, 516: 1290, 1290, 1290, 1290, 1290, 1290, 523: 1290, 1290, 526: 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 550: 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 584: 1290, 1290, 1290, 616: 1290}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3898}, + {9: 3899, 501: 3900, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {57: 3911, 112: 3907, 184: 3913, 191: 3908, 3906, 214: 3910, 514: 3918, 549: 3904, 667: 3917, 702: 3909, 3914, 3915, 707: 3916, 763: 3912, 926: 3905, 1023: 3903}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 3901}, // 1285 - {49: 351}, - {49: 350}, - {49: 1066}, - {49: 1067}, - {508: 2736, 733: 2735, 741: 3828}, + {58: 3902}, + {1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 493: 1291, 1291, 1291, 497: 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 508: 1291, 1291, 511: 1291, 1291, 1291, 516: 1291, 1291, 1291, 1291, 1291, 1291, 523: 1291, 1291, 526: 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 550: 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 584: 1291, 1291, 1291, 616: 1291}, + {58: 3954}, + {58: 316, 492: 3933, 678: 316, 786: 3934, 812: 3953}, + {16: 316, 58: 316, 492: 3933, 514: 316, 549: 316, 667: 316, 678: 316, 786: 3934, 812: 3938}, // 1290 - {287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 16: 287, 49: 287, 51: 287, 106: 287, 287, 110: 287, 472: 287, 476: 287, 287, 287, 287, 484: 287, 488: 287, 492: 287, 505: 287, 529: 287, 287, 287, 581: 287, 590: 287, 287, 642: 287, 287, 287, 287, 647: 287, 740: 287, 743: 287}, - {49: 3817}, - {49: 1068}, - {49: 1069}, - {16: 3836, 49: 275, 505: 3837, 530: 3833, 647: 3835, 773: 3834, 799: 3832}, + {58: 1110, 678: 1110}, + {58: 1109, 678: 1109}, + {58: 316, 492: 3933, 678: 316, 786: 3934, 812: 3937}, + {58: 309, 492: 3920, 678: 309, 786: 3921, 929: 3936, 934: 3922}, + {58: 316, 492: 3933, 678: 316, 786: 3934, 812: 3932}, // 1295 - {49: 1072}, - {272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 16: 3836, 49: 272, 472: 272, 476: 272, 272, 272, 272, 484: 272, 488: 272, 492: 272, 505: 3837, 581: 272, 590: 272, 272, 642: 272, 272, 272, 272, 647: 3835, 773: 3844, 1262: 3843}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 3840}, - {506: 3839}, - {269, 269, 269, 269, 269, 269, 269, 269, 269, 10: 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 50: 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 475: 269, 479: 269, 498: 269, 269, 518: 269, 530: 269}, + {58: 380, 678: 380, 705: 3929, 3930, 1121: 3931}, + {58: 380, 678: 380, 705: 3929, 3930, 1121: 3928}, + {58: 1103, 678: 1103}, + {58: 1102, 678: 1102}, + {58: 309, 492: 3920, 678: 309, 786: 3921, 929: 3919, 934: 3922}, // 1300 - {506: 3838}, - {268, 268, 268, 268, 268, 268, 268, 268, 268, 10: 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 50: 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 475: 268, 479: 268, 498: 268, 268, 518: 268, 530: 268}, - {270, 270, 270, 270, 270, 270, 270, 270, 270, 10: 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 50: 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 475: 270, 479: 270, 498: 270, 270, 518: 270, 530: 270}, - {277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 49: 277, 472: 277, 476: 277, 277, 277, 277, 484: 277, 488: 277, 492: 277, 530: 3841, 581: 277, 590: 277, 277, 642: 277, 277, 277, 277, 1261: 3842}, - {276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 49: 276, 472: 276, 476: 276, 276, 276, 276, 484: 276, 488: 276, 492: 276, 581: 276, 590: 276, 276, 642: 276, 276, 276, 276}, + {58: 1100, 678: 1100}, + {16: 354, 58: 354, 492: 354, 514: 354, 549: 354, 667: 354, 678: 354}, + {16: 353, 58: 353, 492: 353, 514: 353, 549: 353, 667: 353, 678: 353}, + {58: 1101, 678: 1101}, + {525: 2824, 755: 2823, 762: 3923}, // 1305 - {273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 49: 273, 472: 273, 476: 273, 273, 273, 273, 484: 273, 488: 273, 492: 273, 581: 273, 590: 273, 273, 642: 273, 273, 273, 273}, - {274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 49: 274, 472: 274, 476: 274, 274, 274, 274, 484: 274, 488: 274, 492: 274, 581: 274, 590: 274, 274, 642: 274, 274, 274, 274}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 3845}, - {271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 49: 271, 472: 271, 476: 271, 271, 271, 271, 484: 271, 488: 271, 492: 271, 581: 271, 590: 271, 271, 642: 271, 271, 271, 271}, - {49: 1073}, + {308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 57: 308, 308, 491: 308, 495: 308, 308, 308, 308, 308, 507: 308, 510: 308, 600: 308, 607: 308, 613: 308, 662: 308, 308, 308, 666: 308, 678: 308, 763: 308, 765: 308}, + {307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 57: 307, 307, 491: 307, 495: 307, 307, 307, 307, 307, 507: 307, 510: 307, 600: 307, 607: 307, 613: 307, 662: 307, 307, 307, 666: 307, 678: 307, 763: 307, 765: 307}, + {9: 3925, 58: 3924}, + {317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 16: 317, 57: 317, 317, 116: 317, 317, 133: 317, 491: 317, 495: 317, 317, 317, 317, 317, 507: 317, 510: 317, 514: 317, 548: 317, 317, 561: 317, 600: 317, 607: 317, 613: 317, 662: 317, 317, 317, 666: 317, 317, 678: 317, 763: 317, 765: 317}, + {525: 2824, 755: 2823, 762: 3926}, // 1310 - {1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 474: 1251, 1251, 1251, 1251, 1251, 480: 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 489: 1251, 1251, 1251, 493: 1251, 1251, 496: 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 506: 1251, 1251, 509: 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 531: 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 565: 1251, 1251, 594: 1251}, - {507: 3345, 509: 3343, 3344, 3342, 3340, 543: 1079, 734: 3341, 3339}, - {543: 3852, 1159: 3851, 1344: 3850}, - {161: 1075, 543: 3852, 545: 3858, 1159: 3857, 1207: 3856}, - {161: 1078, 543: 1078, 545: 1078}, + {58: 3927}, + {306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 57: 306, 306, 491: 306, 495: 306, 306, 306, 306, 306, 507: 306, 510: 306, 600: 306, 607: 306, 613: 306, 662: 306, 306, 306, 666: 306, 678: 306, 763: 306, 765: 306}, + {58: 1104, 678: 1104}, + {58: 379, 678: 379}, + {58: 378, 678: 378}, // 1315 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3853}, - {507: 3345, 509: 3343, 3344, 3342, 3340, 546: 3854, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3855}, - {161: 1076, 507: 3345, 509: 3343, 3344, 3342, 3340, 543: 1076, 545: 1076, 734: 3341, 3339}, - {161: 3860}, + {58: 1105, 678: 1105}, + {58: 1106, 678: 1106}, + {525: 2824, 755: 2823, 762: 3935}, + {315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 16: 315, 57: 315, 315, 116: 315, 315, 133: 315, 491: 315, 495: 315, 315, 315, 315, 315, 507: 315, 510: 315, 514: 315, 548: 315, 315, 561: 315, 600: 315, 607: 315, 613: 315, 662: 315, 315, 315, 666: 315, 315, 678: 315, 763: 315, 765: 315}, + {58: 3924}, // 1320 - {161: 1077, 543: 1077, 545: 1077}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3859}, - {161: 1074, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 474: 1252, 1252, 1252, 1252, 1252, 480: 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 489: 1252, 1252, 1252, 493: 1252, 1252, 496: 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 506: 1252, 1252, 509: 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 531: 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 565: 1252, 1252, 594: 1252}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3862}, + {58: 1107, 678: 1107}, + {58: 1108, 678: 1108}, + {16: 3943, 58: 303, 514: 3944, 549: 3940, 667: 3942, 678: 303, 798: 3941, 821: 3939}, + {58: 1111, 678: 1111}, + {300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 16: 3943, 58: 300, 491: 300, 495: 300, 300, 300, 300, 300, 507: 300, 510: 300, 514: 3944, 600: 300, 607: 300, 613: 300, 662: 300, 300, 300, 666: 300, 3942, 678: 300, 798: 3951, 1296: 3950}, // 1325 - {478: 3863, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {51: 3804, 104: 3800, 171: 3806, 178: 3801, 3799, 200: 3803, 505: 3811, 530: 3797, 647: 3810, 680: 3802, 3807, 3808, 685: 3809, 740: 3805, 901: 3798, 998: 3864}, - {49: 3865}, - {1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 474: 1253, 1253, 1253, 1253, 1253, 480: 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 489: 1253, 1253, 1253, 493: 1253, 1253, 496: 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 506: 1253, 1253, 509: 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 531: 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 565: 1253, 1253, 594: 1253}, - {1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 474: 1254, 1254, 1254, 1254, 1254, 480: 1254, 1254, 1254, 1254, 3350, 1254, 1254, 1254, 489: 1254, 1254, 1254, 493: 1254, 1254, 496: 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 506: 1254, 1254, 509: 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 531: 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 565: 1254, 1254, 594: 1254}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 3947}, + {526: 3946}, + {297, 297, 297, 297, 297, 297, 297, 297, 297, 10: 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 59: 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 493: 297, 496: 297, 517: 297, 519: 297, 537: 297, 549: 297}, + {526: 3945}, + {296, 296, 296, 296, 296, 296, 296, 296, 296, 10: 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 59: 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 493: 296, 496: 296, 517: 296, 519: 296, 537: 296, 549: 296}, // 1330 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3868}, - {507: 3345, 509: 3343, 3344, 3342, 3340, 523: 3869, 734: 3341, 3339}, - {1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 474: 1255, 1255, 1255, 1255, 1255, 480: 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 489: 1255, 1255, 1255, 493: 1255, 1255, 496: 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 506: 1255, 1255, 509: 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 531: 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 565: 1255, 1255, 594: 1255}, - {1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 474: 1256, 1256, 1256, 1256, 1256, 480: 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 489: 1256, 1256, 1256, 493: 1256, 1256, 496: 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 506: 1256, 1256, 509: 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 531: 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 565: 1256, 1256, 594: 1256}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3872}, + {298, 298, 298, 298, 298, 298, 298, 298, 298, 10: 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 59: 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 493: 298, 496: 298, 517: 298, 519: 298, 537: 298, 549: 298}, + {305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 58: 305, 491: 305, 495: 305, 305, 305, 305, 305, 507: 305, 510: 305, 549: 3948, 600: 305, 607: 305, 613: 305, 662: 305, 305, 305, 666: 305, 678: 305, 1295: 3949}, + {304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 58: 304, 491: 304, 495: 304, 304, 304, 304, 304, 507: 304, 510: 304, 600: 304, 607: 304, 613: 304, 662: 304, 304, 304, 666: 304, 678: 304}, + {301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 58: 301, 491: 301, 495: 301, 301, 301, 301, 301, 507: 301, 510: 301, 600: 301, 607: 301, 613: 301, 662: 301, 301, 301, 666: 301, 678: 301}, + {302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 58: 302, 491: 302, 495: 302, 302, 302, 302, 302, 507: 302, 510: 302, 600: 302, 607: 302, 613: 302, 662: 302, 302, 302, 666: 302, 678: 302}, // 1335 - {9: 3873}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3874}, - {9: 1922, 49: 3875, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 474: 1257, 1257, 1257, 1257, 1257, 480: 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 489: 1257, 1257, 1257, 493: 1257, 1257, 496: 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 506: 1257, 1257, 509: 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 531: 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 565: 1257, 1257, 594: 1257}, - {9: 1923, 49: 3978, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 3952}, + {299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 58: 299, 491: 299, 495: 299, 299, 299, 299, 299, 507: 299, 510: 299, 600: 299, 607: 299, 613: 299, 662: 299, 299, 299, 666: 299, 678: 299}, + {58: 1112, 678: 1112}, + {1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 493: 1292, 1292, 1292, 497: 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 508: 1292, 1292, 511: 1292, 1292, 1292, 516: 1292, 1292, 1292, 1292, 1292, 1292, 523: 1292, 1292, 526: 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 550: 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 584: 1292, 1292, 1292, 616: 1292}, + {527: 3452, 3450, 3451, 3449, 3447, 562: 1118, 756: 3448, 3446}, // 1340 - {9: 3975}, - {9: 1260, 49: 1260, 476: 1260, 1260, 480: 814, 484: 1260, 1260, 1260, 1260, 490: 814, 814, 493: 2728, 499: 1260, 501: 2729, 2725, 507: 1260, 509: 1260, 1260, 1260, 1260, 518: 1260, 520: 1260, 544: 1260, 547: 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 565: 1260, 1260, 594: 1260, 767: 3891, 3892}, - {473: 3779, 575: 3896, 912: 3895, 976: 3894}, - {473: 2588, 495: 2586, 569: 2585, 646: 2581, 709: 3888, 748: 3887, 2582, 2583, 2584, 2593, 756: 2591, 3889, 3890}, - {49: 3886, 480: 815, 490: 815, 815}, + {562: 3959, 1192: 3958, 1379: 3957}, + {175: 1114, 562: 3959, 3965, 1192: 3964, 1240: 3963}, + {175: 1117, 562: 1117, 1117}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3960}, + {527: 3452, 3450, 3451, 3449, 3447, 565: 3961, 756: 3448, 3446}, // 1345 - {49: 3885}, - {49: 3884}, - {842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 480: 842, 842, 842, 842, 842, 842, 842, 842, 489: 842, 842, 842, 493: 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 506: 842, 842, 509: 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 531: 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, 565: 842, 842, 569: 842, 594: 842, 646: 842, 654: 842, 739: 842}, - {843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 480: 843, 843, 843, 843, 843, 843, 843, 843, 489: 843, 843, 843, 493: 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 506: 843, 843, 509: 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 531: 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, 565: 843, 843, 569: 843, 594: 843, 646: 843, 654: 843, 739: 843}, - {844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 480: 844, 844, 844, 844, 844, 844, 844, 844, 489: 844, 844, 844, 493: 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 506: 844, 844, 509: 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 531: 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, 565: 844, 844, 569: 844, 594: 844, 646: 844, 654: 844, 739: 844}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3962}, + {175: 1115, 527: 3452, 3450, 3451, 3449, 3447, 562: 1115, 1115, 756: 3448, 3446}, + {175: 3967}, + {175: 1116, 562: 1116, 1116}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3966}, // 1350 - {999, 999, 49: 999, 472: 999, 474: 999, 480: 815, 999, 490: 815, 815}, - {998, 998, 49: 998, 472: 998, 474: 998, 480: 814, 998, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, - {827, 827, 49: 827, 472: 827, 474: 827, 481: 827}, - {826, 826, 49: 826, 472: 826, 474: 826, 481: 826}, - {820, 820, 49: 820, 472: 820, 474: 820, 481: 820, 493: 2728, 501: 2729, 768: 3893}, + {175: 1113, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 493: 1293, 1293, 1293, 497: 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 508: 1293, 1293, 511: 1293, 1293, 1293, 516: 1293, 1293, 1293, 1293, 1293, 1293, 523: 1293, 1293, 526: 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 550: 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 1293, 584: 1293, 1293, 1293, 616: 1293}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3969}, + {498: 3970, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {57: 3911, 112: 3907, 184: 3913, 191: 3908, 3906, 214: 3910, 514: 3918, 549: 3904, 667: 3917, 702: 3909, 3914, 3915, 707: 3916, 763: 3912, 926: 3905, 1023: 3971}, // 1355 - {819, 819, 49: 819, 472: 819, 474: 819, 481: 819}, - {818, 818, 49: 818, 472: 818, 474: 818, 481: 818}, - {1297, 1297, 9: 3908, 49: 1297, 472: 1297, 474: 1297, 480: 1297, 1297, 490: 1297, 1297, 493: 1297, 1297, 496: 1297, 1297, 501: 1297, 2725, 767: 2726, 812: 3907}, - {10, 10, 9: 10, 49: 10, 472: 10, 474: 10, 480: 10, 10, 490: 10, 10, 493: 10, 10, 496: 10, 10, 501: 10, 10}, - {473: 3897, 839: 3898}, + {58: 1286, 678: 3973, 1208: 3972}, + {58: 3974}, + {58: 1285}, + {1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 493: 1294, 1294, 1294, 497: 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 508: 1294, 1294, 511: 1294, 1294, 1294, 516: 1294, 1294, 1294, 1294, 1294, 1294, 523: 1294, 1294, 526: 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 550: 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 584: 1294, 1294, 1294, 616: 1294}, + {1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 493: 1295, 1295, 1295, 497: 1295, 1295, 3457, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 508: 1295, 1295, 511: 1295, 1295, 1295, 516: 1295, 1295, 1295, 1295, 1295, 1295, 523: 1295, 1295, 526: 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 550: 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 584: 1295, 1295, 1295, 616: 1295}, // 1360 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1337, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 3902, 1334: 3901, 3900}, - {8, 8, 9: 8, 49: 8, 472: 8, 474: 8, 480: 8, 8, 490: 8, 8, 493: 8, 8, 496: 8, 8, 501: 8, 8}, - {1333, 1333, 9: 1333, 49: 1333, 472: 1333, 481: 1333, 493: 1333, 498: 1333, 502: 1333, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {49: 3906}, - {9: 3904, 49: 1336}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3977}, + {527: 3452, 3450, 3451, 3449, 3447, 542: 3978, 756: 3448, 3446}, + {1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 493: 1296, 1296, 1296, 497: 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 508: 1296, 1296, 511: 1296, 1296, 1296, 516: 1296, 1296, 1296, 1296, 1296, 1296, 523: 1296, 1296, 526: 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 550: 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 584: 1296, 1296, 1296, 616: 1296}, + {1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 493: 1297, 1297, 1297, 497: 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 508: 1297, 1297, 511: 1297, 1297, 1297, 516: 1297, 1297, 1297, 1297, 1297, 1297, 523: 1297, 1297, 526: 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 550: 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 1297, 584: 1297, 1297, 1297, 616: 1297}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3981}, // 1365 - {9: 1334, 49: 1334}, - {1332, 1332, 9: 1332, 49: 1332, 472: 1332, 3787, 481: 1332, 493: 1332, 498: 1332, 502: 1332}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 3905}, - {9: 1335, 49: 1335}, - {1338, 1338, 9: 1338, 49: 1338, 88: 1338, 472: 1338, 474: 1338, 480: 1338, 1338, 490: 1338, 1338, 493: 1338, 1338, 496: 1338, 1338, 501: 1338, 1338, 507: 1338}, + {9: 3982}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3983}, + {9: 1983, 58: 3984, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 493: 1298, 1298, 1298, 497: 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 508: 1298, 1298, 511: 1298, 1298, 1298, 516: 1298, 1298, 1298, 1298, 1298, 1298, 523: 1298, 1298, 526: 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 550: 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 584: 1298, 1298, 1298, 616: 1298}, + {9: 1984, 58: 4087, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1370 - {869, 869, 49: 869, 472: 869, 474: 869, 480: 869, 869, 490: 869, 869, 493: 2728, 869, 496: 869, 869, 501: 2729, 768: 2730, 830: 3910}, - {575: 3896, 912: 3909}, - {9, 9, 9: 9, 49: 9, 472: 9, 474: 9, 480: 9, 9, 490: 9, 9, 493: 9, 9, 496: 9, 9, 501: 9, 9}, - {840, 840, 49: 840, 472: 840, 474: 840, 480: 840, 840, 490: 840, 840, 494: 3912, 496: 840, 3913, 888: 3911}, - {846, 846, 49: 846, 472: 846, 474: 846, 480: 846, 846, 490: 846, 846, 496: 3938, 889: 3937}, + {9: 4084}, + {9: 1301, 58: 1301, 495: 1301, 497: 1301, 499: 1301, 853, 504: 1301, 1301, 1301, 509: 853, 511: 853, 2816, 517: 1301, 521: 2817, 523: 2813, 527: 1301, 1301, 1301, 1301, 1301, 537: 1301, 541: 1301, 564: 1301, 566: 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 584: 1301, 1301, 1301, 616: 1301, 790: 4000, 4001}, + {492: 3886, 595: 4005, 937: 4004, 1001: 4003}, + {492: 2667, 515: 2665, 588: 2664, 665: 2660, 731: 3997, 770: 3996, 2661, 2662, 2663, 2672, 778: 2670, 3998, 3999}, + {58: 3995, 500: 854, 509: 854, 511: 854}, // 1375 - {286: 3918, 654: 3917}, - {544: 3914}, - {286: 3915}, - {213: 3916}, - {832, 832, 49: 832, 472: 832, 474: 832, 480: 832, 832, 490: 832, 832, 496: 832}, + {58: 3994}, + {58: 3993}, + {881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 497: 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 508: 881, 881, 511: 881, 881, 881, 515: 881, 881, 881, 881, 881, 881, 881, 523: 881, 881, 526: 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 550: 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 584: 881, 881, 881, 588: 881, 616: 881, 665: 881, 674: 881, 761: 881}, + {882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 497: 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 508: 882, 882, 511: 882, 882, 882, 515: 882, 882, 882, 882, 882, 882, 882, 523: 882, 882, 526: 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 550: 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 584: 882, 882, 882, 588: 882, 616: 882, 665: 882, 674: 882, 761: 882}, + {883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 497: 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 508: 883, 883, 511: 883, 883, 883, 515: 883, 883, 883, 883, 883, 883, 883, 523: 883, 883, 526: 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 550: 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 584: 883, 883, 883, 588: 883, 616: 883, 665: 883, 674: 883, 761: 883}, // 1380 - {831, 831, 49: 831, 140: 831, 153: 831, 176: 831, 472: 831, 474: 831, 480: 831, 831, 490: 831, 831, 496: 831, 1084: 3920, 3931}, - {831, 831, 49: 831, 140: 831, 153: 831, 472: 831, 474: 831, 480: 831, 831, 490: 831, 831, 496: 831, 1084: 3920, 3919}, - {838, 838, 49: 838, 140: 3929, 153: 3928, 472: 838, 474: 838, 480: 838, 838, 490: 838, 838, 496: 838}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 3923}, - {1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 531: 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 565: 1055, 1055, 569: 1055, 581: 1055, 584: 1055, 590: 1055, 1055, 594: 1055, 642: 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 3926, 1055, 1055, 1055, 658: 1055, 660: 1055, 665: 1055, 669: 1055, 1055, 1055, 1055, 1055, 1055, 679: 1055, 686: 1055, 1055, 689: 1055, 704: 1055}, + {1038, 1038, 58: 1038, 491: 1038, 494: 1038, 500: 854, 1038, 509: 854, 511: 854}, + {1037, 1037, 58: 1037, 491: 1037, 494: 1037, 500: 853, 1037, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {866, 866, 58: 866, 491: 866, 494: 866, 501: 866}, + {865, 865, 58: 865, 491: 865, 494: 865, 501: 865}, + {859, 859, 58: 859, 491: 859, 494: 859, 501: 859, 512: 2816, 521: 2817, 791: 4002}, // 1385 - {1053, 1053, 9: 1053, 49: 1053, 140: 1053, 153: 1053, 176: 1053, 472: 1053, 474: 1053, 480: 1053, 1053, 490: 1053, 1053, 496: 1053, 500: 1053, 650: 1053, 670: 1053, 672: 1053}, - {830, 830, 9: 3924, 49: 830, 140: 830, 153: 830, 176: 830, 472: 830, 474: 830, 480: 830, 830, 490: 830, 830, 496: 830}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3925}, - {1052, 1052, 9: 1052, 49: 1052, 140: 1052, 153: 1052, 166: 1052, 176: 1052, 472: 1052, 474: 1052, 480: 1052, 1052, 490: 1052, 1052, 496: 1052, 500: 1052, 650: 1052, 1052, 670: 1052, 672: 1052}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3927, 2762, 2763, 2761}, + {858, 858, 58: 858, 491: 858, 494: 858, 501: 858}, + {857, 857, 58: 857, 491: 857, 494: 857, 501: 857}, + {1338, 1338, 9: 4017, 58: 1338, 491: 1338, 494: 1338, 500: 1338, 1338, 509: 1338, 511: 1338, 1338, 1338, 516: 1338, 518: 1338, 521: 1338, 523: 2813, 790: 2814, 836: 4016}, + {11, 11, 9: 11, 58: 11, 491: 11, 494: 11, 500: 11, 11, 509: 11, 511: 11, 11, 11, 516: 11, 518: 11, 521: 11, 523: 11}, + {492: 4006, 863: 4007}, // 1390 - {1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 531: 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 565: 1054, 1054, 569: 1054, 581: 1054, 584: 1054, 590: 1054, 1054, 594: 1054, 642: 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 653: 1054, 1054, 1054, 658: 1054, 660: 1054, 665: 1054, 669: 1054, 1054, 1054, 1054, 1054, 1054, 679: 1054, 686: 1054, 1054, 689: 1054, 704: 1054}, - {835, 835, 49: 835, 472: 835, 474: 835, 480: 835, 835, 490: 835, 835, 496: 835}, - {268: 3930}, - {833, 833, 49: 833, 472: 833, 474: 833, 480: 833, 833, 490: 833, 833, 496: 833}, - {839, 839, 49: 839, 140: 3934, 153: 3932, 176: 3933, 472: 839, 474: 839, 480: 839, 839, 490: 839, 839, 496: 839}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1378, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 4011, 1369: 4010, 4009}, + {9, 9, 9: 9, 58: 9, 491: 9, 494: 9, 500: 9, 9, 509: 9, 511: 9, 9, 9, 516: 9, 518: 9, 521: 9, 523: 9}, + {1374, 1374, 9: 1374, 58: 1374, 491: 1374, 501: 1374, 512: 1374, 519: 1374, 523: 1374, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {58: 4015}, + {9: 4013, 58: 1377}, // 1395 - {837, 837, 49: 837, 472: 837, 474: 837, 480: 837, 837, 490: 837, 837, 496: 837}, - {508: 2736, 733: 3936}, - {268: 3935}, - {834, 834, 49: 834, 472: 834, 474: 834, 480: 834, 834, 490: 834, 834, 496: 834}, - {836, 836, 49: 836, 472: 836, 474: 836, 480: 836, 836, 490: 836, 836, 496: 836}, + {9: 1375, 58: 1375}, + {1373, 1373, 9: 1373, 58: 1373, 491: 1373, 3894, 501: 1373, 512: 1373, 519: 1373, 523: 1373}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 4014}, + {9: 1376, 58: 1376}, + {1379, 1379, 9: 1379, 58: 1379, 95: 1379, 491: 1379, 494: 1379, 500: 1379, 1379, 509: 1379, 511: 1379, 1379, 1379, 516: 1379, 518: 1379, 521: 1379, 523: 1379, 527: 1379}, // 1400 - {1000, 1000, 49: 1000, 472: 1000, 474: 1000, 480: 1000, 1000, 490: 1000, 1000}, - {1274: 3939}, - {475: 3940}, - {102, 102, 49: 102, 102: 3944, 111: 3943, 472: 102, 474: 102, 480: 102, 102, 490: 102, 102, 658: 102, 834: 3942, 1048: 3941}, - {89, 89, 49: 89, 472: 89, 474: 89, 480: 89, 89, 490: 89, 89, 658: 3965, 944: 3964}, + {908, 908, 58: 908, 491: 908, 494: 908, 500: 908, 908, 509: 908, 511: 908, 2816, 908, 516: 908, 518: 908, 521: 2817, 791: 2818, 852: 4019}, + {595: 4005, 937: 4018}, + {10, 10, 9: 10, 58: 10, 491: 10, 494: 10, 500: 10, 10, 509: 10, 511: 10, 10, 10, 516: 10, 518: 10, 521: 10, 523: 10}, + {879, 879, 58: 879, 491: 879, 494: 879, 500: 879, 879, 509: 879, 511: 879, 513: 4021, 516: 879, 518: 4022, 912: 4020}, + {885, 885, 58: 885, 491: 885, 494: 885, 500: 885, 885, 509: 885, 511: 885, 516: 4047, 913: 4046}, // 1405 - {782: 3947, 788: 3949, 793: 3950, 3948, 1047: 3946, 1213: 3945}, - {100, 100, 17: 100, 50: 100, 52: 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 472: 100, 100, 500: 100, 544: 100, 653: 100, 782: 100, 788: 100, 793: 100, 100}, - {99, 99, 17: 99, 50: 99, 52: 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 472: 99, 99, 500: 99, 544: 99, 653: 99, 782: 99, 788: 99, 793: 99, 99}, - {101, 101, 49: 101, 472: 101, 101, 101, 480: 101, 101, 489: 101, 101, 101, 506: 101, 658: 101, 782: 3947, 788: 3949, 793: 3950, 3948, 1047: 3963}, - {97, 97, 49: 97, 472: 97, 97, 97, 480: 97, 97, 489: 97, 97, 97, 506: 97, 658: 97, 782: 97, 788: 97, 793: 97, 97}, + {301: 4027, 674: 4026}, + {564: 4023}, + {301: 4024}, + {229: 4025}, + {871, 871, 58: 871, 491: 871, 494: 871, 500: 871, 871, 509: 871, 511: 871, 516: 871}, // 1410 - {660: 3961}, - {788: 3958}, - {660: 3956}, - {660: 3951}, - {475: 3953, 576: 3954, 580: 3955, 853: 3952}, + {870, 870, 58: 870, 154: 870, 166: 870, 189: 870, 491: 870, 494: 870, 500: 870, 870, 509: 870, 511: 870, 516: 870, 1114: 4029, 4040}, + {870, 870, 58: 870, 154: 870, 166: 870, 491: 870, 494: 870, 500: 870, 870, 509: 870, 511: 870, 516: 870, 1114: 4029, 4028}, + {877, 877, 58: 877, 154: 4038, 166: 4037, 491: 877, 494: 877, 500: 877, 877, 509: 877, 511: 877, 516: 877}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 4032}, + {1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 550: 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 584: 1094, 1094, 1094, 588: 1094, 600: 1094, 604: 1094, 607: 1094, 613: 1094, 616: 1094, 662: 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 4035, 1094, 1094, 1094, 679: 1094, 681: 1094, 1094, 690: 1094, 1094, 1094, 1094, 1094, 1094, 698: 1094, 701: 1094, 708: 1094, 1094, 711: 1094, 726: 1094}, // 1415 - {93, 93, 49: 93, 472: 93, 93, 93, 480: 93, 93, 489: 93, 93, 93, 506: 93, 658: 93, 782: 93, 788: 93, 793: 93, 93}, - {92, 92, 49: 92, 472: 92, 92, 92, 480: 92, 92, 489: 92, 92, 92, 506: 92, 658: 92, 782: 92, 788: 92, 793: 92, 92}, - {91, 91, 49: 91, 472: 91, 91, 91, 480: 91, 91, 489: 91, 91, 91, 506: 91, 658: 91, 782: 91, 788: 91, 793: 91, 91}, - {90, 90, 49: 90, 472: 90, 90, 90, 480: 90, 90, 489: 90, 90, 90, 506: 90, 658: 90, 782: 90, 788: 90, 793: 90, 90}, - {475: 3953, 576: 3954, 580: 3955, 853: 3957}, + {1092, 1092, 9: 1092, 58: 1092, 154: 1092, 166: 1092, 189: 1092, 491: 1092, 494: 1092, 500: 1092, 1092, 509: 1092, 511: 1092, 516: 1092, 520: 1092, 670: 1092, 691: 1092, 693: 1092}, + {869, 869, 9: 4033, 58: 869, 154: 869, 166: 869, 189: 869, 491: 869, 494: 869, 500: 869, 869, 509: 869, 511: 869, 516: 869}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4034}, + {1091, 1091, 9: 1091, 58: 1091, 154: 1091, 166: 1091, 180: 1091, 189: 1091, 491: 1091, 494: 1091, 500: 1091, 1091, 509: 1091, 511: 1091, 516: 1091, 520: 1091, 670: 1091, 1091, 691: 1091, 693: 1091, 698: 1091}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4036, 2850, 688: 2851, 2849}, // 1420 - {94, 94, 49: 94, 472: 94, 94, 94, 480: 94, 94, 489: 94, 94, 94, 506: 94, 658: 94, 782: 94, 788: 94, 793: 94, 94}, - {660: 3959}, - {475: 3953, 576: 3954, 580: 3955, 853: 3960}, - {95, 95, 49: 95, 472: 95, 95, 95, 480: 95, 95, 489: 95, 95, 95, 506: 95, 658: 95, 782: 95, 788: 95, 793: 95, 95}, - {475: 3953, 576: 3954, 580: 3955, 853: 3962}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 550: 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 584: 1093, 1093, 1093, 588: 1093, 600: 1093, 604: 1093, 607: 1093, 613: 1093, 616: 1093, 662: 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 673: 1093, 1093, 1093, 679: 1093, 681: 1093, 1093, 690: 1093, 1093, 1093, 1093, 1093, 1093, 698: 1093, 701: 1093, 708: 1093, 1093, 711: 1093, 726: 1093}, + {874, 874, 58: 874, 491: 874, 494: 874, 500: 874, 874, 509: 874, 511: 874, 516: 874}, + {283: 4039}, + {872, 872, 58: 872, 491: 872, 494: 872, 500: 872, 872, 509: 872, 511: 872, 516: 872}, + {878, 878, 58: 878, 154: 4043, 166: 4041, 189: 4042, 491: 878, 494: 878, 500: 878, 878, 509: 878, 511: 878, 516: 878}, // 1425 - {96, 96, 49: 96, 472: 96, 96, 96, 480: 96, 96, 489: 96, 96, 96, 506: 96, 658: 96, 782: 96, 788: 96, 793: 96, 96}, - {98, 98, 49: 98, 472: 98, 98, 98, 480: 98, 98, 489: 98, 98, 98, 506: 98, 658: 98, 782: 98, 788: 98, 793: 98, 98}, - {845, 845, 49: 845, 472: 845, 474: 845, 480: 845, 845, 490: 845, 845}, - {87, 87, 49: 87, 472: 87, 87, 87, 480: 87, 87, 489: 87, 87, 87, 506: 87, 782: 87, 1307: 3966, 3967}, - {85, 85, 49: 85, 472: 85, 85, 85, 480: 85, 85, 489: 85, 85, 85, 506: 85, 782: 3971, 1245: 3970}, + {876, 876, 58: 876, 491: 876, 494: 876, 500: 876, 876, 509: 876, 511: 876, 516: 876}, + {525: 2824, 755: 4045}, + {283: 4044}, + {873, 873, 58: 873, 491: 873, 494: 873, 500: 873, 873, 509: 873, 511: 873, 516: 873}, + {875, 875, 58: 875, 491: 875, 494: 875, 500: 875, 875, 509: 875, 511: 875, 516: 875}, // 1430 - {660: 3968}, - {475: 3953, 576: 3954, 580: 3955, 853: 3969}, - {86, 86, 49: 86, 472: 86, 86, 86, 480: 86, 86, 489: 86, 86, 86, 506: 86, 782: 86}, - {88, 88, 49: 88, 472: 88, 88, 88, 480: 88, 88, 489: 88, 88, 88, 506: 88}, - {660: 3972}, + {1039, 1039, 58: 1039, 491: 1039, 494: 1039, 500: 1039, 1039, 509: 1039, 511: 1039}, + {1308: 4048}, + {493: 4049}, + {113, 113, 58: 113, 109: 4053, 136: 4052, 491: 113, 494: 113, 500: 113, 113, 509: 113, 511: 113, 679: 113, 857: 4051, 1076: 4050}, + {100, 100, 58: 100, 491: 100, 494: 100, 500: 100, 100, 509: 100, 511: 100, 679: 4074, 970: 4073}, // 1435 - {475: 3953, 576: 3954, 580: 3955, 853: 3973}, - {84, 84, 49: 84, 472: 84, 84, 84, 480: 84, 84, 489: 84, 84, 84, 506: 84}, - {841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 480: 841, 841, 841, 841, 841, 841, 841, 841, 489: 841, 841, 841, 493: 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 506: 841, 841, 509: 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 531: 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 565: 841, 841, 569: 841, 594: 841, 646: 841, 654: 841, 739: 841}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3976}, - {9: 1922, 49: 3977, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {806: 4056, 811: 4058, 817: 4059, 4057, 1075: 4055, 1246: 4054}, + {111, 111, 17: 111, 56: 111, 59: 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 491: 111, 111, 520: 111, 564: 111, 673: 111, 806: 111, 811: 111, 817: 111, 111}, + {110, 110, 17: 110, 56: 110, 59: 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 491: 110, 110, 520: 110, 564: 110, 673: 110, 806: 110, 811: 110, 817: 110, 110}, + {112, 112, 58: 112, 491: 112, 112, 494: 112, 500: 112, 112, 508: 112, 112, 511: 112, 526: 112, 679: 112, 806: 4056, 811: 4058, 817: 4059, 4057, 1075: 4072}, + {108, 108, 58: 108, 491: 108, 108, 494: 108, 500: 108, 108, 508: 108, 108, 511: 108, 526: 108, 679: 108, 806: 108, 811: 108, 817: 108, 108}, // 1440 - {1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 474: 1258, 1258, 1258, 1258, 1258, 480: 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 489: 1258, 1258, 1258, 493: 1258, 1258, 496: 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 506: 1258, 1258, 509: 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 531: 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 565: 1258, 1258, 594: 1258}, - {1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 474: 1259, 1259, 1259, 1259, 1259, 480: 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 489: 1259, 1259, 1259, 493: 1259, 1259, 496: 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 506: 1259, 1259, 509: 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 531: 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259, 565: 1259, 1259, 594: 1259}, - {1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 474: 1261, 1261, 1261, 1261, 1261, 480: 1261, 1261, 1261, 1261, 3350, 1261, 1261, 1261, 489: 1261, 1261, 1261, 493: 1261, 1261, 496: 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 506: 1261, 1261, 509: 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 531: 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 565: 1261, 1261, 594: 1261}, - {1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 474: 1263, 1263, 1263, 1263, 1263, 480: 1263, 1263, 1263, 1263, 3350, 1263, 1263, 1263, 489: 1263, 1263, 1263, 493: 1263, 1263, 496: 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 506: 1263, 1263, 509: 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 531: 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 565: 1263, 1263, 594: 1263}, - {1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 474: 1264, 1264, 1264, 1264, 1264, 480: 1264, 1264, 1264, 1264, 3350, 1264, 1264, 1264, 489: 1264, 1264, 1264, 493: 1264, 1264, 496: 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 506: 1264, 1264, 509: 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 531: 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 565: 1264, 1264, 594: 1264}, + {681: 4070}, + {811: 4067}, + {681: 4065}, + {681: 4060}, + {493: 4062, 596: 4063, 598: 4064, 876: 4061}, // 1445 - {1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 474: 1265, 1265, 1265, 1265, 1265, 480: 1265, 1265, 1265, 1265, 3350, 1265, 1265, 1265, 489: 1265, 1265, 1265, 493: 1265, 1265, 496: 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 506: 1265, 1265, 509: 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 531: 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 1265, 565: 1265, 1265, 594: 1265}, - {1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 474: 1266, 1266, 1266, 1266, 1266, 480: 1266, 1266, 1266, 1266, 3350, 1266, 1266, 1266, 489: 1266, 1266, 1266, 493: 1266, 1266, 496: 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 506: 1266, 1266, 509: 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 531: 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1266, 565: 1266, 1266, 594: 1266}, - {475: 3987}, - {475: 3986}, - {1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 474: 1246, 1246, 1246, 1246, 1246, 480: 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 489: 1246, 1246, 1246, 493: 1246, 1246, 496: 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 506: 1246, 1246, 509: 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 531: 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 565: 1246, 1246, 594: 1246}, + {104, 104, 58: 104, 491: 104, 104, 494: 104, 500: 104, 104, 508: 104, 104, 511: 104, 526: 104, 679: 104, 806: 104, 811: 104, 817: 104, 104}, + {103, 103, 58: 103, 491: 103, 103, 494: 103, 500: 103, 103, 508: 103, 103, 511: 103, 526: 103, 679: 103, 806: 103, 811: 103, 817: 103, 103}, + {102, 102, 58: 102, 491: 102, 102, 494: 102, 500: 102, 102, 508: 102, 102, 511: 102, 526: 102, 679: 102, 806: 102, 811: 102, 817: 102, 102}, + {101, 101, 58: 101, 491: 101, 101, 494: 101, 500: 101, 101, 508: 101, 101, 511: 101, 526: 101, 679: 101, 806: 101, 811: 101, 817: 101, 101}, + {493: 4062, 596: 4063, 598: 4064, 876: 4066}, // 1450 - {1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 474: 1247, 1247, 1247, 1247, 1247, 480: 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 489: 1247, 1247, 1247, 493: 1247, 1247, 496: 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 506: 1247, 1247, 509: 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 531: 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 565: 1247, 1247, 594: 1247}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3989, 2762, 2763, 2761}, - {1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 3990, 1278, 1278, 1278, 1278, 1278, 480: 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 489: 1278, 1278, 1278, 493: 1278, 1278, 496: 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 506: 1278, 1278, 509: 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 531: 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 565: 1278, 1278, 594: 1278, 652: 3785, 656: 1278, 1278}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 3991}, - {49: 3992}, + {105, 105, 58: 105, 491: 105, 105, 494: 105, 500: 105, 105, 508: 105, 105, 511: 105, 526: 105, 679: 105, 806: 105, 811: 105, 817: 105, 105}, + {681: 4068}, + {493: 4062, 596: 4063, 598: 4064, 876: 4069}, + {106, 106, 58: 106, 491: 106, 106, 494: 106, 500: 106, 106, 508: 106, 106, 511: 106, 526: 106, 679: 106, 806: 106, 811: 106, 817: 106, 106}, + {493: 4062, 596: 4063, 598: 4064, 876: 4071}, // 1455 - {1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 474: 1113, 1113, 1113, 1113, 1113, 480: 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 489: 1113, 1113, 1113, 493: 1113, 1113, 496: 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 506: 1113, 1113, 509: 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 531: 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 565: 1113, 1113, 594: 1113}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 3994}, - {485: 3707}, - {1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 474: 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 496: 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 506: 1317, 1317, 509: 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 531: 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 1317, 565: 1317, 1317, 581: 1317, 590: 1317, 1317, 594: 1317, 642: 1317, 1317, 1317, 1317}, - {1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 474: 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 496: 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 506: 1314, 1314, 509: 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 531: 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 565: 1314, 1314, 581: 1314, 590: 1314, 1314, 594: 1314, 642: 1314, 1314, 1314, 1314}, + {107, 107, 58: 107, 491: 107, 107, 494: 107, 500: 107, 107, 508: 107, 107, 511: 107, 526: 107, 679: 107, 806: 107, 811: 107, 817: 107, 107}, + {109, 109, 58: 109, 491: 109, 109, 494: 109, 500: 109, 109, 508: 109, 109, 511: 109, 526: 109, 679: 109, 806: 109, 811: 109, 817: 109, 109}, + {884, 884, 58: 884, 491: 884, 494: 884, 500: 884, 884, 509: 884, 511: 884}, + {98, 98, 58: 98, 491: 98, 98, 494: 98, 500: 98, 98, 508: 98, 98, 511: 98, 526: 98, 806: 98, 1342: 4075, 4076}, + {96, 96, 58: 96, 491: 96, 96, 494: 96, 500: 96, 96, 508: 96, 96, 511: 96, 526: 96, 806: 4080, 1277: 4079}, // 1460 - {1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 474: 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 496: 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 506: 1313, 1313, 509: 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 531: 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 565: 1313, 1313, 581: 1313, 590: 1313, 1313, 594: 1313, 642: 1313, 1313, 1313, 1313}, - {1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 474: 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 496: 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 506: 1311, 1311, 509: 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 531: 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 1311, 565: 1311, 1311, 581: 1311, 590: 1311, 1311, 594: 1311, 642: 1311, 1311, 1311, 1311}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 4001, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4000}, - {49: 4005, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4002}, + {681: 4077}, + {493: 4062, 596: 4063, 598: 4064, 876: 4078}, + {97, 97, 58: 97, 491: 97, 97, 494: 97, 500: 97, 97, 508: 97, 97, 511: 97, 526: 97, 806: 97}, + {99, 99, 58: 99, 491: 99, 99, 494: 99, 500: 99, 99, 508: 99, 99, 511: 99, 526: 99}, + {681: 4081}, // 1465 - {49: 4003, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 4004}, - {1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 474: 1121, 1121, 1121, 1121, 1121, 480: 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 489: 1121, 1121, 1121, 493: 1121, 1121, 496: 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 506: 1121, 1121, 509: 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 531: 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 565: 1121, 1121, 594: 1121}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 4006}, - {1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 474: 1122, 1122, 1122, 1122, 1122, 480: 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 489: 1122, 1122, 1122, 493: 1122, 1122, 496: 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 506: 1122, 1122, 509: 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 531: 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 565: 1122, 1122, 594: 1122}, + {493: 4062, 596: 4063, 598: 4064, 876: 4082}, + {95, 95, 58: 95, 491: 95, 95, 494: 95, 500: 95, 95, 508: 95, 95, 511: 95, 526: 95}, + {880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 497: 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 508: 880, 880, 511: 880, 880, 880, 515: 880, 880, 880, 880, 880, 880, 880, 523: 880, 880, 526: 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 550: 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 584: 880, 880, 880, 588: 880, 616: 880, 665: 880, 674: 880, 761: 880}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4085}, + {9: 1983, 58: 4086, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 1470 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 4009, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4008}, - {9: 4019, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4010}, - {9: 4011, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 4013, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4012}, + {1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 493: 1299, 1299, 1299, 497: 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 508: 1299, 1299, 511: 1299, 1299, 1299, 516: 1299, 1299, 1299, 1299, 1299, 1299, 523: 1299, 1299, 526: 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 550: 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 584: 1299, 1299, 1299, 616: 1299}, + {1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 493: 1300, 1300, 1300, 497: 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 508: 1300, 1300, 511: 1300, 1300, 1300, 516: 1300, 1300, 1300, 1300, 1300, 1300, 523: 1300, 1300, 526: 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 550: 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 584: 1300, 1300, 1300, 616: 1300}, + {1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 493: 1302, 1302, 1302, 497: 1302, 1302, 3457, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 508: 1302, 1302, 511: 1302, 1302, 1302, 516: 1302, 1302, 1302, 1302, 1302, 1302, 523: 1302, 1302, 526: 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 550: 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 584: 1302, 1302, 1302, 616: 1302}, + {1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 493: 1304, 1304, 1304, 497: 1304, 1304, 3457, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 508: 1304, 1304, 511: 1304, 1304, 1304, 516: 1304, 1304, 1304, 1304, 1304, 1304, 523: 1304, 1304, 526: 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 550: 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 584: 1304, 1304, 1304, 616: 1304}, + {1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 493: 1305, 1305, 1305, 497: 1305, 1305, 3457, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 508: 1305, 1305, 511: 1305, 1305, 1305, 516: 1305, 1305, 1305, 1305, 1305, 1305, 523: 1305, 1305, 526: 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 550: 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 584: 1305, 1305, 1305, 616: 1305}, // 1475 - {49: 4017, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4014}, - {49: 4015, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 4016}, - {1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 474: 1117, 1117, 1117, 1117, 1117, 480: 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 489: 1117, 1117, 1117, 493: 1117, 1117, 496: 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 506: 1117, 1117, 509: 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 531: 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 565: 1117, 1117, 594: 1117}, + {1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 493: 1306, 1306, 1306, 497: 1306, 1306, 3457, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 508: 1306, 1306, 511: 1306, 1306, 1306, 516: 1306, 1306, 1306, 1306, 1306, 1306, 523: 1306, 1306, 526: 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 550: 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 584: 1306, 1306, 1306, 616: 1306}, + {1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 493: 1307, 1307, 1307, 497: 1307, 1307, 3457, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 508: 1307, 1307, 511: 1307, 1307, 1307, 516: 1307, 1307, 1307, 1307, 1307, 1307, 523: 1307, 1307, 526: 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 550: 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307, 584: 1307, 1307, 1307, 616: 1307}, + {493: 4096}, + {493: 4095}, + {1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 493: 1287, 1287, 1287, 497: 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 508: 1287, 1287, 511: 1287, 1287, 1287, 516: 1287, 1287, 1287, 1287, 1287, 1287, 523: 1287, 1287, 526: 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 550: 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 584: 1287, 1287, 1287, 616: 1287}, // 1480 - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 4018}, - {1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 474: 1119, 1119, 1119, 1119, 1119, 480: 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 489: 1119, 1119, 1119, 493: 1119, 1119, 496: 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 506: 1119, 1119, 509: 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 531: 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 1119, 565: 1119, 1119, 594: 1119}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 651: 4021, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4020}, - {49: 4025, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4022}, + {1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 493: 1288, 1288, 1288, 497: 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 508: 1288, 1288, 511: 1288, 1288, 1288, 516: 1288, 1288, 1288, 1288, 1288, 1288, 523: 1288, 1288, 526: 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 550: 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 584: 1288, 1288, 1288, 616: 1288}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4098, 2850, 688: 2851, 2849}, + {1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 4099, 1319, 1319, 1319, 497: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 508: 1319, 1319, 511: 1319, 1319, 1319, 516: 1319, 1319, 1319, 1319, 1319, 1319, 523: 1319, 1319, 526: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 550: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 584: 1319, 1319, 1319, 616: 1319, 672: 3892, 676: 1319, 1319}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 4100}, + {58: 4101}, // 1485 - {49: 4023, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 4024}, - {1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 474: 1118, 1118, 1118, 1118, 1118, 480: 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 489: 1118, 1118, 1118, 493: 1118, 1118, 496: 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 506: 1118, 1118, 509: 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 531: 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 565: 1118, 1118, 594: 1118}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 4026}, - {1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 474: 1120, 1120, 1120, 1120, 1120, 480: 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 489: 1120, 1120, 1120, 493: 1120, 1120, 496: 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 506: 1120, 1120, 509: 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 531: 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 565: 1120, 1120, 594: 1120}, + {1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 493: 1152, 1152, 1152, 497: 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 508: 1152, 1152, 511: 1152, 1152, 1152, 516: 1152, 1152, 1152, 1152, 1152, 1152, 523: 1152, 1152, 526: 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 550: 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 584: 1152, 1152, 1152, 616: 1152}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 4103}, + {504: 3814}, + {1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 493: 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 516: 1358, 1358, 1358, 1358, 1358, 1358, 523: 1358, 1358, 526: 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 550: 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 584: 1358, 1358, 1358, 600: 1358, 607: 1358, 613: 1358, 616: 1358, 662: 1358, 1358, 1358, 666: 1358}, + {1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 493: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 516: 1355, 1355, 1355, 1355, 1355, 1355, 523: 1355, 1355, 526: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 550: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 584: 1355, 1355, 1355, 600: 1355, 607: 1355, 613: 1355, 616: 1355, 662: 1355, 1355, 1355, 666: 1355}, // 1490 - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 796: 4028}, - {9: 4029}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4030}, - {9: 4031, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4032}, + {1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 493: 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 516: 1354, 1354, 1354, 1354, 1354, 1354, 523: 1354, 1354, 526: 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 550: 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 584: 1354, 1354, 1354, 600: 1354, 607: 1354, 613: 1354, 616: 1354, 662: 1354, 1354, 1354, 666: 1354}, + {1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 493: 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 516: 1352, 1352, 1352, 1352, 1352, 1352, 523: 1352, 1352, 526: 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 550: 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1352, 584: 1352, 1352, 1352, 600: 1352, 607: 1352, 613: 1352, 616: 1352, 662: 1352, 1352, 1352, 666: 1352}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 4110, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4109}, + {58: 4114, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4111}, // 1495 - {49: 4033, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 474: 1167, 1167, 1167, 1167, 1167, 480: 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 489: 1167, 1167, 1167, 493: 1167, 1167, 496: 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 506: 1167, 1167, 509: 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 531: 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 565: 1167, 1167, 594: 1167}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 796: 4035}, - {9: 4036}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4037}, + {58: 4112, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 4113}, + {1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 493: 1160, 1160, 1160, 497: 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 508: 1160, 1160, 511: 1160, 1160, 1160, 516: 1160, 1160, 1160, 1160, 1160, 1160, 523: 1160, 1160, 526: 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 550: 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 584: 1160, 1160, 1160, 616: 1160}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 4115}, + {1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 493: 1161, 1161, 1161, 497: 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 508: 1161, 1161, 511: 1161, 1161, 1161, 516: 1161, 1161, 1161, 1161, 1161, 1161, 523: 1161, 1161, 526: 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 550: 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 584: 1161, 1161, 1161, 616: 1161}, // 1500 - {9: 4038, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4039}, - {49: 4040, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 474: 1168, 1168, 1168, 1168, 1168, 480: 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 489: 1168, 1168, 1168, 493: 1168, 1168, 496: 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 506: 1168, 1168, 509: 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 531: 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 565: 1168, 1168, 594: 1168}, - {178: 4044, 4043, 199: 4046, 4045, 1224: 4042}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 4118, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4117}, + {9: 4128, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4119}, + {9: 4120, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 4122, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4121}, // 1505 - {9: 4047}, - {9: 1157}, - {9: 1156}, - {9: 1155}, - {9: 1154}, + {58: 4126, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4123}, + {58: 4124, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 4125}, + {1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 493: 1156, 1156, 1156, 497: 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 508: 1156, 1156, 511: 1156, 1156, 1156, 516: 1156, 1156, 1156, 1156, 1156, 1156, 523: 1156, 1156, 526: 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 550: 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 584: 1156, 1156, 1156, 616: 1156}, // 1510 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4048}, - {49: 4049, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 474: 1174, 1174, 1174, 1174, 1174, 480: 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 489: 1174, 1174, 1174, 493: 1174, 1174, 496: 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 506: 1174, 1174, 509: 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 531: 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 1174, 565: 1174, 1174, 594: 1174}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4051}, - {9: 4052}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 4127}, + {1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 493: 1158, 1158, 1158, 497: 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 508: 1158, 1158, 511: 1158, 1158, 1158, 516: 1158, 1158, 1158, 1158, 1158, 1158, 523: 1158, 1158, 526: 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 550: 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 584: 1158, 1158, 1158, 616: 1158}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 671: 4130, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4129}, + {58: 4134, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4131}, // 1515 - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 4054}, - {1974, 1974, 6: 1974, 1974, 1974, 1974, 15: 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 72: 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 105: 1974, 128: 1974, 1974, 1974, 1974, 479: 1974, 1974, 484: 1974, 493: 1974, 498: 1974, 501: 1974, 503: 1974, 505: 1974, 647: 1974, 649: 1974, 655: 1974}, - {49: 4060}, - {31, 31, 6: 31, 31, 31, 15: 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 49: 31, 72: 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 479: 31, 31, 484: 31, 503: 31, 505: 31, 647: 31, 649: 31, 655: 31}, - {508: 2736, 733: 4053, 763: 4059}, + {58: 4132, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 4133}, + {1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 493: 1157, 1157, 1157, 497: 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 508: 1157, 1157, 511: 1157, 1157, 1157, 516: 1157, 1157, 1157, 1157, 1157, 1157, 523: 1157, 1157, 526: 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 550: 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 584: 1157, 1157, 1157, 616: 1157}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 4135}, + {1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 493: 1159, 1159, 1159, 497: 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 508: 1159, 1159, 511: 1159, 1159, 1159, 516: 1159, 1159, 1159, 1159, 1159, 1159, 523: 1159, 1159, 526: 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 550: 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 584: 1159, 1159, 1159, 616: 1159}, // 1520 - {508: 2736, 733: 4058}, - {29, 29, 6: 29, 29, 29, 15: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 49: 29, 72: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 479: 29, 29, 484: 29, 503: 29, 505: 29, 647: 29, 649: 29, 655: 29}, - {30, 30, 6: 30, 30, 30, 15: 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 49: 30, 72: 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 479: 30, 30, 484: 30, 503: 30, 505: 30, 647: 30, 649: 30, 655: 30}, - {1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 474: 1145, 1145, 1145, 1145, 1145, 480: 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 489: 1145, 1145, 1145, 493: 1145, 1145, 496: 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 506: 1145, 1145, 509: 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 531: 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 565: 1145, 1145, 594: 1145}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4062}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 813: 4137}, + {9: 4138}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4139}, + {9: 4140, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4141}, // 1525 - {49: 4063}, - {1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 474: 1146, 1146, 1146, 1146, 1146, 480: 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 489: 1146, 1146, 1146, 493: 1146, 1146, 496: 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 506: 1146, 1146, 509: 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 531: 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 565: 1146, 1146, 594: 1146}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4065}, - {49: 4066, 478: 4067, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 474: 1162, 1162, 1162, 1162, 1162, 480: 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 489: 1162, 1162, 1162, 493: 1162, 1162, 496: 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 506: 1162, 1162, 509: 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 531: 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 565: 1162, 1162, 594: 1162}, + {58: 4142, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 493: 1206, 1206, 1206, 497: 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 508: 1206, 1206, 511: 1206, 1206, 1206, 516: 1206, 1206, 1206, 1206, 1206, 1206, 523: 1206, 1206, 526: 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 550: 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 584: 1206, 1206, 1206, 616: 1206}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 813: 4144}, + {9: 4145}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4146}, // 1530 - {505: 3811, 530: 4069, 647: 3810, 901: 4068}, - {473: 3826, 764: 4072}, - {473: 3826, 764: 4070}, - {49: 4071}, - {1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 474: 1160, 1160, 1160, 1160, 1160, 480: 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 489: 1160, 1160, 1160, 493: 1160, 1160, 496: 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 506: 1160, 1160, 509: 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 531: 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 565: 1160, 1160, 594: 1160}, + {9: 4147, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4148}, + {58: 4149, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 493: 1207, 1207, 1207, 497: 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 508: 1207, 1207, 511: 1207, 1207, 1207, 516: 1207, 1207, 1207, 1207, 1207, 1207, 523: 1207, 1207, 526: 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 550: 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 584: 1207, 1207, 1207, 616: 1207}, + {191: 4153, 4152, 214: 4154, 238: 4155, 1256: 4151}, // 1535 - {49: 4073}, - {1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 474: 1161, 1161, 1161, 1161, 1161, 480: 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 489: 1161, 1161, 1161, 493: 1161, 1161, 496: 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 506: 1161, 1161, 509: 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 531: 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 565: 1161, 1161, 594: 1161}, - {1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 474: 1184, 1184, 1184, 1184, 1184, 480: 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 489: 1184, 1184, 1184, 493: 1184, 1184, 496: 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 506: 1184, 1184, 509: 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 531: 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 565: 1184, 1184, 594: 1184}, - {1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 474: 1185, 1185, 1185, 1185, 1185, 480: 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 489: 1185, 1185, 1185, 493: 1185, 1185, 496: 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 506: 1185, 1185, 509: 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 531: 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 565: 1185, 1185, 594: 1185}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 4077}, + {9: 4156}, + {9: 1196}, + {9: 1195}, + {9: 1194}, + {9: 1193}, // 1540 - {49: 4078}, - {1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 474: 1181, 1181, 1181, 1181, 1181, 480: 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 489: 1181, 1181, 1181, 493: 1181, 1181, 496: 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 506: 1181, 1181, 509: 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 531: 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 565: 1181, 1181, 594: 1181}, - {1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 474: 1186, 1186, 1186, 1186, 1186, 480: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 489: 1186, 1186, 1186, 493: 1186, 1186, 496: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 506: 1186, 1186, 509: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 531: 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 565: 1186, 1186, 594: 1186}, - {2: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 10: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 50: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 473: 1241, 475: 1241, 1241, 1241, 479: 1241, 482: 1241, 1241, 485: 1241, 1241, 1241, 492: 1241, 495: 1241, 504: 1241, 1241, 508: 1241, 530: 1241, 564: 1241, 567: 1241, 1241, 570: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 582: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 592: 1241, 1241, 595: 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 648: 1241, 651: 3546, 745: 3544, 3545, 784: 3547, 787: 3548, 816: 4081, 818: 3549}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4082}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4157}, + {58: 4158, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 493: 1213, 1213, 1213, 497: 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 508: 1213, 1213, 511: 1213, 1213, 1213, 516: 1213, 1213, 1213, 1213, 1213, 1213, 523: 1213, 1213, 526: 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 550: 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 584: 1213, 1213, 1213, 616: 1213}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4160}, + {9: 4161}, // 1545 - {49: 4083, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 474: 959, 959, 959, 959, 959, 480: 959, 959, 959, 959, 959, 959, 959, 959, 489: 959, 959, 959, 493: 959, 959, 496: 959, 959, 959, 959, 959, 959, 959, 959, 506: 959, 959, 509: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 531: 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 565: 959, 959, 594: 959, 742: 3362, 747: 3554, 765: 4084}, - {1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 474: 1143, 1143, 1143, 1143, 1143, 480: 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 489: 1143, 1143, 1143, 493: 1143, 1143, 496: 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 506: 1143, 1143, 509: 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 531: 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 565: 1143, 1143, 594: 1143}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 4086}, - {49: 4087}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 4163}, + {2035, 2035, 6: 2035, 2035, 2035, 2035, 15: 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 58: 2035, 79: 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 2035, 111: 2035, 143: 2035, 2035, 2035, 2035, 496: 2035, 499: 2035, 2035, 512: 2035, 514: 2035, 519: 2035, 521: 2035, 524: 2035, 667: 2035, 2035, 675: 2035}, + {58: 4169}, + {32, 32, 6: 32, 32, 32, 15: 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 58: 32, 79: 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 496: 32, 499: 32, 32, 514: 32, 524: 32, 667: 32, 32, 675: 32}, + {525: 2824, 755: 4162, 784: 4168}, // 1550 - {1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 474: 1114, 1114, 1114, 1114, 1114, 480: 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 489: 1114, 1114, 1114, 493: 1114, 1114, 496: 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 506: 1114, 1114, 509: 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 531: 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 565: 1114, 1114, 594: 1114}, - {149: 2314, 175: 2314, 194: 2314, 492: 2314, 518: 2314, 544: 2314, 563: 2314, 565: 2314, 2314, 571: 2314, 2314, 583: 2314}, - {149: 2313, 175: 2313, 194: 2313, 492: 2313, 518: 2313, 544: 2313, 563: 2313, 565: 2313, 2313, 571: 2313, 2313, 583: 2313}, - {2: 1901, 1901, 1901, 1901, 1901, 1901, 1901, 10: 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 50: 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 473: 1901, 475: 1901, 1901, 479: 1901, 482: 1901, 1901, 485: 1901, 1901, 1901, 492: 1901, 495: 1901, 504: 1901, 1901, 508: 1901, 530: 1901, 564: 1901, 567: 1901, 1901, 570: 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 582: 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 592: 1901, 1901, 595: 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901, 1901}, - {518: 4115, 544: 4114, 563: 4113, 565: 4099, 4100, 1112: 4116}, + {525: 2824, 755: 4167}, + {30, 30, 6: 30, 30, 30, 15: 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 58: 30, 79: 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 496: 30, 499: 30, 30, 514: 30, 524: 30, 667: 30, 30, 675: 30}, + {31, 31, 6: 31, 31, 31, 15: 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 58: 31, 79: 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 496: 31, 499: 31, 31, 514: 31, 524: 31, 667: 31, 31, 675: 31}, + {1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 493: 1184, 1184, 1184, 497: 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 508: 1184, 1184, 511: 1184, 1184, 1184, 516: 1184, 1184, 1184, 1184, 1184, 1184, 523: 1184, 1184, 526: 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 550: 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 1184, 584: 1184, 1184, 1184, 616: 1184}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4171}, // 1555 - {473: 1897}, - {2: 1895, 1895, 1895, 1895, 1895, 1895, 1895, 10: 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 50: 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 473: 1895, 475: 1895, 1895, 479: 1895, 482: 1895, 1895, 485: 1895, 1895, 1895, 492: 1895, 495: 1895, 504: 1895, 1895, 508: 1895, 530: 1895, 564: 1895, 567: 1895, 1895, 570: 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 582: 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 592: 1895, 1895, 595: 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1895}, - {2: 1893, 1893, 1893, 1893, 1893, 1893, 1893, 10: 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 50: 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 473: 1893, 475: 1893, 1893, 479: 1893, 482: 1893, 1893, 485: 1893, 1893, 1893, 492: 1893, 495: 1893, 504: 1893, 1893, 508: 1893, 530: 1893, 564: 1893, 567: 1893, 1893, 570: 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 582: 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 592: 1893, 1893, 595: 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893, 1893}, - {473: 4109, 709: 4110}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 4106}, + {58: 4172}, + {1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 493: 1185, 1185, 1185, 497: 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 508: 1185, 1185, 511: 1185, 1185, 1185, 516: 1185, 1185, 1185, 1185, 1185, 1185, 523: 1185, 1185, 526: 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 550: 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 584: 1185, 1185, 1185, 616: 1185}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4174}, + {58: 4175, 498: 4176, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 493: 1201, 1201, 1201, 497: 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 508: 1201, 1201, 511: 1201, 1201, 1201, 516: 1201, 1201, 1201, 1201, 1201, 1201, 523: 1201, 1201, 526: 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 550: 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 584: 1201, 1201, 1201, 616: 1201}, // 1560 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 4102, 3253, 3334, 3252, 3249}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 4101, 3253, 3334, 3252, 3249}, - {2: 1882, 1882, 1882, 1882, 1882, 1882, 1882, 10: 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 50: 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 473: 1882, 475: 1882, 1882, 479: 1882, 482: 1882, 1882, 485: 1882, 1882, 1882, 492: 1882, 495: 1882, 504: 1882, 1882, 508: 1882, 530: 1882, 564: 1882, 567: 1882, 1882, 570: 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 582: 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 592: 1882, 1882, 595: 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882, 1882}, - {2: 1881, 1881, 1881, 1881, 1881, 1881, 1881, 10: 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 50: 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 473: 1881, 475: 1881, 1881, 479: 1881, 482: 1881, 1881, 485: 1881, 1881, 1881, 492: 1881, 495: 1881, 504: 1881, 1881, 508: 1881, 530: 1881, 564: 1881, 567: 1881, 1881, 570: 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 582: 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 592: 1881, 1881, 595: 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881, 1881}, - {1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 474: 1884, 1884, 478: 1884, 480: 1884, 1884, 1884, 1884, 3350, 489: 1884, 1884, 1884, 493: 1884, 1884, 496: 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 506: 1884, 1884, 509: 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 519: 1884, 521: 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 531: 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 545: 1884, 1884, 555: 1884, 1884, 1884, 1884, 1884, 1884, 1884, 1884, 594: 3351}, + {514: 3918, 549: 4178, 667: 3917, 926: 4177}, + {492: 3933, 786: 4181}, + {492: 3933, 786: 4179}, + {58: 4180}, + {1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 493: 1199, 1199, 1199, 497: 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 508: 1199, 1199, 511: 1199, 1199, 1199, 516: 1199, 1199, 1199, 1199, 1199, 1199, 523: 1199, 1199, 526: 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 550: 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 1199, 584: 1199, 1199, 1199, 616: 1199}, // 1565 - {1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 4104, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 474: 1880, 1880, 478: 1880, 480: 1880, 1880, 1880, 1880, 3350, 489: 1880, 1880, 1880, 493: 1880, 1880, 496: 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 506: 1880, 1880, 509: 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 519: 1880, 521: 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 531: 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 545: 1880, 1880, 555: 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 594: 3351, 1242: 4103}, - {1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 474: 1885, 1885, 478: 1885, 480: 1885, 1885, 1885, 1885, 489: 1885, 1885, 1885, 493: 1885, 1885, 496: 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 506: 1885, 1885, 509: 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 519: 1885, 521: 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 531: 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885, 545: 1885, 1885, 555: 1885, 1885, 1885, 1885, 1885, 1885, 1885, 1885}, - {475: 4105}, - {1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 474: 1879, 1879, 478: 1879, 480: 1879, 1879, 1879, 1879, 489: 1879, 1879, 1879, 493: 1879, 1879, 496: 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 506: 1879, 1879, 509: 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 519: 1879, 521: 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 531: 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879, 545: 1879, 1879, 555: 1879, 1879, 1879, 1879, 1879, 1879, 1879, 1879}, - {485: 3686, 3687, 3692, 507: 4107, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, + {58: 4182}, + {1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 493: 1200, 1200, 1200, 497: 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 508: 1200, 1200, 511: 1200, 1200, 1200, 516: 1200, 1200, 1200, 1200, 1200, 1200, 523: 1200, 1200, 526: 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 550: 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 584: 1200, 1200, 1200, 616: 1200}, + {1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 493: 1223, 1223, 1223, 497: 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 508: 1223, 1223, 511: 1223, 1223, 1223, 516: 1223, 1223, 1223, 1223, 1223, 1223, 523: 1223, 1223, 526: 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 550: 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 584: 1223, 1223, 1223, 616: 1223}, + {1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 493: 1224, 1224, 1224, 497: 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 508: 1224, 1224, 511: 1224, 1224, 1224, 516: 1224, 1224, 1224, 1224, 1224, 1224, 523: 1224, 1224, 526: 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 550: 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 584: 1224, 1224, 1224, 616: 1224}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 4186}, // 1570 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 4108}, - {1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 474: 1886, 1886, 478: 1886, 480: 1886, 1886, 1886, 1886, 489: 1886, 1886, 1886, 493: 1886, 1886, 496: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 506: 1886, 1886, 509: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 519: 1886, 521: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 531: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 545: 1886, 1886, 555: 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 2587, 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3879, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 2585, 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 646: 2581, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3878, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 748: 3881, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 3883, 3882, 778: 4111}, - {1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 474: 1887, 1887, 478: 1887, 480: 1887, 1887, 1887, 1887, 489: 1887, 1887, 1887, 493: 1887, 1887, 496: 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 506: 1887, 1887, 509: 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 519: 1887, 521: 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 531: 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887, 545: 1887, 1887, 555: 1887, 1887, 1887, 1887, 1887, 1887, 1887, 1887}, - {9: 3590, 49: 4112}, + {58: 4187}, + {1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 493: 1220, 1220, 1220, 497: 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 508: 1220, 1220, 511: 1220, 1220, 1220, 516: 1220, 1220, 1220, 1220, 1220, 1220, 523: 1220, 1220, 526: 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 550: 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220, 584: 1220, 1220, 1220, 616: 1220}, + {1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 493: 1225, 1225, 1225, 497: 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 508: 1225, 1225, 511: 1225, 1225, 1225, 516: 1225, 1225, 1225, 1225, 1225, 1225, 523: 1225, 1225, 526: 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 550: 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 584: 1225, 1225, 1225, 616: 1225}, + {2: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 10: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 59: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 492: 1280, 1280, 495: 1280, 1280, 1280, 502: 1280, 1280, 1280, 1280, 1280, 510: 1280, 514: 1280, 1280, 522: 1280, 525: 1280, 549: 1280, 583: 1280, 587: 1280, 589: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 601: 1280, 1280, 1280, 1280, 1280, 1280, 608: 1280, 1280, 1280, 1280, 1280, 614: 1280, 1280, 617: 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 669: 1280, 671: 3653, 767: 3651, 3652, 808: 3654, 810: 3655, 839: 4190, 3656}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4191}, // 1575 - {1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 474: 1888, 1888, 478: 1888, 480: 1888, 1888, 1888, 1888, 489: 1888, 1888, 1888, 493: 1888, 1888, 496: 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 506: 1888, 1888, 509: 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 519: 1888, 521: 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 531: 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 545: 1888, 1888, 555: 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888}, - {2: 1900, 1900, 1900, 1900, 1900, 1900, 1900, 10: 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 50: 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 473: 1900, 475: 1900, 1900, 479: 1900, 482: 1900, 1900, 485: 1900, 1900, 1900, 492: 1900, 495: 1900, 504: 1900, 1900, 508: 1900, 530: 1900, 564: 1900, 567: 1900, 1900, 570: 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 582: 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 592: 1900, 1900, 595: 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900, 1900}, - {473: 1896}, - {2: 1894, 1894, 1894, 1894, 1894, 1894, 1894, 10: 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 50: 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 473: 1894, 475: 1894, 1894, 479: 1894, 482: 1894, 1894, 485: 1894, 1894, 1894, 492: 1894, 495: 1894, 504: 1894, 1894, 508: 1894, 530: 1894, 564: 1894, 567: 1894, 1894, 570: 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 582: 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 592: 1894, 1894, 595: 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894}, - {2: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 10: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 50: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 473: 1892, 475: 1892, 1892, 479: 1892, 482: 1892, 1892, 485: 1892, 1892, 1892, 492: 1892, 495: 1892, 504: 1892, 1892, 508: 1892, 530: 1892, 564: 1892, 567: 1892, 1892, 570: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 582: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 592: 1892, 1892, 595: 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892}, + {58: 4192, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 493: 998, 998, 998, 497: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 508: 998, 998, 511: 998, 998, 998, 516: 998, 998, 998, 998, 998, 998, 523: 998, 998, 526: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 550: 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 998, 584: 998, 998, 998, 616: 998, 764: 3469, 769: 3661, 787: 4193}, + {1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 493: 1182, 1182, 1182, 497: 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 508: 1182, 1182, 511: 1182, 1182, 1182, 516: 1182, 1182, 1182, 1182, 1182, 1182, 523: 1182, 1182, 526: 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 550: 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 1182, 584: 1182, 1182, 1182, 616: 1182}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 4195}, + {58: 4196}, // 1580 - {175: 4140, 492: 4141, 571: 4139, 4138}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 4132, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 4133, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 4131, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 651: 4134, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 4129, 1174: 4130}, - {2: 1909, 1909, 1909, 1909, 1909, 1909, 1909, 10: 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 50: 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 473: 1909, 475: 1909, 1909, 479: 1909, 482: 1909, 1909, 485: 1909, 1909, 1909, 492: 1909, 495: 1909, 504: 1909, 1909, 508: 1909, 530: 1909, 564: 1909, 567: 1909, 1909, 570: 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 582: 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 592: 1909, 1909, 595: 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 1909, 651: 1909}, - {2: 1908, 1908, 1908, 1908, 1908, 1908, 1908, 10: 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 50: 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 473: 1908, 475: 1908, 1908, 479: 1908, 482: 1908, 1908, 485: 1908, 1908, 1908, 492: 1908, 495: 1908, 504: 1908, 1908, 508: 1908, 530: 1908, 564: 1908, 567: 1908, 1908, 570: 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 582: 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 592: 1908, 1908, 595: 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 1908, 651: 1908}, - {2: 1907, 1907, 1907, 1907, 1907, 1907, 1907, 10: 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 50: 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 473: 1907, 475: 1907, 1907, 479: 1907, 482: 1907, 1907, 485: 1907, 1907, 1907, 492: 1907, 495: 1907, 504: 1907, 1907, 508: 1907, 530: 1907, 564: 1907, 567: 1907, 1907, 570: 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 582: 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 592: 1907, 1907, 595: 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 1907, 651: 1907}, + {1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 493: 1153, 1153, 1153, 497: 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 508: 1153, 1153, 511: 1153, 1153, 1153, 516: 1153, 1153, 1153, 1153, 1153, 1153, 523: 1153, 1153, 526: 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 550: 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 1153, 584: 1153, 1153, 1153, 616: 1153}, + {163: 2381, 188: 2381, 208: 2381, 510: 2381, 537: 2381, 564: 2381, 582: 2381, 584: 2381, 2381, 591: 2381, 2381, 603: 2381}, + {163: 2380, 188: 2380, 208: 2380, 510: 2380, 537: 2380, 564: 2380, 582: 2380, 584: 2380, 2380, 591: 2380, 2380, 603: 2380}, + {2: 1962, 1962, 1962, 1962, 1962, 1962, 1962, 10: 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 59: 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 492: 1962, 1962, 495: 1962, 1962, 502: 1962, 1962, 1962, 1962, 1962, 510: 1962, 514: 1962, 1962, 522: 1962, 525: 1962, 549: 1962, 583: 1962, 587: 1962, 589: 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 601: 1962, 1962, 1962, 1962, 1962, 1962, 608: 1962, 1962, 1962, 1962, 1962, 614: 1962, 1962, 617: 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962}, + {537: 4228, 564: 4227, 582: 4226, 584: 4209, 4210, 1142: 4229}, // 1585 - {2: 1906, 1906, 1906, 1906, 1906, 1906, 1906, 10: 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 50: 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 473: 1906, 475: 1906, 1906, 479: 1906, 482: 1906, 1906, 485: 1906, 1906, 1906, 492: 1906, 495: 1906, 504: 1906, 1906, 508: 1906, 530: 1906, 564: 1906, 567: 1906, 1906, 570: 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 582: 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 592: 1906, 1906, 595: 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 1906, 651: 1906}, - {2: 1905, 1905, 1905, 1905, 1905, 1905, 1905, 10: 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 50: 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 473: 1905, 475: 1905, 1905, 479: 1905, 482: 1905, 1905, 485: 1905, 1905, 1905, 492: 1905, 495: 1905, 504: 1905, 1905, 508: 1905, 530: 1905, 564: 1905, 567: 1905, 1905, 570: 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 582: 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 592: 1905, 1905, 595: 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 1905, 651: 1905}, - {2: 1904, 1904, 1904, 1904, 1904, 1904, 1904, 10: 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 50: 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 473: 1904, 475: 1904, 1904, 479: 1904, 482: 1904, 1904, 485: 1904, 1904, 1904, 492: 1904, 495: 1904, 504: 1904, 1904, 508: 1904, 530: 1904, 564: 1904, 567: 1904, 1904, 570: 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 582: 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 592: 1904, 1904, 595: 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 651: 1904}, - {2: 1903, 1903, 1903, 1903, 1903, 1903, 1903, 10: 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 50: 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 473: 1903, 475: 1903, 1903, 479: 1903, 482: 1903, 1903, 485: 1903, 1903, 1903, 492: 1903, 495: 1903, 504: 1903, 1903, 508: 1903, 530: 1903, 564: 1903, 567: 1903, 1903, 570: 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 582: 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 592: 1903, 1903, 595: 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 651: 1903}, - {2: 1902, 1902, 1902, 1902, 1902, 1902, 1902, 10: 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 50: 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 473: 1902, 475: 1902, 1902, 479: 1902, 482: 1902, 1902, 485: 1902, 1902, 1902, 492: 1902, 495: 1902, 504: 1902, 1902, 508: 1902, 530: 1902, 564: 1902, 567: 1902, 1902, 570: 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 582: 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 592: 1902, 1902, 595: 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 1902, 651: 1902}, + {492: 1958}, + {2: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 10: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 59: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 492: 1956, 1956, 495: 1956, 1956, 502: 1956, 1956, 1956, 1956, 1956, 510: 1956, 514: 1956, 1956, 522: 1956, 525: 1956, 549: 1956, 583: 1956, 587: 1956, 589: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 601: 1956, 1956, 1956, 1956, 1956, 1956, 608: 1956, 1956, 1956, 1956, 1956, 614: 1956, 1956, 617: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956}, + {2: 1954, 1954, 1954, 1954, 1954, 1954, 1954, 10: 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 59: 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 492: 1954, 1954, 495: 1954, 1954, 502: 1954, 1954, 1954, 1954, 1954, 510: 1954, 514: 1954, 1954, 522: 1954, 525: 1954, 549: 1954, 583: 1954, 587: 1954, 589: 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 601: 1954, 1954, 1954, 1954, 1954, 1954, 608: 1954, 1954, 1954, 1954, 1954, 614: 1954, 1954, 617: 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954}, + {492: 4222, 731: 4223}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 4219}, // 1590 - {175: 1899, 476: 4089, 4088, 492: 1899, 571: 1899, 1899, 810: 4128}, - {175: 1898, 492: 1898, 571: 1898, 1898}, - {1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 474: 1913, 1913, 478: 1913, 480: 1913, 1913, 1913, 1913, 489: 1913, 1913, 1913, 493: 1913, 1913, 496: 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 506: 1913, 1913, 509: 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 519: 1913, 521: 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 531: 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913, 545: 1913, 1913, 555: 1913, 1913, 1913, 1913, 1913, 1913, 1913, 1913}, - {473: 2588, 709: 4137}, - {748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 474: 748, 748, 748, 748, 748, 480: 748, 748, 748, 748, 748, 748, 748, 748, 489: 748, 748, 748, 493: 748, 748, 496: 748, 748, 748, 748, 748, 748, 748, 748, 506: 748, 748, 509: 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 531: 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 565: 748, 748, 594: 748, 659: 4135}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4215, 3360, 3441, 3359, 3356}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4214, 3360, 3441, 3359, 3356}, + {492: 4211}, + {2: 1942, 1942, 1942, 1942, 1942, 1942, 1942, 10: 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 59: 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 492: 1942, 1942, 495: 1942, 1942, 502: 1942, 1942, 1942, 1942, 1942, 510: 1942, 514: 1942, 1942, 522: 1942, 525: 1942, 549: 1942, 583: 1942, 587: 1942, 589: 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 601: 1942, 1942, 1942, 1942, 1942, 1942, 608: 1942, 1942, 1942, 1942, 1942, 614: 1942, 1942, 617: 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942}, + {2: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 10: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 59: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 492: 1941, 1941, 495: 1941, 1941, 502: 1941, 1941, 1941, 1941, 1941, 510: 1941, 514: 1941, 1941, 522: 1941, 525: 1941, 549: 1941, 583: 1941, 587: 1941, 589: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 601: 1941, 1941, 1941, 1941, 1941, 1941, 608: 1941, 1941, 1941, 1941, 1941, 614: 1941, 1941, 617: 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941, 1941}, // 1595 - {1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1891, 1714, 1714, 1714, 1714, 1714, 480: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 489: 1714, 1714, 1714, 493: 1714, 1714, 496: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 506: 1714, 1714, 509: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 531: 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 565: 1714, 1714, 594: 1714, 652: 1714, 656: 1714, 1714}, - {1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1890, 1713, 1713, 1713, 1713, 1713, 480: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 489: 1713, 1713, 1713, 493: 1713, 1713, 496: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 506: 1713, 1713, 509: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 531: 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 565: 1713, 1713, 594: 1713, 652: 1713, 656: 1713, 1713}, - {473: 1889}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 4136}, - {1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 474: 1911, 1911, 478: 1911, 480: 1911, 1911, 1911, 1911, 489: 1911, 1911, 1911, 493: 1911, 1911, 496: 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 506: 1911, 1911, 509: 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 519: 1911, 521: 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 531: 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911, 545: 1911, 1911, 555: 1911, 1911, 1911, 1911, 1911, 1911, 1911, 1911}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 4212, 3360, 3441, 3359, 3356}, + {58: 4213, 499: 3457, 616: 3458}, + {1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 493: 1944, 1944, 498: 1944, 500: 1944, 1944, 1944, 1944, 508: 1944, 1944, 511: 1944, 1944, 1944, 516: 1944, 1944, 1944, 1944, 1944, 1944, 523: 1944, 1944, 526: 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 538: 1944, 1944, 1944, 542: 1944, 1944, 1944, 1944, 1944, 1944, 1944, 550: 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 565: 1944, 574: 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944}, + {1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 493: 1945, 1945, 498: 1945, 3457, 1945, 1945, 1945, 1945, 508: 1945, 1945, 511: 1945, 1945, 1945, 516: 1945, 1945, 1945, 1945, 1945, 1945, 523: 1945, 1945, 526: 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 538: 1945, 1945, 1945, 542: 1945, 1945, 1945, 1945, 1945, 1945, 1945, 550: 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 565: 1945, 574: 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945, 616: 3458}, + {1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 4217, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 493: 1940, 1940, 498: 1940, 3457, 1940, 1940, 1940, 1940, 508: 1940, 1940, 511: 1940, 1940, 1940, 516: 1940, 1940, 1940, 1940, 1940, 1940, 523: 1940, 1940, 526: 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 538: 1940, 1940, 1940, 542: 1940, 1940, 1940, 1940, 1940, 1940, 1940, 550: 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 565: 1940, 574: 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 616: 3458, 1274: 4216}, // 1600 - {1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 474: 1912, 1912, 478: 1912, 480: 1912, 1912, 1912, 1912, 489: 1912, 1912, 1912, 493: 1912, 1912, 496: 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 506: 1912, 1912, 509: 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 519: 1912, 521: 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 531: 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912, 545: 1912, 1912, 555: 1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912}, - {1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 474: 1938, 1938, 478: 1938, 480: 1938, 1938, 1938, 1938, 489: 1938, 1938, 1938, 493: 1938, 1938, 496: 1938, 1938, 1938, 500: 1938, 1938, 1938, 1938, 506: 1938, 1938, 509: 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 519: 1938, 521: 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 531: 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 545: 1938, 1938}, - {1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 474: 1937, 1937, 478: 1937, 480: 1937, 1937, 1937, 1937, 489: 1937, 1937, 1937, 493: 1937, 1937, 496: 1937, 1937, 1937, 500: 1937, 1937, 1937, 1937, 506: 1937, 1937, 509: 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 519: 1937, 521: 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 531: 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 545: 1937, 1937}, - {1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 474: 1936, 1936, 478: 1936, 480: 1936, 1936, 1936, 1936, 489: 1936, 1936, 1936, 493: 1936, 1936, 496: 1936, 1936, 1936, 500: 1936, 1936, 1936, 1936, 506: 1936, 1936, 509: 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 519: 1936, 521: 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 531: 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936, 545: 1936, 1936}, - {1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 474: 1914, 1914, 478: 1914, 480: 1914, 1914, 1914, 1914, 489: 1914, 1914, 1914, 493: 1914, 1914, 496: 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 506: 1914, 1914, 509: 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 519: 1914, 521: 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 531: 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 545: 1914, 1914, 555: 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914}, + {1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 493: 1946, 1946, 498: 1946, 500: 1946, 1946, 1946, 1946, 508: 1946, 1946, 511: 1946, 1946, 1946, 516: 1946, 1946, 1946, 1946, 1946, 1946, 523: 1946, 1946, 526: 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 538: 1946, 1946, 1946, 542: 1946, 1946, 1946, 1946, 1946, 1946, 1946, 550: 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946, 565: 1946, 574: 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946}, + {493: 4218}, + {1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 493: 1939, 1939, 498: 1939, 500: 1939, 1939, 1939, 1939, 508: 1939, 1939, 511: 1939, 1939, 1939, 516: 1939, 1939, 1939, 1939, 1939, 1939, 523: 1939, 1939, 526: 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 538: 1939, 1939, 1939, 542: 1939, 1939, 1939, 1939, 1939, 1939, 1939, 550: 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 565: 1939, 574: 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939}, + {504: 3793, 3794, 3799, 527: 4220, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 4221}, // 1605 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 4145}, - {2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 473: 2337, 488: 2337, 493: 2337, 499: 2337, 505: 2337, 2337, 529: 2337, 2337, 2337, 647: 2337, 652: 4166, 669: 2337, 2337, 672: 2337, 677: 2337, 2337, 680: 2337, 2337, 2337, 2337, 2337, 2337, 688: 2337, 690: 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 705: 2337, 2337, 2337, 2337}, - {9: 2334, 49: 2334}, - {9: 4146, 49: 4147}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4165}, + {1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 493: 1947, 1947, 498: 1947, 500: 1947, 1947, 1947, 1947, 508: 1947, 1947, 511: 1947, 1947, 1947, 516: 1947, 1947, 1947, 1947, 1947, 1947, 523: 1947, 1947, 526: 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 538: 1947, 1947, 1947, 542: 1947, 1947, 1947, 1947, 1947, 1947, 1947, 550: 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947, 565: 1947, 574: 1947, 1947, 1947, 1947, 1947, 1947, 1947, 1947}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 2666, 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3988, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 2664, 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 665: 2660, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3987, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 770: 3990, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 3992, 3991, 801: 4224}, + {1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 493: 1948, 1948, 498: 1948, 500: 1948, 1948, 1948, 1948, 508: 1948, 1948, 511: 1948, 1948, 1948, 516: 1948, 1948, 1948, 1948, 1948, 1948, 523: 1948, 1948, 526: 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 538: 1948, 1948, 1948, 542: 1948, 1948, 1948, 1948, 1948, 1948, 1948, 550: 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 565: 1948, 574: 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948}, + {9: 3697, 58: 4225}, + {1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 493: 1949, 1949, 498: 1949, 500: 1949, 1949, 1949, 1949, 508: 1949, 1949, 511: 1949, 1949, 1949, 516: 1949, 1949, 1949, 1949, 1949, 1949, 523: 1949, 1949, 526: 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 538: 1949, 1949, 1949, 542: 1949, 1949, 1949, 1949, 1949, 1949, 1949, 550: 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 565: 1949, 574: 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949}, // 1610 - {310: 4148}, - {473: 4149}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 4150}, - {49: 1932, 474: 4153, 485: 3686, 3687, 3692, 520: 3688, 544: 4152, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685, 1222: 4151}, - {49: 4164}, + {2: 1961, 1961, 1961, 1961, 1961, 1961, 1961, 10: 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 59: 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 492: 1961, 1961, 495: 1961, 1961, 502: 1961, 1961, 1961, 1961, 1961, 510: 1961, 514: 1961, 1961, 522: 1961, 525: 1961, 549: 1961, 583: 1961, 587: 1961, 589: 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 601: 1961, 1961, 1961, 1961, 1961, 1961, 608: 1961, 1961, 1961, 1961, 1961, 614: 1961, 1961, 617: 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961}, + {492: 1957}, + {2: 1955, 1955, 1955, 1955, 1955, 1955, 1955, 10: 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 59: 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 492: 1955, 1955, 495: 1955, 1955, 502: 1955, 1955, 1955, 1955, 1955, 510: 1955, 514: 1955, 1955, 522: 1955, 525: 1955, 549: 1955, 583: 1955, 587: 1955, 589: 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 601: 1955, 1955, 1955, 1955, 1955, 1955, 608: 1955, 1955, 1955, 1955, 1955, 614: 1955, 1955, 617: 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955}, + {2: 1953, 1953, 1953, 1953, 1953, 1953, 1953, 10: 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 59: 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 492: 1953, 1953, 495: 1953, 1953, 502: 1953, 1953, 1953, 1953, 1953, 510: 1953, 514: 1953, 1953, 522: 1953, 525: 1953, 549: 1953, 583: 1953, 587: 1953, 589: 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 601: 1953, 1953, 1953, 1953, 1953, 1953, 608: 1953, 1953, 1953, 1953, 1953, 614: 1953, 1953, 617: 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953}, + {188: 4253, 510: 4254, 591: 4252, 4251}, // 1615 - {230: 4157, 519: 4156}, - {139: 4154}, - {254: 4155}, - {49: 1928}, - {355: 4159}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 4245, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 4246, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 4244, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 671: 4247, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 4242, 1207: 4243}, + {2: 1970, 1970, 1970, 1970, 1970, 1970, 1970, 10: 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 59: 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 492: 1970, 1970, 495: 1970, 1970, 502: 1970, 1970, 1970, 1970, 1970, 510: 1970, 514: 1970, 1970, 522: 1970, 525: 1970, 549: 1970, 583: 1970, 587: 1970, 589: 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 601: 1970, 1970, 1970, 1970, 1970, 1970, 608: 1970, 1970, 1970, 1970, 1970, 614: 1970, 1970, 617: 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 671: 1970}, + {2: 1969, 1969, 1969, 1969, 1969, 1969, 1969, 10: 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 59: 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 492: 1969, 1969, 495: 1969, 1969, 502: 1969, 1969, 1969, 1969, 1969, 510: 1969, 514: 1969, 1969, 522: 1969, 525: 1969, 549: 1969, 583: 1969, 587: 1969, 589: 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 601: 1969, 1969, 1969, 1969, 1969, 1969, 608: 1969, 1969, 1969, 1969, 1969, 614: 1969, 1969, 617: 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 671: 1969}, + {2: 1968, 1968, 1968, 1968, 1968, 1968, 1968, 10: 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 59: 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 492: 1968, 1968, 495: 1968, 1968, 502: 1968, 1968, 1968, 1968, 1968, 510: 1968, 514: 1968, 1968, 522: 1968, 525: 1968, 549: 1968, 583: 1968, 587: 1968, 589: 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 601: 1968, 1968, 1968, 1968, 1968, 1968, 608: 1968, 1968, 1968, 1968, 1968, 614: 1968, 1968, 617: 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 671: 1968}, + {2: 1967, 1967, 1967, 1967, 1967, 1967, 1967, 10: 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 59: 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 492: 1967, 1967, 495: 1967, 1967, 502: 1967, 1967, 1967, 1967, 1967, 510: 1967, 514: 1967, 1967, 522: 1967, 525: 1967, 549: 1967, 583: 1967, 587: 1967, 589: 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 601: 1967, 1967, 1967, 1967, 1967, 1967, 608: 1967, 1967, 1967, 1967, 1967, 614: 1967, 1967, 617: 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 671: 1967}, // 1620 - {213: 4158}, - {49: 1929}, - {213: 4160}, - {49: 1931, 474: 4161}, - {139: 4162}, + {2: 1966, 1966, 1966, 1966, 1966, 1966, 1966, 10: 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 59: 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 492: 1966, 1966, 495: 1966, 1966, 502: 1966, 1966, 1966, 1966, 1966, 510: 1966, 514: 1966, 1966, 522: 1966, 525: 1966, 549: 1966, 583: 1966, 587: 1966, 589: 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 601: 1966, 1966, 1966, 1966, 1966, 1966, 608: 1966, 1966, 1966, 1966, 1966, 614: 1966, 1966, 617: 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966, 671: 1966}, + {2: 1965, 1965, 1965, 1965, 1965, 1965, 1965, 10: 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 59: 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 492: 1965, 1965, 495: 1965, 1965, 502: 1965, 1965, 1965, 1965, 1965, 510: 1965, 514: 1965, 1965, 522: 1965, 525: 1965, 549: 1965, 583: 1965, 587: 1965, 589: 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 601: 1965, 1965, 1965, 1965, 1965, 1965, 608: 1965, 1965, 1965, 1965, 1965, 614: 1965, 1965, 617: 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965, 671: 1965}, + {2: 1964, 1964, 1964, 1964, 1964, 1964, 1964, 10: 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 59: 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 492: 1964, 1964, 495: 1964, 1964, 502: 1964, 1964, 1964, 1964, 1964, 510: 1964, 514: 1964, 1964, 522: 1964, 525: 1964, 549: 1964, 583: 1964, 587: 1964, 589: 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 601: 1964, 1964, 1964, 1964, 1964, 1964, 608: 1964, 1964, 1964, 1964, 1964, 614: 1964, 1964, 617: 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 1964, 671: 1964}, + {2: 1963, 1963, 1963, 1963, 1963, 1963, 1963, 10: 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 59: 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 492: 1963, 1963, 495: 1963, 1963, 502: 1963, 1963, 1963, 1963, 1963, 510: 1963, 514: 1963, 1963, 522: 1963, 525: 1963, 549: 1963, 583: 1963, 587: 1963, 589: 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 601: 1963, 1963, 1963, 1963, 1963, 1963, 608: 1963, 1963, 1963, 1963, 1963, 614: 1963, 1963, 617: 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 1963, 671: 1963}, + {188: 1960, 495: 4198, 497: 4197, 510: 1960, 591: 1960, 1960, 834: 4241}, // 1625 - {254: 4163}, - {49: 1930}, - {1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 474: 1939, 1939, 478: 1939, 480: 1939, 1939, 1939, 1939, 489: 1939, 1939, 1939, 493: 1939, 1939, 496: 1939, 1939, 1939, 500: 1939, 1939, 1939, 1939, 506: 1939, 1939, 509: 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 519: 1939, 521: 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 531: 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 1939, 545: 1939, 1939}, - {9: 2333, 49: 2333}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4167, 2762, 2763, 2761}, + {188: 1959, 510: 1959, 591: 1959, 1959}, + {1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 493: 1974, 1974, 498: 1974, 500: 1974, 1974, 1974, 1974, 508: 1974, 1974, 511: 1974, 1974, 1974, 516: 1974, 1974, 1974, 1974, 1974, 1974, 523: 1974, 1974, 526: 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 538: 1974, 1974, 1974, 542: 1974, 1974, 1974, 1974, 1974, 1974, 1974, 550: 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974, 565: 1974, 574: 1974, 1974, 1974, 1974, 1974, 1974, 1974, 1974}, + {492: 2667, 731: 4250}, + {787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 493: 787, 787, 787, 497: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 508: 787, 787, 511: 787, 787, 787, 516: 787, 787, 787, 787, 787, 787, 523: 787, 787, 526: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 550: 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 584: 787, 787, 787, 616: 787, 680: 4248}, + {1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1952, 1771, 1771, 1771, 497: 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 508: 1771, 1771, 511: 1771, 1771, 1771, 516: 1771, 1771, 1771, 1771, 1771, 1771, 523: 1771, 1771, 526: 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 550: 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 584: 1771, 1771, 1771, 616: 1771, 672: 1771, 676: 1771, 1771}, // 1630 - {2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 473: 2336, 488: 2336, 493: 2336, 499: 2336, 505: 2336, 2336, 529: 2336, 2336, 2336, 647: 2336, 652: 4168, 669: 2336, 2336, 672: 2336, 677: 2336, 2336, 680: 2336, 2336, 2336, 2336, 2336, 2336, 688: 2336, 690: 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 705: 2336, 2336, 2336, 2336}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4169, 2762, 2763, 2761}, - {2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 473: 2335, 488: 2335, 493: 2335, 499: 2335, 505: 2335, 2335, 529: 2335, 2335, 2335, 647: 2335, 669: 2335, 2335, 672: 2335, 677: 2335, 2335, 680: 2335, 2335, 2335, 2335, 2335, 2335, 688: 2335, 690: 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 705: 2335, 2335, 2335, 2335}, - {1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 474: 1940, 1940, 478: 1940, 480: 1940, 1940, 1940, 1940, 489: 1940, 1940, 1940, 493: 1940, 1940, 496: 1940, 1940, 1940, 500: 1940, 1940, 1940, 1940, 506: 1940, 1940, 509: 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 519: 1940, 521: 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 531: 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940, 545: 1940, 1940, 734: 3341, 3339}, - {1303, 1303, 9: 1303, 49: 1303, 127: 1303, 472: 1303, 474: 1303, 480: 1303, 1303, 490: 1303, 1303, 493: 1303, 1303, 496: 1303, 1303, 501: 1303, 1303, 514: 1303, 516: 1303, 524: 1303, 527: 1303, 1303}, + {1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1951, 1770, 1770, 1770, 497: 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 508: 1770, 1770, 511: 1770, 1770, 1770, 516: 1770, 1770, 1770, 1770, 1770, 1770, 523: 1770, 1770, 526: 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 550: 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 584: 1770, 1770, 1770, 616: 1770, 672: 1770, 676: 1770, 1770}, + {492: 1950}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 4249}, + {1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 493: 1972, 1972, 498: 1972, 500: 1972, 1972, 1972, 1972, 508: 1972, 1972, 511: 1972, 1972, 1972, 516: 1972, 1972, 1972, 1972, 1972, 1972, 523: 1972, 1972, 526: 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 538: 1972, 1972, 1972, 542: 1972, 1972, 1972, 1972, 1972, 1972, 1972, 550: 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 565: 1972, 574: 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972}, + {1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 493: 1973, 1973, 498: 1973, 500: 1973, 1973, 1973, 1973, 508: 1973, 1973, 511: 1973, 1973, 1973, 516: 1973, 1973, 1973, 1973, 1973, 1973, 523: 1973, 1973, 526: 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 538: 1973, 1973, 1973, 542: 1973, 1973, 1973, 1973, 1973, 1973, 1973, 550: 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973, 565: 1973, 574: 1973, 1973, 1973, 1973, 1973, 1973, 1973, 1973}, // 1635 - {1302, 1302, 9: 1302, 49: 1302, 127: 1302, 472: 1302, 474: 1302, 480: 1302, 1302, 490: 1302, 1302, 493: 1302, 1302, 496: 1302, 1302, 501: 1302, 1302, 514: 1302, 516: 1302, 524: 1302, 527: 1302, 1302}, - {1301, 1301, 9: 1301, 49: 1301, 127: 1301, 472: 1301, 474: 1301, 480: 1301, 1301, 490: 1301, 1301, 493: 1301, 1301, 496: 1301, 1301, 501: 1301, 1301, 514: 1301, 516: 1301, 524: 1301, 527: 1301, 1301}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4175}, - {1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 474: 1944, 1944, 478: 1944, 480: 1944, 1944, 1944, 1944, 489: 1944, 1944, 1944, 493: 1944, 1944, 496: 1944, 1944, 1944, 500: 1944, 1944, 1944, 1944, 506: 1944, 3345, 509: 3343, 3344, 3342, 3340, 1944, 1944, 1944, 1944, 1944, 519: 1944, 521: 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 531: 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 545: 1944, 1944, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4177}, + {1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 493: 1999, 1999, 498: 1999, 500: 1999, 1999, 1999, 1999, 508: 1999, 1999, 511: 1999, 1999, 1999, 516: 1999, 518: 1999, 1999, 1999, 1999, 523: 1999, 1999, 526: 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 538: 1999, 1999, 1999, 542: 1999, 1999, 1999, 1999, 1999, 1999, 1999, 550: 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 565: 1999}, + {1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 493: 1998, 1998, 498: 1998, 500: 1998, 1998, 1998, 1998, 508: 1998, 1998, 511: 1998, 1998, 1998, 516: 1998, 518: 1998, 1998, 1998, 1998, 523: 1998, 1998, 526: 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 538: 1998, 1998, 1998, 542: 1998, 1998, 1998, 1998, 1998, 1998, 1998, 550: 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 565: 1998}, + {1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 493: 1997, 1997, 498: 1997, 500: 1997, 1997, 1997, 1997, 508: 1997, 1997, 511: 1997, 1997, 1997, 516: 1997, 518: 1997, 1997, 1997, 1997, 523: 1997, 1997, 526: 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 538: 1997, 1997, 1997, 542: 1997, 1997, 1997, 1997, 1997, 1997, 1997, 550: 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 565: 1997}, + {1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 493: 1975, 1975, 498: 1975, 500: 1975, 1975, 1975, 1975, 508: 1975, 1975, 511: 1975, 1975, 1975, 516: 1975, 1975, 1975, 1975, 1975, 1975, 523: 1975, 1975, 526: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 538: 1975, 1975, 1975, 542: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 550: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975, 565: 1975, 574: 1975, 1975, 1975, 1975, 1975, 1975, 1975, 1975}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 4258}, // 1640 - {49: 4178}, - {2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 474: 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 496: 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 506: 2233, 2233, 509: 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 531: 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 2233, 565: 2233, 2233, 581: 2233, 590: 2233, 2233, 594: 2233, 642: 2233, 2233, 2233, 2233}, - {494: 4180}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4181}, - {2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 474: 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 496: 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 506: 2234, 2234, 509: 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 531: 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 2234, 565: 2234, 2234, 581: 2234, 590: 2234, 2234, 594: 2234, 642: 2234, 2234, 2234, 2234}, + {2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 492: 2404, 507: 2404, 512: 2404, 514: 2404, 517: 2404, 526: 2404, 548: 2404, 2404, 561: 2404, 667: 2404, 672: 4279, 690: 2404, 2404, 693: 2404, 699: 2404, 2404, 702: 2404, 2404, 2404, 2404, 2404, 2404, 710: 2404, 712: 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 727: 2404, 2404, 2404, 2404}, + {9: 2401, 58: 2401}, + {9: 4259, 58: 4260}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4278}, + {325: 4261}, // 1645 - {248, 248, 49: 248, 472: 248, 474: 248, 480: 248, 248, 490: 248, 248, 493: 248, 248, 496: 248, 248, 501: 248, 248, 507: 3345, 509: 3343, 3344, 3342, 3340, 248, 248, 516: 248, 734: 3341, 3339}, - {6, 6}, - {139: 4186}, - {2, 2}, - {247, 247, 493: 247, 498: 2722, 501: 247, 247, 790: 2723, 4187}, + {492: 4262}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 4263}, + {58: 1993, 494: 4266, 504: 3793, 3794, 3799, 541: 3795, 564: 4265, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792, 1254: 4264}, + {58: 4277}, + {245: 4270, 538: 4269}, // 1650 - {1297, 1297, 493: 1297, 501: 1297, 2725, 767: 2726, 812: 4188}, - {869, 869, 493: 2728, 501: 2729, 768: 2730, 830: 4189}, - {4, 4}, - {569: 4192}, - {2: 1855, 1855, 1855, 1855, 1855, 1855, 1855, 10: 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 50: 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855, 473: 1855, 496: 1855, 500: 1855, 569: 1855, 579: 1855}, + {153: 4267}, + {269: 4268}, + {58: 1989}, + {368: 4272}, + {229: 4271}, // 1655 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4193}, - {2412, 2412, 2412, 2412, 2412, 2412, 4241, 4243, 400, 10: 4210, 15: 4260, 2176, 4258, 4197, 4262, 4249, 4278, 4242, 4245, 4244, 4247, 4248, 4250, 4257, 400, 4268, 4269, 4255, 4256, 4261, 4263, 4275, 4274, 4280, 4276, 4273, 4266, 4271, 4272, 4265, 4267, 4270, 4259, 71: 4212, 74: 4233, 4234, 83: 4235, 134: 4215, 183: 4204, 203: 4198, 4196, 4219, 208: 4220, 219: 4214, 224: 4230, 237: 4208, 246: 4216, 252: 4211, 269: 4221, 277: 4217, 284: 4231, 4232, 290: 4199, 474: 4229, 479: 4240, 4277, 484: 2176, 488: 2412, 497: 4236, 502: 4218, 4228, 505: 2176, 4201, 584: 4202, 590: 4207, 647: 2176, 649: 4246, 653: 4195, 665: 4223, 669: 4209, 671: 4237, 679: 4222, 686: 4224, 689: 4203, 704: 4213, 781: 4251, 792: 4253, 813: 4252, 835: 4254, 838: 4264, 842: 4279, 870: 4227, 883: 4225, 919: 4200, 926: 4205, 989: 4239, 1138: 4206, 1165: 4226, 1171: 4238, 4194}, - {2174, 2174, 5041, 5042, 5039, 5040, 488: 5043, 1100: 5038, 1170: 5037}, - {488: 5011}, - {2532, 2532, 168: 5005, 488: 5006}, + {58: 1990}, + {229: 4273}, + {58: 1992, 494: 4274}, + {153: 4275}, + {269: 4276}, // 1660 - {165: 4997}, - {475: 2047, 479: 2047, 499: 4281, 736: 4994}, - {475: 2047, 479: 2047, 499: 4281, 736: 4991}, - {2497, 2497, 2497, 2497, 2497, 2497, 4241, 4243, 400, 2497, 15: 4260, 2176, 4258, 4197, 4262, 4249, 4278, 4242, 4245, 4244, 4247, 4248, 4250, 4257, 400, 4268, 4269, 4255, 4256, 4261, 4263, 4275, 4274, 4280, 4276, 4273, 4266, 4271, 4272, 4265, 4267, 4270, 4259, 479: 4240, 4277, 484: 2176, 488: 2497, 503: 4987, 505: 2176, 647: 2176, 649: 4246, 781: 4251, 792: 4253, 813: 4252, 835: 4254, 838: 4264, 842: 4988}, - {168: 4977}, + {58: 1991}, + {2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 493: 2000, 2000, 498: 2000, 500: 2000, 2000, 2000, 2000, 508: 2000, 2000, 511: 2000, 2000, 2000, 516: 2000, 518: 2000, 2000, 2000, 2000, 523: 2000, 2000, 526: 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 538: 2000, 2000, 2000, 542: 2000, 2000, 2000, 2000, 2000, 2000, 2000, 550: 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 565: 2000}, + {9: 2400, 58: 2400}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4280, 2850, 688: 2851, 2849}, + {2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 492: 2403, 507: 2403, 512: 2403, 514: 2403, 517: 2403, 526: 2403, 548: 2403, 2403, 561: 2403, 667: 2403, 672: 4281, 690: 2403, 2403, 693: 2403, 699: 2403, 2403, 702: 2403, 2403, 2403, 2403, 2403, 2403, 710: 2403, 712: 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 2403, 727: 2403, 2403, 2403, 2403}, // 1665 - {650: 4969}, - {2: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 10: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 50: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 473: 2417, 488: 4828, 564: 2417, 581: 2406, 590: 2406, 2406, 642: 2406, 4589, 649: 2406, 675: 2406, 2406, 833: 4830, 847: 4424, 873: 4826, 903: 4827, 914: 4829}, - {488: 4819}, - {2486, 2486, 2486, 2486, 2486, 2486, 9: 2486, 488: 2486}, - {2485, 2485, 2485, 2485, 2485, 2485, 9: 2485, 488: 2485}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4282, 2850, 688: 2851, 2849}, + {2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 492: 2402, 507: 2402, 512: 2402, 514: 2402, 517: 2402, 526: 2402, 548: 2402, 2402, 561: 2402, 667: 2402, 690: 2402, 2402, 693: 2402, 699: 2402, 2402, 702: 2402, 2402, 2402, 2402, 2402, 2402, 710: 2402, 712: 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 2402, 727: 2402, 2402, 2402, 2402}, + {2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 493: 2001, 2001, 498: 2001, 500: 2001, 2001, 2001, 2001, 508: 2001, 2001, 511: 2001, 2001, 2001, 516: 2001, 518: 2001, 2001, 2001, 2001, 523: 2001, 2001, 526: 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 538: 2001, 2001, 2001, 542: 2001, 2001, 2001, 2001, 2001, 2001, 2001, 550: 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 565: 2001, 756: 3448, 3446}, + {1344, 1344, 9: 1344, 58: 1344, 139: 1344, 491: 1344, 494: 1344, 500: 1344, 1344, 509: 1344, 511: 1344, 1344, 1344, 516: 1344, 518: 1344, 521: 1344, 523: 1344, 533: 1344, 535: 1344, 543: 1344, 546: 1344, 1344}, + {1343, 1343, 9: 1343, 58: 1343, 139: 1343, 491: 1343, 494: 1343, 500: 1343, 1343, 509: 1343, 511: 1343, 1343, 1343, 516: 1343, 518: 1343, 521: 1343, 523: 1343, 533: 1343, 535: 1343, 543: 1343, 546: 1343, 1343}, // 1670 - {488: 4817}, - {488: 4814}, - {2: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 10: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 50: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 488: 4793, 564: 2417, 581: 4410, 590: 4425, 4792, 643: 4426, 649: 4411, 675: 4796, 828: 4795, 847: 4424, 873: 4791, 914: 4794, 1000: 4797}, - {488: 4784}, - {488: 4773}, + {1342, 1342, 9: 1342, 58: 1342, 139: 1342, 491: 1342, 494: 1342, 500: 1342, 1342, 509: 1342, 511: 1342, 1342, 1342, 516: 1342, 518: 1342, 521: 1342, 523: 1342, 533: 1342, 535: 1342, 543: 1342, 546: 1342, 1342}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4288}, + {2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 493: 2005, 2005, 498: 2005, 500: 2005, 2005, 2005, 2005, 508: 2005, 2005, 511: 2005, 2005, 2005, 516: 2005, 518: 2005, 2005, 2005, 2005, 523: 2005, 2005, 526: 2005, 3452, 3450, 3451, 3449, 3447, 2005, 2005, 2005, 2005, 2005, 538: 2005, 2005, 2005, 542: 2005, 2005, 2005, 2005, 2005, 2005, 2005, 550: 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 565: 2005, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4290}, + {58: 4291}, // 1675 - {488: 4771}, - {488: 4768}, - {488: 4765}, - {20: 4762, 488: 4761}, - {20: 4758, 488: 4757}, + {2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 493: 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 516: 2298, 2298, 2298, 2298, 2298, 2298, 523: 2298, 2298, 526: 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 550: 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 584: 2298, 2298, 2298, 600: 2298, 607: 2298, 613: 2298, 616: 2298, 662: 2298, 2298, 2298, 666: 2298}, + {513: 4293}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4294}, + {2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 493: 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 516: 2299, 2299, 2299, 2299, 2299, 2299, 523: 2299, 2299, 526: 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 550: 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 584: 2299, 2299, 2299, 600: 2299, 607: 2299, 613: 2299, 616: 2299, 662: 2299, 2299, 2299, 666: 2299}, + {276, 276, 58: 276, 491: 276, 494: 276, 500: 276, 276, 509: 276, 511: 276, 276, 276, 516: 276, 518: 276, 521: 276, 523: 276, 527: 3452, 3450, 3451, 3449, 3447, 276, 276, 535: 276, 756: 3448, 3446}, // 1680 - {488: 4747}, - {660: 4740}, - {943: 4739}, - {943: 4738}, - {2: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 10: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 50: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 564: 2417, 847: 4424, 873: 4734}, + {7, 7}, + {153: 4299}, + {3, 3}, + {275, 275, 512: 275, 519: 2810, 521: 275, 523: 275, 814: 2811, 4300}, + {1338, 1338, 512: 1338, 521: 1338, 523: 2813, 790: 2814, 836: 4301}, // 1685 - {2: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 10: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 50: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 564: 2417, 847: 4424, 873: 4450}, - {2: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 10: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 50: 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 2417, 590: 4425, 643: 4426, 649: 4423, 847: 4424, 873: 4421, 1000: 4422}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 478: 4408, 499: 4281, 581: 4410, 649: 4411, 4406, 736: 4407, 828: 4409, 847: 4405}, - {2453, 2453, 2453, 2453, 2453, 2453, 9: 2453, 488: 2453}, - {2452, 2452, 2452, 2452, 2452, 2452, 9: 2452, 488: 2452}, + {908, 908, 512: 2816, 521: 2817, 791: 2818, 852: 4302}, + {5, 5}, + {588: 4305}, + {2: 1915, 1915, 1915, 1915, 1915, 1915, 1915, 10: 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 59: 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 1915, 492: 1915, 516: 1915, 520: 1915, 588: 1915, 601: 1915}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4306}, // 1690 - {2451, 2451, 2451, 2451, 2451, 2451, 9: 2451, 488: 2451}, - {2450, 2450, 2450, 2450, 2450, 2450, 8: 399, 2450, 29: 399, 488: 2450}, - {201: 4404}, - {201: 4403}, - {2447, 2447, 2447, 2447, 2447, 2447, 9: 2447, 488: 2447}, + {2482, 2482, 2482, 2482, 2482, 2482, 4354, 4356, 428, 10: 4323, 15: 4373, 2238, 4371, 4310, 4375, 4362, 4391, 4355, 4358, 4357, 4360, 4361, 4363, 4370, 428, 4381, 4382, 4392, 4368, 4369, 4374, 4376, 4388, 4387, 4396, 4389, 4386, 4379, 4384, 4385, 4378, 4380, 4383, 4372, 4393, 4394, 78: 4325, 81: 4346, 4347, 90: 4348, 151: 4328, 196: 4317, 217: 4311, 4309, 220: 4332, 223: 4333, 233: 4327, 239: 4343, 253: 4321, 261: 4329, 267: 4324, 284: 4334, 292: 4330, 299: 4344, 4345, 304: 4312, 494: 4342, 496: 4353, 499: 2238, 4390, 507: 2482, 514: 2238, 518: 4349, 523: 4331, 4341, 526: 4314, 604: 4315, 607: 4320, 667: 2238, 4359, 673: 4308, 682: 4336, 690: 4322, 692: 4350, 701: 4335, 708: 4337, 711: 4316, 726: 4326, 803: 4364, 816: 4366, 837: 4365, 858: 4367, 862: 4377, 866: 4395, 893: 4340, 906: 4338, 944: 4313, 951: 4318, 1015: 4352, 1170: 4319, 1198: 4339, 1203: 4351, 4307}, + {2236, 2236, 5172, 5173, 5170, 5171, 507: 5174, 1130: 5169, 1205: 5168}, + {507: 5142}, + {2611, 2611, 182: 5136, 507: 5137}, + {179: 5128}, // 1695 - {2446, 2446, 2446, 2446, 2446, 2446, 9: 2446, 488: 2446}, - {2442, 2442, 2442, 2442, 2442, 2442, 9: 2442, 488: 2442}, - {2441, 2441, 2441, 2441, 2441, 2441, 9: 2441, 488: 2441}, - {151: 2047, 240: 2047, 261: 2047, 263: 2047, 479: 2047, 499: 4281, 736: 4397}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 479: 2047, 499: 4281, 736: 4394}, + {493: 2109, 496: 2109, 517: 4397, 758: 5125}, + {493: 2109, 496: 2109, 517: 4397, 758: 5122}, + {2567, 2567, 2567, 2567, 2567, 2567, 4354, 4356, 428, 2567, 15: 4373, 2238, 4371, 4310, 4375, 4362, 4391, 4355, 4358, 4357, 4360, 4361, 4363, 4370, 428, 4381, 4382, 4392, 4368, 4369, 4374, 4376, 4388, 4387, 4396, 4389, 4386, 4379, 4384, 4385, 4378, 4380, 4383, 4372, 4393, 4394, 496: 4353, 499: 2238, 4390, 507: 2567, 514: 2238, 524: 5118, 667: 2238, 4359, 803: 4364, 816: 4366, 837: 4365, 858: 4367, 862: 4377, 866: 5119}, + {182: 5108}, + {670: 5100}, // 1700 - {154: 4393, 687: 4392}, - {2411, 2411, 2411, 2411, 2411, 2411, 9: 4390, 488: 2411}, - {2410, 2410, 2410, 2410, 2410, 2410, 9: 2410, 488: 2410}, - {16: 2175, 18: 2175, 21: 2175, 484: 2175, 505: 2175, 647: 2175}, - {475: 2047, 499: 4281, 736: 4388}, + {2: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 10: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 59: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 492: 2487, 507: 4959, 583: 2487, 600: 2476, 607: 2476, 613: 2476, 662: 2476, 4715, 668: 2476, 696: 2476, 2476, 855: 4961, 871: 4550, 896: 4957, 928: 4958, 939: 4960}, + {507: 4950}, + {2556, 2556, 2556, 2556, 2556, 2556, 9: 2556, 507: 2556}, + {2555, 2555, 2555, 2555, 2555, 2555, 9: 2555, 507: 2555}, + {507: 4948}, // 1705 - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 499: 4281, 736: 4386}, - {22: 4381, 186: 4382, 247: 4383}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 499: 4281, 736: 4379}, - {245: 4376}, - {245: 4373}, + {507: 4945}, + {2: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 10: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 59: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 507: 4924, 583: 2487, 600: 4536, 607: 4551, 613: 4923, 663: 4552, 668: 4537, 696: 4927, 850: 4926, 871: 4550, 896: 4922, 939: 4925, 1025: 4928}, + {507: 4915}, + {507: 4904}, + {507: 4902}, // 1710 - {499: 4281, 508: 2047, 736: 4371}, - {499: 4281, 508: 2047, 736: 4369}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 499: 4281, 736: 4367}, - {499: 4281, 508: 2047, 736: 4365}, - {2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 15: 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 2120, 49: 2120, 472: 2120, 2120, 2120, 478: 2120, 2120, 2120, 484: 2120, 488: 2120, 2120, 495: 2120, 503: 2120, 2120, 2120, 569: 2120, 646: 2120, 2120, 649: 2120}, + {507: 4899}, + {507: 4896}, + {20: 4893, 507: 4892}, + {20: 4889, 507: 4888}, + {507: 4878}, // 1715 - {434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 15: 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 472: 434, 434, 434, 478: 434, 434, 434, 484: 434, 488: 434, 434, 495: 434, 503: 434, 434, 434, 569: 434, 646: 434, 434, 649: 434}, - {16: 3836, 484: 4360, 505: 3837, 647: 3835, 773: 4359}, - {8: 4353, 29: 4354}, - {499: 4281, 508: 2047, 736: 4351}, - {499: 4281, 508: 2047, 736: 4349}, + {681: 4871}, + {969: 4870}, + {969: 4869}, + {2: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 10: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 59: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 583: 2487, 871: 4550, 896: 4865}, + {2: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 10: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 59: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 583: 2487, 871: 4550, 896: 4576}, // 1720 - {475: 2047, 499: 4281, 736: 4347}, - {499: 4281, 508: 2047, 736: 4345}, - {499: 4281, 508: 2047, 736: 4343}, - {475: 2047, 499: 4281, 736: 4341}, - {475: 2047, 499: 4281, 736: 4339}, + {2: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 10: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 59: 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 607: 4551, 663: 4552, 668: 4549, 871: 4550, 896: 4547, 1025: 4548}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 498: 4534, 517: 4397, 600: 4536, 668: 4537, 670: 4532, 758: 4533, 850: 4535, 871: 4531}, + {2523, 2523, 2523, 2523, 2523, 2523, 9: 2523, 507: 2523}, + {2522, 2522, 2522, 2522, 2522, 2522, 9: 2522, 507: 2522}, + {2521, 2521, 2521, 2521, 2521, 2521, 9: 2521, 507: 2521}, // 1725 - {499: 4281, 508: 2047, 736: 4337}, - {499: 4281, 508: 2047, 736: 4335}, - {420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 15: 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 472: 420, 420, 420, 478: 420, 420, 420, 484: 420, 488: 420, 420, 495: 420, 503: 420, 420, 420, 569: 420, 646: 420, 420, 649: 420}, - {479: 2047, 499: 4281, 508: 2047, 736: 4333}, - {479: 2047, 499: 4281, 508: 2047, 736: 4330}, + {2520, 2520, 2520, 2520, 2520, 2520, 8: 427, 2520, 29: 427, 507: 2520}, + {215: 4530}, + {215: 4529}, + {2517, 2517, 2517, 2517, 2517, 2517, 9: 2517, 507: 2517}, + {2516, 2516, 2516, 2516, 2516, 2516, 9: 2516, 507: 2516}, // 1730 - {479: 2047, 499: 4281, 508: 2047, 736: 4327}, - {499: 4281, 508: 2047, 736: 4325}, - {499: 4281, 508: 2047, 736: 4323}, - {499: 4281, 508: 2047, 573: 2047, 2047, 736: 4321}, - {475: 2047, 499: 4281, 736: 4319}, + {2512, 2512, 2512, 2512, 2512, 2512, 9: 2512, 507: 2512}, + {2511, 2511, 2511, 2511, 2511, 2511, 9: 2511, 507: 2511}, + {141: 2109, 256: 2109, 276: 2109, 278: 2109, 496: 2109, 517: 4397, 758: 4523}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 496: 2109, 517: 4397, 758: 4520}, + {167: 4519, 709: 4518}, // 1735 - {475: 2047, 499: 4281, 736: 4317}, - {499: 4281, 508: 2047, 736: 4315}, - {499: 4281, 508: 2047, 736: 4313}, - {479: 2047, 499: 4281, 508: 2047, 736: 4309}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 492: 2047, 499: 4281, 736: 4306}, + {2481, 2481, 2481, 2481, 2481, 2481, 9: 4516, 507: 2481}, + {2480, 2480, 2480, 2480, 2480, 2480, 9: 2480, 507: 2480}, + {16: 2237, 18: 2237, 21: 2237, 499: 2237, 514: 2237, 667: 2237}, + {493: 2109, 517: 4397, 758: 4514}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 517: 4397, 758: 4512}, // 1740 - {473: 2047, 499: 4281, 736: 4301}, - {475: 2047, 499: 4281, 736: 4298}, - {394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 15: 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 472: 394, 394, 394, 478: 394, 394, 394, 484: 394, 488: 394, 394, 495: 394, 503: 394, 394, 394, 569: 394, 646: 394, 394, 649: 394}, - {180: 2047, 204: 2047, 207: 2047, 238: 2047, 278: 2047, 293: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 479: 2047, 499: 4281, 736: 4282}, - {2: 2046, 2046, 2046, 2046, 2046, 2046, 2046, 10: 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 50: 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 473: 2046, 475: 2046, 479: 2046, 485: 2046, 2046, 489: 2046, 492: 2046, 504: 2046, 508: 2046, 530: 2046, 571: 2046, 2046, 2046, 2046}, + {22: 4507, 199: 4508, 262: 4509}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 517: 4397, 758: 4505}, + {260: 4502}, + {260: 4499}, + {517: 4397, 525: 2109, 758: 4497}, // 1745 - {180: 4285, 204: 4288, 207: 4284, 238: 4286, 278: 4287, 293: 4289, 4290, 4295, 4294, 4291, 4296, 4297, 4292, 4293, 479: 4283}, - {388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 15: 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 472: 388, 388, 388, 478: 388, 388, 388, 484: 388, 488: 388, 388, 495: 388, 503: 388, 388, 388, 569: 388, 646: 388, 388, 649: 388}, - {387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 15: 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 472: 387, 387, 387, 478: 387, 387, 387, 484: 387, 488: 387, 387, 495: 387, 503: 387, 387, 387, 569: 387, 646: 387, 387, 649: 387}, - {386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 15: 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 472: 386, 386, 386, 478: 386, 386, 386, 484: 386, 488: 386, 386, 495: 386, 503: 386, 386, 386, 569: 386, 646: 386, 386, 649: 386}, - {385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 15: 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 472: 385, 385, 385, 478: 385, 385, 385, 484: 385, 488: 385, 385, 495: 385, 503: 385, 385, 385, 569: 385, 646: 385, 385, 649: 385}, + {517: 4397, 525: 2109, 758: 4495}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 517: 4397, 758: 4493}, + {517: 4397, 525: 2109, 758: 4491}, + {2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 15: 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 58: 2182, 491: 2182, 2182, 494: 2182, 496: 2182, 498: 2182, 2182, 2182, 507: 2182, 2182, 514: 2182, 2182, 522: 2182, 524: 2182, 588: 2182, 665: 2182, 667: 2182, 2182}, + {465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 15: 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, 491: 465, 465, 494: 465, 496: 465, 498: 465, 465, 465, 507: 465, 465, 514: 465, 465, 522: 465, 524: 465, 588: 465, 665: 465, 667: 465, 465}, // 1750 - {384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 15: 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 472: 384, 384, 384, 478: 384, 384, 384, 484: 384, 488: 384, 384, 495: 384, 503: 384, 384, 384, 569: 384, 646: 384, 384, 649: 384}, - {383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 15: 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 472: 383, 383, 383, 478: 383, 383, 383, 484: 383, 488: 383, 383, 495: 383, 503: 383, 383, 383, 569: 383, 646: 383, 383, 649: 383}, - {382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 15: 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 472: 382, 382, 382, 478: 382, 382, 382, 484: 382, 488: 382, 382, 495: 382, 503: 382, 382, 382, 569: 382, 646: 382, 382, 649: 382}, - {381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 15: 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 472: 381, 381, 381, 478: 381, 381, 381, 484: 381, 488: 381, 381, 495: 381, 503: 381, 381, 381, 569: 381, 646: 381, 381, 649: 381}, - {380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 15: 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 472: 380, 380, 380, 478: 380, 380, 380, 484: 380, 488: 380, 380, 495: 380, 503: 380, 380, 380, 569: 380, 646: 380, 380, 649: 380}, + {16: 3943, 499: 4486, 514: 3944, 667: 3942, 798: 4485}, + {8: 4479, 29: 4480}, + {517: 4397, 525: 2109, 758: 4477}, + {517: 4397, 525: 2109, 758: 4475}, + {493: 2109, 517: 4397, 758: 4473}, // 1755 - {379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 15: 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 472: 379, 379, 379, 478: 379, 379, 379, 484: 379, 488: 379, 379, 495: 379, 503: 379, 379, 379, 569: 379, 646: 379, 379, 649: 379}, - {378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 15: 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 472: 378, 378, 378, 478: 378, 378, 378, 484: 378, 488: 378, 378, 495: 378, 503: 378, 378, 378, 569: 378, 646: 378, 378, 649: 378}, - {377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 15: 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 472: 377, 377, 377, 478: 377, 377, 377, 484: 377, 488: 377, 377, 495: 377, 503: 377, 377, 377, 569: 377, 646: 377, 377, 649: 377}, - {376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 15: 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 472: 376, 376, 376, 478: 376, 376, 376, 484: 376, 488: 376, 376, 495: 376, 503: 376, 376, 376, 569: 376, 646: 376, 376, 649: 376}, - {375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 15: 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 472: 375, 375, 375, 478: 375, 375, 375, 484: 375, 488: 375, 375, 495: 375, 503: 375, 375, 375, 569: 375, 646: 375, 375, 649: 375}, + {517: 4397, 525: 2109, 758: 4471}, + {517: 4397, 525: 2109, 758: 4469}, + {493: 2109, 517: 4397, 758: 4467}, + {493: 2109, 517: 4397, 758: 4465}, + {517: 4397, 525: 2109, 758: 4463}, // 1760 - {374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 15: 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 472: 374, 374, 374, 478: 374, 374, 374, 484: 374, 488: 374, 374, 495: 374, 503: 374, 374, 374, 569: 374, 646: 374, 374, 649: 374}, - {475: 4300, 1039: 4299}, - {401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 15: 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 472: 401, 401, 401, 478: 401, 401, 401, 484: 401, 488: 401, 401, 495: 401, 503: 401, 401, 401, 569: 401, 646: 401, 401, 649: 401}, - {11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 15: 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 472: 11, 11, 11, 478: 11, 11, 11, 484: 11, 488: 11, 11, 495: 11, 503: 11, 11, 11, 11, 569: 11, 646: 11, 11, 649: 11}, - {473: 4302}, + {517: 4397, 525: 2109, 758: 4461}, + {451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 15: 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 451, 491: 451, 451, 494: 451, 496: 451, 498: 451, 451, 451, 507: 451, 451, 514: 451, 451, 522: 451, 524: 451, 588: 451, 665: 451, 667: 451, 451}, + {496: 2109, 517: 4397, 525: 2109, 758: 4459}, + {496: 2109, 517: 4397, 525: 2109, 758: 4456}, + {496: 2109, 517: 4397, 525: 2109, 758: 4453}, // 1765 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 566, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 4303, 1147: 4304}, - {565, 565, 9: 3924, 49: 565, 474: 565}, - {49: 4305}, - {402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 15: 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 472: 402, 402, 402, 478: 402, 402, 402, 484: 402, 488: 402, 402, 495: 402, 503: 402, 402, 402, 569: 402, 646: 402, 402, 649: 402}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 492: 4307, 661: 3491, 2762, 2763, 2761, 738: 4308}, + {517: 4397, 525: 2109, 758: 4451}, + {517: 4397, 525: 2109, 758: 4449}, + {517: 4397, 525: 2109, 593: 2109, 2109, 758: 4447}, + {493: 2109, 517: 4397, 758: 4445}, + {493: 2109, 517: 4397, 758: 4443}, // 1770 - {404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 15: 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 472: 404, 404, 404, 478: 404, 404, 404, 484: 404, 488: 404, 404, 495: 404, 503: 404, 404, 404, 569: 404, 646: 404, 404, 649: 404}, - {403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 15: 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 472: 403, 403, 403, 478: 403, 403, 403, 484: 403, 488: 403, 403, 495: 403, 503: 403, 403, 403, 569: 403, 646: 403, 403, 649: 403}, - {479: 4311, 508: 2736, 733: 2735, 741: 4312, 1139: 4310}, - {407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 15: 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 472: 407, 407, 407, 478: 407, 407, 407, 484: 407, 488: 407, 407, 495: 407, 503: 407, 407, 407, 569: 407, 646: 407, 407, 649: 407}, - {398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 15: 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 472: 398, 398, 398, 478: 398, 398, 398, 484: 398, 488: 398, 398, 495: 398, 503: 398, 398, 398, 569: 398, 646: 398, 398, 649: 398}, + {517: 4397, 525: 2109, 758: 4441}, + {517: 4397, 525: 2109, 758: 4439}, + {496: 2109, 517: 4397, 525: 2109, 758: 4435}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 510: 2109, 517: 4397, 758: 4432}, + {492: 2109, 517: 4397, 758: 4427}, // 1775 - {397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 15: 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 472: 397, 397, 397, 478: 397, 397, 397, 484: 397, 488: 397, 397, 495: 397, 503: 397, 397, 397, 569: 397, 646: 397, 397, 649: 397}, - {508: 2736, 733: 2735, 741: 4314}, - {408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 15: 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 472: 408, 408, 408, 478: 408, 408, 408, 484: 408, 488: 408, 408, 495: 408, 503: 408, 408, 408, 569: 408, 646: 408, 408, 649: 408}, - {508: 2736, 733: 2735, 741: 4316}, - {409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 15: 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 472: 409, 409, 409, 478: 409, 409, 409, 484: 409, 488: 409, 409, 495: 409, 503: 409, 409, 409, 569: 409, 646: 409, 409, 649: 409}, + {493: 2109, 517: 4397, 758: 4424}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 517: 4397, 758: 4418}, + {493: 2109, 517: 4397, 758: 4416}, + {493: 2109, 517: 4397, 758: 4414}, + {422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 15: 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 491: 422, 422, 494: 422, 496: 422, 498: 422, 422, 422, 507: 422, 422, 514: 422, 422, 522: 422, 524: 422, 588: 422, 665: 422, 667: 422, 422}, // 1780 - {475: 4318}, - {410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 15: 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 472: 410, 410, 410, 478: 410, 410, 410, 484: 410, 488: 410, 410, 495: 410, 503: 410, 410, 410, 569: 410, 646: 410, 410, 649: 410}, - {475: 4320}, - {411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 15: 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 472: 411, 411, 411, 478: 411, 411, 411, 484: 411, 488: 411, 411, 495: 411, 503: 411, 411, 411, 569: 411, 646: 411, 411, 649: 411}, - {508: 3423, 573: 3425, 3424, 820: 4322}, + {193: 2109, 218: 2109, 222: 2109, 254: 2109, 293: 2109, 308: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 496: 2109, 517: 4397, 758: 4398}, + {2: 2108, 2108, 2108, 2108, 2108, 2108, 2108, 10: 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 59: 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 492: 2108, 2108, 496: 2108, 504: 2108, 2108, 508: 2108, 510: 2108, 522: 2108, 525: 2108, 549: 2108, 591: 2108, 2108, 2108, 2108}, + {193: 4401, 218: 4404, 222: 4400, 254: 4402, 293: 4403, 308: 4405, 4406, 4411, 4410, 4407, 4412, 4413, 4408, 4409, 496: 4399}, + {416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 15: 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 491: 416, 416, 494: 416, 496: 416, 498: 416, 416, 416, 507: 416, 416, 514: 416, 416, 522: 416, 524: 416, 588: 416, 665: 416, 667: 416, 416}, + {415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 15: 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 491: 415, 415, 494: 415, 496: 415, 498: 415, 415, 415, 507: 415, 415, 514: 415, 415, 522: 415, 524: 415, 588: 415, 665: 415, 667: 415, 415}, // 1785 - {412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 15: 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 472: 412, 412, 412, 478: 412, 412, 412, 484: 412, 488: 412, 412, 495: 412, 503: 412, 412, 412, 569: 412, 646: 412, 412, 649: 412}, - {508: 2736, 733: 2735, 741: 4324}, - {413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 15: 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 472: 413, 413, 413, 478: 413, 413, 413, 484: 413, 488: 413, 413, 495: 413, 503: 413, 413, 413, 569: 413, 646: 413, 413, 649: 413}, - {508: 2736, 733: 2735, 741: 4326}, - {414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 15: 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 472: 414, 414, 414, 478: 414, 414, 414, 484: 414, 488: 414, 414, 495: 414, 503: 414, 414, 414, 569: 414, 646: 414, 414, 649: 414}, + {414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 15: 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 491: 414, 414, 494: 414, 496: 414, 498: 414, 414, 414, 507: 414, 414, 514: 414, 414, 522: 414, 524: 414, 588: 414, 665: 414, 667: 414, 414}, + {413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 15: 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 491: 413, 413, 494: 413, 496: 413, 498: 413, 413, 413, 507: 413, 413, 514: 413, 413, 522: 413, 524: 413, 588: 413, 665: 413, 667: 413, 413}, + {412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 15: 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 491: 412, 412, 494: 412, 496: 412, 498: 412, 412, 412, 507: 412, 412, 514: 412, 412, 522: 412, 524: 412, 588: 412, 665: 412, 667: 412, 412}, + {411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 15: 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 411, 491: 411, 411, 494: 411, 496: 411, 498: 411, 411, 411, 507: 411, 411, 514: 411, 411, 522: 411, 524: 411, 588: 411, 665: 411, 667: 411, 411}, + {410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 15: 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, 491: 410, 410, 494: 410, 496: 410, 498: 410, 410, 410, 507: 410, 410, 514: 410, 410, 522: 410, 524: 410, 588: 410, 665: 410, 667: 410, 410}, // 1790 - {479: 4329, 508: 2736, 733: 2735, 741: 4328}, - {416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 15: 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 472: 416, 416, 416, 478: 416, 416, 416, 484: 416, 488: 416, 416, 495: 416, 503: 416, 416, 416, 569: 416, 646: 416, 416, 649: 416}, - {415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 15: 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 472: 415, 415, 415, 478: 415, 415, 415, 484: 415, 488: 415, 415, 495: 415, 503: 415, 415, 415, 569: 415, 646: 415, 415, 649: 415}, - {479: 4332, 508: 2736, 733: 2735, 741: 4331}, - {418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 15: 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 472: 418, 418, 418, 478: 418, 418, 418, 484: 418, 488: 418, 418, 495: 418, 503: 418, 418, 418, 569: 418, 646: 418, 418, 649: 418}, + {409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 15: 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 491: 409, 409, 494: 409, 496: 409, 498: 409, 409, 409, 507: 409, 409, 514: 409, 409, 522: 409, 524: 409, 588: 409, 665: 409, 667: 409, 409}, + {408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 15: 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 491: 408, 408, 494: 408, 496: 408, 498: 408, 408, 408, 507: 408, 408, 514: 408, 408, 522: 408, 524: 408, 588: 408, 665: 408, 667: 408, 408}, + {407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 15: 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 491: 407, 407, 494: 407, 496: 407, 498: 407, 407, 407, 507: 407, 407, 514: 407, 407, 522: 407, 524: 407, 588: 407, 665: 407, 667: 407, 407}, + {406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 15: 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 491: 406, 406, 494: 406, 496: 406, 498: 406, 406, 406, 507: 406, 406, 514: 406, 406, 522: 406, 524: 406, 588: 406, 665: 406, 667: 406, 406}, + {405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 15: 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 491: 405, 405, 494: 405, 496: 405, 498: 405, 405, 405, 507: 405, 405, 514: 405, 405, 522: 405, 524: 405, 588: 405, 665: 405, 667: 405, 405}, // 1795 - {417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 15: 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, 472: 417, 417, 417, 478: 417, 417, 417, 484: 417, 488: 417, 417, 495: 417, 503: 417, 417, 417, 569: 417, 646: 417, 417, 649: 417}, - {479: 4311, 508: 2736, 733: 2735, 741: 4312, 1139: 4334}, - {419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 15: 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 472: 419, 419, 419, 478: 419, 419, 419, 484: 419, 488: 419, 419, 495: 419, 503: 419, 419, 419, 569: 419, 646: 419, 419, 649: 419}, - {508: 2736, 733: 2735, 741: 4336}, - {421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 15: 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 472: 421, 421, 421, 478: 421, 421, 421, 484: 421, 488: 421, 421, 495: 421, 503: 421, 421, 421, 569: 421, 646: 421, 421, 649: 421}, + {404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 15: 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 491: 404, 404, 494: 404, 496: 404, 498: 404, 404, 404, 507: 404, 404, 514: 404, 404, 522: 404, 524: 404, 588: 404, 665: 404, 667: 404, 404}, + {403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 15: 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 491: 403, 403, 494: 403, 496: 403, 498: 403, 403, 403, 507: 403, 403, 514: 403, 403, 522: 403, 524: 403, 588: 403, 665: 403, 667: 403, 403}, + {402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 15: 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 491: 402, 402, 494: 402, 496: 402, 498: 402, 402, 402, 507: 402, 402, 514: 402, 402, 522: 402, 524: 402, 588: 402, 665: 402, 667: 402, 402}, + {493: 4415}, + {429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 15: 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 491: 429, 429, 494: 429, 496: 429, 498: 429, 429, 429, 507: 429, 429, 514: 429, 429, 522: 429, 524: 429, 588: 429, 665: 429, 667: 429, 429}, // 1800 - {508: 2736, 733: 2735, 741: 4338}, - {422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 15: 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 472: 422, 422, 422, 478: 422, 422, 422, 484: 422, 488: 422, 422, 495: 422, 503: 422, 422, 422, 569: 422, 646: 422, 422, 649: 422}, - {475: 4340}, - {423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 15: 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, 472: 423, 423, 423, 478: 423, 423, 423, 484: 423, 488: 423, 423, 495: 423, 503: 423, 423, 423, 569: 423, 646: 423, 423, 649: 423}, - {475: 4342}, + {493: 4417}, + {430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 15: 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 491: 430, 430, 494: 430, 496: 430, 498: 430, 430, 430, 507: 430, 430, 514: 430, 430, 522: 430, 524: 430, 588: 430, 665: 430, 667: 430, 430}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4419, 2850, 688: 2851, 2849}, + {504: 4420}, + {599: 4421}, // 1805 - {424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 15: 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 472: 424, 424, 424, 478: 424, 424, 424, 484: 424, 488: 424, 424, 495: 424, 503: 424, 424, 424, 569: 424, 646: 424, 424, 649: 424}, - {508: 2736, 733: 2735, 741: 4344}, - {425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 15: 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 472: 425, 425, 425, 478: 425, 425, 425, 484: 425, 488: 425, 425, 495: 425, 503: 425, 425, 425, 569: 425, 646: 425, 425, 649: 425}, - {508: 2736, 733: 2735, 741: 4346}, - {426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 15: 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 472: 426, 426, 426, 478: 426, 426, 426, 484: 426, 488: 426, 426, 495: 426, 503: 426, 426, 426, 569: 426, 646: 426, 426, 649: 426}, + {493: 3346, 510: 3337, 525: 3341, 591: 3336, 3338, 3340, 3339, 596: 3344, 598: 3345, 614: 3343, 734: 4422, 3342}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 813: 3551, 828: 4423}, + {431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 15: 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 491: 431, 431, 494: 431, 496: 431, 498: 431, 431, 431, 507: 431, 431, 514: 431, 431, 522: 431, 524: 431, 588: 431, 665: 431, 667: 431, 431}, + {493: 4426, 1067: 4425}, + {432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 15: 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 491: 432, 432, 494: 432, 496: 432, 498: 432, 432, 432, 507: 432, 432, 514: 432, 432, 522: 432, 524: 432, 588: 432, 665: 432, 667: 432, 432}, // 1810 - {475: 4348}, - {427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 15: 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 472: 427, 427, 427, 478: 427, 427, 427, 484: 427, 488: 427, 427, 495: 427, 503: 427, 427, 427, 569: 427, 646: 427, 427, 649: 427}, - {508: 2736, 733: 2735, 741: 4350}, - {428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 15: 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 472: 428, 428, 428, 478: 428, 428, 428, 484: 428, 488: 428, 428, 495: 428, 503: 428, 428, 428, 569: 428, 646: 428, 428, 649: 428}, - {508: 2736, 733: 2735, 741: 4352}, + {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 15: 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 491: 12, 12, 494: 12, 496: 12, 498: 12, 12, 12, 507: 12, 12, 514: 12, 12, 522: 12, 524: 12, 526: 12, 588: 12, 665: 12, 667: 12, 12}, + {492: 4428}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 603, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 4429, 1179: 4430}, + {602, 602, 9: 4033, 58: 602, 494: 602}, + {58: 4431}, // 1815 - {430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 15: 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 472: 430, 430, 430, 478: 430, 430, 430, 484: 430, 488: 430, 430, 495: 430, 503: 430, 430, 430, 569: 430, 646: 430, 430, 649: 430}, - {499: 4281, 508: 2047, 736: 4357}, - {499: 4281, 508: 2047, 736: 4355}, - {508: 2736, 733: 2735, 741: 4356}, - {429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 15: 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, 472: 429, 429, 429, 478: 429, 429, 429, 484: 429, 488: 429, 429, 495: 429, 503: 429, 429, 429, 569: 429, 646: 429, 429, 649: 429}, + {433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 15: 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 491: 433, 433, 494: 433, 496: 433, 498: 433, 433, 433, 507: 433, 433, 514: 433, 433, 522: 433, 524: 433, 588: 433, 665: 433, 667: 433, 433}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 510: 4433, 685: 3598, 2850, 688: 2851, 2849, 760: 4434}, + {435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 15: 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 491: 435, 435, 494: 435, 496: 435, 498: 435, 435, 435, 507: 435, 435, 514: 435, 435, 522: 435, 524: 435, 588: 435, 665: 435, 667: 435, 435}, + {434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 15: 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 491: 434, 434, 494: 434, 496: 434, 498: 434, 434, 434, 507: 434, 434, 514: 434, 434, 522: 434, 524: 434, 588: 434, 665: 434, 667: 434, 434}, + {496: 4437, 525: 2824, 755: 2823, 762: 4438, 1171: 4436}, // 1820 - {508: 2736, 733: 2735, 741: 4358}, - {431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 15: 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 472: 431, 431, 431, 478: 431, 431, 431, 484: 431, 488: 431, 431, 495: 431, 503: 431, 431, 431, 569: 431, 646: 431, 431, 649: 431}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 499: 4281, 530: 2047, 736: 4363}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 499: 4281, 530: 2047, 736: 4361}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3489, 661: 3491, 2762, 2763, 2761, 738: 3488, 872: 4362}, + {438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 15: 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 491: 438, 438, 494: 438, 496: 438, 498: 438, 438, 438, 507: 438, 438, 514: 438, 438, 522: 438, 524: 438, 588: 438, 665: 438, 667: 438, 438}, + {426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 15: 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 491: 426, 426, 494: 426, 496: 426, 498: 426, 426, 426, 507: 426, 426, 514: 426, 426, 522: 426, 524: 426, 588: 426, 665: 426, 667: 426, 426}, + {425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 15: 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 491: 425, 425, 494: 425, 496: 425, 498: 425, 425, 425, 507: 425, 425, 514: 425, 425, 522: 425, 524: 425, 588: 425, 665: 425, 667: 425, 425}, + {525: 2824, 755: 2823, 762: 4440}, + {439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 15: 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, 491: 439, 439, 494: 439, 496: 439, 498: 439, 439, 439, 507: 439, 439, 514: 439, 439, 522: 439, 524: 439, 588: 439, 665: 439, 667: 439, 439}, // 1825 - {432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 15: 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 472: 432, 432, 432, 478: 432, 432, 432, 484: 432, 488: 432, 432, 495: 432, 503: 432, 432, 432, 569: 432, 646: 432, 432, 649: 432}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 4364}, - {433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 15: 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 472: 433, 433, 433, 478: 433, 433, 433, 484: 433, 488: 433, 433, 495: 433, 503: 433, 433, 433, 569: 433, 646: 433, 433, 649: 433}, - {508: 2736, 733: 2735, 741: 4366}, - {2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 15: 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 49: 2121, 472: 2121, 2121, 2121, 478: 2121, 2121, 2121, 484: 2121, 488: 2121, 2121, 495: 2121, 503: 2121, 2121, 2121, 569: 2121, 646: 2121, 2121, 649: 2121}, + {525: 2824, 755: 2823, 762: 4442}, + {440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 15: 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 491: 440, 440, 494: 440, 496: 440, 498: 440, 440, 440, 507: 440, 440, 514: 440, 440, 522: 440, 524: 440, 588: 440, 665: 440, 667: 440, 440}, + {493: 4444}, + {441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 15: 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 491: 441, 441, 494: 441, 496: 441, 498: 441, 441, 441, 507: 441, 441, 514: 441, 441, 522: 441, 524: 441, 588: 441, 665: 441, 667: 441, 441}, + {493: 4446}, // 1830 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4368, 2762, 2763, 2761}, - {2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 15: 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 2122, 49: 2122, 472: 2122, 2122, 2122, 478: 2122, 2122, 2122, 484: 2122, 488: 2122, 2122, 495: 2122, 503: 2122, 2122, 2122, 569: 2122, 646: 2122, 2122, 649: 2122}, - {508: 2736, 733: 2735, 741: 4370}, - {2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 15: 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 49: 2123, 472: 2123, 2123, 2123, 478: 2123, 2123, 2123, 484: 2123, 488: 2123, 2123, 495: 2123, 503: 2123, 2123, 2123, 569: 2123, 646: 2123, 2123, 649: 2123}, - {508: 2736, 733: 2735, 741: 4372}, + {442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 15: 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 491: 442, 442, 494: 442, 496: 442, 498: 442, 442, 442, 507: 442, 442, 514: 442, 442, 522: 442, 524: 442, 588: 442, 665: 442, 667: 442, 442}, + {525: 3530, 593: 3532, 3531, 842: 4448}, + {443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 15: 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 491: 443, 443, 494: 443, 496: 443, 498: 443, 443, 443, 507: 443, 443, 514: 443, 443, 522: 443, 524: 443, 588: 443, 665: 443, 667: 443, 443}, + {525: 2824, 755: 2823, 762: 4450}, + {444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 15: 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 491: 444, 444, 494: 444, 496: 444, 498: 444, 444, 444, 507: 444, 444, 514: 444, 444, 522: 444, 524: 444, 588: 444, 665: 444, 667: 444, 444}, // 1835 - {2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 15: 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 49: 2124, 472: 2124, 2124, 2124, 478: 2124, 2124, 2124, 484: 2124, 488: 2124, 2124, 495: 2124, 503: 2124, 2124, 2124, 569: 2124, 646: 2124, 2124, 649: 2124}, - {475: 2047, 499: 4281, 736: 4374}, - {475: 4375}, - {2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 15: 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 2125, 49: 2125, 472: 2125, 2125, 2125, 478: 2125, 2125, 2125, 484: 2125, 488: 2125, 2125, 495: 2125, 503: 2125, 2125, 2125, 569: 2125, 646: 2125, 2125, 649: 2125}, - {475: 2047, 499: 4281, 736: 4377}, + {525: 2824, 755: 2823, 762: 4452}, + {445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 15: 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 491: 445, 445, 494: 445, 496: 445, 498: 445, 445, 445, 507: 445, 445, 514: 445, 445, 522: 445, 524: 445, 588: 445, 665: 445, 667: 445, 445}, + {496: 4455, 525: 2824, 755: 2823, 762: 4454}, + {447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 15: 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 491: 447, 447, 494: 447, 496: 447, 498: 447, 447, 447, 507: 447, 447, 514: 447, 447, 522: 447, 524: 447, 588: 447, 665: 447, 667: 447, 447}, + {446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 15: 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 491: 446, 446, 494: 446, 496: 446, 498: 446, 446, 446, 507: 446, 446, 514: 446, 446, 522: 446, 524: 446, 588: 446, 665: 446, 667: 446, 446}, // 1840 - {475: 4378}, - {2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 15: 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 2126, 49: 2126, 472: 2126, 2126, 2126, 478: 2126, 2126, 2126, 484: 2126, 488: 2126, 2126, 495: 2126, 503: 2126, 2126, 2126, 569: 2126, 646: 2126, 2126, 649: 2126}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 661: 3491, 2762, 2763, 2761, 738: 4380}, - {2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 15: 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127, 49: 2127, 472: 2127, 2127, 2127, 478: 2127, 2127, 2127, 484: 2127, 488: 2127, 2127, 495: 2127, 503: 2127, 2127, 2127, 569: 2127, 646: 2127, 2127, 649: 2127}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 499: 4281, 736: 4384}, + {496: 4458, 525: 2824, 755: 2823, 762: 4457}, + {449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 15: 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 491: 449, 449, 494: 449, 496: 449, 498: 449, 449, 449, 507: 449, 449, 514: 449, 449, 522: 449, 524: 449, 588: 449, 665: 449, 667: 449, 449}, + {448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 15: 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 491: 448, 448, 494: 448, 496: 448, 498: 448, 448, 448, 507: 448, 448, 514: 448, 448, 522: 448, 524: 448, 588: 448, 665: 448, 667: 448, 448}, + {496: 4437, 525: 2824, 755: 2823, 762: 4438, 1171: 4460}, + {450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 15: 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 491: 450, 450, 494: 450, 496: 450, 498: 450, 450, 450, 507: 450, 450, 514: 450, 450, 522: 450, 524: 450, 588: 450, 665: 450, 667: 450, 450}, // 1845 - {406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 15: 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 472: 406, 406, 406, 478: 406, 406, 406, 484: 406, 488: 406, 406, 495: 406, 503: 406, 406, 406, 569: 406, 646: 406, 406, 649: 406}, - {405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 15: 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 472: 405, 405, 405, 478: 405, 405, 405, 484: 405, 488: 405, 405, 495: 405, 503: 405, 405, 405, 569: 405, 646: 405, 405, 649: 405}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 661: 3491, 2762, 2763, 2761, 738: 4385}, - {2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 15: 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 2128, 49: 2128, 472: 2128, 2128, 2128, 478: 2128, 2128, 2128, 484: 2128, 488: 2128, 2128, 495: 2128, 503: 2128, 2128, 2128, 569: 2128, 646: 2128, 2128, 649: 2128}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 661: 3491, 2762, 2763, 2761, 738: 4387}, + {525: 2824, 755: 2823, 762: 4462}, + {452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 15: 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, 491: 452, 452, 494: 452, 496: 452, 498: 452, 452, 452, 507: 452, 452, 514: 452, 452, 522: 452, 524: 452, 588: 452, 665: 452, 667: 452, 452}, + {525: 2824, 755: 2823, 762: 4464}, + {453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 15: 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 491: 453, 453, 494: 453, 496: 453, 498: 453, 453, 453, 507: 453, 453, 514: 453, 453, 522: 453, 524: 453, 588: 453, 665: 453, 667: 453, 453}, + {493: 4466}, // 1850 - {2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 15: 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 49: 2129, 472: 2129, 2129, 2129, 478: 2129, 2129, 2129, 484: 2129, 488: 2129, 2129, 495: 2129, 503: 2129, 2129, 2129, 569: 2129, 646: 2129, 2129, 649: 2129}, - {475: 4389}, - {2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 15: 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 49: 2130, 472: 2130, 2130, 2130, 478: 2130, 2130, 2130, 484: 2130, 488: 2130, 2130, 495: 2130, 503: 2130, 2130, 2130, 569: 2130, 646: 2130, 2130, 649: 2130}, - {6: 4241, 4243, 400, 10: 4210, 15: 4260, 2176, 4258, 4197, 4262, 4249, 4278, 4242, 4245, 4244, 4247, 4248, 4250, 4257, 400, 4268, 4269, 4255, 4256, 4261, 4263, 4275, 4274, 4280, 4276, 4273, 4266, 4271, 4272, 4265, 4267, 4270, 4259, 71: 4212, 74: 4233, 4234, 83: 4235, 134: 4215, 183: 4204, 203: 4198, 205: 4219, 208: 4220, 219: 4214, 224: 4230, 237: 4208, 246: 4216, 252: 4211, 269: 4221, 277: 4217, 284: 4231, 4232, 290: 4199, 474: 4229, 479: 4240, 4277, 484: 2176, 497: 4236, 502: 4218, 4228, 505: 2176, 4201, 584: 4202, 590: 4207, 647: 2176, 649: 4246, 665: 4223, 669: 4209, 671: 4237, 679: 4222, 686: 4224, 689: 4203, 704: 4213, 781: 4251, 792: 4253, 813: 4252, 835: 4254, 838: 4264, 842: 4279, 870: 4227, 883: 4225, 919: 4200, 926: 4205, 989: 4391, 1138: 4206, 1165: 4226}, - {2409, 2409, 2409, 2409, 2409, 2409, 9: 2409, 488: 2409}, + {454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 15: 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, 491: 454, 454, 494: 454, 496: 454, 498: 454, 454, 454, 507: 454, 454, 514: 454, 454, 522: 454, 524: 454, 588: 454, 665: 454, 667: 454, 454}, + {493: 4468}, + {455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 15: 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 491: 455, 455, 494: 455, 496: 455, 498: 455, 455, 455, 507: 455, 455, 514: 455, 455, 522: 455, 524: 455, 588: 455, 665: 455, 667: 455, 455}, + {525: 2824, 755: 2823, 762: 4470}, + {456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 15: 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 491: 456, 456, 494: 456, 496: 456, 498: 456, 456, 456, 507: 456, 456, 514: 456, 456, 522: 456, 524: 456, 588: 456, 665: 456, 667: 456, 456}, // 1855 - {2423, 2423, 2423, 2423, 2423, 2423, 9: 2423, 488: 2423}, - {2422, 2422, 2422, 2422, 2422, 2422, 9: 2422, 488: 2422}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 479: 4395, 661: 4396, 2762, 2763, 2761}, - {2425, 2425, 2425, 2425, 2425, 2425, 9: 2425, 83: 2425, 488: 2425}, - {2424, 2424, 2424, 2424, 2424, 2424, 9: 2424, 83: 2424, 488: 2424}, + {525: 2824, 755: 2823, 762: 4472}, + {457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 15: 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, 491: 457, 457, 494: 457, 496: 457, 498: 457, 457, 457, 507: 457, 457, 514: 457, 457, 522: 457, 524: 457, 588: 457, 665: 457, 667: 457, 457}, + {493: 4474}, + {458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 15: 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 491: 458, 458, 494: 458, 496: 458, 498: 458, 458, 458, 507: 458, 458, 514: 458, 458, 522: 458, 524: 458, 588: 458, 665: 458, 667: 458, 458}, + {525: 2824, 755: 2823, 762: 4476}, // 1860 - {151: 4402, 240: 4399, 261: 4400, 263: 4401, 479: 4398}, - {2430, 2430, 2430, 2430, 2430, 2430, 9: 2430, 488: 2430, 497: 2430}, - {2429, 2429, 2429, 2429, 2429, 2429, 9: 2429, 488: 2429, 497: 2429}, - {2428, 2428, 2428, 2428, 2428, 2428, 9: 2428, 488: 2428, 497: 2428}, - {2427, 2427, 2427, 2427, 2427, 2427, 9: 2427, 488: 2427, 497: 2427}, + {459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 15: 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 491: 459, 459, 494: 459, 496: 459, 498: 459, 459, 459, 507: 459, 459, 514: 459, 459, 522: 459, 524: 459, 588: 459, 665: 459, 667: 459, 459}, + {525: 2824, 755: 2823, 762: 4478}, + {461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 15: 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 491: 461, 461, 494: 461, 496: 461, 498: 461, 461, 461, 507: 461, 461, 514: 461, 461, 522: 461, 524: 461, 588: 461, 665: 461, 667: 461, 461}, + {517: 4397, 525: 2109, 758: 4483}, + {517: 4397, 525: 2109, 758: 4481}, // 1865 - {2426, 2426, 2426, 2426, 2426, 2426, 9: 2426, 488: 2426, 497: 2426}, - {2448, 2448, 2448, 2448, 2448, 2448, 9: 2448, 488: 2448}, - {2449, 2449, 2449, 2449, 2449, 2449, 9: 2449, 488: 2449}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4418, 2762, 2763, 2761}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4417}, + {525: 2824, 755: 2823, 762: 4482}, + {460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 15: 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, 491: 460, 460, 494: 460, 496: 460, 498: 460, 460, 460, 507: 460, 460, 514: 460, 460, 522: 460, 524: 460, 588: 460, 665: 460, 667: 460, 460}, + {525: 2824, 755: 2823, 762: 4484}, + {462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 15: 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, 491: 462, 462, 494: 462, 496: 462, 498: 462, 462, 462, 507: 462, 462, 514: 462, 462, 522: 462, 524: 462, 588: 462, 665: 462, 667: 462, 462}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 517: 4397, 549: 2109, 758: 4489}, // 1870 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4416}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4415}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4412, 2762, 2763, 2761}, - {2: 2421, 2421, 2421, 2421, 2421, 2421, 2421, 10: 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 50: 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 473: 2421, 481: 2421, 494: 2421, 564: 2421}, - {2: 2420, 2420, 2420, 2420, 2420, 2420, 2420, 10: 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 50: 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 473: 2420, 481: 2420, 494: 2420, 564: 2420}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 517: 4397, 549: 2109, 758: 4487}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3596, 685: 3598, 2850, 688: 2851, 2849, 760: 3595, 895: 4488}, + {463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 15: 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, 491: 463, 463, 494: 463, 496: 463, 498: 463, 463, 463, 507: 463, 463, 514: 463, 463, 522: 463, 524: 463, 588: 463, 665: 463, 667: 463, 463}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 4490}, + {464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 15: 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, 491: 464, 464, 494: 464, 496: 464, 498: 464, 464, 464, 507: 464, 464, 514: 464, 464, 522: 464, 524: 464, 588: 464, 665: 464, 667: 464, 464}, // 1875 - {650: 4413}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4414, 2762, 2763, 2761}, - {2454, 2454, 2454, 2454, 2454, 2454, 9: 2454, 488: 2454}, - {2455, 2455, 2455, 2455, 2455, 2455, 9: 2455, 488: 2455}, - {2456, 2456, 2456, 2456, 2456, 2456, 9: 2456, 488: 2456}, + {525: 2824, 755: 2823, 762: 4492}, + {2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 15: 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 58: 2183, 491: 2183, 2183, 494: 2183, 496: 2183, 498: 2183, 2183, 2183, 507: 2183, 2183, 514: 2183, 2183, 522: 2183, 524: 2183, 588: 2183, 665: 2183, 667: 2183, 2183}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4494, 2850, 688: 2851, 2849}, + {2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 15: 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 58: 2184, 491: 2184, 2184, 494: 2184, 496: 2184, 498: 2184, 2184, 2184, 507: 2184, 2184, 514: 2184, 2184, 522: 2184, 524: 2184, 588: 2184, 665: 2184, 667: 2184, 2184}, + {525: 2824, 755: 2823, 762: 4496}, // 1880 - {2457, 2457, 2457, 2457, 2457, 2457, 9: 2457, 488: 2457}, - {650: 4419}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4420, 2762, 2763, 2761}, - {2458, 2458, 2458, 2458, 2458, 2458, 9: 2458, 488: 2458}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4436}, + {2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 15: 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 58: 2185, 491: 2185, 2185, 494: 2185, 496: 2185, 498: 2185, 2185, 2185, 507: 2185, 2185, 514: 2185, 2185, 522: 2185, 524: 2185, 588: 2185, 665: 2185, 667: 2185, 2185}, + {525: 2824, 755: 2823, 762: 4498}, + {2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 15: 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 2186, 58: 2186, 491: 2186, 2186, 494: 2186, 496: 2186, 498: 2186, 2186, 2186, 507: 2186, 2186, 514: 2186, 2186, 522: 2186, 524: 2186, 588: 2186, 665: 2186, 667: 2186, 2186}, + {493: 2109, 517: 4397, 758: 4500}, + {493: 4501}, // 1885 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4431, 2762, 2763, 2761}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4427, 2762, 2763, 2761}, - {2: 2416, 2416, 2416, 2416, 2416, 2416, 2416, 10: 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 50: 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 2416, 473: 2416, 564: 2416}, - {2: 442, 442, 442, 442, 442, 442, 442, 10: 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 50: 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442}, - {2: 441, 441, 441, 441, 441, 441, 441, 10: 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 50: 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, 441}, + {2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 15: 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 58: 2187, 491: 2187, 2187, 494: 2187, 496: 2187, 498: 2187, 2187, 2187, 507: 2187, 2187, 514: 2187, 2187, 522: 2187, 524: 2187, 588: 2187, 665: 2187, 667: 2187, 2187}, + {493: 2109, 517: 4397, 758: 4503}, + {493: 4504}, + {2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 15: 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 2188, 58: 2188, 491: 2188, 2188, 494: 2188, 496: 2188, 498: 2188, 2188, 2188, 507: 2188, 2188, 514: 2188, 2188, 522: 2188, 524: 2188, 588: 2188, 665: 2188, 667: 2188, 2188}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 685: 3598, 2850, 688: 2851, 2849, 760: 4506}, // 1890 - {86: 4430, 89: 4429, 856: 4428}, - {2443, 2443, 2443, 2443, 2443, 2443, 9: 2443, 488: 2443}, - {1834, 1834, 1834, 1834, 1834, 1834, 1834, 9: 1834, 19: 1834, 49: 1834, 83: 1834, 1834, 1834, 1834, 1834, 89: 1834, 474: 1834, 481: 1834, 488: 1834, 497: 1834}, - {1833, 1833, 1833, 1833, 1833, 1833, 1833, 9: 1833, 19: 1833, 49: 1833, 83: 1833, 1833, 1833, 1833, 1833, 89: 1833, 474: 1833, 481: 1833, 488: 1833, 497: 1833}, - {149: 4433, 476: 4089, 4088, 810: 4434, 934: 4432}, + {2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 15: 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 2189, 58: 2189, 491: 2189, 2189, 494: 2189, 496: 2189, 498: 2189, 2189, 2189, 507: 2189, 2189, 514: 2189, 2189, 522: 2189, 524: 2189, 588: 2189, 665: 2189, 667: 2189, 2189}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 517: 4397, 758: 4510}, + {437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 15: 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 491: 437, 437, 494: 437, 496: 437, 498: 437, 437, 437, 507: 437, 437, 514: 437, 437, 522: 437, 524: 437, 588: 437, 665: 437, 667: 437, 437}, + {436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 15: 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 491: 436, 436, 494: 436, 496: 436, 498: 436, 436, 436, 507: 436, 436, 514: 436, 436, 522: 436, 524: 436, 588: 436, 665: 436, 667: 436, 436}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 685: 3598, 2850, 688: 2851, 2849, 760: 4511}, // 1895 - {2445, 2445, 2445, 2445, 2445, 2445, 9: 2445, 488: 2445}, - {2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 49: 2312, 472: 2312, 476: 2312, 2312, 2312, 2312, 484: 2312, 488: 2312, 492: 2312, 581: 2312, 590: 2312, 2312, 642: 2312, 2312, 2312, 2312}, - {149: 4435}, - {2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 49: 2311, 472: 2311, 476: 2311, 2311, 2311, 2311, 484: 2311, 488: 2311, 492: 2311, 581: 2311, 590: 2311, 2311, 642: 2311, 2311, 2311, 2311}, - {506: 4437, 669: 4438}, + {2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 15: 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 2190, 58: 2190, 491: 2190, 2190, 494: 2190, 496: 2190, 498: 2190, 2190, 2190, 507: 2190, 2190, 514: 2190, 2190, 522: 2190, 524: 2190, 588: 2190, 665: 2190, 667: 2190, 2190}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 685: 3598, 2850, 688: 2851, 2849, 760: 4513}, + {2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 15: 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 58: 2191, 491: 2191, 2191, 494: 2191, 496: 2191, 498: 2191, 2191, 2191, 507: 2191, 2191, 514: 2191, 2191, 522: 2191, 524: 2191, 588: 2191, 665: 2191, 667: 2191, 2191}, + {493: 4515}, + {2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 15: 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 58: 2192, 491: 2192, 2192, 494: 2192, 496: 2192, 498: 2192, 2192, 2192, 507: 2192, 2192, 514: 2192, 2192, 522: 2192, 524: 2192, 588: 2192, 665: 2192, 667: 2192, 2192}, // 1900 - {479: 4440}, - {479: 4439}, - {2459, 2459, 2459, 2459, 2459, 2459, 9: 2459, 488: 2459}, - {473: 4442, 475: 3239, 485: 4444, 4445, 492: 3230, 508: 3234, 571: 3229, 3231, 3233, 3232, 576: 3237, 580: 3238, 592: 3236, 712: 4443, 3235, 1134: 4441}, - {2461, 2461, 2461, 2461, 2461, 2461, 9: 2461, 488: 2461}, + {6: 4354, 4356, 428, 10: 4323, 15: 4373, 2238, 4371, 4310, 4375, 4362, 4391, 4355, 4358, 4357, 4360, 4361, 4363, 4370, 428, 4381, 4382, 4392, 4368, 4369, 4374, 4376, 4388, 4387, 4396, 4389, 4386, 4379, 4384, 4385, 4378, 4380, 4383, 4372, 4393, 4394, 78: 4325, 81: 4346, 4347, 90: 4348, 151: 4328, 196: 4317, 217: 4311, 220: 4332, 223: 4333, 233: 4327, 239: 4343, 253: 4321, 261: 4329, 267: 4324, 284: 4334, 292: 4330, 299: 4344, 4345, 304: 4312, 494: 4342, 496: 4353, 499: 2238, 4390, 514: 2238, 518: 4349, 523: 4331, 4341, 526: 4314, 604: 4315, 607: 4320, 667: 2238, 4359, 682: 4336, 690: 4322, 692: 4350, 701: 4335, 708: 4337, 711: 4316, 726: 4326, 803: 4364, 816: 4366, 837: 4365, 858: 4367, 862: 4377, 866: 4395, 893: 4340, 906: 4338, 944: 4313, 951: 4318, 1015: 4517, 1170: 4319, 1198: 4339}, + {2479, 2479, 2479, 2479, 2479, 2479, 9: 2479, 507: 2479}, + {2493, 2493, 2493, 2493, 2493, 2493, 9: 2493, 507: 2493}, + {2492, 2492, 2492, 2492, 2492, 2492, 9: 2492, 507: 2492}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 496: 4521, 685: 4522, 2850, 688: 2851, 2849}, // 1905 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4448}, - {2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 2225, 49: 2225, 472: 2225, 476: 2225, 2225, 2225, 2225, 484: 2225, 488: 2225, 492: 2225, 581: 2225, 590: 2225, 2225, 642: 2225, 2225, 2225, 2225}, - {508: 3423, 573: 3425, 3424, 820: 4447}, - {508: 3423, 573: 3425, 3424, 820: 4446}, - {2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 2223, 49: 2223, 472: 2223, 476: 2223, 2223, 2223, 2223, 484: 2223, 488: 2223, 492: 2223, 581: 2223, 590: 2223, 2223, 642: 2223, 2223, 2223, 2223}, + {2495, 2495, 2495, 2495, 2495, 2495, 9: 2495, 90: 2495, 507: 2495}, + {2494, 2494, 2494, 2494, 2494, 2494, 9: 2494, 90: 2494, 507: 2494}, + {141: 4528, 256: 4525, 276: 4526, 278: 4527, 496: 4524}, + {2500, 2500, 2500, 2500, 2500, 2500, 9: 2500, 507: 2500, 518: 2500}, + {2499, 2499, 2499, 2499, 2499, 2499, 9: 2499, 507: 2499, 518: 2499}, // 1910 - {2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 49: 2224, 472: 2224, 476: 2224, 2224, 2224, 2224, 484: 2224, 488: 2224, 492: 2224, 581: 2224, 590: 2224, 2224, 642: 2224, 2224, 2224, 2224}, - {49: 4449, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2460, 2460, 2460, 2460, 2460, 2460, 9: 2460, 488: 2460}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 4451}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4454}, + {2498, 2498, 2498, 2498, 2498, 2498, 9: 2498, 507: 2498, 518: 2498}, + {2497, 2497, 2497, 2497, 2497, 2497, 9: 2497, 507: 2497, 518: 2497}, + {2496, 2496, 2496, 2496, 2496, 2496, 9: 2496, 507: 2496, 518: 2496}, + {2518, 2518, 2518, 2518, 2518, 2518, 9: 2518, 507: 2518}, + {2519, 2519, 2519, 2519, 2519, 2519, 9: 2519, 507: 2519}, // 1915 - {583: 4453}, - {1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 50: 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 1859, 475: 1859, 488: 1859, 570: 1859}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4456, 848: 4455}, - {2415, 2415, 2415, 2415, 2415, 2415, 9: 2415, 4731, 4732, 488: 2415, 929: 4730}, - {12: 4458, 104: 4506, 109: 4507, 171: 4497, 178: 4517, 4516, 4482, 199: 4518, 4519, 230: 4479, 316: 4486, 4478, 338: 4495, 360: 4502, 4501, 364: 4505, 399: 4513, 505: 4500, 4496, 530: 4491, 647: 4499, 677: 4504, 4503, 680: 4480, 4485, 4483, 4476, 4470, 4484, 688: 4492, 690: 4477, 4509, 4471, 4472, 4473, 4474, 4475, 4498, 4511, 4515, 4510, 4469, 4514, 4481, 705: 4468, 4508, 4467, 4512, 901: 4487, 1157: 4489, 1182: 4466, 4493, 4463, 1202: 4461, 1217: 4464, 1219: 4465, 1237: 4462, 1255: 4488, 1257: 4459, 4490, 1315: 4460, 1327: 4494, 1330: 4457, 1355: 4520}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4544, 2850, 688: 2851, 2849}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4543}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4542}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4541}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4538, 2850, 688: 2851, 2849}, // 1920 - {2272, 2272, 2272, 2272, 2272, 2272, 4600, 4606, 4594, 2272, 2272, 2272, 4598, 4607, 4605, 49: 2272, 472: 4599, 476: 4089, 4088, 2279, 4597, 484: 4604, 488: 2272, 492: 4593, 581: 2316, 590: 2406, 4591, 642: 4596, 4589, 4611, 4608, 810: 4592, 833: 4601, 910: 4603, 928: 4609, 937: 4602, 956: 4595, 1003: 4610, 4729}, - {2272, 2272, 2272, 2272, 2272, 2272, 4600, 4606, 4594, 2272, 2272, 2272, 4598, 4607, 4605, 49: 2272, 472: 4599, 476: 4089, 4088, 2279, 4597, 484: 4604, 488: 2272, 492: 4593, 581: 2316, 590: 2406, 4591, 642: 4596, 4589, 4611, 4608, 810: 4592, 833: 4601, 910: 4603, 928: 4609, 937: 4602, 956: 4595, 1003: 4610, 4590}, - {373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 49: 373, 472: 373, 476: 373, 373, 373, 373, 484: 373, 488: 373, 492: 373, 581: 373, 590: 373, 373, 642: 373, 373, 373, 373}, - {372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 49: 372, 472: 372, 476: 372, 372, 372, 372, 484: 372, 488: 372, 492: 372, 581: 372, 590: 372, 372, 642: 372, 372, 372, 372}, - {371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 49: 371, 472: 371, 476: 371, 371, 371, 371, 484: 371, 488: 371, 492: 371, 581: 371, 590: 371, 371, 642: 371, 371, 371, 371}, + {2: 2491, 2491, 2491, 2491, 2491, 2491, 2491, 10: 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 59: 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 2491, 492: 2491, 501: 2491, 513: 2491, 583: 2491}, + {2: 2490, 2490, 2490, 2490, 2490, 2490, 2490, 10: 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 59: 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 492: 2490, 501: 2490, 513: 2490, 583: 2490}, + {670: 4539}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4540, 2850, 688: 2851, 2849}, + {2524, 2524, 2524, 2524, 2524, 2524, 9: 2524, 507: 2524}, // 1925 - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 51: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 740: 288, 743: 288, 764: 3827, 789: 4587}, - {283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 49: 283, 51: 283, 472: 283, 476: 283, 283, 283, 283, 484: 283, 488: 283, 492: 283, 581: 283, 590: 283, 283, 642: 283, 283, 283, 283, 740: 283, 743: 283, 876: 4586}, - {281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 49: 281, 51: 281, 472: 281, 3813, 476: 281, 281, 281, 281, 484: 281, 488: 281, 492: 281, 581: 281, 590: 281, 281, 642: 281, 281, 281, 281, 740: 281, 743: 281, 764: 3814, 904: 4584, 909: 3815}, - {281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 49: 281, 51: 281, 472: 281, 3813, 476: 281, 281, 281, 281, 484: 281, 488: 281, 492: 281, 581: 281, 590: 281, 281, 642: 281, 281, 281, 281, 740: 281, 743: 281, 764: 3814, 904: 4582, 909: 3815}, - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 764: 3827, 789: 4581}, + {2525, 2525, 2525, 2525, 2525, 2525, 9: 2525, 507: 2525}, + {2526, 2526, 2526, 2526, 2526, 2526, 9: 2526, 507: 2526}, + {2527, 2527, 2527, 2527, 2527, 2527, 9: 2527, 507: 2527}, + {670: 4545}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4546, 2850, 688: 2851, 2849}, // 1930 - {365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 49: 365, 51: 365, 472: 365, 365, 476: 365, 365, 365, 365, 484: 365, 488: 365, 492: 365, 581: 365, 590: 365, 365, 642: 365, 365, 365, 365, 740: 365, 743: 365}, - {364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 49: 364, 51: 364, 472: 364, 364, 476: 364, 364, 364, 364, 484: 364, 488: 364, 492: 364, 581: 364, 590: 364, 364, 642: 364, 364, 364, 364, 740: 364, 743: 364}, - {363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 49: 363, 51: 363, 472: 363, 363, 476: 363, 363, 363, 363, 484: 363, 488: 363, 492: 363, 581: 363, 590: 363, 363, 642: 363, 363, 363, 363, 740: 363, 743: 363}, - {362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 49: 362, 51: 362, 472: 362, 362, 476: 362, 362, 362, 362, 484: 362, 488: 362, 492: 362, 581: 362, 590: 362, 362, 642: 362, 362, 362, 362, 740: 362, 743: 362}, - {361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 49: 361, 51: 361, 472: 361, 361, 476: 361, 361, 361, 361, 484: 361, 488: 361, 492: 361, 581: 361, 590: 361, 361, 642: 361, 361, 361, 361, 740: 361, 743: 361}, + {2528, 2528, 2528, 2528, 2528, 2528, 9: 2528, 507: 2528}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4562}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4557, 2850, 688: 2851, 2849}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4553, 2850, 688: 2851, 2849}, + {2: 2486, 2486, 2486, 2486, 2486, 2486, 2486, 10: 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 59: 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 492: 2486, 583: 2486}, // 1935 - {360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 49: 360, 51: 360, 472: 360, 360, 476: 360, 360, 360, 360, 484: 360, 488: 360, 492: 360, 581: 360, 590: 360, 360, 642: 360, 360, 360, 360, 740: 360, 743: 360}, - {359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 49: 359, 51: 359, 472: 359, 359, 476: 359, 359, 359, 359, 484: 359, 488: 359, 492: 359, 581: 359, 590: 359, 359, 642: 359, 359, 359, 359, 740: 359, 743: 359}, - {358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 49: 358, 51: 358, 472: 358, 358, 476: 358, 358, 358, 358, 484: 358, 488: 358, 492: 358, 581: 358, 590: 358, 358, 642: 358, 358, 358, 358, 740: 358, 743: 358}, - {357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 49: 357, 51: 357, 472: 357, 357, 476: 357, 357, 357, 357, 484: 357, 488: 357, 492: 357, 581: 357, 590: 357, 357, 642: 357, 357, 357, 357, 740: 357, 743: 357}, - {356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 49: 356, 51: 356, 472: 356, 356, 476: 356, 356, 356, 356, 484: 356, 488: 356, 492: 356, 581: 356, 590: 356, 356, 642: 356, 356, 356, 356, 740: 356, 743: 356}, + {2: 473, 473, 473, 473, 473, 473, 473, 10: 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 59: 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473}, + {2: 472, 472, 472, 472, 472, 472, 472, 10: 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 59: 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, 472}, + {93: 4556, 96: 4555, 879: 4554}, + {2513, 2513, 2513, 2513, 2513, 2513, 9: 2513, 507: 2513}, + {1894, 1894, 1894, 1894, 1894, 1894, 1894, 9: 1894, 19: 1894, 58: 1894, 90: 1894, 1894, 1894, 1894, 1894, 96: 1894, 494: 1894, 501: 1894, 507: 1894, 518: 1894}, // 1940 - {355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 49: 355, 51: 355, 472: 355, 355, 476: 355, 355, 355, 355, 484: 355, 488: 355, 492: 355, 581: 355, 590: 355, 355, 642: 355, 355, 355, 355, 740: 355, 743: 355}, - {354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 49: 354, 51: 354, 472: 354, 476: 354, 354, 354, 354, 484: 354, 488: 354, 492: 354, 581: 354, 590: 354, 354, 642: 354, 354, 354, 354, 740: 354, 743: 354}, - {353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 49: 353, 51: 353, 472: 353, 476: 353, 353, 353, 353, 484: 353, 488: 353, 492: 353, 581: 353, 590: 353, 353, 642: 353, 353, 353, 353, 740: 353, 743: 353}, - {349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 49: 349, 51: 349, 472: 349, 349, 476: 349, 349, 349, 349, 484: 349, 488: 349, 492: 349, 581: 349, 590: 349, 349, 642: 349, 349, 349, 349, 740: 349, 743: 349}, - {348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 49: 348, 51: 348, 472: 348, 348, 476: 348, 348, 348, 348, 484: 348, 488: 348, 492: 348, 581: 348, 590: 348, 348, 642: 348, 348, 348, 348, 740: 348, 743: 348}, + {1893, 1893, 1893, 1893, 1893, 1893, 1893, 9: 1893, 19: 1893, 58: 1893, 90: 1893, 1893, 1893, 1893, 1893, 96: 1893, 494: 1893, 501: 1893, 507: 1893, 518: 1893}, + {163: 4559, 495: 4198, 497: 4197, 834: 4560, 960: 4558}, + {2515, 2515, 2515, 2515, 2515, 2515, 9: 2515, 507: 2515}, + {2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 58: 2379, 491: 2379, 495: 2379, 2379, 2379, 2379, 2379, 507: 2379, 510: 2379, 600: 2379, 607: 2379, 613: 2379, 662: 2379, 2379, 2379, 666: 2379}, + {163: 4561}, // 1945 - {347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 49: 347, 51: 347, 472: 347, 347, 476: 347, 347, 347, 347, 484: 347, 488: 347, 492: 347, 581: 347, 590: 347, 347, 642: 347, 347, 347, 347, 740: 347, 743: 347}, - {346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 49: 346, 51: 346, 472: 346, 346, 476: 346, 346, 346, 346, 484: 346, 488: 346, 492: 346, 581: 346, 590: 346, 346, 642: 346, 346, 346, 346, 740: 346, 743: 346}, - {345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 49: 345, 51: 345, 472: 345, 345, 476: 345, 345, 345, 345, 484: 345, 488: 345, 492: 345, 581: 345, 590: 345, 345, 642: 345, 345, 345, 345, 740: 345, 743: 345}, - {344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 49: 344, 51: 344, 472: 344, 344, 476: 344, 344, 344, 344, 484: 344, 488: 344, 492: 344, 581: 344, 590: 344, 344, 642: 344, 344, 344, 344, 740: 344, 743: 344, 1281: 4580}, - {342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 49: 342, 472: 342, 342, 476: 342, 342, 342, 342, 484: 342, 488: 342, 492: 342, 581: 342, 590: 342, 342, 642: 342, 342, 342, 342}, + {2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 2378, 58: 2378, 491: 2378, 495: 2378, 2378, 2378, 2378, 2378, 507: 2378, 510: 2378, 600: 2378, 607: 2378, 613: 2378, 662: 2378, 2378, 2378, 666: 2378}, + {526: 4563, 690: 4564}, + {496: 4566}, + {496: 4565}, + {2529, 2529, 2529, 2529, 2529, 2529, 9: 2529, 507: 2529}, // 1950 - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 472: 275, 3826, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 764: 4577, 773: 3834, 799: 4578}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 472: 275, 3826, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 764: 4574, 773: 3834, 799: 4575}, - {473: 3826, 764: 4572}, - {473: 3826, 764: 4570}, - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 764: 3827, 789: 4569}, + {492: 4568, 3346, 504: 4570, 4571, 510: 3337, 525: 3341, 591: 3336, 3338, 3340, 3339, 596: 3344, 598: 3345, 614: 3343, 734: 4569, 3342, 1166: 4567}, + {2531, 2531, 2531, 2531, 2531, 2531, 9: 2531, 507: 2531}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4574}, + {2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 58: 2288, 491: 2288, 495: 2288, 2288, 2288, 2288, 2288, 507: 2288, 510: 2288, 600: 2288, 607: 2288, 613: 2288, 662: 2288, 2288, 2288, 666: 2288}, + {525: 3530, 593: 3532, 3531, 842: 4573}, // 1955 - {473: 3826, 764: 4568}, - {333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 49: 333, 472: 333, 476: 333, 333, 333, 333, 484: 333, 488: 333, 492: 333, 581: 333, 590: 333, 333, 642: 333, 333, 333, 333}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 106: 4549, 4551, 110: 4550, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4548, 884: 4567}, - {473: 4563}, - {473: 4553}, + {525: 3530, 593: 3532, 3531, 842: 4572}, + {2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 58: 2286, 491: 2286, 495: 2286, 2286, 2286, 2286, 2286, 507: 2286, 510: 2286, 600: 2286, 607: 2286, 613: 2286, 662: 2286, 2286, 2286, 666: 2286}, + {2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 58: 2287, 491: 2287, 495: 2287, 2287, 2287, 2287, 2287, 507: 2287, 510: 2287, 600: 2287, 607: 2287, 613: 2287, 662: 2287, 2287, 2287, 666: 2287}, + {58: 4575, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2530, 2530, 2530, 2530, 2530, 2530, 9: 2530, 507: 2530}, // 1960 - {329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 49: 329, 472: 329, 476: 329, 329, 329, 329, 484: 329, 488: 329, 492: 329, 581: 329, 590: 329, 329, 642: 329, 329, 329, 329}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 106: 4549, 4551, 110: 4550, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 4546, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 4545, 677: 4504, 4503, 688: 4547, 773: 3834, 799: 4548, 884: 4544, 1157: 4543}, - {326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 16: 326, 49: 326, 472: 326, 326, 476: 326, 326, 326, 326, 484: 326, 488: 326, 492: 326, 505: 326, 530: 326, 581: 326, 590: 326, 326, 642: 326, 326, 326, 326, 647: 326, 843: 4542}, - {325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 16: 325, 49: 325, 472: 325, 325, 476: 325, 325, 325, 325, 484: 325, 488: 325, 492: 325, 505: 325, 530: 325, 581: 325, 590: 325, 325, 642: 325, 325, 325, 325, 647: 325, 843: 4541}, - {324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 16: 324, 49: 324, 472: 324, 324, 476: 324, 324, 324, 324, 484: 324, 488: 324, 492: 324, 505: 324, 530: 324, 581: 324, 590: 324, 324, 642: 324, 324, 324, 324, 647: 324, 677: 4539, 4538, 843: 4540}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 4577}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4580}, + {603: 4579}, + {1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 59: 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 493: 1919, 507: 1919, 590: 1919}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4582, 872: 4581}, // 1965 - {505: 4533, 647: 4532, 677: 4535, 4534}, - {319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 16: 319, 49: 319, 106: 319, 319, 110: 319, 472: 319, 319, 476: 319, 319, 319, 319, 484: 319, 488: 319, 492: 319, 505: 319, 530: 319, 581: 319, 590: 319, 319, 642: 319, 319, 319, 319, 647: 319}, - {318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 16: 318, 49: 318, 106: 318, 318, 110: 318, 472: 318, 318, 476: 318, 318, 318, 318, 484: 318, 488: 318, 492: 318, 505: 318, 530: 318, 581: 318, 590: 318, 318, 642: 318, 318, 318, 318, 647: 318}, - {473: 315}, - {309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 49: 309, 51: 309, 472: 309, 309, 476: 309, 309, 309, 309, 484: 309, 488: 309, 492: 309, 581: 309, 590: 309, 309, 642: 309, 309, 309, 309, 740: 309, 743: 309}, + {2485, 2485, 2485, 2485, 2485, 2485, 9: 2485, 4862, 4863, 507: 2485, 954: 4861}, + {12: 4584, 112: 4632, 115: 4633, 184: 4623, 191: 4643, 4642, 4608, 214: 4645, 238: 4644, 245: 4605, 331: 4612, 4604, 352: 4621, 373: 4628, 4627, 378: 4631, 416: 4639, 514: 4626, 526: 4622, 549: 4617, 667: 4625, 699: 4630, 4629, 702: 4606, 4611, 4609, 4602, 4596, 4610, 710: 4618, 712: 4603, 4635, 4597, 4598, 4599, 4600, 4601, 4624, 4637, 4641, 4636, 4595, 4640, 4607, 727: 4594, 4634, 4593, 4638, 926: 4613, 1190: 4615, 1216: 4592, 4619, 4589, 1235: 4587, 1250: 4590, 4591, 1269: 4588, 1289: 4614, 1291: 4585, 4616, 1350: 4586, 1362: 4620, 1365: 4583, 1390: 4646}, + {2339, 2339, 2339, 2339, 2339, 2339, 4726, 4732, 4720, 2339, 2339, 2339, 4724, 4733, 4731, 58: 2339, 491: 4725, 495: 4198, 4723, 4197, 2346, 4730, 507: 2339, 510: 4719, 600: 2383, 607: 2476, 613: 4717, 662: 4722, 4715, 4737, 666: 4734, 834: 4718, 855: 4727, 935: 4729, 953: 4735, 963: 4728, 981: 4721, 1028: 4736, 4860}, + {2339, 2339, 2339, 2339, 2339, 2339, 4726, 4732, 4720, 2339, 2339, 2339, 4724, 4733, 4731, 58: 2339, 491: 4725, 495: 4198, 4723, 4197, 2346, 4730, 507: 2339, 510: 4719, 600: 2383, 607: 2476, 613: 4717, 662: 4722, 4715, 4737, 666: 4734, 834: 4718, 855: 4727, 935: 4729, 953: 4735, 963: 4728, 981: 4721, 1028: 4736, 4716}, + {401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 58: 401, 491: 401, 495: 401, 401, 401, 401, 401, 507: 401, 510: 401, 600: 401, 607: 401, 613: 401, 662: 401, 401, 401, 666: 401}, // 1970 - {308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 49: 308, 51: 308, 472: 308, 308, 476: 308, 308, 308, 308, 484: 308, 488: 308, 492: 308, 581: 308, 590: 308, 308, 642: 308, 308, 308, 308, 740: 308, 743: 308}, - {307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 49: 307, 472: 307, 476: 307, 307, 307, 307, 484: 307, 488: 307, 492: 307, 581: 307, 590: 307, 307, 642: 307, 307, 307, 307}, - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 764: 3827, 789: 4531}, - {305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 49: 305, 472: 305, 476: 305, 305, 305, 305, 484: 305, 488: 305, 492: 305, 581: 305, 590: 305, 305, 642: 305, 305, 305, 305}, - {304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 49: 304, 472: 304, 476: 304, 304, 304, 304, 484: 304, 488: 304, 492: 304, 581: 304, 590: 304, 304, 642: 304, 304, 304, 304}, + {400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 58: 400, 491: 400, 495: 400, 400, 400, 400, 400, 507: 400, 510: 400, 600: 400, 607: 400, 613: 400, 662: 400, 400, 400, 666: 400}, + {399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 58: 399, 491: 399, 495: 399, 399, 399, 399, 399, 507: 399, 510: 399, 600: 399, 607: 399, 613: 399, 662: 399, 399, 399, 666: 399}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 57: 316, 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 763: 316, 765: 316, 786: 3934, 812: 4713}, + {311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 57: 311, 311, 491: 311, 495: 311, 311, 311, 311, 311, 507: 311, 510: 311, 600: 311, 607: 311, 613: 311, 662: 311, 311, 311, 666: 311, 763: 311, 765: 311, 900: 4712}, + {309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 57: 309, 309, 491: 309, 3920, 495: 309, 309, 309, 309, 309, 507: 309, 510: 309, 600: 309, 607: 309, 613: 309, 662: 309, 309, 309, 666: 309, 763: 309, 765: 309, 786: 3921, 929: 4710, 934: 3922}, // 1975 - {302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 16: 302, 49: 302, 106: 302, 302, 110: 302, 472: 302, 476: 302, 302, 302, 302, 484: 302, 488: 302, 492: 302, 505: 302, 530: 302, 581: 302, 590: 302, 302, 642: 302, 302, 302, 302, 647: 302}, - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 16: 288, 49: 288, 106: 288, 288, 110: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 505: 288, 530: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 647: 288, 764: 3827, 789: 4530}, - {300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 16: 300, 49: 300, 106: 300, 300, 110: 300, 472: 300, 476: 300, 300, 300, 300, 484: 300, 488: 300, 492: 300, 505: 300, 530: 300, 581: 300, 590: 300, 300, 642: 300, 300, 300, 300, 647: 300}, - {299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 16: 299, 49: 299, 106: 299, 299, 110: 299, 472: 299, 476: 299, 299, 299, 299, 484: 299, 488: 299, 492: 299, 505: 299, 530: 299, 581: 299, 590: 299, 299, 642: 299, 299, 299, 299, 647: 299}, - {294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 49: 294, 472: 294, 476: 294, 294, 294, 294, 484: 294, 488: 294, 492: 294, 581: 294, 590: 294, 294, 642: 294, 294, 294, 294}, + {309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 57: 309, 309, 491: 309, 3920, 495: 309, 309, 309, 309, 309, 507: 309, 510: 309, 600: 309, 607: 309, 613: 309, 662: 309, 309, 309, 666: 309, 763: 309, 765: 309, 786: 3921, 929: 4708, 934: 3922}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 58: 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 786: 3934, 812: 4707}, + {393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 57: 393, 393, 491: 393, 393, 495: 393, 393, 393, 393, 393, 507: 393, 510: 393, 600: 393, 607: 393, 613: 393, 662: 393, 393, 393, 666: 393, 763: 393, 765: 393}, + {392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 57: 392, 392, 491: 392, 392, 495: 392, 392, 392, 392, 392, 507: 392, 510: 392, 600: 392, 607: 392, 613: 392, 662: 392, 392, 392, 666: 392, 763: 392, 765: 392}, + {391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 57: 391, 391, 491: 391, 391, 495: 391, 391, 391, 391, 391, 507: 391, 510: 391, 600: 391, 607: 391, 613: 391, 662: 391, 391, 391, 666: 391, 763: 391, 765: 391}, // 1980 - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 764: 3827, 789: 4529}, - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 764: 3827, 789: 4528}, - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 764: 3827, 789: 4527}, - {288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 49: 288, 51: 288, 472: 288, 3826, 476: 288, 288, 288, 288, 484: 288, 488: 288, 492: 288, 581: 288, 590: 288, 288, 642: 288, 288, 288, 288, 740: 288, 743: 288, 764: 3827, 789: 4521}, - {283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 49: 283, 51: 283, 472: 283, 476: 283, 283, 283, 283, 484: 283, 488: 283, 492: 283, 581: 283, 590: 283, 283, 642: 283, 283, 283, 283, 740: 283, 743: 283, 876: 4522}, + {390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 57: 390, 390, 491: 390, 390, 495: 390, 390, 390, 390, 390, 507: 390, 510: 390, 600: 390, 607: 390, 613: 390, 662: 390, 390, 390, 666: 390, 763: 390, 765: 390}, + {389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 57: 389, 389, 491: 389, 389, 495: 389, 389, 389, 389, 389, 507: 389, 510: 389, 600: 389, 607: 389, 613: 389, 662: 389, 389, 389, 666: 389, 763: 389, 765: 389}, + {388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 57: 388, 388, 491: 388, 388, 495: 388, 388, 388, 388, 388, 507: 388, 510: 388, 600: 388, 607: 388, 613: 388, 662: 388, 388, 388, 666: 388, 763: 388, 765: 388}, + {387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 57: 387, 387, 491: 387, 387, 495: 387, 387, 387, 387, 387, 507: 387, 510: 387, 600: 387, 607: 387, 613: 387, 662: 387, 387, 387, 666: 387, 763: 387, 765: 387}, + {386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 57: 386, 386, 491: 386, 386, 495: 386, 386, 386, 386, 386, 507: 386, 510: 386, 600: 386, 607: 386, 613: 386, 662: 386, 386, 386, 666: 386, 763: 386, 765: 386}, // 1985 - {290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 49: 290, 51: 4524, 472: 290, 476: 290, 290, 290, 290, 484: 290, 488: 290, 492: 290, 581: 290, 590: 290, 290, 642: 290, 290, 290, 290, 740: 4523, 743: 4525, 875: 4526}, - {286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 49: 286, 51: 286, 472: 286, 476: 286, 286, 286, 286, 484: 286, 488: 286, 492: 286, 581: 286, 590: 286, 286, 642: 286, 286, 286, 286, 740: 286, 743: 286}, - {285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 49: 285, 51: 285, 472: 285, 476: 285, 285, 285, 285, 484: 285, 488: 285, 492: 285, 581: 285, 590: 285, 285, 642: 285, 285, 285, 285, 740: 285, 743: 285}, - {284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 49: 284, 51: 284, 472: 284, 476: 284, 284, 284, 284, 484: 284, 488: 284, 492: 284, 581: 284, 590: 284, 284, 642: 284, 284, 284, 284, 740: 284, 743: 284}, - {282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 49: 282, 51: 282, 472: 282, 476: 282, 282, 282, 282, 484: 282, 488: 282, 492: 282, 581: 282, 590: 282, 282, 642: 282, 282, 282, 282, 740: 282, 743: 282}, + {385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 57: 385, 385, 491: 385, 385, 495: 385, 385, 385, 385, 385, 507: 385, 510: 385, 600: 385, 607: 385, 613: 385, 662: 385, 385, 385, 666: 385, 763: 385, 765: 385}, + {384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 57: 384, 384, 491: 384, 384, 495: 384, 384, 384, 384, 384, 507: 384, 510: 384, 600: 384, 607: 384, 613: 384, 662: 384, 384, 384, 666: 384, 763: 384, 765: 384}, + {383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 57: 383, 383, 491: 383, 383, 495: 383, 383, 383, 383, 383, 507: 383, 510: 383, 600: 383, 607: 383, 613: 383, 662: 383, 383, 383, 666: 383, 763: 383, 765: 383}, + {382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 57: 382, 382, 491: 382, 495: 382, 382, 382, 382, 382, 507: 382, 510: 382, 600: 382, 607: 382, 613: 382, 662: 382, 382, 382, 666: 382, 763: 382, 765: 382}, + {381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 57: 381, 381, 491: 381, 495: 381, 381, 381, 381, 381, 507: 381, 510: 381, 600: 381, 607: 381, 613: 381, 662: 381, 381, 381, 666: 381, 763: 381, 765: 381}, // 1990 - {291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 49: 291, 472: 291, 476: 291, 291, 291, 291, 484: 291, 488: 291, 492: 291, 581: 291, 590: 291, 291, 642: 291, 291, 291, 291}, - {292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 49: 292, 472: 292, 476: 292, 292, 292, 292, 484: 292, 488: 292, 492: 292, 581: 292, 590: 292, 292, 642: 292, 292, 292, 292}, - {293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 49: 293, 472: 293, 476: 293, 293, 293, 293, 484: 293, 488: 293, 492: 293, 581: 293, 590: 293, 293, 642: 293, 293, 293, 293}, - {301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 16: 301, 49: 301, 106: 301, 301, 110: 301, 472: 301, 476: 301, 301, 301, 301, 484: 301, 488: 301, 492: 301, 505: 301, 530: 301, 581: 301, 590: 301, 301, 642: 301, 301, 301, 301, 647: 301}, - {306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 49: 306, 472: 306, 476: 306, 306, 306, 306, 484: 306, 488: 306, 492: 306, 581: 306, 590: 306, 306, 642: 306, 306, 306, 306}, + {377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 57: 377, 377, 491: 377, 377, 495: 377, 377, 377, 377, 377, 507: 377, 510: 377, 600: 377, 607: 377, 613: 377, 662: 377, 377, 377, 666: 377, 763: 377, 765: 377}, + {376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 57: 376, 376, 491: 376, 376, 495: 376, 376, 376, 376, 376, 507: 376, 510: 376, 600: 376, 607: 376, 613: 376, 662: 376, 376, 376, 666: 376, 763: 376, 765: 376}, + {375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 57: 375, 375, 491: 375, 375, 495: 375, 375, 375, 375, 375, 507: 375, 510: 375, 600: 375, 607: 375, 613: 375, 662: 375, 375, 375, 666: 375, 763: 375, 765: 375}, + {374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 57: 374, 374, 491: 374, 374, 495: 374, 374, 374, 374, 374, 507: 374, 510: 374, 600: 374, 607: 374, 613: 374, 662: 374, 374, 374, 666: 374, 763: 374, 765: 374}, + {373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 57: 373, 373, 491: 373, 373, 495: 373, 373, 373, 373, 373, 507: 373, 510: 373, 600: 373, 607: 373, 613: 373, 662: 373, 373, 373, 666: 373, 763: 373, 765: 373}, // 1995 - {323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 16: 323, 49: 323, 472: 323, 323, 476: 323, 323, 323, 323, 484: 323, 488: 323, 492: 323, 505: 323, 530: 323, 581: 323, 590: 323, 323, 642: 323, 323, 323, 323, 647: 323, 843: 4537}, - {322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 16: 322, 49: 322, 472: 322, 322, 476: 322, 322, 322, 322, 484: 322, 488: 322, 492: 322, 505: 322, 530: 322, 581: 322, 590: 322, 322, 642: 322, 322, 322, 322, 647: 322, 843: 4536}, - {473: 317}, - {473: 316}, - {473: 311}, + {372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 57: 372, 372, 491: 372, 372, 495: 372, 372, 372, 372, 372, 507: 372, 510: 372, 600: 372, 607: 372, 613: 372, 662: 372, 372, 372, 666: 372, 763: 372, 765: 372, 1315: 4706}, + {370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 58: 370, 491: 370, 370, 495: 370, 370, 370, 370, 370, 507: 370, 510: 370, 600: 370, 607: 370, 613: 370, 662: 370, 370, 370, 666: 370}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 491: 303, 3933, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 786: 4703, 798: 3941, 821: 4704}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 491: 303, 3933, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 786: 4700, 798: 3941, 821: 4701}, + {492: 3933, 786: 4698}, // 2000 - {473: 312}, - {473: 314}, - {473: 313}, - {473: 310}, - {320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 16: 320, 49: 320, 106: 320, 320, 110: 320, 472: 320, 320, 476: 320, 320, 320, 320, 484: 320, 488: 320, 492: 320, 505: 320, 530: 320, 581: 320, 590: 320, 320, 642: 320, 320, 320, 320, 647: 320}, + {492: 3933, 786: 4696}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 58: 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 786: 3934, 812: 4695}, + {492: 3933, 786: 4694}, + {361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 58: 361, 491: 361, 495: 361, 361, 361, 361, 361, 507: 361, 510: 361, 600: 361, 607: 361, 613: 361, 662: 361, 361, 361, 666: 361}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 116: 4675, 4677, 133: 4676, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4674, 907: 4693}, // 2005 - {321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 16: 321, 49: 321, 106: 321, 321, 110: 321, 472: 321, 321, 476: 321, 321, 321, 321, 484: 321, 488: 321, 492: 321, 505: 321, 530: 321, 581: 321, 590: 321, 321, 642: 321, 321, 321, 321, 647: 321}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 106: 4549, 4551, 110: 4550, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4548, 884: 4552}, - {327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 49: 327, 472: 327, 476: 327, 327, 327, 327, 484: 327, 488: 327, 492: 327, 581: 327, 590: 327, 327, 642: 327, 327, 327, 327}, - {506: 3839, 843: 4542}, - {506: 3838, 843: 4541}, + {492: 4689}, + {492: 4679}, + {357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 58: 357, 491: 357, 495: 357, 357, 357, 357, 357, 507: 357, 510: 357, 600: 357, 607: 357, 613: 357, 662: 357, 357, 357, 666: 357}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 116: 4675, 4677, 133: 4676, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 4672, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 4671, 699: 4630, 4629, 710: 4673, 798: 3941, 821: 4674, 907: 4670, 1190: 4669}, + {354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, 16: 354, 58: 354, 491: 354, 354, 495: 354, 354, 354, 354, 354, 507: 354, 510: 354, 514: 354, 549: 354, 600: 354, 607: 354, 613: 354, 662: 354, 354, 354, 666: 354, 354, 867: 4668}, // 2010 - {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 49: 303, 472: 303, 476: 303, 303, 303, 303, 484: 303, 488: 303, 492: 303, 581: 303, 590: 303, 303, 642: 303, 303, 303, 303}, - {298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 49: 298, 472: 298, 476: 298, 298, 298, 298, 484: 298, 488: 298, 492: 298, 581: 298, 590: 298, 298, 642: 298, 298, 298, 298}, - {297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 49: 297, 472: 297, 476: 297, 297, 297, 297, 484: 297, 488: 297, 492: 297, 581: 297, 590: 297, 297, 642: 297, 297, 297, 297}, - {296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 49: 296, 472: 296, 476: 296, 296, 296, 296, 484: 296, 488: 296, 492: 296, 581: 296, 590: 296, 296, 642: 296, 296, 296, 296}, - {295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 49: 295, 472: 295, 476: 295, 295, 295, 295, 484: 295, 488: 295, 492: 295, 581: 295, 590: 295, 295, 642: 295, 295, 295, 295}, + {353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 16: 353, 58: 353, 491: 353, 353, 495: 353, 353, 353, 353, 353, 507: 353, 510: 353, 514: 353, 549: 353, 600: 353, 607: 353, 613: 353, 662: 353, 353, 353, 666: 353, 353, 867: 4667}, + {352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 16: 352, 58: 352, 491: 352, 352, 495: 352, 352, 352, 352, 352, 507: 352, 510: 352, 514: 352, 549: 352, 600: 352, 607: 352, 613: 352, 662: 352, 352, 352, 666: 352, 352, 699: 4665, 4664, 867: 4666}, + {514: 4659, 667: 4658, 699: 4661, 4660}, + {347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 16: 347, 58: 347, 116: 347, 347, 133: 347, 491: 347, 347, 495: 347, 347, 347, 347, 347, 507: 347, 510: 347, 514: 347, 549: 347, 600: 347, 607: 347, 613: 347, 662: 347, 347, 347, 666: 347, 347}, + {346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 16: 346, 58: 346, 116: 346, 346, 133: 346, 491: 346, 346, 495: 346, 346, 346, 346, 346, 507: 346, 510: 346, 514: 346, 549: 346, 600: 346, 607: 346, 613: 346, 662: 346, 346, 346, 666: 346, 346}, // 2015 - {328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 49: 328, 472: 328, 476: 328, 328, 328, 328, 484: 328, 488: 328, 492: 328, 581: 328, 590: 328, 328, 642: 328, 328, 328, 328}, - {475: 4555, 576: 4556, 580: 4557, 970: 4558, 1151: 4554}, - {9: 4560, 49: 4559}, - {9: 263, 49: 263}, - {9: 262, 49: 262}, + {492: 343}, + {337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 57: 337, 337, 491: 337, 337, 495: 337, 337, 337, 337, 337, 507: 337, 510: 337, 600: 337, 607: 337, 613: 337, 662: 337, 337, 337, 666: 337, 763: 337, 765: 337}, + {336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 57: 336, 336, 491: 336, 336, 495: 336, 336, 336, 336, 336, 507: 336, 510: 336, 600: 336, 607: 336, 613: 336, 662: 336, 336, 336, 666: 336, 763: 336, 765: 336}, + {335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 58: 335, 491: 335, 495: 335, 335, 335, 335, 335, 507: 335, 510: 335, 600: 335, 607: 335, 613: 335, 662: 335, 335, 335, 666: 335}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 58: 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 786: 3934, 812: 4657}, // 2020 - {9: 261, 49: 261}, - {9: 260, 49: 260}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 106: 4549, 4551, 110: 4550, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4548, 884: 4562}, - {475: 4555, 576: 4556, 580: 4557, 970: 4561}, - {9: 259, 49: 259}, + {333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 58: 333, 491: 333, 495: 333, 333, 333, 333, 333, 507: 333, 510: 333, 600: 333, 607: 333, 613: 333, 662: 333, 333, 333, 666: 333}, + {332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 58: 332, 491: 332, 495: 332, 332, 332, 332, 332, 507: 332, 510: 332, 600: 332, 607: 332, 613: 332, 662: 332, 332, 332, 666: 332}, + {330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 16: 330, 58: 330, 116: 330, 330, 133: 330, 491: 330, 495: 330, 330, 330, 330, 330, 507: 330, 510: 330, 514: 330, 549: 330, 600: 330, 607: 330, 613: 330, 662: 330, 330, 330, 666: 330, 330}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 16: 316, 58: 316, 116: 316, 316, 133: 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 514: 316, 549: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 316, 786: 3934, 812: 4656}, + {328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 16: 328, 58: 328, 116: 328, 328, 133: 328, 491: 328, 495: 328, 328, 328, 328, 328, 507: 328, 510: 328, 514: 328, 549: 328, 600: 328, 607: 328, 613: 328, 662: 328, 328, 328, 666: 328, 328}, // 2025 - {330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 49: 330, 472: 330, 476: 330, 330, 330, 330, 484: 330, 488: 330, 492: 330, 581: 330, 590: 330, 330, 642: 330, 330, 330, 330}, - {475: 4555, 576: 4556, 580: 4557, 970: 4558, 1151: 4564}, - {9: 4560, 49: 4565}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 106: 4549, 4551, 110: 4550, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4548, 884: 4566}, - {331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 49: 331, 472: 331, 476: 331, 331, 331, 331, 484: 331, 488: 331, 492: 331, 581: 331, 590: 331, 331, 642: 331, 331, 331, 331}, + {327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 16: 327, 58: 327, 116: 327, 327, 133: 327, 491: 327, 495: 327, 327, 327, 327, 327, 507: 327, 510: 327, 514: 327, 549: 327, 600: 327, 607: 327, 613: 327, 662: 327, 327, 327, 666: 327, 327}, + {322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 58: 322, 491: 322, 495: 322, 322, 322, 322, 322, 507: 322, 510: 322, 600: 322, 607: 322, 613: 322, 662: 322, 322, 322, 666: 322}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 58: 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 786: 3934, 812: 4655}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 58: 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 786: 3934, 812: 4654}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 58: 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 786: 3934, 812: 4653}, // 2030 - {332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 49: 332, 472: 332, 476: 332, 332, 332, 332, 484: 332, 488: 332, 492: 332, 581: 332, 590: 332, 332, 642: 332, 332, 332, 332}, - {334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 49: 334, 472: 334, 476: 334, 334, 334, 334, 484: 334, 488: 334, 492: 334, 581: 334, 590: 334, 334, 642: 334, 334, 334, 334}, - {335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 49: 335, 472: 335, 476: 335, 335, 335, 335, 484: 335, 488: 335, 492: 335, 581: 335, 590: 335, 335, 642: 335, 335, 335, 335}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4571}, - {336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 49: 336, 472: 336, 476: 336, 336, 336, 336, 484: 336, 488: 336, 492: 336, 581: 336, 590: 336, 336, 642: 336, 336, 336, 336}, + {316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 57: 316, 316, 491: 316, 3933, 495: 316, 316, 316, 316, 316, 507: 316, 510: 316, 600: 316, 607: 316, 613: 316, 662: 316, 316, 316, 666: 316, 763: 316, 765: 316, 786: 3934, 812: 4647}, + {311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 57: 311, 311, 491: 311, 495: 311, 311, 311, 311, 311, 507: 311, 510: 311, 600: 311, 607: 311, 613: 311, 662: 311, 311, 311, 666: 311, 763: 311, 765: 311, 900: 4648}, + {318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 57: 4650, 318, 491: 318, 495: 318, 318, 318, 318, 318, 507: 318, 510: 318, 600: 318, 607: 318, 613: 318, 662: 318, 318, 318, 666: 318, 763: 4649, 765: 4651, 899: 4652}, + {314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 57: 314, 314, 491: 314, 495: 314, 314, 314, 314, 314, 507: 314, 510: 314, 600: 314, 607: 314, 613: 314, 662: 314, 314, 314, 666: 314, 763: 314, 765: 314}, + {313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 57: 313, 313, 491: 313, 495: 313, 313, 313, 313, 313, 507: 313, 510: 313, 600: 313, 607: 313, 613: 313, 662: 313, 313, 313, 666: 313, 763: 313, 765: 313}, // 2035 - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4573}, - {337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 49: 337, 472: 337, 476: 337, 337, 337, 337, 484: 337, 488: 337, 492: 337, 581: 337, 590: 337, 337, 642: 337, 337, 337, 337}, - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4576}, - {338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 49: 338, 472: 338, 476: 338, 338, 338, 338, 484: 338, 488: 338, 492: 338, 581: 338, 590: 338, 338, 642: 338, 338, 338, 338}, - {339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 49: 339, 472: 339, 476: 339, 339, 339, 339, 484: 339, 488: 339, 492: 339, 581: 339, 590: 339, 339, 642: 339, 339, 339, 339}, + {312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 57: 312, 312, 491: 312, 495: 312, 312, 312, 312, 312, 507: 312, 510: 312, 600: 312, 607: 312, 613: 312, 662: 312, 312, 312, 666: 312, 763: 312, 765: 312}, + {310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 57: 310, 310, 491: 310, 495: 310, 310, 310, 310, 310, 507: 310, 510: 310, 600: 310, 607: 310, 613: 310, 662: 310, 310, 310, 666: 310, 763: 310, 765: 310}, + {319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 58: 319, 491: 319, 495: 319, 319, 319, 319, 319, 507: 319, 510: 319, 600: 319, 607: 319, 613: 319, 662: 319, 319, 319, 666: 319}, + {320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 58: 320, 491: 320, 495: 320, 320, 320, 320, 320, 507: 320, 510: 320, 600: 320, 607: 320, 613: 320, 662: 320, 320, 320, 666: 320}, + {321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 58: 321, 491: 321, 495: 321, 321, 321, 321, 321, 507: 321, 510: 321, 600: 321, 607: 321, 613: 321, 662: 321, 321, 321, 666: 321}, // 2040 - {275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 16: 3836, 49: 275, 472: 275, 476: 275, 275, 275, 275, 484: 275, 488: 275, 492: 275, 505: 3837, 530: 3833, 581: 275, 590: 275, 275, 642: 275, 275, 275, 275, 647: 3835, 773: 3834, 799: 4579}, - {340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 49: 340, 472: 340, 476: 340, 340, 340, 340, 484: 340, 488: 340, 492: 340, 581: 340, 590: 340, 340, 642: 340, 340, 340, 340}, - {341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 49: 341, 472: 341, 476: 341, 341, 341, 341, 484: 341, 488: 341, 492: 341, 581: 341, 590: 341, 341, 642: 341, 341, 341, 341}, - {343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 49: 343, 51: 343, 472: 343, 343, 476: 343, 343, 343, 343, 484: 343, 488: 343, 492: 343, 581: 343, 590: 343, 343, 642: 343, 343, 343, 343, 740: 343, 743: 343}, - {366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 49: 366, 472: 366, 476: 366, 366, 366, 366, 484: 366, 488: 366, 492: 366, 581: 366, 590: 366, 366, 642: 366, 366, 366, 366}, + {329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 16: 329, 58: 329, 116: 329, 329, 133: 329, 491: 329, 495: 329, 329, 329, 329, 329, 507: 329, 510: 329, 514: 329, 549: 329, 600: 329, 607: 329, 613: 329, 662: 329, 329, 329, 666: 329, 329}, + {334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, 58: 334, 491: 334, 495: 334, 334, 334, 334, 334, 507: 334, 510: 334, 600: 334, 607: 334, 613: 334, 662: 334, 334, 334, 666: 334}, + {351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 16: 351, 58: 351, 491: 351, 351, 495: 351, 351, 351, 351, 351, 507: 351, 510: 351, 514: 351, 549: 351, 600: 351, 607: 351, 613: 351, 662: 351, 351, 351, 666: 351, 351, 867: 4663}, + {350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 16: 350, 58: 350, 491: 350, 350, 495: 350, 350, 350, 350, 350, 507: 350, 510: 350, 514: 350, 549: 350, 600: 350, 607: 350, 613: 350, 662: 350, 350, 350, 666: 350, 350, 867: 4662}, + {492: 345}, // 2045 - {283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 49: 283, 51: 283, 472: 283, 476: 283, 283, 283, 283, 484: 283, 488: 283, 492: 283, 581: 283, 590: 283, 283, 642: 283, 283, 283, 283, 740: 283, 743: 283, 876: 4583}, - {367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 49: 367, 51: 4524, 472: 367, 476: 367, 367, 367, 367, 484: 367, 488: 367, 492: 367, 581: 367, 590: 367, 367, 642: 367, 367, 367, 367, 740: 4523, 743: 4525, 875: 4526}, - {283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 49: 283, 51: 283, 472: 283, 476: 283, 283, 283, 283, 484: 283, 488: 283, 492: 283, 581: 283, 590: 283, 283, 642: 283, 283, 283, 283, 740: 283, 743: 283, 876: 4585}, - {368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 49: 368, 51: 4524, 472: 368, 476: 368, 368, 368, 368, 484: 368, 488: 368, 492: 368, 581: 368, 590: 368, 368, 642: 368, 368, 368, 368, 740: 4523, 743: 4525, 875: 4526}, - {369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 49: 369, 51: 4524, 472: 369, 476: 369, 369, 369, 369, 484: 369, 488: 369, 492: 369, 581: 369, 590: 369, 369, 642: 369, 369, 369, 369, 740: 4523, 743: 4525, 875: 4526}, + {492: 344}, + {492: 339}, + {492: 340}, + {492: 342}, + {492: 341}, // 2050 - {283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 49: 283, 51: 283, 472: 283, 476: 283, 283, 283, 283, 484: 283, 488: 283, 492: 283, 581: 283, 590: 283, 283, 642: 283, 283, 283, 283, 740: 283, 743: 283, 876: 4588}, - {370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 49: 370, 51: 4524, 472: 370, 476: 370, 370, 370, 370, 484: 370, 488: 370, 492: 370, 581: 370, 590: 370, 370, 642: 370, 370, 370, 370, 740: 4523, 743: 4525, 875: 4526}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 581: 2405, 590: 2405, 2405, 642: 2405, 649: 2405, 661: 4728, 2762, 2763, 2761, 675: 2405, 2405, 1144: 4727}, - {2338, 2338, 2338, 2338, 2338, 2338, 9: 2338, 2338, 2338, 49: 2338, 488: 2338}, - {581: 2315}, + {492: 338}, + {348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 16: 348, 58: 348, 116: 348, 348, 133: 348, 491: 348, 348, 495: 348, 348, 348, 348, 348, 507: 348, 510: 348, 514: 348, 549: 348, 600: 348, 607: 348, 613: 348, 662: 348, 348, 348, 666: 348, 348}, + {349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 16: 349, 58: 349, 116: 349, 349, 133: 349, 491: 349, 349, 495: 349, 349, 349, 349, 349, 507: 349, 510: 349, 514: 349, 549: 349, 600: 349, 607: 349, 613: 349, 662: 349, 349, 349, 666: 349, 349}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 116: 4675, 4677, 133: 4676, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4674, 907: 4678}, + {355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 58: 355, 491: 355, 495: 355, 355, 355, 355, 355, 507: 355, 510: 355, 600: 355, 607: 355, 613: 355, 662: 355, 355, 355, 666: 355}, // 2055 - {492: 4726}, - {2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 49: 2305, 472: 2305, 476: 2305, 2305, 2305, 2305, 484: 2305, 488: 2305, 492: 2305, 581: 2305, 590: 2305, 2305, 642: 2305, 2305, 2305, 2305}, - {2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 49: 2304, 472: 2304, 476: 2304, 2304, 2304, 2304, 484: 2304, 488: 2304, 492: 2304, 581: 2304, 590: 2304, 2304, 642: 2304, 2304, 2304, 2304}, - {581: 4722}, - {2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 49: 2301, 472: 2301, 476: 2301, 2301, 2301, 2301, 484: 2301, 488: 2301, 492: 2301, 581: 4721, 590: 2301, 2301, 642: 2301, 2301, 2301, 2301}, + {526: 3946, 867: 4668}, + {526: 3945, 867: 4667}, + {331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 58: 331, 491: 331, 495: 331, 331, 331, 331, 331, 507: 331, 510: 331, 600: 331, 607: 331, 613: 331, 662: 331, 331, 331, 666: 331}, + {326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 58: 326, 491: 326, 495: 326, 326, 326, 326, 326, 507: 326, 510: 326, 600: 326, 607: 326, 613: 326, 662: 326, 326, 326, 666: 326}, + {325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 58: 325, 491: 325, 495: 325, 325, 325, 325, 325, 507: 325, 510: 325, 600: 325, 607: 325, 613: 325, 662: 325, 325, 325, 666: 325}, // 2060 - {151: 4709, 270: 4711, 362: 4712, 473: 4708, 475: 3239, 485: 4444, 4445, 492: 3230, 508: 3234, 571: 3229, 3231, 3233, 3232, 576: 3237, 580: 3238, 585: 4696, 4693, 588: 4694, 4695, 592: 3236, 712: 4443, 3235, 4706, 946: 4691, 4692, 4710, 995: 4707, 1081: 4704, 1134: 4705, 1204: 4703}, - {479: 4701}, - {654: 4689}, - {475: 4688}, - {590: 4679}, + {324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 58: 324, 491: 324, 495: 324, 324, 324, 324, 324, 507: 324, 510: 324, 600: 324, 607: 324, 613: 324, 662: 324, 324, 324, 666: 324}, + {323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 58: 323, 491: 323, 495: 323, 323, 323, 323, 323, 507: 323, 510: 323, 600: 323, 607: 323, 613: 323, 662: 323, 323, 323, 666: 323}, + {356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 58: 356, 491: 356, 495: 356, 356, 356, 356, 356, 507: 356, 510: 356, 600: 356, 607: 356, 613: 356, 662: 356, 356, 356, 666: 356}, + {493: 4681, 596: 4682, 598: 4683, 995: 4684, 1183: 4680}, + {9: 4686, 58: 4685}, // 2065 - {478: 4672}, - {2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 49: 2293, 472: 2293, 476: 2293, 2293, 2293, 2293, 484: 2293, 488: 2293, 492: 2293, 581: 2293, 590: 2293, 2293, 642: 2293, 2293, 2293, 2293}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3489, 661: 3491, 2762, 2763, 2761, 738: 3488, 872: 4671}, - {180: 4669, 207: 4670, 479: 4668, 1189: 4667}, - {186: 4666, 247: 4665, 479: 4664, 1311: 4663}, + {9: 291, 58: 291}, + {9: 290, 58: 290}, + {9: 289, 58: 289}, + {9: 288, 58: 288}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 116: 4675, 4677, 133: 4676, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4674, 907: 4688}, // 2070 - {2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 2288, 49: 2288, 472: 2288, 4657, 476: 2288, 2288, 2288, 2288, 484: 2288, 488: 2288, 492: 2288, 581: 2288, 590: 2288, 2288, 642: 2288, 2288, 2288, 2288, 1179: 4656}, - {312: 4655}, - {2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 49: 2274, 472: 2274, 476: 2274, 2274, 2274, 2274, 484: 2274, 488: 2274, 492: 2274, 581: 2274, 590: 2274, 2274, 642: 2274, 2274, 2274, 2274}, - {2271, 2271, 2271, 2271, 2271, 2271, 4600, 4606, 4594, 2271, 2271, 2271, 4598, 4607, 4605, 49: 2271, 472: 4599, 476: 4089, 4088, 2279, 4597, 484: 4604, 488: 2271, 492: 4593, 581: 2316, 590: 2406, 4591, 642: 4596, 4589, 4611, 4608, 810: 4592, 833: 4601, 910: 4603, 928: 4654, 937: 4602, 956: 4595}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4612}, + {493: 4681, 596: 4682, 598: 4683, 995: 4687}, + {9: 287, 58: 287}, + {358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 58: 358, 491: 358, 495: 358, 358, 358, 358, 358, 507: 358, 510: 358, 600: 358, 607: 358, 613: 358, 662: 358, 358, 358, 666: 358}, + {493: 4681, 596: 4682, 598: 4683, 995: 4684, 1183: 4690}, + {9: 4686, 58: 4691}, // 2075 - {2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 2211, 49: 2211, 472: 2211, 4614, 476: 2211, 2211, 2211, 2211, 484: 2211, 488: 2211, 492: 2211, 581: 2211, 590: 2211, 2211, 642: 2211, 2211, 2211, 2211, 648: 2211, 1233: 4613}, - {2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 2261, 49: 2261, 472: 2261, 476: 2261, 2261, 2261, 2261, 484: 2261, 488: 2261, 492: 2261, 581: 2261, 590: 2261, 2261, 642: 2261, 2261, 2261, 2261, 648: 4629, 1250: 4630, 4631}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4616, 836: 4615}, - {9: 4627, 49: 4626}, - {9: 2209, 49: 2209}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 116: 4675, 4677, 133: 4676, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4674, 907: 4692}, + {359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 58: 359, 491: 359, 495: 359, 359, 359, 359, 359, 507: 359, 510: 359, 600: 359, 607: 359, 613: 359, 662: 359, 359, 359, 666: 359}, + {360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 58: 360, 491: 360, 495: 360, 360, 360, 360, 360, 507: 360, 510: 360, 600: 360, 607: 360, 613: 360, 662: 360, 360, 360, 666: 360}, + {362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 58: 362, 491: 362, 495: 362, 362, 362, 362, 362, 507: 362, 510: 362, 600: 362, 607: 362, 613: 362, 662: 362, 362, 362, 666: 362}, + {363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 58: 363, 491: 363, 495: 363, 363, 363, 363, 363, 507: 363, 510: 363, 600: 363, 607: 363, 613: 363, 662: 363, 363, 363, 666: 363}, // 2080 - {9: 288, 49: 288, 473: 3826, 529: 288, 531: 288, 764: 3827, 789: 4624}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4619}, - {49: 4620, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {9: 1300, 49: 1300, 529: 4623, 531: 4622, 949: 4621}, - {9: 2206, 49: 2206}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4697}, + {364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 58: 364, 491: 364, 495: 364, 364, 364, 364, 364, 507: 364, 510: 364, 600: 364, 607: 364, 613: 364, 662: 364, 364, 364, 666: 364}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4699}, + {365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 58: 365, 491: 365, 495: 365, 365, 365, 365, 365, 507: 365, 510: 365, 600: 365, 607: 365, 613: 365, 662: 365, 365, 365, 666: 365}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4702}, // 2085 - {1299, 1299, 1299, 1299, 1299, 1299, 9: 1299, 49: 1299, 488: 1299}, - {1298, 1298, 1298, 1298, 1298, 1298, 9: 1298, 49: 1298, 488: 1298}, - {9: 1300, 49: 1300, 529: 4623, 531: 4622, 949: 4625}, - {9: 2207, 49: 2207}, - {2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 2210, 49: 2210, 472: 2210, 476: 2210, 2210, 2210, 2210, 484: 2210, 488: 2210, 492: 2210, 581: 2210, 590: 2210, 2210, 642: 2210, 2210, 2210, 2210, 648: 2210}, + {366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 58: 366, 491: 366, 495: 366, 366, 366, 366, 366, 507: 366, 510: 366, 600: 366, 607: 366, 613: 366, 662: 366, 366, 366, 666: 366}, + {367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 58: 367, 491: 367, 495: 367, 367, 367, 367, 367, 507: 367, 510: 367, 600: 367, 607: 367, 613: 367, 662: 367, 367, 367, 666: 367}, + {303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 16: 3943, 58: 303, 491: 303, 495: 303, 303, 303, 303, 303, 507: 303, 510: 303, 514: 3944, 549: 3940, 600: 303, 607: 303, 613: 303, 662: 303, 303, 303, 666: 303, 3942, 798: 3941, 821: 4705}, + {368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 58: 368, 491: 368, 495: 368, 368, 368, 368, 368, 507: 368, 510: 368, 600: 368, 607: 368, 613: 368, 662: 368, 368, 368, 666: 368}, + {369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 58: 369, 491: 369, 495: 369, 369, 369, 369, 369, 507: 369, 510: 369, 600: 369, 607: 369, 613: 369, 662: 369, 369, 369, 666: 369}, // 2090 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4628}, - {9: 2208, 49: 2208}, - {211: 4651, 369: 4652, 387: 4653}, - {2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 49: 2260, 472: 2260, 476: 2260, 2260, 2260, 2260, 484: 2260, 488: 2260, 492: 2260, 581: 2260, 590: 2260, 2260, 642: 2260, 2260, 2260, 2260}, - {2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 2256, 49: 2256, 472: 4633, 476: 2256, 2256, 2256, 2256, 484: 2256, 488: 2256, 492: 2256, 581: 2256, 590: 2256, 2256, 642: 2256, 2256, 2256, 2256, 1087: 4634, 4635, 1259: 4632}, + {371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 57: 371, 371, 491: 371, 371, 495: 371, 371, 371, 371, 371, 507: 371, 510: 371, 600: 371, 607: 371, 613: 371, 662: 371, 371, 371, 666: 371, 763: 371, 765: 371}, + {394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 58: 394, 491: 394, 495: 394, 394, 394, 394, 394, 507: 394, 510: 394, 600: 394, 607: 394, 613: 394, 662: 394, 394, 394, 666: 394}, + {311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 57: 311, 311, 491: 311, 495: 311, 311, 311, 311, 311, 507: 311, 510: 311, 600: 311, 607: 311, 613: 311, 662: 311, 311, 311, 666: 311, 763: 311, 765: 311, 900: 4709}, + {395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 57: 4650, 395, 491: 395, 495: 395, 395, 395, 395, 395, 507: 395, 510: 395, 600: 395, 607: 395, 613: 395, 662: 395, 395, 395, 666: 395, 763: 4649, 765: 4651, 899: 4652}, + {311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 57: 311, 311, 491: 311, 495: 311, 311, 311, 311, 311, 507: 311, 510: 311, 600: 311, 607: 311, 613: 311, 662: 311, 311, 311, 666: 311, 763: 311, 765: 311, 900: 4711}, // 2095 - {2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 49: 2259, 472: 2259, 476: 2259, 2259, 2259, 2259, 484: 2259, 488: 2259, 492: 2259, 581: 2259, 590: 2259, 2259, 642: 2259, 2259, 2259, 2259}, - {654: 4649, 739: 4638}, - {2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 49: 2255, 472: 4647, 476: 2255, 2255, 2255, 2255, 484: 2255, 488: 2255, 492: 2255, 581: 2255, 590: 2255, 2255, 642: 2255, 2255, 2255, 2255, 1088: 4648}, - {2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 49: 2254, 472: 4636, 476: 2254, 2254, 2254, 2254, 484: 2254, 488: 2254, 492: 2254, 581: 2254, 590: 2254, 2254, 642: 2254, 2254, 2254, 2254, 1087: 4637}, - {739: 4638}, + {396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 57: 4650, 396, 491: 396, 495: 396, 396, 396, 396, 396, 507: 396, 510: 396, 600: 396, 607: 396, 613: 396, 662: 396, 396, 396, 666: 396, 763: 4649, 765: 4651, 899: 4652}, + {397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 57: 4650, 397, 491: 397, 495: 397, 397, 397, 397, 397, 507: 397, 510: 397, 600: 397, 607: 397, 613: 397, 662: 397, 397, 397, 666: 397, 763: 4649, 765: 4651, 899: 4652}, + {311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 57: 311, 311, 491: 311, 495: 311, 311, 311, 311, 311, 507: 311, 510: 311, 600: 311, 607: 311, 613: 311, 662: 311, 311, 311, 666: 311, 763: 311, 765: 311, 900: 4714}, + {398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 57: 4650, 398, 491: 398, 495: 398, 398, 398, 398, 398, 507: 398, 510: 398, 600: 398, 607: 398, 613: 398, 662: 398, 398, 398, 666: 398, 763: 4649, 765: 4651, 899: 4652}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 600: 2475, 607: 2475, 613: 2475, 662: 2475, 668: 2475, 685: 4859, 2850, 688: 2851, 2849, 696: 2475, 2475, 1176: 4858}, // 2100 - {2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 49: 2252, 472: 2252, 476: 2252, 2252, 2252, 2252, 484: 2252, 488: 2252, 492: 2252, 581: 2252, 590: 2252, 2252, 642: 2252, 2252, 2252, 2252}, - {72: 4643, 506: 4642, 670: 4641, 672: 4640, 1111: 4639}, - {2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 49: 2258, 472: 2258, 476: 2258, 2258, 2258, 2258, 484: 2258, 488: 2258, 492: 2258, 581: 2258, 590: 2258, 2258, 642: 2258, 2258, 2258, 2258}, - {2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 2251, 49: 2251, 472: 2251, 476: 2251, 2251, 2251, 2251, 484: 2251, 488: 2251, 492: 2251, 581: 2251, 590: 2251, 2251, 642: 2251, 2251, 2251, 2251}, - {2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 49: 2250, 472: 2250, 476: 2250, 2250, 2250, 2250, 484: 2250, 488: 2250, 492: 2250, 581: 2250, 590: 2250, 2250, 642: 2250, 2250, 2250, 2250}, + {2405, 2405, 2405, 2405, 2405, 2405, 9: 2405, 2405, 2405, 58: 2405, 507: 2405}, + {600: 2382}, + {510: 4857}, + {2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 2372, 58: 2372, 491: 2372, 495: 2372, 2372, 2372, 2372, 2372, 507: 2372, 510: 2372, 600: 2372, 607: 2372, 613: 2372, 662: 2372, 2372, 2372, 666: 2372}, + {2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 58: 2371, 491: 2371, 495: 2371, 2371, 2371, 2371, 2371, 507: 2371, 510: 2371, 600: 2371, 607: 2371, 613: 2371, 662: 2371, 2371, 2371, 666: 2371}, // 2105 - {479: 4646, 492: 4645}, - {308: 4644}, - {2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 2248, 49: 2248, 472: 2248, 476: 2248, 2248, 2248, 2248, 484: 2248, 488: 2248, 492: 2248, 581: 2248, 590: 2248, 2248, 642: 2248, 2248, 2248, 2248}, - {2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 2249, 49: 2249, 472: 2249, 476: 2249, 2249, 2249, 2249, 484: 2249, 488: 2249, 492: 2249, 581: 2249, 590: 2249, 2249, 642: 2249, 2249, 2249, 2249}, - {2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 2247, 49: 2247, 472: 2247, 476: 2247, 2247, 2247, 2247, 484: 2247, 488: 2247, 492: 2247, 581: 2247, 590: 2247, 2247, 642: 2247, 2247, 2247, 2247}, + {600: 4853}, + {2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 2368, 58: 2368, 491: 2368, 495: 2368, 2368, 2368, 2368, 2368, 507: 2368, 510: 2368, 600: 4852, 607: 2368, 613: 2368, 662: 2368, 2368, 2368, 666: 2368}, + {141: 4840, 285: 4842, 376: 4843, 492: 4839, 3346, 504: 4570, 4571, 510: 3337, 525: 3341, 591: 3336, 3338, 3340, 3339, 596: 3344, 598: 3345, 605: 4825, 4824, 608: 4820, 4821, 611: 4822, 4823, 614: 3343, 734: 4569, 3342, 4837, 924: 4838, 957: 4819, 972: 4817, 4818, 4841, 1111: 4835, 1166: 4836, 1237: 4834}, + {496: 4832}, + {674: 4815}, // 2110 - {654: 4649}, - {2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 2253, 49: 2253, 472: 2253, 476: 2253, 2253, 2253, 2253, 484: 2253, 488: 2253, 492: 2253, 581: 2253, 590: 2253, 2253, 642: 2253, 2253, 2253, 2253}, - {72: 4643, 506: 4642, 670: 4641, 672: 4640, 1111: 4650}, - {2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 2257, 49: 2257, 472: 2257, 476: 2257, 2257, 2257, 2257, 484: 2257, 488: 2257, 492: 2257, 581: 2257, 590: 2257, 2257, 642: 2257, 2257, 2257, 2257}, - {2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 2264, 49: 2264, 472: 2264, 476: 2264, 2264, 2264, 2264, 484: 2264, 488: 2264, 492: 2264, 581: 2264, 590: 2264, 2264, 642: 2264, 2264, 2264, 2264}, + {493: 4814}, + {607: 4805}, + {498: 4798}, + {2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 2360, 58: 2360, 491: 2360, 495: 2360, 2360, 2360, 2360, 2360, 507: 2360, 510: 2360, 600: 2360, 607: 2360, 613: 2360, 662: 2360, 2360, 2360, 666: 2360}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3596, 685: 3598, 2850, 688: 2851, 2849, 760: 3595, 895: 4797}, // 2115 - {2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 2263, 49: 2263, 472: 2263, 476: 2263, 2263, 2263, 2263, 484: 2263, 488: 2263, 492: 2263, 581: 2263, 590: 2263, 2263, 642: 2263, 2263, 2263, 2263}, - {2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 49: 2262, 472: 2262, 476: 2262, 2262, 2262, 2262, 484: 2262, 488: 2262, 492: 2262, 581: 2262, 590: 2262, 2262, 642: 2262, 2262, 2262, 2262}, - {2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 49: 2273, 472: 2273, 476: 2273, 2273, 2273, 2273, 484: 2273, 488: 2273, 492: 2273, 581: 2273, 590: 2273, 2273, 642: 2273, 2273, 2273, 2273}, - {478: 2278}, - {2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 2289, 49: 2289, 472: 2289, 476: 2289, 2289, 2289, 2289, 484: 2289, 488: 2289, 492: 2289, 581: 2289, 590: 2289, 2289, 642: 2289, 2289, 2289, 2289}, + {193: 4795, 222: 4796, 496: 4794, 1222: 4793}, + {199: 4792, 262: 4791, 496: 4790, 1346: 4789}, + {2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 2355, 58: 2355, 491: 2355, 4783, 495: 2355, 2355, 2355, 2355, 2355, 507: 2355, 510: 2355, 600: 2355, 607: 2355, 613: 2355, 662: 2355, 2355, 2355, 666: 2355, 1213: 4782}, + {327: 4781}, + {2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 58: 2341, 491: 2341, 495: 2341, 2341, 2341, 2341, 2341, 507: 2341, 510: 2341, 600: 2341, 607: 2341, 613: 2341, 662: 2341, 2341, 2341, 666: 2341}, // 2120 - {508: 2736, 733: 2735, 741: 4658}, - {9: 4660, 49: 4659}, - {2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 2287, 49: 2287, 472: 2287, 476: 2287, 2287, 2287, 2287, 484: 2287, 488: 2287, 492: 2287, 581: 2287, 590: 2287, 2287, 642: 2287, 2287, 2287, 2287}, - {508: 2736, 733: 2735, 741: 4661}, - {49: 4662}, + {2338, 2338, 2338, 2338, 2338, 2338, 4726, 4732, 4720, 2338, 2338, 2338, 4724, 4733, 4731, 58: 2338, 491: 4725, 495: 4198, 4723, 4197, 2346, 4730, 507: 2338, 510: 4719, 600: 2383, 607: 2476, 613: 4717, 662: 4722, 4715, 4737, 666: 4734, 834: 4718, 855: 4727, 935: 4729, 953: 4780, 963: 4728, 981: 4721}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4738}, + {2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 2274, 58: 2274, 491: 2274, 4740, 495: 2274, 2274, 2274, 2274, 2274, 507: 2274, 510: 2274, 600: 2274, 607: 2274, 613: 2274, 662: 2274, 2274, 2274, 666: 2274, 669: 2274, 1265: 4739}, + {2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 58: 2328, 491: 2328, 495: 2328, 2328, 2328, 2328, 2328, 507: 2328, 510: 2328, 600: 2328, 607: 2328, 613: 2328, 662: 2328, 2328, 2328, 666: 2328, 669: 4755, 1284: 4756, 4757}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4742, 859: 4741}, // 2125 - {2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 2286, 49: 2286, 472: 2286, 476: 2286, 2286, 2286, 2286, 484: 2286, 488: 2286, 492: 2286, 581: 2286, 590: 2286, 2286, 642: 2286, 2286, 2286, 2286}, - {2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 2290, 49: 2290, 472: 2290, 476: 2290, 2290, 2290, 2290, 484: 2290, 488: 2290, 492: 2290, 581: 2290, 590: 2290, 2290, 642: 2290, 2290, 2290, 2290}, - {2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 49: 2285, 472: 2285, 476: 2285, 2285, 2285, 2285, 484: 2285, 488: 2285, 492: 2285, 581: 2285, 590: 2285, 2285, 642: 2285, 2285, 2285, 2285}, - {2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 49: 2284, 472: 2284, 476: 2284, 2284, 2284, 2284, 484: 2284, 488: 2284, 492: 2284, 581: 2284, 590: 2284, 2284, 642: 2284, 2284, 2284, 2284}, - {2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 2283, 49: 2283, 472: 2283, 476: 2283, 2283, 2283, 2283, 484: 2283, 488: 2283, 492: 2283, 581: 2283, 590: 2283, 2283, 642: 2283, 2283, 2283, 2283}, + {9: 4753, 58: 4752}, + {9: 2272, 58: 2272}, + {9: 316, 58: 316, 492: 3933, 548: 316, 561: 316, 786: 3934, 812: 4750}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4745}, + {58: 4746, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 2130 - {2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 49: 2291, 472: 2291, 476: 2291, 2291, 2291, 2291, 484: 2291, 488: 2291, 492: 2291, 581: 2291, 590: 2291, 2291, 642: 2291, 2291, 2291, 2291}, - {2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 2282, 49: 2282, 472: 2282, 476: 2282, 2282, 2282, 2282, 484: 2282, 488: 2282, 492: 2282, 581: 2282, 590: 2282, 2282, 642: 2282, 2282, 2282, 2282}, - {2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 2281, 49: 2281, 472: 2281, 476: 2281, 2281, 2281, 2281, 484: 2281, 488: 2281, 492: 2281, 581: 2281, 590: 2281, 2281, 642: 2281, 2281, 2281, 2281}, - {2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 2280, 49: 2280, 472: 2280, 476: 2280, 2280, 2280, 2280, 484: 2280, 488: 2280, 492: 2280, 581: 2280, 590: 2280, 2280, 642: 2280, 2280, 2280, 2280}, - {2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 49: 2292, 472: 2292, 476: 2292, 2292, 2292, 2292, 484: 2292, 488: 2292, 492: 2292, 581: 2292, 590: 2292, 2292, 642: 2292, 2292, 2292, 2292}, + {9: 1341, 58: 1341, 548: 4749, 561: 4748, 975: 4747}, + {9: 2269, 58: 2269}, + {1340, 1340, 1340, 1340, 1340, 1340, 9: 1340, 58: 1340, 507: 1340}, + {1339, 1339, 1339, 1339, 1339, 1339, 9: 1339, 58: 1339, 507: 1339}, + {9: 1341, 58: 1341, 548: 4749, 561: 4748, 975: 4751}, // 2135 - {473: 4673}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4674}, - {49: 4675, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 2277, 49: 2277, 472: 2277, 476: 2277, 2277, 2277, 2277, 484: 2277, 488: 2277, 492: 2277, 581: 2277, 590: 2277, 2277, 642: 2277, 2277, 2277, 2277, 1312: 4678, 1342: 4677, 4676}, - {2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 2294, 49: 2294, 472: 2294, 476: 2294, 2294, 2294, 2294, 484: 2294, 488: 2294, 492: 2294, 581: 2294, 590: 2294, 2294, 642: 2294, 2294, 2294, 2294}, + {9: 2270, 58: 2270}, + {2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 2273, 58: 2273, 491: 2273, 495: 2273, 2273, 2273, 2273, 2273, 507: 2273, 510: 2273, 600: 2273, 607: 2273, 613: 2273, 662: 2273, 2273, 2273, 666: 2273, 669: 2273}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4754}, + {9: 2271, 58: 2271}, + {226: 4777, 383: 4778, 403: 4779}, // 2140 - {2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 2276, 49: 2276, 472: 2276, 476: 2276, 2276, 2276, 2276, 484: 2276, 488: 2276, 492: 2276, 581: 2276, 590: 2276, 2276, 642: 2276, 2276, 2276, 2276}, - {2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2275, 49: 2275, 472: 2275, 476: 2275, 2275, 2275, 2275, 484: 2275, 488: 2275, 492: 2275, 581: 2275, 590: 2275, 2275, 642: 2275, 2275, 2275, 2275}, - {473: 4680}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4681}, - {49: 4682, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 58: 2327, 491: 2327, 495: 2327, 2327, 2327, 2327, 2327, 507: 2327, 510: 2327, 600: 2327, 607: 2327, 613: 2327, 662: 2327, 2327, 2327, 666: 2327}, + {2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 58: 2323, 491: 4759, 495: 2323, 2323, 2323, 2323, 2323, 507: 2323, 510: 2323, 600: 2323, 607: 2323, 613: 2323, 662: 2323, 2323, 2323, 666: 2323, 1117: 4760, 4761, 1293: 4758}, + {2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 58: 2326, 491: 2326, 495: 2326, 2326, 2326, 2326, 2326, 507: 2326, 510: 2326, 600: 2326, 607: 2326, 613: 2326, 662: 2326, 2326, 2326, 666: 2326}, + {674: 4775, 761: 4764}, + {2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 2322, 58: 2322, 491: 4773, 495: 2322, 2322, 2322, 2322, 2322, 507: 2322, 510: 2322, 600: 2322, 607: 2322, 613: 2322, 662: 2322, 2322, 2322, 666: 2322, 1118: 4774}, // 2145 - {2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 49: 2310, 149: 4433, 472: 2310, 476: 4089, 4088, 2310, 2310, 484: 2310, 488: 2310, 492: 2310, 581: 2310, 590: 2310, 2310, 642: 2310, 2310, 2310, 2310, 810: 4683, 934: 4684, 1040: 4685, 1208: 4686}, - {149: 4435, 492: 4687}, - {2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 49: 2309, 472: 2309, 476: 2309, 2309, 2309, 2309, 484: 2309, 488: 2309, 492: 2309, 581: 2309, 590: 2309, 2309, 642: 2309, 2309, 2309, 2309}, - {2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 49: 2307, 472: 2307, 476: 2307, 2307, 2307, 2307, 484: 2307, 488: 2307, 492: 2307, 581: 2307, 590: 2307, 2307, 642: 2307, 2307, 2307, 2307}, - {2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 2295, 49: 2295, 472: 2295, 476: 2295, 2295, 2295, 2295, 484: 2295, 488: 2295, 492: 2295, 581: 2295, 590: 2295, 2295, 642: 2295, 2295, 2295, 2295}, + {2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 58: 2321, 491: 4762, 495: 2321, 2321, 2321, 2321, 2321, 507: 2321, 510: 2321, 600: 2321, 607: 2321, 613: 2321, 662: 2321, 2321, 2321, 666: 2321, 1117: 4763}, + {761: 4764}, + {2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 2319, 58: 2319, 491: 2319, 495: 2319, 2319, 2319, 2319, 2319, 507: 2319, 510: 2319, 600: 2319, 607: 2319, 613: 2319, 662: 2319, 2319, 2319, 666: 2319}, + {79: 4769, 526: 4768, 691: 4767, 693: 4766, 1141: 4765}, + {2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 2325, 58: 2325, 491: 2325, 495: 2325, 2325, 2325, 2325, 2325, 507: 2325, 510: 2325, 600: 2325, 607: 2325, 613: 2325, 662: 2325, 2325, 2325, 666: 2325}, // 2150 - {2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 49: 2308, 472: 2308, 476: 2308, 2308, 2308, 2308, 484: 2308, 488: 2308, 492: 2308, 581: 2308, 590: 2308, 2308, 642: 2308, 2308, 2308, 2308}, - {2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 49: 2296, 472: 2296, 476: 2296, 2296, 2296, 2296, 484: 2296, 488: 2296, 492: 2296, 581: 2296, 590: 2296, 2296, 642: 2296, 2296, 2296, 2296}, - {585: 4696, 4693, 588: 4694, 4695, 946: 4691, 4692, 4690}, - {2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 2297, 49: 2297, 472: 2297, 476: 2297, 2297, 2297, 2297, 484: 2297, 488: 2297, 492: 2297, 581: 2297, 590: 2297, 2297, 642: 2297, 2297, 2297, 2297}, - {2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 2237, 49: 2237, 472: 2237, 476: 2237, 2237, 2237, 2237, 484: 2237, 488: 2237, 492: 2237, 581: 2237, 590: 2237, 2237, 642: 2237, 2237, 2237, 2237}, + {2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 2318, 58: 2318, 491: 2318, 495: 2318, 2318, 2318, 2318, 2318, 507: 2318, 510: 2318, 600: 2318, 607: 2318, 613: 2318, 662: 2318, 2318, 2318, 666: 2318}, + {2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 58: 2317, 491: 2317, 495: 2317, 2317, 2317, 2317, 2317, 507: 2317, 510: 2317, 600: 2317, 607: 2317, 613: 2317, 662: 2317, 2317, 2317, 666: 2317}, + {496: 4772, 510: 4771}, + {323: 4770}, + {2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 2315, 58: 2315, 491: 2315, 495: 2315, 2315, 2315, 2315, 2315, 507: 2315, 510: 2315, 600: 2315, 607: 2315, 613: 2315, 662: 2315, 2315, 2315, 666: 2315}, // 2155 - {473: 4697}, - {2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 2228, 49: 2228, 472: 2228, 2232, 476: 2228, 2228, 2228, 2228, 484: 2228, 488: 2228, 492: 2228, 581: 2228, 590: 2228, 2228, 642: 2228, 2228, 2228, 2228}, - {2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 2227, 49: 2227, 472: 2227, 2231, 476: 2227, 2227, 2227, 2227, 484: 2227, 488: 2227, 492: 2227, 581: 2227, 590: 2227, 2227, 642: 2227, 2227, 2227, 2227}, - {2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 2226, 49: 2226, 472: 2226, 2230, 476: 2226, 2226, 2226, 2226, 484: 2226, 488: 2226, 492: 2226, 581: 2226, 590: 2226, 2226, 642: 2226, 2226, 2226, 2226}, - {473: 2229}, + {2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 2316, 58: 2316, 491: 2316, 495: 2316, 2316, 2316, 2316, 2316, 507: 2316, 510: 2316, 600: 2316, 607: 2316, 613: 2316, 662: 2316, 2316, 2316, 666: 2316}, + {2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 58: 2314, 491: 2314, 495: 2314, 2314, 2314, 2314, 2314, 507: 2314, 510: 2314, 600: 2314, 607: 2314, 613: 2314, 662: 2314, 2314, 2314, 666: 2314}, + {674: 4775}, + {2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 58: 2320, 491: 2320, 495: 2320, 2320, 2320, 2320, 2320, 507: 2320, 510: 2320, 600: 2320, 607: 2320, 613: 2320, 662: 2320, 2320, 2320, 666: 2320}, + {79: 4769, 526: 4768, 691: 4767, 693: 4766, 1141: 4776}, // 2160 - {49: 4698, 508: 2736, 733: 4699}, - {2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 2236, 49: 2236, 472: 2236, 476: 2236, 2236, 2236, 2236, 484: 2236, 488: 2236, 492: 2236, 581: 2236, 590: 2236, 2236, 642: 2236, 2236, 2236, 2236}, - {49: 4700}, - {2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 2235, 49: 2235, 472: 2235, 476: 2235, 2235, 2235, 2235, 484: 2235, 488: 2235, 492: 2235, 581: 2235, 590: 2235, 2235, 642: 2235, 2235, 2235, 2235}, - {158: 4702}, + {2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 2324, 58: 2324, 491: 2324, 495: 2324, 2324, 2324, 2324, 2324, 507: 2324, 510: 2324, 600: 2324, 607: 2324, 613: 2324, 662: 2324, 2324, 2324, 666: 2324}, + {2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 58: 2331, 491: 2331, 495: 2331, 2331, 2331, 2331, 2331, 507: 2331, 510: 2331, 600: 2331, 607: 2331, 613: 2331, 662: 2331, 2331, 2331, 666: 2331}, + {2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 58: 2330, 491: 2330, 495: 2330, 2330, 2330, 2330, 2330, 507: 2330, 510: 2330, 600: 2330, 607: 2330, 613: 2330, 662: 2330, 2330, 2330, 666: 2330}, + {2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 58: 2329, 491: 2329, 495: 2329, 2329, 2329, 2329, 2329, 507: 2329, 510: 2329, 600: 2329, 607: 2329, 613: 2329, 662: 2329, 2329, 2329, 666: 2329}, + {2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 58: 2340, 491: 2340, 495: 2340, 2340, 2340, 2340, 2340, 507: 2340, 510: 2340, 600: 2340, 607: 2340, 613: 2340, 662: 2340, 2340, 2340, 666: 2340}, // 2165 - {2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 2298, 49: 2298, 472: 2298, 476: 2298, 2298, 2298, 2298, 484: 2298, 488: 2298, 492: 2298, 581: 2298, 590: 2298, 2298, 642: 2298, 2298, 2298, 2298}, - {2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 2299, 49: 2299, 472: 2299, 476: 2299, 2299, 2299, 2299, 484: 2299, 488: 2299, 492: 2299, 581: 2299, 590: 2299, 2299, 642: 2299, 2299, 2299, 2299}, - {2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 2246, 49: 2246, 472: 2246, 476: 2246, 2246, 2246, 2246, 484: 2246, 488: 2246, 492: 2246, 581: 2246, 590: 2246, 2246, 642: 2246, 2246, 2246, 2246}, - {2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 2245, 49: 2245, 472: 2245, 476: 2245, 2245, 2245, 2245, 484: 2245, 488: 2245, 492: 2245, 581: 2245, 590: 2245, 2245, 642: 2245, 2245, 2245, 2245}, - {2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 2244, 49: 2244, 472: 2244, 476: 2244, 2244, 2244, 2244, 484: 2244, 488: 2244, 492: 2244, 581: 2244, 590: 2244, 2244, 642: 2244, 2244, 2244, 2244}, + {498: 2345}, + {2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 2356, 58: 2356, 491: 2356, 495: 2356, 2356, 2356, 2356, 2356, 507: 2356, 510: 2356, 600: 2356, 607: 2356, 613: 2356, 662: 2356, 2356, 2356, 666: 2356}, + {525: 2824, 755: 2823, 762: 4784}, + {9: 4786, 58: 4785}, + {2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 58: 2354, 491: 2354, 495: 2354, 2354, 2354, 2354, 2354, 507: 2354, 510: 2354, 600: 2354, 607: 2354, 613: 2354, 662: 2354, 2354, 2354, 666: 2354}, // 2170 - {2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 2243, 49: 2243, 472: 2243, 476: 2243, 2243, 2243, 2243, 484: 2243, 488: 2243, 492: 2243, 581: 2243, 590: 2243, 2243, 642: 2243, 2243, 2243, 2243}, - {151: 4709, 473: 4708, 585: 4696, 4693, 588: 4694, 4695, 946: 4691, 4692, 4710, 995: 4717, 1081: 4718}, - {473: 4713}, - {2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 2238, 49: 2238, 472: 2238, 476: 2238, 2238, 2238, 2238, 484: 2238, 488: 2238, 492: 2238, 581: 2238, 590: 2238, 2238, 642: 2238, 2238, 2238, 2238}, - {158: 4179}, + {525: 2824, 755: 2823, 762: 4787}, + {58: 4788}, + {2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 2353, 58: 2353, 491: 2353, 495: 2353, 2353, 2353, 2353, 2353, 507: 2353, 510: 2353, 600: 2353, 607: 2353, 613: 2353, 662: 2353, 2353, 2353, 666: 2353}, + {2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 58: 2357, 491: 2357, 495: 2357, 2357, 2357, 2357, 2357, 507: 2357, 510: 2357, 600: 2357, 607: 2357, 613: 2357, 662: 2357, 2357, 2357, 666: 2357}, + {2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 58: 2352, 491: 2352, 495: 2352, 2352, 2352, 2352, 2352, 507: 2352, 510: 2352, 600: 2352, 607: 2352, 613: 2352, 662: 2352, 2352, 2352, 666: 2352}, // 2175 - {473: 4176}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 4714, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 4715}, - {2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 2241, 49: 2241, 472: 2241, 476: 2241, 2241, 2241, 2241, 484: 2241, 488: 2241, 492: 2241, 581: 2241, 590: 2241, 2241, 642: 2241, 2241, 2241, 2241}, - {9: 3590, 49: 4716}, - {2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 2240, 49: 2240, 472: 2240, 476: 2240, 2240, 2240, 2240, 484: 2240, 488: 2240, 492: 2240, 581: 2240, 590: 2240, 2240, 642: 2240, 2240, 2240, 2240}, + {2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2351, 58: 2351, 491: 2351, 495: 2351, 2351, 2351, 2351, 2351, 507: 2351, 510: 2351, 600: 2351, 607: 2351, 613: 2351, 662: 2351, 2351, 2351, 666: 2351}, + {2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 58: 2350, 491: 2350, 495: 2350, 2350, 2350, 2350, 2350, 507: 2350, 510: 2350, 600: 2350, 607: 2350, 613: 2350, 662: 2350, 2350, 2350, 666: 2350}, + {2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 2358, 58: 2358, 491: 2358, 495: 2358, 2358, 2358, 2358, 2358, 507: 2358, 510: 2358, 600: 2358, 607: 2358, 613: 2358, 662: 2358, 2358, 2358, 666: 2358}, + {2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 58: 2349, 491: 2349, 495: 2349, 2349, 2349, 2349, 2349, 507: 2349, 510: 2349, 600: 2349, 607: 2349, 613: 2349, 662: 2349, 2349, 2349, 666: 2349}, + {2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 58: 2348, 491: 2348, 495: 2348, 2348, 2348, 2348, 2348, 507: 2348, 510: 2348, 600: 2348, 607: 2348, 613: 2348, 662: 2348, 2348, 2348, 666: 2348}, // 2180 - {49: 4720}, - {49: 4719}, - {2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 2239, 49: 2239, 472: 2239, 476: 2239, 2239, 2239, 2239, 484: 2239, 488: 2239, 492: 2239, 581: 2239, 590: 2239, 2239, 642: 2239, 2239, 2239, 2239}, - {2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 2242, 49: 2242, 472: 2242, 476: 2242, 2242, 2242, 2242, 484: 2242, 488: 2242, 492: 2242, 581: 2242, 590: 2242, 2242, 642: 2242, 2242, 2242, 2242}, - {2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 49: 2300, 472: 2300, 476: 2300, 2300, 2300, 2300, 484: 2300, 488: 2300, 492: 2300, 581: 2300, 590: 2300, 2300, 642: 2300, 2300, 2300, 2300}, + {2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 2347, 58: 2347, 491: 2347, 495: 2347, 2347, 2347, 2347, 2347, 507: 2347, 510: 2347, 600: 2347, 607: 2347, 613: 2347, 662: 2347, 2347, 2347, 666: 2347}, + {2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 2359, 58: 2359, 491: 2359, 495: 2359, 2359, 2359, 2359, 2359, 507: 2359, 510: 2359, 600: 2359, 607: 2359, 613: 2359, 662: 2359, 2359, 2359, 666: 2359}, + {492: 4799}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4800}, + {58: 4801, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 2185 - {2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 49: 2303, 85: 4723, 87: 4724, 472: 2303, 476: 2303, 2303, 2303, 2303, 484: 2303, 488: 2303, 492: 2303, 581: 2303, 590: 2303, 2303, 642: 2303, 2303, 2303, 2303, 869: 4725}, - {2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 19: 2432, 49: 2432, 83: 2432, 2432, 2432, 2432, 2432, 89: 2432, 472: 2432, 474: 2432, 476: 2432, 2432, 2432, 2432, 481: 2432, 484: 2432, 488: 2432, 492: 2432, 497: 2432, 581: 2432, 590: 2432, 2432, 642: 2432, 2432, 2432, 2432}, - {2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 19: 2431, 49: 2431, 83: 2431, 2431, 2431, 2431, 2431, 89: 2431, 472: 2431, 474: 2431, 476: 2431, 2431, 2431, 2431, 481: 2431, 484: 2431, 488: 2431, 492: 2431, 497: 2431, 581: 2431, 590: 2431, 2431, 642: 2431, 2431, 2431, 2431}, - {2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 49: 2302, 472: 2302, 476: 2302, 2302, 2302, 2302, 484: 2302, 488: 2302, 492: 2302, 581: 2302, 590: 2302, 2302, 642: 2302, 2302, 2302, 2302}, - {2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 49: 2306, 472: 2306, 476: 2306, 2306, 2306, 2306, 484: 2306, 488: 2306, 492: 2306, 581: 2306, 590: 2306, 2306, 642: 2306, 2306, 2306, 2306}, + {2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 58: 2344, 491: 2344, 495: 2344, 2344, 2344, 2344, 2344, 507: 2344, 510: 2344, 600: 2344, 607: 2344, 613: 2344, 662: 2344, 2344, 2344, 666: 2344, 1347: 4804, 1377: 4803, 4802}, + {2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 58: 2361, 491: 2361, 495: 2361, 2361, 2361, 2361, 2361, 507: 2361, 510: 2361, 600: 2361, 607: 2361, 613: 2361, 662: 2361, 2361, 2361, 666: 2361}, + {2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 58: 2343, 491: 2343, 495: 2343, 2343, 2343, 2343, 2343, 507: 2343, 510: 2343, 600: 2343, 607: 2343, 613: 2343, 662: 2343, 2343, 2343, 666: 2343}, + {2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 58: 2342, 491: 2342, 495: 2342, 2342, 2342, 2342, 2342, 507: 2342, 510: 2342, 600: 2342, 607: 2342, 613: 2342, 662: 2342, 2342, 2342, 666: 2342}, + {492: 4806}, // 2190 - {581: 2404, 590: 2404, 2404, 642: 2404, 649: 2404, 675: 2404, 2404}, - {2403, 2403, 2403, 2403, 2403, 2403, 9: 2403, 488: 2403, 581: 2403, 590: 2403, 2403, 642: 2403, 649: 2403, 675: 2403, 2403}, - {2339, 2339, 2339, 2339, 2339, 2339, 9: 2339, 2339, 2339, 49: 2339, 488: 2339}, - {2462, 2462, 2462, 2462, 2462, 2462, 9: 2462, 488: 2462}, - {2414, 2414, 2414, 2414, 2414, 2414, 9: 2414, 488: 2414}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4807}, + {58: 4808, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 2377, 58: 2377, 163: 4559, 491: 2377, 495: 4198, 2377, 4197, 2377, 2377, 507: 2377, 510: 2377, 600: 2377, 607: 2377, 613: 2377, 662: 2377, 2377, 2377, 666: 2377, 834: 4809, 960: 4810, 1068: 4811, 1241: 4812}, + {163: 4561, 510: 4813}, + {2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 58: 2376, 491: 2376, 495: 2376, 2376, 2376, 2376, 2376, 507: 2376, 510: 2376, 600: 2376, 607: 2376, 613: 2376, 662: 2376, 2376, 2376, 666: 2376}, // 2195 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4733}, - {2413, 2413, 2413, 2413, 2413, 2413, 9: 2413, 488: 2413}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 4735}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4456, 848: 4736}, - {2415, 2415, 2415, 2415, 2415, 2415, 9: 2415, 4731, 4732, 488: 2415, 929: 4737}, + {2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 2374, 58: 2374, 491: 2374, 495: 2374, 2374, 2374, 2374, 2374, 507: 2374, 510: 2374, 600: 2374, 607: 2374, 613: 2374, 662: 2374, 2374, 2374, 666: 2374}, + {2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 2362, 58: 2362, 491: 2362, 495: 2362, 2362, 2362, 2362, 2362, 507: 2362, 510: 2362, 600: 2362, 607: 2362, 613: 2362, 662: 2362, 2362, 2362, 666: 2362}, + {2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 2375, 58: 2375, 491: 2375, 495: 2375, 2375, 2375, 2375, 2375, 507: 2375, 510: 2375, 600: 2375, 607: 2375, 613: 2375, 662: 2375, 2375, 2375, 666: 2375}, + {2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 58: 2363, 491: 2363, 495: 2363, 2363, 2363, 2363, 2363, 507: 2363, 510: 2363, 600: 2363, 607: 2363, 613: 2363, 662: 2363, 2363, 2363, 666: 2363}, + {605: 4825, 4824, 608: 4820, 4821, 611: 4822, 4823, 957: 4819, 972: 4817, 4818, 4816}, // 2200 - {2463, 2463, 2463, 2463, 2463, 2463, 9: 2463, 488: 2463}, - {2464, 2464, 2464, 2464, 2464, 2464, 9: 2464, 488: 2464}, - {2465, 2465, 2465, 2465, 2465, 2465, 9: 2465, 488: 2465}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4743, 985: 4742, 1168: 4741}, - {2466, 2466, 2466, 2466, 2466, 2466, 9: 4745, 488: 2466}, + {2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 58: 2364, 491: 2364, 495: 2364, 2364, 2364, 2364, 2364, 507: 2364, 510: 2364, 600: 2364, 607: 2364, 613: 2364, 662: 2364, 2364, 2364, 666: 2364}, + {2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 58: 2304, 491: 2304, 495: 2304, 2304, 2304, 2304, 2304, 507: 2304, 510: 2304, 600: 2304, 607: 2304, 613: 2304, 662: 2304, 2304, 2304, 666: 2304}, + {492: 4828}, + {492: 4826}, + {2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 58: 2300, 491: 2300, 2289, 495: 2300, 2300, 2300, 2300, 2300, 507: 2300, 510: 2300, 600: 2300, 607: 2300, 613: 2300, 662: 2300, 2300, 2300, 666: 2300}, // 2205 - {1310, 1310, 1310, 1310, 1310, 1310, 9: 1310, 488: 1310}, - {1300, 1300, 1300, 1300, 1300, 1300, 9: 1300, 488: 1300, 529: 4623, 531: 4622, 949: 4744}, - {1308, 1308, 1308, 1308, 1308, 1308, 9: 1308, 488: 1308}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4743, 985: 4746}, - {1309, 1309, 1309, 1309, 1309, 1309, 9: 1309, 488: 1309}, + {2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 2293, 58: 2293, 491: 2293, 2297, 495: 2293, 2293, 2293, 2293, 2293, 507: 2293, 510: 2293, 600: 2293, 607: 2293, 613: 2293, 662: 2293, 2293, 2293, 666: 2293}, + {2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 2292, 58: 2292, 491: 2292, 2296, 495: 2292, 2292, 2292, 2292, 2292, 507: 2292, 510: 2292, 600: 2292, 607: 2292, 613: 2292, 662: 2292, 2292, 2292, 666: 2292}, + {2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 2291, 58: 2291, 491: 2291, 2295, 495: 2291, 2291, 2291, 2291, 2291, 507: 2291, 510: 2291, 600: 2291, 607: 2291, 613: 2291, 662: 2291, 2291, 2291, 666: 2291}, + {492: 2294}, + {492: 2290}, // 2210 - {2: 569, 569, 569, 569, 569, 569, 569, 10: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 50: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 4750, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 651: 569, 811: 4749, 829: 4748}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 651: 4752, 661: 4754, 2762, 2763, 2761, 786: 4753, 832: 4751}, - {568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 50: 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 473: 568, 488: 568, 508: 568, 530: 568, 569: 568, 651: 568}, - {567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 50: 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 473: 567, 488: 567, 508: 567, 530: 567, 569: 567, 651: 567}, - {2469, 2469, 2469, 2469, 2469, 2469, 9: 2469, 488: 2469}, + {58: 4827}, + {2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 58: 2301, 491: 2301, 495: 2301, 2301, 2301, 2301, 2301, 507: 2301, 510: 2301, 600: 2301, 607: 2301, 613: 2301, 662: 2301, 2301, 2301, 666: 2301}, + {58: 4829, 525: 2824, 755: 4830}, + {2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 2303, 58: 2303, 491: 2303, 495: 2303, 2303, 2303, 2303, 2303, 507: 2303, 510: 2303, 600: 2303, 607: 2303, 613: 2303, 662: 2303, 2303, 2303, 666: 2303}, + {58: 4831}, // 2215 - {2438, 2438, 2438, 2438, 2438, 2438, 9: 2438, 20: 2438, 488: 2438}, - {2437, 2437, 2437, 2437, 2437, 2437, 9: 4755, 20: 2437, 488: 2437}, - {2408, 2408, 2408, 2408, 2408, 2408, 9: 2408, 20: 2408, 49: 2408, 102: 2408, 166: 2408, 168: 2408, 474: 2408, 488: 2408, 496: 2408, 649: 2408, 651: 2408}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4756, 2762, 2763, 2761}, - {2407, 2407, 2407, 2407, 2407, 2407, 9: 2407, 20: 2407, 49: 2407, 102: 2407, 166: 2407, 168: 2407, 474: 2407, 488: 2407, 496: 2407, 649: 2407, 651: 2407}, + {2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 2302, 58: 2302, 491: 2302, 495: 2302, 2302, 2302, 2302, 2302, 507: 2302, 510: 2302, 600: 2302, 607: 2302, 613: 2302, 662: 2302, 2302, 2302, 666: 2302}, + {172: 4833}, + {2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 58: 2365, 491: 2365, 495: 2365, 2365, 2365, 2365, 2365, 507: 2365, 510: 2365, 600: 2365, 607: 2365, 613: 2365, 662: 2365, 2365, 2365, 666: 2365}, + {2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 58: 2366, 491: 2366, 495: 2366, 2366, 2366, 2366, 2366, 507: 2366, 510: 2366, 600: 2366, 607: 2366, 613: 2366, 662: 2366, 2366, 2366, 666: 2366}, + {2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 58: 2313, 491: 2313, 495: 2313, 2313, 2313, 2313, 2313, 507: 2313, 510: 2313, 600: 2313, 607: 2313, 613: 2313, 662: 2313, 2313, 2313, 666: 2313}, // 2220 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 651: 4752, 661: 4754, 2762, 2763, 2761, 786: 4753, 832: 4759}, - {2470, 2470, 2470, 2470, 2470, 2470, 9: 2470, 488: 2470}, - {20: 4760}, - {2472, 2472, 2472, 2472, 2472, 2472, 9: 2472, 488: 2472}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 651: 4752, 661: 4754, 2762, 2763, 2761, 786: 4753, 832: 4763}, + {2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 2312, 58: 2312, 491: 2312, 495: 2312, 2312, 2312, 2312, 2312, 507: 2312, 510: 2312, 600: 2312, 607: 2312, 613: 2312, 662: 2312, 2312, 2312, 666: 2312}, + {2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 58: 2311, 491: 2311, 495: 2311, 2311, 2311, 2311, 2311, 507: 2311, 510: 2311, 600: 2311, 607: 2311, 613: 2311, 662: 2311, 2311, 2311, 666: 2311}, + {2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 2310, 58: 2310, 491: 2310, 495: 2310, 2310, 2310, 2310, 2310, 507: 2310, 510: 2310, 600: 2310, 607: 2310, 613: 2310, 662: 2310, 2310, 2310, 666: 2310}, + {141: 4840, 492: 4839, 605: 4825, 4824, 608: 4820, 4821, 611: 4822, 4823, 924: 4848, 957: 4819, 972: 4817, 4818, 4841, 1111: 4849}, + {492: 4844}, // 2225 - {2471, 2471, 2471, 2471, 2471, 2471, 9: 2471, 488: 2471}, - {20: 4764}, - {2473, 2473, 2473, 2473, 2473, 2473, 9: 2473, 488: 2473}, - {2: 569, 569, 569, 569, 569, 569, 569, 10: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 50: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 4750, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 651: 569, 811: 4749, 829: 4766}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 651: 4752, 661: 4754, 2762, 2763, 2761, 786: 4753, 832: 4767}, + {2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 58: 2305, 491: 2305, 495: 2305, 2305, 2305, 2305, 2305, 507: 2305, 510: 2305, 600: 2305, 607: 2305, 613: 2305, 662: 2305, 2305, 2305, 666: 2305}, + {172: 4292}, + {492: 4289}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 4845, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 4846}, + {2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 2308, 58: 2308, 491: 2308, 495: 2308, 2308, 2308, 2308, 2308, 507: 2308, 510: 2308, 600: 2308, 607: 2308, 613: 2308, 662: 2308, 2308, 2308, 666: 2308}, // 2230 - {2474, 2474, 2474, 2474, 2474, 2474, 9: 2474, 488: 2474}, - {2: 569, 569, 569, 569, 569, 569, 569, 10: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 50: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 4750, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 651: 569, 811: 4749, 829: 4769}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 651: 4752, 661: 4754, 2762, 2763, 2761, 786: 4753, 832: 4770}, - {2475, 2475, 2475, 2475, 2475, 2475, 9: 2475, 488: 2475}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 651: 4752, 661: 4754, 2762, 2763, 2761, 786: 4753, 832: 4772}, + {9: 3697, 58: 4847}, + {2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 2307, 58: 2307, 491: 2307, 495: 2307, 2307, 2307, 2307, 2307, 507: 2307, 510: 2307, 600: 2307, 607: 2307, 613: 2307, 662: 2307, 2307, 2307, 666: 2307}, + {58: 4851}, + {58: 4850}, + {2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 58: 2306, 491: 2306, 495: 2306, 2306, 2306, 2306, 2306, 507: 2306, 510: 2306, 600: 2306, 607: 2306, 613: 2306, 662: 2306, 2306, 2306, 666: 2306}, // 2235 - {2476, 2476, 2476, 2476, 2476, 2476, 9: 2476, 488: 2476}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4774, 2762, 2763, 2761}, - {474: 4775}, - {569: 4776}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 4777}, + {2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 58: 2309, 491: 2309, 495: 2309, 2309, 2309, 2309, 2309, 507: 2309, 510: 2309, 600: 2309, 607: 2309, 613: 2309, 662: 2309, 2309, 2309, 666: 2309}, + {2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 58: 2367, 491: 2367, 495: 2367, 2367, 2367, 2367, 2367, 507: 2367, 510: 2367, 600: 2367, 607: 2367, 613: 2367, 662: 2367, 2367, 2367, 666: 2367}, + {2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 58: 2370, 92: 4854, 94: 4855, 491: 2370, 495: 2370, 2370, 2370, 2370, 2370, 507: 2370, 510: 2370, 600: 2370, 607: 2370, 613: 2370, 662: 2370, 2370, 2370, 666: 2370, 892: 4856}, + {2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 19: 2502, 58: 2502, 90: 2502, 2502, 2502, 2502, 2502, 96: 2502, 491: 2502, 494: 2502, 2502, 2502, 2502, 2502, 2502, 501: 2502, 507: 2502, 510: 2502, 518: 2502, 600: 2502, 607: 2502, 613: 2502, 662: 2502, 2502, 2502, 666: 2502}, + {2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 19: 2501, 58: 2501, 90: 2501, 2501, 2501, 2501, 2501, 96: 2501, 491: 2501, 494: 2501, 2501, 2501, 2501, 2501, 2501, 501: 2501, 507: 2501, 510: 2501, 518: 2501, 600: 2501, 607: 2501, 613: 2501, 662: 2501, 2501, 2501, 666: 2501}, // 2240 - {2436, 2436, 2436, 2436, 2436, 2436, 9: 2436, 224: 4781, 474: 4780, 488: 2436, 1353: 4779, 4778}, - {2477, 2477, 2477, 2477, 2477, 2477, 9: 2477, 488: 2477}, - {2435, 2435, 2435, 2435, 2435, 2435, 9: 2435, 488: 2435}, - {201: 4783}, - {201: 4782}, + {2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 2369, 58: 2369, 491: 2369, 495: 2369, 2369, 2369, 2369, 2369, 507: 2369, 510: 2369, 600: 2369, 607: 2369, 613: 2369, 662: 2369, 2369, 2369, 666: 2369}, + {2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 58: 2373, 491: 2373, 495: 2373, 2373, 2373, 2373, 2373, 507: 2373, 510: 2373, 600: 2373, 607: 2373, 613: 2373, 662: 2373, 2373, 2373, 666: 2373}, + {600: 2474, 607: 2474, 613: 2474, 662: 2474, 668: 2474, 696: 2474, 2474}, + {2473, 2473, 2473, 2473, 2473, 2473, 9: 2473, 507: 2473, 600: 2473, 607: 2473, 613: 2473, 662: 2473, 668: 2473, 696: 2473, 2473}, + {2406, 2406, 2406, 2406, 2406, 2406, 9: 2406, 2406, 2406, 58: 2406, 507: 2406}, // 2245 - {2433, 2433, 2433, 2433, 2433, 2433, 9: 2433, 488: 2433}, - {2434, 2434, 2434, 2434, 2434, 2434, 9: 2434, 488: 2434}, - {152: 4785}, - {157: 4786}, - {473: 4787}, + {2532, 2532, 2532, 2532, 2532, 2532, 9: 2532, 507: 2532}, + {2484, 2484, 2484, 2484, 2484, 2484, 9: 2484, 507: 2484}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4864}, + {2483, 2483, 2483, 2483, 2483, 2483, 9: 2483, 507: 2483}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 4866}, // 2250 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 4788}, - {49: 4789, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {1860, 1860, 1860, 1860, 1860, 1860, 9: 1860, 488: 1860, 564: 4452, 780: 4790}, - {2479, 2479, 2479, 2479, 2479, 2479, 9: 2479, 488: 2479}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 4809}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4582, 872: 4867}, + {2485, 2485, 2485, 2485, 2485, 2485, 9: 2485, 4862, 4863, 507: 2485, 954: 4868}, + {2533, 2533, 2533, 2533, 2533, 2533, 9: 2533, 507: 2533}, + {2534, 2534, 2534, 2534, 2534, 2534, 9: 2534, 507: 2534}, + {2535, 2535, 2535, 2535, 2535, 2535, 9: 2535, 507: 2535}, // 2255 - {581: 4808}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 4806}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 4804}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 4802}, - {581: 4799}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4874, 1010: 4873, 1201: 4872}, + {2536, 2536, 2536, 2536, 2536, 2536, 9: 4876, 507: 2536}, + {1351, 1351, 1351, 1351, 1351, 1351, 9: 1351, 507: 1351}, + {1341, 1341, 1341, 1341, 1341, 1341, 9: 1341, 507: 1341, 548: 4749, 561: 4748, 975: 4875}, + {1349, 1349, 1349, 1349, 1349, 1349, 9: 1349, 507: 1349}, // 2260 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4798, 2762, 2763, 2761}, - {2444, 2444, 2444, 2444, 2444, 2444, 9: 2444, 488: 2444}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 4800}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4728, 2762, 2763, 2761, 1144: 4801}, - {2467, 2467, 2467, 2467, 2467, 2467, 9: 2467, 488: 2467}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4874, 1010: 4877}, + {1350, 1350, 1350, 1350, 1350, 1350, 9: 1350, 507: 1350}, + {2: 606, 606, 606, 606, 606, 606, 606, 10: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 59: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 4881, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 671: 606, 835: 4880, 851: 4879}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 671: 4883, 685: 4885, 2850, 688: 2851, 2849, 809: 4884, 854: 4882}, + {605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 59: 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 492: 605, 507: 605, 525: 605, 549: 605, 588: 605, 671: 605}, // 2265 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4803, 2762, 2763, 2761}, - {2468, 2468, 2468, 2468, 2468, 2468, 9: 2468, 488: 2468}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4805, 2762, 2763, 2761}, - {2478, 2478, 2478, 2478, 2478, 2478, 9: 2478, 488: 2478}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 4807}, + {604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 59: 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 492: 604, 507: 604, 525: 604, 549: 604, 588: 604, 671: 604}, + {2539, 2539, 2539, 2539, 2539, 2539, 9: 2539, 507: 2539}, + {2508, 2508, 2508, 2508, 2508, 2508, 9: 2508, 20: 2508, 507: 2508}, + {2507, 2507, 2507, 2507, 2507, 2507, 9: 4886, 20: 2507, 507: 2507}, + {2478, 2478, 2478, 2478, 2478, 2478, 9: 2478, 20: 2478, 58: 2478, 109: 2478, 180: 2478, 182: 2478, 494: 2478, 507: 2478, 516: 2478, 668: 2478, 671: 2478}, // 2270 - {2480, 2480, 2480, 2480, 2480, 2480, 9: 4755, 488: 2480}, - {2481, 2481, 2481, 2481, 2481, 2481, 9: 2481, 488: 2481}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4810}, - {2052, 2052, 2052, 2052, 2052, 2052, 9: 2052, 488: 2052, 670: 4813, 672: 4812, 911: 4811}, - {2482, 2482, 2482, 2482, 2482, 2482, 9: 2482, 488: 2482}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4887, 2850, 688: 2851, 2849}, + {2477, 2477, 2477, 2477, 2477, 2477, 9: 2477, 20: 2477, 58: 2477, 109: 2477, 180: 2477, 182: 2477, 494: 2477, 507: 2477, 516: 2477, 668: 2477, 671: 2477}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 671: 4883, 685: 4885, 2850, 688: 2851, 2849, 809: 4884, 854: 4890}, + {2540, 2540, 2540, 2540, 2540, 2540, 9: 2540, 507: 2540}, + {20: 4891}, // 2275 - {2051, 2051, 2051, 2051, 2051, 2051, 9: 2051, 488: 2051}, - {2050, 2050, 2050, 2050, 2050, 2050, 9: 2050, 488: 2050}, - {136: 4750, 508: 569, 811: 4749, 829: 4815}, - {508: 2736, 733: 4816}, - {2483, 2483, 2483, 2483, 2483, 2483, 9: 2483, 488: 2483}, + {2542, 2542, 2542, 2542, 2542, 2542, 9: 2542, 507: 2542}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 671: 4883, 685: 4885, 2850, 688: 2851, 2849, 809: 4884, 854: 4894}, + {2541, 2541, 2541, 2541, 2541, 2541, 9: 2541, 507: 2541}, + {20: 4895}, + {2543, 2543, 2543, 2543, 2543, 2543, 9: 2543, 507: 2543}, // 2280 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 651: 4752, 661: 4754, 2762, 2763, 2761, 786: 4753, 832: 4818}, - {2484, 2484, 2484, 2484, 2484, 2484, 9: 2484, 488: 2484}, - {152: 4820}, - {157: 4821}, - {473: 4822}, + {2: 606, 606, 606, 606, 606, 606, 606, 10: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 59: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 4881, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 671: 606, 835: 4880, 851: 4897}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 671: 4883, 685: 4885, 2850, 688: 2851, 2849, 809: 4884, 854: 4898}, + {2544, 2544, 2544, 2544, 2544, 2544, 9: 2544, 507: 2544}, + {2: 606, 606, 606, 606, 606, 606, 606, 10: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 59: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 4881, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 671: 606, 835: 4880, 851: 4900}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 671: 4883, 685: 4885, 2850, 688: 2851, 2849, 809: 4884, 854: 4901}, // 2285 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 4823}, - {49: 4824, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {569, 569, 569, 569, 569, 569, 9: 569, 136: 4750, 488: 569, 811: 4749, 829: 4825}, - {2488, 2488, 2488, 2488, 2488, 2488, 9: 2488, 488: 2488}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 473: 1858, 564: 4844, 785: 4958}, + {2545, 2545, 2545, 2545, 2545, 2545, 9: 2545, 507: 2545}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 671: 4883, 685: 4885, 2850, 688: 2851, 2849, 809: 4884, 854: 4903}, + {2546, 2546, 2546, 2546, 2546, 2546, 9: 2546, 507: 2546}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4905, 2850, 688: 2851, 2849}, + {494: 4906}, // 2290 - {2491, 2491, 2491, 2491, 2491, 2491, 9: 2491, 488: 2491}, - {1858, 1858, 1858, 1858, 1858, 1858, 9: 1858, 91: 1858, 136: 1858, 473: 1858, 488: 1858, 564: 4844, 785: 4912, 811: 1858}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 4903}, - {581: 4410, 590: 4836, 4831, 642: 4834, 649: 4411, 675: 4835, 4832, 828: 4833, 1197: 4837}, - {581: 4897}, + {588: 4907}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4908}, + {2506, 2506, 2506, 2506, 2506, 2506, 9: 2506, 239: 4912, 494: 4911, 507: 2506, 1388: 4910, 4909}, + {2547, 2547, 2547, 2547, 2547, 2547, 9: 2547, 507: 2547}, + {2505, 2505, 2505, 2505, 2505, 2505, 9: 2505, 507: 2505}, // 2295 - {2: 2419, 2419, 2419, 2419, 2419, 2419, 2419, 10: 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 50: 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 473: 2419, 581: 4410, 649: 4411, 828: 4853, 1067: 4891}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 473: 1858, 481: 1858, 564: 4844, 785: 4885}, - {2: 2419, 2419, 2419, 2419, 2419, 2419, 2419, 10: 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 50: 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 473: 2419, 481: 2419, 581: 4410, 649: 4411, 828: 4853, 1067: 4854}, - {581: 4842}, - {473: 4838}, + {215: 4914}, + {215: 4913}, + {2503, 2503, 2503, 2503, 2503, 2503, 9: 2503, 507: 2503}, + {2504, 2504, 2504, 2504, 2504, 2504, 9: 2504, 507: 2504}, + {165: 4916}, // 2300 - {443, 443, 443, 443, 443, 443, 9: 443, 49: 443, 488: 443}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 4839}, - {49: 4840, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2310, 2310, 2310, 2310, 2310, 2310, 9: 2310, 49: 2310, 149: 4433, 476: 4089, 4088, 488: 2310, 810: 4434, 934: 4684, 1040: 4841}, - {2265, 2265, 2265, 2265, 2265, 2265, 9: 2265, 49: 2265, 488: 2265}, + {170: 4917}, + {492: 4918}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 4919}, + {58: 4920, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {1920, 1920, 1920, 1920, 1920, 1920, 9: 1920, 507: 1920, 583: 4578, 800: 4921}, // 2305 - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 473: 1858, 564: 4844, 785: 4843}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 1854, 661: 4848, 2762, 2763, 2761, 878: 4847}, - {476: 4089, 4088, 810: 4845}, - {583: 4846}, - {1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 50: 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 1857, 473: 1857, 475: 1857, 481: 1857, 488: 1857, 570: 1857, 811: 1857}, + {2549, 2549, 2549, 2549, 2549, 2549, 9: 2549, 507: 2549}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 4940}, + {600: 4939}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 4937}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 4935}, // 2310 - {473: 4849}, - {473: 1853}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4616, 836: 4850}, - {9: 4627, 49: 4851}, - {644: 4611, 910: 4852}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 4933}, + {600: 4930}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4929, 2850, 688: 2851, 2849}, + {2514, 2514, 2514, 2514, 2514, 2514, 9: 2514, 507: 2514}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 4931}, // 2315 - {2266, 2266, 2266, 2266, 2266, 2266, 9: 2266, 49: 2266, 488: 2266}, - {2: 2418, 2418, 2418, 2418, 2418, 2418, 2418, 10: 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 50: 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 473: 2418, 481: 2418}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 1854, 481: 1854, 661: 4856, 2762, 2763, 2761, 878: 4857, 942: 4855}, - {473: 4865}, - {84: 4863, 473: 1853, 481: 1853}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4859, 2850, 688: 2851, 2849, 1176: 4932}, + {2537, 2537, 2537, 2537, 2537, 2537, 9: 2537, 507: 2537}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4934, 2850, 688: 2851, 2849}, + {2538, 2538, 2538, 2538, 2538, 2538, 9: 2538, 507: 2538}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4936, 2850, 688: 2851, 2849}, // 2320 - {473: 1844, 481: 4858}, - {143: 4861, 177: 4860, 193: 4862, 905: 4859}, - {473: 1843}, - {1837, 1837, 1837, 1837, 1837, 1837, 1837, 9: 1837, 19: 1837, 49: 1837, 83: 1837, 1837, 1837, 1837, 1837, 89: 1837, 472: 1837, 1837, 1837, 481: 1837, 488: 1837, 497: 1837}, - {1836, 1836, 1836, 1836, 1836, 1836, 1836, 9: 1836, 19: 1836, 49: 1836, 83: 1836, 1836, 1836, 1836, 1836, 89: 1836, 472: 1836, 1836, 1836, 481: 1836, 488: 1836, 497: 1836}, + {2548, 2548, 2548, 2548, 2548, 2548, 9: 2548, 507: 2548}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 4938}, + {2550, 2550, 2550, 2550, 2550, 2550, 9: 4886, 507: 2550}, + {2551, 2551, 2551, 2551, 2551, 2551, 9: 2551, 507: 2551}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4941}, // 2325 - {1835, 1835, 1835, 1835, 1835, 1835, 1835, 9: 1835, 19: 1835, 49: 1835, 83: 1835, 1835, 1835, 1835, 1835, 89: 1835, 472: 1835, 1835, 1835, 481: 1835, 488: 1835, 497: 1835}, - {143: 4861, 177: 4860, 193: 4862, 905: 4864}, - {473: 1842}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4616, 836: 4866}, - {9: 4627, 49: 4867}, + {2114, 2114, 2114, 2114, 2114, 2114, 9: 2114, 507: 2114, 691: 4944, 693: 4943, 936: 4942}, + {2552, 2552, 2552, 2552, 2552, 2552, 9: 2552, 507: 2552}, + {2113, 2113, 2113, 2113, 2113, 2113, 9: 2113, 507: 2113}, + {2112, 2112, 2112, 2112, 2112, 2112, 9: 2112, 507: 2112}, + {152: 4881, 525: 606, 835: 4880, 851: 4946}, // 2330 - {1852, 1852, 1852, 1852, 1852, 1852, 1852, 9: 1852, 19: 1852, 49: 1852, 84: 1852, 1852, 1852, 1852, 89: 1852, 474: 1852, 481: 1852, 488: 1852, 880: 4868}, - {2267, 2267, 2267, 2267, 2267, 2267, 4873, 9: 2267, 19: 4870, 49: 2267, 84: 4877, 4723, 4430, 4724, 89: 4429, 474: 4872, 481: 4876, 488: 2267, 856: 4874, 858: 4871, 869: 4875, 879: 4869}, - {1851, 1851, 1851, 1851, 1851, 1851, 1851, 9: 1851, 19: 1851, 49: 1851, 83: 1851, 1851, 1851, 1851, 1851, 89: 1851, 474: 1851, 481: 1851, 488: 1851, 497: 1851}, - {499: 4281, 508: 2047, 736: 4883}, - {1849, 1849, 1849, 1849, 1849, 1849, 1849, 9: 1849, 19: 1849, 49: 1849, 83: 1849, 1849, 1849, 1849, 1849, 89: 1849, 474: 1849, 481: 1849, 488: 1849, 497: 1849}, + {525: 2824, 755: 4947}, + {2553, 2553, 2553, 2553, 2553, 2553, 9: 2553, 507: 2553}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 671: 4883, 685: 4885, 2850, 688: 2851, 2849, 809: 4884, 854: 4949}, + {2554, 2554, 2554, 2554, 2554, 2554, 9: 2554, 507: 2554}, + {165: 4951}, // 2335 - {368: 4881}, - {475: 4880}, - {1846, 1846, 1846, 1846, 1846, 1846, 1846, 9: 1846, 19: 1846, 49: 1846, 83: 1846, 1846, 1846, 1846, 1846, 89: 1846, 474: 1846, 481: 1846, 488: 1846, 497: 1846}, - {1845, 1845, 1845, 1845, 1845, 1845, 1845, 9: 1845, 19: 1845, 49: 1845, 83: 1845, 1845, 1845, 1845, 1845, 89: 1845, 474: 1845, 481: 1845, 488: 1845, 497: 1845}, - {143: 4861, 177: 4860, 193: 4862, 905: 4879}, + {170: 4952}, + {492: 4953}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 4954}, + {58: 4955, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {606, 606, 606, 606, 606, 606, 9: 606, 152: 4881, 507: 606, 835: 4880, 851: 4956}, // 2340 - {143: 4861, 177: 4860, 193: 4862, 905: 4878}, - {1838, 1838, 1838, 1838, 1838, 1838, 1838, 9: 1838, 19: 1838, 49: 1838, 83: 1838, 1838, 1838, 1838, 1838, 89: 1838, 472: 1838, 474: 1838, 481: 1838, 488: 1838, 497: 1838}, - {1839, 1839, 1839, 1839, 1839, 1839, 1839, 9: 1839, 19: 1839, 49: 1839, 83: 1839, 1839, 1839, 1839, 1839, 89: 1839, 472: 1839, 474: 1839, 481: 1839, 488: 1839, 497: 1839}, - {1847, 1847, 1847, 1847, 1847, 1847, 1847, 9: 1847, 19: 1847, 49: 1847, 83: 1847, 1847, 1847, 1847, 1847, 89: 1847, 474: 1847, 481: 1847, 488: 1847, 497: 1847}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4882, 2762, 2763, 2761}, + {2558, 2558, 2558, 2558, 2558, 2558, 9: 2558, 507: 2558}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 492: 1918, 583: 4975, 805: 5089}, + {2561, 2561, 2561, 2561, 2561, 2561, 9: 2561, 507: 2561}, + {1918, 1918, 1918, 1918, 1918, 1918, 9: 1918, 98: 1918, 152: 1918, 492: 1918, 507: 1918, 583: 4975, 805: 5043, 835: 1918}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 5034}, // 2345 - {1848, 1848, 1848, 1848, 1848, 1848, 1848, 9: 1848, 19: 1848, 49: 1848, 83: 1848, 1848, 1848, 1848, 1848, 89: 1848, 474: 1848, 481: 1848, 488: 1848, 497: 1848}, - {508: 2736, 733: 2735, 741: 4884}, - {1850, 1850, 1850, 1850, 1850, 1850, 1850, 9: 1850, 19: 1850, 49: 1850, 83: 1850, 1850, 1850, 1850, 1850, 89: 1850, 474: 1850, 481: 1850, 488: 1850, 497: 1850}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 1854, 481: 1854, 661: 4856, 2762, 2763, 2761, 878: 4857, 942: 4886}, - {473: 4887}, + {600: 4536, 607: 4967, 613: 4962, 662: 4965, 668: 4537, 696: 4966, 4963, 850: 4964, 1230: 4968}, + {600: 5028}, + {2: 2489, 2489, 2489, 2489, 2489, 2489, 2489, 10: 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 59: 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 492: 2489, 600: 4536, 668: 4537, 850: 4984, 1097: 5022}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 492: 1918, 501: 1918, 583: 4975, 805: 5016}, + {2: 2489, 2489, 2489, 2489, 2489, 2489, 2489, 10: 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 59: 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 492: 2489, 501: 2489, 600: 4536, 668: 4537, 850: 4984, 1097: 4985}, // 2350 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4616, 836: 4888}, - {9: 4627, 49: 4889}, - {1852, 1852, 1852, 1852, 1852, 1852, 1852, 9: 1852, 19: 1852, 49: 1852, 84: 1852, 1852, 1852, 1852, 89: 1852, 474: 1852, 481: 1852, 488: 1852, 880: 4890}, - {2268, 2268, 2268, 2268, 2268, 2268, 4873, 9: 2268, 19: 4870, 49: 2268, 84: 4877, 4723, 4430, 4724, 89: 4429, 474: 4872, 481: 4876, 488: 2268, 856: 4874, 858: 4871, 869: 4875, 879: 4869}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 1854, 661: 4848, 2762, 2763, 2761, 878: 4892}, + {600: 4973}, + {492: 4969}, + {474, 474, 474, 474, 474, 474, 9: 474, 58: 474, 507: 474}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4970}, + {58: 4971, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, // 2355 - {473: 4893}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4616, 836: 4894}, - {9: 4627, 49: 4895}, - {1852, 1852, 1852, 1852, 1852, 1852, 1852, 9: 1852, 19: 1852, 49: 1852, 84: 1852, 1852, 1852, 1852, 89: 1852, 474: 1852, 481: 1852, 488: 1852, 880: 4896}, - {2269, 2269, 2269, 2269, 2269, 2269, 4873, 9: 2269, 19: 4870, 49: 2269, 84: 4877, 4723, 4430, 4724, 89: 4429, 474: 4872, 481: 4876, 488: 2269, 856: 4874, 858: 4871, 869: 4875, 879: 4869}, + {2377, 2377, 2377, 2377, 2377, 2377, 9: 2377, 58: 2377, 163: 4559, 495: 4198, 497: 4197, 507: 2377, 834: 4560, 960: 4810, 1068: 4972}, + {2332, 2332, 2332, 2332, 2332, 2332, 9: 2332, 58: 2332, 507: 2332}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 492: 1918, 583: 4975, 805: 4974}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 1914, 685: 4979, 2850, 688: 2851, 2849, 902: 4978}, + {495: 4198, 497: 4197, 834: 4976}, // 2360 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 1854, 481: 1854, 661: 4856, 2762, 2763, 2761, 878: 4857, 942: 4898}, - {473: 4899}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4616, 836: 4900}, - {9: 4627, 49: 4901}, - {1852, 1852, 1852, 1852, 1852, 1852, 1852, 9: 1852, 19: 1852, 49: 1852, 84: 1852, 1852, 1852, 1852, 89: 1852, 474: 1852, 481: 1852, 488: 1852, 880: 4902}, + {603: 4977}, + {1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 59: 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 1917, 492: 1917, 1917, 501: 1917, 507: 1917, 590: 1917, 835: 1917}, + {492: 4980}, + {492: 1913}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4742, 859: 4981}, // 2365 - {2270, 2270, 2270, 2270, 2270, 2270, 4873, 9: 2270, 19: 4870, 49: 2270, 84: 4877, 4723, 4430, 4724, 89: 4429, 474: 4872, 481: 4876, 488: 2270, 856: 4874, 858: 4871, 869: 4875, 879: 4869}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4904, 2762, 2763, 2761}, - {233: 4906, 241: 4908, 244: 4907, 1140: 4905}, - {473: 4909}, - {49: 2219, 473: 2219}, + {9: 4753, 58: 4982}, + {664: 4737, 935: 4983}, + {2333, 2333, 2333, 2333, 2333, 2333, 9: 2333, 58: 2333, 507: 2333}, + {2: 2488, 2488, 2488, 2488, 2488, 2488, 2488, 10: 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 59: 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 2488, 492: 2488, 501: 2488}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 1914, 501: 1914, 685: 4987, 2850, 688: 2851, 2849, 902: 4988, 968: 4986}, // 2370 - {49: 2218, 473: 2218}, - {49: 2217, 473: 2217}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 4910}, - {9: 4146, 49: 4911}, - {2487, 2487, 2487, 2487, 2487, 2487, 9: 2487, 488: 2487}, + {492: 4996}, + {91: 4994, 492: 1913, 501: 1913}, + {492: 1904, 501: 4989}, + {157: 4992, 190: 4991, 207: 4993, 930: 4990}, + {492: 1903}, // 2375 - {569, 569, 569, 569, 569, 569, 9: 569, 91: 569, 136: 4750, 473: 569, 488: 569, 811: 4749, 829: 4913}, - {2142, 2142, 2142, 2142, 2142, 2142, 9: 2142, 91: 4915, 473: 4916, 488: 2142, 1098: 4914}, - {2490, 2490, 2490, 2490, 2490, 2490, 9: 2490, 488: 2490}, - {508: 2736, 733: 4957}, - {488: 4919, 952: 4918, 1097: 4917}, + {1897, 1897, 1897, 1897, 1897, 1897, 1897, 9: 1897, 19: 1897, 58: 1897, 90: 1897, 1897, 1897, 1897, 1897, 96: 1897, 491: 1897, 1897, 494: 1897, 501: 1897, 507: 1897, 518: 1897}, + {1896, 1896, 1896, 1896, 1896, 1896, 1896, 9: 1896, 19: 1896, 58: 1896, 90: 1896, 1896, 1896, 1896, 1896, 96: 1896, 491: 1896, 1896, 494: 1896, 501: 1896, 507: 1896, 518: 1896}, + {1895, 1895, 1895, 1895, 1895, 1895, 1895, 9: 1895, 19: 1895, 58: 1895, 90: 1895, 1895, 1895, 1895, 1895, 96: 1895, 491: 1895, 1895, 494: 1895, 501: 1895, 507: 1895, 518: 1895}, + {157: 4992, 190: 4991, 207: 4993, 930: 4995}, + {492: 1902}, // 2380 - {9: 4955, 49: 4954}, - {9: 2140, 49: 2140}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4920, 2762, 2763, 2761}, - {6: 2119, 2119, 9: 2119, 18: 2119, 20: 2119, 22: 2119, 2119, 2119, 2119, 2119, 2119, 49: 2119, 148: 4925, 348: 4924, 473: 2119, 479: 4923, 495: 4922, 649: 2119, 1275: 4921}, - {6: 2132, 2132, 9: 2132, 18: 2132, 20: 2132, 22: 2132, 2132, 2132, 2132, 2132, 2132, 49: 2132, 473: 2132, 649: 2132, 951: 4941}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4742, 859: 4997}, + {9: 4753, 58: 4998}, + {1912, 1912, 1912, 1912, 1912, 1912, 1912, 9: 1912, 19: 1912, 58: 1912, 91: 1912, 1912, 1912, 1912, 96: 1912, 494: 1912, 501: 1912, 507: 1912, 904: 4999}, + {2334, 2334, 2334, 2334, 2334, 2334, 5004, 9: 2334, 19: 5001, 58: 2334, 91: 5008, 4854, 4556, 4855, 96: 4555, 494: 5003, 501: 5007, 507: 2334, 879: 5005, 881: 5002, 892: 5006, 903: 5000}, + {1911, 1911, 1911, 1911, 1911, 1911, 1911, 9: 1911, 19: 1911, 58: 1911, 90: 1911, 1911, 1911, 1911, 1911, 96: 1911, 494: 1911, 501: 1911, 507: 1911, 518: 1911}, // 2385 - {152: 4926, 544: 4927}, - {6: 2116, 2116, 9: 2116, 18: 2116, 20: 2116, 22: 2116, 2116, 2116, 2116, 2116, 2116, 49: 2116, 473: 2116, 649: 2116}, - {6: 2114, 2114, 9: 2114, 18: 2114, 20: 2114, 22: 2114, 2114, 2114, 2114, 2114, 2114, 49: 2114, 473: 2114, 649: 2114}, - {6: 2113, 2113, 9: 2113, 18: 2113, 20: 2113, 22: 2113, 2113, 2113, 2113, 2113, 2113, 49: 2113, 473: 2113, 649: 2113}, - {157: 4936}, + {517: 4397, 525: 2109, 758: 5014}, + {1909, 1909, 1909, 1909, 1909, 1909, 1909, 9: 1909, 19: 1909, 58: 1909, 90: 1909, 1909, 1909, 1909, 1909, 96: 1909, 494: 1909, 501: 1909, 507: 1909, 518: 1909}, + {382: 5012}, + {493: 5011}, + {1906, 1906, 1906, 1906, 1906, 1906, 1906, 9: 1906, 19: 1906, 58: 1906, 90: 1906, 1906, 1906, 1906, 1906, 96: 1906, 494: 1906, 501: 1906, 507: 1906, 518: 1906}, // 2390 - {473: 4928}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 655: 4930, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 4931, 945: 4932, 1079: 4929}, - {9: 4934, 49: 4933}, - {9: 1934, 49: 1934}, - {9: 1933, 49: 1933, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, + {1905, 1905, 1905, 1905, 1905, 1905, 1905, 9: 1905, 19: 1905, 58: 1905, 90: 1905, 1905, 1905, 1905, 1905, 96: 1905, 494: 1905, 501: 1905, 507: 1905, 518: 1905}, + {157: 4992, 190: 4991, 207: 4993, 930: 5010}, + {157: 4992, 190: 4991, 207: 4993, 930: 5009}, + {1898, 1898, 1898, 1898, 1898, 1898, 1898, 9: 1898, 19: 1898, 58: 1898, 90: 1898, 1898, 1898, 1898, 1898, 96: 1898, 491: 1898, 494: 1898, 501: 1898, 507: 1898, 518: 1898}, + {1899, 1899, 1899, 1899, 1899, 1899, 1899, 9: 1899, 19: 1899, 58: 1899, 90: 1899, 1899, 1899, 1899, 1899, 96: 1899, 491: 1899, 494: 1899, 501: 1899, 507: 1899, 518: 1899}, // 2395 - {9: 1921, 49: 1921}, - {6: 2115, 2115, 9: 2115, 18: 2115, 20: 2115, 22: 2115, 2115, 2115, 2115, 2115, 2115, 49: 2115, 473: 2115, 649: 2115}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 655: 4930, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 4931, 945: 4935}, - {9: 1920, 49: 1920}, - {473: 4938, 655: 4937}, + {1907, 1907, 1907, 1907, 1907, 1907, 1907, 9: 1907, 19: 1907, 58: 1907, 90: 1907, 1907, 1907, 1907, 1907, 96: 1907, 494: 1907, 501: 1907, 507: 1907, 518: 1907}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5013, 2850, 688: 2851, 2849}, + {1908, 1908, 1908, 1908, 1908, 1908, 1908, 9: 1908, 19: 1908, 58: 1908, 90: 1908, 1908, 1908, 1908, 1908, 96: 1908, 494: 1908, 501: 1908, 507: 1908, 518: 1908}, + {525: 2824, 755: 2823, 762: 5015}, + {1910, 1910, 1910, 1910, 1910, 1910, 1910, 9: 1910, 19: 1910, 58: 1910, 90: 1910, 1910, 1910, 1910, 1910, 96: 1910, 494: 1910, 501: 1910, 507: 1910, 518: 1910}, // 2400 - {6: 2118, 2118, 9: 2118, 18: 2118, 20: 2118, 22: 2118, 2118, 2118, 2118, 2118, 2118, 49: 2118, 473: 2118, 649: 2118}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 655: 4930, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 4931, 945: 4932, 1079: 4939}, - {9: 4934, 49: 4940}, - {6: 2117, 2117, 9: 2117, 18: 2117, 20: 2117, 22: 2117, 2117, 2117, 2117, 2117, 2117, 49: 2117, 473: 2117, 649: 2117}, - {6: 4241, 4945, 9: 2137, 18: 4197, 20: 4249, 22: 4242, 4245, 4244, 4247, 4248, 4250, 49: 2137, 473: 4943, 649: 4246, 781: 4251, 813: 4944, 1317: 4942}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 1914, 501: 1914, 685: 4987, 2850, 688: 2851, 2849, 902: 4988, 968: 5017}, + {492: 5018}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4742, 859: 5019}, + {9: 4753, 58: 5020}, + {1912, 1912, 1912, 1912, 1912, 1912, 1912, 9: 1912, 19: 1912, 58: 1912, 91: 1912, 1912, 1912, 1912, 96: 1912, 494: 1912, 501: 1912, 507: 1912, 904: 5021}, // 2405 - {9: 2138, 49: 2138}, - {90: 4948, 1142: 4947, 1316: 4946}, - {2131, 2131, 6: 2131, 2131, 9: 2131, 18: 2131, 20: 2131, 22: 2131, 2131, 2131, 2131, 2131, 2131, 49: 2131, 473: 2131, 649: 2131}, - {22: 4381}, - {9: 4952, 49: 4951}, + {2335, 2335, 2335, 2335, 2335, 2335, 5004, 9: 2335, 19: 5001, 58: 2335, 91: 5008, 4854, 4556, 4855, 96: 4555, 494: 5003, 501: 5007, 507: 2335, 879: 5005, 881: 5002, 892: 5006, 903: 5000}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 1914, 685: 4979, 2850, 688: 2851, 2849, 902: 5023}, + {492: 5024}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4742, 859: 5025}, + {9: 4753, 58: 5026}, // 2410 - {9: 2135, 49: 2135}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4949, 2762, 2763, 2761}, - {6: 2132, 2132, 9: 2132, 18: 2132, 20: 2132, 22: 2132, 2132, 2132, 2132, 2132, 2132, 49: 2132, 649: 2132, 951: 4950}, - {6: 4241, 4945, 9: 2133, 18: 4197, 20: 4249, 22: 4242, 4245, 4244, 4247, 4248, 4250, 49: 2133, 649: 4246, 781: 4251, 813: 4944}, - {9: 2136, 49: 2136}, + {1912, 1912, 1912, 1912, 1912, 1912, 1912, 9: 1912, 19: 1912, 58: 1912, 91: 1912, 1912, 1912, 1912, 96: 1912, 494: 1912, 501: 1912, 507: 1912, 904: 5027}, + {2336, 2336, 2336, 2336, 2336, 2336, 5004, 9: 2336, 19: 5001, 58: 2336, 91: 5008, 4854, 4556, 4855, 96: 4555, 494: 5003, 501: 5007, 507: 2336, 879: 5005, 881: 5002, 892: 5006, 903: 5000}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 1914, 501: 1914, 685: 4987, 2850, 688: 2851, 2849, 902: 4988, 968: 5029}, + {492: 5030}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4742, 859: 5031}, // 2415 - {90: 4948, 1142: 4953}, - {9: 2134, 49: 2134}, - {2141, 2141, 2141, 2141, 2141, 2141, 9: 2141, 472: 2141, 2141, 2141, 478: 2141, 488: 2141, 2141, 495: 2141, 504: 2141, 569: 2141, 646: 2141}, - {488: 4919, 952: 4956}, - {9: 2139, 49: 2139}, + {9: 4753, 58: 5032}, + {1912, 1912, 1912, 1912, 1912, 1912, 1912, 9: 1912, 19: 1912, 58: 1912, 91: 1912, 1912, 1912, 1912, 96: 1912, 494: 1912, 501: 1912, 507: 1912, 904: 5033}, + {2337, 2337, 2337, 2337, 2337, 2337, 5004, 9: 2337, 19: 5001, 58: 2337, 91: 5008, 4854, 4556, 4855, 96: 4555, 494: 5003, 501: 5007, 507: 2337, 879: 5005, 881: 5002, 892: 5006, 903: 5000}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5035, 2850, 688: 2851, 2849}, + {249: 5037, 257: 5039, 259: 5038, 1172: 5036}, // 2420 - {2489, 2489, 2489, 2489, 2489, 2489, 9: 2489, 488: 2489}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4960, 661: 4143, 2762, 2763, 2761, 744: 4456, 848: 4959}, - {2415, 2415, 2415, 2415, 2415, 2415, 9: 2415, 4731, 4732, 488: 2415, 929: 4968}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 581: 2406, 590: 2406, 2406, 642: 2406, 4589, 649: 2406, 661: 4143, 2762, 2763, 2761, 675: 2406, 2406, 744: 4456, 833: 4830, 848: 4962, 903: 4963, 968: 4964, 1145: 4961}, - {9: 4966, 49: 4965}, + {492: 5040}, + {58: 2282, 492: 2282}, + {58: 2281, 492: 2281}, + {58: 2280, 492: 2280}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 5041}, // 2425 - {9: 440, 49: 440}, - {9: 439, 49: 439}, - {9: 438, 49: 438}, - {2492, 2492, 2492, 2492, 2492, 2492, 9: 2492, 488: 2492}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 581: 2406, 590: 2406, 2406, 642: 2406, 4589, 649: 2406, 661: 4143, 2762, 2763, 2761, 675: 2406, 2406, 744: 4456, 833: 4830, 848: 4962, 903: 4963, 968: 4967}, + {9: 4259, 58: 5042}, + {2557, 2557, 2557, 2557, 2557, 2557, 9: 2557, 507: 2557}, + {606, 606, 606, 606, 606, 606, 9: 606, 98: 606, 152: 4881, 492: 606, 507: 606, 835: 4880, 851: 5044}, + {2204, 2204, 2204, 2204, 2204, 2204, 9: 2204, 98: 5046, 492: 5047, 507: 2204, 1128: 5045}, + {2560, 2560, 2560, 2560, 2560, 2560, 9: 2560, 507: 2560}, // 2430 - {9: 437, 49: 437}, - {2493, 2493, 2493, 2493, 2493, 2493, 9: 2493, 488: 2493}, - {16: 3836, 505: 3837, 647: 3835, 773: 4970}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 479: 4972, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 4971}, - {267, 267, 267, 267, 267, 267, 9: 267, 484: 4974, 488: 267, 1089: 4976}, + {525: 2824, 755: 5088}, + {507: 5050, 978: 5049, 1127: 5048}, + {9: 5086, 58: 5085}, + {9: 2202, 58: 2202}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5051, 2850, 688: 2851, 2849}, // 2435 - {267, 267, 267, 267, 267, 267, 9: 267, 484: 4974, 488: 267, 1089: 4973}, - {2494, 2494, 2494, 2494, 2494, 2494, 9: 2494, 488: 2494}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3489, 661: 3491, 2762, 2763, 2761, 738: 3488, 872: 4975}, - {266, 266, 266, 266, 266, 266, 9: 266, 488: 266}, - {2495, 2495, 2495, 2495, 2495, 2495, 9: 2495, 488: 2495}, + {6: 2181, 2181, 9: 2181, 18: 2181, 20: 2181, 22: 2181, 2181, 2181, 2181, 2181, 2181, 58: 2181, 162: 5056, 227: 5055, 492: 2181, 496: 5054, 515: 5053, 668: 2181, 1309: 5052}, + {6: 2194, 2194, 9: 2194, 18: 2194, 20: 2194, 22: 2194, 2194, 2194, 2194, 2194, 2194, 58: 2194, 492: 2194, 668: 2194, 977: 5072}, + {165: 5057, 564: 5058}, + {6: 2178, 2178, 9: 2178, 18: 2178, 20: 2178, 22: 2178, 2178, 2178, 2178, 2178, 2178, 58: 2178, 492: 2178, 668: 2178}, + {6: 2176, 2176, 9: 2176, 18: 2176, 20: 2176, 22: 2176, 2176, 2176, 2176, 2176, 2176, 58: 2176, 492: 2176, 668: 2176}, // 2440 - {191: 4978}, - {508: 2736, 733: 2735, 741: 4979}, - {2499, 2499, 2499, 2499, 2499, 2499, 9: 2499, 184: 4980, 488: 2499, 1077: 4981}, - {267: 4982}, - {2496, 2496, 2496, 2496, 2496, 2496, 9: 2496, 488: 2496}, + {6: 2175, 2175, 9: 2175, 18: 2175, 20: 2175, 22: 2175, 2175, 2175, 2175, 2175, 2175, 58: 2175, 492: 2175, 668: 2175}, + {170: 5067}, + {492: 5059}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 675: 5061, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5062, 971: 5063, 1109: 5060}, + {9: 5065, 58: 5064}, // 2445 - {475: 4984, 1313: 4983}, - {2498, 2498, 2498, 2498, 2498, 2498, 9: 4985, 16: 2498, 18: 2498, 21: 2498, 479: 2498, 484: 2498, 488: 2498, 505: 2498, 2498, 647: 2498}, - {265, 265, 265, 265, 265, 265, 9: 265, 16: 265, 18: 265, 21: 265, 479: 265, 484: 265, 488: 265, 505: 265, 265, 647: 265}, - {475: 4986}, - {264, 264, 264, 264, 264, 264, 9: 264, 16: 264, 18: 264, 21: 264, 479: 264, 484: 264, 488: 264, 505: 264, 264, 647: 264}, + {9: 1995, 58: 1995}, + {9: 1994, 58: 1994, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {9: 1982, 58: 1982}, + {6: 2177, 2177, 9: 2177, 18: 2177, 20: 2177, 22: 2177, 2177, 2177, 2177, 2177, 2177, 58: 2177, 492: 2177, 668: 2177}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 675: 5061, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5062, 971: 5066}, // 2450 - {8: 399, 29: 399}, - {393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 15: 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 472: 393, 393, 393, 478: 393, 393, 393, 484: 393, 488: 393, 393, 495: 393, 503: 393, 393, 393, 569: 393, 646: 393, 393, 649: 393}, - {6: 4241, 4243, 400, 15: 4260, 2176, 4258, 4197, 4262, 4249, 4278, 4242, 4245, 4244, 4247, 4248, 4250, 4257, 400, 4268, 4269, 4255, 4256, 4261, 4263, 4275, 4274, 4280, 4276, 4273, 4266, 4271, 4272, 4265, 4267, 4270, 4259, 479: 4240, 4277, 484: 2176, 503: 4987, 505: 2176, 647: 2176, 649: 4246, 781: 4251, 792: 4253, 813: 4252, 835: 4254, 838: 4264, 842: 4990}, - {392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 15: 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 472: 392, 392, 392, 478: 392, 392, 392, 484: 392, 488: 392, 392, 495: 392, 503: 392, 392, 392, 569: 392, 646: 392, 392, 649: 392}, - {475: 4993, 479: 4992}, + {9: 1981, 58: 1981}, + {492: 5069, 675: 5068}, + {6: 2180, 2180, 9: 2180, 18: 2180, 20: 2180, 22: 2180, 2180, 2180, 2180, 2180, 2180, 58: 2180, 492: 2180, 668: 2180}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 675: 5061, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5062, 971: 5063, 1109: 5070}, + {9: 5065, 58: 5071}, // 2455 - {2508, 2508, 2508, 2508, 2508, 2508, 9: 2508, 488: 2508}, - {2507, 2507, 2507, 2507, 2507, 2507, 9: 2507, 488: 2507}, - {475: 4996, 479: 4995}, - {2510, 2510, 2510, 2510, 2510, 2510, 9: 2510, 488: 2510}, - {2509, 2509, 2509, 2509, 2509, 2509, 9: 2509, 488: 2509}, + {6: 2179, 2179, 9: 2179, 18: 2179, 20: 2179, 22: 2179, 2179, 2179, 2179, 2179, 2179, 58: 2179, 492: 2179, 668: 2179}, + {6: 4354, 5076, 9: 2199, 18: 4310, 20: 4362, 22: 4355, 4358, 4357, 4360, 4361, 4363, 58: 2199, 492: 5074, 668: 4359, 803: 4364, 837: 5075, 1352: 5073}, + {9: 2200, 58: 2200}, + {97: 5079, 1174: 5078, 1351: 5077}, + {2193, 2193, 6: 2193, 2193, 9: 2193, 18: 2193, 20: 2193, 22: 2193, 2193, 2193, 2193, 2193, 2193, 58: 2193, 492: 2193, 668: 2193}, // 2460 - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 479: 2047, 499: 4281, 506: 4999, 736: 4998}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5001, 479: 5003, 661: 5004, 2762, 2763, 2761, 886: 5002}, - {479: 5000}, - {2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 15: 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 2511, 49: 2511, 472: 2511, 2511, 2511, 478: 2511, 2511, 2511, 484: 2511, 488: 2511, 2511, 495: 2511, 503: 2511, 2511, 2511, 2511, 569: 2511, 646: 2511, 2511, 649: 2511}, - {2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 15: 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 49: 2514, 472: 2514, 2514, 2514, 478: 2514, 2514, 2514, 484: 2514, 488: 2514, 2514, 495: 2514, 503: 2514, 2514, 2514, 2514, 569: 2514, 646: 2514, 2514, 649: 2514}, + {22: 4507}, + {9: 5083, 58: 5082}, + {9: 2197, 58: 2197}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5080, 2850, 688: 2851, 2849}, + {6: 2194, 2194, 9: 2194, 18: 2194, 20: 2194, 22: 2194, 2194, 2194, 2194, 2194, 2194, 58: 2194, 668: 2194, 977: 5081}, // 2465 - {2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 15: 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 2513, 49: 2513, 472: 2513, 2513, 2513, 478: 2513, 2513, 2513, 484: 2513, 488: 2513, 2513, 495: 2513, 503: 2513, 2513, 2513, 2513, 569: 2513, 646: 2513, 2513, 649: 2513}, - {2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 15: 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 2512, 49: 2512, 472: 2512, 2512, 2512, 478: 2512, 2512, 2512, 484: 2512, 488: 2512, 2512, 495: 2512, 503: 2512, 2512, 2512, 2512, 569: 2512, 646: 2512, 2512, 649: 2512}, - {2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 15: 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 49: 2192, 88: 2192, 92: 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 472: 2192, 2192, 2192, 478: 2192, 2192, 2192, 484: 2192, 488: 2192, 2192, 495: 2192, 503: 2192, 2192, 2192, 2192, 569: 2192, 646: 2192, 2192, 649: 2192}, - {191: 5010}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 5007}, + {6: 4354, 5076, 9: 2195, 18: 4310, 20: 4362, 22: 4355, 4358, 4357, 4360, 4361, 4363, 58: 2195, 668: 4359, 803: 4364, 837: 5075}, + {9: 2198, 58: 2198}, + {97: 5079, 1174: 5084}, + {9: 2196, 58: 2196}, + {2203, 2203, 2203, 2203, 2203, 2203, 9: 2203, 491: 2203, 2203, 494: 2203, 498: 2203, 507: 2203, 2203, 515: 2203, 522: 2203, 588: 2203, 665: 2203}, // 2470 - {2530, 2530, 9: 4755, 168: 5008}, - {191: 5009}, - {2529, 2529}, - {2531, 2531}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 5012}, + {507: 5050, 978: 5087}, + {9: 2201, 58: 2201}, + {2559, 2559, 2559, 2559, 2559, 2559, 9: 2559, 507: 2559}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5091, 685: 4256, 2850, 688: 2851, 2849, 766: 4582, 872: 5090}, + {2485, 2485, 2485, 2485, 2485, 2485, 9: 2485, 4862, 4863, 507: 2485, 954: 5099}, // 2475 - {2366, 2366, 9: 4755, 474: 5015, 649: 5014, 804: 5013}, - {2534, 2534}, - {908, 908, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 908, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 474: 908, 591: 5032, 661: 5031, 2762, 2763, 2761, 857: 5030}, - {508: 5020, 573: 3425, 3424, 733: 5018, 820: 5019, 991: 5017, 1173: 5016}, - {2365, 2365, 9: 5028}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 600: 2476, 607: 2476, 613: 2476, 662: 2476, 4715, 668: 2476, 685: 4256, 2850, 688: 2851, 2849, 696: 2476, 2476, 766: 4582, 855: 4961, 872: 5093, 928: 5094, 993: 5095, 1177: 5092}, + {9: 5097, 58: 5096}, + {9: 471, 58: 471}, + {9: 470, 58: 470}, + {9: 469, 58: 469}, // 2480 - {2364, 2364, 9: 2364}, - {232: 5022, 236: 5024, 283: 5025, 302: 5023}, - {195: 5021}, - {195: 2222, 232: 1973, 236: 1973, 283: 1973, 302: 1973}, - {2357, 2357, 9: 2357}, + {2562, 2562, 2562, 2562, 2562, 2562, 9: 2562, 507: 2562}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 600: 2476, 607: 2476, 613: 2476, 662: 2476, 4715, 668: 2476, 685: 4256, 2850, 688: 2851, 2849, 696: 2476, 2476, 766: 4582, 855: 4961, 872: 5093, 928: 5094, 993: 5098}, + {9: 468, 58: 468}, + {2563, 2563, 2563, 2563, 2563, 2563, 9: 2563, 507: 2563}, + {16: 3943, 514: 3944, 667: 3942, 798: 5101}, // 2485 - {2362, 2362, 9: 2362}, - {2361, 2361, 9: 2361}, - {333: 5026, 406: 5027}, - {2358, 2358, 9: 2358}, - {2360, 2360, 9: 2360}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 496: 5103, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 5102}, + {295, 295, 295, 295, 295, 295, 9: 295, 499: 5105, 507: 295, 1119: 5107}, + {295, 295, 295, 295, 295, 295, 9: 295, 499: 5105, 507: 295, 1119: 5104}, + {2564, 2564, 2564, 2564, 2564, 2564, 9: 2564, 507: 2564}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3596, 685: 3598, 2850, 688: 2851, 2849, 760: 3595, 895: 5106}, // 2490 - {2359, 2359, 9: 2359}, - {508: 5020, 573: 3425, 3424, 733: 5018, 820: 5019, 991: 5029}, - {2363, 2363, 9: 2363}, - {2366, 2366, 9: 5034, 474: 5015, 804: 5033}, - {907, 907, 9: 907, 49: 907, 474: 907}, + {294, 294, 294, 294, 294, 294, 9: 294, 507: 294}, + {2565, 2565, 2565, 2565, 2565, 2565, 9: 2565, 507: 2565}, + {205: 5109}, + {525: 2824, 755: 2823, 762: 5110}, + {2569, 2569, 2569, 2569, 2569, 2569, 9: 2569, 197: 5111, 507: 2569, 1106: 5112}, // 2495 - {905, 905, 9: 905, 49: 905, 474: 905}, - {2533, 2533}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 591: 5036, 661: 5035, 2762, 2763, 2761}, - {906, 906, 9: 906, 49: 906, 474: 906}, - {904, 904, 9: 904, 49: 904, 474: 904}, + {282: 5113}, + {2566, 2566, 2566, 2566, 2566, 2566, 9: 2566, 507: 2566}, + {493: 5115, 1348: 5114}, + {2568, 2568, 2568, 2568, 2568, 2568, 9: 5116, 16: 2568, 18: 2568, 21: 2568, 496: 2568, 499: 2568, 507: 2568, 514: 2568, 526: 2568, 667: 2568}, + {293, 293, 293, 293, 293, 293, 9: 293, 16: 293, 18: 293, 21: 293, 496: 293, 499: 293, 507: 293, 514: 293, 526: 293, 667: 293}, // 2500 - {2535, 2535}, - {2506, 2506}, - {370: 5149}, - {488: 5141}, - {655: 5134}, + {493: 5117}, + {292, 292, 292, 292, 292, 292, 9: 292, 16: 292, 18: 292, 21: 292, 496: 292, 499: 292, 507: 292, 514: 292, 526: 292, 667: 292}, + {8: 427, 29: 427}, + {421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 15: 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 491: 421, 421, 494: 421, 496: 421, 498: 421, 421, 421, 507: 421, 421, 514: 421, 421, 522: 421, 524: 421, 588: 421, 665: 421, 667: 421, 421}, + {6: 4354, 4356, 428, 15: 4373, 2238, 4371, 4310, 4375, 4362, 4391, 4355, 4358, 4357, 4360, 4361, 4363, 4370, 428, 4381, 4382, 4392, 4368, 4369, 4374, 4376, 4388, 4387, 4396, 4389, 4386, 4379, 4384, 4385, 4378, 4380, 4383, 4372, 4393, 4394, 496: 4353, 499: 2238, 4390, 514: 2238, 524: 5118, 667: 2238, 4359, 803: 4364, 816: 4366, 837: 4365, 858: 4367, 862: 4377, 866: 5121}, // 2505 - {10: 5127}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 660: 5045, 5044, 2762, 2763, 2761}, - {2132, 2132, 6: 2132, 2132, 18: 2132, 20: 2132, 22: 2132, 2132, 2132, 2132, 2132, 2132, 203: 4198, 649: 2132, 926: 5125, 951: 5126}, - {143: 2150, 357: 5050, 395: 5051, 527: 5049, 581: 2150, 1072: 5052, 5047, 1143: 5048, 1277: 5046}, - {2144, 2144, 90: 2144, 5115, 472: 2144, 2144, 2144, 478: 2144, 489: 2144, 495: 2144, 504: 2144, 569: 2144, 646: 2144, 1278: 5114}, + {420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 15: 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 491: 420, 420, 494: 420, 496: 420, 498: 420, 420, 420, 507: 420, 420, 514: 420, 420, 522: 420, 524: 420, 588: 420, 665: 420, 667: 420, 420}, + {493: 5124, 496: 5123}, + {2579, 2579, 2579, 2579, 2579, 2579, 9: 2579, 507: 2579}, + {2578, 2578, 2578, 2578, 2578, 2578, 9: 2578, 507: 2578}, + {493: 5127, 496: 5126}, // 2510 - {143: 5102, 581: 5101}, - {2168, 2168, 90: 2168, 2168, 472: 2168, 2168, 2168, 478: 2168, 489: 2168, 495: 2168, 504: 2168, 569: 2168, 646: 2168}, - {102: 3944, 111: 3943, 473: 5065, 834: 5066}, - {102: 3944, 111: 3943, 473: 5058, 834: 5059}, - {2161, 2161, 90: 2161, 2161, 472: 2161, 2161, 2161, 478: 2161, 489: 2161, 493: 5054, 495: 2161, 504: 2161, 569: 2161, 578: 5053, 646: 2161}, + {2581, 2581, 2581, 2581, 2581, 2581, 9: 2581, 507: 2581}, + {2580, 2580, 2580, 2580, 2580, 2580, 9: 2580, 507: 2580}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 496: 2109, 517: 4397, 526: 5130, 758: 5129}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5132, 496: 5134, 685: 5135, 2850, 688: 2851, 2849, 909: 5133}, + {496: 5131}, // 2515 - {143: 2149, 581: 2149}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5056}, - {508: 2736, 733: 2735, 741: 5055}, - {2162, 2162, 90: 2162, 2162, 472: 2162, 2162, 2162, 478: 2162, 489: 2162, 495: 2162, 504: 2162, 569: 2162, 646: 2162}, - {104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 507: 3345, 509: 3343, 3344, 3342, 3340, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 734: 3341, 3339, 796: 3444, 815: 5057}, + {2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 15: 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 2582, 58: 2582, 491: 2582, 2582, 494: 2582, 496: 2582, 498: 2582, 2582, 2582, 507: 2582, 2582, 514: 2582, 2582, 522: 2582, 524: 2582, 526: 2582, 588: 2582, 665: 2582, 667: 2582, 2582}, + {2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 15: 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 2585, 58: 2585, 491: 2585, 2585, 494: 2585, 496: 2585, 498: 2585, 2585, 2585, 507: 2585, 2585, 514: 2585, 2585, 522: 2585, 524: 2585, 526: 2585, 588: 2585, 665: 2585, 667: 2585, 2585}, + {2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 15: 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 2584, 58: 2584, 491: 2584, 2584, 494: 2584, 496: 2584, 498: 2584, 2584, 2584, 507: 2584, 2584, 514: 2584, 2584, 522: 2584, 524: 2584, 526: 2584, 588: 2584, 665: 2584, 667: 2584, 2584}, + {2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 15: 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 2583, 58: 2583, 491: 2583, 2583, 494: 2583, 496: 2583, 498: 2583, 2583, 2583, 507: 2583, 2583, 514: 2583, 2583, 522: 2583, 524: 2583, 526: 2583, 588: 2583, 665: 2583, 667: 2583, 2583}, + {2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 15: 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 58: 2255, 95: 2255, 99: 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 2255, 491: 2255, 2255, 494: 2255, 496: 2255, 498: 2255, 2255, 2255, 507: 2255, 2255, 514: 2255, 2255, 522: 2255, 524: 2255, 526: 2255, 588: 2255, 665: 2255, 667: 2255, 2255}, // 2520 - {2163, 2163, 90: 2163, 2163, 472: 2163, 2163, 2163, 478: 2163, 489: 2163, 495: 2163, 504: 2163, 569: 2163, 646: 2163}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5063}, - {473: 5060}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 5061}, - {9: 4146, 49: 5062}, + {205: 5141}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 5138}, + {2609, 2609, 9: 4886, 182: 5139}, + {205: 5140}, + {2608, 2608}, // 2525 - {2164, 2164, 90: 2164, 2164, 472: 2164, 2164, 2164, 478: 2164, 489: 2164, 495: 2164, 504: 2164, 569: 2164, 646: 2164}, - {49: 5064, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {2165, 2165, 90: 2165, 2165, 472: 2165, 2165, 2165, 478: 2165, 489: 2165, 495: 2165, 504: 2165, 569: 2165, 646: 2165}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5098}, - {473: 5067}, + {2610, 2610}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 5143}, + {2433, 2433, 9: 4886, 494: 5146, 668: 5145, 826: 5144}, + {2613, 2613}, + {947, 947, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 947, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 494: 947, 613: 5163, 685: 5162, 2850, 688: 2851, 2849, 880: 5161}, // 2530 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 5068}, - {9: 4146, 49: 5069}, - {2160, 2160, 90: 2160, 2160, 472: 2160, 2160, 2160, 478: 2160, 489: 2160, 495: 2160, 504: 2160, 569: 2160, 578: 5071, 646: 2160, 1099: 5070}, - {2166, 2166, 90: 2166, 2166, 472: 2166, 2166, 2166, 478: 2166, 489: 2166, 495: 2166, 504: 2166, 569: 2166, 646: 2166}, - {473: 5072}, + {525: 5151, 593: 3532, 3531, 755: 5149, 842: 5150, 1017: 5148, 1206: 5147}, + {2432, 2432, 9: 5159}, + {2431, 2431, 9: 2431}, + {247: 5153, 252: 5155, 298: 5156, 317: 5154}, + {209: 5152}, // 2535 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5074, 1238: 5073}, - {49: 5076}, - {49: 2158, 104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 485: 3686, 3687, 3692, 520: 3688, 532: 3454, 3451, 3453, 3452, 3448, 3450, 3449, 3446, 3447, 3445, 3455, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685, 796: 3444, 815: 5075}, - {49: 2157}, - {2152, 2152, 10: 5078, 90: 2152, 2152, 472: 2152, 2152, 2152, 478: 2152, 489: 2152, 492: 2152, 495: 2152, 504: 2152, 569: 2152, 646: 2152, 655: 2152, 1215: 5077}, + {209: 2285, 247: 2034, 252: 2034, 298: 2034, 317: 2034}, + {2424, 2424, 9: 2424}, + {2429, 2429, 9: 2429}, + {2428, 2428, 9: 2428}, + {347: 5157, 423: 5158}, // 2540 - {2156, 2156, 90: 2156, 2156, 472: 2156, 2156, 2156, 478: 2156, 489: 2156, 492: 5093, 495: 2156, 504: 2156, 569: 2156, 646: 2156, 655: 2156, 1256: 5092}, - {488: 5079}, - {152: 5080}, - {157: 5081}, - {473: 5082}, + {2425, 2425, 9: 2425}, + {2427, 2427, 9: 2427}, + {2426, 2426, 9: 2426}, + {525: 5151, 593: 3532, 3531, 755: 5149, 842: 5150, 1017: 5160}, + {2430, 2430, 9: 2430}, // 2545 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5083}, - {49: 5084, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {183: 5085}, - {488: 5086}, - {152: 5087}, + {2433, 2433, 9: 5165, 494: 5146, 826: 5164}, + {946, 946, 9: 946, 58: 946, 494: 946}, + {944, 944, 9: 944, 58: 944, 494: 944}, + {2612, 2612}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 613: 5167, 685: 5166, 2850, 688: 2851, 2849}, // 2550 - {157: 5088}, - {473: 5089}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5090}, - {49: 5091, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {2151, 2151, 90: 2151, 2151, 472: 2151, 2151, 2151, 478: 2151, 489: 2151, 492: 2151, 495: 2151, 504: 2151, 569: 2151, 646: 2151, 655: 2151}, + {945, 945, 9: 945, 58: 945, 494: 945}, + {943, 943, 9: 943, 58: 943, 494: 943}, + {2614, 2614}, + {2577, 2577}, + {32: 5281, 384: 5280}, // 2555 - {2154, 2154, 90: 2154, 2154, 472: 2154, 2154, 2154, 478: 2154, 489: 2154, 495: 2154, 504: 2154, 569: 2154, 646: 2154, 655: 5096, 1254: 5095}, - {488: 5094}, - {2155, 2155, 90: 2155, 2155, 472: 2155, 2155, 2155, 478: 2155, 489: 2155, 495: 2155, 504: 2155, 569: 2155, 646: 2155, 655: 2155}, - {2159, 2159, 90: 2159, 2159, 472: 2159, 2159, 2159, 478: 2159, 489: 2159, 495: 2159, 504: 2159, 569: 2159, 646: 2159}, - {488: 5097}, + {507: 5272}, + {675: 5265}, + {10: 5258}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 681: 5176, 685: 5175, 2850, 688: 2851, 2849}, + {2194, 2194, 6: 2194, 2194, 18: 2194, 20: 2194, 22: 2194, 2194, 2194, 2194, 2194, 2194, 217: 4311, 668: 2194, 951: 5256, 977: 5257}, // 2560 - {2153, 2153, 90: 2153, 2153, 472: 2153, 2153, 2153, 478: 2153, 489: 2153, 495: 2153, 504: 2153, 569: 2153, 646: 2153}, - {49: 5099, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {2160, 2160, 90: 2160, 2160, 472: 2160, 2160, 2160, 478: 2160, 489: 2160, 495: 2160, 504: 2160, 569: 2160, 578: 5071, 646: 2160, 1099: 5100}, - {2167, 2167, 90: 2167, 2167, 472: 2167, 2167, 2167, 478: 2167, 489: 2167, 495: 2167, 504: 2167, 569: 2167, 646: 2167}, - {83: 5107, 473: 2170, 1276: 5106}, + {157: 2212, 370: 5181, 412: 5182, 546: 5180, 600: 2212, 1102: 5183, 5178, 1175: 5179, 1311: 5177}, + {2206, 2206, 97: 2206, 5246, 491: 2206, 2206, 494: 2206, 498: 2206, 508: 2206, 515: 2206, 522: 2206, 588: 2206, 665: 2206, 1312: 5245}, + {157: 5233, 600: 5232}, + {2230, 2230, 97: 2230, 2230, 491: 2230, 2230, 494: 2230, 498: 2230, 508: 2230, 515: 2230, 522: 2230, 588: 2230, 665: 2230}, + {109: 4053, 136: 4052, 492: 5196, 857: 5197}, // 2565 - {473: 5103}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5104}, - {49: 5105, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {2171, 2171, 90: 2171, 2171, 222: 2171, 472: 2171, 2171, 2171, 478: 2171, 489: 2171, 495: 2171, 504: 2171, 569: 2171, 646: 2171}, - {473: 5110}, + {109: 4053, 136: 4052, 492: 5189, 857: 5190}, + {2223, 2223, 97: 2223, 2223, 491: 2223, 2223, 494: 2223, 498: 2223, 508: 2223, 512: 5185, 515: 2223, 522: 2223, 588: 2223, 599: 5184, 665: 2223}, + {157: 2211, 600: 2211}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5187}, + {525: 2824, 755: 2823, 762: 5186}, // 2570 - {499: 5108}, - {508: 2736, 733: 5109}, - {473: 2169}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 2332, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 5111, 1001: 5112}, - {9: 4146, 49: 2331}, + {2224, 2224, 97: 2224, 2224, 491: 2224, 2224, 494: 2224, 498: 2224, 508: 2224, 515: 2224, 522: 2224, 588: 2224, 665: 2224}, + {111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 527: 3452, 3450, 3451, 3449, 3447, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 756: 3448, 3446, 813: 3551, 828: 5188}, + {2225, 2225, 97: 2225, 2225, 491: 2225, 2225, 494: 2225, 498: 2225, 508: 2225, 515: 2225, 522: 2225, 588: 2225, 665: 2225}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5194}, + {492: 5191}, // 2575 - {49: 5113}, - {2172, 2172, 90: 2172, 2172, 222: 2172, 472: 2172, 2172, 2172, 478: 2172, 489: 2172, 495: 2172, 504: 2172, 569: 2172, 646: 2172}, - {2148, 2148, 90: 5118, 472: 2148, 2148, 2148, 478: 2148, 489: 2148, 495: 2148, 504: 2148, 569: 2148, 646: 2148, 1319: 5117}, - {508: 2736, 733: 2735, 741: 5116}, - {2143, 2143, 90: 2143, 472: 2143, 2143, 2143, 478: 2143, 489: 2143, 495: 2143, 504: 2143, 569: 2143, 646: 2143}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 5192}, + {9: 4259, 58: 5193}, + {2226, 2226, 97: 2226, 2226, 491: 2226, 2226, 494: 2226, 498: 2226, 508: 2226, 515: 2226, 522: 2226, 588: 2226, 665: 2226}, + {58: 5195, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {2227, 2227, 97: 2227, 2227, 491: 2227, 2227, 494: 2227, 498: 2227, 508: 2227, 515: 2227, 522: 2227, 588: 2227, 665: 2227}, // 2580 - {2142, 2142, 472: 2142, 4916, 2142, 478: 2142, 489: 2142, 495: 2142, 504: 2142, 569: 2142, 646: 2142, 1098: 5124}, - {660: 5119}, - {143: 2150, 581: 2150, 1072: 5052, 5047, 1143: 5120}, - {2146, 2146, 222: 5122, 472: 2146, 2146, 2146, 478: 2146, 489: 2146, 495: 2146, 504: 2146, 569: 2146, 646: 2146, 1318: 5121}, - {2147, 2147, 472: 2147, 2147, 2147, 478: 2147, 489: 2147, 495: 2147, 504: 2147, 569: 2147, 646: 2147}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5229}, + {492: 5198}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 5199}, + {9: 4259, 58: 5200}, + {2222, 2222, 97: 2222, 2222, 491: 2222, 2222, 494: 2222, 498: 2222, 508: 2222, 515: 2222, 522: 2222, 588: 2222, 599: 5202, 665: 2222, 1129: 5201}, // 2585 - {508: 2736, 733: 2735, 741: 5123}, - {2145, 2145, 472: 2145, 2145, 2145, 478: 2145, 489: 2145, 495: 2145, 504: 2145, 569: 2145, 646: 2145}, - {2173, 2173, 472: 2173, 2173, 2173, 478: 2173, 489: 2173, 495: 2173, 504: 2173, 569: 2173, 646: 2173}, - {2501, 2501}, - {2500, 2500, 6: 4241, 4945, 18: 4197, 20: 4249, 22: 4242, 4245, 4244, 4247, 4248, 4250, 649: 4246, 781: 4251, 813: 4944}, + {2228, 2228, 97: 2228, 2228, 491: 2228, 2228, 494: 2228, 498: 2228, 508: 2228, 515: 2228, 522: 2228, 588: 2228, 665: 2228}, + {492: 5203}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5205, 1270: 5204}, + {58: 5207}, + {58: 2220, 111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 504: 3793, 3794, 3799, 541: 3795, 550: 3561, 3558, 3560, 3559, 3555, 3557, 3556, 3553, 3554, 3552, 3562, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792, 813: 3551, 828: 5206}, // 2590 - {488: 5128}, - {152: 5129}, - {157: 5130}, - {473: 5131}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5132}, + {58: 2219}, + {2214, 2214, 10: 5209, 97: 2214, 2214, 491: 2214, 2214, 494: 2214, 498: 2214, 508: 2214, 510: 2214, 515: 2214, 522: 2214, 588: 2214, 665: 2214, 675: 2214, 1248: 5208}, + {2218, 2218, 97: 2218, 2218, 491: 2218, 2218, 494: 2218, 498: 2218, 508: 2218, 510: 5224, 515: 2218, 522: 2218, 588: 2218, 665: 2218, 675: 2218, 1290: 5223}, + {507: 5210}, + {165: 5211}, // 2595 - {49: 5133, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {2502, 2502}, - {488: 5135}, - {152: 5136}, - {157: 5137}, + {170: 5212}, + {492: 5213}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5214}, + {58: 5215, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {196: 5216}, // 2600 - {473: 5138}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 5139}, - {49: 5140, 485: 3686, 3687, 3692, 520: 3688, 547: 3689, 3690, 3683, 3693, 3682, 3691, 3684, 3685}, - {2503, 2503}, - {569, 569, 569, 569, 569, 569, 569, 569, 569, 10: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 50: 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 4750, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 811: 4749, 829: 5142}, + {507: 5217}, + {165: 5218}, + {170: 5219}, + {492: 5220}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5221}, // 2605 - {2440, 2440, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 5144, 1286: 5143}, - {2504, 2504}, - {9: 4755, 496: 5145}, - {473: 5146}, - {488: 4919, 952: 4918, 1097: 5147}, + {58: 5222, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {2213, 2213, 97: 2213, 2213, 491: 2213, 2213, 494: 2213, 498: 2213, 508: 2213, 510: 2213, 515: 2213, 522: 2213, 588: 2213, 665: 2213, 675: 2213}, + {2216, 2216, 97: 2216, 2216, 491: 2216, 2216, 494: 2216, 498: 2216, 508: 2216, 515: 2216, 522: 2216, 588: 2216, 665: 2216, 675: 5227, 1288: 5226}, + {507: 5225}, + {2217, 2217, 97: 2217, 2217, 491: 2217, 2217, 494: 2217, 498: 2217, 508: 2217, 515: 2217, 522: 2217, 588: 2217, 665: 2217, 675: 2217}, // 2610 - {9: 4955, 49: 5148}, - {2439, 2439}, - {2505, 2505}, - {136: 5151, 881: 104, 1076: 5152}, - {881: 103}, + {2221, 2221, 97: 2221, 2221, 491: 2221, 2221, 494: 2221, 498: 2221, 508: 2221, 515: 2221, 522: 2221, 588: 2221, 665: 2221}, + {507: 5228}, + {2215, 2215, 97: 2215, 2215, 491: 2215, 2215, 494: 2215, 498: 2215, 508: 2215, 515: 2215, 522: 2215, 588: 2215, 665: 2215}, + {58: 5230, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {2222, 2222, 97: 2222, 2222, 491: 2222, 2222, 494: 2222, 498: 2222, 508: 2222, 515: 2222, 522: 2222, 588: 2222, 599: 5202, 665: 2222, 1129: 5231}, // 2615 - {881: 5153}, - {475: 5154}, - {19, 19, 185: 19, 359: 5156, 658: 19, 1253: 5155}, - {17, 17, 185: 5159, 658: 17, 1252: 5158}, - {508: 2736, 733: 5157}, + {2229, 2229, 97: 2229, 2229, 491: 2229, 2229, 494: 2229, 498: 2229, 508: 2229, 515: 2229, 522: 2229, 588: 2229, 665: 2229}, + {90: 5238, 492: 2232, 1310: 5237}, + {492: 5234}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5235}, + {58: 5236, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, // 2620 - {18, 18, 185: 18, 658: 18}, - {89, 89, 658: 3965, 944: 5166}, - {15, 15, 189: 15, 371: 5161, 658: 15, 1280: 5160}, - {13, 13, 189: 5164, 658: 13, 1279: 5163}, - {508: 2736, 733: 5162}, + {2233, 2233, 97: 2233, 2233, 236: 2233, 491: 2233, 2233, 494: 2233, 498: 2233, 508: 2233, 515: 2233, 522: 2233, 588: 2233, 665: 2233}, + {492: 5241}, + {517: 5239}, + {525: 2824, 755: 5240}, + {492: 2231}, // 2625 - {14, 14, 189: 14, 658: 14}, - {16, 16, 658: 16}, - {508: 2736, 733: 5165}, - {12, 12, 658: 12}, - {20, 20}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 2399, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 5242, 1026: 5243}, + {9: 4259, 58: 2398}, + {58: 5244}, + {2234, 2234, 97: 2234, 2234, 236: 2234, 491: 2234, 2234, 494: 2234, 498: 2234, 508: 2234, 515: 2234, 522: 2234, 588: 2234, 665: 2234}, + {2210, 2210, 97: 5249, 491: 2210, 2210, 494: 2210, 498: 2210, 508: 2210, 515: 2210, 522: 2210, 588: 2210, 665: 2210, 1354: 5248}, // 2630 - {28: 57, 139: 57, 508: 57}, - {61, 61}, - {508: 2736, 733: 5172}, - {508: 2736, 733: 5171}, - {59, 59}, + {525: 2824, 755: 2823, 762: 5247}, + {2205, 2205, 97: 2205, 491: 2205, 2205, 494: 2205, 498: 2205, 508: 2205, 515: 2205, 522: 2205, 588: 2205, 665: 2205}, + {2204, 2204, 491: 2204, 5047, 494: 2204, 498: 2204, 508: 2204, 515: 2204, 522: 2204, 588: 2204, 665: 2204, 1128: 5255}, + {681: 5250}, + {157: 2212, 600: 2212, 1102: 5183, 5178, 1175: 5251}, // 2635 - {60, 60}, - {493: 5176}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 5175}, - {493: 62}, - {508: 2736, 733: 5177}, + {2208, 2208, 236: 5253, 491: 2208, 2208, 494: 2208, 498: 2208, 508: 2208, 515: 2208, 522: 2208, 588: 2208, 665: 2208, 1353: 5252}, + {2209, 2209, 491: 2209, 2209, 494: 2209, 498: 2209, 508: 2209, 515: 2209, 522: 2209, 588: 2209, 665: 2209}, + {525: 2824, 755: 2823, 762: 5254}, + {2207, 2207, 491: 2207, 2207, 494: 2207, 498: 2207, 508: 2207, 515: 2207, 522: 2207, 588: 2207, 665: 2207}, + {2235, 2235, 491: 2235, 2235, 494: 2235, 498: 2235, 508: 2235, 515: 2235, 522: 2235, 588: 2235, 665: 2235}, // 2640 - {251: 5179, 474: 66, 739: 66, 1205: 5178}, - {474: 2587, 739: 2553, 759: 5182, 766: 2554, 779: 2555, 783: 5183}, - {383: 5180}, - {139: 5181, 474: 65, 739: 65}, - {474: 64, 739: 64}, + {2572, 2572}, + {2571, 2571, 6: 4354, 5076, 18: 4310, 20: 4362, 22: 4355, 4358, 4357, 4360, 4361, 4363, 668: 4359, 803: 4364, 837: 5075}, + {507: 5259}, + {165: 5260}, + {170: 5261}, // 2645 - {739: 2553, 766: 5184, 779: 5185}, - {67, 67}, - {2070, 2070}, - {2069, 2069}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5190, 1146: 5191, 1321: 5189}, + {492: 5262}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5263}, + {58: 5264, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, + {2573, 2573}, + {507: 5266}, // 2650 - {76, 76, 76, 76, 76, 76, 76, 76, 76, 10: 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 50: 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76}, - {75, 75, 75, 75, 75, 75, 75, 75, 75, 10: 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 50: 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75}, - {77, 77, 9: 5197}, - {671: 5193, 687: 5194, 1248: 5192}, - {69, 69, 9: 69}, + {165: 5267}, + {170: 5268}, + {492: 5269}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 5270}, + {58: 5271, 504: 3793, 3794, 3799, 541: 3795, 566: 3796, 3797, 3790, 3800, 3789, 3798, 3791, 3792}, // 2655 - {74, 74, 9: 74}, - {73, 73, 9: 73, 136: 5196}, - {71, 71, 9: 71, 136: 5195}, - {70, 70, 9: 70}, - {72, 72, 9: 72}, + {2574, 2574}, + {606, 606, 606, 606, 606, 606, 606, 606, 606, 10: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 59: 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 4881, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 835: 4880, 851: 5273}, + {2510, 2510, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 5275, 1320: 5274}, + {2575, 2575}, + {9: 4886, 516: 5276}, // 2660 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5190, 1146: 5198}, - {68, 68, 9: 68}, - {78, 78}, - {136: 5151, 881: 104, 1076: 5203}, - {475: 5202}, + {492: 5277}, + {507: 5050, 978: 5049, 1127: 5278}, + {9: 5086, 58: 5279}, + {2509, 2509}, + {2576, 2576}, // 2665 - {56, 56}, - {881: 5204}, - {475: 5205}, - {489: 5206, 496: 2112, 504: 5207, 1037: 5208}, - {2111, 2111, 472: 2111, 2111, 2111, 478: 2111, 495: 2111, 2111, 569: 2111, 646: 2111}, + {2570, 2570}, + {152: 5283, 860: 118, 1280: 5284}, + {860: 117}, + {860: 5285}, + {493: 5286}, // 2670 - {2110, 2110, 472: 2110, 2110, 2110, 478: 2110, 495: 2110, 2110, 569: 2110, 646: 2110}, - {496: 5209}, - {569: 5210}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5211}, - {106, 106, 102: 106, 111: 106, 473: 106, 489: 106, 506: 106, 647: 5213, 658: 106, 1187: 5212}, + {20, 20, 198: 20, 372: 5288, 679: 20, 1287: 5287}, + {18, 18, 198: 5291, 679: 18, 1286: 5290}, + {525: 2824, 755: 5289}, + {19, 19, 198: 19, 679: 19}, + {100, 100, 679: 4074, 970: 5298}, // 2675 - {102, 102, 102: 3944, 111: 3943, 473: 102, 489: 102, 506: 102, 658: 102, 834: 3942, 1048: 5216}, - {506: 5214}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 5215}, - {105, 105, 102: 105, 111: 105, 473: 105, 489: 105, 506: 105, 658: 105}, - {89, 89, 473: 89, 489: 89, 506: 89, 658: 3965, 944: 5217}, + {16, 16, 202: 16, 385: 5293, 679: 16, 1314: 5292}, + {14, 14, 202: 5296, 679: 14, 1313: 5295}, + {525: 2824, 755: 5294}, + {15, 15, 202: 15, 679: 15}, + {17, 17, 679: 17}, // 2680 - {108, 108, 473: 108, 489: 5219, 506: 108, 1229: 5218}, - {2320, 2320, 473: 5222, 506: 2320, 1193: 5223}, - {508: 2736, 733: 5220}, - {658: 5221}, - {107, 107, 473: 107, 506: 107}, + {525: 2824, 755: 5297}, + {13, 13, 679: 13}, + {21, 21}, + {28: 63, 141: 63, 153: 63, 492: 63, 525: 63}, + {141: 4840, 492: 5300, 924: 4848}, // 2685 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 2326, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 568: 3349, 661: 4143, 2762, 2763, 2761, 710: 5236, 744: 5235, 1002: 5234, 1191: 5233, 5237}, - {83, 83, 506: 5225, 1247: 5224}, - {109, 109}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3780, 2762, 2763, 2761, 711: 5228, 1074: 5227, 1246: 5226}, - {82, 82, 9: 5231}, + {68, 68}, + {525: 2824, 755: 5306}, + {525: 2824, 755: 5305}, + {65, 65}, + {66, 66}, // 2690 - {80, 80, 9: 80}, - {499: 5229}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5230}, - {79, 79, 9: 79}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3780, 2762, 2763, 2761, 711: 5228, 1074: 5232}, + {67, 67}, + {512: 5310}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 5309}, + {512: 69}, + {525: 2824, 755: 5311}, // 2695 - {81, 81, 9: 81}, - {9: 5239, 49: 2325}, - {9: 2324, 49: 2324}, - {9: 2322, 49: 2322}, - {9: 2321, 49: 2321}, + {266: 5313, 494: 73, 522: 73, 587: 73, 674: 73, 761: 73, 1238: 5312}, + {494: 2666, 522: 2651, 587: 2650, 674: 2775, 761: 2632, 781: 5316, 788: 2774, 2633, 795: 5320, 5321, 5319, 802: 2634, 807: 5318, 1330: 5317}, + {399: 5314}, + {153: 5315, 494: 72, 522: 72, 587: 72, 674: 72, 761: 72}, + {494: 71, 522: 71, 587: 71, 674: 71, 761: 71}, // 2700 - {49: 5238}, - {2319, 2319, 506: 2319}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 568: 3349, 661: 4143, 2762, 2763, 2761, 710: 5236, 744: 5235, 1002: 5240}, - {9: 2323, 49: 2323}, - {9: 166, 151: 166, 472: 166, 500: 166, 568: 1832, 650: 166, 667: 1832}, + {674: 2775, 761: 2632, 788: 5324, 5322, 802: 5323}, + {78, 78}, + {77, 77}, + {76, 76}, + {75, 75}, // 2705 - {9: 131, 472: 131, 131, 500: 131, 568: 1802, 650: 131, 667: 1802}, - {9: 145, 472: 145, 145, 500: 145, 568: 1776, 650: 145, 667: 1776}, - {9: 132, 472: 132, 132, 500: 132, 568: 1773, 650: 132, 667: 1773}, - {9: 121, 472: 121, 121, 500: 121, 568: 1738, 650: 121, 667: 1738}, - {9: 141, 472: 141, 141, 500: 141, 568: 1661, 650: 141, 667: 1661}, + {74, 74}, + {2132, 2132}, + {2131, 2131}, + {280, 280, 501: 280}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5331, 1178: 5332, 1356: 5330}, // 2710 - {9: 146, 472: 146, 146, 500: 146, 568: 1654, 650: 146, 667: 1654}, - {324: 5350, 388: 5349, 568: 1635, 667: 1635}, - {9: 133, 472: 133, 133, 500: 133, 568: 1632, 650: 133, 667: 1632}, - {9: 122, 472: 122, 122, 500: 122, 568: 1629, 650: 122, 667: 1629}, - {568: 5347, 667: 5346}, + {87, 87, 87, 87, 87, 87, 87, 87, 87, 10: 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 59: 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87}, + {86, 86, 86, 86, 86, 86, 86, 86, 86, 10: 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 59: 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 5329}, + {61, 61, 9: 4033}, + {88, 88, 9: 5338}, // 2715 - {9: 734, 472: 734, 500: 734, 568: 258, 650: 734, 667: 258}, - {9: 733, 472: 733, 500: 733, 650: 733}, - {9: 162, 151: 5345, 472: 162, 500: 162, 650: 162}, - {9: 164, 472: 164, 500: 164, 650: 164}, - {9: 163, 472: 163, 500: 163, 650: 163}, + {692: 5334, 709: 5335, 1282: 5333}, + {80, 80, 9: 80}, + {85, 85, 9: 85}, + {84, 84, 9: 84, 152: 5337}, + {82, 82, 9: 82, 152: 5336}, // 2720 - {500: 5343}, - {9: 142, 472: 142, 142, 496: 5341, 500: 142, 650: 142}, - {9: 159, 472: 159, 500: 159, 650: 159}, - {9: 5293, 472: 5294, 500: 5295}, - {9: 157, 472: 157, 5290, 500: 157, 650: 157}, + {81, 81, 9: 81}, + {83, 83, 9: 83}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5331, 1178: 5339}, + {79, 79, 9: 79}, + {89, 89}, // 2725 - {9: 155, 190: 5289, 472: 155, 155, 500: 155, 650: 155}, - {9: 153, 281: 5288, 472: 153, 153, 500: 153, 650: 153}, - {9: 152, 20: 5282, 103: 5284, 167: 5283, 170: 5281, 174: 5285, 281: 5286, 472: 152, 152, 500: 152, 650: 152}, - {9: 149, 472: 149, 149, 500: 149, 650: 149}, - {9: 148, 472: 148, 148, 500: 148, 650: 148}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 5342}, + {60, 60, 9: 4033}, + {152: 5347, 394: 5348, 860: 116, 1281: 5346}, + {493: 5345}, + {62, 62}, // 2730 - {9: 147, 174: 5280, 472: 147, 147, 500: 147, 650: 147}, - {9: 144, 472: 144, 144, 500: 144, 650: 144}, - {9: 143, 472: 143, 143, 500: 143, 650: 143}, - {103: 5279, 1020: 5278}, - {9: 139, 472: 139, 139, 500: 139, 650: 139}, + {860: 5349}, + {860: 115}, + {860: 114}, + {493: 5350}, + {508: 5351, 516: 2174, 522: 5352, 1065: 5353}, // 2735 - {906: 5277}, - {9: 137, 472: 137, 137, 500: 137, 650: 137}, - {9: 134, 472: 134, 134, 500: 134, 650: 134}, - {125: 5276}, - {9: 129, 472: 129, 129, 500: 129, 650: 129}, + {2173, 2173, 491: 2173, 2173, 494: 2173, 498: 2173, 515: 2173, 2173, 588: 2173, 665: 2173}, + {2172, 2172, 491: 2172, 2172, 494: 2172, 498: 2172, 515: 2172, 2172, 588: 2172, 665: 2172}, + {516: 5354}, + {588: 5355}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5356}, // 2740 - {9: 138, 472: 138, 138, 500: 138, 650: 138}, - {9: 140, 472: 140, 140, 500: 140, 650: 140}, - {9: 127, 472: 127, 127, 500: 127, 650: 127}, - {9: 125, 472: 125, 125, 500: 125, 650: 125}, - {9: 151, 472: 151, 151, 500: 151, 650: 151}, + {120, 120, 109: 120, 136: 120, 492: 120, 508: 120, 526: 120, 667: 5358, 679: 120, 1221: 5357}, + {113, 113, 109: 4053, 136: 4052, 492: 113, 508: 113, 526: 113, 679: 113, 857: 4051, 1076: 5361}, + {526: 5359}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 5360}, + {119, 119, 109: 119, 136: 119, 492: 119, 508: 119, 526: 119, 679: 119}, // 2745 - {9: 150, 472: 150, 150, 500: 150, 650: 150}, - {125: 5287}, - {9: 128, 472: 128, 128, 500: 128, 650: 128}, - {9: 126, 472: 126, 126, 500: 126, 650: 126}, - {9: 124, 472: 124, 124, 500: 124, 650: 124}, + {100, 100, 492: 100, 508: 100, 526: 100, 679: 4074, 970: 5362}, + {122, 122, 492: 122, 508: 5364, 526: 122, 1261: 5363}, + {2387, 2387, 492: 5367, 526: 2387, 1226: 5368}, + {525: 2824, 755: 5365}, + {679: 5366}, // 2750 - {9: 130, 472: 130, 130, 500: 130, 650: 130}, - {9: 123, 472: 123, 123, 500: 123, 650: 123}, - {9: 154, 472: 154, 154, 500: 154, 650: 154}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 5291}, - {9: 4146, 49: 5292}, + {121, 121, 492: 121, 526: 121}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 2393, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 589: 3456, 685: 4256, 2850, 688: 2851, 2849, 732: 5381, 766: 5380, 1027: 5379, 1224: 5378, 5382}, + {94, 94, 526: 5370, 1279: 5369}, + {123, 123}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3887, 2850, 688: 2851, 2849, 733: 5373, 1104: 5372, 1278: 5371}, // 2755 - {9: 156, 472: 156, 500: 156, 650: 156}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5241, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 5243, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 5249, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 5245, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 5242, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 5250, 3206, 2932, 3158, 5244, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 5247, 2843, 2844, 3083, 5248, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 5246, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5252, 497: 5275, 567: 5269, 644: 5273, 646: 5258, 649: 5268, 651: 5262, 654: 5271, 661: 3491, 2762, 2763, 2761, 5263, 669: 5267, 674: 5264, 738: 5251, 5266, 801: 5253, 809: 5257, 854: 5272, 866: 5270, 936: 5254, 957: 5255, 5261, 963: 5256, 5340, 972: 5265, 974: 5274}, - {2: 120, 120, 120, 120, 120, 120, 120, 10: 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 50: 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 5307, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 520: 120, 569: 5306, 959: 5308, 1083: 5309}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5298, 868: 5299}, - {747, 747, 9: 747, 15: 747, 48: 747, 103: 747, 144: 747, 474: 747, 481: 747, 499: 747, 568: 5304, 650: 747, 666: 747, 5303, 747}, + {93, 93, 9: 5376}, + {91, 91, 9: 91}, + {517: 5374}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5375}, + {90, 90, 9: 90}, // 2760 - {1206, 1206, 9: 1206, 15: 1206, 48: 1206, 103: 1206, 144: 1206, 473: 3770, 1206, 481: 1206, 499: 1206, 650: 1206, 666: 1206, 668: 1206, 1092: 5302}, - {743, 743, 9: 743, 474: 743}, - {110, 110, 9: 5300}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5301}, - {742, 742, 9: 742, 474: 742}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3887, 2850, 688: 2851, 2849, 733: 5373, 1104: 5377}, + {92, 92, 9: 92}, + {9: 5384, 58: 2392}, + {9: 2391, 58: 2391}, + {9: 2389, 58: 2389}, // 2765 - {744, 744, 9: 744, 15: 744, 48: 744, 103: 744, 144: 744, 474: 744, 481: 744, 499: 744, 650: 744, 666: 744, 668: 744}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 661: 3491, 2762, 2763, 2761, 738: 5305}, - {745, 745, 9: 745, 15: 745, 48: 745, 103: 745, 144: 745, 474: 745, 481: 745, 499: 745, 650: 745, 666: 745, 668: 745}, - {746, 746, 9: 746, 15: 746, 48: 746, 103: 746, 144: 746, 474: 746, 481: 746, 499: 746, 650: 746, 666: 746, 668: 746}, - {2: 119, 119, 119, 119, 119, 119, 119, 10: 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 50: 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 520: 119}, + {9: 2388, 58: 2388}, + {58: 5383}, + {2386, 2386, 526: 2386}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 589: 3456, 685: 4256, 2850, 688: 2851, 2849, 732: 5381, 766: 5380, 1027: 5385}, + {9: 2390, 58: 2390}, // 2770 - {2: 118, 118, 118, 118, 118, 118, 118, 10: 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 50: 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 520: 118}, - {2: 117, 117, 117, 117, 117, 117, 117, 10: 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 50: 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 520: 117}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 5310, 661: 5311, 2762, 2763, 2761, 1107: 5312}, - {500: 116, 650: 116, 652: 5338}, - {500: 112, 650: 112, 652: 5335}, + {9: 180, 141: 180, 491: 180, 520: 180, 589: 1892, 670: 180, 684: 1892}, + {9: 145, 491: 145, 145, 520: 145, 589: 1861, 670: 145, 684: 1861}, + {9: 159, 491: 159, 159, 520: 159, 589: 1835, 670: 159, 684: 1835}, + {9: 146, 491: 146, 146, 520: 146, 589: 1832, 670: 146, 684: 1832}, + {9: 135, 491: 135, 135, 520: 135, 589: 1795, 670: 135, 684: 1795}, // 2775 - {500: 5313}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5314, 891: 5315, 922: 5316}, - {200, 200, 9: 200, 15: 200, 48: 200, 144: 5320, 474: 200, 666: 200, 1177: 5319}, - {235, 235, 9: 235, 15: 235, 48: 235, 474: 235, 666: 235}, - {111, 111, 9: 5317}, + {9: 155, 491: 155, 155, 520: 155, 589: 1718, 670: 155, 684: 1718}, + {9: 160, 491: 160, 160, 520: 160, 589: 1711, 670: 160, 684: 1711}, + {338: 5495, 404: 5494, 589: 1692, 684: 1692}, + {9: 147, 491: 147, 147, 520: 147, 589: 1689, 670: 147, 684: 1689}, + {9: 136, 491: 136, 136, 520: 136, 589: 1686, 670: 136, 684: 1686}, // 2780 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5314, 891: 5318}, - {234, 234, 9: 234, 15: 234, 48: 234, 474: 234, 666: 234}, - {236, 236, 9: 236, 15: 236, 48: 236, 474: 236, 666: 236}, - {474: 5322, 660: 5321}, - {15: 5333, 475: 5330, 893: 5332}, + {589: 5492, 684: 5491}, + {9: 773, 491: 773, 520: 773, 589: 286, 670: 773, 684: 286}, + {9: 772, 491: 772, 520: 772, 670: 772}, + {9: 176, 141: 5490, 491: 176, 520: 176, 670: 176}, + {9: 178, 491: 178, 520: 178, 670: 178}, // 2785 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 661: 3491, 2762, 2763, 2761, 738: 5324, 1178: 5323}, - {198, 198, 9: 198, 15: 198, 48: 198, 474: 198, 478: 5326, 660: 5325, 666: 198}, - {194, 194, 9: 194, 15: 194, 48: 194, 474: 194, 478: 194, 660: 194, 666: 194}, - {475: 5330, 893: 5331}, - {475: 5328, 576: 5329, 1058: 5327}, + {9: 177, 491: 177, 520: 177, 670: 177}, + {520: 5488}, + {9: 156, 491: 156, 156, 516: 5486, 520: 156, 670: 156}, + {9: 173, 491: 173, 520: 173, 670: 173}, + {9: 5438, 491: 5439, 520: 5440}, // 2790 - {196, 196, 9: 196, 15: 196, 48: 196, 474: 196, 666: 196}, - {193, 193, 9: 193, 15: 193, 48: 193, 474: 193, 666: 193}, - {192, 192, 9: 192, 15: 192, 48: 192, 474: 192, 666: 192}, - {739, 739, 9: 739, 15: 739, 48: 739, 739, 474: 739, 666: 739}, - {197, 197, 9: 197, 15: 197, 48: 197, 474: 197, 666: 197}, + {9: 171, 491: 171, 5435, 520: 171, 670: 171}, + {9: 169, 204: 5434, 491: 169, 169, 520: 169, 670: 169}, + {9: 167, 296: 5433, 491: 167, 167, 520: 167, 670: 167}, + {9: 166, 20: 5427, 110: 5429, 181: 5428, 183: 5426, 187: 5430, 296: 5431, 491: 166, 166, 520: 166, 670: 166}, + {9: 163, 491: 163, 163, 520: 163, 670: 163}, // 2795 - {199, 199, 9: 199, 15: 199, 48: 199, 474: 199, 666: 199}, - {475: 5328, 576: 5329, 1058: 5334}, - {195, 195, 9: 195, 15: 195, 48: 195, 474: 195, 666: 195}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 5336, 661: 5337, 2762, 2763, 2761}, - {500: 114, 650: 114}, + {9: 162, 491: 162, 162, 520: 162, 670: 162}, + {9: 161, 187: 5425, 491: 161, 161, 520: 161, 670: 161}, + {9: 158, 491: 158, 158, 520: 158, 670: 158}, + {9: 157, 491: 157, 157, 520: 157, 670: 157}, + {110: 5424, 1047: 5423}, // 2800 - {500: 113, 650: 113}, - {520: 5339}, - {500: 115, 650: 115}, - {9: 158, 472: 158, 500: 158, 650: 158}, - {282: 5342}, + {9: 153, 491: 153, 153, 520: 153, 670: 153}, + {931: 5422}, + {9: 151, 491: 151, 151, 520: 151, 670: 151}, + {9: 148, 491: 148, 148, 520: 148, 670: 148}, + {137: 5421}, // 2805 - {9: 160, 472: 160, 500: 160, 650: 160}, - {282: 5344}, - {9: 161, 472: 161, 500: 161, 650: 161}, - {9: 165, 151: 165, 472: 165, 500: 165, 650: 165}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 661: 3491, 2762, 2763, 2761, 738: 5348}, + {9: 143, 491: 143, 143, 520: 143, 670: 143}, + {9: 152, 491: 152, 152, 520: 152, 670: 152}, + {9: 154, 491: 154, 154, 520: 154, 670: 154}, + {9: 141, 491: 141, 141, 520: 141, 670: 141}, + {9: 139, 491: 139, 139, 520: 139, 670: 139}, // 2810 - {735, 735, 9: 735, 472: 735, 500: 735, 650: 735}, - {736, 736, 9: 736, 472: 736, 500: 736, 650: 736}, - {9: 136, 472: 136, 136, 500: 136, 650: 136}, - {9: 135, 472: 135, 135, 500: 135, 650: 135}, - {472: 5391, 568: 1749, 667: 1749}, + {9: 165, 491: 165, 165, 520: 165, 670: 165}, + {9: 164, 491: 164, 164, 520: 164, 670: 164}, + {137: 5432}, + {9: 142, 491: 142, 142, 520: 142, 670: 142}, + {9: 140, 491: 140, 140, 520: 140, 670: 140}, // 2815 - {9: 5293, 472: 5353, 650: 5354}, - {2: 120, 120, 120, 120, 120, 120, 120, 10: 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 50: 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 5307, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 520: 120, 569: 5306, 959: 5308, 1083: 5356}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5298, 868: 5355}, - {173, 173, 9: 5300}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 5310, 661: 5311, 2762, 2763, 2761, 1107: 5357}, + {9: 138, 491: 138, 138, 520: 138, 670: 138}, + {9: 144, 491: 144, 144, 520: 144, 670: 144}, + {9: 137, 491: 137, 137, 520: 137, 670: 137}, + {9: 168, 491: 168, 168, 520: 168, 670: 168}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 5436}, // 2820 - {650: 5358}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5314, 891: 5315, 922: 5359}, - {225, 225, 9: 5317, 474: 225, 666: 5361, 960: 5360, 5362}, - {224, 224, 15: 224, 48: 224, 474: 224}, - {133: 5382, 135: 5380, 137: 5383, 5381, 363: 5375, 407: 5377, 962: 5379, 1287: 5378, 1305: 5376}, + {9: 4259, 58: 5437}, + {9: 170, 491: 170, 520: 170, 670: 170}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5386, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 5388, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 5394, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 5390, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 5387, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 5395, 3308, 3023, 3260, 5389, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 5392, 2932, 2933, 3175, 5393, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 5391, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5397, 518: 5420, 587: 5414, 664: 5418, 5403, 668: 5413, 671: 5407, 674: 5416, 682: 5408, 685: 3598, 2850, 688: 2851, 2849, 5412, 695: 5409, 760: 5396, 5411, 823: 5398, 833: 5402, 877: 5417, 889: 5415, 962: 5399, 982: 5400, 5406, 988: 5401, 5485, 997: 5410, 999: 5419}, + {2: 134, 134, 134, 134, 134, 134, 134, 10: 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 59: 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 5452, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 541: 134, 588: 5451, 984: 5453, 1113: 5454}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5443, 891: 5444}, // 2825 - {172, 172, 474: 5364, 1163: 5363}, - {175, 175}, - {128: 5368, 5366, 5367, 5369, 854: 5365}, - {906: 5374}, - {508: 2736, 733: 5373}, + {786, 786, 6: 786, 9: 786, 15: 786, 51: 786, 786, 786, 786, 786, 110: 786, 158: 786, 494: 786, 501: 786, 517: 786, 589: 5449, 670: 786, 683: 786, 5448, 687: 786}, + {1245, 1245, 6: 1245, 9: 1245, 15: 1245, 51: 1245, 1245, 1245, 1245, 1245, 110: 1245, 158: 1245, 492: 3877, 494: 1245, 501: 1245, 517: 1245, 670: 1245, 683: 1245, 687: 1245, 1122: 5447}, + {782, 782, 9: 782, 494: 782}, + {124, 124, 9: 5445}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5446}, // 2830 - {508: 2736, 733: 5372}, - {508: 2736, 733: 5371}, - {508: 2736, 733: 5370}, - {167, 167}, - {168, 168}, + {781, 781, 9: 781, 494: 781}, + {783, 783, 6: 783, 9: 783, 15: 783, 51: 783, 783, 783, 783, 783, 110: 783, 158: 783, 494: 783, 501: 783, 517: 783, 670: 783, 683: 783, 687: 783}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 685: 3598, 2850, 688: 2851, 2849, 760: 5450}, + {784, 784, 6: 784, 9: 784, 15: 784, 51: 784, 784, 784, 784, 784, 110: 784, 158: 784, 494: 784, 501: 784, 517: 784, 670: 784, 683: 784, 687: 784}, + {785, 785, 6: 785, 9: 785, 15: 785, 51: 785, 785, 785, 785, 785, 110: 785, 158: 785, 494: 785, 501: 785, 517: 785, 670: 785, 683: 785, 687: 785}, // 2835 - {169, 169}, - {170, 170}, - {171, 171}, - {223, 223, 15: 223, 48: 223, 474: 223}, - {222, 222, 15: 222, 48: 222, 474: 222}, + {2: 133, 133, 133, 133, 133, 133, 133, 10: 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 59: 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 541: 133}, + {2: 132, 132, 132, 132, 132, 132, 132, 10: 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 59: 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 541: 132}, + {2: 131, 131, 131, 131, 131, 131, 131, 10: 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 59: 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 541: 131}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 5455, 685: 5456, 2850, 688: 2851, 2849, 1137: 5457}, + {520: 130, 670: 130, 672: 5483}, // 2840 - {221, 221, 15: 221, 48: 221, 474: 221}, - {220, 220, 15: 220, 48: 220, 133: 5382, 135: 5380, 137: 5383, 5381, 474: 220, 507: 5388, 962: 5389}, - {219, 219, 15: 219, 48: 219, 133: 219, 135: 219, 137: 219, 219, 474: 219, 507: 219}, - {475: 5387}, - {475: 5386}, + {520: 126, 670: 126, 672: 5480}, + {520: 5458}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5459, 915: 5460, 947: 5461}, + {217, 217, 6: 217, 9: 217, 15: 217, 51: 217, 217, 217, 217, 217, 158: 5465, 494: 217, 683: 217, 1211: 5464}, + {263, 263, 6: 263, 9: 263, 15: 263, 51: 263, 263, 263, 263, 263, 494: 263, 683: 263}, // 2845 - {475: 5385}, - {475: 5384}, - {213, 213, 15: 213, 48: 213, 133: 213, 135: 213, 137: 213, 213, 474: 213, 507: 213}, - {214, 214, 15: 214, 48: 214, 133: 214, 135: 214, 137: 214, 214, 474: 214, 507: 214}, - {215, 215, 15: 215, 48: 215, 133: 215, 135: 215, 137: 215, 215, 474: 215, 507: 215}, + {125, 125, 9: 5462}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5459, 915: 5463}, + {262, 262, 6: 262, 9: 262, 15: 262, 51: 262, 262, 262, 262, 262, 494: 262, 683: 262}, + {264, 264, 6: 264, 9: 264, 15: 264, 51: 264, 264, 264, 264, 264, 494: 264, 683: 264}, + {494: 5467, 681: 5466}, // 2850 - {216, 216, 15: 216, 48: 216, 133: 216, 135: 216, 137: 216, 216, 474: 216, 507: 216}, - {133: 5382, 135: 5380, 137: 5383, 5381, 962: 5390}, - {217, 217, 15: 217, 48: 217, 133: 217, 135: 217, 137: 217, 217, 474: 217, 507: 217}, - {218, 218, 15: 218, 48: 218, 133: 218, 135: 218, 137: 218, 218, 474: 218, 507: 218}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5392}, + {15: 5478, 493: 5475, 917: 5477}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 685: 3598, 2850, 688: 2851, 2849, 760: 5469, 1212: 5468}, + {215, 215, 6: 215, 9: 215, 15: 215, 51: 215, 215, 215, 215, 215, 494: 215, 498: 5471, 681: 5470, 683: 215}, + {211, 211, 6: 211, 9: 211, 15: 211, 51: 211, 211, 211, 211, 211, 494: 211, 498: 211, 681: 211, 683: 211}, + {493: 5475, 917: 5476}, // 2855 - {650: 5393}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5298, 868: 5394}, - {172, 172, 9: 5300, 474: 5364, 1163: 5395}, - {174, 174}, - {2193, 2193, 9: 2193, 16: 2193, 18: 2193, 21: 2193, 479: 2193, 484: 2193, 498: 2193, 500: 2193, 505: 2193, 2193, 518: 2193, 647: 2193, 650: 2193}, + {493: 5473, 596: 5474, 1088: 5472}, + {213, 213, 6: 213, 9: 213, 15: 213, 51: 213, 213, 213, 213, 213, 494: 213, 683: 213}, + {210, 210, 6: 210, 9: 210, 15: 210, 51: 210, 210, 210, 210, 210, 494: 210, 683: 210}, + {209, 209, 6: 209, 9: 209, 15: 209, 51: 209, 209, 209, 209, 209, 494: 209, 683: 209}, + {778, 778, 6: 778, 9: 778, 15: 778, 51: 778, 778, 778, 778, 778, 58: 778, 494: 778, 683: 778}, // 2860 - {249, 249}, - {2: 854, 854, 854, 854, 854, 854, 854, 10: 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 50: 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 473: 854, 475: 854, 854, 854, 479: 854, 482: 854, 854, 485: 854, 854, 854, 489: 854, 492: 854, 495: 854, 854, 500: 854, 504: 854, 854, 508: 854, 515: 854, 520: 854, 530: 854, 564: 854, 567: 854, 854, 570: 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 582: 854, 854, 854, 854, 854, 854, 854, 854, 592: 854, 854, 595: 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 648: 854, 651: 854, 745: 854, 854, 753: 854, 854, 854, 762: 854, 769: 854, 854, 854}, - {2: 852, 852, 852, 852, 852, 852, 852, 10: 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 50: 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 473: 852, 489: 852, 496: 852, 500: 852, 579: 852, 753: 852, 852, 852}, - {2: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 10: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 50: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 473: 1057, 489: 1057, 579: 1057, 753: 5403, 5402, 5401, 837: 5404, 887: 5405}, - {2: 1060, 1060, 1060, 1060, 1060, 1060, 1060, 10: 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 50: 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 473: 1060, 475: 1060, 1060, 1060, 479: 1060, 482: 1060, 1060, 485: 1060, 1060, 1060, 489: 1060, 492: 1060, 495: 1060, 1060, 500: 1060, 504: 1060, 1060, 508: 1060, 515: 1060, 520: 1060, 530: 1060, 564: 1060, 567: 1060, 1060, 570: 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 582: 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 592: 1060, 1060, 595: 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 648: 1060, 651: 1060, 745: 1060, 1060, 753: 1060, 1060, 1060, 762: 1060, 769: 1060, 1060, 1060}, + {214, 214, 6: 214, 9: 214, 15: 214, 51: 214, 214, 214, 214, 214, 494: 214, 683: 214}, + {216, 216, 6: 216, 9: 216, 15: 216, 51: 216, 216, 216, 216, 216, 494: 216, 683: 216}, + {493: 5473, 596: 5474, 1088: 5479}, + {212, 212, 6: 212, 9: 212, 15: 212, 51: 212, 212, 212, 212, 212, 494: 212, 683: 212}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 5481, 685: 5482, 2850, 688: 2851, 2849}, // 2865 - {2: 1059, 1059, 1059, 1059, 1059, 1059, 1059, 10: 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 50: 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 473: 1059, 475: 1059, 1059, 1059, 479: 1059, 482: 1059, 1059, 485: 1059, 1059, 1059, 489: 1059, 492: 1059, 495: 1059, 1059, 500: 1059, 504: 1059, 1059, 508: 1059, 515: 1059, 520: 1059, 530: 1059, 564: 1059, 567: 1059, 1059, 570: 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 582: 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 592: 1059, 1059, 595: 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 648: 1059, 651: 1059, 745: 1059, 1059, 753: 1059, 1059, 1059, 762: 1059, 769: 1059, 1059, 1059}, - {2: 1058, 1058, 1058, 1058, 1058, 1058, 1058, 10: 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 50: 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 473: 1058, 475: 1058, 1058, 1058, 479: 1058, 482: 1058, 1058, 485: 1058, 1058, 1058, 489: 1058, 492: 1058, 495: 1058, 1058, 500: 1058, 504: 1058, 1058, 508: 1058, 515: 1058, 520: 1058, 530: 1058, 564: 1058, 567: 1058, 1058, 570: 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 582: 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 592: 1058, 1058, 595: 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 648: 1058, 651: 1058, 745: 1058, 1058, 753: 1058, 1058, 1058, 762: 1058, 769: 1058, 1058, 1058}, - {2: 1056, 1056, 1056, 1056, 1056, 1056, 1056, 10: 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 50: 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 473: 1056, 489: 1056, 496: 1056, 500: 1056, 579: 1056}, - {2: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 10: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 50: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 473: 1856, 489: 4191, 579: 1856, 855: 5406}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 579: 5410, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5409, 852: 5407, 890: 5408}, + {520: 128, 670: 128}, + {520: 127, 670: 127}, + {541: 5484}, + {520: 129, 670: 129}, + {9: 172, 491: 172, 520: 172, 670: 172}, // 2870 - {931, 931, 9: 931, 49: 931, 472: 931, 474: 931, 480: 931, 931, 490: 931, 931, 493: 931, 931, 496: 931, 931, 931, 501: 931, 931, 506: 931, 513: 931, 931, 516: 931}, - {9: 5461, 506: 5531}, - {9: 929, 482: 5428, 5429, 506: 5518, 515: 5427, 517: 5430, 519: 5426, 521: 5431, 5432, 819: 5425, 823: 5424}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5515, 2762, 2763, 2761}, - {927, 927, 9: 927, 49: 927, 472: 927, 474: 927, 480: 927, 927, 927, 927, 490: 927, 927, 493: 927, 927, 496: 927, 927, 927, 501: 927, 927, 506: 927, 513: 927, 927, 927, 927, 927, 519: 927, 521: 927, 927, 927}, + {297: 5487}, + {9: 174, 491: 174, 520: 174, 670: 174}, + {297: 5489}, + {9: 175, 491: 175, 520: 175, 670: 175}, + {9: 179, 141: 179, 491: 179, 520: 179, 670: 179}, // 2875 - {926, 926, 9: 926, 49: 926, 472: 926, 474: 926, 480: 926, 926, 926, 926, 490: 926, 926, 493: 926, 926, 496: 926, 926, 926, 501: 926, 926, 506: 926, 513: 926, 926, 926, 926, 926, 519: 926, 521: 926, 926, 926}, - {922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 474: 922, 478: 922, 480: 922, 922, 922, 922, 488: 5465, 922, 922, 922, 493: 922, 922, 496: 922, 922, 922, 501: 922, 922, 922, 506: 922, 513: 922, 922, 922, 922, 922, 519: 922, 521: 922, 922, 922, 525: 922, 922, 673: 922, 860: 5464}, - {920, 920, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 920, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 920, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 920, 474: 920, 478: 5422, 480: 920, 920, 920, 920, 490: 920, 920, 493: 920, 920, 496: 920, 920, 920, 501: 920, 920, 506: 920, 513: 920, 920, 920, 920, 920, 519: 920, 521: 920, 920, 920, 661: 5421, 2762, 2763, 2761, 915: 5420, 5419}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 2587, 495: 2586, 569: 2585, 579: 5410, 646: 2581, 661: 3921, 2762, 2763, 2761, 709: 5418, 737: 5413, 748: 3881, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 3883, 3882, 798: 5412, 802: 5411, 5417, 852: 5407, 890: 5416}, - {9: 5461, 49: 5462}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 685: 3598, 2850, 688: 2851, 2849, 760: 5493}, + {774, 774, 9: 774, 491: 774, 520: 774, 670: 774}, + {775, 775, 9: 775, 491: 775, 520: 775, 670: 775}, + {9: 150, 491: 150, 150, 520: 150, 670: 150}, + {9: 149, 491: 149, 149, 520: 149, 670: 149}, // 2880 - {929, 929, 9: 929, 49: 929, 472: 929, 474: 929, 480: 929, 929, 5428, 5429, 490: 929, 929, 493: 929, 929, 496: 929, 929, 929, 501: 929, 929, 506: 929, 513: 929, 929, 5427, 929, 5430, 519: 5426, 521: 5431, 5432, 819: 5425, 823: 5424}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 920, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 3974, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 478: 5422, 480: 814, 482: 920, 920, 490: 814, 814, 493: 2728, 501: 2729, 2725, 515: 920, 517: 920, 519: 920, 521: 920, 920, 661: 5421, 2762, 2763, 2761, 767: 3891, 3892, 915: 5420, 5419}, - {924, 924, 9: 924, 49: 924, 472: 924, 474: 924, 480: 924, 924, 924, 924, 490: 924, 924, 493: 924, 924, 496: 924, 924, 924, 501: 924, 924, 506: 924, 513: 924, 924, 924, 924, 924, 519: 924, 521: 924, 924, 924}, - {919, 919, 9: 919, 49: 919, 472: 919, 474: 919, 480: 919, 919, 919, 919, 489: 919, 919, 919, 493: 919, 919, 496: 919, 919, 919, 501: 919, 919, 919, 506: 919, 513: 919, 919, 919, 919, 919, 519: 919, 521: 919, 919, 919, 525: 919, 919, 673: 919}, - {918, 918, 9: 918, 49: 918, 472: 918, 474: 918, 480: 918, 918, 918, 918, 489: 918, 918, 918, 493: 918, 918, 496: 918, 918, 918, 501: 918, 918, 918, 506: 918, 513: 918, 918, 918, 918, 918, 519: 918, 521: 918, 918, 918, 525: 918, 918, 673: 918}, + {491: 5538, 589: 1808, 684: 1808}, + {9: 5438, 491: 5498, 670: 5499}, + {2: 134, 134, 134, 134, 134, 134, 134, 10: 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 59: 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 5452, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 541: 134, 588: 5451, 984: 5453, 1113: 5501}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5443, 891: 5500}, + {187, 187, 9: 5445}, // 2885 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5423, 2762, 2763, 2761}, - {917, 917, 9: 917, 49: 917, 472: 917, 474: 917, 480: 917, 917, 917, 917, 489: 917, 917, 917, 493: 917, 917, 496: 917, 917, 917, 501: 917, 917, 917, 506: 917, 513: 917, 917, 917, 917, 917, 519: 917, 521: 917, 917, 917, 525: 917, 917, 673: 917}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5454}, - {517: 888, 908: 5441, 1096: 5445}, - {482: 5428, 5429, 517: 5438, 819: 5439}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 5455, 685: 5456, 2850, 688: 2851, 2849, 1137: 5502}, + {670: 5503}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5459, 915: 5460, 947: 5504}, + {253, 253, 9: 5462, 494: 253, 683: 5506, 985: 5505, 5507}, + {252, 252, 6: 252, 15: 252, 51: 252, 252, 252, 252, 252, 494: 252}, // 2890 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5435}, - {517: 890, 908: 890}, - {517: 889, 908: 889}, - {2: 886, 886, 886, 886, 886, 886, 886, 10: 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 50: 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 473: 886}, - {517: 5434}, + {140: 5527, 142: 5525, 148: 5528, 5526, 5529, 377: 5520, 424: 5522, 987: 5524, 1321: 5523, 1340: 5521}, + {186, 186, 494: 5509, 1196: 5508}, + {189, 189}, + {143: 5513, 5511, 5512, 5514, 877: 5510}, + {931: 5519}, // 2895 - {517: 5433}, - {2: 884, 884, 884, 884, 884, 884, 884, 10: 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 50: 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 473: 884}, - {2: 885, 885, 885, 885, 885, 885, 885, 10: 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 50: 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 473: 885}, - {892, 892, 9: 892, 49: 892, 472: 5436, 474: 892, 480: 892, 892, 892, 892, 490: 892, 892, 493: 892, 892, 496: 892, 892, 892, 501: 892, 892, 506: 892, 513: 892, 892, 892, 892, 892, 519: 892, 521: 892, 892, 892, 819: 5425, 823: 5424}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5437}, + {525: 2824, 755: 5518}, + {525: 2824, 755: 5517}, + {525: 2824, 755: 5516}, + {525: 2824, 755: 5515}, + {181, 181}, // 2900 - {891, 891, 9: 891, 49: 891, 472: 891, 474: 891, 480: 891, 891, 891, 891, 490: 891, 891, 493: 891, 891, 496: 891, 891, 891, 501: 891, 891, 506: 891, 3345, 509: 3343, 3344, 3342, 3340, 891, 891, 891, 891, 891, 519: 891, 521: 891, 891, 891, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5444}, - {517: 888, 908: 5441, 1096: 5440}, - {517: 5442}, - {517: 887}, + {182, 182}, + {183, 183}, + {184, 184}, + {185, 185}, + {251, 251, 6: 251, 15: 251, 51: 251, 251, 251, 251, 251, 494: 251}, // 2905 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5443}, - {893, 893, 9: 893, 49: 893, 472: 893, 474: 893, 480: 893, 893, 893, 893, 490: 893, 893, 493: 893, 893, 496: 893, 893, 893, 501: 893, 893, 506: 893, 513: 893, 893, 893, 893, 893, 519: 893, 521: 893, 893, 893, 819: 5425, 823: 5424}, - {894, 894, 9: 894, 49: 894, 472: 894, 474: 894, 480: 894, 894, 894, 894, 490: 894, 894, 493: 894, 894, 496: 894, 894, 894, 501: 894, 894, 506: 894, 513: 894, 894, 894, 894, 894, 519: 894, 521: 894, 894, 894, 819: 5425, 823: 5424}, - {517: 5446}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5447}, + {250, 250, 6: 250, 15: 250, 51: 250, 250, 250, 250, 250, 494: 250}, + {249, 249, 6: 249, 15: 249, 51: 249, 249, 249, 249, 249, 494: 249}, + {248, 248, 6: 248, 15: 248, 51: 248, 248, 248, 248, 248, 140: 5527, 142: 5525, 148: 5528, 5526, 5529, 494: 248, 527: 5535, 987: 5536}, + {247, 247, 6: 247, 15: 247, 51: 247, 247, 247, 247, 247, 140: 247, 142: 247, 148: 247, 247, 247, 494: 247, 527: 247}, + {493: 5534}, // 2910 - {472: 5448, 481: 5449, 5428, 5429, 515: 5427, 517: 5430, 519: 5426, 521: 5431, 5432, 819: 5425, 823: 5424}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5453}, - {473: 5450}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 5451}, - {9: 4146, 49: 5452}, + {493: 5533}, + {493: 5532}, + {493: 5531}, + {493: 5530}, + {240, 240, 6: 240, 15: 240, 51: 240, 240, 240, 240, 240, 140: 240, 142: 240, 148: 240, 240, 240, 494: 240, 527: 240}, // 2915 - {895, 895, 9: 895, 49: 895, 472: 895, 474: 895, 480: 895, 895, 895, 895, 490: 895, 895, 493: 895, 895, 496: 895, 895, 895, 501: 895, 895, 506: 895, 513: 895, 895, 895, 895, 895, 519: 895, 521: 895, 895, 895}, - {896, 896, 9: 896, 49: 896, 472: 896, 474: 896, 480: 896, 896, 896, 896, 490: 896, 896, 493: 896, 896, 496: 896, 896, 896, 501: 896, 896, 506: 896, 3345, 509: 3343, 3344, 3342, 3340, 896, 896, 896, 896, 896, 519: 896, 521: 896, 896, 896, 734: 3341, 3339}, - {899, 899, 9: 899, 49: 899, 472: 5455, 474: 899, 480: 899, 5456, 5428, 5429, 490: 899, 899, 493: 899, 899, 496: 899, 899, 899, 501: 899, 899, 506: 899, 513: 899, 899, 5427, 899, 5430, 519: 5426, 521: 5431, 5432, 899, 819: 5425, 823: 5424}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5460}, - {473: 5457}, + {241, 241, 6: 241, 15: 241, 51: 241, 241, 241, 241, 241, 140: 241, 142: 241, 148: 241, 241, 241, 494: 241, 527: 241}, + {242, 242, 6: 242, 15: 242, 51: 242, 242, 242, 242, 242, 140: 242, 142: 242, 148: 242, 242, 242, 494: 242, 527: 242}, + {243, 243, 6: 243, 15: 243, 51: 243, 243, 243, 243, 243, 140: 243, 142: 243, 148: 243, 243, 243, 494: 243, 527: 243}, + {244, 244, 6: 244, 15: 244, 51: 244, 244, 244, 244, 244, 140: 244, 142: 244, 148: 244, 244, 244, 494: 244, 527: 244}, + {140: 5527, 142: 5525, 148: 5528, 5526, 5529, 987: 5537}, // 2920 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 5458}, - {9: 4146, 49: 5459}, - {897, 897, 9: 897, 49: 897, 472: 897, 474: 897, 480: 897, 897, 897, 897, 490: 897, 897, 493: 897, 897, 496: 897, 897, 897, 501: 897, 897, 506: 897, 513: 897, 897, 897, 897, 897, 519: 897, 521: 897, 897, 897}, - {898, 898, 9: 898, 49: 898, 472: 898, 474: 898, 480: 898, 898, 898, 898, 490: 898, 898, 493: 898, 898, 496: 898, 898, 898, 501: 898, 898, 506: 898, 3345, 509: 3343, 3344, 3342, 3340, 898, 898, 898, 898, 898, 519: 898, 521: 898, 898, 898, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 579: 5410, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5417, 852: 5463}, + {245, 245, 6: 245, 15: 245, 51: 245, 245, 245, 245, 245, 140: 245, 142: 245, 148: 245, 245, 245, 494: 245, 527: 245}, + {246, 246, 6: 246, 15: 246, 51: 246, 246, 246, 246, 246, 140: 246, 142: 246, 148: 246, 246, 246, 494: 246, 527: 246}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5539}, + {670: 5540}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5443, 891: 5541}, // 2925 - {923, 923, 9: 923, 49: 923, 472: 923, 474: 923, 480: 923, 923, 923, 923, 490: 923, 923, 493: 923, 923, 496: 923, 923, 923, 501: 923, 923, 506: 923, 513: 923, 923, 923, 923, 923, 519: 923, 521: 923, 923, 923}, - {930, 930, 9: 930, 49: 930, 472: 930, 474: 930, 480: 930, 930, 490: 930, 930, 493: 930, 930, 496: 930, 930, 930, 501: 930, 930, 506: 930, 513: 930, 930, 516: 930}, - {920, 920, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 920, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 920, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 920, 474: 920, 478: 5422, 480: 920, 920, 920, 920, 489: 920, 920, 920, 493: 920, 920, 496: 920, 920, 920, 501: 920, 920, 920, 506: 920, 513: 920, 920, 920, 920, 920, 519: 920, 521: 920, 920, 920, 525: 920, 920, 661: 5421, 2762, 2763, 2761, 673: 920, 915: 5420, 5469}, - {473: 5466}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 5467}, + {186, 186, 9: 5445, 494: 5509, 1196: 5542}, + {188, 188}, + {2256, 2256, 9: 2256, 16: 2256, 18: 2256, 21: 2256, 496: 2256, 499: 2256, 514: 2256, 519: 2256, 2256, 526: 2256, 537: 2256, 667: 2256, 670: 2256, 698: 2256}, + {277, 277}, + {2: 893, 893, 893, 893, 893, 893, 893, 10: 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 59: 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 492: 893, 893, 495: 893, 893, 893, 502: 893, 893, 893, 893, 893, 508: 893, 510: 893, 514: 893, 893, 893, 520: 893, 522: 893, 525: 893, 534: 893, 541: 893, 549: 893, 583: 893, 587: 893, 589: 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 601: 893, 893, 893, 893, 893, 893, 608: 893, 893, 893, 893, 893, 614: 893, 893, 617: 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, 669: 893, 671: 893, 767: 893, 893, 775: 893, 893, 893, 785: 893, 792: 893, 893, 893}, // 2930 - {9: 4755, 49: 5468}, - {921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 478: 921, 480: 921, 921, 921, 921, 489: 921, 921, 921, 493: 921, 921, 921, 921, 921, 921, 501: 921, 921, 921, 506: 921, 513: 921, 921, 921, 921, 921, 519: 921, 521: 921, 921, 921, 525: 921, 921, 563: 921, 569: 921, 646: 921, 649: 921, 660: 921, 673: 921}, - {1863, 1863, 9: 1863, 49: 1863, 472: 1863, 474: 1863, 480: 1863, 1863, 1863, 1863, 489: 1863, 1863, 1863, 493: 1863, 1863, 496: 1863, 1863, 1863, 501: 1863, 1863, 1863, 506: 1863, 513: 1863, 1863, 1863, 1863, 1863, 519: 1863, 521: 1863, 1863, 1863, 525: 1863, 1863, 673: 5471, 924: 5470, 1175: 5472}, - {1862, 1862, 9: 1862, 49: 1862, 472: 1862, 474: 1862, 480: 1862, 1862, 1862, 1862, 489: 1862, 1862, 1862, 493: 1862, 1862, 496: 1862, 1862, 1862, 501: 1862, 1862, 1862, 506: 1862, 513: 1862, 1862, 1862, 1862, 1862, 519: 1862, 521: 1862, 1862, 1862, 525: 1862, 1862}, - {199: 5513}, + {2: 891, 891, 891, 891, 891, 891, 891, 10: 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 59: 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 492: 891, 508: 891, 516: 891, 520: 891, 601: 891, 775: 891, 891, 891}, + {2: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 10: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 59: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 492: 1096, 508: 1096, 601: 1096, 775: 5550, 5549, 5548, 861: 5551, 910: 5552}, + {2: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 10: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 59: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 492: 1099, 1099, 495: 1099, 1099, 1099, 502: 1099, 1099, 1099, 1099, 1099, 508: 1099, 510: 1099, 514: 1099, 1099, 1099, 520: 1099, 522: 1099, 525: 1099, 534: 1099, 541: 1099, 549: 1099, 583: 1099, 587: 1099, 589: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 601: 1099, 1099, 1099, 1099, 1099, 1099, 608: 1099, 1099, 1099, 1099, 1099, 614: 1099, 1099, 617: 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, 669: 1099, 671: 1099, 767: 1099, 1099, 775: 1099, 1099, 1099, 785: 1099, 792: 1099, 1099, 1099}, + {2: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 10: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 59: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 492: 1098, 1098, 495: 1098, 1098, 1098, 502: 1098, 1098, 1098, 1098, 1098, 508: 1098, 510: 1098, 514: 1098, 1098, 1098, 520: 1098, 522: 1098, 525: 1098, 534: 1098, 541: 1098, 549: 1098, 583: 1098, 587: 1098, 589: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 601: 1098, 1098, 1098, 1098, 1098, 1098, 608: 1098, 1098, 1098, 1098, 1098, 614: 1098, 1098, 617: 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 669: 1098, 671: 1098, 767: 1098, 1098, 775: 1098, 1098, 1098, 785: 1098, 792: 1098, 1098, 1098}, + {2: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 10: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 59: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 492: 1097, 1097, 495: 1097, 1097, 1097, 502: 1097, 1097, 1097, 1097, 1097, 508: 1097, 510: 1097, 514: 1097, 1097, 1097, 520: 1097, 522: 1097, 525: 1097, 534: 1097, 541: 1097, 549: 1097, 583: 1097, 587: 1097, 589: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 601: 1097, 1097, 1097, 1097, 1097, 1097, 608: 1097, 1097, 1097, 1097, 1097, 614: 1097, 1097, 617: 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 669: 1097, 671: 1097, 767: 1097, 1097, 775: 1097, 1097, 1097, 785: 1097, 792: 1097, 1097, 1097}, // 2935 - {901, 901, 9: 901, 49: 901, 472: 901, 474: 901, 480: 901, 901, 901, 901, 489: 5475, 901, 901, 493: 901, 901, 496: 901, 901, 901, 501: 901, 901, 5476, 506: 901, 513: 901, 901, 901, 901, 901, 519: 901, 521: 901, 901, 901, 525: 5474, 901, 940: 5478, 5477, 1062: 5479, 5473}, - {1016, 1016, 9: 1016, 49: 1016, 472: 1016, 474: 1016, 480: 1016, 1016, 1016, 1016, 490: 1016, 1016, 493: 1016, 1016, 496: 1016, 1016, 1016, 501: 1016, 1016, 506: 1016, 513: 1016, 1016, 1016, 1016, 1016, 519: 1016, 521: 1016, 1016, 1016, 526: 5494, 1324: 5495}, - {581: 4410, 649: 4411, 828: 5493}, - {581: 4410, 649: 4411, 828: 5492}, - {581: 4410, 649: 4411, 828: 5491}, + {2: 1095, 1095, 1095, 1095, 1095, 1095, 1095, 10: 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 59: 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 492: 1095, 508: 1095, 516: 1095, 520: 1095, 601: 1095}, + {2: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 10: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 59: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 492: 1916, 508: 4304, 601: 1916, 878: 5553}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 601: 5557, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5556, 875: 5554, 914: 5555}, + {970, 970, 9: 970, 58: 970, 491: 970, 494: 970, 500: 970, 970, 509: 970, 511: 970, 970, 970, 516: 970, 518: 970, 970, 521: 970, 523: 970, 526: 970, 532: 970, 970, 535: 970}, + {9: 5608, 526: 5678}, // 2940 - {473: 913, 494: 5481, 1231: 5482}, - {903, 903, 9: 903, 49: 903, 472: 903, 474: 903, 480: 903, 903, 903, 903, 489: 903, 903, 903, 493: 903, 903, 496: 903, 903, 903, 501: 903, 903, 903, 506: 903, 513: 903, 903, 903, 903, 903, 519: 903, 521: 903, 903, 903, 525: 903, 903}, - {900, 900, 9: 900, 49: 900, 472: 900, 474: 900, 480: 900, 900, 900, 900, 489: 5475, 900, 900, 493: 900, 900, 496: 900, 900, 900, 501: 900, 900, 5476, 506: 900, 513: 900, 900, 900, 900, 900, 519: 900, 521: 900, 900, 900, 525: 5474, 900, 940: 5480, 5477}, - {902, 902, 9: 902, 49: 902, 472: 902, 474: 902, 480: 902, 902, 902, 902, 489: 902, 902, 902, 493: 902, 902, 496: 902, 902, 902, 501: 902, 902, 902, 506: 902, 513: 902, 902, 902, 902, 902, 519: 902, 521: 902, 902, 902, 525: 902, 902}, - {502: 5487, 513: 5488, 517: 5486}, + {9: 968, 502: 5575, 5576, 526: 5665, 534: 5574, 536: 5577, 538: 5573, 5578, 5579, 841: 5572, 845: 5571}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5662, 2850, 688: 2851, 2849}, + {966, 966, 9: 966, 58: 966, 491: 966, 494: 966, 500: 966, 966, 966, 966, 509: 966, 511: 966, 966, 966, 516: 966, 518: 966, 966, 521: 966, 523: 966, 526: 966, 532: 966, 966, 966, 966, 966, 538: 966, 966, 966, 542: 966}, + {965, 965, 9: 965, 58: 965, 491: 965, 494: 965, 500: 965, 965, 965, 965, 509: 965, 511: 965, 965, 965, 516: 965, 518: 965, 965, 521: 965, 523: 965, 526: 965, 532: 965, 965, 965, 965, 965, 538: 965, 965, 965, 542: 965}, + {961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 494: 961, 498: 961, 500: 961, 961, 961, 961, 507: 5612, 961, 961, 511: 961, 961, 961, 516: 961, 518: 961, 961, 521: 961, 523: 961, 961, 526: 961, 532: 961, 961, 961, 961, 961, 538: 961, 961, 961, 542: 961, 544: 961, 961, 694: 961, 883: 5611}, // 2945 - {473: 5483}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 908, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 908, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 591: 5032, 661: 5031, 2762, 2763, 2761, 857: 5484}, - {9: 5034, 49: 5485}, - {909, 909, 9: 909, 49: 909, 472: 909, 474: 909, 480: 909, 909, 909, 909, 489: 909, 909, 909, 493: 909, 909, 496: 909, 909, 909, 501: 909, 909, 909, 506: 909, 513: 909, 909, 909, 909, 909, 519: 909, 521: 909, 909, 909, 525: 909, 909}, - {473: 912}, + {959, 959, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 959, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 959, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 959, 494: 959, 498: 5569, 500: 959, 959, 959, 959, 509: 959, 511: 959, 959, 959, 516: 959, 518: 959, 959, 521: 959, 523: 959, 526: 959, 532: 959, 959, 959, 959, 959, 538: 959, 959, 959, 542: 959, 685: 5568, 2850, 688: 2851, 2849, 940: 5567, 5566}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 494: 2666, 515: 2665, 588: 2664, 601: 5557, 665: 2660, 685: 4030, 2850, 688: 2851, 2849, 731: 5565, 759: 5560, 770: 3990, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 3992, 3991, 820: 5559, 824: 5558, 5564, 875: 5554, 914: 5563}, + {9: 5608, 58: 5609}, + {968, 968, 9: 968, 58: 968, 491: 968, 494: 968, 500: 968, 968, 5575, 5576, 509: 968, 511: 968, 968, 968, 516: 968, 518: 968, 968, 521: 968, 523: 968, 526: 968, 532: 968, 968, 5574, 968, 5577, 538: 5573, 5578, 5579, 841: 5572, 845: 5571}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 959, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 4083, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 498: 5569, 500: 853, 502: 959, 959, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 534: 959, 536: 959, 538: 959, 959, 959, 685: 5568, 2850, 688: 2851, 2849, 790: 4000, 4001, 940: 5567, 5566}, // 2950 - {660: 5490}, - {660: 5489}, - {473: 910}, - {473: 911}, - {473: 914, 494: 914}, + {963, 963, 9: 963, 58: 963, 491: 963, 494: 963, 500: 963, 963, 963, 963, 509: 963, 511: 963, 963, 963, 516: 963, 518: 963, 963, 521: 963, 523: 963, 526: 963, 532: 963, 963, 963, 963, 963, 538: 963, 963, 963, 542: 963}, + {958, 958, 9: 958, 58: 958, 491: 958, 494: 958, 500: 958, 958, 958, 958, 508: 958, 958, 511: 958, 958, 958, 516: 958, 518: 958, 958, 521: 958, 523: 958, 958, 526: 958, 532: 958, 958, 958, 958, 958, 538: 958, 958, 958, 542: 958, 544: 958, 958, 694: 958}, + {957, 957, 9: 957, 58: 957, 491: 957, 494: 957, 500: 957, 957, 957, 957, 508: 957, 957, 511: 957, 957, 957, 516: 957, 518: 957, 957, 521: 957, 523: 957, 957, 526: 957, 532: 957, 957, 957, 957, 957, 538: 957, 957, 957, 542: 957, 544: 957, 957, 694: 957}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5570, 2850, 688: 2851, 2849}, + {956, 956, 9: 956, 58: 956, 491: 956, 494: 956, 500: 956, 956, 956, 956, 508: 956, 956, 511: 956, 956, 956, 516: 956, 518: 956, 956, 521: 956, 523: 956, 956, 526: 956, 532: 956, 956, 956, 956, 956, 538: 956, 956, 956, 542: 956, 544: 956, 956, 694: 956}, // 2955 - {473: 915, 494: 915}, - {473: 916, 494: 916}, - {88: 5499, 314: 5498, 394: 5497, 473: 1013, 1323: 5496}, - {925, 925, 9: 925, 49: 925, 472: 925, 474: 925, 480: 925, 925, 925, 925, 490: 925, 925, 493: 925, 925, 496: 925, 925, 925, 501: 925, 925, 506: 925, 513: 925, 925, 925, 925, 925, 519: 925, 521: 925, 925, 925}, - {473: 5500}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5601}, + {536: 927, 933: 5588, 1126: 5592}, + {502: 5575, 5576, 536: 5585, 841: 5586}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5582}, + {536: 929, 933: 929}, // 2960 - {473: 1012}, - {473: 1011}, - {473: 1010}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 5502, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5501}, - {49: 1009, 372: 5510, 507: 3345, 509: 3343, 3344, 3342, 3340, 524: 5509, 734: 3341, 3339, 1325: 5508}, + {536: 928, 933: 928}, + {2: 925, 925, 925, 925, 925, 925, 925, 10: 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 59: 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, 492: 925}, + {536: 5581}, + {536: 5580}, + {2: 923, 923, 923, 923, 923, 923, 923, 10: 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 59: 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, 492: 923}, // 2965 - {1006, 1006, 9: 1006, 49: 1006, 220: 5504, 472: 1006, 474: 1006, 480: 1006, 1006, 1006, 1006, 490: 1006, 1006, 493: 1006, 1006, 496: 1006, 1006, 1006, 501: 1006, 1006, 506: 1006, 513: 1006, 1006, 1006, 1006, 1006, 519: 1006, 521: 1006, 1006, 1006, 1115: 5503}, - {1014, 1014, 9: 1014, 49: 1014, 472: 1014, 474: 1014, 480: 1014, 1014, 1014, 1014, 490: 1014, 1014, 493: 1014, 1014, 496: 1014, 1014, 1014, 501: 1014, 1014, 506: 1014, 513: 1014, 1014, 1014, 1014, 1014, 519: 1014, 521: 1014, 1014, 1014}, - {473: 5505}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5506}, - {49: 5507, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, + {2: 924, 924, 924, 924, 924, 924, 924, 10: 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 59: 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 492: 924}, + {931, 931, 9: 931, 58: 931, 491: 5583, 494: 931, 500: 931, 931, 931, 931, 509: 931, 511: 931, 931, 931, 516: 931, 518: 931, 931, 521: 931, 523: 931, 526: 931, 532: 931, 931, 931, 931, 931, 538: 931, 931, 931, 542: 931, 841: 5572, 845: 5571}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5584}, + {930, 930, 9: 930, 58: 930, 491: 930, 494: 930, 500: 930, 930, 930, 930, 509: 930, 511: 930, 930, 930, 516: 930, 518: 930, 930, 521: 930, 523: 930, 526: 930, 3452, 3450, 3451, 3449, 3447, 930, 930, 930, 930, 930, 538: 930, 930, 930, 542: 930, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5591}, // 2970 - {1005, 1005, 9: 1005, 49: 1005, 472: 1005, 474: 1005, 480: 1005, 1005, 1005, 1005, 490: 1005, 1005, 493: 1005, 1005, 496: 1005, 1005, 1005, 501: 1005, 1005, 506: 1005, 513: 1005, 1005, 1005, 1005, 1005, 519: 1005, 521: 1005, 1005, 1005}, - {49: 5511}, - {49: 1008}, - {49: 1007}, - {1006, 1006, 9: 1006, 49: 1006, 220: 5504, 472: 1006, 474: 1006, 480: 1006, 1006, 1006, 1006, 490: 1006, 1006, 493: 1006, 1006, 496: 1006, 1006, 1006, 501: 1006, 1006, 506: 1006, 513: 1006, 1006, 1006, 1006, 1006, 519: 1006, 521: 1006, 1006, 1006, 1115: 5512}, + {536: 927, 933: 5588, 1126: 5587}, + {536: 5589}, + {536: 926}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5590}, + {932, 932, 9: 932, 58: 932, 491: 932, 494: 932, 500: 932, 932, 932, 932, 509: 932, 511: 932, 932, 932, 516: 932, 518: 932, 932, 521: 932, 523: 932, 526: 932, 532: 932, 932, 932, 932, 932, 538: 932, 932, 932, 542: 932, 841: 5572, 845: 5571}, // 2975 - {1015, 1015, 9: 1015, 49: 1015, 472: 1015, 474: 1015, 480: 1015, 1015, 1015, 1015, 490: 1015, 1015, 493: 1015, 1015, 496: 1015, 1015, 1015, 501: 1015, 1015, 506: 1015, 513: 1015, 1015, 1015, 1015, 1015, 519: 1015, 521: 1015, 1015, 1015}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5514}, - {1861, 1861, 9: 1861, 49: 1861, 472: 1861, 474: 1861, 480: 1861, 1861, 1861, 1861, 489: 1861, 1861, 1861, 493: 1861, 1861, 496: 1861, 1861, 1861, 501: 1861, 1861, 1861, 506: 1861, 3345, 509: 3343, 3344, 3342, 3340, 1861, 1861, 1861, 1861, 1861, 519: 1861, 521: 1861, 1861, 1861, 525: 1861, 1861, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5516}, - {482: 5428, 5429, 515: 5427, 517: 5430, 519: 5426, 521: 5431, 5432, 5517, 819: 5425, 823: 5424}, + {933, 933, 9: 933, 58: 933, 491: 933, 494: 933, 500: 933, 933, 933, 933, 509: 933, 511: 933, 933, 933, 516: 933, 518: 933, 933, 521: 933, 523: 933, 526: 933, 532: 933, 933, 933, 933, 933, 538: 933, 933, 933, 542: 933, 841: 5572, 845: 5571}, + {536: 5593}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5594}, + {491: 5595, 501: 5596, 5575, 5576, 534: 5574, 536: 5577, 538: 5573, 5578, 5579, 841: 5572, 845: 5571}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5600}, // 2980 - {928, 928, 9: 928, 49: 928, 472: 928, 474: 928, 480: 928, 928, 490: 928, 928, 493: 928, 928, 496: 928, 928, 928, 501: 928, 928, 506: 928, 513: 928, 928, 516: 928}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 5519, 892: 5520, 925: 5521}, - {499: 5529}, - {2355, 2355, 9: 2355, 481: 2355, 493: 2355, 498: 2355, 502: 2355}, - {247, 247, 9: 5522, 481: 247, 493: 247, 498: 2722, 502: 247, 790: 2723, 5523}, + {492: 5597}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 5598}, + {9: 4259, 58: 5599}, + {934, 934, 9: 934, 58: 934, 491: 934, 494: 934, 500: 934, 934, 934, 934, 509: 934, 511: 934, 934, 934, 516: 934, 518: 934, 934, 521: 934, 523: 934, 526: 934, 532: 934, 934, 934, 934, 934, 538: 934, 934, 934, 542: 934}, + {935, 935, 9: 935, 58: 935, 491: 935, 494: 935, 500: 935, 935, 935, 935, 509: 935, 511: 935, 935, 935, 516: 935, 518: 935, 935, 521: 935, 523: 935, 526: 935, 3452, 3450, 3451, 3449, 3447, 935, 935, 935, 935, 935, 538: 935, 935, 935, 542: 935, 756: 3448, 3446}, // 2985 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 5519, 892: 5528}, - {1297, 1297, 481: 1297, 493: 1297, 502: 2725, 767: 2726, 812: 5524}, - {883, 883, 481: 883, 493: 5525, 1071: 5526}, - {508: 2736, 577: 2738, 733: 2735, 741: 2737, 882: 5527}, - {251, 251, 481: 251}, + {938, 938, 9: 938, 58: 938, 491: 5602, 494: 938, 500: 938, 5603, 5575, 5576, 509: 938, 511: 938, 938, 938, 516: 938, 518: 938, 938, 521: 938, 523: 938, 526: 938, 532: 938, 938, 5574, 938, 5577, 538: 5573, 5578, 5579, 542: 938, 841: 5572, 845: 5571}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5607}, + {492: 5604}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 5605}, + {9: 4259, 58: 5606}, // 2990 - {882, 882, 481: 882}, - {2354, 2354, 9: 2354, 481: 2354, 493: 2354, 498: 2354, 502: 2354}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5530}, - {2356, 2356, 9: 2356, 481: 2356, 493: 2356, 498: 2356, 502: 2356}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 5519, 892: 5520, 925: 5532}, + {936, 936, 9: 936, 58: 936, 491: 936, 494: 936, 500: 936, 936, 936, 936, 509: 936, 511: 936, 936, 936, 516: 936, 518: 936, 936, 521: 936, 523: 936, 526: 936, 532: 936, 936, 936, 936, 936, 538: 936, 936, 936, 542: 936}, + {937, 937, 9: 937, 58: 937, 491: 937, 494: 937, 500: 937, 937, 937, 937, 509: 937, 511: 937, 937, 937, 516: 937, 518: 937, 937, 521: 937, 523: 937, 526: 937, 3452, 3450, 3451, 3449, 3447, 937, 937, 937, 937, 937, 538: 937, 937, 937, 542: 937, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 601: 5557, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5564, 875: 5610}, + {962, 962, 9: 962, 58: 962, 491: 962, 494: 962, 500: 962, 962, 962, 962, 509: 962, 511: 962, 962, 962, 516: 962, 518: 962, 962, 521: 962, 523: 962, 526: 962, 532: 962, 962, 962, 962, 962, 538: 962, 962, 962, 542: 962}, + {969, 969, 9: 969, 58: 969, 491: 969, 494: 969, 500: 969, 969, 509: 969, 511: 969, 969, 969, 516: 969, 518: 969, 969, 521: 969, 523: 969, 526: 969, 532: 969, 969, 535: 969}, // 2995 - {247, 247, 9: 5522, 481: 247, 498: 2722, 790: 2723, 5533}, - {250, 250, 481: 250}, - {2: 390, 390, 390, 390, 390, 390, 390, 10: 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 50: 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5536}, - {389, 389}, + {959, 959, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 959, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 959, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 959, 494: 959, 498: 5569, 500: 959, 959, 959, 959, 508: 959, 959, 511: 959, 959, 959, 516: 959, 518: 959, 959, 521: 959, 523: 959, 959, 526: 959, 532: 959, 959, 959, 959, 959, 538: 959, 959, 959, 542: 959, 544: 959, 959, 685: 5568, 2850, 688: 2851, 2849, 694: 959, 940: 5567, 5616}, + {492: 5613}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 5614}, + {9: 4886, 58: 5615}, + {960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 494: 960, 498: 960, 500: 960, 960, 960, 960, 508: 960, 960, 511: 960, 960, 960, 515: 960, 960, 518: 960, 960, 521: 960, 523: 960, 960, 526: 960, 532: 960, 960, 960, 960, 960, 538: 960, 960, 960, 542: 960, 544: 960, 960, 582: 960, 588: 960, 665: 960, 668: 960, 681: 960, 694: 960}, // 3000 - {22: 5549, 125: 5539, 5542, 145: 575, 190: 5541, 198: 5552, 209: 5550, 223: 5543, 235: 5547, 257: 5551, 260: 5544, 530: 5548, 569: 5538, 1148: 5546, 1220: 5540, 1249: 5545}, - {2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 10: 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 50: 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 474: 2049, 564: 2049}, - {2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 10: 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 50: 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 474: 2048, 564: 2048}, - {585, 585}, - {582, 582}, + {1923, 1923, 9: 1923, 58: 1923, 491: 1923, 494: 1923, 500: 1923, 1923, 1923, 1923, 508: 1923, 1923, 511: 1923, 1923, 1923, 516: 1923, 518: 1923, 1923, 521: 1923, 523: 1923, 1923, 526: 1923, 532: 1923, 1923, 1923, 1923, 1923, 538: 1923, 1923, 1923, 542: 1923, 544: 1923, 1923, 694: 5618, 949: 5617, 1209: 5619}, + {1922, 1922, 9: 1922, 58: 1922, 491: 1922, 494: 1922, 500: 1922, 1922, 1922, 1922, 508: 1922, 1922, 511: 1922, 1922, 1922, 516: 1922, 518: 1922, 1922, 521: 1922, 523: 1922, 1922, 526: 1922, 532: 1922, 1922, 1922, 1922, 1922, 538: 1922, 1922, 1922, 542: 1922, 544: 1922, 1922}, + {238: 5660}, + {940, 940, 9: 940, 58: 940, 491: 940, 494: 940, 500: 940, 940, 940, 940, 508: 5622, 940, 511: 940, 940, 940, 516: 940, 518: 940, 940, 521: 940, 523: 940, 5623, 526: 940, 532: 940, 940, 940, 940, 940, 538: 940, 940, 940, 542: 940, 544: 5621, 940, 966: 5625, 5624, 1092: 5626, 5620}, + {1055, 1055, 9: 1055, 58: 1055, 491: 1055, 494: 1055, 500: 1055, 1055, 1055, 1055, 509: 1055, 511: 1055, 1055, 1055, 516: 1055, 518: 1055, 1055, 521: 1055, 523: 1055, 526: 1055, 532: 1055, 1055, 1055, 1055, 1055, 538: 1055, 1055, 1055, 542: 1055, 545: 5641, 1359: 5642}, // 3005 - {581, 581}, - {216: 5559}, - {579, 579}, - {145: 5558}, - {566, 566, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 474: 566, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 4303, 1147: 5553}, + {600: 4536, 668: 4537, 850: 5640}, + {600: 4536, 668: 4537, 850: 5639}, + {600: 4536, 668: 4537, 850: 5638}, + {492: 952, 513: 5628, 1263: 5629}, + {942, 942, 9: 942, 58: 942, 491: 942, 494: 942, 500: 942, 942, 942, 942, 508: 942, 942, 511: 942, 942, 942, 516: 942, 518: 942, 942, 521: 942, 523: 942, 942, 526: 942, 532: 942, 942, 942, 942, 942, 538: 942, 942, 942, 542: 942, 544: 942, 942}, // 3010 - {576, 576}, - {145: 574}, - {145: 573}, - {145: 572}, - {145: 571}, + {939, 939, 9: 939, 58: 939, 491: 939, 494: 939, 500: 939, 939, 939, 939, 508: 5622, 939, 511: 939, 939, 939, 516: 939, 518: 939, 939, 521: 939, 523: 939, 5623, 526: 939, 532: 939, 939, 939, 939, 939, 538: 939, 939, 939, 542: 939, 544: 5621, 939, 966: 5627, 5624}, + {941, 941, 9: 941, 58: 941, 491: 941, 494: 941, 500: 941, 941, 941, 941, 508: 941, 941, 511: 941, 941, 941, 516: 941, 518: 941, 941, 521: 941, 523: 941, 941, 526: 941, 532: 941, 941, 941, 941, 941, 538: 941, 941, 941, 542: 941, 544: 941, 941}, + {523: 5634, 532: 5635, 536: 5633}, + {492: 5630}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 947, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 947, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 613: 5163, 685: 5162, 2850, 688: 2851, 2849, 880: 5631}, // 3015 - {145: 570}, - {562, 562, 474: 5555, 1352: 5554}, - {577, 577}, - {671: 5556}, - {497: 5557}, + {9: 5165, 58: 5632}, + {948, 948, 9: 948, 58: 948, 491: 948, 494: 948, 500: 948, 948, 948, 948, 508: 948, 948, 511: 948, 948, 948, 516: 948, 518: 948, 948, 521: 948, 523: 948, 948, 526: 948, 532: 948, 948, 948, 948, 948, 538: 948, 948, 948, 542: 948, 544: 948, 948}, + {492: 951}, + {681: 5637}, + {681: 5636}, // 3020 - {561, 561}, - {578, 578}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5560, 2762, 2763, 2761, 955: 5561}, - {584, 584, 9: 584}, - {580, 580, 9: 5562}, + {492: 949}, + {492: 950}, + {492: 953, 513: 953}, + {492: 954, 513: 954}, + {492: 955, 513: 955}, // 3025 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5563, 2762, 2763, 2761}, - {583, 583, 9: 583}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 5667, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 5668, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 5669, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5670}, - {569: 5653, 649: 5654}, - {649: 5650}, + {95: 5646, 329: 5645, 411: 5644, 492: 1052, 1358: 5643}, + {964, 964, 9: 964, 58: 964, 491: 964, 494: 964, 500: 964, 964, 964, 964, 509: 964, 511: 964, 964, 964, 516: 964, 518: 964, 964, 521: 964, 523: 964, 526: 964, 532: 964, 964, 964, 964, 964, 538: 964, 964, 964, 542: 964}, + {492: 5647}, + {492: 1051}, + {492: 1050}, // 3030 - {569: 5645, 649: 5644}, - {569: 5642}, - {332: 5636}, - {141: 5633, 221: 5635, 342: 5631, 367: 5632, 914: 5634}, - {205: 5628, 208: 5627}, + {492: 1049}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 5649, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5648}, + {58: 1048, 386: 5657, 527: 3452, 3450, 3451, 3449, 3447, 543: 5656, 756: 3448, 3446, 1360: 5655}, + {1045, 1045, 9: 1045, 58: 1045, 234: 5651, 491: 1045, 494: 1045, 500: 1045, 1045, 1045, 1045, 509: 1045, 511: 1045, 1045, 1045, 516: 1045, 518: 1045, 1045, 521: 1045, 523: 1045, 526: 1045, 532: 1045, 1045, 1045, 1045, 1045, 538: 1045, 1045, 1045, 542: 1045, 1145: 5650}, + {1053, 1053, 9: 1053, 58: 1053, 491: 1053, 494: 1053, 500: 1053, 1053, 1053, 1053, 509: 1053, 511: 1053, 1053, 1053, 516: 1053, 518: 1053, 1053, 521: 1053, 523: 1053, 526: 1053, 532: 1053, 1053, 1053, 1053, 1053, 538: 1053, 1053, 1053, 542: 1053}, // 3035 - {569: 5586}, - {141: 5580, 162: 5582, 172: 594, 197: 5584, 262: 5583, 1310: 5581}, - {141: 5579}, - {141: 5578}, - {397: 5577}, + {492: 5652}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5653}, + {58: 5654, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {1044, 1044, 9: 1044, 58: 1044, 491: 1044, 494: 1044, 500: 1044, 1044, 1044, 1044, 509: 1044, 511: 1044, 1044, 1044, 516: 1044, 518: 1044, 1044, 521: 1044, 523: 1044, 526: 1044, 532: 1044, 1044, 1044, 1044, 1044, 538: 1044, 1044, 1044, 542: 1044}, + {58: 5658}, // 3040 - {698, 698}, - {703, 703}, - {704, 704}, - {705, 705}, - {172: 5585}, + {58: 1047}, + {58: 1046}, + {1045, 1045, 9: 1045, 58: 1045, 234: 5651, 491: 1045, 494: 1045, 500: 1045, 1045, 1045, 1045, 509: 1045, 511: 1045, 1045, 1045, 516: 1045, 518: 1045, 1045, 521: 1045, 523: 1045, 526: 1045, 532: 1045, 1045, 1045, 1045, 1045, 538: 1045, 1045, 1045, 542: 1045, 1145: 5659}, + {1054, 1054, 9: 1054, 58: 1054, 491: 1054, 494: 1054, 500: 1054, 1054, 1054, 1054, 509: 1054, 511: 1054, 1054, 1054, 516: 1054, 518: 1054, 1054, 521: 1054, 523: 1054, 526: 1054, 532: 1054, 1054, 1054, 1054, 1054, 538: 1054, 1054, 1054, 542: 1054}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5661}, // 3045 - {172: 593}, - {172: 592}, - {172: 591}, - {697, 697}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5587}, + {1921, 1921, 9: 1921, 58: 1921, 491: 1921, 494: 1921, 500: 1921, 1921, 1921, 1921, 508: 1921, 1921, 511: 1921, 1921, 1921, 516: 1921, 518: 1921, 1921, 521: 1921, 523: 1921, 1921, 526: 1921, 3452, 3450, 3451, 3449, 3447, 1921, 1921, 1921, 1921, 1921, 538: 1921, 1921, 1921, 542: 1921, 544: 1921, 1921, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5663}, + {502: 5575, 5576, 534: 5574, 536: 5577, 538: 5573, 5578, 5579, 542: 5664, 841: 5572, 845: 5571}, + {967, 967, 9: 967, 58: 967, 491: 967, 494: 967, 500: 967, 967, 509: 967, 511: 967, 967, 967, 516: 967, 518: 967, 967, 521: 967, 523: 967, 526: 967, 532: 967, 967, 535: 967}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 5666, 916: 5667, 950: 5668}, // 3050 - {674: 5588, 931: 5589}, - {162: 5592, 167: 5591, 569: 2064, 950: 5590}, - {706, 706}, - {569: 5594}, - {125: 2063, 569: 2063}, + {517: 5676}, + {2422, 2422, 9: 2422, 501: 2422, 512: 2422, 519: 2422, 523: 2422}, + {275, 275, 9: 5669, 501: 275, 512: 275, 519: 2810, 523: 275, 814: 2811, 5670}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 5666, 916: 5675}, + {1338, 1338, 501: 1338, 512: 1338, 523: 2813, 790: 2814, 836: 5671}, // 3055 - {167: 5593}, - {125: 2062, 569: 2062}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 5595}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5596}, - {436, 436, 6: 436, 436, 436, 15: 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, 472: 436, 5600, 436, 478: 436, 436, 436, 484: 436, 488: 436, 436, 495: 436, 503: 436, 436, 436, 518: 5599, 569: 436, 646: 436, 436, 649: 436, 1244: 5598, 1320: 5597}, + {922, 922, 501: 922, 512: 5672, 1101: 5673}, + {525: 2824, 597: 2826, 755: 2823, 762: 2825, 905: 5674}, + {279, 279, 501: 279}, + {921, 921, 501: 921}, + {2421, 2421, 9: 2421, 501: 2421, 512: 2421, 519: 2421, 523: 2421}, // 3060 - {396, 396, 6: 4241, 4243, 400, 15: 4260, 2176, 4258, 4197, 4262, 4249, 4278, 4242, 4245, 4244, 4247, 4248, 4250, 4257, 400, 4268, 4269, 4255, 4256, 4261, 4263, 4275, 4274, 4280, 4276, 4273, 4266, 4271, 4272, 4265, 4267, 4270, 4259, 472: 396, 396, 396, 478: 396, 4240, 4277, 484: 2176, 488: 396, 396, 495: 396, 503: 4987, 396, 2176, 569: 396, 646: 396, 2176, 649: 4246, 781: 4251, 792: 4253, 813: 4252, 835: 4254, 838: 4264, 842: 4279, 919: 5615, 1017: 5614}, - {2179, 2179, 472: 5608, 1086: 5607}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5606}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 518: 5601, 581: 2406, 590: 2406, 2406, 642: 2406, 4589, 649: 2406, 661: 4143, 2762, 2763, 2761, 675: 2406, 2406, 744: 4456, 833: 4830, 848: 4962, 903: 4963, 968: 4964, 1145: 5602}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5604}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5677}, + {2423, 2423, 9: 2423, 501: 2423, 512: 2423, 519: 2423, 523: 2423}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 5666, 916: 5667, 950: 5679}, + {275, 275, 9: 5669, 501: 275, 519: 2810, 814: 2811, 5680}, + {278, 278, 501: 278}, // 3065 - {9: 4966, 49: 5603}, - {435, 435, 6: 435, 435, 435, 15: 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, 472: 435, 435, 435, 478: 435, 435, 435, 484: 435, 488: 435, 435, 495: 435, 503: 435, 435, 435, 569: 435, 646: 435, 435, 649: 435}, - {49: 5605}, - {2097, 2097, 472: 2097}, - {2098, 2098, 472: 2098}, + {2: 418, 418, 418, 418, 418, 418, 418, 10: 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 59: 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5683}, + {417, 417}, + {22: 5696, 137: 5686, 5689, 159: 612, 204: 5688, 212: 5699, 224: 5697, 237: 5690, 251: 5694, 272: 5698, 275: 5691, 549: 5695, 588: 5685, 1180: 5693, 1252: 5687, 1283: 5692}, + {2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 10: 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 59: 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 494: 2111, 583: 2111}, // 3070 - {2180, 2180}, - {147: 5609}, - {374: 5611, 739: 5610}, - {524: 5613}, - {524: 5612}, + {2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 10: 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 59: 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 494: 2110, 583: 2110}, + {622, 622}, + {619, 619}, + {618, 618}, + {230: 5706}, // 3075 - {2177, 2177}, - {2178, 2178}, - {2174, 2174, 472: 2174, 2174, 2174, 478: 2174, 488: 5617, 2174, 495: 2174, 504: 2174, 569: 2174, 646: 2174, 1100: 5616}, - {395, 395, 6: 4241, 4243, 400, 4989, 15: 4260, 2176, 4258, 4197, 4262, 4249, 4278, 4242, 4245, 4244, 4247, 4248, 4250, 4257, 400, 4268, 4269, 4255, 4256, 4261, 4263, 4275, 4274, 4280, 4276, 4273, 4266, 4271, 4272, 4265, 4267, 4270, 4259, 472: 395, 395, 395, 478: 395, 4240, 4277, 484: 2176, 488: 395, 395, 495: 395, 503: 4987, 395, 2176, 569: 395, 646: 395, 2176, 649: 4246, 781: 4251, 792: 4253, 813: 4252, 835: 4254, 838: 4264, 842: 4988}, - {2112, 2112, 472: 2112, 2112, 2112, 478: 2112, 489: 5206, 495: 2112, 504: 5207, 569: 2112, 646: 2112, 1037: 5618}, + {616, 616}, + {159: 5705}, + {603, 603, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 494: 603, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 4429, 1179: 5700}, + {613, 613}, + {159: 611}, // 3080 - {660: 5045}, - {2109, 2109, 472: 2109, 2109, 2109, 478: 5620, 495: 2109, 569: 2109, 646: 2109, 1176: 5619}, - {2107, 2107, 472: 2107, 2588, 2587, 495: 2586, 569: 2585, 646: 2581, 709: 5625, 748: 5623, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 5624, 5622, 1199: 5621}, - {2108, 2108, 472: 2108, 2108, 2108, 495: 2108, 569: 2108, 646: 2108}, - {2179, 2179, 472: 5608, 1086: 5626}, + {159: 610}, + {159: 609}, + {159: 608}, + {159: 607}, + {599, 599, 494: 5702, 1387: 5701}, // 3085 - {2106, 2106, 472: 2106}, - {2105, 2105, 472: 2105, 480: 815, 490: 815, 815}, - {2104, 2104, 472: 2104}, - {2103, 2103, 472: 2103, 480: 814, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, - {2181, 2181}, + {614, 614}, + {692: 5703}, + {518: 5704}, + {598, 598}, + {615, 615}, // 3090 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5560, 2762, 2763, 2761, 955: 5630}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5560, 2762, 2763, 2761, 955: 5629}, - {708, 708, 9: 5562}, - {709, 709, 9: 5562}, - {711, 711}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5707, 2850, 688: 2851, 2849, 980: 5708}, + {621, 621, 9: 621}, + {617, 617, 9: 5709}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5710, 2850, 688: 2851, 2849}, + {620, 620, 9: 620}, // 3095 - {710, 710}, - {702, 702}, - {701, 701}, - {700, 700}, - {266: 5637}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 5814, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 5815, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 5816, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5817}, + {588: 5800, 668: 5801}, + {668: 5797}, + {588: 5792, 668: 5791}, + {588: 5789}, // 3100 - {508: 2736, 733: 4053, 763: 5639, 1082: 5638}, - {715, 715, 9: 5640}, - {689, 689, 9: 689}, - {508: 2736, 733: 4053, 763: 5641}, - {688, 688, 9: 688}, + {346: 5783}, + {155: 5780, 235: 5782, 356: 5778, 381: 5779, 939: 5781}, + {220: 5775, 223: 5774}, + {588: 5733}, + {155: 5727, 176: 5729, 185: 631, 211: 5731, 277: 5730, 1345: 5728}, // 3105 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 5643}, - {716, 716, 9: 3924}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5648}, - {497: 5646}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 5647}, + {155: 5726}, + {155: 5725}, + {414: 5724}, + {737, 737}, + {742, 742}, // 3110 - {707, 707, 9: 3924}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5649, 2762, 2763, 2761}, - {718, 718}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5651}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5652, 2762, 2763, 2761}, + {743, 743}, + {744, 744}, + {185: 5732}, + {185: 630}, + {185: 629}, // 3115 - {719, 719}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 5666}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5655}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5656, 2762, 2763, 2761}, - {720, 720, 473: 5659, 1057: 5658, 1225: 5657}, + {185: 628}, + {736, 736}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5734}, + {695: 5735, 956: 5736}, + {176: 5739, 181: 5738, 588: 2126, 976: 5737}, // 3120 - {717, 717, 9: 5664}, - {692, 692, 9: 692}, - {508: 2736, 733: 4053, 763: 5660}, - {9: 5661}, - {508: 2736, 733: 4053, 763: 5662}, + {745, 745}, + {588: 5741}, + {137: 2125, 588: 2125}, + {181: 5740}, + {137: 2124, 588: 2124}, // 3125 - {49: 5663}, - {690, 690, 9: 690}, - {473: 5659, 1057: 5665}, - {691, 691, 9: 691}, - {721, 721, 9: 3924}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 5742}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5743}, + {467, 467, 6: 467, 467, 467, 15: 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 491: 467, 5747, 494: 467, 496: 467, 498: 467, 467, 467, 507: 467, 467, 514: 467, 467, 522: 467, 524: 467, 537: 5746, 588: 467, 665: 467, 667: 467, 467, 1276: 5745, 1355: 5744}, + {424, 424, 6: 4354, 4356, 428, 15: 4373, 2238, 4371, 4310, 4375, 4362, 4391, 4355, 4358, 4357, 4360, 4361, 4363, 4370, 428, 4381, 4382, 4392, 4368, 4369, 4374, 4376, 4388, 4387, 4396, 4389, 4386, 4379, 4384, 4385, 4378, 4380, 4383, 4372, 4393, 4394, 491: 424, 424, 494: 424, 496: 4353, 498: 424, 2238, 4390, 507: 424, 424, 514: 2238, 424, 522: 424, 524: 5118, 588: 424, 665: 424, 667: 2238, 4359, 803: 4364, 816: 4366, 837: 4365, 858: 4367, 862: 4377, 866: 4395, 944: 5762, 1044: 5761}, + {2241, 2241, 491: 5755, 1116: 5754}, // 3130 - {163: 1640, 378: 5687, 401: 5688, 652: 1640, 1166: 5686}, - {725, 725, 163: 1480, 265: 5673, 5672, 652: 1480}, - {699, 699, 163: 1460, 652: 1460}, - {163: 5671}, - {722, 722}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5753}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 537: 5748, 600: 2476, 607: 2476, 613: 2476, 662: 2476, 4715, 668: 2476, 685: 4256, 2850, 688: 2851, 2849, 696: 2476, 2476, 766: 4582, 855: 4961, 872: 5093, 928: 5094, 993: 5095, 1177: 5749}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5751}, + {9: 5097, 58: 5750}, + {466, 466, 6: 466, 466, 466, 15: 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, 491: 466, 466, 494: 466, 496: 466, 498: 466, 466, 466, 507: 466, 466, 514: 466, 466, 522: 466, 524: 466, 588: 466, 665: 466, 667: 466, 466}, // 3135 - {247, 247, 498: 2722, 508: 2736, 733: 4053, 763: 5684, 790: 2723, 5683}, - {377: 5674}, - {493: 5675, 508: 2736, 733: 4053, 763: 5639, 1082: 5676, 1167: 5677}, - {508: 2736, 733: 2735, 741: 5678}, - {714, 714, 9: 5640}, + {58: 5752}, + {2159, 2159, 491: 2159}, + {2160, 2160, 491: 2160}, + {2242, 2242}, + {161: 5756}, // 3140 - {713, 713}, - {728, 728, 9: 5679, 164: 5680}, - {508: 2736, 733: 2735, 741: 5682}, - {508: 2736, 733: 2735, 741: 5681}, - {726, 726}, + {388: 5758, 761: 5757}, + {543: 5760}, + {543: 5759}, + {2239, 2239}, + {2240, 2240}, // 3145 - {727, 727}, - {724, 724}, - {247, 247, 498: 2722, 790: 2723, 5685}, - {723, 723}, - {712, 712}, + {2236, 2236, 491: 2236, 2236, 494: 2236, 498: 2236, 507: 5764, 2236, 515: 2236, 522: 2236, 588: 2236, 665: 2236, 1130: 5763}, + {423, 423, 6: 4354, 4356, 428, 5120, 15: 4373, 2238, 4371, 4310, 4375, 4362, 4391, 4355, 4358, 4357, 4360, 4361, 4363, 4370, 428, 4381, 4382, 4392, 4368, 4369, 4374, 4376, 4388, 4387, 4396, 4389, 4386, 4379, 4384, 4385, 4378, 4380, 4383, 4372, 4393, 4394, 491: 423, 423, 494: 423, 496: 4353, 498: 423, 2238, 4390, 507: 423, 423, 514: 2238, 423, 522: 423, 524: 5118, 588: 423, 665: 423, 667: 2238, 4359, 803: 4364, 816: 4366, 837: 4365, 858: 4367, 862: 4377, 866: 5119}, + {2174, 2174, 491: 2174, 2174, 494: 2174, 498: 2174, 508: 5351, 515: 2174, 522: 5352, 588: 2174, 665: 2174, 1065: 5765}, + {681: 5176}, + {2171, 2171, 491: 2171, 2171, 494: 2171, 498: 5767, 515: 2171, 588: 2171, 665: 2171, 1210: 5766}, // 3150 - {508: 2736, 733: 5694}, - {352: 5690, 508: 2736, 651: 5691, 733: 5689}, - {695, 695}, - {508: 2736, 733: 5693}, - {508: 2736, 733: 5692}, + {2169, 2169, 491: 2169, 2667, 494: 2666, 515: 2665, 588: 2664, 665: 2660, 731: 5772, 770: 5770, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 5771, 5769, 1232: 5768}, + {2170, 2170, 491: 2170, 2170, 494: 2170, 515: 2170, 588: 2170, 665: 2170}, + {2241, 2241, 491: 5755, 1116: 5773}, + {2168, 2168, 491: 2168}, + {2167, 2167, 491: 2167, 500: 854, 509: 854, 511: 854}, // 3155 - {693, 693}, - {694, 694}, - {696, 696}, - {2: 269, 269, 269, 269, 269, 269, 269, 10: 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 50: 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 475: 269, 479: 269, 499: 1804, 530: 269, 652: 1804, 659: 1804}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5847, 499: 1802, 652: 1802, 659: 1802, 661: 5846, 2762, 2763, 2761}, + {2166, 2166, 491: 2166}, + {2165, 2165, 491: 2165, 500: 853, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {2243, 2243}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5707, 2850, 688: 2851, 2849, 980: 5777}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5707, 2850, 688: 2851, 2849, 980: 5776}, // 3160 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 5844, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 499: 1765, 652: 1765, 659: 1765, 661: 5708, 2762, 2763, 2761, 831: 5751}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 499: 1759, 652: 1759, 659: 1759, 661: 5708, 2762, 2763, 2761, 831: 5841}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 479: 5837, 499: 1757, 530: 3761, 652: 1757, 659: 1757, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 5836}, - {494: 5826, 499: 5825, 652: 1752, 659: 1752}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 5732, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 479: 5822, 499: 1743, 651: 5820, 1743, 659: 1743, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 5739, 5737, 862: 5735, 1126: 5821, 1295: 5819}, + {747, 747, 9: 5709}, + {748, 748, 9: 5709}, + {750, 750}, + {749, 749}, + {741, 741}, // 3165 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 5817, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 499: 1741, 652: 1741, 659: 1741, 661: 5708, 2762, 2763, 2761, 831: 5748}, - {182: 5802, 499: 1724, 652: 1724, 659: 1724, 671: 5803, 921: 5801, 971: 5800}, - {334: 5756, 336: 5755, 499: 1668, 652: 1668, 659: 1668, 1181: 5757}, - {475: 5754, 499: 1469, 652: 1469, 659: 1469}, - {807, 807, 9: 5744}, + {740, 740}, + {739, 739}, + {281: 5784}, + {525: 2824, 755: 4162, 784: 5786, 1112: 5785}, + {754, 754, 9: 5787}, // 3170 - {174: 5730}, - {499: 775, 652: 5728, 659: 775}, - {499: 5717, 659: 5718, 824: 5726}, - {499: 5717, 659: 5718, 824: 5721}, - {499: 5717, 659: 5718, 824: 5719}, + {728, 728, 9: 728}, + {525: 2824, 755: 4162, 784: 5788}, + {727, 727, 9: 727}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 5790}, + {755, 755, 9: 4033}, // 3175 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 479: 5716, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 5715, 1186: 5714}, - {753, 753, 9: 753}, - {760, 760, 9: 760}, - {759, 759, 9: 759}, - {758, 758, 9: 758}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5795}, + {518: 5793}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 5794}, + {746, 746, 9: 4033}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5796, 2850, 688: 2851, 2849}, // 3180 - {2: 777, 777, 777, 777, 777, 777, 777, 10: 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 50: 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 475: 777, 777, 777, 479: 777, 482: 777, 777, 485: 777, 777, 777, 492: 777, 495: 777, 504: 777, 777, 508: 777, 530: 777, 564: 777, 567: 777, 777, 570: 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 582: 777, 777, 777, 777, 777, 777, 777, 777, 592: 777, 777, 595: 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 777, 648: 777}, - {2: 776, 776, 776, 776, 776, 776, 776, 10: 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 50: 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 475: 776, 776, 776, 479: 776, 482: 776, 776, 485: 776, 776, 776, 492: 776, 495: 776, 504: 776, 776, 508: 776, 530: 776, 564: 776, 567: 776, 776, 570: 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 582: 776, 776, 776, 776, 776, 776, 776, 776, 592: 776, 776, 595: 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 648: 776}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5720}, - {765, 765, 9: 765, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 5723, 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 5722, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5724, 840: 5725}, + {757, 757}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5798}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5799, 2850, 688: 2851, 2849}, + {758, 758}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 5813}, // 3185 - {779, 779, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 779, 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3866, 3253, 3334, 3252, 3249}, - {780, 780, 9: 780}, - {778, 778, 9: 778}, - {766, 766, 9: 766}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 5723, 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 5722, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5724, 840: 5727}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5802}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5803, 2850, 688: 2851, 2849}, + {759, 759, 492: 5806, 1087: 5805, 1257: 5804}, + {756, 756, 9: 5811}, + {731, 731, 9: 731}, // 3190 - {770, 770, 9: 770}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5729, 2762, 2763, 2761}, - {499: 774, 659: 774}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 5732, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 651: 5734, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 5739, 5737, 862: 5735, 1126: 5733}, - {737, 737, 9: 737, 568: 1832, 650: 737, 667: 1832}, + {525: 2824, 755: 4162, 784: 5807}, + {9: 5808}, + {525: 2824, 755: 4162, 784: 5809}, + {58: 5810}, + {729, 729, 9: 729}, // 3195 - {796, 796, 568: 1663, 650: 796, 667: 1663}, - {650: 5742}, - {650: 795}, - {794, 794, 9: 5740, 650: 794}, - {738, 738, 9: 738, 568: 258, 650: 738, 667: 258}, + {492: 5806, 1087: 5812}, + {730, 730, 9: 730}, + {760, 760, 9: 4033}, + {177: 1697, 392: 5834, 418: 5835, 672: 1697, 1199: 5833}, + {764, 764, 177: 1528, 280: 5820, 5819, 672: 1528}, // 3200 - {732, 732, 9: 732, 650: 732}, - {731, 731, 9: 731, 650: 731}, - {730, 730, 9: 730, 650: 730}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 5741, 5737}, - {729, 729, 9: 729, 650: 729}, + {738, 738, 177: 1507, 672: 1507}, + {177: 5818}, + {761, 761}, + {275, 275, 519: 2810, 525: 2824, 755: 4162, 784: 5831, 814: 2811, 5830}, + {391: 5821}, // 3205 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5298, 868: 5743}, - {797, 797, 9: 5300}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 5695, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 5698, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 5745, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 5746, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 5699, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 505: 3837, 568: 5711, 587: 5710, 647: 3835, 661: 5708, 2762, 2763, 2761, 773: 5712, 831: 5709, 978: 5747}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 499: 1765, 652: 1765, 659: 1765, 661: 5708, 2762, 2763, 2761, 831: 5751}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 499: 1741, 652: 1741, 659: 1741, 661: 5708, 2762, 2763, 2761, 831: 5748}, + {512: 5822, 525: 2824, 755: 4162, 784: 5786, 1112: 5823, 1200: 5824}, + {525: 2824, 755: 2823, 762: 5825}, + {753, 753, 9: 5787}, + {752, 752}, + {767, 767, 9: 5826, 178: 5827}, // 3210 - {752, 752, 9: 752}, - {499: 5717, 659: 5718, 824: 5749}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 5723, 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 5722, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5724, 840: 5750}, - {768, 768, 9: 768}, - {499: 5717, 659: 5718, 824: 5752}, + {525: 2824, 755: 2823, 762: 5829}, + {525: 2824, 755: 2823, 762: 5828}, + {765, 765}, + {766, 766}, + {763, 763}, // 3215 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 5723, 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 5722, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5724, 840: 5753}, - {769, 769, 9: 769}, - {799, 799}, - {494: 2216}, - {494: 2215}, + {275, 275, 519: 2810, 814: 2811, 5832}, + {762, 762}, + {751, 751}, + {525: 2824, 755: 5841}, + {365: 5837, 525: 2824, 671: 5838, 755: 5836}, // 3220 - {494: 5758}, - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 709: 5761, 739: 5759, 748: 5762, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 5760, 5764, 5763, 766: 5766, 772: 2689, 774: 5767, 5768, 5765, 846: 5769}, - {2: 853, 853, 853, 853, 853, 853, 853, 10: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 50: 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 853, 489: 853, 500: 853, 753: 853, 853, 853, 762: 5398, 867: 5399, 918: 5773}, - {473: 2588, 495: 2586, 569: 2585, 646: 2581, 654: 2690, 709: 3888, 748: 3887, 2582, 2583, 2584, 2593, 756: 2591, 3889, 3890, 772: 5772}, - {185, 185, 480: 814, 185, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, + {734, 734}, + {525: 2824, 755: 5840}, + {525: 2824, 755: 5839}, + {732, 732}, + {733, 733}, // 3225 - {187, 187, 480: 815, 187, 490: 815, 815}, - {188, 188, 481: 188}, - {186, 186, 481: 186}, - {184, 184, 481: 184}, - {183, 183, 481: 183}, + {735, 735}, + {2: 297, 297, 297, 297, 297, 297, 297, 10: 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 59: 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 493: 297, 496: 297, 517: 1863, 549: 297, 672: 1863, 680: 1863}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5996, 517: 1861, 672: 1861, 680: 1861, 685: 5995, 2850, 688: 2851, 2849}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 5993, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 517: 1824, 672: 1824, 680: 1824, 685: 5855, 2850, 688: 2851, 2849, 853: 5898}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 517: 1818, 672: 1818, 680: 1818, 685: 5855, 2850, 688: 2851, 2849, 853: 5990}, // 3230 - {182, 182, 481: 182}, - {181, 181, 481: 181}, - {177, 177, 481: 5770}, - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 709: 5761, 739: 5759, 748: 5762, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 5760, 5764, 5763, 766: 5766, 772: 2689, 774: 5767, 5768, 5765, 846: 5771}, - {176, 176}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 496: 5986, 517: 1816, 549: 3868, 672: 1816, 680: 1816, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 5985}, + {513: 5975, 517: 5974, 672: 1811, 680: 1811}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 5879, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 496: 5971, 517: 1800, 671: 5969, 1800, 680: 1800, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 5886, 5884, 885: 5882, 1158: 5970, 1329: 5968}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 5966, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 517: 1798, 672: 1798, 680: 1798, 685: 5855, 2850, 688: 2851, 2849, 853: 5895}, + {195: 5951, 517: 1781, 672: 1781, 680: 1781, 692: 5952, 946: 5950, 996: 5949}, // 3235 - {252, 252, 481: 252}, - {2: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 10: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 50: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 489: 1057, 500: 1057, 753: 5403, 5402, 5401, 837: 5404, 887: 5774}, - {2: 1045, 1045, 1045, 1045, 1045, 1045, 1045, 10: 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 50: 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 5776, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 489: 1045, 500: 1045, 1109: 5775}, - {2: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 10: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 50: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 489: 4191, 500: 1856, 855: 5777}, - {2: 1044, 1044, 1044, 1044, 1044, 1044, 1044, 10: 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 50: 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 489: 1044, 500: 1044}, + {348: 5903, 350: 5902, 517: 1725, 672: 1725, 680: 1725, 1215: 5904}, + {493: 5901, 517: 1517, 672: 1517, 680: 1517}, + {846, 846, 9: 5891}, + {187: 5877}, + {517: 814, 672: 5875, 680: 814}, // 3240 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 500: 5778, 661: 5780, 2762, 2763, 2761, 917: 5781, 967: 5779}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 5793}, - {9: 5789, 500: 5788}, - {9: 1047, 481: 1047, 500: 1047, 652: 5783, 907: 5782}, - {9: 1049, 481: 1049, 500: 1049}, + {517: 5864, 680: 5865, 846: 5873}, + {517: 5864, 680: 5865, 846: 5868}, + {517: 5864, 680: 5865, 846: 5866}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 496: 5863, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 5862, 1220: 5861}, + {792, 792, 9: 792}, // 3245 - {9: 1051, 481: 1051, 500: 1051}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 5785, 661: 5784, 2762, 2763, 2761}, - {9: 1047, 481: 1047, 500: 1047, 652: 5787, 907: 5786}, - {9: 1046, 481: 1046, 500: 1046}, - {9: 1050, 481: 1050, 500: 1050}, + {799, 799, 9: 799}, + {798, 798, 9: 798}, + {797, 797, 9: 797}, + {2: 816, 816, 816, 816, 816, 816, 816, 10: 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 59: 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 495: 816, 816, 816, 502: 816, 816, 816, 816, 816, 510: 816, 514: 816, 816, 522: 816, 525: 816, 549: 816, 583: 816, 587: 816, 589: 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 601: 816, 816, 816, 816, 816, 816, 608: 816, 816, 816, 816, 816, 614: 816, 816, 617: 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 669: 816}, + {2: 815, 815, 815, 815, 815, 815, 815, 10: 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 59: 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 495: 815, 815, 815, 502: 815, 815, 815, 815, 815, 510: 815, 514: 815, 815, 522: 815, 525: 815, 549: 815, 583: 815, 587: 815, 589: 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 601: 815, 815, 815, 815, 815, 815, 608: 815, 815, 815, 815, 815, 614: 815, 815, 617: 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 669: 815}, // 3250 - {520: 5785}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 579: 5410, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5417, 852: 5407, 890: 5791}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5780, 2762, 2763, 2761, 917: 5790}, - {9: 1048, 481: 1048, 500: 1048}, - {247, 247, 9: 5461, 481: 247, 498: 2722, 790: 2723, 5792}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 5867}, + {804, 804, 9: 804, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 5870, 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 5869, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5871, 864: 5872}, + {818, 818, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 818, 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3975, 3360, 3441, 3359, 3356}, + {819, 819, 9: 819}, // 3255 - {2074, 2074, 481: 2074}, - {922, 922, 922, 922, 922, 922, 922, 922, 922, 10: 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 50: 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 478: 922, 481: 922, 488: 5465, 922, 493: 922, 498: 922, 502: 922, 922, 525: 922, 860: 5794}, - {920, 920, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 478: 5422, 481: 920, 489: 920, 493: 920, 498: 920, 502: 920, 920, 525: 920, 661: 5421, 2762, 2763, 2761, 915: 5420, 5795}, - {901, 901, 481: 901, 489: 5475, 493: 901, 498: 901, 502: 901, 5476, 525: 5474, 940: 5478, 5477, 1062: 5479, 5796}, - {247, 247, 481: 247, 493: 247, 498: 2722, 502: 247, 790: 2723, 5797}, + {817, 817, 9: 817}, + {805, 805, 9: 805}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 5870, 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 5869, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5871, 864: 5874}, + {809, 809, 9: 809}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5876, 2850, 688: 2851, 2849}, // 3260 - {1297, 1297, 481: 1297, 493: 1297, 502: 2725, 767: 2726, 812: 5798}, - {883, 883, 481: 883, 493: 5525, 1071: 5799}, - {2075, 2075, 481: 2075}, - {802, 802, 9: 5815}, - {790, 790, 9: 790}, + {517: 813, 680: 813}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 5879, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 671: 5881, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 5886, 5884, 885: 5882, 1158: 5880}, + {776, 776, 9: 776, 589: 1892, 670: 776, 684: 1892}, + {835, 835, 589: 1720, 670: 835, 684: 1720}, + {670: 5889}, // 3265 - {356: 5807}, - {154: 5805, 687: 5804}, - {787, 787, 9: 787}, - {786, 786, 9: 786, 673: 5471, 924: 5806}, - {785, 785, 9: 785}, + {670: 834}, + {833, 833, 9: 5887, 670: 833}, + {777, 777, 9: 777, 589: 286, 670: 777, 684: 286}, + {771, 771, 9: 771, 670: 771}, + {770, 770, 9: 770, 670: 770}, // 3270 - {220: 5809, 385: 5811, 671: 5810, 1239: 5808}, - {788, 788, 9: 788}, - {671: 5814}, - {328: 5812, 404: 5813}, - {781, 781, 9: 781}, + {769, 769, 9: 769, 670: 769}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 5888, 5884}, + {768, 768, 9: 768, 670: 768}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5443, 891: 5890}, + {836, 836, 9: 5445}, // 3275 - {783, 783, 9: 783}, - {782, 782, 9: 782}, - {784, 784, 9: 784}, - {182: 5802, 671: 5803, 921: 5816}, - {789, 789, 9: 789}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 5842, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 5845, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 5892, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 5893, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 5846, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 514: 3944, 589: 5858, 610: 5857, 667: 3942, 685: 5855, 2850, 688: 2851, 2849, 798: 5859, 853: 5856, 1003: 5894}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 517: 1824, 672: 1824, 680: 1824, 685: 5855, 2850, 688: 2851, 2849, 853: 5898}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 517: 1798, 672: 1798, 680: 1798, 685: 5855, 2850, 688: 2851, 2849, 853: 5895}, + {791, 791, 9: 791}, + {517: 5864, 680: 5865, 846: 5896}, // 3280 - {182: 5802, 499: 1724, 652: 1724, 659: 1724, 671: 5803, 921: 5801, 971: 5818}, - {803, 803, 9: 5815}, - {798, 798}, - {795, 795, 490: 5823}, - {792, 792}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 5870, 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 5869, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5871, 864: 5897}, + {807, 807, 9: 807}, + {517: 5864, 680: 5865, 846: 5899}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 5870, 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 5869, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5871, 864: 5900}, + {808, 808, 9: 808}, // 3285 - {791, 791}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 5739, 5737, 862: 5824}, - {793, 793, 9: 5740}, - {15: 5831, 475: 5830, 1101: 5835}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5827}, + {838, 838}, + {513: 2279}, + {513: 2278}, + {513: 5905}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 687: 5917, 731: 5908, 761: 5906, 770: 5909, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 5907, 5911, 5910, 788: 2774, 5913, 795: 5914, 5915, 5912, 870: 5916}, // 3290 - {499: 5828}, - {15: 5831, 475: 5830, 1101: 5829}, - {805, 805}, - {741, 741}, - {473: 5832}, + {2: 892, 892, 892, 892, 892, 892, 892, 10: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 59: 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 508: 892, 520: 892, 775: 892, 892, 892, 785: 5545, 890: 5546, 943: 5922}, + {492: 2667, 515: 2665, 588: 2664, 665: 2660, 674: 2775, 731: 3997, 770: 3996, 2661, 2662, 2663, 2672, 778: 2670, 3998, 3999, 788: 5324}, + {202, 202, 500: 853, 202, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {204, 204, 500: 854, 204, 509: 854, 511: 854}, + {205, 205, 501: 205}, // 3295 - {475: 5330, 893: 5833}, - {49: 5834}, - {740, 740}, - {806, 806}, - {764, 764, 9: 764, 484: 5838}, + {203, 203, 501: 203}, + {201, 201, 501: 201}, + {200, 200, 501: 200}, + {199, 199, 501: 199}, + {198, 198, 501: 198}, // 3300 - {761, 761, 9: 761}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 479: 5839, 661: 3491, 2762, 2763, 2761, 738: 5840}, - {763, 763, 9: 763}, - {762, 762, 9: 762}, - {499: 5717, 659: 5718, 824: 5842}, + {192, 192, 501: 5920}, + {219: 5918}, + {493: 5919}, + {190, 190}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 731: 5908, 761: 5906, 770: 5909, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 5907, 5911, 5910, 788: 2774, 5913, 795: 5914, 5915, 5912, 870: 5921}, // 3305 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 5723, 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 5722, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5724, 840: 5843}, - {767, 767, 9: 767}, - {182: 5802, 499: 1724, 652: 1724, 659: 1724, 671: 5803, 921: 5801, 971: 5845}, - {804, 804, 9: 5815}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5849, 2762, 2763, 2761, 902: 5856}, + {191, 191}, + {2: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 10: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 59: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 508: 1096, 520: 1096, 775: 5550, 5549, 5548, 861: 5551, 910: 5923}, + {2: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 10: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 59: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 5925, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 508: 1084, 520: 1084, 1139: 5924}, + {2: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 10: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 59: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 508: 4304, 520: 1916, 878: 5926}, + {2: 1083, 1083, 1083, 1083, 1083, 1083, 1083, 10: 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 59: 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 508: 1083, 520: 1083}, // 3310 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5849, 2762, 2763, 2761, 902: 5848}, - {499: 5717, 659: 5718, 824: 5854}, - {486: 5851, 499: 773, 652: 5850, 659: 773}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5849, 2762, 2763, 2761, 902: 5853}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5849, 2762, 2763, 2761, 902: 5852}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 520: 5927, 685: 5929, 2850, 688: 2851, 2849, 942: 5930, 992: 5928}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 5942}, + {9: 5938, 520: 5937}, + {9: 1086, 501: 1086, 520: 1086, 672: 5932, 932: 5931}, + {9: 1088, 501: 1088, 520: 1088}, // 3315 - {499: 771, 659: 771}, - {499: 772, 659: 772}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 5723, 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 5722, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5724, 840: 5855}, - {800, 800}, - {499: 5717, 659: 5718, 824: 5857}, + {9: 1090, 501: 1090, 520: 1090}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 5934, 685: 5933, 2850, 688: 2851, 2849}, + {9: 1086, 501: 1086, 520: 1086, 672: 5936, 932: 5935}, + {9: 1085, 501: 1085, 520: 1085}, + {9: 1089, 501: 1089, 520: 1089}, // 3320 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 5723, 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 5722, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 5724, 840: 5858}, - {801, 801}, - {650: 5868}, - {650: 5861}, - {272: 5862}, + {541: 5934}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 601: 5557, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5564, 875: 5554, 914: 5940}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5929, 2850, 688: 2851, 2849, 942: 5939}, + {9: 1087, 501: 1087, 520: 1087}, + {275, 275, 9: 5608, 501: 275, 519: 2810, 814: 2811, 5941}, // 3325 - {499: 5863}, - {475: 5864}, - {494: 5865}, - {271: 5866}, - {475: 5867}, + {2136, 2136, 501: 2136}, + {961, 961, 961, 961, 961, 961, 961, 961, 961, 10: 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 59: 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, 498: 961, 501: 961, 507: 5612, 961, 512: 961, 519: 961, 523: 961, 961, 544: 961, 883: 5943}, + {959, 959, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 498: 5569, 501: 959, 508: 959, 512: 959, 519: 959, 523: 959, 959, 544: 959, 685: 5568, 2850, 688: 2851, 2849, 940: 5567, 5944}, + {940, 940, 501: 940, 508: 5622, 512: 940, 519: 940, 523: 940, 5623, 544: 5621, 966: 5625, 5624, 1092: 5626, 5945}, + {275, 275, 501: 275, 512: 275, 519: 2810, 523: 275, 814: 2811, 5946}, // 3330 - {808, 808}, - {272: 5869}, - {499: 5870}, - {475: 5871}, - {494: 5872}, + {1338, 1338, 501: 1338, 512: 1338, 523: 2813, 790: 2814, 836: 5947}, + {922, 922, 501: 922, 512: 5672, 1101: 5948}, + {2137, 2137, 501: 2137}, + {841, 841, 9: 5964}, + {829, 829, 9: 829}, // 3335 - {271: 5873}, - {475: 5874}, - {809, 809}, - {473: 2588, 495: 2586, 569: 2585, 646: 2581, 709: 5886, 748: 5885, 2582, 2583, 2584, 5887}, - {473: 1239, 495: 1239, 569: 1239, 646: 1239, 651: 3546, 745: 3544, 3545, 784: 5879, 787: 5880, 933: 5882, 966: 5884}, + {369: 5956}, + {167: 5954, 709: 5953}, + {826, 826, 9: 826}, + {825, 825, 9: 825, 694: 5618, 949: 5955}, + {824, 824, 9: 824}, // 3340 - {473: 1239, 495: 1239, 569: 1239, 646: 1239, 651: 3546, 745: 3544, 3545, 784: 5879, 787: 5880, 933: 5882, 966: 5883}, - {473: 1239, 495: 1239, 569: 1239, 646: 1239, 651: 3546, 745: 3544, 3545, 784: 5879, 787: 5880, 933: 5882, 966: 5881}, - {2: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 10: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 50: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 473: 1242, 475: 1242, 1242, 1242, 479: 1242, 482: 1242, 1242, 485: 1242, 1242, 1242, 492: 1242, 495: 1242, 504: 1242, 1242, 508: 1242, 515: 1242, 520: 1242, 530: 1242, 564: 1242, 567: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 582: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 592: 1242, 1242, 595: 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 646: 1242, 648: 1242, 651: 1242, 745: 1242, 1242, 753: 1242, 1242, 1242, 762: 1242, 769: 1242, 1242, 1242}, - {473: 1238, 495: 1238, 569: 1238, 646: 1238}, - {473: 811, 495: 811, 569: 811, 646: 811}, + {234: 5958, 401: 5960, 692: 5959, 1271: 5957}, + {827, 827, 9: 827}, + {692: 5963}, + {342: 5961, 421: 5962}, + {820, 820, 9: 820}, // 3345 - {473: 810, 495: 810, 569: 810, 646: 810}, - {473: 812, 495: 812, 569: 812, 646: 812}, - {473: 813, 495: 813, 569: 813, 646: 813}, - {825, 825, 49: 825, 472: 825, 474: 825, 480: 815, 825, 490: 815, 815}, - {824, 824, 49: 824, 472: 824, 474: 824, 480: 814, 824, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 5888, 5889}, + {822, 822, 9: 822}, + {821, 821, 9: 821}, + {823, 823, 9: 823}, + {195: 5951, 692: 5952, 946: 5965}, + {828, 828, 9: 828}, // 3350 - {480: 816, 490: 816, 816}, - {823, 823, 49: 823, 472: 823, 474: 823, 481: 823, 493: 2728, 501: 2729, 768: 5890}, - {822, 822, 49: 822, 472: 822, 474: 822, 481: 822}, - {821, 821, 49: 821, 472: 821, 474: 821, 481: 821}, - {49: 3974, 480: 814, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, + {195: 5951, 517: 1781, 672: 1781, 680: 1781, 692: 5952, 946: 5950, 996: 5967}, + {842, 842, 9: 5964}, + {837, 837}, + {834, 834, 509: 5972}, + {831, 831}, // 3355 - {9: 5906, 473: 997, 495: 997, 569: 997, 646: 997, 654: 997, 739: 997}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5895, 2762, 2763, 2761, 930: 5894, 1164: 5905}, - {9: 994, 473: 994, 495: 994, 569: 994, 646: 994, 654: 994, 739: 994}, - {473: 5896, 478: 2330, 1226: 5897}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5901, 2762, 2763, 2761, 877: 5900}, + {830, 830}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 5886, 5884, 885: 5973}, + {832, 832, 9: 5887}, + {15: 5980, 493: 5979, 1131: 5984}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5976}, // 3360 - {478: 5898}, - {473: 2588, 709: 5899}, - {9: 993, 473: 993, 495: 993, 569: 993, 646: 993, 654: 993, 739: 993}, - {9: 5903, 49: 5902}, - {2328, 2328, 9: 2328, 49: 2328, 474: 2328}, + {517: 5977}, + {15: 5980, 493: 5979, 1131: 5978}, + {844, 844}, + {780, 780}, + {492: 5981}, // 3365 - {478: 2329}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5904, 2762, 2763, 2761}, - {2327, 2327, 9: 2327, 49: 2327, 474: 2327}, - {9: 5906, 473: 996, 495: 996, 569: 996, 646: 996, 654: 996, 739: 996}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5895, 2762, 2763, 2761, 930: 5907}, + {493: 5475, 917: 5982}, + {58: 5983}, + {779, 779}, + {845, 845}, + {803, 803, 9: 803, 499: 5987}, // 3370 - {9: 995, 473: 995, 495: 995, 569: 995, 646: 995, 654: 995, 739: 995}, - {1297, 1297, 49: 1297, 472: 1297, 474: 1297, 480: 1297, 1297, 490: 1297, 1297, 493: 1297, 1297, 496: 1297, 1297, 501: 1297, 2725, 767: 2726, 812: 5909}, - {869, 869, 49: 869, 472: 869, 474: 869, 480: 869, 869, 490: 869, 869, 493: 2728, 869, 496: 869, 869, 501: 2729, 768: 2730, 830: 5910}, - {840, 840, 49: 840, 472: 840, 474: 840, 480: 840, 840, 490: 840, 840, 494: 3912, 496: 840, 3913, 888: 5911}, - {846, 846, 49: 846, 472: 846, 474: 846, 480: 846, 846, 490: 846, 846, 496: 3938, 889: 5912}, + {800, 800, 9: 800}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 496: 5988, 685: 3598, 2850, 688: 2851, 2849, 760: 5989}, + {802, 802, 9: 802}, + {801, 801, 9: 801}, + {517: 5864, 680: 5865, 846: 5991}, // 3375 - {1001, 1001, 49: 1001, 472: 1001, 474: 1001, 480: 1001, 1001, 490: 1001, 1001}, - {869, 869, 49: 869, 472: 869, 474: 869, 480: 869, 869, 490: 869, 869, 493: 2728, 869, 496: 869, 869, 501: 2729, 768: 2730, 830: 5914}, - {840, 840, 49: 840, 472: 840, 474: 840, 480: 840, 840, 490: 840, 840, 494: 3912, 496: 840, 3913, 888: 5915}, - {846, 846, 49: 846, 472: 846, 474: 846, 480: 846, 846, 490: 846, 846, 496: 3938, 889: 5916}, - {1002, 1002, 49: 1002, 472: 1002, 474: 1002, 480: 1002, 1002, 490: 1002, 1002}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 5870, 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 5869, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5871, 864: 5992}, + {806, 806, 9: 806}, + {195: 5951, 517: 1781, 672: 1781, 680: 1781, 692: 5952, 946: 5950, 996: 5994}, + {843, 843, 9: 5964}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5998, 2850, 688: 2851, 2849, 927: 6005}, // 3380 - {660: 5924}, - {1297, 1297, 49: 1297, 472: 1297, 474: 1297, 480: 1297, 1297, 490: 1297, 1297, 493: 1297, 1297, 496: 1297, 1297, 501: 1297, 2725, 767: 2726, 812: 5920}, - {847, 847, 49: 847, 472: 847, 474: 847, 480: 847, 847, 490: 847, 847, 493: 847, 847, 496: 847, 847, 501: 847, 847, 514: 847, 516: 847}, - {869, 869, 49: 869, 472: 869, 474: 869, 480: 869, 869, 490: 869, 869, 493: 2728, 869, 496: 869, 869, 501: 2729, 768: 2730, 830: 5921}, - {840, 840, 49: 840, 472: 840, 474: 840, 480: 840, 840, 490: 840, 840, 494: 3912, 496: 840, 3913, 888: 5922}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5998, 2850, 688: 2851, 2849, 927: 5997}, + {517: 5864, 680: 5865, 846: 6003}, + {505: 6000, 517: 812, 672: 5999, 680: 812}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5998, 2850, 688: 2851, 2849, 927: 6002}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5998, 2850, 688: 2851, 2849, 927: 6001}, // 3385 - {846, 846, 49: 846, 472: 846, 474: 846, 480: 846, 846, 490: 846, 846, 496: 3938, 889: 5923}, - {1003, 1003, 49: 1003, 472: 1003, 474: 1003, 480: 1003, 1003, 490: 1003, 1003}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 2754, 871: 3241, 900: 5925}, - {1866, 1866, 9: 3412, 49: 1866, 472: 1866, 474: 1866, 480: 1866, 1866, 490: 1866, 1866, 493: 1866, 1866, 496: 1866, 1866, 501: 1866, 1866, 514: 1866, 516: 1866}, - {247, 247, 49: 247, 472: 247, 474: 247, 480: 247, 247, 490: 247, 247, 493: 247, 247, 496: 247, 247, 2722, 501: 247, 247, 513: 247, 790: 2723, 5951}, + {517: 810, 680: 810}, + {517: 811, 680: 811}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 5870, 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 5869, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5871, 864: 6004}, + {839, 839}, + {517: 5864, 680: 5865, 846: 6006}, // 3390 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 579: 5410, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5417, 852: 5407, 890: 5936, 1206: 5935, 1322: 5934}, - {848, 848, 49: 848, 472: 848, 474: 848, 480: 848, 848, 490: 848, 848, 493: 848, 848, 496: 848, 848, 501: 848, 848, 513: 5917, 939: 5919, 965: 5929}, - {1297, 1297, 49: 1297, 472: 1297, 474: 1297, 480: 1297, 1297, 490: 1297, 1297, 493: 1297, 1297, 496: 1297, 1297, 501: 1297, 2725, 767: 2726, 812: 5930}, - {869, 869, 49: 869, 472: 869, 474: 869, 480: 869, 869, 490: 869, 869, 493: 2728, 869, 496: 869, 869, 501: 2729, 768: 2730, 830: 5931}, - {840, 840, 49: 840, 472: 840, 474: 840, 480: 840, 840, 490: 840, 840, 494: 3912, 496: 840, 3913, 888: 5932}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 5870, 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 5869, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 5871, 864: 6007}, + {840, 840}, + {670: 6017}, + {670: 6010}, + {287: 6011}, // 3395 - {846, 846, 49: 846, 472: 846, 474: 846, 480: 846, 846, 490: 846, 846, 496: 3938, 889: 5933}, - {1004, 1004, 49: 1004, 472: 1004, 474: 1004, 480: 1004, 1004, 490: 1004, 1004}, - {247, 247, 49: 247, 472: 247, 474: 247, 480: 247, 247, 490: 247, 247, 493: 247, 247, 496: 247, 247, 2722, 501: 247, 247, 513: 247, 247, 516: 247, 790: 2723, 5937}, - {992, 992, 49: 992, 472: 992, 474: 992, 480: 992, 992, 490: 992, 992, 493: 992, 992, 496: 992, 992, 992, 501: 992, 992, 513: 992}, - {932, 932, 9: 5461, 49: 932, 472: 932, 474: 932, 480: 932, 932, 490: 932, 932, 493: 932, 932, 496: 932, 932, 932, 501: 932, 932, 513: 932, 932, 516: 932}, + {517: 6012}, + {493: 6013}, + {513: 6014}, + {286: 6015}, + {493: 6016}, // 3400 - {848, 848, 49: 848, 472: 848, 474: 848, 480: 848, 848, 490: 848, 848, 493: 848, 848, 496: 848, 848, 501: 848, 848, 513: 5917, 848, 516: 848, 939: 5919, 965: 5938}, - {1865, 1865, 49: 1865, 472: 1865, 474: 1865, 480: 1865, 1865, 490: 1865, 1865, 493: 1865, 1865, 496: 1865, 1865, 501: 1865, 1865, 514: 5939, 516: 1865, 1059: 5940}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5950}, - {991, 991, 49: 991, 472: 991, 474: 991, 480: 991, 991, 490: 991, 991, 493: 991, 991, 496: 991, 991, 501: 991, 991, 516: 5942, 1345: 5941}, - {1017, 1017, 49: 1017, 472: 1017, 474: 1017, 480: 1017, 1017, 490: 1017, 1017, 493: 1017, 1017, 496: 1017, 1017, 501: 1017, 1017}, + {847, 847}, + {287: 6018}, + {517: 6019}, + {493: 6020}, + {513: 6021}, // 3405 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3400, 2762, 2763, 2761, 923: 5945, 1160: 5944, 1346: 5943}, - {990, 990, 9: 5948, 49: 990, 472: 990, 474: 990, 480: 990, 990, 490: 990, 990, 493: 990, 990, 496: 990, 990, 501: 990, 990}, - {989, 989, 9: 989, 49: 989, 472: 989, 474: 989, 480: 989, 989, 490: 989, 989, 493: 989, 989, 496: 989, 989, 501: 989, 989}, - {478: 5946}, - {473: 3401, 1162: 5947}, + {286: 6022}, + {493: 6023}, + {848, 848}, + {492: 2667, 515: 2665, 588: 2664, 665: 2660, 731: 6035, 770: 6034, 2661, 2662, 2663, 6036}, + {492: 1278, 515: 1278, 588: 1278, 665: 1278, 671: 3653, 767: 3651, 3652, 808: 6028, 810: 6029, 959: 6031, 991: 6033}, // 3410 - {987, 987, 9: 987, 49: 987, 472: 987, 474: 987, 480: 987, 987, 490: 987, 987, 493: 987, 987, 496: 987, 987, 501: 987, 987}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3400, 2762, 2763, 2761, 923: 5945, 1160: 5949}, - {988, 988, 9: 988, 49: 988, 472: 988, 474: 988, 480: 988, 988, 490: 988, 988, 493: 988, 988, 496: 988, 988, 501: 988, 988}, - {1864, 1864, 49: 1864, 472: 1864, 474: 1864, 480: 1864, 1864, 490: 1864, 1864, 493: 1864, 1864, 496: 1864, 1864, 1864, 500: 1864, 1864, 1864, 507: 3345, 509: 3343, 3344, 3342, 3340, 1864, 516: 1864, 734: 3341, 3339}, - {1018, 1018, 49: 1018, 472: 1018, 474: 1018, 480: 1018, 1018, 490: 1018, 1018, 493: 1018, 1018, 496: 1018, 1018, 501: 1018, 1018, 513: 1018}, + {492: 1278, 515: 1278, 588: 1278, 665: 1278, 671: 3653, 767: 3651, 3652, 808: 6028, 810: 6029, 959: 6031, 991: 6032}, + {492: 1278, 515: 1278, 588: 1278, 665: 1278, 671: 3653, 767: 3651, 3652, 808: 6028, 810: 6029, 959: 6031, 991: 6030}, + {2: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 10: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 59: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 492: 1281, 1281, 495: 1281, 1281, 1281, 502: 1281, 1281, 1281, 1281, 1281, 510: 1281, 514: 1281, 1281, 522: 1281, 525: 1281, 534: 1281, 541: 1281, 549: 1281, 583: 1281, 587: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 601: 1281, 1281, 1281, 1281, 1281, 1281, 608: 1281, 1281, 1281, 1281, 1281, 614: 1281, 1281, 617: 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 665: 1281, 669: 1281, 671: 1281, 767: 1281, 1281, 775: 1281, 1281, 1281, 785: 1281, 792: 1281, 1281, 1281}, + {492: 1277, 515: 1277, 588: 1277, 665: 1277}, + {492: 850, 515: 850, 588: 850, 665: 850}, // 3415 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 520: 5968, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 5969, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5967, 1046: 5970, 1214: 5971, 1290: 5972}, - {2: 867, 867, 867, 867, 867, 867, 867, 10: 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 50: 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 473: 867, 475: 867, 867, 867, 479: 867, 482: 867, 867, 485: 867, 867, 867, 492: 867, 495: 867, 504: 867, 867, 508: 867, 515: 867, 520: 867, 530: 867, 564: 867, 567: 867, 867, 570: 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 582: 867, 867, 867, 867, 867, 867, 867, 867, 592: 867, 867, 595: 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 648: 867, 651: 867, 745: 867, 867, 753: 867, 867, 867, 762: 867, 769: 867, 867, 867}, - {2: 866, 866, 866, 866, 866, 866, 866, 10: 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 50: 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 473: 866, 475: 866, 866, 866, 479: 866, 482: 866, 866, 485: 866, 866, 866, 492: 866, 495: 866, 504: 866, 866, 508: 866, 515: 866, 520: 866, 530: 866, 564: 866, 567: 866, 866, 570: 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 582: 866, 866, 866, 866, 866, 866, 866, 866, 592: 866, 866, 595: 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 648: 866, 651: 866, 745: 866, 866, 753: 866, 866, 866, 762: 866, 769: 866, 866, 866}, - {2: 865, 865, 865, 865, 865, 865, 865, 10: 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 50: 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 473: 865, 475: 865, 865, 865, 479: 865, 482: 865, 865, 485: 865, 865, 865, 492: 865, 495: 865, 504: 865, 865, 508: 865, 515: 865, 520: 865, 530: 865, 564: 865, 567: 865, 865, 570: 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 582: 865, 865, 865, 865, 865, 865, 865, 865, 592: 865, 865, 595: 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 865, 648: 865, 651: 865, 745: 865, 865, 753: 865, 865, 865, 762: 865, 769: 865, 865, 865}, - {2: 864, 864, 864, 864, 864, 864, 864, 10: 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 50: 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 473: 864, 475: 864, 864, 864, 479: 864, 482: 864, 864, 485: 864, 864, 864, 492: 864, 495: 864, 504: 864, 864, 508: 864, 515: 864, 520: 864, 530: 864, 564: 864, 567: 864, 864, 570: 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 582: 864, 864, 864, 864, 864, 864, 864, 864, 592: 864, 864, 595: 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 648: 864, 651: 864, 745: 864, 864, 753: 864, 864, 864, 762: 864, 769: 864, 864, 864}, + {492: 849, 515: 849, 588: 849, 665: 849}, + {492: 851, 515: 851, 588: 851, 665: 851}, + {492: 852, 515: 852, 588: 852, 665: 852}, + {864, 864, 58: 864, 491: 864, 494: 864, 500: 854, 864, 509: 854, 511: 854}, + {863, 863, 58: 863, 491: 863, 494: 863, 500: 853, 863, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 6037, 6038}, // 3420 - {2: 863, 863, 863, 863, 863, 863, 863, 10: 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 50: 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 473: 863, 475: 863, 863, 863, 479: 863, 482: 863, 863, 485: 863, 863, 863, 492: 863, 495: 863, 504: 863, 863, 508: 863, 515: 863, 520: 863, 530: 863, 564: 863, 567: 863, 863, 570: 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 582: 863, 863, 863, 863, 863, 863, 863, 863, 592: 863, 863, 595: 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 648: 863, 651: 863, 745: 863, 863, 753: 863, 863, 863, 762: 863, 769: 863, 863, 863}, - {2: 862, 862, 862, 862, 862, 862, 862, 10: 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 50: 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 473: 862, 475: 862, 862, 862, 479: 862, 482: 862, 862, 485: 862, 862, 862, 492: 862, 495: 862, 504: 862, 862, 508: 862, 515: 862, 520: 862, 530: 862, 564: 862, 567: 862, 862, 570: 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 582: 862, 862, 862, 862, 862, 862, 862, 862, 592: 862, 862, 595: 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 648: 862, 651: 862, 745: 862, 862, 753: 862, 862, 862, 762: 862, 769: 862, 862, 862}, - {2: 861, 861, 861, 861, 861, 861, 861, 10: 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 50: 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 473: 861, 475: 861, 861, 861, 479: 861, 482: 861, 861, 485: 861, 861, 861, 492: 861, 495: 861, 504: 861, 861, 508: 861, 515: 861, 520: 861, 530: 861, 564: 861, 567: 861, 861, 570: 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 582: 861, 861, 861, 861, 861, 861, 861, 861, 592: 861, 861, 595: 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 648: 861, 651: 861, 745: 861, 861, 753: 861, 861, 861, 762: 861, 769: 861, 861, 861}, - {2: 860, 860, 860, 860, 860, 860, 860, 10: 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 50: 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 473: 860, 475: 860, 860, 860, 479: 860, 482: 860, 860, 485: 860, 860, 860, 492: 860, 495: 860, 504: 860, 860, 508: 860, 515: 860, 520: 860, 530: 860, 564: 860, 567: 860, 860, 570: 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 582: 860, 860, 860, 860, 860, 860, 860, 860, 592: 860, 860, 595: 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, 648: 860, 651: 860, 745: 860, 860, 753: 860, 860, 860, 762: 860, 769: 860, 860, 860}, - {2: 859, 859, 859, 859, 859, 859, 859, 10: 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 50: 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 473: 859, 475: 859, 859, 859, 479: 859, 482: 859, 859, 485: 859, 859, 859, 492: 859, 495: 859, 504: 859, 859, 508: 859, 515: 859, 520: 859, 530: 859, 564: 859, 567: 859, 859, 570: 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 582: 859, 859, 859, 859, 859, 859, 859, 859, 592: 859, 859, 595: 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, 648: 859, 651: 859, 745: 859, 859, 753: 859, 859, 859, 762: 859, 769: 859, 859, 859}, + {500: 855, 509: 855, 511: 855}, + {862, 862, 58: 862, 491: 862, 494: 862, 501: 862, 512: 2816, 521: 2817, 791: 6039}, + {861, 861, 58: 861, 491: 861, 494: 861, 501: 861}, + {860, 860, 58: 860, 491: 860, 494: 860, 501: 860}, + {58: 4083, 500: 853, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, // 3425 - {2: 857, 857, 857, 857, 857, 857, 857, 10: 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 50: 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 5958, 5964, 5965, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 473: 857, 475: 857, 857, 857, 479: 857, 482: 857, 857, 485: 857, 857, 857, 492: 857, 495: 857, 504: 857, 857, 508: 857, 515: 5961, 520: 857, 530: 857, 564: 857, 567: 857, 857, 570: 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 582: 857, 857, 857, 857, 857, 857, 857, 857, 592: 857, 857, 595: 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, 648: 857, 651: 3546, 745: 3544, 3545, 753: 5403, 5402, 5401, 762: 5398, 769: 5957, 5960, 5956, 784: 5879, 787: 5954, 837: 5955, 867: 5953, 1123: 5966, 5959}, - {2: 855, 855, 855, 855, 855, 855, 855, 10: 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 50: 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 473: 855, 475: 855, 855, 855, 479: 855, 482: 855, 855, 485: 855, 855, 855, 492: 855, 495: 855, 504: 855, 855, 508: 855, 515: 855, 520: 855, 530: 855, 564: 855, 567: 855, 855, 570: 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 582: 855, 855, 855, 855, 855, 855, 855, 855, 592: 855, 855, 595: 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 855, 648: 855, 651: 855, 745: 855, 855, 753: 855, 855, 855, 762: 855, 769: 855, 855, 855}, - {2: 851, 851, 851, 851, 851, 851, 851, 10: 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 50: 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 473: 851, 475: 851, 851, 851, 479: 851, 482: 851, 851, 485: 851, 851, 851, 492: 851, 495: 851, 504: 851, 851, 508: 851, 515: 851, 520: 851, 530: 851, 564: 851, 567: 851, 851, 570: 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 582: 851, 851, 851, 851, 851, 851, 851, 851, 592: 851, 851, 595: 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, 648: 851, 651: 851, 745: 851, 851, 753: 851, 851, 851, 762: 851, 769: 851, 851, 851}, - {2: 850, 850, 850, 850, 850, 850, 850, 10: 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 50: 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 473: 850, 475: 850, 850, 850, 479: 850, 482: 850, 850, 485: 850, 850, 850, 492: 850, 495: 850, 504: 850, 850, 508: 850, 515: 850, 520: 850, 530: 850, 564: 850, 567: 850, 850, 570: 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 582: 850, 850, 850, 850, 850, 850, 850, 850, 592: 850, 850, 595: 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 648: 850, 651: 850, 745: 850, 850, 753: 850, 850, 850, 762: 850, 769: 850, 850, 850}, - {2: 856, 856, 856, 856, 856, 856, 856, 10: 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 50: 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 473: 856, 475: 856, 856, 856, 479: 856, 482: 856, 856, 485: 856, 856, 856, 492: 856, 495: 856, 504: 856, 856, 508: 856, 515: 856, 520: 856, 530: 856, 564: 856, 567: 856, 856, 570: 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 582: 856, 856, 856, 856, 856, 856, 856, 856, 592: 856, 856, 595: 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 648: 856, 651: 856, 745: 856, 856, 753: 856, 856, 856, 762: 856, 769: 856, 856, 856}, + {9: 6055, 492: 1036, 515: 1036, 588: 1036, 665: 1036, 674: 1036, 761: 1036}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6044, 2850, 688: 2851, 2849, 955: 6043, 1197: 6054}, + {9: 1033, 492: 1033, 515: 1033, 588: 1033, 665: 1033, 674: 1033, 761: 1033}, + {492: 6045, 498: 2397, 1258: 6046}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6050, 2850, 688: 2851, 2849, 901: 6049}, // 3430 - {1874, 1874, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 1874, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1874, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 1874, 474: 1874, 5985, 478: 5984, 480: 1874, 1874, 490: 1874, 1874, 493: 1874, 1874, 496: 1874, 1874, 1874, 500: 1874, 1874, 1874, 507: 3345, 509: 3343, 3344, 3342, 3340, 1874, 1874, 661: 5983, 2762, 2763, 2761, 734: 3341, 3339, 1211: 5982, 5981}, - {1878, 1878, 9: 1878, 49: 1878, 472: 1878, 474: 1878, 480: 1878, 1878, 490: 1878, 1878, 493: 1878, 1878, 496: 1878, 1878, 1878, 500: 1878, 1878, 1878, 513: 1878, 1878}, - {1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 474: 1279, 1279, 1279, 1279, 1279, 480: 1279, 1279, 484: 1279, 1279, 1279, 1279, 490: 1279, 1279, 493: 1279, 1279, 496: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 507: 1279, 509: 1279, 1279, 1279, 1279, 1279, 1279, 518: 1279, 520: 1279, 544: 1279, 547: 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 565: 1279, 1279, 594: 1279, 652: 5976, 656: 1279, 1279}, - {1868, 1868, 9: 1868, 49: 1868, 472: 1868, 474: 1868, 480: 1868, 1868, 490: 1868, 1868, 493: 1868, 1868, 496: 1868, 1868, 1868, 500: 1868, 1868, 1868, 513: 1868, 1868}, - {849, 849, 9: 5974, 49: 849, 472: 849, 474: 849, 480: 849, 849, 490: 849, 849, 493: 849, 849, 496: 849, 849, 849, 500: 849, 849, 849, 513: 849, 849}, + {498: 6047}, + {492: 2667, 731: 6048}, + {9: 1032, 492: 1032, 515: 1032, 588: 1032, 665: 1032, 674: 1032, 761: 1032}, + {9: 6052, 58: 6051}, + {2395, 2395, 9: 2395, 58: 2395, 494: 2395}, // 3435 - {1865, 1865, 49: 1865, 472: 1865, 474: 1865, 480: 1865, 1865, 490: 1865, 1865, 493: 1865, 1865, 496: 1865, 1865, 1865, 500: 1865, 1865, 1865, 513: 1865, 5939, 1059: 5973}, - {1019, 1019, 49: 1019, 472: 1019, 474: 1019, 480: 1019, 1019, 490: 1019, 1019, 493: 1019, 1019, 496: 1019, 1019, 1019, 500: 1019, 1019, 1019, 513: 1019}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 520: 5968, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 5969, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 5967, 1046: 5975}, - {1867, 1867, 9: 1867, 49: 1867, 472: 1867, 474: 1867, 480: 1867, 1867, 490: 1867, 1867, 493: 1867, 1867, 496: 1867, 1867, 1867, 500: 1867, 1867, 1867, 513: 1867, 1867}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 5977, 661: 5978, 2762, 2763, 2761}, + {498: 2396}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6053, 2850, 688: 2851, 2849}, + {2394, 2394, 9: 2394, 58: 2394, 494: 2394}, + {9: 6055, 492: 1035, 515: 1035, 588: 1035, 665: 1035, 674: 1035, 761: 1035}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6044, 2850, 688: 2851, 2849, 955: 6056}, // 3440 - {1877, 1877, 9: 1877, 49: 1877, 472: 1877, 474: 1877, 480: 1877, 1877, 490: 1877, 1877, 493: 1877, 1877, 496: 1877, 1877, 1877, 500: 1877, 1877, 1877, 513: 1877, 1877}, - {1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 3990, 1278, 1278, 1278, 1278, 1278, 480: 1278, 1278, 484: 1278, 1278, 1278, 1278, 490: 1278, 1278, 493: 1278, 1278, 496: 1278, 1278, 1278, 1278, 1278, 1278, 1278, 507: 1278, 509: 1278, 1278, 1278, 1278, 1278, 1278, 518: 1278, 520: 1278, 544: 1278, 547: 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 565: 1278, 1278, 594: 1278, 652: 5979, 656: 1278, 1278}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 5980, 661: 3786, 2762, 2763, 2761}, - {1876, 1876, 9: 1876, 49: 1876, 472: 1876, 474: 1876, 480: 1876, 1876, 490: 1876, 1876, 493: 1876, 1876, 496: 1876, 1876, 1876, 500: 1876, 1876, 1876, 513: 1876, 1876}, - {1875, 1875, 9: 1875, 49: 1875, 472: 1875, 474: 1875, 480: 1875, 1875, 490: 1875, 1875, 493: 1875, 1875, 496: 1875, 1875, 1875, 500: 1875, 1875, 1875, 513: 1875, 1875}, + {9: 1034, 492: 1034, 515: 1034, 588: 1034, 665: 1034, 674: 1034, 761: 1034}, + {1338, 1338, 58: 1338, 491: 1338, 494: 1338, 500: 1338, 1338, 509: 1338, 511: 1338, 1338, 1338, 516: 1338, 518: 1338, 521: 1338, 523: 2813, 790: 2814, 836: 6058}, + {908, 908, 58: 908, 491: 908, 494: 908, 500: 908, 908, 509: 908, 511: 908, 2816, 908, 516: 908, 518: 908, 521: 2817, 791: 2818, 852: 6059}, + {879, 879, 58: 879, 491: 879, 494: 879, 500: 879, 879, 509: 879, 511: 879, 513: 4021, 516: 879, 518: 4022, 912: 6060}, + {885, 885, 58: 885, 491: 885, 494: 885, 500: 885, 885, 509: 885, 511: 885, 516: 4047, 913: 6061}, // 3445 - {1873, 1873, 9: 1873, 49: 1873, 472: 1873, 474: 1873, 480: 1873, 1873, 490: 1873, 1873, 493: 1873, 1873, 496: 1873, 1873, 1873, 500: 1873, 1873, 1873, 513: 1873, 1873}, - {1872, 1872, 9: 1872, 49: 1872, 472: 1872, 474: 1872, 480: 1872, 1872, 490: 1872, 1872, 493: 1872, 1872, 496: 1872, 1872, 1872, 500: 1872, 1872, 1872, 513: 1872, 1872}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5987, 661: 5986, 2762, 2763, 2761}, - {1870, 1870, 9: 1870, 49: 1870, 472: 1870, 474: 1870, 480: 1870, 1870, 490: 1870, 1870, 493: 1870, 1870, 496: 1870, 1870, 1870, 500: 1870, 1870, 1870, 513: 1870, 1870}, - {1871, 1871, 9: 1871, 49: 1871, 472: 1871, 474: 1871, 480: 1871, 1871, 490: 1871, 1871, 493: 1871, 1871, 496: 1871, 1871, 1871, 500: 1871, 1871, 1871, 513: 1871, 1871}, + {1040, 1040, 58: 1040, 491: 1040, 494: 1040, 500: 1040, 1040, 509: 1040, 511: 1040}, + {908, 908, 58: 908, 491: 908, 494: 908, 500: 908, 908, 509: 908, 511: 908, 2816, 908, 516: 908, 518: 908, 521: 2817, 791: 2818, 852: 6063}, + {879, 879, 58: 879, 491: 879, 494: 879, 500: 879, 879, 509: 879, 511: 879, 513: 4021, 516: 879, 518: 4022, 912: 6064}, + {885, 885, 58: 885, 491: 885, 494: 885, 500: 885, 885, 509: 885, 511: 885, 516: 4047, 913: 6065}, + {1041, 1041, 58: 1041, 491: 1041, 494: 1041, 500: 1041, 1041, 509: 1041, 511: 1041}, // 3450 - {1869, 1869, 9: 1869, 49: 1869, 472: 1869, 474: 1869, 480: 1869, 1869, 490: 1869, 1869, 493: 1869, 1869, 496: 1869, 1869, 1869, 500: 1869, 1869, 1869, 513: 1869, 1869}, - {1020, 1020}, - {1032, 1032}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 6003, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6004, 2762, 2763, 2761}, - {72: 5996, 234: 5995}, + {681: 6073}, + {1338, 1338, 58: 1338, 491: 1338, 494: 1338, 500: 1338, 1338, 509: 1338, 511: 1338, 1338, 1338, 516: 1338, 518: 1338, 521: 1338, 523: 2813, 790: 2814, 836: 6069}, + {886, 886, 58: 886, 491: 886, 494: 886, 500: 886, 886, 509: 886, 511: 886, 886, 886, 516: 886, 518: 886, 521: 886, 523: 886, 533: 886, 535: 886}, + {908, 908, 58: 908, 491: 908, 494: 908, 500: 908, 908, 509: 908, 511: 908, 2816, 908, 516: 908, 518: 908, 521: 2817, 791: 2818, 852: 6070}, + {879, 879, 58: 879, 491: 879, 494: 879, 500: 879, 879, 509: 879, 511: 879, 513: 4021, 516: 879, 518: 4022, 912: 6071}, // 3455 - {1024, 1024}, - {800: 5994}, - {1023, 1023}, - {1026, 1026, 72: 6001}, - {234: 5997}, + {885, 885, 58: 885, 491: 885, 494: 885, 500: 885, 885, 509: 885, 511: 885, 516: 4047, 913: 6072}, + {1042, 1042, 58: 1042, 491: 1042, 494: 1042, 500: 1042, 1042, 509: 1042, 511: 1042}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 2842, 894: 3348, 925: 6074}, + {1926, 1926, 9: 3519, 58: 1926, 491: 1926, 494: 1926, 500: 1926, 1926, 509: 1926, 511: 1926, 1926, 1926, 516: 1926, 518: 1926, 521: 1926, 523: 1926, 533: 1926, 535: 1926}, + {275, 275, 58: 275, 491: 275, 494: 275, 500: 275, 275, 509: 275, 511: 275, 275, 275, 516: 275, 518: 275, 2810, 521: 275, 523: 275, 532: 275, 814: 2811, 6100}, // 3460 - {1025, 1025, 72: 5999, 800: 5998}, - {1028, 1028}, - {800: 6000}, - {1027, 1027}, - {800: 6002}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 601: 5557, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5564, 875: 5554, 914: 6085, 1239: 6084, 1357: 6083}, + {887, 887, 58: 887, 491: 887, 494: 887, 500: 887, 887, 509: 887, 511: 887, 887, 887, 516: 887, 518: 887, 521: 887, 523: 887, 532: 6066, 965: 6068, 990: 6078}, + {1338, 1338, 58: 1338, 491: 1338, 494: 1338, 500: 1338, 1338, 509: 1338, 511: 1338, 1338, 1338, 516: 1338, 518: 1338, 521: 1338, 523: 2813, 790: 2814, 836: 6079}, + {908, 908, 58: 908, 491: 908, 494: 908, 500: 908, 908, 509: 908, 511: 908, 2816, 908, 516: 908, 518: 908, 521: 2817, 791: 2818, 852: 6080}, + {879, 879, 58: 879, 491: 879, 494: 879, 500: 879, 879, 509: 879, 511: 879, 513: 4021, 516: 879, 518: 4022, 912: 6081}, // 3465 - {1029, 1029}, - {1645, 1645, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6005, 2762, 2763, 2761}, - {1031, 1031}, - {1030, 1030}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6007, 2762, 2763, 2761}, + {885, 885, 58: 885, 491: 885, 494: 885, 500: 885, 885, 509: 885, 511: 885, 516: 4047, 913: 6082}, + {1043, 1043, 58: 1043, 491: 1043, 494: 1043, 500: 1043, 1043, 509: 1043, 511: 1043}, + {275, 275, 58: 275, 491: 275, 494: 275, 500: 275, 275, 509: 275, 511: 275, 275, 275, 516: 275, 518: 275, 2810, 521: 275, 523: 275, 532: 275, 275, 535: 275, 814: 2811, 6086}, + {1031, 1031, 58: 1031, 491: 1031, 494: 1031, 500: 1031, 1031, 509: 1031, 511: 1031, 1031, 1031, 516: 1031, 518: 1031, 1031, 521: 1031, 523: 1031, 532: 1031}, + {971, 971, 9: 5608, 58: 971, 491: 971, 494: 971, 500: 971, 971, 509: 971, 511: 971, 971, 971, 516: 971, 518: 971, 971, 521: 971, 523: 971, 532: 971, 971, 535: 971}, // 3470 - {1036, 1036}, - {1040, 1040, 481: 6009}, - {568: 3349, 710: 6011, 1332: 6010}, - {1039, 1039, 9: 6012}, - {1038, 1038, 9: 1038}, + {887, 887, 58: 887, 491: 887, 494: 887, 500: 887, 887, 509: 887, 511: 887, 887, 887, 516: 887, 518: 887, 521: 887, 523: 887, 532: 6066, 887, 535: 887, 965: 6068, 990: 6087}, + {1925, 1925, 58: 1925, 491: 1925, 494: 1925, 500: 1925, 1925, 509: 1925, 511: 1925, 1925, 1925, 516: 1925, 518: 1925, 521: 1925, 523: 1925, 533: 6088, 535: 1925, 1089: 6089}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 6099}, + {1030, 1030, 58: 1030, 491: 1030, 494: 1030, 500: 1030, 1030, 509: 1030, 511: 1030, 1030, 1030, 516: 1030, 518: 1030, 521: 1030, 523: 1030, 535: 6091, 1380: 6090}, + {1056, 1056, 58: 1056, 491: 1056, 494: 1056, 500: 1056, 1056, 509: 1056, 511: 1056, 1056, 1056, 516: 1056, 518: 1056, 521: 1056, 523: 1056}, // 3475 - {568: 3349, 710: 6013}, - {1037, 1037, 9: 1037}, - {500: 6015}, - {475: 6017, 568: 3349, 710: 6018, 1282: 6016}, - {1043, 1043}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3507, 2850, 688: 2851, 2849, 948: 6094, 1193: 6093, 1381: 6092}, + {1029, 1029, 9: 6097, 58: 1029, 491: 1029, 494: 1029, 500: 1029, 1029, 509: 1029, 511: 1029, 1029, 1029, 516: 1029, 518: 1029, 521: 1029, 523: 1029}, + {1028, 1028, 9: 1028, 58: 1028, 491: 1028, 494: 1028, 500: 1028, 1028, 509: 1028, 511: 1028, 1028, 1028, 516: 1028, 518: 1028, 521: 1028, 523: 1028}, + {498: 6095}, + {492: 3508, 1195: 6096}, // 3480 - {1042, 1042}, - {1041, 1041}, - {2: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 10: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 50: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 496: 6020, 1066: 6021}, - {2: 1354, 1354, 1354, 1354, 1354, 1354, 1354, 10: 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 50: 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6022}, + {1026, 1026, 9: 1026, 58: 1026, 491: 1026, 494: 1026, 500: 1026, 1026, 509: 1026, 511: 1026, 1026, 1026, 516: 1026, 518: 1026, 521: 1026, 523: 1026}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 3507, 2850, 688: 2851, 2849, 948: 6094, 1193: 6098}, + {1027, 1027, 9: 1027, 58: 1027, 491: 1027, 494: 1027, 500: 1027, 1027, 509: 1027, 511: 1027, 1027, 1027, 516: 1027, 518: 1027, 521: 1027, 523: 1027}, + {1924, 1924, 58: 1924, 491: 1924, 494: 1924, 500: 1924, 1924, 509: 1924, 511: 1924, 1924, 1924, 516: 1924, 518: 1924, 1924, 1924, 1924, 523: 1924, 527: 3452, 3450, 3451, 3449, 3447, 1924, 535: 1924, 756: 3448, 3446}, + {1057, 1057, 58: 1057, 491: 1057, 494: 1057, 500: 1057, 1057, 509: 1057, 511: 1057, 1057, 1057, 516: 1057, 518: 1057, 521: 1057, 523: 1057, 532: 1057}, // 3485 - {158: 922, 473: 922, 922, 488: 5465, 495: 922, 506: 922, 569: 922, 646: 922, 860: 6023}, - {158: 6031, 473: 6024, 2587, 495: 6032, 506: 6030, 569: 2585, 646: 2581, 709: 6029, 748: 6027, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 6028, 6026, 977: 6025, 1065: 6033}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 2332, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 2588, 2587, 495: 2586, 569: 2585, 646: 2581, 661: 4143, 2762, 2763, 2761, 709: 5891, 744: 4144, 748: 3881, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 3883, 3882, 808: 5111, 1001: 6045}, - {473: 3897, 839: 6042, 975: 6041}, - {1347, 1347, 472: 1347, 481: 1347}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 541: 6117, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 6118, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 6116, 1074: 6119, 1247: 6120, 1324: 6121}, + {2: 906, 906, 906, 906, 906, 906, 906, 10: 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 59: 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 492: 906, 906, 495: 906, 906, 906, 502: 906, 906, 906, 906, 906, 510: 906, 514: 906, 906, 522: 906, 525: 906, 534: 906, 541: 906, 549: 906, 583: 906, 587: 906, 589: 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 601: 906, 906, 906, 906, 906, 906, 608: 906, 906, 906, 906, 906, 614: 906, 906, 617: 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, 669: 906, 671: 906, 767: 906, 906, 775: 906, 906, 906, 785: 906, 792: 906, 906, 906}, + {2: 905, 905, 905, 905, 905, 905, 905, 10: 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 59: 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 492: 905, 905, 495: 905, 905, 905, 502: 905, 905, 905, 905, 905, 510: 905, 514: 905, 905, 522: 905, 525: 905, 534: 905, 541: 905, 549: 905, 583: 905, 587: 905, 589: 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 601: 905, 905, 905, 905, 905, 905, 608: 905, 905, 905, 905, 905, 614: 905, 905, 617: 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, 669: 905, 671: 905, 767: 905, 905, 775: 905, 905, 905, 785: 905, 792: 905, 905, 905}, + {2: 904, 904, 904, 904, 904, 904, 904, 10: 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 59: 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 492: 904, 904, 495: 904, 904, 904, 502: 904, 904, 904, 904, 904, 510: 904, 514: 904, 904, 522: 904, 525: 904, 534: 904, 541: 904, 549: 904, 583: 904, 587: 904, 589: 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 601: 904, 904, 904, 904, 904, 904, 608: 904, 904, 904, 904, 904, 614: 904, 904, 617: 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, 669: 904, 671: 904, 767: 904, 904, 775: 904, 904, 904, 785: 904, 792: 904, 904, 904}, + {2: 903, 903, 903, 903, 903, 903, 903, 10: 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 59: 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 492: 903, 903, 495: 903, 903, 903, 502: 903, 903, 903, 903, 903, 510: 903, 514: 903, 903, 522: 903, 525: 903, 534: 903, 541: 903, 549: 903, 583: 903, 587: 903, 589: 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 601: 903, 903, 903, 903, 903, 903, 608: 903, 903, 903, 903, 903, 614: 903, 903, 617: 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, 669: 903, 671: 903, 767: 903, 903, 775: 903, 903, 903, 785: 903, 792: 903, 903, 903}, // 3490 - {1346, 1346, 472: 1346, 480: 815, 1346, 490: 815, 815}, - {1345, 1345, 472: 1345, 481: 1345}, - {1344, 1344, 472: 1344, 480: 814, 1344, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, - {1330, 1330, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 1330, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 1330, 481: 1330, 661: 4143, 2762, 2763, 2761, 744: 6035, 1005: 6036, 1194: 6034}, - {473: 1342}, + {2: 902, 902, 902, 902, 902, 902, 902, 10: 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 59: 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 492: 902, 902, 495: 902, 902, 902, 502: 902, 902, 902, 902, 902, 510: 902, 514: 902, 902, 522: 902, 525: 902, 534: 902, 541: 902, 549: 902, 583: 902, 587: 902, 589: 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 601: 902, 902, 902, 902, 902, 902, 608: 902, 902, 902, 902, 902, 614: 902, 902, 617: 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, 669: 902, 671: 902, 767: 902, 902, 775: 902, 902, 902, 785: 902, 792: 902, 902, 902}, + {2: 901, 901, 901, 901, 901, 901, 901, 10: 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 59: 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 492: 901, 901, 495: 901, 901, 901, 502: 901, 901, 901, 901, 901, 510: 901, 514: 901, 901, 522: 901, 525: 901, 534: 901, 541: 901, 549: 901, 583: 901, 587: 901, 589: 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 601: 901, 901, 901, 901, 901, 901, 608: 901, 901, 901, 901, 901, 614: 901, 901, 617: 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 669: 901, 671: 901, 767: 901, 901, 775: 901, 901, 901, 785: 901, 792: 901, 901, 901}, + {2: 900, 900, 900, 900, 900, 900, 900, 10: 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 59: 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 492: 900, 900, 495: 900, 900, 900, 502: 900, 900, 900, 900, 900, 510: 900, 514: 900, 900, 522: 900, 525: 900, 534: 900, 541: 900, 549: 900, 583: 900, 587: 900, 589: 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 601: 900, 900, 900, 900, 900, 900, 608: 900, 900, 900, 900, 900, 614: 900, 900, 617: 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 669: 900, 671: 900, 767: 900, 900, 775: 900, 900, 900, 785: 900, 792: 900, 900, 900}, + {2: 899, 899, 899, 899, 899, 899, 899, 10: 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 59: 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 492: 899, 899, 495: 899, 899, 899, 502: 899, 899, 899, 899, 899, 510: 899, 514: 899, 899, 522: 899, 525: 899, 534: 899, 541: 899, 549: 899, 583: 899, 587: 899, 589: 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 601: 899, 899, 899, 899, 899, 899, 608: 899, 899, 899, 899, 899, 614: 899, 899, 617: 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, 669: 899, 671: 899, 767: 899, 899, 775: 899, 899, 899, 785: 899, 792: 899, 899, 899}, + {2: 898, 898, 898, 898, 898, 898, 898, 10: 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 59: 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 492: 898, 898, 495: 898, 898, 898, 502: 898, 898, 898, 898, 898, 510: 898, 514: 898, 898, 522: 898, 525: 898, 534: 898, 541: 898, 549: 898, 583: 898, 587: 898, 589: 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 601: 898, 898, 898, 898, 898, 898, 608: 898, 898, 898, 898, 898, 614: 898, 898, 617: 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 669: 898, 671: 898, 767: 898, 898, 775: 898, 898, 898, 785: 898, 792: 898, 898, 898}, // 3495 - {473: 1341, 575: 3896, 912: 3895, 976: 3894}, - {1325, 1325, 481: 1325}, - {1343, 1343, 9: 6039, 472: 1343, 481: 1343}, - {499: 6037}, - {1329, 1329, 9: 1329, 472: 1329, 481: 1329}, + {2: 896, 896, 896, 896, 896, 896, 896, 10: 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 59: 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 6107, 6113, 6114, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 492: 896, 896, 495: 896, 896, 896, 502: 896, 896, 896, 896, 896, 510: 896, 514: 896, 896, 522: 896, 525: 896, 534: 6110, 541: 896, 549: 896, 583: 896, 587: 896, 589: 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 601: 896, 896, 896, 896, 896, 896, 608: 896, 896, 896, 896, 896, 614: 896, 896, 617: 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 669: 896, 671: 3653, 767: 3651, 3652, 775: 5550, 5549, 5548, 785: 5545, 792: 6106, 6109, 6105, 808: 6028, 810: 6103, 861: 6104, 890: 6102, 1155: 6115, 6108}, + {2: 894, 894, 894, 894, 894, 894, 894, 10: 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 59: 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 492: 894, 894, 495: 894, 894, 894, 502: 894, 894, 894, 894, 894, 510: 894, 514: 894, 894, 522: 894, 525: 894, 534: 894, 541: 894, 549: 894, 583: 894, 587: 894, 589: 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 601: 894, 894, 894, 894, 894, 894, 608: 894, 894, 894, 894, 894, 614: 894, 894, 617: 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 669: 894, 671: 894, 767: 894, 894, 775: 894, 894, 894, 785: 894, 792: 894, 894, 894}, + {2: 890, 890, 890, 890, 890, 890, 890, 10: 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 59: 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 492: 890, 890, 495: 890, 890, 890, 502: 890, 890, 890, 890, 890, 510: 890, 514: 890, 890, 522: 890, 525: 890, 534: 890, 541: 890, 549: 890, 583: 890, 587: 890, 589: 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 601: 890, 890, 890, 890, 890, 890, 608: 890, 890, 890, 890, 890, 614: 890, 890, 617: 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 669: 890, 671: 890, 767: 890, 890, 775: 890, 890, 890, 785: 890, 792: 890, 890, 890}, + {2: 889, 889, 889, 889, 889, 889, 889, 10: 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 59: 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 492: 889, 889, 495: 889, 889, 889, 502: 889, 889, 889, 889, 889, 510: 889, 514: 889, 889, 522: 889, 525: 889, 534: 889, 541: 889, 549: 889, 583: 889, 587: 889, 589: 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 601: 889, 889, 889, 889, 889, 889, 608: 889, 889, 889, 889, 889, 614: 889, 889, 617: 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 889, 669: 889, 671: 889, 767: 889, 889, 775: 889, 889, 889, 785: 889, 792: 889, 889, 889}, + {2: 895, 895, 895, 895, 895, 895, 895, 10: 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 59: 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 492: 895, 895, 495: 895, 895, 895, 502: 895, 895, 895, 895, 895, 510: 895, 514: 895, 895, 522: 895, 525: 895, 534: 895, 541: 895, 549: 895, 583: 895, 587: 895, 589: 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 601: 895, 895, 895, 895, 895, 895, 608: 895, 895, 895, 895, 895, 614: 895, 895, 617: 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 669: 895, 671: 895, 767: 895, 895, 775: 895, 895, 895, 785: 895, 792: 895, 895, 895}, // 3500 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3903, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3899, 797: 6038}, - {1331, 1331, 9: 1331, 472: 1331, 481: 1331}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 6035, 1005: 6040}, - {1328, 1328, 9: 1328, 472: 1328, 481: 1328}, - {1348, 1348, 9: 6043, 472: 1348, 481: 1348}, + {1934, 1934, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 1934, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1934, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 1934, 493: 6134, 1934, 498: 6133, 500: 1934, 1934, 509: 1934, 511: 1934, 1934, 1934, 516: 1934, 518: 1934, 1934, 1934, 1934, 523: 1934, 527: 3452, 3450, 3451, 3449, 3447, 1934, 1934, 685: 6132, 2850, 688: 2851, 2849, 756: 3448, 3446, 1244: 6131, 6130}, + {1938, 1938, 9: 1938, 58: 1938, 491: 1938, 494: 1938, 500: 1938, 1938, 509: 1938, 511: 1938, 1938, 1938, 516: 1938, 518: 1938, 1938, 1938, 1938, 523: 1938, 532: 1938, 1938}, + {1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 493: 1320, 1320, 1320, 497: 1320, 1320, 1320, 1320, 1320, 504: 1320, 1320, 1320, 509: 1320, 511: 1320, 1320, 1320, 516: 1320, 1320, 1320, 1320, 1320, 1320, 523: 1320, 527: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 537: 1320, 541: 1320, 564: 1320, 566: 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320, 584: 1320, 1320, 1320, 616: 1320, 672: 6125, 676: 1320, 1320}, + {1928, 1928, 9: 1928, 58: 1928, 491: 1928, 494: 1928, 500: 1928, 1928, 509: 1928, 511: 1928, 1928, 1928, 516: 1928, 518: 1928, 1928, 1928, 1928, 523: 1928, 532: 1928, 1928}, + {888, 888, 9: 6123, 58: 888, 491: 888, 494: 888, 500: 888, 888, 509: 888, 511: 888, 888, 888, 516: 888, 518: 888, 888, 888, 888, 523: 888, 532: 888, 888}, // 3505 - {1340, 1340, 9: 1340, 472: 1340, 481: 1340}, - {473: 3897, 839: 6044}, - {1339, 1339, 9: 1339, 472: 1339, 481: 1339}, - {49: 6046}, - {158: 6031, 473: 2588, 2587, 495: 6032, 569: 2585, 646: 2581, 709: 6051, 748: 6049, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 6050, 6048, 977: 6047}, + {1925, 1925, 58: 1925, 491: 1925, 494: 1925, 500: 1925, 1925, 509: 1925, 511: 1925, 1925, 1925, 516: 1925, 518: 1925, 1925, 1925, 1925, 523: 1925, 532: 1925, 6088, 1089: 6122}, + {1058, 1058, 58: 1058, 491: 1058, 494: 1058, 500: 1058, 1058, 509: 1058, 511: 1058, 1058, 1058, 516: 1058, 518: 1058, 1058, 1058, 1058, 523: 1058, 532: 1058}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 541: 6117, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 6118, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 6116, 1074: 6124}, + {1927, 1927, 9: 1927, 58: 1927, 491: 1927, 494: 1927, 500: 1927, 1927, 509: 1927, 511: 1927, 1927, 1927, 516: 1927, 518: 1927, 1927, 1927, 1927, 523: 1927, 532: 1927, 1927}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 6126, 685: 6127, 2850, 688: 2851, 2849}, // 3510 - {473: 3897, 839: 6042, 975: 6052}, - {1352, 1352, 472: 1352, 481: 1352}, - {1351, 1351, 472: 1351, 480: 815, 1351, 490: 815, 815}, - {1350, 1350, 472: 1350, 481: 1350}, - {1349, 1349, 472: 1349, 480: 814, 1349, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, + {1937, 1937, 9: 1937, 58: 1937, 491: 1937, 494: 1937, 500: 1937, 1937, 509: 1937, 511: 1937, 1937, 1937, 516: 1937, 518: 1937, 1937, 1937, 1937, 523: 1937, 532: 1937, 1937}, + {1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 4099, 1319, 1319, 1319, 497: 1319, 1319, 1319, 1319, 1319, 504: 1319, 1319, 1319, 509: 1319, 511: 1319, 1319, 1319, 516: 1319, 1319, 1319, 1319, 1319, 1319, 523: 1319, 527: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 537: 1319, 541: 1319, 564: 1319, 566: 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 1319, 584: 1319, 1319, 1319, 616: 1319, 672: 6128, 676: 1319, 1319}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 6129, 685: 3893, 2850, 688: 2851, 2849}, + {1936, 1936, 9: 1936, 58: 1936, 491: 1936, 494: 1936, 500: 1936, 1936, 509: 1936, 511: 1936, 1936, 1936, 516: 1936, 518: 1936, 1936, 1936, 1936, 523: 1936, 532: 1936, 1936}, + {1935, 1935, 9: 1935, 58: 1935, 491: 1935, 494: 1935, 500: 1935, 1935, 509: 1935, 511: 1935, 1935, 1935, 516: 1935, 518: 1935, 1935, 1935, 1935, 523: 1935, 532: 1935, 1935}, // 3515 - {1353, 1353, 9: 6043, 472: 1353, 481: 1353}, - {2: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 10: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 50: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 489: 1057, 496: 1057, 753: 5403, 5402, 5401, 837: 5404, 887: 6054}, - {2: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 10: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 50: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 489: 4191, 496: 1856, 855: 6055}, - {2: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 10: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 50: 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 1355, 496: 6020, 1066: 6056}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6057}, + {1933, 1933, 9: 1933, 58: 1933, 491: 1933, 494: 1933, 500: 1933, 1933, 509: 1933, 511: 1933, 1933, 1933, 516: 1933, 518: 1933, 1933, 1933, 1933, 523: 1933, 532: 1933, 1933}, + {1932, 1932, 9: 1932, 58: 1932, 491: 1932, 494: 1932, 500: 1932, 1932, 509: 1932, 511: 1932, 1932, 1932, 516: 1932, 518: 1932, 1932, 1932, 1932, 523: 1932, 532: 1932, 1932}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 6136, 685: 6135, 2850, 688: 2851, 2849}, + {1930, 1930, 9: 1930, 58: 1930, 491: 1930, 494: 1930, 500: 1930, 1930, 509: 1930, 511: 1930, 1930, 1930, 516: 1930, 518: 1930, 1930, 1930, 1930, 523: 1930, 532: 1930, 1930}, + {1931, 1931, 9: 1931, 58: 1931, 491: 1931, 494: 1931, 500: 1931, 1931, 509: 1931, 511: 1931, 1931, 1931, 516: 1931, 518: 1931, 1931, 1931, 1931, 523: 1931, 532: 1931, 1931}, // 3520 - {158: 922, 473: 922, 922, 488: 5465, 495: 922, 506: 922, 569: 922, 646: 922, 860: 6058}, - {158: 6031, 473: 6024, 2587, 495: 6032, 506: 6030, 569: 2585, 646: 2581, 709: 6029, 748: 6027, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 6028, 6026, 977: 6025, 1065: 6059}, - {1327, 1327, 472: 6061, 481: 1327, 1260: 6060}, - {1356, 1356, 481: 1356}, - {206: 6062}, + {1929, 1929, 9: 1929, 58: 1929, 491: 1929, 494: 1929, 500: 1929, 1929, 509: 1929, 511: 1929, 1929, 1929, 516: 1929, 518: 1929, 1929, 1929, 1929, 523: 1929, 532: 1929, 1929}, + {1059, 1059}, + {1071, 1071}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 6152, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6153, 2850, 688: 2851, 2849}, + {79: 6145, 250: 6144}, // 3525 - {581: 6063}, - {654: 6064}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 5519, 892: 5520, 925: 6065}, - {1326, 1326, 9: 5522, 481: 1326}, - {1360, 1360, 473: 6074, 652: 1832}, + {1063, 1063}, + {822: 6143}, + {1062, 1062}, + {1065, 1065, 79: 6150}, + {250: 6146}, // 3530 - {1361, 1361}, - {652: 6069}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6070, 2762, 2763, 2761}, - {1359, 1359, 473: 6071}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 6072}, + {1064, 1064, 79: 6148, 822: 6147}, + {1067, 1067}, + {822: 6149}, + {1066, 1066}, + {822: 6151}, // 3535 - {49: 6073}, - {1357, 1357}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 1919, 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 3588, 778: 3752, 826: 6075}, - {49: 6076}, - {1358, 1358}, + {1068, 1068}, + {1702, 1702, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6154, 2850, 688: 2851, 2849}, + {1070, 1070}, + {1069, 1069}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6156, 2850, 688: 2851, 2849}, // 3540 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6237, 2762, 2763, 2761}, - {600, 600, 498: 6234, 518: 6233, 1297: 6232}, - {18: 6220, 103: 6217, 134: 6222, 170: 6221, 196: 6219, 569: 6216, 582: 6218}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 6205, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6206}, - {676, 676, 494: 6200}, + {1075, 1075}, + {1079, 1079, 501: 6158}, + {589: 3456, 732: 6160, 1367: 6159}, + {1078, 1078, 9: 6161}, + {1077, 1077, 9: 1077}, // 3545 - {126: 6199}, - {102: 3944, 111: 3943, 125: 6194, 217: 6193, 834: 6195}, - {672, 672}, - {664, 664, 186: 6175, 229: 6176, 239: 6177, 242: 6174, 264: 6179, 274: 6178, 288: 6181, 292: 6180, 493: 664, 664, 501: 664, 651: 6182, 1130: 6173, 1300: 6172, 6171}, - {670, 670}, + {589: 3456, 732: 6162}, + {1076, 1076, 9: 1076}, + {520: 6164}, + {493: 6166, 589: 3456, 732: 6167, 1316: 6165}, + {1082, 1082}, // 3550 - {669, 669}, - {602, 602, 267: 6162, 494: 6161, 498: 602, 518: 602}, - {500: 647, 544: 647}, - {500: 646, 544: 646}, - {500: 645, 544: 645}, + {1081, 1081}, + {1080, 1080}, + {2: 1396, 1396, 1396, 1396, 1396, 1396, 1396, 10: 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 59: 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 516: 6169, 1096: 6170}, + {2: 1395, 1395, 1395, 1395, 1395, 1395, 1395, 10: 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 59: 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395, 1395}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6171}, // 3555 - {642, 642, 498: 642, 518: 642}, - {641, 641, 498: 641, 518: 641}, - {640, 640, 498: 640, 518: 640}, - {639, 639, 498: 639, 518: 639}, - {125: 6159}, + {172: 961, 492: 961, 494: 961, 507: 5612, 515: 961, 526: 961, 588: 961, 665: 961, 883: 6172}, + {172: 6180, 492: 6173, 494: 2666, 515: 6181, 526: 6179, 588: 2664, 665: 2660, 731: 6178, 770: 6176, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 6177, 6175, 1002: 6174, 1095: 6182}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 2399, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 2667, 494: 2666, 515: 2665, 588: 2664, 665: 2660, 685: 4256, 2850, 688: 2851, 2849, 731: 6040, 766: 4257, 770: 3990, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 3992, 3991, 831: 5242, 1026: 6194}, + {492: 4006, 863: 6191, 1000: 6190}, + {1388, 1388, 491: 1388, 501: 1388}, // 3560 - {500: 6129, 544: 6130, 805: 6154}, - {102: 590, 111: 590, 211: 6127, 1090: 6148}, - {473: 6143}, - {630, 630, 498: 630, 518: 630}, - {628, 628, 498: 628, 518: 628}, + {1387, 1387, 491: 1387, 500: 854, 1387, 509: 854, 511: 854}, + {1386, 1386, 491: 1386, 501: 1386}, + {1385, 1385, 491: 1385, 500: 853, 1385, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {1371, 1371, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 1371, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 1371, 501: 1371, 685: 4256, 2850, 688: 2851, 2849, 766: 6184, 1030: 6185, 1227: 6183}, + {492: 1383}, // 3565 - {126: 6141, 141: 6142, 202: 6140}, - {624, 624, 498: 624, 518: 624}, - {588, 588, 498: 588, 500: 6129, 518: 588, 544: 6130, 805: 6132, 841: 6139}, - {126: 6138}, - {126: 6137}, + {492: 1382, 595: 4005, 937: 4004, 1001: 4003}, + {1366, 1366, 501: 1366}, + {1384, 1384, 9: 6188, 491: 1384, 501: 1384}, + {517: 6186}, + {1370, 1370, 9: 1370, 491: 1370, 501: 1370}, // 3570 - {126: 6136}, - {126: 6135}, - {126: 6134}, - {588, 588, 498: 588, 500: 6129, 518: 588, 544: 6130, 805: 6132, 841: 6131}, - {616, 616, 498: 616, 518: 616}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 4012, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 4008, 819: 6187}, + {1372, 1372, 9: 1372, 491: 1372, 501: 1372}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 6184, 1030: 6189}, + {1369, 1369, 9: 1369, 491: 1369, 501: 1369}, + {1389, 1389, 9: 6192, 491: 1389, 501: 1389}, // 3575 - {615, 615, 498: 615, 518: 615}, - {614, 614, 498: 614, 518: 614}, - {613, 613, 498: 613, 518: 613}, - {612, 612, 498: 612, 518: 612}, - {611, 611, 498: 611, 518: 611}, + {1381, 1381, 9: 1381, 491: 1381, 501: 1381}, + {492: 4006, 863: 6193}, + {1380, 1380, 9: 1380, 491: 1380, 501: 1380}, + {58: 6195}, + {172: 6180, 492: 2667, 494: 2666, 515: 6181, 588: 2664, 665: 2660, 731: 6200, 770: 6198, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 6199, 6197, 1002: 6196}, // 3580 - {610, 610, 498: 610, 518: 610}, - {609, 609, 498: 609, 518: 609}, - {608, 608, 498: 608, 518: 608}, - {607, 607, 498: 607, 518: 607}, - {126: 6128}, + {492: 4006, 863: 6191, 1000: 6201}, + {1393, 1393, 491: 1393, 501: 1393}, + {1392, 1392, 491: 1392, 500: 854, 1392, 509: 854, 511: 854}, + {1391, 1391, 491: 1391, 501: 1391}, + {1390, 1390, 491: 1390, 500: 853, 1390, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, // 3585 - {605, 605, 498: 605, 518: 605}, - {604, 604, 498: 604, 518: 604}, - {603, 603, 498: 603, 518: 603}, - {126: 596, 141: 596, 202: 596}, - {126: 595, 141: 595, 160: 595, 202: 595}, + {1394, 1394, 9: 6192, 491: 1394, 501: 1394}, + {2: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 10: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 59: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 508: 1096, 516: 1096, 775: 5550, 5549, 5548, 861: 5551, 910: 6203}, + {2: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 10: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 59: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 508: 4304, 516: 1916, 878: 6204}, + {2: 1396, 1396, 1396, 1396, 1396, 1396, 1396, 10: 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 59: 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 516: 6169, 1096: 6205}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6206}, // 3590 - {102: 589, 111: 589, 125: 589, 217: 589}, - {606, 606, 498: 606, 518: 606}, - {2: 644, 644, 644, 644, 644, 644, 644, 10: 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 50: 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644}, - {2: 643, 643, 643, 643, 643, 643, 643, 10: 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 50: 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643, 643}, - {617, 617, 498: 617, 518: 617}, + {172: 961, 492: 961, 494: 961, 507: 5612, 515: 961, 526: 961, 588: 961, 665: 961, 883: 6207}, + {172: 6180, 492: 6173, 494: 2666, 515: 6181, 526: 6179, 588: 2664, 665: 2660, 731: 6178, 770: 6176, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 6177, 6175, 1002: 6174, 1095: 6208}, + {1368, 1368, 491: 6210, 501: 1368, 1294: 6209}, + {1397, 1397, 501: 1397}, + {221: 6211}, // 3595 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5396, 2762, 2763, 2761, 817: 6133}, - {587, 587, 498: 587, 518: 587}, - {618, 618, 498: 618, 518: 618}, - {619, 619, 498: 619, 518: 619}, - {620, 620, 498: 620, 518: 620}, + {600: 6212}, + {674: 6213}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 5666, 916: 5667, 950: 6214}, + {1367, 1367, 9: 5669, 501: 1367}, + {1401, 1401, 492: 6223, 672: 1892}, // 3600 - {621, 621, 498: 621, 518: 621}, - {622, 622, 498: 622, 518: 622}, - {623, 623, 498: 623, 518: 623}, - {627, 627, 498: 627, 518: 627}, - {626, 626, 498: 626, 518: 626}, + {1402, 1402}, + {672: 6218}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6219, 2850, 688: 2851, 2849}, + {1400, 1400, 492: 6220}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 6221}, // 3605 - {625, 625, 498: 625, 518: 625}, - {520: 6144}, - {49: 6145}, - {181: 6147, 307: 6146}, - {631, 631, 498: 631, 518: 631}, + {58: 6222}, + {1398, 1398}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 1980, 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 3695, 801: 3859, 848: 6224}, + {58: 6225}, + {1399, 1399}, // 3610 - {629, 629, 498: 629, 518: 629}, - {102: 3944, 111: 3943, 834: 6149}, - {500: 6129, 544: 6130, 805: 6151, 1132: 6150}, - {588, 588, 498: 588, 500: 6129, 518: 588, 544: 6130, 805: 6132, 841: 6153}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6152}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6391, 2850, 688: 2851, 2849}, + {637, 637, 519: 6388, 537: 6387, 1332: 6386}, + {18: 6370, 51: 6371, 110: 6367, 151: 6373, 183: 6372, 210: 6369, 588: 6366, 602: 6368}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 6355, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6356}, + {714, 714, 513: 6350}, // 3615 - {586, 586, 498: 586, 500: 586, 518: 586, 544: 586}, - {632, 632, 498: 632, 518: 632}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6155, 2762, 2763, 2761, 737: 6156}, - {1055, 1055, 498: 1055, 500: 6129, 518: 1055, 544: 6130, 652: 3926, 805: 6157}, - {635, 635, 498: 635, 518: 635}, + {138: 6349}, + {109: 4053, 136: 4052, 6344, 231: 6343, 857: 6345}, + {710, 710}, + {702, 702, 113: 6324, 199: 6325, 244: 6326, 255: 6327, 279: 6329, 289: 6328, 303: 6331, 306: 6330, 512: 702, 702, 521: 702, 671: 6332, 1162: 6323, 1335: 6322, 6321}, + {708, 708}, // 3620 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6158, 2762, 2763, 2761}, - {634, 634, 498: 634, 518: 634}, - {588, 588, 498: 588, 500: 6129, 518: 588, 544: 6130, 805: 6132, 841: 6160}, - {637, 637, 498: 637, 518: 637}, - {569: 6166, 582: 6163, 851: 6165, 1298: 6164}, + {707, 707}, + {639, 639, 282: 6312, 513: 6311, 519: 639, 537: 639}, + {520: 685, 564: 685}, + {520: 684, 564: 684}, + {520: 683, 564: 683}, // 3625 - {601, 601, 498: 601, 518: 601}, - {2: 2068, 2068, 2068, 2068, 2068, 2068, 2068, 10: 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 50: 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 2068, 479: 2068, 484: 2068, 505: 2068, 2068, 520: 2068, 564: 2068, 647: 2068}, - {668, 668}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5396, 2762, 2763, 2761, 817: 6170}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6167}, + {680, 680, 519: 680, 537: 680}, + {679, 679, 519: 679, 537: 679}, + {678, 678, 519: 678, 537: 678}, + {677, 677, 519: 677, 537: 677}, + {137: 6309}, // 3630 - {666, 666, 488: 6168}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6169, 2762, 2763, 2761}, - {665, 665}, - {667, 667}, - {651, 651, 493: 651, 6189, 501: 651, 1299: 6188}, + {520: 6279, 564: 6280, 827: 6304}, + {109: 627, 136: 627, 226: 6277, 1120: 6298}, + {492: 6293}, + {668, 668, 519: 668, 537: 668}, + {666, 666, 519: 666, 537: 666}, // 3635 - {663, 663, 9: 6186, 493: 663, 663, 501: 663}, - {662, 662, 9: 662, 493: 662, 662, 501: 662}, - {660, 660, 9: 660, 493: 660, 660, 501: 660}, - {659, 659, 9: 659, 493: 659, 659, 501: 659}, - {354: 6185}, + {138: 6291, 155: 6292, 216: 6290}, + {662, 662, 519: 662, 537: 662}, + {625, 625, 519: 625, 6279, 537: 625, 564: 6280, 827: 6282, 865: 6289}, + {138: 6288}, + {138: 6287}, // 3640 - {393: 6184}, - {344: 6183}, - {655, 655, 9: 655, 493: 655, 655, 501: 655}, - {654, 654, 9: 654, 493: 654, 654, 501: 654}, - {653, 653, 9: 653, 493: 653, 653, 501: 653}, + {138: 6286}, + {138: 6285}, + {138: 6284}, + {625, 625, 519: 625, 6279, 537: 625, 564: 6280, 827: 6282, 865: 6281}, + {654, 654, 519: 654, 537: 654}, // 3645 - {652, 652, 9: 652, 493: 652, 652, 501: 652}, - {656, 656, 9: 656, 493: 656, 656, 501: 656}, - {657, 657, 9: 657, 493: 657, 657, 501: 657}, - {658, 658, 9: 658, 493: 658, 658, 501: 658}, - {186: 6175, 229: 6176, 239: 6177, 242: 6174, 264: 6179, 274: 6178, 288: 6181, 292: 6180, 651: 6182, 1130: 6187}, + {653, 653, 519: 653, 537: 653}, + {652, 652, 519: 652, 537: 652}, + {651, 651, 519: 651, 537: 651}, + {650, 650, 519: 650, 537: 650}, + {649, 649, 519: 649, 537: 649}, // 3650 - {661, 661, 9: 661, 493: 661, 661, 501: 661}, - {869, 869, 493: 2728, 501: 2729, 768: 2730, 830: 6192}, - {139: 6190}, - {508: 2736, 733: 4053, 763: 6191}, - {650, 650, 493: 650, 501: 650}, + {648, 648, 519: 648, 537: 648}, + {647, 647, 519: 647, 537: 647}, + {646, 646, 519: 646, 537: 646}, + {645, 645, 519: 645, 537: 645}, + {644, 644, 519: 644, 537: 644}, // 3655 - {671, 671}, - {673, 673}, - {588, 588, 498: 588, 500: 6129, 518: 588, 544: 6130, 805: 6132, 841: 6198}, - {500: 6129, 544: 6130, 805: 6151, 1132: 6196}, - {588, 588, 498: 588, 500: 6129, 518: 588, 544: 6130, 805: 6132, 841: 6197}, + {138: 6278}, + {642, 642, 519: 642, 537: 642}, + {641, 641, 519: 641, 537: 641}, + {640, 640, 519: 640, 537: 640}, + {138: 633, 155: 633, 216: 633}, // 3660 - {633, 633, 498: 633, 518: 633}, - {638, 638, 498: 638, 518: 638}, - {674, 674}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 6201}, - {649, 649, 481: 6203, 1333: 6202}, + {138: 632, 155: 632, 174: 632, 216: 632}, + {109: 626, 136: 626, 626, 231: 626}, + {643, 643, 519: 643, 537: 643}, + {2: 682, 682, 682, 682, 682, 682, 682, 10: 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 59: 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682}, + {2: 681, 681, 681, 681, 681, 681, 681, 10: 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 59: 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681, 681}, // 3665 - {675, 675}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 5739, 5737, 862: 6204}, - {648, 648, 9: 5740}, - {588, 588, 88: 1735, 163: 1735, 488: 1735, 498: 588, 500: 6129, 518: 588, 544: 6130, 649: 1735, 652: 1735, 805: 6132, 841: 6215}, - {88: 922, 163: 6208, 488: 5465, 649: 922, 860: 6207}, + {655, 655, 519: 655, 537: 655}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 6283}, + {624, 624, 519: 624, 537: 624}, + {656, 656, 519: 656, 537: 656}, + {657, 657, 519: 657, 537: 657}, // 3670 - {88: 6209, 649: 6210}, - {678, 678}, - {247, 247, 498: 2722, 790: 2723, 6214}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6211, 2762, 2763, 2761}, - {88: 6212}, + {658, 658, 519: 658, 537: 658}, + {659, 659, 519: 659, 537: 659}, + {660, 660, 519: 660, 537: 660}, + {661, 661, 519: 661, 537: 661}, + {665, 665, 519: 665, 537: 665}, // 3675 - {247, 247, 498: 2722, 790: 2723, 6213}, - {677, 677}, - {679, 679}, - {636, 636, 498: 636, 518: 636}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6231}, + {664, 664, 519: 664, 537: 664}, + {663, 663, 519: 663, 537: 663}, + {541: 6294}, + {58: 6295}, + {194: 6297, 322: 6296}, // 3680 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6230}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 6228}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6227}, - {165: 6225}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 6224}, + {669, 669, 519: 669, 537: 669}, + {667, 667, 519: 667, 537: 667}, + {109: 4053, 136: 4052, 857: 6299}, + {520: 6279, 564: 6280, 827: 6301, 1164: 6300}, + {625, 625, 519: 625, 6279, 537: 625, 564: 6280, 827: 6282, 865: 6303}, // 3685 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6223, 2762, 2763, 2761}, - {680, 680}, - {681, 681}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5004, 2762, 2763, 2761, 886: 6226}, - {682, 682}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6302}, + {623, 623, 519: 623, 623, 537: 623, 564: 623}, + {670, 670, 519: 670, 537: 670}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6305, 2850, 688: 2851, 2849, 759: 6306}, + {1094, 1094, 519: 1094, 6279, 537: 1094, 564: 6280, 672: 4035, 827: 6307}, // 3690 - {683, 683}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5396, 2762, 2763, 2761, 817: 6229}, - {684, 684}, - {685, 685}, - {686, 686}, + {673, 673, 519: 673, 537: 673}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6308, 2850, 688: 2851, 2849}, + {672, 672, 519: 672, 537: 672}, + {625, 625, 519: 625, 6279, 537: 625, 564: 6280, 827: 6282, 865: 6310}, + {675, 675, 519: 675, 537: 675}, // 3695 - {687, 687}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 3349, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3348, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 6236, 3253, 3334, 3252, 3249}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 2840, 2788, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 2869, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 2874, 2801, 2766, 2783, 2948, 3031, 3020, 2818, 2830, 2941, 2942, 2937, 2895, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 2876, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 2760, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 2880, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 2799, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 2866, 2865, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 2936, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 2824, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 2751, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 2882, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 2752, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3144, 2878, 3145, 3146, 2777, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3159, 3160, 3211, 3210, 3057, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 2918, 2935, 3058, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3177, 3178, 3179, 2931, 3130, 3189, 3190, 3201, 3185, 3186, 3187, 3220, 2877, 473: 3260, 475: 3239, 3258, 2755, 479: 3268, 482: 3272, 3276, 485: 3257, 3256, 3295, 492: 3230, 495: 3269, 504: 3275, 3293, 508: 3234, 530: 3264, 564: 3271, 567: 3294, 2753, 570: 3277, 3229, 3231, 3233, 3232, 3261, 3237, 3251, 3242, 3263, 3238, 582: 3270, 3262, 3267, 3273, 3283, 3336, 3284, 3285, 592: 3236, 3314, 595: 3254, 3255, 3309, 3310, 3311, 3312, 3313, 3265, 3291, 3296, 3306, 3307, 3300, 3315, 3316, 3317, 3301, 3319, 3320, 3302, 3318, 3297, 3305, 3303, 3289, 3321, 3322, 3266, 3326, 3278, 3279, 3282, 3325, 3331, 3330, 3332, 3329, 3333, 3328, 3327, 3324, 3274, 3323, 3281, 3280, 3286, 3287, 648: 2756, 661: 3244, 2762, 2763, 2761, 709: 3259, 3335, 3245, 3250, 3235, 3308, 3248, 3246, 3247, 3288, 3299, 3298, 3292, 3290, 3304, 3243, 3253, 3334, 3252, 3249, 2759, 2758, 2757, 6235}, - {598, 598, 507: 3345, 509: 3343, 3344, 3342, 3340, 734: 3341, 3339}, - {599, 599, 484: 3350, 594: 3351}, + {588: 6316, 602: 6313, 856: 6315, 1333: 6314}, + {638, 638, 519: 638, 537: 638}, + {2: 2130, 2130, 2130, 2130, 2130, 2130, 2130, 10: 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 59: 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 2130, 496: 2130, 499: 2130, 514: 2130, 526: 2130, 541: 2130, 583: 2130, 667: 2130}, + {706, 706}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 6320}, // 3700 - {1955, 1955, 181: 6239, 569: 1955, 1263: 6238}, - {564, 564, 569: 6241, 969: 6240}, - {1954, 1954, 569: 1954}, - {1960, 1960}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 6242}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6317}, + {704, 704, 507: 6318}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6319, 2850, 688: 2851, 2849}, + {703, 703}, + {705, 705}, // 3705 - {563, 563, 9: 3924}, - {2: 1957, 1957, 1957, 1957, 1957, 1957, 1957, 10: 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 50: 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 1957, 564: 6245, 1227: 6244}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6248, 2762, 2763, 2761}, - {476: 4089, 4088, 810: 6246}, - {194: 6247}, + {689, 689, 512: 689, 6339, 521: 689, 1334: 6338}, + {701, 701, 9: 6336, 512: 701, 701, 521: 701}, + {700, 700, 9: 700, 512: 700, 700, 521: 700}, + {698, 698, 9: 698, 512: 698, 698, 521: 698}, + {697, 697, 9: 697, 512: 697, 697, 521: 697}, // 3710 - {2: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 10: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 50: 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956}, - {1963, 1963}, - {2: 1959, 1959, 1959, 1959, 1959, 1959, 1959, 10: 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 50: 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 1959, 564: 6251, 1228: 6250}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6253, 2762, 2763, 2761}, - {194: 6252}, + {367: 6335}, + {410: 6334}, + {358: 6333}, + {693, 693, 9: 693, 512: 693, 693, 521: 693}, + {692, 692, 9: 692, 512: 692, 692, 521: 692}, // 3715 - {2: 1958, 1958, 1958, 1958, 1958, 1958, 1958, 10: 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 50: 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958, 1958}, - {1964, 1964}, - {508: 2736, 733: 6255}, - {1966, 1966}, - {500: 6265}, + {691, 691, 9: 691, 512: 691, 691, 521: 691}, + {690, 690, 9: 690, 512: 690, 690, 521: 690}, + {694, 694, 9: 694, 512: 694, 694, 521: 694}, + {695, 695, 9: 695, 512: 695, 695, 521: 695}, + {696, 696, 9: 696, 512: 696, 696, 521: 696}, // 3720 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 6260, 661: 5396, 2762, 2763, 2761, 817: 6262, 1203: 6261}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 6259}, - {9: 3924, 500: 2013, 650: 2013}, - {500: 2015, 650: 2015}, - {9: 6263, 500: 2014, 650: 2014}, + {113: 6324, 199: 6325, 244: 6326, 255: 6327, 279: 6329, 289: 6328, 303: 6331, 306: 6330, 671: 6332, 1162: 6337}, + {699, 699, 9: 699, 512: 699, 699, 521: 699}, + {908, 908, 512: 2816, 521: 2817, 791: 2818, 852: 6342}, + {153: 6340}, + {525: 2824, 755: 4162, 784: 6341}, // 3725 - {9: 2012, 500: 2012, 650: 2012}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5396, 2762, 2763, 2761, 817: 6264}, - {9: 2011, 500: 2011, 650: 2011}, - {475: 6266}, - {2010, 2010, 17: 2010, 50: 2010, 52: 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 472: 2010, 653: 2010, 898: 6267}, + {688, 688, 512: 688, 521: 688}, + {709, 709}, + {711, 711}, + {625, 625, 519: 625, 6279, 537: 625, 564: 6280, 827: 6282, 865: 6348}, + {520: 6279, 564: 6280, 827: 6301, 1164: 6346}, // 3730 - {2016, 2016, 17: 6294, 50: 6270, 52: 6290, 6283, 6273, 6269, 6277, 6281, 6293, 6276, 6282, 6280, 6278, 6291, 6284, 6272, 6292, 6271, 6274, 6275, 6279, 472: 6285, 653: 6295, 894: 6287, 6286, 6289, 6268, 899: 6288}, - {2009, 2009, 17: 2009, 50: 2009, 52: 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 472: 2009, 653: 2009}, - {499: 2008, 508: 2008}, - {499: 2007, 508: 2007}, - {499: 2006, 508: 2006, 571: 2006, 2006}, + {625, 625, 519: 625, 6279, 537: 625, 564: 6280, 827: 6282, 865: 6347}, + {671, 671, 519: 671, 537: 671}, + {676, 676, 519: 676, 537: 676}, + {712, 712}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 6351}, // 3735 - {499: 2005, 508: 2005, 571: 2005, 2005}, - {499: 2004, 508: 2004, 571: 2004, 2004}, - {499: 2003, 508: 2003, 571: 2003, 2003}, - {499: 2002, 508: 2002, 571: 2002, 2002}, - {499: 2001, 508: 2001, 571: 2001, 2001}, + {687, 687, 501: 6353, 1368: 6352}, + {713, 713}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 5886, 5884, 885: 6354}, + {686, 686, 9: 5887}, + {625, 625, 95: 1792, 177: 1792, 507: 1792, 519: 625, 6279, 537: 625, 564: 6280, 668: 1792, 672: 1792, 827: 6282, 865: 6365}, // 3740 - {499: 2000, 508: 2000, 571: 2000, 2000}, - {499: 1999, 508: 1999, 571: 1999, 1999}, - {475: 1998, 499: 1998}, - {475: 1997, 499: 1997}, - {475: 1996, 499: 1996}, + {95: 961, 177: 6358, 507: 5612, 668: 961, 883: 6357}, + {95: 6359, 668: 6360}, + {716, 716}, + {275, 275, 519: 2810, 814: 2811, 6364}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6361, 2850, 688: 2851, 2849}, // 3745 - {475: 1995, 499: 1995}, - {2: 1994, 1994, 1994, 1994, 1994, 1994, 1994, 10: 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 50: 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994, 475: 1994, 489: 1994, 499: 1994, 504: 1994}, - {2: 1993, 1993, 1993, 1993, 1993, 1993, 1993, 10: 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 50: 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993, 475: 1993, 489: 1993, 499: 1993, 504: 1993}, - {206: 6335}, - {499: 4281, 508: 2047, 736: 6333}, + {95: 6362}, + {275, 275, 519: 2810, 814: 2811, 6363}, + {715, 715}, + {717, 717}, + {674, 674, 519: 674, 537: 674}, // 3750 - {499: 4281, 508: 2047, 571: 2047, 2047, 736: 6331}, - {475: 2047, 499: 4281, 736: 6329}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 489: 2047, 499: 4281, 504: 2047, 736: 6324}, - {475: 2047, 499: 4281, 508: 2047, 736: 6319}, - {475: 2047, 499: 4281, 508: 2047, 736: 6316}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6385}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6384}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6382}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6381}, + {179: 6379}, // 3755 - {499: 4281, 508: 2047, 736: 6311}, - {102: 2047, 111: 2047, 499: 4281, 508: 2047, 736: 6308}, - {187: 2047, 2047, 192: 2047, 499: 4281, 508: 2047, 571: 2047, 2047, 736: 6305}, - {187: 2047, 2047, 192: 2047, 499: 4281, 508: 2047, 571: 2047, 2047, 736: 6296}, - {187: 6302, 6303, 192: 6304, 508: 2736, 571: 6300, 6301, 733: 6299, 927: 6297, 1093: 6298}, + {532: 6376}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 6375}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6374, 2850, 688: 2851, 2849}, + {718, 718}, + {719, 719}, // 3760 - {1977, 1977, 17: 1977, 50: 1977, 52: 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 472: 1977, 653: 1977}, - {1976, 1976, 17: 1976, 50: 1976, 52: 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 472: 1976, 653: 1976}, - {1972, 1972, 17: 1972, 50: 1972, 52: 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 1972, 472: 1972, 653: 1972}, - {1971, 1971, 17: 1971, 50: 1971, 52: 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 1971, 472: 1971, 653: 1971}, - {1970, 1970, 17: 1970, 50: 1970, 52: 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 472: 1970, 653: 1970}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6377, 2850, 688: 2851, 2849, 911: 6378}, + {2254, 2254, 113: 2254, 119: 2254, 2254, 125: 2254, 135: 2254}, + {720, 720}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5135, 2850, 688: 2851, 2849, 909: 6380}, + {721, 721}, // 3765 - {1969, 1969, 17: 1969, 50: 1969, 52: 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 1969, 472: 1969, 653: 1969}, - {1968, 1968, 17: 1968, 50: 1968, 52: 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968, 472: 1968, 653: 1968}, - {1967, 1967, 17: 1967, 50: 1967, 52: 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967, 472: 1967, 653: 1967}, - {187: 6302, 6303, 192: 6304, 508: 2736, 571: 6300, 6301, 733: 6299, 927: 6306, 1093: 6307}, - {1979, 1979, 17: 1979, 50: 1979, 52: 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 472: 1979, 653: 1979}, + {722, 722}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 6383}, + {723, 723}, + {724, 724}, + {725, 725}, // 3770 - {1978, 1978, 17: 1978, 50: 1978, 52: 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 1978, 472: 1978, 653: 1978}, - {102: 3944, 111: 3943, 508: 2736, 733: 2735, 741: 6310, 834: 6309}, - {1981, 1981, 17: 1981, 50: 1981, 52: 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 472: 1981, 653: 1981}, - {1980, 1980, 17: 1980, 50: 1980, 52: 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980, 472: 1980, 653: 1980}, - {508: 2736, 733: 2735, 741: 6312}, + {726, 726}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 3456, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3455, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 6390, 3360, 3441, 3359, 3356}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 2929, 2877, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 2960, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 2890, 2965, 3072, 3039, 3123, 2854, 2872, 2919, 3332, 3333, 3032, 3033, 3028, 2986, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 2967, 3335, 2907, 2952, 2948, 3040, 3064, 2848, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 2971, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 2888, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 2956, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 2957, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3027, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 2913, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 2839, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 2973, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 2840, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3245, 2969, 3246, 3247, 2866, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3261, 3262, 3313, 3312, 3149, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3009, 3026, 3150, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3279, 3280, 3281, 3022, 3231, 3291, 3292, 3303, 3287, 3288, 3289, 3322, 2968, 492: 3367, 3346, 495: 3365, 3375, 2843, 502: 3379, 3383, 3364, 3363, 3402, 510: 3337, 514: 3400, 3376, 522: 3382, 525: 3341, 549: 3371, 583: 3378, 587: 3401, 589: 2841, 3384, 3336, 3338, 3340, 3339, 3368, 3344, 3358, 3345, 3349, 601: 3370, 3377, 3369, 3374, 3398, 3380, 608: 3385, 3390, 3443, 3391, 3392, 614: 3343, 3421, 617: 3361, 3362, 3416, 3417, 3418, 3419, 3420, 3372, 3403, 3413, 3414, 3407, 3422, 3423, 3424, 3408, 3426, 3427, 3409, 3425, 3404, 3412, 3410, 3396, 3428, 3429, 3373, 3433, 3386, 3389, 3432, 3438, 3437, 3439, 3436, 3440, 3435, 3434, 3431, 3381, 3430, 3388, 3387, 3393, 3394, 669: 2844, 685: 3351, 2850, 688: 2851, 2849, 731: 3366, 3442, 3352, 3357, 3342, 3415, 3355, 3353, 3354, 3395, 3406, 3405, 3399, 3397, 3411, 3350, 3360, 3441, 3359, 3356, 2847, 2846, 2845, 6389}, + {635, 635, 527: 3452, 3450, 3451, 3449, 3447, 756: 3448, 3446}, + {636, 636, 499: 3457, 616: 3458}, // 3775 - {212: 6313}, - {547: 6314}, - {108: 6315}, - {1982, 1982, 17: 1982, 50: 1982, 52: 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982, 472: 1982, 653: 1982}, - {475: 6317, 508: 2736, 733: 2735, 741: 6318}, + {2016, 2016, 194: 6393, 588: 2016, 1297: 6392}, + {601, 601, 588: 6395, 994: 6394}, + {2015, 2015, 588: 2015}, + {2021, 2021}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 6396}, // 3780 - {1984, 1984, 17: 1984, 50: 1984, 52: 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 472: 1984, 653: 1984}, - {1983, 1983, 17: 1983, 50: 1983, 52: 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983, 472: 1983, 653: 1983}, - {475: 6321, 508: 2736, 733: 2735, 741: 6320}, - {1985, 1985, 17: 1985, 50: 1985, 52: 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 104: 3464, 3460, 108: 3457, 3472, 112: 3459, 3456, 3458, 3462, 3463, 3468, 3467, 3466, 3470, 3471, 3465, 3469, 3461, 472: 1985, 653: 1985, 796: 6322}, - {1986, 1986, 17: 1986, 50: 1986, 52: 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 472: 1986, 653: 1986}, + {600, 600, 9: 4033}, + {2: 2018, 2018, 2018, 2018, 2018, 2018, 2018, 10: 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 59: 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 583: 6399, 1259: 6398}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6402, 2850, 688: 2851, 2849}, + {495: 4198, 497: 4197, 834: 6400}, + {208: 6401}, // 3785 - {311: 6323}, - {1987, 1987, 17: 1987, 50: 1987, 52: 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 1987, 472: 1987, 653: 1987}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 489: 6327, 504: 6328, 661: 3491, 2762, 2763, 2761, 738: 6326, 1314: 6325}, - {1988, 1988, 17: 1988, 50: 1988, 52: 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 1988, 472: 1988, 653: 1988}, - {256, 256, 17: 256, 50: 256, 52: 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 472: 256, 653: 256}, + {2: 2017, 2017, 2017, 2017, 2017, 2017, 2017, 10: 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 59: 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017}, + {2024, 2024}, + {2: 2020, 2020, 2020, 2020, 2020, 2020, 2020, 10: 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 59: 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 583: 6405, 1260: 6404}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6407, 2850, 688: 2851, 2849}, + {208: 6406}, // 3790 - {255, 255, 17: 255, 50: 255, 52: 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 472: 255, 653: 255}, - {254, 254, 17: 254, 50: 254, 52: 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 472: 254, 653: 254}, - {475: 6330}, - {1989, 1989, 17: 1989, 50: 1989, 52: 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 472: 1989, 653: 1989}, - {508: 2736, 571: 6300, 6301, 733: 6299, 927: 6332}, + {2: 2019, 2019, 2019, 2019, 2019, 2019, 2019, 10: 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 59: 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019}, + {2025, 2025}, + {525: 2824, 755: 6409}, + {2027, 2027}, + {520: 6419}, // 3795 - {1990, 1990, 17: 1990, 50: 1990, 52: 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990, 472: 1990, 653: 1990}, - {508: 2736, 733: 2735, 741: 6334}, - {1991, 1991, 17: 1991, 50: 1991, 52: 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 472: 1991, 653: 1991}, - {2: 1992, 1992, 1992, 1992, 1992, 1992, 1992, 10: 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 50: 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992, 475: 1992, 489: 1992, 499: 1992, 504: 1992}, - {650: 6337}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 6414, 685: 5543, 2850, 688: 2851, 2849, 832: 6416, 1236: 6415}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 6413}, + {9: 4033, 520: 2074, 670: 2074}, + {520: 2076, 670: 2076}, + {9: 6417, 520: 2075, 670: 2075}, // 3800 - {475: 6338}, - {2010, 2010, 17: 2010, 50: 2010, 52: 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 472: 2010, 653: 2010, 898: 6339}, - {2017, 2017, 17: 6294, 50: 6270, 52: 6290, 6283, 6273, 6269, 6277, 6281, 6293, 6276, 6282, 6280, 6278, 6291, 6284, 6272, 6292, 6271, 6274, 6275, 6279, 472: 6285, 653: 6295, 894: 6287, 6286, 6289, 6268, 899: 6288}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6341, 2762, 2763, 2761}, - {2018, 2018}, + {9: 2073, 520: 2073, 670: 2073}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 6418}, + {9: 2072, 520: 2072, 670: 2072}, + {493: 6420}, + {2071, 2071, 17: 2071, 56: 2071, 59: 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 491: 2071, 673: 2071, 922: 6421}, // 3805 - {2019, 2019}, - {2037, 2037, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 6375}, - {2035, 2035}, - {28: 6373}, - {1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 10: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 50: 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 499: 6362, 652: 1768}, + {2077, 2077, 17: 6448, 56: 6424, 59: 6444, 6437, 6427, 6423, 6431, 6435, 6447, 6430, 6436, 6434, 6432, 6445, 6438, 6426, 6446, 6425, 6428, 6429, 6433, 491: 6439, 673: 6449, 918: 6441, 6440, 6443, 6422, 923: 6442}, + {2070, 2070, 17: 2070, 56: 2070, 59: 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 491: 2070, 673: 2070}, + {517: 2069, 525: 2069}, + {517: 2068, 525: 2068}, + {517: 2067, 525: 2067, 591: 2067, 2067}, // 3810 - {256: 6349, 473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 665: 2707, 709: 2708, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 6348}, - {2029, 2029}, - {499: 6350}, - {171: 6354, 231: 6357, 249: 6356, 304: 6353, 6359, 6358, 475: 6352, 575: 6355, 1043: 6351}, - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 665: 2707, 709: 2708, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 6361}, + {517: 2066, 525: 2066, 591: 2066, 2066}, + {517: 2065, 525: 2065, 591: 2065, 2065}, + {517: 2064, 525: 2064, 591: 2064, 2064}, + {517: 2063, 525: 2063, 591: 2063, 2063}, + {517: 2062, 525: 2062, 591: 2062, 2062}, // 3815 - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 665: 2707, 709: 2708, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 6360}, - {473: 2026, 2026, 494: 2026, 2026, 504: 2026, 567: 2026, 569: 2026, 646: 2026, 654: 2026, 665: 2026, 739: 2026}, - {473: 2025, 2025, 494: 2025, 2025, 504: 2025, 567: 2025, 569: 2025, 646: 2025, 654: 2025, 665: 2025, 739: 2025}, - {473: 2024, 2024, 494: 2024, 2024, 504: 2024, 567: 2024, 569: 2024, 646: 2024, 654: 2024, 665: 2024, 739: 2024}, - {473: 2023, 2023, 494: 2023, 2023, 504: 2023, 567: 2023, 569: 2023, 646: 2023, 654: 2023, 665: 2023, 739: 2023}, + {517: 2061, 525: 2061, 591: 2061, 2061}, + {517: 2060, 525: 2060, 591: 2060, 2060}, + {493: 2059, 517: 2059}, + {493: 2058, 517: 2058}, + {493: 2057, 517: 2057}, // 3820 - {473: 2022, 2022, 494: 2022, 2022, 504: 2022, 567: 2022, 569: 2022, 646: 2022, 654: 2022, 665: 2022, 739: 2022}, - {473: 2021, 2021, 494: 2021, 2021, 504: 2021, 567: 2021, 569: 2021, 646: 2021, 654: 2021, 665: 2021, 739: 2021}, - {473: 2020, 2020, 494: 2020, 2020, 504: 2020, 567: 2020, 569: 2020, 646: 2020, 654: 2020, 665: 2020, 739: 2020}, - {2027, 2027}, - {2028, 2028}, + {493: 2056, 517: 2056}, + {2: 2055, 2055, 2055, 2055, 2055, 2055, 2055, 10: 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 59: 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 2055, 493: 2055, 508: 2055, 517: 2055, 522: 2055}, + {2: 2054, 2054, 2054, 2054, 2054, 2054, 2054, 10: 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 59: 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 2054, 493: 2054, 508: 2054, 517: 2054, 522: 2054}, + {221: 6489}, + {517: 4397, 525: 2109, 758: 6487}, // 3825 - {171: 6354, 231: 6357, 249: 6356, 304: 6353, 6359, 6358, 475: 6363, 575: 6355, 1043: 6364}, - {473: 2588, 2587, 494: 6369, 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 665: 2707, 709: 2708, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 6370}, - {473: 2588, 2587, 494: 6365, 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 665: 2707, 709: 2708, 739: 2553, 748: 2709, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2715, 2714, 766: 2554, 772: 2689, 774: 2712, 2713, 2711, 779: 2555, 783: 2710, 806: 2716, 825: 6366}, - {28: 6367}, - {2030, 2030}, + {517: 4397, 525: 2109, 591: 2109, 2109, 758: 6485}, + {493: 2109, 517: 4397, 758: 6483}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 508: 2109, 517: 4397, 522: 2109, 758: 6478}, + {493: 2109, 517: 4397, 525: 2109, 758: 6473}, + {493: 2109, 517: 4397, 525: 2109, 758: 6470}, // 3830 - {508: 2736, 733: 6368}, - {2031, 2031}, - {28: 6371}, - {2032, 2032}, - {508: 2736, 733: 6372}, + {517: 4397, 525: 2109, 758: 6465}, + {109: 2109, 136: 2109, 517: 4397, 525: 2109, 758: 6462}, + {200: 2109, 2109, 206: 2109, 517: 4397, 525: 2109, 591: 2109, 2109, 758: 6459}, + {200: 2109, 2109, 206: 2109, 517: 4397, 525: 2109, 591: 2109, 2109, 758: 6450}, + {200: 6456, 6457, 206: 6458, 525: 2824, 591: 6454, 6455, 755: 6453, 952: 6451, 1123: 6452}, // 3835 - {2033, 2033}, - {508: 2736, 733: 6374}, - {2034, 2034}, - {2036, 2036}, - {2044, 2044}, + {2038, 2038, 17: 2038, 56: 2038, 59: 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 2038, 491: 2038, 673: 2038}, + {2037, 2037, 17: 2037, 56: 2037, 59: 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 491: 2037, 673: 2037}, + {2033, 2033, 17: 2033, 56: 2033, 59: 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 2033, 491: 2033, 673: 2033}, + {2032, 2032, 17: 2032, 56: 2032, 59: 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 2032, 491: 2032, 673: 2032}, + {2031, 2031, 17: 2031, 56: 2031, 59: 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 2031, 491: 2031, 673: 2031}, // 3840 - {499: 6402}, - {73: 2547, 147: 2549, 155: 2577, 2562, 159: 2546, 396: 6398, 473: 2588, 2587, 495: 2586, 504: 2572, 506: 6381, 567: 2571, 569: 2585, 646: 2581, 653: 2545, 2690, 709: 6379, 739: 2553, 748: 6380, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 6387, 6386, 766: 2554, 772: 2689, 774: 6384, 6385, 6383, 779: 2555, 783: 6382, 800: 2563, 809: 6396, 844: 6395, 6389, 849: 6390, 859: 6388, 861: 6392, 863: 6393, 6391, 6394, 920: 6397}, - {463, 463, 480: 814, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, - {465, 465, 480: 815, 490: 815, 815}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 5700, 5695, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 5698, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 5697, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 5702, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 5696, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 5705, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 5703, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 5699, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 505: 3837, 568: 5711, 587: 5710, 647: 3835, 661: 5708, 2762, 2763, 2761, 773: 5712, 831: 5709, 978: 5713, 1158: 5706}, + {2030, 2030, 17: 2030, 56: 2030, 59: 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 2030, 491: 2030, 673: 2030}, + {2029, 2029, 17: 2029, 56: 2029, 59: 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 2029, 491: 2029, 673: 2029}, + {2028, 2028, 17: 2028, 56: 2028, 59: 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 2028, 491: 2028, 673: 2028}, + {200: 6456, 6457, 206: 6458, 525: 2824, 591: 6454, 6455, 755: 6453, 952: 6460, 1123: 6461}, + {2040, 2040, 17: 2040, 56: 2040, 59: 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 491: 2040, 673: 2040}, // 3845 - {470, 470}, - {469, 469}, - {468, 468}, - {467, 467}, - {466, 466}, + {2039, 2039, 17: 2039, 56: 2039, 59: 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 491: 2039, 673: 2039}, + {109: 4053, 136: 4052, 525: 2824, 755: 2823, 762: 6464, 857: 6463}, + {2042, 2042, 17: 2042, 56: 2042, 59: 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 491: 2042, 673: 2042}, + {2041, 2041, 17: 2041, 56: 2041, 59: 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 2041, 491: 2041, 673: 2041}, + {525: 2824, 755: 2823, 762: 6466}, // 3850 - {464, 464}, - {462, 462}, - {461, 461}, - {460, 460}, - {459, 459}, + {228: 6467}, + {566: 6468}, + {114: 6469}, + {2043, 2043, 17: 2043, 56: 2043, 59: 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 2043, 491: 2043, 673: 2043}, + {493: 6471, 525: 2824, 755: 2823, 762: 6472}, // 3855 - {458, 458}, - {457, 457}, - {456, 456}, - {455, 455}, - {23: 5200}, + {2045, 2045, 17: 2045, 56: 2045, 59: 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 2045, 491: 2045, 673: 2045}, + {2044, 2044, 17: 2044, 56: 2044, 59: 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 2044, 491: 2044, 673: 2044}, + {493: 6475, 525: 2824, 755: 2823, 762: 6474}, + {2046, 2046, 17: 2046, 56: 2046, 59: 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 111: 3567, 3571, 114: 3564, 3579, 118: 3566, 121: 3563, 3565, 3569, 3570, 126: 3575, 3574, 3573, 3577, 3578, 3572, 3576, 134: 3568, 491: 2046, 673: 2046, 813: 6476}, + {2047, 2047, 17: 2047, 56: 2047, 59: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 491: 2047, 673: 2047}, // 3860 - {2042, 2042}, - {499: 6399}, - {475: 6400}, - {73: 2547, 147: 2549, 155: 2577, 2562, 159: 2546, 473: 2588, 2587, 495: 2586, 504: 2572, 506: 6381, 567: 2571, 569: 2585, 646: 2581, 653: 2545, 2690, 709: 6379, 739: 2553, 748: 6380, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 6387, 6386, 766: 2554, 772: 2689, 774: 6384, 6385, 6383, 779: 2555, 783: 6382, 800: 2563, 809: 6396, 844: 6395, 6389, 849: 6390, 859: 6388, 861: 6392, 863: 6393, 6391, 6394, 920: 6401}, - {2041, 2041}, + {326: 6477}, + {2048, 2048, 17: 2048, 56: 2048, 59: 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 491: 2048, 673: 2048}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 508: 6481, 522: 6482, 685: 3598, 2850, 688: 2851, 2849, 760: 6480, 1349: 6479}, + {2049, 2049, 17: 2049, 56: 2049, 59: 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 2049, 491: 2049, 673: 2049}, + {284, 284, 17: 284, 56: 284, 59: 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 491: 284, 673: 284}, // 3865 - {475: 6403}, - {73: 2547, 147: 2549, 155: 2577, 2562, 159: 2546, 473: 2588, 2587, 495: 2586, 504: 2572, 506: 6381, 567: 2571, 569: 2585, 646: 2581, 653: 2545, 2690, 709: 6379, 739: 2553, 748: 6380, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 6387, 6386, 766: 2554, 772: 2689, 774: 6384, 6385, 6383, 779: 2555, 783: 6382, 800: 2563, 809: 6396, 844: 6395, 6389, 849: 6390, 859: 6388, 861: 6392, 863: 6393, 6391, 6394, 920: 6404}, - {2043, 2043}, - {2: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 10: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 50: 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 489: 1057, 500: 1057, 753: 5403, 5402, 5401, 837: 5404, 887: 6406}, - {2: 1045, 1045, 1045, 1045, 1045, 1045, 1045, 10: 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 50: 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 5776, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 489: 1045, 500: 1045, 1109: 6407}, + {283, 283, 17: 283, 56: 283, 59: 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 491: 283, 673: 283}, + {282, 282, 17: 282, 56: 282, 59: 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 491: 282, 673: 282}, + {493: 6484}, + {2050, 2050, 17: 2050, 56: 2050, 59: 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 2050, 491: 2050, 673: 2050}, + {525: 2824, 591: 6454, 6455, 755: 6453, 952: 6486}, // 3870 - {2: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 10: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 50: 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 1856, 489: 4191, 500: 1856, 855: 6408}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 500: 6409, 661: 5780, 2762, 2763, 2761, 917: 5781, 967: 5779}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6411, 2762, 2763, 2761, 737: 5793, 917: 5781, 967: 6410}, - {9: 5789, 481: 6414}, - {1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1047, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 50: 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 478: 1055, 481: 1047, 488: 1055, 1055, 493: 1055, 498: 1055, 502: 1055, 1055, 525: 1055, 652: 6412, 907: 5782}, + {2051, 2051, 17: 2051, 56: 2051, 59: 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 2051, 491: 2051, 673: 2051}, + {525: 2824, 755: 2823, 762: 6488}, + {2052, 2052, 17: 2052, 56: 2052, 59: 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 491: 2052, 673: 2052}, + {2: 2053, 2053, 2053, 2053, 2053, 2053, 2053, 10: 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 59: 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 2053, 493: 2053, 508: 2053, 517: 2053, 522: 2053}, + {670: 6491}, // 3875 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 520: 5785, 661: 6413, 2762, 2763, 2761}, - {1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1047, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 50: 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 478: 1054, 481: 1047, 488: 1054, 1054, 493: 1054, 498: 1054, 502: 1054, 1054, 525: 1054, 652: 5787, 907: 5786}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 5415, 579: 5410, 661: 3921, 2762, 2763, 2761, 709: 5414, 737: 5413, 798: 5412, 802: 5411, 5417, 852: 5407, 890: 6415}, - {247, 247, 9: 5461, 498: 2722, 790: 2723, 6416}, - {2073, 2073}, + {493: 6492}, + {2071, 2071, 17: 2071, 56: 2071, 59: 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 491: 2071, 673: 2071, 922: 6493}, + {2078, 2078, 17: 6448, 56: 6424, 59: 6444, 6437, 6427, 6423, 6431, 6435, 6447, 6430, 6436, 6434, 6432, 6445, 6438, 6426, 6446, 6425, 6428, 6429, 6433, 491: 6439, 673: 6449, 918: 6441, 6440, 6443, 6422, 923: 6442}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6495, 2850, 688: 2851, 2849}, + {2079, 2079}, // 3880 - {2076, 2076, 9: 3590}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6476, 2762, 2763, 2761}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6474}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6465}, - {125: 5539, 569: 5538, 1148: 6461}, + {2080, 2080}, + {2099, 2099, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 6530}, + {2097, 2097}, + {28: 6528}, + {1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 10: 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 59: 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 1827, 517: 6517, 672: 1827}, // 3885 - {160: 596, 167: 5593}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 564: 6456, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 6455}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 564: 6452, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5298, 868: 6451}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 564: 6448, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 5739, 5737, 862: 6447}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6443}, + {271: 6503, 492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 682: 2795, 731: 2796, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 6502}, + {2091, 2091}, + {517: 6504}, + {184: 6508, 246: 6511, 264: 6510, 307: 6514, 319: 6507, 6513, 6512, 493: 6506, 595: 6509, 1071: 6505}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 682: 2795, 731: 2796, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 6516}, // 3890 - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6441}, - {160: 6436}, - {165: 6433}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6431}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 6432}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 682: 2795, 731: 2796, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 6515}, + {492: 2088, 494: 2088, 513: 2088, 515: 2088, 522: 2088, 587: 2088, 2088, 665: 2088, 674: 2088, 682: 2088, 761: 2088}, + {492: 2087, 494: 2087, 513: 2087, 515: 2087, 522: 2087, 587: 2087, 2087, 665: 2087, 674: 2087, 682: 2087, 761: 2087}, + {492: 2086, 494: 2086, 513: 2086, 515: 2086, 522: 2086, 587: 2086, 2086, 665: 2086, 674: 2086, 682: 2086, 761: 2086}, + {492: 2085, 494: 2085, 513: 2085, 515: 2085, 522: 2085, 587: 2085, 2085, 665: 2085, 674: 2085, 682: 2085, 761: 2085}, // 3895 - {28, 28, 9: 3924}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6434}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5004, 2762, 2763, 2761, 886: 6435}, - {55, 55}, - {494: 6437}, + {492: 2084, 494: 2084, 513: 2084, 515: 2084, 522: 2084, 587: 2084, 2084, 665: 2084, 674: 2084, 682: 2084, 761: 2084}, + {492: 2083, 494: 2083, 513: 2083, 515: 2083, 522: 2083, 587: 2083, 2083, 665: 2083, 674: 2083, 682: 2083, 761: 2083}, + {492: 2082, 494: 2082, 513: 2082, 515: 2082, 522: 2082, 587: 2082, 2082, 665: 2082, 674: 2082, 682: 2082, 761: 2082}, + {492: 2081, 494: 2081, 513: 2081, 515: 2081, 522: 2081, 587: 2081, 2081, 665: 2081, 674: 2081, 682: 2081, 761: 2081}, + {2089, 2089}, // 3900 - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 709: 5761, 739: 5759, 748: 5762, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 5760, 5764, 5763, 766: 5766, 772: 2689, 774: 5767, 5768, 5765, 846: 6438}, - {179, 179, 481: 6439}, - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 709: 5761, 739: 5759, 748: 5762, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 5760, 5764, 5763, 766: 5766, 772: 2689, 774: 5767, 5768, 5765, 846: 6440}, - {178, 178}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6442, 2762, 2763, 2761}, + {2090, 2090}, + {184: 6508, 246: 6511, 264: 6510, 307: 6514, 319: 6507, 6513, 6512, 493: 6518, 595: 6509, 1071: 6519}, + {492: 2667, 494: 2666, 513: 6524, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 682: 2795, 731: 2796, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 6525}, + {492: 2667, 494: 2666, 513: 6520, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 682: 2795, 731: 2796, 761: 2632, 770: 2797, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2803, 2802, 788: 2774, 2633, 795: 2800, 2801, 2799, 802: 2634, 807: 2798, 829: 2804, 847: 6521}, + {28: 6522}, // 3905 - {1961, 1961}, - {2055, 2055, 162: 6445, 488: 6444}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 6446}, - {2053, 2053}, - {2054, 2054, 9: 4755}, + {2092, 2092}, + {525: 2824, 755: 6523}, + {2093, 2093}, + {28: 6526}, + {2094, 2094}, // 3910 - {2057, 2057, 9: 5740}, - {583: 6449}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 5739, 5737, 862: 6450}, - {2056, 2056, 9: 5740}, - {2059, 2059, 9: 5300}, + {525: 2824, 755: 6527}, + {2095, 2095}, + {525: 2824, 755: 6529}, + {2096, 2096}, + {2098, 2098}, // 3915 - {583: 6453}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5298, 868: 6454}, - {2058, 2058, 9: 5300}, - {2052, 2052, 9: 3924, 670: 4813, 672: 4812, 911: 6460}, - {583: 6457}, + {2106, 2106}, + {517: 6557}, + {80: 2626, 161: 2628, 168: 2656, 2641, 173: 2625, 413: 6553, 492: 2667, 494: 2666, 515: 2665, 522: 2651, 526: 6536, 587: 2650, 2664, 665: 2660, 673: 2624, 2775, 731: 6534, 761: 2632, 770: 6535, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 6542, 6541, 788: 2774, 2633, 795: 6539, 6540, 6538, 802: 2634, 807: 6537, 822: 2642, 833: 6551, 868: 6550, 6544, 873: 6545, 882: 6543, 884: 6547, 886: 6548, 6546, 6549, 945: 6552}, + {494, 494, 500: 853, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {496, 496, 500: 854, 509: 854, 511: 854}, // 3920 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 6458}, - {2052, 2052, 9: 3924, 670: 4813, 672: 4812, 911: 6459}, - {2060, 2060}, - {2061, 2061}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6462}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 5847, 5842, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 5845, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 5844, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 5849, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 5843, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 5852, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 5850, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 5846, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 514: 3944, 589: 5858, 610: 5857, 667: 3942, 685: 5855, 2850, 688: 2851, 2849, 798: 5859, 853: 5856, 1003: 5860, 1191: 5853}, + {501, 501}, + {500, 500}, + {499, 499}, + {498, 498}, // 3925 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 3922, 795: 6463}, - {2052, 2052, 9: 3924, 670: 4813, 672: 4812, 911: 6464}, - {2065, 2065}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6466, 2762, 2763, 2761}, - {472: 6467}, + {497, 497}, + {495, 495}, + {493, 493}, + {492, 492}, + {491, 491}, // 3930 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6468}, - {2205, 2205, 83: 4235, 497: 4236, 870: 6470, 883: 6469, 1064: 6471}, - {2204, 2204, 83: 4235, 870: 6473}, - {2203, 2203, 497: 4236, 883: 6472}, - {2066, 2066}, + {490, 490}, + {489, 489}, + {488, 488}, + {487, 487}, + {486, 486}, // 3935 - {2201, 2201}, - {2202, 2202}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5396, 2762, 2763, 2761, 817: 6475}, - {2067, 2067}, - {2213, 2213}, + {23: 5343}, + {2104, 2104}, + {517: 6554}, + {493: 6555}, + {80: 2626, 161: 2628, 168: 2656, 2641, 173: 2625, 492: 2667, 494: 2666, 515: 2665, 522: 2651, 526: 6536, 587: 2650, 2664, 665: 2660, 673: 2624, 2775, 731: 6534, 761: 2632, 770: 6535, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 6542, 6541, 788: 2774, 2633, 795: 6539, 6540, 6538, 802: 2634, 807: 6537, 822: 2642, 833: 6551, 868: 6550, 6544, 873: 6545, 882: 6543, 884: 6547, 886: 6548, 6546, 6549, 945: 6556}, // 3940 - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 6698}, - {649: 6686}, - {649: 2199}, - {649: 2198}, - {649: 2197}, + {2103, 2103}, + {493: 6558}, + {80: 2626, 161: 2628, 168: 2656, 2641, 173: 2625, 492: 2667, 494: 2666, 515: 2665, 522: 2651, 526: 6536, 587: 2650, 2664, 665: 2660, 673: 2624, 2775, 731: 6534, 761: 2632, 770: 6535, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 6542, 6541, 788: 2774, 2633, 795: 6539, 6540, 6538, 802: 2634, 807: 6537, 822: 2642, 833: 6551, 868: 6550, 6544, 873: 6545, 882: 6543, 884: 6547, 886: 6548, 6546, 6549, 945: 6559}, + {2105, 2105}, + {2: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 10: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 59: 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 508: 1096, 520: 1096, 775: 5550, 5549, 5548, 861: 5551, 910: 6561}, // 3945 - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 6663}, - {18: 6584, 83: 6583, 103: 2093, 142: 2093, 668: 2093, 1336: 6582}, - {504: 6581}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 6569}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 475: 1858, 564: 4844, 570: 1858, 785: 6537}, + {2: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 10: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 59: 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 5925, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1084, 508: 1084, 520: 1084, 1139: 6562}, + {2: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 10: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 59: 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 1916, 508: 4304, 520: 1916, 878: 6563}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 520: 6564, 685: 5929, 2850, 688: 2851, 2849, 942: 5930, 992: 5928}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6566, 2850, 688: 2851, 2849, 759: 5942, 942: 5930, 992: 6565}, + {9: 5938, 501: 6569}, // 3950 - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 475: 1858, 564: 4844, 785: 6531}, - {160: 6526}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 6490}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6491}, - {51, 51, 6: 51, 51, 51, 15: 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 72: 6499, 6496, 6502, 6503, 6504, 6497, 6495, 6505, 6501, 6498, 479: 51, 51, 484: 51, 503: 51, 505: 51, 647: 51, 649: 51, 655: 6500, 913: 6494, 1198: 6492, 1293: 6493}, + {1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1086, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 59: 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 498: 1094, 501: 1086, 507: 1094, 1094, 512: 1094, 519: 1094, 523: 1094, 1094, 544: 1094, 672: 6567, 932: 5931}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 541: 5934, 685: 6568, 2850, 688: 2851, 2849}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1086, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 59: 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 498: 1093, 501: 1086, 507: 1093, 1093, 512: 1093, 519: 1093, 523: 1093, 1093, 544: 1093, 672: 5936, 932: 5935}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 5562, 601: 5557, 685: 4030, 2850, 688: 2851, 2849, 731: 5561, 759: 5560, 820: 5559, 824: 5558, 5564, 875: 5554, 914: 6570}, + {275, 275, 9: 5608, 519: 2810, 814: 2811, 6571}, // 3955 - {396, 396, 6: 4241, 4243, 400, 15: 4260, 2176, 4258, 4197, 4262, 4249, 4278, 4242, 4245, 4244, 4247, 4248, 4250, 4257, 400, 4268, 4269, 4255, 4256, 4261, 4263, 4275, 4274, 4280, 4276, 4273, 4266, 4271, 4272, 4265, 4267, 4270, 4259, 479: 4240, 4277, 484: 2176, 503: 4987, 505: 2176, 647: 2176, 649: 4246, 781: 4251, 792: 4253, 813: 4252, 835: 4254, 838: 4264, 842: 4279, 919: 5615, 1017: 6525}, - {50, 50, 6: 50, 50, 50, 15: 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 72: 6499, 6496, 6502, 6503, 6504, 6497, 6495, 6505, 6501, 6498, 479: 50, 50, 484: 50, 503: 50, 505: 50, 647: 50, 649: 50, 655: 6500, 913: 6524}, - {49, 49, 6: 49, 49, 49, 15: 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 72: 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 479: 49, 49, 484: 49, 503: 49, 505: 49, 647: 49, 649: 49, 655: 49}, - {485: 2047, 2047, 499: 4281, 508: 2047, 660: 6521, 736: 6520}, - {474: 6517, 485: 2047, 2047, 499: 4281, 508: 2047, 736: 6516}, + {2135, 2135}, + {2138, 2138, 9: 3697}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6639, 2850, 688: 2851, 2849}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 6637}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 6628}, // 3960 - {485: 2047, 2047, 499: 4281, 508: 2047, 736: 6514}, - {42, 42, 6: 42, 42, 42, 15: 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 72: 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 479: 42, 42, 484: 42, 503: 42, 505: 42, 647: 42, 649: 42, 655: 42}, - {74: 6512, 76: 6513, 6510, 655: 6511}, - {485: 2047, 2047, 499: 4281, 508: 2047, 736: 6508}, - {39, 39, 6: 39, 39, 39, 15: 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 72: 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 479: 39, 39, 484: 39, 503: 39, 505: 39, 647: 39, 649: 39, 655: 39}, + {137: 5686, 588: 5685, 1180: 6624}, + {174: 633, 181: 5740}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 583: 6619, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 6618}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 583: 6615, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5443, 891: 6614}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 583: 6611, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 5886, 5884, 885: 6610}, // 3965 - {485: 2047, 2047, 499: 4281, 508: 2047, 736: 6506}, - {36, 36, 6: 36, 36, 36, 15: 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 72: 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 479: 36, 36, 484: 36, 503: 36, 505: 36, 647: 36, 649: 36, 655: 36}, - {34, 34, 6: 34, 34, 34, 15: 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 72: 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 479: 34, 34, 484: 34, 503: 34, 505: 34, 647: 34, 649: 34, 655: 34}, - {33, 33, 6: 33, 33, 33, 15: 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 72: 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 479: 33, 33, 484: 33, 503: 33, 505: 33, 647: 33, 649: 33, 655: 33}, - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6507}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6606, 804: 6605}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 6603}, + {174: 6595}, + {179: 6592}, + {532: 6589}, // 3970 - {37, 37, 6: 37, 37, 37, 15: 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 72: 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 479: 37, 37, 484: 37, 503: 37, 505: 37, 647: 37, 649: 37, 655: 37}, - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6509}, - {40, 40, 6: 40, 40, 40, 15: 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 72: 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 479: 40, 40, 484: 40, 503: 40, 505: 40, 647: 40, 649: 40, 655: 40}, - {41, 41, 6: 41, 41, 41, 15: 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 72: 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 479: 41, 41, 484: 41, 503: 41, 505: 41, 647: 41, 649: 41, 655: 41}, - {38, 38, 6: 38, 38, 38, 15: 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 72: 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 479: 38, 38, 484: 38, 503: 38, 505: 38, 647: 38, 649: 38, 655: 38}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 6587}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 6588}, + {29, 29, 9: 4033}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 6590}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6377, 2850, 688: 2851, 2849, 911: 6591}, // 3975 - {35, 35, 6: 35, 35, 35, 15: 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 72: 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 479: 35, 35, 484: 35, 503: 35, 505: 35, 647: 35, 649: 35, 655: 35}, - {32, 32, 6: 32, 32, 32, 15: 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 72: 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 479: 32, 32, 484: 32, 503: 32, 505: 32, 647: 32, 649: 32, 655: 32}, - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6515}, - {43, 43, 6: 43, 43, 43, 15: 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 72: 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 479: 43, 43, 484: 43, 503: 43, 505: 43, 647: 43, 649: 43, 655: 43}, - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6519}, + {56, 56}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 6593}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5135, 2850, 688: 2851, 2849, 909: 6594}, + {59, 59}, + {513: 6596}, // 3980 - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6518}, - {44, 44, 6: 44, 44, 44, 15: 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 72: 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 479: 44, 44, 484: 44, 503: 44, 505: 44, 647: 44, 649: 44, 655: 44}, - {45, 45, 6: 45, 45, 45, 15: 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 72: 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 479: 45, 45, 484: 45, 503: 45, 505: 45, 647: 45, 649: 45, 655: 45}, - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6523}, - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6522}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 687: 6598, 731: 5908, 761: 5906, 770: 5909, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 5907, 5911, 5910, 788: 2774, 5913, 795: 5914, 5915, 5912, 870: 6597}, + {195, 195, 501: 6601}, + {219: 6599}, + {493: 6600}, + {193, 193}, // 3985 - {46, 46, 6: 46, 46, 46, 15: 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 72: 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 479: 46, 46, 484: 46, 503: 46, 505: 46, 647: 46, 649: 46, 655: 46}, - {47, 47, 6: 47, 47, 47, 15: 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 72: 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 479: 47, 47, 484: 47, 503: 47, 505: 47, 647: 47, 649: 47, 655: 47}, - {48, 48, 6: 48, 48, 48, 15: 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 72: 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 479: 48, 48, 484: 48, 503: 48, 505: 48, 647: 48, 649: 48, 655: 48}, - {52, 52}, - {494: 6527}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 731: 5908, 761: 5906, 770: 5909, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 5907, 5911, 5910, 788: 2774, 5913, 795: 5914, 5915, 5912, 870: 6602}, + {194, 194}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6604, 2850, 688: 2851, 2849}, + {2022, 2022}, + {2117, 2117, 9: 4033}, // 3990 - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 709: 5761, 739: 5759, 748: 5762, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 5760, 5764, 5763, 766: 5766, 772: 2689, 774: 5767, 5768, 5765, 846: 6528}, - {481: 6529}, - {473: 2588, 2587, 495: 2586, 504: 2572, 567: 2571, 569: 2585, 646: 2581, 654: 2690, 709: 5761, 739: 5759, 748: 5762, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 5760, 5764, 5763, 766: 5766, 772: 2689, 774: 5767, 5768, 5765, 846: 6530}, - {180, 180}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 6533, 5737, 1122: 6534, 1288: 6532}, + {1092, 1092, 9: 1092, 176: 6608, 507: 6607}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 6609}, + {2115, 2115}, + {2116, 2116, 9: 4886}, + {2119, 2119, 9: 5887}, // 3995 - {242, 242, 9: 6535}, - {191, 191, 9: 191}, - {190, 190, 9: 190}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 5731, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 5736, 661: 3491, 2762, 2763, 2761, 738: 5251, 801: 5738, 821: 6533, 5737, 1122: 6536}, - {189, 189, 9: 189}, + {603: 6612}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 5886, 5884, 885: 6613}, + {2118, 2118, 9: 5887}, + {2121, 2121, 9: 5445}, + {603: 6616}, // 4000 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5314, 891: 5315, 922: 6538}, - {225, 225, 9: 5317, 15: 225, 48: 225, 474: 225, 666: 5361, 960: 5360, 6539}, - {233, 233, 15: 233, 48: 233, 474: 6541, 1008: 6540}, - {212, 212, 15: 6558, 48: 6556, 953: 6557, 6555, 1102: 6554, 6553}, - {128: 6546, 6544, 6545, 6547, 1007: 6543, 1196: 6542}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5443, 891: 6617}, + {2120, 2120, 9: 5445}, + {2114, 2114, 9: 4033, 691: 4944, 693: 4943, 936: 6623}, + {603: 6620}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 6621}, // 4005 - {232, 232, 15: 232, 48: 232, 128: 6546, 6544, 6545, 6547, 1007: 6552}, - {231, 231, 15: 231, 48: 231, 128: 231, 231, 231, 231}, - {508: 2736, 733: 4053, 763: 6551}, - {508: 2736, 733: 4053, 763: 6550}, - {508: 2736, 733: 4053, 763: 6549}, + {2114, 2114, 9: 4033, 691: 4944, 693: 4943, 936: 6622}, + {2122, 2122}, + {2123, 2123}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 6625}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 4031, 804: 6626}, // 4010 - {508: 2736, 733: 4053, 763: 6548}, - {226, 226, 15: 226, 48: 226, 128: 226, 226, 226, 226}, - {227, 227, 15: 227, 48: 227, 128: 227, 227, 227, 227}, - {228, 228, 15: 228, 48: 228, 128: 228, 228, 228, 228}, - {229, 229, 15: 229, 48: 229, 128: 229, 229, 229, 229}, + {2114, 2114, 9: 4033, 691: 4944, 693: 4943, 936: 6627}, + {2127, 2127}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6629, 2850, 688: 2851, 2849}, + {491: 6630}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6631}, // 4015 - {230, 230, 15: 230, 48: 230, 128: 230, 230, 230, 230}, - {243, 243}, - {211, 211, 15: 6558, 48: 6556, 953: 6557, 6568}, - {210, 210, 15: 210, 48: 210}, - {497: 6567, 973: 6566}, + {2268, 2268, 90: 4348, 518: 4349, 893: 6633, 906: 6632, 1094: 6634}, + {2267, 2267, 90: 4348, 893: 6636}, + {2266, 2266, 518: 4349, 906: 6635}, + {2128, 2128}, + {2264, 2264}, // 4020 - {206, 206, 15: 206, 48: 206, 214: 6562, 479: 6563, 578: 6561}, - {341: 6559}, - {201, 201, 15: 201, 48: 201, 214: 201, 479: 201, 578: 201, 1188: 6560}, - {202, 202, 15: 202, 48: 202, 214: 202, 479: 202, 578: 202}, - {508: 2736, 733: 4053, 763: 6564}, + {2265, 2265}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 6638}, + {2129, 2129}, + {2276, 2276}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6911}, // 4025 - {204, 204, 15: 204, 48: 204}, - {203, 203, 15: 203, 48: 203}, - {105: 6565}, - {205, 205, 15: 205, 48: 205}, - {208, 208, 15: 208, 48: 208}, + {668: 6899}, + {668: 2262}, + {668: 2261}, + {668: 2260}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6876}, // 4030 - {207, 207, 15: 207, 48: 207}, - {209, 209, 15: 209, 48: 209}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6570, 2762, 2763, 2761}, - {500: 6571}, - {475: 6572}, + {18: 6797, 90: 6796, 110: 2155, 156: 2155, 687: 2155, 1371: 6795}, + {522: 6794}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6782}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 493: 1918, 583: 4975, 590: 1918, 805: 6730}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 493: 1918, 583: 4975, 805: 6724}, // 4035 - {1953, 1953, 17: 1953, 50: 1953, 52: 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 140: 6575, 472: 1953, 504: 6574, 653: 1953, 1041: 6573}, - {2010, 2010, 17: 2010, 50: 2010, 52: 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 472: 2010, 653: 2010, 898: 6580}, - {1952, 1952, 17: 1952, 50: 1952, 52: 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952, 472: 1952, 653: 1952}, - {206: 6578, 392: 6579, 643: 6577, 651: 6576}, - {1951, 1951, 17: 1951, 50: 1951, 52: 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951, 472: 1951, 653: 1951}, + {174: 6713}, + {532: 6690}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6654}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6655}, + {52, 52, 6: 52, 52, 52, 15: 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 79: 6663, 6660, 6666, 6667, 6668, 6661, 6659, 6669, 6665, 6662, 496: 52, 499: 52, 52, 514: 52, 524: 52, 667: 52, 52, 675: 6664, 938: 6658, 1231: 6656, 1327: 6657}, // 4040 - {1950, 1950, 17: 1950, 50: 1950, 52: 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950, 472: 1950, 653: 1950}, - {1949, 1949, 17: 1949, 50: 1949, 52: 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 472: 1949, 653: 1949}, - {1948, 1948, 17: 1948, 50: 1948, 52: 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948, 472: 1948, 653: 1948}, - {1965, 1965, 17: 6294, 50: 6270, 52: 6290, 6283, 6273, 6269, 6277, 6281, 6293, 6276, 6282, 6280, 6278, 6291, 6284, 6272, 6292, 6271, 6274, 6275, 6279, 472: 6285, 653: 6295, 894: 6287, 6286, 6289, 6268, 899: 6288}, - {18: 2094, 83: 2094, 103: 2094, 142: 2094, 668: 2094}, + {424, 424, 6: 4354, 4356, 428, 15: 4373, 2238, 4371, 4310, 4375, 4362, 4391, 4355, 4358, 4357, 4360, 4361, 4363, 4370, 428, 4381, 4382, 4392, 4368, 4369, 4374, 4376, 4388, 4387, 4396, 4389, 4386, 4379, 4384, 4385, 4378, 4380, 4383, 4372, 4393, 4394, 496: 4353, 499: 2238, 4390, 514: 2238, 524: 5118, 667: 2238, 4359, 803: 4364, 816: 4366, 837: 4365, 858: 4367, 862: 4377, 866: 4395, 944: 5762, 1044: 6689}, + {51, 51, 6: 51, 51, 51, 15: 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 79: 6663, 6660, 6666, 6667, 6668, 6661, 6659, 6669, 6665, 6662, 496: 51, 499: 51, 51, 514: 51, 524: 51, 667: 51, 51, 675: 6664, 938: 6688}, + {50, 50, 6: 50, 50, 50, 15: 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 79: 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 496: 50, 499: 50, 50, 514: 50, 524: 50, 667: 50, 50, 675: 50}, + {504: 2109, 2109, 517: 4397, 525: 2109, 681: 6685, 758: 6684}, + {494: 6681, 504: 2109, 2109, 517: 4397, 525: 2109, 758: 6680}, // 4045 - {103: 2089, 142: 6631, 668: 2089, 1338: 6630}, - {499: 6626}, - {165: 6585}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 6586}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5004, 2762, 2763, 2761, 886: 6587}, + {504: 2109, 2109, 517: 4397, 525: 2109, 758: 6678}, + {43, 43, 6: 43, 43, 43, 15: 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 79: 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 496: 43, 499: 43, 43, 514: 43, 524: 43, 667: 43, 43, 675: 43}, + {81: 6676, 83: 6677, 6674, 675: 6675}, + {504: 2109, 2109, 517: 4397, 525: 2109, 758: 6672}, + {40, 40, 6: 40, 40, 40, 15: 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 79: 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 496: 40, 499: 40, 40, 514: 40, 524: 40, 667: 40, 40, 675: 40}, // 4050 - {88: 6591, 92: 6596, 6598, 6592, 6597, 6600, 6594, 6590, 6595, 6599, 6593, 874: 6588, 1104: 6589}, - {2528, 2528, 9: 2528, 88: 2528, 92: 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528}, - {54, 54, 9: 6624, 88: 6591, 92: 6596, 6598, 6592, 6597, 6600, 6594, 6590, 6595, 6599, 6593, 874: 6623}, - {475: 2047, 499: 4281, 736: 6621}, - {475: 2047, 499: 4281, 736: 6619}, + {504: 2109, 2109, 517: 4397, 525: 2109, 758: 6670}, + {37, 37, 6: 37, 37, 37, 15: 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 79: 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 496: 37, 499: 37, 37, 514: 37, 524: 37, 667: 37, 37, 675: 37}, + {35, 35, 6: 35, 35, 35, 15: 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 79: 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 496: 35, 499: 35, 35, 514: 35, 524: 35, 667: 35, 35, 675: 35}, + {34, 34, 6: 34, 34, 34, 15: 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 79: 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 496: 34, 499: 34, 34, 514: 34, 524: 34, 667: 34, 34, 675: 34}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 6671}, // 4055 - {499: 4281, 508: 2047, 736: 6617}, - {499: 4281, 508: 2047, 736: 6615}, - {499: 4281, 508: 2047, 736: 6613}, - {475: 2047, 499: 4281, 736: 6611}, - {475: 2047, 499: 4281, 736: 6609}, + {38, 38, 6: 38, 38, 38, 15: 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 79: 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 496: 38, 499: 38, 38, 514: 38, 524: 38, 667: 38, 38, 675: 38}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 6673}, + {41, 41, 6: 41, 41, 41, 15: 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 79: 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 496: 41, 499: 41, 41, 514: 41, 524: 41, 667: 41, 41, 675: 41}, + {42, 42, 6: 42, 42, 42, 15: 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 79: 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 496: 42, 499: 42, 42, 514: 42, 524: 42, 667: 42, 42, 675: 42}, + {39, 39, 6: 39, 39, 39, 15: 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 79: 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 496: 39, 499: 39, 39, 514: 39, 524: 39, 667: 39, 39, 675: 39}, // 4060 - {475: 2047, 499: 4281, 736: 6607}, - {475: 2047, 499: 4281, 736: 6605}, - {475: 2047, 499: 4281, 736: 6603}, - {475: 2047, 499: 4281, 736: 6601}, - {475: 6602}, + {36, 36, 6: 36, 36, 36, 15: 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 79: 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 496: 36, 499: 36, 36, 514: 36, 524: 36, 667: 36, 36, 675: 36}, + {33, 33, 6: 33, 33, 33, 15: 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 79: 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 496: 33, 499: 33, 33, 514: 33, 524: 33, 667: 33, 33, 675: 33}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 6679}, + {44, 44, 6: 44, 44, 44, 15: 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 79: 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 496: 44, 499: 44, 44, 514: 44, 524: 44, 667: 44, 44, 675: 44}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 6683}, // 4065 - {2515, 2515, 9: 2515, 88: 2515, 92: 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515}, - {475: 6604}, - {2516, 2516, 9: 2516, 88: 2516, 92: 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516}, - {475: 6606}, - {2517, 2517, 9: 2517, 88: 2517, 92: 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 6682}, + {45, 45, 6: 45, 45, 45, 15: 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 79: 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 496: 45, 499: 45, 45, 514: 45, 524: 45, 667: 45, 45, 675: 45}, + {46, 46, 6: 46, 46, 46, 15: 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 79: 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 496: 46, 499: 46, 46, 514: 46, 524: 46, 667: 46, 46, 675: 46}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 6687}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 6686}, // 4070 - {475: 6608}, - {2518, 2518, 9: 2518, 88: 2518, 92: 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518}, - {475: 6610}, - {2519, 2519, 9: 2519, 88: 2519, 92: 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519}, - {475: 6612}, + {47, 47, 6: 47, 47, 47, 15: 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 79: 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 496: 47, 499: 47, 47, 514: 47, 524: 47, 667: 47, 47, 675: 47}, + {48, 48, 6: 48, 48, 48, 15: 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 79: 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 496: 48, 499: 48, 48, 514: 48, 524: 48, 667: 48, 48, 675: 48}, + {49, 49, 6: 49, 49, 49, 15: 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 79: 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 496: 49, 499: 49, 49, 514: 49, 524: 49, 667: 49, 49, 675: 49}, + {53, 53}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6691}, // 4075 - {2520, 2520, 9: 2520, 88: 2520, 92: 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520}, - {508: 2736, 733: 2735, 741: 6614}, - {2521, 2521, 9: 2521, 88: 2521, 92: 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521}, - {508: 2736, 733: 2735, 741: 6616}, - {2522, 2522, 9: 2522, 88: 2522, 92: 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6377, 2850, 688: 2851, 2849, 911: 6692}, + {113: 6697, 119: 6698, 6699, 125: 6695, 135: 6696, 898: 6693, 1147: 6694}, + {2607, 2607, 9: 2607, 113: 2607, 119: 2607, 2607, 125: 2607, 135: 2607}, + {58, 58, 9: 6711, 113: 6697, 119: 6698, 6699, 125: 6695, 135: 6696, 898: 6710}, + {517: 4397, 525: 2109, 758: 6708}, // 4080 - {508: 2736, 733: 2735, 741: 6618}, - {2523, 2523, 9: 2523, 88: 2523, 92: 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523}, - {475: 6620}, - {2524, 2524, 9: 2524, 88: 2524, 92: 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524}, - {475: 6622}, + {517: 4397, 525: 2109, 758: 6706}, + {493: 2109, 517: 4397, 758: 6704}, + {493: 2109, 517: 4397, 758: 6702}, + {493: 2109, 517: 4397, 758: 6700}, + {493: 6701}, // 4085 - {2525, 2525, 9: 2525, 88: 2525, 92: 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525}, - {2527, 2527, 9: 2527, 88: 2527, 92: 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527}, - {88: 6591, 92: 6596, 6598, 6592, 6597, 6600, 6594, 6590, 6595, 6599, 6593, 874: 6625}, - {2526, 2526, 9: 2526, 88: 2526, 92: 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526}, - {3: 6628, 398: 6629, 405: 6627}, + {2600, 2600, 9: 2600, 113: 2600, 119: 2600, 2600, 125: 2600, 135: 2600}, + {493: 6703}, + {2601, 2601, 9: 2601, 113: 2601, 119: 2601, 2601, 125: 2601, 135: 2601}, + {493: 6705}, + {2602, 2602, 9: 2602, 113: 2602, 119: 2602, 2602, 125: 2602, 135: 2602}, // 4090 - {103: 2092, 142: 2092, 668: 2092}, - {103: 2091, 142: 2091, 668: 2091}, - {103: 2090, 142: 2090, 668: 2090}, - {103: 2087, 668: 6635, 1341: 6634}, - {499: 6632}, + {525: 2824, 755: 2823, 762: 6707}, + {2603, 2603, 9: 2603, 113: 2603, 119: 2603, 2603, 125: 2603, 135: 2603}, + {525: 2824, 755: 2823, 762: 6709}, + {2604, 2604, 9: 2604, 113: 2604, 119: 2604, 2604, 125: 2604, 135: 2604}, + {2606, 2606, 9: 2606, 113: 2606, 119: 2606, 2606, 125: 2606, 135: 2606}, // 4095 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 6633}, - {103: 2088, 668: 2088}, - {103: 6639}, - {384: 6636}, - {142: 6637, 353: 6638}, + {113: 6697, 119: 6698, 6699, 125: 6695, 135: 6696, 898: 6712}, + {2605, 2605, 9: 2605, 113: 2605, 119: 2605, 2605, 125: 2605, 135: 2605}, + {513: 6714, 520: 6715}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 731: 5908, 761: 5906, 770: 5909, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 5907, 5911, 5910, 788: 2774, 5913, 795: 5914, 5915, 5912, 870: 6721}, + {227: 6716}, // 4100 - {103: 2086}, - {103: 2085}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6641, 1340: 6640}, - {473: 6643, 478: 2083, 1339: 6642}, - {473: 2084, 478: 2084}, + {501: 6717}, + {203: 6718}, + {219: 6719}, + {493: 6720}, + {196, 196}, // 4105 - {478: 6649}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6645, 2762, 2763, 2761, 1190: 6644}, - {9: 6647, 49: 6646}, - {9: 2081, 49: 2081}, - {478: 2082}, + {501: 6722}, + {492: 2667, 494: 2666, 515: 2665, 522: 2651, 587: 2650, 2664, 665: 2660, 674: 2775, 731: 5908, 761: 5906, 770: 5909, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 5907, 5911, 5910, 788: 2774, 5913, 795: 5914, 5915, 5912, 870: 6723}, + {197, 197}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 6726, 5884, 1154: 6727, 1322: 6725}, + {270, 270, 9: 6728}, // 4110 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6648, 2762, 2763, 2761}, - {9: 2080, 49: 2080}, - {473: 2588, 2587, 495: 2586, 569: 2585, 646: 2581, 709: 6653, 748: 6651, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 3880, 6652, 6650, 1200: 6654}, - {2102, 2102, 474: 2102}, - {2101, 2101, 474: 2101, 480: 815, 490: 815, 815}, + {208, 208, 9: 208}, + {207, 207, 9: 207}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 5878, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 5883, 685: 3598, 2850, 688: 2851, 2849, 760: 5396, 823: 5885, 843: 6726, 5884, 1154: 6729}, + {206, 206, 9: 206}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5459, 915: 5460, 947: 6731}, // 4115 - {2100, 2100, 474: 2100}, - {2099, 2099, 474: 2099, 480: 814, 490: 814, 814, 493: 2728, 501: 2729, 2725, 767: 3891, 3892}, - {2079, 2079, 474: 6656, 1337: 6655}, - {2096, 2096}, - {136: 6658, 321: 6657}, + {253, 253, 6: 253, 9: 5462, 15: 253, 51: 253, 253, 253, 253, 253, 494: 253, 683: 5506, 985: 5505, 6732}, + {261, 261, 6: 261, 15: 261, 51: 261, 261, 261, 261, 261, 494: 6734, 1034: 6733}, + {234, 234, 6: 234, 15: 6750, 51: 234, 234, 6749, 6751, 6752, 979: 6748, 1132: 6747, 6746}, + {143: 6739, 6737, 6738, 6740, 1033: 6736, 1229: 6735}, + {260, 260, 6: 260, 15: 260, 51: 260, 260, 260, 260, 260, 143: 6739, 6737, 6738, 6740, 1033: 6745}, // 4120 - {590: 6661}, - {590: 6659}, - {906: 6660}, - {2077, 2077}, - {906: 6662}, + {259, 259, 6: 259, 15: 259, 51: 259, 259, 259, 259, 259, 143: 259, 259, 259, 259}, + {525: 2824, 755: 4162, 784: 6744}, + {525: 2824, 755: 4162, 784: 6743}, + {525: 2824, 755: 4162, 784: 6742}, + {525: 2824, 755: 4162, 784: 6741}, // 4125 - {2078, 2078}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5396, 2762, 2763, 2761, 817: 6664}, - {2185, 2185, 16: 2176, 18: 2176, 21: 2176, 479: 4240, 484: 2176, 505: 2176, 6668, 647: 2176, 781: 6667, 792: 6666, 850: 6670, 932: 6669, 1201: 6665}, - {2194, 2194}, - {16: 3836, 18: 4197, 21: 6678, 484: 6677, 505: 3837, 647: 3835, 773: 6676, 781: 6679}, + {254, 254, 6: 254, 15: 254, 51: 254, 254, 254, 254, 254, 143: 254, 254, 254, 254}, + {255, 255, 6: 255, 15: 255, 51: 255, 255, 255, 255, 255, 143: 255, 255, 255, 255}, + {256, 256, 6: 256, 15: 256, 51: 256, 256, 256, 256, 256, 143: 256, 256, 256, 256}, + {257, 257, 6: 257, 15: 257, 51: 257, 257, 257, 257, 257, 143: 257, 257, 257, 257}, + {258, 258, 6: 258, 15: 258, 51: 258, 258, 258, 258, 258, 143: 258, 258, 258, 258}, // 4130 - {2187, 2187, 16: 2187, 18: 2187, 21: 2187, 479: 2187, 484: 2187, 505: 2187, 2187, 647: 2187}, - {168: 6672}, - {2184, 2184, 16: 2176, 18: 2176, 21: 2176, 479: 4240, 484: 2176, 505: 2176, 6668, 647: 2176, 781: 6667, 792: 6666, 850: 6671}, - {2183, 2183, 16: 2183, 18: 2183, 21: 2183, 479: 2183, 484: 2183, 505: 2183, 2183, 647: 2183}, - {2182, 2182, 16: 2182, 18: 2182, 21: 2182, 479: 2182, 484: 2182, 505: 2182, 2182, 647: 2182}, + {239, 239, 6: 6774, 51: 239, 6775, 1031: 6773}, + {233, 233, 6: 233, 15: 6750, 51: 233, 233, 6749, 6751, 6752, 979: 6772}, + {232, 232, 6: 232, 15: 232, 51: 232, 232, 232, 232, 232}, + {518: 6771, 998: 6770}, + {227: 6756, 355: 6758, 398: 6757}, // 4135 - {191: 6673}, - {508: 2736, 733: 2735, 741: 6674}, - {2499, 2499, 16: 2499, 18: 2499, 21: 2499, 184: 4980, 479: 2499, 484: 2499, 505: 2499, 2499, 647: 2499, 1077: 6675}, - {2186, 2186, 16: 2186, 18: 2186, 21: 2186, 479: 2186, 484: 2186, 505: 2186, 2186, 647: 2186}, - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 499: 4281, 530: 2047, 736: 6684}, + {525: 2824, 755: 4162, 784: 6755}, + {171: 6754, 525: 2824, 755: 4162, 784: 6753}, + {219, 219, 6: 219, 15: 219, 51: 219, 219, 219, 219, 219}, + {218, 218, 6: 218, 15: 218, 51: 218, 218, 218, 218, 218}, + {220, 220, 6: 220, 15: 220, 51: 220, 220, 220, 220, 220}, // 4140 - {2: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 10: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 50: 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 475: 2047, 499: 4281, 530: 2047, 736: 6682}, - {475: 2047, 499: 4281, 736: 6680}, - {2188, 2188, 16: 2188, 18: 2188, 21: 2188, 479: 2188, 484: 2188, 505: 2188, 2188, 647: 2188}, - {475: 4300, 1039: 6681}, - {2189, 2189, 16: 2189, 18: 2189, 21: 2189, 479: 2189, 484: 2189, 505: 2189, 2189, 647: 2189}, + {496: 6768, 525: 2824, 755: 6769}, + {599: 6764}, + {224, 224, 6: 224, 15: 224, 51: 224, 224, 224, 224, 224, 375: 6760, 496: 6761, 599: 6759}, + {525: 2824, 755: 4162, 784: 6762}, + {222, 222, 6: 222, 15: 222, 51: 222, 222, 222, 222, 222}, // 4145 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3489, 661: 3491, 2762, 2763, 2761, 738: 3488, 872: 6683}, - {2190, 2190, 16: 2190, 18: 2190, 21: 2190, 479: 2190, 484: 2190, 505: 2190, 2190, 647: 2190}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 530: 3761, 661: 3491, 2762, 2763, 2761, 738: 3760, 807: 6685}, - {2191, 2191, 16: 2191, 18: 2191, 21: 2191, 479: 2191, 484: 2191, 505: 2191, 2191, 647: 2191}, - {2: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 10: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 50: 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 564: 4844, 785: 6687}, + {221, 221, 6: 221, 15: 221, 51: 221, 221, 221, 221, 221}, + {111: 6763}, + {223, 223, 6: 223, 15: 223, 51: 223, 223, 223, 223, 223}, + {496: 6765, 525: 2824, 755: 6766}, + {226, 226, 6: 226, 15: 226, 51: 226, 226, 226, 226, 226}, // 4150 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6688, 2762, 2763, 2761}, - {84: 4877, 472: 1841, 481: 4876, 858: 6690, 1234: 6689}, - {472: 6691}, - {472: 1840}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6692}, + {111: 6767}, + {225, 225, 6: 225, 15: 225, 51: 225, 225, 225, 225, 225}, + {228, 228, 6: 228, 15: 228, 51: 228, 228, 228, 228, 228}, + {227, 227, 6: 227, 15: 227, 51: 227, 227, 227, 227, 227}, + {230, 230, 6: 230, 15: 230, 51: 230, 230, 230, 230, 230}, // 4155 - {473: 6693}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 473: 4618, 661: 4143, 2762, 2763, 2761, 744: 4617, 827: 4616, 836: 6694}, - {9: 4627, 49: 6695}, - {1852, 1852, 6: 1852, 19: 1852, 83: 1852, 1852, 1852, 1852, 1852, 89: 1852, 474: 1852, 481: 1852, 497: 1852, 880: 6696}, - {2205, 2205, 6: 4873, 19: 4870, 83: 4235, 4877, 4723, 4430, 4724, 89: 4429, 474: 4872, 481: 4876, 497: 4236, 856: 4874, 858: 4871, 869: 4875, 6470, 879: 4869, 883: 6469, 1064: 6697}, + {229, 229, 6: 229, 15: 229, 51: 229, 229, 229, 229, 229}, + {231, 231, 6: 231, 15: 231, 51: 231, 231, 231, 231, 231}, + {236, 236, 51: 6779, 1146: 6778}, + {493: 6777}, + {493: 6776}, // 4160 - {2212, 2212}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6699, 2762, 2763, 2761}, - {473: 6700}, - {233: 4906, 241: 4908, 244: 4907, 1140: 6701}, - {49: 6702}, + {237, 237, 51: 237}, + {238, 238, 51: 238}, + {271, 271}, + {532: 6780}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6377, 2850, 688: 2851, 2849, 911: 6781}, // 4165 - {472: 6703}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6704}, - {473: 6705}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4143, 2762, 2763, 2761, 744: 4144, 808: 6706}, - {9: 4146, 49: 6707}, + {235, 235}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6783, 2850, 688: 2851, 2849}, + {520: 6784}, + {493: 6785}, + {2014, 2014, 17: 2014, 56: 2014, 59: 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 154: 6788, 491: 2014, 522: 6787, 673: 2014, 1069: 6786}, // 4170 - {2214, 2214}, - {2317, 2317}, - {2342, 2342}, - {2348, 2348, 474: 6712, 671: 6711}, - {154: 6719, 687: 6718}, + {2071, 2071, 17: 2071, 56: 2071, 59: 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 491: 2071, 673: 2071, 922: 6793}, + {2013, 2013, 17: 2013, 56: 2013, 59: 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 491: 2013, 673: 2013}, + {221: 6791, 409: 6792, 663: 6790, 671: 6789}, + {2012, 2012, 17: 2012, 56: 2012, 59: 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 491: 2012, 673: 2012}, + {2011, 2011, 17: 2011, 56: 2011, 59: 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 491: 2011, 673: 2011}, // 4175 - {322: 6714, 331: 6713}, - {52: 6717}, - {330: 6715}, - {154: 6716}, - {2345, 2345}, + {2010, 2010, 17: 2010, 56: 2010, 59: 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 491: 2010, 673: 2010}, + {2009, 2009, 17: 2009, 56: 2009, 59: 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 491: 2009, 673: 2009}, + {2026, 2026, 17: 6448, 56: 6424, 59: 6444, 6437, 6427, 6423, 6431, 6435, 6447, 6430, 6436, 6434, 6432, 6445, 6438, 6426, 6446, 6425, 6428, 6429, 6433, 491: 6439, 673: 6449, 918: 6441, 6440, 6443, 6422, 923: 6442}, + {18: 2156, 90: 2156, 110: 2156, 156: 2156, 687: 2156}, + {110: 2151, 156: 6844, 687: 2151, 1373: 6843}, // 4180 - {2346, 2346}, - {2347, 2347}, - {2344, 2344, 673: 5471, 924: 6720}, - {2343, 2343}, - {2350, 2350}, + {517: 6839}, + {179: 6798}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6799}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5135, 2850, 688: 2851, 2849, 909: 6800}, + {95: 6804, 99: 6809, 6811, 6805, 6810, 6813, 6807, 6803, 6808, 6812, 6806, 897: 6801, 1134: 6802}, // 4185 - {2349, 2349}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6736, 795: 6735}, - {569: 6725}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6726}, - {488: 6728, 649: 6727}, + {2599, 2599, 9: 2599, 95: 2599, 99: 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599}, + {55, 55, 9: 6837, 95: 6804, 99: 6809, 6811, 6805, 6810, 6813, 6807, 6803, 6808, 6812, 6806, 897: 6836}, + {493: 2109, 517: 4397, 758: 6834}, + {493: 2109, 517: 4397, 758: 6832}, + {517: 4397, 525: 2109, 758: 6830}, // 4190 - {908, 908, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 908, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 474: 908, 591: 5032, 661: 5031, 2762, 2763, 2761, 857: 6733}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 6729}, - {9: 4755, 649: 6730}, - {908, 908, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 908, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 474: 908, 591: 5032, 661: 5031, 2762, 2763, 2761, 857: 6731}, - {2366, 2366, 9: 5034, 474: 5015, 804: 6732}, + {517: 4397, 525: 2109, 758: 6828}, + {517: 4397, 525: 2109, 758: 6826}, + {493: 2109, 517: 4397, 758: 6824}, + {493: 2109, 517: 4397, 758: 6822}, + {493: 2109, 517: 4397, 758: 6820}, // 4195 - {2374, 2374}, - {2366, 2366, 9: 5034, 474: 5015, 804: 6734}, - {2377, 2377}, - {2369, 2369, 9: 3924, 166: 6756, 474: 2369, 651: 6755, 981: 6766}, - {1053, 1053, 9: 1053, 102: 6741, 166: 1053, 474: 1053, 488: 6738, 649: 6737, 651: 1053, 654: 6739, 669: 6740}, + {493: 2109, 517: 4397, 758: 6818}, + {493: 2109, 517: 4397, 758: 6816}, + {493: 2109, 517: 4397, 758: 6814}, + {493: 6815}, + {2586, 2586, 9: 2586, 95: 2586, 99: 2586, 2586, 2586, 2586, 2586, 2586, 2586, 2586, 2586, 2586}, // 4200 - {908, 908, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 908, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 474: 908, 591: 5032, 661: 5031, 2762, 2763, 2761, 857: 6764}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 4754, 2762, 2763, 2761, 786: 6751}, - {259: 6747}, - {259: 6744}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5901, 2762, 2763, 2761, 877: 6742}, + {493: 6817}, + {2587, 2587, 9: 2587, 95: 2587, 99: 2587, 2587, 2587, 2587, 2587, 2587, 2587, 2587, 2587, 2587}, + {493: 6819}, + {2588, 2588, 9: 2588, 95: 2588, 99: 2588, 2588, 2588, 2588, 2588, 2588, 2588, 2588, 2588, 2588}, + {493: 6821}, // 4205 - {2366, 2366, 9: 5903, 474: 5015, 804: 6743}, - {2371, 2371}, - {472: 6745}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5901, 2762, 2763, 2761, 877: 6746}, - {2372, 2372, 9: 5903}, + {2589, 2589, 9: 2589, 95: 2589, 99: 2589, 2589, 2589, 2589, 2589, 2589, 2589, 2589, 2589, 2589}, + {493: 6823}, + {2590, 2590, 9: 2590, 95: 2590, 99: 2590, 2590, 2590, 2590, 2590, 2590, 2590, 2590, 2590, 2590}, + {493: 6825}, + {2591, 2591, 9: 2591, 95: 2591, 99: 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591}, // 4210 - {472: 6748}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5901, 2762, 2763, 2761, 877: 6749}, - {2366, 2366, 9: 5903, 474: 5015, 804: 6750}, - {2373, 2373}, - {2369, 2369, 9: 4755, 102: 6754, 166: 6756, 474: 2369, 649: 6753, 651: 6755, 981: 6752}, + {525: 2824, 755: 2823, 762: 6827}, + {2592, 2592, 9: 2592, 95: 2592, 99: 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2592}, + {525: 2824, 755: 2823, 762: 6829}, + {2593, 2593, 9: 2593, 95: 2593, 99: 2593, 2593, 2593, 2593, 2593, 2593, 2593, 2593, 2593, 2593}, + {525: 2824, 755: 2823, 762: 6831}, // 4215 - {2366, 2366, 474: 5015, 804: 6763}, - {908, 908, 3135, 2967, 3002, 2847, 2883, 3004, 2774, 908, 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 474: 908, 591: 5032, 661: 5031, 2762, 2763, 2761, 857: 6761}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5901, 2762, 2763, 2761, 877: 6759}, - {102: 6758}, - {102: 6757}, + {2594, 2594, 9: 2594, 95: 2594, 99: 2594, 2594, 2594, 2594, 2594, 2594, 2594, 2594, 2594, 2594}, + {493: 6833}, + {2595, 2595, 9: 2595, 95: 2595, 99: 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595}, + {493: 6835}, + {2596, 2596, 9: 2596, 95: 2596, 99: 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596}, // 4220 - {2367, 2367, 474: 2367}, - {2368, 2368, 474: 2368}, - {2366, 2366, 9: 5903, 474: 5015, 804: 6760}, - {2370, 2370}, - {2366, 2366, 9: 5034, 474: 5015, 804: 6762}, + {2598, 2598, 9: 2598, 95: 2598, 99: 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2598}, + {95: 6804, 99: 6809, 6811, 6805, 6810, 6813, 6807, 6803, 6808, 6812, 6806, 897: 6838}, + {2597, 2597, 9: 2597, 95: 2597, 99: 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597}, + {3: 6841, 415: 6842, 422: 6840}, + {110: 2154, 156: 2154, 687: 2154}, // 4225 - {2375, 2375}, - {2376, 2376}, - {2366, 2366, 9: 5034, 474: 5015, 804: 6765}, - {2378, 2378}, - {2366, 2366, 474: 5015, 804: 6767}, + {110: 2153, 156: 2153, 687: 2153}, + {110: 2152, 156: 2152, 687: 2152}, + {110: 2149, 687: 6848, 1376: 6847}, + {517: 6845}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 6846}, // 4230 - {2379, 2379}, - {569: 6773}, - {494: 6771}, - {569: 2381}, - {488: 6772, 569: 2382}, + {110: 2150, 687: 2150}, + {110: 6852}, + {400: 6849}, + {156: 6850, 366: 6851}, + {110: 2148}, // 4235 - {569: 2380}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6774}, - {488: 5465, 563: 922, 649: 922, 660: 922, 860: 6775}, - {563: 6778, 649: 6777, 660: 6779, 1135: 6776}, - {2387, 2387}, + {110: 2147}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6854, 1375: 6853}, + {492: 6856, 498: 2145, 1374: 6855}, + {492: 2146, 498: 2146}, + {498: 6862}, // 4240 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6786, 2762, 2763, 2761}, - {473: 3897, 839: 6781}, - {473: 3897, 839: 6042, 975: 6780}, - {2384, 2384, 9: 6043}, - {507: 6782}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6858, 2850, 688: 2851, 2849, 1223: 6857}, + {9: 6860, 58: 6859}, + {9: 2143, 58: 2143}, + {498: 2144}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6861, 2850, 688: 2851, 2849}, // 4245 - {473: 3897, 839: 6783}, - {88: 6784}, - {508: 2736, 733: 4053, 763: 6785}, - {2385, 2385}, - {563: 6778, 660: 6779, 1135: 6787}, + {9: 2142, 58: 2142}, + {492: 2667, 494: 2666, 515: 2665, 588: 2664, 665: 2660, 731: 6866, 770: 6864, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 3989, 6865, 6863, 1233: 6867}, + {2164, 2164, 494: 2164}, + {2163, 2163, 494: 2163, 500: 854, 509: 854, 511: 854}, + {2162, 2162, 494: 2162}, // 4250 - {2386, 2386}, - {650: 6794}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6790}, - {2389, 2389, 650: 6792, 1218: 6791}, - {2390, 2390}, + {2161, 2161, 494: 2161, 500: 853, 509: 853, 511: 853, 2816, 521: 2817, 523: 2813, 790: 4000, 4001}, + {2141, 2141, 494: 6869, 1372: 6868}, + {2158, 2158}, + {152: 6871, 335: 6870}, + {607: 6874}, // 4255 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6793, 2762, 2763, 2761}, - {2388, 2388}, - {199: 6795}, - {475: 6796}, - {2391, 2391}, + {607: 6872}, + {931: 6873}, + {2139, 2139}, + {931: 6875}, + {2140, 2140}, // 4260 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 660: 6798, 3921, 2762, 2763, 2761, 737: 6799}, - {265: 6801}, - {2393, 2393, 508: 2736, 733: 4053, 763: 6800}, - {2392, 2392}, - {508: 2736, 733: 4053, 763: 6802}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 6877}, + {2247, 2247, 16: 2238, 18: 2238, 21: 2238, 496: 4353, 499: 2238, 514: 2238, 526: 6881, 667: 2238, 803: 6880, 816: 6879, 874: 6883, 958: 6882, 1234: 6878}, + {2257, 2257}, + {16: 3943, 18: 4310, 21: 6891, 499: 6890, 514: 3944, 667: 3942, 798: 6889, 803: 6892}, + {2249, 2249, 16: 2249, 18: 2249, 21: 2249, 496: 2249, 499: 2249, 514: 2249, 526: 2249, 667: 2249}, // 4265 - {2394, 2394}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6814, 1150: 6813, 1326: 6812}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 6807, 1155: 6806, 1331: 6805}, - {2398, 2398, 9: 6810}, - {2397, 2397, 9: 2397}, + {182: 6885}, + {2246, 2246, 16: 2238, 18: 2238, 21: 2238, 496: 4353, 499: 2238, 514: 2238, 526: 6881, 667: 2238, 803: 6880, 816: 6879, 874: 6884}, + {2245, 2245, 16: 2245, 18: 2245, 21: 2245, 496: 2245, 499: 2245, 514: 2245, 526: 2245, 667: 2245}, + {2244, 2244, 16: 2244, 18: 2244, 21: 2244, 496: 2244, 499: 2244, 514: 2244, 526: 2244, 667: 2244}, + {205: 6886}, // 4270 - {650: 6808}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 6809}, - {2395, 2395, 9: 2395}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 6807, 1155: 6811}, - {2396, 2396, 9: 2396}, + {525: 2824, 755: 2823, 762: 6887}, + {2569, 2569, 16: 2569, 18: 2569, 21: 2569, 197: 5111, 496: 2569, 499: 2569, 514: 2569, 526: 2569, 667: 2569, 1106: 6888}, + {2248, 2248, 16: 2248, 18: 2248, 21: 2248, 496: 2248, 499: 2248, 514: 2248, 526: 2248, 667: 2248}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 517: 4397, 549: 2109, 758: 6897}, + {2: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 10: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 59: 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 493: 2109, 517: 4397, 549: 2109, 758: 6895}, // 4275 - {2402, 2402, 9: 6817}, - {2401, 2401, 9: 2401}, - {650: 6815}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6816}, - {2399, 2399, 9: 2399}, + {493: 2109, 517: 4397, 758: 6893}, + {2250, 2250, 16: 2250, 18: 2250, 21: 2250, 496: 2250, 499: 2250, 514: 2250, 526: 2250, 667: 2250}, + {493: 4426, 1067: 6894}, + {2251, 2251, 16: 2251, 18: 2251, 21: 2251, 496: 2251, 499: 2251, 514: 2251, 526: 2251, 667: 2251}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3596, 685: 3598, 2850, 688: 2851, 2849, 760: 3595, 895: 6896}, // 4280 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6814, 1150: 6818}, - {2400, 2400, 9: 2400}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 2176, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 479: 4240, 484: 2176, 505: 2176, 6668, 647: 2176, 661: 5396, 2762, 2763, 2761, 781: 6667, 792: 6666, 817: 6868, 850: 6670, 932: 6869}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 6858, 2762, 2763, 2761}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 475: 1860, 564: 4452, 570: 1860, 780: 6847}, + {2252, 2252, 16: 2252, 18: 2252, 21: 2252, 496: 2252, 499: 2252, 514: 2252, 526: 2252, 667: 2252}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 549: 3868, 685: 3598, 2850, 688: 2851, 2849, 760: 3867, 830: 6898}, + {2253, 2253, 16: 2253, 18: 2253, 21: 2253, 496: 2253, 499: 2253, 514: 2253, 526: 2253, 667: 2253}, + {2: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 10: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 59: 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 583: 4975, 805: 6900}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6901, 2850, 688: 2851, 2849}, // 4285 - {279: 6841, 1236: 6840}, - {165: 6836}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6825}, - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 3921, 2762, 2763, 2761, 737: 6826}, - {72: 6499, 6496, 6502, 6503, 6504, 6497, 6495, 6505, 6501, 6498, 6830, 655: 6500, 913: 6829, 987: 6828, 1169: 6827}, + {91: 5008, 491: 1901, 501: 5007, 881: 6903, 1266: 6902}, + {491: 6904}, + {491: 1900}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6905}, + {492: 6906}, // 4290 - {27, 27, 72: 6499, 6496, 6502, 6503, 6504, 6497, 6495, 6505, 6501, 6498, 6830, 655: 6500, 913: 6829, 987: 6835}, - {26, 26, 72: 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 655: 26}, - {24, 24, 72: 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 655: 24}, - {23, 23, 72: 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 474: 6832, 485: 2047, 2047, 499: 4281, 508: 2047, 655: 23, 736: 6831}, - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6834}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 492: 4744, 685: 4256, 2850, 688: 2851, 2849, 766: 4743, 849: 4742, 859: 6907}, + {9: 4753, 58: 6908}, + {1912, 1912, 6: 1912, 19: 1912, 90: 1912, 1912, 1912, 1912, 1912, 96: 1912, 494: 1912, 501: 1912, 518: 1912, 904: 6909}, + {2268, 2268, 6: 5004, 19: 5001, 90: 4348, 5008, 4854, 4556, 4855, 96: 4555, 494: 5003, 501: 5007, 518: 4349, 879: 5005, 881: 5002, 892: 5006, 6633, 903: 5000, 906: 6632, 1094: 6910}, + {2275, 2275}, // 4295 - {485: 4056, 4057, 508: 2736, 733: 4053, 763: 4055, 814: 6833}, - {21, 21, 72: 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 655: 21}, - {22, 22, 72: 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 655: 22}, - {25, 25, 72: 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 655: 25}, - {2: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 10: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 50: 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 1860, 564: 4452, 780: 6837}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6912, 2850, 688: 2851, 2849}, + {492: 6913}, + {249: 5037, 257: 5039, 259: 5038, 1172: 6914}, + {58: 6915}, + {491: 6916}, // 4300 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 3379, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 661: 5004, 2762, 2763, 2761, 886: 6838}, - {88: 6591, 92: 6596, 6598, 6592, 6597, 6600, 6594, 6590, 6595, 6599, 6593, 874: 6588, 1104: 6839}, - {53, 53, 9: 6624, 88: 6591, 92: 6596, 6598, 6592, 6597, 6600, 6594, 6590, 6595, 6599, 6593, 874: 6623}, - {239, 239}, - {400: 6842}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6917}, + {492: 6918}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4256, 2850, 688: 2851, 2849, 766: 4257, 831: 6919}, + {9: 4259, 58: 6920}, + {2277, 2277}, // 4305 - {238, 238, 72: 6843}, - {155: 6844}, - {472: 6845}, - {209: 6846}, - {237, 237}, + {2384, 2384}, + {2409, 2409}, + {2415, 2415, 494: 6925, 692: 6924}, + {167: 6932, 709: 6931}, + {336: 6927, 345: 6926}, // 4310 - {2: 3135, 2967, 3002, 2847, 2883, 3004, 2774, 10: 2820, 2775, 2906, 3021, 3014, 3372, 3367, 2886, 3170, 2888, 2862, 2806, 2809, 2798, 2831, 2890, 2891, 2998, 2885, 3022, 3127, 3126, 2773, 2884, 2887, 2898, 2838, 2842, 2894, 3007, 2853, 2934, 2771, 2772, 2933, 3006, 2770, 3019, 2979, 50: 3090, 2852, 2855, 3073, 3070, 3062, 3074, 3077, 3078, 3075, 3079, 3080, 3076, 3069, 3081, 3064, 3065, 3068, 3071, 3072, 3082, 3375, 2920, 2856, 3049, 3048, 3050, 3045, 3044, 3051, 3046, 3047, 2848, 2964, 3034, 3098, 3032, 3099, 3139, 3033, 2860, 2928, 3222, 3226, 3214, 3225, 3227, 3217, 3223, 3224, 3228, 3221, 2789, 2923, 3376, 3369, 3365, 2783, 3388, 3031, 3020, 2818, 3371, 3386, 3387, 3385, 3381, 3023, 3024, 3025, 3026, 3027, 3028, 3030, 3377, 2861, 2857, 2949, 2953, 2954, 2955, 2956, 2944, 2973, 3016, 2975, 2833, 2791, 2974, 2945, 3095, 2925, 2965, 2828, 2881, 3040, 2902, 2792, 2797, 2808, 2823, 3364, 2832, 3035, 2905, 2850, 2947, 2864, 2872, 2778, 2924, 2807, 2827, 3202, 2837, 3084, 3174, 2961, 3133, 2870, 6848, 2900, 3172, 2841, 2849, 2871, 3085, 2782, 2800, 3368, 2821, 2813, 2899, 2834, 3038, 3054, 2982, 3091, 3092, 3056, 2919, 3037, 3093, 3012, 3169, 3120, 3052, 2851, 2952, 3374, 3373, 3010, 2909, 2767, 2793, 2914, 2804, 2805, 2916, 2812, 2822, 2825, 3063, 2875, 2977, 3171, 2943, 2912, 2972, 3015, 2901, 3122, 2859, 3132, 3011, 3101, 3060, 3102, 2921, 2983, 2781, 3150, 3103, 3106, 2787, 3086, 3107, 3384, 2794, 2985, 3152, 3109, 2981, 2802, 3111, 2994, 3018, 3005, 2803, 3156, 3113, 3142, 3013, 2816, 3043, 3209, 3370, 2826, 2829, 2995, 3041, 3161, 3036, 3162, 2989, 3115, 3114, 3039, 3096, 2926, 3389, 3116, 3117, 2930, 2987, 3118, 3094, 2845, 2846, 2960, 3066, 2962, 3175, 3119, 3008, 3009, 2950, 2854, 2991, 3123, 2769, 3184, 2990, 3191, 3192, 3193, 3194, 3196, 3195, 3197, 3198, 3199, 3134, 2867, 2992, 3219, 3218, 2873, 2764, 2765, 3042, 3059, 2776, 3061, 3087, 2768, 2779, 2780, 3104, 3105, 2784, 2971, 2785, 2786, 2958, 3097, 3380, 3108, 2903, 2790, 2795, 2796, 3110, 3112, 2915, 3157, 2917, 2810, 2811, 2927, 2815, 2978, 3203, 2817, 2988, 2922, 2896, 3129, 2996, 3017, 2980, 2911, 3163, 2966, 2984, 3029, 2908, 2997, 2889, 3053, 2892, 2893, 3390, 2929, 2836, 2858, 3136, 3204, 2839, 3000, 3003, 3055, 3089, 3137, 3100, 2939, 2940, 2946, 3167, 3140, 3168, 3141, 3067, 3143, 2970, 2907, 3121, 3001, 2959, 3128, 3125, 3124, 3176, 2986, 3088, 2999, 3188, 3131, 2968, 2863, 3212, 3200, 2868, 2897, 2904, 2969, 3138, 2976, 3393, 2878, 3145, 3146, 3366, 3147, 3148, 3149, 3205, 3151, 3153, 3154, 3155, 2814, 2963, 3206, 2932, 3158, 2819, 3213, 3394, 3160, 3399, 3398, 3391, 3215, 3216, 3165, 3164, 2835, 3166, 3173, 2938, 2843, 2844, 3083, 2957, 3382, 3383, 3392, 2951, 2879, 2993, 2910, 2913, 3207, 3180, 3181, 3182, 3183, 3208, 3395, 3178, 3179, 2931, 3130, 3396, 3397, 3201, 3185, 3186, 3187, 3220, 3378, 475: 3490, 570: 5297, 661: 3491, 2762, 2763, 2761, 738: 5296, 777: 5314, 891: 5315, 922: 6849}, - {1712, 1712, 9: 1712, 15: 1712, 48: 1712, 144: 1712, 473: 6853, 1712, 568: 1712, 666: 1712, 1712}, - {225, 225, 9: 5317, 15: 225, 48: 225, 474: 225, 666: 5361, 960: 5360, 6850}, - {233, 233, 15: 233, 48: 233, 474: 6541, 1008: 6851}, - {212, 212, 15: 6558, 48: 6556, 953: 6557, 6555, 1102: 6554, 6852}, + {59: 6930}, + {344: 6928}, + {167: 6929}, + {2412, 2412}, + {2413, 2413}, // 4315 - {241, 241}, - {49: 6854}, - {144: 6855}, - {660: 6856}, - {475: 5330, 893: 6857}, + {2414, 2414}, + {2411, 2411, 694: 5618, 949: 6933}, + {2410, 2410}, + {2417, 2417}, + {2416, 2416}, // 4320 - {240, 240}, - {1953, 1953, 17: 1953, 50: 1953, 52: 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 1953, 140: 6575, 472: 1953, 504: 6574, 653: 1953, 1041: 6859}, - {2010, 2010, 17: 2010, 50: 2010, 52: 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 472: 2010, 653: 2010, 898: 6860}, - {1947, 1947, 17: 6294, 50: 6270, 52: 6290, 6283, 6273, 6269, 6277, 6281, 6293, 6276, 6282, 6280, 6278, 6291, 6284, 6272, 6292, 6271, 6274, 6275, 6279, 6862, 472: 6285, 653: 6295, 894: 6287, 6286, 6289, 6268, 899: 6288, 1230: 6861}, - {1962, 1962}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6949, 804: 6948}, + {588: 6938}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6939}, + {507: 6941, 668: 6940}, + {947, 947, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 947, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 494: 947, 613: 5163, 685: 5162, 2850, 688: 2851, 2849, 880: 6946}, // 4325 - {181: 6864, 651: 6863}, - {564, 564, 569: 6241, 969: 6866}, - {564, 564, 569: 6241, 969: 6865}, - {1945, 1945}, - {1946, 1946}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 6942}, + {9: 4886, 668: 6943}, + {947, 947, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 947, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 494: 947, 613: 5163, 685: 5162, 2850, 688: 2851, 2849, 880: 6944}, + {2433, 2433, 9: 5165, 494: 5146, 826: 6945}, + {2441, 2441}, // 4330 - {16: 1420, 18: 1420, 21: 1420, 165: 4997, 479: 1420, 484: 1420, 505: 1420, 1420, 647: 1420}, - {16: 2176, 18: 2176, 21: 2176, 479: 4240, 484: 2176, 505: 2176, 6668, 647: 2176, 781: 6667, 792: 6666, 850: 6670, 932: 6870}, - {2195, 2195, 16: 2176, 18: 2176, 21: 2176, 479: 4240, 484: 2176, 505: 2176, 6668, 647: 2176, 781: 6667, 792: 6666, 850: 6671}, - {2196, 2196, 16: 2176, 18: 2176, 21: 2176, 479: 4240, 484: 2176, 505: 2176, 6668, 647: 2176, 781: 6667, 792: 6666, 850: 6671}, - {2045, 2045, 2544, 50: 2568, 71: 2688, 73: 2547, 82: 2579, 147: 2549, 155: 2577, 2562, 159: 2546, 173: 2573, 210: 2598, 215: 2701, 218: 2542, 225: 2597, 2564, 2697, 2548, 243: 2576, 248: 2552, 253: 2574, 255: 2543, 258: 2580, 276: 2566, 280: 2565, 287: 2578, 291: 2567, 303: 2557, 473: 2588, 2587, 495: 2586, 497: 2696, 504: 2572, 506: 2596, 525: 2691, 529: 2560, 567: 2571, 569: 2585, 646: 2581, 649: 2700, 653: 2545, 2690, 665: 2540, 669: 2551, 674: 2550, 679: 2595, 686: 2541, 709: 2592, 739: 2553, 748: 2594, 2582, 2583, 2584, 2593, 756: 2591, 2590, 2589, 2556, 2668, 2667, 766: 2554, 772: 2689, 774: 2649, 2660, 2679, 779: 2555, 783: 2614, 800: 2563, 806: 2602, 809: 2694, 844: 2608, 2609, 849: 2612, 854: 2692, 859: 2652, 861: 2662, 863: 2657, 2666, 2669, 2569, 931: 2621, 935: 2558, 973: 2695, 980: 2600, 982: 2601, 2604, 2605, 986: 2607, 988: 2606, 990: 2603, 992: 2610, 2611, 996: 2570, 2648, 999: 2617, 1009: 2625, 2618, 2619, 2620, 2626, 2624, 2627, 2628, 1018: 2623, 2622, 1021: 2613, 2575, 2559, 2629, 2641, 2630, 2631, 2632, 2634, 2638, 2635, 2639, 2640, 2633, 2637, 2636, 1038: 2599, 1042: 2615, 1044: 2616, 2561, 1049: 2643, 2644, 2642, 1054: 2646, 2647, 2645, 1060: 2685, 2650, 1068: 2699, 2698, 2651, 1075: 2653, 1078: 2682, 1080: 2686, 1105: 2654, 2655, 1108: 2656, 1110: 2661, 1113: 2658, 2659, 1116: 2684, 2663, 2693, 2665, 2664, 1125: 2670, 1127: 2672, 2671, 2675, 1131: 2676, 1133: 2683, 1136: 2673, 6872, 1141: 2674, 1152: 2677, 2678, 2681, 1156: 2680}, + {2433, 2433, 9: 5165, 494: 5146, 826: 6947}, + {2444, 2444}, + {2436, 2436, 9: 4033, 180: 6969, 494: 2436, 671: 6968, 1006: 6979}, + {1092, 1092, 9: 1092, 109: 6954, 180: 1092, 494: 1092, 507: 6951, 668: 6950, 671: 1092, 674: 6952, 690: 6953}, + {947, 947, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 947, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 494: 947, 613: 5163, 685: 5162, 2850, 688: 2851, 2849, 880: 6977}, // 4335 - {444, 444}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4885, 2850, 688: 2851, 2849, 809: 6964}, + {274: 6960}, + {274: 6957}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6050, 2850, 688: 2851, 2849, 901: 6955}, + {2433, 2433, 9: 6052, 494: 5146, 826: 6956}, + // 4340 + {2438, 2438}, + {491: 6958}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6050, 2850, 688: 2851, 2849, 901: 6959}, + {2439, 2439, 9: 6052}, + {491: 6961}, + // 4345 + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6050, 2850, 688: 2851, 2849, 901: 6962}, + {2433, 2433, 9: 6052, 494: 5146, 826: 6963}, + {2440, 2440}, + {2436, 2436, 9: 4886, 109: 6967, 180: 6969, 494: 2436, 668: 6966, 671: 6968, 1006: 6965}, + {2433, 2433, 494: 5146, 826: 6976}, + // 4350 + {947, 947, 3236, 3058, 3094, 2937, 2974, 3096, 2863, 947, 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 494: 947, 613: 5163, 685: 5162, 2850, 688: 2851, 2849, 880: 6974}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6050, 2850, 688: 2851, 2849, 901: 6972}, + {109: 6971}, + {109: 6970}, + {2434, 2434, 494: 2434}, + // 4355 + {2435, 2435, 494: 2435}, + {2433, 2433, 9: 6052, 494: 5146, 826: 6973}, + {2437, 2437}, + {2433, 2433, 9: 5165, 494: 5146, 826: 6975}, + {2442, 2442}, + // 4360 + {2443, 2443}, + {2433, 2433, 9: 5165, 494: 5146, 826: 6978}, + {2445, 2445}, + {2433, 2433, 494: 5146, 826: 6980}, + {2446, 2446}, + // 4365 + {588: 6986}, + {513: 6984}, + {588: 2448}, + {507: 6985, 588: 2449}, + {588: 2447}, + // 4370 + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 6987}, + {507: 5612, 582: 961, 668: 961, 681: 961, 883: 6988}, + {582: 6991, 668: 6990, 681: 6992, 1167: 6989}, + {2454, 2454}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6999, 2850, 688: 2851, 2849}, + // 4375 + {492: 4006, 863: 6994}, + {492: 4006, 863: 6191, 1000: 6993}, + {2451, 2451, 9: 6192}, + {527: 6995}, + {492: 4006, 863: 6996}, + // 4380 + {95: 6997}, + {525: 2824, 755: 4162, 784: 6998}, + {2452, 2452}, + {582: 6991, 681: 6992, 1167: 7000}, + {2453, 2453}, + // 4385 + {698: 7015}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 7011, 804: 7010}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5543, 2850, 688: 2851, 2849, 832: 7004}, + {2457, 2457, 670: 7006, 698: 7005, 1079: 7007}, + {493: 7009}, + // 4390 + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 7008, 2850, 688: 2851, 2849}, + {2455, 2455}, + {2456, 2456}, + {2459, 2459}, + {9: 4033, 698: 7013}, + // 4395 + {2457, 2457, 9: 1092, 670: 7006, 698: 1092, 1079: 7012}, + {2458, 2458}, + {493: 7014}, + {2460, 2460}, + {493: 7016}, + // 4400 + {2461, 2461}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 681: 7018, 685: 4030, 2850, 688: 2851, 2849, 759: 7019}, + {280: 7021}, + {2463, 2463, 525: 2824, 755: 4162, 784: 7020}, + {2462, 2462}, + // 4405 + {525: 2824, 755: 4162, 784: 7022}, + {2464, 2464}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 7034, 1182: 7033, 1361: 7032}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 7027, 1188: 7026, 1366: 7025}, + {2468, 2468, 9: 7030}, + // 4410 + {2467, 2467, 9: 2467}, + {670: 7028}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 7029}, + {2465, 2465, 9: 2465}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 7027, 1188: 7031}, + // 4415 + {2466, 2466, 9: 2466}, + {2472, 2472, 9: 7037}, + {2471, 2471, 9: 2471}, + {670: 7035}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 7036}, + // 4420 + {2469, 2469, 9: 2469}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 7034, 1182: 7038}, + {2470, 2470, 9: 2470}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 2238, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 496: 4353, 499: 2238, 514: 2238, 526: 6881, 667: 2238, 685: 5543, 2850, 688: 2851, 2849, 803: 6880, 816: 6879, 832: 7095, 874: 6883, 958: 7096}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 7085, 2850, 688: 2851, 2849}, + // 4425 + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 493: 1920, 583: 4578, 590: 1920, 800: 7072}, + {294: 7066, 1268: 7065}, + {532: 7061}, + {179: 7057}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 7046}, + // 4430 + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 4030, 2850, 688: 2851, 2849, 759: 7047}, + {79: 6663, 6660, 6666, 6667, 6668, 6661, 6659, 6669, 6665, 6662, 7051, 675: 6664, 938: 7050, 1013: 7049, 1202: 7048}, + {28, 28, 79: 6663, 6660, 6666, 6667, 6668, 6661, 6659, 6669, 6665, 6662, 7051, 675: 6664, 938: 7050, 1013: 7056}, + {27, 27, 79: 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 675: 27}, + {25, 25, 79: 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 675: 25}, + // 4435 + {24, 24, 79: 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 494: 7053, 504: 2109, 2109, 517: 4397, 525: 2109, 675: 24, 758: 7052}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 7055}, + {504: 4165, 4166, 525: 2824, 755: 4162, 784: 4164, 838: 7054}, + {22, 22, 79: 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 675: 22}, + {23, 23, 79: 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 675: 23}, + // 4440 + {26, 26, 79: 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 675: 26}, + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 7058}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 5135, 2850, 688: 2851, 2849, 909: 7059}, + {95: 6804, 99: 6809, 6811, 6805, 6810, 6813, 6807, 6803, 6808, 6812, 6806, 897: 6801, 1134: 7060}, + {54, 54, 9: 6837, 95: 6804, 99: 6809, 6811, 6805, 6810, 6813, 6807, 6803, 6808, 6812, 6806, 897: 6836}, + // 4445 + {2: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 10: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 59: 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 583: 4578, 800: 7062}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 3486, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 685: 6377, 2850, 688: 2851, 2849, 911: 7063}, + {113: 6697, 119: 6698, 6699, 125: 6695, 135: 6696, 898: 6693, 1147: 7064}, + {57, 57, 9: 6711, 113: 6697, 119: 6698, 6699, 125: 6695, 135: 6696, 898: 6710}, + {267, 267}, + // 4450 + {417: 7067}, + {266, 266, 79: 7068}, + {168: 7069}, + {491: 7070}, + {224: 7071}, + // 4455 + {265, 265}, + {2: 3236, 3058, 3094, 2937, 2974, 3096, 2863, 10: 2909, 2864, 2997, 3113, 3106, 3479, 3474, 2977, 3272, 2979, 2953, 2895, 2898, 2887, 2920, 2981, 2982, 3090, 2976, 3114, 3227, 3226, 3194, 2862, 2975, 2978, 2989, 2927, 2931, 2985, 3099, 2944, 3025, 2860, 2861, 3024, 3098, 2859, 3111, 3195, 3196, 2938, 2855, 3070, 3197, 3198, 3182, 2943, 59: 2946, 3165, 3162, 3154, 3166, 3169, 3170, 3167, 3171, 3172, 3168, 3161, 3173, 3156, 3157, 3160, 3163, 3164, 3174, 3482, 3011, 2947, 3141, 3140, 3142, 3137, 3136, 3143, 3138, 3139, 2939, 3055, 3126, 3190, 3124, 3191, 3240, 3125, 2951, 3019, 3324, 3328, 3316, 3327, 3329, 3319, 3325, 3326, 3330, 3323, 2878, 3014, 3476, 3483, 3072, 3495, 3123, 3472, 2872, 3478, 3332, 3333, 3493, 3494, 3492, 3488, 3334, 3115, 3116, 3117, 3118, 3119, 3120, 3122, 3112, 3484, 3335, 2907, 2952, 2948, 3040, 3064, 3471, 3066, 3044, 3045, 3046, 3047, 3035, 2880, 3065, 3193, 3108, 2922, 3036, 3187, 3016, 3056, 2917, 2972, 3132, 2993, 2881, 2886, 2897, 2912, 2921, 3127, 2996, 2941, 3038, 2955, 2961, 2963, 2867, 3015, 2896, 2916, 3304, 2926, 3176, 3276, 3052, 3234, 7073, 2991, 3274, 2930, 2940, 2962, 3177, 2871, 2889, 3475, 2910, 2902, 2990, 2923, 3130, 3146, 3074, 3183, 3184, 3148, 3273, 3010, 3129, 3185, 3104, 3271, 3220, 3144, 2942, 3043, 3223, 3480, 3102, 3000, 2856, 2882, 3199, 3005, 2893, 2894, 3007, 2901, 2911, 2914, 3088, 3155, 2966, 3034, 3003, 3063, 3107, 2992, 3222, 2950, 3233, 3481, 3103, 3201, 3152, 3202, 3012, 3075, 2870, 3251, 3203, 2873, 3206, 2876, 3178, 3207, 3491, 2883, 3077, 3253, 3209, 2891, 3211, 3086, 3110, 3097, 2892, 3258, 3213, 3243, 3105, 2905, 3135, 3311, 3477, 2915, 2918, 3087, 3133, 3263, 3128, 3264, 3081, 3215, 3214, 3131, 3188, 3017, 3496, 3216, 3217, 3021, 3079, 3218, 3186, 2934, 2935, 3051, 3158, 3053, 3277, 3219, 3100, 3101, 3041, 2945, 3083, 2858, 3286, 3082, 3331, 3293, 3294, 3295, 3296, 3298, 3297, 3299, 3300, 3301, 3235, 2958, 3084, 3321, 3320, 2964, 2852, 2853, 3134, 3151, 2865, 3153, 3179, 2857, 2868, 2869, 3204, 3205, 3062, 2874, 2875, 3049, 3189, 3487, 3208, 2994, 2879, 2884, 2885, 3210, 3212, 3006, 3259, 3008, 2899, 2900, 3018, 2904, 3069, 3305, 2906, 3080, 3013, 2987, 3230, 3109, 3071, 3002, 3265, 3057, 3076, 3121, 2999, 3089, 2980, 3145, 2983, 2984, 3068, 3497, 3020, 2925, 2949, 3237, 3306, 2928, 3092, 3095, 3147, 3181, 3238, 3192, 3030, 3031, 3037, 3269, 3241, 2936, 3270, 3242, 3159, 3200, 3244, 3061, 2998, 3221, 3093, 3050, 3228, 3225, 3229, 3224, 3278, 3078, 3180, 3091, 3290, 3232, 3059, 2954, 3314, 3302, 2959, 2988, 2995, 3060, 3239, 3067, 3500, 2969, 3246, 3247, 3473, 3248, 3249, 3250, 3307, 3252, 3255, 3254, 3256, 3257, 2903, 3054, 3308, 3023, 3260, 2908, 3315, 3501, 3262, 3506, 3505, 3498, 3317, 3318, 3267, 3073, 3266, 2924, 3268, 3275, 3029, 2932, 2933, 3175, 3048, 3489, 3490, 3499, 3042, 2970, 3085, 3001, 3004, 3309, 3282, 3283, 3284, 3285, 3310, 3502, 3280, 3281, 3022, 3231, 3503, 3504, 3303, 3287, 3288, 3289, 3322, 3485, 493: 3597, 590: 5442, 685: 3598, 2850, 688: 2851, 2849, 760: 5441, 799: 5459, 915: 5460, 947: 7074}, + {1769, 1769, 6: 1769, 9: 1769, 15: 1769, 51: 1769, 1769, 1769, 1769, 1769, 158: 1769, 492: 7080, 494: 1769, 589: 1769, 683: 1769, 1769}, + {253, 253, 6: 253, 9: 5462, 15: 253, 51: 253, 253, 253, 253, 253, 494: 253, 683: 5506, 985: 5505, 7075}, + {261, 261, 6: 261, 15: 261, 51: 261, 261, 261, 261, 261, 494: 6734, 1034: 7076}, + // 4460 + {234, 234, 6: 234, 15: 6750, 51: 234, 234, 6749, 6751, 6752, 979: 6748, 1132: 6747, 7077}, + {239, 239, 6: 6774, 51: 239, 6775, 1031: 7078}, + {236, 236, 51: 6779, 1146: 7079}, + {269, 269}, + {58: 7081}, + // 4465 + {158: 7082}, + {681: 7083}, + {493: 5475, 917: 7084}, + {268, 268}, + {2014, 2014, 17: 2014, 56: 2014, 59: 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014, 154: 6788, 491: 2014, 522: 6787, 673: 2014, 1069: 7086}, + // 4470 + {2071, 2071, 17: 2071, 56: 2071, 59: 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 2071, 491: 2071, 673: 2071, 922: 7087}, + {2008, 2008, 17: 6448, 56: 6424, 59: 6444, 6437, 6427, 6423, 6431, 6435, 6447, 6430, 6436, 6434, 6432, 6445, 6438, 6426, 6446, 6425, 6428, 6429, 6433, 7089, 491: 6439, 673: 6449, 918: 6441, 6440, 6443, 6422, 923: 6442, 1262: 7088}, + {2023, 2023}, + {194: 7091, 671: 7090}, + {601, 601, 588: 6395, 994: 7093}, + // 4475 + {601, 601, 588: 6395, 994: 7092}, + {2006, 2006}, + {2007, 2007}, + {16: 1466, 18: 1466, 21: 1466, 179: 5128, 496: 1466, 499: 1466, 514: 1466, 526: 1466, 667: 1466}, + {16: 2238, 18: 2238, 21: 2238, 496: 4353, 499: 2238, 514: 2238, 526: 6881, 667: 2238, 803: 6880, 816: 6879, 874: 6883, 958: 7097}, + // 4480 + {2258, 2258, 16: 2238, 18: 2238, 21: 2238, 496: 4353, 499: 2238, 514: 2238, 526: 6881, 667: 2238, 803: 6880, 816: 6879, 874: 6884}, + {2259, 2259, 16: 2238, 18: 2238, 21: 2238, 496: 4353, 499: 2238, 514: 2238, 526: 6881, 667: 2238, 803: 6880, 816: 6879, 874: 6884}, + {2107, 2107, 2623, 56: 2647, 78: 2773, 80: 2626, 89: 2658, 161: 2628, 168: 2656, 2641, 173: 2625, 186: 2652, 203: 2786, 225: 2677, 232: 2621, 240: 2676, 2643, 2782, 2627, 258: 2655, 263: 2631, 268: 2653, 270: 2622, 273: 2659, 291: 2645, 295: 2644, 302: 2657, 305: 2646, 318: 2636, 492: 2667, 494: 2666, 515: 2665, 518: 2781, 522: 2651, 526: 2675, 544: 2776, 548: 2639, 587: 2650, 2664, 665: 2660, 668: 2785, 673: 2624, 2775, 682: 2619, 690: 2630, 695: 2629, 701: 2674, 708: 2620, 731: 2671, 761: 2632, 770: 2673, 2661, 2662, 2663, 2672, 778: 2670, 2669, 2668, 2635, 2753, 2752, 788: 2774, 2633, 795: 2732, 2745, 2764, 802: 2634, 807: 2694, 822: 2642, 829: 2681, 833: 2779, 868: 2688, 2689, 873: 2692, 877: 2777, 882: 2735, 884: 2747, 886: 2742, 2751, 2754, 2648, 956: 2701, 961: 2637, 998: 2780, 1005: 2679, 1007: 2680, 2683, 2684, 1011: 2686, 2687, 1014: 2685, 1016: 2682, 1018: 2690, 2691, 1021: 2649, 2731, 1024: 2697, 1035: 2705, 2698, 2699, 2700, 2706, 2707, 2704, 2708, 2709, 1045: 2703, 2702, 1048: 2693, 2654, 2638, 2710, 2723, 2711, 2712, 2713, 2715, 2719, 2720, 2716, 2721, 2722, 2714, 2718, 2717, 1066: 2678, 1070: 2695, 1072: 2696, 2640, 1077: 2727, 2725, 1080: 2726, 2724, 1084: 2729, 2730, 2728, 1090: 2770, 2733, 1098: 2784, 2783, 2734, 1105: 2736, 1107: 2737, 2767, 1110: 2771, 1135: 2739, 2740, 1138: 2741, 1140: 2746, 1143: 2743, 2744, 1148: 2769, 2748, 2778, 2750, 2749, 1157: 2755, 1159: 2757, 2756, 2760, 1163: 2761, 1165: 2768, 1168: 2758, 7099, 1173: 2759, 1184: 2762, 2763, 2738, 2766, 1189: 2765}, + {475, 475}, } ) @@ -11404,7 +11753,7 @@ func yylex1(yylex yyLexer, lval *yySymType) (n int) { } func yyParse(yylex yyLexer, parser *Parser) int { - const yyError = 1363 + const yyError = 1398 yyEx, _ := yylex.(yyLexerEx) var yyn int @@ -11636,25 +11985,57 @@ yynewstate: } case 9: { - parser.yyVAL.item = []*ast.PlacementOption{yyS[yypt-0].item.(*ast.PlacementOption)} + parser.yyVAL.item = []*ast.ResourceGroupOption{yyS[yypt-0].item.(*ast.ResourceGroupOption)} } case 10: { - parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.PlacementOption), yyS[yypt-0].item.(*ast.PlacementOption)) + parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.ResourceGroupOption), yyS[yypt-0].item.(*ast.ResourceGroupOption)) } case 11: { - parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.PlacementOption), yyS[yypt-0].item.(*ast.PlacementOption)) + parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.ResourceGroupOption), yyS[yypt-0].item.(*ast.ResourceGroupOption)) } case 12: { - parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionPrimaryRegion, StrValue: yyS[yypt-0].ident} + parser.yyVAL.item = &ast.ResourceGroupOption{Tp: ast.ResourceRRURate, UintValue: yyS[yypt-0].item.(uint64)} } case 13: { - parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionRegions, StrValue: yyS[yypt-0].ident} + parser.yyVAL.item = &ast.ResourceGroupOption{Tp: ast.ResourceWRURate, UintValue: yyS[yypt-0].item.(uint64)} } case 14: + { + parser.yyVAL.item = &ast.ResourceGroupOption{Tp: ast.ResourceUnitCPU, StrValue: yyS[yypt-0].ident} + } + case 15: + { + parser.yyVAL.item = &ast.ResourceGroupOption{Tp: ast.ResourceUnitIOReadBandwidth, StrValue: yyS[yypt-0].ident} + } + case 16: + { + parser.yyVAL.item = &ast.ResourceGroupOption{Tp: ast.ResourceUnitIOWriteBandwidth, StrValue: yyS[yypt-0].ident} + } + case 17: + { + parser.yyVAL.item = []*ast.PlacementOption{yyS[yypt-0].item.(*ast.PlacementOption)} + } + case 18: + { + parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.PlacementOption), yyS[yypt-0].item.(*ast.PlacementOption)) + } + case 19: + { + parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.PlacementOption), yyS[yypt-0].item.(*ast.PlacementOption)) + } + case 20: + { + parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionPrimaryRegion, StrValue: yyS[yypt-0].ident} + } + case 21: + { + parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionRegions, StrValue: yyS[yypt-0].ident} + } + case 22: { cnt := yyS[yypt-0].item.(uint64) if cnt == 0 { @@ -11663,71 +12044,71 @@ yynewstate: } parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionFollowerCount, UintValue: cnt} } - case 15: + case 23: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionVoterCount, UintValue: yyS[yypt-0].item.(uint64)} } - case 16: + case 24: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionLearnerCount, UintValue: yyS[yypt-0].item.(uint64)} } - case 17: + case 25: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionSchedule, StrValue: yyS[yypt-0].ident} } - case 18: + case 26: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionConstraints, StrValue: yyS[yypt-0].ident} } - case 19: + case 27: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionLeaderConstraints, StrValue: yyS[yypt-0].ident} } - case 20: + case 28: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionFollowerConstraints, StrValue: yyS[yypt-0].ident} } - case 21: + case 29: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionVoterConstraints, StrValue: yyS[yypt-0].ident} } - case 22: + case 30: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionLearnerConstraints, StrValue: yyS[yypt-0].ident} } - case 23: + case 31: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionPolicy, StrValue: yyS[yypt-0].ident} } - case 24: + case 32: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionPolicy, StrValue: yyS[yypt-0].ident} } - case 25: + case 33: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionPolicy, StrValue: yyS[yypt-0].ident} } - case 26: + case 34: { parser.yyVAL.item = &ast.PlacementOption{Tp: ast.PlacementOptionPolicy, StrValue: yyS[yypt-0].ident} } - case 27: + case 35: { parser.yyVAL.item = &ast.AttributesSpec{Default: true} } - case 28: + case 36: { parser.yyVAL.item = &ast.AttributesSpec{Default: false, Attributes: yyS[yypt-0].ident} } - case 29: + case 37: { parser.yyVAL.item = &ast.StatsOptionsSpec{Default: true} } - case 30: + case 38: { parser.yyVAL.item = &ast.StatsOptionsSpec{Default: false, StatsOptions: yyS[yypt-0].ident} } - case 31: + case 39: { if yyS[yypt-0].item != nil { parser.yyVAL.item = &ast.AlterTableSpec{ @@ -11738,19 +12119,19 @@ yynewstate: parser.yyVAL.item = nil } } - case 32: + case 40: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableRemovePartitioning, } } - case 33: + case 41: { ret := yyS[yypt-0].item.(*ast.AlterTableSpec) ret.NoWriteToBinlog = yyS[yypt-1].item.(bool) parser.yyVAL.item = ret } - case 34: + case 42: { partitionMethod := ast.PartitionMethod{Expr: yyS[yypt-1].expr} startOffset := parser.yyVAL.offset @@ -11762,7 +12143,7 @@ yynewstate: Partition: &ast.PartitionOptions{PartitionMethod: partitionMethod}, } } - case 35: + case 43: { partitionMethod := ast.PartitionMethod{Expr: yyS[yypt-1].expr} startOffset := parser.yyVAL.offset @@ -11775,7 +12156,7 @@ yynewstate: Partition: &ast.PartitionOptions{PartitionMethod: partitionMethod}, } } - case 36: + case 44: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTablePartitionAttributes, @@ -11783,7 +12164,7 @@ yynewstate: AttributesSpec: yyS[yypt-0].item.(*ast.AttributesSpec), } } - case 37: + case 45: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTablePartitionOptions, @@ -11791,22 +12172,28 @@ yynewstate: Options: yyS[yypt-0].item.([]*ast.TableOption), } } - case 38: + case 46: + { + parser.yyVAL.item = &ast.AlterTableSpec{ + Tp: ast.AlterTableRemoveTTL, + } + } + case 47: { parser.yyVAL.item = []string{} } - case 39: + case 48: { parser.yyVAL.item = yyS[yypt-0].item } - case 40: + case 49: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableOption, Options: yyS[yypt-0].item.([]*ast.TableOption), } } - case 41: + case 50: { tiflashReplicaSpec := &ast.TiFlashReplicaSpec{ Count: yyS[yypt-1].item.(uint64), @@ -11817,7 +12204,7 @@ yynewstate: TiFlashReplica: tiflashReplicaSpec, } } - case 42: + case 51: { op := &ast.AlterTableSpec{ Tp: ast.AlterTableOption, @@ -11829,7 +12216,7 @@ yynewstate: } parser.yyVAL.item = op } - case 43: + case 52: { op := &ast.AlterTableSpec{ Tp: ast.AlterTableOption, @@ -11841,7 +12228,7 @@ yynewstate: } parser.yyVAL.item = op } - case 44: + case 53: { parser.yyVAL.item = &ast.AlterTableSpec{ IfNotExists: yyS[yypt-2].item.(bool), @@ -11850,7 +12237,7 @@ yynewstate: Position: yyS[yypt-0].item.(*ast.ColumnPosition), } } - case 45: + case 54: { tes := yyS[yypt-1].item.([]interface{}) var columnDefs []*ast.ColumnDef @@ -11870,7 +12257,7 @@ yynewstate: NewConstraints: constraints, } } - case 46: + case 55: { constraint := yyS[yypt-0].item.(*ast.Constraint) parser.yyVAL.item = &ast.AlterTableSpec{ @@ -11878,7 +12265,7 @@ yynewstate: Constraint: constraint, } } - case 47: + case 56: { var defs []*ast.PartitionDefinition if yyS[yypt-0].item != nil { @@ -11896,7 +12283,7 @@ yynewstate: PartDefinitions: defs, } } - case 48: + case 57: { noWriteToBinlog := yyS[yypt-2].item.(bool) if noWriteToBinlog { @@ -11910,7 +12297,7 @@ yynewstate: Num: getUint64FromNUM(yyS[yypt-0].item), } } - case 49: + case 58: { noWriteToBinlog := yyS[yypt-0].item.(bool) if noWriteToBinlog { @@ -11929,7 +12316,7 @@ yynewstate: Partition: &ast.PartitionOptions{PartitionMethod: partitionMethod}, } } - case 50: + case 59: { statsSpec := &ast.StatisticsSpec{ StatsName: yyS[yypt-4].ident, @@ -11942,21 +12329,21 @@ yynewstate: Statistics: statsSpec, } } - case 51: + case 60: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableAttributes, AttributesSpec: yyS[yypt-0].item.(*ast.AttributesSpec), } } - case 52: + case 61: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableStatsOptions, StatsOptionsSpec: yyS[yypt-0].item.(*ast.StatsOptionsSpec), } } - case 53: + case 62: { yylex.AppendError(yylex.Errorf("The CHECK PARTITIONING clause is parsed but not implement yet.")) parser.lastErrorAsWarn() @@ -11970,7 +12357,7 @@ yynewstate: } parser.yyVAL.item = ret } - case 54: + case 63: { noWriteToBinlog := yyS[yypt-1].item.(bool) if noWriteToBinlog { @@ -11983,7 +12370,7 @@ yynewstate: Num: getUint64FromNUM(yyS[yypt-0].item), } } - case 55: + case 64: { parser.yyVAL.item = &ast.AlterTableSpec{ IfExists: yyS[yypt-2].item.(bool), @@ -11991,11 +12378,11 @@ yynewstate: OldColumnName: yyS[yypt-1].item.(*ast.ColumnName), } } - case 56: + case 65: { parser.yyVAL.item = &ast.AlterTableSpec{Tp: ast.AlterTableDropPrimaryKey} } - case 57: + case 66: { parser.yyVAL.item = &ast.AlterTableSpec{ IfExists: yyS[yypt-1].item.(bool), @@ -12003,7 +12390,7 @@ yynewstate: PartitionNames: yyS[yypt-0].item.([]model.CIStr), } } - case 58: + case 67: { partitionMethod := ast.PartitionMethod{Expr: yyS[yypt-2].expr} startOffset := parser.yyVAL.offset @@ -12017,7 +12404,7 @@ yynewstate: Partition: &ast.PartitionOptions{PartitionMethod: partitionMethod}, } } - case 59: + case 68: { statsSpec := &ast.StatisticsSpec{ StatsName: yyS[yypt-0].ident, @@ -12028,7 +12415,7 @@ yynewstate: Statistics: statsSpec, } } - case 60: + case 69: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableExchangePartition, @@ -12037,7 +12424,7 @@ yynewstate: WithValidation: yyS[yypt-0].item.(bool), } } - case 61: + case 70: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableTruncatePartition, @@ -12049,7 +12436,7 @@ yynewstate: } parser.yyVAL.item = ret } - case 62: + case 71: { ret := &ast.AlterTableSpec{ NoWriteToBinlog: yyS[yypt-1].item.(bool), @@ -12062,7 +12449,7 @@ yynewstate: } parser.yyVAL.item = ret } - case 63: + case 72: { ret := &ast.AlterTableSpec{ NoWriteToBinlog: yyS[yypt-1].item.(bool), @@ -12075,7 +12462,7 @@ yynewstate: } parser.yyVAL.item = ret } - case 64: + case 73: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableImportPartitionTablespace, @@ -12089,7 +12476,7 @@ yynewstate: yylex.AppendError(yylex.Errorf("The IMPORT PARTITION TABLESPACE clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 65: + case 74: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableDiscardPartitionTablespace, @@ -12103,7 +12490,7 @@ yynewstate: yylex.AppendError(yylex.Errorf("The DISCARD PARTITION TABLESPACE clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 66: + case 75: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableImportTablespace, @@ -12112,7 +12499,7 @@ yynewstate: yylex.AppendError(yylex.Errorf("The IMPORT TABLESPACE clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 67: + case 76: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableDiscardTablespace, @@ -12121,7 +12508,7 @@ yynewstate: yylex.AppendError(yylex.Errorf("The DISCARD TABLESPACE clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 68: + case 77: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableRebuildPartition, @@ -12134,7 +12521,7 @@ yynewstate: } parser.yyVAL.item = ret } - case 69: + case 78: { parser.yyVAL.item = &ast.AlterTableSpec{ IfExists: yyS[yypt-1].item.(bool), @@ -12142,7 +12529,7 @@ yynewstate: Name: yyS[yypt-0].ident, } } - case 70: + case 79: { parser.yyVAL.item = &ast.AlterTableSpec{ IfExists: yyS[yypt-1].item.(bool), @@ -12150,26 +12537,26 @@ yynewstate: Name: yyS[yypt-0].ident, } } - case 71: + case 80: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableOrderByColumns, OrderByList: yyS[yypt-0].item.([]*ast.AlterOrderItem), } } - case 72: + case 81: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableDisableKeys, } } - case 73: + case 82: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableEnableKeys, } } - case 74: + case 83: { parser.yyVAL.item = &ast.AlterTableSpec{ IfExists: yyS[yypt-2].item.(bool), @@ -12178,7 +12565,7 @@ yynewstate: Position: yyS[yypt-0].item.(*ast.ColumnPosition), } } - case 75: + case 84: { parser.yyVAL.item = &ast.AlterTableSpec{ IfExists: yyS[yypt-3].item.(bool), @@ -12188,7 +12575,7 @@ yynewstate: Position: yyS[yypt-0].item.(*ast.ColumnPosition), } } - case 76: + case 85: { option := &ast.ColumnOption{Expr: yyS[yypt-0].expr} colDef := &ast.ColumnDef{ @@ -12200,7 +12587,7 @@ yynewstate: NewColumns: []*ast.ColumnDef{colDef}, } } - case 77: + case 86: { option := &ast.ColumnOption{Expr: yyS[yypt-1].expr} colDef := &ast.ColumnDef{ @@ -12212,7 +12599,7 @@ yynewstate: NewColumns: []*ast.ColumnDef{colDef}, } } - case 78: + case 87: { colDef := &ast.ColumnDef{ Name: yyS[yypt-2].item.(*ast.ColumnName), @@ -12222,7 +12609,7 @@ yynewstate: NewColumns: []*ast.ColumnDef{colDef}, } } - case 79: + case 88: { oldColName := &ast.ColumnName{Name: model.NewCIStr(yyS[yypt-2].ident)} newColName := &ast.ColumnName{Name: model.NewCIStr(yyS[yypt-0].ident)} @@ -12232,28 +12619,28 @@ yynewstate: NewColumnName: newColName, } } - case 80: + case 89: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableRenameTable, NewTable: yyS[yypt-0].item.(*ast.TableName), } } - case 81: + case 90: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableRenameTable, NewTable: yyS[yypt-0].item.(*ast.TableName), } } - case 82: + case 91: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableRenameTable, NewTable: yyS[yypt-0].item.(*ast.TableName), } } - case 83: + case 92: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableRenameIndex, @@ -12261,21 +12648,21 @@ yynewstate: ToKey: model.NewCIStr(yyS[yypt-0].ident), } } - case 84: + case 93: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableLock, LockType: yyS[yypt-0].item.(ast.LockType), } } - case 85: + case 94: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableWriteable, Writeable: yyS[yypt-0].item.(bool), } } - case 86: + case 95: { // Parse it and ignore it. Just for compatibility. parser.yyVAL.item = &ast.AlterTableSpec{ @@ -12283,28 +12670,28 @@ yynewstate: Algorithm: yyS[yypt-0].item.(ast.AlgorithmType), } } - case 87: + case 96: { // Parse it and ignore it. Just for compatibility. parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableForce, } } - case 88: + case 97: { // Parse it and ignore it. Just for compatibility. parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableWithValidation, } } - case 89: + case 98: { // Parse it and ignore it. Just for compatibility. parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableWithoutValidation, } } - case 90: + case 99: { // Parse it and ignore it. Just for compatibility. parser.yyVAL.item = &ast.AlterTableSpec{ @@ -12313,7 +12700,7 @@ yynewstate: yylex.AppendError(yylex.Errorf("The SECONDARY_LOAD clause is parsed but not implement yet.")) parser.lastErrorAsWarn() } - case 91: + case 100: { // Parse it and ignore it. Just for compatibility. parser.yyVAL.item = &ast.AlterTableSpec{ @@ -12322,7 +12709,7 @@ yynewstate: yylex.AppendError(yylex.Errorf("The SECONDARY_UNLOAD VALIDATION clause is parsed but not implement yet.")) parser.lastErrorAsWarn() } - case 92: + case 101: { c := &ast.Constraint{ Name: yyS[yypt-1].ident, @@ -12333,7 +12720,7 @@ yynewstate: Constraint: c, } } - case 93: + case 102: { // Parse it and ignore it. Just for compatibility. c := &ast.Constraint{ @@ -12344,7 +12731,7 @@ yynewstate: Constraint: c, } } - case 94: + case 103: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableIndexInvisible, @@ -12352,19 +12739,19 @@ yynewstate: Visibility: yyS[yypt-0].item.(ast.IndexVisibility), } } - case 95: + case 104: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableCache, } } - case 96: + case 105: { parser.yyVAL.item = &ast.AlterTableSpec{ Tp: ast.AlterTableNoCache, } } - case 97: + case 106: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableReorganizePartition, @@ -12372,7 +12759,7 @@ yynewstate: } parser.yyVAL.item = ret } - case 98: + case 107: { ret := &ast.AlterTableSpec{ Tp: ast.AlterTableReorganizePartition, @@ -12381,56 +12768,56 @@ yynewstate: } parser.yyVAL.item = ret } - case 99: + case 108: { parser.yyVAL.item = nil } - case 101: + case 110: { parser.yyVAL.item = true } - case 103: + case 112: { parser.yyVAL.item = true } - case 104: + case 113: { parser.yyVAL.item = false } - case 105: + case 114: { parser.yyVAL.item = model.PrimaryKeyTypeClustered } - case 106: + case 115: { parser.yyVAL.item = model.PrimaryKeyTypeNonClustered } - case 107: + case 116: { parser.yyVAL.item = ast.AlgorithmTypeDefault } - case 108: + case 117: { parser.yyVAL.item = ast.AlgorithmTypeCopy } - case 109: + case 118: { parser.yyVAL.item = ast.AlgorithmTypeInplace } - case 110: + case 119: { parser.yyVAL.item = ast.AlgorithmTypeInstant } - case 111: + case 120: { yylex.AppendError(ErrUnknownAlterAlgorithm.GenWithStackByArgs(yyS[yypt-2].ident)) return 1 } - case 112: + case 121: { parser.yyVAL.item = ast.LockTypeDefault } - case 113: + case 122: { id := strings.ToUpper(yyS[yypt-0].ident) @@ -12445,144 +12832,165 @@ yynewstate: return 1 } } - case 114: + case 123: { parser.yyVAL.item = true } - case 115: + case 124: { parser.yyVAL.item = false } - case 122: + case 131: { parser.yyVAL.item = &ast.ColumnPosition{Tp: ast.ColumnPositionNone} } - case 123: + case 132: { parser.yyVAL.item = &ast.ColumnPosition{Tp: ast.ColumnPositionFirst} } - case 124: + case 133: { parser.yyVAL.item = &ast.ColumnPosition{ Tp: ast.ColumnPositionAfter, RelativeColumn: yyS[yypt-0].item.(*ast.ColumnName), } } - case 125: + case 134: { parser.yyVAL.item = make([]*ast.AlterTableSpec, 0, 1) } - case 127: + case 136: { parser.yyVAL.item = []*ast.AlterTableSpec{yyS[yypt-0].item.(*ast.AlterTableSpec)} } - case 128: + case 137: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.AlterTableSpec), yyS[yypt-0].item.(*ast.AlterTableSpec)) } - case 129: + case 138: { parser.yyVAL.item = []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)} } - case 130: + case 139: { parser.yyVAL.item = append(yyS[yypt-2].item.([]model.CIStr), model.NewCIStr(yyS[yypt-0].ident)) } - case 131: + case 140: { parser.yyVAL.item = nil } - case 132: + case 141: { parser.yyVAL.item = nil } - case 133: + case 142: { parser.yyVAL.item = yyS[yypt-0].ident } - case 135: + case 144: { parser.yyVAL.statement = &ast.RenameTableStmt{ TableToTables: yyS[yypt-0].item.([]*ast.TableToTable), } } - case 136: + case 145: { parser.yyVAL.item = []*ast.TableToTable{yyS[yypt-0].item.(*ast.TableToTable)} } - case 137: + case 146: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.TableToTable), yyS[yypt-0].item.(*ast.TableToTable)) } - case 138: + case 147: { parser.yyVAL.item = &ast.TableToTable{ OldTable: yyS[yypt-2].item.(*ast.TableName), NewTable: yyS[yypt-0].item.(*ast.TableName), } } - case 139: + case 148: { parser.yyVAL.statement = &ast.RenameUserStmt{ UserToUsers: yyS[yypt-0].item.([]*ast.UserToUser), } } - case 140: + case 149: { parser.yyVAL.item = []*ast.UserToUser{yyS[yypt-0].item.(*ast.UserToUser)} } - case 141: + case 150: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.UserToUser), yyS[yypt-0].item.(*ast.UserToUser)) } - case 142: + case 151: { parser.yyVAL.item = &ast.UserToUser{ OldUser: yyS[yypt-2].item.(*auth.UserIdentity), NewUser: yyS[yypt-0].item.(*auth.UserIdentity), } } - case 143: + case 152: { parser.yyVAL.statement = &ast.RecoverTableStmt{ JobID: yyS[yypt-0].item.(int64), } } - case 144: + case 153: { parser.yyVAL.statement = &ast.RecoverTableStmt{ Table: yyS[yypt-0].item.(*ast.TableName), } } - case 145: + case 154: { parser.yyVAL.statement = &ast.RecoverTableStmt{ Table: yyS[yypt-1].item.(*ast.TableName), JobNum: yyS[yypt-0].item.(int64), } } - case 146: + case 155: { - parser.yyVAL.statement = &ast.FlashBackClusterStmt{ + parser.yyVAL.statement = &ast.FlashBackToTimestampStmt{ FlashbackTS: ast.NewValueExpr(yyS[yypt-0].ident, "", ""), } } - case 147: + case 156: + { + parser.yyVAL.statement = &ast.FlashBackToTimestampStmt{ + Tables: yyS[yypt-2].item.([]*ast.TableName), + FlashbackTS: ast.NewValueExpr(yyS[yypt-0].ident, "", ""), + } + } + case 157: + { + parser.yyVAL.statement = &ast.FlashBackToTimestampStmt{ + DBName: model.NewCIStr(yyS[yypt-2].ident), + FlashbackTS: ast.NewValueExpr(yyS[yypt-0].ident, "", ""), + } + } + case 158: { parser.yyVAL.statement = &ast.FlashBackTableStmt{ Table: yyS[yypt-1].item.(*ast.TableName), NewName: yyS[yypt-0].ident, } } - case 148: + case 159: { parser.yyVAL.ident = "" } - case 149: + case 160: { parser.yyVAL.ident = yyS[yypt-0].ident } - case 150: + case 161: + { + parser.yyVAL.statement = &ast.FlashBackDatabaseStmt{ + DBName: model.NewCIStr(yyS[yypt-1].ident), + NewName: yyS[yypt-0].ident, + } + } + case 162: { parser.yyVAL.statement = &ast.SplitRegionStmt{ SplitSyntaxOpt: yyS[yypt-4].item.(*ast.SplitSyntaxOption), @@ -12591,7 +12999,7 @@ yynewstate: SplitOpt: yyS[yypt-0].item.(*ast.SplitOption), } } - case 151: + case 163: { parser.yyVAL.statement = &ast.SplitRegionStmt{ SplitSyntaxOpt: yyS[yypt-6].item.(*ast.SplitSyntaxOption), @@ -12601,7 +13009,7 @@ yynewstate: SplitOpt: yyS[yypt-0].item.(*ast.SplitOption), } } - case 152: + case 164: { parser.yyVAL.item = &ast.SplitOption{ Lower: yyS[yypt-4].item.([]ast.ExprNode), @@ -12609,52 +13017,52 @@ yynewstate: Num: yyS[yypt-0].item.(int64), } } - case 153: + case 165: { parser.yyVAL.item = &ast.SplitOption{ ValueLists: yyS[yypt-0].item.([][]ast.ExprNode), } } - case 154: + case 166: { parser.yyVAL.item = &ast.SplitSyntaxOption{} } - case 155: + case 167: { parser.yyVAL.item = &ast.SplitSyntaxOption{ HasRegionFor: true, } } - case 156: + case 168: { parser.yyVAL.item = &ast.SplitSyntaxOption{ HasPartition: true, } } - case 157: + case 169: { parser.yyVAL.item = &ast.SplitSyntaxOption{ HasRegionFor: true, HasPartition: true, } } - case 158: + case 170: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{TableNames: yyS[yypt-2].item.([]*ast.TableName), ColumnChoice: yyS[yypt-1].item.(model.ColumnChoice), AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt)} } - case 159: + case 171: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{yyS[yypt-3].item.(*ast.TableName)}, IndexNames: yyS[yypt-1].item.([]model.CIStr), IndexFlag: true, AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt)} } - case 160: + case 172: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{yyS[yypt-3].item.(*ast.TableName)}, IndexNames: yyS[yypt-1].item.([]model.CIStr), IndexFlag: true, Incremental: true, AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt)} } - case 161: + case 173: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{yyS[yypt-4].item.(*ast.TableName)}, PartitionNames: yyS[yypt-2].item.([]model.CIStr), ColumnChoice: yyS[yypt-1].item.(model.ColumnChoice), AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt)} } - case 162: + case 174: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{ TableNames: []*ast.TableName{yyS[yypt-5].item.(*ast.TableName)}, @@ -12664,7 +13072,7 @@ yynewstate: AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt), } } - case 163: + case 175: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{ TableNames: []*ast.TableName{yyS[yypt-5].item.(*ast.TableName)}, @@ -12675,7 +13083,7 @@ yynewstate: AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt), } } - case 164: + case 176: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{ TableNames: []*ast.TableName{yyS[yypt-5].item.(*ast.TableName)}, @@ -12684,7 +13092,7 @@ yynewstate: HistogramOperation: ast.HistogramOperationUpdate, } } - case 165: + case 177: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{ TableNames: []*ast.TableName{yyS[yypt-4].item.(*ast.TableName)}, @@ -12692,7 +13100,7 @@ yynewstate: HistogramOperation: ast.HistogramOperationDrop, } } - case 166: + case 178: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{ TableNames: []*ast.TableName{yyS[yypt-3].item.(*ast.TableName)}, @@ -12700,7 +13108,7 @@ yynewstate: ColumnChoice: model.ColumnList, AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt)} } - case 167: + case 179: { parser.yyVAL.statement = &ast.AnalyzeTableStmt{ TableNames: []*ast.TableName{yyS[yypt-5].item.(*ast.TableName)}, @@ -12709,134 +13117,134 @@ yynewstate: ColumnChoice: model.ColumnList, AnalyzeOpts: yyS[yypt-0].item.([]ast.AnalyzeOpt)} } - case 168: + case 180: { parser.yyVAL.item = model.DefaultChoice } - case 169: + case 181: { parser.yyVAL.item = model.AllColumns } - case 170: + case 182: { parser.yyVAL.item = model.PredicateColumns } - case 171: + case 183: { parser.yyVAL.item = []ast.AnalyzeOpt{} } - case 172: + case 184: { parser.yyVAL.item = yyS[yypt-0].item.([]ast.AnalyzeOpt) } - case 173: + case 185: { parser.yyVAL.item = []ast.AnalyzeOpt{yyS[yypt-0].item.(ast.AnalyzeOpt)} } - case 174: + case 186: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.AnalyzeOpt), yyS[yypt-0].item.(ast.AnalyzeOpt)) } - case 175: + case 187: { parser.yyVAL.item = ast.AnalyzeOpt{Type: ast.AnalyzeOptNumBuckets, Value: ast.NewValueExpr(yyS[yypt-1].item, "", "")} } - case 176: + case 188: { parser.yyVAL.item = ast.AnalyzeOpt{Type: ast.AnalyzeOptNumTopN, Value: ast.NewValueExpr(yyS[yypt-1].item, "", "")} } - case 177: + case 189: { parser.yyVAL.item = ast.AnalyzeOpt{Type: ast.AnalyzeOptCMSketchDepth, Value: ast.NewValueExpr(yyS[yypt-2].item, "", "")} } - case 178: + case 190: { parser.yyVAL.item = ast.AnalyzeOpt{Type: ast.AnalyzeOptCMSketchWidth, Value: ast.NewValueExpr(yyS[yypt-2].item, "", "")} } - case 179: + case 191: { parser.yyVAL.item = ast.AnalyzeOpt{Type: ast.AnalyzeOptNumSamples, Value: ast.NewValueExpr(yyS[yypt-1].item, "", "")} } - case 180: + case 192: { parser.yyVAL.item = ast.AnalyzeOpt{Type: ast.AnalyzeOptSampleRate, Value: ast.NewValueExpr(yyS[yypt-1].item, "", "")} } - case 181: + case 193: { parser.yyVAL.item = &ast.Assignment{Column: yyS[yypt-2].item.(*ast.ColumnName), Expr: yyS[yypt-0].expr} } - case 182: + case 194: { parser.yyVAL.item = []*ast.Assignment{yyS[yypt-0].item.(*ast.Assignment)} } - case 183: + case 195: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.Assignment), yyS[yypt-0].item.(*ast.Assignment)) } - case 184: + case 196: { parser.yyVAL.item = []*ast.Assignment{} } - case 186: + case 198: { parser.yyVAL.statement = &ast.BeginStmt{} } - case 187: + case 199: { parser.yyVAL.statement = &ast.BeginStmt{ Mode: ast.Pessimistic, } } - case 188: + case 200: { parser.yyVAL.statement = &ast.BeginStmt{ Mode: ast.Optimistic, } } - case 189: + case 201: { parser.yyVAL.statement = &ast.BeginStmt{} } - case 190: + case 202: { parser.yyVAL.statement = &ast.BeginStmt{} } - case 191: + case 203: { parser.yyVAL.statement = &ast.BeginStmt{} } - case 192: + case 204: { parser.yyVAL.statement = &ast.BeginStmt{ CausalConsistencyOnly: true, } } - case 193: + case 205: { parser.yyVAL.statement = &ast.BeginStmt{ ReadOnly: true, } } - case 194: + case 206: { parser.yyVAL.statement = &ast.BeginStmt{ ReadOnly: true, AsOf: yyS[yypt-0].item.(*ast.AsOfClause), } } - case 195: + case 207: { parser.yyVAL.statement = &ast.BinlogStmt{Str: yyS[yypt-0].ident} } - case 196: + case 208: { parser.yyVAL.item = []*ast.ColumnDef{yyS[yypt-0].item.(*ast.ColumnDef)} } - case 197: + case 209: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.ColumnDef), yyS[yypt-0].item.(*ast.ColumnDef)) } - case 198: + case 210: { colDef := &ast.ColumnDef{Name: yyS[yypt-2].item.(*ast.ColumnName), Tp: yyS[yypt-1].item.(*types.FieldType), Options: yyS[yypt-0].item.([]*ast.ColumnOption)} if !colDef.Validate() { @@ -12845,7 +13253,7 @@ yynewstate: } parser.yyVAL.item = colDef } - case 199: + case 211: { // TODO: check flen 0 tp := types.NewFieldType(mysql.TypeLonglong) @@ -12859,103 +13267,103 @@ yynewstate: } parser.yyVAL.item = colDef } - case 200: + case 212: { parser.yyVAL.item = &ast.ColumnName{Name: model.NewCIStr(yyS[yypt-0].ident)} } - case 201: + case 213: { parser.yyVAL.item = &ast.ColumnName{Table: model.NewCIStr(yyS[yypt-2].ident), Name: model.NewCIStr(yyS[yypt-0].ident)} } - case 202: + case 214: { parser.yyVAL.item = &ast.ColumnName{Schema: model.NewCIStr(yyS[yypt-4].ident), Table: model.NewCIStr(yyS[yypt-2].ident), Name: model.NewCIStr(yyS[yypt-0].ident)} } - case 203: + case 215: { parser.yyVAL.item = []*ast.ColumnName{yyS[yypt-0].item.(*ast.ColumnName)} } - case 204: + case 216: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.ColumnName), yyS[yypt-0].item.(*ast.ColumnName)) } - case 205: + case 217: { parser.yyVAL.item = []*ast.ColumnName{} } - case 207: + case 219: { parser.yyVAL.item = []model.CIStr{} } - case 208: + case 220: { parser.yyVAL.item = yyS[yypt-1].item } - case 209: + case 221: { parser.yyVAL.item = []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)} } - case 210: + case 222: { parser.yyVAL.item = append(yyS[yypt-2].item.([]model.CIStr), model.NewCIStr(yyS[yypt-0].ident)) } - case 211: + case 223: { parser.yyVAL.item = []*ast.ColumnNameOrUserVar{} } - case 213: + case 225: { parser.yyVAL.item = []*ast.ColumnNameOrUserVar{yyS[yypt-0].item.(*ast.ColumnNameOrUserVar)} } - case 214: + case 226: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.ColumnNameOrUserVar), yyS[yypt-0].item.(*ast.ColumnNameOrUserVar)) } - case 215: + case 227: { parser.yyVAL.item = &ast.ColumnNameOrUserVar{ColumnName: yyS[yypt-0].item.(*ast.ColumnName)} } - case 216: + case 228: { parser.yyVAL.item = &ast.ColumnNameOrUserVar{UserVar: yyS[yypt-0].expr.(*ast.VariableExpr)} } - case 217: + case 229: { parser.yyVAL.item = []*ast.ColumnNameOrUserVar{} } - case 218: + case 230: { parser.yyVAL.item = yyS[yypt-1].item.([]*ast.ColumnNameOrUserVar) } - case 219: + case 231: { parser.yyVAL.statement = &ast.CommitStmt{} } - case 220: + case 232: { parser.yyVAL.statement = &ast.CommitStmt{CompletionType: yyS[yypt-0].item.(ast.CompletionType)} } - case 224: + case 236: { parser.yyVAL.ident = "NOT" } - case 225: + case 237: { parser.yyVAL.item = true } - case 226: + case 238: { parser.yyVAL.item = false } - case 227: + case 239: { parser.yyVAL.item = true } - case 229: + case 241: { parser.yyVAL.item = 0 } - case 230: + case 242: { if yyS[yypt-0].item.(bool) { parser.yyVAL.item = 1 @@ -12963,57 +13371,57 @@ yynewstate: parser.yyVAL.item = 2 } } - case 231: + case 243: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionNotNull} } - case 232: + case 244: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionNull} } - case 233: + case 245: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionAutoIncrement} } - case 234: + case 246: { // KEY is normally a synonym for INDEX. The key attribute PRIMARY KEY // can also be specified as just KEY when given in a column definition. // See http://dev.mysql.com/doc/refman/5.7/en/create-table.html parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionPrimaryKey} } - case 235: + case 247: { // KEY is normally a synonym for INDEX. The key attribute PRIMARY KEY // can also be specified as just KEY when given in a column definition. // See http://dev.mysql.com/doc/refman/5.7/en/create-table.html parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionPrimaryKey, PrimaryKeyTp: yyS[yypt-0].item.(model.PrimaryKeyType)} } - case 236: + case 248: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey} } - case 237: + case 249: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey} } - case 238: + case 250: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionDefaultValue, Expr: yyS[yypt-0].expr} } - case 239: + case 251: { parser.yyVAL.item = []*ast.ColumnOption{{Tp: ast.ColumnOptionNotNull}, {Tp: ast.ColumnOptionAutoIncrement}, {Tp: ast.ColumnOptionUniqKey}} } - case 240: + case 252: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionOnUpdate, Expr: yyS[yypt-0].expr} } - case 241: + case 253: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionComment, Expr: ast.NewValueExpr(yyS[yypt-0].ident, "", "")} } - case 242: + case 254: { // See https://dev.mysql.com/doc/refman/5.7/en/create-table.html // The CHECK clause is parsed but ignored by all storage engines. @@ -13040,7 +13448,7 @@ yynewstate: default: } } - case 243: + case 255: { startOffset := parser.startOffset(&yyS[yypt-2]) endOffset := parser.endOffset(&yyS[yypt-1]) @@ -13053,68 +13461,68 @@ yynewstate: Stored: yyS[yypt-0].item.(bool), } } - case 244: + case 256: { parser.yyVAL.item = &ast.ColumnOption{ Tp: ast.ColumnOptionReference, Refer: yyS[yypt-0].item.(*ast.ReferenceDef), } } - case 245: + case 257: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionCollate, StrValue: yyS[yypt-0].ident} } - case 246: + case 258: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionColumnFormat, StrValue: yyS[yypt-0].ident} } - case 247: + case 259: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionStorage, StrValue: yyS[yypt-0].ident} yylex.AppendError(yylex.Errorf("The STORAGE clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 248: + case 260: { parser.yyVAL.item = &ast.ColumnOption{Tp: ast.ColumnOptionAutoRandom, AutoRandOpt: yyS[yypt-0].item.(ast.AutoRandomOption)} } - case 249: + case 261: { parser.yyVAL.item = ast.AutoRandomOption{ShardBits: types.UnspecifiedLength, RangeBits: types.UnspecifiedLength} } - case 250: + case 262: { parser.yyVAL.item = ast.AutoRandomOption{ShardBits: int(yyS[yypt-1].item.(uint64)), RangeBits: types.UnspecifiedLength} } - case 251: + case 263: { parser.yyVAL.item = ast.AutoRandomOption{ShardBits: int(yyS[yypt-3].item.(uint64)), RangeBits: int(yyS[yypt-1].item.(uint64))} } - case 255: + case 267: { parser.yyVAL.ident = "DEFAULT" } - case 256: + case 268: { parser.yyVAL.ident = "FIXED" } - case 257: + case 269: { parser.yyVAL.ident = "DYNAMIC" } - case 260: + case 272: { parser.yyVAL.item = false } - case 261: + case 273: { parser.yyVAL.item = false } - case 262: + case 274: { parser.yyVAL.item = true } - case 263: + case 275: { if columnOption, ok := yyS[yypt-0].item.(*ast.ColumnOption); ok { parser.yyVAL.item = []*ast.ColumnOption{columnOption} @@ -13122,7 +13530,7 @@ yynewstate: parser.yyVAL.item = yyS[yypt-0].item } } - case 264: + case 276: { if columnOption, ok := yyS[yypt-0].item.(*ast.ColumnOption); ok { parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.ColumnOption), columnOption) @@ -13130,11 +13538,11 @@ yynewstate: parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.ColumnOption), yyS[yypt-0].item.([]*ast.ColumnOption)...) } } - case 265: + case 277: { parser.yyVAL.item = []*ast.ColumnOption{} } - case 267: + case 279: { c := &ast.Constraint{ Tp: ast.ConstraintPrimaryKey, @@ -13153,7 +13561,7 @@ yynewstate: } parser.yyVAL.item = c } - case 268: + case 280: { c := &ast.Constraint{ Tp: ast.ConstraintFulltext, @@ -13166,7 +13574,7 @@ yynewstate: } parser.yyVAL.item = c } - case 269: + case 281: { c := &ast.Constraint{ IfNotExists: yyS[yypt-5].item.(bool), @@ -13186,7 +13594,7 @@ yynewstate: } parser.yyVAL.item = c } - case 270: + case 282: { c := &ast.Constraint{ Tp: ast.ConstraintUniq, @@ -13206,7 +13614,7 @@ yynewstate: } parser.yyVAL.item = c } - case 271: + case 283: { parser.yyVAL.item = &ast.Constraint{ IfNotExists: yyS[yypt-5].item.(bool), @@ -13217,7 +13625,7 @@ yynewstate: IsEmptyIndex: yyS[yypt-4].item.(*ast.NullString).Empty, } } - case 272: + case 284: { parser.yyVAL.item = &ast.Constraint{ Tp: ast.ConstraintCheck, @@ -13225,29 +13633,29 @@ yynewstate: Enforced: yyS[yypt-0].item.(bool), } } - case 273: + case 285: { parser.yyVAL.item = ast.MatchFull } - case 274: + case 286: { parser.yyVAL.item = ast.MatchPartial } - case 275: + case 287: { parser.yyVAL.item = ast.MatchSimple } - case 276: + case 288: { parser.yyVAL.item = ast.MatchNone } - case 277: + case 289: { parser.yyVAL.item = yyS[yypt-0].item yylex.AppendError(yylex.Errorf("The MATCH clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 278: + case 290: { onDeleteUpdate := yyS[yypt-0].item.([2]interface{}) parser.yyVAL.item = &ast.ReferenceDef{ @@ -13258,90 +13666,98 @@ yynewstate: Match: yyS[yypt-1].item.(ast.MatchType), } } - case 279: + case 291: { parser.yyVAL.item = &ast.OnDeleteOpt{ReferOpt: yyS[yypt-0].item.(model.ReferOptionType)} } - case 280: + case 292: { parser.yyVAL.item = &ast.OnUpdateOpt{ReferOpt: yyS[yypt-0].item.(model.ReferOptionType)} } - case 281: + case 293: { parser.yyVAL.item = [2]interface{}{&ast.OnDeleteOpt{}, &ast.OnUpdateOpt{}} } - case 282: + case 294: { parser.yyVAL.item = [2]interface{}{yyS[yypt-0].item, &ast.OnUpdateOpt{}} } - case 283: + case 295: { parser.yyVAL.item = [2]interface{}{&ast.OnDeleteOpt{}, yyS[yypt-0].item} } - case 284: + case 296: { parser.yyVAL.item = [2]interface{}{yyS[yypt-1].item, yyS[yypt-0].item} } - case 285: + case 297: { parser.yyVAL.item = [2]interface{}{yyS[yypt-0].item, yyS[yypt-1].item} } - case 286: + case 298: { parser.yyVAL.item = model.ReferOptionRestrict } - case 287: + case 299: { parser.yyVAL.item = model.ReferOptionCascade } - case 288: + case 300: { parser.yyVAL.item = model.ReferOptionSetNull } - case 289: + case 301: { parser.yyVAL.item = model.ReferOptionNoAction } - case 290: + case 302: { parser.yyVAL.item = model.ReferOptionSetDefault yylex.AppendError(yylex.Errorf("The SET DEFAULT clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 295: + case 307: { parser.yyVAL.expr = yyS[yypt-1].expr.(*ast.FuncCallExpr) } - case 296: + case 308: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-2].ident), } } - case 297: + case 309: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-3].ident), Args: yyS[yypt-1].item.([]ast.ExprNode), } } - case 298: + case 310: { parser.yyVAL.expr = yyS[yypt-1].expr.(*ast.FuncCallExpr) } - case 300: + case 312: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} } - case 301: + case 313: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} } - case 302: + case 314: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP"), Args: []ast.ExprNode{ast.NewValueExpr(yyS[yypt-1].item, parser.charset, parser.collation)}} } - case 303: + case 315: + { + parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_DATE")} + } + case 316: + { + parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_DATE")} + } + case 317: { objNameExpr := &ast.TableNameExpr{ Name: yyS[yypt-0].item.(*ast.TableName), @@ -13351,7 +13767,7 @@ yynewstate: Args: []ast.ExprNode{objNameExpr}, } } - case 304: + case 318: { objNameExpr := &ast.TableNameExpr{ Name: yyS[yypt-1].item.(*ast.TableName), @@ -13361,39 +13777,39 @@ yynewstate: Args: []ast.ExprNode{objNameExpr}, } } - case 312: + case 328: { parser.yyVAL.expr = ast.NewValueExpr(yyS[yypt-0].expr, parser.charset, parser.collation) } - case 313: + case 329: { parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.Plus, V: ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation)} } - case 314: + case 330: { parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation)} } - case 318: + case 334: { parser.yyVAL.item = ast.StatsTypeCardinality } - case 319: + case 335: { parser.yyVAL.item = ast.StatsTypeDependency } - case 320: + case 336: { parser.yyVAL.item = ast.StatsTypeCorrelation } - case 321: + case 337: { parser.yyVAL.item = ast.BindingStatusTypeEnabled } - case 322: + case 338: { parser.yyVAL.item = ast.BindingStatusTypeDisabled } - case 323: + case 339: { parser.yyVAL.statement = &ast.CreateStatisticsStmt{ IfNotExists: yyS[yypt-9].item.(bool), @@ -13403,11 +13819,11 @@ yynewstate: Columns: yyS[yypt-1].item.([]*ast.ColumnName), } } - case 324: + case 340: { parser.yyVAL.statement = &ast.DropStatisticsStmt{StatsName: yyS[yypt-0].ident} } - case 325: + case 341: { var indexOption *ast.IndexOption if yyS[yypt-1].item != nil { @@ -13440,79 +13856,79 @@ yynewstate: LockAlg: indexLockAndAlgorithm, } } - case 326: + case 342: { parser.yyVAL.item = ([]*ast.IndexPartSpecification)(nil) } - case 327: + case 343: { parser.yyVAL.item = yyS[yypt-1].item } - case 328: + case 344: { parser.yyVAL.item = []*ast.IndexPartSpecification{yyS[yypt-0].item.(*ast.IndexPartSpecification)} } - case 329: + case 345: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.IndexPartSpecification), yyS[yypt-0].item.(*ast.IndexPartSpecification)) } - case 330: + case 346: { parser.yyVAL.item = &ast.IndexPartSpecification{Column: yyS[yypt-2].item.(*ast.ColumnName), Length: yyS[yypt-1].item.(int), Desc: yyS[yypt-0].item.(bool)} } - case 331: + case 347: { parser.yyVAL.item = &ast.IndexPartSpecification{Expr: yyS[yypt-2].expr, Desc: yyS[yypt-0].item.(bool)} } - case 332: + case 348: { parser.yyVAL.item = nil } - case 333: + case 349: { parser.yyVAL.item = &ast.IndexLockAndAlgorithm{ LockTp: yyS[yypt-0].item.(ast.LockType), AlgorithmTp: ast.AlgorithmTypeDefault, } } - case 334: + case 350: { parser.yyVAL.item = &ast.IndexLockAndAlgorithm{ LockTp: ast.LockTypeDefault, AlgorithmTp: yyS[yypt-0].item.(ast.AlgorithmType), } } - case 335: + case 351: { parser.yyVAL.item = &ast.IndexLockAndAlgorithm{ LockTp: yyS[yypt-1].item.(ast.LockType), AlgorithmTp: yyS[yypt-0].item.(ast.AlgorithmType), } } - case 336: + case 352: { parser.yyVAL.item = &ast.IndexLockAndAlgorithm{ LockTp: yyS[yypt-0].item.(ast.LockType), AlgorithmTp: yyS[yypt-1].item.(ast.AlgorithmType), } } - case 337: + case 353: { parser.yyVAL.item = ast.IndexKeyTypeNone } - case 338: + case 354: { parser.yyVAL.item = ast.IndexKeyTypeUnique } - case 339: + case 355: { parser.yyVAL.item = ast.IndexKeyTypeSpatial } - case 340: + case 356: { parser.yyVAL.item = ast.IndexKeyTypeFullText } - case 341: + case 357: { parser.yyVAL.statement = &ast.AlterDatabaseStmt{ Name: model.NewCIStr(yyS[yypt-1].ident), @@ -13520,7 +13936,7 @@ yynewstate: Options: yyS[yypt-0].item.([]*ast.DatabaseOption), } } - case 342: + case 358: { parser.yyVAL.statement = &ast.AlterDatabaseStmt{ Name: model.NewCIStr(""), @@ -13528,7 +13944,7 @@ yynewstate: Options: yyS[yypt-0].item.([]*ast.DatabaseOption), } } - case 343: + case 359: { parser.yyVAL.statement = &ast.CreateDatabaseStmt{ IfNotExists: yyS[yypt-2].item.(bool), @@ -13536,19 +13952,19 @@ yynewstate: Options: yyS[yypt-0].item.([]*ast.DatabaseOption), } } - case 346: + case 363: { parser.yyVAL.item = &ast.DatabaseOption{Tp: ast.DatabaseOptionCharset, Value: yyS[yypt-0].ident} } - case 347: + case 364: { parser.yyVAL.item = &ast.DatabaseOption{Tp: ast.DatabaseOptionCollate, Value: yyS[yypt-0].ident} } - case 348: + case 365: { parser.yyVAL.item = &ast.DatabaseOption{Tp: ast.DatabaseOptionEncryption, Value: yyS[yypt-0].ident} } - case 349: + case 366: { placementOptions := yyS[yypt-0].item.(*ast.PlacementOption) parser.yyVAL.item = &ast.DatabaseOption{ @@ -13558,7 +13974,7 @@ yynewstate: UintValue: placementOptions.UintValue, } } - case 350: + case 367: { placementOptions := yyS[yypt-0].item.(*ast.PlacementOption) parser.yyVAL.item = &ast.DatabaseOption{ @@ -13568,7 +13984,7 @@ yynewstate: UintValue: placementOptions.UintValue, } } - case 351: + case 368: { tiflashReplicaSpec := &ast.TiFlashReplicaSpec{ Count: yyS[yypt-1].item.(uint64), @@ -13579,19 +13995,19 @@ yynewstate: TiFlashReplica: tiflashReplicaSpec, } } - case 352: + case 369: { parser.yyVAL.item = []*ast.DatabaseOption{} } - case 354: + case 371: { parser.yyVAL.item = []*ast.DatabaseOption{yyS[yypt-0].item.(*ast.DatabaseOption)} } - case 355: + case 372: { parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.DatabaseOption), yyS[yypt-0].item.(*ast.DatabaseOption)) } - case 356: + case 373: { stmt := yyS[yypt-6].item.(*ast.CreateTableStmt) stmt.Table = yyS[yypt-7].item.(*ast.TableName) @@ -13612,7 +14028,7 @@ yynewstate: } parser.yyVAL.statement = stmt } - case 357: + case 374: { tmp := &ast.CreateTableStmt{ Table: yyS[yypt-2].item.(*ast.TableName), @@ -13629,23 +14045,23 @@ yynewstate: } parser.yyVAL.statement = tmp } - case 358: + case 375: { parser.yyVAL.item = nil } - case 359: + case 376: { parser.yyVAL.item = true } - case 360: + case 377: { parser.yyVAL.item = false } - case 363: + case 380: { parser.yyVAL.item = nil } - case 364: + case 381: { method := yyS[yypt-3].item.(*ast.PartitionMethod) method.Num = yyS[yypt-2].item.(uint64) @@ -13662,7 +14078,7 @@ yynewstate: } parser.yyVAL.item = opt } - case 365: + case 382: { keyAlgorithm, _ := yyS[yypt-3].item.(*ast.PartitionKeyAlgorithm) parser.yyVAL.item = &ast.PartitionMethod{ @@ -13672,7 +14088,7 @@ yynewstate: KeyAlgorithm: keyAlgorithm, } } - case 366: + case 383: { parser.yyVAL.item = &ast.PartitionMethod{ Tp: model.PartitionTypeHash, @@ -13680,11 +14096,11 @@ yynewstate: Expr: yyS[yypt-1].expr.(ast.ExprNode), } } - case 367: + case 384: { parser.yyVAL.item = nil } - case 368: + case 385: { tp := getUint64FromNUM(yyS[yypt-0].item) if tp != 1 && tp != 2 { @@ -13695,7 +14111,7 @@ yynewstate: Type: tp, } } - case 370: + case 387: { partitionInterval, _ := yyS[yypt-0].item.(*ast.PartitionInterval) parser.yyVAL.item = &ast.PartitionMethod{ @@ -13704,7 +14120,7 @@ yynewstate: Interval: partitionInterval, } } - case 371: + case 388: { partitionInterval, _ := yyS[yypt-0].item.(*ast.PartitionInterval) parser.yyVAL.item = &ast.PartitionMethod{ @@ -13713,21 +14129,21 @@ yynewstate: Interval: partitionInterval, } } - case 372: + case 389: { parser.yyVAL.item = &ast.PartitionMethod{ Tp: model.PartitionTypeList, Expr: yyS[yypt-1].expr.(ast.ExprNode), } } - case 373: + case 390: { parser.yyVAL.item = &ast.PartitionMethod{ Tp: model.PartitionTypeList, ColumnNames: yyS[yypt-1].item.([]*ast.ColumnName), } } - case 374: + case 391: { parser.yyVAL.item = &ast.PartitionMethod{ Tp: model.PartitionTypeSystemTime, @@ -13735,24 +14151,24 @@ yynewstate: Unit: yyS[yypt-0].item.(ast.TimeUnitType), } } - case 375: + case 392: { parser.yyVAL.item = &ast.PartitionMethod{ Tp: model.PartitionTypeSystemTime, Limit: yyS[yypt-0].item.(uint64), } } - case 376: + case 393: { parser.yyVAL.item = &ast.PartitionMethod{ Tp: model.PartitionTypeSystemTime, } } - case 377: + case 394: { parser.yyVAL.item = nil } - case 378: + case 395: { partitionInterval := &ast.PartitionInterval{ IntervalExpr: yyS[yypt-4].item.(ast.PartitionIntervalExpr), @@ -13768,35 +14184,35 @@ yynewstate: partitionInterval.SetOriginTextPosition(startOffset) parser.yyVAL.item = partitionInterval } - case 379: + case 396: { parser.yyVAL.item = ast.PartitionIntervalExpr{Expr: yyS[yypt-0].expr, TimeUnit: ast.TimeUnitInvalid} } - case 380: + case 397: { parser.yyVAL.item = ast.PartitionIntervalExpr{Expr: yyS[yypt-1].expr, TimeUnit: yyS[yypt-0].item.(ast.TimeUnitType)} } - case 381: + case 398: { parser.yyVAL.item = false } - case 382: + case 399: { parser.yyVAL.item = true } - case 383: + case 400: { parser.yyVAL.item = false } - case 384: + case 401: { parser.yyVAL.item = true } - case 385: + case 402: { parser.yyVAL.item = ast.PartitionInterval{} // First/LastRangeEnd defaults to nil } - case 386: + case 403: { first := yyS[yypt-8].expr.(ast.ExprNode) last := yyS[yypt-1].expr.(ast.ExprNode) @@ -13805,25 +14221,25 @@ yynewstate: LastRangeEnd: &last, } } - case 387: + case 404: { parser.yyVAL.ident = "" } - case 389: + case 406: { parser.yyVAL.item = nil } - case 390: + case 407: { method := yyS[yypt-1].item.(*ast.PartitionMethod) method.Num = yyS[yypt-0].item.(uint64) parser.yyVAL.item = method } - case 391: + case 408: { parser.yyVAL.item = uint64(0) } - case 392: + case 409: { res := yyS[yypt-0].item.(uint64) if res == 0 { @@ -13832,11 +14248,11 @@ yynewstate: } parser.yyVAL.item = res } - case 393: + case 410: { parser.yyVAL.item = uint64(0) } - case 394: + case 411: { res := yyS[yypt-0].item.(uint64) if res == 0 { @@ -13845,23 +14261,23 @@ yynewstate: } parser.yyVAL.item = res } - case 395: + case 412: { parser.yyVAL.item = nil } - case 396: + case 413: { parser.yyVAL.item = yyS[yypt-1].item.([]*ast.PartitionDefinition) } - case 397: + case 414: { parser.yyVAL.item = []*ast.PartitionDefinition{yyS[yypt-0].item.(*ast.PartitionDefinition)} } - case 398: + case 415: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.PartitionDefinition), yyS[yypt-0].item.(*ast.PartitionDefinition)) } - case 399: + case 416: { parser.yyVAL.item = &ast.PartitionDefinition{ Name: model.NewCIStr(yyS[yypt-3].ident), @@ -13870,80 +14286,80 @@ yynewstate: Sub: yyS[yypt-0].item.([]*ast.SubPartitionDefinition), } } - case 400: + case 417: { parser.yyVAL.item = make([]*ast.SubPartitionDefinition, 0) } - case 401: + case 418: { parser.yyVAL.item = yyS[yypt-1].item } - case 402: + case 419: { parser.yyVAL.item = []*ast.SubPartitionDefinition{yyS[yypt-0].item.(*ast.SubPartitionDefinition)} } - case 403: + case 420: { list := yyS[yypt-2].item.([]*ast.SubPartitionDefinition) parser.yyVAL.item = append(list, yyS[yypt-0].item.(*ast.SubPartitionDefinition)) } - case 404: + case 421: { parser.yyVAL.item = &ast.SubPartitionDefinition{ Name: model.NewCIStr(yyS[yypt-1].ident), Options: yyS[yypt-0].item.([]*ast.TableOption), } } - case 405: + case 422: { parser.yyVAL.item = make([]*ast.TableOption, 0) } - case 406: + case 423: { list := yyS[yypt-1].item.([]*ast.TableOption) parser.yyVAL.item = append(list, yyS[yypt-0].item.(*ast.TableOption)) } - case 407: + case 424: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionComment, StrValue: yyS[yypt-0].ident} } - case 408: + case 425: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: yyS[yypt-0].ident} } - case 409: + case 426: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: yyS[yypt-0].ident} } - case 410: + case 427: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionInsertMethod, StrValue: yyS[yypt-0].ident} } - case 411: + case 428: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionDataDirectory, StrValue: yyS[yypt-0].ident} } - case 412: + case 429: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionIndexDirectory, StrValue: yyS[yypt-0].ident} } - case 413: + case 430: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionMaxRows, UintValue: yyS[yypt-0].item.(uint64)} } - case 414: + case 431: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionMinRows, UintValue: yyS[yypt-0].item.(uint64)} } - case 415: + case 432: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionTablespace, StrValue: yyS[yypt-0].ident} } - case 416: + case 433: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionNodegroup, UintValue: yyS[yypt-0].item.(uint64)} } - case 417: + case 434: { placementOptions := yyS[yypt-0].item.(*ast.PlacementOption) parser.yyVAL.item = &ast.TableOption{ @@ -13953,27 +14369,27 @@ yynewstate: UintValue: placementOptions.UintValue, } } - case 418: + case 435: { parser.yyVAL.item = &ast.PartitionDefinitionClauseNone{} } - case 419: + case 436: { parser.yyVAL.item = &ast.PartitionDefinitionClauseLessThan{ Exprs: []ast.ExprNode{&ast.MaxValueExpr{}}, } } - case 420: + case 437: { parser.yyVAL.item = &ast.PartitionDefinitionClauseLessThan{ Exprs: yyS[yypt-1].item.([]ast.ExprNode), } } - case 421: + case 438: { parser.yyVAL.item = &ast.PartitionDefinitionClauseIn{} } - case 422: + case 439: { exprs := yyS[yypt-1].item.([]ast.ExprNode) values := make([][]ast.ExprNode, 0, len(exprs)) @@ -13986,43 +14402,43 @@ yynewstate: } parser.yyVAL.item = &ast.PartitionDefinitionClauseIn{Values: values} } - case 423: + case 440: { parser.yyVAL.item = &ast.PartitionDefinitionClauseHistory{Current: false} } - case 424: + case 441: { parser.yyVAL.item = &ast.PartitionDefinitionClauseHistory{Current: true} } - case 425: + case 442: { parser.yyVAL.item = ast.OnDuplicateKeyHandlingError } - case 426: + case 443: { parser.yyVAL.item = ast.OnDuplicateKeyHandlingIgnore } - case 427: + case 444: { parser.yyVAL.item = ast.OnDuplicateKeyHandlingReplace } - case 430: + case 447: { parser.yyVAL.item = &ast.CreateTableStmt{} } - case 431: + case 448: { parser.yyVAL.item = &ast.CreateTableStmt{Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 432: + case 449: { parser.yyVAL.item = &ast.CreateTableStmt{Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 433: + case 450: { parser.yyVAL.item = &ast.CreateTableStmt{Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 434: + case 451: { var sel ast.ResultSetNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -14035,7 +14451,7 @@ yynewstate: } parser.yyVAL.item = &ast.CreateTableStmt{Select: sel} } - case 438: + case 455: { var sel ast.StmtNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -14048,15 +14464,15 @@ yynewstate: } parser.yyVAL.statement = sel } - case 439: + case 456: { parser.yyVAL.item = yyS[yypt-0].item } - case 440: + case 457: { parser.yyVAL.item = yyS[yypt-1].item } - case 441: + case 458: { startOffset := parser.startOffset(&yyS[yypt-1]) selStmt := yyS[yypt-1].statement.(ast.StmtNode) @@ -14081,85 +14497,85 @@ yynewstate: } parser.yyVAL.statement = x } - case 442: + case 459: { parser.yyVAL.item = false } - case 443: + case 460: { parser.yyVAL.item = true } - case 444: + case 461: { parser.yyVAL.item = model.AlgorithmUndefined } - case 445: + case 462: { parser.yyVAL.item = model.AlgorithmUndefined } - case 446: + case 463: { parser.yyVAL.item = model.AlgorithmMerge } - case 447: + case 464: { parser.yyVAL.item = model.AlgorithmTemptable } - case 448: + case 465: { parser.yyVAL.item = &auth.UserIdentity{CurrentUser: true} } - case 449: + case 466: { parser.yyVAL.item = yyS[yypt-0].item } - case 450: + case 467: { parser.yyVAL.item = model.SecurityDefiner } - case 451: + case 468: { parser.yyVAL.item = model.SecurityDefiner } - case 452: + case 469: { parser.yyVAL.item = model.SecurityInvoker } - case 454: + case 471: { parser.yyVAL.item = nil } - case 455: + case 472: { parser.yyVAL.item = yyS[yypt-1].item.([]model.CIStr) } - case 456: + case 473: { parser.yyVAL.item = []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)} } - case 457: + case 474: { parser.yyVAL.item = append(yyS[yypt-2].item.([]model.CIStr), model.NewCIStr(yyS[yypt-0].ident)) } - case 458: + case 475: { parser.yyVAL.item = nil } - case 459: + case 476: { parser.yyVAL.item = model.CheckOptionCascaded } - case 460: + case 477: { parser.yyVAL.item = model.CheckOptionLocal } - case 461: + case 478: { parser.yyVAL.statement = &ast.DoStmt{ Exprs: yyS[yypt-0].item.([]ast.ExprNode), } } - case 462: + case 479: { // Single Table tn := yyS[yypt-6].item.(*ast.TableName) @@ -14187,7 +14603,7 @@ yynewstate: parser.yyVAL.statement = x } - case 463: + case 480: { // Multiple Table x := &ast.DeleteStmt{ @@ -14207,7 +14623,7 @@ yynewstate: } parser.yyVAL.statement = x } - case 464: + case 481: { // Multiple Table x := &ast.DeleteStmt{ @@ -14226,23 +14642,23 @@ yynewstate: } parser.yyVAL.statement = x } - case 467: + case 484: { d := yyS[yypt-0].statement.(*ast.DeleteStmt) d.With = yyS[yypt-1].item.(*ast.WithClause) parser.yyVAL.statement = d } - case 468: + case 485: { d := yyS[yypt-0].statement.(*ast.DeleteStmt) d.With = yyS[yypt-1].item.(*ast.WithClause) parser.yyVAL.statement = d } - case 470: + case 487: { parser.yyVAL.statement = &ast.DropDatabaseStmt{IfExists: yyS[yypt-1].item.(bool), Name: model.NewCIStr(yyS[yypt-0].ident)} } - case 471: + case 488: { var indexLockAndAlgorithm *ast.IndexLockAndAlgorithm if yyS[yypt-0].item != nil { @@ -14253,39 +14669,39 @@ yynewstate: } parser.yyVAL.statement = &ast.DropIndexStmt{IfExists: yyS[yypt-4].item.(bool), IndexName: yyS[yypt-3].ident, Table: yyS[yypt-1].item.(*ast.TableName), LockAlg: indexLockAndAlgorithm} } - case 472: + case 489: { parser.yyVAL.statement = &ast.DropTableStmt{IfExists: yyS[yypt-2].item.(bool), Tables: yyS[yypt-1].item.([]*ast.TableName), IsView: false, TemporaryKeyword: yyS[yypt-4].item.(ast.TemporaryKeyword)} } - case 473: + case 490: { parser.yyVAL.item = ast.TemporaryNone } - case 474: + case 491: { parser.yyVAL.item = ast.TemporaryLocal } - case 475: + case 492: { parser.yyVAL.item = ast.TemporaryGlobal } - case 476: + case 493: { parser.yyVAL.statement = &ast.DropTableStmt{Tables: yyS[yypt-1].item.([]*ast.TableName), IsView: true} } - case 477: + case 494: { parser.yyVAL.statement = &ast.DropTableStmt{IfExists: true, Tables: yyS[yypt-1].item.([]*ast.TableName), IsView: true} } - case 478: + case 495: { parser.yyVAL.statement = &ast.DropUserStmt{IsDropRole: false, IfExists: false, UserList: yyS[yypt-0].item.([]*auth.UserIdentity)} } - case 479: + case 496: { parser.yyVAL.statement = &ast.DropUserStmt{IsDropRole: false, IfExists: true, UserList: yyS[yypt-0].item.([]*auth.UserIdentity)} } - case 480: + case 497: { tmp := make([]*auth.UserIdentity, 0, 10) roleList := yyS[yypt-0].item.([]*auth.RoleIdentity) @@ -14294,7 +14710,7 @@ yynewstate: } parser.yyVAL.statement = &ast.DropUserStmt{IsDropRole: true, IfExists: false, UserList: tmp} } - case 481: + case 498: { tmp := make([]*auth.UserIdentity, 0, 10) roleList := yyS[yypt-0].item.([]*auth.RoleIdentity) @@ -14303,29 +14719,33 @@ yynewstate: } parser.yyVAL.statement = &ast.DropUserStmt{IsDropRole: true, IfExists: true, UserList: tmp} } - case 482: + case 499: { - parser.yyVAL.statement = &ast.DropStatsStmt{Table: yyS[yypt-0].item.(*ast.TableName)} + parser.yyVAL.statement = &ast.DropStatsStmt{Tables: yyS[yypt-0].item.([]*ast.TableName)} } - case 483: + case 500: { + yylex.AppendError(ErrWarnDeprecatedSyntaxNoReplacement.FastGenByArgs("DROP STATS ... PARTITION ...")) + parser.lastErrorAsWarn() parser.yyVAL.statement = &ast.DropStatsStmt{ - Table: yyS[yypt-2].item.(*ast.TableName), + Tables: []*ast.TableName{yyS[yypt-2].item.(*ast.TableName)}, PartitionNames: yyS[yypt-0].item.([]model.CIStr), } } - case 484: + case 501: { + yylex.AppendError(ErrWarnDeprecatedSyntax.FastGenByArgs("DROP STATS ... GLOBAL", "DROP STATS ...")) + parser.lastErrorAsWarn() parser.yyVAL.statement = &ast.DropStatsStmt{ - Table: yyS[yypt-1].item.(*ast.TableName), + Tables: []*ast.TableName{yyS[yypt-1].item.(*ast.TableName)}, IsGlobalStats: true, } } - case 492: + case 509: { parser.yyVAL.statement = nil } - case 493: + case 510: { parser.yyVAL.statement = &ast.TraceStmt{ Stmt: yyS[yypt-0].statement, @@ -14335,7 +14755,7 @@ yynewstate: startOffset := parser.startOffset(&yyS[yypt]) yyS[yypt-0].statement.SetText(parser.lexer.client, string(parser.src[startOffset:])) } - case 494: + case 511: { parser.yyVAL.statement = &ast.TraceStmt{ Stmt: yyS[yypt-0].statement, @@ -14345,7 +14765,7 @@ yynewstate: startOffset := parser.startOffset(&yyS[yypt]) yyS[yypt-0].statement.SetText(parser.lexer.client, string(parser.src[startOffset:])) } - case 495: + case 512: { parser.yyVAL.statement = &ast.TraceStmt{ Stmt: yyS[yypt-0].statement, @@ -14354,7 +14774,7 @@ yynewstate: startOffset := parser.startOffset(&yyS[yypt]) yyS[yypt-0].statement.SetText(parser.lexer.client, string(parser.src[startOffset:])) } - case 496: + case 513: { parser.yyVAL.statement = &ast.TraceStmt{ Stmt: yyS[yypt-0].statement, @@ -14364,7 +14784,7 @@ yynewstate: startOffset := parser.startOffset(&yyS[yypt]) yyS[yypt-0].statement.SetText(parser.lexer.client, string(parser.src[startOffset:])) } - case 500: + case 517: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: &ast.ShowStmt{ @@ -14373,7 +14793,7 @@ yynewstate: }, } } - case 501: + case 518: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: &ast.ShowStmt{ @@ -14383,49 +14803,49 @@ yynewstate: }, } } - case 502: + case 519: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: yyS[yypt-0].statement, Format: "row", } } - case 503: + case 520: { parser.yyVAL.statement = &ast.ExplainForStmt{ Format: "row", ConnectionID: getUint64FromNUM(yyS[yypt-0].item), } } - case 504: + case 521: { parser.yyVAL.statement = &ast.ExplainForStmt{ Format: yyS[yypt-3].ident, ConnectionID: getUint64FromNUM(yyS[yypt-0].item), } } - case 505: + case 522: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: yyS[yypt-0].statement, Format: yyS[yypt-1].ident, } } - case 506: + case 523: { parser.yyVAL.statement = &ast.ExplainForStmt{ Format: yyS[yypt-3].ident, ConnectionID: getUint64FromNUM(yyS[yypt-0].item), } } - case 507: + case 524: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: yyS[yypt-0].statement, Format: yyS[yypt-1].ident, } } - case 508: + case 525: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: yyS[yypt-0].statement, @@ -14433,7 +14853,7 @@ yynewstate: Analyze: true, } } - case 509: + case 526: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: yyS[yypt-0].statement, @@ -14441,7 +14861,7 @@ yynewstate: Analyze: true, } } - case 510: + case 527: { parser.yyVAL.statement = &ast.ExplainStmt{ Stmt: yyS[yypt-0].statement, @@ -14449,15 +14869,15 @@ yynewstate: Analyze: true, } } - case 518: + case 536: { parser.yyVAL.statement = &ast.SavepointStmt{Name: yyS[yypt-0].ident} } - case 519: + case 537: { parser.yyVAL.statement = &ast.ReleaseSavepointStmt{Name: yyS[yypt-0].ident} } - case 520: + case 538: { stmt := yyS[yypt-3].item.(*ast.BRIEStmt) stmt.Kind = ast.BRIEKindBackup @@ -14465,7 +14885,7 @@ yynewstate: stmt.Options = yyS[yypt-0].item.([]*ast.BRIEOption) parser.yyVAL.statement = stmt } - case 521: + case 539: { stmt := yyS[yypt-3].item.(*ast.BRIEStmt) stmt.Kind = ast.BRIEKindRestore @@ -14473,110 +14893,110 @@ yynewstate: stmt.Options = yyS[yypt-0].item.([]*ast.BRIEOption) parser.yyVAL.statement = stmt } - case 522: + case 540: { parser.yyVAL.item = &ast.BRIEStmt{} } - case 523: + case 541: { parser.yyVAL.item = &ast.BRIEStmt{Schemas: yyS[yypt-0].item.([]string)} } - case 524: + case 542: { parser.yyVAL.item = &ast.BRIEStmt{Tables: yyS[yypt-0].item.([]*ast.TableName)} } - case 525: + case 543: { parser.yyVAL.item = []string{yyS[yypt-0].ident} } - case 526: + case 544: { parser.yyVAL.item = append(yyS[yypt-2].item.([]string), yyS[yypt-0].ident) } - case 527: + case 545: { parser.yyVAL.item = []*ast.BRIEOption{} } - case 528: + case 546: { parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.BRIEOption), yyS[yypt-0].item.(*ast.BRIEOption)) } - case 529: + case 547: { parser.yyVAL.item = ast.BRIEOptionConcurrency } - case 530: + case 548: { parser.yyVAL.item = ast.BRIEOptionResume } - case 531: + case 549: { parser.yyVAL.item = ast.BRIEOptionSendCreds } - case 532: + case 550: { parser.yyVAL.item = ast.BRIEOptionOnline } - case 533: + case 551: { parser.yyVAL.item = ast.BRIEOptionCheckpoint } - case 534: + case 552: { parser.yyVAL.item = ast.BRIEOptionSkipSchemaFiles } - case 535: + case 553: { parser.yyVAL.item = ast.BRIEOptionStrictFormat } - case 536: + case 554: { parser.yyVAL.item = ast.BRIEOptionCSVNotNull } - case 537: + case 555: { parser.yyVAL.item = ast.BRIEOptionCSVBackslashEscape } - case 538: + case 556: { parser.yyVAL.item = ast.BRIEOptionCSVTrimLastSeparators } - case 539: + case 557: { parser.yyVAL.item = ast.BRIEOptionTiKVImporter } - case 540: + case 558: { parser.yyVAL.item = ast.BRIEOptionCSVSeparator } - case 541: + case 559: { parser.yyVAL.item = ast.BRIEOptionCSVDelimiter } - case 542: + case 560: { parser.yyVAL.item = ast.BRIEOptionCSVNull } - case 543: + case 561: { parser.yyVAL.item = ast.BRIEOptionBackend } - case 544: + case 562: { parser.yyVAL.item = ast.BRIEOptionOnDuplicate } - case 545: + case 563: { parser.yyVAL.item = ast.BRIEOptionOnDuplicate } - case 546: + case 564: { parser.yyVAL.item = &ast.BRIEOption{ Tp: yyS[yypt-2].item.(ast.BRIEOptionType), UintValue: yyS[yypt-0].item.(uint64), } } - case 547: + case 565: { value := uint64(0) if yyS[yypt-0].item.(bool) { @@ -14587,21 +15007,21 @@ yynewstate: UintValue: value, } } - case 548: + case 566: { parser.yyVAL.item = &ast.BRIEOption{ Tp: yyS[yypt-2].item.(ast.BRIEOptionType), StrValue: yyS[yypt-0].ident, } } - case 549: + case 567: { parser.yyVAL.item = &ast.BRIEOption{ Tp: yyS[yypt-2].item.(ast.BRIEOptionType), StrValue: strings.ToLower(yyS[yypt-0].ident), } } - case 550: + case 568: { unit, err := yyS[yypt-1].item.(ast.TimeUnitType).Duration() if err != nil { @@ -14614,35 +15034,35 @@ yynewstate: UintValue: yyS[yypt-2].item.(uint64) * uint64(unit), } } - case 551: + case 569: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionBackupTS, StrValue: yyS[yypt-0].ident, } } - case 552: + case 570: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionBackupTSO, UintValue: yyS[yypt-0].item.(uint64), } } - case 553: + case 571: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionLastBackupTS, StrValue: yyS[yypt-0].ident, } } - case 554: + case 572: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionLastBackupTSO, UintValue: yyS[yypt-0].item.(uint64), } } - case 555: + case 573: { // TODO: check overflow? parser.yyVAL.item = &ast.BRIEOption{ @@ -14650,21 +15070,21 @@ yynewstate: UintValue: yyS[yypt-3].item.(uint64) * 1048576, } } - case 556: + case 574: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionCSVHeader, UintValue: ast.BRIECSVHeaderIsColumns, } } - case 557: + case 575: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionCSVHeader, UintValue: yyS[yypt-0].item.(uint64), } } - case 558: + case 576: { value := uint64(0) if yyS[yypt-0].item.(bool) { @@ -14675,14 +15095,14 @@ yynewstate: UintValue: value, } } - case 559: + case 577: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionChecksum, UintValue: uint64(yyS[yypt-0].item.(ast.BRIEOptionLevel)), } } - case 560: + case 578: { value := uint64(0) if yyS[yypt-0].item.(bool) { @@ -14693,18 +15113,18 @@ yynewstate: UintValue: value, } } - case 561: + case 579: { parser.yyVAL.item = &ast.BRIEOption{ Tp: ast.BRIEOptionAnalyze, UintValue: uint64(yyS[yypt-0].item.(ast.BRIEOptionLevel)), } } - case 562: + case 580: { parser.yyVAL.item = getUint64FromNUM(yyS[yypt-0].item) } - case 563: + case 581: { v, rangeErrMsg := getInt64FromNUM(yyS[yypt-0].item) if len(rangeErrMsg) != 0 { @@ -14713,35 +15133,35 @@ yynewstate: } parser.yyVAL.item = v } - case 565: + case 583: { parser.yyVAL.item = yyS[yypt-0].item.(int64) != 0 } - case 566: + case 584: { parser.yyVAL.item = false } - case 567: + case 585: { parser.yyVAL.item = true } - case 568: + case 586: { parser.yyVAL.item = ast.BRIEOptionLevelOff } - case 569: + case 587: { parser.yyVAL.item = ast.BRIEOptionLevelOptional } - case 570: + case 588: { parser.yyVAL.item = ast.BRIEOptionLevelRequired } - case 571: + case 589: { parser.yyVAL.statement = &ast.PurgeImportStmt{TaskID: getUint64FromNUM(yyS[yypt-0].item)} } - case 572: + case 590: { parser.yyVAL.statement = &ast.CreateImportStmt{ IfNotExists: yyS[yypt-5].item.(bool), @@ -14751,21 +15171,21 @@ yynewstate: Options: yyS[yypt-0].item.([]*ast.BRIEOption), } } - case 573: + case 591: { parser.yyVAL.statement = &ast.StopImportStmt{ IfRunning: yyS[yypt-1].item.(bool), Name: yyS[yypt-0].ident, } } - case 574: + case 592: { parser.yyVAL.statement = &ast.ResumeImportStmt{ IfNotRunning: yyS[yypt-1].item.(bool), Name: yyS[yypt-0].ident, } } - case 575: + case 593: { s := &ast.AlterImportStmt{ Name: yyS[yypt-3].ident, @@ -14777,14 +15197,14 @@ yynewstate: } parser.yyVAL.statement = s } - case 576: + case 594: { parser.yyVAL.statement = &ast.DropImportStmt{ IfExists: yyS[yypt-1].item.(bool), Name: yyS[yypt-0].ident, } } - case 577: + case 595: { parser.yyVAL.statement = &ast.ShowImportStmt{ Name: yyS[yypt-2].ident, @@ -14792,73 +15212,73 @@ yynewstate: TableNames: yyS[yypt-0].item.([]*ast.TableName), } } - case 578: + case 596: { parser.yyVAL.item = false } - case 579: + case 597: { parser.yyVAL.item = true } - case 580: + case 598: { parser.yyVAL.item = false } - case 581: + case 599: { parser.yyVAL.item = true } - case 582: + case 600: { parser.yyVAL.item = false } - case 583: + case 601: { parser.yyVAL.item = true } - case 584: + case 602: { parser.yyVAL.item = ast.ErrorHandleError } - case 585: + case 603: { parser.yyVAL.item = ast.ErrorHandleReplace } - case 586: + case 604: { parser.yyVAL.item = ast.ErrorHandleSkipAll } - case 587: + case 605: { parser.yyVAL.item = ast.ErrorHandleSkipConstraint } - case 588: + case 606: { parser.yyVAL.item = ast.ErrorHandleSkipDuplicate } - case 589: + case 607: { parser.yyVAL.item = ast.ErrorHandleSkipStrict } - case 590: + case 608: { parser.yyVAL.item = nil } - case 591: + case 609: { parser.yyVAL.item = &ast.ImportTruncate{ IsErrorsOnly: false, TableNames: yyS[yypt-0].item.([]*ast.TableName), } } - case 592: + case 610: { parser.yyVAL.item = &ast.ImportTruncate{ IsErrorsOnly: true, TableNames: yyS[yypt-0].item.([]*ast.TableName), } } - case 593: + case 611: { v := yyS[yypt-2].ident v = strings.TrimPrefix(v, "@") @@ -14869,19 +15289,19 @@ yynewstate: Value: yyS[yypt-0].expr, } } - case 594: + case 612: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.LogicOr, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 595: + case 613: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.LogicXor, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 596: + case 614: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.LogicAnd, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 597: + case 615: { expr, ok := yyS[yypt-0].expr.(*ast.ExistsSubqueryExpr) if ok { @@ -14891,7 +15311,7 @@ yynewstate: parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.Not, V: yyS[yypt-0].expr} } } - case 598: + case 616: { parser.yyVAL.expr = &ast.MatchAgainst{ ColumnNames: yyS[yypt-6].item.([]*ast.ColumnName), @@ -14899,87 +15319,87 @@ yynewstate: Modifier: ast.FulltextSearchModifier(yyS[yypt-1].item.(int)), } } - case 599: + case 617: { parser.yyVAL.expr = &ast.IsTruthExpr{Expr: yyS[yypt-2].expr, Not: !yyS[yypt-1].item.(bool), True: int64(1)} } - case 600: + case 618: { parser.yyVAL.expr = &ast.IsTruthExpr{Expr: yyS[yypt-2].expr, Not: !yyS[yypt-1].item.(bool), True: int64(0)} } - case 601: + case 619: { /* https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is */ parser.yyVAL.expr = &ast.IsNullExpr{Expr: yyS[yypt-2].expr, Not: !yyS[yypt-1].item.(bool)} } - case 603: + case 621: { parser.yyVAL.expr = &ast.MaxValueExpr{} } - case 605: + case 623: { parser.yyVAL.item = ast.FulltextSearchModifierNaturalLanguageMode } - case 606: + case 624: { parser.yyVAL.item = ast.FulltextSearchModifierNaturalLanguageMode } - case 607: + case 625: { parser.yyVAL.item = ast.FulltextSearchModifierNaturalLanguageMode | ast.FulltextSearchModifierWithQueryExpansion } - case 608: + case 626: { parser.yyVAL.item = ast.FulltextSearchModifierBooleanMode } - case 609: + case 627: { parser.yyVAL.item = ast.FulltextSearchModifierWithQueryExpansion } - case 614: + case 632: { parser.yyVAL.item = []ast.ExprNode{yyS[yypt-0].expr} } - case 615: + case 633: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.ExprNode), yyS[yypt-0].expr) } - case 616: + case 634: { parser.yyVAL.item = []ast.ExprNode{yyS[yypt-0].expr} } - case 617: + case 635: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.ExprNode), yyS[yypt-0].expr) } - case 618: + case 636: { parser.yyVAL.item = []ast.ExprNode{} } - case 620: + case 638: { parser.yyVAL.item = []ast.ExprNode{} } - case 622: + case 640: { expr := ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation) parser.yyVAL.item = []ast.ExprNode{expr} } - case 623: + case 641: { parser.yyVAL.expr = &ast.IsNullExpr{Expr: yyS[yypt-2].expr, Not: !yyS[yypt-1].item.(bool)} } - case 624: + case 642: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: yyS[yypt-1].item.(opcode.Op), L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 625: + case 643: { sq := yyS[yypt-0].expr.(*ast.SubqueryExpr) sq.MultiRows = true parser.yyVAL.expr = &ast.CompareSubqueryExpr{Op: yyS[yypt-2].item.(opcode.Op), L: yyS[yypt-3].expr, R: sq, All: yyS[yypt-1].item.(bool)} } - case 626: + case 644: { v := yyS[yypt-2].ident v = strings.TrimPrefix(v, "@") @@ -14991,101 +15411,101 @@ yynewstate: } parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: yyS[yypt-3].item.(opcode.Op), L: yyS[yypt-4].expr, R: variable} } - case 628: + case 646: { parser.yyVAL.item = opcode.GE } - case 629: + case 647: { parser.yyVAL.item = opcode.GT } - case 630: + case 648: { parser.yyVAL.item = opcode.LE } - case 631: + case 649: { parser.yyVAL.item = opcode.LT } - case 632: + case 650: { parser.yyVAL.item = opcode.NE } - case 633: + case 651: { parser.yyVAL.item = opcode.NE } - case 634: + case 652: { parser.yyVAL.item = opcode.EQ } - case 635: + case 653: { parser.yyVAL.item = opcode.NullEQ } - case 636: + case 654: { parser.yyVAL.item = true } - case 637: + case 655: { parser.yyVAL.item = false } - case 638: + case 656: { parser.yyVAL.item = true } - case 639: + case 657: { parser.yyVAL.item = false } - case 640: + case 658: { parser.yyVAL.item = true } - case 641: + case 659: { parser.yyVAL.item = false } - case 642: + case 660: { parser.yyVAL.item = true } - case 643: + case 661: { parser.yyVAL.item = false } - case 644: + case 662: { parser.yyVAL.item = true } - case 645: + case 663: { parser.yyVAL.item = false } - case 646: + case 664: { parser.yyVAL.item = false } - case 647: + case 665: { parser.yyVAL.item = false } - case 648: + case 666: { parser.yyVAL.item = true } - case 649: + case 667: { parser.yyVAL.expr = &ast.PatternInExpr{Expr: yyS[yypt-4].expr, Not: !yyS[yypt-3].item.(bool), List: yyS[yypt-1].item.([]ast.ExprNode)} } - case 650: + case 668: { sq := yyS[yypt-0].expr.(*ast.SubqueryExpr) sq.MultiRows = true parser.yyVAL.expr = &ast.PatternInExpr{Expr: yyS[yypt-2].expr, Not: !yyS[yypt-1].item.(bool), Sel: sq} } - case 651: + case 669: { parser.yyVAL.expr = &ast.BetweenExpr{ Expr: yyS[yypt-4].expr, @@ -15094,7 +15514,7 @@ yynewstate: Not: !yyS[yypt-3].item.(bool), } } - case 652: + case 670: { escape := yyS[yypt-0].ident if len(escape) > 1 { @@ -15110,57 +15530,61 @@ yynewstate: Escape: escape[0], } } - case 653: + case 671: { parser.yyVAL.expr = &ast.PatternRegexpExpr{Expr: yyS[yypt-2].expr, Pattern: yyS[yypt-0].expr, Not: !yyS[yypt-1].item.(bool)} } - case 657: + case 672: + { + parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONMemberOf), Args: []ast.ExprNode{yyS[yypt-4].expr, yyS[yypt-1].expr}} + } + case 676: { parser.yyVAL.ident = "\\" } - case 658: + case 677: { parser.yyVAL.ident = yyS[yypt-0].ident } - case 659: + case 678: { parser.yyVAL.item = &ast.SelectField{WildCard: &ast.WildCardField{}} } - case 660: + case 679: { wildCard := &ast.WildCardField{Table: model.NewCIStr(yyS[yypt-2].ident)} parser.yyVAL.item = &ast.SelectField{WildCard: wildCard} } - case 661: + case 680: { wildCard := &ast.WildCardField{Schema: model.NewCIStr(yyS[yypt-4].ident), Table: model.NewCIStr(yyS[yypt-2].ident)} parser.yyVAL.item = &ast.SelectField{WildCard: wildCard} } - case 662: + case 681: { expr := yyS[yypt-1].expr asName := yyS[yypt-0].ident parser.yyVAL.item = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)} } - case 663: + case 682: { parser.yyVAL.ident = "" } - case 666: + case 685: { parser.yyVAL.ident = yyS[yypt-0].ident } - case 668: + case 687: { parser.yyVAL.ident = yyS[yypt-0].ident } - case 669: + case 688: { field := yyS[yypt-0].item.(*ast.SelectField) field.Offset = parser.startOffset(&yyS[yypt]) parser.yyVAL.item = []*ast.SelectField{field} } - case 670: + case 689: { fl := yyS[yypt-2].item.([]*ast.SelectField) last := fl[len(fl)-1] @@ -15172,71 +15596,71 @@ yynewstate: newField.Offset = parser.startOffset(&yyS[yypt]) parser.yyVAL.item = append(fl, newField) } - case 671: + case 690: { parser.yyVAL.item = &ast.GroupByClause{Items: yyS[yypt-0].item.([]*ast.ByItem)} } - case 672: + case 691: { parser.yyVAL.item = nil } - case 673: + case 692: { parser.yyVAL.item = &ast.HavingClause{Expr: yyS[yypt-0].expr} } - case 674: + case 693: { parser.yyVAL.item = nil } - case 676: + case 695: { parser.yyVAL.item = &ast.AsOfClause{ TsExpr: yyS[yypt-0].expr.(ast.ExprNode), } } - case 677: + case 696: { parser.yyVAL.item = false } - case 678: + case 697: { parser.yyVAL.item = true } - case 679: + case 698: { parser.yyVAL.item = false } - case 680: + case 699: { parser.yyVAL.item = true } - case 681: + case 700: { parser.yyVAL.item = false } - case 682: + case 701: { parser.yyVAL.item = true } - case 683: + case 702: { parser.yyVAL.item = &ast.NullString{ String: "", Empty: false, } } - case 684: + case 703: { parser.yyVAL.item = &ast.NullString{ String: yyS[yypt-0].ident, Empty: len(yyS[yypt-0].ident) == 0, } } - case 685: + case 704: { parser.yyVAL.item = nil } - case 686: + case 705: { // Merge the options if yyS[yypt-1].item == nil { @@ -15260,19 +15684,19 @@ yynewstate: parser.yyVAL.item = opt1 } } - case 687: + case 706: { parser.yyVAL.item = &ast.IndexOption{ KeyBlockSize: yyS[yypt-0].item.(uint64), } } - case 688: + case 707: { parser.yyVAL.item = &ast.IndexOption{ Tp: yyS[yypt-0].item.(model.IndexType), } } - case 689: + case 708: { parser.yyVAL.item = &ast.IndexOption{ ParserName: model.NewCIStr(yyS[yypt-0].ident), @@ -15280,75 +15704,75 @@ yynewstate: yylex.AppendError(yylex.Errorf("The WITH PARASER clause is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 690: + case 709: { parser.yyVAL.item = &ast.IndexOption{ Comment: yyS[yypt-0].ident, } } - case 691: + case 710: { parser.yyVAL.item = &ast.IndexOption{ Visibility: yyS[yypt-0].item.(ast.IndexVisibility), } } - case 692: + case 711: { parser.yyVAL.item = &ast.IndexOption{ PrimaryKeyTp: yyS[yypt-0].item.(model.PrimaryKeyType), } } - case 693: + case 712: { parser.yyVAL.item = []interface{}{yyS[yypt-0].item, nil} } - case 694: + case 713: { parser.yyVAL.item = []interface{}{yyS[yypt-2].item, yyS[yypt-0].item} } - case 695: + case 714: { parser.yyVAL.item = []interface{}{&ast.NullString{String: yyS[yypt-2].ident, Empty: len(yyS[yypt-2].ident) == 0}, yyS[yypt-0].item} } - case 696: + case 715: { parser.yyVAL.item = nil } - case 698: + case 717: { parser.yyVAL.item = yyS[yypt-0].item } - case 699: + case 718: { parser.yyVAL.item = yyS[yypt-0].item } - case 700: + case 719: { parser.yyVAL.item = model.IndexTypeBtree } - case 701: + case 720: { parser.yyVAL.item = model.IndexTypeHash } - case 702: + case 721: { parser.yyVAL.item = model.IndexTypeRtree } - case 703: + case 722: { parser.yyVAL.item = ast.IndexVisibilityVisible } - case 704: + case 723: { parser.yyVAL.item = ast.IndexVisibilityInvisible } - case 1176: + case 1214: { parser.yyVAL.statement = &ast.CallStmt{ Procedure: yyS[yypt-0].expr.(*ast.FuncCallExpr), } } - case 1177: + case 1215: { parser.yyVAL.expr = &ast.FuncCallExpr{ Tp: ast.FuncCallExprTypeGeneric, @@ -15356,7 +15780,7 @@ yynewstate: Args: []ast.ExprNode{}, } } - case 1178: + case 1216: { parser.yyVAL.expr = &ast.FuncCallExpr{ Tp: ast.FuncCallExprTypeGeneric, @@ -15365,7 +15789,7 @@ yynewstate: Args: []ast.ExprNode{}, } } - case 1179: + case 1217: { parser.yyVAL.expr = &ast.FuncCallExpr{ Tp: ast.FuncCallExprTypeGeneric, @@ -15373,7 +15797,7 @@ yynewstate: Args: yyS[yypt-1].item.([]ast.ExprNode), } } - case 1180: + case 1218: { parser.yyVAL.expr = &ast.FuncCallExpr{ Tp: ast.FuncCallExprTypeGeneric, @@ -15382,7 +15806,7 @@ yynewstate: Args: yyS[yypt-1].item.([]ast.ExprNode), } } - case 1181: + case 1219: { x := yyS[yypt-1].item.(*ast.InsertStmt) x.Priority = yyS[yypt-6].item.(mysql.PriorityEnum) @@ -15399,26 +15823,26 @@ yynewstate: x.PartitionNames = yyS[yypt-2].item.([]model.CIStr) parser.yyVAL.statement = x } - case 1184: + case 1222: { parser.yyVAL.item = &ast.InsertStmt{ Columns: yyS[yypt-3].item.([]*ast.ColumnName), Lists: yyS[yypt-0].item.([][]ast.ExprNode), } } - case 1185: + case 1223: { parser.yyVAL.item = &ast.InsertStmt{Columns: yyS[yypt-2].item.([]*ast.ColumnName), Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 1186: + case 1224: { parser.yyVAL.item = &ast.InsertStmt{Columns: yyS[yypt-2].item.([]*ast.ColumnName), Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 1187: + case 1225: { parser.yyVAL.item = &ast.InsertStmt{Columns: yyS[yypt-2].item.([]*ast.ColumnName), Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 1188: + case 1226: { var sel ast.ResultSetNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -15431,23 +15855,23 @@ yynewstate: } parser.yyVAL.item = &ast.InsertStmt{Columns: yyS[yypt-2].item.([]*ast.ColumnName), Select: sel} } - case 1189: + case 1227: { parser.yyVAL.item = &ast.InsertStmt{Lists: yyS[yypt-0].item.([][]ast.ExprNode)} } - case 1190: + case 1228: { parser.yyVAL.item = &ast.InsertStmt{Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 1191: + case 1229: { parser.yyVAL.item = &ast.InsertStmt{Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 1192: + case 1230: { parser.yyVAL.item = &ast.InsertStmt{Select: yyS[yypt-0].statement.(ast.ResultSetNode)} } - case 1193: + case 1231: { var sel ast.ResultSetNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -15460,66 +15884,66 @@ yynewstate: } parser.yyVAL.item = &ast.InsertStmt{Select: sel} } - case 1194: + case 1232: { parser.yyVAL.item = &ast.InsertStmt{Setlist: yyS[yypt-0].item.([]*ast.Assignment)} } - case 1197: + case 1235: { parser.yyVAL.item = [][]ast.ExprNode{yyS[yypt-0].item.([]ast.ExprNode)} } - case 1198: + case 1236: { parser.yyVAL.item = append(yyS[yypt-2].item.([][]ast.ExprNode), yyS[yypt-0].item.([]ast.ExprNode)) } - case 1199: + case 1237: { parser.yyVAL.item = yyS[yypt-1].item } - case 1200: + case 1238: { parser.yyVAL.item = []ast.ExprNode{} } - case 1202: + case 1240: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.ExprNode), yyS[yypt-0].expr) } - case 1203: + case 1241: { parser.yyVAL.item = []ast.ExprNode{yyS[yypt-0].expr} } - case 1205: + case 1243: { parser.yyVAL.expr = &ast.DefaultExpr{} } - case 1206: + case 1244: { parser.yyVAL.item = &ast.Assignment{ Column: yyS[yypt-2].item.(*ast.ColumnName), Expr: yyS[yypt-0].expr, } } - case 1207: + case 1245: { parser.yyVAL.item = []*ast.Assignment{} } - case 1208: + case 1246: { parser.yyVAL.item = []*ast.Assignment{yyS[yypt-0].item.(*ast.Assignment)} } - case 1209: + case 1247: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.Assignment), yyS[yypt-0].item.(*ast.Assignment)) } - case 1210: + case 1248: { parser.yyVAL.item = nil } - case 1211: + case 1249: { parser.yyVAL.item = yyS[yypt-0].item } - case 1212: + case 1250: { x := yyS[yypt-0].item.(*ast.InsertStmt) x.IsReplace = true @@ -15529,31 +15953,31 @@ yynewstate: x.PartitionNames = yyS[yypt-1].item.([]model.CIStr) parser.yyVAL.statement = x } - case 1213: + case 1251: { parser.yyVAL.expr = ast.NewValueExpr(false, parser.charset, parser.collation) } - case 1214: + case 1252: { parser.yyVAL.expr = ast.NewValueExpr(nil, parser.charset, parser.collation) } - case 1215: + case 1253: { parser.yyVAL.expr = ast.NewValueExpr(true, parser.charset, parser.collation) } - case 1216: + case 1254: { parser.yyVAL.expr = ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation) } - case 1217: + case 1255: { parser.yyVAL.expr = ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation) } - case 1218: + case 1256: { parser.yyVAL.expr = ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation) } - case 1220: + case 1258: { // See https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html co, err := charset.GetDefaultCollationLegacy(yyS[yypt-1].ident) @@ -15570,15 +15994,15 @@ yynewstate: } parser.yyVAL.expr = expr } - case 1221: + case 1259: { parser.yyVAL.expr = ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation) } - case 1222: + case 1260: { parser.yyVAL.expr = ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation) } - case 1223: + case 1261: { co, err := charset.GetDefaultCollationLegacy(yyS[yypt-1].ident) if err != nil { @@ -15594,7 +16018,7 @@ yynewstate: } parser.yyVAL.expr = expr } - case 1224: + case 1262: { co, err := charset.GetDefaultCollationLegacy(yyS[yypt-1].ident) if err != nil { @@ -15610,12 +16034,12 @@ yynewstate: } parser.yyVAL.expr = expr } - case 1225: + case 1263: { expr := ast.NewValueExpr(yyS[yypt-0].ident, parser.charset, parser.collation) parser.yyVAL.expr = expr } - case 1226: + case 1264: { valExpr := yyS[yypt-1].expr.(ast.ValueExpr) strLit := valExpr.GetString() @@ -15628,31 +16052,31 @@ yynewstate: } parser.yyVAL.expr = expr } - case 1227: + case 1265: { parser.yyVAL.item = []*ast.AlterOrderItem{yyS[yypt-0].item.(*ast.AlterOrderItem)} } - case 1228: + case 1266: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.AlterOrderItem), yyS[yypt-0].item.(*ast.AlterOrderItem)) } - case 1229: + case 1267: { parser.yyVAL.item = &ast.AlterOrderItem{Column: yyS[yypt-1].item.(*ast.ColumnName), Desc: yyS[yypt-0].item.(bool)} } - case 1230: + case 1268: { parser.yyVAL.item = &ast.OrderByClause{Items: yyS[yypt-0].item.([]*ast.ByItem)} } - case 1231: + case 1269: { parser.yyVAL.item = []*ast.ByItem{yyS[yypt-0].item.(*ast.ByItem)} } - case 1232: + case 1270: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.ByItem), yyS[yypt-0].item.(*ast.ByItem)) } - case 1233: + case 1271: { expr := yyS[yypt-0].expr valueExpr, ok := expr.(ast.ValueExpr) @@ -15664,7 +16088,7 @@ yynewstate: } parser.yyVAL.item = &ast.ByItem{Expr: expr, NullOrder: true} } - case 1234: + case 1272: { expr := yyS[yypt-1].expr valueExpr, ok := expr.(ast.ValueExpr) @@ -15676,55 +16100,55 @@ yynewstate: } parser.yyVAL.item = &ast.ByItem{Expr: expr, Desc: yyS[yypt-0].item.(bool)} } - case 1235: + case 1273: { parser.yyVAL.item = false } - case 1236: + case 1274: { parser.yyVAL.item = true } - case 1237: + case 1275: { parser.yyVAL.item = false // ASC by default } - case 1238: + case 1276: { parser.yyVAL.item = false } - case 1239: + case 1277: { parser.yyVAL.item = true } - case 1240: + case 1278: { parser.yyVAL.item = nil } - case 1242: + case 1280: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Or, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1243: + case 1281: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.And, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1244: + case 1282: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.LeftShift, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1245: + case 1283: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.RightShift, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1246: + case 1284: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Plus, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1247: + case 1285: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Minus, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1248: + case 1286: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr("DATE_ADD"), @@ -15735,7 +16159,7 @@ yynewstate: }, } } - case 1249: + case 1287: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr("DATE_SUB"), @@ -15746,7 +16170,7 @@ yynewstate: }, } } - case 1250: + case 1288: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr("DATE_ADD"), @@ -15757,44 +16181,44 @@ yynewstate: }, } } - case 1251: + case 1289: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Mul, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1252: + case 1290: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Div, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1253: + case 1291: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Mod, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1254: + case 1292: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.IntDiv, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1255: + case 1293: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Mod, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1256: + case 1294: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Xor, L: yyS[yypt-2].expr, R: yyS[yypt-0].expr} } - case 1258: + case 1296: { parser.yyVAL.expr = &ast.ColumnNameExpr{Name: &ast.ColumnName{ Name: model.NewCIStr(yyS[yypt-0].ident), }} } - case 1259: + case 1297: { parser.yyVAL.expr = &ast.ColumnNameExpr{Name: &ast.ColumnName{ Table: model.NewCIStr(yyS[yypt-2].ident), Name: model.NewCIStr(yyS[yypt-0].ident), }} } - case 1260: + case 1298: { parser.yyVAL.expr = &ast.ColumnNameExpr{Name: &ast.ColumnName{ Schema: model.NewCIStr(yyS[yypt-4].ident), @@ -15802,39 +16226,39 @@ yynewstate: Name: model.NewCIStr(yyS[yypt-0].ident), }} } - case 1265: + case 1303: { parser.yyVAL.expr = &ast.SetCollationExpr{Expr: yyS[yypt-2].expr, Collate: yyS[yypt-0].ident} } - case 1268: + case 1306: { parser.yyVAL.expr = ast.NewParamMarkerExpr(yyS[yypt].offset) } - case 1271: + case 1309: { parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.Not2, V: yyS[yypt-0].expr} } - case 1272: + case 1310: { parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.BitNeg, V: yyS[yypt-0].expr} } - case 1273: + case 1311: { parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.Minus, V: yyS[yypt-0].expr} } - case 1274: + case 1312: { parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.Plus, V: yyS[yypt-0].expr} } - case 1275: + case 1313: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.Concat), Args: []ast.ExprNode{yyS[yypt-2].expr, yyS[yypt-0].expr}} } - case 1276: + case 1314: { parser.yyVAL.expr = &ast.UnaryOperationExpr{Op: opcode.Not2, V: yyS[yypt-0].expr} } - case 1278: + case 1316: { startOffset := parser.startOffset(&yyS[yypt-1]) endOffset := parser.endOffset(&yyS[yypt]) @@ -15842,23 +16266,23 @@ yynewstate: expr.SetText(parser.lexer.client, parser.src[startOffset:endOffset]) parser.yyVAL.expr = &ast.ParenthesesExpr{Expr: expr} } - case 1279: + case 1317: { values := append(yyS[yypt-3].item.([]ast.ExprNode), yyS[yypt-1].expr) parser.yyVAL.expr = &ast.RowExpr{Values: values} } - case 1280: + case 1318: { values := append(yyS[yypt-3].item.([]ast.ExprNode), yyS[yypt-1].expr) parser.yyVAL.expr = &ast.RowExpr{Values: values} } - case 1281: + case 1319: { sq := yyS[yypt-0].expr.(*ast.SubqueryExpr) sq.Exists = true parser.yyVAL.expr = &ast.ExistsSubqueryExpr{Sel: sq} } - case 1282: + case 1320: { /* * ODBC escape syntax. @@ -15882,7 +16306,7 @@ yynewstate: parser.yyVAL.expr = yyS[yypt-1].expr } } - case 1283: + case 1321: { // See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#operator_binary tp := types.NewFieldType(mysql.TypeString) @@ -15895,10 +16319,10 @@ yynewstate: FunctionType: ast.CastBinaryOperator, } } - case 1284: + case 1322: { /* See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */ - tp := yyS[yypt-1].item.(*types.FieldType) + tp := yyS[yypt-2].item.(*types.FieldType) defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimalForCast(tp.GetType()) if tp.GetFlen() == types.UnspecifiedLength { tp.SetFlen(defaultFlen) @@ -15906,16 +16330,22 @@ yynewstate: if tp.GetDecimal() == types.UnspecifiedLength { tp.SetDecimal(defaultDecimal) } + isArray := yyS[yypt-1].item.(bool) + tp.SetArray(isArray) explicitCharset := parser.explicitCharset + if isArray && !explicitCharset && tp.GetCharset() != charset.CharsetBin { + tp.SetCharset(charset.CharsetUTF8MB4) + tp.SetCollate(charset.CollationUTF8MB4) + } parser.explicitCharset = false parser.yyVAL.expr = &ast.FuncCastExpr{ - Expr: yyS[yypt-3].expr, + Expr: yyS[yypt-4].expr, Tp: tp, FunctionType: ast.CastFunction, ExplicitCharSet: explicitCharset, } } - case 1285: + case 1323: { x := &ast.CaseExpr{WhenClauses: yyS[yypt-2].item.([]*ast.WhenClause)} if yyS[yypt-3].expr != nil { @@ -15926,7 +16356,7 @@ yynewstate: } parser.yyVAL.expr = x } - case 1286: + case 1324: { // See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert tp := yyS[yypt-1].item.(*types.FieldType) @@ -15946,7 +16376,7 @@ yynewstate: ExplicitCharSet: explicitCharset, } } - case 1287: + case 1325: { // See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert charset1 := ast.NewValueExpr(yyS[yypt-1].ident, "", "") @@ -15955,62 +16385,70 @@ yynewstate: Args: []ast.ExprNode{yyS[yypt-3].expr, charset1}, } } - case 1288: + case 1326: { parser.yyVAL.expr = &ast.DefaultExpr{Name: yyS[yypt-1].expr.(*ast.ColumnNameExpr).Name} } - case 1289: + case 1327: { parser.yyVAL.expr = &ast.ValuesExpr{Column: yyS[yypt-1].expr.(*ast.ColumnNameExpr)} } - case 1290: + case 1328: { expr := ast.NewValueExpr(yyS[yypt-0].ident, parser.charset, parser.collation) parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONExtract), Args: []ast.ExprNode{yyS[yypt-2].expr, expr}} } - case 1291: + case 1329: { expr := ast.NewValueExpr(yyS[yypt-0].ident, parser.charset, parser.collation) extract := &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONExtract), Args: []ast.ExprNode{yyS[yypt-2].expr, expr}} parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONUnquote), Args: []ast.ExprNode{extract}} } - case 1294: + case 1330: { parser.yyVAL.item = false } - case 1295: + case 1331: { parser.yyVAL.item = true } - case 1296: + case 1334: { parser.yyVAL.item = false } - case 1298: + case 1335: + { + parser.yyVAL.item = true + } + case 1336: + { + parser.yyVAL.item = false + } + case 1338: { parser.yyVAL.item = true } - case 1301: + case 1341: { parser.yyVAL.item = true } - case 1344: + case 1384: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-3].ident), Args: yyS[yypt-1].item.([]ast.ExprNode)} } - case 1345: + case 1385: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-3].ident), Args: yyS[yypt-1].item.([]ast.ExprNode)} } - case 1346: + case 1386: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-1].ident)} } - case 1347: + case 1387: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-2].ident)} } - case 1348: + case 1388: { args := []ast.ExprNode{} if yyS[yypt-0].item != nil { @@ -16018,7 +16456,7 @@ yynewstate: } parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-1].ident), Args: args} } - case 1349: + case 1389: { nilVal := ast.NewValueExpr(nil, parser.charset, parser.collation) args := yyS[yypt-1].item.([]ast.ExprNode) @@ -16027,7 +16465,7 @@ yynewstate: Args: append(args, nilVal), } } - case 1350: + case 1390: { charset1 := ast.NewValueExpr(yyS[yypt-1].ident, "", "") args := yyS[yypt-3].item.([]ast.ExprNode) @@ -16036,42 +16474,42 @@ yynewstate: Args: append(args, charset1), } } - case 1351: + case 1391: { expr := ast.NewValueExpr(yyS[yypt-0].ident, "", "") parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.DateLiteral), Args: []ast.ExprNode{expr}} } - case 1352: + case 1392: { expr := ast.NewValueExpr(yyS[yypt-0].ident, "", "") parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.TimeLiteral), Args: []ast.ExprNode{expr}} } - case 1353: + case 1393: { expr := ast.NewValueExpr(yyS[yypt-0].ident, "", "") parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.TimestampLiteral), Args: []ast.ExprNode{expr}} } - case 1354: + case 1394: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.InsertFunc), Args: yyS[yypt-1].item.([]ast.ExprNode)} } - case 1355: + case 1395: { parser.yyVAL.expr = &ast.BinaryOperationExpr{Op: opcode.Mod, L: yyS[yypt-3].expr, R: yyS[yypt-1].expr} } - case 1356: + case 1396: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.PasswordFunc), Args: yyS[yypt-1].item.([]ast.ExprNode)} } - case 1357: + case 1397: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-3].ident), Args: yyS[yypt-1].item.([]ast.ExprNode)} } - case 1358: + case 1398: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-3].ident), Args: yyS[yypt-1].item.([]ast.ExprNode)} } - case 1359: + case 1399: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-5].ident), @@ -16082,7 +16520,7 @@ yynewstate: }, } } - case 1360: + case 1400: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-7].ident), @@ -16093,7 +16531,7 @@ yynewstate: }, } } - case 1361: + case 1401: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-7].ident), @@ -16104,7 +16542,7 @@ yynewstate: }, } } - case 1362: + case 1402: { timeUnit := &ast.TimeUnitExpr{Unit: yyS[yypt-3].item.(ast.TimeUnitType)} parser.yyVAL.expr = &ast.FuncCallExpr{ @@ -16112,7 +16550,7 @@ yynewstate: Args: []ast.ExprNode{timeUnit, yyS[yypt-1].expr}, } } - case 1363: + case 1403: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-5].ident), @@ -16122,67 +16560,67 @@ yynewstate: }, } } - case 1364: + case 1404: { parser.yyVAL.expr = &ast.FuncCallExpr{FnName: model.NewCIStr(yyS[yypt-5].ident), Args: []ast.ExprNode{yyS[yypt-3].expr, yyS[yypt-1].expr}} } - case 1365: + case 1405: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-5].ident), Args: []ast.ExprNode{yyS[yypt-3].expr, yyS[yypt-1].expr}, } } - case 1366: + case 1406: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-5].ident), Args: []ast.ExprNode{yyS[yypt-3].expr, yyS[yypt-1].expr}, } } - case 1367: + case 1407: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-7].ident), Args: []ast.ExprNode{yyS[yypt-5].expr, yyS[yypt-3].expr, yyS[yypt-1].expr}, } } - case 1368: + case 1408: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-7].ident), Args: []ast.ExprNode{yyS[yypt-5].expr, yyS[yypt-3].expr, yyS[yypt-1].expr}, } } - case 1369: + case 1409: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-7].ident), Args: []ast.ExprNode{&ast.TimeUnitExpr{Unit: yyS[yypt-5].item.(ast.TimeUnitType)}, yyS[yypt-3].expr, yyS[yypt-1].expr}, } } - case 1370: + case 1410: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-7].ident), Args: []ast.ExprNode{&ast.TimeUnitExpr{Unit: yyS[yypt-5].item.(ast.TimeUnitType)}, yyS[yypt-3].expr, yyS[yypt-1].expr}, } } - case 1371: + case 1411: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-3].ident), Args: []ast.ExprNode{yyS[yypt-1].expr}, } } - case 1372: + case 1412: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-5].ident), Args: []ast.ExprNode{yyS[yypt-1].expr, yyS[yypt-3].expr}, } } - case 1373: + case 1413: { spaceVal := ast.NewValueExpr(" ", parser.charset, parser.collation) direction := &ast.TrimDirectionExpr{Direction: yyS[yypt-3].item.(ast.TrimDirectionType)} @@ -16191,7 +16629,7 @@ yynewstate: Args: []ast.ExprNode{yyS[yypt-1].expr, spaceVal, direction}, } } - case 1374: + case 1414: { direction := &ast.TrimDirectionExpr{Direction: yyS[yypt-4].item.(ast.TrimDirectionType)} parser.yyVAL.expr = &ast.FuncCallExpr{ @@ -16199,63 +16637,63 @@ yynewstate: Args: []ast.ExprNode{yyS[yypt-1].expr, yyS[yypt-3].expr, direction}, } } - case 1375: + case 1415: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-3].ident), Args: []ast.ExprNode{yyS[yypt-1].expr}, } } - case 1376: + case 1416: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-6].ident), Args: []ast.ExprNode{yyS[yypt-4].expr, ast.NewValueExpr("CHAR", parser.charset, parser.collation), ast.NewValueExpr(yyS[yypt-1].item, parser.charset, parser.collation)}, } } - case 1377: + case 1417: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-6].ident), Args: []ast.ExprNode{yyS[yypt-4].expr, ast.NewValueExpr("BINARY", parser.charset, parser.collation), ast.NewValueExpr(yyS[yypt-1].item, parser.charset, parser.collation)}, } } - case 1379: + case 1419: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-7].ident), Args: []ast.ExprNode{yyS[yypt-5].expr, yyS[yypt-3].expr, yyS[yypt-1].expr}, } } - case 1380: + case 1420: { parser.yyVAL.item = ast.GetFormatSelectorDate } - case 1381: + case 1421: { parser.yyVAL.item = ast.GetFormatSelectorDatetime } - case 1382: + case 1422: { parser.yyVAL.item = ast.GetFormatSelectorTime } - case 1383: + case 1423: { parser.yyVAL.item = ast.GetFormatSelectorDatetime } - case 1388: + case 1428: { parser.yyVAL.item = ast.TrimBoth } - case 1389: + case 1429: { parser.yyVAL.item = ast.TrimLeading } - case 1390: + case 1430: { parser.yyVAL.item = ast.TrimTrailing } - case 1391: + case 1431: { objNameExpr := &ast.TableNameExpr{ Name: yyS[yypt-1].item.(*ast.TableName), @@ -16265,7 +16703,7 @@ yynewstate: Args: []ast.ExprNode{objNameExpr}, } } - case 1392: + case 1432: { objNameExpr := &ast.TableNameExpr{ Name: yyS[yypt-3].item.(*ast.TableName), @@ -16276,7 +16714,7 @@ yynewstate: Args: []ast.ExprNode{objNameExpr, valueExpr}, } } - case 1394: + case 1434: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool), Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16284,15 +16722,15 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } } - case 1395: + case 1435: { parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-3].ident, Args: yyS[yypt-1].item.([]ast.ExprNode), Distinct: false} } - case 1396: + case 1436: { parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-3].ident, Args: yyS[yypt-1].item.([]ast.ExprNode)} } - case 1397: + case 1437: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16300,7 +16738,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1398: + case 1438: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16308,7 +16746,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1399: + case 1439: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16316,7 +16754,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1400: + case 1440: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16324,7 +16762,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1401: + case 1441: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16332,7 +16770,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1402: + case 1442: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16340,11 +16778,11 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1403: + case 1443: { parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-4].ident, Args: yyS[yypt-1].item.([]ast.ExprNode), Distinct: true} } - case 1404: + case 1444: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16352,7 +16790,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1405: + case 1445: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16360,7 +16798,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1406: + case 1446: { args := []ast.ExprNode{ast.NewValueExpr(1, parser.charset, parser.collation)} if yyS[yypt-0].item != nil { @@ -16369,7 +16807,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-4].ident, Args: args} } } - case 1407: + case 1447: { args := yyS[yypt-4].item.([]ast.ExprNode) args = append(args, yyS[yypt-2].item.(ast.ExprNode)) @@ -16383,7 +16821,7 @@ yynewstate: parser.yyVAL.expr = agg } } - case 1408: + case 1448: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool), Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16391,7 +16829,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } } - case 1409: + case 1449: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool), Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16399,7 +16837,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } } - case 1410: + case 1450: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool), Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16407,7 +16845,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } } - case 1411: + case 1451: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: ast.AggFuncStddevPop, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool), Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16415,7 +16853,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: ast.AggFuncStddevPop, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } } - case 1412: + case 1452: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool), Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16423,7 +16861,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } } - case 1413: + case 1453: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: ast.AggFuncVarPop, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool), Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16431,11 +16869,11 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: ast.AggFuncVarPop, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } } - case 1414: + case 1454: { parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Distinct: yyS[yypt-3].item.(bool)} } - case 1415: + case 1455: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16443,7 +16881,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1416: + case 1456: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16451,7 +16889,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}} } } - case 1417: + case 1457: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-6].ident, Args: []ast.ExprNode{yyS[yypt-4].expr, yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16459,7 +16897,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-6].ident, Args: []ast.ExprNode{yyS[yypt-4].expr, yyS[yypt-2].expr}} } } - case 1418: + case 1458: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-7].ident, Args: []ast.ExprNode{yyS[yypt-4].expr, yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16467,7 +16905,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-7].ident, Args: []ast.ExprNode{yyS[yypt-4].expr, yyS[yypt-2].expr}} } } - case 1419: + case 1459: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-7].ident, Args: []ast.ExprNode{yyS[yypt-5].expr, yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16475,7 +16913,7 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-7].ident, Args: []ast.ExprNode{yyS[yypt-5].expr, yyS[yypt-2].expr}} } } - case 1420: + case 1460: { if yyS[yypt-0].item != nil { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-8].ident, Args: []ast.ExprNode{yyS[yypt-5].expr, yyS[yypt-2].expr}, Spec: *(yyS[yypt-0].item.(*ast.WindowSpec))} @@ -16483,22 +16921,22 @@ yynewstate: parser.yyVAL.expr = &ast.AggregateFuncExpr{F: yyS[yypt-8].ident, Args: []ast.ExprNode{yyS[yypt-5].expr, yyS[yypt-2].expr}} } } - case 1421: + case 1461: { parser.yyVAL.item = ast.NewValueExpr(",", "", "") } - case 1422: + case 1462: { parser.yyVAL.item = ast.NewValueExpr(yyS[yypt-0].ident, "", "") } - case 1423: + case 1463: { parser.yyVAL.expr = &ast.FuncCallExpr{ FnName: model.NewCIStr(yyS[yypt-3].ident), Args: yyS[yypt-1].item.([]ast.ExprNode), } } - case 1424: + case 1464: { var tp ast.FuncCallExprType if isInTokenMap(yyS[yypt-3].ident) { @@ -16513,159 +16951,159 @@ yynewstate: Args: yyS[yypt-1].item.([]ast.ExprNode), } } - case 1425: + case 1465: { parser.yyVAL.item = nil } - case 1426: + case 1466: { parser.yyVAL.item = nil } - case 1427: + case 1467: { expr := ast.NewValueExpr(yyS[yypt-1].item, parser.charset, parser.collation) parser.yyVAL.item = expr } - case 1429: + case 1469: { parser.yyVAL.item = ast.TimeUnitSecondMicrosecond } - case 1430: + case 1470: { parser.yyVAL.item = ast.TimeUnitMinuteMicrosecond } - case 1431: + case 1471: { parser.yyVAL.item = ast.TimeUnitMinuteSecond } - case 1432: + case 1472: { parser.yyVAL.item = ast.TimeUnitHourMicrosecond } - case 1433: + case 1473: { parser.yyVAL.item = ast.TimeUnitHourSecond } - case 1434: + case 1474: { parser.yyVAL.item = ast.TimeUnitHourMinute } - case 1435: + case 1475: { parser.yyVAL.item = ast.TimeUnitDayMicrosecond } - case 1436: + case 1476: { parser.yyVAL.item = ast.TimeUnitDaySecond } - case 1437: + case 1477: { parser.yyVAL.item = ast.TimeUnitDayMinute } - case 1438: + case 1478: { parser.yyVAL.item = ast.TimeUnitDayHour } - case 1439: + case 1479: { parser.yyVAL.item = ast.TimeUnitYearMonth } - case 1440: + case 1480: { parser.yyVAL.item = ast.TimeUnitMicrosecond } - case 1441: + case 1481: { parser.yyVAL.item = ast.TimeUnitSecond } - case 1442: + case 1482: { parser.yyVAL.item = ast.TimeUnitMinute } - case 1443: + case 1483: { parser.yyVAL.item = ast.TimeUnitHour } - case 1444: + case 1484: { parser.yyVAL.item = ast.TimeUnitDay } - case 1445: + case 1485: { parser.yyVAL.item = ast.TimeUnitWeek } - case 1446: + case 1486: { parser.yyVAL.item = ast.TimeUnitMonth } - case 1447: + case 1487: { parser.yyVAL.item = ast.TimeUnitQuarter } - case 1448: + case 1488: { parser.yyVAL.item = ast.TimeUnitYear } - case 1449: + case 1489: { parser.yyVAL.item = ast.TimeUnitSecond } - case 1450: + case 1490: { parser.yyVAL.item = ast.TimeUnitMinute } - case 1451: + case 1491: { parser.yyVAL.item = ast.TimeUnitHour } - case 1452: + case 1492: { parser.yyVAL.item = ast.TimeUnitDay } - case 1453: + case 1493: { parser.yyVAL.item = ast.TimeUnitWeek } - case 1454: + case 1494: { parser.yyVAL.item = ast.TimeUnitMonth } - case 1455: + case 1495: { parser.yyVAL.item = ast.TimeUnitQuarter } - case 1456: + case 1496: { parser.yyVAL.item = ast.TimeUnitYear } - case 1457: + case 1497: { parser.yyVAL.expr = nil } - case 1459: + case 1499: { parser.yyVAL.item = []*ast.WhenClause{yyS[yypt-0].item.(*ast.WhenClause)} } - case 1460: + case 1500: { parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.WhenClause), yyS[yypt-0].item.(*ast.WhenClause)) } - case 1461: + case 1501: { parser.yyVAL.item = &ast.WhenClause{ Expr: yyS[yypt-2].expr, Result: yyS[yypt-0].expr, } } - case 1462: + case 1502: { parser.yyVAL.item = nil } - case 1463: + case 1503: { parser.yyVAL.item = yyS[yypt-0].expr } - case 1464: + case 1504: { tp := types.NewFieldType(mysql.TypeVarString) tp.SetFlen(yyS[yypt-0].item.(int)) // TODO: Flen should be the flen of expression @@ -16677,7 +17115,7 @@ yynewstate: tp.AddFlag(mysql.BinaryFlag) parser.yyVAL.item = tp } - case 1465: + case 1505: { tp := types.NewFieldType(mysql.TypeVarString) tp.SetFlen(yyS[yypt-1].item.(int)) // TODO: Flen should be the flen of expression @@ -16700,7 +17138,7 @@ yynewstate: } parser.yyVAL.item = tp } - case 1466: + case 1506: { tp := types.NewFieldType(mysql.TypeDate) tp.SetCharset(charset.CharsetBin) @@ -16708,7 +17146,7 @@ yynewstate: tp.AddFlag(mysql.BinaryFlag) parser.yyVAL.item = tp } - case 1467: + case 1507: { tp := types.NewFieldType(mysql.TypeYear) tp.SetCharset(charset.CharsetBin) @@ -16716,7 +17154,7 @@ yynewstate: tp.AddFlag(mysql.BinaryFlag) parser.yyVAL.item = tp } - case 1468: + case 1508: { tp := types.NewFieldType(mysql.TypeDatetime) flen, _ := mysql.GetDefaultFieldLengthAndDecimalForCast(mysql.TypeDatetime) @@ -16730,7 +17168,7 @@ yynewstate: tp.AddFlag(mysql.BinaryFlag) parser.yyVAL.item = tp } - case 1469: + case 1509: { fopt := yyS[yypt-0].item.(*ast.FloatOpt) tp := types.NewFieldType(mysql.TypeNewDecimal) @@ -16741,7 +17179,7 @@ yynewstate: tp.AddFlag(mysql.BinaryFlag) parser.yyVAL.item = tp } - case 1470: + case 1510: { tp := types.NewFieldType(mysql.TypeDuration) flen, _ := mysql.GetDefaultFieldLengthAndDecimalForCast(mysql.TypeDuration) @@ -16755,7 +17193,7 @@ yynewstate: tp.AddFlag(mysql.BinaryFlag) parser.yyVAL.item = tp } - case 1471: + case 1511: { tp := types.NewFieldType(mysql.TypeLonglong) tp.SetCharset(charset.CharsetBin) @@ -16763,7 +17201,7 @@ yynewstate: tp.AddFlag(mysql.BinaryFlag) parser.yyVAL.item = tp } - case 1472: + case 1512: { tp := types.NewFieldType(mysql.TypeLonglong) tp.AddFlag(mysql.UnsignedFlag | mysql.BinaryFlag) @@ -16771,7 +17209,7 @@ yynewstate: tp.SetCollate(charset.CollationBin) parser.yyVAL.item = tp } - case 1473: + case 1513: { tp := types.NewFieldType(mysql.TypeJSON) tp.AddFlag(mysql.BinaryFlag | mysql.ParseToJSONFlag) @@ -16779,7 +17217,7 @@ yynewstate: tp.SetCollate(mysql.DefaultCollationName) parser.yyVAL.item = tp } - case 1474: + case 1514: { tp := types.NewFieldType(mysql.TypeDouble) flen, decimal := mysql.GetDefaultFieldLengthAndDecimalForCast(mysql.TypeDouble) @@ -16790,7 +17228,7 @@ yynewstate: tp.SetCollate(charset.CollationBin) parser.yyVAL.item = tp } - case 1475: + case 1515: { tp := types.NewFieldType(mysql.TypeFloat) fopt := yyS[yypt-0].item.(*ast.FloatOpt) @@ -16807,7 +17245,7 @@ yynewstate: tp.SetCollate(charset.CollationBin) parser.yyVAL.item = tp } - case 1476: + case 1516: { var tp *types.FieldType if parser.lexer.GetSQLMode().HasRealAsFloatMode() { @@ -16823,65 +17261,65 @@ yynewstate: tp.SetCollate(charset.CollationBin) parser.yyVAL.item = tp } - case 1477: + case 1517: { parser.yyVAL.item = mysql.LowPriority } - case 1478: + case 1518: { parser.yyVAL.item = mysql.HighPriority } - case 1479: + case 1519: { parser.yyVAL.item = mysql.DelayedPriority } - case 1480: + case 1520: { parser.yyVAL.item = mysql.NoPriority } - case 1482: + case 1522: { parser.yyVAL.item = &ast.TableName{Name: model.NewCIStr(yyS[yypt-0].ident)} } - case 1483: + case 1523: { parser.yyVAL.item = &ast.TableName{Schema: model.NewCIStr(yyS[yypt-2].ident), Name: model.NewCIStr(yyS[yypt-0].ident)} } - case 1484: + case 1524: { tbl := []*ast.TableName{yyS[yypt-0].item.(*ast.TableName)} parser.yyVAL.item = tbl } - case 1485: + case 1525: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.TableName), yyS[yypt-0].item.(*ast.TableName)) } - case 1486: + case 1526: { parser.yyVAL.item = &ast.TableName{Name: model.NewCIStr(yyS[yypt-1].ident)} } - case 1487: + case 1527: { parser.yyVAL.item = &ast.TableName{Schema: model.NewCIStr(yyS[yypt-3].ident), Name: model.NewCIStr(yyS[yypt-1].ident)} } - case 1488: + case 1528: { tbl := []*ast.TableName{yyS[yypt-0].item.(*ast.TableName)} parser.yyVAL.item = tbl } - case 1489: + case 1529: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.TableName), yyS[yypt-0].item.(*ast.TableName)) } - case 1492: + case 1532: { parser.yyVAL.item = false } - case 1493: + case 1533: { parser.yyVAL.item = true } - case 1494: + case 1534: { var sqlText string var sqlVar *ast.VariableExpr @@ -16897,94 +17335,94 @@ yynewstate: SQLVar: sqlVar, } } - case 1495: + case 1535: { parser.yyVAL.item = yyS[yypt-0].ident } - case 1496: + case 1536: { parser.yyVAL.item = yyS[yypt-0].expr } - case 1497: + case 1537: { parser.yyVAL.statement = &ast.ExecuteStmt{Name: yyS[yypt-0].ident} } - case 1498: + case 1538: { parser.yyVAL.statement = &ast.ExecuteStmt{ Name: yyS[yypt-2].ident, UsingVars: yyS[yypt-0].item.([]ast.ExprNode), } } - case 1499: + case 1539: { parser.yyVAL.item = []ast.ExprNode{yyS[yypt-0].expr} } - case 1500: + case 1540: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.ExprNode), yyS[yypt-0].expr) } - case 1501: + case 1541: { parser.yyVAL.statement = &ast.DeallocateStmt{Name: yyS[yypt-0].ident} } - case 1504: + case 1544: { parser.yyVAL.statement = &ast.RollbackStmt{} } - case 1505: + case 1545: { parser.yyVAL.statement = &ast.RollbackStmt{CompletionType: yyS[yypt-0].item.(ast.CompletionType)} } - case 1506: + case 1546: { parser.yyVAL.statement = &ast.RollbackStmt{SavepointName: yyS[yypt-0].ident} } - case 1507: + case 1547: { parser.yyVAL.statement = &ast.RollbackStmt{SavepointName: yyS[yypt-0].ident} } - case 1508: + case 1548: { parser.yyVAL.item = ast.CompletionTypeChain } - case 1509: + case 1549: { parser.yyVAL.item = ast.CompletionTypeRelease } - case 1510: + case 1550: { parser.yyVAL.item = ast.CompletionTypeDefault } - case 1511: + case 1551: { parser.yyVAL.item = ast.CompletionTypeChain } - case 1512: + case 1552: { parser.yyVAL.item = ast.CompletionTypeDefault } - case 1513: + case 1553: { parser.yyVAL.item = ast.CompletionTypeRelease } - case 1514: + case 1554: { parser.yyVAL.item = ast.CompletionTypeDefault } - case 1515: + case 1555: { parser.yyVAL.statement = &ast.ShutdownStmt{} } - case 1516: + case 1556: { parser.yyVAL.statement = &ast.RestartStmt{} } - case 1517: + case 1557: { parser.yyVAL.statement = &ast.HelpStmt{Topic: yyS[yypt-0].ident} } - case 1518: + case 1558: { st := &ast.SelectStmt{ SelectStmtOpts: yyS[yypt-2].item.(*ast.SelectStmtOpts), @@ -17000,7 +17438,7 @@ yynewstate: } parser.yyVAL.item = st } - case 1519: + case 1559: { st := yyS[yypt-2].item.(*ast.SelectStmt) lastField := st.Fields.Fields[len(st.Fields.Fields)-1] @@ -17012,7 +17450,7 @@ yynewstate: st.Where = yyS[yypt-0].item.(ast.ExprNode) } } - case 1520: + case 1560: { st := yyS[yypt-6].item.(*ast.SelectStmt) st.From = yyS[yypt-4].item.(*ast.TableRefsClause) @@ -17035,11 +17473,11 @@ yynewstate: } parser.yyVAL.item = st } - case 1521: + case 1561: { parser.yyVAL.item = nil } - case 1522: + case 1562: { var repSeed ast.ExprNode if yyS[yypt-0].expr != nil { @@ -17052,7 +17490,7 @@ yynewstate: RepeatableSeed: repSeed, } } - case 1523: + case 1563: { var repSeed ast.ExprNode if yyS[yypt-0].expr != nil { @@ -17063,43 +17501,43 @@ yynewstate: RepeatableSeed: repSeed, } } - case 1524: + case 1564: { parser.yyVAL.item = ast.SampleMethodTypeNone } - case 1525: + case 1565: { parser.yyVAL.item = ast.SampleMethodTypeSystem } - case 1526: + case 1566: { parser.yyVAL.item = ast.SampleMethodTypeBernoulli } - case 1527: + case 1567: { parser.yyVAL.item = ast.SampleMethodTypeTiDBRegion } - case 1528: + case 1568: { parser.yyVAL.item = ast.SampleClauseUnitTypeDefault } - case 1529: + case 1569: { parser.yyVAL.item = ast.SampleClauseUnitTypeRow } - case 1530: + case 1570: { parser.yyVAL.item = ast.SampleClauseUnitTypePercent } - case 1531: + case 1571: { parser.yyVAL.expr = nil } - case 1532: + case 1572: { parser.yyVAL.expr = yyS[yypt-1].expr } - case 1533: + case 1573: { st := yyS[yypt-6].item.(*ast.SelectStmt) if yyS[yypt-1].item != nil { @@ -17146,7 +17584,7 @@ yynewstate: } parser.yyVAL.statement = st } - case 1534: + case 1574: { st := yyS[yypt-5].item.(*ast.SelectStmt) if yyS[yypt-4].item != nil { @@ -17166,7 +17604,7 @@ yynewstate: } parser.yyVAL.statement = st } - case 1535: + case 1575: { st := yyS[yypt-4].item.(*ast.SelectStmt) if yyS[yypt-1].item != nil { @@ -17183,7 +17621,7 @@ yynewstate: } parser.yyVAL.statement = st } - case 1536: + case 1576: { st := &ast.SelectStmt{ Kind: ast.SelectStmtKindTable, @@ -17205,7 +17643,7 @@ yynewstate: } parser.yyVAL.statement = st } - case 1537: + case 1577: { st := &ast.SelectStmt{ Kind: ast.SelectStmtKindValues, @@ -17226,13 +17664,13 @@ yynewstate: } parser.yyVAL.statement = st } - case 1538: + case 1578: { sel := yyS[yypt-0].statement.(*ast.SelectStmt) sel.With = yyS[yypt-1].item.(*ast.WithClause) parser.yyVAL.statement = sel } - case 1539: + case 1579: { var sel ast.StmtNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -17248,11 +17686,11 @@ yynewstate: } parser.yyVAL.statement = sel } - case 1540: + case 1580: { parser.yyVAL.item = yyS[yypt-0].item } - case 1541: + case 1581: { ws := yyS[yypt-0].item.(*ast.WithClause) ws.IsRecursive = true @@ -17261,20 +17699,20 @@ yynewstate: } parser.yyVAL.item = ws } - case 1542: + case 1582: { ws := yyS[yypt-2].item.(*ast.WithClause) ws.CTEs = append(ws.CTEs, yyS[yypt-0].item.(*ast.CommonTableExpression)) parser.yyVAL.item = ws } - case 1543: + case 1583: { ws := &ast.WithClause{} ws.CTEs = make([]*ast.CommonTableExpression, 0, 4) ws.CTEs = append(ws.CTEs, yyS[yypt-0].item.(*ast.CommonTableExpression)) parser.yyVAL.item = ws } - case 1544: + case 1584: { cte := &ast.CommonTableExpression{} cte.Name = model.NewCIStr(yyS[yypt-3].ident) @@ -17282,37 +17720,37 @@ yynewstate: cte.Query = yyS[yypt-0].expr.(*ast.SubqueryExpr) parser.yyVAL.item = cte } - case 1546: + case 1586: { parser.yyVAL.item = nil } - case 1547: + case 1587: { parser.yyVAL.item = yyS[yypt-0].item.([]ast.WindowSpec) } - case 1548: + case 1588: { parser.yyVAL.item = []ast.WindowSpec{yyS[yypt-0].item.(ast.WindowSpec)} } - case 1549: + case 1589: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.WindowSpec), yyS[yypt-0].item.(ast.WindowSpec)) } - case 1550: + case 1590: { var spec = yyS[yypt-0].item.(ast.WindowSpec) spec.Name = yyS[yypt-2].item.(model.CIStr) parser.yyVAL.item = spec } - case 1551: + case 1591: { parser.yyVAL.item = model.NewCIStr(yyS[yypt-0].ident) } - case 1552: + case 1592: { parser.yyVAL.item = yyS[yypt-1].item.(ast.WindowSpec) } - case 1553: + case 1593: { spec := ast.WindowSpec{Ref: yyS[yypt-3].item.(model.CIStr)} if yyS[yypt-2].item != nil { @@ -17326,138 +17764,138 @@ yynewstate: } parser.yyVAL.item = spec } - case 1554: + case 1594: { parser.yyVAL.item = model.CIStr{} } - case 1556: + case 1596: { parser.yyVAL.item = nil } - case 1557: + case 1597: { parser.yyVAL.item = &ast.PartitionByClause{Items: yyS[yypt-0].item.([]*ast.ByItem)} } - case 1558: + case 1598: { parser.yyVAL.item = nil } - case 1559: + case 1599: { parser.yyVAL.item = &ast.OrderByClause{Items: yyS[yypt-0].item.([]*ast.ByItem)} } - case 1560: + case 1600: { parser.yyVAL.item = nil } - case 1561: + case 1601: { parser.yyVAL.item = &ast.FrameClause{ Type: yyS[yypt-1].item.(ast.FrameType), Extent: yyS[yypt-0].item.(ast.FrameExtent), } } - case 1562: + case 1602: { parser.yyVAL.item = ast.FrameType(ast.Rows) } - case 1563: + case 1603: { parser.yyVAL.item = ast.FrameType(ast.Ranges) } - case 1564: + case 1604: { parser.yyVAL.item = ast.FrameType(ast.Groups) } - case 1565: + case 1605: { parser.yyVAL.item = ast.FrameExtent{ Start: yyS[yypt-0].item.(ast.FrameBound), End: ast.FrameBound{Type: ast.CurrentRow}, } } - case 1567: + case 1607: { parser.yyVAL.item = ast.FrameBound{Type: ast.Preceding, UnBounded: true} } - case 1568: + case 1608: { parser.yyVAL.item = ast.FrameBound{Type: ast.Preceding, Expr: ast.NewValueExpr(yyS[yypt-1].item, parser.charset, parser.collation)} } - case 1569: + case 1609: { parser.yyVAL.item = ast.FrameBound{Type: ast.Preceding, Expr: ast.NewParamMarkerExpr(yyS[yypt].offset)} } - case 1570: + case 1610: { parser.yyVAL.item = ast.FrameBound{Type: ast.Preceding, Expr: yyS[yypt-2].expr, Unit: yyS[yypt-1].item.(ast.TimeUnitType)} } - case 1571: + case 1611: { parser.yyVAL.item = ast.FrameBound{Type: ast.CurrentRow} } - case 1572: + case 1612: { parser.yyVAL.item = ast.FrameExtent{Start: yyS[yypt-2].item.(ast.FrameBound), End: yyS[yypt-0].item.(ast.FrameBound)} } - case 1574: + case 1614: { parser.yyVAL.item = ast.FrameBound{Type: ast.Following, UnBounded: true} } - case 1575: + case 1615: { parser.yyVAL.item = ast.FrameBound{Type: ast.Following, Expr: ast.NewValueExpr(yyS[yypt-1].item, parser.charset, parser.collation)} } - case 1576: + case 1616: { parser.yyVAL.item = ast.FrameBound{Type: ast.Following, Expr: ast.NewParamMarkerExpr(yyS[yypt].offset)} } - case 1577: + case 1617: { parser.yyVAL.item = ast.FrameBound{Type: ast.Following, Expr: yyS[yypt-2].expr, Unit: yyS[yypt-1].item.(ast.TimeUnitType)} } - case 1578: + case 1618: { parser.yyVAL.item = nil } - case 1579: + case 1619: { spec := yyS[yypt-0].item.(ast.WindowSpec) parser.yyVAL.item = &spec } - case 1580: + case 1620: { parser.yyVAL.item = yyS[yypt-0].item.(ast.WindowSpec) } - case 1581: + case 1621: { parser.yyVAL.item = ast.WindowSpec{Name: yyS[yypt-0].item.(model.CIStr), OnlyAlias: true} } - case 1583: + case 1623: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-3].ident, Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1584: + case 1624: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-3].ident, Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1585: + case 1625: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-3].ident, Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1586: + case 1626: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-3].ident, Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1587: + case 1627: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-3].ident, Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1588: + case 1628: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-4].ident, Args: []ast.ExprNode{yyS[yypt-2].expr}, Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1589: + case 1629: { args := []ast.ExprNode{yyS[yypt-4].expr} if yyS[yypt-3].item != nil { @@ -17465,7 +17903,7 @@ yynewstate: } parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-6].ident, Args: args, IgnoreNull: yyS[yypt-1].item.(bool), Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1590: + case 1630: { args := []ast.ExprNode{yyS[yypt-4].expr} if yyS[yypt-3].item != nil { @@ -17473,23 +17911,23 @@ yynewstate: } parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-6].ident, Args: args, IgnoreNull: yyS[yypt-1].item.(bool), Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1591: + case 1631: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-3].expr}, IgnoreNull: yyS[yypt-1].item.(bool), Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1592: + case 1632: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-5].ident, Args: []ast.ExprNode{yyS[yypt-3].expr}, IgnoreNull: yyS[yypt-1].item.(bool), Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1593: + case 1633: { parser.yyVAL.expr = &ast.WindowFuncExpr{F: yyS[yypt-8].ident, Args: []ast.ExprNode{yyS[yypt-6].expr, yyS[yypt-4].expr}, FromLast: yyS[yypt-2].item.(bool), IgnoreNull: yyS[yypt-1].item.(bool), Spec: yyS[yypt-0].item.(ast.WindowSpec)} } - case 1594: + case 1634: { parser.yyVAL.item = nil } - case 1595: + case 1635: { args := []ast.ExprNode{ast.NewValueExpr(yyS[yypt-1].item, parser.charset, parser.collation)} if yyS[yypt-0].item != nil { @@ -17497,7 +17935,7 @@ yynewstate: } parser.yyVAL.item = args } - case 1596: + case 1636: { args := []ast.ExprNode{ast.NewParamMarkerExpr(yyS[yypt-1].offset)} if yyS[yypt-0].item != nil { @@ -17505,43 +17943,43 @@ yynewstate: } parser.yyVAL.item = args } - case 1597: + case 1637: { parser.yyVAL.item = nil } - case 1598: + case 1638: { parser.yyVAL.item = yyS[yypt-0].expr } - case 1599: + case 1639: { parser.yyVAL.item = false } - case 1600: + case 1640: { parser.yyVAL.item = false } - case 1601: + case 1641: { parser.yyVAL.item = true } - case 1602: + case 1642: { parser.yyVAL.item = false } - case 1603: + case 1643: { parser.yyVAL.item = false } - case 1604: + case 1644: { parser.yyVAL.item = true } - case 1605: + case 1645: { parser.yyVAL.item = &ast.TableRefsClause{TableRefs: yyS[yypt-0].item.(*ast.Join)} } - case 1606: + case 1646: { if j, ok := yyS[yypt-0].item.(*ast.Join); ok { // if $1 is Join, use it directly @@ -17550,12 +17988,12 @@ yynewstate: parser.yyVAL.item = &ast.Join{Left: yyS[yypt-0].item.(ast.ResultSetNode), Right: nil} } } - case 1607: + case 1647: { /* from a, b is default cross join */ parser.yyVAL.item = &ast.Join{Left: yyS[yypt-2].item.(ast.ResultSetNode), Right: yyS[yypt-0].item.(ast.ResultSetNode), Tp: ast.CrossJoin} } - case 1609: + case 1649: { /* * ODBC escape syntax for outer join is { OJ join_table } @@ -17563,7 +18001,7 @@ yynewstate: */ parser.yyVAL.item = yyS[yypt-1].item } - case 1612: + case 1652: { tn := yyS[yypt-5].item.(*ast.TableName) tn.PartitionNames = yyS[yypt-4].item.([]model.CIStr) @@ -17576,66 +18014,66 @@ yynewstate: } parser.yyVAL.item = &ast.TableSource{Source: tn, AsName: yyS[yypt-3].item.(model.CIStr)} } - case 1613: + case 1653: { resultNode := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query parser.yyVAL.item = &ast.TableSource{Source: resultNode, AsName: yyS[yypt-0].item.(model.CIStr)} } - case 1614: + case 1654: { j := yyS[yypt-1].item.(*ast.Join) j.ExplicitParens = true parser.yyVAL.item = yyS[yypt-1].item } - case 1615: + case 1655: { parser.yyVAL.item = []model.CIStr{} } - case 1616: + case 1656: { parser.yyVAL.item = yyS[yypt-1].item } - case 1617: + case 1657: { parser.yyVAL.item = model.CIStr{} } - case 1619: + case 1659: { parser.yyVAL.item = model.NewCIStr(yyS[yypt-0].ident) } - case 1620: + case 1660: { parser.yyVAL.item = model.NewCIStr(yyS[yypt-0].ident) } - case 1621: + case 1661: { parser.yyVAL.item = ast.HintUse } - case 1622: + case 1662: { parser.yyVAL.item = ast.HintIgnore } - case 1623: + case 1663: { parser.yyVAL.item = ast.HintForce } - case 1624: + case 1664: { parser.yyVAL.item = ast.HintForScan } - case 1625: + case 1665: { parser.yyVAL.item = ast.HintForJoin } - case 1626: + case 1666: { parser.yyVAL.item = ast.HintForOrderBy } - case 1627: + case 1667: { parser.yyVAL.item = ast.HintForGroupBy } - case 1628: + case 1668: { parser.yyVAL.item = &ast.IndexHint{ IndexNames: yyS[yypt-1].item.([]model.CIStr), @@ -17643,134 +18081,134 @@ yynewstate: HintScope: yyS[yypt-3].item.(ast.IndexHintScope), } } - case 1629: + case 1669: { var nameList []model.CIStr parser.yyVAL.item = nameList } - case 1630: + case 1670: { parser.yyVAL.item = []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)} } - case 1631: + case 1671: { parser.yyVAL.item = append(yyS[yypt-2].item.([]model.CIStr), model.NewCIStr(yyS[yypt-0].ident)) } - case 1632: + case 1672: { parser.yyVAL.item = []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)} } - case 1633: + case 1673: { parser.yyVAL.item = append(yyS[yypt-2].item.([]model.CIStr), model.NewCIStr(yyS[yypt-0].ident)) } - case 1634: + case 1674: { parser.yyVAL.item = []*ast.IndexHint{yyS[yypt-0].item.(*ast.IndexHint)} } - case 1635: + case 1675: { parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.IndexHint), yyS[yypt-0].item.(*ast.IndexHint)) } - case 1636: + case 1676: { parser.yyVAL.item = []*ast.IndexHint{} } - case 1638: + case 1678: { parser.yyVAL.item = ast.NewCrossJoin(yyS[yypt-2].item.(ast.ResultSetNode), yyS[yypt-0].item.(ast.ResultSetNode)) } - case 1639: + case 1679: { on := &ast.OnCondition{Expr: yyS[yypt-0].expr} parser.yyVAL.item = &ast.Join{Left: yyS[yypt-4].item.(ast.ResultSetNode), Right: yyS[yypt-2].item.(ast.ResultSetNode), Tp: ast.CrossJoin, On: on} } - case 1640: + case 1680: { parser.yyVAL.item = &ast.Join{Left: yyS[yypt-6].item.(ast.ResultSetNode), Right: yyS[yypt-4].item.(ast.ResultSetNode), Tp: ast.CrossJoin, Using: yyS[yypt-1].item.([]*ast.ColumnName)} } - case 1641: + case 1681: { on := &ast.OnCondition{Expr: yyS[yypt-0].expr} parser.yyVAL.item = &ast.Join{Left: yyS[yypt-6].item.(ast.ResultSetNode), Right: yyS[yypt-2].item.(ast.ResultSetNode), Tp: yyS[yypt-5].item.(ast.JoinType), On: on} } - case 1642: + case 1682: { parser.yyVAL.item = &ast.Join{Left: yyS[yypt-8].item.(ast.ResultSetNode), Right: yyS[yypt-4].item.(ast.ResultSetNode), Tp: yyS[yypt-7].item.(ast.JoinType), Using: yyS[yypt-1].item.([]*ast.ColumnName)} } - case 1643: + case 1683: { parser.yyVAL.item = &ast.Join{Left: yyS[yypt-3].item.(ast.ResultSetNode), Right: yyS[yypt-0].item.(ast.ResultSetNode), NaturalJoin: true} } - case 1644: + case 1684: { parser.yyVAL.item = &ast.Join{Left: yyS[yypt-5].item.(ast.ResultSetNode), Right: yyS[yypt-0].item.(ast.ResultSetNode), Tp: yyS[yypt-3].item.(ast.JoinType), NaturalJoin: true} } - case 1645: + case 1685: { parser.yyVAL.item = &ast.Join{Left: yyS[yypt-2].item.(ast.ResultSetNode), Right: yyS[yypt-0].item.(ast.ResultSetNode), StraightJoin: true} } - case 1646: + case 1686: { on := &ast.OnCondition{Expr: yyS[yypt-0].expr} parser.yyVAL.item = &ast.Join{Left: yyS[yypt-4].item.(ast.ResultSetNode), Right: yyS[yypt-2].item.(ast.ResultSetNode), StraightJoin: true, On: on} } - case 1647: + case 1687: { parser.yyVAL.item = ast.LeftJoin } - case 1648: + case 1688: { parser.yyVAL.item = ast.RightJoin } - case 1654: + case 1694: { parser.yyVAL.item = nil } - case 1655: + case 1695: { parser.yyVAL.item = &ast.Limit{Count: yyS[yypt-0].item.(ast.ValueExpr)} } - case 1656: + case 1696: { parser.yyVAL.item = ast.NewValueExpr(yyS[yypt-0].item, parser.charset, parser.collation) } - case 1657: + case 1697: { parser.yyVAL.item = ast.NewParamMarkerExpr(yyS[yypt].offset) } - case 1662: + case 1702: { parser.yyVAL.item = ast.NewValueExpr(uint64(1), parser.charset, parser.collation) } - case 1664: + case 1704: { parser.yyVAL.item = &ast.Limit{Count: yyS[yypt-0].item.(ast.ExprNode)} } - case 1665: + case 1705: { parser.yyVAL.item = &ast.Limit{Offset: yyS[yypt-2].item.(ast.ExprNode), Count: yyS[yypt-0].item.(ast.ExprNode)} } - case 1666: + case 1706: { parser.yyVAL.item = &ast.Limit{Offset: yyS[yypt-0].item.(ast.ExprNode), Count: yyS[yypt-2].item.(ast.ExprNode)} } - case 1667: + case 1707: { parser.yyVAL.item = &ast.Limit{Count: yyS[yypt-2].item.(ast.ExprNode)} } - case 1668: + case 1708: { parser.yyVAL.item = nil } - case 1670: + case 1710: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true opt.TableHints = yyS[yypt-0].item.([]*ast.TableOptimizerHint) parser.yyVAL.item = opt } - case 1671: + case 1711: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true @@ -17782,61 +18220,61 @@ yynewstate: } parser.yyVAL.item = opt } - case 1672: + case 1712: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true opt.Priority = yyS[yypt-0].item.(mysql.PriorityEnum) parser.yyVAL.item = opt } - case 1673: + case 1713: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true opt.SQLSmallResult = true parser.yyVAL.item = opt } - case 1674: + case 1714: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true opt.SQLBigResult = true parser.yyVAL.item = opt } - case 1675: + case 1715: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true opt.SQLBufferResult = true parser.yyVAL.item = opt } - case 1676: + case 1716: { opt := &ast.SelectStmtOpts{} opt.SQLCache = yyS[yypt-0].item.(bool) parser.yyVAL.item = opt } - case 1677: + case 1717: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true opt.CalcFoundRows = true parser.yyVAL.item = opt } - case 1678: + case 1718: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true opt.StraightJoin = true parser.yyVAL.item = opt } - case 1679: + case 1719: { opt := &ast.SelectStmtOpts{} opt.SQLCache = true parser.yyVAL.item = opt } - case 1681: + case 1721: { opts := yyS[yypt-1].item.(*ast.SelectStmtOpts) opt := yyS[yypt-0].item.(*ast.SelectStmtOpts) @@ -17881,7 +18319,7 @@ yynewstate: parser.yyVAL.item = opts } - case 1683: + case 1723: { hints, warns := parser.parseHint(yyS[yypt-0].ident) for _, w := range warns { @@ -17890,31 +18328,31 @@ yynewstate: } parser.yyVAL.item = hints } - case 1684: + case 1724: { parser.yyVAL.item = nil } - case 1686: + case 1726: { parser.yyVAL.item = true } - case 1687: + case 1727: { parser.yyVAL.item = false } - case 1688: + case 1728: { parser.yyVAL.item = &ast.FieldList{Fields: yyS[yypt-0].item.([]*ast.SelectField)} } - case 1689: + case 1729: { parser.yyVAL.item = nil } - case 1691: + case 1731: { parser.yyVAL.item = nil } - case 1692: + case 1732: { x := &ast.SelectIntoOption{ Tp: ast.SelectIntoOutfile, @@ -17929,7 +18367,7 @@ yynewstate: parser.yyVAL.item = x } - case 1693: + case 1733: { rs := yyS[yypt-1].statement.(*ast.SelectStmt) endOffset := parser.endOffset(&yyS[yypt]) @@ -17939,14 +18377,14 @@ yynewstate: rs.SetText(parser.lexer.client, src[yyS[yypt-1].offset:yyS[yypt].offset]) parser.yyVAL.expr = &ast.SubqueryExpr{Query: rs} } - case 1694: + case 1734: { rs := yyS[yypt-1].statement.(*ast.SetOprStmt) src := parser.src rs.SetText(parser.lexer.client, src[yyS[yypt-1].offset:yyS[yypt].offset]) parser.yyVAL.expr = &ast.SubqueryExpr{Query: rs} } - case 1695: + case 1735: { rs := yyS[yypt-1].statement.(*ast.SelectStmt) endOffset := parser.endOffset(&yyS[yypt]) @@ -17956,7 +18394,7 @@ yynewstate: rs.SetText(parser.lexer.client, src[yyS[yypt-1].offset:yyS[yypt].offset]) parser.yyVAL.expr = &ast.SubqueryExpr{Query: rs} } - case 1696: + case 1736: { subQuery := yyS[yypt-1].expr.(*ast.SubqueryExpr).Query isRecursive := true @@ -17979,32 +18417,32 @@ yynewstate: parser.yyVAL.expr = &ast.SubqueryExpr{Query: rs} } } - case 1697: + case 1737: { parser.yyVAL.item = nil } - case 1698: + case 1738: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForUpdate, Tables: yyS[yypt-0].item.([]*ast.TableName), } } - case 1699: + case 1739: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForShare, Tables: yyS[yypt-0].item.([]*ast.TableName), } } - case 1700: + case 1740: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForUpdateNoWait, Tables: yyS[yypt-1].item.([]*ast.TableName), } } - case 1701: + case 1741: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForUpdateWaitN, @@ -18012,55 +18450,55 @@ yynewstate: Tables: yyS[yypt-2].item.([]*ast.TableName), } } - case 1702: + case 1742: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForShareNoWait, Tables: yyS[yypt-1].item.([]*ast.TableName), } } - case 1703: + case 1743: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForUpdateSkipLocked, Tables: yyS[yypt-2].item.([]*ast.TableName), } } - case 1704: + case 1744: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForShareSkipLocked, Tables: yyS[yypt-2].item.([]*ast.TableName), } } - case 1705: + case 1745: { parser.yyVAL.item = &ast.SelectLockInfo{ LockType: ast.SelectLockForShare, Tables: []*ast.TableName{}, } } - case 1706: + case 1746: { parser.yyVAL.item = []*ast.TableName{} } - case 1707: + case 1747: { parser.yyVAL.item = yyS[yypt-0].item.([]*ast.TableName) } - case 1710: + case 1750: { setOpr := yyS[yypt-0].statement.(*ast.SetOprStmt) setOpr.With = yyS[yypt-1].item.(*ast.WithClause) parser.yyVAL.statement = setOpr } - case 1711: + case 1751: { setOpr := yyS[yypt-0].statement.(*ast.SetOprStmt) setOpr.With = yyS[yypt-1].item.(*ast.WithClause) parser.yyVAL.statement = setOpr } - case 1712: + case 1752: { setOprList1 := yyS[yypt-2].item.([]ast.Node) if sel, isSelect := setOprList1[len(setOprList1)-1].(*ast.SelectStmt); isSelect && !sel.IsInBraces { @@ -18077,7 +18515,7 @@ yynewstate: setOpr.SelectList.Selects = append(setOpr.SelectList.Selects, st) parser.yyVAL.statement = setOpr } - case 1713: + case 1753: { setOprList1 := yyS[yypt-2].item.([]ast.Node) if sel, isSelect := setOprList1[len(setOprList1)-1].(*ast.SelectStmt); isSelect && !sel.IsInBraces { @@ -18100,7 +18538,7 @@ yynewstate: setOpr := &ast.SetOprStmt{SelectList: &ast.SetOprSelectList{Selects: setOprList}} parser.yyVAL.statement = setOpr } - case 1714: + case 1754: { setOprList1 := yyS[yypt-3].item.([]ast.Node) if sel, isSelect := setOprList1[len(setOprList1)-1].(*ast.SelectStmt); isSelect && !sel.IsInBraces { @@ -18124,7 +18562,7 @@ yynewstate: setOpr.OrderBy = yyS[yypt-0].item.(*ast.OrderByClause) parser.yyVAL.statement = setOpr } - case 1715: + case 1755: { setOprList1 := yyS[yypt-3].item.([]ast.Node) if sel, isSelect := setOprList1[len(setOprList1)-1].(*ast.SelectStmt); isSelect && !sel.IsInBraces { @@ -18148,7 +18586,7 @@ yynewstate: setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr } - case 1716: + case 1756: { setOprList1 := yyS[yypt-4].item.([]ast.Node) if sel, isSelect := setOprList1[len(setOprList1)-1].(*ast.SelectStmt); isSelect && !sel.IsInBraces { @@ -18173,7 +18611,7 @@ yynewstate: setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr } - case 1717: + case 1757: { var setOprList []ast.Node var with *ast.WithClause @@ -18189,7 +18627,7 @@ yynewstate: setOpr.OrderBy = yyS[yypt-0].item.(*ast.OrderByClause) parser.yyVAL.statement = setOpr } - case 1718: + case 1758: { var setOprList []ast.Node var with *ast.WithClause @@ -18205,7 +18643,7 @@ yynewstate: setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr } - case 1719: + case 1759: { var setOprList []ast.Node var with *ast.WithClause @@ -18222,7 +18660,7 @@ yynewstate: setOpr.Limit = yyS[yypt-0].item.(*ast.Limit) parser.yyVAL.statement = setOpr } - case 1721: + case 1761: { setOprList1 := yyS[yypt-2].item.([]ast.Node) setOprList2 := yyS[yypt-0].item.([]ast.Node) @@ -18238,11 +18676,11 @@ yynewstate: } parser.yyVAL.item = append(setOprList1, setOprList2...) } - case 1722: + case 1762: { parser.yyVAL.item = []ast.Node{yyS[yypt-0].statement.(*ast.SelectStmt)} } - case 1723: + case 1763: { var setOprList []ast.Node switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -18253,7 +18691,7 @@ yynewstate: } parser.yyVAL.item = setOprList } - case 1724: + case 1764: { var tp ast.SetOprType tp = ast.Union @@ -18262,7 +18700,7 @@ yynewstate: } parser.yyVAL.item = &tp } - case 1725: + case 1765: { var tp ast.SetOprType tp = ast.Except @@ -18271,7 +18709,7 @@ yynewstate: } parser.yyVAL.item = &tp } - case 1726: + case 1766: { var tp ast.SetOprType tp = ast.Intersect @@ -18280,7 +18718,7 @@ yynewstate: } parser.yyVAL.item = &tp } - case 1728: + case 1768: { parser.yyVAL.statement = &ast.ChangeStmt{ NodeType: ast.PumpType, @@ -18288,7 +18726,7 @@ yynewstate: NodeID: yyS[yypt-0].ident, } } - case 1729: + case 1769: { parser.yyVAL.statement = &ast.ChangeStmt{ NodeType: ast.DrainerType, @@ -18296,19 +18734,19 @@ yynewstate: NodeID: yyS[yypt-0].ident, } } - case 1730: + case 1770: { parser.yyVAL.statement = &ast.SetStmt{Variables: yyS[yypt-0].item.([]*ast.VariableAssignment)} } - case 1731: + case 1771: { parser.yyVAL.statement = &ast.SetPwdStmt{Password: yyS[yypt-0].ident} } - case 1732: + case 1772: { parser.yyVAL.statement = &ast.SetPwdStmt{User: yyS[yypt-2].item.(*auth.UserIdentity), Password: yyS[yypt-0].ident} } - case 1733: + case 1773: { vars := yyS[yypt-0].item.([]*ast.VariableAssignment) for _, v := range vars { @@ -18316,11 +18754,11 @@ yynewstate: } parser.yyVAL.statement = &ast.SetStmt{Variables: vars} } - case 1734: + case 1774: { parser.yyVAL.statement = &ast.SetStmt{Variables: yyS[yypt-0].item.([]*ast.VariableAssignment)} } - case 1735: + case 1775: { assigns := yyS[yypt-0].item.([]*ast.VariableAssignment) for i := 0; i < len(assigns); i++ { @@ -18331,23 +18769,23 @@ yynewstate: } parser.yyVAL.statement = &ast.SetStmt{Variables: assigns} } - case 1736: + case 1776: { parser.yyVAL.statement = &ast.SetConfigStmt{Type: strings.ToLower(yyS[yypt-3].ident), Name: yyS[yypt-2].ident, Value: yyS[yypt-0].expr} } - case 1737: + case 1777: { parser.yyVAL.statement = &ast.SetConfigStmt{Instance: yyS[yypt-3].ident, Name: yyS[yypt-2].ident, Value: yyS[yypt-0].expr} } - case 1738: + case 1778: { parser.yyVAL.statement = &ast.SetSessionStatesStmt{SessionStates: yyS[yypt-0].ident} } - case 1739: + case 1779: { parser.yyVAL.statement = yyS[yypt-0].item.(*ast.SetRoleStmt) } - case 1740: + case 1780: { tmp := yyS[yypt-2].item.(*ast.SetRoleStmt) parser.yyVAL.statement = &ast.SetDefaultRoleStmt{ @@ -18356,27 +18794,27 @@ yynewstate: UserList: yyS[yypt-0].item.([]*auth.UserIdentity), } } - case 1741: + case 1781: { parser.yyVAL.item = &ast.SetRoleStmt{SetRoleOpt: ast.SetRoleNone, RoleList: nil} } - case 1742: + case 1782: { parser.yyVAL.item = &ast.SetRoleStmt{SetRoleOpt: ast.SetRoleAll, RoleList: nil} } - case 1743: + case 1783: { parser.yyVAL.item = &ast.SetRoleStmt{SetRoleOpt: ast.SetRoleRegular, RoleList: yyS[yypt-0].item.([]*auth.RoleIdentity)} } - case 1744: + case 1784: { parser.yyVAL.item = &ast.SetRoleStmt{SetRoleOpt: ast.SetRoleAllExcept, RoleList: yyS[yypt-0].item.([]*auth.RoleIdentity)} } - case 1746: + case 1786: { parser.yyVAL.item = &ast.SetRoleStmt{SetRoleOpt: ast.SetRoleDefault, RoleList: nil} } - case 1747: + case 1787: { if yyS[yypt-0].item != nil { parser.yyVAL.item = yyS[yypt-0].item @@ -18384,7 +18822,7 @@ yynewstate: parser.yyVAL.item = []*ast.VariableAssignment{} } } - case 1748: + case 1788: { if yyS[yypt-0].item != nil { varAssigns := yyS[yypt-0].item.([]*ast.VariableAssignment) @@ -18393,28 +18831,28 @@ yynewstate: parser.yyVAL.item = yyS[yypt-2].item } } - case 1749: + case 1789: { varAssigns := []*ast.VariableAssignment{} expr := ast.NewValueExpr(yyS[yypt-0].ident, parser.charset, parser.collation) varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_isolation", Value: expr, IsSystem: true}) parser.yyVAL.item = varAssigns } - case 1750: + case 1790: { varAssigns := []*ast.VariableAssignment{} expr := ast.NewValueExpr("0", parser.charset, parser.collation) varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_read_only", Value: expr, IsSystem: true}) parser.yyVAL.item = varAssigns } - case 1751: + case 1791: { varAssigns := []*ast.VariableAssignment{} expr := ast.NewValueExpr("1", parser.charset, parser.collation) varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_read_only", Value: expr, IsSystem: true}) parser.yyVAL.item = varAssigns } - case 1752: + case 1792: { varAssigns := []*ast.VariableAssignment{} asof := yyS[yypt-0].item.(*ast.AsOfClause) @@ -18423,59 +18861,59 @@ yynewstate: } parser.yyVAL.item = varAssigns } - case 1753: + case 1793: { parser.yyVAL.ident = ast.RepeatableRead } - case 1754: + case 1794: { parser.yyVAL.ident = ast.ReadCommitted } - case 1755: + case 1795: { parser.yyVAL.ident = ast.ReadUncommitted } - case 1756: + case 1796: { parser.yyVAL.ident = ast.Serializable } - case 1757: + case 1797: { parser.yyVAL.expr = ast.NewValueExpr("ON", parser.charset, parser.collation) } - case 1758: + case 1798: { parser.yyVAL.expr = ast.NewValueExpr("BINARY", parser.charset, parser.collation) } - case 1763: + case 1803: { parser.yyVAL.ident = yyS[yypt-2].ident + "." + yyS[yypt-0].ident } - case 1765: + case 1805: { parser.yyVAL.ident = yyS[yypt-2].ident + "." + yyS[yypt-0].ident } - case 1766: + case 1806: { parser.yyVAL.ident = yyS[yypt-2].ident + "-" + yyS[yypt-0].ident } - case 1767: + case 1807: { parser.yyVAL.item = &ast.VariableAssignment{Name: yyS[yypt-2].ident, Value: yyS[yypt-0].expr, IsSystem: true} } - case 1768: + case 1808: { parser.yyVAL.item = &ast.VariableAssignment{Name: yyS[yypt-2].ident, Value: yyS[yypt-0].expr, IsGlobal: true, IsSystem: true} } - case 1769: + case 1809: { parser.yyVAL.item = &ast.VariableAssignment{Name: yyS[yypt-2].ident, Value: yyS[yypt-0].expr, IsSystem: true} } - case 1770: + case 1810: { parser.yyVAL.item = &ast.VariableAssignment{Name: yyS[yypt-2].ident, Value: yyS[yypt-0].expr, IsSystem: true} } - case 1771: + case 1811: { v := strings.ToLower(yyS[yypt-2].ident) var isGlobal bool @@ -18491,27 +18929,27 @@ yynewstate: } parser.yyVAL.item = &ast.VariableAssignment{Name: v, Value: yyS[yypt-0].expr, IsGlobal: isGlobal, IsSystem: true} } - case 1772: + case 1812: { v := yyS[yypt-2].ident v = strings.TrimPrefix(v, "@") parser.yyVAL.item = &ast.VariableAssignment{Name: v, Value: yyS[yypt-0].expr} } - case 1773: + case 1813: { parser.yyVAL.item = &ast.VariableAssignment{ Name: ast.SetNames, Value: ast.NewValueExpr(yyS[yypt-0].ident, "", ""), } } - case 1774: + case 1814: { parser.yyVAL.item = &ast.VariableAssignment{ Name: ast.SetNames, Value: ast.NewValueExpr(yyS[yypt-2].ident, "", ""), } } - case 1775: + case 1815: { parser.yyVAL.item = &ast.VariableAssignment{ Name: ast.SetNames, @@ -18519,24 +18957,24 @@ yynewstate: ExtendValue: ast.NewValueExpr(yyS[yypt-0].ident, "", ""), } } - case 1776: + case 1816: { v := &ast.DefaultExpr{} parser.yyVAL.item = &ast.VariableAssignment{Name: ast.SetNames, Value: v} } - case 1777: + case 1817: { parser.yyVAL.item = &ast.VariableAssignment{Name: ast.SetCharset, Value: yyS[yypt-0].expr} } - case 1778: + case 1818: { parser.yyVAL.expr = ast.NewValueExpr(yyS[yypt-0].ident, "", "") } - case 1779: + case 1819: { parser.yyVAL.expr = &ast.DefaultExpr{} } - case 1780: + case 1820: { // Validate input charset name to keep the same behavior as parser of MySQL. cs, err := charset.GetCharsetInfo(yyS[yypt-0].ident) @@ -18548,11 +18986,11 @@ yynewstate: // to keep lower case of input for generated column restore. parser.yyVAL.ident = cs.Name } - case 1781: + case 1821: { parser.yyVAL.ident = charset.CharsetBin } - case 1782: + case 1822: { info, err := charset.GetCollationByName(yyS[yypt-0].ident) if err != nil { @@ -18561,19 +18999,19 @@ yynewstate: } parser.yyVAL.ident = info.Name } - case 1783: + case 1823: { parser.yyVAL.ident = charset.CollationBin } - case 1784: + case 1824: { parser.yyVAL.item = []*ast.VariableAssignment{yyS[yypt-0].item.(*ast.VariableAssignment)} } - case 1785: + case 1825: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.VariableAssignment), yyS[yypt-0].item.(*ast.VariableAssignment)) } - case 1788: + case 1828: { v := strings.ToLower(yyS[yypt-0].ident) var isGlobal bool @@ -18590,89 +19028,89 @@ yynewstate: } parser.yyVAL.expr = &ast.VariableExpr{Name: v, IsGlobal: isGlobal, IsSystem: true, ExplicitScope: explicitScope} } - case 1789: + case 1829: { v := yyS[yypt-0].ident v = strings.TrimPrefix(v, "@") parser.yyVAL.expr = &ast.VariableExpr{Name: v, IsGlobal: false, IsSystem: false} } - case 1790: + case 1830: { parser.yyVAL.item = &auth.UserIdentity{Username: yyS[yypt-0].ident, Hostname: "%"} } - case 1791: + case 1831: { parser.yyVAL.item = &auth.UserIdentity{Username: yyS[yypt-2].ident, Hostname: strings.ToLower(yyS[yypt-0].ident)} } - case 1792: + case 1832: { parser.yyVAL.item = &auth.UserIdentity{Username: yyS[yypt-1].ident, Hostname: strings.ToLower(strings.TrimPrefix(yyS[yypt-0].ident, "@"))} } - case 1793: + case 1833: { parser.yyVAL.item = &auth.UserIdentity{CurrentUser: true} } - case 1794: + case 1834: { parser.yyVAL.item = []*auth.UserIdentity{yyS[yypt-0].item.(*auth.UserIdentity)} } - case 1795: + case 1835: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*auth.UserIdentity), yyS[yypt-0].item.(*auth.UserIdentity)) } - case 1797: + case 1837: { parser.yyVAL.ident = yyS[yypt-1].ident } - case 1801: + case 1841: { parser.yyVAL.item = &auth.RoleIdentity{Username: yyS[yypt-2].ident, Hostname: strings.ToLower(yyS[yypt-0].ident)} } - case 1802: + case 1842: { parser.yyVAL.item = &auth.RoleIdentity{Username: yyS[yypt-1].ident, Hostname: strings.ToLower(strings.TrimPrefix(yyS[yypt-0].ident, "@"))} } - case 1803: + case 1843: { parser.yyVAL.item = &auth.RoleIdentity{Username: yyS[yypt-0].ident, Hostname: "%"} } - case 1804: + case 1844: { parser.yyVAL.item = yyS[yypt-0].item } - case 1805: + case 1845: { parser.yyVAL.item = &auth.RoleIdentity{Username: yyS[yypt-0].ident, Hostname: "%"} } - case 1806: + case 1846: { parser.yyVAL.item = yyS[yypt-0].item } - case 1807: + case 1847: { parser.yyVAL.item = []*auth.RoleIdentity{yyS[yypt-0].item.(*auth.RoleIdentity)} } - case 1808: + case 1848: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*auth.RoleIdentity), yyS[yypt-0].item.(*auth.RoleIdentity)) } - case 1809: + case 1849: { parser.yyVAL.item = &ast.LimitSimple{Offset: 0, Count: yyS[yypt-0].item.(uint64)} } - case 1810: + case 1850: { parser.yyVAL.item = &ast.LimitSimple{Offset: yyS[yypt-2].item.(uint64), Count: yyS[yypt-0].item.(uint64)} } - case 1811: + case 1851: { parser.yyVAL.item = &ast.LimitSimple{Offset: yyS[yypt-0].item.(uint64), Count: yyS[yypt-2].item.(uint64)} } - case 1812: + case 1852: { parser.yyVAL.statement = &ast.AdminStmt{Tp: ast.AdminShowDDL} } - case 1813: + case 1853: { stmt := &ast.AdminStmt{Tp: ast.AdminShowDDLJobs} if yyS[yypt-0].item != nil { @@ -18680,7 +19118,7 @@ yynewstate: } parser.yyVAL.statement = stmt } - case 1814: + case 1854: { stmt := &ast.AdminStmt{ Tp: ast.AdminShowDDLJobs, @@ -18691,21 +19129,21 @@ yynewstate: } parser.yyVAL.statement = stmt } - case 1815: + case 1855: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminShowNextRowID, Tables: []*ast.TableName{yyS[yypt-1].item.(*ast.TableName)}, } } - case 1816: + case 1856: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminCheckTable, Tables: yyS[yypt-0].item.([]*ast.TableName), } } - case 1817: + case 1857: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminCheckIndex, @@ -18713,7 +19151,7 @@ yynewstate: Index: string(yyS[yypt-0].ident), } } - case 1818: + case 1858: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminRecoverIndex, @@ -18721,7 +19159,7 @@ yynewstate: Index: string(yyS[yypt-0].ident), } } - case 1819: + case 1859: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminCleanupIndex, @@ -18729,7 +19167,7 @@ yynewstate: Index: string(yyS[yypt-0].ident), } } - case 1820: + case 1860: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminCheckIndexRange, @@ -18738,28 +19176,28 @@ yynewstate: HandleRanges: yyS[yypt-0].item.([]ast.HandleRange), } } - case 1821: + case 1861: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminChecksumTable, Tables: yyS[yypt-0].item.([]*ast.TableName), } } - case 1822: + case 1862: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminCancelDDLJobs, JobIDs: yyS[yypt-0].item.([]int64), } } - case 1823: + case 1863: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminShowDDLJobQueries, JobIDs: yyS[yypt-0].item.([]int64), } } - case 1824: + case 1864: { ret := &ast.AdminStmt{ Tp: ast.AdminShowDDLJobQueriesWithRange, @@ -18768,115 +19206,115 @@ yynewstate: ret.LimitSimple.Offset = yyS[yypt-0].item.(*ast.LimitSimple).Offset parser.yyVAL.statement = ret } - case 1825: + case 1865: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminShowSlow, ShowSlow: yyS[yypt-0].item.(*ast.ShowSlow), } } - case 1826: + case 1866: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminReloadExprPushdownBlacklist, } } - case 1827: + case 1867: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminReloadOptRuleBlacklist, } } - case 1828: + case 1868: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminPluginEnable, Plugins: yyS[yypt-0].item.([]string), } } - case 1829: + case 1869: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminPluginDisable, Plugins: yyS[yypt-0].item.([]string), } } - case 1830: + case 1870: { parser.yyVAL.statement = &ast.CleanupTableLockStmt{ Tables: yyS[yypt-0].item.([]*ast.TableName), } } - case 1831: + case 1871: { parser.yyVAL.statement = &ast.RepairTableStmt{ Table: yyS[yypt-1].item.(*ast.TableName), CreateStmt: yyS[yypt-0].statement.(*ast.CreateTableStmt), } } - case 1832: + case 1872: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminFlushBindings, } } - case 1833: + case 1873: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminCaptureBindings, } } - case 1834: + case 1874: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminEvolveBindings, } } - case 1835: + case 1875: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminReloadBindings, } } - case 1836: + case 1876: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminReloadStatistics, } } - case 1837: + case 1877: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminReloadStatistics, } } - case 1838: + case 1878: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminShowTelemetry, } } - case 1839: + case 1879: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminResetTelemetryID, } } - case 1840: + case 1880: { parser.yyVAL.statement = &ast.AdminStmt{ Tp: ast.AdminFlushPlanCache, StatementScope: yyS[yypt-1].item.(ast.StatementScope), } } - case 1841: + case 1881: { parser.yyVAL.item = &ast.ShowSlow{ Tp: ast.ShowSlowRecent, Count: getUint64FromNUM(yyS[yypt-0].item), } } - case 1842: + case 1882: { parser.yyVAL.item = &ast.ShowSlow{ Tp: ast.ShowSlowTop, @@ -18884,7 +19322,7 @@ yynewstate: Count: getUint64FromNUM(yyS[yypt-0].item), } } - case 1843: + case 1883: { parser.yyVAL.item = &ast.ShowSlow{ Tp: ast.ShowSlowTop, @@ -18892,7 +19330,7 @@ yynewstate: Count: getUint64FromNUM(yyS[yypt-0].item), } } - case 1844: + case 1884: { parser.yyVAL.item = &ast.ShowSlow{ Tp: ast.ShowSlowTop, @@ -18900,27 +19338,27 @@ yynewstate: Count: getUint64FromNUM(yyS[yypt-0].item), } } - case 1845: + case 1885: { parser.yyVAL.item = []ast.HandleRange{yyS[yypt-0].item.(ast.HandleRange)} } - case 1846: + case 1886: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.HandleRange), yyS[yypt-0].item.(ast.HandleRange)) } - case 1847: + case 1887: { parser.yyVAL.item = ast.HandleRange{Begin: yyS[yypt-3].item.(int64), End: yyS[yypt-1].item.(int64)} } - case 1848: + case 1888: { parser.yyVAL.item = []int64{yyS[yypt-0].item.(int64)} } - case 1849: + case 1889: { parser.yyVAL.item = append(yyS[yypt-2].item.([]int64), yyS[yypt-0].item.(int64)) } - case 1850: + case 1890: { stmt := yyS[yypt-1].item.(*ast.ShowStmt) if yyS[yypt-0].item != nil { @@ -18932,21 +19370,21 @@ yynewstate: } parser.yyVAL.statement = stmt } - case 1851: + case 1891: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowCreateTable, Table: yyS[yypt-0].item.(*ast.TableName), } } - case 1852: + case 1892: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowCreateView, Table: yyS[yypt-0].item.(*ast.TableName), } } - case 1853: + case 1893: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowCreateDatabase, @@ -18954,21 +19392,28 @@ yynewstate: DBName: yyS[yypt-0].ident, } } - case 1854: + case 1894: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowCreateSequence, Table: yyS[yypt-0].item.(*ast.TableName), } } - case 1855: + case 1895: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowCreatePlacementPolicy, DBName: yyS[yypt-0].ident, } } - case 1856: + case 1896: + { + parser.yyVAL.statement = &ast.ShowStmt{ + Tp: ast.ShowCreateResourceGroup, + ResourceGroupName: yyS[yypt-0].ident, + } + } + case 1897: { // See https://dev.mysql.com/doc/refman/5.7/en/show-create-user.html parser.yyVAL.statement = &ast.ShowStmt{ @@ -18976,14 +19421,14 @@ yynewstate: User: yyS[yypt-0].item.(*auth.UserIdentity), } } - case 1857: + case 1898: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowCreateImport, DBName: yyS[yypt-0].ident, // we reuse DBName of ShowStmt } } - case 1858: + case 1899: { stmt := &ast.ShowStmt{ Tp: ast.ShowRegions, @@ -18995,14 +19440,14 @@ yynewstate: } parser.yyVAL.statement = stmt } - case 1859: + case 1900: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowTableNextRowId, Table: yyS[yypt-1].item.(*ast.TableName), } } - case 1860: + case 1901: { stmt := &ast.ShowStmt{ Tp: ast.ShowRegions, @@ -19015,12 +19460,12 @@ yynewstate: } parser.yyVAL.statement = stmt } - case 1861: + case 1902: { // See https://dev.mysql.com/doc/refman/5.7/en/show-grants.html parser.yyVAL.statement = &ast.ShowStmt{Tp: ast.ShowGrants} } - case 1862: + case 1903: { // See https://dev.mysql.com/doc/refman/5.7/en/show-grants.html if yyS[yypt-0].item != nil { @@ -19037,26 +19482,26 @@ yynewstate: } } } - case 1863: + case 1904: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowMasterStatus, } } - case 1864: + case 1905: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowProcessList, Full: yyS[yypt-1].item.(bool), } } - case 1865: + case 1906: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowProfiles, } } - case 1866: + case 1907: { v := &ast.ShowStmt{ Tp: ast.ShowProfile, @@ -19072,37 +19517,37 @@ yynewstate: } parser.yyVAL.statement = v } - case 1867: + case 1908: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowPrivileges, } } - case 1868: + case 1909: { parser.yyVAL.statement = &ast.ShowStmt{ Tp: ast.ShowBuiltins, } } - case 1869: + case 1910: { parser.yyVAL.statement = yyS[yypt-0].item.(*ast.ShowStmt) } - case 1870: + case 1911: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowPlacementForDatabase, DBName: yyS[yypt-0].ident, } } - case 1871: + case 1912: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowPlacementForTable, Table: yyS[yypt-0].item.(*ast.TableName), } } - case 1872: + case 1913: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowPlacementForPartition, @@ -19110,90 +19555,90 @@ yynewstate: Partition: model.NewCIStr(yyS[yypt-0].ident), } } - case 1873: + case 1914: { parser.yyVAL.item = nil } - case 1875: + case 1916: { parser.yyVAL.item = []int{yyS[yypt-0].item.(int)} } - case 1876: + case 1917: { l := yyS[yypt-2].item.([]int) l = append(l, yyS[yypt-0].item.(int)) parser.yyVAL.item = l } - case 1877: + case 1918: { parser.yyVAL.item = ast.ProfileTypeCPU } - case 1878: + case 1919: { parser.yyVAL.item = ast.ProfileTypeMemory } - case 1879: + case 1920: { parser.yyVAL.item = ast.ProfileTypeBlockIo } - case 1880: + case 1921: { parser.yyVAL.item = ast.ProfileTypeContextSwitch } - case 1881: + case 1922: { parser.yyVAL.item = ast.ProfileTypePageFaults } - case 1882: + case 1923: { parser.yyVAL.item = ast.ProfileTypeIpc } - case 1883: + case 1924: { parser.yyVAL.item = ast.ProfileTypeSwaps } - case 1884: + case 1925: { parser.yyVAL.item = ast.ProfileTypeSource } - case 1885: + case 1926: { parser.yyVAL.item = ast.ProfileTypeAll } - case 1886: + case 1927: { parser.yyVAL.item = nil } - case 1887: + case 1928: { v := yyS[yypt-0].item.(int64) parser.yyVAL.item = &v } - case 1888: + case 1929: { parser.yyVAL.item = nil } - case 1889: + case 1930: { parser.yyVAL.item = yyS[yypt-0].item.([]*auth.RoleIdentity) } - case 1895: + case 1936: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowEngines} } - case 1896: + case 1937: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowDatabases} } - case 1897: + case 1938: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowConfig} } - case 1898: + case 1939: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowCharset} } - case 1899: + case 1940: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowTables, @@ -19201,28 +19646,28 @@ yynewstate: Full: yyS[yypt-2].item.(bool), } } - case 1900: + case 1941: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowOpenTables, DBName: yyS[yypt-0].ident, } } - case 1901: + case 1942: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowTableStatus, DBName: yyS[yypt-0].ident, } } - case 1902: + case 1943: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowIndex, Table: yyS[yypt-0].item.(*ast.TableName), } } - case 1903: + case 1944: { show := &ast.ShowStmt{ Tp: ast.ShowIndex, @@ -19230,7 +19675,7 @@ yynewstate: } parser.yyVAL.item = show } - case 1904: + case 1945: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowColumns, @@ -19239,7 +19684,7 @@ yynewstate: Full: yyS[yypt-3].item.(bool), } } - case 1905: + case 1946: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowColumns, @@ -19249,81 +19694,81 @@ yynewstate: Extended: true, } } - case 1906: + case 1947: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowWarnings, CountWarningsOrErrors: true} } - case 1907: + case 1948: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowWarnings} } - case 1908: + case 1949: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowErrors, CountWarningsOrErrors: true} } - case 1909: + case 1950: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowErrors} } - case 1910: + case 1951: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowVariables, GlobalScope: yyS[yypt-1].item.(bool), } } - case 1911: + case 1952: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowStatus, GlobalScope: yyS[yypt-1].item.(bool), } } - case 1912: + case 1953: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowBindings, GlobalScope: yyS[yypt-1].item.(bool), } } - case 1913: + case 1954: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowCollation, } } - case 1914: + case 1955: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowTriggers, DBName: yyS[yypt-0].ident, } } - case 1915: + case 1956: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowBindingCacheStatus, } } - case 1916: + case 1957: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowProcedureStatus, } } - case 1917: + case 1958: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowPumpStatus, } } - case 1918: + case 1959: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowDrainerStatus, } } - case 1919: + case 1960: { // This statement is similar to SHOW PROCEDURE STATUS but for stored functions. // See http://dev.mysql.com/doc/refman/5.7/en/show-function-status.html @@ -19333,189 +19778,193 @@ yynewstate: Tp: ast.ShowProcedureStatus, } } - case 1920: + case 1961: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowEvents, DBName: yyS[yypt-0].ident, } } - case 1921: + case 1962: { parser.yyVAL.item = &ast.ShowStmt{ Tp: ast.ShowPlugins, } } - case 1922: + case 1963: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowSessionStates} } - case 1923: + case 1964: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowStatsExtended} } - case 1924: + case 1965: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowStatsMeta, Table: &ast.TableName{Name: model.NewCIStr("STATS_META"), Schema: model.NewCIStr(mysql.SystemDB)}} } - case 1925: + case 1966: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowStatsHistograms, Table: &ast.TableName{Name: model.NewCIStr("STATS_HISTOGRAMS"), Schema: model.NewCIStr(mysql.SystemDB)}} } - case 1926: + case 1967: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowStatsTopN} } - case 1927: + case 1968: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowStatsBuckets, Table: &ast.TableName{Name: model.NewCIStr("STATS_BUCKETS"), Schema: model.NewCIStr(mysql.SystemDB)}} } - case 1928: + case 1969: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowStatsHealthy} } - case 1929: + case 1970: + { + parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowStatsLocked, Table: &ast.TableName{Name: model.NewCIStr("STATS_TABLE_LOCKED"), Schema: model.NewCIStr(mysql.SystemDB)}} + } + case 1971: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowHistogramsInFlight} } - case 1930: + case 1972: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowColumnStatsUsage} } - case 1931: + case 1973: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowAnalyzeStatus} } - case 1932: + case 1974: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowBackups} } - case 1933: + case 1975: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowRestores} } - case 1934: + case 1976: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowImports} } - case 1935: + case 1977: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowPlacement} } - case 1936: + case 1978: { parser.yyVAL.item = &ast.ShowStmt{Tp: ast.ShowPlacementLabels} } - case 1937: + case 1979: { parser.yyVAL.item = nil } - case 1938: + case 1980: { parser.yyVAL.item = &ast.PatternLikeExpr{ Pattern: yyS[yypt-0].expr, Escape: '\\', } } - case 1939: + case 1981: { parser.yyVAL.item = yyS[yypt-0].expr } - case 1940: + case 1982: { parser.yyVAL.item = false } - case 1941: + case 1983: { parser.yyVAL.item = true } - case 1942: + case 1984: { parser.yyVAL.item = false } - case 1943: + case 1985: { parser.yyVAL.item = ast.StatementScopeSession } - case 1944: + case 1986: { parser.yyVAL.item = ast.StatementScopeGlobal } - case 1945: + case 1987: { parser.yyVAL.item = ast.StatementScopeInstance } - case 1946: + case 1988: { parser.yyVAL.item = ast.StatementScopeSession } - case 1947: + case 1989: { parser.yyVAL.item = false } - case 1948: + case 1990: { parser.yyVAL.item = true } - case 1949: + case 1991: { parser.yyVAL.ident = "" } - case 1950: + case 1992: { parser.yyVAL.ident = yyS[yypt-0].ident } - case 1951: + case 1993: { parser.yyVAL.item = yyS[yypt-0].item.(*ast.TableName) } - case 1952: + case 1994: { tmp := yyS[yypt-0].item.(*ast.FlushStmt) tmp.NoWriteToBinLog = yyS[yypt-1].item.(bool) parser.yyVAL.statement = tmp } - case 1953: + case 1995: { parser.yyVAL.item = []string{yyS[yypt-0].ident} } - case 1954: + case 1996: { parser.yyVAL.item = append(yyS[yypt-2].item.([]string), yyS[yypt-0].ident) } - case 1955: + case 1997: { parser.yyVAL.item = &ast.FlushStmt{ Tp: ast.FlushPrivileges, } } - case 1956: + case 1998: { parser.yyVAL.item = &ast.FlushStmt{ Tp: ast.FlushStatus, } } - case 1957: + case 1999: { parser.yyVAL.item = &ast.FlushStmt{ Tp: ast.FlushTiDBPlugin, Plugins: yyS[yypt-0].item.([]string), } } - case 1958: + case 2000: { parser.yyVAL.item = &ast.FlushStmt{ Tp: ast.FlushHosts, } } - case 1959: + case 2001: { parser.yyVAL.item = &ast.FlushStmt{ Tp: ast.FlushLogs, LogType: yyS[yypt-1].item.(ast.LogType), } } - case 1960: + case 2002: { parser.yyVAL.item = &ast.FlushStmt{ Tp: ast.FlushTables, @@ -19523,69 +19972,69 @@ yynewstate: ReadLock: yyS[yypt-0].item.(bool), } } - case 1961: + case 2003: { parser.yyVAL.item = &ast.FlushStmt{ Tp: ast.FlushClientErrorsSummary, } } - case 1962: + case 2004: { parser.yyVAL.item = ast.LogTypeDefault } - case 1963: + case 2005: { parser.yyVAL.item = ast.LogTypeBinary } - case 1964: + case 2006: { parser.yyVAL.item = ast.LogTypeEngine } - case 1965: + case 2007: { parser.yyVAL.item = ast.LogTypeError } - case 1966: + case 2008: { parser.yyVAL.item = ast.LogTypeGeneral } - case 1967: + case 2009: { parser.yyVAL.item = ast.LogTypeSlow } - case 1968: + case 2010: { parser.yyVAL.item = false } - case 1969: + case 2011: { parser.yyVAL.item = true } - case 1970: + case 2012: { parser.yyVAL.item = true } - case 1971: + case 2013: { parser.yyVAL.item = []*ast.TableName{} } - case 1973: + case 2015: { parser.yyVAL.item = []*ast.TableName{} } - case 1974: + case 2016: { parser.yyVAL.item = yyS[yypt-0].item } - case 1975: + case 2017: { parser.yyVAL.item = false } - case 1976: + case 2018: { parser.yyVAL.item = true } - case 2048: + case 2096: { var sel ast.StmtNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -19598,7 +20047,7 @@ yynewstate: } parser.yyVAL.statement = sel } - case 2074: + case 2122: { var sel ast.StmtNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -19611,7 +20060,7 @@ yynewstate: } parser.yyVAL.statement = sel } - case 2090: + case 2138: { var sel ast.StmtNode switch x := yyS[yypt-0].expr.(*ast.SubqueryExpr).Query.(type) { @@ -19624,7 +20073,7 @@ yynewstate: } parser.yyVAL.statement = sel } - case 2092: + case 2140: { if yyS[yypt-0].statement != nil { s := yyS[yypt-0].statement @@ -19634,7 +20083,7 @@ yynewstate: parser.result = append(parser.result, s) } } - case 2093: + case 2141: { if yyS[yypt-0].statement != nil { s := yyS[yypt-0].statement @@ -19644,7 +20093,7 @@ yynewstate: parser.result = append(parser.result, s) } } - case 2094: + case 2142: { cst := yyS[yypt-0].item.(*ast.Constraint) if yyS[yypt-1].item != nil { @@ -19653,7 +20102,7 @@ yynewstate: } parser.yyVAL.item = cst } - case 2099: + case 2147: { if yyS[yypt-0].item != nil { parser.yyVAL.item = []interface{}{yyS[yypt-0].item.(interface{})} @@ -19661,7 +20110,7 @@ yynewstate: parser.yyVAL.item = []interface{}{} } } - case 2100: + case 2148: { if yyS[yypt-0].item != nil { parser.yyVAL.item = append(yyS[yypt-2].item.([]interface{}), yyS[yypt-0].item) @@ -19669,7 +20118,7 @@ yynewstate: parser.yyVAL.item = yyS[yypt-2].item } } - case 2101: + case 2149: { var columnDefs []*ast.ColumnDef var constraints []*ast.Constraint @@ -19678,7 +20127,7 @@ yynewstate: Constraints: constraints, } } - case 2102: + case 2150: { tes := yyS[yypt-1].item.([]interface{}) var columnDefs []*ast.ColumnDef @@ -19696,69 +20145,69 @@ yynewstate: Constraints: constraints, } } - case 2104: + case 2152: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionCharset, StrValue: yyS[yypt-0].ident, UintValue: ast.TableOptionCharsetWithoutConvertTo} } - case 2105: + case 2153: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: yyS[yypt-0].ident, UintValue: ast.TableOptionCharsetWithoutConvertTo} } - case 2106: + case 2154: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionAutoIncrement, UintValue: yyS[yypt-0].item.(uint64), BoolValue: yyS[yypt-3].item.(bool)} } - case 2107: + case 2155: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionAutoIdCache, UintValue: yyS[yypt-0].item.(uint64)} } - case 2108: + case 2156: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionAutoRandomBase, UintValue: yyS[yypt-0].item.(uint64), BoolValue: yyS[yypt-3].item.(bool)} } - case 2109: + case 2157: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionAvgRowLength, UintValue: yyS[yypt-0].item.(uint64)} } - case 2110: + case 2158: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionConnection, StrValue: yyS[yypt-0].ident} } - case 2111: + case 2159: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionCheckSum, UintValue: yyS[yypt-0].item.(uint64)} } - case 2112: + case 2160: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionTableCheckSum, UintValue: yyS[yypt-0].item.(uint64)} } - case 2113: + case 2161: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionPassword, StrValue: yyS[yypt-0].ident} } - case 2114: + case 2162: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionCompression, StrValue: yyS[yypt-0].ident} } - case 2115: + case 2163: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionKeyBlockSize, UintValue: yyS[yypt-0].item.(uint64)} } - case 2116: + case 2164: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionDelayKeyWrite, UintValue: yyS[yypt-0].item.(uint64)} } - case 2117: + case 2165: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionRowFormat, UintValue: yyS[yypt-0].item.(uint64)} } - case 2118: + case 2166: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} } - case 2119: + case 2167: { n := yyS[yypt-0].item.(uint64) if n != 0 && n != 1 { @@ -19769,13 +20218,13 @@ yynewstate: yylex.AppendError(yylex.Errorf("The STATS_AUTO_RECALC is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 2120: + case 2168: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionStatsAutoRecalc, Default: true} yylex.AppendError(yylex.Errorf("The STATS_AUTO_RECALC is parsed but ignored by all storage engines.")) parser.lastErrorAsWarn() } - case 2121: + case 2169: { // Parse it but will ignore it. // In MySQL, STATS_SAMPLE_PAGES=N(Where 0 1 { @@ -21503,7 +22094,7 @@ yynewstate: OptEnclosed: true, } } - case 2443: + case 2511: { str := yyS[yypt-0].ident if str != "\\" && len(str) > 1 { @@ -21515,7 +22106,7 @@ yynewstate: Value: str, } } - case 2444: + case 2512: { str := yyS[yypt-0].ident if str != "\\" && len(str) > 1 { @@ -21527,147 +22118,147 @@ yynewstate: Value: str, } } - case 2446: + case 2514: { parser.yyVAL.ident = yyS[yypt-0].item.(ast.BinaryLiteral).ToString() } - case 2447: + case 2515: { parser.yyVAL.ident = yyS[yypt-0].item.(ast.BinaryLiteral).ToString() } - case 2448: + case 2516: { parser.yyVAL.item = &ast.LinesClause{Terminated: "\n"} } - case 2449: + case 2517: { parser.yyVAL.item = &ast.LinesClause{Starting: yyS[yypt-1].ident, Terminated: yyS[yypt-0].ident} } - case 2450: + case 2518: { parser.yyVAL.ident = "" } - case 2451: + case 2519: { parser.yyVAL.ident = yyS[yypt-0].ident } - case 2452: + case 2520: { parser.yyVAL.ident = "\n" } - case 2453: + case 2521: { parser.yyVAL.ident = yyS[yypt-0].ident } - case 2454: + case 2522: { parser.yyVAL.item = nil } - case 2455: + case 2523: { parser.yyVAL.item = yyS[yypt-0].item } - case 2456: + case 2524: { l := yyS[yypt-2].item.([]*ast.Assignment) parser.yyVAL.item = append(l, yyS[yypt-0].item.(*ast.Assignment)) } - case 2457: + case 2525: { parser.yyVAL.item = []*ast.Assignment{yyS[yypt-0].item.(*ast.Assignment)} } - case 2458: + case 2526: { parser.yyVAL.item = &ast.Assignment{ Column: yyS[yypt-2].expr.(*ast.ColumnNameExpr).Name, Expr: yyS[yypt-0].expr, } } - case 2459: + case 2527: { parser.yyVAL.statement = &ast.UnlockTablesStmt{} } - case 2460: + case 2528: { parser.yyVAL.statement = &ast.LockTablesStmt{ TableLocks: yyS[yypt-0].item.([]ast.TableLock), } } - case 2463: + case 2531: { parser.yyVAL.item = ast.TableLock{ Table: yyS[yypt-1].item.(*ast.TableName), Type: yyS[yypt-0].item.(model.TableLockType), } } - case 2464: + case 2532: { parser.yyVAL.item = model.TableLockRead } - case 2465: + case 2533: { parser.yyVAL.item = model.TableLockReadLocal } - case 2466: + case 2534: { parser.yyVAL.item = model.TableLockWrite } - case 2467: + case 2535: { parser.yyVAL.item = model.TableLockWriteLocal } - case 2468: + case 2536: { parser.yyVAL.item = []ast.TableLock{yyS[yypt-0].item.(ast.TableLock)} } - case 2469: + case 2537: { parser.yyVAL.item = append(yyS[yypt-2].item.([]ast.TableLock), yyS[yypt-0].item.(ast.TableLock)) } - case 2470: + case 2538: { - parser.yyVAL.statement = &ast.NonTransactionalDeleteStmt{ + parser.yyVAL.statement = &ast.NonTransactionalDMLStmt{ DryRun: yyS[yypt-1].item.(int), ShardColumn: yyS[yypt-4].item.(*ast.ColumnName), Limit: getUint64FromNUM(yyS[yypt-2].item), - DeleteStmt: yyS[yypt-0].statement.(*ast.DeleteStmt), + DMLStmt: yyS[yypt-0].statement.(ast.ShardableDMLStmt), } } - case 2471: + case 2543: { parser.yyVAL.item = ast.NoDryRun } - case 2472: + case 2544: { parser.yyVAL.item = ast.DryRunSplitDml } - case 2473: + case 2545: { parser.yyVAL.item = ast.DryRunQuery } - case 2474: + case 2546: { parser.yyVAL.item = (*ast.ColumnName)(nil) } - case 2475: + case 2547: { parser.yyVAL.item = yyS[yypt-0].item.(*ast.ColumnName) } - case 2476: + case 2548: { parser.yyVAL.statement = &ast.KillStmt{ ConnectionID: getUint64FromNUM(yyS[yypt-0].item), TiDBExtension: yyS[yypt-1].item.(bool), } } - case 2477: + case 2549: { parser.yyVAL.statement = &ast.KillStmt{ ConnectionID: getUint64FromNUM(yyS[yypt-0].item), TiDBExtension: yyS[yypt-2].item.(bool), } } - case 2478: + case 2550: { parser.yyVAL.statement = &ast.KillStmt{ ConnectionID: getUint64FromNUM(yyS[yypt-0].item), @@ -21675,28 +22266,70 @@ yynewstate: TiDBExtension: yyS[yypt-2].item.(bool), } } - case 2479: + case 2551: + { + parser.yyVAL.statement = &ast.KillStmt{ + TiDBExtension: yyS[yypt-1].item.(bool), + Expr: yyS[yypt-0].expr, + } + } + case 2552: { parser.yyVAL.item = false } - case 2480: + case 2553: { parser.yyVAL.item = true } - case 2481: + case 2554: { parser.yyVAL.statement = &ast.LoadStatsStmt{ Path: yyS[yypt-0].ident, } } - case 2482: + case 2555: + { + parser.yyVAL.statement = &ast.LockStatsStmt{ + Tables: yyS[yypt-0].item.([]*ast.TableName), + } + } + case 2556: + { + parser.yyVAL.statement = &ast.UnlockStatsStmt{ + Tables: yyS[yypt-0].item.([]*ast.TableName), + } + } + case 2557: { parser.yyVAL.statement = &ast.DropPlacementPolicyStmt{ IfExists: yyS[yypt-1].item.(bool), PolicyName: model.NewCIStr(yyS[yypt-0].ident), } } - case 2483: + case 2558: + { + parser.yyVAL.statement = &ast.CreateResourceGroupStmt{ + IfNotExists: yyS[yypt-2].item.(bool), + ResourceGroupName: model.NewCIStr(yyS[yypt-1].ident), + ResourceGroupOptionList: yyS[yypt-0].item.([]*ast.ResourceGroupOption), + } + } + case 2559: + { + parser.yyVAL.statement = &ast.AlterResourceGroupStmt{ + IfExists: yyS[yypt-2].item.(bool), + ResourceGroupName: model.NewCIStr(yyS[yypt-1].ident), + ResourceGroupOptionList: yyS[yypt-0].item.([]*ast.ResourceGroupOption), + } + } + case 2560: + { + parser.yyVAL.statement = &ast.DropResourceGroupStmt{ + IfExists: yyS[yypt-1].item.(bool), + ResourceGroupName: model.NewCIStr(yyS[yypt-0].ident), + } + } + case 2561: { parser.yyVAL.statement = &ast.CreatePlacementPolicyStmt{ OrReplace: yyS[yypt-5].item.(bool), @@ -21705,7 +22338,7 @@ yynewstate: PlacementOptions: yyS[yypt-0].item.([]*ast.PlacementOption), } } - case 2484: + case 2562: { parser.yyVAL.statement = &ast.AlterPlacementPolicyStmt{ IfExists: yyS[yypt-2].item.(bool), @@ -21713,7 +22346,7 @@ yynewstate: PlacementOptions: yyS[yypt-0].item.([]*ast.PlacementOption), } } - case 2485: + case 2563: { parser.yyVAL.statement = &ast.CreateSequenceStmt{ IfNotExists: yyS[yypt-3].item.(bool), @@ -21722,87 +22355,87 @@ yynewstate: TblOptions: yyS[yypt-0].item.([]*ast.TableOption), } } - case 2486: + case 2564: { parser.yyVAL.item = []*ast.SequenceOption{} } - case 2488: + case 2566: { parser.yyVAL.item = []*ast.SequenceOption{yyS[yypt-0].item.(*ast.SequenceOption)} } - case 2489: + case 2567: { parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.SequenceOption), yyS[yypt-0].item.(*ast.SequenceOption)) } - case 2490: + case 2568: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceOptionIncrementBy, IntValue: yyS[yypt-0].item.(int64)} } - case 2491: + case 2569: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceOptionIncrementBy, IntValue: yyS[yypt-0].item.(int64)} } - case 2492: + case 2570: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceStartWith, IntValue: yyS[yypt-0].item.(int64)} } - case 2493: + case 2571: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceStartWith, IntValue: yyS[yypt-0].item.(int64)} } - case 2494: + case 2572: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceMinValue, IntValue: yyS[yypt-0].item.(int64)} } - case 2495: + case 2573: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoMinValue} } - case 2496: + case 2574: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoMinValue} } - case 2497: + case 2575: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceMaxValue, IntValue: yyS[yypt-0].item.(int64)} } - case 2498: + case 2576: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoMaxValue} } - case 2499: + case 2577: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoMaxValue} } - case 2500: + case 2578: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceCache, IntValue: yyS[yypt-0].item.(int64)} } - case 2501: + case 2579: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoCache} } - case 2502: + case 2580: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoCache} } - case 2503: + case 2581: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceCycle} } - case 2504: + case 2582: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoCycle} } - case 2505: + case 2583: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceNoCycle} } - case 2507: + case 2585: { parser.yyVAL.item = yyS[yypt-0].item } - case 2508: + case 2586: { unsigned_num := getUint64FromNUM(yyS[yypt-0].item) if unsigned_num > 9223372036854775808 { @@ -21815,14 +22448,14 @@ yynewstate: parser.yyVAL.item = -int64(unsigned_num) } } - case 2509: + case 2587: { parser.yyVAL.statement = &ast.DropSequenceStmt{ IfExists: yyS[yypt-1].item.(bool), Sequences: yyS[yypt-0].item.([]*ast.TableName), } } - case 2510: + case 2588: { parser.yyVAL.statement = &ast.AlterSequenceStmt{ IfExists: yyS[yypt-2].item.(bool), @@ -21830,27 +22463,27 @@ yynewstate: SeqOptions: yyS[yypt-0].item.([]*ast.SequenceOption), } } - case 2511: + case 2589: { parser.yyVAL.item = []*ast.SequenceOption{yyS[yypt-0].item.(*ast.SequenceOption)} } - case 2512: + case 2590: { parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.SequenceOption), yyS[yypt-0].item.(*ast.SequenceOption)) } - case 2514: + case 2592: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceRestart} } - case 2515: + case 2593: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceRestartWith, IntValue: yyS[yypt-0].item.(int64)} } - case 2516: + case 2594: { parser.yyVAL.item = &ast.SequenceOption{Tp: ast.SequenceRestartWith, IntValue: yyS[yypt-0].item.(int64)} } - case 2517: + case 2595: { x := &ast.IndexAdviseStmt{ Path: yyS[yypt-3].ident, @@ -21867,42 +22500,42 @@ yynewstate: } parser.yyVAL.statement = x } - case 2518: + case 2596: { parser.yyVAL.item = uint64(ast.UnspecifiedSize) } - case 2519: + case 2597: { parser.yyVAL.item = getUint64FromNUM(yyS[yypt-0].item) } - case 2520: + case 2598: { parser.yyVAL.item = nil } - case 2521: + case 2599: { parser.yyVAL.item = &ast.MaxIndexNumClause{ PerTable: yyS[yypt-1].item.(uint64), PerDB: yyS[yypt-0].item.(uint64), } } - case 2522: + case 2600: { parser.yyVAL.item = uint64(ast.UnspecifiedSize) } - case 2523: + case 2601: { parser.yyVAL.item = getUint64FromNUM(yyS[yypt-0].item) } - case 2524: + case 2602: { parser.yyVAL.item = uint64(ast.UnspecifiedSize) } - case 2525: + case 2603: { parser.yyVAL.item = getUint64FromNUM(yyS[yypt-0].item) } - case 2526: + case 2604: { // Parse it but will ignore it switch yyS[yypt-0].ident { @@ -21917,19 +22550,19 @@ yynewstate: } parser.yyVAL.ident = yyS[yypt-0].ident } - case 2527: + case 2605: { parser.yyVAL.item = append([]*ast.RowExpr{}, yyS[yypt-0].item.(*ast.RowExpr)) } - case 2528: + case 2606: { parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.RowExpr), yyS[yypt-0].item.(*ast.RowExpr)) } - case 2529: + case 2607: { parser.yyVAL.item = &ast.RowExpr{Values: yyS[yypt-0].item.([]ast.ExprNode)} } - case 2530: + case 2608: { x := &ast.PlanReplayerStmt{ Stmt: yyS[yypt-0].statement, @@ -21945,7 +22578,7 @@ yynewstate: parser.yyVAL.statement = x } - case 2531: + case 2609: { x := &ast.PlanReplayerStmt{ Stmt: yyS[yypt-0].statement, @@ -21961,7 +22594,7 @@ yynewstate: parser.yyVAL.statement = x } - case 2532: + case 2610: { x := &ast.PlanReplayerStmt{ Stmt: nil, @@ -21981,7 +22614,7 @@ yynewstate: parser.yyVAL.statement = x } - case 2533: + case 2611: { x := &ast.PlanReplayerStmt{ Stmt: nil, @@ -22001,7 +22634,7 @@ yynewstate: parser.yyVAL.statement = x } - case 2534: + case 2612: { x := &ast.PlanReplayerStmt{ Stmt: nil, @@ -22011,7 +22644,7 @@ yynewstate: } parser.yyVAL.statement = x } - case 2535: + case 2613: { x := &ast.PlanReplayerStmt{ Stmt: nil, @@ -22021,7 +22654,7 @@ yynewstate: } parser.yyVAL.statement = x } - case 2536: + case 2614: { x := &ast.PlanReplayerStmt{ Stmt: nil, @@ -22033,6 +22666,21 @@ yynewstate: Limit: nil, } + parser.yyVAL.statement = x + } + case 2615: + { + x := &ast.PlanReplayerStmt{ + Stmt: nil, + Analyze: false, + Capture: true, + SQLDigest: yyS[yypt-1].ident, + PlanDigest: yyS[yypt-0].ident, + Where: nil, + OrderBy: nil, + Limit: nil, + } + parser.yyVAL.statement = x } diff --git a/parser/parser.y b/parser/parser.y index b988926d4ebee..51015c919f364 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -35,6 +35,7 @@ import ( "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/types" + "github.com/pingcap/tidb/parser/duration" ) %} @@ -50,8 +51,10 @@ import ( %token /*yy:token "%c" */ - identifier "identifier" - asof "AS OF" + identifier "identifier" + asof "AS OF" + toTimestamp "TO TIMESTAMP" + memberof "MEMBER OF" /*yy:token "_%c" */ underscoreCS "UNDERSCORE_CHARSET" @@ -76,6 +79,7 @@ import ( alter "ALTER" analyze "ANALYZE" and "AND" + array "ARRAY" as "AS" asc "ASC" between "BETWEEN" @@ -298,6 +302,7 @@ import ( always "ALWAYS" any "ANY" ascii "ASCII" + attribute "ATTRIBUTE" attributes "ATTRIBUTES" statsOptions "STATS_OPTIONS" statsSampleRate "STATS_SAMPLE_RATE" @@ -371,6 +376,7 @@ import ( deallocate "DEALLOCATE" definer "DEFINER" delayKeyWrite "DELAY_KEY_WRITE" + digest "DIGEST" directory "DIRECTORY" disable "DISABLE" disabled "DISABLED" @@ -455,6 +461,7 @@ import ( maxUpdatesPerHour "MAX_UPDATES_PER_HOUR" maxUserConnections "MAX_USER_CONNECTIONS" mb "MB" + member "MEMBER" memory "MEMORY" merge "MERGE" microsecond "MICROSECOND" @@ -521,6 +528,7 @@ import ( recover "RECOVER" redundant "REDUNDANT" reload "RELOAD" + remote "REMOTE" remove "REMOVE" reorganize "REORGANIZE" repair "REPAIR" @@ -529,11 +537,13 @@ import ( replicas "REPLICAS" replication "REPLICATION" required "REQUIRED" + resource "RESOURCE" respect "RESPECT" restart "RESTART" restore "RESTORE" restores "RESTORES" resume "RESUME" + reuse "REUSE" reverse "REVERSE" role "ROLE" rollback "ROLLBACK" @@ -604,12 +614,16 @@ import ( tikvImporter "TIKV_IMPORTER" timestampType "TIMESTAMP" timeType "TIME" + tokenIssuer "TOKEN_ISSUER" tp "TYPE" trace "TRACE" traditional "TRADITIONAL" transaction "TRANSACTION" triggers "TRIGGERS" truncate "TRUNCATE" + ttl "TTL" + ttlEnable "TTL_ENABLE" + ttlJobInterval "TTL_JOB_INTERVAL" unbounded "UNBOUNDED" uncommitted "UNCOMMITTED" undefined "UNDEFINED" @@ -628,6 +642,8 @@ import ( x509 "X509" yearType "YEAR" wait "WAIT" + failedLoginAttempts "FAILED_LOGIN_ATTEMPTS" + passwordLockTime "PASSWORD_LOCK_TIME" /* The following tokens belong to NotKeywordToken. Notice: make sure these tokens are contained in NotKeywordToken. */ addDate "ADDDATE" @@ -642,6 +658,7 @@ import ( copyKwd "COPY" constraints "CONSTRAINTS" curTime "CURTIME" + curDate "CURDATE" dateAdd "DATE_ADD" dateSub "DATE_SUB" dotType "DOT" @@ -693,6 +710,7 @@ import ( sum "SUM" substring "SUBSTRING" target "TARGET" + tidbJson "TIDB_JSON" timestampAdd "TIMESTAMPADD" timestampDiff "TIMESTAMPDIFF" tls "TLS" @@ -715,6 +733,10 @@ import ( voter "VOTER" voterConstraints "VOTER_CONSTRAINTS" voters "VOTERS" + rruRate "RRU_PER_SEC" + wruRate "WRU_PER_SEC" + ioReadBandwidth "IO_READ_BANDWIDTH" + ioWriteBandwidth "IO_WRITE_BANDWIDTH" /* The following tokens belong to TiDBKeyword. Notice: make sure these tokens are contained in TiDBKeyword. */ admin "ADMIN" @@ -749,6 +771,7 @@ import ( statsBuckets "STATS_BUCKETS" statsHealthy "STATS_HEALTHY" statsTopN "STATS_TOPN" + statsLocked "STATS_LOCKED" histogramsInFlight "HISTOGRAMS_IN_FLIGHT" telemetry "TELEMETRY" telemetryID "TELEMETRY_ID" @@ -860,6 +883,7 @@ import ( AlterImportStmt "ALTER IMPORT statement" AlterInstanceStmt "Alter instance statement" AlterPolicyStmt "Alter Placement Policy statement" + AlterResourceGroupStmt "Alter Resource Group statement" AlterSequenceStmt "Alter sequence statement" AnalyzeTableStmt "Analyze table statement" BeginTransactionStmt "BEGIN TRANSACTION statement" @@ -875,12 +899,14 @@ import ( CreateImportStmt "CREATE IMPORT statement" CreateBindingStmt "CREATE BINDING statement" CreatePolicyStmt "CREATE PLACEMENT POLICY statement" + CreateResourceGroupStmt "CREATE RESOURCE GROUP statement" CreateSequenceStmt "CREATE SEQUENCE statement" CreateStatisticsStmt "CREATE STATISTICS statement" DoStmt "Do statement" DropDatabaseStmt "DROP DATABASE statement" DropImportStmt "DROP IMPORT statement" DropIndexStmt "DROP INDEX statement" + DropResourceGroupStmt "DROP RESOURCE GROUP statement" DropStatisticsStmt "DROP STATISTICS statement" DropStatsStmt "DROP STATS statement" DropTableStmt "DROP TABLE statement" @@ -900,7 +926,8 @@ import ( ExplainableStmt "explainable statement" FlushStmt "Flush statement" FlashbackTableStmt "Flashback table statement" - FlashbackClusterStmt "Flashback cluster statement" + FlashbackToTimestampStmt "Flashback cluster statement" + FlashbackDatabaseStmt "Flashback Database statement" GrantStmt "Grant statement" GrantProxyStmt "Grant proxy statement" GrantRoleStmt "Grant role statement" @@ -910,8 +937,10 @@ import ( KillStmt "Kill statement" LoadDataStmt "Load data statement" LoadStatsStmt "Load statistic statement" + LockStatsStmt "Lock statistic statement" + UnlockStatsStmt "Unlock statistic statement" LockTablesStmt "Lock tables statement" - NonTransactionalDeleteStmt "Non-transactional delete statement" + NonTransactionalDMLStmt "Non-transactional DML statement" PlanReplayerStmt "Plan replayer statement" PreparedStmt "PreparedStmt" PurgeImportStmt "PURGE IMPORT statement that removes a IMPORT task record" @@ -952,18 +981,20 @@ import ( BindableStmt "Statement that can be created binding on" UpdateStmtNoWith "Update statement without CTE clause" HelpStmt "HELP statement" + ShardableStmt "Shardable statement that can be used in non-transactional DMLs" %type AdminShowSlow "Admin Show Slow statement" AdminStmtLimitOpt "Admin show ddl jobs limit option" AllOrPartitionNameList "All or partition name list" AlgorithmClause "Alter table algorithm" - AlterTablePartitionOpt "Alter table partition option" + AlterTableSpecSingleOpt "Alter table single option" AlterTableSpec "Alter table specification" AlterTableSpecList "Alter table specification list" AlterTableSpecListOpt "Alter table specification list optional" AlterSequenceOption "Alter sequence option" AlterSequenceOptionList "Alter sequence option list" + ArrayKwdOpt "Array options" AnalyzeOption "Analyze option" AnalyzeOptionList "Analyze option list" AnalyzeOptionListOpt "Optional analyze option list" @@ -976,7 +1007,6 @@ import ( Boolean "Boolean (0, 1, false, true)" OptionalBraces "optional braces" CastType "Cast function target type" - ClearPasswordExpireOptions "Clear password expire options" ColumnDef "table column definition" ColumnDefList "table column definition list" ColumnName "column name" @@ -1087,6 +1117,7 @@ import ( LoadDataSetList "Load data specifications" LoadDataSetItem "Single load data specification" LocalOpt "Local opt" + LocationOpt "Data file location of LOAD DATA" LockClause "Alter table lock clause" LogTypeOpt "Optional log type used in FLUSH statements" MaxValPartOpt "MAXVALUE partition option" @@ -1125,10 +1156,10 @@ import ( PartDefValuesOpt "VALUES {LESS THAN {(expr | value_list) | MAXVALUE} | IN {value_list}" PartDefOptionList "PartDefOption list" PartDefOption "COMMENT [=] xxx | TABLESPACE [=] tablespace_name | ENGINE [=] xxx" - PasswordExpire "Single password option for create user statement" PasswordOrLockOption "Single password or lock option for create user statement" PasswordOrLockOptionList "Password or lock options for create user statement" PasswordOrLockOptions "Optional password or lock options for create user statement" + CommentOrAttributeOption "Optional comment or attribute option for CREATE/ALTER USER statements" ColumnPosition "Column position [First|After ColumnName]" PrepareSQL "Prepare statement sql string" Priority "Statement priority" @@ -1143,8 +1174,9 @@ import ( OptGConcatSeparator "optional GROUP_CONCAT SEPARATOR" ReferOpt "reference option" ReorganizePartitionRuleOpt "optional reorganize partition partition list and definitions" - RequireList "require list" - RequireListElement "require list element" + RequireList "require list for tls options" + RequireListElement "require list element for tls option" + ResourceGroupNameOption "resource group name for user" Rolename "Rolename" RolenameComposed "Rolename that composed with more than 1 symbol" RolenameList "RolenameList" @@ -1338,6 +1370,8 @@ import ( PlacementPolicyOption "Anonymous or placement policy option" DirectPlacementOption "Subset of anonymous or direct placement option" PlacementOptionList "Anomymous or direct placement option list" + DirectResourceGroupOption "Subset of anonymous or direct resource group option" + ResourceGroupOptionList "Anomymous or direct resource group option list" AttributesOpt "Attributes options" AllColumnsOrPredicateColumnsOpt "all columns or predicate columns option" StatsOptionsOpt "Stats options" @@ -1351,6 +1385,7 @@ import ( PrimaryOpt "Optional primary keyword" NowSym "CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP" NowSymFunc "CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP/NOW" + CurdateSym "CURDATE or CURRENT_DATE" DefaultKwdOpt "optional DEFAULT keyword" DatabaseSym "DATABASE or SCHEMA" ExplainSym "EXPLAIN or DESCRIBE or DESC" @@ -1403,6 +1438,7 @@ import ( ColumnFormat "Column format" DBName "Database Name" PolicyName "Placement Policy Name" + ResourceGroupName "Resource Group Name" ExplainFormatType "explain format type" FieldAsName "Field alias name" FieldAsNameOpt "Field alias name opt" @@ -1501,7 +1537,7 @@ Start: * See https://dev.mysql.com/doc/refman/5.7/en/alter-table.html *******************************************************************************************/ AlterTableStmt: - "ALTER" IgnoreOptional "TABLE" TableName AlterTableSpecListOpt AlterTablePartitionOpt + "ALTER" IgnoreOptional "TABLE" TableName AlterTableSpecListOpt AlterTableSpecSingleOpt { specs := $5.([]*ast.AlterTableSpec) if $6 != nil { @@ -1557,6 +1593,42 @@ AlterTableStmt: } } +ResourceGroupOptionList: + DirectResourceGroupOption + { + $$ = []*ast.ResourceGroupOption{$1.(*ast.ResourceGroupOption)} + } +| ResourceGroupOptionList DirectResourceGroupOption + { + $$ = append($1.([]*ast.ResourceGroupOption), $2.(*ast.ResourceGroupOption)) + } +| ResourceGroupOptionList ',' DirectResourceGroupOption + { + $$ = append($1.([]*ast.ResourceGroupOption), $3.(*ast.ResourceGroupOption)) + } + +DirectResourceGroupOption: + "RRU_PER_SEC" EqOpt LengthNum + { + $$ = &ast.ResourceGroupOption{Tp: ast.ResourceRRURate, UintValue: $3.(uint64)} + } +| "WRU_PER_SEC" EqOpt LengthNum + { + $$ = &ast.ResourceGroupOption{Tp: ast.ResourceWRURate, UintValue: $3.(uint64)} + } +| "CPU" EqOpt stringLit + { + $$ = &ast.ResourceGroupOption{Tp: ast.ResourceUnitCPU, StrValue: $3} + } +| "IO_READ_BANDWIDTH" EqOpt stringLit + { + $$ = &ast.ResourceGroupOption{Tp: ast.ResourceUnitIOReadBandwidth, StrValue: $3} + } +| "IO_WRITE_BANDWIDTH" EqOpt stringLit + { + $$ = &ast.ResourceGroupOption{Tp: ast.ResourceUnitIOWriteBandwidth, StrValue: $3} + } + PlacementOptionList: DirectPlacementOption { @@ -1660,7 +1732,8 @@ StatsOptionsOpt: $$ = &ast.StatsOptionsSpec{Default: false, StatsOptions: $3} } -AlterTablePartitionOpt: +// Some spec can only have one, but not in a list +AlterTableSpecSingleOpt: PartitionOpt { if $1 != nil { @@ -1725,6 +1798,12 @@ AlterTablePartitionOpt: Options: $3.([]*ast.TableOption), } } +| "REMOVE" "TTL" + { + $$ = &ast.AlterTableSpec{ + Tp: ast.AlterTableRemoveTTL, + } + } LocationLabelList: { @@ -2584,15 +2663,29 @@ RecoverTableStmt: /******************************************************************* * - * Flush Back Cluster Statement + * FLASHBACK [CLUSTER | DATABASE | TABLE] TO TIMESTAMP * * Example: * *******************************************************************/ -FlashbackClusterStmt: - "FLASHBACK" "CLUSTER" "TO" "TIMESTAMP" stringLit +FlashbackToTimestampStmt: + "FLASHBACK" "CLUSTER" toTimestamp stringLit + { + $$ = &ast.FlashBackToTimestampStmt{ + FlashbackTS: ast.NewValueExpr($4, "", ""), + } + } +| "FLASHBACK" "TABLE" TableNameList toTimestamp stringLit + { + $$ = &ast.FlashBackToTimestampStmt{ + Tables: $3.([]*ast.TableName), + FlashbackTS: ast.NewValueExpr($5, "", ""), + } + } +| "FLASHBACK" DatabaseSym DBName toTimestamp stringLit { - $$ = &ast.FlashBackClusterStmt{ + $$ = &ast.FlashBackToTimestampStmt{ + DBName: model.NewCIStr($3), FlashbackTS: ast.NewValueExpr($5, "", ""), } } @@ -2622,6 +2715,23 @@ FlashbackToNewName: $$ = $2 } +/******************************************************************* + * + * Flush Back Database Statement + * + * Example: + * FLASHBACK DATABASE/SCHEMA DBName TO newDBName + * + *******************************************************************/ +FlashbackDatabaseStmt: + "FLASHBACK" DatabaseSym DBName FlashbackToNewName + { + $$ = &ast.FlashBackDatabaseStmt{ + DBName: model.NewCIStr($3), + NewName: $4, + } + } + /******************************************************************* * * Split index region statement @@ -3516,6 +3626,14 @@ NowSymOptionFraction: { $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP"), Args: []ast.ExprNode{ast.NewValueExpr($3, parser.charset, parser.collation)}} } +| CurdateSym '(' ')' + { + $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_DATE")} + } +| "CURRENT_DATE" + { + $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_DATE")} + } NextValueForSequence: "NEXT" "VALUE" forKwd TableName @@ -3554,6 +3672,10 @@ NowSym: | "LOCALTIME" | "LOCALTIMESTAMP" +CurdateSym: + builtinCurDate +| "CURRENT_DATE" + SignedLiteral: Literal { @@ -3815,6 +3937,9 @@ DBName: PolicyName: Identifier +ResourceGroupName: + Identifier + DatabaseOption: DefaultKwdOpt CharsetKw EqOpt CharsetName { @@ -4739,21 +4864,25 @@ DropRoleStmt: } DropStatsStmt: - "DROP" "STATS" TableName + "DROP" "STATS" TableNameList { - $$ = &ast.DropStatsStmt{Table: $3.(*ast.TableName)} + $$ = &ast.DropStatsStmt{Tables: $3.([]*ast.TableName)} } | "DROP" "STATS" TableName "PARTITION" PartitionNameList { + yylex.AppendError(ErrWarnDeprecatedSyntaxNoReplacement.FastGenByArgs("DROP STATS ... PARTITION ...")) + parser.lastErrorAsWarn() $$ = &ast.DropStatsStmt{ - Table: $3.(*ast.TableName), + Tables: []*ast.TableName{$3.(*ast.TableName)}, PartitionNames: $5.([]model.CIStr), } } | "DROP" "STATS" TableName "GLOBAL" { + yylex.AppendError(ErrWarnDeprecatedSyntax.FastGenByArgs("DROP STATS ... GLOBAL", "DROP STATS ...")) + parser.lastErrorAsWarn() $$ = &ast.DropStatsStmt{ - Table: $3.(*ast.TableName), + Tables: []*ast.TableName{$3.(*ast.TableName)}, IsGlobalStats: true, } } @@ -4918,6 +5047,7 @@ ExplainFormatType: | "BRIEF" | "VERBOSE" | "TRUE_CARD_COST" +| "TIDB_JSON" SavepointStmt: "SAVEPOINT" Identifier @@ -5707,6 +5837,10 @@ PredicateExpr: { $$ = &ast.PatternRegexpExpr{Expr: $1, Pattern: $3, Not: !$2.(bool)} } +| BitExpr memberof '(' SimpleExpr ')' + { + $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONMemberOf), Args: []ast.ExprNode{$1, $4}} + } | BitExpr RegexpSym: @@ -6009,6 +6143,7 @@ UnReservedKeyword: "ACTION" | "ADVISE" | "ASCII" +| "ATTRIBUTE" | "ATTRIBUTES" | "BINDING_CACHE" | "STATS_OPTIONS" @@ -6089,7 +6224,9 @@ UnReservedKeyword: | "QUICK" | "REBUILD" | "REDUNDANT" +| "REMOTE" | "REORGANIZE" +| "RESOURCE" | "RESTART" | "ROLE" | "ROLLBACK" @@ -6224,6 +6361,7 @@ UnReservedKeyword: | "ACCOUNT" | "INCREMENTAL" | "CPU" +| "MEMBER" | "MEMORY" | "BLOCK" | "IO" @@ -6345,6 +6483,14 @@ UnReservedKeyword: | "CLUSTERED" | "NONCLUSTERED" | "PRESERVE" +| "TOKEN_ISSUER" +| "TTL" +| "TTL_ENABLE" +| "TTL_JOB_INTERVAL" +| "FAILED_LOGIN_ATTEMPTS" +| "PASSWORD_LOCK_TIME" +| "DIGEST" +| "REUSE" %prec lowerThanEq TiDBKeyword: "ADMIN" @@ -6375,6 +6521,7 @@ TiDBKeyword: | "STATS_TOPN" | "STATS_BUCKETS" | "STATS_HEALTHY" +| "STATS_LOCKED" | "HISTOGRAMS_IN_FLIGHT" | "TELEMETRY" | "TELEMETRY_ID" @@ -6402,6 +6549,7 @@ NotKeywordToken: | "CAST" | "COPY" | "CURTIME" +| "CURDATE" | "DATE_ADD" | "DATE_SUB" | "DOT" @@ -6477,6 +6625,11 @@ NotKeywordToken: | "FOLLOWER_CONSTRAINTS" | "LEARNER_CONSTRAINTS" | "VOTER_CONSTRAINTS" +| "TIDB_JSON" +| "IO_READ_BANDWIDTH" +| "IO_WRITE_BANDWIDTH" +| "RRU_PER_SEC" +| "WRU_PER_SEC" /************************************************************************************ * @@ -7119,7 +7272,7 @@ SimpleExpr: FunctionType: ast.CastBinaryOperator, } } -| builtinCast '(' Expression "AS" CastType ')' +| builtinCast '(' Expression "AS" CastType ArrayKwdOpt ')' { /* See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */ tp := $5.(*types.FieldType) @@ -7130,7 +7283,13 @@ SimpleExpr: if tp.GetDecimal() == types.UnspecifiedLength { tp.SetDecimal(defaultDecimal) } + isArray := $6.(bool) + tp.SetArray(isArray) explicitCharset := parser.explicitCharset + if isArray && !explicitCharset && tp.GetCharset() != charset.CharsetBin { + tp.SetCharset(charset.CharsetUTF8MB4) + tp.SetCollate(charset.CollationUTF8MB4) + } parser.explicitCharset = false $$ = &ast.FuncCastExpr{ Expr: $3, @@ -7199,6 +7358,15 @@ SimpleExpr: $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONUnquote), Args: []ast.ExprNode{extract}} } +ArrayKwdOpt: + { + $$ = false + } +| "ARRAY" + { + $$ = true + } + DistinctKwd: "DISTINCT" | "DISTINCTROW" @@ -10624,6 +10792,13 @@ ShowStmt: DBName: $5, } } +| "SHOW" "CREATE" "RESOURCE" "GROUP" ResourceGroupName + { + $$ = &ast.ShowStmt{ + Tp: ast.ShowCreateResourceGroup, + ResourceGroupName: $5, + } + } | "SHOW" "CREATE" "USER" Username { // See https://dev.mysql.com/doc/refman/5.7/en/show-create-user.html @@ -11051,6 +11226,10 @@ ShowTargetFilterable: { $$ = &ast.ShowStmt{Tp: ast.ShowStatsHealthy} } +| "STATS_LOCKED" + { + $$ = &ast.ShowStmt{Tp: ast.ShowStatsLocked, Table: &ast.TableName{Name: model.NewCIStr("STATS_TABLE_LOCKED"), Schema: model.NewCIStr(mysql.SystemDB)}} + } | "HISTOGRAMS_IN_FLIGHT" { $$ = &ast.ShowStmt{Tp: ast.ShowHistogramsInFlight} @@ -11296,6 +11475,7 @@ Statement: | AlterInstanceStmt | AlterSequenceStmt | AlterPolicyStmt +| AlterResourceGroupStmt | AnalyzeTableStmt | BeginTransactionStmt | BinlogStmt @@ -11315,6 +11495,7 @@ Statement: | CreateRoleStmt | CreateBindingStmt | CreatePolicyStmt +| CreateResourceGroupStmt | CreateSequenceStmt | CreateStatisticsStmt | DoStmt @@ -11326,13 +11507,15 @@ Statement: | DropSequenceStmt | DropViewStmt | DropUserStmt +| DropResourceGroupStmt | DropRoleStmt | DropStatisticsStmt | DropStatsStmt | DropBindingStmt | FlushStmt -| FlashbackClusterStmt | FlashbackTableStmt +| FlashbackToTimestampStmt +| FlashbackDatabaseStmt | GrantStmt | GrantProxyStmt | GrantRoleStmt @@ -11342,6 +11525,8 @@ Statement: | KillStmt | LoadDataStmt | LoadStatsStmt +| LockStatsStmt +| UnlockStatsStmt | PlanReplayerStmt | PreparedStmt | PurgeImportStmt @@ -11388,7 +11573,7 @@ Statement: | ShutdownStmt | RestartStmt | HelpStmt -| NonTransactionalDeleteStmt +| NonTransactionalDMLStmt TraceableStmt: DeleteFromStmt @@ -11707,6 +11892,36 @@ TableOption: // Parse it but will ignore it $$ = &ast.TableOption{Tp: ast.TableOptionEncryption, StrValue: $3} } +| "TTL" EqOpt Identifier '+' "INTERVAL" Literal TimeUnit + { + $$ = &ast.TableOption{ + Tp: ast.TableOptionTTL, + ColumnName: &ast.ColumnName{Name: model.NewCIStr($3)}, + Value: ast.NewValueExpr($6, parser.charset, parser.collation), + TimeUnitValue: &ast.TimeUnitExpr{Unit: $7.(ast.TimeUnitType)}, + } + } +| "TTL_ENABLE" EqOpt stringLit + { + onOrOff := strings.ToLower($3) + if onOrOff == "on" { + $$ = &ast.TableOption{Tp: ast.TableOptionTTLEnable, BoolValue: true} + } else if onOrOff == "off" { + $$ = &ast.TableOption{Tp: ast.TableOptionTTLEnable, BoolValue: false} + } else { + yylex.AppendError(yylex.Errorf("The TTL_ENABLE option has to be set 'ON' or 'OFF'")) + return 1 + } + } +| "TTL_JOB_INTERVAL" EqOpt stringLit + { + _, err := duration.ParseDuration($3) + if err != nil { + yylex.AppendError(yylex.Errorf("The TTL_JOB_INTERVAL option is not a valid duration: %s", err.Error())) + return 1 + } + $$ = &ast.TableOption{Tp: ast.TableOptionTTLJobInterval, StrValue: $3} + } ForceOpt: /* empty */ @@ -12580,17 +12795,24 @@ CommaOpt: * https://dev.mysql.com/doc/refman/5.7/en/account-management-sql.html ************************************************************************************/ CreateUserStmt: - "CREATE" "USER" IfNotExists UserSpecList RequireClauseOpt ConnectionOptions PasswordOrLockOptions + "CREATE" "USER" IfNotExists UserSpecList RequireClauseOpt ConnectionOptions PasswordOrLockOptions CommentOrAttributeOption ResourceGroupNameOption { - // See https://dev.mysql.com/doc/refman/5.7/en/create-user.html - $$ = &ast.CreateUserStmt{ + // See https://dev.mysql.com/doc/refman/8.0/en/create-user.html + ret := &ast.CreateUserStmt{ IsCreateRole: false, IfNotExists: $3.(bool), Specs: $4.([]*ast.UserSpec), - TLSOptions: $5.([]*ast.TLSOption), + AuthTokenOrTLSOptions: $5.([]*ast.AuthTokenOrTLSOption), ResourceOptions: $6.([]*ast.ResourceOption), PasswordOrLockOptions: $7.([]*ast.PasswordOrLockOption), } + if $8 != nil { + ret.CommentOrAttributeOption = $8.(*ast.CommentOrAttributeOption) + } + if $9 != nil { + ret.ResourceGroupNameOption = $9.(*ast.ResourceGroupNameOption) + } + $$ = ret } CreateRoleStmt: @@ -12604,17 +12826,24 @@ CreateRoleStmt: } } -/* See http://dev.mysql.com/doc/refman/5.7/en/alter-user.html */ +/* See http://dev.mysql.com/doc/refman/8.0/en/alter-user.html */ AlterUserStmt: - "ALTER" "USER" IfExists UserSpecList RequireClauseOpt ConnectionOptions PasswordOrLockOptions + "ALTER" "USER" IfExists UserSpecList RequireClauseOpt ConnectionOptions PasswordOrLockOptions CommentOrAttributeOption ResourceGroupNameOption { - $$ = &ast.AlterUserStmt{ + ret := &ast.AlterUserStmt{ IfExists: $3.(bool), Specs: $4.([]*ast.UserSpec), - TLSOptions: $5.([]*ast.TLSOption), + AuthTokenOrTLSOptions: $5.([]*ast.AuthTokenOrTLSOption), ResourceOptions: $6.([]*ast.ResourceOption), PasswordOrLockOptions: $7.([]*ast.PasswordOrLockOption), } + if $8 != nil { + ret.CommentOrAttributeOption = $8.(*ast.CommentOrAttributeOption) + } + if $9 != nil { + ret.ResourceGroupNameOption = $9.(*ast.ResourceGroupNameOption) + } + $$ = ret } | "ALTER" "USER" IfExists "USER" '(' ')' "IDENTIFIED" "BY" AuthString { @@ -12728,31 +12957,31 @@ ConnectionOption: RequireClauseOpt: { - $$ = []*ast.TLSOption{} + $$ = []*ast.AuthTokenOrTLSOption{} } | RequireClause RequireClause: "REQUIRE" "NONE" { - t := &ast.TLSOption{ + t := &ast.AuthTokenOrTLSOption{ Type: ast.TlsNone, } - $$ = []*ast.TLSOption{t} + $$ = []*ast.AuthTokenOrTLSOption{t} } | "REQUIRE" "SSL" { - t := &ast.TLSOption{ + t := &ast.AuthTokenOrTLSOption{ Type: ast.Ssl, } - $$ = []*ast.TLSOption{t} + $$ = []*ast.AuthTokenOrTLSOption{t} } | "REQUIRE" "X509" { - t := &ast.TLSOption{ + t := &ast.AuthTokenOrTLSOption{ Type: ast.X509, } - $$ = []*ast.TLSOption{t} + $$ = []*ast.AuthTokenOrTLSOption{t} } | "REQUIRE" RequireList { @@ -12762,50 +12991,79 @@ RequireClause: RequireList: RequireListElement { - $$ = []*ast.TLSOption{$1.(*ast.TLSOption)} + $$ = []*ast.AuthTokenOrTLSOption{$1.(*ast.AuthTokenOrTLSOption)} } | RequireList "AND" RequireListElement { - l := $1.([]*ast.TLSOption) - l = append(l, $3.(*ast.TLSOption)) + l := $1.([]*ast.AuthTokenOrTLSOption) + l = append(l, $3.(*ast.AuthTokenOrTLSOption)) $$ = l } | RequireList RequireListElement { - l := $1.([]*ast.TLSOption) - l = append(l, $2.(*ast.TLSOption)) + l := $1.([]*ast.AuthTokenOrTLSOption) + l = append(l, $2.(*ast.AuthTokenOrTLSOption)) $$ = l } RequireListElement: "ISSUER" stringLit { - $$ = &ast.TLSOption{ + $$ = &ast.AuthTokenOrTLSOption{ Type: ast.Issuer, Value: $2, } } | "SUBJECT" stringLit { - $$ = &ast.TLSOption{ + $$ = &ast.AuthTokenOrTLSOption{ Type: ast.Subject, Value: $2, } } | "CIPHER" stringLit { - $$ = &ast.TLSOption{ + $$ = &ast.AuthTokenOrTLSOption{ Type: ast.Cipher, Value: $2, } } | "SAN" stringLit { - $$ = &ast.TLSOption{ + $$ = &ast.AuthTokenOrTLSOption{ Type: ast.SAN, Value: $2, } } +| "TOKEN_ISSUER" stringLit + { + $$ = &ast.AuthTokenOrTLSOption{ + Type: ast.TokenIssuer, + Value: $2, + } + } + +CommentOrAttributeOption: + { + $$ = nil + } +| "COMMENT" stringLit + { + $$ = &ast.CommentOrAttributeOption{Type: ast.UserCommentType, Value: $2} + } +| "ATTRIBUTE" stringLit + { + $$ = &ast.CommentOrAttributeOption{Type: ast.UserAttributeType, Value: $2} + } + +ResourceGroupNameOption: + { + $$ = nil + } +| "RESOURCE" "GROUP" ResourceGroupName + { + $$ = &ast.ResourceGroupNameOption{Type: ast.UserResourceGroupName, Value: $3} + } PasswordOrLockOptions: { @@ -12841,49 +13099,76 @@ PasswordOrLockOption: Type: ast.Lock, } } -| PasswordExpire +| "PASSWORD" "HISTORY" "DEFAULT" + { + $$ = &ast.PasswordOrLockOption{ + Type: ast.PasswordHistoryDefault, + } + } +| "PASSWORD" "HISTORY" NUM + { + $$ = &ast.PasswordOrLockOption{ + Type: ast.PasswordHistory, + Count: $3.(int64), + } + } +| "PASSWORD" "REUSE" "INTERVAL" "DEFAULT" + { + $$ = &ast.PasswordOrLockOption{ + Type: ast.PasswordReuseDefault, + } + } +| "PASSWORD" "REUSE" "INTERVAL" NUM "DAY" + { + $$ = &ast.PasswordOrLockOption{ + Type: ast.PasswordReuseInterval, + Count: $4.(int64), + } + } +| "PASSWORD" "EXPIRE" { $$ = &ast.PasswordOrLockOption{ Type: ast.PasswordExpire, } - yylex.AppendError(yylex.Errorf("TiDB does not support PASSWORD EXPIRE, they would be parsed but ignored.")) - parser.lastErrorAsWarn() } -| PasswordExpire "INTERVAL" Int64Num "DAY" +| "PASSWORD" "EXPIRE" "INTERVAL" Int64Num "DAY" { $$ = &ast.PasswordOrLockOption{ Type: ast.PasswordExpireInterval, - Count: $3.(int64), + Count: $4.(int64), } - yylex.AppendError(yylex.Errorf("TiDB does not support PASSWORD EXPIRE, they would be parsed but ignored.")) - parser.lastErrorAsWarn() } -| PasswordExpire "NEVER" +| "PASSWORD" "EXPIRE" "NEVER" { $$ = &ast.PasswordOrLockOption{ Type: ast.PasswordExpireNever, } - yylex.AppendError(yylex.Errorf("TiDB does not support PASSWORD EXPIRE, they would be parsed but ignored.")) - parser.lastErrorAsWarn() } -| PasswordExpire "DEFAULT" +| "PASSWORD" "EXPIRE" "DEFAULT" { $$ = &ast.PasswordOrLockOption{ Type: ast.PasswordExpireDefault, } - yylex.AppendError(yylex.Errorf("TiDB does not support PASSWORD EXPIRE, they would be parsed but ignored.")) - parser.lastErrorAsWarn() } - -PasswordExpire: - "PASSWORD" "EXPIRE" ClearPasswordExpireOptions +| "FAILED_LOGIN_ATTEMPTS" Int64Num { - $$ = nil + $$ = &ast.PasswordOrLockOption{ + Type: ast.FailedLoginAttempts, + Count: $2.(int64), + } } - -ClearPasswordExpireOptions: +| "PASSWORD_LOCK_TIME" Int64Num { - $$ = nil + $$ = &ast.PasswordOrLockOption{ + Type: ast.PasswordLockTime, + Count: $2.(int64), + } + } +| "PASSWORD_LOCK_TIME" "UNBOUNDED" + { + $$ = &ast.PasswordOrLockOption{ + Type: ast.PasswordLockTimeUnbounded, + } } AuthOption: @@ -12914,15 +13199,17 @@ AuthOption: | "IDENTIFIED" "WITH" AuthPlugin "AS" HashString { $$ = &ast.AuthOption{ - AuthPlugin: $3, - HashString: $5, + AuthPlugin: $3, + HashString: $5, + ByHashString: true, } } | "IDENTIFIED" "BY" "PASSWORD" HashString { $$ = &ast.AuthOption{ - AuthPlugin: mysql.AuthNativePassword, - HashString: $4, + AuthPlugin: mysql.AuthNativePassword, + HashString: $4, + ByHashString: true, } } @@ -13007,6 +13294,15 @@ CreateBindingStmt: GlobalScope: $2.(bool), } + $$ = x + } +| "CREATE" GlobalScope "BINDING" "FROM" "HISTORY" "USING" "PLAN" "DIGEST" stringLit + { + x := &ast.CreateBindingStmt{ + GlobalScope: $2.(bool), + PlanDigest: $9, + } + $$ = x } @@ -13048,6 +13344,15 @@ DropBindingStmt: GlobalScope: $2.(bool), } + $$ = x + } +| "DROP" GlobalScope "BINDING" "FOR" "SQL" "DIGEST" stringLit + { + x := &ast.DropBindingStmt{ + GlobalScope: $2.(bool), + SQLDigest: $7, + } + $$ = x } @@ -13082,6 +13387,15 @@ SetBindingStmt: HintedNode: hintedStmt, } + $$ = x + } +| "SET" "BINDING" BindingStatusType "FOR" "SQL" "DIGEST" stringLit + { + x := &ast.SetBindingStmt{ + BindingStatusType: $3.(ast.BindingStatusType), + SQLDigest: $7, + } + $$ = x } @@ -13098,12 +13412,12 @@ GrantStmt: return 1 } $$ = &ast.GrantStmt{ - Privs: p, - ObjectType: $4.(ast.ObjectTypeType), - Level: $5.(*ast.GrantLevel), - Users: $7.([]*ast.UserSpec), - TLSOptions: $8.([]*ast.TLSOption), - WithGrant: $9.(bool), + Privs: p, + ObjectType: $4.(ast.ObjectTypeType), + Level: $5.(*ast.GrantLevel), + Users: $7.([]*ast.UserSpec), + AuthTokenOrTLSOptions: $8.([]*ast.AuthTokenOrTLSOption), + WithGrant: $9.(bool), } } @@ -13476,17 +13790,17 @@ RevokeRoleStmt: * See https://dev.mysql.com/doc/refman/5.7/en/load-data.html *******************************************************************************************/ LoadDataStmt: - "LOAD" "DATA" LocalOpt "INFILE" stringLit DuplicateOpt "INTO" "TABLE" TableName CharsetOpt Fields Lines IgnoreLines ColumnNameOrUserVarListOptWithBrackets LoadDataSetSpecOpt + "LOAD" "DATA" LocationOpt "INFILE" stringLit DuplicateOpt "INTO" "TABLE" TableName CharsetOpt Fields Lines IgnoreLines ColumnNameOrUserVarListOptWithBrackets LoadDataSetSpecOpt { x := &ast.LoadDataStmt{ + FileLocRef: $3.(ast.FileLocRefTp), Path: $5, OnDuplicate: $6.(ast.OnDuplicateKeyHandlingType), Table: $9.(*ast.TableName), ColumnsAndUserVars: $14.([]*ast.ColumnNameOrUserVar), IgnoreLines: $13.(uint64), } - if $3 != nil { - x.IsLocal = true + if x.FileLocRef == ast.FileLocClient { // See https://dev.mysql.com/doc/refman/5.7/en/load-data.html#load-data-duplicate-key-handling // If you do not specify IGNORE or REPLACE modifier , then we set default behavior to IGNORE when LOCAL modifier is specified if x.OnDuplicate == ast.OnDuplicateKeyHandlingError { @@ -13535,6 +13849,19 @@ LocalOpt: $$ = $1 } +LocationOpt: + { + $$ = ast.FileLocServer + } +| "LOCAL" + { + $$ = ast.FileLocClient + } +| "REMOTE" + { + $$ = ast.FileLocRemote + } + Fields: { escape := "\\" @@ -13768,17 +14095,23 @@ TableLockList: * Non-transactional Delete Statement * Split a SQL on a column. Used for bulk delete that doesn't need ACID. *******************************************************************/ -NonTransactionalDeleteStmt: - "BATCH" OptionalShardColumn "LIMIT" NUM DryRunOptions DeleteFromStmt +NonTransactionalDMLStmt: + "BATCH" OptionalShardColumn "LIMIT" NUM DryRunOptions ShardableStmt { - $$ = &ast.NonTransactionalDeleteStmt{ + $$ = &ast.NonTransactionalDMLStmt{ DryRun: $5.(int), ShardColumn: $2.(*ast.ColumnName), Limit: getUint64FromNUM($4), - DeleteStmt: $6.(*ast.DeleteStmt), + DMLStmt: $6.(ast.ShardableDMLStmt), } } +ShardableStmt: + DeleteFromStmt +| UpdateStmt +| InsertIntoStmt +| ReplaceIntoStmt + DryRunOptions: { $$ = ast.NoDryRun @@ -13828,6 +14161,13 @@ KillStmt: TiDBExtension: $1.(bool), } } +| KillOrKillTiDB BuiltinFunction + { + $$ = &ast.KillStmt{ + TiDBExtension: $1.(bool), + Expr: $2, + } + } KillOrKillTiDB: "KILL" @@ -13849,6 +14189,22 @@ LoadStatsStmt: } } +LockStatsStmt: + "LOCK" "STATS" TableNameList + { + $$ = &ast.LockStatsStmt{ + Tables: $3.([]*ast.TableName), + } + } + +UnlockStatsStmt: + "UNLOCK" "STATS" TableNameList + { + $$ = &ast.UnlockStatsStmt{ + Tables: $3.([]*ast.TableName), + } + } + DropPolicyStmt: "DROP" "PLACEMENT" "POLICY" IfExists PolicyName { @@ -13858,6 +14214,35 @@ DropPolicyStmt: } } +CreateResourceGroupStmt: + "CREATE" "RESOURCE" "GROUP" IfNotExists ResourceGroupName ResourceGroupOptionList + { + $$ = &ast.CreateResourceGroupStmt{ + IfNotExists: $4.(bool), + ResourceGroupName: model.NewCIStr($5), + ResourceGroupOptionList: $6.([]*ast.ResourceGroupOption), + } + } + +AlterResourceGroupStmt: + "ALTER" "RESOURCE" "GROUP" IfExists ResourceGroupName ResourceGroupOptionList + { + $$ = &ast.AlterResourceGroupStmt{ + IfExists: $4.(bool), + ResourceGroupName: model.NewCIStr($5), + ResourceGroupOptionList: $6.([]*ast.ResourceGroupOption), + } + } + +DropResourceGroupStmt: + "DROP" "RESOURCE" "GROUP" IfExists ResourceGroupName + { + $$ = &ast.DropResourceGroupStmt{ + IfExists: $4.(bool), + ResourceGroupName: model.NewCIStr($5), + } + } + CreatePolicyStmt: "CREATE" OrReplace "PLACEMENT" "POLICY" IfNotExists PolicyName PlacementOptionList { @@ -14184,7 +14569,8 @@ RowStmt: * [ASC | DESC], ... [WITH ROLLUP]] * [LIMIT {[offset,] row_count | row_count OFFSET offset}]} * | 'file_name' - * | LOAD 'file_name'] + * | LOAD 'file_name' + * | CAPTURE `sql_digest` `plan_digest`] *******************************************************************/ PlanReplayerStmt: "PLAN" "REPLAYER" "DUMP" "EXPLAIN" ExplainableStmt @@ -14291,6 +14677,21 @@ PlanReplayerStmt: Limit: nil, } + $$ = x + } +| "PLAN" "REPLAYER" "CAPTURE" stringLit stringLit + { + x := &ast.PlanReplayerStmt{ + Stmt: nil, + Analyze: false, + Capture: true, + SQLDigest: $4, + PlanDigest: $5, + Where: nil, + OrderBy: nil, + Limit: nil, + } + $$ = x } %% diff --git a/parser/parser_test.go b/parser/parser_test.go index 21147a8040c45..2fb9b073fd398 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -60,7 +60,7 @@ func TestSimple(t *testing.T) { "delayed", "high_priority", "low_priority", "cumeDist", "denseRank", "firstValue", "lag", "lastValue", "lead", "nthValue", "ntile", "over", "percentRank", "rank", "row", "rows", "rowNumber", "window", "linear", - "match", "until", "placement", "tablesample", "attributes", + "match", "until", "placement", "tablesample", "failedLoginAttempts", "passwordLockTime", // TODO: support the following keywords // "with", } @@ -98,7 +98,7 @@ func TestSimple(t *testing.T) { "max_connections_per_hour", "max_queries_per_hour", "max_updates_per_hour", "max_user_connections", "event", "reload", "routine", "temporary", "following", "preceding", "unbounded", "respect", "nulls", "current", "last", "against", "expansion", "chain", "error", "general", "nvarchar", "pack_keys", "p", "shard_row_id_bits", "pre_split_regions", - "constraints", "role", "replicas", "policy", "s3", "strict", "running", "stop", "preserve", "placement", + "constraints", "role", "replicas", "policy", "s3", "strict", "running", "stop", "preserve", "placement", "attributes", "attribute", "resource", } for _, kw := range unreservedKws { src := fmt.Sprintf("SELECT %s FROM tbl;", kw) @@ -364,10 +364,10 @@ func RunTest(t *testing.T, table []testCase, enableWindowFunc bool) { for _, tbl := range table { _, _, err := p.Parse(tbl.src, "", "") if !tbl.ok { - require.Errorf(t, err, "source %v", tbl.src) + require.Errorf(t, err, "source %v", tbl.src, errors.Trace(err)) continue } - require.NoErrorf(t, err, "source %v", tbl.src) + require.NoErrorf(t, err, "source %v", tbl.src, errors.Trace(err)) // restore correctness test if tbl.ok { RunRestoreTest(t, tbl.src, tbl.restore, enableWindowFunc) @@ -666,6 +666,8 @@ func TestDMLStmt(t *testing.T) { {"LOAD DATA LOCAL INFILE '/tmp/t.csv' IGNORE INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';", true, "LOAD DATA LOCAL INFILE '/tmp/t.csv' IGNORE INTO TABLE `t1` FIELDS TERMINATED BY ','"}, {"LOAD DATA LOCAL INFILE '/tmp/t.csv' REPLACE INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';", true, "LOAD DATA LOCAL INFILE '/tmp/t.csv' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ','"}, + {"load data remote infile 's3://bucket-name/t.csv' into table t", true, "LOAD DATA REMOTE INFILE 's3://bucket-name/t.csv' INTO TABLE `t`"}, + // select for update/share {"select * from t for update", true, "SELECT * FROM `t` FOR UPDATE"}, {"select * from t for share", true, "SELECT * FROM `t` FOR SHARE"}, @@ -1135,6 +1137,9 @@ func TestDBAStmt(t *testing.T) { // for show stats_meta. {"show stats_meta", true, "SHOW STATS_META"}, {"show stats_meta where table_name = 't'", true, "SHOW STATS_META WHERE `table_name`=_UTF8MB4't'"}, + // for show stats_locked. + {"show stats_locked", true, "SHOW STATS_LOCKED"}, + {"show stats_locked where table_name = 't'", true, "SHOW STATS_LOCKED WHERE `table_name`=_UTF8MB4't'"}, // for show stats_histograms {"show stats_histograms", true, "SHOW STATS_HISTOGRAMS"}, {"show stats_histograms where col_name = 'a'", true, "SHOW STATS_HISTOGRAMS WHERE `col_name`=_UTF8MB4'a'"}, @@ -1174,6 +1179,12 @@ func TestDBAStmt(t *testing.T) { // for load stats {"load stats '/tmp/stats.json'", true, "LOAD STATS '/tmp/stats.json'"}, + // for lock stats + {"lock stats test.t", true, "LOCK STATS `test`.`t`"}, + {"lock stats t, t2", true, "LOCK STATS `t`, `t2`"}, + // for unlock stats + {"unlock stats test.t", true, "UNLOCK STATS `test`.`t`"}, + {"unlock stats t, t2", true, "UNLOCK STATS `t`, `t2`"}, // set // user defined {"SET @ = 1", true, "SET @``=1"}, @@ -1593,6 +1604,9 @@ func TestBuiltin(t *testing.T) { {"select cast('2000' as year);", true, "SELECT CAST(_UTF8MB4'2000' AS YEAR)"}, {"select cast(time '2000' as year);", true, "SELECT CAST(TIME '2000' AS YEAR)"}, + {"select cast(b as signed array);", true, "SELECT CAST(`b` AS SIGNED ARRAY)"}, + {"select cast(b as char(10) array);", true, "SELECT CAST(`b` AS CHAR(10) ARRAY)"}, + // for last_insert_id {"SELECT last_insert_id();", true, "SELECT LAST_INSERT_ID()"}, {"SELECT last_insert_id(1);", true, "SELECT LAST_INSERT_ID(1)"}, @@ -2135,6 +2149,13 @@ func TestBuiltin(t *testing.T) { {`SELECT a->3 FROM t`, false, ""}, {`SELECT a->>3 FROM t`, false, ""}, + {`SELECT 1 member of (a)`, true, "SELECT 1 MEMBER OF (`a`)"}, + {`SELECT 1 member of a`, false, ""}, + {`SELECT 1 member a`, false, ""}, + {`SELECT 1 not member of a`, false, ""}, + {`SELECT 1 member of (1+1)`, false, ""}, + {`SELECT concat('a') member of (cast(1 as char(1)))`, true, "SELECT CONCAT(_UTF8MB4'a') MEMBER OF (CAST(1 AS CHAR(1)))"}, + // Test that quoted identifier can be a function name. {"SELECT `uuid`()", true, "SELECT UUID()"}, @@ -2651,9 +2672,10 @@ func TestDDL(t *testing.T) { {"drop view if exists xxx", true, "DROP VIEW IF EXISTS `xxx`"}, {"drop view if exists xxx, yyy", true, "DROP VIEW IF EXISTS `xxx`, `yyy`"}, {"drop stats t", true, "DROP STATS `t`"}, + {"drop stats t1, t2, t3", true, "DROP STATS `t1`, `t2`, `t3`"}, + {"drop stats t global", true, "DROP STATS `t` GLOBAL"}, {"drop stats t partition p0", true, "DROP STATS `t` PARTITION `p0`"}, {"drop stats t partition p0, p1, p2", true, "DROP STATS `t` PARTITION `p0`,`p1`,`p2`"}, - {"drop stats t global", true, "DROP STATS `t` GLOBAL"}, // for issue 974 {`CREATE TABLE address ( id bigint(20) NOT NULL AUTO_INCREMENT, @@ -2803,6 +2825,11 @@ func TestDDL(t *testing.T) { {"create table t (a int default (rand(1)))", true, "CREATE TABLE `t` (`a` INT DEFAULT RAND(1))"}, {"create table t (a int default (((rand()))))", true, "CREATE TABLE `t` (`a` INT DEFAULT RAND())"}, {"create table t (a int default (((rand(1)))))", true, "CREATE TABLE `t` (`a` INT DEFAULT RAND(1))"}, + {"create table t (d date default current_date())", true, "CREATE TABLE `t` (`d` DATE DEFAULT CURRENT_DATE())"}, + {"create table t (d date default current_date)", true, "CREATE TABLE `t` (`d` DATE DEFAULT CURRENT_DATE())"}, + {"create table t (d date default (current_date()))", true, "CREATE TABLE `t` (`d` DATE DEFAULT CURRENT_DATE())"}, + {"create table t (d date default (curdate()))", true, "CREATE TABLE `t` (`d` DATE DEFAULT CURRENT_DATE())"}, + {"create table t (d date default curdate())", true, "CREATE TABLE `t` (`d` DATE DEFAULT CURRENT_DATE())"}, // For table option `ENCRYPTION` {"create table t (a int) encryption = 'n';", true, "CREATE TABLE `t` (`a` INT) ENCRYPTION = 'n'"}, @@ -3224,6 +3251,7 @@ func TestDDL(t *testing.T) { {"create table t (a bigint, b bigint as (a+1) not null);", true, "CREATE TABLE `t` (`a` BIGINT,`b` BIGINT GENERATED ALWAYS AS(`a`+1) VIRTUAL NOT NULL)"}, {"create table t (a bigint, b bigint as (a+1) not null);", true, "CREATE TABLE `t` (`a` BIGINT,`b` BIGINT GENERATED ALWAYS AS(`a`+1) VIRTUAL NOT NULL)"}, {"create table t (a bigint, b bigint as (a+1) not null comment 'ttt');", true, "CREATE TABLE `t` (`a` BIGINT,`b` BIGINT GENERATED ALWAYS AS(`a`+1) VIRTUAL NOT NULL COMMENT 'ttt')"}, + {"create table t(a int, index idx((cast(a as binary(1)))));", true, "CREATE TABLE `t` (`a` INT,INDEX `idx`((CAST(`a` AS BINARY(1)))))"}, {"alter table t add column (f timestamp as (a+1) default '2019-01-01 11:11:11');", false, ""}, {"alter table t modify column f int as (a+1) default 55;", false, ""}, @@ -3246,11 +3274,24 @@ func TestDDL(t *testing.T) { // for flashback table. {"flashback table t", true, "FLASHBACK TABLE `t`"}, {"flashback table t TO t1", true, "FLASHBACK TABLE `t` TO `t1`"}, + {"flashback table t TO timestamp", true, "FLASHBACK TABLE `t` TO `timestamp`"}, + + // for flashback database. + {"flashback database db1", true, "FLASHBACK DATABASE `db1`"}, + {"flashback schema db1", true, "FLASHBACK DATABASE `db1`"}, + {"flashback database db1 to db2", true, "FLASHBACK DATABASE `db1` TO `db2`"}, + {"flashback schema db1 to db2", true, "FLASHBACK DATABASE `db1` TO `db2`"}, - // for flashback cluster + // for flashback to timestamp {"flashback cluster to timestamp '2021-05-26 16:45:26'", true, "FLASHBACK CLUSTER TO TIMESTAMP '2021-05-26 16:45:26'"}, + {"flashback table t to timestamp '2021-05-26 16:45:26'", true, "FLASHBACK TABLE `t` TO TIMESTAMP '2021-05-26 16:45:26'"}, + {"flashback table t,t1 to timestamp '2021-05-26 16:45:26'", true, "FLASHBACK TABLE `t`, `t1` TO TIMESTAMP '2021-05-26 16:45:26'"}, + {"flashback database test to timestamp '2021-05-26 16:45:26'", true, "FLASHBACK DATABASE `test` TO TIMESTAMP '2021-05-26 16:45:26'"}, + {"flashback schema test to timestamp '2021-05-26 16:45:26'", true, "FLASHBACK DATABASE `test` TO TIMESTAMP '2021-05-26 16:45:26'"}, {"flashback cluster to timestamp TIDB_BOUNDED_STALENESS(DATE_SUB(NOW(), INTERVAL 3 SECOND), NOW())", false, ""}, {"flashback cluster to timestamp DATE_SUB(NOW(), INTERVAL 3 SECOND)", false, ""}, + {"flashback table to timestamp '2021-05-26 16:45:26'", false, ""}, + {"flashback database to timestamp '2021-05-26 16:45:26'", false, ""}, // for remove partitioning {"alter table t remove partitioning", true, "ALTER TABLE `t` REMOVE PARTITIONING"}, @@ -3602,6 +3643,31 @@ func TestDDL(t *testing.T) { {"alter placement policy if exists x regions = 'us', follower_constraints='yy'", true, "ALTER PLACEMENT POLICY IF EXISTS `x` REGIONS = 'us' FOLLOWER_CONSTRAINTS = 'yy'"}, {"alter placement policy x placement policy y", false, ""}, + // for create resource group + {"create resource group x cpu ='8c'", true, "CREATE RESOURCE GROUP `x` CPU = '8c'"}, + {"create resource group x region ='us, 3'", false, ""}, + {"create resource group x cpu='8c', io_read_bandwidth='2GB/s', io_write_bandwidth='200MB/s'", true, "CREATE RESOURCE GROUP `x` CPU = '8c' IO_READ_BANDWIDTH = '2GB/s' IO_WRITE_BANDWIDTH = '200MB/s'"}, + {"create resource group x rru_per_sec=2000", true, "CREATE RESOURCE GROUP `x` RRU_PER_SEC = 2000"}, + {"create resource group x wru_per_sec=200000", true, "CREATE RESOURCE GROUP `x` WRU_PER_SEC = 200000"}, + {"create resource group x rru_per_sec=2000 wru_per_sec=200000", true, "CREATE RESOURCE GROUP `x` RRU_PER_SEC = 2000 WRU_PER_SEC = 200000"}, + {"create resource group x followers=0", false, ""}, + + {"alter resource group x cpu ='8c'", true, "ALTER RESOURCE GROUP `x` CPU = '8c'"}, + {"alter resource group x region ='us, 3'", false, ""}, + {"alter resource group x cpu='8c', io_read_bandwidth='2GB/s', io_write_bandwidth='200MB/s'", true, "ALTER RESOURCE GROUP `x` CPU = '8c' IO_READ_BANDWIDTH = '2GB/s' IO_WRITE_BANDWIDTH = '200MB/s'"}, + {"alter resource group x rru_per_sec=2000", true, "ALTER RESOURCE GROUP `x` RRU_PER_SEC = 2000"}, + {"alter resource group x wru_per_sec=200000", true, "ALTER RESOURCE GROUP `x` WRU_PER_SEC = 200000"}, + {"alter resource group x rru_per_sec=2000 wru_per_sec=200000", true, "ALTER RESOURCE GROUP `x` RRU_PER_SEC = 2000 WRU_PER_SEC = 200000"}, + {"alter resource group x followers=0", false, ""}, + + {"drop resource group x;", true, "DROP RESOURCE GROUP `x`"}, + {"drop resource group if exists x;", true, "DROP RESOURCE GROUP IF EXISTS `x`"}, + {"drop resource group x,y", false, ""}, + {"drop resource group if exists x,y", false, ""}, + + {"CREATE ROLE `RESOURCE`", true, "CREATE ROLE `RESOURCE`@`%`"}, + {"CREATE ROLE RESOURCE", false, ""}, + // for table stats options // 1. create table with options {"CREATE TABLE t (a int) STATS_BUCKETS=1", true, "CREATE TABLE `t` (`a` INT) STATS_BUCKETS = 1"}, @@ -3833,6 +3899,44 @@ func TestOptimizerHints(t *testing.T) { require.Len(t, hints[1].Indexes, 1) require.Equal(t, "t4", hints[1].Indexes[0].L) + // Test KEEP_ORDER + stmt, _, err = p.Parse("select /*+ KEEP_ORDER(T1,T2), keep_order(t3,t4) */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "") + require.NoError(t, err) + selectStmt = stmt[0].(*ast.SelectStmt) + + hints = selectStmt.TableHints + require.Len(t, hints, 2) + require.Equal(t, "keep_order", hints[0].HintName.L) + require.Len(t, hints[0].Tables, 1) + require.Equal(t, "t1", hints[0].Tables[0].TableName.L) + require.Len(t, hints[0].Indexes, 1) + require.Equal(t, "t2", hints[0].Indexes[0].L) + + require.Equal(t, "keep_order", hints[1].HintName.L) + require.Len(t, hints[1].Tables, 1) + require.Equal(t, "t3", hints[1].Tables[0].TableName.L) + require.Len(t, hints[1].Indexes, 1) + require.Equal(t, "t4", hints[1].Indexes[0].L) + + // Test NO_KEEP_ORDER + stmt, _, err = p.Parse("select /*+ NO_KEEP_ORDER(T1,T2), no_keep_order(t3,t4) */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "") + require.NoError(t, err) + selectStmt = stmt[0].(*ast.SelectStmt) + + hints = selectStmt.TableHints + require.Len(t, hints, 2) + require.Equal(t, "no_keep_order", hints[0].HintName.L) + require.Len(t, hints[0].Tables, 1) + require.Equal(t, "t1", hints[0].Tables[0].TableName.L) + require.Len(t, hints[0].Indexes, 1) + require.Equal(t, "t2", hints[0].Indexes[0].L) + + require.Equal(t, "no_keep_order", hints[1].HintName.L) + require.Len(t, hints[1].Tables, 1) + require.Equal(t, "t3", hints[1].Tables[0].TableName.L) + require.Len(t, hints[1].Indexes, 1) + require.Equal(t, "t4", hints[1].Indexes[0].L) + // Test TIDB_SMJ stmt, _, err = p.Parse("select /*+ TIDB_SMJ(T1,t2), tidb_smj(T3,t4) */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "") require.NoError(t, err) @@ -4203,6 +4307,35 @@ func TestOptimizerHints(t *testing.T) { require.Equal(t, "hash_agg", hints[0].HintName.L) require.Equal(t, "hash_agg", hints[1].HintName.L) + // Test MPPAgg + stmt, _, err = p.Parse("select /*+ MPP_1PHASE_AGG(), mpp_1phase_agg() */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "") + require.NoError(t, err) + selectStmt = stmt[0].(*ast.SelectStmt) + + hints = selectStmt.TableHints + require.Len(t, hints, 2) + require.Equal(t, "mpp_1phase_agg", hints[0].HintName.L) + require.Equal(t, "mpp_1phase_agg", hints[1].HintName.L) + + stmt, _, err = p.Parse("select /*+ MPP_2PHASE_AGG(), mpp_2phase_agg() */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "") + require.NoError(t, err) + selectStmt = stmt[0].(*ast.SelectStmt) + + hints = selectStmt.TableHints + require.Len(t, hints, 2) + require.Equal(t, "mpp_2phase_agg", hints[0].HintName.L) + require.Equal(t, "mpp_2phase_agg", hints[1].HintName.L) + + // Test ShuffleJoin + stmt, _, err = p.Parse("select /*+ SHUFFLE_JOIN(t1, t2), shuffle_join(t1, t2) */ * from t1, t2 where t1.c1 = t2.c1", "", "") + require.NoError(t, err) + selectStmt = stmt[0].(*ast.SelectStmt) + + hints = selectStmt.TableHints + require.Len(t, hints, 2) + require.Equal(t, "shuffle_join", hints[0].HintName.L) + require.Equal(t, "shuffle_join", hints[1].HintName.L) + // Test STREAM_AGG stmt, _, err = p.Parse("select /*+ STREAM_AGG(), stream_agg() */ c1, c2 from t1, t2 where t1.c1 = t2.c1", "", "") require.NoError(t, err) @@ -4350,7 +4483,7 @@ func TestPrivilege(t *testing.T) { {`CREATE USER 'ttt' REQUIRE SAN 'DNS:mysql-user, URI:spiffe://example.org/myservice'`, true, "CREATE USER `ttt`@`%` REQUIRE SAN 'DNS:mysql-user, URI:spiffe://example.org/myservice'"}, {`CREATE USER 'ttt' WITH MAX_QUERIES_PER_HOUR 2;`, true, "CREATE USER `ttt`@`%` WITH MAX_QUERIES_PER_HOUR 2"}, {`CREATE USER 'ttt'@'localhost' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 10 PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;`, true, "CREATE USER `ttt`@`localhost` REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 10 PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK"}, - {`CREATE USER 'u1'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK ;`, true, "CREATE USER `u1`@`%` IDENTIFIED WITH 'mysql_native_password' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK"}, + {`CREATE USER 'u1'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK ;`, true, "CREATE USER `u1`@`%` IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK"}, {`CREATE USER 'test'`, true, "CREATE USER `test`@`%`"}, {`CREATE USER test`, true, "CREATE USER `test`@`%`"}, {"CREATE USER `test`", true, "CREATE USER `test`@`%`"}, @@ -4374,9 +4507,15 @@ func TestPrivilege(t *testing.T) { {"create user 'test@localhost' password expire never;", true, "CREATE USER `test@localhost`@`%` PASSWORD EXPIRE NEVER"}, {"create user 'test@localhost' password expire default;", true, "CREATE USER `test@localhost`@`%` PASSWORD EXPIRE DEFAULT"}, {"create user 'test@localhost' password expire interval 3 day;", true, "CREATE USER `test@localhost`@`%` PASSWORD EXPIRE INTERVAL 3 DAY"}, + {"create user 'test@localhost' identified by 'password' failed_login_attempts 3 password_lock_time 3;", true, "CREATE USER `test@localhost`@`%` IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3"}, + {"create user 'test@localhost' identified by 'password' failed_login_attempts 3 password_lock_time unbounded;", true, "CREATE USER `test@localhost`@`%` IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME UNBOUNDED"}, + {"create user 'test@localhost' identified by 'password' failed_login_attempts 3;", true, "CREATE USER `test@localhost`@`%` IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3"}, + {"create user 'test@localhost' identified by 'password' password_lock_time 3;", true, "CREATE USER `test@localhost`@`%` IDENTIFIED BY 'password' PASSWORD_LOCK_TIME 3"}, + {"create user 'test@localhost' identified by 'password' password_lock_time unbounded;", true, "CREATE USER `test@localhost`@`%` IDENTIFIED BY 'password' PASSWORD_LOCK_TIME UNBOUNDED"}, {"CREATE USER 'sha_test'@'localhost' IDENTIFIED WITH 'caching_sha2_password' BY 'sha_test'", true, "CREATE USER `sha_test`@`localhost` IDENTIFIED WITH 'caching_sha2_password' BY 'sha_test'"}, {"CREATE USER 'sha_test3'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS 0x24412430303524255B03496C662C1055127B3B654A2F04207D01485276703644704B76303247474564416A516662346C5868646D32764C6B514F43585A473779565947514F34", true, "CREATE USER `sha_test3`@`localhost` IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$%[\x03Ilf,\x10U\x12{;eJ/\x04 }\x01HRvp6DpKv02GGEdAjQfb4lXhdm2vLkQOCXZG7yVYGQO4'"}, {"CREATE USER 'sha_test4'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$%[\x03Ilf,\x10U\x12{;eJ/\x04 }\x01HRvp6DpKv02GGEdAjQfb4lXhdm2vLkQOCXZG7yVYGQO4'", true, "CREATE USER `sha_test4`@`localhost` IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$%[\x03Ilf,\x10U\x12{;eJ/\x04 }\x01HRvp6DpKv02GGEdAjQfb4lXhdm2vLkQOCXZG7yVYGQO4'"}, + {"CREATE USER `user@pingcap.com`@'localhost' IDENTIFIED WITH 'tidb_auth_token' REQUIRE token_issuer 'issuer-abc' ATTRIBUTE '{\"email\": \"user@pingcap.com\"}'", true, "CREATE USER `user@pingcap.com`@`localhost` IDENTIFIED WITH 'tidb_auth_token' REQUIRE TOKEN_ISSUER 'issuer-abc' ATTRIBUTE '{\"email\": \"user@pingcap.com\"}'"}, {"CREATE USER 'nopwd_native'@'localhost' IDENTIFIED WITH 'mysql_native_password'", true, "CREATE USER `nopwd_native`@`localhost` IDENTIFIED WITH 'mysql_native_password'"}, {"CREATE USER 'nopwd_sha'@'localhost' IDENTIFIED WITH 'caching_sha2_password'", true, "CREATE USER `nopwd_sha`@`localhost` IDENTIFIED WITH 'caching_sha2_password'"}, {"CREATE ROLE `test-role`, `role1`@'localhost'", true, "CREATE ROLE `test-role`@`%`, `role1`@`localhost`"}, @@ -4390,8 +4529,10 @@ func TestPrivilege(t *testing.T) { {`CREATE USER 'root'@'localhost' IDENTIFIED BY 'new-password'`, true, "CREATE USER `root`@`localhost` IDENTIFIED BY 'new-password'"}, {`CREATE USER 'root'@'localhost' IDENTIFIED BY PASSWORD 'hashstring'`, true, "CREATE USER `root`@`localhost` IDENTIFIED WITH 'mysql_native_password' AS 'hashstring'"}, {`CREATE USER 'root'@'localhost' IDENTIFIED BY 'new-password', 'root'@'127.0.0.1' IDENTIFIED BY PASSWORD 'hashstring'`, true, "CREATE USER `root`@`localhost` IDENTIFIED BY 'new-password', `root`@`127.0.0.1` IDENTIFIED WITH 'mysql_native_password' AS 'hashstring'"}, + {`CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'hashstring' RESOURCE GROUP rg1`, true, "CREATE USER `root`@`127.0.0.1` IDENTIFIED BY 'hashstring' RESOURCE GROUP `rg1`"}, {`ALTER USER IF EXISTS 'root'@'localhost' IDENTIFIED BY 'new-password'`, true, "ALTER USER IF EXISTS `root`@`localhost` IDENTIFIED BY 'new-password'"}, {`ALTER USER 'root'@'localhost' IDENTIFIED BY 'new-password'`, true, "ALTER USER `root`@`localhost` IDENTIFIED BY 'new-password'"}, + {`ALTER USER 'root'@'localhost' RESOURCE GROUP rg2`, true, "ALTER USER `root`@`localhost` RESOURCE GROUP `rg2`"}, {`ALTER USER 'root'@'localhost' IDENTIFIED BY PASSWORD 'hashstring'`, true, "ALTER USER `root`@`localhost` IDENTIFIED WITH 'mysql_native_password' AS 'hashstring'"}, {`ALTER USER 'root'@'localhost' IDENTIFIED BY 'new-password', 'root'@'127.0.0.1' IDENTIFIED BY PASSWORD 'hashstring'`, true, "ALTER USER `root`@`localhost` IDENTIFIED BY 'new-password', `root`@`127.0.0.1` IDENTIFIED WITH 'mysql_native_password' AS 'hashstring'"}, {`ALTER USER USER() IDENTIFIED BY 'new-password'`, true, "ALTER USER USER() IDENTIFIED BY 'new-password'"}, @@ -4501,6 +4642,14 @@ func TestComment(t *testing.T) { {"create table t (never int)", true, "CREATE TABLE `t` (`never` INT)"}, {"create table t (subject int)", true, "CREATE TABLE `t` (`subject` INT)"}, {"create table t (x509 int)", true, "CREATE TABLE `t` (`x509` INT)"}, + + // COMMENT/ATTRIBUTE in CREATE/ALTER USER + {"create user commentUser COMMENT '123456' '{\"name\": \"Tom\", \"age\", 19}", false, ""}, + {"alter user commentUser COMMENT '123456' '{\"name\": \"Tom\", \"age\", 19}", false, ""}, + {"create user commentUser COMMENT '123456'", true, "CREATE USER `commentUser`@`%` COMMENT '123456'"}, + {"alter user commentUser COMMENT '123456'", true, "ALTER USER `commentUser`@`%` COMMENT '123456'"}, + {"create user commentUser ATTRIBUTE '{\"name\": \"Tom\", \"age\", 19}'", true, "CREATE USER `commentUser`@`%` ATTRIBUTE '{\"name\": \"Tom\", \"age\", 19}'"}, + {"alter user commentUser ATTRIBUTE '{\"name\": \"Tom\", \"age\", 19}'", true, "ALTER USER `commentUser`@`%` ATTRIBUTE '{\"name\": \"Tom\", \"age\", 19}'"}, } RunTest(t, table, false) } @@ -4930,6 +5079,9 @@ func TestExplain(t *testing.T) { {"EXPLAIN ANALYZE FORMAT = 'binary' SELECT 1", true, "EXPLAIN ANALYZE FORMAT = 'binary' SELECT 1"}, {"EXPLAIN ALTER TABLE t1 ADD INDEX (a)", true, "EXPLAIN FORMAT = 'row' ALTER TABLE `t1` ADD INDEX(`a`)"}, {"EXPLAIN ALTER TABLE t1 ADD a varchar(255)", true, "EXPLAIN FORMAT = 'row' ALTER TABLE `t1` ADD COLUMN `a` VARCHAR(255)"}, + {"EXPLAIN FORMAT = TIDB_JSON FOR CONNECTION 1", true, "EXPLAIN FORMAT = 'TIDB_JSON' FOR CONNECTION 1"}, + {"EXPLAIN FORMAT = tidb_json SELECT 1", true, "EXPLAIN FORMAT = 'tidb_json' SELECT 1"}, + {"EXPLAIN ANALYZE FORMAT = tidb_json SELECT 1", true, "EXPLAIN ANALYZE FORMAT = 'tidb_json' SELECT 1"}, } RunTest(t, table, false) } @@ -5045,6 +5197,12 @@ func TestBinding(t *testing.T) { {"drop session binding for replace into t1 select * from t2 where t1.a=1", true, "DROP SESSION BINDING FOR REPLACE INTO `t1` SELECT * FROM `t2` WHERE `t1`.`a`=1"}, {"DROP GLOBAL BINDING FOR REPLACE INTO `t1` SELECT * FROM `t2` WHERE `t2`.`a`=1 USING REPLACE INTO `t1` SELECT /*+ USE_INDEX(`t2` `a`)*/ * FROM `t2` WHERE `t2`.`a`=1", true, "DROP GLOBAL BINDING FOR REPLACE INTO `t1` SELECT * FROM `t2` WHERE `t2`.`a`=1 USING REPLACE INTO `t1` SELECT /*+ USE_INDEX(`t2` `a`)*/ * FROM `t2` WHERE `t2`.`a`=1"}, {"DROP SESSION BINDING FOR REPLACE INTO `t1` SELECT * FROM `t2` WHERE `t2`.`a`=1 USING REPLACE INTO `t1` SELECT /*+ USE_INDEX(`t2` `a`)*/ * FROM `t2` WHERE `t2`.`a`=1", true, "DROP SESSION BINDING FOR REPLACE INTO `t1` SELECT * FROM `t2` WHERE `t2`.`a`=1 USING REPLACE INTO `t1` SELECT /*+ USE_INDEX(`t2` `a`)*/ * FROM `t2` WHERE `t2`.`a`=1"}, + {"DROP SESSION BINDING FOR SQL DIGEST 'a'", true, "DROP SESSION BINDING FOR SQL DIGEST 'a'"}, + {"drop global binding for sql digest 's'", true, "DROP GLOBAL BINDING FOR SQL DIGEST 's'"}, + {"create session binding from history using plan digest 'sss'", true, "CREATE SESSION BINDING FROM HISTORY USING PLAN DIGEST 'sss'"}, + {"CREATE GLOBAL BINDING FROM HISTORY USING PLAN DIGEST 'sss'", true, "CREATE GLOBAL BINDING FROM HISTORY USING PLAN DIGEST 'sss'"}, + {"set binding enabled for sql digest '1'", true, "SET BINDING ENABLED FOR SQL DIGEST '1'"}, + {"set binding disabled for sql digest '1'", true, "SET BINDING DISABLED FOR SQL DIGEST '1'"}, } RunTest(t, table, false) @@ -5231,6 +5389,7 @@ func TestSessionManage(t *testing.T) { // Kill statement. // See https://dev.mysql.com/doc/refman/5.7/en/kill.html {"kill 23123", true, "KILL 23123"}, + {"kill CONNECTION_ID()", true, "KILL CONNECTION_ID()"}, {"kill connection 23123", true, "KILL 23123"}, {"kill query 23123", true, "KILL QUERY 23123"}, {"kill tidb 23123", true, "KILL TIDB 23123"}, @@ -6749,6 +6908,7 @@ func TestPlanReplayer(t *testing.T) { {"PLAN REPLAYER LOAD '/tmp/sdfaalskdjf.zip'", true, "PLAN REPLAYER LOAD '/tmp/sdfaalskdjf.zip'"}, {"PLAN REPLAYER DUMP EXPLAIN 'sql.txt'", true, "PLAN REPLAYER DUMP EXPLAIN 'sql.txt'"}, {"PLAN REPLAYER DUMP EXPLAIN ANALYZE 'sql.txt'", true, "PLAN REPLAYER DUMP EXPLAIN ANALYZE 'sql.txt'"}, + {"PLAN REPLAYER CAPTURE '123' '123'", true, "PLAN REPLAYER CAPTURE '123' '123'"}, } RunTest(t, table, false) @@ -6866,8 +7026,9 @@ func TestCharsetIntroducer(t *testing.T) { require.EqualError(t, err, "[ddl:1115]Unsupported character introducer: 'gbk'") } -func TestNonTransactionalDelete(t *testing.T) { +func TestNonTransactionalDML(t *testing.T) { cases := []testCase{ + // deletes {"batch on c limit 10 delete from t where c = 10", true, "BATCH ON `c` LIMIT 10 DELETE FROM `t` WHERE `c`=10"}, {"batch on c limit 10 dry run delete from t where c = 10", true, @@ -6880,6 +7041,45 @@ func TestNonTransactionalDelete(t *testing.T) { "BATCH LIMIT 10 DRY RUN DELETE FROM `t` WHERE `c`=10"}, {"batch limit 10 dry run query delete from t where c = 10", true, "BATCH LIMIT 10 DRY RUN QUERY DELETE FROM `t` WHERE `c`=10"}, + // updates + {"batch on c limit 10 update t set c = 10", true, + "BATCH ON `c` LIMIT 10 UPDATE `t` SET `c`=10"}, + {"batch on c limit 10 dry run update t set c = 10", true, + "BATCH ON `c` LIMIT 10 DRY RUN UPDATE `t` SET `c`=10"}, + {"batch on c limit 10 dry run query update t set c = 10", true, + "BATCH ON `c` LIMIT 10 DRY RUN QUERY UPDATE `t` SET `c`=10"}, + {"batch limit 10 update t set c = 10", true, + "BATCH LIMIT 10 UPDATE `t` SET `c`=10"}, + {"batch limit 10 dry run update t set c = 10", true, + "BATCH LIMIT 10 DRY RUN UPDATE `t` SET `c`=10"}, + {"batch limit 10 dry run query update t set c = 10", true, + "BATCH LIMIT 10 DRY RUN QUERY UPDATE `t` SET `c`=10"}, + // inserts + {"batch on c limit 10 insert into t1 select * from t2 where c = 10", true, + "BATCH ON `c` LIMIT 10 INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10"}, + {"batch on c limit 10 dry run insert into t1 select * from t2 where c = 10", true, + "BATCH ON `c` LIMIT 10 DRY RUN INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10"}, + {"batch on c limit 10 dry run query insert into t1 select * from t2 where c = 10", true, + "BATCH ON `c` LIMIT 10 DRY RUN QUERY INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10"}, + {"batch limit 10 insert into t1 select * from t2 where c = 10", true, + "BATCH LIMIT 10 INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10"}, + {"batch limit 10 dry run insert into t1 select * from t2 where c = 10", true, + "BATCH LIMIT 10 DRY RUN INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10"}, + {"batch limit 10 dry run query insert into t1 select * from t2 where c = 10", true, + "BATCH LIMIT 10 DRY RUN QUERY INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10"}, + // inserts on duplicate key update + {"batch on c limit 10 insert into t1 select * from t2 where c = 10 on duplicate key update t1.val = t2.val", true, + "BATCH ON `c` LIMIT 10 INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10 ON DUPLICATE KEY UPDATE `t1`.`val`=`t2`.`val`"}, + {"batch on c limit 10 dry run insert into t1 select * from t2 where c = 10 on duplicate key update t1.val = t2.val", true, + "BATCH ON `c` LIMIT 10 DRY RUN INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10 ON DUPLICATE KEY UPDATE `t1`.`val`=`t2`.`val`"}, + {"batch on c limit 10 dry run query insert into t1 select * from t2 where c = 10 on duplicate key update t1.val = t2.val", true, + "BATCH ON `c` LIMIT 10 DRY RUN QUERY INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10 ON DUPLICATE KEY UPDATE `t1`.`val`=`t2`.`val`"}, + {"batch limit 10 insert into t1 select * from t2 where c = 10 on duplicate key update t1.val = t2.val", true, + "BATCH LIMIT 10 INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10 ON DUPLICATE KEY UPDATE `t1`.`val`=`t2`.`val`"}, + {"batch limit 10 dry run insert into t1 select * from t2 where c = 10 on duplicate key update t1.val = t2.val", true, + "BATCH LIMIT 10 DRY RUN INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10 ON DUPLICATE KEY UPDATE `t1`.`val`=`t2`.`val`"}, + {"batch limit 10 dry run query insert into t1 select * from t2 where c = 10 on duplicate key update t1.val = t2.val", true, + "BATCH LIMIT 10 DRY RUN QUERY INSERT INTO `t1` SELECT * FROM `t2` WHERE `c`=10 ON DUPLICATE KEY UPDATE `t1`.`val`=`t2`.`val`"}, } RunTest(t, cases, false) @@ -6904,3 +7104,41 @@ func TestIntervalPartition(t *testing.T) { RunTest(t, table, false) } + +func TestTTLTableOption(t *testing.T) { + table := []testCase{ + // create table with various temporal interval + {"create table t (created_at datetime) TTL = created_at + INTERVAL 3.1415 YEAR", true, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 3.1415 YEAR"}, + {"create table t (created_at datetime) TTL = created_at + INTERVAL '1 1:1:1' DAY_SECOND", true, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL _UTF8MB4'1 1:1:1' DAY_SECOND"}, + {"create table t (created_at datetime) TTL = created_at + INTERVAL 1 YEAR", true, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR"}, + {"create table t (created_at datetime) TTL = created_at + INTERVAL 1 YEAR TTL_ENABLE = 'OFF'", true, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'OFF'"}, + {"create table t (created_at datetime) TTL created_at + INTERVAL 1 YEAR TTL_ENABLE 'OFF'", true, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'OFF'"}, + {"create table t (created_at datetime) TTL created_at + INTERVAL 1 YEAR TTL_ENABLE 'OFF' TTL_JOB_INTERVAL='8h'", true, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'OFF' TTL_JOB_INTERVAL = '8h'"}, + {"create table t (created_at datetime) /*T![ttl] ttl=created_at + INTERVAL 1 YEAR ttl_enable='ON'*/", true, "CREATE TABLE `t` (`created_at` DATETIME) TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'ON'"}, + + // alter table with various temporal interval + {"alter table t TTL = created_at + INTERVAL 1 MONTH", true, "ALTER TABLE `t` TTL = `created_at` + INTERVAL 1 MONTH"}, + {"alter table t TTL_ENABLE = 'ON'", true, "ALTER TABLE `t` TTL_ENABLE = 'ON'"}, + {"alter table t TTL_ENABLE = 'OFF'", true, "ALTER TABLE `t` TTL_ENABLE = 'OFF'"}, + {"alter table t TTL = created_at + INTERVAL 1 MONTH TTL_ENABLE 'OFF'", true, "ALTER TABLE `t` TTL = `created_at` + INTERVAL 1 MONTH TTL_ENABLE = 'OFF'"}, + {"alter table t TTL = created_at + INTERVAL 1 MONTH TTL_ENABLE 'OFF' TTL_JOB_INTERVAL '1h'", true, "ALTER TABLE `t` TTL = `created_at` + INTERVAL 1 MONTH TTL_ENABLE = 'OFF' TTL_JOB_INTERVAL = '1h'"}, + {"alter table t /*T![ttl] ttl=created_at + INTERVAL 1 YEAR ttl_enable='ON'*/", true, "ALTER TABLE `t` TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'ON'"}, + {"alter table t /*T![ttl] ttl=created_at + INTERVAL 1 YEAR ttl_enable='ON' TTL_JOB_INTERVAL='8h'*/", true, "ALTER TABLE `t` TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'ON' TTL_JOB_INTERVAL = '8h'"}, + {"alter table t /*T![ttl] ttl=created_at + INTERVAL 1 YEAR ttl_enable='ON' TTL_JOB_INTERVAL='8.645124531235h'*/", true, "ALTER TABLE `t` TTL = `created_at` + INTERVAL 1 YEAR TTL_ENABLE = 'ON' TTL_JOB_INTERVAL = '8.645124531235h'"}, + + // alter table to remove ttl settings + {"alter table t remove ttl", true, "ALTER TABLE `t` REMOVE TTL"}, + + // validate invalid TTL_ENABLE settings + {"create table t (created_at datetime) TTL_ENABLE = 'test_case'", false, ""}, + {"create table t (created_at datetime) /*T![ttl] TTL_ENABLE = 'test_case' */", false, ""}, + {"alter table t /*T![ttl] TTL_ENABLE = 'test_case' */", false, ""}, + + // validate invalid TTL_JOB_INTERVAL settings + {"create table t (created_at datetime) TTL_JOB_INTERVAL = '@monthly'", false, ""}, + {"create table t (created_at datetime) TTL_JOB_INTERVAL = '10hourxx'", false, ""}, + {"create table t (created_at datetime) TTL_JOB_INTERVAL = '10.10.255h'", false, ""}, + } + + RunTest(t, table, false) +} diff --git a/parser/reserved_words_test.go b/parser/reserved_words_test.go index f58359a7d20a3..6896167741284 100644 --- a/parser/reserved_words_test.go +++ b/parser/reserved_words_test.go @@ -28,7 +28,7 @@ import ( // needed to connect to MySQL dbsql "database/sql" - "io/ioutil" + gio "io" "os" "testing" @@ -41,7 +41,7 @@ func TestCompareReservedWordsWithMySQL(t *testing.T) { parserFilename := "parser.y" parserFile, err := os.Open(parserFilename) requires.NoError(t, err) - data, err := ioutil.ReadAll(parserFile) + data, err := gio.ReadAll(parserFile) requires.NoError(t, err) content := string(data) diff --git a/parser/tidb/features.go b/parser/tidb/features.go index 296a3d6b37d9b..1bdb511d20f35 100644 --- a/parser/tidb/features.go +++ b/parser/tidb/features.go @@ -28,6 +28,10 @@ const ( FeatureIDForceAutoInc = "force_inc" // FeatureIDPlacement is the `placement rule` feature. FeatureIDPlacement = "placement" + // FeatureIDTTL is the `ttl` feature + FeatureIDTTL = "ttl" + // FeatureIDResourceGroup is the `resource group` feature. + FeatureIDResourceGroup = "resource_group" ) var featureIDs = map[string]struct{}{ @@ -37,6 +41,7 @@ var featureIDs = map[string]struct{}{ FeatureIDClusteredIndex: {}, FeatureIDForceAutoInc: {}, FeatureIDPlacement: {}, + FeatureIDTTL: {}, } // CanParseFeature is used to check if a feature can be parsed. diff --git a/parser/types/field_type.go b/parser/types/field_type.go index 0436d088dd121..464ba38a6cb7c 100644 --- a/parser/types/field_type.go +++ b/parser/types/field_type.go @@ -56,6 +56,7 @@ type FieldType struct { // elems is the element list for enum and set type. elems []string elemsIsBinaryLit []bool + array bool // Please keep in mind that jsonFieldType should be updated if you add a new field here. } @@ -71,14 +72,27 @@ func NewFieldType(tp byte) *FieldType { // IsDecimalValid checks whether the decimal is valid. func (ft *FieldType) IsDecimalValid() bool { - if ft.tp == mysql.TypeNewDecimal && (ft.decimal < 0 || ft.decimal > mysql.MaxDecimalScale || ft.flen <= 0 || ft.flen > mysql.MaxDecimalWidth || ft.flen < ft.decimal) { + if ft.GetType() == mysql.TypeNewDecimal && (ft.decimal < 0 || ft.decimal > mysql.MaxDecimalScale || ft.flen <= 0 || ft.flen > mysql.MaxDecimalWidth || ft.flen < ft.decimal) { return false } return true } +// IsVarLengthType Determine whether the column type is a variable-length type +func (ft *FieldType) IsVarLengthType() bool { + switch ft.GetType() { + case mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeJSON, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob: + return true + default: + return false + } +} + // GetType returns the type of the FieldType. func (ft *FieldType) GetType() byte { + if ft.array { + return mysql.TypeJSON + } return ft.tp } @@ -115,6 +129,7 @@ func (ft *FieldType) GetElems() []string { // SetType sets the type of the FieldType. func (ft *FieldType) SetType(tp byte) { ft.tp = tp + ft.array = false } // SetFlag sets the flag of the FieldType. @@ -149,7 +164,7 @@ func (ft *FieldType) SetFlen(flen int) { // SetFlenUnderLimit sets the length of the field to the value of the argument func (ft *FieldType) SetFlenUnderLimit(flen int) { - if ft.tp == mysql.TypeNewDecimal { + if ft.GetType() == mysql.TypeNewDecimal { ft.flen = mathutil.Min(flen, mysql.MaxDecimalWidth) } else { ft.flen = flen @@ -163,7 +178,7 @@ func (ft *FieldType) SetDecimal(decimal int) { // SetDecimalUnderLimit sets the decimal of the field to the value of the argument func (ft *FieldType) SetDecimalUnderLimit(decimal int) { - if ft.tp == mysql.TypeNewDecimal { + if ft.GetType() == mysql.TypeNewDecimal { ft.decimal = mathutil.Min(decimal, mysql.MaxDecimalScale) } else { ft.decimal = decimal @@ -172,7 +187,7 @@ func (ft *FieldType) SetDecimalUnderLimit(decimal int) { // UpdateFlenAndDecimalUnderLimit updates the length and decimal to the value of the argument func (ft *FieldType) UpdateFlenAndDecimalUnderLimit(old *FieldType, deltaDecimal int, deltaFlen int) { - if ft.tp != mysql.TypeNewDecimal { + if ft.GetType() != mysql.TypeNewDecimal { return } if old.decimal < 0 { @@ -208,6 +223,26 @@ func (ft *FieldType) SetElem(idx int, element string) { ft.elems[idx] = element } +// SetArray sets the array field of the FieldType. +func (ft *FieldType) SetArray(array bool) { + ft.array = array +} + +// IsArray return true if the filed type is array. +func (ft *FieldType) IsArray() bool { + return ft.array +} + +// ArrayType return the type of the array. +func (ft *FieldType) ArrayType() *FieldType { + if !ft.array { + return ft + } + clone := ft.Clone() + clone.SetArray(false) + return clone +} + // SetElemWithIsBinaryLit sets the element of the FieldType. func (ft *FieldType) SetElemWithIsBinaryLit(idx int, element string, isBinaryLit bool) { ft.elems[idx] = element @@ -253,7 +288,7 @@ func (ft *FieldType) Equal(other *FieldType) bool { // When tp is float or double with decimal unspecified, do not check whether flen is equal, // because flen for them is useless. // The decimal field can be ignored if the type is int or string. - tpEqual := (ft.tp == other.tp) || (ft.tp == mysql.TypeVarchar && other.tp == mysql.TypeVarString) || (ft.tp == mysql.TypeVarString && other.tp == mysql.TypeVarchar) + tpEqual := (ft.GetType() == other.GetType()) || (ft.GetType() == mysql.TypeVarchar && other.GetType() == mysql.TypeVarString) || (ft.GetType() == mysql.TypeVarString && other.GetType() == mysql.TypeVarchar) flenEqual := ft.flen == other.flen || (ft.EvalType() == ETReal && ft.decimal == UnspecifiedLength) ignoreDecimal := ft.EvalType() == ETInt || ft.EvalType() == ETString partialEqual := tpEqual && @@ -295,7 +330,7 @@ func (ft *FieldType) PartialEqual(other *FieldType, unsafe bool) bool { // EvalType gets the type in evaluation. func (ft *FieldType) EvalType() EvalType { - switch ft.tp { + switch ft.GetType() { case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong, mysql.TypeBit, mysql.TypeYear: return ETInt @@ -321,7 +356,7 @@ func (ft *FieldType) EvalType() EvalType { // Hybrid checks whether a type is a hybrid type, which can represent different types of value in specific context. func (ft *FieldType) Hybrid() bool { - return ft.tp == mysql.TypeEnum || ft.tp == mysql.TypeBit || ft.tp == mysql.TypeSet + return ft.GetType() == mysql.TypeEnum || ft.GetType() == mysql.TypeBit || ft.GetType() == mysql.TypeSet } // Init initializes the FieldType data. @@ -334,10 +369,10 @@ func (ft *FieldType) Init(tp byte) { // CompactStr only considers tp/CharsetBin/flen/Deimal. // This is used for showing column type in infoschema. func (ft *FieldType) CompactStr() string { - ts := TypeToStr(ft.tp, ft.charset) + ts := TypeToStr(ft.GetType(), ft.charset) suffix := "" - defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimal(ft.tp) + defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimal(ft.GetType()) isDecimalNotDefault := ft.decimal != defaultDecimal && ft.decimal != 0 && ft.decimal != UnspecifiedLength // displayFlen and displayDecimal are flen and decimal values with `-1` substituted with default value. @@ -349,7 +384,7 @@ func (ft *FieldType) CompactStr() string { displayDecimal = defaultDecimal } - switch ft.tp { + switch ft.GetType() { case mysql.TypeEnum, mysql.TypeSet: // Format is ENUM ('e1', 'e2') or SET ('e1', 'e2') es := make([]string, 0, len(ft.elems)) @@ -392,7 +427,9 @@ func (ft *FieldType) CompactStr() string { // returns a string. func (ft *FieldType) InfoSchemaStr() string { suffix := "" - if mysql.HasUnsignedFlag(ft.flag) { + if mysql.HasUnsignedFlag(ft.flag) && + ft.GetType() != mysql.TypeBit && + ft.GetType() != mysql.TypeYear { suffix = " unsigned" } return ft.CompactStr() + suffix @@ -408,11 +445,11 @@ func (ft *FieldType) String() string { if mysql.HasZerofillFlag(ft.flag) { strs = append(strs, "ZEROFILL") } - if mysql.HasBinaryFlag(ft.flag) && ft.tp != mysql.TypeString { + if mysql.HasBinaryFlag(ft.flag) && ft.GetType() != mysql.TypeString { strs = append(strs, "BINARY") } - if IsTypeChar(ft.tp) || IsTypeBlob(ft.tp) { + if IsTypeChar(ft.GetType()) || IsTypeBlob(ft.GetType()) { if ft.charset != "" && ft.charset != charset.CharsetBin { strs = append(strs, fmt.Sprintf("CHARACTER SET %s", ft.charset)) } @@ -426,12 +463,12 @@ func (ft *FieldType) String() string { // Restore implements Node interface. func (ft *FieldType) Restore(ctx *format.RestoreCtx) error { - ctx.WriteKeyWord(TypeToStr(ft.tp, ft.charset)) + ctx.WriteKeyWord(TypeToStr(ft.GetType(), ft.charset)) precision := UnspecifiedLength scale := UnspecifiedLength - switch ft.tp { + switch ft.GetType() { case mysql.TypeEnum, mysql.TypeSet: ctx.WritePlain("(") for i, e := range ft.elems { @@ -468,7 +505,7 @@ func (ft *FieldType) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord(" BINARY") } - if IsTypeChar(ft.tp) || IsTypeBlob(ft.tp) { + if IsTypeChar(ft.GetType()) || IsTypeBlob(ft.GetType()) { if ft.charset != "" && ft.charset != charset.CharsetBin { ctx.WriteKeyWord(" CHARACTER SET " + ft.charset) } @@ -484,7 +521,7 @@ func (ft *FieldType) Restore(ctx *format.RestoreCtx) error { // RestoreAsCastType is used for write AST back to string. func (ft *FieldType) RestoreAsCastType(ctx *format.RestoreCtx, explicitCharset bool) { switch ft.tp { - case mysql.TypeVarString: + case mysql.TypeVarString, mysql.TypeString: skipWriteBinary := false if ft.charset == charset.CharsetBin && ft.collate == charset.CollationBin { ctx.WriteKeyWord("BINARY") @@ -496,7 +533,7 @@ func (ft *FieldType) RestoreAsCastType(ctx *format.RestoreCtx, explicitCharset b ctx.WritePlainf("(%d)", ft.flen) } if !explicitCharset { - return + break } if !skipWriteBinary && ft.flag&mysql.BinaryFlag != 0 { ctx.WriteKeyWord(" BINARY") @@ -539,6 +576,10 @@ func (ft *FieldType) RestoreAsCastType(ctx *format.RestoreCtx, explicitCharset b case mysql.TypeYear: ctx.WriteKeyWord("YEAR") } + if ft.array { + ctx.WritePlain(" ") + ctx.WriteKeyWord("ARRAY") + } } // FormatAsCastType is used for write AST back to string. @@ -554,7 +595,7 @@ const VarStorageLen = -1 // StorageLength is the length of stored value for the type. func (ft *FieldType) StorageLength() int { - switch ft.tp { + switch ft.GetType() { case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong, mysql.TypeDouble, mysql.TypeFloat, mysql.TypeYear, mysql.TypeDuration, mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp, mysql.TypeEnum, mysql.TypeSet, @@ -572,7 +613,7 @@ func (ft *FieldType) StorageLength() int { // HasCharset indicates if a COLUMN has an associated charset. Returning false here prevents some information // statements(like `SHOW CREATE TABLE`) from attaching a CHARACTER SET clause to the column. func HasCharset(ft *FieldType) bool { - switch ft.tp { + switch ft.GetType() { case mysql.TypeVarchar, mysql.TypeString, mysql.TypeVarString, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob: return !mysql.HasBinaryFlag(ft.flag) @@ -592,6 +633,7 @@ type jsonFieldType struct { Collate string Elems []string ElemsIsBinaryLit []bool + Array bool } // UnmarshalJSON implements the json.Unmarshaler interface. @@ -607,6 +649,7 @@ func (ft *FieldType) UnmarshalJSON(data []byte) error { ft.collate = r.Collate ft.elems = r.Elems ft.elemsIsBinaryLit = r.ElemsIsBinaryLit + ft.array = r.Array } return err } @@ -622,6 +665,7 @@ func (ft *FieldType) MarshalJSON() ([]byte, error) { r.Collate = ft.collate r.Elems = ft.elems r.ElemsIsBinaryLit = ft.elemsIsBinaryLit + r.Array = ft.array return json.Marshal(r) } @@ -632,12 +676,11 @@ func (ft *FieldType) MemoryUsage() (sum int64) { if ft == nil { return } - sum = emptyFieldTypeSize + int64(len(ft.charset)+len(ft.collate)) + sum = emptyFieldTypeSize + int64(len(ft.charset)+len(ft.collate)) + int64(cap(ft.elems))*int64(unsafe.Sizeof(*new(string))) + + int64(cap(ft.elemsIsBinaryLit))*int64(unsafe.Sizeof(*new(bool))) for _, s := range ft.elems { sum += int64(len(s)) } - sum += int64(cap(ft.elems)) * int64(unsafe.Sizeof(*new(string))) - sum += int64(cap(ft.elemsIsBinaryLit)) * int64(unsafe.Sizeof(*new(bool))) return } diff --git a/parser/yy_parser.go b/parser/yy_parser.go index 7ab66a19937d1..48409d81085a7 100644 --- a/parser/yy_parser.go +++ b/parser/yy_parser.go @@ -52,6 +52,8 @@ var ( ErrUnknownAlterAlgorithm = terror.ClassParser.NewStd(mysql.ErrUnknownAlterAlgorithm) // ErrWrongValue returns for wrong value ErrWrongValue = terror.ClassParser.NewStd(mysql.ErrWrongValue) + // ErrWarnDeprecatedSyntax return when the syntax was deprecated + ErrWarnDeprecatedSyntax = terror.ClassParser.NewStd(mysql.ErrWarnDeprecatedSyntax) // ErrWarnDeprecatedSyntaxNoReplacement return when the syntax was deprecated and there is no replacement. ErrWarnDeprecatedSyntaxNoReplacement = terror.ClassParser.NewStd(mysql.ErrWarnDeprecatedSyntaxNoReplacement) // ErrWarnDeprecatedIntegerDisplayWidth share the same code 1681, and it will be returned when length is specified in integer. diff --git a/planner/cascades/main_test.go b/planner/cascades/main_test.go index 5ebbbc50eebfb..8e3fb1f656b17 100644 --- a/planner/cascades/main_test.go +++ b/planner/cascades/main_test.go @@ -48,7 +48,9 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } if err := goleak.Find(opts...); err != nil { diff --git a/planner/cascades/testdata/integration_suite_in.json b/planner/cascades/testdata/integration_suite_in.json index 569cb12860ac3..c5ac4131897cd 100644 --- a/planner/cascades/testdata/integration_suite_in.json +++ b/planner/cascades/testdata/integration_suite_in.json @@ -124,7 +124,7 @@ { "name": "TestMemTableScan", "cases": [ - "select USER, HOST, DB, COMMAND, TIME, STATE, INFO, DIGEST from information_schema.processlist" + "select USER, HOST, DB, COMMAND, TIME, STATE, INFO, `DIGEST` from information_schema.processlist" ] }, { @@ -142,7 +142,7 @@ { "name": "TestCascadePlannerHashedPartTable", "cases": [ - "select * from pt1" + "select * from pt1 order by a" ] }, { diff --git a/planner/cascades/testdata/integration_suite_out.json b/planner/cascades/testdata/integration_suite_out.json index e8d98a41ec557..25d3a20d484af 100644 --- a/planner/cascades/testdata/integration_suite_out.json +++ b/planner/cascades/testdata/integration_suite_out.json @@ -1093,12 +1093,12 @@ "Name": "TestMemTableScan", "Cases": [ { - "SQL": "select USER, HOST, DB, COMMAND, TIME, STATE, INFO, DIGEST from information_schema.processlist", + "SQL": "select USER, HOST, DB, COMMAND, TIME, STATE, INFO, `DIGEST` from information_schema.processlist", "Plan": [ "Projection_3 10000.00 root Column#2, Column#3, Column#4, Column#5, Column#6, Column#7, Column#8, Column#9", "└─MemTableScan_4 10000.00 root table:PROCESSLIST " ], - "Result": [" test Sleep 0 autocommit select USER, HOST, DB, COMMAND, TIME, STATE, INFO, DIGEST from information_schema.processlist 7284ef6cf62f14bccb9fa24aff861b419e9cf59b2c098d3069c7c10bc35d0c14"] + "Result": [" test Sleep 0 autocommit select USER, HOST, DB, COMMAND, TIME, STATE, INFO, `DIGEST` from information_schema.processlist 7284ef6cf62f14bccb9fa24aff861b419e9cf59b2c098d3069c7c10bc35d0c14"] } ] }, @@ -1198,17 +1198,18 @@ "Name": "TestCascadePlannerHashedPartTable", "Cases": [ { - "SQL": "select * from pt1", + "SQL": "select * from pt1 order by a", "Plan": [ - "TableReader_5 10000.00 root partition:all data:TableFullScan_6", - "└─TableFullScan_6 10000.00 cop[tikv] table:pt1 keep order:false, stats:pseudo" + "Sort_11 10000.00 root test.pt1.a", + "└─TableReader_9 10000.00 root partition:all data:TableFullScan_10", + " └─TableFullScan_10 10000.00 cop[tikv] table:pt1 keep order:false, stats:pseudo" ], "Result": [ - "4 40", "1 10", - "5 50", "2 20", - "3 30" + "3 30", + "4 40", + "5 50" ] } ] diff --git a/planner/cascades/transformation_rules.go b/planner/cascades/transformation_rules.go index 0991379df468b..3dd85fbaa5120 100644 --- a/planner/cascades/transformation_rules.go +++ b/planner/cascades/transformation_rules.go @@ -550,8 +550,8 @@ func (*PushSelDownProjection) OnTransform(old *memo.ExprIter) (newExprs []*memo. canBePushed := make([]expression.Expression, 0, len(sel.Conditions)) canNotBePushed := make([]expression.Expression, 0, len(sel.Conditions)) for _, cond := range sel.Conditions { - substituted, newFilter := expression.ColumnSubstitute4PPD(cond, projSchema, proj.Exprs) - if substituted && !expression.HasGetSetVarFunc(newFilter) { + substituted, hasFailed, newFilter := expression.ColumnSubstituteImpl(cond, projSchema, proj.Exprs, true) + if substituted && !hasFailed && !expression.HasGetSetVarFunc(newFilter) { canBePushed = append(canBePushed, newFilter) } else { canNotBePushed = append(canNotBePushed, cond) diff --git a/planner/core/BUILD.bazel b/planner/core/BUILD.bazel index 21996f693918e..3afbdf3b8a0bc 100644 --- a/planner/core/BUILD.bazel +++ b/planner/core/BUILD.bazel @@ -18,6 +18,7 @@ go_library( "handle_cols.go", "hashcode.go", "hints.go", + "indexmerge_path.go", "initialize.go", "logical_plan_builder.go", "logical_plans.go", @@ -106,6 +107,7 @@ go_library( "//sessiontxn/staleread", "//statistics", "//statistics/handle", + "//store/driver/backoff", "//table", "//table/tables", "//table/temptable", @@ -137,12 +139,14 @@ go_library( "//util/set", "//util/size", "//util/sqlexec", + "//util/stmtsummary", "//util/stringutil", "//util/texttree", "//util/tracing", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_kvproto//pkg/coprocessor", + "@com_github_pingcap_kvproto//pkg/diagnosticspb", "@com_github_pingcap_tipb//go-tipb", "@com_github_tikv_client_go_v2//kv", "@com_github_tikv_client_go_v2//tikv", @@ -167,6 +171,8 @@ go_test( "find_best_task_test.go", "flat_plan_test.go", "fragment_test.go", + "indexmerge_intersection_test.go", + "indexmerge_path_test.go", "indexmerge_test.go", "integration_partition_test.go", "integration_test.go", @@ -188,6 +194,7 @@ go_test( "plan_cost_detail_test.go", "plan_cost_ver1_test.go", "plan_cost_ver2_test.go", + "plan_replayer_capture_test.go", "plan_stats_test.go", "plan_test.go", "plan_to_pb_test.go", @@ -236,9 +243,12 @@ go_test( "//sessiontxn", "//statistics", "//statistics/handle", + "//store/mockstore", + "//store/mockstore/unistore", "//table", "//testkit", "//testkit/ddlhelper", + "//testkit/external", "//testkit/testdata", "//testkit/testmain", "//testkit/testsetup", @@ -263,10 +273,12 @@ go_test( "@com_github_golang_snappy//:snappy", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_kvproto//pkg/metapb", "@com_github_pingcap_tipb//go-tipb", "@com_github_prometheus_client_golang//prometheus", "@com_github_prometheus_client_model//go", "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//testutils", "@org_golang_x_exp//slices", "@org_uber_go_goleak//:goleak", ], diff --git a/planner/core/binary_plan_test.go b/planner/core/binary_plan_test.go index b7c047253c6db..95c67990b09be 100644 --- a/planner/core/binary_plan_test.go +++ b/planner/core/binary_plan_test.go @@ -17,7 +17,7 @@ package core_test import ( "encoding/base64" "fmt" - "io/ioutil" + "io" "os" "regexp" "strings" @@ -77,12 +77,6 @@ func simplifyAndCheckBinaryOperator(t *testing.T, pb *tipb.ExplainOperator, with } func TestBinaryPlanInExplainAndSlowLog(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - // If we don't set this, it will be false sometimes and the cost in the result will be different. - tk.MustExec("set @@tidb_enable_chunk_rpc=true") - // Prepare the slow log originCfg := config.GetGlobalConfig() newCfg := *originCfg @@ -96,6 +90,12 @@ func TestBinaryPlanInExplainAndSlowLog(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + // If we don't set this, it will be false sometimes and the cost in the result will be different. + tk.MustExec("set @@tidb_enable_chunk_rpc=true") tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("set tidb_slow_log_threshold=0;") defer func() { @@ -148,10 +148,6 @@ func TestBinaryPlanInExplainAndSlowLog(t *testing.T) { } func TestBinaryPlanSwitch(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) - originCfg := config.GetGlobalConfig() newCfg := *originCfg f, err := os.CreateTemp("", "tidb-slow-*.log") @@ -164,6 +160,9 @@ func TestBinaryPlanSwitch(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("use test") @@ -218,10 +217,6 @@ func TestBinaryPlanSwitch(t *testing.T) { // TestTooLongBinaryPlan asserts that if the binary plan is larger than 1024*1024 bytes, it should be output to slow query but not to stmt summary. func TestTooLongBinaryPlan(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) - originCfg := config.GetGlobalConfig() newCfg := *originCfg f, err := os.CreateTemp("", "tidb-slow-*.log") @@ -234,6 +229,9 @@ func TestTooLongBinaryPlan(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("use test") @@ -280,10 +278,6 @@ func TestTooLongBinaryPlan(t *testing.T) { // TestLongBinaryPlan asserts that if the binary plan is smaller than 1024*1024 bytes, it should be output to both slow query and stmt summary. // The size of the binary plan in this test case is designed to be larger than 1024*1024*0.85 bytes but smaller than 1024*1024 bytes. func TestLongBinaryPlan(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) - originCfg := config.GetGlobalConfig() newCfg := *originCfg f, err := os.CreateTemp("", "tidb-slow-*.log") @@ -296,6 +290,10 @@ func TestLongBinaryPlan(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("use test") @@ -335,10 +333,6 @@ func TestLongBinaryPlan(t *testing.T) { } func TestBinaryPlanOfPreparedStmt(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) - originCfg := config.GetGlobalConfig() newCfg := *originCfg f, err := os.CreateTemp("", "tidb-slow-*.log") @@ -351,6 +345,9 @@ func TestBinaryPlanOfPreparedStmt(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("use test") @@ -388,10 +385,6 @@ func TestBinaryPlanOfPreparedStmt(t *testing.T) { // TestDecodeBinaryPlan asserts that the result of EXPLAIN ANALYZE FORMAT = 'verbose' is the same as tidb_decode_binary_plan(). func TestDecodeBinaryPlan(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - // Prepare the slow log originCfg := config.GetGlobalConfig() newCfg := *originCfg @@ -405,6 +398,9 @@ func TestDecodeBinaryPlan(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("set tidb_slow_log_threshold=0;") defer func() { @@ -498,10 +494,6 @@ func TestInvalidDecodeBinaryPlan(t *testing.T) { } func TestUnnecessaryBinaryPlanInSlowLog(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) - originCfg := config.GetGlobalConfig() newCfg := *originCfg f, err := os.CreateTemp("", "tidb-slow-*.log") @@ -514,13 +506,16 @@ func TestUnnecessaryBinaryPlanInSlowLog(t *testing.T) { require.NoError(t, os.Remove(newCfg.Log.SlowQueryFile)) }() require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig())) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name())) tk.MustExec("use test") tk.MustExec("drop table if exists th") tk.MustExec("set global tidb_slow_log_threshold = 1;") tk.MustExec("create table th (i int, a int,b int, c int, index (a)) partition by hash (a) partitions 100;") - slowLogBytes, err := ioutil.ReadAll(f) + slowLogBytes, err := io.ReadAll(f) require.NoError(t, err) require.NotContains(t, string(slowLogBytes), `tidb_decode_binary_plan('')`) } diff --git a/planner/core/cbo_test.go b/planner/core/cbo_test.go index 31ba6bfeb3e07..8448a66cd0bf0 100644 --- a/planner/core/cbo_test.go +++ b/planner/core/cbo_test.go @@ -57,6 +57,34 @@ func loadTableStats(fileName string, dom *domain.Domain) error { return nil } +func TestExplainCostTrace(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (a int)") + tk.MustExec("insert into t values (1)") + + tk.MustExec("set tidb_cost_model_version=2") + tk.MustQuery("explain format='cost_trace' select * from t").Check(testkit.Rows( + `TableReader_5 10000.00 177906.67 ((scan(10000*logrowsize(32)*tikv_scan_factor(40.7))) + (net(10000*rowsize(16)*tidb_kv_net_factor(3.96))))/15.00 root data:TableFullScan_4`, + `└─TableFullScan_4 10000.00 2035000.00 scan(10000*logrowsize(32)*tikv_scan_factor(40.7)) cop[tikv] table:t keep order:false, stats:pseudo`)) + tk.MustQuery("explain analyze format='cost_trace' select * from t").CheckAt([]int{0, 1, 2, 3, 4}, [][]interface{}{ + {"TableReader_5", "10000.00", "177906.67", "((scan(10000*logrowsize(32)*tikv_scan_factor(40.7))) + (net(10000*rowsize(16)*tidb_kv_net_factor(3.96))))/15.00", "1"}, + {"└─TableFullScan_4", "10000.00", "2035000.00", "scan(10000*logrowsize(32)*tikv_scan_factor(40.7))", "1"}, + }) + + tk.MustExec("set tidb_cost_model_version=1") + tk.MustQuery("explain format='cost_trace' select * from t").Check(testkit.Rows( + // cost trace on model ver1 is not supported + `TableReader_5 10000.00 34418.00 N/A root data:TableFullScan_4`, + `└─TableFullScan_4 10000.00 435000.00 N/A cop[tikv] table:t keep order:false, stats:pseudo`, + )) + tk.MustQuery("explain analyze format='cost_trace' select * from t").CheckAt([]int{0, 1, 2, 3, 4}, [][]interface{}{ + {"TableReader_5", "10000.00", "34418.00", "N/A", "1"}, + {"└─TableFullScan_4", "10000.00", "435000.00", "N/A", "1"}, + }) +} + func TestExplainAnalyze(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -167,6 +195,7 @@ func TestEstimation(t *testing.T) { statistics.RatioOfPseudoEstimate.Store(10.0) defer statistics.RatioOfPseudoEstimate.Store(0.7) testKit.MustExec("use test") + testKit.MustExec("set tidb_cost_model_version=2") testKit.MustExec("create table t (a int)") testKit.MustExec("insert into t values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)") testKit.MustExec("insert into t select * from t") @@ -211,6 +240,7 @@ func constructInsertSQL(i, n int) string { func TestIndexRead(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) testKit := testkit.NewTestKit(t, store) + testKit.MustExec("set tidb_cost_model_version=2") testKit.MustExec("set @@session.tidb_executor_concurrency = 4;") testKit.MustExec("set @@session.tidb_hash_join_concurrency = 5;") testKit.MustExec("set @@session.tidb_distsql_scan_concurrency = 15;") @@ -246,7 +276,7 @@ func TestIndexRead(t *testing.T) { require.Len(t, stmts, 1) stmt := stmts[0] ret := &core.PreprocessorReturn{} - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(ret)) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), ctx, stmt, ret.InfoSchema) require.NoError(t, err) @@ -262,6 +292,7 @@ func TestEmptyTable(t *testing.T) { store := testkit.CreateMockStore(t) testKit := testkit.NewTestKit(t, store) testKit.MustExec("use test") + testKit.MustExec("set tidb_cost_model_version=2") testKit.MustExec("drop table if exists t, t1") testKit.MustExec("create table t (c1 int)") testKit.MustExec("create table t1 (c1 int)") @@ -276,7 +307,7 @@ func TestEmptyTable(t *testing.T) { require.Len(t, stmts, 1) stmt := stmts[0] ret := &core.PreprocessorReturn{} - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(ret)) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), ctx, stmt, ret.InfoSchema) require.NoError(t, err) @@ -343,7 +374,7 @@ func TestAnalyze(t *testing.T) { err = executor.ResetContextOfStmt(ctx, stmt) require.NoError(t, err) ret := &core.PreprocessorReturn{} - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(ret)) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), ctx, stmt, ret.InfoSchema) require.NoError(t, err) @@ -432,6 +463,7 @@ func TestCorrelatedEstimation(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by tk.MustExec("create table t(a int, b int, c int, index idx(c,b,a))") tk.MustExec("insert into t values(1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,6,6), (7,7,7), (8,8,8), (9,9,9),(10,10,10)") @@ -586,7 +618,7 @@ func BenchmarkOptimize(b *testing.B) { require.Len(b, stmts, 1) stmt := stmts[0] ret := &core.PreprocessorReturn{} - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(ret)) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(ret)) require.NoError(b, err) b.Run(tt.sql, func(b *testing.B) { @@ -605,6 +637,7 @@ func TestIssue9562(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") var input [][]string var output []struct { SQL []string @@ -662,6 +695,7 @@ func TestLimitCrossEstimation(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@session.tidb_executor_concurrency = 4;") tk.MustExec("set @@session.tidb_hash_join_concurrency = 5;") tk.MustExec("set @@session.tidb_distsql_scan_concurrency = 15;") @@ -697,6 +731,7 @@ func TestLowSelIndexGreedySearch(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) testKit := testkit.NewTestKit(t, store) testKit.MustExec("use test") + testKit.MustExec("set tidb_cost_model_version=2") testKit.MustExec(`set tidb_opt_limit_push_down_threshold=0`) testKit.MustExec("drop table if exists t") testKit.MustExec("create table t (a varchar(32) default null, b varchar(10) default null, c varchar(12) default null, d varchar(32) default null, e bigint(10) default null, key idx1 (d,a), key idx2 (a,c), key idx3 (c,b), key idx4 (e))") @@ -796,6 +831,7 @@ func TestLimitIndexEstimation(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int, key idx_a(a), key idx_b(b))") tk.MustExec("set session tidb_enable_extended_stats = on") @@ -827,7 +863,7 @@ func TestBatchPointGetTablePartition(t *testing.T) { testKit.MustExec("use test") testKit.MustExec("drop table if exists t1,t2,t3,t4,t5,t6") - testKit.MustExec("create table t1(a int, b int, primary key(a,b)) partition by hash(b) partitions 2") + testKit.MustExec("create table t1(a int, b int, primary key(a,b) nonclustered) partition by hash(b) partitions 2") testKit.MustExec("insert into t1 values(1,1),(1,2),(2,1),(2,2)") testKit.MustExec("set @@tidb_partition_prune_mode = 'static'") testKit.MustQuery("explain format = 'brief' select * from t1 where a in (1,2) and b = 1").Check(testkit.Rows( @@ -864,7 +900,7 @@ func TestBatchPointGetTablePartition(t *testing.T) { "1 2", )) - testKit.MustExec("create table t2(a int, b int, primary key(a,b)) partition by range(b) (partition p0 values less than (2), partition p1 values less than maxvalue)") + testKit.MustExec("create table t2(a int, b int, primary key(a,b) nonclustered) partition by range(b) (partition p0 values less than (2), partition p1 values less than maxvalue)") testKit.MustExec("insert into t2 values(1,1),(1,2),(2,1),(2,2)") testKit.MustExec("set @@tidb_partition_prune_mode = 'static'") testKit.MustQuery("explain format = 'brief' select * from t2 where a in (1,2) and b = 1").Check(testkit.Rows( diff --git a/planner/core/collect_column_stats_usage.go b/planner/core/collect_column_stats_usage.go index 49f5cfdfd7011..5cb184136d875 100644 --- a/planner/core/collect_column_stats_usage.go +++ b/planner/core/collect_column_stats_usage.go @@ -43,9 +43,14 @@ type columnStatsUsageCollector struct { histNeededCols map[model.TableItemID]struct{} // cols is used to store columns collected from expressions and saves some allocation. cols []*expression.Column + + // collectVisitedTable indicates whether to collect visited table + collectVisitedTable bool + // visitedtbls indicates the visited table + visitedtbls map[int64]struct{} } -func newColumnStatsUsageCollector(collectMode uint64) *columnStatsUsageCollector { +func newColumnStatsUsageCollector(collectMode uint64, enabledPlanCapture bool) *columnStatsUsageCollector { collector := &columnStatsUsageCollector{ collectMode: collectMode, // Pre-allocate a slice to reduce allocation, 8 doesn't have special meaning. @@ -58,6 +63,10 @@ func newColumnStatsUsageCollector(collectMode uint64) *columnStatsUsageCollector if collectMode&collectHistNeededColumns != 0 { collector.histNeededCols = make(map[model.TableItemID]struct{}) } + if enabledPlanCapture { + collector.collectVisitedTable = true + collector.visitedtbls = map[int64]struct{}{} + } return collector } @@ -103,6 +112,9 @@ func (c *columnStatsUsageCollector) collectPredicateColumnsForDataSource(ds *Dat // For partition tables, no matter whether it is static or dynamic pruning mode, we use table ID rather than partition ID to // set TableColumnID.TableID. In this way, we keep the set of predicate columns consistent between different partitions and global table. tblID := ds.TableInfo().ID + if c.collectVisitedTable { + c.visitedtbls[tblID] = struct{}{} + } for _, col := range ds.Schema().Columns { tblColID := model.TableItemID{TableID: tblID, ID: col.ID, IsIndex: false} c.colMap[col.UniqueID] = map[model.TableItemID]struct{}{tblColID: {}} @@ -147,6 +159,10 @@ func (c *columnStatsUsageCollector) collectPredicateColumnsForUnionAll(p *Logica } func (c *columnStatsUsageCollector) addHistNeededColumns(ds *DataSource) { + if c.collectVisitedTable { + tblID := ds.TableInfo().ID + c.visitedtbls[tblID] = struct{}{} + } columns := expression.ExtractColumnsFromExpressions(c.cols[:0], ds.pushedDownConds, nil) for _, col := range columns { tblColID := model.TableItemID{TableID: ds.physicalTableID, ID: col.ID, IsIndex: false} @@ -283,8 +299,11 @@ func CollectColumnStatsUsage(lp LogicalPlan, predicate, histNeeded bool) ([]mode if histNeeded { mode |= collectHistNeededColumns } - collector := newColumnStatsUsageCollector(mode) + collector := newColumnStatsUsageCollector(mode, lp.SCtx().GetSessionVars().IsPlanReplayerCaptureEnabled()) collector.collectFromPlan(lp) + if collector.collectVisitedTable { + recordTableRuntimeStats(lp.SCtx(), collector.visitedtbls) + } set2slice := func(set map[model.TableItemID]struct{}) []model.TableItemID { ret := make([]model.TableItemID, 0, len(set)) for tblColID := range set { diff --git a/planner/core/collect_column_stats_usage_test.go b/planner/core/collect_column_stats_usage_test.go index 38d246ff8bfd7..249f210050c56 100644 --- a/planner/core/collect_column_stats_usage_test.go +++ b/planner/core/collect_column_stats_usage_test.go @@ -256,7 +256,7 @@ func TestCollectPredicateColumns(t *testing.T) { } stmt, err := s.p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err, comment) builder, _ := NewPlanBuilder().Init(s.ctx, s.is, &hint.BlockHintProcessor{}) p, err := builder.Build(ctx, stmt) @@ -331,9 +331,14 @@ func TestCollectHistNeededColumns(t *testing.T) { if len(tt.pruneMode) > 0 { s.ctx.GetSessionVars().PartitionPruneMode.Store(tt.pruneMode) } + if s.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { + s.ctx.GetSessionVars().StmtCtx.UseDynamicPruneMode = true + } else { + s.ctx.GetSessionVars().StmtCtx.UseDynamicPruneMode = false + } stmt, err := s.p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err, comment) builder, _ := NewPlanBuilder().Init(s.ctx, s.is, &hint.BlockHintProcessor{}) p, err := builder.Build(ctx, stmt) diff --git a/planner/core/common_plans.go b/planner/core/common_plans.go index 7816b9deaec02..97293c365021f 100644 --- a/planner/core/common_plans.go +++ b/planner/core/common_plans.go @@ -250,6 +250,10 @@ const ( OpReloadBindings // OpSetBindingStatus is used to set binding status. OpSetBindingStatus + // OpSQLBindDropByDigest is used to drop SQL binds by digest + OpSQLBindDropByDigest + // OpSetBindingStatusByDigest represents the operation to set SQL binding status by sql digest. + OpSetBindingStatusByDigest ) // SQLBindPlan represents a plan for SQL bind. @@ -265,6 +269,9 @@ type SQLBindPlan struct { Charset string Collation string NewStatus string + Source string // Source indicate how this binding was created, eg: bindinfo.Manual or bindinfo.History + SQLDigest string + PlanDigest string } // Simple represents a simple statement plan which doesn't need any optimization. @@ -362,7 +369,8 @@ type Insert struct { RowLen int - FKChecks []*FKCheck + FKChecks []*FKCheck + FKCascades []*FKCascade } // MemoryUsage return the memory usage of Insert @@ -429,7 +437,8 @@ type Update struct { tblID2Table map[int64]table.Table - FKChecks map[int64][]*FKCheck + FKChecks map[int64][]*FKCheck + FKCascades map[int64][]*FKCascade } // MemoryUsage return the memory usage of Update @@ -470,7 +479,8 @@ type Delete struct { TblColPosInfos TblColPosInfoSlice - FKChecks map[int64][]*FKCheck + FKChecks map[int64][]*FKCheck + FKCascades map[int64][]*FKCascade } // MemoryUsage return the memory usage of Delete @@ -541,7 +551,7 @@ type Analyze struct { type LoadData struct { baseSchemaProducer - IsLocal bool + FileLocRef ast.FileLocRefTp OnDuplicate ast.OnDuplicateKeyHandlingType Path string Table *ast.TableName @@ -563,6 +573,20 @@ type LoadStats struct { Path string } +// LockStats represents a lock stats for table +type LockStats struct { + baseSchemaProducer + + Tables []*ast.TableName +} + +// UnlockStats represents a unlock stats for table +type UnlockStats struct { + baseSchemaProducer + + Tables []*ast.TableName +} + // PlanReplayer represents a plan replayer plan. type PlanReplayer struct { baseSchemaProducer @@ -570,6 +594,10 @@ type PlanReplayer struct { Analyze bool Load bool File string + + Capture bool + SQLDigest string + PlanDigest string } // IndexAdvise represents a index advise plan. @@ -628,6 +656,37 @@ type SelectInto struct { IntoOpt *ast.SelectIntoOption } +// ExplainInfoForEncode store explain info for JSON encode +type ExplainInfoForEncode struct { + ID string `json:"id"` + EstRows string `json:"estRows"` + ActRows string `json:"actRows,omitempty"` + TaskType string `json:"taskType"` + AccessObject string `json:"accessObject,omitempty"` + ExecuteInfo string `json:"executeInfo,omitempty"` + OperatorInfo string `json:"operatorInfo,omitempty"` + EstCost string `json:"estCost,omitempty"` + CostFormula string `json:"costFormula,omitempty"` + MemoryInfo string `json:"memoryInfo,omitempty"` + DiskInfo string `json:"diskInfo,omitempty"` + TotalMemoryConsumed string `json:"totalMemoryConsumed,omitempty"` + SubOperators []*ExplainInfoForEncode `json:"subOperators,omitempty"` +} + +// JSONToString convert json to string +func JSONToString(j []*ExplainInfoForEncode) (string, error) { + byteBuffer := bytes.NewBuffer([]byte{}) + encoder := json.NewEncoder(byteBuffer) + // avoid wrongly embedding + encoder.SetEscapeHTML(false) + encoder.SetIndent("", " ") + err := encoder.Encode(j) + if err != nil { + return "", err + } + return byteBuffer.String(), nil +} + // Explain represents a explain plan. type Explain struct { baseSchemaProducer @@ -685,6 +744,12 @@ func (e *Explain) prepareSchema() error { } case format == types.ExplainFormatTrueCardCost: fieldNames = []string{"id", "estRows", "estCost", "costFormula", "actRows", "task", "access object", "execution info", "operator info", "memory", "disk"} + case format == types.ExplainFormatCostTrace: + if e.Analyze || e.RuntimeStatsColl != nil { + fieldNames = []string{"id", "estRows", "estCost", "costFormula", "actRows", "task", "access object", "execution info", "operator info", "memory", "disk"} + } else { + fieldNames = []string{"id", "estRows", "estCost", "costFormula", "task", "access object", "operator info"} + } case (format == types.ExplainFormatROW || format == types.ExplainFormatBrief) && (e.Analyze || e.RuntimeStatsColl != nil): fieldNames = []string{"id", "estRows", "actRows", "task", "access object", "execution info", "operator info", "memory", "disk"} case format == types.ExplainFormatDOT: @@ -693,6 +758,8 @@ func (e *Explain) prepareSchema() error { fieldNames = []string{"hint"} case format == types.ExplainFormatBinary: fieldNames = []string{"binary plan"} + case format == types.ExplainFormatTiDBJSON: + fieldNames = []string{"TiDB_JSON"} default: return errors.Errorf("explain format '%s' is not supported now", e.Format) } @@ -717,6 +784,7 @@ func (e *Explain) RenderResult() error { } if e.Analyze && strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost { + // true_card_cost mode is used to calibrate the cost model. pp, ok := e.TargetPlan.(PhysicalPlan) if ok { if _, err := getPlanCost(pp, property.RootTaskType, @@ -725,21 +793,46 @@ func (e *Explain) RenderResult() error { } if pp.SCtx().GetSessionVars().CostModelVersion == modelVer2 { // output cost formula and factor costs through warning under model ver2 and true_card_cost mode for cost calibration. - trace, _ := pp.getPlanCostVer2(property.RootTaskType, NewDefaultPlanCostOption()) + cost, _ := pp.getPlanCostVer2(property.RootTaskType, NewDefaultPlanCostOption()) + trace := cost.trace pp.SCtx().GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("cost formula: %v", trace.formula)) data, err := json.Marshal(trace.factorCosts) if err != nil { pp.SCtx().GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("marshal factor costs error %v", err)) } pp.SCtx().GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("factor costs: %v", string(data))) + + // output cost factor weights for cost calibration + factors := defaultVer2Factors.tolist() + weights := make(map[string]float64) + for _, factor := range factors { + if factorCost, ok := trace.factorCosts[factor.Name]; ok && factor.Value > 0 { + weights[factor.Name] = factorCost / factor.Value // cost = [factors] * [weights] + } + } + if wstr, err := json.Marshal(weights); err != nil { + pp.SCtx().GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("marshal weights error %v", err)) + } else { + pp.SCtx().GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("factor weights: %v", string(wstr))) + } } } else { e.SCtx().GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("'explain format=true_card_cost' cannot support this plan")) } } + if strings.ToLower(e.Format) == types.ExplainFormatCostTrace { + if pp, ok := e.TargetPlan.(PhysicalPlan); ok { + // trigger getPlanCost again with CostFlagTrace to record all cost formulas + if _, err := getPlanCost(pp, property.RootTaskType, + NewDefaultPlanCostOption().WithCostFlag(CostFlagRecalculate|CostFlagTrace)); err != nil { + return err + } + } + } + switch strings.ToLower(e.Format) { - case types.ExplainFormatROW, types.ExplainFormatBrief, types.ExplainFormatVerbose, types.ExplainFormatTrueCardCost: + case types.ExplainFormatROW, types.ExplainFormatBrief, types.ExplainFormatVerbose, types.ExplainFormatTrueCardCost, types.ExplainFormatCostTrace: if e.Rows == nil || e.Analyze { flat := FlattenPhysicalPlan(e.TargetPlan, true) e.explainFlatPlanInRowFormat(flat) @@ -747,7 +840,7 @@ func (e *Explain) RenderResult() error { e.SCtx().GetSessionVars().MemoryDebugModeMinHeapInUse != 0 && e.SCtx().GetSessionVars().MemoryDebugModeAlarmRatio > 0 { row := e.Rows[0] - tracker := e.SCtx().GetSessionVars().StmtCtx.MemTracker + tracker := e.SCtx().GetSessionVars().MemTracker row[7] = row[7] + "(Total: " + tracker.FormatBytes(tracker.MaxConsumed()) + ")" } } @@ -764,6 +857,21 @@ func (e *Explain) RenderResult() error { flat := FlattenPhysicalPlan(e.TargetPlan, false) str := BinaryPlanStrFromFlatPlan(e.ctx, flat) e.Rows = append(e.Rows, []string{str}) + case types.ExplainFormatTiDBJSON: + flat := FlattenPhysicalPlan(e.TargetPlan, true) + encodes := e.explainFlatPlanInJSONFormat(flat) + if e.Analyze && len(encodes) > 0 && + e.SCtx().GetSessionVars().MemoryDebugModeMinHeapInUse != 0 && + e.SCtx().GetSessionVars().MemoryDebugModeAlarmRatio > 0 { + encodeRoot := encodes[0] + tracker := e.SCtx().GetSessionVars().MemTracker + encodeRoot.TotalMemoryConsumed = tracker.FormatBytes(tracker.MaxConsumed()) + } + if str, err := JSONToString(encodes); err == nil { + e.Rows = append(e.Rows, []string{str}) + } else { + return err + } default: return errors.Errorf("explain format '%s' is not supported now", e.Format) } @@ -784,6 +892,38 @@ func (e *Explain) explainFlatPlanInRowFormat(flat *FlatPhysicalPlan) { } } +func (e *Explain) explainFlatPlanInJSONFormat(flat *FlatPhysicalPlan) (encodes []*ExplainInfoForEncode) { + if flat == nil || len(flat.Main) == 0 || flat.InExplain { + return + } + // flat.Main[0] must be the root node of tree + encodes = append(encodes, e.explainOpRecursivelyInJSONFormat(flat.Main[0], flat.Main)) + + for _, cte := range flat.CTEs { + encodes = append(encodes, e.explainOpRecursivelyInJSONFormat(cte[0], cte)) + } + return +} + +func (e *Explain) explainOpRecursivelyInJSONFormat(flatOp *FlatOperator, flats FlatPlanTree) *ExplainInfoForEncode { + taskTp := "" + if flatOp.IsRoot { + taskTp = "root" + } else { + taskTp = flatOp.ReqType.Name() + "[" + flatOp.StoreType.Name() + "]" + } + explainID := flatOp.Origin.ExplainID().String() + flatOp.Label.String() + textTreeExplainID := texttree.PrettyIdentifier(explainID, flatOp.TextTreeIndent, flatOp.IsLastChild) + + cur := e.prepareOperatorInfoForJSONFormat(flatOp.Origin, taskTp, textTreeExplainID, explainID) + + for _, idx := range flatOp.ChildrenIdx { + cur.SubOperators = append(cur.SubOperators, + e.explainOpRecursivelyInJSONFormat(flats[idx], flats)) + } + return cur +} + func (e *Explain) explainFlatOpInRowFormat(flatOp *FlatOperator) { taskTp := "" if flatOp.IsRoot { @@ -795,11 +935,6 @@ func (e *Explain) explainFlatOpInRowFormat(flatOp *FlatOperator) { flatOp.TextTreeIndent, flatOp.IsLastChild) e.prepareOperatorInfo(flatOp.Origin, taskTp, textTreeExplainID) - if e.ctx != nil && e.ctx.GetSessionVars() != nil && e.ctx.GetSessionVars().StmtCtx != nil { - if optimInfo, ok := e.ctx.GetSessionVars().StmtCtx.OptimInfo[flatOp.Origin.ID()]; ok { - e.ctx.GetSessionVars().StmtCtx.AppendNote(errors.New(optimInfo)) - } - } } func getRuntimeInfoStr(ctx sessionctx.Context, p Plan, runtimeStatsColl *execdetails.RuntimeStatsColl) (actRows, analyzeInfo, memoryInfo, diskInfo string) { @@ -868,24 +1003,49 @@ func (e *Explain) prepareOperatorInfo(p Plan, taskType, id string) { var row []string if e.Analyze || e.RuntimeStatsColl != nil { row = []string{id, estRows} - if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost { + if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost || strings.ToLower(e.Format) == types.ExplainFormatCostTrace { row = append(row, estCost) } - if strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost { + if strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost || strings.ToLower(e.Format) == types.ExplainFormatCostTrace { row = append(row, costFormula) } actRows, analyzeInfo, memoryInfo, diskInfo := getRuntimeInfoStr(e.ctx, p, e.RuntimeStatsColl) row = append(row, actRows, taskType, accessObject, analyzeInfo, operatorInfo, memoryInfo, diskInfo) } else { row = []string{id, estRows} - if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost { + if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost || + strings.ToLower(e.Format) == types.ExplainFormatCostTrace { row = append(row, estCost) } + if strings.ToLower(e.Format) == types.ExplainFormatCostTrace { + row = append(row, costFormula) + } row = append(row, taskType, accessObject, operatorInfo) } e.Rows = append(e.Rows, row) } +func (e *Explain) prepareOperatorInfoForJSONFormat(p Plan, taskType, id string, explainID string) *ExplainInfoForEncode { + if p.ExplainID().String() == "_0" { + return nil + } + + estRows, _, _, accessObject, operatorInfo := e.getOperatorInfo(p, id) + jsonRow := &ExplainInfoForEncode{ + ID: explainID, + EstRows: estRows, + TaskType: taskType, + AccessObject: accessObject, + OperatorInfo: operatorInfo, + SubOperators: make([]*ExplainInfoForEncode, 0), + } + + if e.Analyze || e.RuntimeStatsColl != nil { + jsonRow.ActRows, jsonRow.ExecuteInfo, jsonRow.MemoryInfo, jsonRow.DiskInfo = getRuntimeInfoStr(e.ctx, p, e.RuntimeStatsColl) + } + return jsonRow +} + func (e *Explain) getOperatorInfo(p Plan, id string) (string, string, string, string, string) { // For `explain for connection` statement, `e.ExplainRows` will be set. for _, row := range e.ExplainRows { @@ -896,22 +1056,27 @@ func (e *Explain) getOperatorInfo(p Plan, id string) (string, string, string, st return row[1], "N/A", "N/A", row[3], row[4] } } + + pp, isPhysicalPlan := p.(PhysicalPlan) estRows := "N/A" - if si := p.statsInfo(); si != nil { - estRows = strconv.FormatFloat(si.RowCount, 'f', 2, 64) - } estCost := "N/A" costFormula := "N/A" - if pp, ok := p.(PhysicalPlan); ok { + if isPhysicalPlan { + estRows = strconv.FormatFloat(pp.getEstRowCountForDisplay(), 'f', 2, 64) if e.ctx != nil && e.ctx.GetSessionVars().CostModelVersion == modelVer2 { costVer2, _ := pp.getPlanCostVer2(property.RootTaskType, NewDefaultPlanCostOption()) estCost = strconv.FormatFloat(costVer2.cost, 'f', 2, 64) - costFormula = costVer2.formula + if costVer2.trace != nil { + costFormula = costVer2.trace.formula + } } else { planCost, _ := getPlanCost(pp, property.RootTaskType, NewDefaultPlanCostOption()) estCost = strconv.FormatFloat(planCost, 'f', 2, 64) } + } else if si := p.statsInfo(); si != nil { + estRows = strconv.FormatFloat(si.RowCount, 'f', 2, 64) } + var accessObject, operatorInfo string if plan, ok := p.(dataAccesser); ok { accessObject = plan.AccessObject().String() @@ -1008,18 +1173,21 @@ func binaryOpFromFlatOp(explainCtx sessionctx.Context, op *FlatOperator, out *ti } } - // Runtime info - rootStats, copStats, memTracker, diskTracker := getRuntimeInfo(explainCtx, op.Origin, nil) - if statsInfo := op.Origin.statsInfo(); statsInfo != nil { - out.EstRows = statsInfo.RowCount - } if op.IsPhysicalPlan { p := op.Origin.(PhysicalPlan) out.Cost, _ = getPlanCost(p, property.RootTaskType, NewDefaultPlanCostOption()) + out.EstRows = p.getEstRowCountForDisplay() + } else if statsInfo := op.Origin.statsInfo(); statsInfo != nil { + out.EstRows = statsInfo.RowCount } + + // Runtime info + rootStats, copStats, memTracker, diskTracker := getRuntimeInfo(explainCtx, op.Origin, nil) if rootStats != nil { basic, groups := rootStats.MergeStats() - out.RootBasicExecInfo = basic.String() + if basic != nil { + out.RootBasicExecInfo = basic.String() + } for _, group := range groups { str := group.String() if len(str) > 0 { diff --git a/planner/core/encode.go b/planner/core/encode.go index 686e6ef965475..bf02059dafdda 100644 --- a/planner/core/encode.go +++ b/planner/core/encode.go @@ -41,7 +41,7 @@ func EncodeFlatPlan(flat *FlatPhysicalPlan) string { return "" } failpoint.Inject("mockPlanRowCount", func(val failpoint.Value) { - selectPlan := flat.Main.GetSelectPlan() + selectPlan, _ := flat.Main.GetSelectPlan() for _, op := range selectPlan { op.Origin.statsInfo().RowCount = float64(val.(int)) } @@ -69,7 +69,9 @@ func EncodeFlatPlan(flat *FlatPhysicalPlan) string { p := op.Origin actRows, analyzeInfo, memoryInfo, diskInfo := getRuntimeInfoStr(p.SCtx(), p, nil) var estRows float64 - if statsInfo := p.statsInfo(); statsInfo != nil { + if op.IsPhysicalPlan { + estRows = op.Origin.(PhysicalPlan).getEstRowCountForDisplay() + } else if statsInfo := p.statsInfo(); statsInfo != nil { estRows = statsInfo.RowCount } plancodec.EncodePlanNode( @@ -98,7 +100,9 @@ func encodeFlatPlanTree(flatTree FlatPlanTree, offset int, buf *bytes.Buffer) { p := op.Origin actRows, analyzeInfo, memoryInfo, diskInfo := getRuntimeInfoStr(p.SCtx(), p, nil) var estRows float64 - if statsInfo := p.statsInfo(); statsInfo != nil { + if op.IsPhysicalPlan { + estRows = op.Origin.(PhysicalPlan).getEstRowCountForDisplay() + } else if statsInfo := p.statsInfo(); statsInfo != nil { estRows = statsInfo.RowCount } plancodec.EncodePlanNode( @@ -199,8 +203,10 @@ func (pn *planEncoder) encodePlan(p Plan, isRoot bool, store kv.StoreType, depth taskTypeInfo := plancodec.EncodeTaskType(isRoot, store) actRows, analyzeInfo, memoryInfo, diskInfo := getRuntimeInfoStr(p.SCtx(), p, nil) rowCount := 0.0 - if statsInfo := p.statsInfo(); statsInfo != nil { - rowCount = p.statsInfo().RowCount + if pp, ok := p.(PhysicalPlan); ok { + rowCount = pp.getEstRowCountForDisplay() + } else if statsInfo := p.statsInfo(); statsInfo != nil { + rowCount = statsInfo.RowCount } plancodec.EncodePlanNode(depth, strconv.Itoa(p.ID()), p.TP(), rowCount, taskTypeInfo, p.ExplainInfo(), actRows, analyzeInfo, memoryInfo, diskInfo, &pn.buf) pn.encodedPlans[p.ID()] = true @@ -256,7 +262,10 @@ type planDigester struct { // NormalizeFlatPlan normalizes a FlatPhysicalPlan and generates plan digest. func NormalizeFlatPlan(flat *FlatPhysicalPlan) (normalized string, digest *parser.Digest) { - selectPlan := flat.Main.GetSelectPlan() + if flat == nil { + return "", parser.NewDigest(nil) + } + selectPlan, selectPlanOffset := flat.Main.GetSelectPlan() if len(selectPlan) == 0 || !selectPlan[0].IsPhysicalPlan { return "", parser.NewDigest(nil) } @@ -268,12 +277,11 @@ func NormalizeFlatPlan(flat *FlatPhysicalPlan) (normalized string, digest *parse }() // assume an operator costs around 30 bytes, preallocate space for them d.buf.Grow(30 * len(selectPlan)) - depthOffset := len(flat.Main) - len(selectPlan) for _, op := range selectPlan { taskTypeInfo := plancodec.EncodeTaskTypeForNormalize(op.IsRoot, op.StoreType) p := op.Origin.(PhysicalPlan) plancodec.NormalizePlanNode( - int(op.Depth-uint32(depthOffset)), + int(op.Depth-uint32(selectPlanOffset)), op.Origin.TP(), taskTypeInfo, p.ExplainNormalizedInfo(), @@ -281,6 +289,9 @@ func NormalizeFlatPlan(flat *FlatPhysicalPlan) (normalized string, digest *parse ) } normalized = d.buf.String() + if len(normalized) == 0 { + return "", parser.NewDigest(nil) + } _, err := d.hasher.Write(d.buf.Bytes()) if err != nil { panic(err) diff --git a/planner/core/enforce_mpp_test.go b/planner/core/enforce_mpp_test.go index 8b0582ee54492..dfd0a4fadbe3a 100644 --- a/planner/core/enforce_mpp_test.go +++ b/planner/core/enforce_mpp_test.go @@ -35,6 +35,7 @@ func TestSetVariables(t *testing.T) { tk := testkit.NewTestKit(t, store) // test value limit of tidb_opt_tiflash_concurrency_factor + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@tidb_opt_tiflash_concurrency_factor = 0") tk.MustQuery("SHOW WARNINGS").Check(testkit.Rows("Warning 1292 Truncated incorrect tidb_opt_tiflash_concurrency_factor value: '0'")) tk.MustQuery(`select @@tidb_opt_tiflash_concurrency_factor`).Check(testkit.Rows("1")) @@ -52,6 +53,7 @@ func TestRowSizeInMPP(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a varchar(10), b varchar(20), c varchar(256))") tk.MustExec("insert into t values (space(10), space(20), space(256))") @@ -89,6 +91,7 @@ func TestEnforceMPP(t *testing.T) { // test query tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int)") tk.MustExec("create index idx on t(a)") @@ -154,6 +157,7 @@ func TestEnforceMPPWarning1(t *testing.T) { // test query tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int as (a+1), c enum('xx', 'yy'), d bit(1))") tk.MustExec("create index idx on t(a)") @@ -224,6 +228,7 @@ func TestEnforceMPPWarning2(t *testing.T) { // test query tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("CREATE TABLE t (a int, b char(20)) PARTITION BY HASH(a)") @@ -275,6 +280,7 @@ func TestEnforceMPPWarning3(t *testing.T) { // test query tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("CREATE TABLE t (a int, b char(20))") @@ -335,6 +341,7 @@ func TestEnforceMPPWarning4(t *testing.T) { // test table tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("CREATE TABLE t(a int primary key)") tk.MustExec("drop table if exists s") @@ -388,6 +395,7 @@ func TestMPP2PhaseAggPushDown(t *testing.T) { // test table tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists c") tk.MustExec("drop table if exists o") tk.MustExec("create table c(c_id bigint)") @@ -441,6 +449,7 @@ func TestMPPSkewedGroupDistinctRewrite(t *testing.T) { // test table tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b bigint not null, c bigint, d date, e varchar(20))") @@ -492,6 +501,7 @@ func TestMPPSingleDistinct3Stage(t *testing.T) { // test table tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b bigint not null, c bigint, d date, e varchar(20) collate utf8mb4_general_ci)") diff --git a/planner/core/exhaust_physical_plans.go b/planner/core/exhaust_physical_plans.go index e726996268831..205a2d8242b4b 100644 --- a/planner/core/exhaust_physical_plans.go +++ b/planner/core/exhaust_physical_plans.go @@ -1148,7 +1148,7 @@ func (p *LogicalJoin) constructInnerIndexScanTask( cop.commonHandleCols = ds.commonHandleCols } is.initSchema(append(path.FullIdxCols, ds.commonHandleCols...), cop.tablePlan != nil) - indexConds, tblConds := ds.splitIndexFilterConditions(filterConds, path.FullIdxCols, path.FullIdxColLens, ds.tableInfo) + indexConds, tblConds := ds.splitIndexFilterConditions(filterConds, path.FullIdxCols, path.FullIdxColLens) if maxOneRow { // Theoretically, this line is unnecessary because row count estimation of join should guarantee rowCount is not larger // than 1.0; however, there may be rowCount larger than 1.0 in reality, e.g, pseudo statistics cases, which does not reflect @@ -1928,7 +1928,7 @@ func (p *LogicalJoin) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]P } }) - if (p.preferJoinType&preferBCJoin) == 0 && p.preferJoinType > 0 { + if (p.preferJoinType&preferBCJoin) == 0 && (p.preferJoinType&preferShuffleJoin) == 0 && p.preferJoinType > 0 { p.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because you have used hint to specify a join algorithm which is not supported by mpp now.") if prop.IsFlashProp() { return nil, false, nil @@ -1940,16 +1940,38 @@ func (p *LogicalJoin) exhaustPhysicalPlans(prop *property.PhysicalProperty) ([]P joins := make([]PhysicalPlan, 0, 8) canPushToTiFlash := p.canPushToCop(kv.TiFlash) if p.ctx.GetSessionVars().IsMPPAllowed() && canPushToTiFlash { + if (p.preferJoinType & preferShuffleJoin) > 0 { + if shuffleJoins := p.tryToGetMppHashJoin(prop, false); len(shuffleJoins) > 0 { + return shuffleJoins, true, nil + } + } + if (p.preferJoinType & preferBCJoin) > 0 { + if bcastJoins := p.tryToGetMppHashJoin(prop, true); len(bcastJoins) > 0 { + return bcastJoins, true, nil + } + } if p.shouldUseMPPBCJ() { mppJoins := p.tryToGetMppHashJoin(prop, true) - if (p.preferJoinType & preferBCJoin) > 0 { - return mppJoins, true, nil - } joins = append(joins, mppJoins...) } else { mppJoins := p.tryToGetMppHashJoin(prop, false) joins = append(joins, mppJoins...) } + } else { + hasMppHints := false + var errMsg string + if (p.preferJoinType & preferShuffleJoin) > 0 { + errMsg = "The join can not push down to the MPP side, the shuffle_join() hint is invalid" + hasMppHints = true + } + if (p.preferJoinType & preferBCJoin) > 0 { + errMsg = "The join can not push down to the MPP side, the broadcast_join() hint is invalid" + hasMppHints = true + } + if hasMppHints { + warning := ErrInternal.GenWithStack(errMsg) + p.ctx.GetSessionVars().StmtCtx.AppendWarning(warning) + } } if prop.IsFlashProp() { return joins, true, nil @@ -2508,7 +2530,7 @@ func (p *baseLogicalPlan) exhaustPhysicalPlans(_ *property.PhysicalProperty) ([] } // canPushToCop checks if it can be pushed to some stores. For TiKV, it only checks datasource. -// For TiFlash, it will check whether the operator is supported, but note that the check might be inaccrute. +// For TiFlash, it will check whether the operator is supported, but note that the check might be inaccrate. func (p *baseLogicalPlan) canPushToCop(storeTp kv.StoreType) bool { return p.canPushToCopImpl(storeTp, false) } @@ -2723,8 +2745,11 @@ func (la *LogicalAggregation) checkCanPushDownToMPP() bool { } } if hasUnsupportedDistinct { + warnErr := errors.New("Aggregation can not be pushed to storage layer in mpp mode because it contains agg function with distinct") if la.ctx.GetSessionVars().StmtCtx.InExplainStmt { - la.ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("Aggregation can not be pushed to storage layer in mpp mode because it contains agg function with distinct")) + la.ctx.GetSessionVars().StmtCtx.AppendWarning(warnErr) + } else { + la.ctx.GetSessionVars().StmtCtx.AppendExtraWarning(warnErr) } return false } @@ -2803,6 +2828,24 @@ func (la *LogicalAggregation) tryToGetMppHashAggs(prop *property.PhysicalPropert } hashAggs = append(hashAggs, agg) } + + // handle MPP Agg hints + var preferMode AggMppRunMode + var prefer bool + if la.aggHints.preferAggType&preferMPP1PhaseAgg > 0 { + preferMode, prefer = Mpp1Phase, true + } else if la.aggHints.preferAggType&preferMPP2PhaseAgg > 0 { + preferMode, prefer = Mpp2Phase, true + } + if prefer { + var preferPlans []PhysicalPlan + for _, agg := range hashAggs { + if hg, ok := agg.(*PhysicalHashAgg); ok && hg.MppRunMode == preferMode { + preferPlans = append(preferPlans, hg) + } + } + hashAggs = preferPlans + } return } @@ -2830,6 +2873,21 @@ func (la *LogicalAggregation) getHashAggs(prop *property.PhysicalProperty) []Phy } if canPushDownToMPP { taskTypes = append(taskTypes, property.MppTaskType) + } else { + hasMppHints := false + var errMsg string + if la.aggHints.preferAggType&preferMPP1PhaseAgg > 0 { + errMsg = "The agg can not push down to the MPP side, the MPP_1PHASE_AGG() hint is invalid" + hasMppHints = true + } + if la.aggHints.preferAggType&preferMPP2PhaseAgg > 0 { + errMsg = "The agg can not push down to the MPP side, the MPP_2PHASE_AGG() hint is invalid" + hasMppHints = true + } + if hasMppHints { + warning := ErrInternal.GenWithStack(errMsg) + la.ctx.GetSessionVars().StmtCtx.AppendWarning(warning) + } } if prop.IsFlashProp() { taskTypes = []property.TaskType{prop.TaskTp} diff --git a/planner/core/explain.go b/planner/core/explain.go index 3f4c37e60d131..ade44533eb360 100644 --- a/planner/core/explain.go +++ b/planner/core/explain.go @@ -285,8 +285,11 @@ func (p *PhysicalIndexLookUpReader) ExplainInfo() string { } // ExplainInfo implements Plan interface. -func (*PhysicalIndexMergeReader) ExplainInfo() string { - return "" +func (p *PhysicalIndexMergeReader) ExplainInfo() string { + if p.IsIntersectionType { + return "type: intersection" + } + return "type: union" } // ExplainInfo implements Plan interface. @@ -382,6 +385,9 @@ func (p *basePhysicalAgg) explainInfo(normalized bool) string { builder.WriteString(", ") } } + if p.TiFlashFineGrainedShuffleStreamCount > 0 { + builder.WriteString(fmt.Sprintf(", stream_count: %d", p.TiFlashFineGrainedShuffleStreamCount)) + } return builder.String() } @@ -540,6 +546,9 @@ func (p *PhysicalHashJoin) explainInfo(normalized bool) string { buffer.WriteString(", other cond:") buffer.Write(sortedExplainExpressionList(p.OtherConditions)) } + if p.TiFlashFineGrainedShuffleStreamCount > 0 { + buffer.WriteString(fmt.Sprintf(", stream_count: %d", p.TiFlashFineGrainedShuffleStreamCount)) + } return buffer.String() } diff --git a/planner/core/expression_rewriter.go b/planner/core/expression_rewriter.go index 73a998197cc0f..a2d1f242a0ff6 100644 --- a/planner/core/expression_rewriter.go +++ b/planner/core/expression_rewriter.go @@ -55,7 +55,7 @@ func evalAstExpr(sctx sessionctx.Context, expr ast.ExprNode) (types.Datum, error if val, ok := expr.(*driver.ValueExpr); ok { return val.Datum, nil } - newExpr, err := rewriteAstExpr(sctx, expr, nil, nil) + newExpr, err := rewriteAstExpr(sctx, expr, nil, nil, false) if err != nil { return types.Datum{}, err } @@ -63,13 +63,14 @@ func evalAstExpr(sctx sessionctx.Context, expr ast.ExprNode) (types.Datum, error } // rewriteAstExpr rewrites ast expression directly. -func rewriteAstExpr(sctx sessionctx.Context, expr ast.ExprNode, schema *expression.Schema, names types.NameSlice) (expression.Expression, error) { +func rewriteAstExpr(sctx sessionctx.Context, expr ast.ExprNode, schema *expression.Schema, names types.NameSlice, allowCastArray bool) (expression.Expression, error) { var is infoschema.InfoSchema // in tests, it may be null if s, ok := sctx.GetInfoSchema().(infoschema.InfoSchema); ok { is = s } b, savedBlockNames := NewPlanBuilder().Init(sctx, is, &hint.BlockHintProcessor{}) + b.allowBuildCastArray = allowCastArray fakePlan := LogicalTableDual{}.Init(sctx, 0) if schema != nil { fakePlan.schema = schema @@ -1183,6 +1184,10 @@ func (er *expressionRewriter) Leave(originInNode ast.Node) (retNode ast.Node, ok er.disableFoldCounter-- } case *ast.FuncCastExpr: + if v.Tp.IsArray() && !er.b.allowBuildCastArray { + er.err = expression.ErrNotSupportedYet.GenWithStackByArgs("Use of CAST( .. AS .. ARRAY) outside of functional index in CREATE(non-SELECT)/ALTER TABLE or in general expressions") + return retNode, false + } arg := er.ctxStack[len(er.ctxStack)-1] er.err = expression.CheckArgsNotMultiColumnRow(arg) if er.err != nil { @@ -1195,7 +1200,11 @@ func (er *expressionRewriter) Leave(originInNode ast.Node) (retNode ast.Node, ok return retNode, false } - castFunction := expression.BuildCastFunction(er.sctx, arg, v.Tp) + castFunction, err := expression.BuildCastFunctionWithCheck(er.sctx, arg, v.Tp) + if err != nil { + er.err = err + return retNode, false + } if v.Tp.EvalType() == types.ETString { castFunction.SetCoercibility(expression.CoercibilityImplicit) if v.Tp.GetCharset() == charset.CharsetASCII { @@ -1391,9 +1400,9 @@ func (er *expressionRewriter) rewriteVariable(v *ast.VariableExpr) { if sysVar.HasNoneScope() { val = sysVar.Value } else if v.IsGlobal { - val, err = sessionVars.GetGlobalSystemVar(name) + val, err = sessionVars.GetGlobalSystemVar(er.ctx, name) } else { - val, err = sessionVars.GetSessionOrGlobalSystemVar(name) + val, err = sessionVars.GetSessionOrGlobalSystemVar(er.ctx, name) } if err != nil { er.err = err @@ -1550,16 +1559,10 @@ func (er *expressionRewriter) inToExpression(lLen int, not bool, tp *types.Field if c, ok := args[i].(*expression.Constant); ok { var isExceptional bool if expression.MaybeOverOptimized4PlanCache(er.sctx, []expression.Expression{c}) { - if c.GetType().EvalType() == types.ETString { - // To keep the result be compatible with MySQL, refine `int non-constant str constant` - // here and skip this refine operation in all other cases for safety. - er.sctx.GetSessionVars().StmtCtx.SkipPlanCache = true - expression.RemoveMutableConst(er.sctx, []expression.Expression{c}) - } else { - continue + if c.GetType().EvalType() == types.ETInt { + continue // no need to refine it } - } else if er.sctx.GetSessionVars().StmtCtx.SkipPlanCache { - // We should remove the mutable constant for correctness, because its value may be changed. + er.sctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: '%v' may be converted to INT", c.String())) expression.RemoveMutableConst(er.sctx, []expression.Expression{c}) } args[i], isExceptional = expression.RefineComparedConstant(er.sctx, *leftFt, c, opcode.EQ) @@ -2169,6 +2172,9 @@ func decodeKeyFromString(ctx sessionctx.Context, s string) string { return s } tbl, _ := is.TableByID(tableID) + if tbl == nil { + tbl, _, _ = is.FindTableByPartitionID(tableID) + } loc := ctx.GetSessionVars().Location() if tablecodec.IsRecordKey(key) { ret, err := decodeRecordKey(key, tableID, tbl, loc) @@ -2185,7 +2191,7 @@ func decodeKeyFromString(ctx sessionctx.Context, s string) string { } return ret } else if tablecodec.IsTableKey(key) { - ret, err := decodeTableKey(key, tableID) + ret, err := decodeTableKey(key, tableID, tbl) if err != nil { sc.AppendWarning(err) return s @@ -2203,6 +2209,10 @@ func decodeRecordKey(key []byte, tableID int64, tbl table.Table, loc *time.Locat } if handle.IsInt() { ret := make(map[string]interface{}) + if tbl != nil && tbl.Meta().Partition != nil { + ret["partition_id"] = tableID + tableID = tbl.Meta().ID + } ret["table_id"] = strconv.FormatInt(tableID, 10) // When the clustered index is enabled, we should show the PK name. if tbl != nil && tbl.Meta().HasClusteredIndex() { @@ -2239,6 +2249,10 @@ func decodeRecordKey(key []byte, tableID int64, tbl table.Table, loc *time.Locat return "", errors.Trace(err) } ret := make(map[string]interface{}) + if tbl.Meta().Partition != nil { + ret["partition_id"] = tableID + tableID = tbl.Meta().ID + } ret["table_id"] = tableID handleRet := make(map[string]interface{}) for colID := range datumMap { @@ -2308,6 +2322,10 @@ func decodeIndexKey(key []byte, tableID int64, tbl table.Table, loc *time.Locati ds = append(ds, d) } ret := make(map[string]interface{}) + if tbl.Meta().Partition != nil { + ret["partition_id"] = tableID + tableID = tbl.Meta().ID + } ret["table_id"] = tableID ret["index_id"] = indexID idxValMap := make(map[string]interface{}, len(targetIndex.Columns)) @@ -2340,8 +2358,13 @@ func decodeIndexKey(key []byte, tableID int64, tbl table.Table, loc *time.Locati return string(retStr), nil } -func decodeTableKey(_ []byte, tableID int64) (string, error) { - ret := map[string]int64{"table_id": tableID} +func decodeTableKey(_ []byte, tableID int64, tbl table.Table) (string, error) { + ret := map[string]int64{} + if tbl != nil && tbl.Meta().GetPartitionInfo() != nil { + ret["partition_id"] = tableID + tableID = tbl.Meta().ID + } + ret["table_id"] = tableID retStr, err := json.Marshal(ret) if err != nil { return "", errors.Trace(err) diff --git a/planner/core/expression_rewriter_test.go b/planner/core/expression_rewriter_test.go index 3de3509c3e093..94a63d814c030 100644 --- a/planner/core/expression_rewriter_test.go +++ b/planner/core/expression_rewriter_test.go @@ -71,7 +71,8 @@ func TestDefaultFunction(t *testing.T) { c int default '10', d double default '3.14', e datetime default '20180101', - f datetime default current_timestamp);`) + f datetime default current_timestamp, + g date default current_date);`) tk.MustExec("insert into t1(a, b, c, d) values ('1', '1', 1, 1)") tk.MustExec("set @@timestamp = 1321009871") defer tk.MustExec("set @@timestamp = DEFAULT") @@ -83,8 +84,9 @@ func TestDefaultFunction(t *testing.T) { default(c) as defc, default(d) as defd, default(e) as defe, - default(f) as deff - from t1`).Check(testkit.RowsWithSep("|", "def||10|3.14|2018-01-01 00:00:00|2011-11-11 11:11:11")) + default(f) as deff, + default(g) as defg + from t1`).Check(testkit.RowsWithSep("|", "def||10|3.14|2018-01-01 00:00:00|2011-11-11 11:11:11|2011-11-11")) require.EqualError(t, tk.ExecToErr("select default(x) from t1"), "[planner:1054]Unknown column 'x' in 'field list'") tk.MustQuery("select default(a0) from (select a as a0 from t1) as t0").Check(testkit.Rows("def")) @@ -381,6 +383,7 @@ func TestMultiColInExpression(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2") tk.MustExec("create table t1(a int, b int)") tk.MustExec("insert into t1 values(1,1),(2,null),(null,3),(4,4)") @@ -416,6 +419,7 @@ func TestBitFuncsReturnType(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("create table t (a timestamp, b varbinary(32))") tk.MustExec("insert into t values ('2006-08-27 21:57:57', 0x373037343631313230)") tk.MustExec("analyze table t") @@ -427,6 +431,9 @@ func TestBitFuncsReturnType(t *testing.T) { expressionRewriterSuiteData := plannercore.GetExpressionRewriterSuiteData() expressionRewriterSuiteData.LoadTestCases(t, &input, &output) for i, tt := range input { + testdata.OnRecord(func() { + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + tt).Rows()) + }) tk.MustQuery("explain format = 'brief' " + tt).Check(testkit.Rows(output[i].Plan...)) } } diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index c73ce9f3c086d..c2d3e1a62d7bc 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -20,6 +20,7 @@ import ( "strings" "github.com/pingcap/errors" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" @@ -741,7 +742,7 @@ func (ds *DataSource) skylinePruning(prop *property.PhysicalProperty) []*candida } func (ds *DataSource) getPruningInfo(candidates []*candidatePath, prop *property.PhysicalProperty) string { - if !ds.ctx.GetSessionVars().StmtCtx.InVerboseExplain || len(candidates) == len(ds.possibleAccessPaths) { + if len(candidates) == len(ds.possibleAccessPaths) { return "" } if len(candidates) == 1 && len(candidates[0].path.Ranges) == 0 { @@ -806,7 +807,30 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter planCounter.Dec(1) return nil, 1, nil } - + if ds.isForUpdateRead && ds.ctx.GetSessionVars().TxnCtx.IsExplicit { + hasPointGetPath := false + for _, path := range ds.possibleAccessPaths { + if ds.isPointGetPath(path) { + hasPointGetPath = true + break + } + } + tblName := ds.tableInfo.Name + ds.possibleAccessPaths, err = filterPathByIsolationRead(ds.ctx, ds.possibleAccessPaths, tblName, ds.DBName) + if err != nil { + return nil, 1, err + } + if hasPointGetPath { + newPaths := make([]*util.AccessPath, 0) + for _, path := range ds.possibleAccessPaths { + // if the path is the point get range path with for update lock, we should forbid tiflash as it's store path (#39543) + if path.StoreType != kv.TiFlash { + newPaths = append(newPaths, path) + } + } + ds.possibleAccessPaths = newPaths + } + } t = ds.getTask(prop) if t != nil { cntPlan = 1 @@ -865,10 +889,12 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter pruningInfo := ds.getPruningInfo(candidates, prop) defer func() { if err == nil && t != nil && !t.invalid() && pruningInfo != "" { - if ds.ctx.GetSessionVars().StmtCtx.OptimInfo == nil { - ds.ctx.GetSessionVars().StmtCtx.OptimInfo = make(map[int]string) + warnErr := errors.New(pruningInfo) + if ds.ctx.GetSessionVars().StmtCtx.InVerboseExplain { + ds.ctx.GetSessionVars().StmtCtx.AppendNote(warnErr) + } else { + ds.ctx.GetSessionVars().StmtCtx.AppendExtraNote(warnErr) } - ds.ctx.GetSessionVars().StmtCtx.OptimInfo[t.plan().ID()] = pruningInfo } }() @@ -902,7 +928,7 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter if len(path.Ranges) == 0 { // We should uncache the tableDual plan. if expression.MaybeOverOptimized4PlanCache(ds.ctx, path.AccessConds) { - ds.ctx.GetSessionVars().StmtCtx.SkipPlanCache = true + ds.ctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: get a TableDual plan")) } dual := PhysicalTableDual{}.Init(ds.ctx, ds.stats, ds.blockOffset) dual.SetSchema(ds.schema) @@ -912,6 +938,7 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter p: dual, }, cntPlan, nil } + canConvertPointGet := len(path.Ranges) > 0 && path.StoreType == kv.TiKV && ds.isPointGetConvertableSchema() if canConvertPointGet && expression.MaybeOverOptimized4PlanCache(ds.ctx, path.AccessConds) { @@ -1108,6 +1135,8 @@ func (ds *DataSource) convertToIndexMergeScan(prop *property.PhysicalProperty, c } cop.tablePlan = ts cop.idxMergePartPlans = scans + cop.idxMergeIsIntersection = path.IndexMergeIsIntersection + cop.idxMergeAccessMVIndex = path.IndexMergeAccessMVIndex if remainingFilters != nil { cop.rootTaskConds = remainingFilters } @@ -1118,9 +1147,9 @@ func (ds *DataSource) convertToIndexMergeScan(prop *property.PhysicalProperty, c func (ds *DataSource) convertToPartialIndexScan(prop *property.PhysicalProperty, path *util.AccessPath) (indexPlan PhysicalPlan) { is := ds.getOriginalPhysicalIndexScan(prop, path, false, false) - // TODO: Consider using isCoveringIndex() to avoid another TableRead + // TODO: Consider using isIndexCoveringColumns() to avoid another TableRead indexConds := path.IndexFilters - if indexConds != nil { + if len(indexConds) > 0 { var selectivity float64 if path.CountAfterAccess > 0 { selectivity = path.CountAfterIndex / path.CountAfterAccess @@ -1281,33 +1310,80 @@ func extractFiltersForIndexMerge(sc *stmtctx.StatementContext, client kv.Client, return } -func indexCoveringCol(col *expression.Column, indexCols []*expression.Column, idxColLens []int) bool { +func isIndexColsCoveringCol(col *expression.Column, indexCols []*expression.Column, idxColLens []int, ignoreLen bool) bool { for i, indexCol := range indexCols { - isFullLen := idxColLens[i] == types.UnspecifiedLength || idxColLens[i] == col.RetType.GetFlen() - if indexCol != nil && col.EqualByExprAndID(nil, indexCol) && isFullLen { + if indexCol == nil || !col.EqualByExprAndID(nil, indexCol) { + continue + } + if ignoreLen || idxColLens[i] == types.UnspecifiedLength || idxColLens[i] == col.RetType.GetFlen() { return true } } return false } -func (ds *DataSource) isCoveringIndex(columns, indexColumns []*expression.Column, idxColLens []int, tblInfo *model.TableInfo) bool { +func (ds *DataSource) indexCoveringColumn(column *expression.Column, indexColumns []*expression.Column, idxColLens []int, ignoreLen bool) bool { + if ds.tableInfo.PKIsHandle && mysql.HasPriKeyFlag(column.RetType.GetFlag()) { + return true + } + if column.ID == model.ExtraHandleID { + return true + } + coveredByPlainIndex := isIndexColsCoveringCol(column, indexColumns, idxColLens, ignoreLen) + coveredByClusteredIndex := isIndexColsCoveringCol(column, ds.commonHandleCols, ds.commonHandleLens, ignoreLen) + if !coveredByPlainIndex && !coveredByClusteredIndex { + return false + } + isClusteredNewCollationIdx := collate.NewCollationEnabled() && + column.GetType().EvalType() == types.ETString && + !mysql.HasBinaryFlag(column.GetType().GetFlag()) + if !coveredByPlainIndex && coveredByClusteredIndex && isClusteredNewCollationIdx && ds.table.Meta().CommonHandleVersion == 0 { + return false + } + return true +} + +func (ds *DataSource) isIndexCoveringColumns(columns, indexColumns []*expression.Column, idxColLens []int) bool { for _, col := range columns { - if tblInfo.PKIsHandle && mysql.HasPriKeyFlag(col.RetType.GetFlag()) { - continue + if !ds.indexCoveringColumn(col, indexColumns, idxColLens, false) { + return false } - if col.ID == model.ExtraHandleID { - continue + } + return true +} + +func (ds *DataSource) isIndexCoveringCondition(condition expression.Expression, indexColumns []*expression.Column, idxColLens []int) bool { + switch v := condition.(type) { + case *expression.Column: + return ds.indexCoveringColumn(v, indexColumns, idxColLens, false) + case *expression.ScalarFunction: + // Even if the index only contains prefix `col`, the index can cover `col is null`. + if v.FuncName.L == ast.IsNull { + if col, ok := v.GetArgs()[0].(*expression.Column); ok { + return ds.indexCoveringColumn(col, indexColumns, idxColLens, true) + } } - coveredByPlainIndex := indexCoveringCol(col, indexColumns, idxColLens) - coveredByClusteredIndex := indexCoveringCol(col, ds.commonHandleCols, ds.commonHandleLens) - if !coveredByPlainIndex && !coveredByClusteredIndex { - return false + for _, arg := range v.GetArgs() { + if !ds.isIndexCoveringCondition(arg, indexColumns, idxColLens) { + return false + } } - isClusteredNewCollationIdx := collate.NewCollationEnabled() && - col.GetType().EvalType() == types.ETString && - !mysql.HasBinaryFlag(col.GetType().GetFlag()) - if !coveredByPlainIndex && coveredByClusteredIndex && isClusteredNewCollationIdx && ds.table.Meta().CommonHandleVersion == 0 { + return true + } + return true +} + +func (ds *DataSource) isSingleScan(indexColumns []*expression.Column, idxColLens []int) bool { + if !ds.ctx.GetSessionVars().OptPrefixIndexSingleScan || ds.colsRequiringFullLen == nil { + // ds.colsRequiringFullLen is set at (*DataSource).PruneColumns. In some cases we don't reach (*DataSource).PruneColumns + // and ds.colsRequiringFullLen is nil, so we fall back to ds.isIndexCoveringColumns(ds.schema.Columns, indexColumns, idxColLens). + return ds.isIndexCoveringColumns(ds.schema.Columns, indexColumns, idxColLens) + } + if !ds.isIndexCoveringColumns(ds.colsRequiringFullLen, indexColumns, idxColLens) { + return false + } + for _, cond := range ds.allConds { + if !ds.isIndexCoveringCondition(cond, indexColumns, idxColLens) { return false } } @@ -1343,6 +1419,12 @@ func (ds *DataSource) addSelection4PlanCache(task *rootTask, stats *property.Sta // convertToIndexScan converts the DataSource to index scan with idx. func (ds *DataSource) convertToIndexScan(prop *property.PhysicalProperty, candidate *candidatePath, _ *physicalOptimizeOp) (task task, err error) { + if candidate.path.Index.MVIndex { + // MVIndex is special since different index rows may return the same _row_id and this can break some assumptions of IndexReader. + // Currently only support using IndexMerge to access MVIndex instead of IndexReader. + // TODO: make IndexReader support accessing MVIndex directly. + return invalidTask, nil + } if !candidate.path.IsSingleScan { // If it's parent requires single read task, return max cost. if prop.TaskTp == property.CopSingleReadTaskType { @@ -1355,6 +1437,14 @@ func (ds *DataSource) convertToIndexScan(prop *property.PhysicalProperty, if !prop.IsSortItemEmpty() && !candidate.isMatchProp { return invalidTask, nil } + // If we need to keep order for the index scan, we should forbid the non-keep-order index scan when we try to generate the path. + if prop.IsSortItemEmpty() && candidate.path.ForceKeepOrder { + return invalidTask, nil + } + // If we don't need to keep order for the index scan, we should forbid the non-keep-order index scan when we try to generate the path. + if !prop.IsSortItemEmpty() && candidate.path.ForceNoKeepOrder { + return invalidTask, nil + } path := candidate.path is := ds.getOriginalPhysicalIndexScan(prop, path, candidate.isMatchProp, candidate.path.IsSingleScan) cop := &copTask{ @@ -1575,11 +1665,17 @@ func matchIndicesProp(idxCols []*expression.Column, colLens []int, propItems []p return true } -func (ds *DataSource) splitIndexFilterConditions(conditions []expression.Expression, indexColumns []*expression.Column, idxColLens []int, - table *model.TableInfo) (indexConds, tableConds []expression.Expression) { +func (ds *DataSource) splitIndexFilterConditions(conditions []expression.Expression, indexColumns []*expression.Column, + idxColLens []int) (indexConds, tableConds []expression.Expression) { var indexConditions, tableConditions []expression.Expression for _, cond := range conditions { - if ds.isCoveringIndex(expression.ExtractColumns(cond), indexColumns, idxColLens, table) { + var covered bool + if ds.ctx.GetSessionVars().OptPrefixIndexSingleScan { + covered = ds.isIndexCoveringCondition(cond, indexColumns, idxColLens) + } else { + covered = ds.isIndexCoveringColumns(expression.ExtractColumns(cond), indexColumns, idxColLens) + } + if covered { indexConditions = append(indexConditions, cond) } else { tableConditions = append(tableConditions, cond) @@ -1711,9 +1807,10 @@ func (ds *DataSource) crossEstimateRowCount(path *util.AccessPath, conds []expre if len(ranges) == 0 || len(accessConds) == 0 || err != nil { return 0, err == nil, corr } - idxID, idxExists := ds.stats.HistColl.ColID2IdxID[colID] - if !idxExists { - idxID = -1 + idxID := int64(-1) + idxIDs, idxExists := ds.stats.HistColl.ColID2IdxIDs[colID] + if idxExists && len(idxIDs) > 0 { + idxID = idxIDs[0] } rangeCounts, ok := getColumnRangeCounts(ds.ctx, colID, ranges, ds.tableStats.HistColl, idxID) if !ok { @@ -1848,6 +1945,36 @@ func (s *LogicalIndexScan) GetPhysicalIndexScan(_ *expression.Schema, stats *pro return is } +// isPointGetPath indicates whether the conditions are point-get-able. +// eg: create table t(a int, b int,c int unique, primary (a,b)) +// select * from t where a = 1 and b = 1 and c =1; +// the datasource can access by primary key(a,b) or unique key c which are both point-get-able +func (ds *DataSource) isPointGetPath(path *util.AccessPath) bool { + if len(path.Ranges) < 1 { + return false + } + if !path.IsIntHandlePath { + if path.Index == nil { + return false + } + if !path.Index.Unique || path.Index.HasPrefixIndex() { + return false + } + idxColsLen := len(path.Index.Columns) + for _, ran := range path.Ranges { + if len(ran.LowVal) != idxColsLen { + return false + } + } + } + for _, ran := range path.Ranges { + if !ran.IsPointNonNullable(ds.ctx) { + return false + } + } + return true +} + // convertToTableScan converts the DataSource to table scan. func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candidate *candidatePath, _ *physicalOptimizeOp) (task task, err error) { // It will be handled in convertToIndexScan. @@ -1857,6 +1984,14 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid if !prop.IsSortItemEmpty() && !candidate.isMatchProp { return invalidTask, nil } + // If we need to keep order for the index scan, we should forbid the non-keep-order index scan when we try to generate the path. + if prop.IsSortItemEmpty() && candidate.path.ForceKeepOrder { + return invalidTask, nil + } + // If we don't need to keep order for the index scan, we should forbid the non-keep-order index scan when we try to generate the path. + if !prop.IsSortItemEmpty() && candidate.path.ForceNoKeepOrder { + return invalidTask, nil + } ts, _ := ds.getOriginalPhysicalTableScan(prop, candidate.path, candidate.isMatchProp) if ts.KeepOrder && ts.StoreType == kv.TiFlash && (ts.Desc || ds.SCtx().GetSessionVars().TiFlashFastScan) { // TiFlash fast mode(https://github.com/pingcap/tidb/pull/35851) does not keep order in TableScan @@ -1875,12 +2010,17 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid } } } - if prop.TaskTp == property.MppTaskType { + // In disaggregated tiflash mode, only MPP is allowed, cop and batchCop is deprecated. + // So if prop.TaskTp is RootTaskType, have to use mppTask then convert to rootTask. + isDisaggregatedTiFlashPath := config.GetGlobalConfig().DisaggregatedTiFlash && ts.StoreType == kv.TiFlash + canMppConvertToRootForDisaggregatedTiFlash := isDisaggregatedTiFlashPath && prop.TaskTp == property.RootTaskType && ds.SCtx().GetSessionVars().IsMPPAllowed() + if prop.TaskTp == property.MppTaskType || canMppConvertToRootForDisaggregatedTiFlash { if ts.KeepOrder { return invalidTask, nil } - if prop.MPPPartitionTp != property.AnyType || ts.isPartition { + if prop.MPPPartitionTp != property.AnyType || (ts.isPartition && !canMppConvertToRootForDisaggregatedTiFlash) { // If ts is a single partition, then this partition table is in static-only prune, then we should not choose mpp execution. + // But in disaggregated tiflash mode, we can only use mpp, so we add ExchangeSender and ExchangeReceiver above TableScan for static pruning partition table. ds.SCtx().GetSessionVars().RaiseWarningWhenMPPEnforced("MPP mode may be blocked because table `" + ds.tableInfo.Name.O + "`is a partition table which is not supported when `@@tidb_partition_prune_mode=static`.") return invalidTask, nil } @@ -1891,8 +2031,9 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid } } mppTask := &mppTask{ - p: ts, - partTp: property.AnyType, + p: ts, + partTp: property.AnyType, + tblColHists: ds.TblColHists, } ts.PartitionInfo = PartitionInfo{ PruningConds: pushDownNot(ds.ctx, ds.allConds), @@ -1901,7 +2042,26 @@ func (ds *DataSource) convertToTableScan(prop *property.PhysicalProperty, candid ColumnNames: ds.names, } mppTask = ts.addPushedDownSelectionToMppTask(mppTask, ds.stats.ScaleByExpectCnt(prop.ExpectedCnt)) - return mppTask, nil + task = mppTask + if !mppTask.invalid() { + if prop.TaskTp == property.MppTaskType && len(mppTask.rootTaskConds) > 0 { + // If got filters cannot be pushed down to tiflash, we have to make sure it will be executed in TiDB, + // So have to return a rootTask, but prop requires mppTask, cannot meet this requirement. + task = invalidTask + } else if prop.TaskTp == property.RootTaskType { + // when got here, canMppConvertToRootForDisaggregatedTiFlash is true. + task = mppTask + task = task.convertToRootTask(ds.ctx) + if !task.invalid() { + ds.addSelection4PlanCache(task.(*rootTask), ds.stats.ScaleByExpectCnt(prop.ExpectedCnt), prop) + } + } + } + return task, nil + } + if isDisaggregatedTiFlashPath { + // prop.TaskTp is cop related, just return invalidTask. + return invalidTask, nil } copTask := &copTask{ tablePlan: ts, @@ -2111,10 +2271,8 @@ func (ts *PhysicalTableScan) addPushedDownSelectionToMppTask(mpp *mppTask, stats filterCondition, rootTaskConds := SplitSelCondsWithVirtualColumn(ts.filterCondition) var newRootConds []expression.Expression filterCondition, newRootConds = expression.PushDownExprs(ts.ctx.GetSessionVars().StmtCtx, filterCondition, ts.ctx.GetClient(), ts.StoreType) - rootTaskConds = append(rootTaskConds, newRootConds...) - if len(rootTaskConds) > 0 { - return &mppTask{} - } + mpp.rootTaskConds = append(rootTaskConds, newRootConds...) + ts.filterCondition = filterCondition // Add filter condition to table plan now. if len(ts.filterCondition) > 0 { @@ -2234,6 +2392,7 @@ func (ds *DataSource) getOriginalPhysicalIndexScan(prop *property.PhysicalProper physicalTableID: ds.physicalTableID, tblColHists: ds.TblColHists, pkIsHandleCol: ds.getPKIsHandleCol(), + constColsByCond: path.ConstCols, prop: prop, }.Init(ds.ctx, ds.blockOffset) statsTbl := ds.statisticTable diff --git a/planner/core/flat_plan.go b/planner/core/flat_plan.go index 3058f0fd82e92..da200961e821c 100644 --- a/planner/core/flat_plan.go +++ b/planner/core/flat_plan.go @@ -15,6 +15,8 @@ package core import ( + "sort" + "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/util/texttree" ) @@ -52,23 +54,34 @@ type FlatPhysicalPlan struct { // depth-first traversal plus some special rule for some operators. type FlatPlanTree []*FlatOperator -// GetSelectPlan skips Insert, Delete and Update at the beginning of the FlatPlanTree. +// GetSelectPlan skips Insert, Delete, and Update at the beginning of the FlatPlanTree and the foreign key check/cascade plan at the end of the FlatPlanTree. // Note: // // It returns a reference to the original FlatPlanTree, please avoid modifying the returned value. -// Since you get a part of the original slice, you need to adjust the FlatOperator.Depth and FlatOperator.ChildrenIdx when using them. -func (e FlatPlanTree) GetSelectPlan() FlatPlanTree { +// The second return value is the offset. Because the returned FlatPlanTree is a part of the original slice, you need to minus them by the offset when using the returned FlatOperator.Depth and FlatOperator.ChildrenIdx. +func (e FlatPlanTree) GetSelectPlan() (FlatPlanTree, int) { if len(e) == 0 { - return nil + return nil, 0 } + hasDML := false for i, op := range e { switch op.Origin.(type) { case *Insert, *Delete, *Update: + hasDML = true default: - return e[i:] + if hasDML { + for j := i; j < len(e); j++ { + switch e[j].Origin.(type) { + case *FKCheck, *FKCascade: + // The later plans are belong to foreign key check/cascade plans, doesn't belong to select plan, just skip it. + return e[i:j], i + } + } + } + return e[i:], i } } - return nil + return nil, 0 } // FlatOperator is a simplified operator. @@ -339,31 +352,38 @@ func (f *FlatPhysicalPlan) flattenRecursively(p Plan, info *operatorCtx, target target, childIdx = f.flattenRecursively(plan.DataSource, childCtx, target) childIdxs = append(childIdxs, childIdx) case *PhysicalCTE: - f.ctesToFlatten = append(f.ctesToFlatten, plan) + // We shallow copy the PhysicalCTE here because we don't want the probeParents (see comments in PhysicalPlan + // for details) to affect the row count display of the independent CTE plan tree. + copiedCTE := *plan + copiedCTE.probeParents = nil + f.ctesToFlatten = append(f.ctesToFlatten, &copiedCTE) case *Insert: if plan.SelectPlan != nil { childCtx.isRoot = true childCtx.label = Empty - childCtx.isLastChild = true + childCtx.isLastChild = len(plan.FKChecks) == 0 && len(plan.FKCascades) == 0 target, childIdx = f.flattenRecursively(plan.SelectPlan, childCtx, target) childIdxs = append(childIdxs, childIdx) } + target, childIdxs = f.flattenForeignKeyChecksAndCascades(childCtx, target, childIdxs, plan.FKChecks, plan.FKCascades, true) case *Update: if plan.SelectPlan != nil { childCtx.isRoot = true childCtx.label = Empty - childCtx.isLastChild = true + childCtx.isLastChild = len(plan.FKChecks) == 0 && len(plan.FKCascades) == 0 target, childIdx = f.flattenRecursively(plan.SelectPlan, childCtx, target) childIdxs = append(childIdxs, childIdx) } + target, childIdxs = f.flattenForeignKeyChecksAndCascadesMap(childCtx, target, childIdxs, plan.FKChecks, plan.FKCascades) case *Delete: if plan.SelectPlan != nil { childCtx.isRoot = true childCtx.label = Empty - childCtx.isLastChild = true + childCtx.isLastChild = len(plan.FKChecks) == 0 && len(plan.FKCascades) == 0 target, childIdx = f.flattenRecursively(plan.SelectPlan, childCtx, target) childIdxs = append(childIdxs, childIdx) } + target, childIdxs = f.flattenForeignKeyChecksAndCascadesMap(childCtx, target, childIdxs, plan.FKChecks, plan.FKCascades) case *Execute: f.InExecute = true if plan.Plan != nil { @@ -389,6 +409,13 @@ func (f *FlatPhysicalPlan) flattenRecursively(p Plan, info *operatorCtx, target target, childIdx = f.flattenRecursively(plan.TargetPlan, initInfo, target) childIdxs = append(childIdxs, childIdx) } + case *FKCascade: + for i, child := range plan.CascadePlans { + childCtx.label = Empty + childCtx.isLastChild = i == len(plan.CascadePlans)-1 + target, childIdx = f.flattenRecursively(child, childCtx, target) + childIdxs = append(childIdxs, childIdx) + } } if flat != nil { flat.ChildrenIdx = childIdxs @@ -397,6 +424,50 @@ func (f *FlatPhysicalPlan) flattenRecursively(p Plan, info *operatorCtx, target return target, idx } +func (f *FlatPhysicalPlan) flattenForeignKeyChecksAndCascadesMap(childCtx *operatorCtx, target FlatPlanTree, childIdxs []int, fkChecksMap map[int64][]*FKCheck, fkCascadesMap map[int64][]*FKCascade) (FlatPlanTree, []int) { + tids := make([]int64, 0, len(fkChecksMap)) + for tid := range fkChecksMap { + tids = append(tids, tid) + } + // Sort by table id for explain result stable. + sort.Slice(tids, func(i, j int) bool { + return tids[i] < tids[j] + }) + for i, tid := range tids { + target, childIdxs = f.flattenForeignKeyChecksAndCascades(childCtx, target, childIdxs, fkChecksMap[tid], nil, len(fkCascadesMap) == 0 && i == len(tids)-1) + } + tids = tids[:0] + for tid := range fkCascadesMap { + tids = append(tids, tid) + } + sort.Slice(tids, func(i, j int) bool { + return tids[i] < tids[j] + }) + for i, tid := range tids { + target, childIdxs = f.flattenForeignKeyChecksAndCascades(childCtx, target, childIdxs, nil, fkCascadesMap[tid], i == len(tids)-1) + } + return target, childIdxs +} + +func (f *FlatPhysicalPlan) flattenForeignKeyChecksAndCascades(childCtx *operatorCtx, target FlatPlanTree, childIdxs []int, fkChecks []*FKCheck, fkCascades []*FKCascade, isLast bool) (FlatPlanTree, []int) { + var childIdx int + for i, fkCheck := range fkChecks { + childCtx.isRoot = true + childCtx.label = Empty + childCtx.isLastChild = isLast && len(fkCascades) == 0 && i == len(fkChecks)-1 + target, childIdx = f.flattenRecursively(fkCheck, childCtx, target) + childIdxs = append(childIdxs, childIdx) + } + for i, fkCascade := range fkCascades { + childCtx.isRoot = true + childCtx.label = Empty + childCtx.isLastChild = isLast && i == len(fkCascades)-1 + target, childIdx = f.flattenRecursively(fkCascade, childCtx, target) + childIdxs = append(childIdxs, childIdx) + } + return target, childIdxs +} + func (f *FlatPhysicalPlan) flattenCTERecursively(cteDef *CTEDefinition, info *operatorCtx, target FlatPlanTree) FlatPlanTree { flat := f.flattenSingle(cteDef, info) if flat != nil { diff --git a/planner/core/foreign_key.go b/planner/core/foreign_key.go index 063a823a14e74..f6cec0fa8f069 100644 --- a/planner/core/foreign_key.go +++ b/planner/core/foreign_key.go @@ -15,8 +15,10 @@ package core import ( + "fmt" "unsafe" + "github.com/pingcap/errors" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" @@ -26,6 +28,7 @@ import ( // FKCheck indicates the foreign key constraint checker. type FKCheck struct { + basePhysicalPlan FK *model.FKInfo ReferredFK *model.ReferredFKInfo Tbl table.Table @@ -39,7 +42,57 @@ type FKCheck struct { FailedErr error } -const emptyFkCheckSize = int64(unsafe.Sizeof(FKCheck{})) +// FKCascade indicates the foreign key constraint cascade behaviour. +type FKCascade struct { + basePhysicalPlan + Tp FKCascadeType + ReferredFK *model.ReferredFKInfo + ChildTable table.Table + FK *model.FKInfo + FKCols []*model.ColumnInfo + FKIdx *model.IndexInfo + // CascadePlans contains the child cascade plan. + // CascadePlans will be filled during execution, so only `explain analyze` statement result contains the cascade plan, + // `explain` statement result doesn't contain the cascade plan. + CascadePlans []Plan +} + +// FKCascadeType indicates in which (delete/update) statements. +type FKCascadeType int8 + +const ( + // FKCascadeOnDelete indicates in delete statement. + FKCascadeOnDelete FKCascadeType = 1 + // FKCascadeOnUpdate indicates in update statement. + FKCascadeOnUpdate FKCascadeType = 2 + + emptyFkCheckSize = int64(unsafe.Sizeof(FKCheck{})) + emptyFkCascadeSize = int64(unsafe.Sizeof(FKCascade{})) +) + +// AccessObject implements dataAccesser interface. +func (f *FKCheck) AccessObject() AccessObject { + if f.Idx == nil { + return OtherAccessObject(fmt.Sprintf("table:%s", f.Tbl.Meta().Name)) + } + return OtherAccessObject(fmt.Sprintf("table:%s, index:%s", f.Tbl.Meta().Name, f.Idx.Meta().Name)) +} + +// OperatorInfo implements dataAccesser interface. +func (f *FKCheck) OperatorInfo(normalized bool) string { + if f.FK != nil { + return fmt.Sprintf("foreign_key:%s, check_exist", f.FK.Name) + } + if f.ReferredFK != nil { + return fmt.Sprintf("foreign_key:%s, check_not_exist", f.ReferredFK.ChildFKName) + } + return "" +} + +// ExplainInfo implement Plan interface. +func (f *FKCheck) ExplainInfo() string { + return f.AccessObject().String() + ", " + f.OperatorInfo(false) +} // MemoryUsage return the memory usage of FKCheck func (f *FKCheck) MemoryUsage() (sum int64) { @@ -54,36 +107,86 @@ func (f *FKCheck) MemoryUsage() (sum int64) { return } -func (p *Insert) buildOnInsertFKChecks(ctx sessionctx.Context, is infoschema.InfoSchema, dbName string) ([]*FKCheck, error) { +// AccessObject implements dataAccesser interface. +func (f *FKCascade) AccessObject() AccessObject { + if f.FKIdx == nil { + return OtherAccessObject(fmt.Sprintf("table:%s", f.ChildTable.Meta().Name)) + } + return OtherAccessObject(fmt.Sprintf("table:%s, index:%s", f.ChildTable.Meta().Name, f.FKIdx.Name)) +} + +// OperatorInfo implements dataAccesser interface. +func (f *FKCascade) OperatorInfo(normalized bool) string { + switch f.Tp { + case FKCascadeOnDelete: + return fmt.Sprintf("foreign_key:%s, on_delete:%s", f.FK.Name, model.ReferOptionType(f.FK.OnDelete).String()) + case FKCascadeOnUpdate: + return fmt.Sprintf("foreign_key:%s, on_update:%s", f.FK.Name, model.ReferOptionType(f.FK.OnUpdate).String()) + } + return "" +} + +// ExplainInfo implement Plan interface. +func (f *FKCascade) ExplainInfo() string { + return f.AccessObject().String() + ", " + f.OperatorInfo(false) +} + +// MemoryUsage return the memory usage of FKCascade +func (f *FKCascade) MemoryUsage() (sum int64) { + if f == nil { + return + } + sum = emptyFkCascadeSize + return +} + +func (p *Insert) buildOnInsertFKTriggers(ctx sessionctx.Context, is infoschema.InfoSchema, dbName string) error { if !ctx.GetSessionVars().ForeignKeyChecks { - return nil, nil + return nil } tblInfo := p.Table.Meta() fkChecks := make([]*FKCheck, 0, len(tblInfo.ForeignKeys)) + fkCascades := make([]*FKCascade, 0, len(tblInfo.ForeignKeys)) updateCols := p.buildOnDuplicateUpdateColumns() if len(updateCols) > 0 { - referredFKChecks, err := buildOnUpdateReferredFKChecks(is, dbName, tblInfo, updateCols) + referredFKChecks, referredFKCascades, err := buildOnUpdateReferredFKTriggers(ctx, is, dbName, tblInfo, updateCols) if err != nil { - return nil, err + return err } if len(referredFKChecks) > 0 { fkChecks = append(fkChecks, referredFKChecks...) } + if len(referredFKCascades) > 0 { + fkCascades = append(fkCascades, referredFKCascades...) + } + } else if p.IsReplace { + referredFKChecks, referredFKCascades, err := p.buildOnReplaceReferredFKTriggers(ctx, is, dbName, tblInfo) + if err != nil { + return err + } + if len(referredFKChecks) > 0 { + fkChecks = append(fkChecks, referredFKChecks...) + } + if len(referredFKCascades) > 0 { + fkCascades = append(fkCascades, referredFKCascades...) + } } for _, fk := range tblInfo.ForeignKeys { if fk.Version < 1 { continue } failedErr := ErrNoReferencedRow2.FastGenByArgs(fk.String(dbName, tblInfo.Name.L)) - fkCheck, err := buildFKCheckOnModifyChildTable(is, fk, failedErr) + fkCheck, err := buildFKCheckOnModifyChildTable(ctx, is, fk, failedErr) if err != nil { - return nil, err + return err } if fkCheck != nil { fkChecks = append(fkChecks, fkCheck) } } - return fkChecks, nil + p.FKChecks = fkChecks + p.FKCascades = fkCascades + return nil } func (p *Insert) buildOnDuplicateUpdateColumns() map[string]struct{} { @@ -94,12 +197,32 @@ func (p *Insert) buildOnDuplicateUpdateColumns() map[string]struct{} { return m } -func (updt *Update) buildOnUpdateFKChecks(ctx sessionctx.Context, is infoschema.InfoSchema, tblID2table map[int64]table.Table) error { +func (p *Insert) buildOnReplaceReferredFKTriggers(ctx sessionctx.Context, is infoschema.InfoSchema, dbName string, tblInfo *model.TableInfo) ([]*FKCheck, []*FKCascade, error) { + referredFKs := is.GetTableReferredForeignKeys(dbName, tblInfo.Name.L) + fkChecks := make([]*FKCheck, 0, len(referredFKs)) + fkCascades := make([]*FKCascade, 0, len(referredFKs)) + for _, referredFK := range referredFKs { + fkCheck, fkCascade, err := buildOnDeleteOrUpdateFKTrigger(ctx, is, referredFK, FKCascadeOnDelete) + if err != nil { + return nil, nil, err + } + if fkCheck != nil { + fkChecks = append(fkChecks, fkCheck) + } + if fkCascade != nil { + fkCascades = append(fkCascades, fkCascade) + } + } + return fkChecks, fkCascades, nil +} + +func (updt *Update) buildOnUpdateFKTriggers(ctx sessionctx.Context, is infoschema.InfoSchema, tblID2table map[int64]table.Table) error { if !ctx.GetSessionVars().ForeignKeyChecks { return nil } tblID2UpdateColumns := updt.buildTbl2UpdateColumns() fkChecks := make(map[int64][]*FKCheck) + fkCascades := make(map[int64][]*FKCascade) for tid, tbl := range tblID2table { tblInfo := tbl.Meta() dbInfo, exist := is.SchemaByTable(tblInfo) @@ -111,14 +234,17 @@ func (updt *Update) buildOnUpdateFKChecks(ctx sessionctx.Context, is infoschema. if len(updateCols) == 0 { continue } - referredFKChecks, err := buildOnUpdateReferredFKChecks(is, dbInfo.Name.L, tblInfo, updateCols) + referredFKChecks, referredFKCascades, err := buildOnUpdateReferredFKTriggers(ctx, is, dbInfo.Name.L, tblInfo, updateCols) if err != nil { return err } if len(referredFKChecks) > 0 { fkChecks[tid] = append(fkChecks[tid], referredFKChecks...) } - childFKChecks, err := buildOnUpdateChildFKChecks(is, dbInfo.Name.L, tblInfo, updateCols) + if len(referredFKCascades) > 0 { + fkCascades[tid] = append(fkCascades[tid], referredFKCascades...) + } + childFKChecks, err := buildOnUpdateChildFKChecks(ctx, is, dbInfo.Name.L, tblInfo, updateCols) if err != nil { return err } @@ -127,14 +253,16 @@ func (updt *Update) buildOnUpdateFKChecks(ctx sessionctx.Context, is infoschema. } } updt.FKChecks = fkChecks + updt.FKCascades = fkCascades return nil } -func (del *Delete) buildOnDeleteFKChecks(ctx sessionctx.Context, is infoschema.InfoSchema, tblID2table map[int64]table.Table) error { +func (del *Delete) buildOnDeleteFKTriggers(ctx sessionctx.Context, is infoschema.InfoSchema, tblID2table map[int64]table.Table) error { if !ctx.GetSessionVars().ForeignKeyChecks { return nil } fkChecks := make(map[int64][]*FKCheck) + fkCascades := make(map[int64][]*FKCascade) for tid, tbl := range tblID2table { tblInfo := tbl.Meta() dbInfo, exist := is.SchemaByTable(tblInfo) @@ -143,38 +271,46 @@ func (del *Delete) buildOnDeleteFKChecks(ctx sessionctx.Context, is infoschema.I } referredFKs := is.GetTableReferredForeignKeys(dbInfo.Name.L, tblInfo.Name.L) for _, referredFK := range referredFKs { - fkCheck, err := buildFKCheckOnModifyReferTable(is, referredFK) + fkCheck, fkCascade, err := buildOnDeleteOrUpdateFKTrigger(ctx, is, referredFK, FKCascadeOnDelete) if err != nil { return err } if fkCheck != nil { fkChecks[tid] = append(fkChecks[tid], fkCheck) } + if fkCascade != nil { + fkCascades[tid] = append(fkCascades[tid], fkCascade) + } } } del.FKChecks = fkChecks + del.FKCascades = fkCascades return nil } -func buildOnUpdateReferredFKChecks(is infoschema.InfoSchema, dbName string, tblInfo *model.TableInfo, updateCols map[string]struct{}) ([]*FKCheck, error) { +func buildOnUpdateReferredFKTriggers(ctx sessionctx.Context, is infoschema.InfoSchema, dbName string, tblInfo *model.TableInfo, updateCols map[string]struct{}) ([]*FKCheck, []*FKCascade, error) { referredFKs := is.GetTableReferredForeignKeys(dbName, tblInfo.Name.L) fkChecks := make([]*FKCheck, 0, len(referredFKs)) + fkCascades := make([]*FKCascade, 0, len(referredFKs)) for _, referredFK := range referredFKs { if !isMapContainAnyCols(updateCols, referredFK.Cols...) { continue } - fkCheck, err := buildFKCheckOnModifyReferTable(is, referredFK) + fkCheck, fkCascade, err := buildOnDeleteOrUpdateFKTrigger(ctx, is, referredFK, FKCascadeOnUpdate) if err != nil { - return nil, err + return nil, nil, err } if fkCheck != nil { fkChecks = append(fkChecks, fkCheck) } + if fkCascade != nil { + fkCascades = append(fkCascades, fkCascade) + } } - return fkChecks, nil + return fkChecks, fkCascades, nil } -func buildOnUpdateChildFKChecks(is infoschema.InfoSchema, dbName string, tblInfo *model.TableInfo, updateCols map[string]struct{}) ([]*FKCheck, error) { +func buildOnUpdateChildFKChecks(ctx sessionctx.Context, is infoschema.InfoSchema, dbName string, tblInfo *model.TableInfo, updateCols map[string]struct{}) ([]*FKCheck, error) { fkChecks := make([]*FKCheck, 0, len(tblInfo.ForeignKeys)) for _, fk := range tblInfo.ForeignKeys { if fk.Version < 1 { @@ -184,7 +320,7 @@ func buildOnUpdateChildFKChecks(is infoschema.InfoSchema, dbName string, tblInfo continue } failedErr := ErrNoReferencedRow2.FastGenByArgs(fk.String(dbName, tblInfo.Name.L)) - fkCheck, err := buildFKCheckOnModifyChildTable(is, fk, failedErr) + fkCheck, err := buildFKCheckOnModifyChildTable(ctx, is, fk, failedErr) if err != nil { return nil, err } @@ -229,6 +365,36 @@ func (updt *Update) buildTbl2UpdateColumns() map[int64]map[string]struct{} { return tblID2UpdateColumns } +func buildOnDeleteOrUpdateFKTrigger(ctx sessionctx.Context, is infoschema.InfoSchema, referredFK *model.ReferredFKInfo, tp FKCascadeType) (*FKCheck, *FKCascade, error) { + childTable, err := is.TableByName(referredFK.ChildSchema, referredFK.ChildTable) + if err != nil { + return nil, nil, nil + } + fk := model.FindFKInfoByName(childTable.Meta().ForeignKeys, referredFK.ChildFKName.L) + if fk == nil || fk.Version < 1 { + return nil, nil, nil + } + var fkReferOption model.ReferOptionType + if fk.State != model.StatePublic { + fkReferOption = model.ReferOptionRestrict + } else { + switch tp { + case FKCascadeOnDelete: + fkReferOption = model.ReferOptionType(fk.OnDelete) + case FKCascadeOnUpdate: + fkReferOption = model.ReferOptionType(fk.OnUpdate) + } + } + switch fkReferOption { + case model.ReferOptionCascade, model.ReferOptionSetNull: + fkCascade, err := buildFKCascade(ctx, tp, referredFK, childTable, fk) + return nil, fkCascade, err + default: + fkCheck, err := buildFKCheckForReferredFK(ctx, childTable, fk, referredFK) + return fkCheck, nil, err + } +} + func isMapContainAnyCols(colsMap map[string]struct{}, cols ...model.CIStr) bool { for _, col := range cols { _, exist := colsMap[col.L] @@ -239,12 +405,12 @@ func isMapContainAnyCols(colsMap map[string]struct{}, cols ...model.CIStr) bool return false } -func buildFKCheckOnModifyChildTable(is infoschema.InfoSchema, fk *model.FKInfo, failedErr error) (*FKCheck, error) { +func buildFKCheckOnModifyChildTable(ctx sessionctx.Context, is infoschema.InfoSchema, fk *model.FKInfo, failedErr error) (*FKCheck, error) { referTable, err := is.TableByName(fk.RefSchema, fk.RefTable) if err != nil { return nil, nil } - fkCheck, err := buildFKCheck(referTable, fk.RefCols, failedErr) + fkCheck, err := buildFKCheck(ctx, referTable, fk.RefCols, failedErr) if err != nil { return nil, err } @@ -253,17 +419,9 @@ func buildFKCheckOnModifyChildTable(is infoschema.InfoSchema, fk *model.FKInfo, return fkCheck, nil } -func buildFKCheckOnModifyReferTable(is infoschema.InfoSchema, referredFK *model.ReferredFKInfo) (*FKCheck, error) { - childTable, err := is.TableByName(referredFK.ChildSchema, referredFK.ChildTable) - if err != nil { - return nil, nil - } - fk := model.FindFKInfoByName(childTable.Meta().ForeignKeys, referredFK.ChildFKName.L) - if fk == nil || fk.Version < 1 { - return nil, nil - } +func buildFKCheckForReferredFK(ctx sessionctx.Context, childTable table.Table, fk *model.FKInfo, referredFK *model.ReferredFKInfo) (*FKCheck, error) { failedErr := ErrRowIsReferenced2.GenWithStackByArgs(fk.String(referredFK.ChildSchema.L, referredFK.ChildTable.L)) - fkCheck, err := buildFKCheck(childTable, fk.Cols, failedErr) + fkCheck, err := buildFKCheck(ctx, childTable, fk.Cols, failedErr) if err != nil { return nil, err } @@ -272,21 +430,21 @@ func buildFKCheckOnModifyReferTable(is infoschema.InfoSchema, referredFK *model. return fkCheck, nil } -func buildFKCheck(tbl table.Table, cols []model.CIStr, failedErr error) (*FKCheck, error) { +func buildFKCheck(ctx sessionctx.Context, tbl table.Table, cols []model.CIStr, failedErr error) (*FKCheck, error) { tblInfo := tbl.Meta() if tblInfo.PKIsHandle && len(cols) == 1 { refColInfo := model.FindColumnInfo(tblInfo.Columns, cols[0].L) if refColInfo != nil && mysql.HasPriKeyFlag(refColInfo.GetFlag()) { - return &FKCheck{ + return FKCheck{ Tbl: tbl, IdxIsPrimaryKey: true, IdxIsExclusive: true, FailedErr: failedErr, - }, nil + }.Init(ctx), nil } } - referTbIdxInfo := model.FindIndexByColumns(tblInfo, cols...) + referTbIdxInfo := model.FindIndexByColumns(tblInfo, tblInfo.Indices, cols...) if referTbIdxInfo == nil { return nil, failedErr } @@ -300,11 +458,42 @@ func buildFKCheck(tbl table.Table, cols []model.CIStr, failedErr error) (*FKChec return nil, failedErr } - return &FKCheck{ + return FKCheck{ Tbl: tbl, Idx: tblIdx, IdxIsExclusive: len(cols) == len(referTbIdxInfo.Columns), IdxIsPrimaryKey: referTbIdxInfo.Primary && tblInfo.IsCommonHandle, FailedErr: failedErr, - }, nil + }.Init(ctx), nil +} + +func buildFKCascade(ctx sessionctx.Context, tp FKCascadeType, referredFK *model.ReferredFKInfo, childTable table.Table, fk *model.FKInfo) (*FKCascade, error) { + cols := make([]*model.ColumnInfo, len(fk.Cols)) + childTableColumns := childTable.Meta().Columns + for i, c := range fk.Cols { + col := model.FindColumnInfo(childTableColumns, c.L) + if col == nil { + return nil, errors.Errorf("foreign key column %s is not found in table %s", c.L, childTable.Meta().Name) + } + cols[i] = col + } + fkCascade := FKCascade{ + Tp: tp, + ReferredFK: referredFK, + ChildTable: childTable, + FK: fk, + FKCols: cols, + }.Init(ctx) + if childTable.Meta().PKIsHandle && len(cols) == 1 { + refColInfo := model.FindColumnInfo(childTableColumns, cols[0].Name.L) + if refColInfo != nil && mysql.HasPriKeyFlag(refColInfo.GetFlag()) { + return fkCascade, nil + } + } + indexForFK := model.FindIndexByColumns(childTable.Meta(), childTable.Meta().Indices, fk.Cols...) + if indexForFK == nil { + return nil, errors.Errorf("Missing index for '%s' foreign key columns in the table '%s'", fk.Name, childTable.Meta().Name) + } + fkCascade.FKIdx = indexForFK + return fkCascade, nil } diff --git a/planner/core/fragment.go b/planner/core/fragment.go index 5dfa93186826f..2496d463f2e24 100644 --- a/planner/core/fragment.go +++ b/planner/core/fragment.go @@ -16,10 +16,12 @@ package core import ( "context" + "sync/atomic" "time" "unsafe" "github.com/pingcap/errors" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/distsql" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" @@ -79,29 +81,45 @@ type tasksAndFrags struct { } type mppTaskGenerator struct { - ctx sessionctx.Context - startTS uint64 - is infoschema.InfoSchema - frags []*Fragment - cache map[int]tasksAndFrags + ctx sessionctx.Context + startTS uint64 + mppQueryID kv.MPPQueryID + is infoschema.InfoSchema + frags []*Fragment + cache map[int]tasksAndFrags } // GenerateRootMPPTasks generate all mpp tasks and return root ones. -func GenerateRootMPPTasks(ctx sessionctx.Context, startTs uint64, sender *PhysicalExchangeSender, is infoschema.InfoSchema) ([]*Fragment, error) { +func GenerateRootMPPTasks(ctx sessionctx.Context, startTs uint64, mppQueryID kv.MPPQueryID, sender *PhysicalExchangeSender, is infoschema.InfoSchema) ([]*Fragment, error) { g := &mppTaskGenerator{ - ctx: ctx, - startTS: startTs, - is: is, - cache: make(map[int]tasksAndFrags), + ctx: ctx, + startTS: startTs, + mppQueryID: mppQueryID, + is: is, + cache: make(map[int]tasksAndFrags), } return g.generateMPPTasks(sender) } +// AllocMPPTaskID allocates task id for mpp tasks. It will reset the task id when the query finished. +func AllocMPPTaskID(ctx sessionctx.Context) int64 { + mppQueryInfo := &ctx.GetSessionVars().StmtCtx.MPPQueryInfo + return mppQueryInfo.AllocatedMPPTaskID.Add(1) +} + +var mppQueryID uint64 = 1 + +// AllocMPPQueryID allocates local query id for mpp queries. +func AllocMPPQueryID() uint64 { + return atomic.AddUint64(&mppQueryID, 1) +} + func (e *mppTaskGenerator) generateMPPTasks(s *PhysicalExchangeSender) ([]*Fragment, error) { logutil.BgLogger().Info("Mpp will generate tasks", zap.String("plan", ToString(s))) tidbTask := &kv.MPPTask{ - StartTs: e.startTS, - ID: -1, + StartTs: e.startTS, + MppQueryID: e.mppQueryID, + ID: -1, } _, frags, err := e.generateMPPTasksForExchangeSender(s) if err != nil { @@ -132,10 +150,11 @@ func (e *mppTaskGenerator) constructMPPTasksByChildrenTasks(tasks []*kv.MPPTask) _, ok := addressMap[addr] if !ok { mppTask := &kv.MPPTask{ - Meta: &mppAddr{addr: addr}, - ID: e.ctx.GetSessionVars().AllocMPPTaskID(e.startTS), - StartTs: e.startTS, - TableID: -1, + Meta: &mppAddr{addr: addr}, + ID: AllocMPPTaskID(e.ctx), + MppQueryID: e.mppQueryID, + StartTs: e.startTS, + TableID: -1, } newTasks = append(newTasks, mppTask) addressMap[addr] = struct{}{} @@ -357,17 +376,30 @@ func (e *mppTaskGenerator) constructMPPTasksImpl(ctx context.Context, ts *Physic var allPartitionsIDs []int64 var err error splitedRanges, _ := distsql.SplitRangesAcrossInt64Boundary(ts.Ranges, false, false, ts.Table.IsCommonHandle) + // True when: + // 0. Is disaggregated tiflash. because in non-disaggregated tiflash, we dont use mpp for static pruning. + // 1. Is partition table. + // 2. Dynamic prune is not used. + var isDisaggregatedTiFlashStaticPrune bool if ts.Table.GetPartitionInfo() != nil { + isDisaggregatedTiFlashStaticPrune = config.GetGlobalConfig().DisaggregatedTiFlash && + !e.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() + tmp, _ := e.is.TableByID(ts.Table.ID) tbl := tmp.(table.PartitionedTable) - var partitions []table.PhysicalTable - partitions, err = partitionPruning(e.ctx, tbl, ts.PartitionInfo.PruningConds, ts.PartitionInfo.PartitionNames, ts.PartitionInfo.Columns, ts.PartitionInfo.ColumnNames) - if err != nil { - return nil, errors.Trace(err) + if !isDisaggregatedTiFlashStaticPrune { + var partitions []table.PhysicalTable + partitions, err = partitionPruning(e.ctx, tbl, ts.PartitionInfo.PruningConds, ts.PartitionInfo.PartitionNames, ts.PartitionInfo.Columns, ts.PartitionInfo.ColumnNames) + if err != nil { + return nil, errors.Trace(err) + } + req, allPartitionsIDs, err = e.constructMPPBuildTaskReqForPartitionedTable(ts, splitedRanges, partitions) + } else { + singlePartTbl := tbl.GetPartition(ts.physicalTableID) + req, err = e.constructMPPBuildTaskForNonPartitionTable(singlePartTbl.GetPhysicalID(), ts.Table.IsCommonHandle, splitedRanges) } - req, allPartitionsIDs, err = e.constructMPPBuildTaskReqForPartitionedTable(ts, splitedRanges, partitions) } else { - req, err = e.constructMPPBuildTaskForNonPartitionTable(ts, splitedRanges) + req, err = e.constructMPPBuildTaskForNonPartitionTable(ts.Table.ID, ts.Table.IsCommonHandle, splitedRanges) } if err != nil { return nil, errors.Trace(err) @@ -378,14 +410,22 @@ func (e *mppTaskGenerator) constructMPPTasksImpl(ctx context.Context, ts *Physic logutil.BgLogger().Warn("MPP store fail ttl is invalid", zap.Error(err)) ttl = 30 * time.Second } - metas, err := e.ctx.GetMPPClient().ConstructMPPTasks(ctx, req, e.ctx.GetSessionVars().MPPStoreLastFailTime, ttl) + metas, err := e.ctx.GetMPPClient().ConstructMPPTasks(ctx, req, ttl) if err != nil { return nil, errors.Trace(err) } tasks := make([]*kv.MPPTask, 0, len(metas)) for _, meta := range metas { - task := &kv.MPPTask{Meta: meta, ID: e.ctx.GetSessionVars().AllocMPPTaskID(e.startTS), StartTs: e.startTS, TableID: ts.Table.ID, PartitionTableIDs: allPartitionsIDs} + task := &kv.MPPTask{ + Meta: meta, + ID: AllocMPPTaskID(e.ctx), + StartTs: e.startTS, + MppQueryID: e.mppQueryID, + TableID: ts.Table.ID, + PartitionTableIDs: allPartitionsIDs, + IsDisaggregatedTiFlashStaticPrune: isDisaggregatedTiFlashStaticPrune, + } tasks = append(tasks, task) } return tasks, nil @@ -406,16 +446,16 @@ func (e *mppTaskGenerator) constructMPPBuildTaskReqForPartitionedTable(ts *Physi return nil, nil, errors.Trace(err) } partitionIDAndRanges[i].ID = pid - partitionIDAndRanges[i].KeyRanges = kvRanges + partitionIDAndRanges[i].KeyRanges = kvRanges.FirstPartitionRange() allPartitionsIDs[i] = pid } return &kv.MPPBuildTasksRequest{PartitionIDAndRanges: partitionIDAndRanges}, allPartitionsIDs, nil } -func (e *mppTaskGenerator) constructMPPBuildTaskForNonPartitionTable(ts *PhysicalTableScan, splitedRanges []*ranger.Range) (*kv.MPPBuildTasksRequest, error) { - kvRanges, err := distsql.TableHandleRangesToKVRanges(e.ctx.GetSessionVars().StmtCtx, []int64{ts.Table.ID}, ts.Table.IsCommonHandle, splitedRanges, nil) +func (e *mppTaskGenerator) constructMPPBuildTaskForNonPartitionTable(tid int64, isCommonHandle bool, splitedRanges []*ranger.Range) (*kv.MPPBuildTasksRequest, error) { + kvRanges, err := distsql.TableHandleRangesToKVRanges(e.ctx.GetSessionVars().StmtCtx, []int64{tid}, isCommonHandle, splitedRanges, nil) if err != nil { return nil, errors.Trace(err) } - return &kv.MPPBuildTasksRequest{KeyRanges: kvRanges}, nil + return &kv.MPPBuildTasksRequest{KeyRanges: kvRanges.FirstPartitionRange()}, nil } diff --git a/planner/core/hints.go b/planner/core/hints.go index f67a66b1df001..baf9f91330d20 100644 --- a/planner/core/hints.go +++ b/planner/core/hints.go @@ -35,7 +35,7 @@ func GenHintsFromFlatPlan(flat *FlatPhysicalPlan) []*ast.TableOptimizerHint { nodeTp = utilhint.TypeDelete } var hints []*ast.TableOptimizerHint - selectPlan := flat.Main.GetSelectPlan() + selectPlan, _ := flat.Main.GetSelectPlan() if len(selectPlan) == 0 || !selectPlan[0].IsPhysicalPlan { return nil } diff --git a/planner/core/indexmerge_intersection_test.go b/planner/core/indexmerge_intersection_test.go new file mode 100644 index 0000000000000..8b352f3b5cead --- /dev/null +++ b/planner/core/indexmerge_intersection_test.go @@ -0,0 +1,178 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core_test + +import ( + "regexp" + "testing" + + "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/testkit/testdata" + "github.com/stretchr/testify/require" +) + +func TestSPMForIntersectionIndexMerge(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int, c int, d int, e int, index ia(a), index ib(b), index ic(c), index id(d), index ie(e))") + require.False(t, tk.HasPlan("select * from t where a = 10 and b = 20 and c > 30 and d is null and e in (0, 100)", "IndexMerge")) + require.True(t, + tk.HasPlan("select /*+ use_index_merge(t, ia, ib, ic, id, ie) */ * from t where a = 10 and b = 20 and c > 30 and d is null and e in (0, 100)", + "IndexMerge", + ), + ) + tk.MustExec(` +create global binding for + select * from t where a = 10 and b = 20 and c > 30 and d is null and e in (0, 100) +using + select /*+ use_index_merge(t, ia, ib, ic, id, ie) */ * from t where a = 10 and b = 20 and c > 30 and d is null and e in (0, 100) +`) + require.True(t, tk.HasPlan("select * from t where a = 10 and b = 20 and c > 30 and d is null and e in (0, 100)", "IndexMerge")) +} + +func TestPlanCacheForIntersectionIndexMerge(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int, c int, d int, e int, index ia(a), index ib(b), index ic(c), index id(d), index ie(e))") + tk.MustExec("prepare stmt from 'select /*+ use_index_merge(t, ia, ib, ic, id, ie) */ * from t where a = 10 and b = ? and c > ? and d is null and e in (0, 100)'") + tk.MustExec("set @a=1, @b=3") + tk.MustQuery("execute stmt using @a,@b").Check(testkit.Rows()) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + tk.MustQuery("execute stmt using @a,@b").Check(testkit.Rows()) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustExec("set @a=100, @b=500") + tk.MustQuery("execute stmt using @a,@b").Check(testkit.Rows()) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("execute stmt using @a,@b").Check(testkit.Rows()) + require.True(t, tk.HasPlanForLastExecution("IndexMerge")) +} + +func TestHintForIntersectionIndexMerge(t *testing.T) { + store, domain := testkit.CreateMockStoreAndDomain(t) + handle := domain.StatsHandle() + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t1(a int, b int, c int, d int, e int, index ia(a), index ibc(b, c),index ic(c), index id(d), index ie(e))" + + "partition by range(c) (" + + "partition p0 values less than (10)," + + "partition p1 values less than (20)," + + "partition p2 values less than (30)," + + "partition p3 values less than (maxvalue))") + tk.MustExec("insert into t1 values (10, 20, 5, 5, 3), (20, 20, 50, 5, 200), (20, 20, 10, 5, 5), (10, 30, 5, 3, 1)") + tk.MustExec("create definer='root'@'localhost' view vh as " + + "select /*+ use_index_merge(t1, ia, ibc, id) */ * from t1 where a = 10 and b = 20 and c < 30 and d in (2,5)") + tk.MustExec("create definer='root'@'localhost' view v as " + + "select * from t1 where a = 10 and b = 20 and c < 30 and d in (2,5)") + tk.MustExec("create definer='root'@'localhost' view v1 as " + + "select * from t1 where a = 10 and b = 20") + tk.MustExec("create table t2(a int, b int, c int, d int, e int, index ia(a), index ibc(b, c), index id(d), index ie(e))" + + "partition by range columns (c, d) (" + + "partition p0 values less than (10, 20)," + + "partition p1 values less than (30, 40)," + + "partition p2 values less than (50, 60)," + + "partition p3 values less than (maxvalue, maxvalue))") + tk.MustExec("insert into t2 values (10, 20, 5, 5, 3), (20, 20, 20, 5, 100), (100, 30, 5, 3, 100)") + tk.MustExec("create table t3(a int, b int, c int, d int, e int, index ia(a), index ibc(b, c), index id(d), index ie(e))" + + "partition by hash (e) partitions 5") + tk.MustExec("insert into t3 values (10, 20, 5, 5, 3), (20, 20, 20, 5, 100), (10, 30, 5, 3, 100)") + tk.MustExec("create table t4(a int, b int, c int, d int, e int, index ia(a), index ibc(b, c), index id(d), index ie(e))" + + "partition by list (d) (" + + "partition p0 values in (1,2,3,4,5)," + + "partition p1 values in (6,7,8,9,10)," + + "partition p2 values in (11,12,13,14,15)," + + "partition p3 values in (16,17,18,19,20))") + tk.MustExec("insert into t4 values (30, 20, 5, 8, 100), (20, 20, 20, 3, 2), (10, 30, 5, 3, 100)") + tk.MustExec("create table t5(" + + "s1 varchar(20) collate utf8mb4_bin," + + "s2 varchar(30) collate ascii_bin," + + "s3 varchar(50) collate utf8_unicode_ci," + + "s4 varchar(20) collate gbk_chinese_ci," + + "index is1(s1), index is2(s2), index is3(s3), index is4(s4))") + tk.MustExec("insert into t5 values ('Abc', 'zzzz', 'aa', 'ccc'), ('abc', 'zzzz', 'CCC', 'ccc')") + tk.MustExec("create table t6(" + + "s1 varchar(20) collate utf8mb4_bin," + + "s2 varchar(30) collate ascii_bin," + + "s3 varchar(50) collate utf8_unicode_ci," + + "s4 varchar(20) collate gbk_chinese_ci," + + "primary key (s1, s2(10)) nonclustered," + + "index is1(s1), index is2(s2), index is3(s3), index is4(s4))") + tk.MustExec("insert into t6 values ('Abc', 'zzzz', 'A啊A', 'Cdaa'), ('Abc', 'zczz', 'A啊', 'Cda')") + tk.MustExec("create table t7(" + + "a tinyint unsigned," + + "b bit(3)," + + "c float," + + "d decimal(10,3)," + + "e datetime," + + "f timestamp(5)," + + "g year," + + "primary key (d) nonclustered," + + "index ia(a), unique index ib(b), index ic(c), index ie(e), index iff(f), index ig(g))") + tk.MustExec("insert into t7 values (100, 6, 12.2, 56, '2022-11-22 17:00', '2022-12-21 00:00', 2021)," + + "(20, 7, 12.4, 30, '2022-12-22 17:00', '2016-12-21 00:00', 2021)") + tk.MustExec("create table t8(" + + "s1 mediumtext collate utf8mb4_general_ci," + + "s2 varbinary(20)," + + "s3 tinyblob," + + "s4 enum('测试', 'aA', '??') collate gbk_chinese_ci," + + "s5 set('^^^', 'tEsT', '2') collate utf8_general_ci," + + "primary key (s1(10)) nonclustered," + + "unique index is2(s2(20)), index is3(s3(20)), index is4(s4), index is5(s5))") + tk.MustExec("insert into t8 values('啊aabbccdd', 'abcc', 'cccc', 'aa', '2,test')," + + "('啊aabb', 'abcdc', 'aaaa', '??', '2')") + + require.NoError(t, handle.HandleDDLEvent(<-handle.DDLEventCh())) + require.Nil(t, handle.Update(domain.InfoSchema())) + tk.MustExec("set @@tidb_partition_prune_mode = 'dynamic'") + tk.MustExec("analyze table t1,t2,t3,t4") + require.Nil(t, handle.Update(domain.InfoSchema())) + + var ( + input []string + output []struct { + SQL string + Plan []string + Result []string + } + ) + planSuiteData := core.GetIndexMergeSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + + matchSetStmt, err := regexp.Compile("^set") + require.NoError(t, err) + for i, ts := range input { + testdata.OnRecord(func() { + output[i].SQL = ts + }) + ok := matchSetStmt.MatchString(ts) + if ok { + tk.MustExec(ts) + continue + } + testdata.OnRecord(func() { + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + ts).Rows()) + output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(ts).Sort().Rows()) + }) + tk.MustQuery("explain format = 'brief' " + ts).Check(testkit.Rows(output[i].Plan...)) + tk.MustQuery(ts).Sort().Check(testkit.Rows(output[i].Result...)) + // Expect no warnings. + tk.MustQuery("show warnings").Check(testkit.Rows()) + } +} diff --git a/planner/core/indexmerge_path.go b/planner/core/indexmerge_path.go new file mode 100644 index 0000000000000..8a71e5d5d4f5a --- /dev/null +++ b/planner/core/indexmerge_path.go @@ -0,0 +1,905 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "fmt" + "math" + "strings" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/charset" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/planner/util" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/ranger" + "go.uber.org/zap" +) + +// generateIndexMergePath generates IndexMerge AccessPaths on this DataSource. +func (ds *DataSource) generateIndexMergePath() error { + // Consider the IndexMergePath. Now, we just generate `IndexMergePath` in DNF case. + // Use allConds instread of pushedDownConds, + // because we want to use IndexMerge even if some expr cannot be pushed to TiKV. + // We will create new Selection for exprs that cannot be pushed in convertToIndexMergeScan. + indexMergeConds := make([]expression.Expression, 0, len(ds.allConds)) + for _, expr := range ds.allConds { + indexMergeConds = append(indexMergeConds, expression.PushDownNot(ds.ctx, expr)) + } + + stmtCtx := ds.ctx.GetSessionVars().StmtCtx + isPossibleIdxMerge := len(indexMergeConds) > 0 && // have corresponding access conditions, and + (len(ds.possibleAccessPaths) > 1 || // (have multiple index paths, or + (len(ds.possibleAccessPaths) == 1 && isMVIndexPath(ds.possibleAccessPaths[0]))) // have a MVIndex) + sessionAndStmtPermission := (ds.ctx.GetSessionVars().GetEnableIndexMerge() || len(ds.indexMergeHints) > 0) && !stmtCtx.NoIndexMergeHint + // We current do not consider `IndexMergePath`: + // 1. If there is an index path. + // 2. TODO: If there exists exprs that cannot be pushed down. This is to avoid wrongly estRow of Selection added by rule_predicate_push_down. + needConsiderIndexMerge := true + if len(ds.indexMergeHints) == 0 { + for i := 1; i < len(ds.possibleAccessPaths); i++ { + if len(ds.possibleAccessPaths[i].AccessConds) != 0 { + needConsiderIndexMerge = false + break + } + } + if needConsiderIndexMerge { + // PushDownExprs() will append extra warnings, which is annoying. So we reset warnings here. + warnings := stmtCtx.GetWarnings() + extraWarnings := stmtCtx.GetExtraWarnings() + _, remaining := expression.PushDownExprs(stmtCtx, indexMergeConds, ds.ctx.GetClient(), kv.UnSpecified) + stmtCtx.SetWarnings(warnings) + stmtCtx.SetExtraWarnings(extraWarnings) + + remainingExpr := 0 + for _, expr := range remaining { + // Handle these 3 functions specially since they can be used to access MVIndex. + if sf, ok := expr.(*expression.ScalarFunction); ok { + if sf.FuncName.L == ast.JSONMemberOf || sf.FuncName.L == ast.JSONOverlaps || + sf.FuncName.L == ast.JSONContains { + continue + } + } + remainingExpr++ + } + if remainingExpr > 0 { + needConsiderIndexMerge = false + } + } + } + + if isPossibleIdxMerge && sessionAndStmtPermission && needConsiderIndexMerge && ds.tableInfo.TempTableType != model.TempTableLocal { + err := ds.generateAndPruneIndexMergePath(indexMergeConds, ds.indexMergeHints != nil) + if err != nil { + return err + } + } else if len(ds.indexMergeHints) > 0 { + ds.indexMergeHints = nil + var msg string + if !isPossibleIdxMerge { + msg = "No available filter or available index." + } else if !sessionAndStmtPermission { + msg = "Got no_index_merge hint or tidb_enable_index_merge is off." + } else if ds.tableInfo.TempTableType == model.TempTableLocal { + msg = "Cannot use IndexMerge on temporary table." + } + msg = fmt.Sprintf("IndexMerge is inapplicable or disabled. %s", msg) + stmtCtx.AppendWarning(errors.Errorf(msg)) + logutil.BgLogger().Debug(msg) + } + + return nil +} + +// getIndexMergeOrPath generates all possible IndexMergeOrPaths. +func (ds *DataSource) generateIndexMergeOrPaths(filters []expression.Expression) error { + usedIndexCount := len(ds.possibleAccessPaths) + for i, cond := range filters { + sf, ok := cond.(*expression.ScalarFunction) + if !ok || sf.FuncName.L != ast.LogicOr { + continue + } + var partialPaths = make([]*util.AccessPath, 0, usedIndexCount) + dnfItems := expression.FlattenDNFConditions(sf) + for _, item := range dnfItems { + cnfItems := expression.SplitCNFItems(item) + itemPaths := ds.accessPathsForConds(cnfItems, usedIndexCount) + if len(itemPaths) == 0 { + partialPaths = nil + break + } + partialPath, err := ds.buildIndexMergePartialPath(itemPaths) + if err != nil { + return err + } + if partialPath == nil { + partialPaths = nil + break + } + partialPaths = append(partialPaths, partialPath) + } + // If all of the partialPaths use the same index, we will not use the indexMerge. + singlePath := true + for i := len(partialPaths) - 1; i >= 1; i-- { + if partialPaths[i].Index != partialPaths[i-1].Index { + singlePath = false + break + } + } + if singlePath { + continue + } + if len(partialPaths) > 1 { + possiblePath := ds.buildIndexMergeOrPath(filters, partialPaths, i) + if possiblePath == nil { + return nil + } + + accessConds := make([]expression.Expression, 0, len(partialPaths)) + for _, p := range partialPaths { + indexCondsForP := p.AccessConds[:] + indexCondsForP = append(indexCondsForP, p.IndexFilters...) + if len(indexCondsForP) > 0 { + accessConds = append(accessConds, expression.ComposeCNFCondition(ds.ctx, indexCondsForP...)) + } + } + accessDNF := expression.ComposeDNFCondition(ds.ctx, accessConds...) + sel, _, err := ds.tableStats.HistColl.Selectivity(ds.ctx, []expression.Expression{accessDNF}, nil) + if err != nil { + logutil.BgLogger().Debug("something wrong happened, use the default selectivity", zap.Error(err)) + sel = SelectionFactor + } + possiblePath.CountAfterAccess = sel * ds.tableStats.RowCount + ds.possibleAccessPaths = append(ds.possibleAccessPaths, possiblePath) + } + } + return nil +} + +// isInIndexMergeHints returns true if the input index name is not excluded by the IndexMerge hints, which means either +// (1) there's no IndexMerge hint, (2) there's IndexMerge hint but no specified index names, or (3) the input index +// name is specified in the IndexMerge hints. +func (ds *DataSource) isInIndexMergeHints(name string) bool { + if len(ds.indexMergeHints) == 0 { + return true + } + for _, hint := range ds.indexMergeHints { + if hint.indexHint == nil || len(hint.indexHint.IndexNames) == 0 { + return true + } + for _, hintName := range hint.indexHint.IndexNames { + if strings.EqualFold(strings.ToLower(name), strings.ToLower(hintName.String())) { + return true + } + } + } + return false +} + +// indexMergeHintsHasSpecifiedIdx returns true if there's IndexMerge hint, and it has specified index names. +func (ds *DataSource) indexMergeHintsHasSpecifiedIdx() bool { + for _, hint := range ds.indexMergeHints { + if hint.indexHint == nil || len(hint.indexHint.IndexNames) == 0 { + continue + } + if len(hint.indexHint.IndexNames) > 0 { + return true + } + } + return false +} + +// indexMergeHintsHasSpecifiedIdx return true if the input index name is specified in the IndexMerge hint. +func (ds *DataSource) isSpecifiedInIndexMergeHints(name string) bool { + for _, hint := range ds.indexMergeHints { + if hint.indexHint == nil || len(hint.indexHint.IndexNames) == 0 { + continue + } + for _, hintName := range hint.indexHint.IndexNames { + if strings.EqualFold(strings.ToLower(name), strings.ToLower(hintName.String())) { + return true + } + } + } + return false +} + +// accessPathsForConds generates all possible index paths for conditions. +func (ds *DataSource) accessPathsForConds(conditions []expression.Expression, usedIndexCount int) []*util.AccessPath { + var results = make([]*util.AccessPath, 0, usedIndexCount) + for i := 0; i < usedIndexCount; i++ { + path := &util.AccessPath{} + if ds.possibleAccessPaths[i].IsTablePath() { + if !ds.isInIndexMergeHints("primary") { + continue + } + if ds.tableInfo.IsCommonHandle { + path.IsCommonHandlePath = true + path.Index = ds.possibleAccessPaths[i].Index + } else { + path.IsIntHandlePath = true + } + err := ds.deriveTablePathStats(path, conditions, true) + if err != nil { + logutil.BgLogger().Debug("can not derive statistics of a path", zap.Error(err)) + continue + } + var unsignedIntHandle bool + if path.IsIntHandlePath && ds.tableInfo.PKIsHandle { + if pkColInfo := ds.tableInfo.GetPkColInfo(); pkColInfo != nil { + unsignedIntHandle = mysql.HasUnsignedFlag(pkColInfo.GetFlag()) + } + } + // If the path contains a full range, ignore it. + if ranger.HasFullRange(path.Ranges, unsignedIntHandle) { + continue + } + // If we have point or empty range, just remove other possible paths. + if len(path.Ranges) == 0 || path.OnlyPointRange(ds.SCtx()) { + if len(results) == 0 { + results = append(results, path) + } else { + results[0] = path + results = results[:1] + } + break + } + } else { + path.Index = ds.possibleAccessPaths[i].Index + if !ds.isInIndexMergeHints(path.Index.Name.L) { + continue + } + err := ds.fillIndexPath(path, conditions) + if err != nil { + logutil.BgLogger().Debug("can not derive statistics of a path", zap.Error(err)) + continue + } + ds.deriveIndexPathStats(path, conditions, true) + // If the path contains a full range, ignore it. + if ranger.HasFullRange(path.Ranges, false) { + continue + } + // If we have empty range, or point range on unique index, just remove other possible paths. + if len(path.Ranges) == 0 || (path.OnlyPointRange(ds.SCtx()) && path.Index.Unique) { + if len(results) == 0 { + results = append(results, path) + } else { + results[0] = path + results = results[:1] + } + break + } + } + results = append(results, path) + } + return results +} + +// buildIndexMergePartialPath chooses the best index path from all possible paths. +// Now we choose the index with minimal estimate row count. +func (ds *DataSource) buildIndexMergePartialPath(indexAccessPaths []*util.AccessPath) (*util.AccessPath, error) { + if len(indexAccessPaths) == 1 { + return indexAccessPaths[0], nil + } + + minEstRowIndex := 0 + minEstRow := math.MaxFloat64 + for i := 0; i < len(indexAccessPaths); i++ { + rc := indexAccessPaths[i].CountAfterAccess + if len(indexAccessPaths[i].IndexFilters) > 0 { + rc = indexAccessPaths[i].CountAfterIndex + } + if rc < minEstRow { + minEstRowIndex = i + minEstRow = rc + } + } + return indexAccessPaths[minEstRowIndex], nil +} + +// buildIndexMergeOrPath generates one possible IndexMergePath. +func (ds *DataSource) buildIndexMergeOrPath(filters []expression.Expression, partialPaths []*util.AccessPath, current int) *util.AccessPath { + indexMergePath := &util.AccessPath{PartialIndexPaths: partialPaths} + indexMergePath.TableFilters = append(indexMergePath.TableFilters, filters[:current]...) + indexMergePath.TableFilters = append(indexMergePath.TableFilters, filters[current+1:]...) + var addCurrentFilter bool + for _, path := range partialPaths { + // If any partial path contains table filters, we need to keep the whole DNF filter in the Selection. + if len(path.TableFilters) > 0 { + addCurrentFilter = true + } + // If any partial path's index filter cannot be pushed to TiKV, we should keep the whole DNF filter. + if len(path.IndexFilters) != 0 && !expression.CanExprsPushDown(ds.ctx.GetSessionVars().StmtCtx, path.IndexFilters, ds.ctx.GetClient(), kv.TiKV) { + addCurrentFilter = true + // Clear IndexFilter, the whole filter will be put in indexMergePath.TableFilters. + path.IndexFilters = nil + } + if len(path.TableFilters) != 0 && !expression.CanExprsPushDown(ds.ctx.GetSessionVars().StmtCtx, path.TableFilters, ds.ctx.GetClient(), kv.TiKV) { + addCurrentFilter = true + path.TableFilters = nil + } + } + if addCurrentFilter { + indexMergePath.TableFilters = append(indexMergePath.TableFilters, filters[current]) + } + return indexMergePath +} + +// generateIndexMergeAndPaths generates IndexMerge paths for `AND` (a.k.a. intersection type IndexMerge) +func (ds *DataSource) generateIndexMergeAndPaths(normalPathCnt int) *util.AccessPath { + // For now, we only consider intersection type IndexMerge when the index names are specified in the hints. + if !ds.indexMergeHintsHasSpecifiedIdx() { + return nil + } + + // 1. Collect partial paths from normal paths. + var partialPaths []*util.AccessPath + for i := 0; i < normalPathCnt; i++ { + originalPath := ds.possibleAccessPaths[i] + // No need to consider table path as a partial path. + if ds.possibleAccessPaths[i].IsTablePath() { + continue + } + if !ds.isSpecifiedInIndexMergeHints(originalPath.Index.Name.L) { + continue + } + // If the path contains a full range, ignore it. + if ranger.HasFullRange(originalPath.Ranges, false) { + continue + } + newPath := originalPath.Clone() + partialPaths = append(partialPaths, newPath) + } + if len(partialPaths) < 2 { + return nil + } + + // 2. Collect filters that can't be covered by the partial paths and deduplicate them. + finalFilters := make([]expression.Expression, 0) + partialFilters := make([]expression.Expression, 0, len(partialPaths)) + hashCodeSet := make(map[string]struct{}) + for _, path := range partialPaths { + // Classify filters into coveredConds and notCoveredConds. + coveredConds := make([]expression.Expression, 0, len(path.AccessConds)+len(path.IndexFilters)) + notCoveredConds := make([]expression.Expression, 0, len(path.IndexFilters)+len(path.TableFilters)) + // AccessConds can be covered by partial path. + coveredConds = append(coveredConds, path.AccessConds...) + for i, cond := range path.IndexFilters { + // IndexFilters can be covered by partial path if it can be pushed down to TiKV. + if !expression.CanExprsPushDown(ds.ctx.GetSessionVars().StmtCtx, []expression.Expression{cond}, ds.ctx.GetClient(), kv.TiKV) { + path.IndexFilters = append(path.IndexFilters[:i], path.IndexFilters[i+1:]...) + notCoveredConds = append(notCoveredConds, cond) + } else { + coveredConds = append(coveredConds, cond) + } + } + // TableFilters can't be covered by partial path. + notCoveredConds = append(notCoveredConds, path.TableFilters...) + + // Record covered filters in hashCodeSet. + // Note that we only record filters that not appear in the notCoveredConds. It's possible that a filter appear + // in both coveredConds and notCoveredConds (e.g. because of prefix index). So we need this extra check to + // avoid wrong deduplication. + notCoveredHashCodeSet := make(map[string]struct{}) + for _, cond := range notCoveredConds { + hashCode := string(cond.HashCode(ds.ctx.GetSessionVars().StmtCtx)) + notCoveredHashCodeSet[hashCode] = struct{}{} + } + for _, cond := range coveredConds { + hashCode := string(cond.HashCode(ds.ctx.GetSessionVars().StmtCtx)) + if _, ok := notCoveredHashCodeSet[hashCode]; !ok { + hashCodeSet[hashCode] = struct{}{} + } + } + + finalFilters = append(finalFilters, notCoveredConds...) + partialFilters = append(partialFilters, coveredConds...) + } + + // Remove covered filters from finalFilters and deduplicate finalFilters. + dedupedFinalFilters := make([]expression.Expression, 0, len(finalFilters)) + for _, cond := range finalFilters { + hashCode := string(cond.HashCode(ds.ctx.GetSessionVars().StmtCtx)) + if _, ok := hashCodeSet[hashCode]; !ok { + dedupedFinalFilters = append(dedupedFinalFilters, cond) + hashCodeSet[hashCode] = struct{}{} + } + } + + // 3. Estimate the row count after partial paths. + sel, _, err := ds.tableStats.HistColl.Selectivity(ds.ctx, partialFilters, nil) + if err != nil { + logutil.BgLogger().Debug("something wrong happened, use the default selectivity", zap.Error(err)) + sel = SelectionFactor + } + + indexMergePath := &util.AccessPath{ + PartialIndexPaths: partialPaths, + IndexMergeIsIntersection: true, + TableFilters: dedupedFinalFilters, + CountAfterAccess: sel * ds.tableStats.RowCount, + } + return indexMergePath +} + +func (ds *DataSource) generateAndPruneIndexMergePath(indexMergeConds []expression.Expression, needPrune bool) error { + regularPathCount := len(ds.possibleAccessPaths) + // 1. Generate possible IndexMerge paths for `OR`. + err := ds.generateIndexMergeOrPaths(indexMergeConds) + if err != nil { + return err + } + // 2. Generate possible IndexMerge paths for `AND`. + indexMergeAndPath := ds.generateIndexMergeAndPaths(regularPathCount) + if indexMergeAndPath != nil { + ds.possibleAccessPaths = append(ds.possibleAccessPaths, indexMergeAndPath) + } + // 3. Generate possible IndexMerge paths for MVIndex. + mvIndexMergePath, err := ds.generateIndexMerge4MVIndex(regularPathCount, indexMergeConds) + if err != nil { + return err + } + if mvIndexMergePath != nil { + ds.possibleAccessPaths = append(ds.possibleAccessPaths, mvIndexMergePath...) + } + + // 4. If needed, append a warning if no IndexMerge is generated. + + // If without hints, it means that `enableIndexMerge` is true + if len(ds.indexMergeHints) == 0 { + return nil + } + // With hints and without generated IndexMerge paths + if regularPathCount == len(ds.possibleAccessPaths) { + ds.indexMergeHints = nil + ds.ctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("IndexMerge is inapplicable")) + return nil + } + + // 4. If needPrune is true, prune non-IndexMerge paths. + + // Do not need to consider the regular paths in find_best_task(). + // So we can use index merge's row count as DataSource's row count. + if needPrune { + ds.possibleAccessPaths = ds.possibleAccessPaths[regularPathCount:] + minRowCount := ds.possibleAccessPaths[0].CountAfterAccess + for _, path := range ds.possibleAccessPaths { + if minRowCount < path.CountAfterAccess { + minRowCount = path.CountAfterAccess + } + } + if ds.stats.RowCount > minRowCount { + ds.stats = ds.tableStats.ScaleByExpectCnt(minRowCount) + } + } + return nil +} + +// generateIndexMergeOnDNF4MVIndex generates IndexMerge paths for MVIndex upon DNF filters. +/* + select * from t where ((1 member of (a) and b=1) or (2 member of (a) and b=2)) and (c > 10) + IndexMerge(OR) + IndexRangeScan(a, b, [1 1, 1 1]) + IndexRangeScan(a, b, [2 2, 2 2]) + Selection(c > 10) + TableRowIdScan(t) + Two limitations now: + 1). all filters in the DNF have to be used as access-filters: ((1 member of (a)) or (2 member of (a)) or b > 10) cannot be used to access the MVIndex. + 2). cannot support json_contains: (json_contains(a, '[1, 2]') or json_contains(a, '[3, 4]')) is not supported since a single IndexMerge cannot represent this SQL. +*/ +func (ds *DataSource) generateIndexMergeOnDNF4MVIndex(normalPathCnt int, filters []expression.Expression) (mvIndexPaths []*util.AccessPath, err error) { + for idx := 0; idx < normalPathCnt; idx++ { + if !isMVIndexPath(ds.possibleAccessPaths[idx]) { + continue // not a MVIndex path + } + + idxCols, ok := ds.prepareCols4MVIndex(ds.possibleAccessPaths[idx].Index) + if !ok { + continue + } + + for current, filter := range filters { + sf, ok := filter.(*expression.ScalarFunction) + if !ok || sf.FuncName.L != ast.LogicOr { + continue + } + dnfFilters := expression.FlattenDNFConditions(sf) // [(1 member of (a) and b=1), (2 member of (a) and b=2)] + + // build partial paths for each dnf filter + cannotFit := false + var partialPaths []*util.AccessPath + for _, dnfFilter := range dnfFilters { + mvIndexFilters := []expression.Expression{dnfFilter} + if sf, ok := dnfFilter.(*expression.ScalarFunction); ok && sf.FuncName.L == ast.LogicAnd { + mvIndexFilters = expression.FlattenCNFConditions(sf) // (1 member of (a) and b=1) --> [(1 member of (a)), b=1] + } + + accessFilters, remainingFilters := ds.collectFilters4MVIndex(mvIndexFilters, idxCols) + if len(accessFilters) == 0 || len(remainingFilters) > 0 { // limitation 1 + cannotFit = true + break + } + paths, isIntersection, ok, err := ds.buildPartialPaths4MVIndex(accessFilters, idxCols, ds.possibleAccessPaths[idx].Index) + if err != nil { + return nil, err + } + if isIntersection || !ok { // limitation 2 + cannotFit = true + break + } + partialPaths = append(partialPaths, paths...) + } + if cannotFit { + continue + } + + var remainingFilters []expression.Expression + remainingFilters = append(remainingFilters, filters[:current]...) + remainingFilters = append(remainingFilters, filters[current+1:]...) + + indexMergePath := ds.buildPartialPathUp4MVIndex(partialPaths, false, remainingFilters) + mvIndexPaths = append(mvIndexPaths, indexMergePath) + } + } + return +} + +// generateIndexMergeJSONMVIndexPath generates paths for (json_member_of / json_overlaps / json_contains) on multi-valued index. +/* + 1. select * from t where 1 member of (a) + IndexMerge(AND) + IndexRangeScan(a, [1,1]) + TableRowIdScan(t) + 2. select * from t where json_contains(a, '[1, 2, 3]') + IndexMerge(AND) + IndexRangeScan(a, [1,1]) + IndexRangeScan(a, [2,2]) + IndexRangeScan(a, [3,3]) + TableRowIdScan(t) + 3. select * from t where json_overlap(a, '[1, 2, 3]') + IndexMerge(OR) + IndexRangeScan(a, [1,1]) + IndexRangeScan(a, [2,2]) + IndexRangeScan(a, [3,3]) + TableRowIdScan(t) +*/ +func (ds *DataSource) generateIndexMerge4MVIndex(normalPathCnt int, filters []expression.Expression) (mvIndexPaths []*util.AccessPath, err error) { + dnfMVIndexPaths, err := ds.generateIndexMergeOnDNF4MVIndex(normalPathCnt, filters) + if err != nil { + return nil, err + } + mvIndexPaths = append(mvIndexPaths, dnfMVIndexPaths...) + + for idx := 0; idx < normalPathCnt; idx++ { + if !isMVIndexPath(ds.possibleAccessPaths[idx]) { + continue // not a MVIndex path + } + + idxCols, ok := ds.prepareCols4MVIndex(ds.possibleAccessPaths[idx].Index) + if !ok { + continue + } + + accessFilters, remainingFilters := ds.collectFilters4MVIndex(filters, idxCols) + if len(accessFilters) == 0 { // cannot use any filter on this MVIndex + continue + } + + partialPaths, isIntersection, ok, err := ds.buildPartialPaths4MVIndex(accessFilters, idxCols, ds.possibleAccessPaths[idx].Index) + if err != nil { + return nil, err + } + if !ok { + continue + } + + mvIndexPaths = append(mvIndexPaths, ds.buildPartialPathUp4MVIndex(partialPaths, isIntersection, remainingFilters)) + } + return +} + +// buildPartialPathUp4MVIndex builds these partial paths up to a complete index merge path. +func (ds *DataSource) buildPartialPathUp4MVIndex(partialPaths []*util.AccessPath, isIntersection bool, remainingFilters []expression.Expression) *util.AccessPath { + indexMergePath := &util.AccessPath{PartialIndexPaths: partialPaths, IndexMergeAccessMVIndex: true} + indexMergePath.IndexMergeIsIntersection = isIntersection + indexMergePath.TableFilters = remainingFilters + + // TODO: use a naive estimation strategy here now for simplicity, make it more accurate. + minEstRows, maxEstRows := math.MaxFloat64, -1.0 + for _, p := range indexMergePath.PartialIndexPaths { + minEstRows = math.Min(minEstRows, p.CountAfterAccess) + maxEstRows = math.Max(maxEstRows, p.CountAfterAccess) + } + if indexMergePath.IndexMergeIsIntersection { + indexMergePath.CountAfterAccess = minEstRows + } else { + indexMergePath.CountAfterAccess = maxEstRows + } + return indexMergePath +} + +// buildPartialPaths4MVIndex builds partial paths by using these accessFilters upon this MVIndex. +// The accessFilters must be corresponding to these idxCols. +// OK indicates whether it builds successfully. These partial paths should be ignored if ok==false. +func (ds *DataSource) buildPartialPaths4MVIndex(accessFilters []expression.Expression, + idxCols []*expression.Column, mvIndex *model.IndexInfo) ( + partialPaths []*util.AccessPath, isIntersection bool, ok bool, err error) { + var virColID = -1 + for i := range idxCols { + if idxCols[i].VirtualExpr != nil { + virColID = i + break + } + } + if virColID == -1 { // unexpected, no vir-col on this MVIndex + return nil, false, false, nil + } + if len(accessFilters) <= virColID { // no filter related to the vir-col, build a partial path directly. + partialPath, ok, err := ds.buildPartialPath4MVIndex(accessFilters, idxCols, mvIndex) + return []*util.AccessPath{partialPath}, false, ok, err + } + + virCol := idxCols[virColID] + jsonType := virCol.GetType().ArrayType() + targetJSONPath, ok := unwrapJSONCast(virCol.VirtualExpr) + if !ok { + return nil, false, false, nil + } + + // extract values related to this vir-col, for example, extract [1, 2] from `json_contains(j, '[1, 2]')` + var virColVals []expression.Expression + sf, ok := accessFilters[virColID].(*expression.ScalarFunction) + if !ok { + return nil, false, false, nil + } + switch sf.FuncName.L { + case ast.JSONMemberOf: // (1 member of a->'$.zip') + v, ok := unwrapJSONCast(sf.GetArgs()[0]) // cast(1 as json) --> 1 + if !ok { + return nil, false, false, nil + } + virColVals = append(virColVals, v) + case ast.JSONContains: // (json_contains(a->'$.zip', '[1, 2, 3]') + isIntersection = true + virColVals, ok = jsonArrayExpr2Exprs(ds.ctx, sf.GetArgs()[1], jsonType) + if !ok { + return nil, false, false, nil + } + case ast.JSONOverlaps: // (json_overlaps(a->'$.zip', '[1, 2, 3]') + var jsonPathIdx int + if sf.GetArgs()[0].Equal(ds.ctx, targetJSONPath) { + jsonPathIdx = 0 // (json_overlaps(a->'$.zip', '[1, 2, 3]') + } else if sf.GetArgs()[1].Equal(ds.ctx, targetJSONPath) { + jsonPathIdx = 1 // (json_overlaps('[1, 2, 3]', a->'$.zip') + } else { + return nil, false, false, nil + } + var ok bool + virColVals, ok = jsonArrayExpr2Exprs(ds.ctx, sf.GetArgs()[1-jsonPathIdx], jsonType) + if !ok { + return nil, false, false, nil + } + default: + return nil, false, false, nil + } + + for _, v := range virColVals { + // rewrite json functions to EQ to calculate range, `(1 member of j)` -> `j=1`. + eq, err := expression.NewFunction(ds.ctx, ast.EQ, types.NewFieldType(mysql.TypeTiny), virCol, v) + if err != nil { + return nil, false, false, err + } + accessFilters[virColID] = eq + + partialPath, ok, err := ds.buildPartialPath4MVIndex(accessFilters, idxCols, mvIndex) + if !ok || err != nil { + return nil, false, ok, err + } + partialPaths = append(partialPaths, partialPath) + } + return partialPaths, isIntersection, true, nil +} + +// buildPartialPath4MVIndex builds a partial path on this MVIndex with these accessFilters. +func (ds *DataSource) buildPartialPath4MVIndex(accessFilters []expression.Expression, idxCols []*expression.Column, mvIndex *model.IndexInfo) (*util.AccessPath, bool, error) { + partialPath := &util.AccessPath{Index: mvIndex} + partialPath.Ranges = ranger.FullRange() + for i := 0; i < len(idxCols); i++ { + partialPath.IdxCols = append(partialPath.IdxCols, idxCols[i]) + partialPath.IdxColLens = append(partialPath.IdxColLens, mvIndex.Columns[i].Length) + partialPath.FullIdxCols = append(partialPath.FullIdxCols, idxCols[i]) + partialPath.FullIdxColLens = append(partialPath.FullIdxColLens, mvIndex.Columns[i].Length) + } + if err := ds.detachCondAndBuildRangeForPath(partialPath, accessFilters); err != nil { + return nil, false, err + } + if len(partialPath.AccessConds) != len(accessFilters) || len(partialPath.TableFilters) > 0 { + // not all filters are used in this case. + return nil, false, nil + } + return partialPath, true, nil +} + +func (ds *DataSource) prepareCols4MVIndex(mvIndex *model.IndexInfo) (idxCols []*expression.Column, ok bool) { + var virColNum = 0 + for i := range mvIndex.Columns { + colOffset := mvIndex.Columns[i].Offset + colMeta := ds.table.Meta().Cols()[colOffset] + var col *expression.Column + for _, c := range ds.TblCols { + if c.ID == colMeta.ID { + col = c + break + } + } + if col == nil { // unexpected, no vir-col on this MVIndex + return nil, false + } + if col.GetType().IsArray() { + virColNum++ + col = col.Clone().(*expression.Column) + col.RetType = col.GetType().ArrayType() // use the underlying type directly: JSON-ARRAY(INT) --> INT + col.RetType.SetCharset(charset.CharsetBin) + col.RetType.SetCollate(charset.CollationBin) + } + idxCols = append(idxCols, col) + } + if virColNum != 1 { // assume only one vir-col in the MVIndex + return nil, false + } + return idxCols, true +} + +// collectFilters4MVIndex splits these filters into 2 parts where accessFilters can be used to access this index directly. +// For idx(x, cast(a as array), z), `x=1 and (2 member of a) and z=1 and x+z>0` is splitted to: +// accessFilters: `x=1 and (2 member of a) and z=1`, remaining: `x+z>0`. +func (ds *DataSource) collectFilters4MVIndex(filters []expression.Expression, idxCols []*expression.Column) (accessFilters, remainingFilters []expression.Expression) { + usedAsAccess := make([]bool, len(filters)) + for _, col := range idxCols { + found := false + for i, f := range filters { + if usedAsAccess[i] { + continue + } + if ds.checkFilter4MVIndexColumn(f, col) { + accessFilters = append(accessFilters, f) + usedAsAccess[i] = true + found = true + break + } + } + if !found { + break + } + } + for i := range usedAsAccess { + if !usedAsAccess[i] { + remainingFilters = append(remainingFilters, filters[i]) + } + } + return accessFilters, remainingFilters +} + +// checkFilter4MVIndexColumn checks whether this filter can be used as an accessFilter to access the MVIndex column. +func (ds *DataSource) checkFilter4MVIndexColumn(filter expression.Expression, idxCol *expression.Column) bool { + sf, ok := filter.(*expression.ScalarFunction) + if !ok { + return false + } + if idxCol.VirtualExpr != nil { // the virtual column on the MVIndex + targetJSONPath, ok := unwrapJSONCast(idxCol.VirtualExpr) + if !ok { + return false + } + switch sf.FuncName.L { + case ast.JSONMemberOf: // (1 member of a) + return targetJSONPath.Equal(ds.ctx, sf.GetArgs()[1]) + case ast.JSONContains: // json_contains(a, '1') + return targetJSONPath.Equal(ds.ctx, sf.GetArgs()[0]) + case ast.JSONOverlaps: // json_overlaps(a, '1') or json_overlaps('1', a) + return targetJSONPath.Equal(ds.ctx, sf.GetArgs()[0]) || + targetJSONPath.Equal(ds.ctx, sf.GetArgs()[1]) + default: + return false + } + } else { + if sf.FuncName.L != ast.EQ { // only support EQ now + return false + } + args := sf.GetArgs() + var argCol *expression.Column + var argConst *expression.Constant + if c, isCol := args[0].(*expression.Column); isCol { + if con, isCon := args[1].(*expression.Constant); isCon { + argCol, argConst = c, con + } + } else if c, isCol := args[1].(*expression.Column); isCol { + if con, isCon := args[0].(*expression.Constant); isCon { + argCol, argConst = c, con + } + } + if argCol == nil || argConst == nil { + return false + } + if argCol.Equal(ds.ctx, idxCol) { + return true + } + } + return false +} + +// jsonArrayExpr2Exprs converts a JsonArray expression to expression list: cast('[1, 2, 3]' as JSON) --> []expr{1, 2, 3} +func jsonArrayExpr2Exprs(sctx sessionctx.Context, jsonArrayExpr expression.Expression, targetType *types.FieldType) ([]expression.Expression, bool) { + if !expression.IsInmutableExpr(jsonArrayExpr) || jsonArrayExpr.GetType().EvalType() != types.ETJson { + return nil, false + } + + jsonArray, isNull, err := jsonArrayExpr.EvalJSON(sctx, chunk.Row{}) + if isNull || err != nil { + return nil, false + } + if jsonArray.TypeCode != types.JSONTypeCodeArray { + single, ok := jsonValue2Expr(jsonArray, targetType) // '1' -> []expr{1} + if ok { + return []expression.Expression{single}, true + } + return nil, false + } + var exprs []expression.Expression + for i := 0; i < jsonArray.GetElemCount(); i++ { // '[1, 2, 3]' -> []expr{1, 2, 3} + expr, ok := jsonValue2Expr(jsonArray.ArrayGetElem(i), targetType) + if !ok { + return nil, false + } + exprs = append(exprs, expr) + } + return exprs, true +} + +func jsonValue2Expr(v types.BinaryJSON, targetType *types.FieldType) (expression.Expression, bool) { + datum, err := expression.ConvertJSON2Tp(v, targetType) + if err != nil { + return nil, false + } + return &expression.Constant{ + Value: types.NewDatum(datum), + RetType: targetType, + }, true +} + +func unwrapJSONCast(expr expression.Expression) (expression.Expression, bool) { + if expr == nil { + return nil, false + } + sf, ok := expr.(*expression.ScalarFunction) + if !ok { + return nil, false + } + if sf == nil || sf.FuncName.L != ast.Cast || sf.GetType().EvalType() != types.ETJson { + return nil, false + } + return sf.GetArgs()[0], true +} + +func isMVIndexPath(path *util.AccessPath) bool { + return !path.IsTablePath() && path.Index != nil && path.Index.MVIndex +} diff --git a/planner/core/indexmerge_path_test.go b/planner/core/indexmerge_path_test.go new file mode 100644 index 0000000000000..1119cfb5c666e --- /dev/null +++ b/planner/core/indexmerge_path_test.go @@ -0,0 +1,151 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core_test + +import ( + "testing" + + "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/testkit/testdata" +) + +func TestIndexMergeJSONMemberOf(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t( +a int, j0 json, j1 json, +index j0_0((cast(j0->'$.path0' as signed array))), +index j0_1((cast(j0->'$.path1' as signed array))), +index j0_string((cast(j0->'$.path_string' as char(10) array))), +index j0_date((cast(j0->'$.path_date' as date array))), +index j1((cast(j1 as signed array))))`) + + var input []string + var output []struct { + SQL string + Plan []string + } + planSuiteData := core.GetIndexMergeSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + + for i, query := range input { + testdata.OnRecord(func() { + output[i].SQL = query + }) + result := tk.MustQuery("explain format = 'brief' " + query) + testdata.OnRecord(func() { + output[i].Plan = testdata.ConvertRowsToStrings(result.Rows()) + }) + result.Check(testkit.Rows(output[i].Plan...)) + } +} + +func TestDNFOnMVIndex(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t(a int, b int, c int, j json, +index idx1((cast(j as signed array))), +index idx2(a, b, (cast(j as signed array)), c))`) + + var input []string + var output []struct { + SQL string + Plan []string + } + planSuiteData := core.GetIndexMergeSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + + for i, query := range input { + testdata.OnRecord(func() { + output[i].SQL = query + }) + result := tk.MustQuery("explain format = 'brief' " + query) + testdata.OnRecord(func() { + output[i].Plan = testdata.ConvertRowsToStrings(result.Rows()) + }) + result.Check(testkit.Rows(output[i].Plan...)) + } +} + +func TestCompositeMVIndex(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t(a int, b int , c int, j json, +index idx(a, b, (cast(j as signed array)), c), +index idx2(a, b, (cast(j->'$.str' as char(10) array)), c))`) + + var input []string + var output []struct { + SQL string + Plan []string + } + planSuiteData := core.GetIndexMergeSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + + for i, query := range input { + testdata.OnRecord(func() { + output[i].SQL = query + }) + result := tk.MustQuery("explain format = 'brief' " + query) + testdata.OnRecord(func() { + output[i].Plan = testdata.ConvertRowsToStrings(result.Rows()) + }) + result.Check(testkit.Rows(output[i].Plan...)) + } +} + +func TestMVIndexSelection(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t(a int, j json, +index i_int((cast(j->'$.int' as signed array))))`) + + var input []string + var output []struct { + SQL string + Plan []string + } + planSuiteData := core.GetIndexMergeSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + + for i, query := range input { + testdata.OnRecord(func() { + output[i].SQL = query + }) + result := tk.MustQuery("explain format = 'brief' " + query) + testdata.OnRecord(func() { + output[i].Plan = testdata.ConvertRowsToStrings(result.Rows()) + }) + result.Check(testkit.Rows(output[i].Plan...)) + } +} + +func TestMVIndexIndexMergePlanCache(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t(j json, index kj((cast(j as signed array))))`) + + tk.MustExec("prepare st from 'select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j))'") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: query accesses generated columns is un-cacheable")) + tk.MustExec("execute st") + tk.MustExec("execute st") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) +} diff --git a/planner/core/indexmerge_test.go b/planner/core/indexmerge_test.go index f109b85aaee18..8867e5a64c744 100644 --- a/planner/core/indexmerge_test.go +++ b/planner/core/indexmerge_test.go @@ -69,7 +69,7 @@ func TestIndexMergePathGeneration(t *testing.T) { for i, tc := range input { stmt, err := parser.ParseOneStmt(tc, "", "") require.NoErrorf(t, err, "case:%v sql:%s", i, tc) - err = Preprocess(sctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: is})) + err = Preprocess(context.Background(), sctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: is})) require.NoError(t, err) builder, _ := NewPlanBuilder().Init(MockContext(), is, &hint.BlockHintProcessor{}) p, err := builder.Build(ctx, stmt) diff --git a/planner/core/initialize.go b/planner/core/initialize.go index bb2fc22b60546..4a096b7b49204 100644 --- a/planner/core/initialize.go +++ b/planner/core/initialize.go @@ -597,3 +597,17 @@ func (p PhysicalCTETable) Init(ctx sessionctx.Context, stats *property.StatsInfo p.stats = stats return &p } + +// Init initializes FKCheck. +func (p FKCheck) Init(ctx sessionctx.Context) *FKCheck { + p.basePhysicalPlan = newBasePhysicalPlan(ctx, plancodec.TypeForeignKeyCheck, &p, 0) + p.stats = &property.StatsInfo{} + return &p +} + +// Init initializes FKCascade +func (p FKCascade) Init(ctx sessionctx.Context) *FKCascade { + p.basePhysicalPlan = newBasePhysicalPlan(ctx, plancodec.TypeForeignKeyCascade, &p, 0) + p.stats = &property.StatsInfo{} + return &p +} diff --git a/planner/core/integration_partition_test.go b/planner/core/integration_partition_test.go index f3e1dc96195f1..9df4c962541ee 100644 --- a/planner/core/integration_partition_test.go +++ b/planner/core/integration_partition_test.go @@ -39,6 +39,7 @@ func TestListPartitionPushDown(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("create database list_push_down") tk.MustExec("use list_push_down") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists tlist") tk.MustExec(`set tidb_enable_list_partition = 1`) tk.MustExec(`create table tlist (a int) partition by list (a) ( @@ -1457,12 +1458,12 @@ func TestRangeColumnsExpr(t *testing.T) { "TableReader 1.14 root partition:p5,p12 data:Selection", "└─Selection 1.14 cop[tikv] in(rce.t.a, 4, 14), in(rce.t.b, NULL, 10)", " └─TableFullScan 21.00 cop[tikv] table:t keep order:false")) - tk.MustQuery(`select * from tref where a in (4,14) and b in (null,10)`).Check(testkit.Rows( - "4 10 3", - "14 10 4")) - tk.MustQuery(`select * from t where a in (4,14) and b in (null,10)`).Check(testkit.Rows( - "4 10 3", - "14 10 4")) + tk.MustQuery(`select * from tref where a in (4,14) and b in (null,10)`).Sort().Check(testkit.Rows( + "14 10 4", + "4 10 3")) + tk.MustQuery(`select * from t where a in (4,14) and b in (null,10)`).Sort().Check(testkit.Rows( + "14 10 4", + "4 10 3")) tk.MustQuery(`explain format = 'brief' select * from t where a in (4,14) and (b in (11,10) OR b is null)`).Check(testkit.Rows( "TableReader 3.43 root partition:p1,p5,p6,p11,p12 data:Selection", "└─Selection 3.43 cop[tikv] in(rce.t.a, 4, 14), or(in(rce.t.b, 11, 10), isnull(rce.t.b))", @@ -1618,3 +1619,39 @@ func TestPartitionRangeColumnPruning(t *testing.T) { tk.MustQuery(`select * from t1 where a = 'a' AND c = 'd'`).Check(testkit.Rows("a d")) tk.MustExec(`drop table t1`) } + +func TestPartitionProcessorWithUninitializedTable(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(" create table q1(a int, b int, key (a)) partition by range (a) (partition p0 values less than (10), partition p1 values less than (20));") + tk.MustExec(" create table q2(a int, b int, key (a)) partition by range (a) (partition p0 values less than (10), partition p1 values less than (20));") + + rows := [][]interface{}{ + {"HashJoin"}, + {"├─PartitionUnion(Build)"}, + {"│ ├─TableReader"}, + {"│ │ └─TableFullScan"}, + {"│ └─TableReader"}, + {"│ └─TableFullScan"}, + {"└─PartitionUnion(Probe)"}, + {" ├─TableReader"}, + {" │ └─TableFullScan"}, + {" └─TableReader"}, + {" └─TableFullScan"}, + } + tk.MustQuery("explain format=brief select * from q1,q2").CheckAt([]int{0}, rows) + + tk.MustExec("analyze table q1") + tk.MustQuery("explain format=brief select * from q1,q2").CheckAt([]int{0}, rows) + + tk.MustExec("analyze table q2") + rows = [][]interface{}{ + {"HashJoin"}, + {"├─TableReader(Build)"}, + {"│ └─TableFullScan"}, + {"└─TableReader(Probe)"}, + {" └─TableFullScan"}, + } + tk.MustQuery("explain format=brief select * from q1,q2").CheckAt([]int{0}, rows) +} diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index e716561b114e1..81da36394968d 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -50,6 +50,7 @@ func TestShowSubquery(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a varchar(10), b int, c int)") tk.MustQuery("show columns from t where true").Check(testkit.Rows( @@ -68,7 +69,7 @@ func TestShowSubquery(t *testing.T) { )) tk.MustQuery("show columns from t where field in (select 'b') and false").Check(testkit.Rows()) tk.MustExec("insert into t values('c', 0, 0)") - tk.MustQuery("show columns from t where field < all (select a from t)").Check(testkit.Rows( + tk.MustQuery("show columns from t where field < all (select a from t)").Sort().Check(testkit.Rows( "a varchar(10) YES ", "b int(11) YES ", )) @@ -123,6 +124,7 @@ func TestAggPushDownLeftJoin(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists customer") tk.MustExec("create table customer (C_CUSTKEY bigint(20) NOT NULL, C_NAME varchar(25) NOT NULL, " + "C_ADDRESS varchar(25) NOT NULL, PRIMARY KEY (`C_CUSTKEY`) /*T![clustered_index] CLUSTERED */)") @@ -165,6 +167,7 @@ func TestPushLimitDownIndexLookUpReader(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@session.tidb_executor_concurrency = 4;") tk.MustExec("set @@session.tidb_hash_join_concurrency = 5;") tk.MustExec("set @@session.tidb_distsql_scan_concurrency = 15;") @@ -195,6 +198,7 @@ func TestAggColumnPrune(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int)") tk.MustExec("insert into t values(1),(2)") @@ -219,6 +223,7 @@ func TestIsFromUnixtimeNullRejective(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(a bigint, b bigint);`) var input []string @@ -376,6 +381,7 @@ func TestSimplifyOuterJoinWithCast(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int not null, b datetime default null)") @@ -449,6 +455,7 @@ func TestSelPushDownTiFlash(t *testing.T) { tk.MustExec("set @@session.tidb_isolation_read_engines = 'tiflash'") tk.MustExec("set @@session.tidb_allow_mpp = 0") + tk.MustExec("set tidb_cost_model_version=2") var input []string var output []struct { @@ -471,6 +478,7 @@ func TestVerboseExplain(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`set tidb_opt_limit_push_down_threshold=0`) tk.MustExec("drop table if exists t1, t2, t3") tk.MustExec("create table t1(a int, b int)") @@ -544,6 +552,7 @@ func TestPushDownToTiFlashWithKeepOrder(t *testing.T) { } } + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@session.tidb_isolation_read_engines = 'tiflash'") tk.MustExec("set @@session.tidb_allow_mpp = 0") var input []string @@ -585,6 +594,7 @@ func TestPushDownToTiFlashWithKeepOrderInFastMode(t *testing.T) { } } + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@session.tidb_isolation_read_engines = 'tiflash'") tk.MustExec("set @@session.tidb_allow_mpp = 0") var input []string @@ -608,6 +618,7 @@ func TestMPPJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists d1_t") tk.MustExec("create table d1_t(d1_k int, value int)") tk.MustExec("insert into d1_t values(1,2),(2,3)") @@ -713,6 +724,7 @@ func TestMPPOuterJoinBuildSideForBroadcastJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists a") tk.MustExec("create table a(id int, value int)") tk.MustExec("insert into a values(1,2),(2,3)") @@ -759,6 +771,7 @@ func TestMPPOuterJoinBuildSideForShuffleJoinWithFixedBuildSide(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists a") tk.MustExec("create table a(id int, value int)") tk.MustExec("insert into a values(1,2),(2,3)") @@ -805,6 +818,7 @@ func TestMPPOuterJoinBuildSideForShuffleJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists a") tk.MustExec("create table a(id int, value int)") tk.MustExec("insert into a values(1,2),(2,3)") @@ -851,6 +865,7 @@ func TestMPPShuffledJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists d1_t") tk.MustExec("create table d1_t(d1_k int, value int)") tk.MustExec("insert into d1_t values(1,2),(2,3)") @@ -913,6 +928,7 @@ func TestMPPJoinWithCanNotFoundColumnInSchemaColumnsError(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1") tk.MustExec("create table t1(id int, v1 decimal(20,2), v2 decimal(20,2))") tk.MustExec("create table t2(id int, v1 decimal(10,2), v2 decimal(10,2))") @@ -1194,6 +1210,7 @@ func TestAggPushDownEngine(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int primary key, b varchar(20))") @@ -1268,6 +1285,7 @@ func TestReadFromStorageHint(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, tt, ttt") tk.MustExec("set session tidb_allow_mpp=OFF") tk.MustExec("create table t(a int, b int, index ia(a))") @@ -1306,11 +1324,272 @@ func TestReadFromStorageHint(t *testing.T) { } } +func TestKeepOrderHint(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("drop table if exists t, t1, th") + tk.MustExec("drop view if exists v, v1") + tk.MustExec("create table t(a int, b int, primary key(a));") + tk.MustExec("create table t1(a int, b int, index idx_a(a));") + tk.MustExec("create table th (a int, key(a)) partition by hash(a) partitions 4;") + tk.MustExec("create definer='root'@'localhost' view v as select * from t1 where a<10 order by a limit 1;") + tk.MustExec("create definer='root'@'localhost' view v1 as select * from t where a<10 order by a limit 1;") + + // If the optimizer can not generate the keep order plan, it will report error + err := tk.ExecToErr("explain select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 limit 1;") + require.EqualError(t, err, "[planner:1815]Internal : Can't find a proper physical plan for this query") + + err = tk.ExecToErr("explain select /*+ keep_order(t, primary) */ * from t where a<10 limit 1;") + require.EqualError(t, err, "[planner:1815]Internal : Can't find a proper physical plan for this query") + + // The partition table can not keep order + tk.MustExec("analyze table th;") + err = tk.ExecToErr("select a from th where a<1 order by a limit 1;") + require.NoError(t, err) + + err = tk.ExecToErr("select /*+ keep_order(th, a) */ a from th where a<1 order by a limit 1;") + require.EqualError(t, err, "[planner:1815]Internal : Can't find a proper physical plan for this query") + + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + integrationSuiteData := core.GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + require.Equal(t, output[i].Warn, testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings())) + } +} + +func TestKeepOrderHintWithBinding(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(a int, b int, index idx_a(a));") + + // create binding for keep_order hint + tk.MustExec("select * from t1 where a<10 order by a limit 1;") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + tk.MustExec("create global binding for select * from t1 where a<10 order by a limit 1 using select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;") + tk.MustExec("select * from t1 where a<10 order by a limit 1;") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res := tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select * from `test` . `t1` where `a` < ? order by `a` limit ?") + require.Equal(t, res[0][1], "SELECT /*+ keep_order(`t1` `idx_a`)*/ * FROM `test`.`t1` WHERE `a` < 10 ORDER BY `a` LIMIT 1") + + tk.MustExec("drop global binding for select * from t1 where a<10 order by a limit 1;") + tk.MustExec("select * from t1 where a<10 order by a limit 1;") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, len(res), 0) + + // create binding for no_keep_order hint + tk.MustExec("create global binding for select * from t1 where a<10 order by a limit 1 using select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;") + tk.MustExec("select * from t1 where a<10 order by a limit 1;") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select * from `test` . `t1` where `a` < ? order by `a` limit ?") + require.Equal(t, res[0][1], "SELECT /*+ no_keep_order(`t1` `idx_a`)*/ * FROM `test`.`t1` WHERE `a` < 10 ORDER BY `a` LIMIT 1") + + tk.MustExec("drop global binding for select * from t1 where a<10 order by a limit 1;") + tk.MustExec("select * from t1 where a<10 order by a limit 1;") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, len(res), 0) +} + +func TestViewHint(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("drop view if exists v, v1, v2") + tk.MustExec("drop table if exists t, t1, t2") + tk.MustExec("create table t(a int, b int);") + tk.MustExec("create table t1(a int, b int);") + tk.MustExec("create table t2(a int, b int);") + tk.MustExec("create definer='root'@'localhost' view v as select t.a, t.b from t join (select count(*) as a from t1 join t2 on t1.b=t2.b group by t2.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v1 as select t.a, t.b from t join (select count(*) as a from t1 join v on t1.b=v.b group by v.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v2 as select t.a, t.b from t join (select count(*) as a from t1 join v1 on t1.b=v1.b group by v1.a) tt on t.a = tt.a;") + + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + integrationSuiteData := core.GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + require.Equal(t, output[i].Warn, testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings())) + } +} + +func TestViewHintScope(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("drop view if exists v, v1, v2, v3, v4") + tk.MustExec("drop table if exists t, t1, t2, t3, t4") + tk.MustExec("create table t(a int, b int);") + tk.MustExec("create table t1(a int, b int);") + tk.MustExec("create table t2(a int, b int);") + tk.MustExec("create table t3(a int, b int)") + tk.MustExec("create table t4(a int, b int, index idx_a(a), index idx_b(b))") + tk.MustExec("create definer='root'@'localhost' view v as select t.a, t.b from t join (select count(*) as a from t1 join t2 join t3 where t1.b=t2.b and t2.a = t3.a group by t2.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v1 as select t.a, t.b from t join (select count(*) as a from t1 join v on t1.b=v.b group by v.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v2 as select t.a, t.b from t join (select count(*) as a from t1 join v1 on t1.b=v1.b group by v1.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v3 as select /*+ merge_join(t) */ t.a, t.b from t join (select /*+ stream_agg() */ count(*) as a from t1 join v1 on t1.b=v1.b group by v1.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v4 as select * from t4 where a > 2 and b > 3;") + + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + integrationSuiteData := core.GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + require.Equal(t, output[i].Warn, testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings())) + } +} + +func TestViewHintWithBinding(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("drop view if exists v, v1") + tk.MustExec("drop table if exists t, t1, t2, t3") + tk.MustExec("create table t(a int, b int);") + tk.MustExec("create table t1(a int, b int);") + tk.MustExec("create table t2(a int, b int);") + tk.MustExec("create table t3(a int, b int)") + tk.MustExec("create definer='root'@'localhost' view v as select t.a, t.b from t join (select count(*) as a from t1 join t2 join t3 where t1.b=t2.b and t2.a = t3.a group by t2.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v1 as select t.a, t.b from t join (select count(*) as a from t1 join v on t1.b=v.b group by v.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v2 as select t.a, t.b from t join (select count(*) as a from t1 join v1 on t1.b=v1.b group by v1.a) tt on t.a = tt.a;") + + tk.MustExec("select * from v2") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + tk.MustExec("create global binding for select * from v2 using select /*+ qb_name(qb_v_2, v2.v1@sel_2 .v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v2. v1@sel_2 .v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v2;") + tk.MustExec("select * from v2") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res := tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select * from `test` . `v2`") + require.Equal(t, res[0][1], "SELECT /*+ qb_name(`qb_v_2` , `v2`. `v1`@`sel_2`. `v`@`sel_2`. ``@`sel_2`) merge_join(`t1`@`qb_v_2`) stream_agg(@`qb_v_2`) qb_name(`qb_v_1` , `v2`. `v1`@`sel_2`. `v`@`sel_2`. ``@`sel_1`) merge_join(`t`@`qb_v_1`)*/ * FROM `test`.`v2`") + + tk.MustExec("drop global binding for select * from v2") + tk.MustExec("select * from v2") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, len(res), 0) +} + +func TestAllViewHintType(t *testing.T) { + store := testkit.CreateMockStore(t, withMockTiFlash(2)) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("set @@session.tidb_allow_mpp=ON") + tk.MustExec("set @@session.tidb_isolation_read_engines='tiflash, tikv'") + tk.MustExec("drop view if exists v, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12") + tk.MustExec("drop table if exists t, t1, t2, t4, t3, t5") + tk.MustExec("create table t(a int not null, b int, index idx_a(a));") + tk.MustExec("create table t1(a int not null, b int, index idx_a(a));") + tk.MustExec("create table t2(a int, b int, index idx_a(a));") + tk.MustExec("create table t3(a int, b int, index idx_a(a));") + tk.MustExec("create table t4(a int, b int, index idx_a(a));") + tk.MustExec("create table t5(a int, b int, index idx_a(a), index idx_b(b));") + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Session()) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + tk.MustExec("create definer='root'@'localhost' view v as select t.a, t.b from t join t1 on t.a = t1.a;") + tk.MustExec("create definer='root'@'localhost' view v1 as select t2.a, t2.b from t2 join t3 join v where t2.b = t3.b and t3.a = v.a;") + tk.MustExec("create definer='root'@'localhost' view v2 as select t.a, t.b from t join (select count(*) as a from t1 join v1 on t1.b=v1.b group by v1.a) tt on t.a = tt.a;") + tk.MustExec("create definer='root'@'localhost' view v3 as select * from t5 where a > 1 and b < 2;") + tk.MustExec("create definer='root'@'localhost' view v4 as select * from t5 where a > 1 or b < 2;") + tk.MustExec("create definer='root'@'localhost' view v5 as SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t1 WHERE t1.b = t.b);") + tk.MustExec("create definer='root'@'localhost' view v6 as select * from t1 where t1.a < (select sum(t2.a) from t2 where t2.b = t1.b);") + tk.MustExec("create definer='root'@'localhost' view v7 as WITH CTE AS (SELECT * FROM t WHERE t.a < 60) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;") + tk.MustExec("create definer='root'@'localhost' view v8 as WITH CTE1 AS (SELECT b FROM t1), CTE2 AS (WITH CTE3 AS (SELECT a FROM t2), CTE4 AS (SELECT a FROM t3) SELECT CTE3.a FROM CTE3, CTE4) SELECT b FROM CTE1, CTE2 union select * from CTE1;") + tk.MustExec("create definer='root'@'localhost' view v9 as select sum(a) from t;") + tk.MustExec("create definer='root'@'localhost' view v10 as SELECT * FROM t WHERE a > 10 ORDER BY b LIMIT 1;") + tk.MustExec("create definer='root'@'localhost' view v11 as select a, sum(b) from t group by a") + tk.MustExec("create definer='root'@'localhost' view v12 as select t.a, t.b from t join t t1 on t.a = t1.a;") + + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + integrationSuiteData := core.GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Warn = testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + require.Equal(t, output[i].Warn, testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings())) + } +} + func TestReadFromStorageHintAndIsolationRead(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, tt, ttt") tk.MustExec("create table t(a int, b int, index ia(a))") tk.MustExec("set @@session.tidb_isolation_read_engines=\"tikv\"") @@ -1566,6 +1845,7 @@ func TestMaxMinEliminate(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int primary key)") @@ -1605,6 +1885,7 @@ func TestIndexJoinUniqueCompositeIndex(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") tk.Session().GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeIntOnly @@ -1763,6 +2044,7 @@ func TestSubqueryWithTopN(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int)") @@ -1923,6 +2205,7 @@ func TestIssue17813(t *testing.T) { func TestHintWithRequiredProperty(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@session.tidb_executor_concurrency = 4;") tk.MustExec("set @@session.tidb_hash_join_concurrency = 5;") tk.MustExec("set @@session.tidb_distsql_scan_concurrency = 15;") @@ -2126,6 +2409,7 @@ func TestIndexJoinInnerIndexNDV(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2") tk.MustExec("create table t1(a int not null, b int not null, c int not null)") tk.MustExec("create table t2(a int not null, b int not null, c int not null, index idx1(a,b), index idx2(c))") @@ -2156,7 +2440,7 @@ func TestIssue16837(t *testing.T) { tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int,b int,c int,d int,e int,unique key idx_ab(a,b),unique key(c),unique key(d))") tk.MustQuery("explain format = 'brief' select /*+ use_index_merge(t,c,idx_ab) */ * from t where a = 1 or (e = 1 and c = 1)").Check(testkit.Rows( - "IndexMerge 0.01 root ", + "IndexMerge 0.01 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx_ab(a, b) range:[1,1], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:c(c) range:[1,1], keep order:false, stats:pseudo", "└─Selection(Probe) 0.01 cop[tikv] or(eq(test.t.a, 1), and(eq(test.t.e, 1), eq(test.t.c, 1)))", @@ -2397,7 +2681,7 @@ func TestIssue16407(t *testing.T) { tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int,b char(100),key(a),key(b(10)))") tk.MustQuery("explain format = 'brief' select /*+ use_index_merge(t) */ * from t where a=10 or b='x'").Check(testkit.Rows( - "IndexMerge 0.04 root ", + "IndexMerge 0.04 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:a(a) range:[10,10], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:b(b) range:[\"x\",\"x\"], keep order:false, stats:pseudo", "└─Selection(Probe) 0.04 cop[tikv] or(eq(test.t.a, 10), eq(test.t.b, \"x\"))", @@ -2527,6 +2811,7 @@ func TestSelectLimit(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int)") tk.MustExec("insert into t values(1),(1),(2)") @@ -2551,9 +2836,9 @@ func TestSelectLimit(t *testing.T) { result = tk.MustQuery("select (select * from t limit 1) s") // limit write in subquery, has no effect. result.Check(testkit.Rows("1")) result = tk.MustQuery("select * from t where t.a in (select * from t) limit 3") // select_limit will not effect subquery - result.Check(testkit.Rows("1", "1", "2")) + result.Sort().Check(testkit.Rows("1", "1", "2")) result = tk.MustQuery("select * from (select * from t) s limit 3") // select_limit will not effect subquery - result.Check(testkit.Rows("1", "1", "2")) + result.Sort().Check(testkit.Rows("1", "1", "2")) // test for union result = tk.MustQuery("select * from t union all select * from t limit 2") // limit outside subquery @@ -2581,14 +2866,14 @@ func TestSelectLimit(t *testing.T) { result.Check(testkit.Rows("1")) tk.MustExec("set @@session.sql_select_limit=default") result = tk.MustQuery("select * from s") - result.Check(testkit.Rows("1", "1", "2")) + result.Sort().Check(testkit.Rows("1", "1", "2")) // test for DML tk.MustExec("set @@session.sql_select_limit=1") tk.MustExec("create table b (a int)") tk.MustExec("insert into b select * from t") // all values are inserted result = tk.MustQuery("select * from b limit 3") - result.Check(testkit.Rows("1", "1", "2")) + result.Sort().Check(testkit.Rows("1", "1", "2")) tk.MustExec("update b set a = 2 where a = 1") // all values are updated result = tk.MustQuery("select * from b limit 3") result.Check(testkit.Rows("2", "2", "2")) @@ -2668,6 +2953,7 @@ func TestIndexJoinOnClusteredIndex(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.Session().GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeOn tk.MustExec("drop table if exists t1") tk.MustExec("create table t (a int, b varchar(20), c decimal(40,10), d int, primary key(a,b), key(c))") @@ -2786,6 +3072,7 @@ func TestBitColumnPushDown(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec("create table t1(a bit(8), b int)") tk.MustExec("create table t2(a bit(8), b int)") tk.MustExec("insert into t1 values ('1', 1), ('2', 2), ('3', 3), ('4', 4), ('1', 1), ('2', 2), ('3', 3), ('4', 4)") @@ -3179,6 +3466,10 @@ func TestScalarFunctionPushDown(t *testing.T) { tk.MustQuery("explain analyze select /*+read_from_storage(tikv[t])*/ * from t where ascii(e);"). CheckAt([]int{0, 3, 6}, rows) + rows[1][2] = "eq(json_valid(test.t.c), 1)" + tk.MustQuery("explain analyze select /*+read_from_storage(tikv[t])*/ * from t where json_valid(c)=1;"). + CheckAt([]int{0, 3, 6}, rows) + rows[1][2] = "json_contains(cast(test.t.c, json BINARY), cast(\"1\", json BINARY))" tk.MustQuery("explain analyze select /*+read_from_storage(tikv[t])*/ * from t where json_contains(c, '1');"). CheckAt([]int{0, 3, 6}, rows) @@ -4256,6 +4547,7 @@ func TestPushDownProjectionForTiKV(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (a int, b real, i int, id int, value decimal(6,3), name char(128), d decimal(6,3), s char(128), t datetime, c bigint as ((a+1)) virtual, e real as ((b+a)))") tk.MustExec("analyze table t") @@ -4282,6 +4574,7 @@ func TestPushDownProjectionForTiFlashCoprocessor(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (a int, b real, i int, id int, value decimal(6,3), name char(128), d decimal(6,3), s char(128), t datetime, c bigint as ((a+1)) virtual, e real as ((b+a)))") tk.MustExec("analyze table t") @@ -4322,6 +4615,7 @@ func TestPushDownProjectionForTiFlash(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (id int, value decimal(6,3), name char(128))") tk.MustExec("analyze table t") @@ -4362,6 +4656,7 @@ func TestPushDownSelectionForMPP(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (id int, value decimal(6,3), name char(128))") tk.MustExec("analyze table t") @@ -4404,6 +4699,7 @@ func TestPushDownProjectionForMPP(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (id int, value decimal(6,3), name char(128))") tk.MustExec("analyze table t") @@ -4446,10 +4742,11 @@ func TestReorderSimplifiedOuterJoins(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1,t2,t3") - tk.MustExec("create table t1 (pk char(32) primary key, col1 char(32), col2 varchar(40), col3 char(32), key (col1), key (col3), key (col2,col3), key (col1,col3))") - tk.MustExec("create table t2 (pk char(32) primary key, col1 varchar(100))") - tk.MustExec("create table t3 (pk char(32) primary key, keycol varchar(100), pad1 tinyint(1) default null, pad2 varchar(40), key (keycol,pad1,pad2))") + tk.MustExec("create table t1 (pk char(32) primary key nonclustered, col1 char(32), col2 varchar(40), col3 char(32), key (col1), key (col3), key (col2,col3), key (col1,col3))") + tk.MustExec("create table t2 (pk char(32) primary key nonclustered, col1 varchar(100))") + tk.MustExec("create table t3 (pk char(32) primary key nonclustered, keycol varchar(100), pad1 tinyint(1) default null, pad2 varchar(40), key (keycol,pad1,pad2))") var input []string var output []struct { @@ -4534,6 +4831,7 @@ func TestPushDownAggForMPP(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (id int, value decimal(6,3))") tk.MustExec("analyze table t") @@ -4575,6 +4873,7 @@ func TestMppUnionAll(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("drop table if exists t1") tk.MustExec("create table t (a int not null, b int, c varchar(20))") @@ -4615,6 +4914,7 @@ func TestMppJoinDecimal(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("drop table if exists tt") tk.MustExec("create table t (c1 decimal(8, 5), c2 decimal(9, 5), c3 decimal(9, 4) NOT NULL, c4 decimal(8, 4) NOT NULL, c5 decimal(40, 20))") @@ -4657,10 +4957,115 @@ func TestMppJoinDecimal(t *testing.T) { } } +func TestMppJoinExchangeColumnPrune(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("drop table if exists tt") + tk.MustExec("create table t (c1 int, c2 int, c3 int NOT NULL, c4 int NOT NULL, c5 int)") + tk.MustExec("create table tt (b1 int)") + tk.MustExec("analyze table t") + tk.MustExec("analyze table tt") + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Session()) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" || tblInfo.Name.L == "tt" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + tk.MustExec("set @@tidb_allow_mpp=1;") + tk.MustExec("set @@session.tidb_broadcast_join_threshold_size = 1") + tk.MustExec("set @@session.tidb_broadcast_join_threshold_count = 1") + + var input []string + var output []struct { + SQL string + Plan []string + } + integrationSuiteData := core.GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + } +} + +func TestMppFineGrainedJoinAndAgg(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("drop table if exists tt") + tk.MustExec("create table t (c1 int, c2 int, c3 int NOT NULL, c4 int NOT NULL, c5 int)") + tk.MustExec("create table tt (b1 int)") + tk.MustExec("analyze table t") + tk.MustExec("analyze table tt") + + instances := []string{ + "tiflash,127.0.0.1:3933,127.0.0.1:7777,,", + "tikv,127.0.0.1:11080,127.0.0.1:10080,,", + } + fpName := "github.com/pingcap/tidb/infoschema/mockStoreServerInfo" + fpExpr := `return("` + strings.Join(instances, ";") + `")` + require.NoError(t, failpoint.Enable(fpName, fpExpr)) + defer func() { require.NoError(t, failpoint.Disable(fpName)) }() + fpName2 := "github.com/pingcap/tidb/planner/core/mockTiFlashStreamCountUsingMinLogicalCores" + require.NoError(t, failpoint.Enable(fpName2, `return("8")`)) + defer func() { require.NoError(t, failpoint.Disable(fpName2)) }() + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Session()) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" || tblInfo.Name.L == "tt" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + tk.MustExec("set @@tidb_allow_mpp=1;") + tk.MustExec("set @@session.tidb_broadcast_join_threshold_size = 1") + tk.MustExec("set @@session.tidb_broadcast_join_threshold_count = 1") + + var input []string + var output []struct { + SQL string + Plan []string + } + integrationSuiteData := core.GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + }) + res := tk.MustQuery(tt) + res.Check(testkit.Rows(output[i].Plan...)) + } +} + func TestMppAggTopNWithJoin(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (id int, value decimal(6,3))") tk.MustExec("analyze table t") @@ -4702,6 +5107,7 @@ func TestLimitIndexLookUpKeepOrder(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t;") tk.MustExec("create table t(a int, b int, c int, d int, index idx(a,b,c));") @@ -4781,7 +5187,7 @@ func TestIndexMergeTableFilter(t *testing.T) { tk.MustExec("insert into t values(10,1,1,10)") tk.MustQuery("explain format = 'brief' select /*+ use_index_merge(t) */ * from t where a=10 or (b=10 and c=10)").Check(testkit.Rows( - "IndexMerge 0.02 root ", + "IndexMerge 0.02 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:a(a) range:[10,10], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:b(b) range:[10,10], keep order:false, stats:pseudo", "└─Selection(Probe) 0.02 cop[tikv] or(eq(test.t.a, 10), and(eq(test.t.b, 10), eq(test.t.c, 10)))", @@ -4791,7 +5197,7 @@ func TestIndexMergeTableFilter(t *testing.T) { "10 1 1 10", )) tk.MustQuery("explain format = 'brief' select /*+ use_index_merge(t) */ * from t where (a=10 and d=10) or (b=10 and c=10)").Check(testkit.Rows( - "IndexMerge 0.00 root ", + "IndexMerge 0.00 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:a(a) range:[10,10], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:b(b) range:[10,10], keep order:false, stats:pseudo", "└─Selection(Probe) 0.00 cop[tikv] or(and(eq(test.t.a, 10), eq(test.t.d, 10)), and(eq(test.t.b, 10), eq(test.t.c, 10)))", @@ -4920,7 +5326,7 @@ func TestMultiColMaxOneRow(t *testing.T) { tk.MustExec("use test") tk.MustExec("drop table if exists t1,t2") tk.MustExec("create table t1(a int)") - tk.MustExec("create table t2(a int, b int, c int, primary key(a,b))") + tk.MustExec("create table t2(a int, b int, c int, primary key(a,b) nonclustered)") var input []string var output []struct { @@ -5011,6 +5417,7 @@ func TestIssue24095(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (id int, value decimal(10,5));") tk.MustExec("desc format = 'brief' select count(*) from t join (select t.id, t.value v1 from t join t t1 on t.id = t1.id order by t.value limit 1) v on v.id = t.id and v.v1 = t.value;") @@ -5140,6 +5547,7 @@ func TestSequenceAsDataSource(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop sequence if exists s1, s2") tk.MustExec("create sequence s1") tk.MustExec("create sequence s2") @@ -5440,36 +5848,36 @@ func TestIssue29221(t *testing.T) { tk.MustExec("set @@session.sql_select_limit=3;") tk.MustQuery("explain format = 'brief' select * from t where a = 1 or b = 1;").Check(testkit.Rows( "Limit 3.00 root offset:0, count:3", - "└─IndexMerge 3.00 root ", + "└─IndexMerge 3.00 root type: union", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_a(a) range:[1,1], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_b(b) range:[1,1], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t keep order:false, stats:pseudo")) tk.MustQuery("explain format = 'brief' select /*+ use_index_merge(t) */ * from t where a = 1 or b = 1;").Check(testkit.Rows( "Limit 3.00 root offset:0, count:3", - "└─IndexMerge 3.00 root ", + "└─IndexMerge 3.00 root type: union", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_a(a) range:[1,1], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_b(b) range:[1,1], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t keep order:false, stats:pseudo")) tk.MustExec("set @@session.sql_select_limit=18446744073709551615;") tk.MustQuery("explain format = 'brief' select * from t where a = 1 or b = 1;").Check(testkit.Rows( - "IndexMerge 19.99 root ", + "IndexMerge 19.99 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx_a(a) range:[1,1], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx_b(b) range:[1,1], keep order:false, stats:pseudo", "└─TableRowIDScan(Probe) 19.99 cop[tikv] table:t keep order:false, stats:pseudo")) tk.MustQuery("explain format = 'brief' select * from t where a = 1 or b = 1 limit 3;").Check(testkit.Rows( "Limit 3.00 root offset:0, count:3", - "└─IndexMerge 3.00 root ", + "└─IndexMerge 3.00 root type: union", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_a(a) range:[1,1], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_b(b) range:[1,1], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t keep order:false, stats:pseudo")) tk.MustQuery("explain format = 'brief' select /*+ use_index_merge(t) */ * from t where a = 1 or b = 1;").Check(testkit.Rows( - "IndexMerge 19.99 root ", + "IndexMerge 19.99 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx_a(a) range:[1,1], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx_b(b) range:[1,1], keep order:false, stats:pseudo", "└─TableRowIDScan(Probe) 19.99 cop[tikv] table:t keep order:false, stats:pseudo")) tk.MustQuery("explain format = 'brief' select /*+ use_index_merge(t) */ * from t where a = 1 or b = 1 limit 3;").Check(testkit.Rows( "Limit 3.00 root offset:0, count:3", - "└─IndexMerge 3.00 root ", + "└─IndexMerge 3.00 root type: union", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_a(a) range:[1,1], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 1.50 cop[tikv] table:t, index:idx_b(b) range:[1,1], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t keep order:false, stats:pseudo")) @@ -5536,65 +5944,11 @@ func TestIssue29503(t *testing.T) { require.Len(t, res.Rows(), 2) } -func TestIndexJoinCost(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec(`drop table if exists t_outer, t_inner_pk, t_inner_idx`) - tk.MustExec(`create table t_outer (a int)`) - tk.MustExec(`create table t_inner_pk (a int primary key)`) - tk.MustExec(`create table t_inner_idx (a int, b int, key(a))`) - - // Default RPC encoding may cause statistics explain result differ and then the test unstable. - tk.MustExec("set @@tidb_enable_chunk_rpc = on") - - tk.MustQuery(`explain format=verbose select /*+ TIDB_INLJ(t_outer, t_inner_pk) */ * from t_outer, t_inner_pk where t_outer.a=t_inner_pk.a`).Check(testkit.Rows( // IndexJoin with inner TableScan - `IndexJoin_11 12487.50 206368.09 root inner join, inner:TableReader_8, outer key:test.t_outer.a, inner key:test.t_inner_pk.a, equal cond:eq(test.t_outer.a, test.t_inner_pk.a)`, - `├─TableReader_18(Build) 9990.00 36412.58 root data:Selection_17`, - `│ └─Selection_17 9990.00 465000.00 cop[tikv] not(isnull(test.t_outer.a))`, - `│ └─TableFullScan_16 10000.00 435000.00 cop[tikv] table:t_outer keep order:false, stats:pseudo`, - `└─TableReader_8(Probe) 1.00 3.88 root data:TableRangeScan_7`, - ` └─TableRangeScan_7 1.00 30.00 cop[tikv] table:t_inner_pk range: decided by [test.t_outer.a], keep order:false, stats:pseudo`)) - tk.MustQuery(`explain format=verbose select /*+ TIDB_INLJ(t_outer, t_inner_idx) */ t_inner_idx.a from t_outer, t_inner_idx where t_outer.a=t_inner_idx.a`).Check(testkit.Rows( // IndexJoin with inner IndexScan - `IndexJoin_10 12487.50 235192.19 root inner join, inner:IndexReader_9, outer key:test.t_outer.a, inner key:test.t_inner_idx.a, equal cond:eq(test.t_outer.a, test.t_inner_idx.a)`, - `├─TableReader_20(Build) 9990.00 36412.58 root data:Selection_19`, - `│ └─Selection_19 9990.00 465000.00 cop[tikv] not(isnull(test.t_outer.a))`, - `│ └─TableFullScan_18 10000.00 435000.00 cop[tikv] table:t_outer keep order:false, stats:pseudo`, - `└─IndexReader_9(Probe) 1.25 5.89 root index:Selection_8`, - ` └─Selection_8 1.25 58.18 cop[tikv] not(isnull(test.t_inner_idx.a))`, - ` └─IndexRangeScan_7 1.25 54.43 cop[tikv] table:t_inner_idx, index:a(a) range: decided by [eq(test.t_inner_idx.a, test.t_outer.a)], keep order:false, stats:pseudo`)) - tk.MustQuery(`explain format=verbose select /*+ TIDB_INLJ(t_outer, t_inner_idx) */ * from t_outer, t_inner_idx where t_outer.a=t_inner_idx.a`).Check(testkit.Rows( // IndexJoin with inner IndexLookup - `IndexJoin_11 12487.50 531469.38 root inner join, inner:IndexLookUp_10, outer key:test.t_outer.a, inner key:test.t_inner_idx.a, equal cond:eq(test.t_outer.a, test.t_inner_idx.a)`, - `├─TableReader_23(Build) 9990.00 36412.58 root data:Selection_22`, - `│ └─Selection_22 9990.00 465000.00 cop[tikv] not(isnull(test.t_outer.a))`, - `│ └─TableFullScan_21 10000.00 435000.00 cop[tikv] table:t_outer keep order:false, stats:pseudo`, - `└─IndexLookUp_10(Probe) 1.25 35.55 root `, - ` ├─Selection_9(Build) 1.25 75.08 cop[tikv] not(isnull(test.t_inner_idx.a))`, - ` │ └─IndexRangeScan_7 1.25 71.32 cop[tikv] table:t_inner_idx, index:a(a) range: decided by [eq(test.t_inner_idx.a, test.t_outer.a)], keep order:false, stats:pseudo`, - ` └─TableRowIDScan_8(Probe) 1.25 71.25 cop[tikv] table:t_inner_idx keep order:false, stats:pseudo`)) - - tk.MustQuery("explain format=verbose select /*+ inl_hash_join(t_outer, t_inner_idx) */ t_inner_idx.a from t_outer, t_inner_idx where t_outer.a=t_inner_idx.a").Check(testkit.Rows( - `IndexHashJoin_12 12487.50 235192.19 root inner join, inner:IndexReader_9, outer key:test.t_outer.a, inner key:test.t_inner_idx.a, equal cond:eq(test.t_outer.a, test.t_inner_idx.a)`, - `├─TableReader_20(Build) 9990.00 36412.58 root data:Selection_19`, - `│ └─Selection_19 9990.00 465000.00 cop[tikv] not(isnull(test.t_outer.a))`, - `│ └─TableFullScan_18 10000.00 435000.00 cop[tikv] table:t_outer keep order:false, stats:pseudo`, - `└─IndexReader_9(Probe) 1.25 5.89 root index:Selection_8`, - ` └─Selection_8 1.25 58.18 cop[tikv] not(isnull(test.t_inner_idx.a))`, - ` └─IndexRangeScan_7 1.25 54.43 cop[tikv] table:t_inner_idx, index:a(a) range: decided by [eq(test.t_inner_idx.a, test.t_outer.a)], keep order:false, stats:pseudo`)) - tk.MustQuery("explain format=verbose select /*+ inl_merge_join(t_outer, t_inner_idx) */ t_inner_idx.a from t_outer, t_inner_idx where t_outer.a=t_inner_idx.a").Check(testkit.Rows( - `IndexMergeJoin_17 12487.50 229210.68 root inner join, inner:IndexReader_15, outer key:test.t_outer.a, inner key:test.t_inner_idx.a`, - `├─TableReader_20(Build) 9990.00 36412.58 root data:Selection_19`, - `│ └─Selection_19 9990.00 465000.00 cop[tikv] not(isnull(test.t_outer.a))`, - `│ └─TableFullScan_18 10000.00 435000.00 cop[tikv] table:t_outer keep order:false, stats:pseudo`, - `└─IndexReader_15(Probe) 1.25 5.89 root index:Selection_14`, - ` └─Selection_14 1.25 58.18 cop[tikv] not(isnull(test.t_inner_idx.a))`, - ` └─IndexRangeScan_13 1.25 54.43 cop[tikv] table:t_inner_idx, index:a(a) range: decided by [eq(test.t_inner_idx.a, test.t_outer.a)], keep order:true, stats:pseudo`)) -} - func TestHeuristicIndexSelection(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2") tk.MustExec("create table t1(a int, b int, c int, d int, e int, f int, g int, primary key (a), unique key c_d_e (c, d, e), unique key f (f), unique key f_g (f, g), key g (g))") tk.MustExec("create table t2(a int, b int, c int, d int, unique index idx_a (a), unique index idx_b_c (b, c), unique index idx_b_c_a_d (b, c, a, d))") @@ -5627,6 +5981,7 @@ func TestOutputSkylinePruningInfo(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int, b int, c int, d int, e int, f int, g int, primary key (a), unique key c_d_e (c, d, e), unique key f (f), unique key f_g (f, g), key g (g))") @@ -5656,6 +6011,7 @@ func TestPreferRangeScanForUnsignedIntHandle(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int unsigned primary key, b int, c int, index idx_b(b))") tk.MustExec("insert into t values (1,2,3), (4,5,6), (7,8,9), (10,11,12), (13,14,15)") @@ -5725,6 +6081,7 @@ func TestIssues27130(t *testing.T) { tk.MustExec("use test") tk.MustExec("drop table if exists t1") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("create table t1( a enum('y','b','Abc','null'),b enum('y','b','Abc','null'),key(a));") tk.MustQuery(`explain format=brief select * from t1 where a like "A%"`).Check(testkit.Rows( "TableReader 8000.00 root data:Selection", @@ -5740,14 +6097,14 @@ func TestIssues27130(t *testing.T) { tk.MustExec("drop table if exists t2") tk.MustExec("create table t2( a enum('y','b','Abc','null'),b enum('y','b','Abc','null'),key(a, b));") tk.MustQuery(`explain format=brief select * from t2 where a like "A%"`).Check(testkit.Rows( - "TableReader 8000.00 root data:Selection", + "IndexReader 8000.00 root index:Selection", "└─Selection 8000.00 cop[tikv] like(test.t2.a, \"A%\", 92)", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a, b) keep order:false, stats:pseudo", )) tk.MustQuery(`explain format=brief select * from t2 where a like "A%" and b like "A%"`).Check(testkit.Rows( - "TableReader 8000.00 root data:Selection", + "IndexReader 8000.00 root index:Selection", "└─Selection 8000.00 cop[tikv] like(test.t2.a, \"A%\", 92), like(test.t2.b, \"A%\", 92)", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a, b) keep order:false, stats:pseudo", )) tk.MustExec("drop table if exists t3") @@ -6013,6 +6370,7 @@ func TestRejectSortForMPP(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t (id int, value decimal(6,3), name char(128))") tk.MustExec("analyze table t") @@ -6286,6 +6644,7 @@ func TestIndexMergeWithCorrelatedColumns(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2;") tk.MustExec("create table t1(c1 int, c2 int, c3 int, primary key(c1), key(c2));") tk.MustExec("insert into t1 values(1, 1, 1);") @@ -6471,6 +6830,7 @@ func TestAggPushToCopForCachedTable(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`create table t32157( process_code varchar(8) NOT NULL, ctrl_class varchar(2) NOT NULL, @@ -6478,7 +6838,7 @@ func TestAggPushToCopForCachedTable(t *testing.T) { oper_no varchar(12) DEFAULT NULL, modify_date datetime DEFAULT NULL, d_c_flag varchar(2) NOT NULL, - PRIMARY KEY (process_code,ctrl_class,d_c_flag));`) + PRIMARY KEY (process_code,ctrl_class,d_c_flag) NONCLUSTERED);`) tk.MustExec("insert into t32157 values ('GDEP0071', '05', '1', '10000', '2016-06-29 00:00:00', 'C')") tk.MustExec("insert into t32157 values ('GDEP0071', '05', '0', '0000', '2016-06-01 00:00:00', 'D')") tk.MustExec("alter table t32157 cache") @@ -6510,6 +6870,7 @@ func TestIssue31240(t *testing.T) { tk.MustExec("use test") tk.MustExec("create table t31240(a int, b int);") tk.MustExec("set @@tidb_allow_mpp = 0") + tk.MustExec("set tidb_cost_model_version=2") tbl, err := dom.InfoSchema().TableByName(model.CIStr{O: "test", L: "test"}, model.CIStr{O: "t31240", L: "t31240"}) require.NoError(t, err) @@ -6602,6 +6963,7 @@ func TestTiFlashPartitionTableScan(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec("set @@tidb_partition_prune_mode = 'dynamic'") tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") tk.MustExec("set @@tidb_enforce_mpp = on") @@ -6639,6 +7001,7 @@ func TestTiFlashFineGrainedShuffle(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") tk.MustExec("set @@tidb_enforce_mpp = on") tk.MustExec("drop table if exists t1;") @@ -6859,10 +7222,10 @@ func TestIssue29663(t *testing.T) { " └─Apply_20 10000.00 root CARTESIAN left outer join", " ├─TableReader_22(Build) 10000.00 root data:TableFullScan_21", " │ └─TableFullScan_21 10000.00 cop[tikv] table:one keep order:false, stats:pseudo", - " └─MaxOneRow_23(Probe) 1.00 root ", - " └─TableReader_26 2.00 root data:Selection_25", - " └─Selection_25 2.00 cop[tikv] eq(test.t2.c, test.t1.b)", - " └─TableFullScan_24 2000.00 cop[tikv] table:two keep order:false, stats:pseudo")) + " └─MaxOneRow_23(Probe) 10000.00 root ", + " └─TableReader_26 20000.00 root data:Selection_25", + " └─Selection_25 20000.00 cop[tikv] eq(test.t2.c, test.t1.b)", + " └─TableFullScan_24 20000000.00 cop[tikv] table:two keep order:false, stats:pseudo")) } func TestIssue31609(t *testing.T) { @@ -6966,6 +7329,7 @@ func TestIssue36194(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int)") // create virtual tiflash replica. @@ -6980,7 +7344,7 @@ func TestIssue36194(t *testing.T) { } } } - tk.MustQuery("explain format = 'brief' select * from t where a + 1 > 20 limit 100;;").Check(testkit.Rows( + tk.MustQuery("explain format = 'brief' select /*+ read_from_storage(tiflash[t]) */ * from t where a + 1 > 20 limit 100;;").Check(testkit.Rows( "Limit 100.00 root offset:0, count:100", "└─TableReader 100.00 root data:ExchangeSender", " └─ExchangeSender 100.00 mpp[tiflash] ExchangeType: PassThrough", @@ -7015,6 +7379,7 @@ func TestAggWithJsonPushDownToTiFlash(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t(a json);") tk.MustExec("insert into t values(null);") @@ -7199,6 +7564,105 @@ func TestEltPushDownToTiFlash(t *testing.T) { tk.MustQuery("explain select elt(a, b) from t;").CheckAt([]int{0, 2, 4}, rows) } +func TestRegexpInstrPushDownToTiFlash(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists test.t;") + tk.MustExec("create table test.t (expr varchar(30), pattern varchar(30), pos int, occur int, ret_op int, match_type varchar(30));") + tk.MustExec("insert into test.t values ('123', '12.', 1, 1, 0, ''), ('aBb', 'bb', 1, 1, 0, 'i'), ('ab\nabc', '^abc$', 1, 1, 0, 'm');") + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1") + tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") + + // Create virtual tiflash replica info. + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + rows := [][]interface{}{ + {"TableReader_9", "root", "data:ExchangeSender_8"}, + {"└─ExchangeSender_8", "mpp[tiflash]", "ExchangeType: PassThrough"}, + {" └─Projection_4", "mpp[tiflash]", "regexp_instr(test.t.expr, test.t.pattern, 1, 1, 0, test.t.match_type)->Column#8"}, + {" └─TableFullScan_7", "mpp[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select regexp_instr(expr, pattern, 1, 1, 0, match_type) as res from test.t;").CheckAt([]int{0, 2, 4}, rows) +} + +func TestRegexpSubstrPushDownToTiFlash(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists test.t;") + tk.MustExec("create table test.t (expr varchar(30), pattern varchar(30), pos int, occur int, match_type varchar(30));") + tk.MustExec("insert into test.t values ('123', '12.', 1, 1, ''), ('aBb', 'bb', 1, 1, 'i'), ('ab\nabc', '^abc$', 1, 1, 'm');") + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1") + tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") + + // Create virtual tiflash replica info. + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + rows := [][]interface{}{ + {"TableReader_9", "root", "data:ExchangeSender_8"}, + {"└─ExchangeSender_8", "mpp[tiflash]", "ExchangeType: PassThrough"}, + {" └─Projection_4", "mpp[tiflash]", "regexp_substr(test.t.expr, test.t.pattern, 1, 1, test.t.match_type)->Column#7"}, + {" └─TableFullScan_7", "mpp[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select regexp_substr(expr, pattern, 1, 1, match_type) as res from test.t;").CheckAt([]int{0, 2, 4}, rows) +} + +func TestRegexpReplacePushDownToTiFlash(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists test.t;") + tk.MustExec("create table test.t (expr varchar(30), pattern varchar(30), repl varchar(30), pos int, occur int, match_type varchar(30));") + tk.MustExec("insert into test.t values ('123', '12.', '233', 1, 1, ''), ('aBb', 'bb', 'bc', 1, 1, 'i'), ('ab\nabc', '^abc$', 'd', 1, 1, 'm');") + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1") + tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") + + // Create virtual tiflash replica info. + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + rows := [][]interface{}{ + {"TableReader_9", "root", "data:ExchangeSender_8"}, + {"└─ExchangeSender_8", "mpp[tiflash]", "ExchangeType: PassThrough"}, + {" └─Projection_4", "mpp[tiflash]", "regexp_replace(test.t.expr, test.t.pattern, test.t.repl, 1, 1, test.t.match_type)->Column#8"}, + {" └─TableFullScan_7", "mpp[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select regexp_replace(expr, pattern, repl, 1, 1, match_type) as res from test.t;").CheckAt([]int{0, 2, 4}, rows) +} + func TestCastTimeAsDurationToTiFlash(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) @@ -7236,6 +7700,39 @@ func TestCastTimeAsDurationToTiFlash(t *testing.T) { tk.MustQuery("explain select cast(a as time), cast(b as time) from t;").CheckAt([]int{0, 2, 4}, rows) } +func TestUnhexPushDownToTiFlash(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b varchar(20));") + tk.MustExec("insert into t values(6162, '7469666C617368');") + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1;") + tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") + + tbl, err := dom.InfoSchema().TableByName(model.CIStr{O: "test", L: "test"}, model.CIStr{O: "t", L: "t"}) + require.NoError(t, err) + // Set the hacked TiFlash replica for explain tests. + tbl.Meta().TiFlashReplica = &model.TiFlashReplicaInfo{Count: 1, Available: true} + + rows := [][]interface{}{ + {"TableReader_9", "root", "data:ExchangeSender_8"}, + {"└─ExchangeSender_8", "mpp[tiflash]", "ExchangeType: PassThrough"}, + {" └─Projection_4", "mpp[tiflash]", "unhex(cast(test.t.a, var_string(20)))->Column#4"}, + {" └─TableFullScan_7", "mpp[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select unhex(a) from t;").CheckAt([]int{0, 2, 4}, rows) + + rows = [][]interface{}{ + {"TableReader_9", "root", "data:ExchangeSender_8"}, + {"└─ExchangeSender_8", "mpp[tiflash]", "ExchangeType: PassThrough"}, + {" └─Projection_4", "mpp[tiflash]", "unhex(test.t.b)->Column#4"}, + {" └─TableFullScan_7", "mpp[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select unhex(b) from t;").CheckAt([]int{0, 2, 4}, rows) +} + func TestPartitionTableFallBackStatic(t *testing.T) { store, _ := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) @@ -7339,6 +7836,50 @@ func TestEnableTiFlashReadForWriteStmt(t *testing.T) { checkMpp(rs) } +func TestPointGetWithSelectLock(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(a int, b int, primary key(a, b));") + tk.MustExec("create table t1(c int unique, d int);") + tbl, err := dom.InfoSchema().TableByName(model.CIStr{O: "test", L: "test"}, model.CIStr{O: "t", L: "t"}) + require.NoError(t, err) + // Set the hacked TiFlash replica for explain tests. + tbl.Meta().TiFlashReplica = &model.TiFlashReplicaInfo{Count: 1, Available: true} + tbl1, err := dom.InfoSchema().TableByName(model.CIStr{O: "test", L: "test"}, model.CIStr{O: "t1", L: "t1"}) + require.NoError(t, err) + // Set the hacked TiFlash replica for explain tests. + tbl1.Meta().TiFlashReplica = &model.TiFlashReplicaInfo{Count: 1, Available: true} + + sqls := []string{ + "explain select a, b from t where (a = 1 and b = 2) or (a =2 and b = 1) for update;", + "explain select a, b from t where a = 1 and b = 2 for update;", + "explain select c, d from t1 where c = 1 for update;", + "explain select c, d from t1 where c = 1 and d = 1 for update;", + "explain select c, d from t1 where (c = 1 or c = 2 )and d = 1 for update;", + "explain select c, d from t1 where c in (1,2,3,4) for update;", + } + tk.MustExec("set @@tidb_enable_tiflash_read_for_write_stmt = on;") + tk.MustExec("set @@tidb_isolation_read_engines='tidb,tiflash';") + tk.MustExec("begin;") + // assert point get / batch point get can't work with tiflash in interaction txn + for _, sql := range sqls { + err = tk.ExecToErr(sql) + require.Error(t, err) + } + // assert point get / batch point get can work with tikv in interaction txn + tk.MustExec("set @@tidb_isolation_read_engines='tidb,tikv,tiflash';") + for _, sql := range sqls { + tk.MustQuery(sql) + } + tk.MustExec("commit") + // assert point get / batch point get can work with tiflash in auto commit + tk.MustExec("set @@tidb_isolation_read_engines='tidb,tiflash';") + for _, sql := range sqls { + tk.MustQuery(sql) + } +} + func TestTableRangeFallback(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -7463,7 +8004,8 @@ func TestPlanCacheForTableRangeFallback(t *testing.T) { tk.MustExec("prepare stmt from 'select * from t where a in (?, ?, ?, ?, ?) and b > 1'") tk.MustExec("set @a=10, @b=20, @c=30, @d=40, @e=50") tk.MustExec("execute stmt using @a, @b, @c, @d, @e") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 Memory capacity of 10 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen")) + tk.MustQuery("show warnings").Sort().Check(testkit.Rows("Warning 1105 Memory capacity of 10 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen", + "Warning 1105 skip plan-cache: in-list is too long")) tk.MustExec("execute stmt using @a, @b, @c, @d, @e") // The plan with range fallback is not cached. tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) @@ -7510,7 +8052,8 @@ func TestPlanCacheForIndexRangeFallback(t *testing.T) { tk.MustExec("prepare stmt2 from 'select * from t where a in (?, ?, ?, ?, ?) and b in (?, ?, ?, ?, ?)'") tk.MustExec("set @a='aa', @b='bb', @c='cc', @d='dd', @e='ee', @f='ff', @g='gg', @h='hh', @i='ii', @j='jj'") tk.MustExec("execute stmt2 using @a, @b, @c, @d, @e, @f, @g, @h, @i, @j") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 Memory capacity of 1330 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen")) + tk.MustQuery("show warnings").Sort().Check(testkit.Rows("Warning 1105 Memory capacity of 1330 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen", + "Warning 1105 skip plan-cache: in-list is too long")) tk.MustExec("execute stmt2 using @a, @b, @c, @d, @e, @f, @g, @h, @i, @j") tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) } @@ -7528,6 +8071,10 @@ func TestCorColRangeWithRangeMaxSize(t *testing.T) { tk.MustExec("insert into t3 values (2), (4)") tk.MustExec("insert into mysql.opt_rule_blacklist value(\"decorrelate\")") tk.MustExec("admin reload opt_rule_blacklist") + defer func() { + tk.MustExec("delete from mysql.opt_rule_blacklist where name = \"decorrelate\"") + tk.MustExec("admin reload opt_rule_blacklist") + }() // Correlated column in index range. tk.MustExec("set @@tidb_opt_range_max_size=1000") @@ -7662,7 +8209,8 @@ func TestPlanCacheForIndexJoinRangeFallback(t *testing.T) { tk.MustExec("prepare stmt2 from 'select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.d where t1.b in (?, ?, ?, ?, ?)'") tk.MustExec("set @a='a', @b='b', @c='c', @d='d', @e='e'") tk.MustExec("execute stmt2 using @a, @b, @c, @d, @e") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 Memory capacity of 1275 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen")) + tk.MustQuery("show warnings").Sort().Check(testkit.Rows("Warning 1105 Memory capacity of 1275 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen", + "Warning 1105 skip plan-cache: in-list is too long")) tk.MustExec("execute stmt2 using @a, @b, @c, @d, @e") tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) } @@ -7693,3 +8241,91 @@ func TestOuterJoinEliminationForIssue18216(t *testing.T) { tk.MustExec("select group_concat(c order by (select group_concat(c order by a) from t2 where a=t1.a)) from t1; ") tk.MustQuery("select group_concat(c order by (select group_concat(c order by c) from t2 where a=t1.a), c desc) from t1;").Check(testkit.Rows("2,1,4,3")) } + +func TestNullConditionForPrefixIndex(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`CREATE TABLE t1 ( + id char(1) DEFAULT NULL, + c1 varchar(255) DEFAULT NULL, + c2 text DEFAULT NULL, + KEY idx1 (c1), + KEY idx2 (c1,c2(5)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`) + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("create table t2(a int, b varchar(10), index idx(b(5)))") + tk.MustExec("create table t3(a int, b varchar(10), c int, primary key (a, b(5)) clustered)") + tk.MustExec("set tidb_opt_prefix_index_single_scan = 1") + tk.MustExec("insert into t1 values ('a', '0xfff', '111111'), ('b', '0xfff', '22 '), ('c', '0xfff', ''), ('d', '0xfff', null)") + tk.MustExec("insert into t2 values (1, 'aaaaaa'), (2, 'bb '), (3, ''), (4, null)") + tk.MustExec("insert into t3 values (1, 'aaaaaa', 2), (1, 'bb ', 3), (1, '', 4)") + + var input []string + var output []struct { + SQL string + Plan []string + Result []string + } + integrationSuiteData := core.GetIntegrationSuiteData() + integrationSuiteData.LoadTestCases(t, &input, &output) + for i, tt := range input { + testdata.OnRecord(func() { + output[i].SQL = tt + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format='brief' " + tt).Rows()) + output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Sort().Rows()) + }) + tk.MustQuery("explain format='brief' " + tt).Check(testkit.Rows(output[i].Plan...)) + tk.MustQuery(tt).Sort().Check(testkit.Rows(output[i].Result...)) + } + + // test plan cache + tk.MustExec(`set tidb_enable_prepared_plan_cache=1`) + tk.MustExec("set @@tidb_enable_collect_execution_info=0") + tk.MustExec("prepare stmt from 'select count(1) from t1 where c1 = ? and c2 is not null'") + tk.MustExec("set @a = '0xfff'") + tk.MustQuery("execute stmt using @a").Check(testkit.Rows("3")) + tk.MustQuery("execute stmt using @a").Check(testkit.Rows("3")) + tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1")) + tk.MustQuery("execute stmt using @a").Check(testkit.Rows("3")) + tkProcess := tk.Session().ShowProcess() + ps := []*util.ProcessInfo{tkProcess} + tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) + tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Check(testkit.Rows( + "StreamAgg_18 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader_19 1.00 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_17 99.90 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" -inf,\"0xfff\" +inf], keep order:false, stats:pseudo")) +} + +func TestAutoIncrementCheckWithCheckConstraint(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`CREATE TABLE t ( + id INTEGER NOT NULL AUTO_INCREMENT, + CHECK (id IN (0, 1)), + KEY idx_autoinc_id (id) + )`) +} + +// https://github.com/pingcap/tidb/issues/36888. +func TestIssue36888(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("CREATE TABLE t0(c0 INT);") + tk.MustExec("CREATE TABLE t1(c0 INT);") + + tk.MustExec("INSERT INTO t0 VALUES (NULL);") + tk.MustQuery("SELECT t0.c0 FROM t0 LEFT JOIN t1 ON t0.c0>=t1.c0 WHERE (CONCAT_WS(t0.c0, t1.c0) IS NULL);").Check(testkit.Rows("")) +} + +// https://github.com/pingcap/tidb/issues/40285. +func TestIssue40285(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("CREATE TABLE t(col1 enum('p5', '9a33x') NOT NULL DEFAULT 'p5',col2 tinyblob DEFAULT NULL) ENGINE = InnoDB DEFAULT CHARSET = latin1 COLLATE = latin1_bin;") + tk.MustQuery("(select last_value(col1) over () as r0 from t) union all (select col2 as r0 from t);") +} diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 4d6e99f8a81fb..2d73534fc2e1e 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -27,6 +27,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/expression/aggregation" @@ -49,6 +50,7 @@ import ( "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/statistics/handle" + "github.com/pingcap/tidb/store/driver/backoff" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/table/temptable" @@ -59,11 +61,13 @@ import ( "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/hack" + "github.com/pingcap/tidb/util/hint" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/plancodec" "github.com/pingcap/tidb/util/set" "github.com/pingcap/tidb/util/size" + "github.com/tikv/client-go/v2/tikv" ) const ( @@ -76,6 +80,8 @@ const ( TiDBBroadCastJoin = "tidb_bcj" // HintBCJ indicates applying broadcast join by force. HintBCJ = "broadcast_join" + // HintShuffleJoin indicates applying shuffle join by force. + HintShuffleJoin = "shuffle_join" // HintStraightJoin causes TiDB to join tables in the order in which they appear in the FROM clause. HintStraightJoin = "straight_join" @@ -102,12 +108,20 @@ const ( HintHashAgg = "hash_agg" // HintStreamAgg is hint enforce stream aggregation. HintStreamAgg = "stream_agg" + // HintMPP1PhaseAgg enforces the optimizer to use the mpp-1phase aggregation. + HintMPP1PhaseAgg = "mpp_1phase_agg" + // HintMPP2PhaseAgg enforces the optimizer to use the mpp-2phase aggregation. + HintMPP2PhaseAgg = "mpp_2phase_agg" // HintUseIndex is hint enforce using some indexes. HintUseIndex = "use_index" // HintIgnoreIndex is hint enforce ignoring some indexes. HintIgnoreIndex = "ignore_index" // HintForceIndex make optimizer to use this index even if it thinks a table scan is more efficient. HintForceIndex = "force_index" + // HintKeepOrder is hint enforce using some indexes and keep the index's order. + HintKeepOrder = "keep_order" + // HintNoKeepOrder is hint enforce using some indexes and not keep the index's order. + HintNoKeepOrder = "no_keep_order" // HintAggToCop is hint enforce pushing aggregation to coprocessor. HintAggToCop = "agg_to_cop" // HintReadFromStorage is hint enforce some tables read from specific type of storage. @@ -152,7 +166,7 @@ func (a *aggOrderByResolver) Enter(inNode ast.Node) (ast.Node, bool) { a.exprDepth++ if n, ok := inNode.(*driver.ParamMarkerExpr); ok { if a.exprDepth == 1 { - _, isNull, isExpectedType := getUintFromNode(a.ctx, n) + _, isNull, isExpectedType := getUintFromNode(a.ctx, n, false) // For constant uint expression in top level, it should be treated as position expression. if !isNull && isExpectedType { return expression.ConstructPositionExpr(n), true @@ -586,6 +600,9 @@ func (p *LogicalJoin) setPreferredJoinTypeAndOrder(hintInfo *tableHintInfo) { if hintInfo.ifPreferBroadcastJoin(lhsAlias, rhsAlias) { p.preferJoinType |= preferBCJoin } + if hintInfo.ifPreferShuffleJoin(lhsAlias, rhsAlias) { + p.preferJoinType |= preferShuffleJoin + } if hintInfo.ifPreferHashJoin(lhsAlias, rhsAlias) { p.preferJoinType |= preferHashJoin } @@ -675,6 +692,13 @@ func (ds *DataSource) setPreferredStoreType(hintInfo *tableHintInfo) { ds.preferStoreType = 0 return } + if config.GetGlobalConfig().DisaggregatedTiFlash && !isTiFlashComputeNodeAvailable(ds.ctx) { + // TiFlash is in disaggregated mode, need to make sure tiflash_compute node is available. + errMsg := "No available tiflash_compute node" + warning := ErrInternal.GenWithStack(errMsg) + ds.ctx.GetSessionVars().StmtCtx.AppendWarning(warning) + return + } for _, path := range ds.possibleAccessPaths { if path.StoreType == kv.TiFlash { ds.preferStoreType |= preferTiFlash @@ -692,6 +716,15 @@ func (ds *DataSource) setPreferredStoreType(hintInfo *tableHintInfo) { } } +func isTiFlashComputeNodeAvailable(ctx sessionctx.Context) bool { + bo := backoff.NewBackofferWithVars(context.Background(), 5000, nil) + stores, err := ctx.GetStore().(tikv.Storage).GetRegionCache().GetTiFlashComputeStores(bo.TiKVBackoffer()) + if err != nil || len(stores) == 0 { + return false + } + return true +} + func resetNotNullFlag(schema *expression.Schema, start, end int) { for i := start; i < end; i++ { col := *schema.Columns[i] @@ -1547,7 +1580,9 @@ func (*PlanBuilder) setUnionFlen(resultTp *types.FieldType, cols []expression.Ex childTp := cols[i].GetType() childTpCharLen := 1 if isBinary { - childTpCharLen = charset.CharacterSetInfos[childTp.GetCharset()].Maxlen + if charsetInfo, ok := charset.CharacterSetInfos[childTp.GetCharset()]; ok { + childTpCharLen = charsetInfo.Maxlen + } } resultTp.SetFlen(mathutil.Max(resultTp.GetFlen(), childTpCharLen*childTp.GetFlen())) } @@ -1712,7 +1747,9 @@ func (b *PlanBuilder) buildSemiJoinForSetOperator( if err != nil { return nil, err } - if leftCol.RetType.GetType() != rightCol.RetType.GetType() { + _, leftArgIsColumn := eqCond.(*expression.ScalarFunction).GetArgs()[0].(*expression.Column) + _, rightArgIsColumn := eqCond.(*expression.ScalarFunction).GetArgs()[1].(*expression.Column) + if leftCol.RetType.GetType() != rightCol.RetType.GetType() || !leftArgIsColumn || !rightArgIsColumn { joinPlan.OtherConditions = append(joinPlan.OtherConditions, eqCond) } else { joinPlan.EqualConditions = append(joinPlan.EqualConditions, eqCond.(*expression.ScalarFunction)) @@ -1970,7 +2007,7 @@ CheckReferenced: // getUintFromNode gets uint64 value from ast.Node. // For ordinary statement, node should be uint64 constant value. // For prepared statement, node is string. We should convert it to uint64. -func getUintFromNode(ctx sessionctx.Context, n ast.Node) (uVal uint64, isNull bool, isExpectedType bool) { +func getUintFromNode(ctx sessionctx.Context, n ast.Node, mustInt64orUint64 bool) (uVal uint64, isNull bool, isExpectedType bool) { var val interface{} switch v := n.(type) { case *driver.ValueExpr: @@ -1979,6 +2016,11 @@ func getUintFromNode(ctx sessionctx.Context, n ast.Node) (uVal uint64, isNull bo if !v.InExecute { return 0, false, true } + if mustInt64orUint64 { + if expected, _ := CheckParamTypeInt64orUint64(v); !expected { + return 0, false, false + } + } param, err := expression.ParamMarkerExpression(ctx, v, false) if err != nil { return 0, false, false @@ -2012,17 +2054,32 @@ func getUintFromNode(ctx sessionctx.Context, n ast.Node) (uVal uint64, isNull bo return 0, false, false } +// CheckParamTypeInt64orUint64 check param type for plan cache limit, only allow int64 and uint64 now +// eg: set @a = 1; +func CheckParamTypeInt64orUint64(param *driver.ParamMarkerExpr) (bool, uint64) { + val := param.GetValue() + switch v := val.(type) { + case int64: + if v >= 0 { + return true, uint64(v) + } + case uint64: + return true, v + } + return false, 0 +} + func extractLimitCountOffset(ctx sessionctx.Context, limit *ast.Limit) (count uint64, offset uint64, err error) { var isExpectedType bool if limit.Count != nil { - count, _, isExpectedType = getUintFromNode(ctx, limit.Count) + count, _, isExpectedType = getUintFromNode(ctx, limit.Count, true) if !isExpectedType { return 0, 0, ErrWrongArguments.GenWithStackByArgs("LIMIT") } } if limit.Offset != nil { - offset, _, isExpectedType = getUintFromNode(ctx, limit.Offset) + offset, _, isExpectedType = getUintFromNode(ctx, limit.Offset, true) if !isExpectedType { return 0, 0, ErrWrongArguments.GenWithStackByArgs("LIMIT") } @@ -2803,7 +2860,7 @@ func (g *gbyResolver) Enter(inNode ast.Node) (ast.Node, bool) { case *driver.ParamMarkerExpr: g.isParam = true if g.exprDepth == 1 { - _, isNull, isExpectedType := getUintFromNode(g.ctx, n) + _, isNull, isExpectedType := getUintFromNode(g.ctx, n, false) // For constant uint expression in top level, it should be treated as position expression. if !isNull && isExpectedType { return expression.ConstructPositionExpr(n), true @@ -3564,6 +3621,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev hints = b.hintProcessor.GetCurrentStmtHints(hints, currentLevel) var ( sortMergeTables, inljTables, inlhjTables, inlmjTables, hashJoinTables, bcTables []hintTableInfo + shuffleJoinTables []hintTableInfo indexHintList, indexMergeHintList []indexHintInfo tiflashTables, tikvTables []hintTableInfo aggHints aggHintInfo @@ -3578,7 +3636,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev // Set warning for the hint that requires the table name. switch hint.HintName.L { case TiDBMergeJoin, HintSMJ, TiDBIndexNestedLoopJoin, HintINLJ, HintINLHJ, HintINLMJ, - TiDBHashJoin, HintHJ, HintUseIndex, HintIgnoreIndex, HintForceIndex, HintIndexMerge, HintLeading: + TiDBHashJoin, HintHJ, HintUseIndex, HintIgnoreIndex, HintForceIndex, HintKeepOrder, HintNoKeepOrder, HintIndexMerge, HintLeading: if len(hint.Tables) == 0 { b.pushHintWithoutTableWarning(hint) continue @@ -3590,6 +3648,8 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev sortMergeTables = append(sortMergeTables, tableNames2HintTableInfo(b.ctx, hint.HintName.L, hint.Tables, b.hintProcessor, currentLevel)...) case TiDBBroadCastJoin, HintBCJ: bcTables = append(bcTables, tableNames2HintTableInfo(b.ctx, hint.HintName.L, hint.Tables, b.hintProcessor, currentLevel)...) + case HintShuffleJoin: + shuffleJoinTables = append(shuffleJoinTables, tableNames2HintTableInfo(b.ctx, hint.HintName.L, hint.Tables, b.hintProcessor, currentLevel)...) case TiDBIndexNestedLoopJoin, HintINLJ: inljTables = append(inljTables, tableNames2HintTableInfo(b.ctx, hint.HintName.L, hint.Tables, b.hintProcessor, currentLevel)...) case HintINLHJ: @@ -3598,6 +3658,10 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev inlmjTables = append(inlmjTables, tableNames2HintTableInfo(b.ctx, hint.HintName.L, hint.Tables, b.hintProcessor, currentLevel)...) case TiDBHashJoin, HintHJ: hashJoinTables = append(hashJoinTables, tableNames2HintTableInfo(b.ctx, hint.HintName.L, hint.Tables, b.hintProcessor, currentLevel)...) + case HintMPP1PhaseAgg: + aggHints.preferAggType |= preferMPP1PhaseAgg + case HintMPP2PhaseAgg: + aggHints.preferAggType |= preferMPP2PhaseAgg case HintHashJoinBuild: hjBuildTables = append(hjBuildTables, tableNames2HintTableInfo(b.ctx, hint.HintName.L, hint.Tables, b.hintProcessor, currentLevel)...) case HintHashJoinProbe: @@ -3608,25 +3672,23 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev aggHints.preferAggType |= preferStreamAgg case HintAggToCop: aggHints.preferAggToCop = true - case HintUseIndex: + case HintUseIndex, HintIgnoreIndex, HintForceIndex, HintKeepOrder, HintNoKeepOrder: dbName := hint.Tables[0].DBName if dbName.L == "" { dbName = model.NewCIStr(b.ctx.GetSessionVars().CurrentDB) } - indexHintList = append(indexHintList, indexHintInfo{ - dbName: dbName, - tblName: hint.Tables[0].TableName, - partitions: hint.Tables[0].PartitionList, - indexHint: &ast.IndexHint{ - IndexNames: hint.Indexes, - HintType: ast.HintUse, - HintScope: ast.HintForScan, - }, - }) - case HintIgnoreIndex: - dbName := hint.Tables[0].DBName - if dbName.L == "" { - dbName = model.NewCIStr(b.ctx.GetSessionVars().CurrentDB) + var hintType ast.IndexHintType + switch hint.HintName.L { + case HintUseIndex: + hintType = ast.HintUse + case HintIgnoreIndex: + hintType = ast.HintIgnore + case HintForceIndex: + hintType = ast.HintForce + case HintKeepOrder: + hintType = ast.HintKeepOrder + case HintNoKeepOrder: + hintType = ast.HintNoKeepOrder } indexHintList = append(indexHintList, indexHintInfo{ dbName: dbName, @@ -3634,22 +3696,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev partitions: hint.Tables[0].PartitionList, indexHint: &ast.IndexHint{ IndexNames: hint.Indexes, - HintType: ast.HintIgnore, - HintScope: ast.HintForScan, - }, - }) - case HintForceIndex: - dbName := hint.Tables[0].DBName - if dbName.L == "" { - dbName = model.NewCIStr(b.ctx.GetSessionVars().CurrentDB) - } - indexHintList = append(indexHintList, indexHintInfo{ - dbName: dbName, - tblName: hint.Tables[0].TableName, - partitions: hint.Tables[0].PartitionList, - indexHint: &ast.IndexHint{ - IndexNames: hint.Indexes, - HintType: ast.HintForce, + HintType: hintType, HintScope: ast.HintForScan, }, }) @@ -3718,6 +3765,7 @@ func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLev b.tableHintInfo = append(b.tableHintInfo, tableHintInfo{ sortMergeJoinTables: sortMergeTables, broadcastJoinTables: bcTables, + shuffleJoinTables: shuffleJoinTables, indexNestedLoopJoinTables: indexNestedLoopJoinTables{inljTables, inlhjTables, inlmjTables}, hashJoinTables: hashJoinTables, indexHintList: indexHintList, @@ -3750,6 +3798,7 @@ func (b *PlanBuilder) popTableHints() { b.appendUnmatchedJoinHintWarning(HintINLMJ, "", hintInfo.indexNestedLoopJoinTables.inlmjTables) b.appendUnmatchedJoinHintWarning(HintSMJ, TiDBMergeJoin, hintInfo.sortMergeJoinTables) b.appendUnmatchedJoinHintWarning(HintBCJ, TiDBBroadCastJoin, hintInfo.broadcastJoinTables) + b.appendUnmatchedJoinHintWarning(HintShuffleJoin, HintShuffleJoin, hintInfo.shuffleJoinTables) b.appendUnmatchedJoinHintWarning(HintHJ, TiDBHashJoin, hintInfo.hashJoinTables) b.appendUnmatchedJoinHintWarning(HintHashJoinBuild, "", hintInfo.hjBuildTables) b.appendUnmatchedJoinHintWarning(HintHashJoinProbe, "", hintInfo.hjProbeTables) @@ -4393,7 +4442,35 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as if tn.TableSample != nil { return nil, expression.ErrInvalidTableSample.GenWithStackByArgs("Unsupported TABLESAMPLE in views") } - return b.BuildDataSourceFromView(ctx, dbName, tableInfo) + + // Get the hints belong to the current view. + currentQBNameMap4View := make(map[string][]ast.HintTable) + currentViewHints := make(map[string][]*ast.TableOptimizerHint) + for qbName, viewQBNameHintTable := range b.hintProcessor.QbNameMap4View { + if len(viewQBNameHintTable) == 0 { + continue + } + viewSelectOffset := b.getSelectOffset() + + var viewHintSelectOffset int + if viewQBNameHintTable[0].QBName.L == "" { + // If we do not explicit set the qbName, we will set the empty qb name to @sel_1. + viewHintSelectOffset = 1 + } else { + viewHintSelectOffset = b.hintProcessor.GetHintOffset(viewQBNameHintTable[0].QBName, viewSelectOffset) + } + + // Check whether the current view can match the view name in the hint. + if viewQBNameHintTable[0].TableName.L == tblName.L && viewHintSelectOffset == viewSelectOffset { + // If the view hint can match the current view, we pop the first view table in the query block hint's table list. + // It means the hint belong the current view, the first view name in hint is matched. + // Because of the nested views, so we should check the left table list in hint when build the data source from the view inside the current view. + currentQBNameMap4View[qbName] = viewQBNameHintTable[1:] + currentViewHints[qbName] = b.hintProcessor.QbHints4View[qbName] + b.hintProcessor.QbNameUsed4View[qbName] = struct{}{} + } + } + return b.BuildDataSourceFromView(ctx, dbName, tableInfo, currentQBNameMap4View, currentViewHints) } if tableInfo.IsSequence() { @@ -4405,30 +4482,39 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as } if tableInfo.GetPartitionInfo() != nil { - h := domain.GetDomain(b.ctx).StatsHandle() - tblStats := h.GetTableStats(tableInfo) - isDynamicEnabled := b.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() - globalStatsReady := tblStats.IsInitialized() - // If dynamic partition prune isn't enabled or global stats is not ready, we won't enable dynamic prune mode in query - usePartitionProcessor := !isDynamicEnabled || !globalStatsReady - - failpoint.Inject("forceDynamicPrune", func(val failpoint.Value) { - if val.(bool) { - if isDynamicEnabled { - usePartitionProcessor = false - } - } - }) - - if usePartitionProcessor { + // If `UseDynamicPruneMode` already been false, then we don't need to check whether execute `flagPartitionProcessor` + // otherwise we need to check global stats initialized for each partition table + if !b.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { b.optFlag = b.optFlag | flagPartitionProcessor - b.ctx.GetSessionVars().StmtCtx.UseDynamicPruneMode = false - if isDynamicEnabled { - b.ctx.GetSessionVars().StmtCtx.AppendWarning( - fmt.Errorf("disable dynamic pruning due to %s has no global stats", tableInfo.Name.String())) + } else { + if !b.ctx.GetSessionVars().StmtCtx.UseDynamicPruneMode { + b.optFlag = b.optFlag | flagPartitionProcessor + } else { + h := domain.GetDomain(b.ctx).StatsHandle() + tblStats := h.GetTableStats(tableInfo) + isDynamicEnabled := b.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() + globalStatsReady := tblStats.IsInitialized() + // If dynamic partition prune isn't enabled or global stats is not ready, we won't enable dynamic prune mode in query + usePartitionProcessor := !isDynamicEnabled || !globalStatsReady + + failpoint.Inject("forceDynamicPrune", func(val failpoint.Value) { + if val.(bool) { + if isDynamicEnabled { + usePartitionProcessor = false + } + } + }) + + if usePartitionProcessor { + b.optFlag = b.optFlag | flagPartitionProcessor + b.ctx.GetSessionVars().StmtCtx.UseDynamicPruneMode = false + if isDynamicEnabled { + b.ctx.GetSessionVars().StmtCtx.AppendWarning( + fmt.Errorf("disable dynamic pruning due to %s has no global stats", tableInfo.Name.String())) + } + } } } - pt := tbl.(table.PartitionedTable) // check partition by name. if len(tn.PartitionNames) > 0 { @@ -4447,11 +4533,15 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as return nil, ErrPartitionClauseOnNonpartitioned } - // Skip storage engine check for CreateView. - if b.capFlag&canExpandAST == 0 { - possiblePaths, err = filterPathByIsolationRead(b.ctx, possiblePaths, tblName, dbName) - if err != nil { - return nil, err + // remain tikv access path to generate point get acceess path if existed + // see detail in issue: https://github.com/pingcap/tidb/issues/39543 + if !(b.isForUpdateRead && b.ctx.GetSessionVars().TxnCtx.IsExplicit) { + // Skip storage engine check for CreateView. + if b.capFlag&canExpandAST == 0 { + possiblePaths, err = filterPathByIsolationRead(b.ctx, possiblePaths, tblName, dbName) + if err != nil { + return nil, err + } } } @@ -4603,7 +4693,10 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as if i < len(columns) { if columns[i].IsGenerated() && !columns[i].GeneratedStored { var err error + originVal := b.allowBuildCastArray + b.allowBuildCastArray = true expr, _, err = b.rewrite(ctx, columns[i].GeneratedExpr, ds, nil, true) + b.allowBuildCastArray = originVal if err != nil { return nil, err } @@ -4923,7 +5016,10 @@ func (b *PlanBuilder) checkRecursiveView(dbName model.CIStr, tableName model.CIS } // BuildDataSourceFromView is used to build LogicalPlan from view -func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model.CIStr, tableInfo *model.TableInfo) (LogicalPlan, error) { +// qbNameMap4View and viewHints are used for the view's hint. +// qbNameMap4View maps the query block name to the view table lists. +// viewHints group the view hints based on the view's query block name. +func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model.CIStr, tableInfo *model.TableInfo, qbNameMap4View map[string][]ast.HintTable, viewHints map[string][]*ast.TableOptimizerHint) (LogicalPlan, error) { viewDepth := b.ctx.GetSessionVars().StmtCtx.ViewDepth b.ctx.GetSessionVars().StmtCtx.ViewDepth++ deferFunc, err := b.checkRecursiveView(dbName, tableInfo.Name) @@ -4958,6 +5054,51 @@ func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model. b.buildingCTE = o }() + hintProcessor := &hint.BlockHintProcessor{Ctx: b.ctx} + selectNode.Accept(hintProcessor) + currentQbNameMap4View := make(map[string][]ast.HintTable) + currentQbHints4View := make(map[string][]*ast.TableOptimizerHint) + currentQbHints := make(map[int][]*ast.TableOptimizerHint) + currentQbNameMap := make(map[string]int) + + for qbName, viewQbNameHint := range qbNameMap4View { + // Check whether the view hint belong the current view or its nested views. + selectOffset := -1 + if len(viewQbNameHint) == 0 { + selectOffset = 1 + } else if len(viewQbNameHint) == 1 && viewQbNameHint[0].TableName.L == "" { + selectOffset = hintProcessor.GetHintOffset(viewQbNameHint[0].QBName, -1) + } else { + currentQbNameMap4View[qbName] = viewQbNameHint + currentQbHints4View[qbName] = viewHints[qbName] + } + + if selectOffset != -1 { + // If the hint belongs to the current view and not belongs to it's nested views, we should convert the view hint to the normal hint. + // After we convert the view hint to the normal hint, it can be reused the origin hint's infrastructure. + currentQbHints[selectOffset] = viewHints[qbName] + currentQbNameMap[qbName] = selectOffset + + delete(qbNameMap4View, qbName) + delete(viewHints, qbName) + } + } + + hintProcessor.QbNameMap4View = qbNameMap4View + hintProcessor.QbHints4View = viewHints + hintProcessor.QbNameUsed4View = make(map[string]struct{}) + hintProcessor.QbHints = currentQbHints + hintProcessor.QbNameMap = currentQbNameMap + + originHintProcessor := b.hintProcessor + originPlannerSelectBlockAsName := b.ctx.GetSessionVars().PlannerSelectBlockAsName + b.hintProcessor = hintProcessor + b.ctx.GetSessionVars().PlannerSelectBlockAsName = make([]ast.HintTable, hintProcessor.MaxSelectStmtOffset()+1) + defer func() { + b.hintProcessor.HandleUnusedViewHints() + b.hintProcessor = originHintProcessor + b.ctx.GetSessionVars().PlannerSelectBlockAsName = originPlannerSelectBlockAsName + }() selectLogicalPlan, err := b.Build(ctx, selectNode) if err != nil { if terror.ErrorNotEqual(err, ErrViewRecursive) && @@ -5398,7 +5539,7 @@ func (b *PlanBuilder) buildUpdate(ctx context.Context, update *ast.UpdateStmt) ( } updt.PartitionedTable = b.partitionedTable updt.tblID2Table = tblID2table - err = updt.buildOnUpdateFKChecks(b.ctx, b.is, tblID2table) + err = updt.buildOnUpdateFKTriggers(b.ctx, b.is, tblID2table) return updt, err } @@ -5618,7 +5759,10 @@ func (b *PlanBuilder) buildUpdateLists(ctx context.Context, tableList []*ast.Tab } } + o := b.allowBuildCastArray + b.allowBuildCastArray = true newExpr, np, err = b.rewriteWithPreprocess(ctx, assign.Expr, p, nil, nil, false, rewritePreprocess(assign)) + b.allowBuildCastArray = o if err != nil { return nil, nil, false, err } @@ -5874,7 +6018,7 @@ func (b *PlanBuilder) buildDelete(ctx context.Context, ds *ast.DeleteStmt) (Plan if err != nil { return nil, err } - err = del.buildOnDeleteFKChecks(b.ctx, b.is, tblID2table) + err = del.buildOnDeleteFKTriggers(b.ctx, b.is, tblID2table) return del, err } @@ -6081,7 +6225,7 @@ func (b *PlanBuilder) buildWindowFunctionFrameBound(_ context.Context, spec *ast if bound.Type == ast.CurrentRow { return bound, nil } - numRows, _, _ := getUintFromNode(b.ctx, boundClause.Expr) + numRows, _, _ := getUintFromNode(b.ctx, boundClause.Expr, false) bound.Num = numRows return bound, nil } @@ -6397,7 +6541,7 @@ func (b *PlanBuilder) checkOriginWindowFrameBound(bound *ast.FrameBound, spec *a if bound.Unit != ast.TimeUnitInvalid { return ErrWindowRowsIntervalUse.GenWithStackByArgs(getWindowName(spec.Name.O)) } - _, isNull, isExpectedType := getUintFromNode(b.ctx, bound.Expr) + _, isNull, isExpectedType := getUintFromNode(b.ctx, bound.Expr, false) if isNull || !isExpectedType { return ErrWindowFrameIllegal.GenWithStackByArgs(getWindowName(spec.Name.O)) } diff --git a/planner/core/logical_plan_test.go b/planner/core/logical_plan_test.go index 4e320c62e2e50..82786703338f4 100644 --- a/planner/core/logical_plan_test.go +++ b/planner/core/logical_plan_test.go @@ -502,7 +502,7 @@ func TestSubquery(t *testing.T) { stmt, err := s.p.ParseOneStmt(ca, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) p, _, err := BuildLogicalPlanForTest(ctx, s.ctx, stmt, s.is) require.NoError(t, err) @@ -530,7 +530,7 @@ func TestPlanBuilder(t *testing.T) { require.NoError(t, err, comment) s.ctx.GetSessionVars().SetHashJoinConcurrency(1) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) p, _, err := BuildLogicalPlanForTest(ctx, s.ctx, stmt, s.is) require.NoError(t, err) @@ -863,7 +863,7 @@ func TestValidate(t *testing.T) { err: ErrUnknownColumn, }, { - sql: "select * from t t1 use index(e)", + sql: "select * from t t1 use index(x)", err: ErrKeyDoesNotExist, }, { @@ -927,7 +927,7 @@ func TestValidate(t *testing.T) { comment := fmt.Sprintf("for %s", sql) stmt, err := s.p.ParseOneStmt(sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) _, _, err = BuildLogicalPlanForTest(ctx, s.ctx, stmt, s.is) if tt.err == nil { @@ -1422,7 +1422,7 @@ func TestVisitInfo(t *testing.T) { require.NoError(t, err, comment) // TODO: to fix, Table 'test.ttt' doesn't exist - _ = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + _ = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) domain.GetDomain(sctx).MockInfoCacheAndLoadInfoSchema(s.is) @@ -1502,7 +1502,7 @@ func TestUnion(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tt) stmt, err := s.p.ParseOneStmt(tt, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) @@ -1535,7 +1535,7 @@ func TestTopNPushDown(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tt) stmt, err := s.p.ParseOneStmt(tt, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) @@ -1612,7 +1612,7 @@ func TestOuterJoinEliminator(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tt) stmt, err := s.p.ParseOneStmt(tt, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) @@ -1649,7 +1649,7 @@ func TestSelectView(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tt.sql) stmt, err := s.p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) builder, _ := NewPlanBuilder().Init(MockContext(), s.is, &hint.BlockHintProcessor{}) p, err := builder.Build(ctx, stmt) @@ -1732,7 +1732,7 @@ func (s *plannerSuiteWithOptimizeVars) optimize(ctx context.Context, sql string) if err != nil { return nil, nil, err } - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) if err != nil { return nil, nil, err } @@ -1841,7 +1841,7 @@ func TestSkylinePruning(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tt.sql) stmt, err := s.p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) @@ -1914,7 +1914,7 @@ func TestFastPlanContextTables(t *testing.T) { for _, tt := range tests { stmt, err := s.p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) s.ctx.GetSessionVars().StmtCtx.Tables = nil p := TryFastPlan(s.ctx, stmt) @@ -1946,7 +1946,7 @@ func TestUpdateEQCond(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tt.sql) stmt, err := s.p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) @@ -1965,7 +1965,7 @@ func TestConflictedJoinTypeHints(t *testing.T) { ctx := context.TODO() stmt, err := s.p.ParseOneStmt(sql, "", "") require.NoError(t, err) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) @@ -1988,7 +1988,7 @@ func TestSimplyOuterJoinWithOnlyOuterExpr(t *testing.T) { ctx := context.TODO() stmt, err := s.p.ParseOneStmt(sql, "", "") require.NoError(t, err) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err) sctx := MockContext() builder, _ := NewPlanBuilder().Init(sctx, s.is, &hint.BlockHintProcessor{}) @@ -2042,7 +2042,7 @@ func TestResolvingCorrelatedAggregate(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tt.sql) stmt, err := s.p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err, comment) p, _, err := BuildLogicalPlanForTest(ctx, s.ctx, stmt, s.is) require.NoError(t, err, comment) @@ -2084,7 +2084,7 @@ func TestFastPathInvalidBatchPointGet(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, tc.sql) stmt, err := s.p.ParseOneStmt(tc.sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err, comment) plan := TryFastPlan(s.ctx, stmt) if tc.fastPlan { @@ -2106,7 +2106,7 @@ func TestTraceFastPlan(t *testing.T) { comment := fmt.Sprintf("sql:%s", sql) stmt, err := s.p.ParseOneStmt(sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err, comment) plan := TryFastPlan(s.ctx, stmt) require.NotNil(t, plan) diff --git a/planner/core/logical_plan_trace_test.go b/planner/core/logical_plan_trace_test.go index 5bf38b6e18f86..7233b49cb24e1 100644 --- a/planner/core/logical_plan_trace_test.go +++ b/planner/core/logical_plan_trace_test.go @@ -399,7 +399,7 @@ func TestSingleRuleTraceStep(t *testing.T) { comment := fmt.Sprintf("case:%v sql:%s", i, sql) stmt, err := s.p.ParseOneStmt(sql, "", "") require.NoError(t, err, comment) - err = Preprocess(s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) + err = Preprocess(context.Background(), s.ctx, stmt, WithPreprocessorReturn(&PreprocessorReturn{InfoSchema: s.is})) require.NoError(t, err, comment) sctx := MockContext() sctx.GetSessionVars().StmtCtx.EnableOptimizeTrace = true diff --git a/planner/core/logical_plans.go b/planner/core/logical_plans.go index e3c24d2375134..f6bb7284e9afc 100644 --- a/planner/core/logical_plans.go +++ b/planner/core/logical_plans.go @@ -123,9 +123,12 @@ const ( preferRightAsHJProbe preferMergeJoin preferBCJoin + preferShuffleJoin preferRewriteSemiJoin preferHashAgg preferStreamAgg + preferMPP1PhaseAgg + preferMPP2PhaseAgg ) const ( @@ -1217,6 +1220,10 @@ type DataSource struct { // contain unique index and the first field is tidb_shard(), // such as (tidb_shard(a), a ...), the fields are more than 2 containExprPrefixUk bool + + // colsRequiringFullLen is the columns that must be fetched with full length. + // It is used to decide whether single scan is enough when reading from an index. + colsRequiringFullLen []*expression.Column } // ExtractCorrelatedCols implements LogicalPlan interface. @@ -1340,7 +1347,7 @@ func (ds *DataSource) Convert2Gathers() (gathers []LogicalPlan) { path.FullIdxCols, path.FullIdxColLens = expression.IndexInfo2Cols(ds.Columns, ds.schema.Columns, path.Index) path.IdxCols, path.IdxColLens = expression.IndexInfo2PrefixCols(ds.Columns, ds.schema.Columns, path.Index) // If index columns can cover all of the needed columns, we can use a IndexGather + IndexScan. - if ds.isCoveringIndex(ds.schema.Columns, path.FullIdxCols, path.FullIdxColLens, ds.tableInfo) { + if ds.isSingleScan(path.FullIdxCols, path.FullIdxColLens) { gathers = append(gathers, ds.buildIndexGather(path)) } // TODO: If index columns can not cover the schema, use IndexLookUpGather. @@ -1545,7 +1552,7 @@ func (ds *DataSource) deriveIndexPathStats(path *util.AccessPath, _ []expression } } var indexFilters []expression.Expression - indexFilters, path.TableFilters = ds.splitIndexFilterConditions(path.TableFilters, path.FullIdxCols, path.FullIdxColLens, ds.tableInfo) + indexFilters, path.TableFilters = ds.splitIndexFilterConditions(path.TableFilters, path.FullIdxCols, path.FullIdxColLens) path.IndexFilters = append(path.IndexFilters, indexFilters...) // If the `CountAfterAccess` is less than `stats.RowCount`, there must be some inconsistent stats info. // We prefer the `stats.RowCount` because it could use more stats info to calculate the selectivity. @@ -1871,15 +1878,16 @@ func ExtractCorColumnsBySchema4PhysicalPlan(p PhysicalPlan, schema *expression.S // ShowContents stores the contents for the `SHOW` statement. type ShowContents struct { - Tp ast.ShowStmtType // Databases/Tables/Columns/.... - DBName string - Table *ast.TableName // Used for showing columns. - Partition model.CIStr // Use for showing partition - Column *ast.ColumnName // Used for `desc table column`. - IndexName model.CIStr - Flag int // Some flag parsed from sql, such as FULL. - User *auth.UserIdentity // Used for show grants. - Roles []*auth.RoleIdentity // Used for show grants. + Tp ast.ShowStmtType // Databases/Tables/Columns/.... + DBName string + Table *ast.TableName // Used for showing columns. + Partition model.CIStr // Use for showing partition + Column *ast.ColumnName // Used for `desc table column`. + IndexName model.CIStr + ResourceGroupName string // Used for showing resource group + Flag int // Some flag parsed from sql, such as FULL. + User *auth.UserIdentity // Used for show grants. + Roles []*auth.RoleIdentity // Used for show grants. CountWarningsOrErrors bool // Used for showing count(*) warnings | errors diff --git a/planner/core/main_test.go b/planner/core/main_test.go index 5818baba86199..230cc3f4bdd2d 100644 --- a/planner/core/main_test.go +++ b/planner/core/main_test.go @@ -50,15 +50,18 @@ func TestMain(m *testing.M) { testDataMap.LoadTestSuiteData("testdata", "join_reorder_suite") testDataMap.LoadTestSuiteData("testdata", "flat_plan_suite") testDataMap.LoadTestSuiteData("testdata", "binary_plan_suite") + testDataMap.LoadTestSuiteData("testdata", "json_plan_suite") indexMergeSuiteData = testDataMap["index_merge_suite"] planSuiteUnexportedData = testDataMap["plan_suite_unexported"] opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } callback := func(i int) int { @@ -128,3 +131,11 @@ func GetFlatPlanSuiteData() testdata.TestData { func GetBinaryPlanSuiteData() testdata.TestData { return testDataMap["binary_plan_suite"] } + +func GetIndexMergeSuiteData() testdata.TestData { + return testDataMap["index_merge_suite"] +} + +func GetJSONPlanSuiteData() testdata.TestData { + return testDataMap["json_plan_suite"] +} diff --git a/planner/core/memtable_predicate_extractor.go b/planner/core/memtable_predicate_extractor.go index 1b8d953518b49..b4fa83d335a36 100644 --- a/planner/core/memtable_predicate_extractor.go +++ b/planner/core/memtable_predicate_extractor.go @@ -83,10 +83,14 @@ func (extractHelper) extractColInConsExpr(extractCols map[int64]*types.FieldName results := make([]types.Datum, 0, len(args[1:])) for _, arg := range args[1:] { constant, ok := arg.(*expression.Constant) - if !ok || constant.DeferredExpr != nil || constant.ParamMarker != nil { + if !ok || constant.DeferredExpr != nil { return "", nil } - results = append(results, constant.Value) + v := constant.Value + if constant.ParamMarker != nil { + v = constant.ParamMarker.GetUserVar() + } + results = append(results, v) } return name.ColName.L, results } @@ -117,10 +121,14 @@ func (extractHelper) extractColBinaryOpConsExpr(extractCols map[int64]*types.Fie // SELECT * FROM t1 WHERE c='rhs' // SELECT * FROM t1 WHERE 'lhs'=c constant, ok := args[1-colIdx].(*expression.Constant) - if !ok || constant.DeferredExpr != nil || constant.ParamMarker != nil { + if !ok || constant.DeferredExpr != nil { return "", nil } - return name.ColName.L, []types.Datum{constant.Value} + v := constant.Value + if constant.ParamMarker != nil { + v = constant.ParamMarker.GetUserVar() + } + return name.ColName.L, []types.Datum{v} } // extract the OR expression, e.g: diff --git a/planner/core/memtable_predicate_extractor_test.go b/planner/core/memtable_predicate_extractor_test.go index 97d55b09ed8ec..ecf7c47218ab9 100644 --- a/planner/core/memtable_predicate_extractor_test.go +++ b/planner/core/memtable_predicate_extractor_test.go @@ -25,10 +25,14 @@ import ( "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/planner" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/hint" "github.com/pingcap/tidb/util/set" "github.com/stretchr/testify/require" @@ -1749,3 +1753,112 @@ PARTITION BY RANGE COLUMNS ( id ) ( require.Equal(t, ca.tableIDs, tableids) } } + +func TestExtractorInPreparedStmt(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + var cases = []struct { + prepared string + userVars []interface{} + params []interface{} + checker func(extractor plannercore.MemTablePredicateExtractor) + }{ + { + prepared: "select * from information_schema.TIKV_REGION_STATUS where table_id = ?", + userVars: []interface{}{1}, + params: []interface{}{1}, + checker: func(extractor plannercore.MemTablePredicateExtractor) { + rse := extractor.(*plannercore.TiKVRegionStatusExtractor) + tableids := rse.GetTablesID() + slices.Sort(tableids) + require.Equal(t, []int64{1}, tableids) + }, + }, + { + prepared: "select * from information_schema.TIKV_REGION_STATUS where table_id = ? or table_id = ?", + userVars: []interface{}{1, 2}, + params: []interface{}{1, 2}, + checker: func(extractor plannercore.MemTablePredicateExtractor) { + rse := extractor.(*plannercore.TiKVRegionStatusExtractor) + tableids := rse.GetTablesID() + slices.Sort(tableids) + require.Equal(t, []int64{1, 2}, tableids) + }, + }, + { + prepared: "select * from information_schema.TIKV_REGION_STATUS where table_id in (?,?)", + userVars: []interface{}{1, 2}, + params: []interface{}{1, 2}, + checker: func(extractor plannercore.MemTablePredicateExtractor) { + rse := extractor.(*plannercore.TiKVRegionStatusExtractor) + tableids := rse.GetTablesID() + slices.Sort(tableids) + require.Equal(t, []int64{1, 2}, tableids) + }, + }, + { + prepared: "select * from information_schema.COLUMNS where table_name like ?", + userVars: []interface{}{`"a%"`}, + params: []interface{}{"a%"}, + checker: func(extractor plannercore.MemTablePredicateExtractor) { + rse := extractor.(*plannercore.ColumnsTableExtractor) + require.EqualValues(t, []string{"a%"}, rse.TableNamePatterns) + }, + }, + { + prepared: "select * from information_schema.tidb_hot_regions_history where update_time>=?", + userVars: []interface{}{"cast('2019-10-10 10:10:10' as datetime)"}, + params: []interface{}{func() types.Time { + tt, err := types.ParseTimestamp(tk.Session().GetSessionVars().StmtCtx, "2019-10-10 10:10:10") + require.NoError(t, err) + return tt + }()}, + checker: func(extractor plannercore.MemTablePredicateExtractor) { + rse := extractor.(*plannercore.HotRegionsHistoryTableExtractor) + require.Equal(t, timestamp(t, "2019-10-10 10:10:10"), rse.StartTime) + }, + }, + } + + // text protocol + parser := parser.New() + for _, ca := range cases { + tk.MustExec(fmt.Sprintf("prepare stmt from '%s'", ca.prepared)) + setStmt := "set " + exec := "execute stmt using " + for i, uv := range ca.userVars { + name := fmt.Sprintf("@a%d", i) + setStmt += fmt.Sprintf("%s=%v", name, uv) + exec += name + if i != len(ca.userVars)-1 { + setStmt += "," + exec += "," + } + } + tk.MustExec(setStmt) + stmt, err := parser.ParseOneStmt(exec, "", "") + require.NoError(t, err) + plan, _, err := planner.OptimizeExecStmt(context.Background(), tk.Session(), stmt.(*ast.ExecuteStmt), dom.InfoSchema()) + require.NoError(t, err) + extractor := plan.(*plannercore.Execute).Plan.(*plannercore.PhysicalMemTable).Extractor + ca.checker(extractor) + } + + // binary protocol + for _, ca := range cases { + id, _, _, err := tk.Session().PrepareStmt(ca.prepared) + require.NoError(t, err) + prepStmt, err := tk.Session().GetSessionVars().GetPreparedStmtByID(id) + require.NoError(t, err) + params := expression.Args2Expressions4Test(ca.params...) + execStmt := &ast.ExecuteStmt{ + BinaryArgs: params, + PrepStmt: prepStmt, + } + plan, _, err := planner.OptimizeExecStmt(context.Background(), tk.Session(), execStmt, dom.InfoSchema()) + require.NoError(t, err) + extractor := plan.(*plannercore.Execute).Plan.(*plannercore.PhysicalMemTable).Extractor + ca.checker(extractor) + } +} diff --git a/planner/core/mock.go b/planner/core/mock.go index e96c10ca20d13..93d389352e3af 100644 --- a/planner/core/mock.go +++ b/planner/core/mock.go @@ -73,7 +73,7 @@ func MockSignedTable() *model.TableInfo { Unique: true, }, { - Name: model.NewCIStr("e"), + Name: model.NewCIStr("x"), Columns: []*model.IndexColumn{ { Name: model.NewCIStr("e"), @@ -401,9 +401,13 @@ func MockContext() sessionctx.Context { ctx.Store = &mock.Store{ Client: &mock.Client{}, } + initStatsCtx := mock.NewContext() + initStatsCtx.Store = &mock.Store{ + Client: &mock.Client{}, + } ctx.GetSessionVars().CurrentDB = "test" do := domain.NewMockDomain() - if err := do.CreateStatsHandle(ctx); err != nil { + if err := do.CreateStatsHandle(ctx, initStatsCtx); err != nil { panic(fmt.Sprintf("create mock context panic: %+v", err)) } domain.BindDomain(ctx, do) diff --git a/planner/core/optimizer.go b/planner/core/optimizer.go index 09c370dd11f60..a5db249fd2be1 100644 --- a/planner/core/optimizer.go +++ b/planner/core/optimizer.go @@ -16,11 +16,16 @@ package core import ( "context" + "fmt" "math" + "strconv" "github.com/pingcap/errors" + "github.com/pingcap/failpoint" + "github.com/pingcap/kvproto/pkg/diagnosticspb" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/expression/aggregation" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/lock" @@ -295,7 +300,10 @@ func DoOptimize(ctx context.Context, sctx sessionctx.Context, flag uint64, logic if err != nil { return nil, 0, err } - finalPlan := postOptimize(sctx, physical) + finalPlan, err := postOptimize(ctx, sctx, physical) + if err != nil { + return nil, 0, err + } if sctx.GetSessionVars().StmtCtx.EnableOptimizerCETrace { refineCETrace(sctx) @@ -372,25 +380,282 @@ func mergeContinuousSelections(p PhysicalPlan) { } } -func postOptimize(sctx sessionctx.Context, plan PhysicalPlan) PhysicalPlan { +func postOptimize(ctx context.Context, sctx sessionctx.Context, plan PhysicalPlan) (PhysicalPlan, error) { // some cases from update optimize will require avoiding projection elimination. // see comments ahead of call of DoOptimize in function of buildUpdate(). + err := prunePhysicalColumns(sctx, plan) + if err != nil { + return nil, err + } plan = eliminatePhysicalProjection(plan) plan = InjectExtraProjection(plan) mergeContinuousSelections(plan) plan = eliminateUnionScanAndLock(sctx, plan) plan = enableParallelApply(sctx, plan) - handleFineGrainedShuffle(sctx, plan) - checkPlanCacheable(sctx, plan) - return plan + handleFineGrainedShuffle(ctx, sctx, plan) + propagateProbeParents(plan, nil) + countStarRewrite(plan) + return plan, nil +} + +// prunePhysicalColumns currently only work for MPP(HashJoin<-Exchange). +// Here add projection instead of pruning columns directly for safety considerations. +// And projection is cheap here for it saves the network cost and work in memory. +func prunePhysicalColumns(sctx sessionctx.Context, plan PhysicalPlan) error { + if tableReader, ok := plan.(*PhysicalTableReader); ok { + if _, isExchangeSender := tableReader.tablePlan.(*PhysicalExchangeSender); isExchangeSender { + err := prunePhysicalColumnsInternal(sctx, tableReader.tablePlan) + if err != nil { + return err + } + } + } else { + for _, child := range plan.Children() { + return prunePhysicalColumns(sctx, child) + } + } + return nil +} + +func (p *PhysicalHashJoin) extractUsedCols(parentUsedCols []*expression.Column) (leftCols []*expression.Column, rightCols []*expression.Column) { + for _, eqCond := range p.EqualConditions { + parentUsedCols = append(parentUsedCols, expression.ExtractColumns(eqCond)...) + } + for _, neCond := range p.NAEqualConditions { + parentUsedCols = append(parentUsedCols, expression.ExtractColumns(neCond)...) + } + for _, leftCond := range p.LeftConditions { + parentUsedCols = append(parentUsedCols, expression.ExtractColumns(leftCond)...) + } + for _, rightCond := range p.RightConditions { + parentUsedCols = append(parentUsedCols, expression.ExtractColumns(rightCond)...) + } + for _, otherCond := range p.OtherConditions { + parentUsedCols = append(parentUsedCols, expression.ExtractColumns(otherCond)...) + } + lChild := p.children[0] + rChild := p.children[1] + for _, col := range parentUsedCols { + if lChild.Schema().Contains(col) { + leftCols = append(leftCols, col) + } else if rChild.Schema().Contains(col) { + rightCols = append(rightCols, col) + } + } + return leftCols, rightCols +} + +func prunePhysicalColumnForHashJoinChild(sctx sessionctx.Context, hashJoin *PhysicalHashJoin, joinUsedCols []*expression.Column, sender *PhysicalExchangeSender) error { + var err error + joinUsed := expression.GetUsedList(joinUsedCols, sender.Schema()) + hashCols := make([]*expression.Column, len(sender.HashCols)) + for i, mppCol := range sender.HashCols { + hashCols[i] = mppCol.Col + } + hashUsed := expression.GetUsedList(hashCols, sender.Schema()) + + needPrune := false + usedExprs := make([]expression.Expression, len(sender.Schema().Columns)) + prunedSchema := sender.Schema().Clone() + for i := len(joinUsed) - 1; i >= 0; i-- { + usedExprs[i] = sender.Schema().Columns[i] + if !joinUsed[i] && !hashUsed[i] { + needPrune = true + usedExprs = append(usedExprs[:i], usedExprs[i+1:]...) + prunedSchema.Columns = append(prunedSchema.Columns[:i], prunedSchema.Columns[i+1:]...) + } + } + + if needPrune && len(sender.children) > 0 { + ch := sender.children[0] + proj := PhysicalProjection{ + Exprs: usedExprs, + }.Init(sctx, ch.statsInfo(), ch.SelectBlockOffset()) + + proj.SetSchema(prunedSchema) + proj.SetChildren(ch) + sender.children[0] = proj + + // Resolve Indices from bottom to up + err = proj.ResolveIndicesItself() + if err != nil { + return err + } + err = sender.ResolveIndicesItself() + if err != nil { + return err + } + err = hashJoin.ResolveIndicesItself() + if err != nil { + return err + } + } + return err +} + +func prunePhysicalColumnsInternal(sctx sessionctx.Context, plan PhysicalPlan) error { + var err error + switch x := plan.(type) { + case *PhysicalHashJoin: + schemaColumns := x.Schema().Clone().Columns + leftCols, rightCols := x.extractUsedCols(schemaColumns) + matchPattern := false + for i := 0; i <= 1; i++ { + // Pattern: HashJoin <- ExchangeReceiver <- ExchangeSender + matchPattern = false + var exchangeSender *PhysicalExchangeSender + if receiver, ok := x.children[i].(*PhysicalExchangeReceiver); ok { + exchangeSender, matchPattern = receiver.children[0].(*PhysicalExchangeSender) + } + + if matchPattern { + if i == 0 { + err = prunePhysicalColumnForHashJoinChild(sctx, x, leftCols, exchangeSender) + } else { + err = prunePhysicalColumnForHashJoinChild(sctx, x, rightCols, exchangeSender) + } + if err != nil { + return nil + } + } + + /// recursively travel the physical plan + err = prunePhysicalColumnsInternal(sctx, x.children[i]) + if err != nil { + return nil + } + } + default: + for _, child := range x.Children() { + err = prunePhysicalColumnsInternal(sctx, child) + if err != nil { + return err + } + } + } + return nil +} + +/* +* +The countStarRewriter is used to rewrite + + count(*) -> count(not null column) + +**Only for TiFlash** +Attention: +Since count(*) is directly translated into count(1) during grammar parsing, +the rewritten pattern actually matches count(constant) + +Pattern: +PhysicalAggregation: count(constant) + + | + TableFullScan: TiFlash + +Optimize: +Table + + + +Query: select count(*) from table +ColumnPruningRule: datasource pick row_id +countStarRewrite: datasource pick k1 instead of row_id + + rewrite count(*) -> count(k1) + +Rewritten Query: select count(k1) from table +*/ +func countStarRewrite(plan PhysicalPlan) { + countStarRewriteInternal(plan) + if tableReader, ok := plan.(*PhysicalTableReader); ok { + countStarRewrite(tableReader.tablePlan) + } else { + for _, child := range plan.Children() { + countStarRewrite(child) + } + } +} + +func countStarRewriteInternal(plan PhysicalPlan) { + // match pattern any agg(count(constant)) -> tablefullscan(tiflash) + var physicalAgg *basePhysicalAgg + switch x := plan.(type) { + case *PhysicalHashAgg: + physicalAgg = x.getPointer() + case *PhysicalStreamAgg: + physicalAgg = x.getPointer() + default: + return + } + if len(physicalAgg.GroupByItems) > 0 || len(physicalAgg.children) != 1 { + return + } + for _, aggFunc := range physicalAgg.AggFuncs { + if aggFunc.Name != "count" || len(aggFunc.Args) != 1 || aggFunc.HasDistinct { + return + } + if _, ok := aggFunc.Args[0].(*expression.Constant); !ok { + return + } + } + physicalTableScan, ok := physicalAgg.Children()[0].(*PhysicalTableScan) + if !ok || !physicalTableScan.isFullScan() || physicalTableScan.StoreType != kv.TiFlash || len(physicalTableScan.schema.Columns) != 1 { + return + } + // rewrite datasource and agg args + rewriteTableScanAndAggArgs(physicalTableScan, physicalAgg.AggFuncs) +} + +// rewriteTableScanAndAggArgs Pick the narrowest and not null column from table +// If there is no not null column in Data Source, the row_id or pk column will be retained +func rewriteTableScanAndAggArgs(physicalTableScan *PhysicalTableScan, aggFuncs []*aggregation.AggFuncDesc) { + var resultColumnInfo *model.ColumnInfo + var resultColumn *expression.Column + + resultColumnInfo = physicalTableScan.Columns[0] + resultColumn = physicalTableScan.schema.Columns[0] + // prefer not null column from table + for _, columnInfo := range physicalTableScan.Table.Columns { + if columnInfo.FieldType.IsVarLengthType() { + continue + } + if mysql.HasNotNullFlag(columnInfo.GetFlag()) { + if columnInfo.GetFlen() < resultColumnInfo.GetFlen() { + resultColumnInfo = columnInfo + resultColumn = &expression.Column{ + UniqueID: physicalTableScan.ctx.GetSessionVars().AllocPlanColumnID(), + ID: resultColumnInfo.ID, + RetType: resultColumnInfo.FieldType.Clone(), + OrigName: fmt.Sprintf("%s.%s.%s", physicalTableScan.DBName.L, physicalTableScan.Table.Name.L, resultColumnInfo.Name), + } + } + } + } + // table scan (row_id) -> (not null column) + physicalTableScan.Columns[0] = resultColumnInfo + physicalTableScan.schema.Columns[0] = resultColumn + // agg arg count(1) -> count(not null column) + arg := resultColumn.Clone() + for _, aggFunc := range aggFuncs { + constExpr, ok := aggFunc.Args[0].(*expression.Constant) + if !ok { + return + } + // count(null) shouldn't be rewritten + if constExpr.Value.IsNull() { + continue + } + aggFunc.Args[0] = arg + } } // Only for MPP(Window<-[Sort]<-ExchangeReceiver<-ExchangeSender). // TiFlashFineGrainedShuffleStreamCount: // < 0: fine grained shuffle is disabled. // > 0: use TiFlashFineGrainedShuffleStreamCount as stream count. -// == 0: use TiFlashMaxThreads as stream count when it's greater than 0. Otherwise use DefStreamCountWhenMaxThreadsNotSet. -func handleFineGrainedShuffle(sctx sessionctx.Context, plan PhysicalPlan) { +// == 0: use TiFlashMaxThreads as stream count when it's greater than 0. Otherwise set status as uninitialized. +func handleFineGrainedShuffle(ctx context.Context, sctx sessionctx.Context, plan PhysicalPlan) { streamCount := sctx.GetSessionVars().TiFlashFineGrainedShuffleStreamCount if streamCount < 0 { return @@ -398,22 +663,27 @@ func handleFineGrainedShuffle(sctx sessionctx.Context, plan PhysicalPlan) { if streamCount == 0 { if sctx.GetSessionVars().TiFlashMaxThreads > 0 { streamCount = sctx.GetSessionVars().TiFlashMaxThreads - } else { - streamCount = variable.DefStreamCountWhenMaxThreadsNotSet } } - setupFineGrainedShuffle(uint64(streamCount), plan) + // use two separate cluster info to avoid grpc calls cost + tiflashServerCountInfo := tiflashClusterInfo{unInitialized, 0} + streamCountInfo := tiflashClusterInfo{unInitialized, 0} + if streamCount != 0 { + streamCountInfo.itemStatus = initialized + streamCountInfo.itemValue = uint64(streamCount) + } + setupFineGrainedShuffle(ctx, sctx, &streamCountInfo, &tiflashServerCountInfo, plan) } -func setupFineGrainedShuffle(streamCount uint64, plan PhysicalPlan) { +func setupFineGrainedShuffle(ctx context.Context, sctx sessionctx.Context, streamCountInfo *tiflashClusterInfo, tiflashServerCountInfo *tiflashClusterInfo, plan PhysicalPlan) { if tableReader, ok := plan.(*PhysicalTableReader); ok { if _, isExchangeSender := tableReader.tablePlan.(*PhysicalExchangeSender); isExchangeSender { helper := fineGrainedShuffleHelper{shuffleTarget: unknown, plans: make([]*basePhysicalPlan, 1)} - setupFineGrainedShuffleInternal(tableReader.tablePlan, &helper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, tableReader.tablePlan, &helper, streamCountInfo, tiflashServerCountInfo) } } else { for _, child := range plan.Children() { - setupFineGrainedShuffle(streamCount, child) + setupFineGrainedShuffle(ctx, sctx, streamCountInfo, tiflashServerCountInfo, child) } } } @@ -424,16 +694,32 @@ const ( unknown shuffleTarget = iota window joinBuild + hashAgg ) type fineGrainedShuffleHelper struct { shuffleTarget shuffleTarget plans []*basePhysicalPlan + joinKeysCount int +} + +type tiflashClusterInfoStatus uint8 + +const ( + unInitialized tiflashClusterInfoStatus = iota + initialized + failed +) + +type tiflashClusterInfo struct { + itemStatus tiflashClusterInfoStatus + itemValue uint64 } func (h *fineGrainedShuffleHelper) clear() { h.shuffleTarget = unknown h.plans = h.plans[:0] + h.joinKeysCount = 0 } func (h *fineGrainedShuffleHelper) updateTarget(t shuffleTarget, p *basePhysicalPlan) { @@ -441,14 +727,153 @@ func (h *fineGrainedShuffleHelper) updateTarget(t shuffleTarget, p *basePhysical h.plans = append(h.plans, p) } -func setupFineGrainedShuffleInternal(plan PhysicalPlan, helper *fineGrainedShuffleHelper, streamCount uint64) { +// calculateTiFlashStreamCountUsingMinLogicalCores uses minimal logical cpu cores among tiflash servers, and divide by 2 +// return false, 0 if any err happens +func calculateTiFlashStreamCountUsingMinLogicalCores(ctx context.Context, sctx sessionctx.Context, serversInfo []infoschema.ServerInfo) (bool, uint64) { + failpoint.Inject("mockTiFlashStreamCountUsingMinLogicalCores", func(val failpoint.Value) { + intVal, err := strconv.Atoi(val.(string)) + if err == nil { + failpoint.Return(true, uint64(intVal)) + } else { + failpoint.Return(false, 0) + } + }) + rows, err := infoschema.FetchClusterServerInfoWithoutPrivilegeCheck(ctx, sctx, serversInfo, diagnosticspb.ServerInfoType_HardwareInfo, false) + if err != nil { + return false, 0 + } + var initialMaxCores uint64 = 10000 + var minLogicalCores uint64 = initialMaxCores // set to a large enough value here + for _, row := range rows { + if row[4].GetString() == "cpu-logical-cores" { + logicalCpus, err := strconv.Atoi(row[5].GetString()) + if err == nil && logicalCpus > 0 && uint64(logicalCpus) < minLogicalCores { + minLogicalCores = uint64(logicalCpus) + } + } + } + // No need to check len(serersInfo) == serverCount here, since missing some servers' info won't affect the correctness + if minLogicalCores > 1 && minLogicalCores != initialMaxCores { + return true, minLogicalCores / 2 + } + + return false, 0 +} + +func checkFineGrainedShuffleForJoinAgg(ctx context.Context, sctx sessionctx.Context, streamCountInfo *tiflashClusterInfo, tiflashServerCountInfo *tiflashClusterInfo, exchangeColCount int, splitLimit uint64) (applyFlag bool, streamCount uint64) { + switch (*streamCountInfo).itemStatus { + case unInitialized: + streamCount = 4 // assume 8c node in cluster as minimal, stream count is 8 / 2 = 4 + case initialized: + streamCount = (*streamCountInfo).itemValue + case failed: + return false, 0 // probably won't reach this path + } + + var tiflashServerCount uint64 = 0 + switch (*tiflashServerCountInfo).itemStatus { + case unInitialized: + serversInfo, err := infoschema.GetTiFlashServerInfo(sctx) + if err != nil { + (*tiflashServerCountInfo).itemStatus = failed + (*tiflashServerCountInfo).itemValue = 0 + if (*streamCountInfo).itemStatus == unInitialized { + setDefaultStreamCount(streamCountInfo) + } + return false, 0 + } + tiflashServerCount = uint64(len(serversInfo)) + (*tiflashServerCountInfo).itemStatus = initialized + (*tiflashServerCountInfo).itemValue = tiflashServerCount + case initialized: + tiflashServerCount = (*tiflashServerCountInfo).itemValue + case failed: + return false, 0 + } + + // if already exceeds splitLimit, no need to fetch actual logical cores + if tiflashServerCount*uint64(exchangeColCount)*streamCount > splitLimit { + return false, 0 + } + + // if streamCount already initialized, and can pass splitLimit check + if (*streamCountInfo).itemStatus == initialized { + return true, streamCount + } + + serversInfo, err := infoschema.GetTiFlashServerInfo(sctx) + if err != nil { + (*tiflashServerCountInfo).itemStatus = failed + (*tiflashServerCountInfo).itemValue = 0 + return false, 0 + } + flag, temStreamCount := calculateTiFlashStreamCountUsingMinLogicalCores(ctx, sctx, serversInfo) + if !flag { + setDefaultStreamCount(streamCountInfo) + (*tiflashServerCountInfo).itemStatus = failed + return false, 0 + } + streamCount = temStreamCount + (*streamCountInfo).itemStatus = initialized + (*streamCountInfo).itemValue = streamCount + applyFlag = tiflashServerCount*uint64(exchangeColCount)*streamCount <= splitLimit + return applyFlag, streamCount +} + +func inferFineGrainedShuffleStreamCountForWindow(ctx context.Context, sctx sessionctx.Context, streamCountInfo *tiflashClusterInfo, tiflashServerCountInfo *tiflashClusterInfo) (streamCount uint64) { + switch (*streamCountInfo).itemStatus { + case unInitialized: + if (*tiflashServerCountInfo).itemStatus == failed { + setDefaultStreamCount(streamCountInfo) + streamCount = (*streamCountInfo).itemValue + break + } + + serversInfo, err := infoschema.GetTiFlashServerInfo(sctx) + if err != nil { + setDefaultStreamCount(streamCountInfo) + streamCount = (*streamCountInfo).itemValue + (*tiflashServerCountInfo).itemStatus = failed + break + } + + if (*tiflashServerCountInfo).itemStatus == unInitialized { + (*tiflashServerCountInfo).itemStatus = initialized + (*tiflashServerCountInfo).itemValue = uint64(len(serversInfo)) + } + + flag, temStreamCount := calculateTiFlashStreamCountUsingMinLogicalCores(ctx, sctx, serversInfo) + if !flag { + setDefaultStreamCount(streamCountInfo) + streamCount = (*streamCountInfo).itemValue + (*tiflashServerCountInfo).itemStatus = failed + break + } + streamCount = temStreamCount + (*streamCountInfo).itemStatus = initialized + (*streamCountInfo).itemValue = streamCount + case initialized: + streamCount = (*streamCountInfo).itemValue + case failed: + setDefaultStreamCount(streamCountInfo) + streamCount = (*streamCountInfo).itemValue + } + return streamCount +} + +func setDefaultStreamCount(streamCountInfo *tiflashClusterInfo) { + (*streamCountInfo).itemStatus = initialized + (*streamCountInfo).itemValue = variable.DefStreamCountWhenMaxThreadsNotSet +} + +func setupFineGrainedShuffleInternal(ctx context.Context, sctx sessionctx.Context, plan PhysicalPlan, helper *fineGrainedShuffleHelper, streamCountInfo *tiflashClusterInfo, tiflashServerCountInfo *tiflashClusterInfo) { switch x := plan.(type) { case *PhysicalWindow: // Do not clear the plans because window executor will keep the data partition. // For non hash partition window function, there will be a passthrough ExchangeSender to collect data, // which will break data partition. helper.updateTarget(window, &x.basePhysicalPlan) - setupFineGrainedShuffleInternal(x.children[0], helper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, x.children[0], helper, streamCountInfo, tiflashServerCountInfo) case *PhysicalSort: if x.IsPartialSort { // Partial sort will keep the data partition. @@ -457,90 +882,123 @@ func setupFineGrainedShuffleInternal(plan PhysicalPlan, helper *fineGrainedShuff // Global sort will break the data partition. helper.clear() } - setupFineGrainedShuffleInternal(x.children[0], helper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, x.children[0], helper, streamCountInfo, tiflashServerCountInfo) case *PhysicalSelection: helper.plans = append(helper.plans, &x.basePhysicalPlan) - setupFineGrainedShuffleInternal(x.children[0], helper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, x.children[0], helper, streamCountInfo, tiflashServerCountInfo) case *PhysicalProjection: helper.plans = append(helper.plans, &x.basePhysicalPlan) - setupFineGrainedShuffleInternal(x.children[0], helper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, x.children[0], helper, streamCountInfo, tiflashServerCountInfo) case *PhysicalExchangeReceiver: helper.plans = append(helper.plans, &x.basePhysicalPlan) - setupFineGrainedShuffleInternal(x.children[0], helper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, x.children[0], helper, streamCountInfo, tiflashServerCountInfo) case *PhysicalHashAgg: - // HashAgg is not implemented for now. - helper.clear() - setupFineGrainedShuffleInternal(x.children[0], helper, streamCount) + // Todo: allow hash aggregation's output still benefits from fine grained shuffle + aggHelper := fineGrainedShuffleHelper{shuffleTarget: hashAgg, plans: []*basePhysicalPlan{}} + aggHelper.plans = append(aggHelper.plans, &x.basePhysicalPlan) + setupFineGrainedShuffleInternal(ctx, sctx, x.children[0], &aggHelper, streamCountInfo, tiflashServerCountInfo) case *PhysicalHashJoin: child0 := x.children[0] child1 := x.children[1] - if x.InnerChildIdx == 0 { - // Child0 is build side. - child0Helper := fineGrainedShuffleHelper{shuffleTarget: joinBuild, plans: []*basePhysicalPlan{}} - setupFineGrainedShuffleInternal(child0, &child0Helper, streamCount) - - // HashJoin is not implemented for now. - helper.clear() - setupFineGrainedShuffleInternal(child1, helper, streamCount) - } else { + buildChild := child0 + probChild := child1 + joinKeys := x.LeftJoinKeys + if x.InnerChildIdx != 0 { // Child1 is build side. - child1Helper := fineGrainedShuffleHelper{shuffleTarget: joinBuild, plans: []*basePhysicalPlan{}} - setupFineGrainedShuffleInternal(child1, &child1Helper, streamCount) - - // HashJoin is not implemented for now. - helper.clear() - setupFineGrainedShuffleInternal(child0, helper, streamCount) + buildChild = child1 + joinKeys = x.RightJoinKeys + probChild = child0 } + if len(joinKeys) > 0 { // Not cross join + buildHelper := fineGrainedShuffleHelper{shuffleTarget: joinBuild, plans: []*basePhysicalPlan{}} + buildHelper.plans = append(buildHelper.plans, &x.basePhysicalPlan) + buildHelper.joinKeysCount = len(joinKeys) + setupFineGrainedShuffleInternal(ctx, sctx, buildChild, &buildHelper, streamCountInfo, tiflashServerCountInfo) + } else { + buildHelper := fineGrainedShuffleHelper{shuffleTarget: unknown, plans: []*basePhysicalPlan{}} + setupFineGrainedShuffleInternal(ctx, sctx, buildChild, &buildHelper, streamCountInfo, tiflashServerCountInfo) + } + // don't apply fine grained shuffle for probe side + helper.clear() + setupFineGrainedShuffleInternal(ctx, sctx, probChild, helper, streamCountInfo, tiflashServerCountInfo) case *PhysicalExchangeSender: if x.ExchangeType == tipb.ExchangeType_Hash { - if helper.shuffleTarget == window { - // Set up stream count for all plans based on shuffle target type. - // Currently, only enable fine grained shuffle if the shuffle target is window. + // Set up stream count for all plans based on shuffle target type. + var exchangeColCount = x.Schema().Len() + switch helper.shuffleTarget { + case window: + streamCount := inferFineGrainedShuffleStreamCountForWindow(ctx, sctx, streamCountInfo, tiflashServerCountInfo) x.TiFlashFineGrainedShuffleStreamCount = streamCount for _, p := range helper.plans { p.TiFlashFineGrainedShuffleStreamCount = streamCount } + case hashAgg: + applyFlag, streamCount := checkFineGrainedShuffleForJoinAgg(ctx, sctx, streamCountInfo, tiflashServerCountInfo, exchangeColCount, 1200) // 1200: performance test result + if applyFlag { + x.TiFlashFineGrainedShuffleStreamCount = streamCount + for _, p := range helper.plans { + p.TiFlashFineGrainedShuffleStreamCount = streamCount + } + } + case joinBuild: + // Support hashJoin only when shuffle hash keys equals to join keys due to tiflash implementations + if len(x.HashCols) != helper.joinKeysCount { + break + } + applyFlag, streamCount := checkFineGrainedShuffleForJoinAgg(ctx, sctx, streamCountInfo, tiflashServerCountInfo, exchangeColCount, 600) // 600: performance test result + if applyFlag { + x.TiFlashFineGrainedShuffleStreamCount = streamCount + for _, p := range helper.plans { + p.TiFlashFineGrainedShuffleStreamCount = streamCount + } + } } } // exchange sender will break the data partition. helper.clear() - setupFineGrainedShuffleInternal(x.children[0], helper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, x.children[0], helper, streamCountInfo, tiflashServerCountInfo) default: for _, child := range x.Children() { childHelper := fineGrainedShuffleHelper{shuffleTarget: unknown, plans: []*basePhysicalPlan{}} - setupFineGrainedShuffleInternal(child, &childHelper, streamCount) + setupFineGrainedShuffleInternal(ctx, sctx, child, &childHelper, streamCountInfo, tiflashServerCountInfo) } } } -// checkPlanCacheable used to check whether a plan can be cached. Plans that -// meet the following characteristics cannot be cached: -// 1. Use the TiFlash engine. -// Todo: make more careful check here. -func checkPlanCacheable(sctx sessionctx.Context, plan PhysicalPlan) { - if sctx.GetSessionVars().StmtCtx.UseCache && useTiFlash(plan) { - sctx.GetSessionVars().StmtCtx.SkipPlanCache = true - } -} +// propagateProbeParents doesn't affect the execution plan, it only sets the probeParents field of a PhysicalPlan. +// It's for handling the inconsistency between row count in the statsInfo and the recorded actual row count. Please +// see comments in PhysicalPlan for details. +func propagateProbeParents(plan PhysicalPlan, probeParents []PhysicalPlan) { + plan.setProbeParents(probeParents) + switch x := plan.(type) { + case *PhysicalApply, *PhysicalIndexJoin, *PhysicalIndexHashJoin, *PhysicalIndexMergeJoin: + if join, ok := plan.(interface{ getInnerChildIdx() int }); ok { + propagateProbeParents(plan.Children()[1-join.getInnerChildIdx()], probeParents) -// useTiFlash used to check whether the plan use the TiFlash engine. -func useTiFlash(p PhysicalPlan) bool { - switch x := p.(type) { + // The core logic of this method: + // Record every Apply and Index Join we met, record it in a slice, and set it in their inner children. + newParents := make([]PhysicalPlan, len(probeParents), len(probeParents)+1) + copy(newParents, probeParents) + newParents = append(newParents, plan) + propagateProbeParents(plan.Children()[join.getInnerChildIdx()], newParents) + } case *PhysicalTableReader: - switch x.StoreType { - case kv.TiFlash: - return true - default: - return false + propagateProbeParents(x.tablePlan, probeParents) + case *PhysicalIndexReader: + propagateProbeParents(x.indexPlan, probeParents) + case *PhysicalIndexLookUpReader: + propagateProbeParents(x.indexPlan, probeParents) + propagateProbeParents(x.tablePlan, probeParents) + case *PhysicalIndexMergeReader: + for _, pchild := range x.partialPlans { + propagateProbeParents(pchild, probeParents) } + propagateProbeParents(x.tablePlan, probeParents) default: - if len(p.Children()) > 0 { - for _, plan := range p.Children() { - return useTiFlash(plan) - } + for _, child := range plan.Children() { + propagateProbeParents(child, probeParents) } } - return false } func enableParallelApply(sctx sessionctx.Context, plan PhysicalPlan) PhysicalPlan { diff --git a/planner/core/optimizer_test.go b/planner/core/optimizer_test.go index 6cf80c57fa5ec..59afdf9e9afba 100644 --- a/planner/core/optimizer_test.go +++ b/planner/core/optimizer_test.go @@ -16,8 +16,12 @@ package core import ( "reflect" + "strings" "testing" + "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/planner/property" "github.com/pingcap/tidb/types" @@ -161,7 +165,7 @@ func TestHandleFineGrainedShuffle(t *testing.T) { sctx.GetSessionVars().TiFlashFineGrainedShuffleStreamCount = expStreamCount start := func(p PhysicalPlan, expStreamCount int64, expChildCount int, curChildCount int) { - handleFineGrainedShuffle(sctx, tableReader) + handleFineGrainedShuffle(nil, sctx, tableReader) check(p, expStreamCount, expChildCount, curChildCount) clear(plans) } @@ -287,4 +291,210 @@ func TestHandleFineGrainedShuffle(t *testing.T) { tableScan1 = &PhysicalTableScan{} hashSender1.children = []PhysicalPlan{tableScan1} start(partWindow, expStreamCount, 3, 0) + + instances := []string{ + "tiflash,127.0.0.1:3933,127.0.0.1:7777,,", + "tikv,127.0.0.1:11080,127.0.0.1:10080,,", + } + fpName := "github.com/pingcap/tidb/infoschema/mockStoreServerInfo" + fpExpr := `return("` + strings.Join(instances, ";") + `")` + require.NoError(t, failpoint.Enable(fpName, fpExpr)) + defer func() { require.NoError(t, failpoint.Disable(fpName)) }() + fpName2 := "github.com/pingcap/tidb/planner/core/mockTiFlashStreamCountUsingMinLogicalCores" + require.NoError(t, failpoint.Enable(fpName2, `return("8")`)) + sctx.GetSessionVars().TiFlashFineGrainedShuffleStreamCount = 0 + + col0 := &expression.Column{ + UniqueID: sctx.GetSessionVars().AllocPlanColumnID(), + RetType: types.NewFieldType(mysql.TypeLonglong), + } + cond, err := expression.NewFunction(sctx, ast.EQ, types.NewFieldType(mysql.TypeTiny), col0, col0) + require.True(t, err == nil) + sf, isSF := cond.(*expression.ScalarFunction) + require.True(t, isSF) + var partitionCols = make([]*property.MPPPartitionColumn, 0, 1) + partitionCols = append(partitionCols, &property.MPPPartitionColumn{ + Col: col0, + CollateID: property.GetCollateIDByNameForPartition(col0.GetType().GetCollate()), + }) + + // HashAgg(x) <- ExchangeReceiver <- ExchangeSender + tableReader.tablePlan = passSender + hashAgg = &PhysicalHashAgg{} + passSender.children = []PhysicalPlan{hashAgg} + hashAgg.children = []PhysicalPlan{recv} + recv.children = []PhysicalPlan{hashSender} + hashSender.children = []PhysicalPlan{tableScan} + tableScan.Schema().Columns = append(tableScan.Schema().Columns, col0) + start(hashAgg, 8, 3, 0) + + // Join(x) <- ExchangeReceiver <- ExchangeSender + // <- ExchangeReceiver <- ExchangeSender + tableReader.tablePlan = passSender + hashJoin = &PhysicalHashJoin{} + hashJoin.EqualConditions = append(hashJoin.EqualConditions, sf) + hashJoin.RightJoinKeys = append(hashJoin.RightJoinKeys, col0) + hashJoin.InnerChildIdx = 1 + passSender.children = []PhysicalPlan{hashJoin} + recv = &PhysicalExchangeReceiver{} + recv1 = &PhysicalExchangeReceiver{} + tableScan = &PhysicalTableScan{} + tableScan1 = &PhysicalTableScan{} + hashSender = &PhysicalExchangeSender{ + ExchangeType: tipb.ExchangeType_Hash, + } + hashSender1 = &PhysicalExchangeSender{ + ExchangeType: tipb.ExchangeType_Hash, + } + hashJoin.children = []PhysicalPlan{recv, recv1} + recv.children = []PhysicalPlan{hashSender} + recv1.children = []PhysicalPlan{hashSender1} + hashSender.children = []PhysicalPlan{tableScan} + hashSender1.children = []PhysicalPlan{tableScan1} + hashSender1.HashCols = partitionCols + tableScan1.Schema().Columns = append(tableScan1.Schema().Columns, col0) + handleFineGrainedShuffle(nil, sctx, tableReader) + require.Equal(t, uint64(8), hashJoin.TiFlashFineGrainedShuffleStreamCount) + require.Equal(t, uint64(8), recv1.TiFlashFineGrainedShuffleStreamCount) + require.Equal(t, uint64(8), hashSender1.TiFlashFineGrainedShuffleStreamCount) + require.Equal(t, uint64(0), recv.TiFlashFineGrainedShuffleStreamCount) + require.Equal(t, uint64(0), hashSender.TiFlashFineGrainedShuffleStreamCount) + clear(plans) + + require.NoError(t, failpoint.Disable(fpName2)) + require.NoError(t, failpoint.Enable(fpName2, `return("8000")`)) + // HashAgg(x) <- ExchangeReceiver <- ExchangeSender, exceed splitLimit + tableReader.tablePlan = passSender + hashAgg = &PhysicalHashAgg{} + passSender.children = []PhysicalPlan{hashAgg} + hashAgg.children = []PhysicalPlan{recv} + recv.children = []PhysicalPlan{hashSender} + hashSender.children = []PhysicalPlan{tableScan} + tableScan.Schema().Columns = append(tableScan.Schema().Columns, col0) + start(hashAgg, 0, 3, 0) + + // exceed splitLimit + // Join(x) <- ExchangeReceiver <- ExchangeSender + // <- ExchangeReceiver <- ExchangeSender + tableReader.tablePlan = passSender + hashJoin = &PhysicalHashJoin{} + hashJoin.EqualConditions = append(hashJoin.EqualConditions, sf) + hashJoin.LeftJoinKeys = append(hashJoin.LeftJoinKeys, col0) + hashJoin.InnerChildIdx = 1 + passSender.children = []PhysicalPlan{hashJoin} + recv1 = &PhysicalExchangeReceiver{} + tableScan1 = &PhysicalTableScan{} + hashSender1 = &PhysicalExchangeSender{ + ExchangeType: tipb.ExchangeType_Hash, + } + hashJoin.children = []PhysicalPlan{recv, recv1} + recv.children = []PhysicalPlan{hashSender} + recv1.children = []PhysicalPlan{hashSender1} + hashSender.children = []PhysicalPlan{tableScan} + hashSender1.children = []PhysicalPlan{tableScan1} + hashSender1.HashCols = partitionCols + tableScan1.Schema().Columns = append(tableScan1.Schema().Columns, col0) + start(hashJoin, 0, 3, 0) + require.NoError(t, failpoint.Disable(fpName2)) +} + +// Test for core.prunePhysicalColumns() +func TestPrunePhysicalColumns(t *testing.T) { + sctx := MockContext() + col0 := &expression.Column{ + UniqueID: sctx.GetSessionVars().AllocPlanColumnID(), + RetType: types.NewFieldType(mysql.TypeLonglong), + } + col1 := &expression.Column{ + UniqueID: sctx.GetSessionVars().AllocPlanColumnID(), + RetType: types.NewFieldType(mysql.TypeLonglong), + } + col2 := &expression.Column{ + UniqueID: sctx.GetSessionVars().AllocPlanColumnID(), + RetType: types.NewFieldType(mysql.TypeLonglong), + } + col3 := &expression.Column{ + UniqueID: sctx.GetSessionVars().AllocPlanColumnID(), + RetType: types.NewFieldType(mysql.TypeLonglong), + } + + // Join[col2, col3; col2==col3] <- ExchangeReceiver[col0, col1, col2] <- ExchangeSender[col0, col1, col2] <- Selection[col0, col1, col2; col0 < col1] <- TableScan[col0, col1, col2] + // <- ExchangeReceiver1[col3] <- ExchangeSender1[col3] <- TableScan1[col3] + tableReader := &PhysicalTableReader{} + passSender := &PhysicalExchangeSender{ + ExchangeType: tipb.ExchangeType_PassThrough, + } + hashJoin := &PhysicalHashJoin{} + recv := &PhysicalExchangeReceiver{} + recv1 := &PhysicalExchangeReceiver{} + hashSender := &PhysicalExchangeSender{ + ExchangeType: tipb.ExchangeType_Hash, + } + hashSender1 := &PhysicalExchangeSender{ + ExchangeType: tipb.ExchangeType_Hash, + } + tableScan := &PhysicalTableScan{} + tableScan1 := &PhysicalTableScan{} + + tableReader.tablePlan = passSender + passSender.children = []PhysicalPlan{hashJoin} + hashJoin.children = []PhysicalPlan{recv, recv1} + selection := &PhysicalSelection{} + + cond, err := expression.NewFunction(sctx, ast.EQ, types.NewFieldType(mysql.TypeTiny), col2, col3) + require.True(t, err == nil) + sf, isSF := cond.(*expression.ScalarFunction) + require.True(t, isSF) + hashJoin.EqualConditions = append(hashJoin.EqualConditions, sf) + hashJoin.LeftJoinKeys = append(hashJoin.LeftJoinKeys, col2) + hashJoin.RightJoinKeys = append(hashJoin.RightJoinKeys, col3) + hashJoinSchema := make([]*expression.Column, 0) + hashJoinSchema = append(hashJoinSchema, col3) + hashJoin.SetSchema(expression.NewSchema(hashJoinSchema...)) + + selection.SetChildren(tableScan) + hashSender.SetChildren(selection) + var partitionCols = make([]*property.MPPPartitionColumn, 0, 1) + partitionCols = append(partitionCols, &property.MPPPartitionColumn{ + Col: col2, + CollateID: property.GetCollateIDByNameForPartition(col2.GetType().GetCollate()), + }) + hashSender.HashCols = partitionCols + recv.SetChildren(hashSender) + tableScan.Schema().Columns = append(tableScan.Schema().Columns, col0, col1, col2) + + hashSender1.SetChildren(tableScan1) + recv1.SetChildren(hashSender1) + tableScan1.Schema().Columns = append(tableScan1.Schema().Columns, col3) + + prunePhysicalColumns(sctx, tableReader) + + // Optimized Plan: + // Join[col2, col3; col2==col3] <- ExchangeReceiver[col2] <- ExchangeSender[col2;col2] <- Projection[col2] <- Selection[col0, col1, col2; col0 < col1] <- TableScan[col0, col1, col2] + // <- ExchangeReceiver1[col3] <- ExchangeSender1[col3] <- TableScan1[col3] + require.True(t, len(recv.Schema().Columns) == 1) + require.True(t, recv.Schema().Contains(col2)) + require.False(t, recv.Schema().Contains(col0)) + require.False(t, recv.Schema().Contains(col1)) + require.True(t, len(recv.children[0].Children()) == 1) + physicalProj := recv.children[0].Children()[0] + switch x := physicalProj.(type) { + case *PhysicalProjection: + require.True(t, x.Schema().Contains(col2)) + require.False(t, recv.Schema().Contains(col0)) + require.False(t, recv.Schema().Contains(col1)) + // Check PhysicalProj resolved index + require.True(t, len(x.Exprs) == 1) + require.True(t, x.Exprs[0].(*expression.Column).Index == 2) + default: + require.True(t, false) + } + + // Check resolved indices + require.True(t, hashJoin.LeftJoinKeys[0].Index == 0) + require.True(t, hashSender.HashCols[0].Col.Index == 0) + + // Check recv1,no changes + require.True(t, len(recv1.Schema().Columns) == 1) + require.True(t, recv1.Schema().Contains(col3)) } diff --git a/planner/core/partition_pruner_test.go b/planner/core/partition_pruner_test.go index fffef54373bd8..166f251b53fc3 100644 --- a/planner/core/partition_pruner_test.go +++ b/planner/core/partition_pruner_test.go @@ -68,6 +68,7 @@ func TestHashPartitionPruner(t *testing.T) { func TestRangeColumnPartitionPruningForIn(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop database if exists test_range_col_in") tk.MustExec("create database test_range_col_in") tk.MustExec("use test_range_col_in") @@ -78,7 +79,7 @@ func TestRangeColumnPartitionPruningForIn(t *testing.T) { tk.MustExec(`CREATE TABLE t1 ( id bigint(20) NOT NULL AUTO_INCREMENT, dt date, - PRIMARY KEY (id,dt)) + PRIMARY KEY (id,dt) NONCLUSTERED) PARTITION BY RANGE COLUMNS(dt) ( PARTITION p20201125 VALUES LESS THAN ("20201126"), PARTITION p20201126 VALUES LESS THAN ("20201127"), @@ -260,6 +261,7 @@ func TestListPartitionPruner(t *testing.T) { tk.MustExec("drop database if exists test_partition;") tk.MustExec("create database test_partition") tk.MustExec("use test_partition") + tk.MustExec("set tidb_cost_model_version=2") tk.Session().GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeIntOnly tk.MustExec("set @@session.tidb_enable_list_partition = ON") tk.MustExec(`set @@session.tidb_regard_null_as_point=false`) @@ -310,15 +312,15 @@ func TestListPartitionPruner(t *testing.T) { for i, tt := range input { testdata.OnRecord(func() { output[i].SQL = tt - output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) + output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Sort().Rows()) output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + tt).Rows()) }) tk.MustQuery("explain format = 'brief' " + tt).Check(testkit.Rows(output[i].Plan...)) - result := tk.MustQuery(tt) + result := tk.MustQuery(tt).Sort() result.Check(testkit.Rows(output[i].Result...)) // If the query doesn't specified the partition, compare the result with normal table if !strings.Contains(tt, "partition(") { - result.Check(tk2.MustQuery(tt).Rows()) + result.Check(tk.MustQuery(tt).Sort().Rows()) valid = true } require.True(t, valid) @@ -330,6 +332,7 @@ func TestListColumnsPartitionPruner(t *testing.T) { defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set @@session.tidb_enable_list_partition = ON") tk.MustExec("drop database if exists test_partition;") tk.MustExec("create database test_partition") @@ -342,6 +345,7 @@ func TestListColumnsPartitionPruner(t *testing.T) { // tk1 use to test partition table with index. tk1 := testkit.NewTestKit(t, store) + tk1.MustExec("set tidb_cost_model_version=2") tk1.MustExec("drop database if exists test_partition_1;") tk1.MustExec(`set @@session.tidb_regard_null_as_point=false`) tk1.MustExec("create database test_partition_1") @@ -354,6 +358,7 @@ func TestListColumnsPartitionPruner(t *testing.T) { // tk2 use to compare the result with normal table. tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("set tidb_cost_model_version=2") tk2.MustExec("drop database if exists test_partition_2;") tk2.MustExec(`set @@session.tidb_regard_null_as_point=false`) tk2.MustExec("create database test_partition_2") @@ -388,7 +393,7 @@ func TestListColumnsPartitionPruner(t *testing.T) { indexPlanTree := testdata.ConvertRowsToStrings(indexPlan.Rows()) testdata.OnRecord(func() { output[i].SQL = tt.SQL - output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(tt.SQL).Rows()) + output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(tt.SQL).Sort().Rows()) // Test for table without index. output[i].Plan = planTree // Test for table with index. @@ -403,14 +408,14 @@ func TestListColumnsPartitionPruner(t *testing.T) { checkPrunePartitionInfo(t, tt.SQL, tt.Pruner, indexPlanTree) // compare the result. - result := tk.MustQuery(tt.SQL) + result := tk.MustQuery(tt.SQL).Sort() idxResult := tk1.MustQuery(tt.SQL) - result.Check(idxResult.Rows()) + result.Check(idxResult.Sort().Rows()) result.Check(testkit.Rows(output[i].Result...)) // If the query doesn't specified the partition, compare the result with normal table if !strings.Contains(tt.SQL, "partition(") { - result.Check(tk2.MustQuery(tt.SQL).Rows()) + result.Check(tk2.MustQuery(tt.SQL).Sort().Rows()) valid = true } } diff --git a/planner/core/physical_plan_test.go b/planner/core/physical_plan_test.go index c00fbbaac80de..640c0f04630c1 100644 --- a/planner/core/physical_plan_test.go +++ b/planner/core/physical_plan_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/pingcap/failpoint" + "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/infoschema" @@ -38,10 +39,14 @@ import ( "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" + "github.com/pingcap/tidb/store/mockstore" + "github.com/pingcap/tidb/store/mockstore/unistore" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/testkit/external" "github.com/pingcap/tidb/testkit/testdata" "github.com/pingcap/tidb/util/hint" "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/testutils" ) func TestDAGPlanBuilderSimpleCase(t *testing.T) { @@ -49,6 +54,7 @@ func TestDAGPlanBuilderSimpleCase(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set tidb_opt_limit_push_down_threshold=0") var input []string var output []struct { @@ -123,7 +129,7 @@ func TestAnalyzeBuildSucc(t *testing.T) { } else if err != nil { continue } - err = core.Preprocess(tk.Session(), stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) + err = core.Preprocess(context.Background(), tk.Session(), stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) require.NoError(t, err) _, _, err = planner.Optimize(context.Background(), tk.Session(), stmt, is) if tt.succ { @@ -165,7 +171,7 @@ func TestAnalyzeSetRate(t *testing.T) { stmt, err := p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = core.Preprocess(tk.Session(), stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) + err = core.Preprocess(context.Background(), tk.Session(), stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) require.NoError(t, err, comment) p, _, err := planner.Optimize(context.Background(), tk.Session(), stmt, is) require.NoError(t, err, comment) @@ -179,6 +185,7 @@ func TestDAGPlanBuilderJoin(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") sessionVars := tk.Session().GetSessionVars() sessionVars.ExecutorConcurrency = 4 sessionVars.SetDistSQLScanConcurrency(15) @@ -214,6 +221,7 @@ func TestDAGPlanBuilderSubquery(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by sessionVars := tk.Session().GetSessionVars() sessionVars.SetHashAggFinalConcurrency(1) @@ -310,7 +318,7 @@ func TestDAGPlanBuilderBasePhysicalPlan(t *testing.T) { stmt, err := p.ParseOneStmt(tt, "", "") require.NoError(t, err, comment) - err = core.Preprocess(se, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) + err = core.Preprocess(context.Background(), se, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), se, stmt, is) require.NoError(t, err) @@ -363,36 +371,37 @@ func TestDAGPlanBuilderUnion(t *testing.T) { func TestDAGPlanBuilderUnionScan(t *testing.T) { store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int, c int)") var input []string var output []struct { SQL string Best string } + planSuiteData := core.GetPlanSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + p := parser.New() - is := infoschema.MockInfoSchema([]*model.TableInfo{core.MockSignedTable(), core.MockUnsignedTable()}) for i, tt := range input { + tk.MustExec("begin;") + tk.MustExec("insert into t values(2, 2, 2);") + comment := fmt.Sprintf("input: %s", tt) stmt, err := p.ParseOneStmt(tt, "", "") require.NoError(t, err, comment) - require.NoError(t, sessiontxn.NewTxn(context.Background(), tk.Session())) - - // Make txn not read only. - txn, err := tk.Session().Txn(true) - require.NoError(t, err) - err = txn.Set(kv.Key("AAA"), []byte("BBB")) - require.NoError(t, err) - tk.Session().StmtCommit() - p, _, err := planner.Optimize(context.TODO(), tk.Session(), stmt, is) + dom := domain.GetDomain(tk.Session()) + require.NoError(t, dom.Reload()) + plan, _, err := planner.Optimize(context.TODO(), tk.Session(), stmt, dom.InfoSchema()) require.NoError(t, err) testdata.OnRecord(func() { output[i].SQL = tt - output[i].Best = core.ToString(p) + output[i].Best = core.ToString(plan) }) - require.Equal(t, output[i].Best, core.ToString(p), fmt.Sprintf("input: %s", tt)) + require.Equal(t, output[i].Best, core.ToString(plan), fmt.Sprintf("input: %s", tt)) + tk.MustExec("rollback;") } } @@ -400,6 +409,7 @@ func TestDAGPlanBuilderAgg(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by sessionVars := tk.Session().GetSessionVars() sessionVars.SetHashAggFinalConcurrency(1) @@ -436,6 +446,7 @@ func TestRefine(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") var input []string var output []struct { @@ -467,6 +478,7 @@ func TestAggEliminator(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set tidb_opt_limit_push_down_threshold=0") tk.MustExec("set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by var input []string @@ -593,6 +605,7 @@ func TestIndexJoinUnionScan(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("create table t (a int primary key, b int, index idx(a))") tk.MustExec("create table tt (a int primary key) partition by range (a) (partition p0 values less than (100), partition p1 values less than (200))") tk.MustExec(`set @@tidb_partition_prune_mode='` + string(variable.Static) + `'`) @@ -714,6 +727,7 @@ func TestSemiJoinToInner(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") var input []string var output []struct { @@ -774,10 +788,154 @@ func TestUnmatchedTableInHint(t *testing.T) { } } +// withMockTiFlash sets the mockStore to have N TiFlash stores (naming as tiflash0, tiflash1, ...). +func withMockTiFlash(nodes int) mockstore.MockTiKVStoreOption { + return mockstore.WithMultipleOptions( + mockstore.WithClusterInspector(func(c testutils.Cluster) { + mockCluster := c.(*unistore.Cluster) + _, _, region1 := mockstore.BootstrapWithSingleStore(c) + tiflashIdx := 0 + for tiflashIdx < nodes { + store2 := c.AllocID() + peer2 := c.AllocID() + addr2 := fmt.Sprintf("tiflash%d", tiflashIdx) + mockCluster.AddStore(store2, addr2, &metapb.StoreLabel{Key: "engine", Value: "tiflash"}) + mockCluster.AddPeer(region1, store2, peer2) + tiflashIdx++ + } + }), + mockstore.WithStoreType(mockstore.EmbedUnistore), + ) +} + +func TestMPPHints(t *testing.T) { + store := testkit.CreateMockStore(t, withMockTiFlash(2)) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("create table t (a int, b int, c int, index idx_a(a), index idx_b(b))") + tk.MustExec("alter table t set tiflash replica 1") + tk.MustExec("set @@session.tidb_allow_mpp=ON") + tk.MustExec("create definer='root'@'localhost' view v as select a, sum(b) from t group by a, c;") + tk.MustExec("create definer='root'@'localhost' view v1 as select t1.a from t t1, t t2 where t1.a=t2.a;") + tb := external.GetTableByName(t, tk, "test", "t") + err := domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + + var input []string + var output []struct { + SQL string + Plan []string + Warn []string + } + + planSuiteData := core.GetPlanSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + + for i, ts := range input { + testdata.OnRecord(func() { + output[i].SQL = ts + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + ts).Rows()) + output[i].Warn = testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings()) + }) + tk.MustQuery("explain format = 'brief' " + ts).Check(testkit.Rows(output[i].Plan...)) + require.Equal(t, output[i].Warn, testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings())) + } +} + +func TestMPPHintsScope(t *testing.T) { + store := testkit.CreateMockStore(t, withMockTiFlash(2)) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("create table t (a int, b int, c int, index idx_a(a), index idx_b(b))") + tk.MustExec("select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The agg can not push down to the MPP side, the MPP_1PHASE_AGG() hint is invalid")) + tk.MustExec("select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The agg can not push down to the MPP side, the MPP_2PHASE_AGG() hint is invalid")) + tk.MustExec("select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The join can not push down to the MPP side, the shuffle_join() hint is invalid")) + tk.MustExec("select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The join can not push down to the MPP side, the broadcast_join() hint is invalid")) + tk.MustExec("alter table t set tiflash replica 1") + tb := external.GetTableByName(t, tk, "test", "t") + err := domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + tk.MustExec("set @@session.tidb_allow_mpp=true") + tk.MustExec("explain select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c") + tk.MustQuery("show warnings").Check(testkit.Rows()) + tk.MustExec("explain select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c") + tk.MustQuery("show warnings").Check(testkit.Rows()) + tk.MustExec("explain select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("show warnings").Check(testkit.Rows()) + tk.MustExec("explain select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("show warnings").Check(testkit.Rows()) + + tk.MustExec("set @@session.tidb_allow_mpp=false") + tk.MustExec("explain select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The agg can not push down to the MPP side, the MPP_1PHASE_AGG() hint is invalid")) + tk.MustExec("explain select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The agg can not push down to the MPP side, the MPP_2PHASE_AGG() hint is invalid")) + tk.MustExec("explain select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The join can not push down to the MPP side, the shuffle_join() hint is invalid")) + tk.MustExec("explain select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1815 The join can not push down to the MPP side, the broadcast_join() hint is invalid")) +} + +func TestMPPHintsWithBinding(t *testing.T) { + store := testkit.CreateMockStore(t, withMockTiFlash(2)) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") + tk.MustExec("create table t (a int, b int, c int)") + tk.MustExec("alter table t set tiflash replica 1") + tk.MustExec("set @@session.tidb_allow_mpp=ON") + tb := external.GetTableByName(t, tk, "test", "t") + err := domain.GetDomain(tk.Session()).DDL().UpdateTableReplicaInfo(tk.Session(), tb.Meta().ID, true) + require.NoError(t, err) + + tk.MustExec("explain select a, sum(b) from t group by a, c") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + tk.MustExec("create global binding for select a, sum(b) from t group by a, c using select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c;") + tk.MustExec("explain select a, sum(b) from t group by a, c") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res := tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select `a` , sum ( `b` ) from `test` . `t` group by `a` , `c`") + require.Equal(t, res[0][1], "SELECT /*+ read_from_storage(tiflash[`t`]) MPP_1PHASE_AGG()*/ `a`,sum(`b`) FROM `test`.`t` GROUP BY `a`,`c`") + tk.MustExec("create global binding for select a, sum(b) from t group by a, c using select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c;") + tk.MustExec("explain select a, sum(b) from t group by a, c") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select `a` , sum ( `b` ) from `test` . `t` group by `a` , `c`") + require.Equal(t, res[0][1], "SELECT /*+ read_from_storage(tiflash[`t`]) MPP_2PHASE_AGG()*/ `a`,sum(`b`) FROM `test`.`t` GROUP BY `a`,`c`") + tk.MustExec("drop global binding for select a, sum(b) from t group by a, c;") + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, len(res), 0) + + tk.MustExec("explain select * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0")) + tk.MustExec("create global binding for select * from t t1, t t2 where t1.a=t2.a using select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a") + tk.MustExec("explain select * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select * from ( `test` . `t` as `t1` ) join `test` . `t` as `t2` where `t1` . `a` = `t2` . `a`") + require.Equal(t, res[0][1], "SELECT /*+ read_from_storage(tiflash[`t1`, `t2`]) shuffle_join(`t1`, `t2`)*/ * FROM (`test`.`t` AS `t1`) JOIN `test`.`t` AS `t2` WHERE `t1`.`a` = `t2`.`a`") + tk.MustExec("create global binding for select * from t t1, t t2 where t1.a=t2.a using select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a;") + tk.MustExec("explain select * from t t1, t t2 where t1.a=t2.a") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, res[0][0], "select * from ( `test` . `t` as `t1` ) join `test` . `t` as `t2` where `t1` . `a` = `t2` . `a`") + require.Equal(t, res[0][1], "SELECT /*+ read_from_storage(tiflash[`t1`, `t2`]) broadcast_join(`t1`, `t2`)*/ * FROM (`test`.`t` AS `t1`) JOIN `test`.`t` AS `t2` WHERE `t1`.`a` = `t2`.`a`") + tk.MustExec("drop global binding for select * from t t1, t t2 where t1.a=t2.a;") + res = tk.MustQuery("show global bindings").Rows() + require.Equal(t, len(res), 0) +} + func TestHintScope(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") var input []string var output []struct { @@ -811,6 +969,7 @@ func TestJoinHints(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") var input []string var output []struct { @@ -919,6 +1078,7 @@ func TestSemiJoinRewriteHints(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("create table t(a int, b int, c int)") sessionVars := tk.Session().GetSessionVars() @@ -1040,6 +1200,7 @@ func TestLimitToCopHint(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists tn") tk.MustExec("create table tn(a int, b int, c int, d int, key (a, b, c, d))") tk.MustExec(`set tidb_opt_limit_push_down_threshold=0`) @@ -1160,6 +1321,7 @@ func TestForceInlineCTE(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t;") tk.MustExec("CREATE TABLE `t` (`a` int(11));") tk.MustExec("insert into t values (1), (5), (10), (15), (20), (30), (50);") @@ -1260,6 +1422,7 @@ func TestPushdownDistinctEnable(t *testing.T) { vars := []string{ fmt.Sprintf("set @@session.%s = 1", variable.TiDBOptDistinctAggPushDown), "set session tidb_opt_agg_push_down = 1", + "set tidb_cost_model_version = 2", } doTestPushdownDistinct(t, vars, input, output) } @@ -1297,6 +1460,7 @@ func TestPushdownDistinctEnableAggPushDownDisable(t *testing.T) { vars := []string{ fmt.Sprintf("set @@session.%s = 1", variable.TiDBOptDistinctAggPushDown), "set session tidb_opt_agg_push_down = 0", + "set tidb_cost_model_version=2", } doTestPushdownDistinct(t, vars, input, output) } @@ -1494,6 +1658,7 @@ func TestIndexMergeHint(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") var input []string var output []struct { @@ -1547,6 +1712,7 @@ func TestQueryBlockHint(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") var input []string var output []struct { @@ -1635,13 +1801,14 @@ func TestDAGPlanBuilderSplitAvg(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tests := []struct { sql string plan string }{ { sql: "select avg(a),avg(b),avg(c) from t", - plan: "TableReader(Table(t)->StreamAgg)->StreamAgg", + plan: "TableReader(Table(t)->HashAgg)->HashAgg", }, { sql: "select /*+ HASH_AGG() */ avg(a),avg(b),avg(c) from t", @@ -1657,7 +1824,7 @@ func TestDAGPlanBuilderSplitAvg(t *testing.T) { stmt, err := p.ParseOneStmt(tt.sql, "", "") require.NoError(t, err, comment) - err = core.Preprocess(tk.Session(), stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) + err = core.Preprocess(context.Background(), tk.Session(), stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is})) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), tk.Session(), stmt, is) require.NoError(t, err, comment) @@ -1702,6 +1869,7 @@ func TestIndexJoinHint(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`drop table if exists test.t1, test.t2, test.t;`) tk.MustExec(`create table test.t1(a bigint, b bigint, index idx_a(a), index idx_b(b));`) tk.MustExec(`create table test.t2(a bigint, b bigint, index idx_a(a), index idx_b(b));`) @@ -2052,6 +2220,7 @@ func TestSkewDistinctAgg(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("CREATE TABLE `t` (`a` int(11), `b` int(11), `c` int(11), `d` date)") tk.MustExec("insert into t (a,b,c,d) value(1,4,5,'2019-06-01')") @@ -2104,6 +2273,7 @@ func TestHJBuildAndProbeHint(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2, t3") tk.MustExec("create table t1(a int primary key, b int not null)") tk.MustExec("create table t2(a int primary key, b int not null)") @@ -2140,6 +2310,7 @@ func TestHJBuildAndProbeHint4StaticPartitionTable(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2, t3") tk.MustExec(`create table t1(a int, b int) partition by hash(a) partitions 4`) tk.MustExec(`create table t2(a int, b int) partition by hash(a) partitions 5`) @@ -2214,6 +2385,7 @@ func TestHJBuildAndProbeHint4TiFlash(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2, t3") tk.MustExec("create table t1(a int primary key, b int not null)") tk.MustExec("create table t2(a int primary key, b int not null)") @@ -2252,6 +2424,7 @@ func TestHJBuildAndProbeHintWithBinding(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, t1, t2, t3;") tk.MustExec("create table t(a int, b int, key(a));") tk.MustExec("create table t1(a int, b int, key(a));") @@ -2292,6 +2465,7 @@ func TestMPPSinglePartitionType(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists employee") tk.MustExec("create table employee(empid int, deptid int, salary decimal(10,2))") tk.MustExec("set tidb_enforce_mpp=0") @@ -2331,7 +2505,7 @@ func TestPhysicalPlanMemoryTrace(t *testing.T) { ls.ByItems = append(ls.ByItems, &util.ByItems{}) require.Greater(t, ls.MemoryUsage(), size) - //PhysicalProperty + // PhysicalProperty pp := property.PhysicalProperty{} size = pp.MemoryUsage() pp.MPPPartitionCols = append(pp.MPPPartitionCols, &property.MPPPartitionColumn{}) @@ -2353,6 +2527,7 @@ func TestNoDecorrelateHint(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2") tk.MustExec("create table t1(a int, b int)") tk.MustExec("create table t2(a int primary key, b int)") @@ -2378,3 +2553,76 @@ func TestNoDecorrelateHint(t *testing.T) { tk.MustQuery("show warnings").Check(testkit.Rows(output[i].Warning...)) } } + +func TestCountStarForTikv(t *testing.T) { + var ( + input []string + output []struct { + SQL string + Plan []string + Warning []string + } + ) + planSuiteData := core.GetPlanSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") + tk.MustExec("create table t (a int(11) not null, b varchar(10) not null, c date not null, d char(1) not null, e bigint not null, f datetime not null, g bool not null, h bool )") + tk.MustExec("create table t_pick_row_id (a char(20) not null)") + + // tikv + for i, ts := range input { + testdata.OnRecord(func() { + output[i].SQL = ts + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + ts).Rows()) + }) + tk.MustQuery("explain format = 'brief' " + ts).Check(testkit.Rows(output[i].Plan...)) + } +} + +func TestCountStarForTiFlash(t *testing.T) { + var ( + input []string + output []struct { + SQL string + Plan []string + Warning []string + } + ) + planSuiteData := core.GetPlanSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=1") + tk.MustExec("create table t (a int(11) not null, b varchar(10) not null, c date not null, d char(1) not null, e bigint not null, f datetime not null, g bool not null, h bool )") + tk.MustExec("create table t_pick_row_id (a char(20) not null)") + + // tiflash + dom := domain.GetDomain(tk.Session()) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + tableName := tblInfo.Name.L + if tableName == "t" || tableName == "t_pick_row_id" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1;") + for i, ts := range input { + testdata.OnRecord(func() { + output[i].SQL = ts + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + ts).Rows()) + }) + tk.MustQuery("explain format = 'brief' " + ts).Check(testkit.Rows(output[i].Plan...)) + } +} diff --git a/planner/core/physical_plan_trace_test.go b/planner/core/physical_plan_trace_test.go index b6df1b1869452..5390fc20af0bd 100644 --- a/planner/core/physical_plan_trace_test.go +++ b/planner/core/physical_plan_trace_test.go @@ -90,10 +90,11 @@ func TestPhysicalOptimizeWithTraceEnabled(t *testing.T) { sql := testcase.sql stmt, err := p.ParseOneStmt(sql, "", "") require.NoError(t, err) - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) require.NoError(t, err) sctx := core.MockContext() sctx.GetSessionVars().StmtCtx.EnableOptimizeTrace = true + sctx.GetSessionVars().CostModelVersion = 2 builder, _ := core.NewPlanBuilder().Init(sctx, dom.InfoSchema(), &hint.BlockHintProcessor{}) domain.GetDomain(sctx).MockInfoCacheAndLoadInfoSchema(dom.InfoSchema()) plan, err := builder.Build(context.TODO(), stmt) @@ -144,7 +145,7 @@ func TestPhysicalOptimizerTrace(t *testing.T) { stmt, err := p.ParseOneStmt(sql, "", "") require.NoError(t, err) - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) require.NoError(t, err) sctx := core.MockContext() sctx.GetSessionVars().StmtCtx.EnableOptimizeTrace = true @@ -207,7 +208,7 @@ func TestPhysicalOptimizerTraceChildrenNotDuplicated(t *testing.T) { sql := "select * from t" stmt, err := p.ParseOneStmt(sql, "", "") require.NoError(t, err) - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) require.NoError(t, err) sctx := core.MockContext() sctx.GetSessionVars().StmtCtx.EnableOptimizeTrace = true diff --git a/planner/core/physical_plans.go b/planner/core/physical_plans.go index 54180e2ce58fe..02d01aad5db4c 100644 --- a/planner/core/physical_plans.go +++ b/planner/core/physical_plans.go @@ -75,6 +75,19 @@ type tableScanAndPartitionInfo struct { partitionInfo PartitionInfo } +// MemoryUsage return the memory usage of tableScanAndPartitionInfo +func (t *tableScanAndPartitionInfo) MemoryUsage() (sum int64) { + if t == nil { + return + } + + sum += t.partitionInfo.MemoryUsage() + if t.tableScan != nil { + sum += t.tableScan.MemoryUsage() + } + return +} + // ReadReqType is the read request type of the operator. Currently, only PhysicalTableReader uses this. type ReadReqType uint8 @@ -196,12 +209,9 @@ func (p *PhysicalTableReader) MemoryUsage() (sum int64) { if p.tablePlan != nil { sum += p.tablePlan.MemoryUsage() } - - for _, plan := range p.TablePlans { - sum += plan.MemoryUsage() - } - for _, pInfos := range p.PartitionInfos { - sum += pInfos.tableScan.MemoryUsage() + pInfos.partitionInfo.MemoryUsage() + // since TablePlans is the flats of tablePlan, so we don't count it + for _, pInfo := range p.PartitionInfos { + sum += pInfo.MemoryUsage() } return } @@ -317,7 +327,7 @@ func (p *PhysicalIndexReader) Clone() (PhysicalPlan, error) { if cloned.IndexPlans, err = clonePhysicalPlan(p.IndexPlans); err != nil { return nil, err } - cloned.OutputColumns = cloneCols(p.OutputColumns) + cloned.OutputColumns = util.CloneCols(p.OutputColumns) return cloned, err } @@ -527,12 +537,7 @@ func (p *PhysicalIndexLookUpReader) MemoryUsage() (sum int64) { sum += p.PushedLimit.MemoryUsage() } - for _, plan := range p.IndexPlans { - sum += plan.MemoryUsage() - } - for _, plan := range p.TablePlans { - sum += plan.MemoryUsage() - } + // since IndexPlans and TablePlans are the flats of indexPlan and tablePlan, so we don't count it for _, col := range p.CommonHandleCols { sum += col.MemoryUsage() } @@ -543,6 +548,12 @@ func (p *PhysicalIndexLookUpReader) MemoryUsage() (sum int64) { type PhysicalIndexMergeReader struct { physicalSchemaProducer + // IsIntersectionType means whether it's intersection type or union type. + // Intersection type is for expressions connected by `AND` and union type is for `OR`. + IsIntersectionType bool + // AccessMVIndex indicates whether this IndexMergeReader access a MVIndex. + AccessMVIndex bool + // PartialPlans flats the partialPlans to construct executor pb. PartialPlans [][]PhysicalPlan // TablePlans flats the tablePlan to construct executor pb. @@ -668,7 +679,12 @@ type PhysicalIndexScan struct { // tblColHists contains all columns before pruning, which are used to calculate row-size tblColHists *statistics.HistColl pkIsHandleCol *expression.Column - prop *property.PhysicalProperty + + // constColsByCond records the constant part of the index columns caused by the access conds. + // e.g. the index is (a, b, c) and there's filter a = 1 and b = 2, then the column a and b are const part. + constColsByCond []bool + + prop *property.PhysicalProperty } // Clone implements PhysicalPlan interface. @@ -680,18 +696,18 @@ func (p *PhysicalIndexScan) Clone() (PhysicalPlan, error) { return nil, err } cloned.physicalSchemaProducer = *base - cloned.AccessCondition = cloneExprs(p.AccessCondition) + cloned.AccessCondition = util.CloneExprs(p.AccessCondition) if p.Table != nil { cloned.Table = p.Table.Clone() } if p.Index != nil { cloned.Index = p.Index.Clone() } - cloned.IdxCols = cloneCols(p.IdxCols) + cloned.IdxCols = util.CloneCols(p.IdxCols) cloned.IdxColLens = make([]int, len(p.IdxColLens)) copy(cloned.IdxColLens, p.IdxColLens) - cloned.Ranges = cloneRanges(p.Ranges) - cloned.Columns = cloneColInfos(p.Columns) + cloned.Ranges = util.CloneRanges(p.Ranges) + cloned.Columns = util.CloneColInfos(p.Columns) if p.dataSourceSchema != nil { cloned.dataSourceSchema = p.dataSourceSchema.Clone() } @@ -719,7 +735,7 @@ func (p *PhysicalIndexScan) MemoryUsage() (sum int64) { } sum = emptyPhysicalIndexScanSize + p.physicalSchemaProducer.MemoryUsage() + int64(cap(p.IdxColLens))*size.SizeOfInt + - p.DBName.MemoryUsage() + int64(len(p.rangeInfo)) + p.DBName.MemoryUsage() + int64(len(p.rangeInfo)) + int64(len(p.Columns))*model.EmptyColumnInfoSize if p.TableAsName != nil { sum += p.TableAsName.MemoryUsage() } @@ -729,6 +745,9 @@ func (p *PhysicalIndexScan) MemoryUsage() (sum int64) { if p.prop != nil { sum += p.prop.MemoryUsage() } + if p.dataSourceSchema != nil { + sum += p.dataSourceSchema.MemoryUsage() + } // slice memory usage for _, cond := range p.AccessCondition { sum += cond.MemoryUsage() @@ -828,13 +847,13 @@ func (ts *PhysicalTableScan) Clone() (PhysicalPlan, error) { return nil, err } clonedScan.physicalSchemaProducer = *prod - clonedScan.AccessCondition = cloneExprs(ts.AccessCondition) - clonedScan.filterCondition = cloneExprs(ts.filterCondition) + clonedScan.AccessCondition = util.CloneExprs(ts.AccessCondition) + clonedScan.filterCondition = util.CloneExprs(ts.filterCondition) if ts.Table != nil { clonedScan.Table = ts.Table.Clone() } - clonedScan.Columns = cloneColInfos(ts.Columns) - clonedScan.Ranges = cloneRanges(ts.Ranges) + clonedScan.Columns = util.CloneColInfos(ts.Columns) + clonedScan.Ranges = util.CloneRanges(ts.Ranges) clonedScan.TableAsName = ts.TableAsName if ts.Hist != nil { clonedScan.Hist = ts.Hist.Copy() @@ -941,7 +960,7 @@ func (ts *PhysicalTableScan) MemoryUsage() (sum int64) { } sum = emptyPhysicalTableScanSize + ts.physicalSchemaProducer.MemoryUsage() + ts.DBName.MemoryUsage() + - int64(cap(ts.HandleIdx))*size.SizeOfInt + ts.PartitionInfo.MemoryUsage() + int64(cap(ts.HandleIdx))*size.SizeOfInt + ts.PartitionInfo.MemoryUsage() + int64(len(ts.rangeInfo)) if ts.TableAsName != nil { sum += ts.TableAsName.MemoryUsage() } @@ -961,7 +980,6 @@ func (ts *PhysicalTableScan) MemoryUsage() (sum int64) { for _, rang := range ts.Ranges { sum += rang.MemUsage() } - sum += int64(len(ts.rangeInfo)) for _, col := range ts.tblCols { sum += col.MemoryUsage() } @@ -986,7 +1004,7 @@ func (p *PhysicalProjection) Clone() (PhysicalPlan, error) { return nil, err } cloned.basePhysicalPlan = *base - cloned.Exprs = cloneExprs(p.Exprs) + cloned.Exprs = util.CloneExprs(p.Exprs) return cloned, err } @@ -1135,6 +1153,10 @@ type basePhysicalJoin struct { RightNAJoinKeys []*expression.Column } +func (p *basePhysicalJoin) getInnerChildIdx() int { + return p.InnerChildIdx +} + func (p *basePhysicalJoin) cloneWithSelf(newSelf PhysicalPlan) (*basePhysicalJoin, error) { cloned := new(basePhysicalJoin) base, err := p.physicalSchemaProducer.cloneWithSelf(newSelf) @@ -1143,16 +1165,16 @@ func (p *basePhysicalJoin) cloneWithSelf(newSelf PhysicalPlan) (*basePhysicalJoi } cloned.physicalSchemaProducer = *base cloned.JoinType = p.JoinType - cloned.LeftConditions = cloneExprs(p.LeftConditions) - cloned.RightConditions = cloneExprs(p.RightConditions) - cloned.OtherConditions = cloneExprs(p.OtherConditions) + cloned.LeftConditions = util.CloneExprs(p.LeftConditions) + cloned.RightConditions = util.CloneExprs(p.RightConditions) + cloned.OtherConditions = util.CloneExprs(p.OtherConditions) cloned.InnerChildIdx = p.InnerChildIdx - cloned.OuterJoinKeys = cloneCols(p.OuterJoinKeys) - cloned.InnerJoinKeys = cloneCols(p.InnerJoinKeys) - cloned.LeftJoinKeys = cloneCols(p.LeftJoinKeys) - cloned.RightJoinKeys = cloneCols(p.RightJoinKeys) - cloned.LeftNAJoinKeys = cloneCols(p.LeftNAJoinKeys) - cloned.RightNAJoinKeys = cloneCols(p.RightNAJoinKeys) + cloned.OuterJoinKeys = util.CloneCols(p.OuterJoinKeys) + cloned.InnerJoinKeys = util.CloneCols(p.InnerJoinKeys) + cloned.LeftJoinKeys = util.CloneCols(p.LeftJoinKeys) + cloned.RightJoinKeys = util.CloneCols(p.RightJoinKeys) + cloned.LeftNAJoinKeys = util.CloneCols(p.LeftNAJoinKeys) + cloned.RightNAJoinKeys = util.CloneCols(p.RightNAJoinKeys) for _, d := range p.DefaultValues { cloned.DefaultValues = append(cloned.DefaultValues, *d.Clone()) } @@ -1182,7 +1204,10 @@ func (p *basePhysicalJoin) MemoryUsage() (sum int64) { return } - sum = emptyBasePhysicalJoinSize + p.physicalSchemaProducer.MemoryUsage() + int64(cap(p.IsNullEQ))*size.SizeOfBool + sum = emptyBasePhysicalJoinSize + p.physicalSchemaProducer.MemoryUsage() + int64(cap(p.IsNullEQ))*size.SizeOfBool + + int64(cap(p.LeftConditions)+cap(p.RightConditions)+cap(p.OtherConditions))*size.SizeOfInterface + + int64(cap(p.OuterJoinKeys)+cap(p.InnerJoinKeys)+cap(p.LeftJoinKeys)+cap(p.RightNAJoinKeys)+cap(p.LeftNAJoinKeys)+ + cap(p.RightNAJoinKeys))*size.SizeOfPointer + int64(cap(p.DefaultValues))*types.EmptyDatumSize for _, cond := range p.LeftConditions { sum += cond.MemoryUsage() @@ -1353,6 +1378,9 @@ func (p *PhysicalIndexJoin) MemoryUsage() (sum int64) { sum = p.basePhysicalJoin.MemoryUsage() + size.SizeOfInterface*2 + size.SizeOfSlice*4 + int64(cap(p.KeyOff2IdxOff)+cap(p.IdxColLens))*size.SizeOfInt + size.SizeOfPointer + if p.innerTask != nil { + sum += p.innerTask.MemoryUsage() + } if p.CompareFilters != nil { sum += p.CompareFilters.MemoryUsage() } @@ -1454,8 +1482,6 @@ func (p *PhysicalExchangeReceiver) GetExchangeSender() *PhysicalExchangeSender { return p.children[0].(*PhysicalExchangeSender) } -const emptyMPPTaskSize = int64(unsafe.Sizeof(mppTask{})) - // MemoryUsage return the memory usage of PhysicalExchangeReceiver func (p *PhysicalExchangeReceiver) MemoryUsage() (sum int64) { if p == nil { @@ -1654,7 +1680,7 @@ func (p *basePhysicalAgg) cloneWithSelf(newSelf PhysicalPlan) (*basePhysicalAgg, for _, aggDesc := range p.AggFuncs { cloned.AggFuncs = append(cloned.AggFuncs, aggDesc.Clone()) } - cloned.GroupByItems = cloneExprs(p.GroupByItems) + cloned.GroupByItems = util.CloneExprs(p.GroupByItems) return cloned, nil } @@ -1729,6 +1755,10 @@ type PhysicalHashAgg struct { basePhysicalAgg } +func (p *PhysicalHashAgg) getPointer() *basePhysicalAgg { + return &p.basePhysicalAgg +} + // Clone implements PhysicalPlan interface. func (p *PhysicalHashAgg) Clone() (PhysicalPlan, error) { cloned := new(PhysicalHashAgg) @@ -1763,6 +1793,10 @@ type PhysicalStreamAgg struct { basePhysicalAgg } +func (p *PhysicalStreamAgg) getPointer() *basePhysicalAgg { + return &p.basePhysicalAgg +} + // Clone implements PhysicalPlan interface. func (p *PhysicalStreamAgg) Clone() (PhysicalPlan, error) { cloned := new(PhysicalStreamAgg) @@ -1881,7 +1915,10 @@ func (p *PhysicalUnionScan) MemoryUsage() (sum int64) { return } - sum = p.basePhysicalPlan.MemoryUsage() + size.SizeOfSlice + p.HandleCols.MemoryUsage() + sum = p.basePhysicalPlan.MemoryUsage() + size.SizeOfSlice + if p.HandleCols != nil { + sum += p.HandleCols.MemoryUsage() + } for _, cond := range p.Conditions { sum += cond.MemoryUsage() } @@ -1921,7 +1958,7 @@ func (p *PhysicalSelection) Clone() (PhysicalPlan, error) { return nil, err } cloned.basePhysicalPlan = *base - cloned.Conditions = cloneExprs(p.Conditions) + cloned.Conditions = util.CloneExprs(p.Conditions) return cloned, nil } @@ -2164,7 +2201,10 @@ func (p *PhysicalShuffleReceiverStub) MemoryUsage() (sum int64) { return } - sum = p.physicalSchemaProducer.MemoryUsage() + size.SizeOfPointer + size.SizeOfInterface + p.DataSource.MemoryUsage() + sum = p.physicalSchemaProducer.MemoryUsage() + size.SizeOfPointer + size.SizeOfInterface + if p.DataSource != nil { + sum += p.DataSource.MemoryUsage() + } return } diff --git a/planner/core/plan.go b/planner/core/plan.go index 03e7a0fafa43f..e492ad08d0fc7 100644 --- a/planner/core/plan.go +++ b/planner/core/plan.go @@ -28,6 +28,7 @@ import ( "github.com/pingcap/tidb/planner/util" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/size" "github.com/pingcap/tidb/util/stringutil" @@ -196,7 +197,7 @@ func optimizeByShuffle4StreamAgg(pp *PhysicalStreamAgg, ctx sessionctx.Context) Tails: []PhysicalPlan{tail}, DataSources: []PhysicalPlan{dataSource}, SplitterType: PartitionHashSplitterType, - ByItemArrays: [][]expression.Expression{cloneExprs(pp.GroupByItems)}, + ByItemArrays: [][]expression.Expression{util.CloneExprs(pp.GroupByItems)}, }.Init(ctx, pp.statsInfo(), pp.SelectBlockOffset(), reqProp) return shuffle } @@ -379,6 +380,26 @@ type PhysicalPlan interface { // MemoryUsage return the memory usage of PhysicalPlan MemoryUsage() int64 + + // Below three methods help to handle the inconsistency between row count in the statsInfo and the recorded + // actual row count. + // For the children in the inner side (probe side) of Index Join and Apply, the row count in the statsInfo + // means the estimated row count for a single "probe", but the recorded actual row count is the total row + // count for all "probes". + // To handle this inconsistency without breaking anything else, we added a field `probeParents` of + // type `[]PhysicalPlan` into all PhysicalPlan to record all operators that are (indirect or direct) parents + // of this PhysicalPlan and will cause this inconsistency. + // Using this information, we can convert the row count between the "single probe" row count and "all probes" + // row count freely. + + // setProbeParents sets the above stated `probeParents` field. + setProbeParents([]PhysicalPlan) + // getEstRowCountForDisplay uses the "single probe" row count in statsInfo and the probeParents to calculate + // the "all probe" row count. + // All places that display the row count for a PhysicalPlan are expected to use this method. + getEstRowCountForDisplay() float64 + // getEstRowCountForDisplay uses the runtime stats and the probeParents to calculate the actual "probe" count. + getActualProbeCnt(*execdetails.RuntimeStatsColl) int64 } // NewDefaultPlanCostOption returns PlanCostOption @@ -449,6 +470,42 @@ func (*baseLogicalPlan) ExplainInfo() string { return "" } +func getEstimatedProbeCntFromProbeParents(probeParents []PhysicalPlan) float64 { + res := float64(1) + for _, pp := range probeParents { + switch pp.(type) { + case *PhysicalApply, *PhysicalIndexHashJoin, *PhysicalIndexMergeJoin, *PhysicalIndexJoin: + if join, ok := pp.(interface{ getInnerChildIdx() int }); ok { + outer := pp.Children()[1-join.getInnerChildIdx()] + res *= outer.statsInfo().RowCount + } + } + } + return res +} + +func getActualProbeCntFromProbeParents(pps []PhysicalPlan, statsColl *execdetails.RuntimeStatsColl) int64 { + res := int64(1) + for _, pp := range pps { + switch pp.(type) { + case *PhysicalApply, *PhysicalIndexHashJoin, *PhysicalIndexMergeJoin, *PhysicalIndexJoin: + if join, ok := pp.(interface{ getInnerChildIdx() int }); ok { + outerChildID := pp.Children()[1-join.getInnerChildIdx()].ID() + actRows := int64(1) + if statsColl.ExistsRootStats(outerChildID) { + actRows = statsColl.GetRootStats(outerChildID).GetActRows() + } + if statsColl.ExistsCopStats(outerChildID) { + actRows = statsColl.GetCopStats(outerChildID).GetActRows() + } + // TODO: For PhysicalApply, we need to consider cache hit ratio in JoinRuntimeStats and use actRows/(1-ratio) here. + res *= actRows + } + } + } + return res +} + type basePhysicalPlan struct { basePlan @@ -461,6 +518,10 @@ type basePhysicalPlan struct { planCost float64 planCostVer2 costVer2 + // probeParents records the IndexJoins and Applys with this operator in their inner children. + // Please see comments in PhysicalPlan for details. + probeParents []PhysicalPlan + // Only for MPP. If TiFlashFineGrainedShuffleStreamCount > 0: // 1. For ExchangeSender, means its output will be partitioned by hash key. // 2. For ExchangeReceiver/Window/Sort, means its input is already partitioned. @@ -472,6 +533,7 @@ func (p *basePhysicalPlan) cloneWithSelf(newSelf PhysicalPlan) (*basePhysicalPla basePlan: p.basePlan, self: newSelf, TiFlashFineGrainedShuffleStreamCount: p.TiFlashFineGrainedShuffleStreamCount, + probeParents: p.probeParents, } for _, child := range p.children { cloned, err := child.Clone() @@ -522,9 +584,6 @@ func (p *basePhysicalPlan) MemoryUsage() (sum int64) { sum = p.basePlan.MemoryUsage() + size.SizeOfSlice + int64(cap(p.childrenReqProps))*size.SizeOfPointer + size.SizeOfSlice + int64(cap(p.children)+1)*size.SizeOfInterface + size.SizeOfFloat64 + size.SizeOfUint64 + size.SizeOfBool - if p.self != nil { - sum += p.self.MemoryUsage() - } for _, prop := range p.childrenReqProps { sum += prop.MemoryUsage() @@ -535,6 +594,24 @@ func (p *basePhysicalPlan) MemoryUsage() (sum int64) { return } +func (p *basePhysicalPlan) getEstRowCountForDisplay() float64 { + if p == nil { + return 0 + } + return p.statsInfo().RowCount * getEstimatedProbeCntFromProbeParents(p.probeParents) +} + +func (p *basePhysicalPlan) getActualProbeCnt(statsColl *execdetails.RuntimeStatsColl) int64 { + if p == nil { + return 1 + } + return getActualProbeCntFromProbeParents(p.probeParents, statsColl) +} + +func (p *basePhysicalPlan) setProbeParents(probeParents []PhysicalPlan) { + p.probeParents = probeParents +} + // GetLogicalTS4TaskMap get the logical TimeStamp now to help rollback the TaskMap changes after that. func (p *baseLogicalPlan) GetLogicalTS4TaskMap() uint64 { p.ctx.GetSessionVars().StmtCtx.TaskMapBakTS++ @@ -804,11 +881,6 @@ func (p *basePlan) SCtx() sessionctx.Context { return p.ctx } -// SetSCtx Context implements Plan Set Context interface. -func (p *basePlan) SetSCtx(ctx sessionctx.Context) { - p.ctx = ctx -} - // buildPlanTrace implements Plan func (p *basePhysicalPlan) buildPlanTrace() *tracing.PlanTrace { planTrace := &tracing.PlanTrace{ID: p.ID(), TP: p.self.TP(), ExplainInfo: p.self.ExplainInfo()} diff --git a/planner/core/plan_cache.go b/planner/core/plan_cache.go index e4bf81791e19c..98b49c1bcc452 100644 --- a/planner/core/plan_cache.go +++ b/planner/core/plan_cache.go @@ -42,8 +42,7 @@ import ( "go.uber.org/zap" ) -func planCachePreprocess(sctx sessionctx.Context, isGeneralPlanCache bool, is infoschema.InfoSchema, - stmt *PlanCacheStmt, params []expression.Expression) error { +func planCachePreprocess(ctx context.Context, sctx sessionctx.Context, isNonPrepared bool, is infoschema.InfoSchema, stmt *PlanCacheStmt, params []expression.Expression) error { vars := sctx.GetSessionVars() stmtAst := stmt.PreparedAst vars.StmtCtx.StmtType = stmtAst.StmtType @@ -88,7 +87,7 @@ func planCachePreprocess(sctx sessionctx.Context, isGeneralPlanCache bool, is in // We should reset the tableRefs in the prepared update statements, otherwise, the ast nodes still hold the old // tableRefs columnInfo which will cause chaos in logic of trying point get plan. (should ban non-public column) ret := &PreprocessorReturn{InfoSchema: is} - err := Preprocess(sctx, stmtAst.Stmt, InPrepare, WithPreprocessorReturn(ret)) + err := Preprocess(ctx, sctx, stmtAst.Stmt, InPrepare, WithPreprocessorReturn(ret)) if err != nil { return ErrSchemaChanged.GenWithStack("Schema change caused error: %s", err.Error()) } @@ -101,8 +100,8 @@ func planCachePreprocess(sctx sessionctx.Context, isGeneralPlanCache bool, is in // So we need to clear the current session's plan cache. // And update lastUpdateTime to the newest one. expiredTimeStamp4PC := domain.GetDomain(sctx).ExpiredTimeStamp4PC() - if stmtAst.UseCache && expiredTimeStamp4PC.Compare(vars.LastUpdateTime4PC) > 0 { - sctx.GetPlanCache(isGeneralPlanCache).DeleteAll() + if stmt.StmtCacheable && expiredTimeStamp4PC.Compare(vars.LastUpdateTime4PC) > 0 { + sctx.GetPlanCache(isNonPrepared).DeleteAll() stmtAst.CachedPlan = nil vars.LastUpdateTime4PC = expiredTimeStamp4PC } @@ -112,11 +111,15 @@ func planCachePreprocess(sctx sessionctx.Context, isGeneralPlanCache bool, is in // GetPlanFromSessionPlanCache is the entry point of Plan Cache. // It tries to get a valid cached plan from this session's plan cache. // If there is no such a plan, it'll call the optimizer to generate a new one. -// isGeneralPlanCache indicates whether to use the general plan cache or the prepared plan cache. +// isNonPrepared indicates whether to use the non-prepared plan cache or the prepared plan cache. func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, - isGeneralPlanCache bool, is infoschema.InfoSchema, stmt *PlanCacheStmt, + isNonPrepared bool, is infoschema.InfoSchema, stmt *PlanCacheStmt, params []expression.Expression) (plan Plan, names []*types.FieldName, err error) { - if err := planCachePreprocess(sctx, isGeneralPlanCache, is, stmt, params); err != nil { + if v := ctx.Value("____GetPlanFromSessionPlanCacheErr"); v != nil { // for testing + return nil, nil, errors.New("____GetPlanFromSessionPlanCacheErr") + } + + if err := planCachePreprocess(ctx, sctx, isNonPrepared, is, stmt, params); err != nil { return nil, nil, err } @@ -124,17 +127,25 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, sessVars := sctx.GetSessionVars() stmtCtx := sessVars.StmtCtx stmtAst := stmt.PreparedAst - stmtCtx.UseCache = stmtAst.UseCache + stmtCtx.UseCache = stmt.StmtCacheable + if !stmt.StmtCacheable { + stmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: %s", stmt.UncacheableReason)) + } var bindSQL string - var ignorePlanCache = false + if stmtCtx.UseCache { + var ignoreByBinding bool + bindSQL, ignoreByBinding = GetBindSQL4PlanCache(sctx, stmt) + if ignoreByBinding { + stmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: ignore plan cache by binding")) + } + } // In rc or for update read, we need the latest schema version to decide whether we need to // rebuild the plan. So we set this value in rc or for update read. In other cases, let it be 0. var latestSchemaVersion int64 - if stmtAst.UseCache { - bindSQL, ignorePlanCache = GetBindSQL4PlanCache(sctx, stmt) + if stmtCtx.UseCache { if sctx.GetSessionVars().IsIsolation(ast.ReadCommitted) || stmt.ForUpdateRead { // In Rc or ForUpdateRead, we should check if the information schema has been changed since // last time. If it changed, we should rebuild the plan. Here, we use a different and more @@ -147,28 +158,29 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, } } - paramNum, paramTypes := parseParamTypes(sctx, params) + paramTypes := parseParamTypes(sctx, params) - if stmtAst.UseCache && stmtAst.CachedPlan != nil && !ignorePlanCache { // for point query plan - if plan, names, ok, err := getPointQueryPlan(stmtAst, sessVars, stmtCtx); ok { + if stmtCtx.UseCache && stmtAst.CachedPlan != nil { // for point query plan + if plan, names, ok, err := getCachedPointPlan(stmtAst, sessVars, stmtCtx); ok { return plan, names, err } } - - if stmtAst.UseCache && !ignorePlanCache { // for general plans - if plan, names, ok, err := getGeneralPlan(sctx, isGeneralPlanCache, cacheKey, bindSQL, is, stmt, - paramTypes); err != nil || ok { + limitCountAndOffset, paramErr := ExtractLimitFromAst(stmt.PreparedAst.Stmt, sctx) + if paramErr != nil { + return nil, nil, paramErr + } + if stmtCtx.UseCache { // for non-point plans + if plan, names, ok, err := getCachedPlan(sctx, isNonPrepared, cacheKey, bindSQL, is, stmt, + paramTypes, limitCountAndOffset); err != nil || ok { return plan, names, err } } - return generateNewPlan(ctx, sctx, isGeneralPlanCache, is, stmt, ignorePlanCache, cacheKey, - latestSchemaVersion, paramNum, paramTypes, bindSQL) + return generateNewPlan(ctx, sctx, isNonPrepared, is, stmt, cacheKey, latestSchemaVersion, paramTypes, bindSQL, limitCountAndOffset) } // parseParamTypes get parameters' types in PREPARE statement -func parseParamTypes(sctx sessionctx.Context, params []expression.Expression) (paramNum int, paramTypes []*types.FieldType) { - paramNum = len(params) +func parseParamTypes(sctx sessionctx.Context, params []expression.Expression) (paramTypes []*types.FieldType) { for _, param := range params { if c, ok := param.(*expression.Constant); ok { // from binary protocol paramTypes = append(paramTypes, c.GetType()) @@ -186,7 +198,7 @@ func parseParamTypes(sctx sessionctx.Context, params []expression.Expression) (p return } -func getPointQueryPlan(stmt *ast.Prepared, sessVars *variable.SessionVars, stmtCtx *stmtctx.StatementContext) (Plan, +func getCachedPointPlan(stmt *ast.Prepared, sessVars *variable.SessionVars, stmtCtx *stmtctx.StatementContext) (Plan, []*types.FieldName, bool, error) { // short path for point-get plans // Rewriting the expression in the select.where condition will convert its @@ -210,13 +222,13 @@ func getPointQueryPlan(stmt *ast.Prepared, sessVars *variable.SessionVars, stmtC return plan, names, true, nil } -func getGeneralPlan(sctx sessionctx.Context, isGeneralPlanCache bool, cacheKey kvcache.Key, bindSQL string, - is infoschema.InfoSchema, stmt *PlanCacheStmt, paramTypes []*types.FieldType) (Plan, +func getCachedPlan(sctx sessionctx.Context, isNonPrepared bool, cacheKey kvcache.Key, bindSQL string, + is infoschema.InfoSchema, stmt *PlanCacheStmt, paramTypes []*types.FieldType, limitParams []uint64) (Plan, []*types.FieldName, bool, error) { sessVars := sctx.GetSessionVars() stmtCtx := sessVars.StmtCtx - candidate, exist := sctx.GetPlanCache(isGeneralPlanCache).Get(cacheKey, paramTypes) + candidate, exist := sctx.GetPlanCache(isNonPrepared).Get(cacheKey, paramTypes, limitParams) if !exist { return nil, nil, false, nil } @@ -228,7 +240,7 @@ func getGeneralPlan(sctx sessionctx.Context, isGeneralPlanCache bool, cacheKey k if !unionScan && tableHasDirtyContent(sctx, tblInfo) { // TODO we can inject UnionScan into cached plan to avoid invalidating it, though // rebuilding the filters in UnionScan is pretty trivial. - sctx.GetPlanCache(isGeneralPlanCache).Delete(cacheKey) + sctx.GetPlanCache(isNonPrepared).Delete(cacheKey) return nil, nil, false, nil } } @@ -254,9 +266,9 @@ func getGeneralPlan(sctx sessionctx.Context, isGeneralPlanCache bool, cacheKey k // generateNewPlan call the optimizer to generate a new plan for current statement // and try to add it to cache -func generateNewPlan(ctx context.Context, sctx sessionctx.Context, isGeneralPlanCache bool, is infoschema.InfoSchema, stmt *PlanCacheStmt, - ignorePlanCache bool, cacheKey kvcache.Key, latestSchemaVersion int64, paramNum int, - paramTypes []*types.FieldType, bindSQL string) (Plan, []*types.FieldName, error) { +func generateNewPlan(ctx context.Context, sctx sessionctx.Context, isNonPrepared bool, is infoschema.InfoSchema, + stmt *PlanCacheStmt, cacheKey kvcache.Key, latestSchemaVersion int64, paramTypes []*types.FieldType, + bindSQL string, limitParams []uint64) (Plan, []*types.FieldName, error) { stmtAst := stmt.PreparedAst sessVars := sctx.GetSessionVars() stmtCtx := sessVars.StmtCtx @@ -273,11 +285,13 @@ func generateNewPlan(ctx context.Context, sctx sessionctx.Context, isGeneralPlan return nil, nil, err } - // We only cache the tableDual plan when the number of parameters are zero. - if containTableDual(p) && paramNum > 0 { - stmtCtx.SkipPlanCache = true + // check whether this plan is cacheable. + if stmtCtx.UseCache { + checkPlanCacheability(sctx, p, len(paramTypes)) } - if stmtAst.UseCache && !stmtCtx.SkipPlanCache && !ignorePlanCache { + + // put this plan into the plan cache. + if stmtCtx.UseCache { // rebuild key to exclude kv.TiFlash when stmt is not read only if _, isolationReadContainTiFlash := sessVars.IsolationReadEngines[kv.TiFlash]; isolationReadContainTiFlash && !IsReadOnly(stmtAst.Stmt, sessVars) { delete(sessVars.IsolationReadEngines, kv.TiFlash) @@ -287,16 +301,54 @@ func generateNewPlan(ctx context.Context, sctx sessionctx.Context, isGeneralPlan } sessVars.IsolationReadEngines[kv.TiFlash] = struct{}{} } - cached := NewPlanCacheValue(p, names, stmtCtx.TblInfo2UnionScan, paramTypes) + cached := NewPlanCacheValue(p, names, stmtCtx.TblInfo2UnionScan, paramTypes, limitParams) stmt.NormalizedPlan, stmt.PlanDigest = NormalizePlan(p) stmtCtx.SetPlan(p) stmtCtx.SetPlanDigest(stmt.NormalizedPlan, stmt.PlanDigest) - sctx.GetPlanCache(isGeneralPlanCache).Put(cacheKey, cached, paramTypes) + sctx.GetPlanCache(isNonPrepared).Put(cacheKey, cached, paramTypes, limitParams) } sessVars.FoundInPlanCache = false return p, names, err } +// checkPlanCacheability checks whether this plan is cacheable and set to skip plan cache if it's uncacheable. +func checkPlanCacheability(sctx sessionctx.Context, p Plan, paramNum int) { + stmtCtx := sctx.GetSessionVars().StmtCtx + var pp PhysicalPlan + switch x := p.(type) { + case *Insert: + pp = x.SelectPlan + case *Update: + pp = x.SelectPlan + case *Delete: + pp = x.SelectPlan + case PhysicalPlan: + pp = x + default: + stmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: unexpected un-cacheable plan %v", p.ExplainID().String())) + return + } + if pp == nil { // simple DML statements + return + } + + if useTiFlash(pp) { + stmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: TiFlash plan is un-cacheable")) + return + } + + // We only cache the tableDual plan when the number of parameters are zero. + if containTableDual(pp) && paramNum > 0 { + stmtCtx.SetSkipPlanCache(errors.New("skip plan-cache: get a TableDual plan")) + return + } + + if accessMVIndexWithIndexMerge(pp) { + stmtCtx.SetSkipPlanCache(errors.New("skip plan-cache: the plan with IndexMerge accessing Multi-Valued Index is un-cacheable")) + return + } +} + // RebuildPlan4CachedPlan will rebuild this plan under current user parameters. func RebuildPlan4CachedPlan(p Plan) error { sc := p.SCtx().GetSessionVars().StmtCtx @@ -637,7 +689,7 @@ func CheckPreparedPriv(sctx sessionctx.Context, stmt *PlanCacheStmt, is infosche // short paths for these executions, currently "point select" and "point update" func tryCachePointPlan(_ context.Context, sctx sessionctx.Context, stmt *PlanCacheStmt, _ infoschema.InfoSchema, p Plan) error { - if !sctx.GetSessionVars().StmtCtx.UseCache || sctx.GetSessionVars().StmtCtx.SkipPlanCache { + if !sctx.GetSessionVars().StmtCtx.UseCache { return nil } var ( @@ -666,22 +718,53 @@ func tryCachePointPlan(_ context.Context, sctx sessionctx.Context, return err } -func containTableDual(p Plan) bool { +func containTableDual(p PhysicalPlan) bool { _, isTableDual := p.(*PhysicalTableDual) if isTableDual { return true } - physicalPlan, ok := p.(PhysicalPlan) - if !ok { - return false - } childContainTableDual := false - for _, child := range physicalPlan.Children() { + for _, child := range p.Children() { childContainTableDual = childContainTableDual || containTableDual(child) } return childContainTableDual } +func accessMVIndexWithIndexMerge(p PhysicalPlan) bool { + if idxMerge, ok := p.(*PhysicalIndexMergeReader); ok { + if idxMerge.AccessMVIndex { + return true + } + } + + for _, c := range p.Children() { + if accessMVIndexWithIndexMerge(c) { + return true + } + } + return false +} + +// useTiFlash used to check whether the plan use the TiFlash engine. +func useTiFlash(p PhysicalPlan) bool { + switch x := p.(type) { + case *PhysicalTableReader: + switch x.StoreType { + case kv.TiFlash: + return true + default: + return false + } + default: + if len(p.Children()) > 0 { + for _, plan := range p.Children() { + return useTiFlash(plan) + } + } + } + return false +} + // GetBindSQL4PlanCache used to get the bindSQL for plan cache to build the plan cache key. func GetBindSQL4PlanCache(sctx sessionctx.Context, stmt *PlanCacheStmt) (string, bool) { useBinding := sctx.GetSessionVars().UsePlanBaselines diff --git a/planner/core/plan_cache_lru.go b/planner/core/plan_cache_lru.go index ed29a1274e97f..062ed6cc13735 100644 --- a/planner/core/plan_cache_lru.go +++ b/planner/core/plan_cache_lru.go @@ -18,6 +18,8 @@ import ( "sync" "github.com/pingcap/errors" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/kvcache" @@ -31,6 +33,15 @@ type planCacheEntry struct { PlanValue kvcache.Value } +// MemoryUsage return the memory usage of planCacheEntry +func (e *planCacheEntry) MemoryUsage() (sum int64) { + if e == nil { + return + } + + return e.PlanKey.(*planCacheKey).MemoryUsage() + e.PlanValue.(*PlanCacheValue).MemoryUsage() +} + // LRUPlanCache is a dedicated least recently used cache, Only used for plan cache. type LRUPlanCache struct { capacity uint @@ -42,19 +53,22 @@ type LRUPlanCache struct { lock sync.Mutex // pickFromBucket get one element from bucket. The LRUPlanCache can not work if it is nil - pickFromBucket func(map[*list.Element]struct{}, []*types.FieldType) (*list.Element, bool) + pickFromBucket func(map[*list.Element]struct{}, *planCacheMatchOpts) (*list.Element, bool) // onEvict will be called if any eviction happened, only for test use now onEvict func(kvcache.Key, kvcache.Value) // 0 indicates no quota quota uint64 guard float64 + + memoryUsageTotal int64 + sctx sessionctx.Context } // NewLRUPlanCache creates a PCLRUCache object, whose capacity is "capacity". // NOTE: "capacity" should be a positive value. func NewLRUPlanCache(capacity uint, guard float64, quota uint64, - pickFromBucket func(map[*list.Element]struct{}, []*types.FieldType) (*list.Element, bool)) *LRUPlanCache { + pickFromBucket func(map[*list.Element]struct{}, *planCacheMatchOpts) (*list.Element, bool), sctx sessionctx.Context) *LRUPlanCache { if capacity < 1 { capacity = 100 logutil.BgLogger().Info("capacity of LRU cache is less than 1, will use default value(100) init cache") @@ -67,6 +81,7 @@ func NewLRUPlanCache(capacity uint, guard float64, quota uint64, pickFromBucket: pickFromBucket, quota: quota, guard: guard, + sctx: sctx, } } @@ -79,13 +94,17 @@ func strHashKey(key kvcache.Key, deepCopy bool) string { } // Get tries to find the corresponding value according to the given key. -func (l *LRUPlanCache) Get(key kvcache.Key, paramTypes []*types.FieldType) (value kvcache.Value, ok bool) { +func (l *LRUPlanCache) Get(key kvcache.Key, paramTypes []*types.FieldType, limitParams []uint64) (value kvcache.Value, ok bool) { l.lock.Lock() defer l.lock.Unlock() bucket, bucketExist := l.buckets[strHashKey(key, false)] if bucketExist { - if element, exist := l.pickFromBucket(bucket, paramTypes); exist { + matchOpts := &planCacheMatchOpts{ + paramTypes: paramTypes, + limitOffsetAndCount: limitParams, + } + if element, exist := l.pickFromBucket(bucket, matchOpts); exist { l.lruList.MoveToFront(element) return element.Value.(*planCacheEntry).PlanValue, true } @@ -94,14 +113,19 @@ func (l *LRUPlanCache) Get(key kvcache.Key, paramTypes []*types.FieldType) (valu } // Put puts the (key, value) pair into the LRU Cache. -func (l *LRUPlanCache) Put(key kvcache.Key, value kvcache.Value, paramTypes []*types.FieldType) { +func (l *LRUPlanCache) Put(key kvcache.Key, value kvcache.Value, paramTypes []*types.FieldType, limitParams []uint64) { l.lock.Lock() defer l.lock.Unlock() hash := strHashKey(key, true) bucket, bucketExist := l.buckets[hash] if bucketExist { - if element, exist := l.pickFromBucket(bucket, paramTypes); exist { + matchOpts := &planCacheMatchOpts{ + paramTypes: paramTypes, + limitOffsetAndCount: limitParams, + } + if element, exist := l.pickFromBucket(bucket, matchOpts); exist { + l.updateInstanceMetric(&planCacheEntry{PlanKey: key, PlanValue: value}, element.Value.(*planCacheEntry)) element.Value.(*planCacheEntry).PlanValue = value l.lruList.MoveToFront(element) return @@ -117,6 +141,7 @@ func (l *LRUPlanCache) Put(key kvcache.Key, value kvcache.Value, paramTypes []*t element := l.lruList.PushFront(newCacheEntry) l.buckets[hash][element] = struct{}{} l.size++ + l.updateInstanceMetric(newCacheEntry, nil) if l.size > l.capacity { l.removeOldest() } @@ -132,6 +157,7 @@ func (l *LRUPlanCache) Delete(key kvcache.Key) { bucket, bucketExist := l.buckets[hash] if bucketExist { for element := range bucket { + l.updateInstanceMetric(nil, element.Value.(*planCacheEntry)) l.lruList.Remove(element) l.size-- } @@ -145,6 +171,7 @@ func (l *LRUPlanCache) DeleteAll() { defer l.lock.Unlock() for lru := l.lruList.Back(); lru != nil; lru = l.lruList.Back() { + l.updateInstanceMetric(nil, lru.Value.(*planCacheEntry)) l.lruList.Remove(lru) l.size-- } @@ -174,6 +201,25 @@ func (l *LRUPlanCache) SetCapacity(capacity uint) error { return nil } +// MemoryUsage return the memory usage of LRUPlanCache +func (l *LRUPlanCache) MemoryUsage() (sum int64) { + if l == nil { + return + } + return l.memoryUsageTotal +} + +// Close do some clean work for LRUPlanCache when close the session +func (l *LRUPlanCache) Close() { + if l == nil { + return + } + if l.sctx.GetSessionVars().EnablePreparedPlanCacheMemoryMonitor { + metrics.PlanCacheInstanceMemoryUsage.WithLabelValues("instance").Sub(float64(l.memoryUsageTotal)) + } + metrics.PlanCacheInstancePlanNumCounter.WithLabelValues("plan_num").Sub(float64(l.size)) +} + // removeOldest removes the oldest element from the cache. func (l *LRUPlanCache) removeOldest() { lru := l.lruList.Back() @@ -184,6 +230,7 @@ func (l *LRUPlanCache) removeOldest() { l.onEvict(lru.Value.(*planCacheEntry).PlanKey, lru.Value.(*planCacheEntry).PlanValue) } + l.updateInstanceMetric(nil, lru.Value.(*planCacheEntry)) l.lruList.Remove(lru) l.removeFromBucket(lru) l.size-- @@ -213,12 +260,63 @@ func (l *LRUPlanCache) memoryControl() { } // PickPlanFromBucket pick one plan from bucket -func PickPlanFromBucket(bucket map[*list.Element]struct{}, paramTypes []*types.FieldType) (*list.Element, bool) { +func PickPlanFromBucket(bucket map[*list.Element]struct{}, matchOpts *planCacheMatchOpts) (*list.Element, bool) { for k := range bucket { plan := k.Value.(*planCacheEntry).PlanValue.(*PlanCacheValue) - if plan.ParamTypes.CheckTypesCompatibility4PC(paramTypes) { + ok1 := plan.matchOpts.paramTypes.CheckTypesCompatibility4PC(matchOpts.paramTypes) + if !ok1 { + continue + } + ok2 := checkUint64SliceIfEqual(plan.matchOpts.limitOffsetAndCount, matchOpts.limitOffsetAndCount) + if ok2 { return k, true } } return nil, false } + +func checkUint64SliceIfEqual(a, b []uint64) bool { + if (a == nil && b != nil) || (a != nil && b == nil) { + return false + } + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + +// updateInstanceMetric update the memory usage and plan num for show in grafana +func (l *LRUPlanCache) updateInstanceMetric(in, out *planCacheEntry) { + updateInstancePlanNum(in, out) + if l == nil || !l.sctx.GetSessionVars().EnablePreparedPlanCacheMemoryMonitor { + return + } + + if in != nil && out != nil { // replace plan + metrics.PlanCacheInstanceMemoryUsage.WithLabelValues("instance").Sub(float64(out.MemoryUsage())) + metrics.PlanCacheInstanceMemoryUsage.WithLabelValues("instance").Add(float64(in.MemoryUsage())) + l.memoryUsageTotal += in.MemoryUsage() - out.MemoryUsage() + } else if in != nil { // put plan + metrics.PlanCacheInstanceMemoryUsage.WithLabelValues("instance").Add(float64(in.MemoryUsage())) + l.memoryUsageTotal += in.MemoryUsage() + } else { // delete plan + metrics.PlanCacheInstanceMemoryUsage.WithLabelValues("instance").Sub(float64(out.MemoryUsage())) + l.memoryUsageTotal -= out.MemoryUsage() + } +} + +// updateInstancePlanNum update the plan num +func updateInstancePlanNum(in, out *planCacheEntry) { + if in != nil && out != nil { // replace plan + return + } else if in != nil { // put plan + metrics.PlanCacheInstancePlanNumCounter.WithLabelValues("plan_num").Add(1) + } else { // delete plan + metrics.PlanCacheInstancePlanNumCounter.WithLabelValues("plan_num").Sub(1) + } +} diff --git a/planner/core/plan_cache_lru_test.go b/planner/core/plan_cache_lru_test.go index 0ec108e35b838..72e4549b337a9 100644 --- a/planner/core/plan_cache_lru_test.go +++ b/planner/core/plan_cache_lru_test.go @@ -14,8 +14,10 @@ package core import ( - "container/list" + "math/rand" + "strconv" "testing" + "time" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" @@ -24,79 +26,59 @@ import ( "github.com/stretchr/testify/require" ) -type mockCacheKey struct { - hash []byte - key int64 -} - -func (mk *mockCacheKey) Hash() []byte { - if mk.hash != nil { - return mk.hash +func randomPlanCacheKey() *planCacheKey { + random := rand.New(rand.NewSource(time.Now().UnixNano())) + return &planCacheKey{ + database: strconv.FormatInt(int64(random.Int()), 10), + schemaVersion: time.Now().UnixNano(), } - mk.hash = make([]byte, 8) - for i := uint(0); i < 8; i++ { - mk.hash[i] = byte((mk.key >> ((i - 1) * 8)) & 0xff) - } - return mk.hash } -func newMockHashKey(key int64) *mockCacheKey { - return &mockCacheKey{ - key: key, +func randomPlanCacheValue(types []*types.FieldType) *PlanCacheValue { + plans := []Plan{&Insert{}, &Update{}, &Delete{}, &PhysicalTableScan{}, &PhysicalTableDual{}, &PhysicalTableReader{}, + &PhysicalTableScan{}, &PhysicalIndexJoin{}, &PhysicalIndexHashJoin{}, &PhysicalIndexMergeJoin{}, &PhysicalIndexMergeReader{}, + &PhysicalIndexLookUpReader{}, &PhysicalApply{}, &PhysicalApply{}, &PhysicalLimit{}} + random := rand.New(rand.NewSource(time.Now().UnixNano())) + return &PlanCacheValue{ + Plan: plans[random.Int()%len(plans)], + matchOpts: planCacheMatchOpts{paramTypes: types}, } } -type fakePlan struct { - plan int64 - tps []*types.FieldType -} - -func pickFromBucket(bucket map[*list.Element]struct{}, ptypes []*types.FieldType) (*list.Element, bool) { - for element := range bucket { - itemsA := element.Value.(*planCacheEntry).PlanValue.(*fakePlan).tps - flag := true - for j := 0; j < len(itemsA); j++ { - if itemsA[j] != ptypes[j] { - flag = false - break - } - } - if flag { - return element, true - } - } - return nil, false -} - func TestLRUPCPut(t *testing.T) { // test initialize - lruA := NewLRUPlanCache(0, 0, 0, pickFromBucket) + lruA := NewLRUPlanCache(0, 0, 0, PickPlanFromBucket, MockContext()) require.Equal(t, lruA.capacity, uint(100)) maxMemDroppedKv := make(map[kvcache.Key]kvcache.Value) - lru := NewLRUPlanCache(3, 0, 0, pickFromBucket) + lru := NewLRUPlanCache(3, 0, 0, PickPlanFromBucket, MockContext()) lru.onEvict = func(key kvcache.Key, value kvcache.Value) { maxMemDroppedKv[key] = value } require.Equal(t, uint(3), lru.capacity) - keys := make([]*mockCacheKey, 5) - vals := make([]*fakePlan, 5) + keys := make([]*planCacheKey, 5) + vals := make([]*PlanCacheValue, 5) pTypes := [][]*types.FieldType{{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeEnum)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDate)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeLong)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeInt24)}, } + limitParams := [][]uint64{ + {1}, {2}, {3}, {4}, {5}, + } // one key corresponding to multi values for i := 0; i < 5; i++ { - keys[i] = newMockHashKey(1) - vals[i] = &fakePlan{ - plan: int64(i), - tps: pTypes[i], + keys[i] = &planCacheKey{database: strconv.FormatInt(int64(1), 10)} + vals[i] = &PlanCacheValue{ + matchOpts: planCacheMatchOpts{ + paramTypes: pTypes[i], + limitOffsetAndCount: limitParams[i], + }, } - lru.Put(keys[i], vals[i], pTypes[i]) + lru.Put(keys[i], vals[i], pTypes[i], limitParams[i]) } require.Equal(t, lru.size, lru.capacity) require.Equal(t, uint(3), lru.size) @@ -127,13 +109,17 @@ func TestLRUPCPut(t *testing.T) { bucket, exist := lru.buckets[string(hack.String(keys[i].Hash()))] require.True(t, exist) - element, exist := lru.pickFromBucket(bucket, pTypes[i]) + matchOpts := &planCacheMatchOpts{ + paramTypes: pTypes[i], + limitOffsetAndCount: limitParams[i], + } + element, exist := lru.pickFromBucket(bucket, matchOpts) require.NotNil(t, element) require.True(t, exist) require.Equal(t, root, element) // test value - value, ok := entry.PlanValue.(*fakePlan) + value, ok := entry.PlanValue.(*PlanCacheValue) require.True(t, ok) require.Equal(t, vals[i], value) @@ -145,35 +131,40 @@ func TestLRUPCPut(t *testing.T) { } func TestLRUPCGet(t *testing.T) { - lru := NewLRUPlanCache(3, 0, 0, pickFromBucket) + lru := NewLRUPlanCache(3, 0, 0, PickPlanFromBucket, MockContext()) - keys := make([]*mockCacheKey, 5) - vals := make([]*fakePlan, 5) + keys := make([]*planCacheKey, 5) + vals := make([]*PlanCacheValue, 5) pTypes := [][]*types.FieldType{{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeEnum)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDate)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeLong)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeInt24)}, } + limitParams := [][]uint64{ + {1}, {2}, {3}, {4}, {5}, + } // 5 bucket for i := 0; i < 5; i++ { - keys[i] = newMockHashKey(int64(i % 4)) - vals[i] = &fakePlan{ - plan: int64(i), - tps: pTypes[i], + keys[i] = &planCacheKey{database: strconv.FormatInt(int64(i%4), 10)} + vals[i] = &PlanCacheValue{ + matchOpts: planCacheMatchOpts{ + paramTypes: pTypes[i], + limitOffsetAndCount: limitParams[i], + }, } - lru.Put(keys[i], vals[i], pTypes[i]) + lru.Put(keys[i], vals[i], pTypes[i], limitParams[i]) } // test for non-existent elements for i := 0; i < 2; i++ { - value, exists := lru.Get(keys[i], pTypes[i]) + value, exists := lru.Get(keys[i], pTypes[i], limitParams[i]) require.False(t, exists) require.Nil(t, value) } for i := 2; i < 5; i++ { - value, exists := lru.Get(keys[i], pTypes[i]) + value, exists := lru.Get(keys[i], pTypes[i], limitParams[i]) require.True(t, exists) require.NotNil(t, value) require.Equal(t, vals[i], value) @@ -187,67 +178,73 @@ func TestLRUPCGet(t *testing.T) { require.True(t, ok) require.Equal(t, keys[i], entry.PlanKey) - value, ok = entry.PlanValue.(*fakePlan) + value, ok = entry.PlanValue.(*PlanCacheValue) require.True(t, ok) require.Equal(t, vals[i], value) } } func TestLRUPCDelete(t *testing.T) { - lru := NewLRUPlanCache(3, 0, 0, pickFromBucket) + lru := NewLRUPlanCache(3, 0, 0, PickPlanFromBucket, MockContext()) - keys := make([]*mockCacheKey, 3) - vals := make([]*fakePlan, 3) + keys := make([]*planCacheKey, 3) + vals := make([]*PlanCacheValue, 3) pTypes := [][]*types.FieldType{{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeEnum)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDate)}, } + limitParams := [][]uint64{ + {1}, {2}, {3}, + } for i := 0; i < 3; i++ { - keys[i] = newMockHashKey(int64(i)) - vals[i] = &fakePlan{ - plan: int64(i), - tps: pTypes[i], + keys[i] = &planCacheKey{database: strconv.FormatInt(int64(i), 10)} + vals[i] = &PlanCacheValue{ + matchOpts: planCacheMatchOpts{ + paramTypes: pTypes[i], + limitOffsetAndCount: limitParams[i], + }, } - lru.Put(keys[i], vals[i], pTypes[i]) + lru.Put(keys[i], vals[i], pTypes[i], []uint64{}) } require.Equal(t, 3, int(lru.size)) lru.Delete(keys[1]) - value, exists := lru.Get(keys[1], pTypes[1]) + value, exists := lru.Get(keys[1], pTypes[1], limitParams[1]) require.False(t, exists) require.Nil(t, value) require.Equal(t, 2, int(lru.size)) - _, exists = lru.Get(keys[0], pTypes[0]) + _, exists = lru.Get(keys[0], pTypes[0], limitParams[0]) require.True(t, exists) - _, exists = lru.Get(keys[2], pTypes[2]) + _, exists = lru.Get(keys[2], pTypes[2], limitParams[2]) require.True(t, exists) } func TestLRUPCDeleteAll(t *testing.T) { - lru := NewLRUPlanCache(3, 0, 0, pickFromBucket) + lru := NewLRUPlanCache(3, 0, 0, PickPlanFromBucket, MockContext()) - keys := make([]*mockCacheKey, 3) - vals := make([]*fakePlan, 3) + keys := make([]*planCacheKey, 3) + vals := make([]*PlanCacheValue, 3) pTypes := [][]*types.FieldType{{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeEnum)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDate)}, } for i := 0; i < 3; i++ { - keys[i] = newMockHashKey(int64(i)) - vals[i] = &fakePlan{ - plan: int64(i), - tps: pTypes[i], + keys[i] = &planCacheKey{database: strconv.FormatInt(int64(i), 10)} + vals[i] = &PlanCacheValue{ + matchOpts: planCacheMatchOpts{ + paramTypes: pTypes[i], + }, } - lru.Put(keys[i], vals[i], pTypes[i]) + lru.Put(keys[i], vals[i], pTypes[i], []uint64{}) } require.Equal(t, 3, int(lru.size)) lru.DeleteAll() for i := 0; i < 3; i++ { - value, exists := lru.Get(keys[i], pTypes[i]) + value, exists := lru.Get(keys[i], pTypes[i], []uint64{}) require.False(t, exists) require.Nil(t, value) require.Equal(t, 0, int(lru.size)) @@ -256,14 +253,14 @@ func TestLRUPCDeleteAll(t *testing.T) { func TestLRUPCSetCapacity(t *testing.T) { maxMemDroppedKv := make(map[kvcache.Key]kvcache.Value) - lru := NewLRUPlanCache(5, 0, 0, pickFromBucket) + lru := NewLRUPlanCache(5, 0, 0, PickPlanFromBucket, MockContext()) lru.onEvict = func(key kvcache.Key, value kvcache.Value) { maxMemDroppedKv[key] = value } require.Equal(t, uint(5), lru.capacity) - keys := make([]*mockCacheKey, 5) - vals := make([]*fakePlan, 5) + keys := make([]*planCacheKey, 5) + vals := make([]*PlanCacheValue, 5) pTypes := [][]*types.FieldType{{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeEnum)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDate)}, @@ -273,12 +270,12 @@ func TestLRUPCSetCapacity(t *testing.T) { // one key corresponding to multi values for i := 0; i < 5; i++ { - keys[i] = newMockHashKey(1) - vals[i] = &fakePlan{ - plan: int64(i), - tps: pTypes[i], - } - lru.Put(keys[i], vals[i], pTypes[i]) + keys[i] = &planCacheKey{database: strconv.FormatInt(int64(1), 10)} + vals[i] = &PlanCacheValue{ + matchOpts: planCacheMatchOpts{ + paramTypes: pTypes[i], + }} + lru.Put(keys[i], vals[i], pTypes[i], []uint64{}) } require.Equal(t, lru.size, lru.capacity) require.Equal(t, uint(5), lru.size) @@ -306,7 +303,7 @@ func TestLRUPCSetCapacity(t *testing.T) { require.NotNil(t, entry) // test value - value, ok := entry.PlanValue.(*fakePlan) + value, ok := entry.PlanValue.(*PlanCacheValue) require.True(t, ok) require.Equal(t, vals[i], value) @@ -321,26 +318,23 @@ func TestLRUPCSetCapacity(t *testing.T) { } func TestIssue37914(t *testing.T) { - lru := NewLRUPlanCache(3, 0.1, 1, pickFromBucket) + lru := NewLRUPlanCache(3, 0.1, 1, PickPlanFromBucket, MockContext()) pTypes := []*types.FieldType{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)} - key := newMockHashKey(int64(1)) - val := &fakePlan{ - plan: int64(1), - tps: pTypes, - } + key := &planCacheKey{database: strconv.FormatInt(int64(1), 10)} + val := &PlanCacheValue{matchOpts: planCacheMatchOpts{paramTypes: pTypes}} require.NotPanics(t, func() { - lru.Put(key, val, pTypes) + lru.Put(key, val, pTypes, []uint64{}) }) } func TestIssue38244(t *testing.T) { - lru := NewLRUPlanCache(3, 0, 0, pickFromBucket) + lru := NewLRUPlanCache(3, 0, 0, PickPlanFromBucket, MockContext()) require.Equal(t, uint(3), lru.capacity) - keys := make([]*mockCacheKey, 5) - vals := make([]*fakePlan, 5) + keys := make([]*planCacheKey, 5) + vals := make([]*PlanCacheValue, 5) pTypes := [][]*types.FieldType{{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeEnum)}, {types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDate)}, @@ -350,14 +344,48 @@ func TestIssue38244(t *testing.T) { // one key corresponding to multi values for i := 0; i < 5; i++ { - keys[i] = newMockHashKey(int64(i)) - vals[i] = &fakePlan{ - plan: int64(i), - tps: pTypes[i], - } - lru.Put(keys[i], vals[i], pTypes[i]) + keys[i] = &planCacheKey{database: strconv.FormatInt(int64(i), 10)} + vals[i] = &PlanCacheValue{matchOpts: planCacheMatchOpts{paramTypes: pTypes[i]}} + lru.Put(keys[i], vals[i], pTypes[i], []uint64{}) } require.Equal(t, lru.size, lru.capacity) require.Equal(t, uint(3), lru.size) require.Equal(t, len(lru.buckets), 3) } + +func TestLRUPlanCacheMemoryUsage(t *testing.T) { + pTypes := []*types.FieldType{types.NewFieldType(mysql.TypeFloat), types.NewFieldType(mysql.TypeDouble)} + ctx := MockContext() + ctx.GetSessionVars().EnablePreparedPlanCacheMemoryMonitor = true + lru := NewLRUPlanCache(3, 0, 0, PickPlanFromBucket, ctx) + evict := make(map[kvcache.Key]kvcache.Value) + lru.onEvict = func(key kvcache.Key, value kvcache.Value) { + evict[key] = value + } + var res int64 = 0 + // put + for i := 0; i < 3; i++ { + k := randomPlanCacheKey() + v := randomPlanCacheValue(pTypes) + lru.Put(k, v, pTypes, []uint64{}) + res += k.MemoryUsage() + v.MemoryUsage() + require.Equal(t, lru.MemoryUsage(), res) + } + // evict + p := &PhysicalTableScan{} + k := &planCacheKey{database: "3"} + v := &PlanCacheValue{Plan: p} + lru.Put(k, v, pTypes, []uint64{}) + res += k.MemoryUsage() + v.MemoryUsage() + for kk, vv := range evict { + res -= kk.(*planCacheKey).MemoryUsage() + vv.(*PlanCacheValue).MemoryUsage() + } + require.Equal(t, lru.MemoryUsage(), res) + // delete + lru.Delete(k) + res -= k.MemoryUsage() + v.MemoryUsage() + require.Equal(t, lru.MemoryUsage(), res) + // delete all + lru.DeleteAll() + require.Equal(t, lru.MemoryUsage(), int64(0)) +} diff --git a/planner/core/plan_cache_param.go b/planner/core/plan_cache_param.go index a1e4b5a3f6703..9094edec621c0 100644 --- a/planner/core/plan_cache_param.go +++ b/planner/core/plan_cache_param.go @@ -15,6 +15,7 @@ package core import ( + "context" "errors" "strings" "sync" @@ -54,7 +55,7 @@ func (pr *paramReplacer) Enter(in ast.Node) (out ast.Node, skipChildren bool) { switch n := in.(type) { case *driver.ValueExpr: pr.params = append(pr.params, n) - // offset is used as order in general plan cache. + // offset is used as order in non-prepared plan cache. param := ast.NewParamMarkerExpr(len(pr.params) - 1) return param, true } @@ -70,7 +71,7 @@ func (pr *paramReplacer) Reset() { pr.params = nil } // ParameterizeAST parameterizes this StmtNode. // e.g. `select * from t where a<10 and b<23` --> `select * from t where a `select * from t where a<10 and b<23`. -func RestoreASTWithParams(_ sessionctx.Context, stmt ast.StmtNode, params []*driver.ValueExpr) error { +func RestoreASTWithParams(ctx context.Context, _ sessionctx.Context, stmt ast.StmtNode, params []*driver.ValueExpr) error { + if v := ctx.Value("____RestoreASTWithParamsErr"); v != nil { + return errors.New("____RestoreASTWithParamsErr") + } + pr := paramRestorerPool.Get().(*paramRestorer) defer func() { pr.Reset() diff --git a/planner/core/plan_cache_param_test.go b/planner/core/plan_cache_param_test.go index 5c65b89767a60..ee4a8e9ae65c5 100644 --- a/planner/core/plan_cache_param_test.go +++ b/planner/core/plan_cache_param_test.go @@ -15,6 +15,7 @@ package core import ( + "context" "strings" "testing" @@ -61,7 +62,7 @@ func TestParameterize(t *testing.T) { for _, c := range cases { stmt, err := parser.New().ParseOneStmt(c.sql, "", "") require.Nil(t, err) - paramSQL, params, err := ParameterizeAST(sctx, stmt) + paramSQL, params, err := ParameterizeAST(context.Background(), sctx, stmt) require.Nil(t, err) require.Equal(t, c.paramSQL, paramSQL) require.Equal(t, len(c.params), len(params)) @@ -69,7 +70,7 @@ func TestParameterize(t *testing.T) { require.Equal(t, c.params[i], params[i].Datum.GetValue()) } - err = RestoreASTWithParams(sctx, stmt, params) + err = RestoreASTWithParams(context.Background(), sctx, stmt, params) require.Nil(t, err) var buf strings.Builder rCtx := format.NewRestoreCtx(format.DefaultRestoreFlags, &buf) diff --git a/planner/core/plan_cache_test.go b/planner/core/plan_cache_test.go index 15ef06ab4595d..8acc28b7b0062 100644 --- a/planner/core/plan_cache_test.go +++ b/planner/core/plan_cache_test.go @@ -15,6 +15,7 @@ package core_test import ( + "context" "errors" "fmt" "math/rand" @@ -77,11 +78,101 @@ func TestInitLRUWithSystemVar(t *testing.T) { tk.MustQuery("select @@session.tidb_prepared_plan_cache_size").Check(testkit.Rows("1")) sessionVar := tk.Session().GetSessionVars() - lru := plannercore.NewLRUPlanCache(uint(sessionVar.PreparedPlanCacheSize), 0, 0, plannercore.PickPlanFromBucket) + lru := plannercore.NewLRUPlanCache(uint(sessionVar.PreparedPlanCacheSize), 0, 0, plannercore.PickPlanFromBucket, tk.Session()) require.NotNil(t, lru) } -func TestGeneralPlanCacheBasically(t *testing.T) { +func TestIssue40296(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`create database test_40296`) + tk.MustExec(`use test_40296`) + tk.MustExec(`CREATE TABLE IDT_MULTI15880STROBJSTROBJ ( + COL1 enum('aa','bb','cc','dd','ff','gg','kk','ll','mm','ee') DEFAULT NULL, + COL2 decimal(20,0) DEFAULT NULL, + COL3 date DEFAULT NULL, + KEY U_M_COL4 (COL1,COL2), + KEY U_M_COL5 (COL3,COL2))`) + tk.MustExec(`insert into IDT_MULTI15880STROBJSTROBJ values("ee", -9605492323393070105, "0850-03-15")`) + tk.MustExec(`set session tidb_enable_non_prepared_plan_cache=on`) + tk.MustQuery(`select * from IDT_MULTI15880STROBJSTROBJ where col1 in ("dd", "dd") or col2 = 9923875910817805958 or col3 = "9994-11-11"`).Check( + testkit.Rows()) + tk.MustQuery(`select * from IDT_MULTI15880STROBJSTROBJ where col1 in ("aa", "aa") or col2 = -9605492323393070105 or col3 = "0005-06-22"`).Check( + testkit.Rows("ee -9605492323393070105 0850-03-15")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // unary operator '-' is not supported now. +} + +func TestNonPreparedPlanCacheWithExplain(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int)") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + tk.MustExec("select * from t where a=1") // cache this plan + + tk.MustQuery("explain select * from t where a=2").Check(testkit.Rows( + `Selection_8 10.00 root eq(test.t.a, 2)`, + `└─TableReader_7 10.00 root data:Selection_6`, + ` └─Selection_6 10.00 cop[tikv] eq(test.t.a, 2)`, + ` └─TableFullScan_5 10000.00 cop[tikv] table:t keep order:false, stats:pseudo`)) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + + tk.MustQuery("explain format=verbose select * from t where a=2").Check(testkit.Rows( + `Selection_8 10.00 169474.57 root eq(test.t.a, 2)`, + `└─TableReader_7 10.00 168975.57 root data:Selection_6`, + ` └─Selection_6 10.00 2534000.00 cop[tikv] eq(test.t.a, 2)`, + ` └─TableFullScan_5 10000.00 2035000.00 cop[tikv] table:t keep order:false, stats:pseudo`)) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + + tk.MustQuery("explain analyze select * from t where a=2").CheckAt([]int{0, 1, 2, 3}, [][]interface{}{ + {"Selection_8", "10.00", "0", "root"}, + {"└─TableReader_7", "10.00", "0", "root"}, + {" └─Selection_6", "10.00", "0", "cop[tikv]"}, + {" └─TableFullScan_5", "10000.00", "0", "cop[tikv]"}, + }) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) +} + +func TestNonPreparedPlanCacheFallback(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec(`create table t (a int)`) + for i := 0; i < 5; i++ { + tk.MustExec(fmt.Sprintf("insert into t values (%v)", i)) + } + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + // inject a fault to GeneratePlanCacheStmtWithAST + ctx := context.WithValue(context.Background(), "____GeneratePlanCacheStmtWithASTErr", struct{}{}) + tk.MustQueryWithContext(ctx, "select * from t where a in (1, 2)").Sort().Check(testkit.Rows("1", "2")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // cannot generate PlanCacheStmt + tk.MustQueryWithContext(ctx, "select * from t where a in (1, 3)").Sort().Check(testkit.Rows("1", "3")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // cannot generate PlanCacheStmt + tk.MustQuery("select * from t where a in (1, 2)").Sort().Check(testkit.Rows("1", "2")) + tk.MustQuery("select * from t where a in (1, 3)").Sort().Check(testkit.Rows("1", "3")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) // no error + + // inject a fault to GetPlanFromSessionPlanCache + tk.MustQuery("select * from t where a=1").Check(testkit.Rows("1")) // cache this plan + tk.MustQuery("select * from t where a=2").Check(testkit.Rows("2")) // plan from cache + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + ctx = context.WithValue(context.Background(), "____GetPlanFromSessionPlanCacheErr", struct{}{}) + tk.MustQueryWithContext(ctx, "select * from t where a=3").Check(testkit.Rows("3")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // fallback to the normal opt-path + tk.MustQueryWithContext(ctx, "select * from t where a=4").Check(testkit.Rows("4")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // fallback to the normal opt-path + tk.MustQueryWithContext(context.Background(), "select * from t where a=0").Check(testkit.Rows("0")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) // use the cached plan if no error + + // inject a fault to RestoreASTWithParams + ctx = context.WithValue(context.Background(), "____GetPlanFromSessionPlanCacheErr", struct{}{}) + ctx = context.WithValue(ctx, "____RestoreASTWithParamsErr", struct{}{}) + _, err := tk.ExecWithContext(ctx, "select * from t where a=1") + require.NotNil(t, err) +} + +func TestNonPreparedPlanCacheBasically(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec(`use test`) @@ -101,11 +192,11 @@ func TestGeneralPlanCacheBasically(t *testing.T) { } for _, query := range queries { - tk.MustExec(`set tidb_enable_general_plan_cache=0`) + tk.MustExec(`set tidb_enable_non_prepared_plan_cache=0`) resultNormal := tk.MustQuery(query).Sort() tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0")) - tk.MustExec(`set tidb_enable_general_plan_cache=1`) + tk.MustExec(`set tidb_enable_non_prepared_plan_cache=1`) tk.MustQuery(query) // first process tk.MustQuery(query).Sort().Check(resultNormal.Rows()) // equal to the result without plan-cache tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1")) // this plan is from plan-cache @@ -130,3 +221,285 @@ func TestIssue38269(t *testing.T) { rows := tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Rows() require.Contains(t, rows[6][4], "range: decided by [eq(test.t2.a, test.t1.a) in(test.t2.b, 40, 50, 60)]") } + +func TestIssue38533(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (a int, key (a))") + tk.MustExec(`prepare st from "select /*+ use_index(t, a) */ a from t where a=? and a=?"`) + tk.MustExec(`set @a=1`) + tk.MustExec(`execute st using @a, @a`) + tkProcess := tk.Session().ShowProcess() + ps := []*util.ProcessInfo{tkProcess} + tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) + plan := tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Rows() + require.True(t, strings.Contains(plan[1][0].(string), "RangeScan")) // range-scan instead of full-scan + + tk.MustExec(`execute st using @a, @a`) + tk.MustExec(`execute st using @a, @a`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) +} + +func TestInvalidRange(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (a int, key(a))") + tk.MustExec("prepare st from 'select * from t where a>? and a 123 + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: '123' may be converted to INT")) + + tk.MustExec("prepare stmt from 'select * from t where a=? and a=?'") + tk.MustExec("set @a=1, @b=1") + tk.MustExec("execute stmt using @a, @b") // a=1 and a=1 -> a=1 + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: some parameters may be overwritten")) +} + +func TestIssue40224(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (a int, key(a))") + tk.MustExec("prepare st from 'select a from t where a in (?, ?)'") + tk.MustExec("set @a=1.0, @b=2.0") + tk.MustExec("execute st using @a, @b") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: '1.0' may be converted to INT")) + tk.MustExec("execute st using @a, @b") + tkProcess := tk.Session().ShowProcess() + ps := []*util.ProcessInfo{tkProcess} + tk.Session().SetSessionManager(&testkit.MockSessionManager{PS: ps}) + tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).CheckAt([]int{0}, + [][]interface{}{ + {"IndexReader_6"}, + {"└─IndexRangeScan_5"}, // range scan not full scan + }) + + tk.MustExec("set @a=1, @b=2") + tk.MustExec("execute st using @a, @b") + tk.MustQuery("show warnings").Check(testkit.Rows()) // no warning for INT values + tk.MustExec("execute st using @a, @b") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) // cacheable for INT + tk.MustExec("execute st using @a, @b") + tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).CheckAt([]int{0}, + [][]interface{}{ + {"IndexReader_6"}, + {"└─IndexRangeScan_5"}, // range scan not full scan + }) +} + +func TestIssue40225(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (a int, key(a))") + tk.MustExec("prepare st from 'select * from t where a INT) since plan-cache is totally disabled. + + tk.MustExec("prepare st from 'select * from t where a>?'") + tk.MustExec("set @a=1") + tk.MustExec("execute st using @a") + tk.MustExec("execute st using @a") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustExec("create binding for select * from t where a>1 using select /*+ ignore_plan_cache() */ * from t where a>1") + tk.MustExec("execute st using @a") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + tk.MustExec("execute st using @a") + tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1")) +} + +func TestPlanCacheWithLimit(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int primary key, b int)") + + testCases := []struct { + sql string + params []int + }{ + {"prepare stmt from 'select * from t limit ?'", []int{1}}, + {"prepare stmt from 'select * from t limit ?, ?'", []int{1, 2}}, + {"prepare stmt from 'delete from t order by a limit ?'", []int{1}}, + {"prepare stmt from 'insert into t select * from t order by a desc limit ?'", []int{1}}, + {"prepare stmt from 'insert into t select * from t order by a desc limit ?, ?'", []int{1, 2}}, + {"prepare stmt from 'update t set a = 1 limit ?'", []int{1}}, + {"prepare stmt from '(select * from t order by a limit ?) union (select * from t order by a desc limit ?)'", []int{1, 2}}, + {"prepare stmt from 'select * from t where a = ? limit ?, ?'", []int{1, 1, 1}}, + {"prepare stmt from 'select * from t where a in (?, ?) limit ?, ?'", []int{1, 2, 1, 1}}, + } + + for idx, testCase := range testCases { + tk.MustExec(testCase.sql) + var using []string + for i, p := range testCase.params { + tk.MustExec(fmt.Sprintf("set @a%d = %d", i, p)) + using = append(using, fmt.Sprintf("@a%d", i)) + } + + tk.MustExec("execute stmt using " + strings.Join(using, ", ")) + tk.MustExec("execute stmt using " + strings.Join(using, ", ")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + + if idx < 6 { + tk.MustExec("set @a0 = 6") + tk.MustExec("execute stmt using " + strings.Join(using, ", ")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + } + } + + tk.MustExec("prepare stmt from 'select * from t limit ?'") + tk.MustExec("set @a = 10001") + tk.MustExec("execute stmt using @a") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: limit count more than 10000")) +} diff --git a/planner/core/plan_cache_utils.go b/planner/core/plan_cache_utils.go index ac73f34e9babb..3271392d62e97 100644 --- a/planner/core/plan_cache_utils.go +++ b/planner/core/plan_cache_utils.go @@ -19,6 +19,7 @@ import ( "math" "strconv" "time" + "unsafe" "github.com/pingcap/errors" "github.com/pingcap/tidb/kv" @@ -34,6 +35,7 @@ import ( "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/hint" "github.com/pingcap/tidb/util/kvcache" + "github.com/pingcap/tidb/util/size" atomic2 "go.uber.org/atomic" "golang.org/x/exp/slices" ) @@ -62,18 +64,24 @@ func (e *paramMarkerExtractor) Leave(in ast.Node) (ast.Node, bool) { } // GeneratePlanCacheStmtWithAST generates the PlanCacheStmt structure for this AST. -func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, stmt ast.StmtNode) (*PlanCacheStmt, Plan, int, error) { +// paramSQL is the corresponding parameterized sql like 'select * from t where a?'. +// paramStmt is the Node of paramSQL. +func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, paramSQL string, paramStmt ast.StmtNode) (*PlanCacheStmt, Plan, int, error) { + if v := ctx.Value("____GeneratePlanCacheStmtWithASTErr"); v != nil { // for testing + return nil, nil, 0, errors.New("____GeneratePlanCacheStmtWithASTErr") + } + vars := sctx.GetSessionVars() var extractor paramMarkerExtractor - stmt.Accept(&extractor) + paramStmt.Accept(&extractor) // DDL Statements can not accept parameters - if _, ok := stmt.(ast.DDLNode); ok && len(extractor.markers) > 0 { + if _, ok := paramStmt.(ast.DDLNode); ok && len(extractor.markers) > 0 { return nil, nil, 0, ErrPrepareDDL } - switch stmt.(type) { - case *ast.LoadDataStmt, *ast.PrepareStmt, *ast.ExecuteStmt, *ast.DeallocateStmt, *ast.NonTransactionalDeleteStmt: + switch paramStmt.(type) { + case *ast.LoadDataStmt, *ast.PrepareStmt, *ast.ExecuteStmt, *ast.DeallocateStmt, *ast.NonTransactionalDMLStmt: return nil, nil, 0, ErrUnsupportedPs } @@ -84,7 +92,7 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, } ret := &PreprocessorReturn{} - err := Preprocess(sctx, stmt, InPrepare, WithPreprocessorReturn(ret)) + err := Preprocess(ctx, sctx, paramStmt, InPrepare, WithPreprocessorReturn(ret)) if err != nil { return nil, nil, 0, err } @@ -101,8 +109,8 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, } prepared := &ast.Prepared{ - Stmt: stmt, - StmtType: ast.GetStmtLabel(stmt), + Stmt: paramStmt, + StmtType: ast.GetStmtLabel(paramStmt), Params: extractor.markers, SchemaVersion: ret.InfoSchema.SchemaMetaVersion(), } @@ -111,12 +119,18 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, var ( normalizedSQL4PC, digest4PC string selectStmtNode ast.StmtNode + cacheable bool + reason string ) if !vars.EnablePreparedPlanCache { - prepared.UseCache = false + cacheable = false + reason = "plan cache is disabled" } else { - prepared.UseCache = CacheableWithCtx(sctx, stmt, ret.InfoSchema) - selectStmtNode, normalizedSQL4PC, digest4PC, err = ExtractSelectAndNormalizeDigest(stmt, vars.CurrentDB) + cacheable, reason = CacheableWithCtx(sctx, paramStmt, ret.InfoSchema) + if !cacheable { + sctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("skip plan-cache: " + reason)) + } + selectStmtNode, normalizedSQL4PC, digest4PC, err = ExtractSelectAndNormalizeDigest(paramStmt, vars.CurrentDB) if err != nil || selectStmtNode == nil { normalizedSQL4PC = "" digest4PC = "" @@ -132,7 +146,7 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, var p Plan destBuilder, _ := NewPlanBuilder().Init(sctx, ret.InfoSchema, &hint.BlockHintProcessor{}) - p, err = destBuilder.Build(ctx, stmt) + p, err = destBuilder.Build(ctx, paramStmt) if err != nil { return nil, nil, 0, err } @@ -140,7 +154,7 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, preparedObj := &PlanCacheStmt{ PreparedAst: prepared, StmtDB: vars.CurrentDB, - StmtText: stmt.Text(), + StmtText: paramSQL, VisitInfos: destBuilder.GetVisitInfo(), NormalizedSQL: normalizedSQL, SQLDigest: digest, @@ -148,6 +162,8 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, SnapshotTSEvaluator: ret.SnapshotTSEvaluator, NormalizedSQL4PC: normalizedSQL4PC, SQLDigest4PC: digest4PC, + StmtCacheable: cacheable, + UncacheableReason: reason, } if err = CheckPreparedPriv(sctx, preparedObj, ret.InfoSchema); err != nil { return nil, nil, 0, err @@ -155,21 +171,6 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context, return preparedObj, p, ParamCount, nil } -func getValidPlanFromCache(sctx sessionctx.Context, isGeneralPlanCache bool, key kvcache.Key, paramTypes []*types.FieldType) (*PlanCacheValue, bool) { - cache := sctx.GetPlanCache(isGeneralPlanCache) - val, exist := cache.Get(key, paramTypes) - if !exist { - return nil, exist - } - candidate := val.(*PlanCacheValue) - return candidate, true -} - -func putPlanIntoCache(sctx sessionctx.Context, isGeneralPlanCache bool, key kvcache.Key, plan *PlanCacheValue, paramTypes []*types.FieldType) { - cache := sctx.GetPlanCache(isGeneralPlanCache) - cache.Put(key, plan, paramTypes) -} - // planCacheKey is used to access Plan Cache. We put some variables that do not affect the plan into planCacheKey, such as the sql text. // Put the parameters that may affect the plan in planCacheValue. // However, due to some compatibility reasons, we will temporarily keep some system variable-related values in planCacheKey. @@ -194,7 +195,8 @@ type planCacheKey struct { restrictedReadOnly bool TiDBSuperReadOnly bool - hash []byte + memoryUsage int64 // Do not include in hash + hash []byte } // Hash implements Key interface. @@ -232,6 +234,31 @@ func (key *planCacheKey) Hash() []byte { return key.hash } +const emptyPlanCacheKeySize = int64(unsafe.Sizeof(planCacheKey{})) + +// MemoryUsage return the memory usage of planCacheKey +func (key *planCacheKey) MemoryUsage() (sum int64) { + if key == nil { + return + } + + if key.memoryUsage > 0 { + return key.memoryUsage + } + sum = emptyPlanCacheKeySize + int64(len(key.database)+len(key.stmtText)+len(key.bindSQL)) + + int64(len(key.isolationReadEngines))*size.SizeOfUint8 + int64(cap(key.hash)) + key.memoryUsage = sum + return +} + +type planCacheMatchOpts struct { + // paramTypes stores all parameters' FieldType, some different parameters may share same plan + paramTypes FieldSlice + // limitOffsetAndCount stores all the offset and key parameters extract from limit statement + // only used for cache and pick plan with parameters in limit + limitOffsetAndCount []uint64 +} + // SetPstmtIDSchemaVersion implements PstmtCacheKeyMutator interface to change pstmtID and schemaVersion of cacheKey. // so we can reuse Key instead of new every time. func SetPstmtIDSchemaVersion(key kvcache.Key, stmtText string, schemaVersion int64, isolationReadEngines map[kv.StoreType]struct{}) { @@ -302,9 +329,7 @@ func (s FieldSlice) CheckTypesCompatibility4PC(tps []*types.FieldType) bool { // string types will show up here, and (2) we don't need flen and decimal to be matched exactly to use plan cache tpEqual := (s[i].GetType() == tps[i].GetType()) || (s[i].GetType() == mysql.TypeVarchar && tps[i].GetType() == mysql.TypeVarString) || - (s[i].GetType() == mysql.TypeVarString && tps[i].GetType() == mysql.TypeVarchar) || - // TypeNull should be considered the same as other types. - (s[i].GetType() == mysql.TypeNull || tps[i].GetType() == mysql.TypeNull) + (s[i].GetType() == mysql.TypeVarString && tps[i].GetType() == mysql.TypeVarchar) if !tpEqual || s[i].GetCharset() != tps[i].GetCharset() || s[i].GetCollate() != tps[i].GetCollate() || (s[i].EvalType() == types.ETInt && mysql.HasUnsignedFlag(s[i].GetFlag()) != mysql.HasUnsignedFlag(tps[i].GetFlag())) { return false @@ -324,16 +349,58 @@ type PlanCacheValue struct { Plan Plan OutPutNames []*types.FieldName TblInfo2UnionScan map[*model.TableInfo]bool - ParamTypes FieldSlice + memoryUsage int64 + + // matchOpts stores some fields help to choose a suitable plan + matchOpts planCacheMatchOpts } func (v *PlanCacheValue) varTypesUnchanged(txtVarTps []*types.FieldType) bool { - return v.ParamTypes.CheckTypesCompatibility4PC(txtVarTps) + return v.matchOpts.paramTypes.CheckTypesCompatibility4PC(txtVarTps) +} + +// unKnownMemoryUsage represent the memory usage of uncounted structure, maybe need implement later +// 100 KiB is approximate consumption of a plan from our internal tests +const unKnownMemoryUsage = int64(50 * size.KB) + +// MemoryUsage return the memory usage of PlanCacheValue +func (v *PlanCacheValue) MemoryUsage() (sum int64) { + if v == nil { + return + } + + if v.memoryUsage > 0 { + return v.memoryUsage + } + switch x := v.Plan.(type) { + case PhysicalPlan: + sum = x.MemoryUsage() + case *Insert: + sum = x.MemoryUsage() + case *Update: + sum = x.MemoryUsage() + case *Delete: + sum = x.MemoryUsage() + default: + sum = unKnownMemoryUsage + } + + sum += size.SizeOfInterface + size.SizeOfSlice*2 + int64(cap(v.OutPutNames)+cap(v.matchOpts.paramTypes))*size.SizeOfPointer + + size.SizeOfMap + int64(len(v.TblInfo2UnionScan))*(size.SizeOfPointer+size.SizeOfBool) + size.SizeOfInt64*2 + + for _, name := range v.OutPutNames { + sum += name.MemoryUsage() + } + for _, ft := range v.matchOpts.paramTypes { + sum += ft.MemoryUsage() + } + v.memoryUsage = sum + return } // NewPlanCacheValue creates a SQLCacheValue. func NewPlanCacheValue(plan Plan, names []*types.FieldName, srcMap map[*model.TableInfo]bool, - paramTypes []*types.FieldType) *PlanCacheValue { + paramTypes []*types.FieldType, limitParams []uint64) *PlanCacheValue { dstMap := make(map[*model.TableInfo]bool) for k, v := range srcMap { dstMap[k] = v @@ -346,17 +413,27 @@ func NewPlanCacheValue(plan Plan, names []*types.FieldName, srcMap map[*model.Ta Plan: plan, OutPutNames: names, TblInfo2UnionScan: dstMap, - ParamTypes: userParamTypes, + matchOpts: planCacheMatchOpts{ + paramTypes: userParamTypes, + limitOffsetAndCount: limitParams, + }, } } // PlanCacheStmt store prepared ast from PrepareExec and other related fields type PlanCacheStmt struct { - PreparedAst *ast.Prepared - StmtDB string // which DB the statement will be processed over - VisitInfos []visitInfo - ColumnInfos interface{} - Executor interface{} + PreparedAst *ast.Prepared + StmtDB string // which DB the statement will be processed over + VisitInfos []visitInfo + ColumnInfos interface{} + // Executor is only used for point get scene. + // Notice that we should only cache the PointGetExecutor that have a snapshot with MaxTS in it. + // If the current plan is not PointGet or does not use MaxTS optimization, this value should be nil here. + Executor interface{} + + StmtCacheable bool // Whether this stmt is cacheable. + UncacheableReason string // Why this stmt is uncacheable. + NormalizedSQL string NormalizedPlan string SQLDigest *parser.Digest @@ -389,3 +466,69 @@ func GetPreparedStmt(stmt *ast.ExecuteStmt, vars *variable.SessionVars) (*PlanCa } return nil, ErrStmtNotFound } + +type limitExtractor struct { + cacheable bool // For safety considerations, check if limit count less than 10000 + offsetAndCount []uint64 + unCacheableReason string + paramTypeErr error +} + +// Enter implements Visitor interface. +func (checker *limitExtractor) Enter(in ast.Node) (out ast.Node, skipChildren bool) { + switch node := in.(type) { + case *ast.Limit: + if node.Count != nil { + if count, isParamMarker := node.Count.(*driver.ParamMarkerExpr); isParamMarker { + typeExpected, val := CheckParamTypeInt64orUint64(count) + if typeExpected { + if val > 10000 { + checker.cacheable = false + checker.unCacheableReason = "limit count more than 10000" + return in, true + } + checker.offsetAndCount = append(checker.offsetAndCount, val) + } else { + checker.paramTypeErr = ErrWrongArguments.GenWithStackByArgs("LIMIT") + return in, true + } + } + } + if node.Offset != nil { + if offset, isParamMarker := node.Offset.(*driver.ParamMarkerExpr); isParamMarker { + typeExpected, val := CheckParamTypeInt64orUint64(offset) + if typeExpected { + checker.offsetAndCount = append(checker.offsetAndCount, val) + } else { + checker.paramTypeErr = ErrWrongArguments.GenWithStackByArgs("LIMIT") + return in, true + } + } + } + } + return in, false +} + +// Leave implements Visitor interface. +func (checker *limitExtractor) Leave(in ast.Node) (out ast.Node, ok bool) { + return in, checker.cacheable +} + +// ExtractLimitFromAst extract limit offset and count from ast for plan cache key encode +func ExtractLimitFromAst(node ast.Node, sctx sessionctx.Context) ([]uint64, error) { + if node == nil { + return nil, nil + } + checker := limitExtractor{ + cacheable: true, + offsetAndCount: []uint64{}, + } + node.Accept(&checker) + if checker.paramTypeErr != nil { + return nil, checker.paramTypeErr + } + if sctx != nil && !checker.cacheable { + sctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.New("skip plan-cache: " + checker.unCacheableReason)) + } + return checker.offsetAndCount, nil +} diff --git a/planner/core/plan_cacheable_checker.go b/planner/core/plan_cacheable_checker.go index 0e4e28250ad4c..2ff9e51823ee2 100644 --- a/planner/core/plan_cacheable_checker.go +++ b/planner/core/plan_cacheable_checker.go @@ -15,6 +15,8 @@ package core import ( + "fmt" + "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/parser/ast" @@ -27,20 +29,21 @@ import ( // Cacheable checks whether the input ast is cacheable with empty session context, which is mainly for testing. func Cacheable(node ast.Node, is infoschema.InfoSchema) bool { - return CacheableWithCtx(nil, node, is) + c, _ := CacheableWithCtx(nil, node, is) + return c } // CacheableWithCtx checks whether the input ast is cacheable. // Handle "ignore_plan_cache()" hint // If there are multiple hints, only one will take effect -func CacheableWithCtx(sctx sessionctx.Context, node ast.Node, is infoschema.InfoSchema) bool { +func CacheableWithCtx(sctx sessionctx.Context, node ast.Node, is infoschema.InfoSchema) (bool, string) { _, isSelect := node.(*ast.SelectStmt) _, isUpdate := node.(*ast.UpdateStmt) _, isInsert := node.(*ast.InsertStmt) _, isDelete := node.(*ast.DeleteStmt) _, isSetOpr := node.(*ast.SetOprStmt) if !(isSelect || isUpdate || isInsert || isDelete || isSetOpr) { - return false + return false, "not a SELECT/UPDATE/INSERT/DELETE/SET statement" } checker := cacheableChecker{ sctx: sctx, @@ -48,7 +51,7 @@ func CacheableWithCtx(sctx sessionctx.Context, node ast.Node, is infoschema.Info schema: is, } node.Accept(&checker) - return checker.cacheable + return checker.cacheable, checker.reason } // cacheableChecker checks whether a query's plan can be cached, querys that: @@ -61,6 +64,7 @@ type cacheableChecker struct { sctx sessionctx.Context cacheable bool schema infoschema.InfoSchema + reason string // reason why cannot use plan-cache } // Enter implements Visitor interface. @@ -70,6 +74,7 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren for _, hints := range node.TableHints { if hints.HintName.L == HintIgnorePlanCache { checker.cacheable = false + checker.reason = "ignore plan cache by hint" return in, true } } @@ -77,6 +82,7 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren for _, hints := range node.TableHints { if hints.HintName.L == HintIgnorePlanCache { checker.cacheable = false + checker.reason = "ignore plan cache by hint" return in, true } } @@ -84,21 +90,40 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren for _, hints := range node.TableHints { if hints.HintName.L == HintIgnorePlanCache { checker.cacheable = false + checker.reason = "ignore plan cache by hint" + return in, true + } + } + case *ast.InsertStmt: + if node.Select == nil { + // do not cache insert-values-stmt like 'insert into t values (...)' since + // no performance benefit and to save memory. + checker.cacheable = false + checker.reason = "ignore insert-values-stmt" + return in, true + } + for _, hints := range node.TableHints { + if hints.HintName.L == HintIgnorePlanCache { + checker.cacheable = false + checker.reason = "ignore plan cache by hint" return in, true } } case *ast.VariableExpr, *ast.ExistsSubqueryExpr, *ast.SubqueryExpr: checker.cacheable = false + checker.reason = "query has sub-queries is un-cacheable" return in, true case *ast.FuncCallExpr: if _, found := expression.UnCacheableFunctions[node.FnName.L]; found { checker.cacheable = false + checker.reason = fmt.Sprintf("query has '%v' is un-cacheable", node.FnName.L) return in, true } case *ast.OrderByClause: for _, item := range node.Items { if _, isParamMarker := item.Expr.(*driver.ParamMarkerExpr); isParamMarker { checker.cacheable = false + checker.reason = "query has 'order by ?' is un-cacheable" return in, true } } @@ -106,25 +131,30 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren for _, item := range node.Items { if _, isParamMarker := item.Expr.(*driver.ParamMarkerExpr); isParamMarker { checker.cacheable = false + checker.reason = "query has 'group by ?' is un-cacheable" return in, true } } - case *ast.Limit: - if node.Count != nil { - if _, isParamMarker := node.Count.(*driver.ParamMarkerExpr); isParamMarker { - checker.cacheable = false - return in, true - } - } - if node.Offset != nil { - if _, isParamMarker := node.Offset.(*driver.ParamMarkerExpr); isParamMarker { - checker.cacheable = false - return in, true - } - } + // todo: these comment is used to add switch in the later pr + //case *ast.Limit: + // if node.Count != nil { + // if _, isParamMarker := node.Count.(*driver.ParamMarkerExpr); isParamMarker { + // checker.cacheable = false + // checker.reason = "query has 'limit ?' is un-cacheable" + // return in, true + // } + // } + // if node.Offset != nil { + // if _, isParamMarker := node.Offset.(*driver.ParamMarkerExpr); isParamMarker { + // checker.cacheable = false + // checker.reason = "query has 'limit ?, 10' is un-cacheable" + // return in, true + // } + // } case *ast.FrameBound: if _, ok := node.Expr.(*driver.ParamMarkerExpr); ok { checker.cacheable = false + checker.reason = "query has ? in window function frames is un-cacheable" return in, true } case *ast.TableName: @@ -138,14 +168,17 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren } */ checker.cacheable = false + checker.reason = "query accesses partitioned tables is un-cacheable" return in, true } if hasGeneratedCol(checker.schema, node) { checker.cacheable = false + checker.reason = "query accesses generated columns is un-cacheable" return in, true } if isTempTable(checker.schema, node) { checker.cacheable = false + checker.reason = "query accesses temporary tables is un-cacheable" return in, true } } @@ -158,16 +191,16 @@ func (checker *cacheableChecker) Leave(in ast.Node) (out ast.Node, ok bool) { return in, checker.cacheable } -// GeneralPlanCacheable checks whether the input ast is cacheable for general plan cache with empty session context, which is mainly for testing. -func GeneralPlanCacheable(node ast.Node, is infoschema.InfoSchema) bool { - return GeneralPlanCacheableWithCtx(nil, node, is) +// NonPreparedPlanCacheable checks whether the input ast is cacheable for non-prepared plan cache with empty session context, which is mainly for testing. +func NonPreparedPlanCacheable(node ast.Node, is infoschema.InfoSchema) bool { + return NonPreparedPlanCacheableWithCtx(nil, node, is) } -// GeneralPlanCacheableWithCtx checks whether the input ast is cacheable for general plan cache. +// NonPreparedPlanCacheableWithCtx checks whether the input ast is cacheable for non-prepared plan cache. // Only support: select {field} from {single-table} where {cond} and {cond} ... // {cond}: {col} {op} {val} // {op}: >, <, = -func GeneralPlanCacheableWithCtx(sctx sessionctx.Context, node ast.Node, is infoschema.InfoSchema) bool { +func NonPreparedPlanCacheableWithCtx(sctx sessionctx.Context, node ast.Node, is infoschema.InfoSchema) bool { selectStmt, isSelect := node.(*ast.SelectStmt) if !isSelect { // only support select statement now return false @@ -189,7 +222,7 @@ func GeneralPlanCacheableWithCtx(sctx sessionctx.Context, node ast.Node, is info } tableRefs := from.TableRefs if tableRefs.Right != nil { - // We don't support the join for the general plan cache now. + // We don't support the join for the non-prepared plan cache now. return false } switch x := tableRefs.Left.(type) { @@ -200,7 +233,7 @@ func GeneralPlanCacheableWithCtx(sctx sessionctx.Context, node ast.Node, is info } } - checker := generalPlanCacheableChecker{ + checker := nonPreparedPlanCacheableChecker{ sctx: sctx, cacheable: true, schema: is, @@ -209,46 +242,45 @@ func GeneralPlanCacheableWithCtx(sctx sessionctx.Context, node ast.Node, is info return checker.cacheable } -// generalPlanCacheableChecker checks whether a query's plan can be cached for general plan cache. +// nonPreparedPlanCacheableChecker checks whether a query's plan can be cached for non-prepared plan cache. // NOTE: we can add more rules in the future. -type generalPlanCacheableChecker struct { +type nonPreparedPlanCacheableChecker struct { sctx sessionctx.Context cacheable bool schema infoschema.InfoSchema } // Enter implements Visitor interface. -func (checker *generalPlanCacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren bool) { +func (checker *nonPreparedPlanCacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren bool) { switch node := in.(type) { + case *ast.SelectStmt, *ast.FieldList, *ast.SelectField, *ast.TableRefsClause, *ast.Join, + *ast.TableSource, *ast.ColumnNameExpr, *ast.ColumnName, *driver.ValueExpr, *ast.PatternInExpr: + return in, !checker.cacheable // skip child if un-cacheable case *ast.BinaryOperationExpr: - if _, found := expression.GeneralPlanCacheableOp[node.Op.String()]; !found { + if _, found := expression.NonPreparedPlanCacheableOp[node.Op.String()]; !found { checker.cacheable = false - return in, true } - case *ast.FuncCallExpr: - checker.cacheable = false - return in, true + return in, !checker.cacheable case *ast.TableName: if checker.schema != nil { if isPartitionTable(checker.schema, node) { checker.cacheable = false - return in, true } if hasGeneratedCol(checker.schema, node) { checker.cacheable = false - return in, true } if isTempTable(checker.schema, node) { checker.cacheable = false - return in, true } } + return in, !checker.cacheable } - return in, false + checker.cacheable = false // unexpected cases + return in, !checker.cacheable } // Leave implements Visitor interface. -func (checker *generalPlanCacheableChecker) Leave(in ast.Node) (out ast.Node, ok bool) { +func (checker *nonPreparedPlanCacheableChecker) Leave(in ast.Node) (out ast.Node, ok bool) { return in, checker.cacheable } diff --git a/planner/core/plan_cacheable_checker_test.go b/planner/core/plan_cacheable_checker_test.go index a32294e34c54c..7d417e377888f 100644 --- a/planner/core/plan_cacheable_checker_test.go +++ b/planner/core/plan_cacheable_checker_test.go @@ -53,7 +53,9 @@ func TestCacheable(t *testing.T) { tableRefsClause := &ast.TableRefsClause{TableRefs: &ast.Join{Left: &ast.TableSource{Source: tbl}}} // test InsertStmt - stmt = &ast.InsertStmt{Table: tableRefsClause} + stmt = &ast.InsertStmt{Table: tableRefsClause} // insert-values-stmt + require.False(t, core.Cacheable(stmt, is)) + stmt = &ast.InsertStmt{Table: tableRefsClause, Select: &ast.SelectStmt{}} // insert-select-stmt require.True(t, core.Cacheable(stmt, is)) // test DeleteStmt @@ -85,7 +87,7 @@ func TestCacheable(t *testing.T) { TableRefs: tableRefsClause, Limit: limitStmt, } - require.False(t, core.Cacheable(stmt, is)) + require.True(t, core.Cacheable(stmt, is)) limitStmt = &ast.Limit{ Offset: &driver.ParamMarkerExpr{}, @@ -94,7 +96,7 @@ func TestCacheable(t *testing.T) { TableRefs: tableRefsClause, Limit: limitStmt, } - require.False(t, core.Cacheable(stmt, is)) + require.True(t, core.Cacheable(stmt, is)) limitStmt = &ast.Limit{} stmt = &ast.DeleteStmt{ @@ -137,7 +139,7 @@ func TestCacheable(t *testing.T) { TableRefs: tableRefsClause, Limit: limitStmt, } - require.False(t, core.Cacheable(stmt, is)) + require.True(t, core.Cacheable(stmt, is)) limitStmt = &ast.Limit{ Offset: &driver.ParamMarkerExpr{}, @@ -146,7 +148,7 @@ func TestCacheable(t *testing.T) { TableRefs: tableRefsClause, Limit: limitStmt, } - require.False(t, core.Cacheable(stmt, is)) + require.True(t, core.Cacheable(stmt, is)) limitStmt = &ast.Limit{} stmt = &ast.UpdateStmt{ @@ -186,7 +188,7 @@ func TestCacheable(t *testing.T) { stmt = &ast.SelectStmt{ Limit: limitStmt, } - require.False(t, core.Cacheable(stmt, is)) + require.True(t, core.Cacheable(stmt, is)) limitStmt = &ast.Limit{ Offset: &driver.ParamMarkerExpr{}, @@ -194,7 +196,7 @@ func TestCacheable(t *testing.T) { stmt = &ast.SelectStmt{ Limit: limitStmt, } - require.False(t, core.Cacheable(stmt, is)) + require.True(t, core.Cacheable(stmt, is)) limitStmt = &ast.Limit{} stmt = &ast.SelectStmt{ @@ -247,7 +249,7 @@ func TestCacheable(t *testing.T) { require.True(t, core.Cacheable(stmt, is)) } -func TestGeneralPlanCacheable(t *testing.T) { +func TestNonPreparedPlanCacheable(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -297,12 +299,12 @@ func TestGeneralPlanCacheable(t *testing.T) { for _, q := range unsupported { stmt, err := p.ParseOneStmt(q, charset, collation) require.NoError(t, err) - require.False(t, core.GeneralPlanCacheable(stmt, is)) + require.False(t, core.NonPreparedPlanCacheable(stmt, is)) } for _, q := range supported { stmt, err := p.ParseOneStmt(q, charset, collation) require.NoError(t, err) - require.True(t, core.GeneralPlanCacheable(stmt, is)) + require.True(t, core.NonPreparedPlanCacheable(stmt, is)) } } diff --git a/planner/core/plan_cost_detail_test.go b/planner/core/plan_cost_detail_test.go index 34584773aa6e8..8a5d04f2df187 100644 --- a/planner/core/plan_cost_detail_test.go +++ b/planner/core/plan_cost_detail_test.go @@ -133,11 +133,12 @@ func TestPlanCostDetail(t *testing.T) { func optimize(t *testing.T, sql string, p *parser.Parser, ctx sessionctx.Context, dom *domain.Domain) map[int]*tracing.PhysicalPlanCostDetail { stmt, err := p.ParseOneStmt(sql, "", "") require.NoError(t, err) - err = plannercore.Preprocess(ctx, stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) + err = plannercore.Preprocess(context.Background(), ctx, stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) require.NoError(t, err) sctx := plannercore.MockContext() sctx.GetSessionVars().StmtCtx.EnableOptimizeTrace = true sctx.GetSessionVars().EnableNewCostInterface = true + sctx.GetSessionVars().CostModelVersion = 1 builder, _ := plannercore.NewPlanBuilder().Init(sctx, dom.InfoSchema(), &hint.BlockHintProcessor{}) domain.GetDomain(sctx).MockInfoCacheAndLoadInfoSchema(dom.InfoSchema()) plan, err := builder.Build(context.TODO(), stmt) diff --git a/planner/core/plan_cost_ver1.go b/planner/core/plan_cost_ver1.go index 0d78c0dde8fdf..f7459c70fb01a 100644 --- a/planner/core/plan_cost_ver1.go +++ b/planner/core/plan_cost_ver1.go @@ -851,8 +851,8 @@ func (p *PhysicalHashJoin) GetCost(lCnt, rCnt float64, isMPP bool, costFlag uint } sessVars := p.ctx.GetSessionVars() oomUseTmpStorage := variable.EnableTmpStorageOnOOM.Load() - memQuota := sessVars.StmtCtx.MemTracker.GetBytesLimit() // sessVars.MemQuotaQuery && hint - rowSize := getAvgRowSize(build.statsInfo(), build.Schema()) + memQuota := sessVars.MemTracker.GetBytesLimit() // sessVars.MemQuotaQuery && hint + rowSize := getAvgRowSize(build.statsInfo(), build.Schema().Columns) spill := oomUseTmpStorage && memQuota > 0 && rowSize*buildCnt > float64(memQuota) && p.storeTp != kv.TiFlash // Cost of building hash table. cpuFactor := sessVars.GetCPUFactor() @@ -1048,8 +1048,8 @@ func (p *PhysicalSort) GetCost(count float64, schema *expression.Schema) float64 memoryCost := count * sessVars.GetMemoryFactor() oomUseTmpStorage := variable.EnableTmpStorageOnOOM.Load() - memQuota := sessVars.StmtCtx.MemTracker.GetBytesLimit() // sessVars.MemQuotaQuery && hint - rowSize := getAvgRowSize(p.statsInfo(), schema) + memQuota := sessVars.MemTracker.GetBytesLimit() // sessVars.MemQuotaQuery && hint + rowSize := getAvgRowSize(p.statsInfo(), schema.Columns) spill := oomUseTmpStorage && memQuota > 0 && rowSize*count > float64(memQuota) diskCost := count * sessVars.GetDiskFactor() * rowSize if !spill { @@ -1269,9 +1269,15 @@ func getOperatorActRows(operator PhysicalPlan) float64 { func getCardinality(operator PhysicalPlan, costFlag uint64) float64 { if hasCostFlag(costFlag, CostFlagUseTrueCardinality) { - return getOperatorActRows(operator) + actualProbeCnt := operator.getActualProbeCnt(operator.SCtx().GetSessionVars().StmtCtx.RuntimeStatsColl) + return getOperatorActRows(operator) / float64(actualProbeCnt) } - return operator.StatsCount() + rows := operator.StatsCount() + if rows == 0 && operator.SCtx().GetSessionVars().CostModelVersion == modelVer2 { + // 0 est-row can lead to 0 operator cost which makes plan choice unstable. + rows = 1 + } + return rows } // estimateNetSeekCost calculates the net seek cost for the plan. diff --git a/planner/core/plan_cost_ver2.go b/planner/core/plan_cost_ver2.go index 9d1fc4416ac18..dfecbd0761fff 100644 --- a/planner/core/plan_cost_ver2.go +++ b/planner/core/plan_cost_ver2.go @@ -17,16 +17,24 @@ package core import ( "fmt" "math" - "strings" + "strconv" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/expression/aggregation" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/planner/property" + "github.com/pingcap/tidb/planner/util" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/util/paging" + "github.com/pingcap/tipb/go-tipb" ) +// GetPlanCost returns the cost of this plan. +func GetPlanCost(p PhysicalPlan, taskType property.TaskType, option *PlanCostOption) (float64, error) { + return getPlanCost(p, taskType, option) +} + func getPlanCost(p PhysicalPlan, taskType property.TaskType, option *PlanCostOption) (float64, error) { if p.SCtx().GetSessionVars().CostModelVersion == modelVer2 { planCost, err := p.getPlanCostVer2(taskType, option) @@ -54,7 +62,7 @@ func (p *basePhysicalPlan) getPlanCostVer2(taskType property.TaskType, option *P p.planCostVer2 = sumCostVer2(childCosts...) } p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -76,7 +84,7 @@ func (p *PhysicalSelection) getPlanCostVer2(taskType property.TaskType, option * p.planCostVer2 = sumCostVer2(filterCost, childCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -100,7 +108,7 @@ func (p *PhysicalProjection) getPlanCostVer2(taskType property.TaskType, option p.planCostVer2 = sumCostVer2(childCost, divCostVer2(projCost, concurrency)) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -112,12 +120,12 @@ func (p *PhysicalIndexScan) getPlanCostVer2(taskType property.TaskType, option * } rows := getCardinality(p, option.CostFlag) - rowSize := math.Max(p.getScanRowSize(), 2.0) - scanFactor := getTaskScanFactorVer2(p, taskType) + rowSize := math.Max(getAvgRowSize(p.stats, p.schema.Columns), 2.0) // consider all index columns + scanFactor := getTaskScanFactorVer2(p, kv.TiKV, taskType) p.planCostVer2 = scanCostVer2(option, rows, rowSize, scanFactor) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -129,8 +137,14 @@ func (p *PhysicalTableScan) getPlanCostVer2(taskType property.TaskType, option * } rows := getCardinality(p, option.CostFlag) - rowSize := math.Max(p.getScanRowSize(), 2.0) - scanFactor := getTaskScanFactorVer2(p, taskType) + var rowSize float64 + if p.StoreType == kv.TiKV { + rowSize = getAvgRowSize(p.stats, p.tblCols) // consider all columns if TiKV + } else { // TiFlash + rowSize = getAvgRowSize(p.stats, p.schema.Columns) + } + rowSize = math.Max(rowSize, 2.0) + scanFactor := getTaskScanFactorVer2(p, p.StoreType, taskType) p.planCostVer2 = scanCostVer2(option, rows, rowSize, scanFactor) @@ -140,78 +154,75 @@ func (p *PhysicalTableScan) getPlanCostVer2(taskType property.TaskType, option * } p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: -// plan-cost = (child-cost + net-cost + seek-cost) / concurrency +// plan-cost = (child-cost + net-cost) / concurrency // net-cost = rows * row-size * net-factor -// seek-cost = num-tasks * seek-factor func (p *PhysicalIndexReader) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { if p.planCostInit && !hasCostFlag(option.CostFlag, CostFlagRecalculate) { return p.planCostVer2, nil } rows := getCardinality(p.indexPlan, option.CostFlag) - rowSize := getAvgRowSize(p.indexPlan.Stats(), p.indexPlan.Schema()) + rowSize := getAvgRowSize(p.stats, p.schema.Columns) netFactor := getTaskNetFactorVer2(p, taskType) - seekFactor := getTaskSeekFactorVer2(p, taskType) concurrency := float64(p.ctx.GetSessionVars().DistSQLScanConcurrency()) netCost := netCostVer2(option, rows, rowSize, netFactor) - seekCost := seekCostVer2(option, estimateNumTasks(p.indexPlan), seekFactor) childCost, err := p.indexPlan.getPlanCostVer2(property.CopSingleReadTaskType, option) if err != nil { return zeroCostVer2, err } - p.planCostVer2 = divCostVer2(sumCostVer2(childCost, netCost, seekCost), concurrency) + p.planCostVer2 = divCostVer2(sumCostVer2(childCost, netCost), concurrency) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: -// plan-cost = (child-cost + net-cost + seek-cost) / concurrency +// plan-cost = (child-cost + net-cost) / concurrency // net-cost = rows * row-size * net-factor -// seek-cost = num-tasks * seek-factor func (p *PhysicalTableReader) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { if p.planCostInit && !hasCostFlag(option.CostFlag, CostFlagRecalculate) { return p.planCostVer2, nil } rows := getCardinality(p.tablePlan, option.CostFlag) - rowSize := getAvgRowSize(p.tablePlan.Stats(), p.tablePlan.Schema()) + rowSize := getAvgRowSize(p.stats, p.schema.Columns) netFactor := getTaskNetFactorVer2(p, taskType) - seekFactor := getTaskSeekFactorVer2(p, taskType) concurrency := float64(p.ctx.GetSessionVars().DistSQLScanConcurrency()) + childType := property.CopSingleReadTaskType + if p.StoreType == kv.TiFlash { // mpp protocol + childType = property.MppTaskType + } netCost := netCostVer2(option, rows, rowSize, netFactor) - seekCost := seekCostVer2(option, estimateNumTasks(p.tablePlan), seekFactor) - childCost, err := p.tablePlan.getPlanCostVer2(property.CopSingleReadTaskType, option) + childCost, err := p.tablePlan.getPlanCostVer2(childType, option) if err != nil { return zeroCostVer2, err } - p.planCostVer2 = divCostVer2(sumCostVer2(childCost, netCost, seekCost), concurrency) + p.planCostVer2 = divCostVer2(sumCostVer2(childCost, netCost), concurrency) p.planCostInit = true // consider tidb_enforce_mpp - _, isMPP := p.tablePlan.(*PhysicalExchangeSender) - if isMPP && p.ctx.GetSessionVars().IsMPPEnforced() && + if p.StoreType == kv.TiFlash && p.ctx.GetSessionVars().IsMPPEnforced() && !hasCostFlag(option.CostFlag, CostFlagRecalculate) { // show the real cost in explain-statements p.planCostVer2 = divCostVer2(p.planCostVer2, 1000000000) } - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: // plan-cost = index-side-cost + (table-side-cost + double-read-cost) / double-read-concurrency -// index-side-cost = (index-child-cost + index-net-cost + index-seek-cost) / dist-concurrency # same with IndexReader -// table-side-cost = (table-child-cost + table-net-cost + table-seek-cost) / dist-concurrency # same with TableReader -// double-read-cost = double-read-seek-cost + double-read-cpu-cost -// double-read-seek-cost = double-read-tasks * seek-factor +// index-side-cost = (index-child-cost + index-net-cost) / dist-concurrency # same with IndexReader +// table-side-cost = (table-child-cost + table-net-cost) / dist-concurrency # same with TableReader +// double-read-cost = double-read-request-cost + double-read-cpu-cost +// double-read-request-cost = double-read-tasks * request-factor // double-read-cpu-cost = index-rows * cpu-factor // double-read-tasks = index-rows / batch-size * task-per-batch # task-per-batch is a magic number now func (p *PhysicalIndexLookUpReader) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { @@ -225,89 +236,91 @@ func (p *PhysicalIndexLookUpReader) getPlanCostVer2(taskType property.TaskType, tableRowSize := getTblStats(p.tablePlan).GetAvgRowSize(p.ctx, p.tablePlan.Schema().Columns, false, false) cpuFactor := getTaskCPUFactorVer2(p, taskType) netFactor := getTaskNetFactorVer2(p, taskType) - seekFactor := getTaskSeekFactorVer2(p, taskType) + requestFactor := getTaskRequestFactorVer2(p, taskType) distConcurrency := float64(p.ctx.GetSessionVars().DistSQLScanConcurrency()) doubleReadConcurrency := float64(p.ctx.GetSessionVars().IndexLookupConcurrency()) // index-side indexNetCost := netCostVer2(option, indexRows, indexRowSize, netFactor) - indexSeekCost := seekCostVer2(option, estimateNetSeekCost(p.indexPlan), seekFactor) indexChildCost, err := p.indexPlan.getPlanCostVer2(property.CopDoubleReadTaskType, option) if err != nil { return zeroCostVer2, err } - indexSideCost := divCostVer2(sumCostVer2(indexNetCost, indexSeekCost, indexChildCost), distConcurrency) + indexSideCost := divCostVer2(sumCostVer2(indexNetCost, indexChildCost), distConcurrency) // table-side tableNetCost := netCostVer2(option, tableRows, tableRowSize, netFactor) - tableSeekCost := seekCostVer2(option, estimateNetSeekCost(p.tablePlan), seekFactor) tableChildCost, err := p.tablePlan.getPlanCostVer2(property.CopDoubleReadTaskType, option) if err != nil { return zeroCostVer2, err } - tableSideCost := divCostVer2(sumCostVer2(tableNetCost, tableSeekCost, tableChildCost), distConcurrency) + tableSideCost := divCostVer2(sumCostVer2(tableNetCost, tableChildCost), distConcurrency) - // double-read + doubleReadRows := indexRows doubleReadCPUCost := newCostVer2(option, cpuFactor, indexRows*cpuFactor.Value, - "double-read-cpu(%v*%v)", indexRows, cpuFactor) + func() string { return fmt.Sprintf("double-read-cpu(%v*%v)", doubleReadRows, cpuFactor) }) batchSize := float64(p.ctx.GetSessionVars().IndexLookupSize) - taskPerBatch := 40.0 // TODO: remove this magic number - doubleReadTasks := indexRows / batchSize * taskPerBatch - doubleReadSeekCost := seekCostVer2(option, doubleReadTasks, seekFactor) - doubleReadCost := sumCostVer2(doubleReadCPUCost, doubleReadSeekCost) + taskPerBatch := 32.0 // TODO: remove this magic number + doubleReadTasks := doubleReadRows / batchSize * taskPerBatch + doubleReadRequestCost := doubleReadCostVer2(option, doubleReadTasks, requestFactor) + doubleReadCost := sumCostVer2(doubleReadCPUCost, doubleReadRequestCost) p.planCostVer2 = sumCostVer2(indexSideCost, divCostVer2(sumCostVer2(tableSideCost, doubleReadCost), doubleReadConcurrency)) + + if p.ctx.GetSessionVars().EnablePaging && p.expectedCnt > 0 && p.expectedCnt <= paging.Threshold { + // if the expectCnt is below the paging threshold, using paging API + p.Paging = true // TODO: move this operation from cost model to physical optimization + p.planCostVer2 = mulCostVer2(p.planCostVer2, 0.6) + } + p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: // plan-cost = table-side-cost + sum(index-side-cost) -// index-side-cost = (index-child-cost + index-net-cost + index-seek-cost) / dist-concurrency # same with IndexReader -// table-side-cost = (table-child-cost + table-net-cost + table-seek-cost) / dist-concurrency # same with TableReader +// index-side-cost = (index-child-cost + index-net-cost) / dist-concurrency # same with IndexReader +// table-side-cost = (table-child-cost + table-net-cost) / dist-concurrency # same with TableReader func (p *PhysicalIndexMergeReader) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { if p.planCostInit && !hasCostFlag(option.CostFlag, CostFlagRecalculate) { return p.planCostVer2, nil } netFactor := getTaskNetFactorVer2(p, taskType) - seekFactor := getTaskSeekFactorVer2(p, taskType) distConcurrency := float64(p.ctx.GetSessionVars().DistSQLScanConcurrency()) var tableSideCost costVer2 if tablePath := p.tablePlan; tablePath != nil { rows := getCardinality(tablePath, option.CostFlag) - rowSize := getAvgRowSize(tablePath.Stats(), tablePath.Schema()) + rowSize := getAvgRowSize(tablePath.Stats(), tablePath.Schema().Columns) tableNetCost := netCostVer2(option, rows, rowSize, netFactor) - tableSeekCost := seekCostVer2(option, estimateNumTasks(tablePath), seekFactor) tableChildCost, err := tablePath.getPlanCostVer2(taskType, option) if err != nil { return zeroCostVer2, err } - tableSideCost = divCostVer2(sumCostVer2(tableNetCost, tableSeekCost, tableChildCost), distConcurrency) + tableSideCost = divCostVer2(sumCostVer2(tableNetCost, tableChildCost), distConcurrency) } indexSideCost := make([]costVer2, 0, len(p.partialPlans)) for _, indexPath := range p.partialPlans { rows := getCardinality(indexPath, option.CostFlag) - rowSize := getAvgRowSize(indexPath.Stats(), indexPath.Schema()) + rowSize := getAvgRowSize(indexPath.Stats(), indexPath.Schema().Columns) indexNetCost := netCostVer2(option, rows, rowSize, netFactor) - indexSeekCost := seekCostVer2(option, estimateNumTasks(indexPath), seekFactor) indexChildCost, err := indexPath.getPlanCostVer2(taskType, option) if err != nil { return zeroCostVer2, err } indexSideCost = append(indexSideCost, - divCostVer2(sumCostVer2(indexNetCost, indexSeekCost, indexChildCost), distConcurrency)) + divCostVer2(sumCostVer2(indexNetCost, indexChildCost), distConcurrency)) } sumIndexSideCost := sumCostVer2(indexSideCost...) p.planCostVer2 = sumCostVer2(tableSideCost, sumIndexSideCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -325,34 +338,32 @@ func (p *PhysicalSort) getPlanCostVer2(taskType property.TaskType, option *PlanC } rows := math.Max(getCardinality(p.children[0], option.CostFlag), 1) - rowSize := getAvgRowSize(p.statsInfo(), p.Schema()) + rowSize := getAvgRowSize(p.statsInfo(), p.Schema().Columns) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) diskFactor := defaultVer2Factors.TiDBDisk oomUseTmpStorage := variable.EnableTmpStorageOnOOM.Load() - memQuota := p.ctx.GetSessionVars().StmtCtx.MemTracker.GetBytesLimit() + memQuota := p.ctx.GetSessionVars().MemTracker.GetBytesLimit() spill := taskType == property.RootTaskType && // only TiDB can spill oomUseTmpStorage && // spill is enabled memQuota > 0 && // mem-quota is set rowSize*rows > float64(memQuota) // exceed the mem-quota - sortCPUCost := newCostVer2(option, cpuFactor, - rows*math.Log2(rows)*float64(len(p.ByItems))*cpuFactor.Value, - "sortCPU(%v*log2(%v)*%v*%v)", rows, rows, len(p.ByItems), cpuFactor) + sortCPUCost := orderCostVer2(option, rows, rows, p.ByItems, cpuFactor) var sortMemCost, sortDiskCost costVer2 if !spill { sortMemCost = newCostVer2(option, memFactor, rows*rowSize*memFactor.Value, - "sortMem(%v*%v*%v)", rows, rowSize, memFactor) + func() string { return fmt.Sprintf("sortMem(%v*%v*%v)", rows, rowSize, memFactor) }) sortDiskCost = zeroCostVer2 } else { sortMemCost = newCostVer2(option, memFactor, float64(memQuota)*memFactor.Value, - "sortMem(%v*%v)", memQuota, memFactor) + func() string { return fmt.Sprintf("sortMem(%v*%v)", memQuota, memFactor) }) sortDiskCost = newCostVer2(option, diskFactor, rows*rowSize*diskFactor.Value, - "sortDisk(%v*%v*%v)", rows, rowSize, diskFactor) + func() string { return fmt.Sprintf("sortDisk(%v*%v*%v)", rows, rowSize, diskFactor) }) } childCost, err := p.children[0].getPlanCostVer2(taskType, option) @@ -362,7 +373,7 @@ func (p *PhysicalSort) getPlanCostVer2(taskType property.TaskType, option *PlanC p.planCostVer2 = sumCostVer2(childCost, sortCPUCost, sortMemCost, sortDiskCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -376,16 +387,14 @@ func (p *PhysicalTopN) getPlanCostVer2(taskType property.TaskType, option *PlanC rows := getCardinality(p.children[0], option.CostFlag) N := math.Max(1, float64(p.Count+p.Offset)) - rowSize := getAvgRowSize(p.statsInfo(), p.Schema()) + rowSize := getAvgRowSize(p.statsInfo(), p.Schema().Columns) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) - topNCPUCost := newCostVer2(option, cpuFactor, - rows*math.Log2(N)*float64(len(p.ByItems))*cpuFactor.Value, - "topCPU(%v*%v*%v*%v)", rows, math.Log2(N), len(p.ByItems), cpuFactor) + topNCPUCost := orderCostVer2(option, rows, N, p.ByItems, cpuFactor) topNMemCost := newCostVer2(option, memFactor, N*rowSize*memFactor.Value, - "topMem(%v*%v*%v)", N, rowSize, memFactor) + func() string { return fmt.Sprintf("topMem(%v*%v*%v)", N, rowSize, memFactor) }) childCost, err := p.children[0].getPlanCostVer2(taskType, option) if err != nil { @@ -394,7 +403,7 @@ func (p *PhysicalTopN) getPlanCostVer2(taskType property.TaskType, option *PlanC p.planCostVer2 = sumCostVer2(childCost, topNCPUCost, topNMemCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -417,7 +426,7 @@ func (p *PhysicalStreamAgg) getPlanCostVer2(taskType property.TaskType, option * p.planCostVer2 = sumCostVer2(childCost, aggCost, groupCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -429,24 +438,27 @@ func (p *PhysicalHashAgg) getPlanCostVer2(taskType property.TaskType, option *Pl inputRows := getCardinality(p.children[0], option.CostFlag) outputRows := getCardinality(p, option.CostFlag) - outputRowSize := getAvgRowSize(p.Stats(), p.Schema()) + outputRowSize := getAvgRowSize(p.Stats(), p.Schema().Columns) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) - concurrency := p.ctx.GetSessionVars().GetConcurrencyFactor() + concurrency := float64(p.ctx.GetSessionVars().HashAggFinalConcurrency()) aggCost := aggCostVer2(option, inputRows, p.AggFuncs, cpuFactor) groupCost := groupCostVer2(option, inputRows, p.GroupByItems, cpuFactor) - hashBuildCost := hashBuildCostVer2(option, outputRows, outputRowSize, p.GroupByItems, cpuFactor, memFactor) - hashProbeCost := hashProbeCostVer2(option, inputRows, p.GroupByItems, cpuFactor) + hashBuildCost := hashBuildCostVer2(option, outputRows, outputRowSize, float64(len(p.GroupByItems)), cpuFactor, memFactor) + hashProbeCost := hashProbeCostVer2(option, inputRows, float64(len(p.GroupByItems)), cpuFactor) + startCost := newCostVer2(option, cpuFactor, + 10*3*cpuFactor.Value, // 10rows * 3func * cpuFactor + func() string { return fmt.Sprintf("cpu(10*3*%v)", cpuFactor) }) childCost, err := p.children[0].getPlanCostVer2(taskType, option) if err != nil { return zeroCostVer2, err } - p.planCostVer2 = sumCostVer2(childCost, divCostVer2(sumCostVer2(aggCost, groupCost, hashBuildCost, hashProbeCost), concurrency)) + p.planCostVer2 = sumCostVer2(startCost, childCost, divCostVer2(sumCostVer2(aggCost, groupCost, hashBuildCost, hashProbeCost), concurrency)) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -476,7 +488,7 @@ func (p *PhysicalMergeJoin) getPlanCostVer2(taskType property.TaskType, option * p.planCostVer2 = sumCostVer2(leftChildCost, rightChildCost, filterCost, groupCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -497,16 +509,17 @@ func (p *PhysicalHashJoin) getPlanCostVer2(taskType property.TaskType, option *P } buildRows := getCardinality(build, option.CostFlag) probeRows := getCardinality(probe, option.CostFlag) - buildRowSize := getAvgRowSize(build.Stats(), build.Schema()) - concurrency := float64(p.Concurrency) + buildRowSize := getAvgRowSize(build.Stats(), build.Schema().Columns) + tidbConcurrency := float64(p.Concurrency) + mppConcurrency := float64(3) // TODO: remove this empirical value cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) buildFilterCost := filterCostVer2(option, buildRows, buildFilters, cpuFactor) - buildHashCost := hashBuildCostVer2(option, buildRows, buildRowSize, cols2Exprs(buildKeys), cpuFactor, memFactor) + buildHashCost := hashBuildCostVer2(option, buildRows, buildRowSize, float64(len(buildKeys)), cpuFactor, memFactor) probeFilterCost := filterCostVer2(option, probeRows, probeFilters, cpuFactor) - probeHashCost := hashProbeCostVer2(option, probeRows, cols2Exprs(probeKeys), cpuFactor) + probeHashCost := hashProbeCostVer2(option, probeRows, float64(len(probeKeys)), cpuFactor) buildChildCost, err := build.getPlanCostVer2(taskType, option) if err != nil { @@ -517,60 +530,101 @@ func (p *PhysicalHashJoin) getPlanCostVer2(taskType property.TaskType, option *P return zeroCostVer2, err } - p.planCostVer2 = sumCostVer2(buildChildCost, probeChildCost, buildHashCost, buildFilterCost, - divCostVer2(sumCostVer2(probeFilterCost, probeHashCost), concurrency)) + if taskType == property.MppTaskType { // BCast or Shuffle Join, use mppConcurrency + p.planCostVer2 = sumCostVer2(buildChildCost, probeChildCost, + divCostVer2(sumCostVer2(buildHashCost, buildFilterCost, probeHashCost, probeFilterCost), mppConcurrency)) + } else { // TiDB HashJoin + startCost := newCostVer2(option, cpuFactor, + 10*3*cpuFactor.Value, // 10rows * 3func * cpuFactor + func() string { return fmt.Sprintf("cpu(10*3*%v)", cpuFactor) }) + p.planCostVer2 = sumCostVer2(startCost, buildChildCost, probeChildCost, buildHashCost, buildFilterCost, + divCostVer2(sumCostVer2(probeFilterCost, probeHashCost), tidbConcurrency)) + } p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } -// getPlanCostVer2 returns the plan-cost of this sub-plan, which is: -// plan-cost = build-child-cost + build-filter-cost + -// (probe-cost + probe-filter-cost) / concurrency -// probe-cost = probe-child-cost * build-rows / batchRatio -func (p *PhysicalIndexJoin) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { +func (p *PhysicalIndexJoin) getIndexJoinCostVer2(taskType property.TaskType, option *PlanCostOption, indexJoinType int) (costVer2, error) { if p.planCostInit && !hasCostFlag(option.CostFlag, CostFlagRecalculate) { return p.planCostVer2, nil } build, probe := p.children[1-p.InnerChildIdx], p.children[p.InnerChildIdx] buildRows := getCardinality(build, option.CostFlag) + buildRowSize := getAvgRowSize(build.Stats(), build.Schema().Columns) probeRowsOne := getCardinality(probe, option.CostFlag) probeRowsTot := probeRowsOne * buildRows + probeRowSize := getAvgRowSize(probe.Stats(), probe.Schema().Columns) buildFilters, probeFilters := p.LeftConditions, p.RightConditions probeConcurrency := float64(p.ctx.GetSessionVars().IndexLookupJoinConcurrency()) cpuFactor := getTaskCPUFactorVer2(p, taskType) + memFactor := getTaskMemFactorVer2(p, taskType) + requestFactor := getTaskRequestFactorVer2(p, taskType) buildFilterCost := filterCostVer2(option, buildRows, buildFilters, cpuFactor) buildChildCost, err := build.getPlanCostVer2(taskType, option) if err != nil { return zeroCostVer2, err } + buildTaskCost := newCostVer2(option, cpuFactor, + buildRows*10*cpuFactor.Value, + func() string { return fmt.Sprintf("cpu(%v*10*%v)", buildRows, cpuFactor) }) + startCost := newCostVer2(option, cpuFactor, + 10*3*cpuFactor.Value, + func() string { return fmt.Sprintf("cpu(10*3*%v)", cpuFactor) }) probeFilterCost := filterCostVer2(option, probeRowsTot, probeFilters, cpuFactor) probeChildCost, err := probe.getPlanCostVer2(taskType, option) if err != nil { return zeroCostVer2, err } + + var hashTableCost costVer2 + switch indexJoinType { + case 1: // IndexHashJoin + hashTableCost = hashBuildCostVer2(option, buildRows, buildRowSize, float64(len(p.RightJoinKeys)), cpuFactor, memFactor) + case 2: // IndexMergeJoin + hashTableCost = newZeroCostVer2(traceCost(option)) + default: // IndexJoin + hashTableCost = hashBuildCostVer2(option, probeRowsTot, probeRowSize, float64(len(p.LeftJoinKeys)), cpuFactor, memFactor) + } + // IndexJoin executes a batch of rows at a time, so the actual cost of this part should be // `innerCostPerBatch * numberOfBatches` instead of `innerCostPerRow * numberOfOuterRow`. // Use an empirical value batchRatio to handle this now. // TODO: remove this empirical value. - batchRatio := 30.0 + batchRatio := 6.0 probeCost := divCostVer2(mulCostVer2(probeChildCost, buildRows), batchRatio) - p.planCostVer2 = sumCostVer2(buildChildCost, buildFilterCost, divCostVer2(sumCostVer2(probeCost, probeFilterCost), probeConcurrency)) + // Double Read Cost + doubleReadCost := newZeroCostVer2(traceCost(option)) + if p.ctx.GetSessionVars().IndexJoinDoubleReadPenaltyCostRate > 0 { + batchSize := float64(p.ctx.GetSessionVars().IndexJoinBatchSize) + taskPerBatch := 1024.0 // TODO: remove this magic number + doubleReadTasks := buildRows / batchSize * taskPerBatch + doubleReadCost = doubleReadCostVer2(option, doubleReadTasks, requestFactor) + doubleReadCost = mulCostVer2(doubleReadCost, p.ctx.GetSessionVars().IndexJoinDoubleReadPenaltyCostRate) + } + + p.planCostVer2 = sumCostVer2(startCost, buildChildCost, buildFilterCost, buildTaskCost, divCostVer2(sumCostVer2(doubleReadCost, probeCost, probeFilterCost, hashTableCost), probeConcurrency)) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil +} + +// getPlanCostVer2 returns the plan-cost of this sub-plan, which is: +// plan-cost = build-child-cost + build-filter-cost + +// (probe-cost + probe-filter-cost) / concurrency +// probe-cost = probe-child-cost * build-rows / batchRatio +func (p *PhysicalIndexJoin) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { + return p.getIndexJoinCostVer2(taskType, option, 0) } func (p *PhysicalIndexHashJoin) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { - // TODO: distinguish IndexHashJoin with IndexJoin - return p.PhysicalIndexJoin.getPlanCostVer2(taskType, option) + return p.getIndexJoinCostVer2(taskType, option, 1) } func (p *PhysicalIndexMergeJoin) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { - // TODO: distinguish IndexMergeJoin with IndexJoin - return p.PhysicalIndexJoin.getPlanCostVer2(taskType, option) + return p.getIndexJoinCostVer2(taskType, option, 2) } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -601,7 +655,7 @@ func (p *PhysicalApply) getPlanCostVer2(taskType property.TaskType, option *Plan p.planCostVer2 = sumCostVer2(buildChildCost, buildFilterCost, probeCost, probeFilterCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 calculates the cost of the plan if it has not been calculated yet and returns the cost. @@ -611,7 +665,7 @@ func (p *PhysicalUnionAll) getPlanCostVer2(taskType property.TaskType, option *P return p.planCostVer2, nil } - concurrency := p.ctx.GetSessionVars().GetConcurrencyFactor() + concurrency := float64(p.ctx.GetSessionVars().UnionConcurrency()) childCosts := make([]costVer2, 0, len(p.children)) for _, child := range p.children { childCost, err := child.getPlanCostVer2(taskType, option) @@ -622,7 +676,7 @@ func (p *PhysicalUnionAll) getPlanCostVer2(taskType property.TaskType, option *P } p.planCostVer2 = divCostVer2(sumCostVer2(childCosts...), concurrency) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: @@ -633,10 +687,18 @@ func (p *PhysicalExchangeReceiver) getPlanCostVer2(taskType property.TaskType, o } rows := getCardinality(p, option.CostFlag) - rowSize := getAvgRowSize(p.stats, p.Schema()) + rowSize := getAvgRowSize(p.stats, p.Schema().Columns) netFactor := getTaskNetFactorVer2(p, taskType) + isBCast := false + if sender, ok := p.children[0].(*PhysicalExchangeSender); ok { + isBCast = sender.ExchangeType == tipb.ExchangeType_Broadcast + } + numNode := float64(3) // TODO: remove this empirical value netCost := netCostVer2(option, rows, rowSize, netFactor) + if isBCast { + netCost = mulCostVer2(netCost, numNode) + } childCost, err := p.children[0].getPlanCostVer2(taskType, option) if err != nil { return zeroCostVer2, err @@ -644,11 +706,10 @@ func (p *PhysicalExchangeReceiver) getPlanCostVer2(taskType property.TaskType, o p.planCostVer2 = sumCostVer2(childCost, netCost) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: -// plan-cost = seek-cost + net-cost func (p *PointGetPlan) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { if p.planCostInit && !hasCostFlag(option.CostFlag, CostFlagRecalculate) { return p.planCostVer2, nil @@ -659,20 +720,15 @@ func (p *PointGetPlan) getPlanCostVer2(taskType property.TaskType, option *PlanC p.planCostInit = true return zeroCostVer2, nil } - rowSize := getAvgRowSize(p.stats, p.schema) + rowSize := getAvgRowSize(p.stats, p.schema.Columns) netFactor := getTaskNetFactorVer2(p, taskType) - seekFactor := getTaskSeekFactorVer2(p, taskType) - - netCost := netCostVer2(option, 1, rowSize, netFactor) - seekCost := divCostVer2(seekCostVer2(option, 1, seekFactor), 20) // 20 times faster than general request - p.planCostVer2 = sumCostVer2(netCost, seekCost) + p.planCostVer2 = netCostVer2(option, 1, rowSize, netFactor) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } // getPlanCostVer2 returns the plan-cost of this sub-plan, which is: -// plan-cost = seek-cost + net-cost func (p *BatchPointGetPlan) getPlanCostVer2(taskType property.TaskType, option *PlanCostOption) (costVer2, error) { if p.planCostInit && !hasCostFlag(option.CostFlag, CostFlagRecalculate) { return p.planCostVer2, nil @@ -684,93 +740,109 @@ func (p *BatchPointGetPlan) getPlanCostVer2(taskType property.TaskType, option * return zeroCostVer2, nil } rows := getCardinality(p, option.CostFlag) - rowSize := getAvgRowSize(p.stats, p.schema) + rowSize := getAvgRowSize(p.stats, p.schema.Columns) netFactor := getTaskNetFactorVer2(p, taskType) - seekFactor := getTaskSeekFactorVer2(p, taskType) - netCost := netCostVer2(option, rows, rowSize, netFactor) - seekCost := divCostVer2(seekCostVer2(option, 1, seekFactor), 20) // in one batch - - p.planCostVer2 = sumCostVer2(netCost, seekCost) + p.planCostVer2 = netCostVer2(option, rows, rowSize, netFactor) p.planCostInit = true - return p.planCostVer2.label(p), nil + return p.planCostVer2, nil } func scanCostVer2(option *PlanCostOption, rows, rowSize float64, scanFactor costVer2Factor) costVer2 { + if rowSize < 1 { + rowSize = 1 + } return newCostVer2(option, scanFactor, // rows * log(row-size) * scanFactor, log2 from experiments - rows*math.Log2(math.Max(1, rowSize))*scanFactor.Value, - "scan(%v*logrowsize(%v)*%v)", rows, rowSize, scanFactor) + rows*math.Log2(rowSize)*scanFactor.Value, + func() string { return fmt.Sprintf("scan(%v*logrowsize(%v)*%v)", rows, rowSize, scanFactor) }) } func netCostVer2(option *PlanCostOption, rows, rowSize float64, netFactor costVer2Factor) costVer2 { return newCostVer2(option, netFactor, rows*rowSize*netFactor.Value, - "net(%v*rowsize(%v)*%v)", rows, rowSize, netFactor) + func() string { return fmt.Sprintf("net(%v*rowsize(%v)*%v)", rows, rowSize, netFactor) }) } func filterCostVer2(option *PlanCostOption, rows float64, filters []expression.Expression, cpuFactor costVer2Factor) costVer2 { + numFuncs := numFunctions(filters) return newCostVer2(option, cpuFactor, - rows*float64(len(filters))*cpuFactor.Value, - "cpu(%v*filters(%v)*%v)", rows, len(filters), cpuFactor) + rows*numFuncs*cpuFactor.Value, + func() string { return fmt.Sprintf("cpu(%v*filters(%v)*%v)", rows, numFuncs, cpuFactor) }) } func aggCostVer2(option *PlanCostOption, rows float64, aggFuncs []*aggregation.AggFuncDesc, cpuFactor costVer2Factor) costVer2 { return newCostVer2(option, cpuFactor, // TODO: consider types of agg-funcs rows*float64(len(aggFuncs))*cpuFactor.Value, - "agg(%v*aggs(%v)*%v)", rows, len(aggFuncs), cpuFactor) + func() string { return fmt.Sprintf("agg(%v*aggs(%v)*%v)", rows, len(aggFuncs), cpuFactor) }) } func groupCostVer2(option *PlanCostOption, rows float64, groupItems []expression.Expression, cpuFactor costVer2Factor) costVer2 { + numFuncs := numFunctions(groupItems) return newCostVer2(option, cpuFactor, - rows*float64(len(groupItems))*cpuFactor.Value, - "group(%v*cols(%v)*%v)", rows, len(groupItems), cpuFactor) + rows*numFuncs*cpuFactor.Value, + func() string { return fmt.Sprintf("group(%v*cols(%v)*%v)", rows, numFuncs, cpuFactor) }) +} + +func numFunctions(exprs []expression.Expression) float64 { + num := 0.0 + for _, e := range exprs { + if _, ok := e.(*expression.ScalarFunction); ok { + num++ + } else { // Column and Constant + num += 0.01 // an empirical value + } + } + return num } -func hashBuildCostVer2(option *PlanCostOption, buildRows, buildRowSize float64, keys []expression.Expression, cpuFactor, memFactor costVer2Factor) costVer2 { +func orderCostVer2(option *PlanCostOption, rows, N float64, byItems []*util.ByItems, cpuFactor costVer2Factor) costVer2 { + numFuncs := 0 + for _, byItem := range byItems { + if _, ok := byItem.Expr.(*expression.ScalarFunction); ok { + numFuncs++ + } + } + exprCost := newCostVer2(option, cpuFactor, + rows*float64(numFuncs)*cpuFactor.Value, + func() string { return fmt.Sprintf("exprCPU(%v*%v*%v)", rows, numFuncs, cpuFactor) }) + orderCost := newCostVer2(option, cpuFactor, + rows*math.Log2(N)*cpuFactor.Value, + func() string { return fmt.Sprintf("orderCPU(%v*log(%v)*%v)", rows, N, cpuFactor) }) + return sumCostVer2(exprCost, orderCost) +} + +func hashBuildCostVer2(option *PlanCostOption, buildRows, buildRowSize, nKeys float64, cpuFactor, memFactor costVer2Factor) costVer2 { // TODO: 1) consider types of keys, 2) dedicated factor for build-probe hash table hashKeyCost := newCostVer2(option, cpuFactor, - buildRows*float64(len(keys))*cpuFactor.Value, - "hashkey(%v*%v*%v)", buildRows, len(keys), cpuFactor) + buildRows*nKeys*cpuFactor.Value, + func() string { return fmt.Sprintf("hashkey(%v*%v*%v)", buildRows, nKeys, cpuFactor) }) hashMemCost := newCostVer2(option, memFactor, buildRows*buildRowSize*memFactor.Value, - "hashmem(%v*%v*%v)", buildRows, buildRowSize, memFactor) + func() string { return fmt.Sprintf("hashmem(%v*%v*%v)", buildRows, buildRowSize, memFactor) }) hashBuildCost := newCostVer2(option, cpuFactor, - buildRows*float64(len(keys))*cpuFactor.Value, - "hashbuild(%v*%v*%v)", buildRows, len(keys), cpuFactor) + buildRows*cpuFactor.Value, + func() string { return fmt.Sprintf("hashbuild(%v*%v)", buildRows, cpuFactor) }) return sumCostVer2(hashKeyCost, hashMemCost, hashBuildCost) } -func hashProbeCostVer2(option *PlanCostOption, probeRows float64, keys []expression.Expression, cpuFactor costVer2Factor) costVer2 { +func hashProbeCostVer2(option *PlanCostOption, probeRows, nKeys float64, cpuFactor costVer2Factor) costVer2 { // TODO: 1) consider types of keys, 2) dedicated factor for build-probe hash table hashKeyCost := newCostVer2(option, cpuFactor, - probeRows*float64(len(keys))*cpuFactor.Value, - "hashkey(%v*%v*%v)", probeRows, len(keys), cpuFactor) + probeRows*nKeys*cpuFactor.Value, + func() string { return fmt.Sprintf("hashkey(%v*%v*%v)", probeRows, nKeys, cpuFactor) }) hashProbeCost := newCostVer2(option, cpuFactor, - probeRows*float64(len(keys))*cpuFactor.Value, - "hashmem(%v*%v*%v)", probeRows, len(keys), cpuFactor) + probeRows*cpuFactor.Value, + func() string { return fmt.Sprintf("hashprobe(%v*%v)", probeRows, cpuFactor) }) return sumCostVer2(hashKeyCost, hashProbeCost) } -func seekCostVer2(option *PlanCostOption, numTasks float64, seekFactor costVer2Factor) costVer2 { - return newCostVer2(option, seekFactor, - numTasks*seekFactor.Value, - "seek(tasks(%v)*%v)", numTasks, seekFactor) -} - -func estimateNumTasks(copTaskPlan PhysicalPlan) float64 { - switch x := copTaskPlan.(type) { - case *PhysicalTableScan: - if x.StoreType == kv.TiFlash { // the old TiFlash interface uses cop-task protocol - return float64(len(x.Ranges)) * float64(len(x.Columns)) - } - return float64(len(x.Ranges)) // TiKV - case *PhysicalIndexScan: - return float64(len(x.Ranges)) // TiKV - default: - return estimateNetSeekCost(copTaskPlan.Children()[0]) - } +// For simplicity and robust, only operators that need double-read like IndexLookup and IndexJoin consider this cost. +func doubleReadCostVer2(option *PlanCostOption, numTasks float64, requestFactor costVer2Factor) costVer2 { + return newCostVer2(option, requestFactor, + numTasks*requestFactor.Value, + func() string { return fmt.Sprintf("doubleRead(tasks(%v)*%v)", numTasks, requestFactor) }) } type costVer2Factor struct { @@ -801,22 +873,27 @@ type costVer2Factors struct { TiDBRequest costVer2Factor // per net request } +func (c costVer2Factors) tolist() (l []costVer2Factor) { + return append(l, c.TiDBTemp, c.TiKVScan, c.TiKVDescScan, c.TiFlashScan, c.TiDBCPU, c.TiKVCPU, c.TiFlashCPU, + c.TiDB2KVNet, c.TiDB2FlashNet, c.TiFlashMPPNet, c.TiDBMem, c.TiKVMem, c.TiFlashMem, c.TiDBDisk, c.TiDBRequest) +} + var defaultVer2Factors = costVer2Factors{ - TiDBTemp: costVer2Factor{"tidb_temp_table_factor", 0}, - TiKVScan: costVer2Factor{"tikv_scan_factor", 100}, - TiKVDescScan: costVer2Factor{"tikv_desc_scan_factor", 150}, - TiFlashScan: costVer2Factor{"tiflash_scan_factor", 5}, - TiDBCPU: costVer2Factor{"tidb_cpu_factor", 30}, - TiKVCPU: costVer2Factor{"tikv_cpu_factor", 30}, - TiFlashCPU: costVer2Factor{"tiflash_cpu_factor", 5}, - TiDB2KVNet: costVer2Factor{"tidb_kv_net_factor", 8}, - TiDB2FlashNet: costVer2Factor{"tidb_flash_net_factor", 4}, - TiFlashMPPNet: costVer2Factor{"tiflash_mpp_net_factor", 4}, - TiDBMem: costVer2Factor{"tidb_mem_factor", 1}, - TiKVMem: costVer2Factor{"tikv_mem_factor", 1}, - TiFlashMem: costVer2Factor{"tiflash_mem_factor", 1}, - TiDBDisk: costVer2Factor{"tidb_disk_factor", 1000}, - TiDBRequest: costVer2Factor{"tidb_request_factor", 9500000}, + TiDBTemp: costVer2Factor{"tidb_temp_table_factor", 0.00}, + TiKVScan: costVer2Factor{"tikv_scan_factor", 40.70}, + TiKVDescScan: costVer2Factor{"tikv_desc_scan_factor", 61.05}, + TiFlashScan: costVer2Factor{"tiflash_scan_factor", 11.60}, + TiDBCPU: costVer2Factor{"tidb_cpu_factor", 49.90}, + TiKVCPU: costVer2Factor{"tikv_cpu_factor", 49.90}, + TiFlashCPU: costVer2Factor{"tiflash_cpu_factor", 2.40}, + TiDB2KVNet: costVer2Factor{"tidb_kv_net_factor", 3.96}, + TiDB2FlashNet: costVer2Factor{"tidb_flash_net_factor", 2.20}, + TiFlashMPPNet: costVer2Factor{"tiflash_mpp_net_factor", 1.00}, + TiDBMem: costVer2Factor{"tidb_mem_factor", 0.20}, + TiKVMem: costVer2Factor{"tikv_mem_factor", 0.20}, + TiFlashMem: costVer2Factor{"tiflash_mem_factor", 0.05}, + TiDBDisk: costVer2Factor{"tidb_disk_factor", 200.00}, + TiDBRequest: costVer2Factor{"tidb_request_factor", 6000000.00}, } func getTaskCPUFactorVer2(p PhysicalPlan, taskType property.TaskType) costVer2Factor { @@ -841,10 +918,13 @@ func getTaskMemFactorVer2(p PhysicalPlan, taskType property.TaskType) costVer2Fa } } -func getTaskScanFactorVer2(p PhysicalPlan, taskType property.TaskType) costVer2Factor { +func getTaskScanFactorVer2(p PhysicalPlan, storeType kv.StoreType, taskType property.TaskType) costVer2Factor { if isTemporaryTable(getTableInfo(p)) { return defaultVer2Factors.TiDBTemp } + if storeType == kv.TiFlash { + return defaultVer2Factors.TiFlashScan + } switch taskType { case property.MppTaskType: // TiFlash return defaultVer2Factors.TiFlashScan @@ -878,7 +958,7 @@ func getTaskNetFactorVer2(p PhysicalPlan, _ property.TaskType) costVer2Factor { return defaultVer2Factors.TiDB2KVNet } -func getTaskSeekFactorVer2(p PhysicalPlan, _ property.TaskType) costVer2Factor { +func getTaskRequestFactorVer2(p PhysicalPlan, _ property.TaskType) costVer2Factor { if isTemporaryTable(getTableInfo(p)) { return defaultVer2Factors.TiDBTemp } @@ -922,19 +1002,14 @@ func cols2Exprs(cols []*expression.Column) []expression.Expression { return exprs } -type costVer2 struct { - cost float64 - trace bool // Whether to trace the cost calculation. +type costTrace struct { factorCosts map[string]float64 // map[factorName]cost, used to calibrate the cost model formula string // It used to trace the cost calculation. } -func (c costVer2) label(p PhysicalPlan) costVer2 { - if !c.trace { - return c - } - c.formula = p.ExplainID().String() - return c +type costVer2 struct { + cost float64 + trace *costTrace } func traceCost(option *PlanCostOption) bool { @@ -946,65 +1021,63 @@ func traceCost(option *PlanCostOption) bool { func newZeroCostVer2(trace bool) (ret costVer2) { if trace { - ret.trace = true - ret.factorCosts = make(map[string]float64) - ret.formula = "0" + ret.trace = &costTrace{make(map[string]float64), ""} } return } -func newCostVer2(option *PlanCostOption, factor costVer2Factor, cost float64, - formulaFormat string, formulaArgs ...any) costVer2 { - ret := newZeroCostVer2(traceCost(option)) +func newCostVer2(option *PlanCostOption, factor costVer2Factor, cost float64, lazyFormula func() string) (ret costVer2) { ret.cost = cost - if ret.trace { - ret.factorCosts[factor.Name] = cost - ret.formula = fmt.Sprintf(formulaFormat, formulaArgs...) + if traceCost(option) { + ret.trace = &costTrace{make(map[string]float64), ""} + ret.trace.factorCosts[factor.Name] = cost + ret.trace.formula = lazyFormula() } return ret } -func sumCostVer2(costs ...costVer2) costVer2 { +func sumCostVer2(costs ...costVer2) (ret costVer2) { if len(costs) == 0 { - return newZeroCostVer2(false) + return } - ret := newZeroCostVer2(costs[0].trace) - var subFormulas []string - for _, c := range costs { + for i, c := range costs { ret.cost += c.cost - if ret.trace { - for factor, factorCost := range c.factorCosts { - ret.factorCosts[factor] += factorCost + if c.trace != nil { + if i == 0 { // init + ret.trace = &costTrace{make(map[string]float64), ""} } - subFormulas = append(subFormulas, fmt.Sprintf("(%v)", c.formula)) + for factor, factorCost := range c.trace.factorCosts { + ret.trace.factorCosts[factor] += factorCost + } + if ret.trace.formula != "" { + ret.trace.formula += " + " + } + ret.trace.formula += "(" + c.trace.formula + ")" } } - if ret.trace { - ret.formula = strings.Join(subFormulas, " + ") - } return ret } -func divCostVer2(cost costVer2, denominator float64) costVer2 { - ret := newZeroCostVer2(cost.trace) +func divCostVer2(cost costVer2, denominator float64) (ret costVer2) { ret.cost = cost.cost / denominator - if ret.trace { - for f, c := range cost.factorCosts { - ret.factorCosts[f] = c / denominator + if cost.trace != nil { + ret.trace = &costTrace{make(map[string]float64), ""} + for f, c := range cost.trace.factorCosts { + ret.trace.factorCosts[f] = c / denominator } - ret.formula = fmt.Sprintf("(%v)/%v", cost.formula, denominator) + ret.trace.formula = "(" + cost.trace.formula + ")/" + strconv.FormatFloat(denominator, 'f', 2, 64) } return ret } -func mulCostVer2(cost costVer2, scale float64) costVer2 { - ret := newZeroCostVer2(cost.trace) +func mulCostVer2(cost costVer2, scale float64) (ret costVer2) { ret.cost = cost.cost * scale - if ret.trace { - for f, c := range cost.factorCosts { - ret.factorCosts[f] = c * scale + if cost.trace != nil { + ret.trace = &costTrace{make(map[string]float64), ""} + for f, c := range cost.trace.factorCosts { + ret.trace.factorCosts[f] = c * scale } - ret.formula = fmt.Sprintf("(%v)*%v", cost.formula, scale) + ret.trace.formula = "(" + cost.trace.formula + ")*" + strconv.FormatFloat(scale, 'f', 2, 64) } return ret } diff --git a/planner/core/plan_cost_ver2_test.go b/planner/core/plan_cost_ver2_test.go index 3a93a90420eaf..259fcdf870132 100644 --- a/planner/core/plan_cost_ver2_test.go +++ b/planner/core/plan_cost_ver2_test.go @@ -15,6 +15,7 @@ package core_test import ( + "context" "encoding/json" "fmt" "math" @@ -22,6 +23,11 @@ import ( "strings" "testing" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/planner" + "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/planner/property" + "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/testkit" "github.com/stretchr/testify/require" ) @@ -134,7 +140,6 @@ func TestCostModelShowFormula(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec(`create table t (a int)`) - tk.MustExec("insert into t values (1), (2), (3)") tk.MustExec("set @@tidb_cost_model_version=2") tk.MustExecToErr("explain format='true_card_cost' select * from t") // 'true_card_cost' must work with 'explain analyze' @@ -142,15 +147,56 @@ func TestCostModelShowFormula(t *testing.T) { actual := make([][]interface{}, 0, len(plan)) for _, row := range plan { actual = append(actual, []interface{}{row[0], row[3]}) // id,costFormula - fmt.Println(actual) } require.Equal(t, actual, [][]interface{}{ - {"TableReader_7", "((Selection_6) + (net(2*rowsize(16)*tidb_kv_net_factor(8))) + (seek(tasks(20)*tidb_request_factor(9.5e+06))))/15"}, - {"└─Selection_6", "(cpu(3*filters(1)*tikv_cpu_factor(30))) + (TableFullScan_5)"}, - {" └─TableFullScan_5", "scan(3*logrowsize(29)*tikv_scan_factor(100))"}, + {"TableReader_7", "(((cpu(0*filters(1)*tikv_cpu_factor(49.9))) + (scan(0*logrowsize(32)*tikv_scan_factor(40.7)))) + (net(0*rowsize(16)*tidb_kv_net_factor(3.96))))/15.00"}, + {"└─Selection_6", "(cpu(0*filters(1)*tikv_cpu_factor(49.9))) + (scan(0*logrowsize(32)*tikv_scan_factor(40.7)))"}, + {" └─TableFullScan_5", "scan(0*logrowsize(32)*tikv_scan_factor(40.7))"}, }) } +func TestCostModelVer2ScanRowSize(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t (pk int, a int, b int, c int, d int, primary key(pk), index ab(a, b), index abc(a, b, c))`) + tk.MustExec("insert into t values (1, 1, 1, 1, 1)") + tk.MustExec(`set @@tidb_cost_model_version=2`) + tk.MustExec("set global tidb_enable_collect_execution_info=1;") + + cases := []struct { + query string + scanFormula string + }{ + // index scan row-size on idx_ab is always equal to row-size(index_ab) + {"select a from t use index(ab) where a=1", "scan(1*logrowsize(32)*tikv_scan_factor(40.7))"}, + {"select a, b from t use index(ab) where a=1", "scan(1*logrowsize(32)*tikv_scan_factor(40.7))"}, + {"select b from t use index(ab) where a=1 and b=1", "scan(1*logrowsize(32)*tikv_scan_factor(40.7))"}, + // index scan row-size on idx_abc is always equal to row-size(index_abc) + {"select a from t use index(abc) where a=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + {"select a from t use index(abc) where a=1 and b=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + {"select a, b from t use index(abc) where a=1 and b=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + {"select a, b, c from t use index(abc) where a=1 and b=1 and c=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + // table scan row-size is always equal to row-size(*) + {"select a from t use index(primary) where a=1", "scan(1*logrowsize(80)*tikv_scan_factor(40.7))"}, + {"select a, d from t use index(primary) where a=1", "scan(1*logrowsize(80)*tikv_scan_factor(40.7))"}, + {"select * from t use index(primary) where a=1", "scan(1*logrowsize(80)*tikv_scan_factor(40.7))"}, + } + for _, c := range cases { + rs := tk.MustQuery("explain analyze format=true_card_cost " + c.query).Rows() + scan := rs[len(rs)-1] + formula := scan[3] + require.Equal(t, formula, c.scanFormula) + } + + tk.MustQuery("explain select a from t where a=1").Check(testkit.Rows( + `IndexReader_6 10.00 root index:IndexRangeScan_5`, // use idx_ab automatically since it has the smallest row-size in all access paths. + `└─IndexRangeScan_5 10.00 cop[tikv] table:t, index:ab(a, b) range:[1,1], keep order:false, stats:pseudo`)) + tk.MustQuery("explain select a, b, c from t where a=1").Check(testkit.Rows( + `IndexReader_6 10.00 root index:IndexRangeScan_5`, // use idx_abc automatically + `└─IndexRangeScan_5 10.00 cop[tikv] table:t, index:abc(a, b, c) range:[1,1], keep order:false, stats:pseudo`)) +} + func TestCostModelTraceVer2(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -202,3 +248,64 @@ func TestCostModelTraceVer2(t *testing.T) { require.True(t, ok) } } + +func TestIndexJoinPenaltyCost(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t1 (a int, key(a))`) + tk.MustExec(`create table t2 (a int, key(a))`) + + // default value 0 + tk.MustQuery("select @@tidb_index_join_double_read_penalty_cost_rate").Check(testkit.Rows("0")) + //tk.MustQuery("select global @@tidb_index_join_double_read_penalty_cost_rate").Check(testkit.Rows("0")) + + rs1 := tk.MustQuery("explain format='verbose' select /*+ tidb_inlj(t1, t2) */ * from t1, t2 where t1.a=t2.a").Rows() + cost1, err := strconv.ParseFloat(rs1[0][2].(string), 64) + require.Nil(t, err) + + tk.MustExec("set tidb_index_join_double_read_penalty_cost_rate=0.5") + rs2 := tk.MustQuery("explain format='verbose' select /*+ tidb_inlj(t1, t2) */ * from t1, t2 where t1.a=t2.a").Rows() + cost2, err := strconv.ParseFloat(rs2[0][2].(string), 64) + require.Nil(t, err) + + tk.MustExec("set tidb_index_join_double_read_penalty_cost_rate=1") + rs3 := tk.MustQuery("explain format='verbose' select /*+ tidb_inlj(t1, t2) */ * from t1, t2 where t1.a=t2.a").Rows() + cost3, err := strconv.ParseFloat(rs3[0][2].(string), 64) + require.Nil(t, err) + + require.Greater(t, cost2, cost1) + require.Greater(t, cost3, cost2) +} + +func BenchmarkGetPlanCost(b *testing.B) { + store := testkit.CreateMockStore(b) + tk := testkit.NewTestKit(b, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (a int, b int);") + + p := parser.New() + sql := "select sum(t1.b), t1.a from t t1, t t2 where t1.a>0 and t2.a>10 and t1.b=t2.b group by t1.a order by t1.a limit 5" + stmt, err := p.ParseOneStmt(sql, "", "") + if err != nil { + b.Fatal(err) + } + sctx := tk.Session() + sctx.GetSessionVars().CostModelVersion = 2 + is := sessiontxn.GetTxnManager(sctx).GetTxnInfoSchema() + plan, _, err := planner.Optimize(context.TODO(), sctx, stmt, is) + if err != nil { + b.Fatal(err) + } + phyPlan := plan.(core.PhysicalPlan) + _, err = core.GetPlanCost(phyPlan, property.RootTaskType, core.NewDefaultPlanCostOption().WithCostFlag(core.CostFlagRecalculate)) + if err != nil { + b.Fatal(err) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = core.GetPlanCost(phyPlan, property.RootTaskType, core.NewDefaultPlanCostOption().WithCostFlag(core.CostFlagRecalculate)) + } +} diff --git a/planner/core/plan_replayer_capture_test.go b/planner/core/plan_replayer_capture_test.go new file mode 100644 index 0000000000000..6778cdba20bbf --- /dev/null +++ b/planner/core/plan_replayer_capture_test.go @@ -0,0 +1,83 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core_test + +import ( + "context" + "testing" + + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/util/hint" + "github.com/stretchr/testify/require" +) + +func TestPlanReplayerCaptureRecordJsonStats(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + ctx := tk.Session().(sessionctx.Context) + tk.MustExec("use test") + tk.MustExec("create table t1(a int)") + tk.MustExec("create table t2(a int)") + tk.MustExec("analyze table t1") + tk.MustExec("analyze table t2") + testcases := []struct { + sql string + count int + }{ + { + sql: "select * from t1", + count: 1, + }, + { + sql: "select * from t2", + count: 1, + }, + { + sql: "select * from t1,t2", + count: 2, + }, + } + for _, tc := range testcases { + tableStats := getTableStats(tc.sql, t, ctx, dom) + require.Equal(t, tc.count, len(tableStats)) + } +} + +func getTableStats(sql string, t *testing.T, ctx sessionctx.Context, dom *domain.Domain) map[int64]*statistics.Table { + p := parser.New() + stmt, err := p.ParseOneStmt(sql, "", "") + require.NoError(t, err) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: dom.InfoSchema()})) + require.NoError(t, err) + sctx := core.MockContext() + sctx.GetSessionVars().EnablePlanReplayerCapture = true + builder, _ := core.NewPlanBuilder().Init(sctx, dom.InfoSchema(), &hint.BlockHintProcessor{}) + domain.GetDomain(sctx).MockInfoCacheAndLoadInfoSchema(dom.InfoSchema()) + plan, err := builder.Build(context.TODO(), stmt) + require.NoError(t, err) + _, _, err = core.DoOptimize(context.TODO(), sctx, builder.GetOptFlag(), plan.(core.LogicalPlan)) + require.NoError(t, err) + tableStats := sctx.GetSessionVars().StmtCtx.TableStats + r := make(map[int64]*statistics.Table) + for key, v := range tableStats { + r[key] = v.(*statistics.Table) + } + return r +} diff --git a/planner/core/plan_stats.go b/planner/core/plan_stats.go index 681b5c1e8a78e..eaf3cf3120a0f 100644 --- a/planner/core/plan_stats.go +++ b/planner/core/plan_stats.go @@ -18,13 +18,12 @@ import ( "context" "time" - "github.com/pingcap/errors" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" "go.uber.org/zap" @@ -65,7 +64,10 @@ func (syncWaitStatsLoadPoint) optimize(_ context.Context, plan LogicalPlan, _ *l if plan.SCtx().GetSessionVars().InRestrictedSQL { return plan, nil } - _, err := SyncWaitStatsLoad(plan) + if plan.SCtx().GetSessionVars().StmtCtx.IsSyncStatsFailed { + return plan, nil + } + err := SyncWaitStatsLoad(plan) return plan, err } @@ -90,37 +92,36 @@ func RequestLoadStats(ctx sessionctx.Context, neededHistItems []model.TableItemI var timeout = time.Duration(waitTime) err := domain.GetDomain(ctx).StatsHandle().SendLoadRequests(stmtCtx, neededHistItems, timeout) if err != nil { - logutil.BgLogger().Warn("SendLoadRequests failed", zap.Error(err)) stmtCtx.IsSyncStatsFailed = true - return handleTimeout(stmtCtx) + if variable.StatsLoadPseudoTimeout.Load() { + logutil.BgLogger().Warn("RequestLoadStats failed", zap.Error(err)) + stmtCtx.AppendWarning(err) + return nil + } + logutil.BgLogger().Error("RequestLoadStats failed", zap.Error(err)) + return err } return nil } // SyncWaitStatsLoad sync-wait for stats load until timeout -func SyncWaitStatsLoad(plan LogicalPlan) (bool, error) { +func SyncWaitStatsLoad(plan LogicalPlan) error { stmtCtx := plan.SCtx().GetSessionVars().StmtCtx - if stmtCtx.StatsLoad.Fallback { - return false, nil - } - success := domain.GetDomain(plan.SCtx()).StatsHandle().SyncWaitStatsLoad(stmtCtx) - if success { - return true, nil - } - logutil.BgLogger().Warn("SyncWaitStatsLoad failed") - stmtCtx.IsSyncStatsFailed = true - err := handleTimeout(stmtCtx) - return false, err -} - -func handleTimeout(stmtCtx *stmtctx.StatementContext) error { - err := errors.New("Timeout when sync-load full stats for needed columns") - if variable.StatsLoadPseudoTimeout.Load() { - stmtCtx.AppendWarning(err) - stmtCtx.StatsLoad.Fallback = true + if len(stmtCtx.StatsLoad.NeededItems) <= 0 { return nil } - return err + err := domain.GetDomain(plan.SCtx()).StatsHandle().SyncWaitStatsLoad(stmtCtx) + if err != nil { + stmtCtx.IsSyncStatsFailed = true + if variable.StatsLoadPseudoTimeout.Load() { + logutil.BgLogger().Warn("SyncWaitStatsLoad failed", zap.Error(err)) + stmtCtx.AppendWarning(err) + return nil + } + logutil.BgLogger().Error("SyncWaitStatsLoad failed", zap.Error(err)) + return err + } + return nil } // collectSyncIndices will collect the indices which includes following conditions: @@ -154,7 +155,7 @@ func collectSyncIndices(ctx sessionctx.Context, histNeededColumns []model.TableI continue } idxStats, ok := tblStats.Indices[idx.Meta().ID] - if !ok || idxStats == nil || !idxStats.IsFullLoad() { + if ok && idxStats.IsStatsInitialized() && !idxStats.IsFullLoad() { histNeededIndices[model.TableItemID{TableID: column.TableID, ID: idxID, IsIndex: true}] = struct{}{} } } @@ -170,3 +171,34 @@ func collectHistNeededItems(histNeededColumns []model.TableItemID, histNeededInd histNeededItems = append(histNeededItems, histNeededColumns...) return } + +func recordTableRuntimeStats(sctx sessionctx.Context, tbls map[int64]struct{}) { + tblStats := sctx.GetSessionVars().StmtCtx.TableStats + if tblStats == nil { + tblStats = map[int64]interface{}{} + } + for tblID := range tbls { + tblJSONStats, err := recordSingleTableRuntimeStats(sctx, tblID) + if err != nil { + logutil.BgLogger().Warn("record table json stats failed", zap.Int64("tblID", tblID), zap.Error(err)) + } + if tblJSONStats == nil { + logutil.BgLogger().Warn("record table json stats failed due to empty", zap.Int64("tblID", tblID)) + } + tblStats[tblID] = tblJSONStats + } + sctx.GetSessionVars().StmtCtx.TableStats = tblStats +} + +func recordSingleTableRuntimeStats(sctx sessionctx.Context, tblID int64) (*statistics.Table, error) { + dom := domain.GetDomain(sctx) + is := dom.InfoSchema() + statsHandle := dom.StatsHandle() + tbl, ok := is.TableByID(tblID) + if !ok { + return nil, nil + } + tableInfo := tbl.Meta() + stats := statsHandle.GetTableStats(tableInfo) + return stats, nil +} diff --git a/planner/core/plan_test.go b/planner/core/plan_test.go index 242d868a8c571..f1c65fcd9fb4d 100644 --- a/planner/core/plan_test.go +++ b/planner/core/plan_test.go @@ -16,6 +16,7 @@ package core_test import ( "bytes" + "encoding/json" "fmt" "strings" "testing" @@ -109,6 +110,14 @@ func TestNormalizedPlan(t *testing.T) { tk.MustExec("create table t2 (a int key,b int,c int, index (b));") tk.MustExec("create table t3 (a int key,b int) partition by hash(a) partitions 2;") tk.MustExec("create table t4 (a int, b int, index(a)) partition by range(a) (partition p0 values less than (10),partition p1 values less than MAXVALUE);") + tk.MustExec("set @@global.tidb_enable_foreign_key=1") + tk.MustExec("set @@foreign_key_checks=1") + tk.MustExec("create table t5 (id int key, id2 int, id3 int, unique index idx2(id2), index idx3(id3));") + tk.MustExec("create table t6 (id int, id2 int, id3 int, index idx_id(id), index idx_id2(id2), " + + "foreign key fk_1 (id) references t5(id) ON UPDATE CASCADE ON DELETE CASCADE, " + + "foreign key fk_2 (id2) references t5(id2) ON UPDATE CASCADE, " + + "foreign key fk_3 (id3) references t5(id3) ON DELETE CASCADE);") + tk.MustExec("insert into t5 values (1,1,1), (2,2,2)") var input []string var output []struct { SQL string @@ -130,6 +139,8 @@ func TestNormalizedPlan(t *testing.T) { newNormalized, newDigest := core.NormalizeFlatPlan(flat) require.Equal(t, normalized, newNormalized) require.Equal(t, digest, newDigest) + // Test for GenHintsFromFlatPlan won't panic. + core.GenHintsFromFlatPlan(flat) normalizedPlan, err := plancodec.DecodeNormalizedPlan(normalized) normalizedPlanRows := getPlanRows(normalizedPlan) @@ -314,7 +325,7 @@ func TestNormalizedDigest(t *testing.T) { ol_supply_w_id int(11) DEFAULT NULL, ol_quantity int(11) DEFAULT NULL, ol_dist_info char(24) DEFAULT NULL, - PRIMARY KEY ( ol_w_id , ol_d_id , ol_o_id , ol_number ) + PRIMARY KEY ( ol_w_id , ol_d_id , ol_o_id , ol_number ) NONCLUSTERED );`) tk.MustExec(`CREATE TABLE bmsql_district ( d_w_id int(11) NOT NULL, @@ -328,7 +339,7 @@ func TestNormalizedDigest(t *testing.T) { d_city varchar(20) DEFAULT NULL, d_state char(2) DEFAULT NULL, d_zip char(9) DEFAULT NULL, - PRIMARY KEY ( d_w_id , d_id ) + PRIMARY KEY ( d_w_id , d_id ) NONCLUSTERED );`) tk.MustExec(`CREATE TABLE bmsql_stock ( s_w_id int(11) NOT NULL, @@ -348,7 +359,7 @@ func TestNormalizedDigest(t *testing.T) { s_dist_08 char(24) DEFAULT NULL, s_dist_09 char(24) DEFAULT NULL, s_dist_10 char(24) DEFAULT NULL, - PRIMARY KEY ( s_w_id , s_i_id ) + PRIMARY KEY ( s_w_id , s_i_id ) NONCLUSTERED );`) err := failpoint.Enable("github.com/pingcap/tidb/planner/mockRandomPlanID", "return(true)") @@ -787,6 +798,7 @@ func TestCopPaging(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("set session tidb_enable_paging = 1") tk.MustExec("create table t(id int, c1 int, c2 int, primary key (id), key i(c1))") @@ -1076,3 +1088,57 @@ func TestNullEQConditionPlan(t *testing.T) { {"Point_Get_5", "root", "handle:0"}, }) } + +// https://github.com/pingcap/tidb/issues/38304 +// https://github.com/pingcap/tidb/issues/38654 +func TestOuterJoinOnNull(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("CREATE TABLE t0(c0 BLOB(5), c1 BLOB(5));") + tk.MustExec("CREATE TABLE t1 (c0 BOOL);") + tk.MustExec("INSERT INTO t1 VALUES(false);") + tk.MustExec("INSERT INTO t0(c0, c1) VALUES ('>', true);") + tk.MustQuery("SELECT * FROM t0 LEFT OUTER JOIN t1 ON NULL; ").Check(testkit.Rows("> 1 ")) + tk.MustQuery("SELECT NOT '2' =(t1.c0 AND t0.c1 IS NULL) FROM t0 LEFT OUTER JOIN t1 ON NULL; ").Check(testkit.Rows("1")) + tk.MustQuery("SELECT * FROM t0 LEFT JOIN t1 ON NULL WHERE NOT '2' =(t1.c0 AND t0.c1 IS NULL); ").Check(testkit.Rows("> 1 ")) + tk.MustQuery("SELECT * FROM t0 LEFT JOIN t1 ON NULL WHERE t1.c0 or true; ").Check(testkit.Rows("> 1 ")) + tk.MustQuery("SELECT * FROM t0 LEFT JOIN t1 ON NULL WHERE not(t1.c0 and false); ").Check(testkit.Rows("> 1 ")) + + tk.MustExec("CREATE TABLE t2(c0 INT);") + tk.MustExec("CREATE TABLE t3(c0 INT);") + tk.MustExec("INSERT INTO t3 VALUES (1);") + tk.MustQuery("SELECT ((NOT ('i'))AND(t2.c0)) IS NULL FROM t2 RIGHT JOIN t3 ON t3.c0;").Check(testkit.Rows("1")) + tk.MustQuery("SELECT * FROM t2 RIGHT JOIN t3 ON t2.c0 WHERE ((NOT ('i'))AND(t2.c0)) IS NULL;").Check(testkit.Rows(" 1")) +} + +func TestJSONPlanInExplain(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1(id int, key(id))") + tk.MustExec("create table t2(id int, key(id))") + + var input []string + var output []struct { + SQL string + JSONPlan []*core.ExplainInfoForEncode + } + planSuiteData := core.GetJSONPlanSuiteData() + planSuiteData.LoadTestCases(t, &input, &output) + + for i, test := range input { + resJSON := tk.MustQuery(test).Rows() + var res []*core.ExplainInfoForEncode + require.NoError(t, json.Unmarshal([]byte(resJSON[0][0].(string)), &res)) + for j, expect := range output[i].JSONPlan { + require.Equal(t, expect.ID, res[j].ID) + require.Equal(t, expect.EstRows, res[j].EstRows) + require.Equal(t, expect.ActRows, res[j].ActRows) + require.Equal(t, expect.TaskType, res[j].TaskType) + require.Equal(t, expect.AccessObject, res[j].AccessObject) + require.Equal(t, expect.OperatorInfo, res[j].OperatorInfo) + } + } +} diff --git a/planner/core/plan_to_pb.go b/planner/core/plan_to_pb.go index 5b296acf79a4b..922b61975ab3c 100644 --- a/planner/core/plan_to_pb.go +++ b/planner/core/plan_to_pb.go @@ -21,12 +21,9 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/table/tables" - "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/telemetry" "github.com/pingcap/tidb/util" - "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/ranger" "github.com/pingcap/tipb/go-tipb" ) @@ -63,7 +60,13 @@ func (p *PhysicalHashAgg) ToPB(ctx sessionctx.Context, storeType kv.StoreType) ( } executorID = p.ExplainID().String() } - return &tipb.Executor{Tp: tipb.ExecType_TypeAggregation, Aggregation: aggExec, ExecutorId: &executorID}, nil + return &tipb.Executor{ + Tp: tipb.ExecType_TypeAggregation, + Aggregation: aggExec, + ExecutorId: &executorID, + FineGrainedShuffleStreamCount: p.TiFlashFineGrainedShuffleStreamCount, + FineGrainedShuffleBatchSize: ctx.GetSessionVars().TiFlashFineGrainedShuffleBatchSize, + }, nil } // ToPB implements PhysicalPlan ToPB interface. @@ -206,7 +209,7 @@ func (p *PhysicalTableScan) ToPB(ctx sessionctx.Context, storeType kv.StoreType) telemetry.CurrentTiflashTableScanWithFastScanCount.Inc() } } - err := SetPBColumnsDefaultValue(ctx, tsExec.Columns, p.Columns) + err := tables.SetPBColumnsDefaultValue(ctx, tsExec.Columns, p.Columns) return &tipb.Executor{Tp: tipb.ExecType_TypeTableScan, TblScan: tsExec, ExecutorId: &executorID}, err } @@ -218,7 +221,7 @@ func (p *PhysicalTableScan) partitionTableScanToPBForFlash(ctx sessionctx.Contex } ptsExec.Desc = p.Desc executorID := p.ExplainID().String() - err := SetPBColumnsDefaultValue(ctx, ptsExec.Columns, p.Columns) + err := tables.SetPBColumnsDefaultValue(ctx, ptsExec.Columns, p.Columns) return &tipb.Executor{Tp: tipb.ExecType_TypePartitionTableScan, PartitionTableScan: ptsExec, ExecutorId: &executorID}, err } @@ -373,7 +376,7 @@ func (p *PhysicalIndexScan) ToPB(_ sessionctx.Context, _ kv.StoreType) (*tipb.Ex idxExec := &tipb.IndexScan{ TableId: p.Table.ID, IndexId: p.Index.ID, - Columns: util.ColumnsToProto(columns, p.Table.PKIsHandle), + Columns: util.ColumnsToProto(columns, p.Table.PKIsHandle, true), Desc: p.Desc, PrimaryColumnIds: pkColIds, } @@ -495,7 +498,13 @@ func (p *PhysicalHashJoin) ToPB(ctx sessionctx.Context, storeType kv.StoreType) } executorID := p.ExplainID().String() - return &tipb.Executor{Tp: tipb.ExecType_TypeJoin, Join: join, ExecutorId: &executorID}, nil + return &tipb.Executor{ + Tp: tipb.ExecType_TypeJoin, + Join: join, + ExecutorId: &executorID, + FineGrainedShuffleStreamCount: p.TiFlashFineGrainedShuffleStreamCount, + FineGrainedShuffleBatchSize: ctx.GetSessionVars().TiFlashFineGrainedShuffleBatchSize, + }, nil } // ToPB converts FrameBound to tipb structure. @@ -599,32 +608,3 @@ func (p *PhysicalSort) ToPB(ctx sessionctx.Context, storeType kv.StoreType) (*ti FineGrainedShuffleBatchSize: ctx.GetSessionVars().TiFlashFineGrainedShuffleBatchSize, }, nil } - -// SetPBColumnsDefaultValue sets the default values of tipb.ColumnInfos. -func SetPBColumnsDefaultValue(ctx sessionctx.Context, pbColumns []*tipb.ColumnInfo, columns []*model.ColumnInfo) error { - for i, c := range columns { - // For virtual columns, we set their default values to NULL so that TiKV will return NULL properly, - // They real values will be compute later. - if c.IsGenerated() && !c.GeneratedStored { - pbColumns[i].DefaultVal = []byte{codec.NilFlag} - } - if c.GetOriginDefaultValue() == nil { - continue - } - - sessVars := ctx.GetSessionVars() - originStrict := sessVars.StrictSQLMode - sessVars.StrictSQLMode = false - d, err := table.GetColOriginDefaultValue(ctx, c) - sessVars.StrictSQLMode = originStrict - if err != nil { - return err - } - - pbColumns[i].DefaultVal, err = tablecodec.EncodeValue(sessVars.StmtCtx, nil, d) - if err != nil { - return err - } - } - return nil -} diff --git a/planner/core/plan_to_pb_test.go b/planner/core/plan_to_pb_test.go index 9ea55a23babdd..cb108678629f2 100644 --- a/planner/core/plan_to_pb_test.go +++ b/planner/core/plan_to_pb_test.go @@ -35,16 +35,16 @@ func TestColumnToProto(t *testing.T) { col := &model.ColumnInfo{ FieldType: *tp, } - pc := util.ColumnToProto(col) + pc := util.ColumnToProto(col, false) expect := &tipb.ColumnInfo{ColumnId: 0, Tp: 3, Collation: 83, ColumnLen: 11, Decimal: 0, Flag: 10, Elems: []string(nil), DefaultVal: []uint8(nil), PkHandle: false, XXX_unrecognized: []uint8(nil)} require.Equal(t, expect, pc) cols := []*model.ColumnInfo{col, col} - pcs := util.ColumnsToProto(cols, false) + pcs := util.ColumnsToProto(cols, false, false) for _, v := range pcs { require.Equal(t, int32(10), v.GetFlag()) } - pcs = util.ColumnsToProto(cols, true) + pcs = util.ColumnsToProto(cols, true, false) for _, v := range pcs { require.Equal(t, int32(10), v.GetFlag()) } @@ -56,19 +56,19 @@ func TestColumnToProto(t *testing.T) { col1 := &model.ColumnInfo{ FieldType: *tp, } - pc = util.ColumnToProto(col1) + pc = util.ColumnToProto(col1, false) require.Equal(t, int32(8), pc.Collation) collate.SetNewCollationEnabledForTest(true) - pc = util.ColumnToProto(col) + pc = util.ColumnToProto(col, false) expect = &tipb.ColumnInfo{ColumnId: 0, Tp: 3, Collation: -83, ColumnLen: 11, Decimal: 0, Flag: 10, Elems: []string(nil), DefaultVal: []uint8(nil), PkHandle: false, XXX_unrecognized: []uint8(nil)} require.Equal(t, expect, pc) - pcs = util.ColumnsToProto(cols, true) + pcs = util.ColumnsToProto(cols, true, false) for _, v := range pcs { require.Equal(t, int32(-83), v.Collation) } - pc = util.ColumnToProto(col1) + pc = util.ColumnToProto(col1, false) require.Equal(t, int32(-8), pc.Collation) tp = types.NewFieldType(mysql.TypeEnum) @@ -77,6 +77,6 @@ func TestColumnToProto(t *testing.T) { col2 := &model.ColumnInfo{ FieldType: *tp, } - pc = util.ColumnToProto(col2) + pc = util.ColumnToProto(col2, false) require.Len(t, pc.Elems, 2) } diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 39bae869f68c5..5af0bb004d6c9 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -26,6 +26,7 @@ import ( "unsafe" "github.com/pingcap/errors" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/bindinfo" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" @@ -65,6 +66,7 @@ import ( "github.com/pingcap/tidb/util/sem" "github.com/pingcap/tidb/util/set" "github.com/pingcap/tidb/util/sqlexec" + "github.com/pingcap/tidb/util/stmtsummary" "github.com/tikv/client-go/v2/tikv" "go.uber.org/zap" ) @@ -90,6 +92,7 @@ type tableHintInfo struct { indexNestedLoopJoinTables sortMergeJoinTables []hintTableInfo broadcastJoinTables []hintTableInfo + shuffleJoinTables []hintTableInfo hashJoinTables []hintTableInfo indexHintList []indexHintInfo tiflashTables []hintTableInfo @@ -227,6 +230,10 @@ func (info *tableHintInfo) ifPreferBroadcastJoin(tableNames ...*hintTableInfo) b return info.matchTableName(tableNames, info.broadcastJoinTables) } +func (info *tableHintInfo) ifPreferShuffleJoin(tableNames ...*hintTableInfo) bool { + return info.matchTableName(tableNames, info.shuffleJoinTables) +} + func (info *tableHintInfo) ifPreferHashJoin(tableNames ...*hintTableInfo) bool { return info.matchTableName(tableNames, info.hashJoinTables) } @@ -571,6 +578,9 @@ type PlanBuilder struct { // disableSubQueryPreprocessing indicates whether to pre-process uncorrelated sub-queries in rewriting stage. disableSubQueryPreprocessing bool + + // allowBuildCastArray indicates whether allow cast(... as ... array). + allowBuildCastArray bool } type handleColHelper struct { @@ -628,7 +638,7 @@ func (b *PlanBuilder) GetIsForUpdateRead() bool { } // GetDBTableInfo gets the accessed dbs and tables info. -func (b *PlanBuilder) GetDBTableInfo() []stmtctx.TableEntry { +func GetDBTableInfo(visitInfo []visitInfo) []stmtctx.TableEntry { var tables []stmtctx.TableEntry existsFunc := func(tbls []stmtctx.TableEntry, tbl *stmtctx.TableEntry) bool { for _, t := range tbls { @@ -638,7 +648,13 @@ func (b *PlanBuilder) GetDBTableInfo() []stmtctx.TableEntry { } return false } - for _, v := range b.visitInfo { + for _, v := range visitInfo { + if v.db == "" && v.table == "" { + // when v.db == "" and v.table == "", it means this visitInfo is for dynamic privilege, + // so it is not related to any database or table. + continue + } + tbl := &stmtctx.TableEntry{DB: v.db, Table: v.table} if !existsFunc(tables, tbl) { tables = append(tables, *tbl) @@ -685,6 +701,14 @@ func (p PlanBuilderOptNoExecution) Apply(builder *PlanBuilder) { builder.disableSubQueryPreprocessing = true } +// PlanBuilderOptAllowCastArray means the plan builder should allow build cast(... as ... array). +type PlanBuilderOptAllowCastArray struct{} + +// Apply implements the interface PlanBuilderOpt. +func (p PlanBuilderOptAllowCastArray) Apply(builder *PlanBuilder) { + builder.allowBuildCastArray = true +} + // NewPlanBuilder creates a new PlanBuilder. func NewPlanBuilder(opts ...PlanBuilderOpt) *PlanBuilder { builder := &PlanBuilder{ @@ -775,6 +799,10 @@ func (b *PlanBuilder) Build(ctx context.Context, node ast.Node) (Plan, error) { return b.buildLoadData(ctx, x) case *ast.LoadStatsStmt: return b.buildLoadStats(x), nil + case *ast.LockStatsStmt: + return b.buildLockStats(x), nil + case *ast.UnlockStatsStmt: + return b.buildUnlockStats(x), nil case *ast.IndexAdviseStmt: return b.buildIndexAdvise(x), nil case *ast.PlanReplayerStmt: @@ -804,7 +832,7 @@ func (b *PlanBuilder) Build(ctx context.Context, node ast.Node) (Plan, error) { *ast.BeginStmt, *ast.CommitStmt, *ast.SavepointStmt, *ast.ReleaseSavepointStmt, *ast.RollbackStmt, *ast.CreateUserStmt, *ast.SetPwdStmt, *ast.AlterInstanceStmt, *ast.GrantStmt, *ast.DropUserStmt, *ast.AlterUserStmt, *ast.RevokeStmt, *ast.KillStmt, *ast.DropStatsStmt, *ast.GrantRoleStmt, *ast.RevokeRoleStmt, *ast.SetRoleStmt, *ast.SetDefaultRoleStmt, *ast.ShutdownStmt, - *ast.RenameUserStmt, *ast.NonTransactionalDeleteStmt, *ast.SetSessionStatesStmt: + *ast.RenameUserStmt, *ast.NonTransactionalDMLStmt, *ast.SetSessionStatesStmt: return b.buildSimple(ctx, node.(ast.StmtNode)) case ast.DDLNode: return b.buildDDL(ctx, x) @@ -964,24 +992,43 @@ func (b *PlanBuilder) buildSet(ctx context.Context, v *ast.SetStmt) (Plan, error } func (b *PlanBuilder) buildDropBindPlan(v *ast.DropBindingStmt) (Plan, error) { - p := &SQLBindPlan{ - SQLBindOp: OpSQLBindDrop, - NormdOrigSQL: parser.Normalize(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())), - IsGlobal: v.GlobalScope, - Db: utilparser.GetDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB), - } - if v.HintedNode != nil { - p.BindSQL = utilparser.RestoreWithDefaultDB(v.HintedNode, b.ctx.GetSessionVars().CurrentDB, v.HintedNode.Text()) + var p *SQLBindPlan + if v.OriginNode != nil { + p = &SQLBindPlan{ + SQLBindOp: OpSQLBindDrop, + NormdOrigSQL: parser.Normalize(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())), + IsGlobal: v.GlobalScope, + Db: utilparser.GetDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB), + } + if v.HintedNode != nil { + p.BindSQL = utilparser.RestoreWithDefaultDB(v.HintedNode, b.ctx.GetSessionVars().CurrentDB, v.HintedNode.Text()) + } + } else { + p = &SQLBindPlan{ + SQLBindOp: OpSQLBindDropByDigest, + IsGlobal: v.GlobalScope, + SQLDigest: v.SQLDigest, + } } b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil) return p, nil } func (b *PlanBuilder) buildSetBindingStatusPlan(v *ast.SetBindingStmt) (Plan, error) { - p := &SQLBindPlan{ - SQLBindOp: OpSetBindingStatus, - NormdOrigSQL: parser.Normalize(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())), - Db: utilparser.GetDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB), + var p *SQLBindPlan + if v.OriginNode != nil { + p = &SQLBindPlan{ + SQLBindOp: OpSetBindingStatus, + NormdOrigSQL: parser.Normalize(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())), + Db: utilparser.GetDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB), + } + } else if v.SQLDigest != "" { + p = &SQLBindPlan{ + SQLBindOp: OpSetBindingStatusByDigest, + SQLDigest: v.SQLDigest, + } + } else { + return nil, errors.New("sql digest is empty") } switch v.BindingStatusType { case ast.BindingStatusTypeEnabled: @@ -1015,7 +1062,78 @@ func checkHintedSQL(sql, charset, collation, db string) error { return nil } +func fetchRecordFromClusterStmtSummary(sctx sessionctx.Context, planDigest string) ([]chunk.Row, error) { + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBindInfo) + exec, _ := sctx.(sqlexec.SQLExecutor) + fields := "stmt_type, schema_name, digest_text, sample_user, prepared, query_sample_text, charset, collation, plan_hint, plan_digest" + sql := fmt.Sprintf("select %s from information_schema.cluster_statements_summary where plan_digest = '%s' union distinct ", fields, planDigest) + + fmt.Sprintf("select %s from information_schema.cluster_statements_summary_history where plan_digest = '%s' ", fields, planDigest) + + "order by length(plan_digest) desc" + rs, err := exec.ExecuteInternal(ctx, sql) + if rs == nil { + return nil, errors.New("can't find any records for '" + planDigest + "' in statement summary") + } + if err != nil { + return nil, err + } + + var rows []chunk.Row + defer terror.Call(rs.Close) + if rows, err = sqlexec.DrainRecordSet(ctx, rs, 8); err != nil { + return nil, err + } + return rows, nil +} + +func (b *PlanBuilder) buildCreateBindPlanFromPlanDigest(v *ast.CreateBindingStmt) (Plan, error) { + if v.PlanDigest == "" { + return nil, errors.New("plan digest is empty") + } + rows, err := fetchRecordFromClusterStmtSummary(b.ctx, v.PlanDigest) + if err != nil { + return nil, err + } + bindableStmt := stmtsummary.GetBindableStmtFromCluster(rows) + if bindableStmt == nil { + return nil, errors.New("can't find any plans for '" + v.PlanDigest + "'") + } + + parser4binding := parser.New() + originNode, err := parser4binding.ParseOneStmt(bindableStmt.Query, bindableStmt.Charset, bindableStmt.Collation) + if err != nil { + return nil, errors.Errorf("binding failed: %v", err) + } + if err = hint.CheckBindingFromHistoryBindable(originNode, bindableStmt.PlanHint); err != nil { + return nil, err + } + bindSQL := bindinfo.GenerateBindSQL(context.TODO(), originNode, bindableStmt.PlanHint, true, bindableStmt.Schema) + var hintNode ast.StmtNode + hintNode, err = parser4binding.ParseOneStmt(bindSQL, bindableStmt.Charset, bindableStmt.Collation) + if err != nil { + return nil, errors.Errorf("binding failed: %v", err) + } + normdOrigSQL, sqlDigestWithDB := parser.NormalizeDigest(utilparser.RestoreWithDefaultDB(originNode, bindableStmt.Schema, bindableStmt.Query)) + p := &SQLBindPlan{ + SQLBindOp: OpSQLBindCreate, + NormdOrigSQL: normdOrigSQL, + BindSQL: utilparser.RestoreWithDefaultDB(hintNode, bindableStmt.Schema, hintNode.Text()), + IsGlobal: v.GlobalScope, + BindStmt: hintNode, + Db: utilparser.GetDefaultDB(originNode, bindableStmt.Schema), + Charset: bindableStmt.Charset, + Collation: bindableStmt.Collation, + Source: bindinfo.History, + SQLDigest: sqlDigestWithDB.String(), + PlanDigest: v.PlanDigest, + } + b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil) + return p, nil +} + func (b *PlanBuilder) buildCreateBindPlan(v *ast.CreateBindingStmt) (Plan, error) { + if v.OriginNode == nil { + return b.buildCreateBindPlanFromPlanDigest(v) + } charSet, collation := b.ctx.GetSessionVars().GetCharsetInfo() // Because we use HintedNode.Restore instead of HintedNode.Text, so we need do some check here @@ -1027,15 +1145,18 @@ func (b *PlanBuilder) buildCreateBindPlan(v *ast.CreateBindingStmt) (Plan, error return nil, err } + normdOrigSQL, sqlDigestWithDB := parser.NormalizeDigest(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())) p := &SQLBindPlan{ SQLBindOp: OpSQLBindCreate, - NormdOrigSQL: parser.Normalize(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())), + NormdOrigSQL: normdOrigSQL, BindSQL: utilparser.RestoreWithDefaultDB(v.HintedNode, b.ctx.GetSessionVars().CurrentDB, v.HintedNode.Text()), IsGlobal: v.GlobalScope, BindStmt: v.HintedNode, Db: utilparser.GetDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB), Charset: charSet, Collation: collation, + Source: bindinfo.Manual, + SQLDigest: sqlDigestWithDB.String(), } b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil) return p, nil @@ -1096,7 +1217,8 @@ func (b *PlanBuilder) detectSelectWindow(sel *ast.SelectStmt) bool { } func getPathByIndexName(paths []*util.AccessPath, idxName model.CIStr, tblInfo *model.TableInfo) *util.AccessPath { - var primaryIdxPath *util.AccessPath + var primaryIdxPath, indexPrefixPath *util.AccessPath + prefixMatches := 0 for _, path := range paths { if path.StoreType == kv.TiFlash { continue @@ -1108,10 +1230,19 @@ func getPathByIndexName(paths []*util.AccessPath, idxName model.CIStr, tblInfo * if path.Index.Name.L == idxName.L { return path } + if strings.HasPrefix(path.Index.Name.L, idxName.L) { + indexPrefixPath = path + prefixMatches++ + } } if isPrimaryIndex(idxName) && tblInfo.HasClusteredIndex() { return primaryIdxPath } + + // Return only unique prefix matches + if prefixMatches == 1 { + return indexPrefixPath + } return nil } @@ -1290,6 +1421,12 @@ func getPossibleAccessPaths(ctx sessionctx.Context, tableHints *tableHintInfo, i // our cost estimation is not reliable. hasUseOrForce = true path.Forced = true + if hint.HintType == ast.HintKeepOrder { + path.ForceKeepOrder = true + } + if hint.HintType == ast.HintNoKeepOrder { + path.ForceNoKeepOrder = true + } available = append(available, path) } } @@ -1299,10 +1436,6 @@ func getPossibleAccessPaths(ctx sessionctx.Context, tableHints *tableHintInfo, i } available = removeIgnoredPaths(available, ignored, tblInfo) - if staleread.IsStmtStaleness(ctx) { - // skip tiflash if the statement is for stale read until tiflash support stale read - available = removeTiflashDuringStaleRead(available) - } // If we have got "FORCE" or "USE" index hint but got no available index, // we have to use table scan. @@ -1320,7 +1453,10 @@ func filterPathByIsolationRead(ctx sessionctx.Context, paths []*util.AccessPath, isolationReadEngines := ctx.GetSessionVars().GetIsolationReadEngines() availableEngine := map[kv.StoreType]struct{}{} var availableEngineStr string + var outputComputeNodeErrMsg bool + noTiFlashComputeNode := config.GetGlobalConfig().DisaggregatedTiFlash && !isTiFlashComputeNodeAvailable(ctx) for i := len(paths) - 1; i >= 0; i-- { + // availableEngineStr is for warning message. if _, ok := availableEngine[paths[i].StoreType]; !ok { availableEngine[paths[i].StoreType] = struct{}{} if availableEngineStr != "" { @@ -1328,7 +1464,20 @@ func filterPathByIsolationRead(ctx sessionctx.Context, paths []*util.AccessPath, } availableEngineStr += paths[i].StoreType.Name() } - if _, ok := isolationReadEngines[paths[i].StoreType]; !ok && paths[i].StoreType != kv.TiDB { + _, exists := isolationReadEngines[paths[i].StoreType] + // Prune this path if: + // 1. path.StoreType doesn't exists in isolationReadEngines or + // 2. TiFlash is disaggregated and the number of tiflash_compute node is zero. + shouldPruneTiFlashCompute := noTiFlashComputeNode && exists && paths[i].StoreType == kv.TiFlash + failpoint.Inject("testDisaggregatedTiFlashQuery", func(val failpoint.Value) { + // Ignore check if tiflash_compute node number. + // After we support disaggregated tiflash in test framework, can delete this failpoint. + shouldPruneTiFlashCompute = val.(bool) + }) + if shouldPruneTiFlashCompute { + outputComputeNodeErrMsg = true + } + if (!exists && paths[i].StoreType != kv.TiDB) || shouldPruneTiFlashCompute { paths = append(paths[:i], paths[i+1:]...) } } @@ -1337,7 +1486,11 @@ func filterPathByIsolationRead(ctx sessionctx.Context, paths []*util.AccessPath, if len(paths) == 0 { helpMsg := "" if engineVals == "tiflash" { - helpMsg = ". Please check tiflash replica or ensure the query is readonly" + if outputComputeNodeErrMsg { + helpMsg = ". Please check tiflash_compute node is available" + } else { + helpMsg = ". Please check tiflash replica or ensure the query is readonly" + } } err = ErrInternal.GenWithStackByArgs(fmt.Sprintf("No access path for table '%s' is found with '%v' = '%v', valid values can be '%s'%s.", tblName.String(), variable.TiDBIsolationReadEngines, engineVals, availableEngineStr, helpMsg)) @@ -3036,6 +3189,7 @@ func (b *PlanBuilder) buildShow(ctx context.Context, show *ast.ShowStmt) (Plan, Partition: show.Partition, Column: show.Column, IndexName: show.IndexName, + ResourceGroupName: show.ResourceGroupName, Flag: show.Flag, User: show.User, Roles: show.Roles, @@ -3109,7 +3263,7 @@ func (b *PlanBuilder) buildShow(ctx context.Context, show *ast.ShowStmt) (Plan, err = ErrDBaccessDenied.GenWithStackByArgs(user.AuthUsername, user.AuthHostname, mysql.SystemDB) } b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SelectPriv, mysql.SystemDB, "", "", err) - case ast.ShowStatsBuckets, ast.ShowStatsHistograms, ast.ShowStatsMeta: + case ast.ShowStatsBuckets, ast.ShowStatsHistograms, ast.ShowStatsMeta, ast.ShowStatsLocked: var err error if user := b.ctx.GetSessionVars().User; user != nil { err = ErrTableaccessDenied.GenWithStackByArgs("SHOW", user.AuthUsername, user.AuthHostname, show.Table.Name.L) @@ -3278,6 +3432,16 @@ func (b *PlanBuilder) buildSimple(ctx context.Context, node ast.StmtNode) (Plan, p.StaleTxnStartTS = readTS // consume read ts here b.ctx.GetSessionVars().TxnReadTS.UseTxnReadTS() + } else if b.ctx.GetSessionVars().EnableExternalTSRead && !b.ctx.GetSessionVars().InRestrictedSQL { + // try to get the stale ts from external timestamp + startTS, err := staleread.GetExternalTimestamp(ctx, b.ctx) + if err != nil { + return nil, err + } + if err := sessionctx.ValidateStaleReadTS(ctx, b.ctx, startTS); err != nil { + return nil, err + } + p.StaleTxnStartTS = startTS } } return p, nil @@ -3455,7 +3619,10 @@ func (b *PlanBuilder) resolveGeneratedColumns(ctx context.Context, columns []*ta } colExpr := mockPlan.Schema().Columns[idx] + originalVal := b.allowBuildCastArray + b.allowBuildCastArray = true expr, _, err := b.rewrite(ctx, column.GeneratedExpr, mockPlan, nil, true) + b.allowBuildCastArray = originalVal if err != nil { return igc, err } @@ -3616,7 +3783,7 @@ func (b *PlanBuilder) buildInsert(ctx context.Context, insert *ast.InsertStmt) ( if err != nil { return nil, err } - insertPlan.FKChecks, err = insertPlan.buildOnInsertFKChecks(b.ctx, b.is, tn.DBInfo.Name.L) + err = insertPlan.buildOnInsertFKTriggers(b.ctx, b.is, tn.DBInfo.Name.L) return insertPlan, err } @@ -3999,7 +4166,7 @@ func (b *PlanBuilder) buildLoadData(ctx context.Context, ld *ast.LoadDataStmt) ( return nil, ErrNotSupportedYet.GenWithStackByArgs("load data with empty field terminator") } p := LoadData{ - IsLocal: ld.IsLocal, + FileLocRef: ld.FileLocRef, OnDuplicate: ld.OnDuplicate, Path: ld.Path, Table: ld.Table, @@ -4046,6 +4213,16 @@ func (b *PlanBuilder) buildLoadStats(ld *ast.LoadStatsStmt) Plan { return p } +func (b *PlanBuilder) buildLockStats(ld *ast.LockStatsStmt) Plan { + p := &LockStats{Tables: ld.Tables} + return p +} + +func (b *PlanBuilder) buildUnlockStats(ld *ast.UnlockStatsStmt) Plan { + p := &UnlockStats{Tables: ld.Tables} + return p +} + func (b *PlanBuilder) buildIndexAdvise(node *ast.IndexAdviseStmt) Plan { p := &IndexAdvise{ IsLocal: node.IsLocal, @@ -4367,6 +4544,14 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err } b.visitInfo = appendVisitInfo(b.visitInfo, mysql.UpdatePriv, mysql.SystemDB, "stats_extended", "", authErr) + } else if spec.Tp == ast.AlterTableAddConstraint { + if b.ctx.GetSessionVars().User != nil && spec.Constraint != nil && + spec.Constraint.Tp == ast.ConstraintForeignKey && spec.Constraint.Refer != nil { + authErr = ErrTableaccessDenied.GenWithStackByArgs("REFERENCES", b.ctx.GetSessionVars().User.AuthUsername, + b.ctx.GetSessionVars().User.AuthHostname, spec.Constraint.Refer.Table.Name.L) + b.visitInfo = appendVisitInfo(b.visitInfo, mysql.ReferencesPriv, spec.Constraint.Refer.Table.Schema.L, + spec.Constraint.Refer.Table.Name.L, "", authErr) + } } } case *ast.AlterSequenceStmt: @@ -4457,9 +4642,9 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err if len(v.Cols) != schema.Len() { return nil, dbterror.ErrViewWrongList } - if b.ctx.GetSessionVars().User != nil { - authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE VIEW", b.ctx.GetSessionVars().User.AuthUsername, - b.ctx.GetSessionVars().User.AuthHostname, v.ViewName.Name.L) + if user := b.ctx.GetSessionVars().User; user != nil { + authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE VIEW", user.AuthUsername, + user.AuthHostname, v.ViewName.Name.L) } b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreateViewPriv, v.ViewName.Schema.L, v.ViewName.Name.L, "", authErr) @@ -4545,9 +4730,12 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err } b.visitInfo = appendVisitInfo(b.visitInfo, mysql.InsertPriv, v.TableToTables[0].NewTable.Schema.L, v.TableToTables[0].NewTable.Name.L, "", authErr) - case *ast.RecoverTableStmt, *ast.FlashBackTableStmt: + case *ast.RecoverTableStmt, *ast.FlashBackTableStmt, *ast.FlashBackDatabaseStmt: // Recover table command can only be executed by administrator. b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil) + case *ast.FlashBackToTimestampStmt: + // Flashback cluster can only be executed by user with `super` privilege. + b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil) case *ast.LockTablesStmt: user := b.ctx.GetSessionVars().User for _, lock := range v.TableLocks { @@ -4568,6 +4756,9 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err case *ast.DropPlacementPolicyStmt, *ast.CreatePlacementPolicyStmt, *ast.AlterPlacementPolicyStmt: err := ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or PLACEMENT_ADMIN") b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "PLACEMENT_ADMIN", false, err) + case *ast.CreateResourceGroupStmt, *ast.DropResourceGroupStmt, *ast.AlterResourceGroupStmt: + err := ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESOURCE_GROUP_ADMIN") + b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESOURCE_GROUP_ADMIN", false, err) } p := &DDL{Statement: node} return p, nil @@ -4848,6 +5039,8 @@ func buildShowSchema(s *ast.ShowStmt, isView bool, isSequence bool) (schema *exp } case ast.ShowCreatePlacementPolicy: names = []string{"Policy", "Create Policy"} + case ast.ShowCreateResourceGroup: + names = []string{"Resource_Group", "Create Resource Group"} case ast.ShowCreateUser: if s.User != nil { names = []string{fmt.Sprintf("CREATE USER for %s", s.User)} @@ -4915,6 +5108,9 @@ func buildShowSchema(s *ast.ShowStmt, isView bool, isSequence bool) (schema *exp case ast.ShowColumnStatsUsage: names = []string{"Db_name", "Table_name", "Partition_name", "Column_name", "Last_used_at", "Last_analyzed_at"} ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeDatetime, mysql.TypeDatetime} + case ast.ShowStatsLocked: + names = []string{"Db_name", "Table_name", "Partition_name", "Status"} + ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar} case ast.ShowProfiles: // ShowProfiles is deprecated. names = []string{"Query_ID", "Duration", "Query"} ftypes = []byte{mysql.TypeLong, mysql.TypeDouble, mysql.TypeVarchar} @@ -4925,8 +5121,8 @@ func buildShowSchema(s *ast.ShowStmt, isView bool, isSequence bool) (schema *exp names = []string{"Privilege", "Context", "Comment"} ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar} case ast.ShowBindings: - names = []string{"Original_sql", "Bind_sql", "Default_db", "Status", "Create_time", "Update_time", "Charset", "Collation", "Source"} - ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeDatetime, mysql.TypeDatetime, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar} + names = []string{"Original_sql", "Bind_sql", "Default_db", "Status", "Create_time", "Update_time", "Charset", "Collation", "Source", "Sql_digest", "Plan_digest"} + ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeDatetime, mysql.TypeDatetime, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar} case ast.ShowBindingCacheStatus: names = []string{"bindings_in_cache", "bindings_in_table", "memory_usage", "memory_quota"} ftypes = []byte{mysql.TypeLonglong, mysql.TypeLonglong, mysql.TypeVarchar, mysql.TypeVarchar} @@ -4974,7 +5170,7 @@ func buildShowSchema(s *ast.ShowStmt, isView bool, isSequence bool) (schema *exp } func (b *PlanBuilder) buildPlanReplayer(pc *ast.PlanReplayerStmt) Plan { - p := &PlanReplayer{ExecStmt: pc.Stmt, Analyze: pc.Analyze, Load: pc.Load, File: pc.File} + p := &PlanReplayer{ExecStmt: pc.Stmt, Analyze: pc.Analyze, Load: pc.Load, File: pc.File, Capture: pc.Capture, SQLDigest: pc.SQLDigest, PlanDigest: pc.PlanDigest} schema := newColumnsWithNames(1) schema.Append(buildColumnWithName("", "File_token", mysql.TypeVarchar, 128)) p.SetSchema(schema.col2Schema()) diff --git a/planner/core/planbuilder_test.go b/planner/core/planbuilder_test.go index 13494433f0fbe..8ad1d5c49c0e2 100644 --- a/planner/core/planbuilder_test.go +++ b/planner/core/planbuilder_test.go @@ -91,6 +91,11 @@ func TestGetPathByIndexName(t *testing.T) { require.NotNil(t, path) require.Equal(t, accessPath[1], path) + // "id" is a prefix of "idx" + path = getPathByIndexName(accessPath, model.NewCIStr("id"), tblInfo) + require.NotNil(t, path) + require.Equal(t, accessPath[1], path) + path = getPathByIndexName(accessPath, model.NewCIStr("primary"), tblInfo) require.NotNil(t, path) require.Equal(t, accessPath[0], path) diff --git a/planner/core/point_get_plan.go b/planner/core/point_get_plan.go index 96e17291e421c..23bc05d2f117f 100644 --- a/planner/core/point_get_plan.go +++ b/planner/core/point_get_plan.go @@ -22,6 +22,7 @@ import ( "unsafe" "github.com/pingcap/errors" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" @@ -44,6 +45,7 @@ import ( tidbutil "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" + "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/plancodec" @@ -90,6 +92,28 @@ type PointGetPlan struct { planCostVer2 costVer2 // accessCols represents actual columns the PointGet will access, which are used to calculate row-size accessCols []*expression.Column + + // probeParents records the IndexJoins and Applys with this operator in their inner children. + // Please see comments in PhysicalPlan for details. + probeParents []PhysicalPlan +} + +func (p *PointGetPlan) getEstRowCountForDisplay() float64 { + if p == nil { + return 0 + } + return p.statsInfo().RowCount * getEstimatedProbeCntFromProbeParents(p.probeParents) +} + +func (p *PointGetPlan) getActualProbeCnt(statsColl *execdetails.RuntimeStatsColl) int64 { + if p == nil { + return 1 + } + return getActualProbeCntFromProbeParents(p.probeParents, statsColl) +} + +func (p *PointGetPlan) setProbeParents(probeParents []PhysicalPlan) { + p.probeParents = probeParents } type nameValuePair struct { @@ -317,6 +341,27 @@ type BatchPointGetPlan struct { planCostVer2 costVer2 // accessCols represents actual columns the PointGet will access, which are used to calculate row-size accessCols []*expression.Column + + // probeParents records the IndexJoins and Applys with this operator in their inner children. + // Please see comments in PhysicalPlan for details. + probeParents []PhysicalPlan +} + +func (p *BatchPointGetPlan) getEstRowCountForDisplay() float64 { + if p == nil { + return 0 + } + return p.statsInfo().RowCount * getEstimatedProbeCntFromProbeParents(p.probeParents) +} + +func (p *BatchPointGetPlan) getActualProbeCnt(statsColl *execdetails.RuntimeStatsColl) int64 { + if p == nil { + return 1 + } + return getActualProbeCntFromProbeParents(p.probeParents, statsColl) +} +func (p *BatchPointGetPlan) setProbeParents(probeParents []PhysicalPlan) { + p.probeParents = probeParents } // Cost implements PhysicalPlan interface @@ -564,7 +609,7 @@ func getLockWaitTime(ctx sessionctx.Context, lockInfo *ast.SelectLockInfo) (lock // autocommit to 0. If autocommit is enabled, the rows matching the specification are not locked. // See https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html sessVars := ctx.GetSessionVars() - if !sessVars.IsAutocommit() || sessVars.InTxn() { + if !sessVars.IsAutocommit() || sessVars.InTxn() || config.GetGlobalConfig().PessimisticTxn.PessimisticAutoCommit.Load() { lock = true waitTime = sessVars.LockWaitTimeout if lockInfo.LockType == ast.SelectLockForUpdateWaitN { @@ -1310,7 +1355,7 @@ func getNameValuePairs(ctx sessionctx.Context, tbl *model.TableInfo, tblName mod case *driver.ValueExpr: d = x.Datum case *driver.ParamMarkerExpr: - con, err = expression.ParamMarkerExpression(ctx, x, true) + con, err = expression.ParamMarkerExpression(ctx, x, false) if err != nil { return nil, false } @@ -1324,7 +1369,7 @@ func getNameValuePairs(ctx sessionctx.Context, tbl *model.TableInfo, tblName mod case *driver.ValueExpr: d = x.Datum case *driver.ParamMarkerExpr: - con, err = expression.ParamMarkerExpression(ctx, x, true) + con, err = expression.ParamMarkerExpression(ctx, x, false) if err != nil { return nil, false } @@ -1549,7 +1594,7 @@ func buildPointUpdatePlan(ctx sessionctx.Context, pointPlan PhysicalPlan, dbName updatePlan.PartitionedTable = append(updatePlan.PartitionedTable, pt) } } - err := updatePlan.buildOnUpdateFKChecks(ctx, is, updatePlan.tblID2Table) + err := updatePlan.buildOnUpdateFKTriggers(ctx, is, updatePlan.tblID2Table) if err != nil { return nil } @@ -1643,10 +1688,12 @@ func buildPointDeletePlan(ctx sessionctx.Context, pointPlan PhysicalPlan, dbName var err error is := sessiontxn.GetTxnManager(ctx).GetTxnInfoSchema() t, _ := is.TableByID(tbl.ID) - tblID2Table := map[int64]table.Table{tbl.ID: t} - err = delPlan.buildOnDeleteFKChecks(ctx, is, tblID2Table) - if err != nil { - return nil + if t != nil { + tblID2Table := map[int64]table.Table{tbl.ID: t} + err = delPlan.buildOnDeleteFKTriggers(ctx, is, tblID2Table) + if err != nil { + return nil + } } return delPlan } @@ -1851,12 +1898,7 @@ func getPartitionExpr(ctx sessionctx.Context, tbl *model.TableInfo) *tables.Part } // PartitionExpr don't need columns and names for hash partition. - partitionExpr, err := partTable.PartitionExpr() - if err != nil { - return nil - } - - return partitionExpr + return partTable.PartitionExpr() } func getHashPartitionColumnName(ctx sessionctx.Context, tbl *model.TableInfo) *ast.ColumnName { @@ -1873,10 +1915,7 @@ func getHashPartitionColumnName(ctx sessionctx.Context, tbl *model.TableInfo) *a return nil } // PartitionExpr don't need columns and names for hash partition. - partitionExpr, err := table.(partitionTable).PartitionExpr() - if err != nil { - return nil - } + partitionExpr := table.(partitionTable).PartitionExpr() expr := partitionExpr.OrigExpr col, ok := expr.(*ast.ColumnNameExpr) if !ok { diff --git a/planner/core/point_get_plan_test.go b/planner/core/point_get_plan_test.go index 3a92d25719c09..812151afc26ec 100644 --- a/planner/core/point_get_plan_test.go +++ b/planner/core/point_get_plan_test.go @@ -175,6 +175,7 @@ func TestGetExtraColumn(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`CREATE TABLE t ( a int(11) DEFAULT NULL, b int(11) DEFAULT NULL, @@ -328,7 +329,7 @@ func TestPointGetId(t *testing.T) { require.Len(t, stmts, 1) stmt := stmts[0] ret := &core.PreprocessorReturn{} - err = core.Preprocess(ctx, stmt, core.WithPreprocessorReturn(ret)) + err = core.Preprocess(context.Background(), ctx, stmt, core.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := planner.Optimize(context.TODO(), ctx, stmt, ret.InfoSchema) require.NoError(t, err) @@ -959,7 +960,7 @@ func TestIssue26638(t *testing.T) { tk.MustQuery("execute stmt1 using @c;").Check(testkit.Rows()) tk.MustQuery("execute stmt2 using @c, @d;").Check(testkit.Rows()) tk.MustExec("drop table if exists t2;") - tk.MustExec("create table t2(a float, b float, c float, primary key(a, b, c));") + tk.MustExec("create table t2(a float, b float, c float, primary key(a, b, c) nonclustered);") tk.MustExec("insert into t2 values(-1, 0, 1), (-1.1, 0, 1.1), (-1.56018e38, -1.96716e38, 9.46347e37), (0, 1, 2);") tk.MustQuery("explain format='brief' select * from t2 where (a, b, c) in ((-1.1, 0, 1.1), (-1.56018e38, -1.96716e38, 9.46347e37));").Check(testkit.Rows("TableDual 0.00 root rows:0")) tk.MustQuery("select * from t2 where (a, b, c) in ((-1.1, 0, 1.1), (-1.56018e38, -1.96716e38, 9.46347e37), (-1, 0, 1));").Check(testkit.Rows("-1 0 1")) @@ -976,7 +977,7 @@ func TestIssue23511(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2;") - tk.MustExec("CREATE TABLE `t1` (`COL1` bit(11) NOT NULL,PRIMARY KEY (`COL1`));") + tk.MustExec("CREATE TABLE `t1` (`COL1` bit(11) NOT NULL,PRIMARY KEY (`COL1`) NONCLUSTERED);") tk.MustExec("CREATE TABLE `t2` (`COL1` bit(11) NOT NULL);") tk.MustExec("insert into t1 values(b'00000111001'), (b'00000000000');") tk.MustExec("insert into t2 values(b'00000111001');") diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index 8d5cb077ad5c7..656aed73ca189 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -60,7 +60,7 @@ func TestPointGetPreparedPlan4PlanCache(t *testing.T) { pspk1Id, _, _, err := tk1.Session().PrepareStmt("select * from t where a = ?") require.NoError(t, err) - tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*core.PlanCacheStmt).PreparedAst.UseCache = false + tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*core.PlanCacheStmt).StmtCacheable = false ctx := context.Background() // first time plan generated @@ -1339,7 +1339,7 @@ func TestPlanCacheSwitchDB(t *testing.T) { // DB is not specified se2, err := session.CreateSession4TestWithOpt(store, &session.Opt{ - PreparedPlanCache: core.NewLRUPlanCache(100, 0.1, math.MaxUint64, core.PickPlanFromBucket), + PreparedPlanCache: core.NewLRUPlanCache(100, 0.1, math.MaxUint64, core.PickPlanFromBucket, tk.Session()), }) require.NoError(t, err) tk2 := testkit.NewTestKitWithSession(t, store, se2) @@ -1373,7 +1373,6 @@ func TestPlanCacheSwitchDB(t *testing.T) { } func TestPlanCacheHitInfo(t *testing.T) { - t.Skip("unstable, skip it and fix it before 20210705") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec(`set tidb_enable_prepared_plan_cache=1`) @@ -1420,7 +1419,7 @@ func TestIssue29303(t *testing.T) { tk.MustQuery(`execute stmt using @a,@b,@c,@d`).Check(testkit.Rows()) tk.MustExec(`set @a="龂", @b="龂", @c="龂", @d="龂"`) tk.MustQuery(`execute stmt using @a,@b,@c,@d`).Check(testkit.Rows("� 龂 � 龂")) - tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0")) + tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1")) } func TestIssue34725(t *testing.T) { @@ -1940,17 +1939,16 @@ func TestPlanCachePointGetAndTableDual(t *testing.T) { tk.MustQuery("execute s0 using @a0, @b0, @a0").Check(testkit.Rows()) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s0 using @a0, @a0, @b0").Check(testkit.Rows("0000 7777 1")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustExec("create table t1(c1 varchar(20), c2 varchar(20), c3 bigint(20), primary key(c1, c2))") tk.MustExec("insert into t1 values('0000','7777',1)") tk.MustExec("prepare s1 from 'select * from t1 where c1=? and c2>=? and c2<=?'") tk.MustExec("set @a1='0000', @b1='9999'") - // IndexLookup plan would be built, we should cache it. tk.MustQuery("execute s1 using @a1, @b1, @b1").Check(testkit.Rows()) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s1 using @a1, @a1, @b1").Check(testkit.Rows("0000 7777 1")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // c2>=9999 and c2<=9999 --> c2=9999 tk.MustExec("create table t2(c1 bigint(20) primary key, c2 varchar(20))") tk.MustExec("insert into t2 values(1,'7777')") @@ -1966,17 +1964,15 @@ func TestPlanCachePointGetAndTableDual(t *testing.T) { tk.MustExec("insert into t3 values(2,1,1)") tk.MustExec("prepare s3 from 'select /*+ use_index_merge(t3) */ * from t3 where (c1 >= ? and c1 <= ?) or c2 > 1'") tk.MustExec("set @a3=1,@b3=3") - // TableReader plan would be built, we should cache it. tk.MustQuery("execute s3 using @a3,@a3").Check(testkit.Rows()) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s3 using @a3,@b3").Check(testkit.Rows("2 1 1")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // c1>=1 and c1<=1 --> c1==1 tk.MustExec("prepare s3 from 'select /*+ use_index_merge(t3) */ * from t3 where (c1 >= ? and c1 <= ?) or c2 > 1'") tk.MustExec("set @a3=1,@b3=3") - // TableReader plan would be built, we should cache it. tk.MustQuery("execute s3 using @b3,@a3").Check(testkit.Rows()) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s3 using @a3,@b3").Check(testkit.Rows("2 1 1")) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) @@ -1987,7 +1983,7 @@ func TestPlanCachePointGetAndTableDual(t *testing.T) { tk.MustQuery("execute s4 using @a4,@a4").Check(testkit.Rows()) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s4 using @a4,@b4").Check(testkit.Rows("2 1 1")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // c1>=3 and c1<=3 --> c1=3 tk.MustExec("prepare s4 from 'select /*+ use_index_merge(t4) */ * from t4 where (c1 >= ? and c1 <= ?) or c2 > 1'") tk.MustExec("set @a4=1,@b4=3") @@ -2044,7 +2040,7 @@ func TestIssue23671(t *testing.T) { tk.MustQuery("execute s1 using @a, @b, @c").Check(testkit.Rows("1 1")) tk.MustExec("set @a=1, @b=1, @c=10") tk.MustQuery("execute s1 using @a, @b, @c").Check(testkit.Rows("1 1", "2 2")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // b>=1 and b<=1 --> b=1 } func TestIssue29296(t *testing.T) { @@ -2550,7 +2546,7 @@ func TestCachedTable(t *testing.T) { // IndexLookup tk.MustQuery("execute indexLookup using @a, @b").Check(testkit.Rows("2")) require.True(t, lastReadFromCache(tk)) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // b>1 and b<3 --> b=2 // PointGet tk.MustQuery("execute pointGet using @a").Check(testkit.Rows("1")) diff --git a/planner/core/preprocess.go b/planner/core/preprocess.go index da3f60d907bef..c5a2a9999db90 100644 --- a/planner/core/preprocess.go +++ b/planner/core/preprocess.go @@ -24,6 +24,7 @@ import ( "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/ast" @@ -118,12 +119,12 @@ func TryAddExtraLimit(ctx sessionctx.Context, node ast.StmtNode) ast.StmtNode { // Preprocess resolves table names of the node, and checks some statements' validation. // preprocessReturn used to extract the infoschema for the tableName and the timestamp from the asof clause. -func Preprocess(ctx sessionctx.Context, node ast.Node, preprocessOpt ...PreprocessOpt) error { +func Preprocess(ctx context.Context, sctx sessionctx.Context, node ast.Node, preprocessOpt ...PreprocessOpt) error { v := preprocessor{ - ctx: ctx, + sctx: sctx, tableAliasInJoin: make([]map[string]interface{}, 0), preprocessWith: &preprocessWith{cteCanUsed: make([]string, 0), cteBeforeOffset: make([]int, 0)}, - staleReadProcessor: staleread.NewStaleReadProcessor(ctx), + staleReadProcessor: staleread.NewStaleReadProcessor(ctx, sctx), } for _, optFn := range preprocessOpt { optFn(&v) @@ -208,7 +209,7 @@ func (pw *preprocessWith) UpdateCTEConsumerCount(tableName string) { // preprocessor is an ast.Visitor that preprocess // ast Nodes parsed from parser. type preprocessor struct { - ctx sessionctx.Context + sctx sessionctx.Context flag preprocessorFlag stmtTp byte showTp ast.ShowStmtType @@ -297,23 +298,38 @@ func (p *preprocessor) Enter(in ast.Node) (out ast.Node, skipChildren bool) { p.checkNonUniqTableAlias(node) case *ast.CreateBindingStmt: p.stmtTp = TypeCreate - EraseLastSemicolon(node.OriginNode) - EraseLastSemicolon(node.HintedNode) - p.checkBindGrammar(node.OriginNode, node.HintedNode, p.ctx.GetSessionVars().CurrentDB) + if node.OriginNode != nil { + // if node.PlanDigest is not empty, this binding will be created from history, the node.OriginNode and node.HintedNode should be nil + EraseLastSemicolon(node.OriginNode) + EraseLastSemicolon(node.HintedNode) + p.checkBindGrammar(node.OriginNode, node.HintedNode, p.sctx.GetSessionVars().CurrentDB) + } return in, true case *ast.DropBindingStmt: p.stmtTp = TypeDrop - EraseLastSemicolon(node.OriginNode) - if node.HintedNode != nil { - EraseLastSemicolon(node.HintedNode) - p.checkBindGrammar(node.OriginNode, node.HintedNode, p.ctx.GetSessionVars().CurrentDB) + if node.OriginNode != nil { + EraseLastSemicolon(node.OriginNode) + if node.HintedNode != nil { + EraseLastSemicolon(node.HintedNode) + p.checkBindGrammar(node.OriginNode, node.HintedNode, p.sctx.GetSessionVars().CurrentDB) + } } return in, true - case *ast.RecoverTableStmt, *ast.FlashBackTableStmt: + case *ast.RecoverTableStmt: // The specified table in recover table statement maybe already been dropped. // So skip check table name here, otherwise, recover table [table_name] syntax will return // table not exists error. But recover table statement is use to recover the dropped table. So skip children here. return in, true + case *ast.FlashBackTableStmt: + if len(node.NewName) > 0 { + p.checkFlashbackTableGrammar(node) + } + return in, true + case *ast.FlashBackDatabaseStmt: + if len(node.NewName) > 0 { + p.checkFlashbackDatabaseGrammar(node) + } + return in, true case *ast.RepairTableStmt: p.stmtTp = TypeRepair // The RepairTable should consist of the logic for creating tables and renaming tables. @@ -339,7 +355,7 @@ func (p *preprocessor) Enter(in ast.Node) (out ast.Node, skipChildren bool) { p.flag |= inCreateOrDropTable } case *ast.TableSource: - isModeOracle := p.ctx.GetSessionVars().SQLMode&mysql.ModeOracle != 0 + isModeOracle := p.sctx.GetSessionVars().SQLMode&mysql.ModeOracle != 0 if _, ok := node.Source.(*ast.SelectStmt); ok && !isModeOracle && len(node.AsName.L) == 0 { p.err = dbterror.ErrDerivedMustHaveAlias.GenWithStackByArgs() } @@ -364,14 +380,14 @@ func (p *preprocessor) Enter(in ast.Node) (out ast.Node, skipChildren bool) { // start transaction read only as of timestamp .... // then we need set StmtCtx.IsStaleness as true in order to avoid take tso in PrepareTSFuture. if node.AsOf != nil { - p.ctx.GetSessionVars().StmtCtx.IsStaleness = true + p.sctx.GetSessionVars().StmtCtx.IsStaleness = true p.IsStaleness = true - } else if p.ctx.GetSessionVars().TxnReadTS.PeakTxnReadTS() > 0 { + } else if p.sctx.GetSessionVars().TxnReadTS.PeakTxnReadTS() > 0 { // If the begin statement was like following: // set transaction read only as of timestamp ... // begin // then we need set StmtCtx.IsStaleness as true in order to avoid take tso in PrepareTSFuture. - p.ctx.GetSessionVars().StmtCtx.IsStaleness = true + p.sctx.GetSessionVars().StmtCtx.IsStaleness = true p.IsStaleness = true } default: @@ -442,7 +458,7 @@ func bindableStmtType(node ast.StmtNode) byte { } func (p *preprocessor) tableByName(tn *ast.TableName) (table.Table, error) { - currentDB := p.ctx.GetSessionVars().CurrentDB + currentDB := p.sctx.GetSessionVars().CurrentDB if tn.Schema.String() != "" { currentDB = tn.Schema.L } @@ -462,8 +478,8 @@ func (p *preprocessor) tableByName(tn *ast.TableName) (table.Table, error) { // We should never leak that the table doesn't exist (i.e. attach ErrTableNotExists) // unless we know that the user has permissions to it, should it exist. // By checking here, this makes all SELECT/SHOW/INSERT/UPDATE/DELETE statements safe. - currentUser, activeRoles := p.ctx.GetSessionVars().User, p.ctx.GetSessionVars().ActiveRoles - if pm := privilege.GetPrivilegeManager(p.ctx); pm != nil { + currentUser, activeRoles := p.sctx.GetSessionVars().User, p.sctx.GetSessionVars().ActiveRoles + if pm := privilege.GetPrivilegeManager(p.sctx); pm != nil { if !pm.RequestVerification(activeRoles, sName.L, tn.Name.O, "", mysql.AllPrivMask) { u := currentUser.Username h := currentUser.Hostname @@ -664,6 +680,10 @@ func checkAutoIncrementOp(colDef *ast.ColumnDef, index int) (bool, error) { func isConstraintKeyTp(constraints []*ast.Constraint, colDef *ast.ColumnDef) bool { for _, c := range constraints { + // ignore constraint check + if c.Tp == ast.ConstraintCheck { + continue + } if c.Keys[0].Expr != nil { continue } @@ -788,6 +808,18 @@ func (p *preprocessor) checkDropDatabaseGrammar(stmt *ast.DropDatabaseStmt) { } } +func (p *preprocessor) checkFlashbackTableGrammar(stmt *ast.FlashBackTableStmt) { + if isIncorrectName(stmt.NewName) { + p.err = dbterror.ErrWrongTableName.GenWithStackByArgs(stmt.NewName) + } +} + +func (p *preprocessor) checkFlashbackDatabaseGrammar(stmt *ast.FlashBackDatabaseStmt) { + if isIncorrectName(stmt.NewName) { + p.err = dbterror.ErrWrongDBName.GenWithStackByArgs(stmt.NewName) + } +} + func (p *preprocessor) checkAdminCheckTableGrammar(stmt *ast.AdminStmt) { for _, table := range stmt.Tables { tableInfo, err := p.tableByName(table) @@ -811,7 +843,7 @@ func (p *preprocessor) checkAdminCheckTableGrammar(stmt *ast.AdminStmt) { func (p *preprocessor) checkCreateTableGrammar(stmt *ast.CreateTableStmt) { if stmt.ReferTable != nil { - schema := model.NewCIStr(p.ctx.GetSessionVars().CurrentDB) + schema := model.NewCIStr(p.sctx.GetSessionVars().CurrentDB) if stmt.ReferTable.Schema.String() != "" { schema = stmt.ReferTable.Schema } @@ -985,7 +1017,7 @@ func (p *preprocessor) checkDropTableGrammar(stmt *ast.DropTableStmt) { } func (p *preprocessor) checkDropTemporaryTableGrammar(stmt *ast.DropTableStmt) { - currentDB := model.NewCIStr(p.ctx.GetSessionVars().CurrentDB) + currentDB := model.NewCIStr(p.sctx.GetSessionVars().CurrentDB) for _, t := range stmt.Tables { if isIncorrectName(t.Name.String()) { p.err = dbterror.ErrWrongTableName.GenWithStackByArgs(t.Name.String()) @@ -1030,7 +1062,7 @@ func (p *preprocessor) checkNonUniqTableAlias(stmt *ast.Join) { p.tableAliasInJoin = append(p.tableAliasInJoin, make(map[string]interface{})) } tableAliases := p.tableAliasInJoin[len(p.tableAliasInJoin)-1] - isOracleMode := p.ctx.GetSessionVars().SQLMode&mysql.ModeOracle != 0 + isOracleMode := p.sctx.GetSessionVars().SQLMode&mysql.ModeOracle != 0 if !isOracleMode { if err := isTableAliasDuplicate(stmt.Left, tableAliases); err != nil { p.err = err @@ -1103,7 +1135,7 @@ func (p *preprocessor) checkCreateIndexGrammar(stmt *ast.CreateIndexStmt) { } func (p *preprocessor) checkGroupBy(stmt *ast.GroupByClause) { - noopFuncsMode := p.ctx.GetSessionVars().NoopFuncsMode + noopFuncsMode := p.sctx.GetSessionVars().NoopFuncsMode for _, item := range stmt.Items { if !item.NullOrder && noopFuncsMode != variable.OnInt { err := expression.ErrFunctionsNoopImpl.GenWithStackByArgs("GROUP BY expr ASC|DESC") @@ -1112,7 +1144,7 @@ func (p *preprocessor) checkGroupBy(stmt *ast.GroupByClause) { return } // NoopFuncsMode is Warn, append an error - p.ctx.GetSessionVars().StmtCtx.AppendWarning(err) + p.sctx.GetSessionVars().StmtCtx.AppendWarning(err) } } } @@ -1495,7 +1527,7 @@ func (p *preprocessor) handleTableName(tn *ast.TableName) { } } - currentDB := p.ctx.GetSessionVars().CurrentDB + currentDB := p.sctx.GetSessionVars().CurrentDB if currentDB == "" { p.err = errors.Trace(ErrNoDB) return @@ -1537,11 +1569,11 @@ func (p *preprocessor) handleTableName(tn *ast.TableName) { p.err = err return } - currentDB := p.ctx.GetSessionVars().CurrentDB + currentDB := p.sctx.GetSessionVars().CurrentDB if tn.Schema.String() != "" { currentDB = tn.Schema.L } - table, err = tryLockMDLAndUpdateSchemaIfNecessary(p.ctx, model.NewCIStr(currentDB), table, p.ensureInfoSchema()) + table, err = tryLockMDLAndUpdateSchemaIfNecessary(p.sctx, model.NewCIStr(currentDB), table, p.ensureInfoSchema()) if err != nil { p.err = err return @@ -1586,8 +1618,8 @@ func (p *preprocessor) handleRepairName(tn *ast.TableName) { p.err = dbterror.ErrRepairTableFail.GenWithStackByArgs("table " + tn.Name.L + " is not in repair") return } - p.ctx.SetValue(domainutil.RepairedTable, tableInfo) - p.ctx.SetValue(domainutil.RepairedDatabase, dbInfo) + p.sctx.SetValue(domainutil.RepairedTable, tableInfo) + p.sctx.SetValue(domainutil.RepairedDatabase, dbInfo) } func (p *preprocessor) resolveShowStmt(node *ast.ShowStmt) { @@ -1595,14 +1627,14 @@ func (p *preprocessor) resolveShowStmt(node *ast.ShowStmt) { if node.Table != nil && node.Table.Schema.L != "" { node.DBName = node.Table.Schema.O } else { - node.DBName = p.ctx.GetSessionVars().CurrentDB + node.DBName = p.sctx.GetSessionVars().CurrentDB } } else if node.Table != nil && node.Table.Schema.L == "" { node.Table.Schema = model.NewCIStr(node.DBName) } if node.User != nil && node.User.CurrentUser { // Fill the Username and Hostname with the current user. - currentUser := p.ctx.GetSessionVars().User + currentUser := p.sctx.GetSessionVars().User if currentUser != nil { node.User.Username = currentUser.Username node.User.Hostname = currentUser.Hostname @@ -1613,7 +1645,7 @@ func (p *preprocessor) resolveShowStmt(node *ast.ShowStmt) { } func (p *preprocessor) resolveExecuteStmt(node *ast.ExecuteStmt) { - prepared, err := GetPreparedStmt(node, p.ctx.GetSessionVars()) + prepared, err := GetPreparedStmt(node, p.sctx.GetSessionVars()) if err != nil { p.err = err return @@ -1704,16 +1736,17 @@ func (p *preprocessor) updateStateFromStaleReadProcessor() error { p.LastSnapshotTS = p.staleReadProcessor.GetStalenessReadTS() p.SnapshotTSEvaluator = p.staleReadProcessor.GetStalenessTSEvaluatorForPrepare() p.InfoSchema = p.staleReadProcessor.GetStalenessInfoSchema() + p.InfoSchema = &infoschema.SessionExtendedInfoSchema{InfoSchema: p.InfoSchema} // If the select statement was like 'select * from t as of timestamp ...' or in a stale read transaction // or is affected by the tidb_read_staleness session variable, then the statement will be makred as isStaleness // in stmtCtx if p.flag&initTxnContextProvider != 0 { - p.ctx.GetSessionVars().StmtCtx.IsStaleness = true - if !p.ctx.GetSessionVars().InTxn() { - txnManager := sessiontxn.GetTxnManager(p.ctx) + p.sctx.GetSessionVars().StmtCtx.IsStaleness = true + if !p.sctx.GetSessionVars().InTxn() { + txnManager := sessiontxn.GetTxnManager(p.sctx) newTxnRequest := &sessiontxn.EnterNewTxnRequest{ Type: sessiontxn.EnterNewTxnWithReplaceProvider, - Provider: staleread.NewStalenessTxnContextProvider(p.ctx, p.LastSnapshotTS, p.InfoSchema), + Provider: staleread.NewStalenessTxnContextProvider(p.sctx, p.LastSnapshotTS, p.InfoSchema), } if err := txnManager.EnterNewTxn(context.TODO(), newTxnRequest); err != nil { return err @@ -1738,12 +1771,12 @@ func (p *preprocessor) ensureInfoSchema() infoschema.InfoSchema { return p.InfoSchema } - p.InfoSchema = sessiontxn.GetTxnManager(p.ctx).GetTxnInfoSchema() + p.InfoSchema = sessiontxn.GetTxnManager(p.sctx).GetTxnInfoSchema() return p.InfoSchema } func (p *preprocessor) hasAutoConvertWarning(colDef *ast.ColumnDef) bool { - sessVars := p.ctx.GetSessionVars() + sessVars := p.sctx.GetSessionVars() if !sessVars.SQLMode.HasStrictMode() && colDef.Tp.GetType() == mysql.TypeVarchar { colDef.Tp.SetType(mysql.TypeBlob) if colDef.Tp.GetCharset() == charset.CharsetBin { @@ -1781,10 +1814,7 @@ func tryLockMDLAndUpdateSchemaIfNecessary(sctx sessionctx.Context, dbName model. } tableInfo := tbl.Meta() if _, ok := sctx.GetSessionVars().GetRelatedTableForMDL().Load(tableInfo.ID); !ok { - if se, ok := is.(*infoschema.SessionExtendedInfoSchema); ok && skipLock { - if se.MdlTables == nil { - return tbl, nil - } + if se, ok := is.(*infoschema.SessionExtendedInfoSchema); ok && skipLock && se.MdlTables != nil { if _, ok := se.MdlTables.TableByID(tableInfo.ID); ok { // Already attach. return tbl, nil @@ -1800,15 +1830,14 @@ func tryLockMDLAndUpdateSchemaIfNecessary(sctx sessionctx.Context, dbName model. } domainSchema := domain.GetDomain(sctx).InfoSchema() domainSchemaVer := domainSchema.SchemaMetaVersion() - if !skipLock { - sctx.GetSessionVars().GetRelatedTableForMDL().Store(tableInfo.ID, domainSchemaVer) - } - var err error tbl, err = domainSchema.TableByName(dbName, tableInfo.Name) if err != nil { return nil, err } + if !skipLock { + sctx.GetSessionVars().GetRelatedTableForMDL().Store(tbl.Meta().ID, domainSchemaVer) + } // Check the table change, if adding new public index or modify a column, we need to handle them. if !sctx.GetSessionVars().IsPessimisticReadConsistency() { var copyTableInfo *model.TableInfo @@ -1850,22 +1879,28 @@ func tryLockMDLAndUpdateSchemaIfNecessary(sctx sessionctx.Context, dbName model. } } if found { - return nil, ErrSchemaChanged.GenWithStack("public column %s has changed", col.Name) + return nil, domain.ErrInfoSchemaChanged.GenWithStack("public column %s has changed", col.Name) } } } se, ok := is.(*infoschema.SessionExtendedInfoSchema) if !ok { - se = infoschema.AttachMDLTableInfoSchema(is).(*infoschema.SessionExtendedInfoSchema) - sessiontxn.GetTxnManager(sctx).SetTxnInfoSchema(se) - sctx.GetSessionVars().TxnCtx.InfoSchema = se + logutil.BgLogger().Error("InfoSchema is not SessionExtendedInfoSchema", zap.Stack("stack")) + return nil, errors.New("InfoSchema is not SessionExtendedInfoSchema") } db, _ := domainSchema.SchemaByTable(tbl.Meta()) err = se.UpdateTableInfo(db, tbl) if err != nil { return nil, err } + curTxn, err := sctx.Txn(false) + if err != nil { + return nil, err + } + if curTxn.Valid() { + curTxn.SetOption(kv.TableToColumnMaps, nil) + } return tbl, nil } return tbl, nil diff --git a/planner/core/preprocess_test.go b/planner/core/preprocess_test.go index 2ff7bb8ce6d6a..6d6ebb1b8bf49 100644 --- a/planner/core/preprocess_test.go +++ b/planner/core/preprocess_test.go @@ -15,6 +15,7 @@ package core_test import ( + "context" "strings" "testing" @@ -45,7 +46,7 @@ func runSQL(t *testing.T, ctx sessionctx.Context, is infoschema.InfoSchema, sql if inPrepare { opts = append(opts, core.InPrepare) } - err = core.Preprocess(ctx, stmt, append(opts, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is}))...) + err = core.Preprocess(context.Background(), ctx, stmt, append(opts, core.WithPreprocessorReturn(&core.PreprocessorReturn{InfoSchema: is}))...) require.Truef(t, terror.ErrorEqual(err, terr), "sql: %s, err:%v", sql, err) } @@ -415,7 +416,7 @@ func TestPreprocessCTE(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) - err = core.Preprocess(tk.Session(), stmts[0]) + err = core.Preprocess(context.Background(), tk.Session(), stmts[0]) require.NoError(t, err) var rs strings.Builder diff --git a/planner/core/resolve_indices.go b/planner/core/resolve_indices.go index 483d0b9f92299..b602c46a78bd2 100644 --- a/planner/core/resolve_indices.go +++ b/planner/core/resolve_indices.go @@ -21,12 +21,8 @@ import ( "github.com/pingcap/tidb/util/disjointset" ) -// ResolveIndices implements Plan interface. -func (p *PhysicalProjection) ResolveIndices() (err error) { - err = p.physicalSchemaProducer.ResolveIndices() - if err != nil { - return err - } +// ResolveIndicesItself resolve indices for PhysicalPlan itself +func (p *PhysicalProjection) ResolveIndicesItself() (err error) { for i, expr := range p.Exprs { p.Exprs[i], err = expr.ResolveIndices(p.children[0].Schema()) if err != nil { @@ -41,6 +37,15 @@ func (p *PhysicalProjection) ResolveIndices() (err error) { return } +// ResolveIndices implements Plan interface. +func (p *PhysicalProjection) ResolveIndices() (err error) { + err = p.physicalSchemaProducer.ResolveIndices() + if err != nil { + return err + } + return p.ResolveIndicesItself() +} + // refine4NeighbourProj refines the index for p.Exprs whose type is *Column when // there is two neighbouring Projections. // This function is introduced because that different childProj.Expr may refer @@ -74,12 +79,8 @@ func refine4NeighbourProj(p, childProj *PhysicalProjection) { } } -// ResolveIndices implements Plan interface. -func (p *PhysicalHashJoin) ResolveIndices() (err error) { - err = p.physicalSchemaProducer.ResolveIndices() - if err != nil { - return err - } +// ResolveIndicesItself resolve indices for PhyicalPlan itself +func (p *PhysicalHashJoin) ResolveIndicesItself() (err error) { lSchema := p.children[0].Schema() rSchema := p.children[1].Schema() for i, fun := range p.EqualConditions { @@ -129,6 +130,15 @@ func (p *PhysicalHashJoin) ResolveIndices() (err error) { return } +// ResolveIndices implements Plan interface. +func (p *PhysicalHashJoin) ResolveIndices() (err error) { + err = p.physicalSchemaProducer.ResolveIndices() + if err != nil { + return err + } + return p.ResolveIndicesItself() +} + // ResolveIndices implements Plan interface. func (p *PhysicalMergeJoin) ResolveIndices() (err error) { err = p.physicalSchemaProducer.ResolveIndices() @@ -380,12 +390,8 @@ func (p *PhysicalSelection) ResolveIndices() (err error) { return nil } -// ResolveIndices implements Plan interface. -func (p *PhysicalExchangeSender) ResolveIndices() (err error) { - err = p.basePhysicalPlan.ResolveIndices() - if err != nil { - return err - } +// ResolveIndicesItself resolve indices for PhyicalPlan itself +func (p *PhysicalExchangeSender) ResolveIndicesItself() (err error) { for i, col := range p.HashCols { colExpr, err1 := col.Col.ResolveIndices(p.children[0].Schema()) if err1 != nil { @@ -393,7 +399,16 @@ func (p *PhysicalExchangeSender) ResolveIndices() (err error) { } p.HashCols[i].Col, _ = colExpr.(*expression.Column) } - return err + return +} + +// ResolveIndices implements Plan interface. +func (p *PhysicalExchangeSender) ResolveIndices() (err error) { + err = p.basePhysicalPlan.ResolveIndices() + if err != nil { + return err + } + return p.ResolveIndicesItself() } // ResolveIndices implements Plan interface. diff --git a/planner/core/rule_column_pruning.go b/planner/core/rule_column_pruning.go index f42d385acc161..34a5259abbd32 100644 --- a/planner/core/rule_column_pruning.go +++ b/planner/core/rule_column_pruning.go @@ -312,6 +312,14 @@ func (ds *DataSource) PruneColumns(parentUsedCols []*expression.Column, opt *log originSchemaColumns := ds.schema.Columns originColumns := ds.Columns + + ds.colsRequiringFullLen = make([]*expression.Column, 0, len(used)) + for i, col := range ds.schema.Columns { + if used[i] || (ds.containExprPrefixUk && expression.GcColumnExprIsTidbShard(col.VirtualExpr)) { + ds.colsRequiringFullLen = append(ds.colsRequiringFullLen, col) + } + } + for i := len(used) - 1; i >= 0; i-- { if !used[i] && !exprUsed[i] { // If ds has a shard index, and the column is generated column by `tidb_shard()` @@ -331,19 +339,7 @@ func (ds *DataSource) PruneColumns(parentUsedCols []*expression.Column, opt *log if ds.schema.Len() == 0 { var handleCol *expression.Column var handleColInfo *model.ColumnInfo - if ds.table.Type().IsClusterTable() && len(originColumns) > 0 { - // use the first line. - handleCol = originSchemaColumns[0] - handleColInfo = originColumns[0] - } else { - if ds.handleCols != nil { - handleCol = ds.handleCols.GetCol(0) - handleColInfo = handleCol.ToInfo() - } else { - handleCol = ds.newExtraHandleSchemaCol() - handleColInfo = model.NewExtraHandleColInfo() - } - } + handleCol, handleColInfo = preferKeyColumnFromTable(ds, originSchemaColumns, originColumns) ds.Columns = append(ds.Columns, handleColInfo) ds.schema.Append(handleCol) } @@ -650,3 +646,23 @@ func appendItemPruneTraceStep(p LogicalPlan, itemType string, prunedObjects []fm } opt.appendStepToCurrent(p.ID(), p.TP(), reason, action) } + +func preferKeyColumnFromTable(dataSource *DataSource, originColumns []*expression.Column, + originSchemaColumns []*model.ColumnInfo) (*expression.Column, *model.ColumnInfo) { + var resultColumnInfo *model.ColumnInfo + var resultColumn *expression.Column + if dataSource.table.Type().IsClusterTable() && len(originColumns) > 0 { + // use the first column. + resultColumnInfo = originSchemaColumns[0] + resultColumn = originColumns[0] + } else { + if dataSource.handleCols != nil { + resultColumn = dataSource.handleCols.GetCol(0) + resultColumnInfo = resultColumn.ToInfo() + } else { + resultColumn = dataSource.newExtraHandleSchemaCol() + resultColumnInfo = model.NewExtraHandleColInfo() + } + } + return resultColumn, resultColumnInfo +} diff --git a/planner/core/rule_join_reorder_test.go b/planner/core/rule_join_reorder_test.go index a0c136d8d4a2f..9fb0c7e83ab1f 100644 --- a/planner/core/rule_join_reorder_test.go +++ b/planner/core/rule_join_reorder_test.go @@ -52,6 +52,7 @@ func TestStraightJoinHint(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, t1, t2, t3, t4;") tk.MustExec("create table t(a int, b int, key(a));") tk.MustExec("create table t1(a int, b int, key(a));") @@ -66,6 +67,7 @@ func TestLeadingJoinHint(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, t1, t2, t3, t4, t5, t6, t7, t8;") tk.MustExec("create table t(a int, b int, key(a));") tk.MustExec("create table t1(a int, b int, key(a));") @@ -219,6 +221,7 @@ func TestJoinOrderHint4StaticPartitionTable(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, t1, t2, t3;") tk.MustExec(`create table t(a int, b int) partition by hash(a) partitions 3`) tk.MustExec(`create table t1(a int, b int) partition by hash(a) partitions 4`) @@ -259,6 +262,7 @@ func TestJoinOrderHint4DifferentJoinType(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, t1, t2, t3, t4, t5, t6, t7, t8;") tk.MustExec("create table t(a int, b int, key(a));") tk.MustExec("create table t1(a int, b int, key(a));") @@ -312,6 +316,7 @@ func TestJoinOrderHint4Subquery(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, t1, t2, t3, t4, t5, t6, t7, t8;") tk.MustExec("create table t(a int, b int, key(a));") tk.MustExec("create table t1(a int, b int, key(a));") @@ -333,6 +338,7 @@ func TestLeadingJoinHint4OuterJoin(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t, t1, t2, t3, t4, t5, t6, t7, t8;") tk.MustExec("create table t(a int, b int, key(a));") tk.MustExec("create table t1(a int, b int, key(a));") diff --git a/planner/core/rule_partition_processor.go b/planner/core/rule_partition_processor.go index d188854686491..5982bcb32d6ba 100644 --- a/planner/core/rule_partition_processor.go +++ b/planner/core/rule_partition_processor.go @@ -110,7 +110,7 @@ func (s *partitionProcessor) rewriteDataSource(lp LogicalPlan, opt *logicalOptim // partitionTable is for those tables which implement partition. type partitionTable interface { - PartitionExpr() (*tables.PartitionExpr, error) + PartitionExpr() *tables.PartitionExpr } func generateHashPartitionExpr(ctx sessionctx.Context, pi *model.PartitionInfo, columns []*expression.Column, names types.NameSlice) (expression.Expression, error) { @@ -288,7 +288,8 @@ func (s *partitionProcessor) pruneHashPartition(ctx sessionctx.Context, tbl tabl // please see https://github.com/pingcap/tidb/issues/22635 for more details. func (s *partitionProcessor) reconstructTableColNames(ds *DataSource) ([]*types.FieldName, error) { names := make([]*types.FieldName, 0, len(ds.TblCols)) - colsInfo := ds.table.FullHiddenColsAndVisibleCols() + // Use DeletableCols to get all the columns. + colsInfo := ds.table.DeletableCols() colsInfoMap := make(map[int64]*table.Column, len(colsInfo)) for _, c := range colsInfo { colsInfoMap[c.ID] = c @@ -594,13 +595,11 @@ func (l *listPartitionPruner) findUsedListPartitions(conds []expression.Expressi func (s *partitionProcessor) findUsedListPartitions(ctx sessionctx.Context, tbl table.Table, partitionNames []model.CIStr, conds []expression.Expression) ([]int, error) { pi := tbl.Meta().Partition - partExpr, err := tbl.(partitionTable).PartitionExpr() - if err != nil { - return nil, err - } + partExpr := tbl.(partitionTable).PartitionExpr() listPruner := newListPartitionPruner(ctx, tbl, partitionNames, s, conds, partExpr.ForListPruning) var used map[int]struct{} + var err error if partExpr.ForListPruning.ColPrunes == nil { used, err = listPruner.findUsedListPartitions(conds) } else { @@ -825,10 +824,7 @@ func intersectionRange(start, end, newStart, newEnd int) (int, int) { func (s *partitionProcessor) pruneRangePartition(ctx sessionctx.Context, pi *model.PartitionInfo, tbl table.PartitionedTable, conds []expression.Expression, columns []*expression.Column, names types.NameSlice) (partitionRangeOR, error) { - partExpr, err := tbl.(partitionTable).PartitionExpr() - if err != nil { - return nil, err - } + partExpr := tbl.(partitionTable).PartitionExpr() // Partition by range columns. if len(pi.Columns) > 0 { diff --git a/planner/core/rule_predicate_push_down.go b/planner/core/rule_predicate_push_down.go index 96d62942f2346..94f92f780202a 100644 --- a/planner/core/rule_predicate_push_down.go +++ b/planner/core/rule_predicate_push_down.go @@ -440,16 +440,20 @@ func isNullRejected(ctx sessionctx.Context, schema *expression.Schema, expr expr } sc := ctx.GetSessionVars().StmtCtx sc.InNullRejectCheck = true - result := expression.EvaluateExprWithNull(ctx, schema, expr) - sc.InNullRejectCheck = false - x, ok := result.(*expression.Constant) - if !ok { - return false - } - if x.Value.IsNull() { - return true - } else if isTrue, err := x.Value.ToBool(sc); err == nil && isTrue == 0 { - return true + defer func() { + sc.InNullRejectCheck = false + }() + for _, cond := range expression.SplitCNFItems(expr) { + result := expression.EvaluateExprWithNull(ctx, schema, cond) + x, ok := result.(*expression.Constant) + if !ok { + continue + } + if x.Value.IsNull() { + return true + } else if isTrue, err := x.Value.ToBool(sc); err == nil && isTrue == 0 { + return true + } } return false } @@ -470,8 +474,8 @@ func (p *LogicalProjection) PredicatePushDown(predicates []expression.Expression } } for _, cond := range predicates { - substituted, newFilter := expression.ColumnSubstitute4PPD(cond, p.Schema(), p.Exprs) - if substituted && !expression.HasGetSetVarFunc(newFilter) { + substituted, hasFailed, newFilter := expression.ColumnSubstituteImpl(cond, p.Schema(), p.Exprs, true) + if substituted && !hasFailed && !expression.HasGetSetVarFunc(newFilter) { canBePushed = append(canBePushed, newFilter) } else { canNotBePushed = append(canNotBePushed, cond) diff --git a/planner/core/rule_result_reorder_test.go b/planner/core/rule_result_reorder_test.go index e6a248bee4071..1a178cd66bfe7 100644 --- a/planner/core/rule_result_reorder_test.go +++ b/planner/core/rule_result_reorder_test.go @@ -106,6 +106,7 @@ func TestOrderedResultMode(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec(`set tidb_opt_limit_push_down_threshold=0`) tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t") @@ -129,6 +130,7 @@ func TestOrderedResultModeOnSubQuery(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") @@ -142,6 +144,7 @@ func TestOrderedResultModeOnJoin(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") @@ -156,6 +159,7 @@ func TestOrderedResultModeOnOtherOperators(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("set tidb_enable_ordered_result_mode=1") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") diff --git a/planner/core/stats.go b/planner/core/stats.go index 4ece8209397cd..96065fccf12b5 100644 --- a/planner/core/stats.go +++ b/planner/core/stats.go @@ -22,9 +22,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/expression" - "github.com/pingcap/tidb/kv" - "github.com/pingcap/tidb/parser/ast" - "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/planner/property" "github.com/pingcap/tidb/planner/util" @@ -277,7 +274,7 @@ func (ds *DataSource) derivePathStatsAndTryHeuristics() error { path.IsSingleScan = true } else { ds.deriveIndexPathStats(path, ds.pushedDownConds, false) - path.IsSingleScan = ds.isCoveringIndex(ds.schema.Columns, path.FullIdxCols, path.FullIdxColLens, ds.tableInfo) + path.IsSingleScan = ds.isSingleScan(path.FullIdxCols, path.FullIdxColLens) } // Try some heuristic rules to select access path. if len(path.Ranges) == 0 { @@ -343,35 +340,37 @@ func (ds *DataSource) derivePathStatsAndTryHeuristics() error { if selected != nil { ds.possibleAccessPaths[0] = selected ds.possibleAccessPaths = ds.possibleAccessPaths[:1] - if ds.ctx.GetSessionVars().StmtCtx.InVerboseExplain { - var tableName string - if ds.TableAsName.O == "" { - tableName = ds.tableInfo.Name.O + var tableName string + if ds.TableAsName.O == "" { + tableName = ds.tableInfo.Name.O + } else { + tableName = ds.TableAsName.O + } + var sb strings.Builder + if selected.IsTablePath() { + // TODO: primary key / handle / real name? + sb.WriteString(fmt.Sprintf("handle of %s is selected since the path only has point ranges", tableName)) + } else { + if selected.Index.Unique { + sb.WriteString("unique ") + } + sb.WriteString(fmt.Sprintf("index %s of %s is selected since the path", selected.Index.Name.O, tableName)) + if isRefinedPath { + sb.WriteString(" only fetches limited number of rows") } else { - tableName = ds.TableAsName.O + sb.WriteString(" only has point ranges") } - if selected.IsTablePath() { - // TODO: primary key / handle / real name? - ds.ctx.GetSessionVars().StmtCtx.AppendNote(fmt.Errorf("handle of %s is selected since the path only has point ranges", tableName)) + if selected.IsSingleScan { + sb.WriteString(" with single scan") } else { - var sb strings.Builder - if selected.Index.Unique { - sb.WriteString("unique ") - } - sb.WriteString(fmt.Sprintf("index %s of %s is selected since the path", selected.Index.Name.O, tableName)) - if isRefinedPath { - sb.WriteString(" only fetches limited number of rows") - } else { - sb.WriteString(" only has point ranges") - } - if selected.IsSingleScan { - sb.WriteString(" with single scan") - } else { - sb.WriteString(" with double scan") - } - ds.ctx.GetSessionVars().StmtCtx.AppendNote(errors.New(sb.String())) + sb.WriteString(" with double scan") } } + if ds.ctx.GetSessionVars().StmtCtx.InVerboseExplain { + ds.ctx.GetSessionVars().StmtCtx.AppendNote(errors.New(sb.String())) + } else { + ds.ctx.GetSessionVars().StmtCtx.AppendExtraNote(errors.New(sb.String())) + } } return nil } @@ -409,95 +408,13 @@ func (ds *DataSource) DeriveStats(_ []*property.StatsInfo, _ *expression.Schema, return nil, err } - // Consider the IndexMergePath. Now, we just generate `IndexMergePath` in DNF case. - // Use allConds instread of pushedDownConds, - // because we want to use IndexMerge even if some expr cannot be pushed to TiKV. - // We will create new Selection for exprs that cannot be pushed in convertToIndexMergeScan. - indexMergeConds := make([]expression.Expression, 0, len(ds.allConds)) - for _, expr := range ds.allConds { - indexMergeConds = append(indexMergeConds, expression.PushDownNot(ds.ctx, expr)) - } - - stmtCtx := ds.ctx.GetSessionVars().StmtCtx - isPossibleIdxMerge := len(indexMergeConds) > 0 && len(ds.possibleAccessPaths) > 1 - sessionAndStmtPermission := (ds.ctx.GetSessionVars().GetEnableIndexMerge() || len(ds.indexMergeHints) > 0) && !stmtCtx.NoIndexMergeHint - // We current do not consider `IndexMergePath`: - // 1. If there is an index path. - // 2. TODO: If there exists exprs that cannot be pushed down. This is to avoid wrongly estRow of Selection added by rule_predicate_push_down. - needConsiderIndexMerge := true - if len(ds.indexMergeHints) == 0 { - for i := 1; i < len(ds.possibleAccessPaths); i++ { - if len(ds.possibleAccessPaths[i].AccessConds) != 0 { - needConsiderIndexMerge = false - break - } - } - if needConsiderIndexMerge { - // PushDownExprs() will append extra warnings, which is annoying. So we reset warnings here. - warnings := stmtCtx.GetWarnings() - _, remaining := expression.PushDownExprs(stmtCtx, indexMergeConds, ds.ctx.GetClient(), kv.UnSpecified) - stmtCtx.SetWarnings(warnings) - if len(remaining) != 0 { - needConsiderIndexMerge = false - } - } + if err := ds.generateIndexMergePath(); err != nil { + return nil, err } - if isPossibleIdxMerge && sessionAndStmtPermission && needConsiderIndexMerge && ds.tableInfo.TempTableType != model.TempTableLocal { - err := ds.generateAndPruneIndexMergePath(indexMergeConds, ds.indexMergeHints != nil) - if err != nil { - return nil, err - } - } else if len(ds.indexMergeHints) > 0 { - ds.indexMergeHints = nil - var msg string - if !isPossibleIdxMerge { - msg = "No available filter or available index." - } else if !sessionAndStmtPermission { - msg = "Got no_index_merge hint or tidb_enable_index_merge is off." - } else if ds.tableInfo.TempTableType == model.TempTableLocal { - msg = "Cannot use IndexMerge on temporary table." - } - msg = fmt.Sprintf("IndexMerge is inapplicable or disabled. %s", msg) - stmtCtx.AppendWarning(errors.Errorf(msg)) - logutil.BgLogger().Debug(msg) - } return ds.stats, nil } -func (ds *DataSource) generateAndPruneIndexMergePath(indexMergeConds []expression.Expression, needPrune bool) error { - regularPathCount := len(ds.possibleAccessPaths) - err := ds.generateIndexMergeOrPaths(indexMergeConds) - if err != nil { - return err - } - // If without hints, it means that `enableIndexMerge` is true - if len(ds.indexMergeHints) == 0 { - return nil - } - // With hints and without generated IndexMerge paths - if regularPathCount == len(ds.possibleAccessPaths) { - ds.indexMergeHints = nil - ds.ctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("IndexMerge is inapplicable")) - return nil - } - // Do not need to consider the regular paths in find_best_task(). - // So we can use index merge's row count as DataSource's row count. - if needPrune { - ds.possibleAccessPaths = ds.possibleAccessPaths[regularPathCount:] - minRowCount := ds.possibleAccessPaths[0].CountAfterAccess - for _, path := range ds.possibleAccessPaths { - if minRowCount < path.CountAfterAccess { - minRowCount = path.CountAfterAccess - } - } - if ds.stats.RowCount > minRowCount { - ds.stats = ds.tableStats.ScaleByExpectCnt(minRowCount) - } - } - return nil -} - // DeriveStats implements LogicalPlan DeriveStats interface. func (ts *LogicalTableScan) DeriveStats(_ []*property.StatsInfo, _ *expression.Schema, _ []*expression.Schema, _ [][]*expression.Column) (_ *property.StatsInfo, err error) { ts.Source.initStats(nil) @@ -550,210 +467,6 @@ func (is *LogicalIndexScan) DeriveStats(_ []*property.StatsInfo, selfSchema *exp return is.stats, nil } -// getIndexMergeOrPath generates all possible IndexMergeOrPaths. -func (ds *DataSource) generateIndexMergeOrPaths(filters []expression.Expression) error { - usedIndexCount := len(ds.possibleAccessPaths) - for i, cond := range filters { - sf, ok := cond.(*expression.ScalarFunction) - if !ok || sf.FuncName.L != ast.LogicOr { - continue - } - var partialPaths = make([]*util.AccessPath, 0, usedIndexCount) - dnfItems := expression.FlattenDNFConditions(sf) - for _, item := range dnfItems { - cnfItems := expression.SplitCNFItems(item) - itemPaths := ds.accessPathsForConds(cnfItems, usedIndexCount) - if len(itemPaths) == 0 { - partialPaths = nil - break - } - partialPath, err := ds.buildIndexMergePartialPath(itemPaths) - if err != nil { - return err - } - if partialPath == nil { - partialPaths = nil - break - } - partialPaths = append(partialPaths, partialPath) - } - // If all of the partialPaths use the same index, we will not use the indexMerge. - singlePath := true - for i := len(partialPaths) - 1; i >= 1; i-- { - if partialPaths[i].Index != partialPaths[i-1].Index { - singlePath = false - break - } - } - if singlePath { - continue - } - if len(partialPaths) > 1 { - possiblePath := ds.buildIndexMergeOrPath(filters, partialPaths, i) - if possiblePath == nil { - return nil - } - - accessConds := make([]expression.Expression, 0, len(partialPaths)) - for _, p := range partialPaths { - indexCondsForP := p.AccessConds[:] - indexCondsForP = append(indexCondsForP, p.IndexFilters...) - if len(indexCondsForP) > 0 { - accessConds = append(accessConds, expression.ComposeCNFCondition(ds.ctx, indexCondsForP...)) - } - } - accessDNF := expression.ComposeDNFCondition(ds.ctx, accessConds...) - sel, _, err := ds.tableStats.HistColl.Selectivity(ds.ctx, []expression.Expression{accessDNF}, nil) - if err != nil { - logutil.BgLogger().Debug("something wrong happened, use the default selectivity", zap.Error(err)) - sel = SelectionFactor - } - possiblePath.CountAfterAccess = sel * ds.tableStats.RowCount - ds.possibleAccessPaths = append(ds.possibleAccessPaths, possiblePath) - } - } - return nil -} - -// isInIndexMergeHints checks whether current index or primary key is in IndexMerge hints. -func (ds *DataSource) isInIndexMergeHints(name string) bool { - if len(ds.indexMergeHints) == 0 { - return true - } - for _, hint := range ds.indexMergeHints { - if hint.indexHint == nil || len(hint.indexHint.IndexNames) == 0 { - return true - } - for _, hintName := range hint.indexHint.IndexNames { - if strings.EqualFold(strings.ToLower(name), strings.ToLower(hintName.String())) { - return true - } - } - } - return false -} - -// accessPathsForConds generates all possible index paths for conditions. -func (ds *DataSource) accessPathsForConds(conditions []expression.Expression, usedIndexCount int) []*util.AccessPath { - var results = make([]*util.AccessPath, 0, usedIndexCount) - for i := 0; i < usedIndexCount; i++ { - path := &util.AccessPath{} - if ds.possibleAccessPaths[i].IsTablePath() { - if !ds.isInIndexMergeHints("primary") { - continue - } - if ds.tableInfo.IsCommonHandle { - path.IsCommonHandlePath = true - path.Index = ds.possibleAccessPaths[i].Index - } else { - path.IsIntHandlePath = true - } - err := ds.deriveTablePathStats(path, conditions, true) - if err != nil { - logutil.BgLogger().Debug("can not derive statistics of a path", zap.Error(err)) - continue - } - var unsignedIntHandle bool - if path.IsIntHandlePath && ds.tableInfo.PKIsHandle { - if pkColInfo := ds.tableInfo.GetPkColInfo(); pkColInfo != nil { - unsignedIntHandle = mysql.HasUnsignedFlag(pkColInfo.GetFlag()) - } - } - // If the path contains a full range, ignore it. - if ranger.HasFullRange(path.Ranges, unsignedIntHandle) { - continue - } - // If we have point or empty range, just remove other possible paths. - if len(path.Ranges) == 0 || path.OnlyPointRange(ds.SCtx()) { - if len(results) == 0 { - results = append(results, path) - } else { - results[0] = path - results = results[:1] - } - break - } - } else { - path.Index = ds.possibleAccessPaths[i].Index - if !ds.isInIndexMergeHints(path.Index.Name.L) { - continue - } - err := ds.fillIndexPath(path, conditions) - if err != nil { - logutil.BgLogger().Debug("can not derive statistics of a path", zap.Error(err)) - continue - } - ds.deriveIndexPathStats(path, conditions, true) - // If the path contains a full range, ignore it. - if ranger.HasFullRange(path.Ranges, false) { - continue - } - // If we have empty range, or point range on unique index, just remove other possible paths. - if len(path.Ranges) == 0 || (path.OnlyPointRange(ds.SCtx()) && path.Index.Unique) { - if len(results) == 0 { - results = append(results, path) - } else { - results[0] = path - results = results[:1] - } - break - } - } - results = append(results, path) - } - return results -} - -// buildIndexMergePartialPath chooses the best index path from all possible paths. -// Now we choose the index with minimal estimate row count. -func (ds *DataSource) buildIndexMergePartialPath(indexAccessPaths []*util.AccessPath) (*util.AccessPath, error) { - if len(indexAccessPaths) == 1 { - return indexAccessPaths[0], nil - } - - minEstRowIndex := 0 - minEstRow := math.MaxFloat64 - for i := 0; i < len(indexAccessPaths); i++ { - rc := indexAccessPaths[i].CountAfterAccess - if len(indexAccessPaths[i].IndexFilters) > 0 { - rc = indexAccessPaths[i].CountAfterIndex - } - if rc < minEstRow { - minEstRowIndex = i - minEstRow = rc - } - } - return indexAccessPaths[minEstRowIndex], nil -} - -// buildIndexMergeOrPath generates one possible IndexMergePath. -func (ds *DataSource) buildIndexMergeOrPath(filters []expression.Expression, partialPaths []*util.AccessPath, current int) *util.AccessPath { - indexMergePath := &util.AccessPath{PartialIndexPaths: partialPaths} - indexMergePath.TableFilters = append(indexMergePath.TableFilters, filters[:current]...) - indexMergePath.TableFilters = append(indexMergePath.TableFilters, filters[current+1:]...) - var addCurrentFilter bool - for _, path := range partialPaths { - // If any partial path contains table filters, we need to keep the whole DNF filter in the Selection. - if len(path.TableFilters) > 0 { - addCurrentFilter = true - } - // If any partial path's index filter cannot be pushed to TiKV, we should keep the whole DNF filter. - if len(path.IndexFilters) != 0 && !expression.CanExprsPushDown(ds.ctx.GetSessionVars().StmtCtx, path.IndexFilters, ds.ctx.GetClient(), kv.TiKV) { - addCurrentFilter = true - // Clear IndexFilter, the whole filter will be put in indexMergePath.TableFilters. - path.IndexFilters = nil - } - if len(path.TableFilters) != 0 && !expression.CanExprsPushDown(ds.ctx.GetSessionVars().StmtCtx, path.TableFilters, ds.ctx.GetClient(), kv.TiKV) { - addCurrentFilter = true - path.TableFilters = nil - } - } - if addCurrentFilter { - indexMergePath.TableFilters = append(indexMergePath.TableFilters, filters[current]) - } - return indexMergePath -} - // DeriveStats implement LogicalPlan DeriveStats interface. func (p *LogicalSelection) DeriveStats(childStats []*property.StatsInfo, _ *expression.Schema, _ []*expression.Schema, _ [][]*expression.Column) (*property.StatsInfo, error) { if p.stats != nil { diff --git a/planner/core/stats_test.go b/planner/core/stats_test.go index a301b42f48ff3..2948c90abb4df 100644 --- a/planner/core/stats_test.go +++ b/planner/core/stats_test.go @@ -55,7 +55,7 @@ func TestGroupNDVs(t *testing.T) { stmt, err := p.ParseOneStmt(tt, "", "") require.NoError(t, err, comment) ret := &core.PreprocessorReturn{} - err = core.Preprocess(tk.Session(), stmt, core.WithPreprocessorReturn(ret)) + err = core.Preprocess(context.Background(), tk.Session(), stmt, core.WithPreprocessorReturn(ret)) require.NoError(t, err) tk.Session().GetSessionVars().PlanColumnID = 0 builder, _ := core.NewPlanBuilder().Init(tk.Session(), ret.InfoSchema, &hint.BlockHintProcessor{}) @@ -123,6 +123,7 @@ func TestNDVGroupCols(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t1, t2") tk.MustExec("create table t1(a int not null, b int not null, key(a,b))") tk.MustExec("insert into t1 values(1,1),(1,2),(2,1),(2,2)") diff --git a/planner/core/task.go b/planner/core/task.go index 7b35c1bbae19c..5d7ca6e5fd424 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -24,11 +24,13 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/charset" + "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/planner/property" "github.com/pingcap/tidb/planner/util" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" @@ -36,6 +38,7 @@ import ( "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/paging" "github.com/pingcap/tidb/util/plancodec" + "github.com/pingcap/tidb/util/size" "github.com/pingcap/tipb/go-tipb" "go.uber.org/zap" ) @@ -54,6 +57,7 @@ type task interface { plan() PhysicalPlan invalid() bool convertToRootTask(ctx sessionctx.Context) *rootTask + MemoryUsage() int64 } // copTask is a task that runs in a distributed kv store. @@ -78,8 +82,12 @@ type copTask struct { tblColHists *statistics.HistColl // tblCols stores the original columns of DataSource before being pruned, it // is used to compute average row width when computing scan cost. - tblCols []*expression.Column - idxMergePartPlans []PhysicalPlan + tblCols []*expression.Column + + idxMergePartPlans []PhysicalPlan + idxMergeIsIntersection bool + idxMergeAccessMVIndex bool + // rootTaskConds stores select conditions containing virtual columns. // These conditions can't push to TiKV, so we have to add a selection for rootTask rootTaskConds []expression.Expression @@ -173,6 +181,42 @@ func (t *copTask) getStoreType() kv.StoreType { return kv.TiKV } +// MemoryUsage return the memory usage of copTask +func (t *copTask) MemoryUsage() (sum int64) { + if t == nil { + return + } + + sum = size.SizeOfInterface*(2+int64(cap(t.idxMergePartPlans)+cap(t.rootTaskConds))) + size.SizeOfBool*3 + size.SizeOfUint64 + + size.SizeOfPointer*(3+int64(cap(t.commonHandleCols)+cap(t.tblCols))) + size.SizeOfSlice*4 + t.partitionInfo.MemoryUsage() + if t.indexPlan != nil { + sum += t.indexPlan.MemoryUsage() + } + if t.tablePlan != nil { + sum += t.tablePlan.MemoryUsage() + } + if t.originSchema != nil { + sum += t.originSchema.MemoryUsage() + } + if t.extraHandleCol != nil { + sum += t.extraHandleCol.MemoryUsage() + } + + for _, col := range t.commonHandleCols { + sum += col.MemoryUsage() + } + for _, col := range t.tblCols { + sum += col.MemoryUsage() + } + for _, p := range t.idxMergePartPlans { + sum += p.MemoryUsage() + } + for _, expr := range t.rootTaskConds { + sum += expr.MemoryUsage() + } + return +} + func (p *basePhysicalPlan) attach2Task(tasks ...task) task { t := tasks[0].convertToRootTask(p.ctx) return attachPlan2Task(p.self, t) @@ -259,12 +303,11 @@ func (p *PhysicalIndexJoin) attach2Task(tasks ...task) task { return t } -func getAvgRowSize(stats *property.StatsInfo, schema *expression.Schema) (size float64) { +func getAvgRowSize(stats *property.StatsInfo, cols []*expression.Column) (size float64) { if stats.HistColl != nil { - size = stats.HistColl.GetAvgRowSizeListInDisk(schema.Columns) + size = stats.HistColl.GetAvgRowSizeListInDisk(cols) } else { // Estimate using just the type info. - cols := schema.Columns for _, col := range cols { size += float64(chunk.EstimateTypeWidth(col.GetType())) } @@ -643,8 +686,10 @@ func (t *copTask) convertToRootTaskImpl(ctx sessionctx.Context) *rootTask { newTask := &rootTask{} if t.idxMergePartPlans != nil { p := PhysicalIndexMergeReader{ - partialPlans: t.idxMergePartPlans, - tablePlan: t.tablePlan, + partialPlans: t.idxMergePartPlans, + tablePlan: t.tablePlan, + IsIntersectionType: t.idxMergeIsIntersection, + AccessMVIndex: t.idxMergeAccessMVIndex, }.Init(ctx, t.idxMergePartPlans[0].SelectBlockOffset()) p.PartitionInfo = t.partitionInfo setTableScanToTableRowIDScan(p.tablePlan) @@ -757,6 +802,19 @@ func (t *rootTask) plan() PhysicalPlan { return t.p } +// MemoryUsage return the memory usage of rootTask +func (t *rootTask) MemoryUsage() (sum int64) { + if t == nil { + return + } + + sum = size.SizeOfInterface + size.SizeOfBool + if t.p != nil { + sum += t.p.MemoryUsage() + } + return sum +} + func (p *PhysicalLimit) attach2Task(tasks ...task) task { t := tasks[0].copy() sunk := false @@ -905,6 +963,10 @@ func (p *PhysicalTopN) attach2Task(tasks ...task) task { } needPushDown := len(cols) > 0 if copTask, ok := t.(*copTask); ok && needPushDown && p.canPushDown(copTask.getStoreType()) && len(copTask.rootTaskConds) == 0 { + newTask, changed := p.pushTopNDownToDynamicPartition(copTask) + if changed { + return newTask + } // If all columns in topN are from index plan, we push it to index plan, otherwise we finish the index plan and // push it to table plan. var pushedDownTopN *PhysicalTopN @@ -924,6 +986,139 @@ func (p *PhysicalTopN) attach2Task(tasks ...task) task { return attachPlan2Task(p, rootTask) } +// pushTopNDownToDynamicPartition is a temp solution for partition table. It actually does the same thing as DataSource's isMatchProp. +// We need to support a more enhanced read strategy in the execution phase. So that we can achieve Limit(TiDB)->Reader(TiDB)->Limit(TiKV/TiFlash)->Scan(TiKV/TiFlash). +// Before that is done, we use this logic to provide a way to keep the order property when reading from TiKV, so that we can use the orderliness of index to speed up the query. +// Here we can change the execution plan to TopN(TiDB)->Reader(TiDB)->Limit(TiKV)->Scan(TiKV).(TiFlash is not supported). +func (p *PhysicalTopN) pushTopNDownToDynamicPartition(copTsk *copTask) (task, bool) { + if copTsk.getStoreType() != kv.TiKV { + return nil, false + } + copTsk = copTsk.copy().(*copTask) + if len(copTsk.rootTaskConds) > 0 { + return nil, false + } + colsProp, ok := GetPropByOrderByItems(p.ByItems) + if !ok { + return nil, false + } + allSameOrder, isDesc := colsProp.AllSameOrder() + if !allSameOrder { + return nil, false + } + checkIndexMatchProp := func(idxCols []*expression.Column, idxColLens []int, constColsByCond []bool, colsProp *property.PhysicalProperty) bool { + // If the number of the by-items is bigger than the index columns. We cannot push down since it must not keep order. + if len(idxCols) < len(colsProp.SortItems) { + return false + } + idxPos := 0 + for _, byItem := range colsProp.SortItems { + found := false + for ; idxPos < len(idxCols); idxPos++ { + if idxColLens[idxPos] == types.UnspecifiedLength && idxCols[idxPos].Equal(p.SCtx(), byItem.Col) { + found = true + idxPos++ + break + } + if len(constColsByCond) == 0 || idxPos > len(constColsByCond) || !constColsByCond[idxPos] { + found = false + break + } + } + if !found { + return false + } + } + return true + } + var ( + idxScan *PhysicalIndexScan + tblScan *PhysicalTableScan + tblInfo *model.TableInfo + err error + ) + if copTsk.indexPlan != nil { + copTsk.indexPlan, err = copTsk.indexPlan.Clone() + if err != nil { + return nil, false + } + finalIdxScanPlan := copTsk.indexPlan + for len(finalIdxScanPlan.Children()) > 0 && finalIdxScanPlan.Children()[0] != nil { + finalIdxScanPlan = finalIdxScanPlan.Children()[0] + } + idxScan = finalIdxScanPlan.(*PhysicalIndexScan) + tblInfo = idxScan.Table + } + if copTsk.tablePlan != nil { + copTsk.tablePlan, err = copTsk.tablePlan.Clone() + if err != nil { + return nil, false + } + finalTblScanPlan := copTsk.tablePlan + for len(finalTblScanPlan.Children()) > 0 { + finalTblScanPlan = finalTblScanPlan.Children()[0] + } + tblScan = finalTblScanPlan.(*PhysicalTableScan) + tblInfo = tblScan.Table + } + + pi := tblInfo.GetPartitionInfo() + if pi == nil { + return nil, false + } + + if !copTsk.indexPlanFinished { + // If indexPlan side isn't finished, there's no selection on the table side. + + propMatched := checkIndexMatchProp(idxScan.IdxCols, idxScan.IdxColLens, idxScan.constColsByCond, colsProp) + if !propMatched { + return nil, false + } + idxScan.Desc = isDesc + childProfile := copTsk.plan().statsInfo() + newCount := p.Offset + p.Count + stats := deriveLimitStats(childProfile, float64(newCount)) + pushedLimit := PhysicalLimit{ + Count: newCount, + }.Init(p.SCtx(), stats, p.SelectBlockOffset()) + pushedLimit.SetSchema(copTsk.indexPlan.Schema()) + copTsk = attachPlan2Task(pushedLimit, copTsk).(*copTask) + } else if copTsk.indexPlan == nil { + if tblScan.HandleCols == nil { + return nil, false + } + + if tblScan.HandleCols.IsInt() { + pk := tblScan.HandleCols.GetCol(0) + if len(colsProp.SortItems) != 1 || !colsProp.SortItems[0].Col.Equal(p.SCtx(), pk) { + return nil, false + } + } else { + idxCols, idxColLens := expression.IndexInfo2PrefixCols(tblScan.Columns, tblScan.Schema().Columns, tables.FindPrimaryIndex(tblScan.Table)) + matched := checkIndexMatchProp(idxCols, idxColLens, nil, colsProp) + if !matched { + return nil, false + } + } + tblScan.Desc = isDesc + // SplitRangesAcrossInt64Boundary needs the KeepOrder flag. See that func and the struct tableResultHandler for more details. + tblScan.KeepOrder = true + childProfile := copTsk.plan().statsInfo() + newCount := p.Offset + p.Count + stats := deriveLimitStats(childProfile, float64(newCount)) + pushedLimit := PhysicalLimit{ + Count: newCount, + }.Init(p.SCtx(), stats, p.SelectBlockOffset()) + pushedLimit.SetSchema(copTsk.tablePlan.Schema()) + copTsk = attachPlan2Task(pushedLimit, copTsk).(*copTask) + } else { + return nil, false + } + + rootTask := copTsk.convertToRootTask(p.ctx) + return attachPlan2Task(p, rootTask), true +} + func (p *PhysicalProjection) attach2Task(tasks ...task) task { t := tasks[0].copy() if cop, ok := t.(*copTask); ok { @@ -1044,12 +1239,17 @@ func CheckAggCanPushCop(sctx sessionctx.Context, aggFuncs []*aggregation.AggFunc ret = false } - if !ret && sc.InExplainStmt { + if !ret { storageName := storeType.Name() if storeType == kv.UnSpecified { storageName = "storage layer" } - sc.AppendWarning(errors.New("Aggregation can not be pushed to " + storageName + " because " + reason)) + warnErr := errors.New("Aggregation can not be pushed to " + storageName + " because " + reason) + if sc.InExplainStmt { + sc.AppendWarning(warnErr) + } else { + sc.AppendExtraWarning(warnErr) + } } return ret } @@ -1548,8 +1748,12 @@ func (p *PhysicalStreamAgg) attach2Task(tasks ...task) task { t = cop.convertToRootTask(p.ctx) attachPlan2Task(p, t) } else { - copTaskType := cop.getStoreType() - partialAgg, finalAgg := p.newPartialAggregate(copTaskType, false) + storeType := cop.getStoreType() + // TiFlash doesn't support Stream Aggregation + if storeType == kv.TiFlash && len(p.GroupByItems) > 0 { + return invalidTask + } + partialAgg, finalAgg := p.newPartialAggregate(storeType, false) if partialAgg != nil { if cop.tablePlan != nil { cop.finishIndexPlan() @@ -1864,6 +2068,19 @@ type mppTask struct { partTp property.MPPPartitionType hashCols []*property.MPPPartitionColumn + + // rootTaskConds record filters of TableScan that cannot be pushed down to TiFlash. + + // For logical plan like: HashAgg -> Selection -> TableScan, if filters in Selection cannot be pushed to TiFlash. + // Planner will generate physical plan like: PhysicalHashAgg -> PhysicalSelection -> TableReader -> PhysicalTableScan(cop tiflash) + // Because planner will make mppTask invalid directly then use copTask directly. + + // But in DisaggregatedTiFlash mode, cop and batchCop protocol is disabled, so we have to consider this situation for mppTask. + // When generating PhysicalTableScan, if prop.TaskTp is RootTaskType, mppTask will be converted to rootTask, + // and filters in rootTaskConds will be added in a Selection which will be executed in TiDB. + // So physical plan be like: PhysicalHashAgg -> PhysicalSelection -> TableReader -> ExchangeSender -> PhysicalTableScan(mpp tiflash) + rootTaskConds []expression.Expression + tblColHists *statistics.HistColl } func (t *mppTask) count() float64 { @@ -1887,6 +2104,19 @@ func (t *mppTask) convertToRootTask(ctx sessionctx.Context) *rootTask { return t.copy().(*mppTask).convertToRootTaskImpl(ctx) } +// MemoryUsage return the memory usage of mppTask +func (t *mppTask) MemoryUsage() (sum int64) { + if t == nil { + return + } + + sum = size.SizeOfInterface + size.SizeOfInt + size.SizeOfSlice + int64(cap(t.hashCols))*size.SizeOfPointer + if t.p != nil { + sum += t.p.MemoryUsage() + } + return +} + func collectPartitionInfosFromMPPPlan(p *PhysicalTableReader, mppPlan PhysicalPlan) { switch x := mppPlan.(type) { case *PhysicalTableScan: @@ -1930,6 +2160,32 @@ func (t *mppTask) convertToRootTaskImpl(ctx sessionctx.Context) *rootTask { rt := &rootTask{ p: p, } + + if len(t.rootTaskConds) > 0 { + // Some Filter cannot be pushed down to TiFlash, need to add Selection in rootTask, + // so this Selection will be executed in TiDB. + _, isTableScan := t.p.(*PhysicalTableScan) + _, isSelection := t.p.(*PhysicalSelection) + if isSelection { + _, isTableScan = t.p.Children()[0].(*PhysicalTableScan) + } + if !isTableScan { + // Need to make sure oriTaskPlan is TableScan, because rootTaskConds is part of TableScan.FilterCondition. + // It's only for TableScan. This is ensured by converting mppTask to rootTask just after TableScan is built, + // so no other operators are added into this mppTask. + logutil.BgLogger().Error("expect Selection or TableScan for mppTask.p", zap.String("mppTask.p", t.p.TP())) + return invalidTask + } + selectivity, _, err := t.tblColHists.Selectivity(ctx, t.rootTaskConds, nil) + if err != nil { + logutil.BgLogger().Debug("calculate selectivity failed, use selection factor", zap.Error(err)) + selectivity = SelectionFactor + } + sel := PhysicalSelection{Conditions: t.rootTaskConds}.Init(ctx, rt.p.statsInfo().Scale(selectivity), rt.p.SelectBlockOffset()) + sel.fromDataSource = true + sel.SetChildren(rt.p) + rt.p = sel + } return rt } diff --git a/planner/core/testdata/analyze_suite_out.json b/planner/core/testdata/analyze_suite_out.json index 74d7201f50c06..ea1e33b3ca0b8 100644 --- a/planner/core/testdata/analyze_suite_out.json +++ b/planner/core/testdata/analyze_suite_out.json @@ -160,13 +160,13 @@ ], "Plan": [ "Limit 1.00 root offset:0, count:1", - "└─IndexJoin 1.00 root left outer semi join, inner:IndexReader, outer key:test.t.a, inner key:test.t.b, equal cond:eq(test.t.a, test.t.b)", - " ├─TopN(Build) 1.00 root test.t.a, offset:0, count:1", - " │ └─IndexReader 1.00 root index:TopN", - " │ └─TopN 1.00 cop[tikv] test.t.a, offset:0, count:1", - " │ └─IndexRangeScan 6.00 cop[tikv] table:t1, index:idx_bc(b, c) range:[-inf,6], keep order:false", - " └─IndexReader(Probe) 1.04 root index:IndexRangeScan", - " └─IndexRangeScan 1.04 cop[tikv] table:t2, index:idx_bc(b, c) range: decided by [eq(test.t.b, test.t.a)], keep order:false" + "└─MergeJoin 1.00 root left outer semi join, left key:test.t.a, right key:test.t.b", + " ├─IndexReader(Build) 25.00 root index:IndexFullScan", + " │ └─IndexFullScan 25.00 cop[tikv] table:t2, index:idx_bc(b, c) keep order:true", + " └─TopN(Probe) 1.00 root test.t.a, offset:0, count:1", + " └─IndexReader 1.00 root index:TopN", + " └─TopN 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─IndexRangeScan 6.00 cop[tikv] table:t1, index:idx_bc(b, c) range:[-inf,6], keep order:false" ] }, { @@ -259,9 +259,9 @@ "├─TableReader(Build) 9980.01 root data:Selection", "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.c))", "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.c))", - " └─IndexRangeScan 1.25 cop[tikv] table:t2, index:idx(a, b, c) range: decided by [eq(test.t2.a, test.t1.a) gt(test.t2.b, minus(test.t1.b, 1)) lt(test.t2.b, plus(test.t1.b, 1))], keep order:false, stats:pseudo" + "└─IndexReader(Probe) 12475.01 root index:Selection", + " └─Selection 12475.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.c))", + " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:idx(a, b, c) range: decided by [eq(test.t2.a, test.t1.a) gt(test.t2.b, minus(test.t1.b, 1)) lt(test.t2.b, plus(test.t1.b, 1))], keep order:false, stats:pseudo" ] }, { @@ -272,12 +272,12 @@ "Plan": [ "Projection 0.00 root test.t.a, test.t.b, test.t.a, test.t.b", "└─HashJoin 0.00 root inner join, equal:[eq(test.t.b, test.t.b)]", - " ├─TableReader(Build) 0.00 root data:Selection", + " ├─IndexReader(Build) 0.00 root index:Selection", " │ └─Selection 0.00 cop[tikv] isnull(test.t.b), not(isnull(test.t.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root data:Selection", + " │ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_ab(a, b) keep order:false, stats:pseudo", + " └─IndexReader(Probe) 9990.00 root index:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_ab(a, b) keep order:false, stats:pseudo" ] } ] @@ -381,27 +381,27 @@ [ "Projection 10.00 root Column#22", "└─Apply 10.00 root CARTESIAN left outer semi join, other cond:eq(test.t.c, Column#21)", - " ├─TableReader(Build) 10.00 root data:TableFullScan", - " │ └─TableFullScan 10.00 cop[tikv] table:t keep order:false", - " └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#21", - " └─HashJoin 1.00 root inner join, equal:[eq(test.t.a, test.t.a)]", - " ├─TableReader(Build) 1.00 root data:Selection", - " │ └─Selection 1.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a))", - " │ └─TableFullScan 10.00 cop[tikv] table:t1 keep order:false", - " └─TableReader(Probe) 1.00 root data:Selection", - " └─Selection 1.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a))", - " └─TableFullScan 10.00 cop[tikv] table:s keep order:false" + " ├─IndexReader(Build) 10.00 root index:IndexFullScan", + " │ └─IndexFullScan 10.00 cop[tikv] table:t, index:idx(c, b, a) keep order:false", + " └─StreamAgg(Probe) 10.00 root funcs:count(1)->Column#21", + " └─HashJoin 10.00 root inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─IndexReader(Build) 10.00 root index:Selection", + " │ └─Selection 10.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a))", + " │ └─IndexFullScan 100.00 cop[tikv] table:t1, index:idx(c, b, a) keep order:false", + " └─IndexReader(Probe) 10.00 root index:Selection", + " └─Selection 10.00 cop[tikv] eq(test.t.a, test.t.a), not(isnull(test.t.a))", + " └─IndexFullScan 100.00 cop[tikv] table:s, index:idx(c, b, a) keep order:false" ], [ "Projection 10.00 root Column#13", "└─Apply 10.00 root CARTESIAN left outer join", - " ├─TableReader(Build) 10.00 root data:TableFullScan", - " │ └─TableFullScan 10.00 cop[tikv] table:t keep order:false", - " └─MaxOneRow(Probe) 1.00 root ", - " └─Projection 0.10 root concat(cast(test.t.a, var_string(20)), ,, cast(test.t.b, var_string(20)))->Column#13", - " └─IndexReader 0.10 root index:Selection", - " └─Selection 0.10 cop[tikv] eq(test.t.a, test.t.a)", - " └─IndexRangeScan 1.00 cop[tikv] table:t1, index:idx(c, b, a) range: decided by [eq(test.t.c, test.t.c)], keep order:false" + " ├─IndexReader(Build) 10.00 root index:IndexFullScan", + " │ └─IndexFullScan 10.00 cop[tikv] table:t, index:idx(c, b, a) keep order:false", + " └─MaxOneRow(Probe) 10.00 root ", + " └─Projection 1.00 root concat(cast(test.t.a, var_string(20)), ,, cast(test.t.b, var_string(20)))->Column#13", + " └─IndexReader 1.00 root index:Selection", + " └─Selection 1.00 cop[tikv] eq(test.t.a, test.t.a)", + " └─IndexRangeScan 10.00 cop[tikv] table:t1, index:idx(c, b, a) range: decided by [eq(test.t.c, test.t.c)], keep order:false" ] ] }, @@ -414,9 +414,9 @@ "StreamAgg 1.00 root funcs:max(test.t.e)->Column#7", "└─TopN 0.00 root test.t.e:desc, offset:0, count:1", " └─IndexLookUp 0.00 root ", - " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, c) range:[\"T3382\" \"TOPIC\",\"T3382\" \"TOPIC\"], keep order:false", - " └─Selection(Probe) 0.00 cop[tikv] eq(test.t.b, \"ECO\"), eq(test.t.d, \"23660fa1ace9455cb7f3ee831e14a342\"), not(isnull(test.t.e))", - " └─TableRowIDScan 0.00 cop[tikv] table:t keep order:false" + " ├─IndexRangeScan(Build) 0.01 cop[tikv] table:t, index:idx1(d, a) range:[\"23660fa1ace9455cb7f3ee831e14a342\" \"T3382\",\"23660fa1ace9455cb7f3ee831e14a342\" \"T3382\"], keep order:false", + " └─Selection(Probe) 0.00 cop[tikv] eq(test.t.b, \"ECO\"), eq(test.t.c, \"TOPIC\"), not(isnull(test.t.e))", + " └─TableRowIDScan 0.01 cop[tikv] table:t keep order:false" ] } ] @@ -425,7 +425,7 @@ "Name": "TestEmptyTable", "Cases": [ "TableReader(Table(t)->Sel([le(test.t.c1, 50)]))", - "LeftHashJoin{TableReader(Table(t)->Sel([not(isnull(test.t.c1))]))->TableReader(Table(t1)->Sel([not(isnull(test.t1.c1))]))->HashAgg}(test.t.c1,test.t1.c1)", + "LeftHashJoin{TableReader(Table(t)->Sel([not(isnull(test.t.c1))]))->TableReader(Table(t1)->Sel([not(isnull(test.t1.c1))])->HashAgg)->HashAgg}(test.t.c1,test.t1.c1)", "LeftHashJoin{TableReader(Table(t)->Sel([not(isnull(test.t.c1))]))->TableReader(Table(t1)->Sel([not(isnull(test.t1.c1))]))}(test.t.c1,test.t1.c1)", "Dual" ] @@ -433,23 +433,23 @@ { "Name": "TestIndexRead", "Cases": [ - "IndexReader(Index(t.e)[[NULL,+inf]])->HashAgg", + "IndexReader(Index(t.e)[[NULL,+inf]]->StreamAgg)->StreamAgg", "IndexReader(Index(t.e)[[-inf,10]]->StreamAgg)->StreamAgg", "IndexReader(Index(t.e)[[-inf,50]]->StreamAgg)->StreamAgg", - "IndexReader(Index(t.b_c)[[NULL,+inf]]->Sel([gt(test.t.c, 1)])->HashAgg)->HashAgg", + "IndexReader(Index(t.b_c)[[NULL,+inf]]->Sel([gt(test.t.c, 1)])->StreamAgg)->StreamAgg", "IndexLookUp(Index(t.e)[[1,1]], Table(t))->HashAgg", "TableReader(Table(t)->Sel([gt(test.t.e, 1)])->HashAgg)->HashAgg", - "IndexLookUp(Index(t.b)[[-inf,20]], Table(t)->HashAgg)->HashAgg", - "TableReader(Table(t)->Sel([le(test.t.b, 30)])->StreamAgg)->StreamAgg", - "TableReader(Table(t)->Sel([le(test.t.b, 40)])->StreamAgg)->StreamAgg", - "TableReader(Table(t)->Sel([le(test.t.b, 50)])->StreamAgg)->StreamAgg", - "TableReader(Table(t)->Sel([le(test.t.b, 100000000000)])->StreamAgg)->StreamAgg", + "TableReader(Table(t)->Sel([le(test.t.b, 20)])->HashAgg)->HashAgg", + "TableReader(Table(t)->Sel([le(test.t.b, 30)])->HashAgg)->HashAgg", + "TableReader(Table(t)->Sel([le(test.t.b, 40)])->HashAgg)->HashAgg", + "TableReader(Table(t)->Sel([le(test.t.b, 50)])->HashAgg)->HashAgg", + "TableReader(Table(t)->Sel([le(test.t.b, 100000000000)])->HashAgg)->HashAgg", "TableReader(Table(t)->Sel([le(test.t.b, 40)]))", "TableReader(Table(t)->Sel([le(test.t.b, 50)]))", "TableReader(Table(t)->Sel([le(test.t.b, 10000000000)]))", "TableReader(Table(t)->Sel([le(test.t.b, 50)]))", "TableReader(Table(t)->Sel([le(test.t.b, 100)])->Limit)->Limit", - "IndexLookUp(Index(t.b)[[-inf,1]]->TopN([test.t.a],0,10), Table(t))->TopN([test.t.a],0,10)", + "TableReader(Table(t)->Sel([le(test.t.b, 1)])->Limit)->Limit", "IndexLookUp(Index(t.b)[[1,1]], Table(t))", "IndexLookUp(Index(t.d)[[-inf,1991-09-05 00:00:00)], Table(t))", "IndexLookUp(Index(t.ts)[[-inf,1991-09-05 00:00:00)], Table(t))", @@ -501,10 +501,10 @@ "SQL": "explain format = 'brief' select * from t where a <= 10000 order by b limit 1", "Plan": [ "TopN 1.00 root test.t.b, offset:0, count:1", - "└─IndexLookUp 1.00 root ", - " ├─IndexRangeScan(Build) 10000.00 cop[tikv] table:t, index:idx_a(a) range:[-inf,10000], keep order:false", - " └─TopN(Probe) 1.00 cop[tikv] test.t.b, offset:0, count:1", - " └─TableRowIDScan 10000.00 cop[tikv] table:t keep order:false" + "└─TableReader 1.00 root data:TopN", + " └─TopN 1.00 cop[tikv] test.t.b, offset:0, count:1", + " └─Selection 10000.00 cop[tikv] le(test.t.a, 10000)", + " └─TableFullScan 1000000.00 cop[tikv] table:t keep order:false" ] }, { diff --git a/planner/core/testdata/binary_plan_suite_out.json b/planner/core/testdata/binary_plan_suite_out.json index 3c702871c50ff..a361c5ca0b23f 100644 --- a/planner/core/testdata/binary_plan_suite_out.json +++ b/planner/core/testdata/binary_plan_suite_out.json @@ -46,7 +46,7 @@ "children": [ { "name": "TableFullScan_4", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 2, "task_type": 2, @@ -54,7 +54,7 @@ "operator_info": "keep order:false, stats:pseudo" } ], - "cost": 48834.666666666664, + "cost": 236018.64918623405, "est_rows": 10000, "act_rows": 2, "task_type": 1, @@ -81,7 +81,7 @@ "children": [ { "name": "IndexFullScan_14", - "cost": 435000, + "cost": 1628000, "est_rows": 10000, "act_rows": 2, "task_type": 2, @@ -92,7 +92,7 @@ "labels": [ 2 ], - "cost": 34418, + "cost": 150773.33333333334, "est_rows": 10000, "act_rows": 2, "task_type": 1, @@ -104,7 +104,7 @@ "children": [ { "name": "TableFullScan_16", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 4, "task_type": 2, @@ -115,7 +115,7 @@ "labels": [ 1 ], - "cost": 43418, + "cost": 193778.64918623405, "est_rows": 10000, "act_rows": 4, "task_type": 1, @@ -123,7 +123,7 @@ "operator_info": "data:TableFullScan_16" } ], - "cost": 60107864, + "cost": 976848.9825195674, "est_rows": 100000000, "act_rows": 8, "task_type": 1, @@ -131,7 +131,7 @@ "operator_info": "CARTESIAN inner join" } ], - "cost": 120107882, + "cost": 998976848.9825196, "est_rows": 100000000, "act_rows": 8, "task_type": 1, @@ -139,7 +139,7 @@ "operator_info": "cast(test.t.a, decimal(10,0) BINARY)->Column#8" } ], - "cost": 120107897.001, + "cost": 1996978357.5625196, "est_rows": 1, "act_rows": 1, "task_type": 1, @@ -157,14 +157,14 @@ "children": [ { "name": "IndexRangeScan_5", - "cost": 145000, + "cost": 542666.6666666667, "est_rows": 3333.3333333333335, "task_type": 2, "store_type": 2, "operator_info": "range:(100,+inf], keep order:false, stats:pseudo" } ], - "cost": 11473.555555555557, + "cost": 50257.77777777778, "est_rows": 3333.3333333333335, "task_type": 1, "store_type": 1, @@ -184,7 +184,7 @@ "children": [ { "name": "TableFullScan_5", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 2, "task_type": 2, @@ -192,14 +192,14 @@ "operator_info": "keep order:false, stats:pseudo" } ], - "cost": 600000, + "cost": 2772079.737793511, "est_rows": 3333.3333333333335, "task_type": 2, "store_type": 2, "operator_info": "gt(test.t.a, 100)" } ], - "cost": 41806.88888888889, + "cost": 198885.3158529007, "est_rows": 3333.3333333333335, "task_type": 1, "store_type": 1, @@ -222,7 +222,7 @@ "children": [ { "name": "TableFullScan_35", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 2, "task_type": 2, @@ -230,7 +230,7 @@ "operator_info": "keep order:false, stats:pseudo" } ], - "cost": 600000, + "cost": 2772079.737793511, "est_rows": 9990, "act_rows": 2, "task_type": 2, @@ -241,7 +241,7 @@ "labels": [ 2 ], - "cost": 50823.833333333336, + "cost": 269200.8358529007, "est_rows": 9990, "act_rows": 2, "task_type": 1, @@ -256,7 +256,7 @@ "children": [ { "name": "TableFullScan_32", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 4, "task_type": 2, @@ -264,7 +264,7 @@ "operator_info": "keep order:false, stats:pseudo" } ], - "cost": 600000, + "cost": 2772079.737793511, "est_rows": 9990, "act_rows": 4, "task_type": 2, @@ -275,7 +275,7 @@ "labels": [ 1 ], - "cost": 50823.833333333336, + "cost": 269200.8358529007, "est_rows": 9990, "act_rows": 4, "task_type": 1, @@ -283,7 +283,7 @@ "operator_info": "data:Selection_33" } ], - "cost": 139138.15666666668, + "cost": 1800237.0717058014, "est_rows": 12487.5, "task_type": 1, "store_type": 1, @@ -322,7 +322,7 @@ "labels": [ 3 ], - "cost": 18.6, + "cost": 0.0998, "est_rows": 1, "act_rows": 1, "task_type": 1, @@ -344,7 +344,7 @@ "operator_info": "Scan on CTE_0" } ], - "cost": 3, + "cost": 49.9, "est_rows": 0.8, "act_rows": 4, "task_type": 1, @@ -355,7 +355,7 @@ "labels": [ 4 ], - "cost": 21.48, + "cost": 57.884, "est_rows": 0.8, "act_rows": 4, "task_type": 1, @@ -387,7 +387,7 @@ "children": [ { "name": "TableFullScan_6", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 4, "task_type": 2, @@ -395,14 +395,14 @@ "operator_info": "keep order:false, stats:pseudo" } ], - "cost": 600000, + "cost": 2772079.737793511, "est_rows": 3333.3333333333335, "task_type": 2, "store_type": 2, "operator_info": "gt(test.t2.b, 10)" } ], - "cost": 45418, + "cost": 227045.3158529007, "est_rows": 3333.3333333333335, "task_type": 1, "store_type": 1, @@ -439,7 +439,7 @@ "children": [ { "name": "TableFullScan_6", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 2, "task_type": 2, @@ -447,7 +447,7 @@ "operator_info": "keep order:false, stats:pseudo" } ], - "cost": 48834.666666666664, + "cost": 236018.64918623405, "est_rows": 10000, "act_rows": 2, "task_type": 1, @@ -473,7 +473,7 @@ "children": [ { "name": "TableFullScan_5", - "cost": 570000, + "cost": 2273079.737793511, "est_rows": 10000, "act_rows": 8, "task_type": 2, @@ -481,7 +481,7 @@ "operator_info": "keep order:false, stats:pseudo" } ], - "cost": 54251.333333333336, + "cost": 278258.64918623405, "est_rows": 10000, "act_rows": 8, "task_type": 1, diff --git a/planner/core/testdata/enforce_mpp_suite_out.json b/planner/core/testdata/enforce_mpp_suite_out.json index 146e33f350308..91de0d5bd1348 100644 --- a/planner/core/testdata/enforce_mpp_suite_out.json +++ b/planner/core/testdata/enforce_mpp_suite_out.json @@ -31,31 +31,30 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "StreamAgg_24 1.00 35.88 root funcs:count(Column#6)->Column#4", - "└─IndexReader_25 1.00 32.88 root index:StreamAgg_9", - " └─StreamAgg_9 1.00 465.00 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_23 10.00 435.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_24 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_25 1.00 143.91 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_23 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_17 1.00 35.88 root funcs:count(Column#6)->Column#4", - "└─IndexReader_18 1.00 32.88 root index:StreamAgg_9", - " └─StreamAgg_9 1.00 465.00 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_16 10.00 435.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_17 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_18 1.00 143.91 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_16 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_20 1.00 19006.88 root funcs:count(Column#6)->Column#4", - "└─TableReader_21 1.00 19003.88 root data:StreamAgg_9", - " └─StreamAgg_9 1.00 285030.00 batchCop[tiflash] funcs:count(1)->Column#6", - " └─Selection_19 10.00 285000.00 batchCop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_18 10000.00 255000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_10 1.00 64007.91 root funcs:count(1)->Column#4", + "└─TableReader_24 10.00 63508.91 root data:Selection_23", + " └─Selection_23 10.00 952000.00 cop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_22 10000.00 928000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null }, @@ -72,32 +71,30 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "StreamAgg_31 1.00 35.88 root funcs:count(Column#7)->Column#4", - "└─IndexReader_32 1.00 32.88 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 465.00 cop[tikv] funcs:count(1)->Column#7", - " └─IndexRangeScan_30 10.00 435.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_31 1.00 193.81 root funcs:count(Column#7)->Column#4", + "└─IndexReader_32 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_30 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_19 1.00 35.88 root funcs:count(Column#6)->Column#4", - "└─IndexReader_20 1.00 32.88 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 465.00 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_18 10.00 435.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_19 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_20 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_18 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", "Plan": [ - "HashAgg_22 1.00 11910.73 root funcs:count(Column#6)->Column#4", - "└─TableReader_24 1.00 11877.13 root data:ExchangeSender_23", - " └─ExchangeSender_23 1.00 285030.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg_10 1.00 285030.00 mpp[tiflash] funcs:count(1)->Column#6", - " └─Selection_21 10.00 285000.00 mpp[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_20 10000.00 255000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_12 1.00 64007.91 root funcs:count(1)->Column#4", + "└─TableReader_31 10.00 63508.91 root data:Selection_30", + " └─Selection_30 10.00 952000.00 cop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_29 10000.00 928000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null }, @@ -109,34 +106,30 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "HashAgg_25 1.00 33.89 root funcs:count(Column#6)->Column#4", - "└─TableReader_27 1.00 0.29 root data:ExchangeSender_26", - " └─ExchangeSender_26 1.00 285030.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg_10 1.00 285030.00 mpp[tiflash] funcs:count(1)->Column#6", - " └─Selection_24 10.00 285000.00 mpp[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_23 10000.00 255000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_31 1.00 193.81 root funcs:count(Column#7)->Column#4", + "└─IndexReader_32 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_30 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_19 1.00 35.88 root funcs:count(Column#6)->Column#4", - "└─IndexReader_20 1.00 32.88 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 465.00 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_18 10.00 435.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_19 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_20 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_18 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", "Plan": [ - "HashAgg_22 1.00 33.89 root funcs:count(Column#6)->Column#4", - "└─TableReader_24 1.00 0.29 root data:ExchangeSender_23", - " └─ExchangeSender_23 1.00 285030.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg_10 1.00 285030.00 mpp[tiflash] funcs:count(1)->Column#6", - " └─Selection_21 10.00 285000.00 mpp[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_20 10000.00 255000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_12 1.00 64007.91 root funcs:count(1)->Column#4", + "└─TableReader_31 10.00 63508.91 root data:Selection_30", + " └─Selection_30 10.00 952000.00 cop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_29 10000.00 928000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null }, @@ -148,22 +141,20 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "HashAgg_25 1.00 33.60 root funcs:count(Column#6)->Column#4", - "└─TableReader_27 1.00 0.00 root data:ExchangeSender_26", - " └─ExchangeSender_26 1.00 285030.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg_10 1.00 285030.00 mpp[tiflash] funcs:count(1)->Column#6", - " └─Selection_24 10.00 285000.00 mpp[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_23 10000.00 255000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_31 1.00 193.81 root funcs:count(Column#7)->Column#4", + "└─IndexReader_32 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_30 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_19 1.00 35.88 root funcs:count(Column#6)->Column#4", - "└─IndexReader_20 1.00 32.88 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 465.00 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_18 10.00 435.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_19 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_20 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_18 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": [ "MPP mode may be blocked because you have set a hint to read table `t` from TiKV." @@ -172,12 +163,11 @@ { "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", "Plan": [ - "HashAgg_22 1.00 33.60 root funcs:count(Column#6)->Column#4", - "└─TableReader_24 1.00 0.00 root data:ExchangeSender_23", - " └─ExchangeSender_23 1.00 285030.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg_10 1.00 285030.00 mpp[tiflash] funcs:count(1)->Column#6", - " └─Selection_21 10.00 285000.00 mpp[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_20 10000.00 255000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_27 1.00 49.90 root funcs:count(Column#7)->Column#4", + "└─TableReader_28 1.00 0.00 root data:StreamAgg_11", + " └─StreamAgg_11 1.00 1427024.00 batchCop[tiflash] funcs:count(1)->Column#7", + " └─Selection_26 10.00 1427000.00 batchCop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_25 10000.00 928000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null } @@ -291,9 +281,9 @@ "SQL": "EXPLAIN format = 'brief' SELECT count(b) from t where a=1; -- 7. agg func has virtual column", "Plan": [ "StreamAgg 1.00 root funcs:count(test.t.b)->Column#6", - "└─IndexLookUp 10.00 root ", - " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + "└─TableReader 10.00 root data:Selection", + " └─Selection 10.00 cop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": [ "Aggregation can not be pushed to tiflash because expressions of AggFunc `count` contain virtual column or correlated column, which is not supported now", @@ -338,9 +328,9 @@ "SQL": "EXPLAIN format = 'brief' SELECT count(a) from t where c=1; -- 11. type not supported", "Plan": [ "StreamAgg 1.00 root funcs:count(test.t.a)->Column#6", - "└─Selection 10.00 root eq(test.t.c, 1)", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + "└─TableReader 10.00 root data:Selection", + " └─Selection 10.00 cop[tikv] eq(test.t.c, 1)", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warn": [ "Expression about 'test.t.c' can not be pushed to TiFlash because it contains unsupported calculation of type 'enum'.", @@ -354,9 +344,9 @@ "SQL": "EXPLAIN format = 'brief' SELECT count(a) from t where d=1; -- 11.1. type not supported", "Plan": [ "StreamAgg 1.00 root funcs:count(test.t.a)->Column#6", - "└─Selection 10.00 root eq(test.t.d, 1)", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + "└─TableReader 10.00 root data:Selection", + " └─Selection 10.00 cop[tikv] eq(test.t.d, 1)", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warn": [ "Expression about 'test.t.d' can not be pushed to TiFlash because it contains unsupported calculation of type 'bit'.", @@ -474,8 +464,8 @@ "IndexJoin_15 12500.00 root inner join, inner:TableReader_12, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a)", "├─TableReader_32(Build) 10000.00 root data:TableFullScan_31", "│ └─TableFullScan_31 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", - "└─TableReader_12(Probe) 1.00 root data:TableRangeScan_11", - " └─TableRangeScan_11 1.00 cop[tikv] table:s range: decided by [test.t.a], keep order:false, stats:pseudo" + "└─TableReader_12(Probe) 10000.00 root data:TableRangeScan_11", + " └─TableRangeScan_11 10000.00 cop[tikv] table:s range: decided by [test.t.a], keep order:false, stats:pseudo" ], "Warn": [ "MPP mode may be blocked because you have used hint to specify a join algorithm which is not supported by mpp now.", @@ -488,8 +478,8 @@ "IndexHashJoin_16 12500.00 root inner join, inner:TableReader_11, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a)", "├─TableReader_31(Build) 10000.00 root data:TableFullScan_30", "│ └─TableFullScan_30 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", - "└─TableReader_11(Probe) 1.00 root data:TableRangeScan_10", - " └─TableRangeScan_10 1.00 cop[tikv] table:s range: decided by [test.t.a], keep order:false, stats:pseudo" + "└─TableReader_11(Probe) 10000.00 root data:TableRangeScan_10", + " └─TableRangeScan_10 10000.00 cop[tikv] table:s range: decided by [test.t.a], keep order:false, stats:pseudo" ], "Warn": [ "MPP mode may be blocked because you have used hint to specify a join algorithm which is not supported by mpp now.", @@ -650,13 +640,14 @@ "└─TableReader_35 9990.00 root data:ExchangeSender_34", " └─ExchangeSender_34 9990.00 mpp[tiflash] ExchangeType: PassThrough", " └─HashJoin_14 9990.00 mpp[tiflash] inner join, equal:[eq(test.c.c_id, test.o.c_id)]", - " ├─ExchangeReceiver_26(Build) 8000.00 mpp[tiflash] ", - " │ └─ExchangeSender_25 8000.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Projection_24 8000.00 mpp[tiflash] Column#7, test.o.c_id", - " │ └─HashAgg_19 8000.00 mpp[tiflash] group by:test.o.c_id, funcs:count(1)->Column#7, funcs:firstrow(test.o.c_id)->test.o.c_id", - " │ └─ExchangeReceiver_23 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender_22 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.c_id, collate: binary]", - " │ └─TableFullScan_21 10000.00 mpp[tiflash] table:o keep order:false, stats:pseudo", + " ├─ExchangeReceiver_33(Build) 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender_32 8000.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Projection_28 8000.00 mpp[tiflash] Column#7, test.o.c_id", + " │ └─HashAgg_29 8000.00 mpp[tiflash] group by:test.o.c_id, funcs:sum(Column#8)->Column#7, funcs:firstrow(test.o.c_id)->test.o.c_id", + " │ └─ExchangeReceiver_31 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender_30 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.c_id, collate: binary]", + " │ └─HashAgg_20 8000.00 mpp[tiflash] group by:test.o.c_id, funcs:count(1)->Column#8", + " │ └─TableFullScan_27 10000.00 mpp[tiflash] table:o keep order:false, stats:pseudo", " └─Selection_18(Probe) 9990.00 mpp[tiflash] not(isnull(test.c.c_id))", " └─TableFullScan_17 10000.00 mpp[tiflash] table:c keep order:false, stats:pseudo" ], @@ -673,13 +664,14 @@ " └─ExchangeReceiver_71 9990.00 mpp[tiflash] ", " └─ExchangeSender_70 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.o_id, collate: binary]", " └─HashJoin_69 9990.00 mpp[tiflash] inner join, equal:[eq(test.c.c_id, test.o.c_id)]", - " ├─ExchangeReceiver_27(Build) 8000.00 mpp[tiflash] ", - " │ └─ExchangeSender_26 8000.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Projection_25 8000.00 mpp[tiflash] Column#7, Column#8, test.o.o_id, test.o.c_id", - " │ └─HashAgg_20 8000.00 mpp[tiflash] group by:test.o.c_id, test.o.o_id, funcs:count(1)->Column#7, funcs:firstrow(test.o.o_id)->Column#8, funcs:firstrow(test.o.o_id)->test.o.o_id, funcs:firstrow(test.o.c_id)->test.o.c_id", - " │ └─ExchangeReceiver_24 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender_23 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.o_id, collate: binary], [name: test.o.c_id, collate: binary]", - " │ └─TableFullScan_22 10000.00 mpp[tiflash] table:o keep order:false, stats:pseudo", + " ├─ExchangeReceiver_34(Build) 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender_33 8000.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Projection_29 8000.00 mpp[tiflash] Column#7, Column#8, test.o.o_id, test.o.c_id", + " │ └─HashAgg_30 8000.00 mpp[tiflash] group by:test.o.c_id, test.o.o_id, funcs:sum(Column#9)->Column#7, funcs:firstrow(test.o.o_id)->Column#8, funcs:firstrow(test.o.o_id)->test.o.o_id, funcs:firstrow(test.o.c_id)->test.o.c_id", + " │ └─ExchangeReceiver_32 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender_31 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.o_id, collate: binary], [name: test.o.c_id, collate: binary]", + " │ └─HashAgg_21 8000.00 mpp[tiflash] group by:test.o.c_id, test.o.o_id, funcs:count(1)->Column#9", + " │ └─TableFullScan_28 10000.00 mpp[tiflash] table:o keep order:false, stats:pseudo", " └─Selection_19(Probe) 9990.00 mpp[tiflash] not(isnull(test.c.c_id))", " └─TableFullScan_18 10000.00 mpp[tiflash] table:c keep order:false, stats:pseudo" ], @@ -696,13 +688,14 @@ " └─ExchangeReceiver_71 9990.00 mpp[tiflash] ", " └─ExchangeSender_70 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.c_id, collate: binary]", " └─HashJoin_69 9990.00 mpp[tiflash] inner join, equal:[eq(test.c.c_id, test.o.c_id)]", - " ├─ExchangeReceiver_27(Build) 8000.00 mpp[tiflash] ", - " │ └─ExchangeSender_26 8000.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Projection_25 8000.00 mpp[tiflash] Column#7, Column#8, test.o.c_id", - " │ └─HashAgg_20 8000.00 mpp[tiflash] group by:test.o.c_id, funcs:count(1)->Column#7, funcs:firstrow(test.o.c_id)->Column#8, funcs:firstrow(test.o.c_id)->test.o.c_id", - " │ └─ExchangeReceiver_24 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender_23 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.c_id, collate: binary]", - " │ └─TableFullScan_22 10000.00 mpp[tiflash] table:o keep order:false, stats:pseudo", + " ├─ExchangeReceiver_34(Build) 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender_33 8000.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Projection_29 8000.00 mpp[tiflash] Column#7, Column#8, test.o.c_id", + " │ └─HashAgg_30 8000.00 mpp[tiflash] group by:test.o.c_id, funcs:sum(Column#9)->Column#7, funcs:firstrow(test.o.c_id)->Column#8, funcs:firstrow(test.o.c_id)->test.o.c_id", + " │ └─ExchangeReceiver_32 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender_31 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.o.c_id, collate: binary]", + " │ └─HashAgg_21 8000.00 mpp[tiflash] group by:test.o.c_id, funcs:count(1)->Column#9", + " │ └─TableFullScan_28 10000.00 mpp[tiflash] table:o keep order:false, stats:pseudo", " └─Selection_19(Probe) 9990.00 mpp[tiflash] not(isnull(test.c.c_id))", " └─TableFullScan_18 10000.00 mpp[tiflash] table:c keep order:false, stats:pseudo" ], @@ -1169,10 +1162,10 @@ { "SQL": "EXPLAIN select count(distinct b), json_objectagg(d,c) from t;", "Plan": [ - "StreamAgg_7 1.00 root funcs:count(distinct Column#9)->Column#7, funcs:json_objectagg(Column#10, Column#11)->Column#8", + "HashAgg_6 1.00 root funcs:count(distinct Column#9)->Column#7, funcs:json_objectagg(Column#10, Column#11)->Column#8", "└─Projection_16 10000.00 root test.t.b, cast(test.t.d, var_string(10))->Column#10, test.t.c", - " └─TableReader_15 10000.00 root data:TableFullScan_14", - " └─TableFullScan_14 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + " └─TableReader_11 10000.00 root data:TableFullScan_10", + " └─TableFullScan_10 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": [ "Aggregation can not be pushed to tiflash because AggFunc `json_objectagg` is not supported now", diff --git a/planner/core/testdata/expression_rewriter_suite_out.json b/planner/core/testdata/expression_rewriter_suite_out.json index 3c850e434fc9b..72b86884a1412 100644 --- a/planner/core/testdata/expression_rewriter_suite_out.json +++ b/planner/core/testdata/expression_rewriter_suite_out.json @@ -7,10 +7,9 @@ "Plan": [ "HashJoin 2.25 root inner join, equal:[eq(test.t1.a, test.t2.a) eq(test.t1.b, test.t2.b)]", "├─HashAgg(Build) 1.69 root group by:test.t2.a, test.t2.b, funcs:firstrow(test.t2.a)->test.t2.a, funcs:firstrow(test.t2.b)->test.t2.b", - "│ └─TableReader 1.69 root data:HashAgg", - "│ └─HashAgg 1.69 cop[tikv] group by:test.t2.a, test.t2.b, ", - "│ └─Selection 2.25 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - "│ └─TableFullScan 4.00 cop[tikv] table:t2 keep order:false", + "│ └─TableReader 2.25 root data:Selection", + "│ └─Selection 2.25 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 4.00 cop[tikv] table:t2 keep order:false", "└─TableReader(Probe) 2.25 root data:Selection", " └─Selection 2.25 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", " └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false" @@ -37,10 +36,9 @@ "Plan": [ "HashJoin 1.69 root inner join, equal:[eq(test.t2.a, test.t1.a) eq(test.t2.b, Column#7)]", "├─HashAgg(Build) 1.69 root group by:test.t2.a, test.t2.b, funcs:firstrow(test.t2.a)->test.t2.a, funcs:firstrow(test.t2.b)->test.t2.b", - "│ └─TableReader 1.69 root data:HashAgg", - "│ └─HashAgg 1.69 cop[tikv] group by:test.t2.a, test.t2.b, ", - "│ └─Selection 2.25 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - "│ └─TableFullScan 4.00 cop[tikv] table:t2 keep order:false", + "│ └─TableReader 2.25 root data:Selection", + "│ └─Selection 2.25 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 4.00 cop[tikv] table:t2 keep order:false", "└─HashAgg(Probe) 2.25 root group by:test.t1.a, funcs:count(1)->Column#7, funcs:firstrow(test.t1.a)->test.t1.a", " └─TableReader 3.00 root data:Selection", " └─Selection 3.00 cop[tikv] not(isnull(test.t1.a))", diff --git a/planner/core/testdata/index_merge_suite_in.json b/planner/core/testdata/index_merge_suite_in.json index 55c9c1cca1f7c..22e595e22a8ce 100644 --- a/planner/core/testdata/index_merge_suite_in.json +++ b/planner/core/testdata/index_merge_suite_in.json @@ -1,4 +1,90 @@ [ + { + "name": "TestIndexMergeJSONMemberOf", + "cases": [ + "select /*+ use_index_merge(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))", + "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10", + "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.XXX')) and a<10", + "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10", + "select /*+ use_index(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))", + "select /*+ use_index(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10", + "select * from t use index(j0_0) where (1 member of (j0->'$.path0'))", + "select * from t use index(j0_1) where (1 member of (j0->'$.path1')) and a<10", + "select * from t force index(j0_0) where (1 member of (j0->'$.path0'))", + "select * from t force index(j0_1) where (1 member of (j0->'$.path1')) and a<10", + "select /*+ use_index_merge(t, j1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]')", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]')", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0'))", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]') and a<10", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]') and a<10", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0')) and a<10", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1')", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1')", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0'))", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1') and a<10", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1') and a<10", + "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0')) and a<10", + "select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string'))", + "select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string')) and a<10", + "select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')", + "select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10", + "select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')", + "select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10", + "select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date'))", + "select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date')) and a<10", + "select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))", + "select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10", + "select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))", + "select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10" + ] + }, + { + "name": "TestCompositeMVIndex", + "cases": [ + "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4", + "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j))", + "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2", + "select /*+ use_index_merge(t, idx) */ * from t where a=1", + "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str')) and c=4", + "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str'))", + "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2", + "select /*+ use_index_merge(t, idx2) */ * from t where a=1", + "select /*+ use_index(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4", + "select * from t use index(idx) where a=1 and b=2 and (3 member of (j))", + "select /*+ use_index(t, idx) */ * from t where a=1 and b=2", + "select * from t use index(idx) where a=1", + "select * from t force index(idx) where a=1 and b=2 and (3 member of (j))", + "select * from t force index(idx) where a=1" + ] + }, + { + "name": "TestDNFOnMVIndex", + "cases": [ + "select /*+ use_index_merge(t, idx1) */ * from t where (1 member of (j)) or (2 member of (j))", + "select /*+ use_index_merge(t, idx1) */ * from t where ((1 member of (j)) or (2 member of (j))) and (a > 10)", + "select /*+ use_index_merge(t, idx1) */ * from t where (json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))", + "select /*+ use_index_merge(t, idx1) */ * from t where ((json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))) and (a > 10)", + "select /*+ use_index_merge(t, idx1) */ * from t where (json_contains(j, '[1, 2]')) or (json_contains(j, '[3, 4]'))", + "select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))", + "select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)) and c=14)", + "select /*+ use_index_merge(t, idx2) */ * from t where ((a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))) and (c > 10)" + ] + }, + { + "name": "TestMVIndexSelection", + "cases": [ + "select (j->'$.int') from t where (1 member of (j->'$.int'))", + "select * from t where (1 member of (j->'$.int'))", + "select * from t where (1 member of (j->'$.int')) and a<10", + "select (j->'$.int') from t where json_contains((j->'$.int'), '[1, 2, 3]')", + "select * from t where json_contains((j->'$.int'), '[1, 2, 3]')", + "select * from t where json_contains((j->'$.int'), '[1, 2, 3]') and a<10", + "select (j->'$.int') from t where json_overlaps((j->'$.int'), '[1, 2, 3]')", + "select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]')", + "select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]') and a<10" + ] + }, { "name": "TestIndexMergePathGeneration", "cases": [ @@ -9,5 +95,35 @@ "select * from t where (c < 1 or f > 2) and (c > 5 or f < 7) and (c < 1 or g > 2)", "select * from t where (c < 1 or f > 2) and (c > 5 or f < 7) and (e < 1 or f > 2)" ] + }, + { + "name": "TestHintForIntersectionIndexMerge", + "cases": [ + "set @@tidb_partition_prune_mode = 'dynamic'", + "select * from vh", + "select /*+ qb_name(v, v), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "select /*+ qb_name(v, v@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "select /*+ qb_name(v, v1@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v1 where c < 30 and d in (2,5)", + "select /*+ use_index_merge(t2, ia, ibc, id, ie) */ * from t2 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "select /*+ use_index_merge(t3, ia, ibc, id, ie) */ * from t3 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "select /*+ use_index_merge(t4, ia, ibc, id, ie) */ * from t4 where a > 10 and b = 20 and c < 35 and d in (1,3,8,9) and e = 100", + "select /*+ use_index_merge(t5, is1, is2, is3, is4) */ * from t5 where s1 = 'Abc' and s2 > 'zzz' and s3 < 'B啊a' and s4 = 'CcC'", + "select /*+ use_index_merge(t6, primary, is3, is4) */ * from t6 where s1 = 'Abc' and s2 > 'zzz' and s3 = 'A啊a' and s4 not like 'Cd_'", + "select /*+ use_index_merge(t7, primary,ia,ib,ic,ie,iff,ig) */ * from t7 where a = 100 and b > 5 and c < 12.3 and d > 54.321 and e = '2022-11-22 17:00' and f > '2020-6-23 10:00' and g < 2025", + "select /*+ use_index_merge(t8, primary,is2,is3,is4,is5) */ * from t8 where s1 like '啊A%' and s2 > 'abc' and s3 > 'cba' and s4 in ('aA', '??') and s5 = 'test,2'", + "select (select /*+ use_index_merge(t1,ia,ibc,ic) */ a from t1 where t1.a > 10 and t1.b = 20 and t1.c = t2.a) from t2", + "select (select /*+ use_index_merge(t1,ia,ibc,ic) */ a from t1 where t1.a > 10 and t1.b = 20 and t1.c > t2.a) from t2", + "select (select /*+ use_index_merge(t1,ia,ibc,ic) */ a from t1 where t1.a > 10 and t1.b = 20 and t1.e > t2.a) from t2", + "set @@tidb_partition_prune_mode = 'static'", + "select * from vh", + "select /*+ qb_name(v, v), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "select /*+ qb_name(v, v@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "select /*+ use_index_merge(t2, ia, ibc, id, ie) */ * from t2 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "select /*+ use_index_merge(t3, ia, ibc, id, ie) */ * from t3 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "select /*+ use_index_merge(t4, ia, ibc, id, ie) */ * from t4 where a > 10 and b = 20 and c < 35 and d in (1,3,8,9) and e = 100" + ] } -] \ No newline at end of file +] diff --git a/planner/core/testdata/index_merge_suite_out.json b/planner/core/testdata/index_merge_suite_out.json index 4fdd67789e205..5810f67c85e9c 100644 --- a/planner/core/testdata/index_merge_suite_out.json +++ b/planner/core/testdata/index_merge_suite_out.json @@ -1,4 +1,677 @@ [ + { + "Name": "TestIndexMergeJSONMemberOf", + "Cases": [ + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))", + "Plan": [ + "Selection 8.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10", + "Plan": [ + "Selection 8.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path1\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.XXX')) and a<10", + "Plan": [ + "Selection 2658.67 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.XXX\"))", + "└─TableReader 3323.33 root data:Selection", + " └─Selection 3323.33 cop[tikv] lt(test.t.a, 10)", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10", + "Plan": [ + "Selection 8.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path1\")), json_memberof(cast(2, json BINARY), test.t.j1)", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))", + "Plan": [ + "Selection 8000.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10", + "Plan": [ + "Selection 2658.67 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path1\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t use index(j0_0) where (1 member of (j0->'$.path0'))", + "Plan": [ + "Selection 8000.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t use index(j0_1) where (1 member of (j0->'$.path1')) and a<10", + "Plan": [ + "Selection 2658.67 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path1\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t force index(j0_0) where (1 member of (j0->'$.path0'))", + "Plan": [ + "Selection 8000.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t force index(j0_1) where (1 member of (j0->'$.path1')) and a<10", + "Plan": [ + "Selection 2658.67 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path1\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10", + "Plan": [ + "Selection 8.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.path1\")), json_memberof(cast(2, json BINARY), test.t.j1)", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]')", + "Plan": [ + "IndexMerge 10.00 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]')", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"[1, 2, 3]\", json BINARY))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0'))", + "Plan": [ + "Selection 8.00 root json_overlaps(cast(\"[1, 2, 3]\", json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]') and a<10", + "Plan": [ + "IndexMerge 3.32 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo", + "└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]') and a<10", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"[1, 2, 3]\", json BINARY))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0')) and a<10", + "Plan": [ + "Selection 8.00 root json_overlaps(cast(\"[1, 2, 3]\", json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1')", + "Plan": [ + "IndexMerge 10.00 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1')", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"1\", json BINARY))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0'))", + "Plan": [ + "Selection 8.00 root json_overlaps(cast(\"1\", json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1') and a<10", + "Plan": [ + "IndexMerge 3.32 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + "└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1') and a<10", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"1\", json BINARY))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0')) and a<10", + "Plan": [ + "Selection 8.00 root json_overlaps(cast(\"1\", json BINARY), json_extract(test.t.j0, \"$.path0\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string'))", + "Plan": [ + "Selection 8.00 root json_memberof(cast(\"a\", json BINARY), json_extract(test.t.j0, \"$.path_string\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string')) and a<10", + "Plan": [ + "Selection 8.00 root json_memberof(cast(\"a\", json BINARY), json_extract(test.t.j0, \"$.path_string\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')", + "Plan": [ + "IndexMerge 10.00 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10", + "Plan": [ + "IndexMerge 3.32 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo", + "└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_string\"), cast(\"[\"a\", \"b\", \"c\"]\", json BINARY))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_string\"), cast(\"[\"a\", \"b\", \"c\"]\", json BINARY))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date'))", + "Plan": [ + "Selection 8.00 root json_memberof(cast(\"2023-01-01\", json BINARY), json_extract(test.t.j0, \"$.path_date\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date')) and a<10", + "Plan": [ + "Selection 8.00 root json_memberof(cast(\"2023-01-01\", json BINARY), json_extract(test.t.j0, \"$.path_date\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))", + "Plan": [ + "IndexMerge 10.00 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10", + "Plan": [ + "IndexMerge 3.32 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo", + "└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_date\"), json_array(cast(2023-01-01, json BINARY), cast(2023-01-02, json BINARY), cast(2023-01-03, json BINARY)))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10", + "Plan": [ + "Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_date\"), json_array(cast(2023-01-01, json BINARY), cast(2023-01-02, json BINARY), cast(2023-01-03, json BINARY)))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + } + ] + }, + { + "Name": "TestCompositeMVIndex", + "Cases": [ + { + "SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4", + "Plan": [ + "Selection 0.00 root json_memberof(cast(3, json BINARY), test.t.j)", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3 4,1 2 3 4], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j))", + "Plan": [ + "Selection 0.08 root json_memberof(cast(3, json BINARY), test.t.j)", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2", + "Plan": [ + "IndexMerge 0.10 root type: union", + "├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1", + "Plan": [ + "IndexMerge 10.00 root type: union", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str')) and c=4", + "Plan": [ + "Selection 0.00 root json_memberof(cast(\"3\", json BINARY), json_extract(test.t.j, \"$.str\"))", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(json_extract(`j`, _utf8mb4'$.str') as char(10) array), c) range:[1 2 0x33 4,1 2 0x33 4], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str'))", + "Plan": [ + "Selection 0.08 root json_memberof(cast(\"3\", json BINARY), json_extract(test.t.j, \"$.str\"))", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(json_extract(`j`, _utf8mb4'$.str') as char(10) array), c) range:[1 2 0x33,1 2 0x33], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2", + "Plan": [ + "IndexMerge 0.10 root type: union", + "├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1", + "Plan": [ + "IndexMerge 10.00 root type: union", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4", + "Plan": [ + "Selection 0.00 root json_memberof(cast(3, json BINARY), test.t.j)", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3 4,1 2 3 4], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t use index(idx) where a=1 and b=2 and (3 member of (j))", + "Plan": [ + "Selection 0.08 root json_memberof(cast(3, json BINARY), test.t.j)", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index(t, idx) */ * from t where a=1 and b=2", + "Plan": [ + "IndexMerge 0.10 root type: union", + "├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t use index(idx) where a=1", + "Plan": [ + "IndexMerge 10.00 root type: union", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t force index(idx) where a=1 and b=2 and (3 member of (j))", + "Plan": [ + "Selection 0.08 root json_memberof(cast(3, json BINARY), test.t.j)", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t force index(idx) where a=1", + "Plan": [ + "IndexMerge 10.00 root type: union", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + } + ] + }, + { + "Name": "TestDNFOnMVIndex", + "Cases": [ + { + "SQL": "select /*+ use_index_merge(t, idx1) */ * from t where (1 member of (j)) or (2 member of (j))", + "Plan": [ + "Selection 8.00 root or(json_memberof(cast(1, json BINARY), test.t.j), json_memberof(cast(2, json BINARY), test.t.j))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx1) */ * from t where ((1 member of (j)) or (2 member of (j))) and (a > 10)", + "Plan": [ + "Selection 8.00 root or(json_memberof(cast(1, json BINARY), test.t.j), json_memberof(cast(2, json BINARY), test.t.j))", + "└─IndexMerge 3.33 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.33 cop[tikv] gt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx1) */ * from t where (json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))", + "Plan": [ + "Selection 8.00 root or(json_overlaps(test.t.j, cast(\"[1, 2]\", json BINARY)), json_overlaps(test.t.j, cast(\"[3, 4]\", json BINARY)))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[3,3], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[4,4], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx1) */ * from t where ((json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))) and (a > 10)", + "Plan": [ + "Selection 8.00 root or(json_overlaps(test.t.j, cast(\"[1, 2]\", json BINARY)), json_overlaps(test.t.j, cast(\"[3, 4]\", json BINARY)))", + "└─IndexMerge 3.33 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[3,3], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[4,4], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.33 cop[tikv] gt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx1) */ * from t where (json_contains(j, '[1, 2]')) or (json_contains(j, '[3, 4]'))", + "Plan": [ + "TableReader 9600.00 root data:Selection", + "└─Selection 9600.00 cop[tikv] or(json_contains(test.t.j, cast(\"[1, 2]\", json BINARY)), json_contains(test.t.j, cast(\"[3, 4]\", json BINARY)))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))", + "Plan": [ + "Selection 0.00 root or(and(eq(test.t.a, 1), and(eq(test.t.b, 2), json_memberof(cast(3, json BINARY), test.t.j))), and(eq(test.t.a, 11), and(eq(test.t.b, 12), json_memberof(cast(13, json BINARY), test.t.j))))", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13,11 12 13], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)) and c=14)", + "Plan": [ + "Selection 0.00 root or(and(eq(test.t.a, 1), and(eq(test.t.b, 2), json_memberof(cast(3, json BINARY), test.t.j))), and(and(eq(test.t.a, 11), eq(test.t.b, 12)), and(json_memberof(cast(13, json BINARY), test.t.j), eq(test.t.c, 14))))", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13 14,11 12 13 14], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select /*+ use_index_merge(t, idx2) */ * from t where ((a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))) and (c > 10)", + "Plan": [ + "Selection 0.00 root or(and(eq(test.t.a, 1), and(eq(test.t.b, 2), json_memberof(cast(3, json BINARY), test.t.j))), and(eq(test.t.a, 11), and(eq(test.t.b, 12), json_memberof(cast(13, json BINARY), test.t.j))))", + "└─IndexMerge 0.00 root type: union", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13,11 12 13], keep order:false, stats:pseudo", + " └─Selection(Probe) 0.00 cop[tikv] gt(test.t.c, 10)", + " └─TableRowIDScan 0.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + } + ] + }, + { + "Name": "TestMVIndexSelection", + "Cases": [ + { + "SQL": "select (j->'$.int') from t where (1 member of (j->'$.int'))", + "Plan": [ + "Projection 8000.00 root json_extract(test.t.j, $.int)->Column#5", + "└─Selection 8000.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j, \"$.int\"))", + " └─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t where (1 member of (j->'$.int'))", + "Plan": [ + "Selection 8000.00 root json_memberof(cast(1, json BINARY), json_extract(test.t.j, \"$.int\"))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t where (1 member of (j->'$.int')) and a<10", + "Plan": [ + "Selection 2658.67 root json_memberof(cast(1, json BINARY), json_extract(test.t.j, \"$.int\"))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select (j->'$.int') from t where json_contains((j->'$.int'), '[1, 2, 3]')", + "Plan": [ + "Projection 8000.00 root json_extract(test.t.j, $.int)->Column#5", + "└─IndexMerge 10.00 root type: intersection", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t where json_contains((j->'$.int'), '[1, 2, 3]')", + "Plan": [ + "IndexMerge 10.00 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t where json_contains((j->'$.int'), '[1, 2, 3]') and a<10", + "Plan": [ + "IndexMerge 3.32 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo", + "└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select (j->'$.int') from t where json_overlaps((j->'$.int'), '[1, 2, 3]')", + "Plan": [ + "Projection 8000.00 root json_extract(test.t.j, $.int)->Column#5", + "└─Selection 8000.00 root json_overlaps(json_extract(test.t.j, \"$.int\"), cast(\"[1, 2, 3]\", json BINARY))", + " └─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]')", + "Plan": [ + "Selection 8000.00 root json_overlaps(json_extract(test.t.j, \"$.int\"), cast(\"[1, 2, 3]\", json BINARY))", + "└─IndexMerge 10.00 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + }, + { + "SQL": "select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]') and a<10", + "Plan": [ + "Selection 2658.67 root json_overlaps(json_extract(test.t.j, \"$.int\"), cast(\"[1, 2, 3]\", json BINARY))", + "└─IndexMerge 3.32 root type: union", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo", + " └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)", + " └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo" + ] + } + ] + }, { "Name": "TestIndexMergePathGeneration", "Cases": [ @@ -9,5 +682,427 @@ "[{Idxs:[c_d_e,f],TbFilters:[or(gt(test.t.c, 5), lt(test.t.f, 7)),or(lt(test.t.c, 1), gt(test.t.g, 2))]},{Idxs:[c_d_e,f],TbFilters:[or(lt(test.t.c, 1), gt(test.t.f, 2)),or(lt(test.t.c, 1), gt(test.t.g, 2))]},{Idxs:[c_d_e,g],TbFilters:[or(lt(test.t.c, 1), gt(test.t.f, 2)),or(gt(test.t.c, 5), lt(test.t.f, 7))]}]", "[{Idxs:[c_d_e,f],TbFilters:[or(gt(test.t.c, 5), lt(test.t.f, 7)),or(lt(test.t.e, 1), gt(test.t.f, 2))]},{Idxs:[c_d_e,f],TbFilters:[or(lt(test.t.c, 1), gt(test.t.f, 2)),or(lt(test.t.e, 1), gt(test.t.f, 2))]}]" ] + }, + { + "Name": "TestHintForIntersectionIndexMerge", + "Cases": [ + { + "SQL": "set @@tidb_partition_prune_mode = 'dynamic'", + "Plan": null, + "Result": null + }, + { + "SQL": "select * from vh", + "Plan": [ + "IndexMerge 0.97 root partition:p0,p1,p2 type: intersection", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, index:ia(a) range:[10,10], keep order:false", + "├─IndexRangeScan(Build) 2.60 cop[tikv] table:t1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t1, index:id(d) range:[2,2], [5,5], keep order:false", + "└─TableRowIDScan(Probe) 0.97 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "Plan": [ + "IndexMerge 0.97 root partition:p0,p1,p2 type: intersection", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, index:ia(a) range:[10,10], keep order:false", + "├─IndexRangeScan(Build) 2.60 cop[tikv] table:t1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t1, index:id(d) range:[2,2], [5,5], keep order:false", + "└─TableRowIDScan(Probe) 0.97 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "Plan": [ + "IndexMerge 0.97 root partition:p0,p1,p2 type: intersection", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, index:ia(a) range:[10,10], keep order:false", + "├─IndexRangeScan(Build) 2.60 cop[tikv] table:t1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t1, index:id(d) range:[2,2], [5,5], keep order:false", + "└─TableRowIDScan(Probe) 0.97 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "Plan": [ + "IndexMerge 0.97 root partition:p0,p1,p2 type: intersection", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, index:ia(a) range:[10,10], keep order:false", + "├─IndexRangeScan(Build) 2.60 cop[tikv] table:t1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t1, index:id(d) range:[2,2], [5,5], keep order:false", + "└─TableRowIDScan(Probe) 0.97 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v1@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v1 where c < 30 and d in (2,5)", + "Plan": [ + "IndexMerge 0.97 root partition:p0,p1,p2 type: intersection", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, index:ia(a) range:[10,10], keep order:false", + "├─IndexRangeScan(Build) 2.60 cop[tikv] table:t1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t1, index:id(d) range:[2,2], [5,5], keep order:false", + "└─TableRowIDScan(Probe) 0.97 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ use_index_merge(t2, ia, ibc, id, ie) */ * from t2 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "Plan": [ + "IndexMerge 0.89 root partition:p0,p1,p2 type: intersection", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t2, index:ia(a) range:(10,+inf], keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t2, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t2, index:id(d) range:[-inf,45), keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t2, index:ie(e) range:[100,100], keep order:false", + "└─TableRowIDScan(Probe) 0.89 cop[tikv] table:t2 keep order:false" + ], + "Result": [ + "20 20 20 5 100" + ] + }, + { + "SQL": "select /*+ use_index_merge(t3, ia, ibc, id, ie) */ * from t3 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "Plan": [ + "IndexMerge 0.44 root partition:p0 type: intersection", + "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t3, index:ia(a) range:(10,+inf], keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t3, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t3, index:id(d) range:[-inf,45), keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t3, index:ie(e) range:[100,100], keep order:false", + "└─TableRowIDScan(Probe) 0.44 cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "20 20 20 5 100" + ] + }, + { + "SQL": "select /*+ use_index_merge(t4, ia, ibc, id, ie) */ * from t4 where a > 10 and b = 20 and c < 35 and d in (1,3,8,9) and e = 100", + "Plan": [ + "IndexMerge 0.89 root partition:p0,p1 type: intersection", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t4, index:ia(a) range:(10,+inf], keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t4, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + "├─IndexRangeScan(Build) 3.00 cop[tikv] table:t4, index:id(d) range:[1,1], [3,3], [8,8], [9,9], keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t4, index:ie(e) range:[100,100], keep order:false", + "└─TableRowIDScan(Probe) 0.89 cop[tikv] table:t4 keep order:false" + ], + "Result": [ + "30 20 5 8 100" + ] + }, + { + "SQL": "select /*+ use_index_merge(t5, is1, is2, is3, is4) */ * from t5 where s1 = 'Abc' and s2 > 'zzz' and s3 < 'B啊a' and s4 = 'CcC'", + "Plan": [ + "IndexMerge 0.00 root type: intersection", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t5, index:is1(s1) range:[\"Abc\",\"Abc\"], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:is2(s2) range:(\"zzz\",+inf], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:is3(s3) range:[-inf,\"B啊a\"), keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t5, index:is4(s4) range:[\"CcC\",\"CcC\"], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Result": [ + "Abc zzzz aa ccc" + ] + }, + { + "SQL": "select /*+ use_index_merge(t6, primary, is3, is4) */ * from t6 where s1 = 'Abc' and s2 > 'zzz' and s3 = 'A啊a' and s4 not like 'Cd_'", + "Plan": [ + "IndexMerge 0.03 root type: intersection", + "├─IndexRangeScan(Build) 33.33 cop[tikv] table:t6, index:PRIMARY(s1, s2) range:(\"Abc\" \"zzz\",\"Abc\" +inf], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t6, index:is3(s3) range:[\"A啊a\",\"A啊a\"], keep order:false, stats:pseudo", + "└─Selection(Probe) 0.03 cop[tikv] gt(test.t6.s2, \"zzz\"), not(like(test.t6.s4, \"Cd_\", 92))", + " └─TableRowIDScan 0.03 cop[tikv] table:t6 keep order:false, stats:pseudo" + ], + "Result": [ + "Abc zzzz A啊A Cdaa" + ] + }, + { + "SQL": "select /*+ use_index_merge(t7, primary,ia,ib,ic,ie,iff,ig) */ * from t7 where a = 100 and b > 5 and c < 12.3 and d > 54.321 and e = '2022-11-22 17:00' and f > '2020-6-23 10:00' and g < 2025", + "Plan": [ + "IndexMerge 0.00 root type: intersection", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t7, index:PRIMARY(d) range:(54.321,+inf], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t7, index:ia(a) range:[100,100], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t7, index:ib(b) range:(\"0x05\",+inf], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t7, index:ic(c) range:[-inf,12.3), keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t7, index:ie(e) range:[2022-11-22 17:00:00,2022-11-22 17:00:00], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t7, index:iff(f) range:(2020-06-23 10:00:00.00000,+inf], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t7, index:ig(g) range:[-inf,2025), keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t7 keep order:false, stats:pseudo" + ], + "Result": [ + "100 \u0006 12.2 56.000 2022-11-22 17:00:00 2022-12-21 00:00:00.00000 2021" + ] + }, + { + "SQL": "select /*+ use_index_merge(t8, primary,is2,is3,is4,is5) */ * from t8 where s1 like '啊A%' and s2 > 'abc' and s3 > 'cba' and s4 in ('aA', '??') and s5 = 'test,2'", + "Plan": [ + "Selection 1.42 root eq(test.t8.s5, \"test,2\")", + "└─IndexMerge 0.59 root type: intersection", + " ├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t8, index:is2(s2) range:(0x616263,+inf], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t8, index:is3(s3) range:(0x636261,+inf], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 20.00 cop[tikv] table:t8, index:is4(s4) range:[\"aA\",\"aA\"], [\"??\",\"??\"], keep order:false, stats:pseudo", + " └─Selection(Probe) 0.59 cop[tikv] gt(test.t8.s3, \"cba\"), like(test.t8.s1, \"啊A%\", 92)", + " └─TableRowIDScan 2.22 cop[tikv] table:t8 keep order:false, stats:pseudo" + ], + "Result": [ + "啊aabbccdd abcc cccc aA tEsT,2" + ] + }, + { + "SQL": "select (select /*+ use_index_merge(t1,ia,ibc,ic) */ a from t1 where t1.a > 10 and t1.b = 20 and t1.c = t2.a) from t2", + "Plan": [ + "Projection 3.00 root test.t1.a", + "└─Apply 3.00 root CARTESIAN left outer join", + " ├─IndexReader(Build) 3.00 root partition:all index:IndexFullScan", + " │ └─IndexFullScan 3.00 cop[tikv] table:t2, index:ia(a) keep order:false", + " └─MaxOneRow(Probe) 3.00 root ", + " └─IndexMerge 1.50 root partition:all type: intersection", + " ├─IndexRangeScan(Build) 6.00 cop[tikv] table:t1, index:ia(a) range:(10,+inf], keep order:false", + " ├─IndexRangeScan(Build) 4.00 cop[tikv] table:t1, index:ibc(b, c) range: decided by [eq(test.t1.b, 20) eq(test.t1.c, test.t2.a)], keep order:false", + " └─TableRowIDScan(Probe) 1.50 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "20", + "", + "" + ] + }, + { + "SQL": "select (select /*+ use_index_merge(t1,ia,ibc,ic) */ a from t1 where t1.a > 10 and t1.b = 20 and t1.c > t2.a) from t2", + "Plan": [ + "Projection 3.00 root test.t1.a", + "└─Apply 3.00 root CARTESIAN left outer join", + " ├─IndexReader(Build) 3.00 root partition:all index:IndexFullScan", + " │ └─IndexFullScan 3.00 cop[tikv] table:t2, index:ia(a) keep order:false", + " └─MaxOneRow(Probe) 3.00 root ", + " └─IndexMerge 3.60 root partition:all type: intersection", + " ├─IndexRangeScan(Build) 6.00 cop[tikv] table:t1, index:ia(a) range:(10,+inf], keep order:false", + " ├─Selection(Build) 7.20 cop[tikv] gt(test.t1.c, test.t2.a)", + " │ └─IndexRangeScan 9.00 cop[tikv] table:t1, index:ibc(b, c) range:[20,20], keep order:false", + " └─TableRowIDScan(Probe) 3.60 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "20", + "20", + "" + ] + }, + { + "SQL": "select (select /*+ use_index_merge(t1,ia,ibc,ic) */ a from t1 where t1.a > 10 and t1.b = 20 and t1.e > t2.a) from t2", + "Plan": [ + "Projection 3.00 root test.t1.a", + "└─Apply 3.00 root CARTESIAN left outer join", + " ├─IndexReader(Build) 3.00 root partition:all index:IndexFullScan", + " │ └─IndexFullScan 3.00 cop[tikv] table:t2, index:ia(a) keep order:false", + " └─MaxOneRow(Probe) 3.00 root ", + " └─IndexMerge 3.60 root partition:all type: intersection", + " ├─IndexRangeScan(Build) 6.00 cop[tikv] table:t1, index:ia(a) range:(10,+inf], keep order:false", + " ├─IndexRangeScan(Build) 9.00 cop[tikv] table:t1, index:ibc(b, c) range:[20,20], keep order:false", + " └─Selection(Probe) 3.60 cop[tikv] gt(test.t1.e, test.t2.a)", + " └─TableRowIDScan 4.50 cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "20", + "20", + "20" + ] + }, + { + "SQL": "set @@tidb_partition_prune_mode = 'static'", + "Plan": null, + "Result": null + }, + { + "SQL": "select * from vh", + "Plan": [ + "PartitionUnion 0.50 root ", + "├─IndexMerge 0.50 root type: intersection", + "│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 0.50 cop[tikv] table:t1, partition:p0 keep order:false", + "├─IndexMerge 1.00 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p1 keep order:false", + "└─IndexMerge 0.00 root type: intersection", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, partition:p2, index:ia(a) range:[10,10], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 33.23 cop[tikv] table:t1, partition:p2, index:ibc(b, c) range:[20 -inf,20 30), keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 20.00 cop[tikv] table:t1, partition:p2, index:id(d) range:[2,2], [5,5], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "Plan": [ + "PartitionUnion 0.50 root ", + "├─IndexMerge 0.50 root type: intersection", + "│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 0.50 cop[tikv] table:t1, partition:p0 keep order:false", + "├─IndexMerge 1.00 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p1 keep order:false", + "└─IndexMerge 0.00 root type: intersection", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, partition:p2, index:ia(a) range:[10,10], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 33.23 cop[tikv] table:t1, partition:p2, index:ibc(b, c) range:[20 -inf,20 30), keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 20.00 cop[tikv] table:t1, partition:p2, index:id(d) range:[2,2], [5,5], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "Plan": [ + "PartitionUnion 0.50 root ", + "├─IndexMerge 0.50 root type: intersection", + "│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 0.50 cop[tikv] table:t1, partition:p0 keep order:false", + "├─IndexMerge 1.00 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p1 keep order:false", + "└─IndexMerge 0.00 root type: intersection", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, partition:p2, index:ia(a) range:[10,10], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 33.23 cop[tikv] table:t1, partition:p2, index:ibc(b, c) range:[20 -inf,20 30), keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 20.00 cop[tikv] table:t1, partition:p2, index:id(d) range:[2,2], [5,5], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "Plan": [ + "PartitionUnion 0.50 root ", + "├─IndexMerge 0.50 root type: intersection", + "│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 0.50 cop[tikv] table:t1, partition:p0 keep order:false", + "├─IndexMerge 1.00 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p1 keep order:false", + "└─IndexMerge 0.00 root type: intersection", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, partition:p2, index:ia(a) range:[10,10], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 33.23 cop[tikv] table:t1, partition:p2, index:ibc(b, c) range:[20 -inf,20 30), keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 20.00 cop[tikv] table:t1, partition:p2, index:id(d) range:[2,2], [5,5], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ qb_name(v, v@sel_1 .@sel_1), use_index_merge(@v t1, ia, ibc, id) */ * from v", + "Plan": [ + "PartitionUnion 0.50 root ", + "├─IndexMerge 0.50 root type: intersection", + "│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t1, partition:p0, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p0, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 0.50 cop[tikv] table:t1, partition:p0 keep order:false", + "├─IndexMerge 1.00 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ia(a) range:[10,10], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:ibc(b, c) range:[20 -inf,20 30), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, partition:p1, index:id(d) range:[2,2], [5,5], keep order:false", + "│ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t1, partition:p1 keep order:false", + "└─IndexMerge 0.00 root type: intersection", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, partition:p2, index:ia(a) range:[10,10], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 33.23 cop[tikv] table:t1, partition:p2, index:ibc(b, c) range:[20 -inf,20 30), keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 20.00 cop[tikv] table:t1, partition:p2, index:id(d) range:[2,2], [5,5], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo" + ], + "Result": [ + "10 20 5 5 3" + ] + }, + { + "SQL": "select /*+ use_index_merge(t2, ia, ibc, id, ie) */ * from t2 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "Plan": [ + "PartitionUnion 1.25 root ", + "├─IndexMerge 0.25 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, partition:p0, index:ia(a) range:(10,+inf], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, partition:p0, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + "│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t2, partition:p0, index:id(d) range:[-inf,45), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, partition:p0, index:ie(e) range:[100,100], keep order:false", + "│ └─TableRowIDScan(Probe) 0.25 cop[tikv] table:t2, partition:p0 keep order:false", + "├─IndexMerge 1.00 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, partition:p1, index:ia(a) range:(10,+inf], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, partition:p1, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, partition:p1, index:id(d) range:[-inf,45), keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, partition:p1, index:ie(e) range:[100,100], keep order:false", + "│ └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2, partition:p1 keep order:false", + "└─IndexMerge 0.00 root type: intersection", + " ├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t2, partition:p2, index:ia(a) range:(10,+inf], keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 33.23 cop[tikv] table:t2, partition:p2, index:ibc(b, c) range:[20 -inf,20 35), keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t2, partition:p2, index:id(d) range:[-inf,45), keep order:false, stats:pseudo", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t2, partition:p2, index:ie(e) range:[100,100], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo" + ], + "Result": [ + "20 20 20 5 100" + ] + }, + { + "SQL": "select /*+ use_index_merge(t3, ia, ibc, id, ie) */ * from t3 where a > 10 and b = 20 and c < 35 and d < 45 and e = 100", + "Plan": [ + "IndexMerge 0.50 root type: intersection", + "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t3, partition:p0, index:ia(a) range:(10,+inf], keep order:false", + "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t3, partition:p0, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t3, partition:p0, index:id(d) range:[-inf,45), keep order:false", + "├─IndexRangeScan(Build) 2.00 cop[tikv] table:t3, partition:p0, index:ie(e) range:[100,100], keep order:false", + "└─TableRowIDScan(Probe) 0.50 cop[tikv] table:t3, partition:p0 keep order:false" + ], + "Result": [ + "20 20 20 5 100" + ] + }, + { + "SQL": "select /*+ use_index_merge(t4, ia, ibc, id, ie) */ * from t4 where a > 10 and b = 20 and c < 35 and d in (1,3,8,9) and e = 100", + "Plan": [ + "PartitionUnion 1.25 root ", + "├─IndexMerge 0.25 root type: intersection", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t4, partition:p0, index:ia(a) range:(10,+inf], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t4, partition:p0, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + "│ ├─IndexRangeScan(Build) 2.00 cop[tikv] table:t4, partition:p0, index:id(d) range:[1,1], [3,3], [8,8], [9,9], keep order:false", + "│ ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t4, partition:p0, index:ie(e) range:[100,100], keep order:false", + "│ └─TableRowIDScan(Probe) 0.25 cop[tikv] table:t4, partition:p0 keep order:false", + "└─IndexMerge 1.00 root type: intersection", + " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t4, partition:p1, index:ia(a) range:(10,+inf], keep order:false", + " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t4, partition:p1, index:ibc(b, c) range:[20 -inf,20 35), keep order:false", + " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t4, partition:p1, index:id(d) range:[1,1], [3,3], [8,8], [9,9], keep order:false", + " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t4, partition:p1, index:ie(e) range:[100,100], keep order:false", + " └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t4, partition:p1 keep order:false" + ], + "Result": [ + "30 20 5 8 100" + ] + } + ] } ] diff --git a/planner/core/testdata/integration_partition_suite_out.json b/planner/core/testdata/integration_partition_suite_out.json index e9b75469bc21d..e496996969211 100644 --- a/planner/core/testdata/integration_partition_suite_out.json +++ b/planner/core/testdata/integration_partition_suite_out.json @@ -1059,13 +1059,13 @@ "Plan": [ "HashAgg 1.00 root funcs:avg(Column#4, Column#5)->Column#3", "└─PartitionUnion 2.00 root ", - " ├─StreamAgg 1.00 root funcs:count(Column#8)->Column#4, funcs:sum(Column#9)->Column#5", - " │ └─TableReader 1.00 root data:StreamAgg", - " │ └─StreamAgg 1.00 cop[tikv] funcs:count(list_push_down.tlist.a)->Column#8, funcs:sum(list_push_down.tlist.a)->Column#9", + " ├─HashAgg 1.00 root funcs:count(Column#6)->Column#4, funcs:sum(Column#7)->Column#5", + " │ └─TableReader 1.00 root data:HashAgg", + " │ └─HashAgg 1.00 cop[tikv] funcs:count(list_push_down.tlist.a)->Column#6, funcs:sum(list_push_down.tlist.a)->Column#7", " │ └─TableFullScan 10000.00 cop[tikv] table:tlist, partition:p0 keep order:false, stats:pseudo", - " └─StreamAgg 1.00 root funcs:count(Column#12)->Column#4, funcs:sum(Column#13)->Column#5", - " └─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(list_push_down.tlist.a)->Column#12, funcs:sum(list_push_down.tlist.a)->Column#13", + " └─HashAgg 1.00 root funcs:count(Column#10)->Column#4, funcs:sum(Column#11)->Column#5", + " └─TableReader 1.00 root data:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(list_push_down.tlist.a)->Column#10, funcs:sum(list_push_down.tlist.a)->Column#11", " └─TableFullScan 10000.00 cop[tikv] table:tlist, partition:p1 keep order:false, stats:pseudo" ] }, @@ -1116,13 +1116,13 @@ "Plan": [ "HashAgg 1.00 root funcs:avg(Column#4, Column#5)->Column#3", "└─PartitionUnion 2.00 root ", - " ├─StreamAgg 1.00 root funcs:count(Column#8)->Column#4, funcs:sum(Column#9)->Column#5", - " │ └─TableReader 1.00 root data:StreamAgg", - " │ └─StreamAgg 1.00 cop[tikv] funcs:count(list_push_down.tcollist.a)->Column#8, funcs:sum(list_push_down.tcollist.a)->Column#9", + " ├─HashAgg 1.00 root funcs:count(Column#6)->Column#4, funcs:sum(Column#7)->Column#5", + " │ └─TableReader 1.00 root data:HashAgg", + " │ └─HashAgg 1.00 cop[tikv] funcs:count(list_push_down.tcollist.a)->Column#6, funcs:sum(list_push_down.tcollist.a)->Column#7", " │ └─TableFullScan 10000.00 cop[tikv] table:tcollist, partition:p0 keep order:false, stats:pseudo", - " └─StreamAgg 1.00 root funcs:count(Column#12)->Column#4, funcs:sum(Column#13)->Column#5", - " └─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(list_push_down.tcollist.a)->Column#12, funcs:sum(list_push_down.tcollist.a)->Column#13", + " └─HashAgg 1.00 root funcs:count(Column#10)->Column#4, funcs:sum(Column#11)->Column#5", + " └─TableReader 1.00 root data:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(list_push_down.tcollist.a)->Column#10, funcs:sum(list_push_down.tcollist.a)->Column#11", " └─TableFullScan 10000.00 cop[tikv] table:tcollist, partition:p1 keep order:false, stats:pseudo" ] }, diff --git a/planner/core/testdata/integration_suite_in.json b/planner/core/testdata/integration_suite_in.json index 940c67c7f0f47..c5185349f0aa2 100644 --- a/planner/core/testdata/integration_suite_in.json +++ b/planner/core/testdata/integration_suite_in.json @@ -468,10 +468,10 @@ "explain format = 'verbose' select /*+ use_index(t3, c) */ count(a) from t3 where b = 0", "explain format = 'verbose' select count(*) from t2 where a = 0", "explain format = 'verbose' select count(*) from t3 t join t3 on t.a = t3.b", - "explain format = 'verbose' select count(*) from t1 join t2 on t1.a = t2.a", - "explain format = 'verbose' select count(*) from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b", - "explain format = 'verbose' select (2) in (select count(*) from t1) from (select t.b < (select t.b from t2 limit 1 ) from t3 t) t", - "explain format = 'verbose' select /*+ merge_join(t1) */ count(*) from t1 join t2 on t1.a = t2.a" + "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a", + "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b", + "explain format = 'verbose' select (2) in (select /*+ read_from_storage(tiflash[t1]) */ count(*) from t1) from (select t.b < (select /*+ read_from_storage(tiflash[t2]) */ t.b from t2 limit 1 ) from t3 t) t", + "explain format = 'verbose' select /*+ merge_join(t1), read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a" ] }, @@ -653,6 +653,203 @@ "desc format = 'brief' select /*+ read_from_storage(tiflash[t, ttt], tikv[tt]) */ * from ttt" ] }, + { + "name": "TestKeepOrderHint", + "cases": [ + "explain select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "explain select /*+ keep_order(t, primary) */ * from t where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t, primary) */ * from t where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 limit 1;", + "explain select /*+ no_keep_order(t, primary) */ * from t where a<10 limit 1;", + + // The index doesn't exist + "explain select /*+ keep_order(t1, idx_b) */ * from t1 where b<10 order by b limit 1;", + "explain select /*+ keep_order(t, idx_b) */ * from t where b<10 order by b limit 1;", + "explain select /*+ no_keep_order(t1, idx_b) */ * from t1 where b<10 order by b limit 1;", + "explain select /*+ no_keep_order(t, idx_b) */ * from t where b<10 order by b limit 1;", + + // Use the keep_order/ no_keep_order with the use_index/ ignore_index/ force_index hint at the same time + "explain select /*+ keep_order(t1, idx_a) use_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "explain select /*+ keep_order(t1, idx_a) */ * from t1 use index(idx_a) where a<10 order by a limit 1;", + "explain select /*+ keep_order(t1, idx_a) force_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "explain select /*+ keep_order(t1, idx_a) */ * from t1 force index(idx_a) where a<10 order by a limit 1;", + "explain select /*+ keep_order(t1, idx_a) ignore_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + + "explain select /*+ keep_order(t, primary) use_index(t, primary) */ * from t where a<10 order by a limit 1;", + "explain select /*+ keep_order(t, primary) */ * from t use index(primary) where a<10 order by a limit 1;", + "explain select /*+ keep_order(t, primary) force_index(t, primary) */ * from t where a<10 order by a limit 1;", + "explain select /*+ keep_order(t, primary) */ * from t force index(primary) where a<10 order by a limit 1;", + "explain select /*+ keep_order(t, primary) ignore_index(t, primary) */ * from t where a<10 order by a limit 1;", + + "explain select /*+ no_keep_order(t, primary) use_index(t, primary) */ * from t where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t, primary) */ * from t use index(primary) where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t, primary) force_index(t, primary) */ * from t where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t, primary) */ * from t force index(primary) where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t, primary) ignore_index(t, primary) */ * from t where a<10 order by a limit 1;", + + "explain select /*+ no_keep_order(t1, idx_a) use_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 use index(idx_a) where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t1, idx_a) force_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 force index(idx_a) where a<10 order by a limit 1;", + "explain select /*+ no_keep_order(t1, idx_a) ignore_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + + // Use the keep_order/ no_keep_order with the use_view hint at the same time + "explain select /*+ qb_name(qb, v) keep_order(t1@qb, idx_a) */ * from v", + "explain select /*+ qb_name(qb, v1) keep_order(t@qb, primary) */ * from v1", + "explain select /*+ qb_name(qb, v) no_keep_order(t1@qb, idx_a) */ * from v", + "explain select /*+ qb_name(qb, v1) no_keep_order(t@qb, primary) */ * from v1", + + // Use the keep_order/ no_keep_order with CTE at the same time + "explain WITH CTE AS (select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "explain WITH CTE AS (select /*+ keep_order(t, primary) */ * from t where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "explain WITH CTE AS (select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "explain WITH CTE AS (select /*+ no_keep_order(t, primary) */ * from t where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;" + ] + }, + { + "name": "TestViewHint", + "cases": [ + // Hint for view v + "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel_1), merge_join(t@qb_v_1) */ * from v;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v2;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v2;", + + // Hint for view v1 + "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v1@sel_1 .@sel_1), merge_join(t@qb_v1_1) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_2 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;", + "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_2 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_2 .@sel_1), merge_join(t@qb_v1_1) */ * from v2;", + + // Hint for view v2 + "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2;", + "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2), stream_agg(@qb_v2_2), qb_name(qb_v2_1, v2), merge_join(t@qb_v2_1) */ * from v2;" + ] + }, + { + "name": "TestViewHintScope", + "cases": [ + // Same qb name in one query + "explain format = 'brief' select /*+ qb_name(qb_v, v@sel_1 .@sel_2), qb_name(qb_v, v@sel_1 .@sel_1), merge_join(t1@qb_v) */ * from v;", + "explain format = 'brief' select /*+ qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_2), qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_2), qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v2;", + + // Set the unappeared view name + "explain format = 'brief' select /*+ qb_name(qb_v1_2, v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;", + + // Exist the view alias + "explain format = 'brief' select /*+ qb_name(qb_v2_2, vv@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;", + "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;", + + // Tht view hint isn't set in the first query block. + "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v) t;", + "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v.@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel1), merge_join(t@qb_v_1) */ * from v) t;", + "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1) t;", + "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1.v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1) t;", + + "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v) t;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_2 .@sel_2), qb_name(qb_v_1, v@sel_2 .@sel1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v) t;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_2 . v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v1) t;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v1@sel_2 . v@sel_2 .@sel_1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v1) t;", + + // Define more tables in one view hint + "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2. v1@sel_2 .@sel_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_2 .@sel_1), merge_join(t1@qb_v1_2, t@qb_v1_1), merge_join(t1@qb_v1_2) */ * from v2;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t1@qb_v_2, t3@qb_v_2) */ * from v2;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(@qb_v_2 t1, t3) */ * from v2;", + + // Ignore the @sel_1 query block + "explain format = 'brief' select /*+ qb_name(qb_v_2, v .@sel_2), merge_join(t1@qb_v_2) */ * from v;", + "explain format = 'brief' select /*+ qb_name(qb_v_1, v@sel_1), merge_join(t@qb_v_1) */ * from v;", + "explain format = 'brief' select /*+ qb_name(qb_v_2, v1 .v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v_1, v1 .v@sel_2), merge_join(t@qb_v_1) */ * from v1;", + + // Use the query block before define it + "explain format = 'brief' select /*+ merge_join(t1@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2) */ * from v;", + "explain format = 'brief' select /*+ merge_join(t@qb_v_1), stream_agg(@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2), qb_name(qb_v_1, v@sel_1 .@sel_1) */ * from v;", + + // The view contains the hint when creation + "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2) */ * from v3;", + "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2), hash_agg(@qb_v3_2), qb_name(qb_v3_1, v3@sel_1 .@sel_1), hash_join(t@qb_v3_1) */ * from v3;", + + // The view is in the CTE + "explain with d1 as (\n select a from (\n select a from (\n select /*+ qb_name(qb, v4) use_index(t4@qb, idx_a) */ a from v4 where a < 10\n ) as t0 where a < 9\n ) as t1 where a < 8\n), d2 as (select /*+ qb_name(qb2, v4) use_index(t4@qb2, idx_b) */ a from v4 where b < 10)\n\nselect * from (select * from d1) as t0 join (select * from d2) as t1;", + "explain with d1 as (\n select a from (\n select a from (\n select a from v4 where a < 10\n ) as t0 where a < 9\n ) as t1 where a < 8\n), d2 as (select a from v4 where b < 10)\n\nselect /*+ qb_name(qb, v4@sel_4) use_index(t4@qb, idx_a) qb_name(qb2, v4@sel_5) use_index(t4@qb, idx_b) */ * from (select * from d1) as t0 join (select * from d2) as t1;", + "explain with d1 as (\n select a from (\n select a from (\n select /*+ qb_name(qb, v5) use_index(t4@qb, idx_a) */ a from v4 where a < 10\n ) as t0 where a < 9\n ) as t1 where a < 8\n), d2 as (select /*+ qb_name(qb2, v4) use_index(t4@qb2, idx_b) */ a from v4 where b < 10)\n\nselect * from (select * from d1) as t0 join (select * from d2) as t1;" + ] + }, + { + "name": "TestAllViewHintType", + "cases": [ + // leading hint + // join nodes in the same view + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 v, t2) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(v@qb_v1, t2@qb_v1) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 t3, t2) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(t3@qb_v1, t2@qb_v1) */ * from v1;", + + // join node across view + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), qb_name(qb_v, v1.v), leading(t2@qb_v1, t@qb_v) */ * from v1;", + + // hash_join hint + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(@qb_v1 v, t2) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(t2@qb_v1, t3@qb_v1) */ * from v1;", + + // hash join build hint + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(@qb_v1 v) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(t2@qb_v1) */ * from v1;", + + // hash join probe hint + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(@qb_v1 v) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(t2@qb_v1) */ * from v1;", + + // merge join hint + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(@qb_v1 v) */ * from v1;", + "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(t2@qb_v1) */ * from v1;", + + // index join hint + "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(@qb_v t) */ * from v;", + "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(t@qb_v) */ * from v;", + + // agg hint + "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), hash_agg(@qb_v2) */ * from v2;", + "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), stream_agg(@qb_v2) */ * from v2;", + + // index hint + "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(t5@qb_v3, idx_a) */ * from v3;", + "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(@qb_v3 t5, idx_b) */ * from v3;", + "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(t5@qb_v3, idx_a) */ * from v3;", + "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(@qb_v3 t5, idx_b) */ * from v3;", + "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(t5@qb_v3, idx_a) */ * from v3;", + "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(@qb_v3 t5, idx_b) */ * from v3;", + "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(t5@qb_v4, idx_a, idx_b) */ * from v4;", + "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(@qb_v4 t5, idx_b, idx_a) */ * from v4;", + + // read from storage + "explain format = 'brief' select /*+ qb_name(qb_v, v), READ_FROM_STORAGE(TIFLASH[t@qb_v], TIKV[t1@qb_v]) */ * from v;", + + // subquery hint + "explain format = 'brief' select /*+ qb_name(qb_v5, v5.@sel_2), SEMI_JOIN_REWRITE(@qb_v5) */ * from v5;", + "explain format = 'brief' select /*+ qb_name(qb_v6, v6.@sel_2), NO_DECORRELATE(@qb_v6) */ * from v6;", + + // cte hint + "explain format = 'brief' select /*+ qb_name(qb_v7, v7), merge(@qb_v7) */ * from v7;", + "explain format = 'brief' select /*+ qb_name(qb_v8, v8), merge(@qb_v8) */ * from v8;", + + // agg to cop hint + "explain format = 'brief' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;", + "explain format = 'brief' select /*+ qb_name(qb_v10, v10), LIMIT_TO_COP(@qb_v10) */ * from v10;", + + // MPP hint + "explain format = 'brief' select /*+ qb_name(qb, v11) read_from_storage(tiflash[t@qb]), MPP_1PHASE_AGG(@qb) */ * from v11;", + "explain format = 'brief' select /*+ qb_name(qb, v11) read_from_storage(tiflash[t@qb]), MPP_2PHASE_AGG(@qb) */ * from v11;", + "explain format = 'brief' select /*+ qb_name(qb, v12) read_from_storage(tiflash[t1@qb, t@qb]), shuffle_join(t1@qb, t@qb) */ * from v12;", + "explain format = 'brief' select /*+ qb_name(qb, v12) read_from_storage(tiflash[t1@qb, t@qb]), broadcast_join(t1@qb, t@qb) */ * from v12;" + ] + }, { "name": "TestReadFromStorageHintAndIsolationRead", "cases": [ @@ -745,12 +942,12 @@ { "name": "TestPushDownProjectionForTiFlash", "cases": [ - "desc format = 'brief' select /*+ hash_agg()*/ count(b) from (select id + 1 as b from t)A", - "desc format = 'brief' select /*+ hash_agg()*/ count(*) from (select id + 1 as b from t)A", - "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from (select id + 1 as b from t)A", - "desc format = 'brief' select /*+ stream_agg()*/ count(b) from (select id + 1 as b from t)A", - "desc format = 'brief' select /*+ stream_agg()*/ count(*) from (select id + 1 as b from t)A", - "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from (select id + 1 as b from t)A", + "desc format = 'brief' select /*+ hash_agg()*/ count(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", + "desc format = 'brief' select /*+ hash_agg()*/ count(*) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", + "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", + "desc format = 'brief' select /*+ stream_agg()*/ count(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", + "desc format = 'brief' select /*+ stream_agg()*/ count(*) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", + "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", "desc format = 'brief' select * from (select id-2 as b from t) B join (select id-2 as b from t) A on A.b=B.b", "desc format = 'brief' select * from t join (select id-2 as b from t) A on A.b=t.id", "desc format = 'brief' select * from t left join (select id-2 as b from t) A on A.b=t.id", @@ -811,6 +1008,19 @@ "desc format = 'brief' SELECT STRAIGHT_JOIN t1 . col_varchar_64 , t1 . col_char_64_not_null FROM tt AS t1 INNER JOIN( tt AS t2 JOIN tt AS t3 ON(t3 . col_decimal_30_10_key = t2 . col_tinyint)) ON(t3 . col_varchar_64 = t2 . col_varchar_key) WHERE t3 . col_varchar_64 = t1 . col_char_64_not_null GROUP BY 1 , 2" ] }, + { + "name": "TestMppJoinExchangeColumnPrune", + "cases": [ + "desc format = 'brief' select * from tt t1 where exists (select * from t t2 where t1.b1 = t2.c3 and t2.c1 < t2.c2)" + ] + }, + { + "name": "TestMppFineGrainedJoinAndAgg", + "cases": [ + "desc format = 'brief' select * from tt t1 where exists (select * from t t2 where t1.b1 = t2.c3 and t2.c1 < t2.c2)", + "desc format = 'brief' select count(*) from tt group by b1" + ] + }, { "name": "TestPushDownAggForMPP", "cases": [ @@ -1011,5 +1221,26 @@ "set @@tidb_opt_range_max_size = 300", "explain format='brief' select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.e where t1.b > t2.f and t1.b < t2.f + 10" ] + }, + { + "name": "TestNullConditionForPrefixIndex", + "cases": [ + "select count(1) from t1 where c1 = '0xfff' and c2 is not null", + "select count(1) from t1 where c1 = '0xfff' and c2 is null", + "select count(1) from t1 where c1 >= '0xfff' and c2 is not null", + "select count(1) from t1 where c1 >= '0xfff' and c2 is null", + "select count(1) from t1 where c1 = '0xfff' and (c2 + 1) is not null", + "select count(1) from t1 where c1 = '0xfff' and (c2 + 1) is null", + "select c2 from t1 use index(idx2) where c1 = '0xfff' and c2 is not null", + "select c2 from t1 use index(idx2) where c1 = '0xfff' and c2 is null", + "select c2 from t1 use index(idx2) where c1 >= '0xfff' and c2 is not null", + "select c2 from t1 use index(idx2) where c1 >= '0xfff' and c2 is null", + "select count(1) from t2 use index(idx) where b is not null", + "select count(1) from t2 use index(idx) where b is null", + "select b from t2 use index(idx) where b is not null", + "select b from t2 use index(idx) where b is null", + "select b from t3 where a = 1 and b is not null", + "select b from t3 where a = 1 and b is null" + ] } ] diff --git a/planner/core/testdata/integration_suite_out.json b/planner/core/testdata/integration_suite_out.json index a42fe6c2f03e8..cb7b47742f619 100644 --- a/planner/core/testdata/integration_suite_out.json +++ b/planner/core/testdata/integration_suite_out.json @@ -14,11 +14,12 @@ { "SQL": "explain format = 'brief' select * from tbl use index(idx_b_c) where b > 1 order by b desc limit 2,1", "Plan": [ - "TopN 1.00 root test.tbl.b:desc, offset:2, count:1", - "└─IndexLookUp 3.00 root ", - " ├─TopN(Build) 3.00 cop[tikv] test.tbl.b:desc, offset:0, count:3", - " │ └─IndexRangeScan 4.00 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:false", - " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:tbl keep order:false" + "Limit 1.00 root offset:2, count:1", + "└─Projection 3.00 root test.tbl.a, test.tbl.b, test.tbl.c", + " └─IndexLookUp 3.00 root ", + " ├─Limit(Build) 3.00 cop[tikv] offset:0, count:3", + " │ └─IndexRangeScan 3.00 cop[tikv] table:tbl, index:idx_b_c(b, c) range:(1,+inf], keep order:true, desc", + " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:tbl keep order:false" ] }, { @@ -143,9 +144,9 @@ "IndexJoin 3.00 root inner join, inner:IndexLookUp, outer key:test.t1.c, inner key:test.t2.c, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b), eq(test.t1.c, test.t2.c)", "├─TableReader(Build) 3.00 root data:TableFullScan", "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false", - "└─IndexLookUp(Probe) 1.00 root ", - " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, index:idx2(c) range: decided by [eq(test.t2.c, test.t1.c)], keep order:false", - " └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false" + "└─IndexLookUp(Probe) 3.00 root ", + " ├─IndexRangeScan(Build) 3.00 cop[tikv] table:t2, index:idx2(c) range: decided by [eq(test.t2.c, test.t1.c)], keep order:false", + " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t2 keep order:false" ] } ] @@ -338,7 +339,7 @@ { "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, a, b) */ * from t where a = 1 or b = 2", "Plan": [ - "IndexMerge 2.00 root ", + "IndexMerge 2.00 root type: union", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:b(b) range:[2,2], keep order:false, stats:pseudo", "└─TableRowIDScan(Probe) 2.00 cop[tikv] table:t keep order:false, stats:pseudo" @@ -347,7 +348,7 @@ { "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, A, B) */ * from t where a = 1 or b = 2", "Plan": [ - "IndexMerge 2.00 root ", + "IndexMerge 2.00 root type: union", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:b(b) range:[2,2], keep order:false, stats:pseudo", "└─TableRowIDScan(Probe) 2.00 cop[tikv] table:t keep order:false, stats:pseudo" @@ -385,7 +386,7 @@ { "SQL": "explain format = 'brief' select /*+ USE_INDEX_MERGE(t, a, c) */ * from t where b = 1 and (a = 1 or c = 1)", "Plan": [ - "IndexMerge 0.02 root ", + "IndexMerge 0.02 root type: union", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false, stats:pseudo", "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:c(c) range:[1,1], keep order:false, stats:pseudo", "└─Selection(Probe) 0.02 cop[tikv] eq(test.t.b, 1)", @@ -405,13 +406,13 @@ " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─Selection(Probe) 0.80 root not(isnull(test.t.a))", - " └─Projection 1.00 root test.t.a", - " └─TopN 1.00 root Column#7, offset:0, count:1", - " └─Projection 1.00 root test.t.a, plus(test.t.a, test.t.a)->Column#7", - " └─TableReader 1.00 root data:TopN", - " └─TopN 1.00 cop[tikv] plus(test.t.a, test.t.a), offset:0, count:1", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─Selection(Probe) 7992.00 root not(isnull(test.t.a))", + " └─Projection 9990.00 root test.t.a", + " └─TopN 9990.00 root Column#7, offset:0, count:1", + " └─Projection 9990.00 root test.t.a, plus(test.t.a, test.t.a)->Column#7", + " └─TableReader 9990.00 root data:TopN", + " └─TopN 9990.00 cop[tikv] plus(test.t.a, test.t.a), offset:0, count:1", + " └─TableFullScan 99900000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ] }, { @@ -454,9 +455,9 @@ "IndexJoin 12487.50 root inner join, inner:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b)", "├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ └─IndexFullScan 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root data:Selection", - " └─Selection 1.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo" + "└─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.b))", + " └─TableRangeScan 9990.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo" ] }, { @@ -465,9 +466,9 @@ "IndexJoin 12487.50 root inner join, inner:TableReader, outer key:test.t1.a, test.t1.b, inner key:test.t2.a, test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.a), eq(test.t1.b, test.t2.b)", "├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ └─IndexFullScan 9990.00 cop[tikv] table:t1, index:idx_t1_b(b) keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root data:Selection", - " └─Selection 1.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t1.a test.t1.b], keep order:false, stats:pseudo" + "└─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.b))", + " └─TableRangeScan 9990.00 cop[tikv] table:t2 range: decided by [test.t1.a test.t1.b], keep order:false, stats:pseudo" ] }, { @@ -477,9 +478,9 @@ "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - "└─TableReader(Probe) 0.00 root data:Selection", - " └─Selection 0.00 cop[tikv] eq(test.t4.b, 1)", - " └─TableRangeScan 1.00 cop[tikv] table:t4 range: decided by [eq(test.t4.a, test.t3.a) eq(test.t4.b, 1)], keep order:false, stats:pseudo" + "└─TableReader(Probe) 9.99 root data:Selection", + " └─Selection 9.99 cop[tikv] eq(test.t4.b, 1)", + " └─TableRangeScan 9990.00 cop[tikv] table:t4 range: decided by [eq(test.t4.a, test.t3.a) eq(test.t4.b, 1)], keep order:false, stats:pseudo" ] }, { @@ -489,9 +490,9 @@ "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - "└─TableReader(Probe) 0.00 root data:Selection", - " └─Selection 0.00 cop[tikv] eq(test.t4.a, 1)", - " └─TableRangeScan 1.00 cop[tikv] table:t4 range: decided by [eq(test.t4.b, test.t3.b) eq(test.t4.a, 1)], keep order:false, stats:pseudo" + "└─TableReader(Probe) 9.99 root data:Selection", + " └─Selection 9.99 cop[tikv] eq(test.t4.a, 1)", + " └─TableRangeScan 9990.00 cop[tikv] table:t4 range: decided by [eq(test.t4.b, test.t3.b) eq(test.t4.a, 1)], keep order:false, stats:pseudo" ] } ] @@ -506,10 +507,10 @@ "└─IndexJoin 12487.50 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.t.b, equal cond:eq(test.t.a, test.t.b)", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t.b))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:b(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 12487.50 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t.b))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:b(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warnings": [] }, @@ -520,10 +521,10 @@ "└─IndexHashJoin 12487.50 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.t.b, equal cond:eq(test.t.a, test.t.b)", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t.b))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:b(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 12487.50 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t.b))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:b(b) range: decided by [eq(test.t.b, test.t.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warnings": [] }, @@ -531,13 +532,13 @@ "SQL": "desc format = 'brief' select /*+ INL_MERGE_JOIN(t2)*/ t1.a, t2.a from t t1, t t2 ,t t3 where t1.a = t2.a and t3.a=t2.a", "Plan": [ "HashJoin 15625.00 root inner join, equal:[eq(test.t.a, test.t.a)]", - "├─TableReader(Build) 10000.00 root data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t3, index:b(b) keep order:false, stats:pseudo", "└─IndexMergeJoin(Probe) 12500.00 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a", - " ├─TableReader(Build) 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:true, stats:pseudo" + " ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + " │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:b(b) keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:true, stats:pseudo" ], "Warnings": [] }, @@ -561,10 +562,10 @@ "SQL": "desc format = 'brief' select /*+ INL_HASH_JOIN(t2) */ distinct t2.a from t t1 join t t2 on t1.a = t2.a", "Plan": [ "IndexHashJoin 12500.00 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a)", - "├─TableReader(Build) 10000.00 root data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:false, stats:pseudo" + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:b(b) keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:false, stats:pseudo" ], "Warnings": [] }, @@ -941,7 +942,7 @@ "SQL": "select /*+ use_index_merge(t partition(p0)) */ * from t where t.b = 1 or t.c = \"8\"", "Plan": [ "PartitionUnion 59.97 root ", - "├─IndexMerge 19.99 root ", + "├─IndexMerge 19.99 root type: union", "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p0, index:b(b) range:[1,1], keep order:false, stats:pseudo", "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p0, index:c(c) range:[\"8\",\"8\"], keep order:false, stats:pseudo", "│ └─TableRowIDScan(Probe) 19.99 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", @@ -958,11 +959,11 @@ "SQL": "select /*+ use_index_merge(t partition(p0, p1) primary, b) */ * from t where t.a = 1 or t.b = 2", "Plan": [ "PartitionUnion 33.00 root ", - "├─IndexMerge 11.00 root ", + "├─IndexMerge 11.00 root type: union", "│ ├─TableRangeScan(Build) 1.00 cop[tikv] table:t, partition:p0 range:[1,1], keep order:false, stats:pseudo", "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p0, index:b(b) range:[2,2], keep order:false, stats:pseudo", "│ └─TableRowIDScan(Probe) 11.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", - "├─IndexMerge 11.00 root ", + "├─IndexMerge 11.00 root type: union", "│ ├─TableRangeScan(Build) 1.00 cop[tikv] table:t, partition:p1 range:[1,1], keep order:false, stats:pseudo", "│ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, partition:p1, index:b(b) range:[2,2], keep order:false, stats:pseudo", "│ └─TableRowIDScan(Probe) 11.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", @@ -1093,7 +1094,7 @@ { "SQL": "select /*+ use_index_merge(t1 primary, c) */ * from t1 where t1.a >= 1 or t1.c = 2.2", "Plan": [ - "IndexMerge 3.00 root ", + "IndexMerge 3.00 root type: union", "├─TableRangeScan(Build) 3.00 cop[tikv] table:t1 range:[1,+inf], keep order:false", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, index:c(c) range:[2.2000000000,2.2000000000], keep order:false", "└─TableRowIDScan(Probe) 3.00 cop[tikv] table:t1 keep order:false" @@ -1107,7 +1108,7 @@ { "SQL": "select /*+ use_index_merge(t1 primary, c) */ * from t1 where t1.a = 1 and t1.b = '111' or t1.c = 3.3", "Plan": [ - "IndexMerge 1.67 root ", + "IndexMerge 1.67 root type: union", "├─TableRangeScan(Build) 1.00 cop[tikv] table:t1 range:[1 \"111\",1 \"111\"], keep order:false", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, index:c(c) range:[3.3000000000,3.3000000000], keep order:false", "└─TableRowIDScan(Probe) 1.67 cop[tikv] table:t1 keep order:false" @@ -1128,8 +1129,8 @@ "IndexJoin 3.00 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a)", "├─TableReader(Build) 3.00 root data:TableFullScan", "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:false" + "└─TableReader(Probe) 3.00 root data:TableRangeScan", + " └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:false" ], "Res": [ "1 111 1.1000000000 11 1 111 1.1000000000 11", @@ -1143,8 +1144,8 @@ "IndexMergeJoin 3.00 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a", "├─TableReader(Build) 3.00 root data:TableFullScan", "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:true" + "└─TableReader(Probe) 3.00 root data:TableRangeScan", + " └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:true" ], "Res": [ "1 111 1.1000000000 11 1 111 1.1000000000 11", @@ -1158,8 +1159,8 @@ "IndexHashJoin 3.00 root inner join, inner:TableReader, outer key:test.t.a, inner key:test.t.a, equal cond:eq(test.t.a, test.t.a)", "├─TableReader(Build) 3.00 root data:TableFullScan", "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:false" + "└─TableReader(Probe) 3.00 root data:TableRangeScan", + " └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a)], keep order:false" ], "Res": [ "1 111 1.1000000000 11 1 111 1.1000000000 11", @@ -1173,8 +1174,8 @@ "IndexJoin 3.00 root inner join, inner:TableReader, outer key:test.t.a, test.t.b, inner key:test.t.a, test.t.b, equal cond:eq(test.t.a, test.t.a), eq(test.t.b, test.t.b)", "├─TableReader(Build) 3.00 root data:TableFullScan", "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a) eq(test.t.b, test.t.b)], keep order:false" + "└─TableReader(Probe) 3.00 root data:TableRangeScan", + " └─TableRangeScan 3.00 cop[tikv] table:t2 range: decided by [eq(test.t.a, test.t.a) eq(test.t.b, test.t.b)], keep order:false" ], "Res": [ "1 111 1.1000000000 11 1 111 1.1000000000 11", @@ -1189,10 +1190,10 @@ "├─TableReader(Build) 3.00 root data:Selection", "│ └─Selection 3.00 cop[tikv] not(isnull(test.t.c))", "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false", - "└─IndexLookUp(Probe) 1.00 root ", - " ├─Selection(Build) 1.00 cop[tikv] not(isnull(test.t.c))", - " │ └─IndexRangeScan 1.00 cop[tikv] table:t2, index:c(c) range: decided by [eq(test.t.c, test.t.c)], keep order:false", - " └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false" + "└─IndexLookUp(Probe) 3.00 root ", + " ├─Selection(Build) 3.00 cop[tikv] not(isnull(test.t.c))", + " │ └─IndexRangeScan 3.00 cop[tikv] table:t2, index:c(c) range: decided by [eq(test.t.c, test.t.c)], keep order:false", + " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t2 keep order:false" ], "Res": [ "1 111 1.1000000000 11 1 111 1.1000000000 11", @@ -1205,12 +1206,12 @@ "Plan": [ "IndexMergeJoin 3.00 root left outer join, inner:Projection, outer key:Column#9, inner key:test.t.c", "├─Projection(Build) 3.00 root cast(test.t.a, decimal(10,0) BINARY)->Column#9", - "│ └─TableReader 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t1 keep order:false", - "└─Projection(Probe) 1.00 root test.t.a, test.t.c, test.t.d", - " └─IndexLookUp 1.00 root ", - " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t2, index:c(c) range: decided by [eq(test.t.c, Column#9)], keep order:true", - " └─TableRowIDScan(Probe) 1.00 cop[tikv] table:t2 keep order:false" + "│ └─IndexReader 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t1, index:c(c) keep order:false", + "└─Projection(Probe) 3.00 root test.t.a, test.t.c, test.t.d", + " └─IndexLookUp 3.00 root ", + " ├─IndexRangeScan(Build) 3.00 cop[tikv] table:t2, index:c(c) range: decided by [eq(test.t.c, Column#9)], keep order:true", + " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:t2 keep order:false" ], "Res": [ " ", @@ -1337,7 +1338,7 @@ { "SQL": "select * from pt where id = 4 or c < 7", "Plan": [ - "IndexMerge_11 3330.01 root partition:all ", + "IndexMerge_11 3330.01 root partition:all type: union", "├─IndexRangeScan_8(Build) 10.00 cop[tikv] table:pt, index:i_id(id) range:[4,4], keep order:false, stats:pseudo", "├─IndexRangeScan_9(Build) 3323.33 cop[tikv] table:pt, index:i_c(c) range:[-inf,7), keep order:false, stats:pseudo", "└─TableRowIDScan_10(Probe) 3330.01 cop[tikv] table:pt keep order:false, stats:pseudo" @@ -1346,7 +1347,7 @@ { "SQL": "select * from pt where id > 4 or c = 7", "Plan": [ - "IndexMerge_11 3340.00 root partition:all ", + "IndexMerge_11 3340.00 root partition:all type: union", "├─IndexRangeScan_8(Build) 3333.33 cop[tikv] table:pt, index:i_id(id) range:(4,+inf], keep order:false, stats:pseudo", "├─IndexRangeScan_9(Build) 10.00 cop[tikv] table:pt, index:i_c(c) range:[7,7], keep order:false, stats:pseudo", "└─TableRowIDScan_10(Probe) 3340.00 cop[tikv] table:pt keep order:false, stats:pseudo" @@ -1486,7 +1487,7 @@ "SQL": "explain format = 'brief' SELECT /*+ use_index_merge(t1)*/ COUNT(*) FROM t1 WHERE (key4=42 AND key6 IS NOT NULL) OR (key1=4 AND key3=6)", "Plan": [ "StreamAgg 1.00 root funcs:count(1)->Column#10", - "└─IndexMerge 0.02 root ", + "└─IndexMerge 0.02 root type: union", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:i4(key4) range:[42,42], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:i1(key1) range:[4,4], keep order:false, stats:pseudo", " └─Selection(Probe) 0.02 cop[tikv] or(and(eq(test.t1.key4, 42), not(isnull(test.t1.key6))), and(eq(test.t1.key1, 4), eq(test.t1.key3, 6)))", @@ -1501,41 +1502,41 @@ { "SQL": "explain format = 'brief' SELECT t1.pk FROM t1 INNER JOIN t2 ON t1.col1 = t2.pk INNER JOIN t3 ON t1.col3 = t3.pk WHERE t2.col1 IN ('a' , 'b') AND t3.keycol = 'c' AND t1.col2 = 'a' AND t1.col1 != 'abcdef' AND t1.col1 != 'aaaaaa'", "Plan": [ - "IndexJoin 13.81 root inner join, inner:IndexLookUp, outer key:test.t1.col1, inner key:test.t2.pk, equal cond:eq(test.t1.col1, test.t2.pk)", - "├─IndexJoin(Build) 12.50 root inner join, inner:IndexLookUp, outer key:test.t3.pk, inner key:test.t1.col3, equal cond:eq(test.t3.pk, test.t1.col3)", + "IndexHashJoin 13.81 root inner join, inner:IndexLookUp, outer key:test.t1.col1, inner key:test.t2.pk, equal cond:eq(test.t1.col1, test.t2.pk)", + "├─IndexHashJoin(Build) 12.50 root inner join, inner:IndexLookUp, outer key:test.t3.pk, inner key:test.t1.col3, equal cond:eq(test.t3.pk, test.t1.col3)", "│ ├─IndexLookUp(Build) 10.00 root ", "│ │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t3, index:keycol(keycol, pad1, pad2) range:[\"c\",\"c\"], keep order:false, stats:pseudo", "│ │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.81 cop[tikv] not(isnull(test.t1.col3))", - "│ │ └─IndexRangeScan 1.81 cop[tikv] table:t1, index:col2(col2, col3) range: decided by [eq(test.t1.col3, test.t3.pk) eq(test.t1.col2, a)], keep order:false, stats:pseudo", - "│ └─Selection(Probe) 1.25 cop[tikv] ne(test.t1.col1, \"aaaaaa\"), ne(test.t1.col1, \"abcdef\"), not(isnull(test.t1.col1))", - "│ └─TableRowIDScan 1.81 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.00 root ", - " ├─Selection(Build) 1.00 cop[tikv] ne(test.t2.pk, \"aaaaaa\"), ne(test.t2.pk, \"abcdef\")", - " │ └─IndexRangeScan 1.00 cop[tikv] table:t2, index:PRIMARY(pk) range: decided by [eq(test.t2.pk, test.t1.col1)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.00 cop[tikv] in(test.t2.col1, \"a\", \"b\")", - " └─TableRowIDScan 1.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + "│ └─IndexLookUp(Probe) 12.50 root ", + "│ ├─Selection(Build) 18.10 cop[tikv] not(isnull(test.t1.col3))", + "│ │ └─IndexRangeScan 18.12 cop[tikv] table:t1, index:col2(col2, col3) range: decided by [eq(test.t1.col3, test.t3.pk) eq(test.t1.col2, a)], keep order:false, stats:pseudo", + "│ └─Selection(Probe) 12.50 cop[tikv] ne(test.t1.col1, \"aaaaaa\"), ne(test.t1.col1, \"abcdef\"), not(isnull(test.t1.col1))", + "│ └─TableRowIDScan 18.10 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12.50 root ", + " ├─Selection(Build) 12.50 cop[tikv] ne(test.t2.pk, \"aaaaaa\"), ne(test.t2.pk, \"abcdef\")", + " │ └─IndexRangeScan 12.50 cop[tikv] table:t2, index:PRIMARY(pk) range: decided by [eq(test.t2.pk, test.t1.col1)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12.50 cop[tikv] in(test.t2.col1, \"a\", \"b\")", + " └─TableRowIDScan 12.50 cop[tikv] table:t2 keep order:false, stats:pseudo" ] }, { "SQL": "explain format = 'brief' SELECT t1.pk FROM t1 LEFT JOIN t2 ON t1.col1 = t2.pk LEFT JOIN t3 ON t1.col3 = t3.pk WHERE t2.col1 IN ('a' , 'b') AND t3.keycol = 'c' AND t1.col2 = 'a' AND t1.col1 != 'abcdef' AND t1.col1 != 'aaaaaa'", "Plan": [ - "IndexJoin 13.81 root inner join, inner:IndexLookUp, outer key:test.t1.col1, inner key:test.t2.pk, equal cond:eq(test.t1.col1, test.t2.pk)", - "├─IndexJoin(Build) 12.50 root inner join, inner:IndexLookUp, outer key:test.t3.pk, inner key:test.t1.col3, equal cond:eq(test.t3.pk, test.t1.col3)", + "IndexHashJoin 13.81 root inner join, inner:IndexLookUp, outer key:test.t1.col1, inner key:test.t2.pk, equal cond:eq(test.t1.col1, test.t2.pk)", + "├─IndexHashJoin(Build) 12.50 root inner join, inner:IndexLookUp, outer key:test.t3.pk, inner key:test.t1.col3, equal cond:eq(test.t3.pk, test.t1.col3)", "│ ├─IndexLookUp(Build) 10.00 root ", "│ │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t3, index:keycol(keycol, pad1, pad2) range:[\"c\",\"c\"], keep order:false, stats:pseudo", "│ │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.81 cop[tikv] not(isnull(test.t1.col3))", - "│ │ └─IndexRangeScan 1.81 cop[tikv] table:t1, index:col2(col2, col3) range: decided by [eq(test.t1.col3, test.t3.pk) eq(test.t1.col2, a)], keep order:false, stats:pseudo", - "│ └─Selection(Probe) 1.25 cop[tikv] ne(test.t1.col1, \"aaaaaa\"), ne(test.t1.col1, \"abcdef\"), not(isnull(test.t1.col1))", - "│ └─TableRowIDScan 1.81 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.00 root ", - " ├─Selection(Build) 1.00 cop[tikv] ne(test.t2.pk, \"aaaaaa\"), ne(test.t2.pk, \"abcdef\")", - " │ └─IndexRangeScan 1.00 cop[tikv] table:t2, index:PRIMARY(pk) range: decided by [eq(test.t2.pk, test.t1.col1)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.00 cop[tikv] in(test.t2.col1, \"a\", \"b\")", - " └─TableRowIDScan 1.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + "│ └─IndexLookUp(Probe) 12.50 root ", + "│ ├─Selection(Build) 18.10 cop[tikv] not(isnull(test.t1.col3))", + "│ │ └─IndexRangeScan 18.12 cop[tikv] table:t1, index:col2(col2, col3) range: decided by [eq(test.t1.col3, test.t3.pk) eq(test.t1.col2, a)], keep order:false, stats:pseudo", + "│ └─Selection(Probe) 12.50 cop[tikv] ne(test.t1.col1, \"aaaaaa\"), ne(test.t1.col1, \"abcdef\"), not(isnull(test.t1.col1))", + "│ └─TableRowIDScan 18.10 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12.50 root ", + " ├─Selection(Build) 12.50 cop[tikv] ne(test.t2.pk, \"aaaaaa\"), ne(test.t2.pk, \"abcdef\")", + " │ └─IndexRangeScan 12.50 cop[tikv] table:t2, index:PRIMARY(pk) range: decided by [eq(test.t2.pk, test.t1.col1)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12.50 cop[tikv] in(test.t2.col1, \"a\", \"b\")", + " └─TableRowIDScan 12.50 cop[tikv] table:t2 keep order:false, stats:pseudo" ] } ] @@ -1663,11 +1664,11 @@ "└─Apply 10000.00 root CARTESIAN semi join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─Limit(Probe) 2.00 root offset:1, count:2", - " └─TableReader 3.00 root data:Limit", - " └─Limit 3.00 cop[tikv] offset:0, count:3", - " └─Selection 3.00 cop[tikv] eq(test.test.id, test.test.id)", - " └─TableFullScan 3000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─Limit(Probe) 20000.00 root offset:1, count:2", + " └─TableReader 30000.00 root data:Limit", + " └─Limit 30000.00 cop[tikv] offset:0, count:3", + " └─Selection 30000.00 cop[tikv] eq(test.test.id, test.test.id)", + " └─TableFullScan 30000000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ] }, { @@ -1676,12 +1677,12 @@ "Apply 10000.00 root CARTESIAN semi join", "├─TableReader(Build) 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─Selection(Probe) 2.40 root eq(9, test.t.c)", - " └─Limit 3.00 root offset:0, count:3", - " └─TableReader 3.00 root data:Limit", - " └─Limit 3.00 cop[tikv] offset:0, count:3", - " └─Selection 3.00 cop[tikv] lt(test.t.c, test.t.c)", - " └─TableFullScan 3.75 cop[tikv] table:s keep order:false, stats:pseudo" + "└─Selection(Probe) 24000.00 root eq(9, test.t.c)", + " └─Limit 30000.00 root offset:0, count:3", + " └─TableReader 30000.00 root data:Limit", + " └─Limit 30000.00 cop[tikv] offset:0, count:3", + " └─Selection 30000.00 cop[tikv] lt(test.t.c, test.t.c)", + " └─TableFullScan 37500.00 cop[tikv] table:s keep order:false, stats:pseudo" ] } ] @@ -1707,11 +1708,11 @@ "└─Apply 10000.00 root CARTESIAN left outer join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─MaxOneRow(Probe) 1.00 root ", - " └─IndexLookUp 0.02 root ", - " ├─Selection(Build) 0.02 cop[tikv] or(eq(test.t2.b, 1), eq(test.t2.b, 2))", - " │ └─IndexRangeScan 10.00 cop[tikv] table:t2, index:PRIMARY(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 0.02 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─MaxOneRow(Probe) 10000.00 root ", + " └─IndexLookUp 200.00 root ", + " ├─Selection(Build) 200.00 cop[tikv] or(eq(test.t2.b, 1), eq(test.t2.b, 2))", + " │ └─IndexRangeScan 100000.00 cop[tikv] table:t2, index:PRIMARY(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 200.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ] } ] @@ -1833,7 +1834,7 @@ { "SQL": "select * from t1 where a = 3 or a = 5", "Plan": [ - "Batch_Point_Get_5 2.00 12.53 root table:t1 handle:[3 5], keep order:false, desc:false" + "Batch_Point_Get_5 2.00 887.04 root table:t1 handle:[3 5], keep order:false, desc:false" ], "Warnings": [ "Note 1105 handle of t1 is selected since the path only has point ranges" @@ -1842,7 +1843,7 @@ { "SQL": "select f, g from t1 where f = 2 and g in (3, 4, 5)", "Plan": [ - "Batch_Point_Get_5 3.00 11.40 root table:t1, index:f_g(f, g) keep order:false, desc:false" + "Batch_Point_Get_5 3.00 380.16 root table:t1, index:f_g(f, g) keep order:false, desc:false" ], "Warnings": [ "Note 1105 unique index f_g of t1 is selected since the path only has point ranges with single scan" @@ -1851,7 +1852,7 @@ { "SQL": "select * from t1 where c = 1 and (d = 2 or d = 3) and e in (4, 5)", "Plan": [ - "Batch_Point_Get_5 4.00 27.20 root table:t1, index:c_d_e(c, d, e) keep order:false, desc:false" + "Batch_Point_Get_5 4.00 1774.08 root table:t1, index:c_d_e(c, d, e) keep order:false, desc:false" ], "Warnings": [ "Note 1105 unique index c_d_e of t1 is selected since the path only has point ranges with double scan" @@ -1860,8 +1861,8 @@ { "SQL": "select f, g from t1 where f = 2 and g > 3", "Plan": [ - "IndexReader_6 33.33 160.78 root index:IndexRangeScan_5", - "└─IndexRangeScan_5 33.33 1850.00 cop[tikv] table:t1, index:f_g(f, g) range:(2 3,2 +inf], keep order:false, stats:pseudo" + "IndexReader_6 33.33 733.82 root index:IndexRangeScan_5", + "└─IndexRangeScan_5 33.33 6783.33 cop[tikv] table:t1, index:f_g(f, g) range:(2 3,2 +inf], keep order:false, stats:pseudo" ], "Warnings": [ "Note 1105 unique index f_g of t1 is selected since the path only fetches limited number of rows with single scan" @@ -1870,8 +1871,8 @@ { "SQL": "select a, b, c from t2 where a = 1 and b = 2 and c in (1, 2, 3, 4, 5)", "Plan": [ - "Selection_6 0.01 8.60 root eq(test.t2.b, 2), in(test.t2.c, 1, 2, 3, 4, 5)", - "└─Point_Get_5 1.00 5.60 root table:t2, index:idx_a(a) " + "Selection_6 0.01 289.88 root eq(test.t2.b, 2), in(test.t2.c, 1, 2, 3, 4, 5)", + "└─Point_Get_5 1.00 190.08 root table:t2, index:idx_a(a) " ], "Warnings": [ "Note 1105 unique index idx_a of t2 is selected since the path only has point ranges with double scan" @@ -1880,7 +1881,7 @@ { "SQL": "select * from t3 where (a = 1 or a = 3) and b = 'xx'", "Plan": [ - "Batch_Point_Get_5 2.00 7.60 root table:t3, clustered index:PRIMARY(a, b) keep order:false, desc:false" + "Batch_Point_Get_5 2.00 1449.36 root table:t3, clustered index:PRIMARY(a, b) keep order:false, desc:false" ], "Warnings": [ "Note 1105 handle of t3 is selected since the path only has point ranges" @@ -1889,7 +1890,7 @@ { "SQL": "select * from t4 where (a = 1 or a = 3) and b = 'xx'", "Plan": [ - "Batch_Point_Get_5 2.00 10.00 root table:t4, index:PRIMARY(a, b) keep order:false, desc:false" + "Batch_Point_Get_5 2.00 1449.36 root table:t4, index:PRIMARY(a, b) keep order:false, desc:false" ], "Warnings": [ "Note 1105 unique index PRIMARY of t4 is selected since the path only has point ranges with double scan" @@ -1898,7 +1899,7 @@ { "SQL": "select a, b from t3 where (a = 1 or a = 3) and b = 'xx'", "Plan": [ - "Batch_Point_Get_5 2.00 7.60 root table:t3, clustered index:PRIMARY(a, b) keep order:false, desc:false" + "Batch_Point_Get_5 2.00 1322.64 root table:t3, clustered index:PRIMARY(a, b) keep order:false, desc:false" ], "Warnings": [ "Note 1105 handle of t3 is selected since the path only has point ranges" @@ -1907,7 +1908,7 @@ { "SQL": "select a, b from t4 where (a = 1 or a = 3) and b = 'xx'", "Plan": [ - "Batch_Point_Get_5 2.00 7.60 root table:t4, index:PRIMARY(a, b) keep order:false, desc:false" + "Batch_Point_Get_5 2.00 1322.64 root table:t4, index:PRIMARY(a, b) keep order:false, desc:false" ], "Warnings": [ "Note 1105 unique index PRIMARY of t4 is selected since the path only has point ranges with single scan" @@ -1917,7 +1918,7 @@ "SQL": "update t1 set b = 2 where a = 4 or a = 6", "Plan": [ "Update_4 N/A N/A root N/A", - "└─Batch_Point_Get_6 2.00 12.53 root table:t1 handle:[4 6], keep order:false, desc:false" + "└─Batch_Point_Get_6 2.00 887.04 root table:t1 handle:[4 6], keep order:false, desc:false" ], "Warnings": [ "Note 1105 handle of t1 is selected since the path only has point ranges" @@ -1927,8 +1928,8 @@ "SQL": "delete from t1 where f = 2 and g in (3, 4)", "Plan": [ "Delete_4 N/A N/A root N/A", - "└─Selection_7 2.00 9.80 root in(test.t1.g, 3, 4)", - " └─Point_Get_6 1.00 6.80 root table:t1, index:f(f) " + "└─Selection_7 2.00 493.42 root in(test.t1.g, 3, 4)", + " └─Point_Get_6 1.00 443.52 root table:t1, index:f(f) " ], "Warnings": [ "Note 1105 unique index f of t1 is selected since the path only has point ranges with double scan" @@ -1938,8 +1939,8 @@ "SQL": "insert into t3 select a, b, c from t1 where f = 2", "Plan": [ "Insert_1 N/A N/A root N/A", - "└─Projection_6 1.00 25.40 root test.t1.a, test.t1.b, test.t1.c", - " └─Point_Get_7 1.00 6.80 root table:t1, index:f(f) " + "└─Projection_6 1.00 253.74 root test.t1.a, test.t1.b, test.t1.c", + " └─Point_Get_7 1.00 253.44 root table:t1, index:f(f) " ], "Warnings": [ "Note 1105 unique index f of t1 is selected since the path only has point ranges with double scan" @@ -1949,7 +1950,7 @@ "SQL": "replace into t3 select a, b, c from t1 where a = 3", "Plan": [ "Insert_1 N/A N/A root N/A", - "└─Point_Get_7 1.00 6.27 root table:t1 handle:3" + "└─Point_Get_7 1.00 190.08 root table:t1 handle:3" ], "Warnings": [ "Note 1105 handle of t1 is selected since the path only has point ranges" @@ -1963,21 +1964,21 @@ { "SQL": "select * from t where a > 1 order by f", "Plan": [ - "IndexLookUp_14 3333.33 136747.00 root ", - "├─Selection_13(Build) 3333.33 585000.00 cop[tikv] gt(test.t.a, 1)", - "│ └─IndexFullScan_11 10000.00 555000.00 cop[tikv] table:t, index:f(f) keep order:true, stats:pseudo", - "└─TableRowIDScan_12(Probe) 3333.33 370000.00 cop[tikv] table:t keep order:false, stats:pseudo" + "Sort_5 3333.33 2146348.14 root test.t.f", + "└─TableReader_9 3333.33 160128.74 root data:TableRangeScan_8", + " └─TableRangeScan_8 3333.33 923531.15 cop[tikv] table:t range:(1,+inf], keep order:false, stats:pseudo" ], "Warnings": [ + "Note 1105 [t] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}", "Note 1105 [t,f,f_g] remain after pruning paths for t given Prop{SortItems: [{test.t.f asc}], TaskTp: rootTask}" ] }, { "SQL": "select * from t where f > 1", "Plan": [ - "IndexLookUp_10 3333.33 86674.83 root ", - "├─IndexRangeScan_8(Build) 3333.33 185000.00 cop[tikv] table:t, index:f(f) range:(1,+inf], keep order:false, stats:pseudo", - "└─TableRowIDScan_9(Probe) 3333.33 370000.00 cop[tikv] table:t keep order:false, stats:pseudo" + "TableReader_7 3333.33 316532.90 root data:Selection_6", + "└─Selection_6 3333.33 3269593.45 cop[tikv] gt(test.t.f, 1)", + " └─TableFullScan_5 10000.00 2770593.45 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warnings": [ "Note 1105 [t,f,f_g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}" @@ -1986,8 +1987,8 @@ { "SQL": "select f from t where f > 1", "Plan": [ - "IndexReader_6 3333.33 11140.22 root index:IndexRangeScan_5", - "└─IndexRangeScan_5 3333.33 140000.00 cop[tikv] table:t, index:f(f) range:(1,+inf], keep order:false, stats:pseudo" + "IndexReader_6 3333.33 50257.78 root index:IndexRangeScan_5", + "└─IndexRangeScan_5 3333.33 542666.67 cop[tikv] table:t, index:f(f) range:(1,+inf], keep order:false, stats:pseudo" ], "Warnings": [ "Note 1105 [f,f_g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}" @@ -1996,10 +1997,10 @@ { "SQL": "select * from t where f > 3 and g = 5", "Plan": [ - "IndexLookUp_15 3.33 206.74 root ", - "├─IndexRangeScan_12(Build) 10.00 570.00 cop[tikv] table:t, index:g(g) range:[5,5], keep order:false, stats:pseudo", - "└─Selection_14(Probe) 3.33 1140.00 cop[tikv] gt(test.t.f, 3)", - " └─TableRowIDScan_13 10.00 1110.00 cop[tikv] table:t keep order:false, stats:pseudo" + "IndexLookUp_15 3.33 19551.99 root ", + "├─IndexRangeScan_12(Build) 10.00 2035.00 cop[tikv] table:t, index:g(g) range:[5,5], keep order:false, stats:pseudo", + "└─Selection_14(Probe) 3.33 3269.59 cop[tikv] gt(test.t.f, 3)", + " └─TableRowIDScan_13 10.00 2770.59 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warnings": [ "Note 1105 [t,f_g,g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}" @@ -2008,24 +2009,26 @@ { "SQL": "select * from t where g = 5 order by f", "Plan": [ - "Sort_5 10.00 353.68 root test.t.f", - "└─IndexLookUp_13 10.00 230.01 root ", - " ├─IndexRangeScan_11(Build) 10.00 570.00 cop[tikv] table:t, index:g(g) range:[5,5], keep order:false, stats:pseudo", - " └─TableRowIDScan_12(Probe) 10.00 1110.00 cop[tikv] table:t keep order:false, stats:pseudo" + "Sort_5 10.00 21321.97 root test.t.f", + "└─IndexLookUp_13 10.00 19545.34 root ", + " ├─IndexRangeScan_11(Build) 10.00 2035.00 cop[tikv] table:t, index:g(g) range:[5,5], keep order:false, stats:pseudo", + " └─TableRowIDScan_12(Probe) 10.00 2770.59 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warnings": [ - "Note 1105 [t,g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}" + "Note 1105 [t,g] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}", + "Note 1105 [t,f_g,g] remain after pruning paths for t given Prop{SortItems: [{test.t.f asc}], TaskTp: rootTask}" ] }, { "SQL": "select * from t where d = 3 order by c, e", "Plan": [ - "IndexLookUp_15 10.00 57222.78 root ", - "├─Selection_14(Build) 10.00 855000.00 cop[tikv] eq(test.t.d, 3)", - "│ └─IndexFullScan_12 10000.00 825000.00 cop[tikv] table:t, index:c_d_e(c, d, e) keep order:true, stats:pseudo", - "└─TableRowIDScan_13(Probe) 10.00 1110.00 cop[tikv] table:t keep order:false, stats:pseudo" + "IndexLookUp_15 10.00 215519.24 root ", + "├─Selection_14(Build) 10.00 2941000.00 cop[tikv] eq(test.t.d, 3)", + "│ └─IndexFullScan_12 10000.00 2442000.00 cop[tikv] table:t, index:c_d_e(c, d, e) keep order:true, stats:pseudo", + "└─TableRowIDScan_13(Probe) 10.00 2770.59 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warnings": [ + "Note 1105 [t] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}", "Note 1105 [t,c_d_e] remain after pruning paths for t given Prop{SortItems: [{test.t.c asc} {test.t.e asc}], TaskTp: rootTask}" ] } @@ -2042,31 +2045,31 @@ { "SQL": "explain format = 'verbose' select * from t where b > 5", "Plan": [ - "TableReader_7 3.00 19.21 root data:Selection_6", - "└─Selection_6 3.00 195.00 cop[tikv] gt(test.t.b, 5)", - " └─TableFullScan_5 5.00 180.00 cop[tikv] table:t keep order:false" + "TableReader_7 3.00 130.42 root data:Selection_6", + "└─Selection_6 3.00 1386.04 cop[tikv] gt(test.t.b, 5)", + " └─TableFullScan_5 5.00 1136.54 cop[tikv] table:t keep order:false" ], "Warnings": null }, { "SQL": "explain format = 'verbose' select * from t where b = 6 order by a limit 1", "Plan": [ - "Limit_11 0.00 14.33 root offset:0, count:1", - "└─TableReader_24 0.00 14.33 root data:Limit_23", - " └─Limit_23 0.00 195.00 cop[tikv] offset:0, count:1", - " └─Selection_22 0.00 195.00 cop[tikv] eq(test.t.b, 6)", - " └─TableFullScan_21 5.00 180.00 cop[tikv] table:t keep order:true" + "Limit_11 0.00 98.74 root offset:0, count:1", + "└─TableReader_24 0.00 98.74 root data:Limit_23", + " └─Limit_23 0.00 1386.04 cop[tikv] offset:0, count:1", + " └─Selection_22 0.00 1386.04 cop[tikv] eq(test.t.b, 6)", + " └─TableFullScan_21 5.00 1136.54 cop[tikv] table:t keep order:true" ], "Warnings": null }, { "SQL": "explain format = 'verbose' select * from t where b = 6 limit 1", "Plan": [ - "Limit_8 0.00 14.33 root offset:0, count:1", - "└─TableReader_13 0.00 14.33 root data:Limit_12", - " └─Limit_12 0.00 195.00 cop[tikv] offset:0, count:1", - " └─Selection_11 0.00 195.00 cop[tikv] eq(test.t.b, 6)", - " └─TableFullScan_10 5.00 180.00 cop[tikv] table:t keep order:false" + "Limit_8 0.00 98.74 root offset:0, count:1", + "└─TableReader_13 0.00 98.74 root data:Limit_12", + " └─Limit_12 0.00 1386.04 cop[tikv] offset:0, count:1", + " └─Selection_11 0.00 1386.04 cop[tikv] eq(test.t.b, 6)", + " └─TableFullScan_10 5.00 1136.54 cop[tikv] table:t keep order:false" ], "Warnings": null }, @@ -2078,9 +2081,9 @@ { "SQL": "explain format = 'verbose' select * from t where b > 5", "Plan": [ - "IndexLookUp_7 3.00 57.91 root ", - "├─IndexRangeScan_5(Build) 3.00 171.00 cop[tikv] table:t, index:idx_b(b) range:(5,+inf], keep order:false", - "└─TableRowIDScan_6(Probe) 3.00 108.00 cop[tikv] table:t keep order:false" + "IndexLookUp_7 3.00 5856.46 root ", + "├─IndexRangeScan_5(Build) 3.00 610.50 cop[tikv] table:t, index:idx_b(b) range:(5,+inf], keep order:false", + "└─TableRowIDScan_6(Probe) 3.00 681.92 cop[tikv] table:t keep order:false" ], "Warnings": [ "Note 1105 [idx_b] remain after pruning paths for t given Prop{SortItems: [], TaskTp: rootTask}" @@ -2089,11 +2092,11 @@ { "SQL": "explain format = 'verbose' select * from t where b = 6 order by a limit 1", "Plan": [ - "TopN_9 0.00 19.34 root test.t.a, offset:0, count:1", - "└─IndexLookUp_16 0.00 19.33 root ", - " ├─TopN_15(Build) 0.00 0.00 cop[tikv] test.t.a, offset:0, count:1", - " │ └─IndexRangeScan_13 0.00 0.00 cop[tikv] table:t, index:idx_b(b) range:[6,6], keep order:false", - " └─TableRowIDScan_14(Probe) 0.00 0.00 cop[tikv] table:t keep order:false" + "TopN_9 0.00 1956.63 root test.t.a, offset:0, count:1", + "└─IndexLookUp_16 0.00 1951.83 root ", + " ├─TopN_15(Build) 0.00 206.70 cop[tikv] test.t.a, offset:0, count:1", + " │ └─IndexRangeScan_13 0.00 203.50 cop[tikv] table:t, index:idx_b(b) range:[6,6], keep order:false", + " └─TableRowIDScan_14(Probe) 0.00 186.61 cop[tikv] table:t keep order:false" ], "Warnings": [ "Note 1105 [idx_b] remain after pruning paths for t given Prop{SortItems: [], TaskTp: copDoubleReadTask}" @@ -2102,10 +2105,10 @@ { "SQL": "explain format = 'verbose' select * from t where b = 6 limit 1", "Plan": [ - "IndexLookUp_13 0.00 19.33 root limit embedded(offset:0, count:1)", - "├─Limit_12(Build) 0.00 0.00 cop[tikv] offset:0, count:1", - "│ └─IndexRangeScan_10 0.00 0.00 cop[tikv] table:t, index:idx_b(b) range:[6,6], keep order:false", - "└─TableRowIDScan_11(Probe) 0.00 0.00 cop[tikv] table:t keep order:false" + "IndexLookUp_13 0.00 1170.97 root limit embedded(offset:0, count:1)", + "├─Limit_12(Build) 0.00 203.50 cop[tikv] offset:0, count:1", + "│ └─IndexRangeScan_10 0.00 203.50 cop[tikv] table:t, index:idx_b(b) range:[6,6], keep order:false", + "└─TableRowIDScan_11(Probe) 0.00 186.61 cop[tikv] table:t keep order:false" ], "Warnings": [ "Note 1105 [idx_b] remain after pruning paths for t given Prop{SortItems: [], TaskTp: copDoubleReadTask}" @@ -2211,7 +2214,7 @@ "Plan": [ "Projection 15.99 root 1->Column#5", "└─Selection 15.99 root or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(from_base64(to_base64(test.t1.c1)), \"ab\")))", - " └─IndexMerge 19.99 root ", + " └─IndexMerge 19.99 root type: union", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo" @@ -2225,7 +2228,7 @@ "Plan": [ "Projection 17.99 root 1->Column#5", "└─Selection 0.04 root or(eq(test.t1.c1, \"ab\"), and(eq(test.t1.c2, \"10\"), eq(char_length(left(test.t1.c1, 10)), 10)))", - " └─IndexMerge 19.99 root ", + " └─IndexMerge 19.99 root type: union", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"ab\",\"ab\"], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo" @@ -2239,7 +2242,7 @@ "Plan": [ "Projection 15.99 root 1->Column#6", "└─Selection 15.99 root or(eq(test.tt1.c1, \"de\"), and(eq(test.tt1.c2, \"10\"), eq(from_base64(to_base64(test.tt1.c3)), \"10\")))", - " └─IndexMerge 19.99 root ", + " └─IndexMerge 19.99 root type: union", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tt1, index:idx_0(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tt1, index:idx_1(c2, c3) range:[\"10\",\"10\"], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 19.99 cop[tikv] table:tt1 keep order:false, stats:pseudo" @@ -2253,7 +2256,7 @@ "Plan": [ "Projection 2.40 root 1->Column#3", "└─Selection 2.40 root or(eq(test.tt2.c1, -3896405), and(in(test.tt2.pk, 1, 53330), istrue_with_null(cast(to_base64(left(cast(test.tt2.pk, var_string(20)), 5)), double BINARY))))", - " └─IndexMerge 3.00 root ", + " └─IndexMerge 3.00 root type: union", " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:tt2, index:c1(c1) range:[-3896405,-3896405], keep order:false, stats:pseudo", " ├─TableRangeScan(Build) 2.00 cop[tikv] table:tt2 range:[1,1], [53330,53330], keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 3.00 cop[tikv] table:tt2 keep order:false, stats:pseudo" @@ -2267,7 +2270,7 @@ "Plan": [ "Projection 5098.44 root 1->Column#5", "└─Selection 2825.66 root or(lt(test.tt3.c1, -10), and(lt(test.tt3.c2, 10), eq(reverse(cast(test.tt3.c3, var_string(20))), \"2\")))", - " └─IndexMerge 5542.21 root ", + " └─IndexMerge 5542.21 root type: union", " ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c1(c1) range:[-inf,-10), keep order:false, stats:pseudo", " ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:tt3, index:c2(c2) range:[-inf,10), keep order:false, stats:pseudo", " └─TableRowIDScan(Probe) 5542.21 cop[tikv] table:tt3 keep order:false, stats:pseudo" @@ -2301,14 +2304,14 @@ " └─Apply 10000.00 root CARTESIAN inner join, other cond:or(and(lt(test.t2.c1, Column#8), if(ne(Column#9, 0), NULL, 1)), or(eq(Column#10, 0), if(isnull(test.t2.c1), NULL, 0)))", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10", - " └─IndexMerge 0.01 root ", - " ├─Selection(Build) 1.00 cop[tikv] eq(10, test.t2.c3)", - " │ └─TableRangeScan 1.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo", - " ├─Selection(Build) 8.00 cop[tikv] eq(1, test.t2.c3)", - " │ └─IndexRangeScan 10.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.01 cop[tikv] or(and(eq(test.t1.c1, 10), eq(10, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), substring(cast(test.t1.c3, var_string(20)), 10)", - " └─TableRowIDScan 9.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10", + " └─IndexMerge 63.35 root type: union", + " ├─Selection(Build) 10000.00 cop[tikv] eq(10, test.t2.c3)", + " │ └─TableRangeScan 10000.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo", + " ├─Selection(Build) 80000.00 cop[tikv] eq(1, test.t2.c3)", + " │ └─IndexRangeScan 100000.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 63.35 cop[tikv] or(and(eq(test.t1.c1, 10), eq(10, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), substring(cast(test.t1.c3, var_string(20)), 10)", + " └─TableRowIDScan 89992.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1 1 1", @@ -2323,14 +2326,14 @@ " └─Apply 10000.00 root CARTESIAN inner join, other cond:or(and(lt(test.t2.c1, Column#8), if(ne(Column#9, 0), NULL, 1)), or(eq(Column#10, 0), if(isnull(test.t2.c1), NULL, 0)))", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10", - " └─IndexMerge 0.01 root ", - " ├─Selection(Build) 1.00 cop[tikv] eq(10, test.t2.c3)", - " │ └─TableRangeScan 1.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo", - " ├─Selection(Build) 8.00 cop[tikv] eq(1, test.t2.c3)", - " │ └─IndexRangeScan 10.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.01 cop[tikv] or(and(eq(test.t1.c1, 10), eq(10, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), reverse(cast(test.t1.c3, var_string(20)))", - " └─TableRowIDScan 9.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10", + " └─IndexMerge 63.35 root type: union", + " ├─Selection(Build) 10000.00 cop[tikv] eq(10, test.t2.c3)", + " │ └─TableRangeScan 10000.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo", + " ├─Selection(Build) 80000.00 cop[tikv] eq(1, test.t2.c3)", + " │ └─IndexRangeScan 100000.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 63.35 cop[tikv] or(and(eq(test.t1.c1, 10), eq(10, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), reverse(cast(test.t1.c3, var_string(20)))", + " └─TableRowIDScan 89992.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "2 2 2" @@ -2344,14 +2347,14 @@ " └─Apply 10000.00 root CARTESIAN inner join, other cond:or(and(lt(test.t2.c1, Column#8), if(ne(Column#9, 0), NULL, 1)), or(eq(Column#10, 0), if(isnull(test.t2.c1), NULL, 0)))", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10", - " └─IndexMerge 3.03 root ", - " ├─Selection(Build) 3.33 cop[tikv] eq(test.t1.c1, test.t2.c3)", - " │ └─TableRangeScan 3333.33 cop[tikv] table:t1 range:[10,+inf], keep order:false, stats:pseudo", - " ├─Selection(Build) 8.00 cop[tikv] eq(1, test.t2.c3)", - " │ └─IndexRangeScan 10.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo", - " └─Selection(Probe) 3.03 cop[tikv] or(and(ge(test.t1.c1, 10), eq(test.t1.c1, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), substring(cast(test.t1.c3, var_string(20)), 10)", - " └─TableRowIDScan 3338.67 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:min(test.t1.c1)->Column#8, funcs:sum(0)->Column#9, funcs:count(1)->Column#10", + " └─IndexMerge 30263.46 root type: union", + " ├─Selection(Build) 33333.33 cop[tikv] eq(test.t1.c1, test.t2.c3)", + " │ └─TableRangeScan 33333333.33 cop[tikv] table:t1 range:[10,+inf], keep order:false, stats:pseudo", + " ├─Selection(Build) 80000.00 cop[tikv] eq(1, test.t2.c3)", + " │ └─IndexRangeScan 100000.00 cop[tikv] table:t1, index:c2(c2) range:[1,1], keep order:false, stats:pseudo", + " └─Selection(Probe) 30263.46 cop[tikv] or(and(ge(test.t1.c1, 10), eq(test.t1.c1, test.t2.c3)), and(eq(test.t1.c2, 1), eq(1, test.t2.c3))), substring(cast(test.t1.c3, var_string(20)), 10)", + " └─TableRowIDScan 33386666.67 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1 1 1", @@ -2365,15 +2368,15 @@ "└─Apply 10000.00 root CARTESIAN inner join, other cond:or(and(lt(test.tt1.c_decimal, Column#9), if(ne(Column#10, 0), NULL, 1)), or(eq(Column#11, 0), if(isnull(test.tt1.c_decimal), NULL, 0)))", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:tt1 keep order:true, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:min(Column#14)->Column#9, funcs:sum(Column#15)->Column#10, funcs:count(1)->Column#11", - " └─Projection 0.00 root test.tt2.c_decimal, cast(isnull(test.tt2.c_decimal), decimal(20,0) BINARY)->Column#15", - " └─IndexMerge 0.00 root ", - " ├─Selection(Build) 0.00 cop[tikv] eq(test.tt1.c_int, test.tt2.c_int)", - " │ └─IndexRangeScan 1.00 cop[tikv] table:tt2, index:c_decimal(c_decimal) range:[9.060000,9.060000], keep order:false, stats:pseudo", - " ├─Selection(Build) 3.32 cop[tikv] eq(test.tt1.c_int, test.tt2.c_int)", - " │ └─IndexRangeScan 3323.33 cop[tikv] table:tt2, index:c_str(c_str) range:[-inf,\"interesting shtern\"], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.00 cop[tikv] or(and(eq(test.tt1.c_int, test.tt2.c_int), and(gt(test.tt1.c_datetime, test.tt2.c_datetime), eq(test.tt2.c_decimal, 9.060))), and(le(test.tt2.c_str, \"interesting shtern\"), eq(test.tt1.c_int, test.tt2.c_int)))", - " └─TableRowIDScan 3.32 cop[tikv] table:tt2 keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:min(Column#14)->Column#9, funcs:sum(Column#15)->Column#10, funcs:count(1)->Column#11", + " └─Projection 11.05 root test.tt2.c_decimal, cast(isnull(test.tt2.c_decimal), decimal(20,0) BINARY)->Column#15", + " └─IndexMerge 11.05 root type: union", + " ├─Selection(Build) 10.00 cop[tikv] eq(test.tt1.c_int, test.tt2.c_int)", + " │ └─IndexRangeScan 10000.00 cop[tikv] table:tt2, index:c_decimal(c_decimal) range:[9.060000,9.060000], keep order:false, stats:pseudo", + " ├─Selection(Build) 33233.33 cop[tikv] eq(test.tt1.c_int, test.tt2.c_int)", + " │ └─IndexRangeScan 33233333.33 cop[tikv] table:tt2, index:c_str(c_str) range:[-inf,\"interesting shtern\"], keep order:false, stats:pseudo", + " └─Selection(Probe) 11.05 cop[tikv] or(and(eq(test.tt1.c_int, test.tt2.c_int), and(gt(test.tt1.c_datetime, test.tt2.c_datetime), eq(test.tt2.c_decimal, 9.060))), and(le(test.tt2.c_str, \"interesting shtern\"), eq(test.tt1.c_int, test.tt2.c_int)))", + " └─TableRowIDScan 33243.33 cop[tikv] table:tt2 keep order:false, stats:pseudo" ], "Res": [ "7", @@ -2388,15 +2391,15 @@ "└─Apply 10000.00 root CARTESIAN inner join, other cond:or(and(gt(test.tt1.c_decimal, Column#9), if(ne(Column#10, 0), NULL, 1)), or(eq(Column#11, 0), if(isnull(test.tt1.c_decimal), NULL, 0)))", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:tt1 keep order:true, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:max(Column#14)->Column#9, funcs:sum(Column#15)->Column#10, funcs:count(1)->Column#11", - " └─Projection 0.00 root test.tt2.c_decimal, cast(isnull(test.tt2.c_decimal), decimal(20,0) BINARY)->Column#15", - " └─IndexMerge 0.00 root ", - " ├─Selection(Build) 1.00 cop[tikv] lt(7, test.tt1.c_decimal)", - " │ └─TableRangeScan 1.00 cop[tikv] table:tt2 range:[7,7], keep order:false, stats:pseudo", - " ├─Selection(Build) 3.33 cop[tikv] eq(test.tt1.c_int, test.tt2.c_int)", - " │ └─IndexRangeScan 3333.33 cop[tikv] table:tt2, index:c_str(c_str) range:[\"zzzzzzzzzzzzzzzzzzz\",+inf], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.00 cop[tikv] or(and(eq(test.tt2.c_int, 7), lt(7, test.tt1.c_decimal)), and(ge(test.tt2.c_str, \"zzzzzzzzzzzzzzzzzzz\"), eq(test.tt1.c_int, test.tt2.c_int)))", - " └─TableRowIDScan 4.33 cop[tikv] table:tt2 keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:max(Column#14)->Column#9, funcs:sum(Column#15)->Column#10, funcs:count(1)->Column#11", + " └─Projection 17.91 root test.tt2.c_decimal, cast(isnull(test.tt2.c_decimal), decimal(20,0) BINARY)->Column#15", + " └─IndexMerge 17.91 root type: union", + " ├─Selection(Build) 10000.00 cop[tikv] lt(7, test.tt1.c_decimal)", + " │ └─TableRangeScan 10000.00 cop[tikv] table:tt2 range:[7,7], keep order:false, stats:pseudo", + " ├─Selection(Build) 33333.33 cop[tikv] eq(test.tt1.c_int, test.tt2.c_int)", + " │ └─IndexRangeScan 33333333.33 cop[tikv] table:tt2, index:c_str(c_str) range:[\"zzzzzzzzzzzzzzzzzzz\",+inf], keep order:false, stats:pseudo", + " └─Selection(Probe) 17.91 cop[tikv] or(and(eq(test.tt2.c_int, 7), lt(7, test.tt1.c_decimal)), and(ge(test.tt2.c_str, \"zzzzzzzzzzzzzzzzzzz\"), eq(test.tt1.c_int, test.tt2.c_int)))", + " └─TableRowIDScan 43330.00 cop[tikv] table:tt2 keep order:false, stats:pseudo" ], "Res": [ "6", @@ -2415,7 +2418,7 @@ "Plan": [ "StreamAgg 1.00 root funcs:count(Column#6)->Column#4", "└─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(test.t31240._tidb_rowid)->Column#6", " └─TableFullScan 10000.00 batchCop[tiflash] table:t31240 keep order:false, stats:pseudo" ] }, @@ -2428,7 +2431,7 @@ "Plan": [ "StreamAgg 1.00 root funcs:count(Column#6)->Column#4", "└─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(1)->Column#6", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(test.t31240._tidb_rowid)->Column#6", " └─TableFullScan 10000.00 batchCop[tiflash] table:t31240 keep order:false, stats:pseudo" ] } @@ -2485,172 +2488,168 @@ { "SQL": "explain format = 'verbose' select count(*) from t3", "Plan": [ - "StreamAgg_20 1.00 12.68 root funcs:count(Column#9)->Column#4", - "└─TableReader_21 1.00 9.68 root data:StreamAgg_8", - " └─StreamAgg_8 1.00 117.00 cop[tikv] funcs:count(1)->Column#9", - " └─TableFullScan_18 3.00 108.00 cop[tikv] table:t3 keep order:false" + "StreamAgg_20 1.00 102.69 root funcs:count(Column#9)->Column#4", + "└─IndexReader_21 1.00 52.79 root index:StreamAgg_8", + " └─StreamAgg_8 1.00 760.20 cop[tikv] funcs:count(1)->Column#9", + " └─IndexFullScan_19 3.00 610.50 cop[tikv] table:t3, index:c(b) keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t2", "Plan": [ - "StreamAgg_26 1.00 8.18 root funcs:count(Column#7)->Column#4", - "└─TableReader_27 1.00 5.17 root data:StreamAgg_10", - " └─StreamAgg_10 1.00 49.50 batchCop[tiflash] funcs:count(1)->Column#7", - " └─TableFullScan_25 3.00 40.50 batchCop[tiflash] table:t2 keep order:false" + "StreamAgg_26 1.00 107.45 root funcs:count(Column#7)->Column#4", + "└─TableReader_27 1.00 57.55 root data:StreamAgg_10", + " └─StreamAgg_10 1.00 831.62 cop[tikv] funcs:count(1)->Column#7", + " └─TableFullScan_24 3.00 681.92 cop[tikv] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by a", "Plan": [ - "Sort_4 3.00 45.85 root test.t3.a", - "└─TableReader_8 3.00 11.78 root data:TableFullScan_7", - " └─TableFullScan_7 3.00 108.00 cop[tikv] table:t3 keep order:false" + "Sort_4 3.00 318.27 root test.t3.a", + "└─TableReader_8 3.00 70.81 root data:TableFullScan_7", + " └─TableFullScan_7 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by b", "Plan": [ - "Sort_4 3.00 45.85 root test.t3.b", - "└─TableReader_8 3.00 11.78 root data:TableFullScan_7", - " └─TableFullScan_7 3.00 108.00 cop[tikv] table:t3 keep order:false" + "Sort_4 3.00 318.27 root test.t3.b", + "└─TableReader_8 3.00 70.81 root data:TableFullScan_7", + " └─TableFullScan_7 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by a limit 1", "Plan": [ - "TopN_7 1.00 13.22 root test.t3.a, offset:0, count:1", - "└─TableReader_16 1.00 10.22 root data:TopN_15", - " └─TopN_15 1.00 117.00 cop[tikv] test.t3.a, offset:0, count:1", - " └─TableFullScan_14 3.00 108.00 cop[tikv] table:t3 keep order:false" + "TopN_7 1.00 53.10 root test.t3.a, offset:0, count:1", + "└─TableReader_16 1.00 49.90 root data:TopN_15", + " └─TopN_15 1.00 685.12 cop[tikv] test.t3.a, offset:0, count:1", + " └─TableFullScan_14 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by b limit 1", "Plan": [ - "TopN_7 1.00 13.22 root test.t3.b, offset:0, count:1", - "└─TableReader_16 1.00 10.22 root data:TopN_15", - " └─TopN_15 1.00 117.00 cop[tikv] test.t3.b, offset:0, count:1", - " └─TableFullScan_14 3.00 108.00 cop[tikv] table:t3 keep order:false" + "TopN_7 1.00 53.10 root test.t3.b, offset:0, count:1", + "└─TableReader_16 1.00 49.90 root data:TopN_15", + " └─TopN_15 1.00 685.12 cop[tikv] test.t3.b, offset:0, count:1", + " └─TableFullScan_14 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t2 group by a", "Plan": [ - "TableReader_44 3.00 4.98 root data:ExchangeSender_43", - "└─ExchangeSender_43 3.00 96.60 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection_38 3.00 76.80 mpp[tiflash] Column#4", - " └─HashAgg_36 3.00 57.00 mpp[tiflash] group by:test.t2.a, funcs:count(1)->Column#4", - " └─ExchangeReceiver_22 3.00 48.00 mpp[tiflash] ", - " └─ExchangeSender_21 3.00 45.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t2.a, collate: binary]", - " └─TableFullScan_20 3.00 45.00 mpp[tiflash] table:t2 keep order:false" + "HashAgg_8 3.00 1706.09 root group by:test.t2.a, funcs:count(1)->Column#4", + "└─TableReader_17 3.00 58.13 root data:TableFullScan_16", + " └─TableFullScan_16 3.00 681.92 cop[tikv] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t3 where b = 0", "Plan": [ - "StreamAgg_10 1.00 1.33 root funcs:count(1)->Column#4", - "└─IndexReader_15 0.00 1.33 root index:IndexRangeScan_14", - " └─IndexRangeScan_14 0.00 0.00 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false" + "StreamAgg_10 1.00 64.98 root funcs:count(1)->Column#4", + "└─IndexReader_15 0.00 15.08 root index:IndexRangeScan_14", + " └─IndexRangeScan_14 0.00 162.80 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false" ] }, { "SQL": "explain format = 'verbose' select /*+ use_index(t3, c) */ count(a) from t3 where b = 0", "Plan": [ - "StreamAgg_10 1.00 19.33 root funcs:count(test.t3.a)->Column#4", - "└─IndexLookUp_17 0.00 19.33 root ", - " ├─IndexRangeScan_15(Build) 0.00 0.00 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false", - " └─TableRowIDScan_16(Probe) 0.00 0.00 cop[tikv] table:t3 keep order:false" + "StreamAgg_10 1.00 2001.63 root funcs:count(test.t3.a)->Column#4", + "└─IndexLookUp_17 0.00 1951.73 root ", + " ├─IndexRangeScan_15(Build) 0.00 203.50 cop[tikv] table:t3, index:c(b) range:[0,0], keep order:false", + " └─TableRowIDScan_16(Probe) 0.00 227.31 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t2 where a = 0", "Plan": [ - "StreamAgg_12 1.00 4.93 root funcs:count(1)->Column#4", - "└─TableReader_24 0.00 4.93 root data:Selection_23", - " └─Selection_23 0.00 54.00 cop[tiflash] eq(test.t2.a, 0)", - " └─TableFullScan_22 3.00 45.00 cop[tiflash] table:t2 keep order:false" + "StreamAgg_12 1.00 109.57 root funcs:count(1)->Column#4", + "└─TableReader_21 0.00 59.67 root data:Selection_20", + " └─Selection_20 0.00 831.62 cop[tikv] eq(test.t2.a, 0)", + " └─TableFullScan_19 3.00 681.92 cop[tikv] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t3 t join t3 on t.a = t3.b", "Plan": [ - "StreamAgg_10 1.00 60.22 root funcs:count(1)->Column#7", - "└─HashJoin_40 3.00 51.22 root inner join, equal:[eq(test.t3.a, test.t3.b)]", - " ├─IndexReader_28(Build) 3.00 11.66 root index:IndexFullScan_27", - " │ └─IndexFullScan_27 3.00 130.50 cop[tikv] table:t3, index:c(b) keep order:false", - " └─TableReader_26(Probe) 3.00 10.76 root data:Selection_25", - " └─Selection_25 3.00 117.00 cop[tikv] not(isnull(test.t3.a))", - " └─TableFullScan_24 3.00 108.00 cop[tikv] table:t keep order:false" - ] - }, - { - "SQL": "explain format = 'verbose' select count(*) from t1 join t2 on t1.a = t2.a", - "Plan": [ - "StreamAgg_15 1.00 18.93 root funcs:count(1)->Column#7", - "└─TableReader_47 3.00 9.93 root data:ExchangeSender_46", - " └─ExchangeSender_46 3.00 195.38 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin_43 3.00 195.38 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─ExchangeReceiver_22(Build) 3.00 57.00 mpp[tiflash] ", - " │ └─ExchangeSender_21 3.00 54.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Selection_20 3.00 54.00 mpp[tiflash] not(isnull(test.t1.a))", - " │ └─TableFullScan_19 3.00 45.00 mpp[tiflash] table:t1 keep order:false", - " └─Selection_24(Probe) 3.00 54.00 mpp[tiflash] not(isnull(test.t2.a))", - " └─TableFullScan_23 3.00 45.00 mpp[tiflash] table:t2 keep order:false" - ] - }, - { - "SQL": "explain format = 'verbose' select count(*) from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b", - "Plan": [ - "StreamAgg_15 1.00 60.60 root funcs:count(1)->Column#10", - "└─HashJoin_65 3.00 51.60 root inner join, equal:[eq(test.t1.b, test.t3.b)]", - " ├─IndexReader_53(Build) 3.00 11.66 root index:IndexFullScan_52", - " │ └─IndexFullScan_52 3.00 130.50 cop[tikv] table:t3, index:c(b) keep order:false", - " └─TableReader_39(Probe) 3.00 11.14 root data:ExchangeSender_38", - " └─ExchangeSender_38 3.00 204.38 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin_29 3.00 204.38 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─ExchangeReceiver_35(Build) 3.00 66.00 mpp[tiflash] ", - " │ └─ExchangeSender_34 3.00 63.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Selection_33 3.00 63.00 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan_32 3.00 54.00 mpp[tiflash] table:t1 keep order:false", - " └─Selection_37(Probe) 3.00 54.00 mpp[tiflash] not(isnull(test.t2.a))", - " └─TableFullScan_36 3.00 45.00 mpp[tiflash] table:t2 keep order:false" - ] - }, - { - "SQL": "explain format = 'verbose' select (2) in (select count(*) from t1) from (select t.b < (select t.b from t2 limit 1 ) from t3 t) t", - "Plan": [ - "HashJoin_19 3.00 127.40 root CARTESIAN left outer semi join", - "├─Selection_39(Build) 0.80 11.18 root eq(2, Column#18)", - "│ └─StreamAgg_61 1.00 8.18 root funcs:count(Column#32)->Column#18", - "│ └─TableReader_62 1.00 5.17 root data:StreamAgg_45", - "│ └─StreamAgg_45 1.00 49.50 batchCop[tiflash] funcs:count(1)->Column#32", - "│ └─TableFullScan_60 3.00 40.50 batchCop[tiflash] table:t1 keep order:false", - "└─Projection_20(Probe) 3.00 95.82 root 1->Column#28", - " └─Apply_22 3.00 76.02 root CARTESIAN left outer join", - " ├─TableReader_24(Build) 3.00 10.16 root data:TableFullScan_23", - " │ └─TableFullScan_23 3.00 108.00 cop[tikv] table:t keep order:false", - " └─Projection_27(Probe) 1.00 21.95 root 1->Column#26", - " └─Limit_30 1.00 3.35 root offset:0, count:1", - " └─TableReader_38 1.00 3.35 root data:ExchangeSender_37", - " └─ExchangeSender_37 1.00 19.50 mpp[tiflash] ExchangeType: PassThrough", - " └─Limit_36 1.00 19.50 mpp[tiflash] offset:0, count:1", - " └─TableFullScan_35 1.00 19.50 mpp[tiflash] table:t2 keep order:false" - ] - }, - { - "SQL": "explain format = 'verbose' select /*+ merge_join(t1) */ count(*) from t1 join t2 on t1.a = t2.a", - "Plan": [ - "StreamAgg_14 1.00 59.65 root funcs:count(1)->Column#7", - "└─MergeJoin_32 3.00 50.65 root inner join, left key:test.t1.a, right key:test.t2.a", - " ├─Sort_30(Build) 3.00 20.83 root test.t2.a", - " │ └─TableReader_29 3.00 6.56 root data:Selection_28", - " │ └─Selection_28 3.00 54.00 cop[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan_27 3.00 45.00 cop[tiflash] table:t2 keep order:false", - " └─Sort_23(Probe) 3.00 20.83 root test.t1.a", - " └─TableReader_22 3.00 6.56 root data:Selection_21", - " └─Selection_21 3.00 54.00 cop[tiflash] not(isnull(test.t1.a))", - " └─TableFullScan_20 3.00 45.00 cop[tiflash] table:t1 keep order:false" + "StreamAgg_10 1.00 2128.93 root funcs:count(1)->Column#7", + "└─HashJoin_40 3.00 1979.23 root inner join, equal:[eq(test.t3.a, test.t3.b)]", + " ├─IndexReader_28(Build) 3.00 45.23 root index:IndexFullScan_27", + " │ └─IndexFullScan_27 3.00 488.40 cop[tikv] table:t3, index:c(b) keep order:false", + " └─TableReader_26(Probe) 3.00 68.11 root data:Selection_25", + " └─Selection_25 3.00 831.62 cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan_24 3.00 681.92 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a", + "Plan": [ + "StreamAgg_15 1.00 62053.22 root funcs:count(1)->Column#7", + "└─TableReader_41 3.00 61903.52 root data:ExchangeSender_40", + " └─ExchangeSender_40 3.00 928447.20 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_37 3.00 928447.20 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─ExchangeReceiver_22(Build) 3.00 464290.40 mpp[tiflash] ", + " │ └─ExchangeSender_21 3.00 464146.40 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection_20 3.00 464146.40 mpp[tiflash] not(isnull(test.t1.a))", + " │ └─TableFullScan_19 3.00 464139.20 mpp[tiflash] table:t1 keep order:false", + " └─Selection_24(Probe) 3.00 464146.40 mpp[tiflash] not(isnull(test.t2.a))", + " └─TableFullScan_23 3.00 464139.20 mpp[tiflash] table:t2 keep order:false" + ] + }, + { + "SQL": "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b", + "Plan": [ + "StreamAgg_15 1.00 71713.64 root funcs:count(1)->Column#10", + "└─HashJoin_59 3.00 71563.94 root inner join, equal:[eq(test.t1.b, test.t3.b)]", + " ├─IndexReader_47(Build) 3.00 45.23 root index:IndexFullScan_46", + " │ └─IndexFullScan_46 3.00 488.40 cop[tikv] table:t3, index:c(b) keep order:false", + " └─TableReader_39(Probe) 3.00 69652.83 root data:ExchangeSender_38", + " └─ExchangeSender_38 3.00 1044634.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_29 3.00 1044634.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─ExchangeReceiver_35(Build) 3.00 580476.40 mpp[tiflash] ", + " │ └─ExchangeSender_34 3.00 580188.40 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection_33 3.00 580188.40 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan_32 3.00 580174.00 mpp[tiflash] table:t1 keep order:false", + " └─Selection_37(Probe) 3.00 464146.40 mpp[tiflash] not(isnull(test.t2.a))", + " └─TableFullScan_36 3.00 464139.20 mpp[tiflash] table:t2 keep order:false" + ] + }, + { + "SQL": "explain format = 'verbose' select (2) in (select /*+ read_from_storage(tiflash[t1]) */ count(*) from t1) from (select t.b < (select /*+ read_from_storage(tiflash[t2]) */ t.b from t2 limit 1 ) from t3 t) t", + "Plan": [ + "HashJoin_19 3.00 162261.76 root CARTESIAN left outer semi join", + "├─Selection_38(Build) 0.80 31045.01 root eq(2, Column#18)", + "│ └─StreamAgg_56 1.00 30995.11 root funcs:count(Column#32)->Column#18", + "│ └─TableReader_57 1.00 30945.21 root data:StreamAgg_44", + "│ └─StreamAgg_44 1.00 464146.40 batchCop[tiflash] funcs:count(test.t1._tidb_rowid)->Column#32", + "│ └─TableFullScan_55 3.00 464139.20 batchCop[tiflash] table:t1 keep order:false", + "└─Projection_20(Probe) 3.00 129648.62 root 1->Column#28", + " └─Apply_22 3.00 129648.32 root CARTESIAN left outer join", + " ├─IndexReader_26(Build) 3.00 53.37 root index:IndexFullScan_25", + " │ └─IndexFullScan_25 3.00 610.50 cop[tikv] table:t, index:c(b) keep order:false", + " └─Projection_27(Probe) 3.00 43198.32 root 1->Column#26", + " └─Limit_30 3.00 43198.22 root offset:0, count:1", + " └─TableReader_37 3.00 43198.22 root data:ExchangeSender_36", + " └─ExchangeSender_36 3.00 647920.44 mpp[tiflash] ExchangeType: PassThrough", + " └─Limit_35 3.00 647920.44 mpp[tiflash] offset:0, count:1", + " └─TableFullScan_34 3.00 647920.44 mpp[tiflash] table:t2 keep order:false" + ] + }, + { + "SQL": "explain format = 'verbose' select /*+ merge_join(t1), read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a", + "Plan": [ + "StreamAgg_14 1.00 62557.96 root funcs:count(1)->Column#7", + "└─MergeJoin_26 3.00 62408.26 root inner join, left key:test.t1.a, right key:test.t2.a", + " ├─Sort_24(Build) 3.00 31202.63 root test.t2.a", + " │ └─TableReader_23 3.00 30955.77 root data:Selection_22", + " │ └─Selection_22 3.00 464146.40 cop[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan_21 3.00 464139.20 cop[tiflash] table:t2 keep order:false", + " └─Sort_20(Probe) 3.00 31202.63 root test.t1.a", + " └─TableReader_19 3.00 30955.77 root data:Selection_18", + " └─Selection_18 3.00 464146.40 cop[tiflash] not(isnull(test.t1.a))", + " └─TableFullScan_17 3.00 464139.20 cop[tiflash] table:t1 keep order:false" ] } ] @@ -3196,47 +3195,44 @@ { "SQL": "explain format = 'brief' select count(*) from fact_t join d1_t on fact_t.d1_k > d1_t.d1_k", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#12)->Column#11", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#12", - " └─HashJoin 16.00 mpp[tiflash] CARTESIAN inner join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)", - " ├─ExchangeReceiver(Build) 2.00 mpp[tiflash] ", - " │ └─ExchangeSender 2.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Selection 2.00 mpp[tiflash] not(isnull(test.d1_t.d1_k))", - " │ └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false", - " └─Selection(Probe) 8.00 mpp[tiflash] not(isnull(test.fact_t.d1_k))", - " └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false" + "StreamAgg 1.00 root funcs:count(1)->Column#11", + "└─TableReader 16.00 root data:ExchangeSender", + " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 16.00 mpp[tiflash] CARTESIAN inner join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)", + " ├─ExchangeReceiver(Build) 2.00 mpp[tiflash] ", + " │ └─ExchangeSender 2.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 2.00 mpp[tiflash] not(isnull(test.d1_t.d1_k))", + " │ └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false", + " └─Selection(Probe) 8.00 mpp[tiflash] not(isnull(test.fact_t.d1_k))", + " └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false" ] }, { "SQL": "explain format = 'brief' select count(*) from fact_t left join d1_t on fact_t.d1_k > d1_t.d1_k", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#12)->Column#11", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#12", - " └─HashJoin 16.00 mpp[tiflash] CARTESIAN left outer join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)", - " ├─ExchangeReceiver(Build) 2.00 mpp[tiflash] ", - " │ └─ExchangeSender 2.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Selection 2.00 mpp[tiflash] not(isnull(test.d1_t.d1_k))", - " │ └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false", - " └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false" + "StreamAgg 1.00 root funcs:count(1)->Column#11", + "└─TableReader 16.00 root data:ExchangeSender", + " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 16.00 mpp[tiflash] CARTESIAN left outer join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)", + " ├─ExchangeReceiver(Build) 2.00 mpp[tiflash] ", + " │ └─ExchangeSender 2.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 2.00 mpp[tiflash] not(isnull(test.d1_t.d1_k))", + " │ └─TableFullScan 2.00 mpp[tiflash] table:d1_t keep order:false", + " └─TableFullScan(Probe) 8.00 mpp[tiflash] table:fact_t keep order:false" ] }, { "SQL": "explain format = 'brief' select count(*) from fact_t right join d1_t on fact_t.d1_k > d1_t.d1_k", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#12)->Column#11", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#12", - " └─HashJoin 16.00 mpp[tiflash] CARTESIAN right outer join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)", - " ├─ExchangeReceiver(Build) 8.00 mpp[tiflash] ", - " │ └─ExchangeSender 8.00 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Selection 8.00 mpp[tiflash] not(isnull(test.fact_t.d1_k))", - " │ └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false", - " └─TableFullScan(Probe) 2.00 mpp[tiflash] table:d1_t keep order:false" + "StreamAgg 1.00 root funcs:count(1)->Column#11", + "└─TableReader 16.00 root data:ExchangeSender", + " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 16.00 mpp[tiflash] CARTESIAN right outer join, other cond:gt(test.fact_t.d1_k, test.d1_t.d1_k)", + " ├─ExchangeReceiver(Build) 8.00 mpp[tiflash] ", + " │ └─ExchangeSender 8.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 8.00 mpp[tiflash] not(isnull(test.fact_t.d1_k))", + " │ └─TableFullScan 8.00 mpp[tiflash] table:fact_t keep order:false", + " └─TableFullScan(Probe) 2.00 mpp[tiflash] table:d1_t keep order:false" ] }, { @@ -3846,69 +3842,65 @@ { "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select 1 from d1_t where d1_k = fact_t.d1_k)", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#13)->Column#12", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#13", - " └─HashJoin 12.80 mpp[tiflash] semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]", - " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", - " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", - " │ └─Selection 4.00 mpp[tiflash] not(isnull(test.d1_t.d1_k))", - " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", - " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", - " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", - " └─Selection 16.00 mpp[tiflash] not(isnull(test.fact_t.d1_k))", - " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" + "StreamAgg 1.00 root funcs:count(1)->Column#12", + "└─TableReader 12.80 root data:ExchangeSender", + " └─ExchangeSender 12.80 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12.80 mpp[tiflash] semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]", + " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", + " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", + " │ └─Selection 4.00 mpp[tiflash] not(isnull(test.d1_t.d1_k))", + " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", + " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", + " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", + " └─Selection 16.00 mpp[tiflash] not(isnull(test.fact_t.d1_k))", + " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" ] }, { "SQL": "explain format = 'brief' select count(*) from fact_t where exists (select 1 from d1_t where d1_k = fact_t.d1_k and value > fact_t.col1)", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#13)->Column#12", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#13", - " └─HashJoin 12.80 mpp[tiflash] semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)", - " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", - " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", - " │ └─Selection 4.00 mpp[tiflash] not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))", - " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", - " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", - " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", - " └─Selection 16.00 mpp[tiflash] not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))", - " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" + "StreamAgg 1.00 root funcs:count(1)->Column#12", + "└─TableReader 12.80 root data:ExchangeSender", + " └─ExchangeSender 12.80 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12.80 mpp[tiflash] semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)", + " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", + " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", + " │ └─Selection 4.00 mpp[tiflash] not(isnull(test.d1_t.d1_k)), not(isnull(test.d1_t.value))", + " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", + " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", + " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", + " └─Selection 16.00 mpp[tiflash] not(isnull(test.fact_t.col1)), not(isnull(test.fact_t.d1_k))", + " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" ] }, { "SQL": "explain format = 'brief' select count(*) from fact_t where not exists (select 1 from d1_t where d1_k = fact_t.d1_k)", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#13)->Column#12", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#13", - " └─HashJoin 12.80 mpp[tiflash] anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]", - " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", - " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", - " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", - " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", - " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", - " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" + "StreamAgg 1.00 root funcs:count(1)->Column#12", + "└─TableReader 12.80 root data:ExchangeSender", + " └─ExchangeSender 12.80 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12.80 mpp[tiflash] anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)]", + " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", + " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", + " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", + " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", + " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", + " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" ] }, { "SQL": "explain format = 'brief' select count(*) from fact_t where not exists (select 1 from d1_t where d1_k = fact_t.d1_k and value > fact_t.col1)", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#13)->Column#12", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#13", - " └─HashJoin 12.80 mpp[tiflash] anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)", - " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", - " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", - " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", - " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", - " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", - " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" + "StreamAgg 1.00 root funcs:count(1)->Column#12", + "└─TableReader 12.80 root data:ExchangeSender", + " └─ExchangeSender 12.80 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12.80 mpp[tiflash] anti semi join, equal:[eq(test.fact_t.d1_k, test.d1_t.d1_k)], other cond:gt(test.d1_t.value, test.fact_t.col1)", + " ├─ExchangeReceiver(Build) 4.00 mpp[tiflash] ", + " │ └─ExchangeSender 4.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.d1_t.d1_k, collate: binary]", + " │ └─TableFullScan 4.00 mpp[tiflash] table:d1_t keep order:false", + " └─ExchangeReceiver(Probe) 16.00 mpp[tiflash] ", + " └─ExchangeSender 16.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.fact_t.d1_k, collate: binary]", + " └─TableFullScan 16.00 mpp[tiflash] table:fact_t keep order:false" ] } ] @@ -3946,18 +3938,19 @@ "TableReader 2.00 root data:ExchangeSender", "└─ExchangeSender 2.00 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 2.00 mpp[tiflash] Column#9, test.t2.v1, test.t2.v2", - " └─HashAgg 2.00 mpp[tiflash] group by:test.t2.v1, test.t2.v2, funcs:count(1)->Column#9, funcs:firstrow(test.t2.v1)->test.t2.v1, funcs:firstrow(test.t2.v2)->test.t2.v2", + " └─HashAgg 2.00 mpp[tiflash] group by:test.t2.v1, test.t2.v2, funcs:sum(Column#22)->Column#9, funcs:firstrow(test.t2.v1)->test.t2.v1, funcs:firstrow(test.t2.v2)->test.t2.v2", " └─ExchangeReceiver 2.00 mpp[tiflash] ", " └─ExchangeSender 2.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t2.v1, collate: binary], [name: test.t2.v2, collate: binary]", - " └─HashJoin 2.00 mpp[tiflash] left outer join, equal:[eq(test.t1.v1, test.t2.v1) eq(test.t1.v2, test.t2.v2)]", - " ├─ExchangeReceiver(Build) 2.00 mpp[tiflash] ", - " │ └─ExchangeSender 2.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.v1, collate: binary], [name: test.t1.v2, collate: binary]", - " │ └─TableFullScan 2.00 mpp[tiflash] table:t1 keep order:false", - " └─ExchangeReceiver(Probe) 8.00 mpp[tiflash] ", - " └─ExchangeSender 8.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#12, collate: binary], [name: Column#13, collate: binary]", - " └─Projection 8.00 mpp[tiflash] test.t2.v1, test.t2.v2, cast(test.t2.v1, decimal(20,2))->Column#12, cast(test.t2.v2, decimal(20,2))->Column#13", - " └─Selection 8.00 mpp[tiflash] not(isnull(test.t2.v1)), not(isnull(test.t2.v2))", - " └─TableFullScan 8.00 mpp[tiflash] table:t2 keep order:false" + " └─HashAgg 2.00 mpp[tiflash] group by:test.t2.v1, test.t2.v2, funcs:count(1)->Column#22", + " └─HashJoin 2.00 mpp[tiflash] left outer join, equal:[eq(test.t1.v1, test.t2.v1) eq(test.t1.v2, test.t2.v2)]", + " ├─ExchangeReceiver(Build) 2.00 mpp[tiflash] ", + " │ └─ExchangeSender 2.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.v1, collate: binary], [name: test.t1.v2, collate: binary]", + " │ └─TableFullScan 2.00 mpp[tiflash] table:t1 keep order:false", + " └─ExchangeReceiver(Probe) 8.00 mpp[tiflash] ", + " └─ExchangeSender 8.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#14, collate: binary], [name: Column#15, collate: binary]", + " └─Projection 8.00 mpp[tiflash] test.t2.v1, test.t2.v2, cast(test.t2.v1, decimal(20,2))->Column#14, cast(test.t2.v2, decimal(20,2))->Column#15", + " └─Selection 8.00 mpp[tiflash] not(isnull(test.t2.v1)), not(isnull(test.t2.v2))", + " └─TableFullScan 8.00 mpp[tiflash] table:t2 keep order:false" ] }, { @@ -4187,9 +4180,9 @@ { "SQL": "desc format = 'brief' select avg(a) from t", "Plan": [ - "StreamAgg 1.00 root funcs:avg(Column#7, Column#8)->Column#4", - "└─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(Column#9)->Column#7, funcs:sum(Column#10)->Column#8", + "HashAgg 1.00 root funcs:avg(Column#5, Column#6)->Column#4", + "└─TableReader 1.00 root data:HashAgg", + " └─HashAgg 1.00 batchCop[tiflash] funcs:count(Column#9)->Column#5, funcs:sum(Column#10)->Column#6", " └─Projection 10000.00 batchCop[tiflash] test.t.a, cast(test.t.a, decimal(10,0) BINARY)->Column#10", " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ], @@ -4198,9 +4191,9 @@ { "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ avg(a) from t", "Plan": [ - "StreamAgg 1.00 root funcs:avg(Column#7, Column#8)->Column#4", - "└─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(Column#9)->Column#7, funcs:sum(Column#10)->Column#8", + "HashAgg 1.00 root funcs:avg(Column#5, Column#6)->Column#4", + "└─TableReader 1.00 root data:HashAgg", + " └─HashAgg 1.00 batchCop[tiflash] funcs:count(Column#9)->Column#5, funcs:sum(Column#10)->Column#6", " └─Projection 10000.00 batchCop[tiflash] test.t.a, cast(test.t.a, decimal(10,0) BINARY)->Column#10", " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ], @@ -4269,7 +4262,7 @@ "SQL": "desc format = 'brief' select * from tt where (tt.a > 1 and tt.a < 20) or (tt.a >= 30 and tt.a < 55)", "Plan": [ "TableReader 44.00 root data:TableRangeScan", - "└─TableRangeScan 44.00 cop[tiflash] table:tt range:(1,20), [30,55), keep order:false, stats:pseudo" + "└─TableRangeScan 44.00 cop[tikv] table:tt range:(1,20), [30,55), keep order:false, stats:pseudo" ], "Warn": null }, @@ -4329,215 +4322,2604 @@ ] }, { - "Name": "TestReadFromStorageHintAndIsolationRead", + "Name": "TestKeepOrderHint", "Cases": [ { - "SQL": "desc format = 'brief' select /*+ read_from_storage(tikv[t], tiflash[t]) */ avg(a) from t", + "SQL": "explain select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", "Plan": [ - "StreamAgg 1.00 root funcs:avg(Column#7, Column#8)->Column#4", - "└─IndexReader 1.00 root index:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(test.t.a)->Column#7, funcs:sum(test.t.a)->Column#8", - " └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo" + "Limit_12 1.00 root offset:0, count:1", + "└─Projection_17 1.00 root test.t1.a, test.t1.b", + " └─IndexLookUp_16 1.00 root ", + " ├─Limit_15(Build) 1.00 cop[tikv] offset:0, count:1", + " │ └─IndexRangeScan_13 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:true, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], - "Warn": [ - "[planner:1815]Storage hints are conflict, you can only specify one storage type of table test.t" - ] + "Warn": null }, { - "SQL": "desc format = 'brief' select /*+ read_from_storage(tikv[t]) */ avg(a) from t", + "SQL": "explain select /*+ keep_order(t, primary) */ * from t where a<10 order by a limit 1;", "Plan": [ - "StreamAgg 1.00 root funcs:avg(Column#7, Column#8)->Column#4", - "└─IndexReader 1.00 root index:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(test.t.a)->Column#7, funcs:sum(test.t.a)->Column#8", - " └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo" + "Limit_11 1.00 root offset:0, count:1", + "└─TableReader_15 1.00 root data:Limit_14", + " └─Limit_14 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_13 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" ], "Warn": null }, { - "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ avg(a) from t", + "SQL": "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", "Plan": [ - "StreamAgg 1.00 root funcs:avg(Column#7, Column#8)->Column#4", - "└─IndexReader 1.00 root index:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(test.t.a)->Column#7, funcs:sum(test.t.a)->Column#8", - " └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo" + "TopN_9 1.00 root test.t1.a, offset:0, count:1", + "└─IndexLookUp_16 1.00 root ", + " ├─TopN_15(Build) 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " │ └─IndexRangeScan_13 3323.33 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t, primary) */ * from t where a<10 order by a limit 1;", + "Plan": [ + "TopN_8 1.00 root test.t.a, offset:0, count:1", + "└─TableReader_15 1.00 root data:TopN_14", + " └─TopN_14 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_13 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 limit 1;", + "Plan": [ + "IndexLookUp_13 1.00 root limit embedded(offset:0, count:1)", + "├─Limit_12(Build) 1.00 cop[tikv] offset:0, count:1", + "│ └─IndexRangeScan_10 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + "└─TableRowIDScan_11(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t, primary) */ * from t where a<10 limit 1;", + "Plan": [ + "Limit_8 1.00 root offset:0, count:1", + "└─TableReader_12 1.00 root data:Limit_11", + " └─Limit_11 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_10 333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ keep_order(t1, idx_b) */ * from t1 where b<10 order by b limit 1;", + "Plan": [ + "TopN_8 1.00 root test.t1.b, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t1.b, offset:0, count:1", + " └─Selection_14 3323.33 cop[tikv] lt(test.t1.b, 10)", + " └─TableFullScan_13 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": [ - "[planner:1815]No available path for table test.t with the store type tiflash of the hint /*+ read_from_storage */, please check the status of the table replica and variable value of tidb_isolation_read_engines(map[0:{}])" + "[planner:1176]Key 'idx_b' doesn't exist in table 't1'" ] - } - ] - }, - { - "Name": "TestIsolationReadDoNotFilterSystemDB", - "Cases": [ + }, { - "SQL": "desc format = 'brief' select * from metrics_schema.tidb_query_duration where time >= '2019-12-23 16:10:13' and time <= '2019-12-23 16:30:13'", + "SQL": "explain select /*+ keep_order(t, idx_b) */ * from t where b<10 order by b limit 1;", "Plan": [ - "MemTableScan 10000.00 root table:tidb_query_duration PromQL:histogram_quantile(0.9, sum(rate(tidb_server_handle_query_duration_seconds_bucket{}[60s])) by (le,sql_type,instance)), start_time:2019-12-23 16:10:13, end_time:2019-12-23 16:30:13, step:1m0s" + "TopN_8 1.00 root test.t.b, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t.b, offset:0, count:1", + " └─Selection_14 3323.33 cop[tikv] lt(test.t.b, 10)", + " └─TableFullScan_13 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1176]Key 'idx_b' doesn't exist in table 't'" ] }, { - "SQL": "desc format = 'brief' select * from information_schema.tables", + "SQL": "explain select /*+ no_keep_order(t1, idx_b) */ * from t1 where b<10 order by b limit 1;", "Plan": [ - "MemTableScan 10000.00 root table:TABLES " + "TopN_8 1.00 root test.t1.b, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t1.b, offset:0, count:1", + " └─Selection_14 3323.33 cop[tikv] lt(test.t1.b, 10)", + " └─TableFullScan_13 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1176]Key 'idx_b' doesn't exist in table 't1'" ] }, { - "SQL": "desc format = 'brief' select * from mysql.stats_meta", + "SQL": "explain select /*+ no_keep_order(t, idx_b) */ * from t where b<10 order by b limit 1;", "Plan": [ - "TableReader 10000.00 root data:TableFullScan", - "└─TableFullScan 10000.00 cop[tikv] table:stats_meta keep order:false, stats:pseudo" + "TopN_8 1.00 root test.t.b, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t.b, offset:0, count:1", + " └─Selection_14 3323.33 cop[tikv] lt(test.t.b, 10)", + " └─TableFullScan_13 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1176]Key 'idx_b' doesn't exist in table 't'" ] - } - ] - }, - { - "Name": "TestIsolationReadTiFlashNotChoosePointGet", - "Cases": [ + }, { - "SQL": "explain format = 'brief' select * from t where t.a = 1", - "Result": [ - "TableReader 1.00 root data:ExchangeSender", - "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─TableRangeScan 1.00 mpp[tiflash] table:t range:[1,1], keep order:false, stats:pseudo" - ] + "SQL": "explain select /*+ keep_order(t1, idx_a) use_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "Plan": [ + "Limit_12 1.00 root offset:0, count:1", + "└─Projection_19 1.00 root test.t1.a, test.t1.b", + " └─IndexLookUp_18 1.00 root ", + " ├─Limit_17(Build) 1.00 cop[tikv] offset:0, count:1", + " │ └─IndexRangeScan_13 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:true, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null }, { - "SQL": "explain format = 'brief' select * from t where t.a in (1, 2)", - "Result": [ - "TableReader 2.00 root data:ExchangeSender", - "└─ExchangeSender 2.00 mpp[tiflash] ExchangeType: PassThrough", - " └─TableRangeScan 2.00 mpp[tiflash] table:t range:[1,1], [2,2], keep order:false, stats:pseudo" - ] - } - ] - }, - { - "Name": "TestIsolationReadTiFlashUseIndexHint", - "Cases": [ + "SQL": "explain select /*+ keep_order(t1, idx_a) */ * from t1 use index(idx_a) where a<10 order by a limit 1;", + "Plan": [ + "Limit_12 1.00 root offset:0, count:1", + "└─Projection_19 1.00 root test.t1.a, test.t1.b", + " └─IndexLookUp_18 1.00 root ", + " ├─Limit_17(Build) 1.00 cop[tikv] offset:0, count:1", + " │ └─IndexRangeScan_13 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:true, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, { - "SQL": "explain format = 'brief' select * from t", + "SQL": "explain select /*+ keep_order(t1, idx_a) force_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", "Plan": [ - "TableReader 10000.00 root data:ExchangeSender", - "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "Limit_12 1.00 root offset:0, count:1", + "└─Projection_19 1.00 root test.t1.a, test.t1.b", + " └─IndexLookUp_18 1.00 root ", + " ├─Limit_17(Build) 1.00 cop[tikv] offset:0, count:1", + " │ └─IndexRangeScan_13 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:true, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": null }, { - "SQL": "explain format = 'brief' select * from t use index();", + "SQL": "explain select /*+ keep_order(t1, idx_a) */ * from t1 force index(idx_a) where a<10 order by a limit 1;", "Plan": [ - "TableReader 10000.00 root data:ExchangeSender", - "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "Limit_12 1.00 root offset:0, count:1", + "└─Projection_19 1.00 root test.t1.a, test.t1.b", + " └─IndexLookUp_18 1.00 root ", + " ├─Limit_17(Build) 1.00 cop[tikv] offset:0, count:1", + " │ └─IndexRangeScan_13 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:true, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": null }, { - "SQL": "explain format = 'brief' select /*+ use_index(t, idx)*/ * from t", + "SQL": "explain select /*+ keep_order(t1, idx_a) ignore_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", "Plan": [ - "TableReader 10000.00 root data:ExchangeSender", - "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "TopN_8 1.00 root test.t1.a, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " └─Selection_14 3323.33 cop[tikv] lt(test.t1.a, 10)", + " └─TableFullScan_13 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], - "Warn": [ - "TiDB doesn't support index in the isolation read engines(value: 'tiflash')" - ] + "Warn": null }, { - "SQL": "explain format = 'brief' select /*+ use_index(t)*/ * from t", + "SQL": "explain select /*+ keep_order(t, primary) use_index(t, primary) */ * from t where a<10 order by a limit 1;", "Plan": [ - "TableReader 10000.00 root data:ExchangeSender", - "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "Limit_11 1.00 root offset:0, count:1", + "└─TableReader_16 1.00 root data:Limit_15", + " └─Limit_15 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_13 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" ], "Warn": null - } - ] - }, - { - "Name": "TestIssue20710", - "Cases": [ + }, { - "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.b", + "SQL": "explain select /*+ keep_order(t, primary) */ * from t use index(primary) where a<10 order by a limit 1;", "Plan": [ - "IndexJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)", - "├─TableReader(Build) 9980.01 root data:Selection", - "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.s.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.s.b))", - " └─TableRowIDScan 1.25 cop[tikv] table:s keep order:false, stats:pseudo" - ] + "Limit_11 1.00 root offset:0, count:1", + "└─TableReader_16 1.00 root data:Limit_15", + " └─Limit_15 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_13 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" + ], + "Warn": null }, { - "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.a", + "SQL": "explain select /*+ keep_order(t, primary) force_index(t, primary) */ * from t where a<10 order by a limit 1;", "Plan": [ - "IndexJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)", - "├─TableReader(Build) 9980.01 root data:Selection", - "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.s.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:s keep order:false, stats:pseudo" - ] + "Limit_11 1.00 root offset:0, count:1", + "└─TableReader_16 1.00 root data:Limit_15", + " └─Limit_15 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_13 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" + ], + "Warn": null }, { - "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.a = s.b", + "SQL": "explain select /*+ keep_order(t, primary) */ * from t force index(primary) where a<10 order by a limit 1;", "Plan": [ - "IndexJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)", - "├─TableReader(Build) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.s.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.s.b))", - " └─TableRowIDScan 1.25 cop[tikv] table:s keep order:false, stats:pseudo" - ] + "Limit_11 1.00 root offset:0, count:1", + "└─TableReader_16 1.00 root data:Limit_15", + " └─Limit_15 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_13 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" + ], + "Warn": null }, { - "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.b", + "SQL": "explain select /*+ keep_order(t, primary) ignore_index(t, primary) */ * from t where a<10 order by a limit 1;", "Plan": [ - "IndexHashJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)", - "├─TableReader(Build) 9980.01 root data:Selection", - "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.s.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.s.b))", - " └─TableRowIDScan 1.25 cop[tikv] table:s keep order:false, stats:pseudo" - ] + "Limit_11 1.00 root offset:0, count:1", + "└─TableReader_15 1.00 root data:Limit_14", + " └─Limit_14 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_13 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" + ], + "Warn": null }, { - "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.a", + "SQL": "explain select /*+ no_keep_order(t, primary) use_index(t, primary) */ * from t where a<10 order by a limit 1;", "Plan": [ - "IndexHashJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)", - "├─TableReader(Build) 9980.01 root data:Selection", - "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.s.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:s keep order:false, stats:pseudo" - ] + "TopN_8 1.00 root test.t.a, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_13 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null }, { - "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.a = s.b", + "SQL": "explain select /*+ no_keep_order(t, primary) */ * from t use index(primary) where a<10 order by a limit 1;", "Plan": [ - "IndexHashJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)", - "├─TableReader(Build) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + "TopN_8 1.00 root test.t.a, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_13 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t, primary) force_index(t, primary) */ * from t where a<10 order by a limit 1;", + "Plan": [ + "TopN_8 1.00 root test.t.a, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_13 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t, primary) */ * from t force index(primary) where a<10 order by a limit 1;", + "Plan": [ + "TopN_8 1.00 root test.t.a, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_13 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t, primary) ignore_index(t, primary) */ * from t where a<10 order by a limit 1;", + "Plan": [ + "TopN_8 1.00 root test.t.a, offset:0, count:1", + "└─TableReader_15 1.00 root data:TopN_14", + " └─TopN_14 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_13 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t1, idx_a) use_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "Plan": [ + "TopN_9 1.00 root test.t1.a, offset:0, count:1", + "└─IndexLookUp_18 1.00 root ", + " ├─TopN_17(Build) 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " │ └─IndexRangeScan_13 3323.33 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 use index(idx_a) where a<10 order by a limit 1;", + "Plan": [ + "TopN_9 1.00 root test.t1.a, offset:0, count:1", + "└─IndexLookUp_18 1.00 root ", + " ├─TopN_17(Build) 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " │ └─IndexRangeScan_13 3323.33 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t1, idx_a) force_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "Plan": [ + "TopN_9 1.00 root test.t1.a, offset:0, count:1", + "└─IndexLookUp_18 1.00 root ", + " ├─TopN_17(Build) 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " │ └─IndexRangeScan_13 3323.33 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t1, idx_a) */ * from t1 force index(idx_a) where a<10 order by a limit 1;", + "Plan": [ + "TopN_9 1.00 root test.t1.a, offset:0, count:1", + "└─IndexLookUp_18 1.00 root ", + " ├─TopN_17(Build) 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " │ └─IndexRangeScan_13 3323.33 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + " └─TableRowIDScan_14(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ no_keep_order(t1, idx_a) ignore_index(t1, idx_a) */ * from t1 where a<10 order by a limit 1;", + "Plan": [ + "TopN_8 1.00 root test.t1.a, offset:0, count:1", + "└─TableReader_16 1.00 root data:TopN_15", + " └─TopN_15 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " └─Selection_14 3323.33 cop[tikv] lt(test.t1.a, 10)", + " └─TableFullScan_13 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ qb_name(qb, v) keep_order(t1@qb, idx_a) */ * from v", + "Plan": [ + "Limit_14 1.00 root offset:0, count:1", + "└─Projection_19 1.00 root test.t1.a, test.t1.b", + " └─IndexLookUp_18 1.00 root ", + " ├─Limit_17(Build) 1.00 cop[tikv] offset:0, count:1", + " │ └─IndexRangeScan_15 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:true, stats:pseudo", + " └─TableRowIDScan_16(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ qb_name(qb, v1) keep_order(t@qb, primary) */ * from v1", + "Plan": [ + "Limit_13 1.00 root offset:0, count:1", + "└─TableReader_17 1.00 root data:Limit_16", + " └─Limit_16 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_15 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ qb_name(qb, v) no_keep_order(t1@qb, idx_a) */ * from v", + "Plan": [ + "TopN_11 1.00 root test.t1.a, offset:0, count:1", + "└─IndexLookUp_18 1.00 root ", + " ├─TopN_17(Build) 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " │ └─IndexRangeScan_15 3323.33 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + " └─TableRowIDScan_16(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain select /*+ qb_name(qb, v1) no_keep_order(t@qb, primary) */ * from v1", + "Plan": [ + "TopN_10 1.00 root test.t.a, offset:0, count:1", + "└─TableReader_17 1.00 root data:TopN_16", + " └─TopN_16 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_15 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain WITH CTE AS (select /*+ keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg_30 2.00 root group by:Column#8, Column#9, funcs:firstrow(Column#8)->Column#8, funcs:firstrow(Column#9)->Column#9", + "└─Union_31 1.28 root ", + " ├─Selection_33 0.64 root lt(test.t1.a, 18)", + " │ └─CTEFullScan_34 0.80 root CTE:cte data:CTE_0", + " └─Selection_36 0.64 root gt(test.t1.b, 1)", + " └─CTEFullScan_37 0.80 root CTE:cte data:CTE_0", + "CTE_0 0.80 root Non-Recursive CTE", + "└─Selection_18(Seed Part) 0.80 root or(lt(test.t1.a, 18), gt(test.t1.b, 1))", + " └─Limit_24 1.00 root offset:0, count:1", + " └─Projection_29 1.00 root test.t1.a, test.t1.b", + " └─IndexLookUp_28 1.00 root ", + " ├─Limit_27(Build) 1.00 cop[tikv] offset:0, count:1", + " │ └─IndexRangeScan_25 1.00 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:true, stats:pseudo", + " └─TableRowIDScan_26(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain WITH CTE AS (select /*+ keep_order(t, primary) */ * from t where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg_28 2.00 root group by:Column#7, Column#8, funcs:firstrow(Column#7)->Column#7, funcs:firstrow(Column#8)->Column#8", + "└─Union_29 1.28 root ", + " ├─Selection_31 0.64 root lt(test.t.a, 18)", + " │ └─CTEFullScan_32 0.80 root CTE:cte data:CTE_0", + " └─Selection_34 0.64 root gt(test.t.b, 1)", + " └─CTEFullScan_35 0.80 root CTE:cte data:CTE_0", + "CTE_0 0.80 root Non-Recursive CTE", + "└─Selection_18(Seed Part) 0.80 root or(lt(test.t.a, 18), gt(test.t.b, 1))", + " └─Limit_23 1.00 root offset:0, count:1", + " └─TableReader_27 1.00 root data:Limit_26", + " └─Limit_26 1.00 cop[tikv] offset:0, count:1", + " └─TableRangeScan_25 333.33 cop[tikv] table:t range:[-inf,10), keep order:true, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain WITH CTE AS (select /*+ no_keep_order(t1, idx_a) */ * from t1 where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg_29 2.00 root group by:Column#8, Column#9, funcs:firstrow(Column#8)->Column#8, funcs:firstrow(Column#9)->Column#9", + "└─Union_30 1.28 root ", + " ├─Selection_32 0.64 root lt(test.t1.a, 18)", + " │ └─CTEFullScan_33 0.80 root CTE:cte data:CTE_0", + " └─Selection_35 0.64 root gt(test.t1.b, 1)", + " └─CTEFullScan_36 0.80 root CTE:cte data:CTE_0", + "CTE_0 0.80 root Non-Recursive CTE", + "└─Selection_18(Seed Part) 0.80 root or(lt(test.t1.a, 18), gt(test.t1.b, 1))", + " └─TopN_21 1.00 root test.t1.a, offset:0, count:1", + " └─IndexLookUp_28 1.00 root ", + " ├─TopN_27(Build) 1.00 cop[tikv] test.t1.a, offset:0, count:1", + " │ └─IndexRangeScan_25 3323.33 cop[tikv] table:t1, index:idx_a(a) range:[-inf,10), keep order:false, stats:pseudo", + " └─TableRowIDScan_26(Probe) 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain WITH CTE AS (select /*+ no_keep_order(t, primary) */ * from t where a<10 order by a limit 1) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg_28 2.00 root group by:Column#7, Column#8, funcs:firstrow(Column#7)->Column#7, funcs:firstrow(Column#8)->Column#8", + "└─Union_29 1.28 root ", + " ├─Selection_31 0.64 root lt(test.t.a, 18)", + " │ └─CTEFullScan_32 0.80 root CTE:cte data:CTE_0", + " └─Selection_34 0.64 root gt(test.t.b, 1)", + " └─CTEFullScan_35 0.80 root CTE:cte data:CTE_0", + "CTE_0 0.80 root Non-Recursive CTE", + "└─Selection_18(Seed Part) 0.80 root or(lt(test.t.a, 18), gt(test.t.b, 1))", + " └─TopN_20 1.00 root test.t.a, offset:0, count:1", + " └─TableReader_27 1.00 root data:TopN_26", + " └─TopN_26 1.00 cop[tikv] test.t.a, offset:0, count:1", + " └─TableRangeScan_25 3333.33 cop[tikv] table:t range:[-inf,10), keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + }, + { + "Name": "TestViewHint", + "Cases": [ + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v;", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, Column#10)]", + "├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#10", + "│ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9990.00 root test.t2.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel_1), merge_join(t@qb_v_1) */ * from v;", + "Plan": [ + "MergeJoin 9990.00 root inner join, left key:test.t.a, right key:Column#10", + "├─Sort(Build) 7992.00 root Column#10", + "│ └─StreamAgg 7992.00 root group by:test.t2.a, funcs:count(1)->Column#10", + "│ └─Sort 12487.50 root test.t2.a", + "│ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9990.00 root test.t2.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─Sort(Probe) 9990.00 root test.t.a", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#17)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#17", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#16)]", + "│ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16", + "│ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ ├─Sort(Build) 9990.00 root test.t2.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#17)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#17", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]", + "│ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#16", + "│ │ ├─Sort(Build) 7992.00 root Column#16", + "│ │ │ └─StreamAgg 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16", + "│ │ │ └─Sort 12487.50 root test.t2.a", + "│ │ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ │ ├─Sort(Build) 9990.00 root test.t2.b", + "│ │ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9980.01 root test.t.a", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#23)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23", + "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]", + "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22", + "│ │ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ │ ├─Sort(Build) 9990.00 root test.t2.b", + "│ │ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#23)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23", + "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]", + "│ │ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#22", + "│ │ │ ├─Sort(Build) 7992.00 root Column#22", + "│ │ │ │ └─StreamAgg 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22", + "│ │ │ │ └─Sort 12487.50 root test.t2.a", + "│ │ │ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ │ │ ├─Sort(Build) 9990.00 root test.t2.b", + "│ │ │ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9980.01 root test.t.a", + "│ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#17)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#17", + "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#16)]", + "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16", + "│ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v1@sel_1 .@sel_1), merge_join(t@qb_v1_1) */ * from v1;", + "Plan": [ + "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#17", + "├─Sort(Build) 7984.01 root Column#17", + "│ └─StreamAgg 7984.01 root group by:test.t.a, funcs:count(1)->Column#17", + "│ └─Sort 12475.01 root test.t.a", + "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#16)]", + "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16", + "│ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─Sort(Probe) 9990.00 root test.t.a", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_2 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#23)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23", + "│ │ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ │ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#22)]", + "│ │ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22", + "│ │ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_2 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_2 .@sel_1), merge_join(t@qb_v1_1) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]", + "│ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#23", + "│ │ ├─Sort(Build) 7984.01 root Column#23", + "│ │ │ └─StreamAgg 7984.01 root group by:test.t.a, funcs:count(1)->Column#23", + "│ │ │ └─Sort 12475.01 root test.t.a", + "│ │ │ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ │ │ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ │ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#22)]", + "│ │ │ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22", + "│ │ │ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + "│ │ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ │ └─TableReader(Probe) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9980.01 root test.t.a", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24", + "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#23)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23", + "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]", + "│ │ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22", + "│ │ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2), stream_agg(@qb_v2_2), qb_name(qb_v2_1, v2), merge_join(t@qb_v2_1) */ * from v2;", + "Plan": [ + "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#24", + "├─Sort(Build) 7984.01 root Column#24", + "│ └─StreamAgg 7984.01 root group by:test.t.a, funcs:count(1)->Column#24", + "│ └─Sort 12475.01 root test.t.a", + "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#23)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23", + "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]", + "│ │ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22", + "│ │ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─Sort(Probe) 9990.00 root test.t.a", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + }, + { + "Name": "TestViewHintScope", + "Cases": [ + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v@sel_1 .@sel_2), qb_name(qb_v, v@sel_1 .@sel_1), merge_join(t1@qb_v) */ * from v;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]", + "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "Duplicate query block name qb_v for view's query block hint, only the first one is effective" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_2), qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v1;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "Duplicate query block name qb_v for view's query block hint, only the first one is effective" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_2), qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "Duplicate query block name qb_v for view's query block hint, only the first one is effective" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v1_2 is unused, please check whether the table list in the qb_name hint qb_v1_2 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v1_2 is unused, please check whether the table list in the qb_name hint qb_v1_2 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, vv@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v2_2 is unused, please check whether the table list in the qb_name hint qb_v2_2 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]", + "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v_2 is unused, please check whether the table list in the qb_name hint qb_v_2 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v.@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel1), merge_join(t@qb_v_1) */ * from v) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]", + "├─StreamAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─Sort 15593.77 root test.t2.a", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v_1 is unused, please check whether the table list in the qb_name hint qb_v_1 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v_2 is unused, please check whether the table list in the qb_name hint qb_v_2 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1.v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]", + "│ ├─StreamAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ └─Sort 15593.77 root test.t2.a", + "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v_1 is unused, please check whether the table list in the qb_name hint qb_v_1 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]", + "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_2 .@sel_2), qb_name(qb_v_1, v@sel_2 .@sel1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]", + "├─StreamAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─Sort 15593.77 root test.t2.a", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb_v_1 is unused, please check whether the table list in the qb_name hint qb_v_1 is correct" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_2 . v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v1) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v1@sel_2 . v@sel_2 .@sel_1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v1) t;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]", + "│ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#19", + "│ │ ├─Sort(Build) 7984.01 root Column#19", + "│ │ │ └─StreamAgg 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ │ └─Sort 15593.77 root test.t2.a", + "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9980.01 root test.t.a", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2. v1@sel_2 .@sel_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_2 .@sel_1), merge_join(t1@qb_v1_2, t@qb_v1_1), merge_join(t1@qb_v1_2) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ │ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "Only one query block name is allowed in a view hint, otherwise the hint will be invalid" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t1@qb_v_2, t3@qb_v_2) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ └─MergeJoin 15593.77 root inner join, left key:test.t2.a, right key:test.t3.a", + "│ │ │ ├─Sort(Build) 9990.00 root test.t3.a", + "│ │ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 12475.01 root test.t2.a", + "│ │ │ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(@qb_v_2 t1, t3) */ * from v2;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ └─MergeJoin 15593.77 root inner join, left key:test.t2.a, right key:test.t3.a", + "│ │ │ ├─Sort(Build) 9990.00 root test.t3.a", + "│ │ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 12475.01 root test.t2.a", + "│ │ │ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ │ └─TableReader 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v .@sel_2), merge_join(t1@qb_v_2) */ * from v;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]", + "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_1, v@sel_1), merge_join(t@qb_v_1) */ * from v;", + "Plan": [ + "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#13", + "├─Sort(Build) 7984.01 root Column#13", + "│ └─HashAgg 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─Sort(Probe) 9990.00 root test.t.a", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1 .v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]", + "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ │ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ │ └─TableReader 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9990.00 root test.t1.b", + "│ │ └─TableReader 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_1, v1 .v@sel_2), merge_join(t@qb_v_1) */ * from v1;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20", + "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]", + "│ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#19", + "│ │ ├─Sort(Build) 7984.01 root Column#19", + "│ │ │ └─HashAgg 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─Sort(Probe) 9980.01 root test.t.a", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ merge_join(t1@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2) */ * from v;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]", + "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b", + "│ ├─Sort(Build) 9980.01 root test.t2.b", + "│ │ └─TableReader 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ merge_join(t@qb_v_1), stream_agg(@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2), qb_name(qb_v_1, v@sel_1 .@sel_1) */ * from v;", + "Plan": [ + "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#13", + "├─Sort(Build) 7984.01 root Column#13", + "│ └─StreamAgg 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13", + "│ └─Sort 15593.77 root test.t2.a", + "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─Sort(Probe) 9990.00 root test.t.a", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2) */ * from v3;", + "Plan": [ + "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#27", + "├─Sort(Build) 7984.01 root Column#27", + "│ └─StreamAgg 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─Sort 12475.01 root test.t.a", + "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─Sort(Probe) 9990.00 root test.t.a", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2), hash_agg(@qb_v3_2), qb_name(qb_v3_1, v3@sel_1 .@sel_1), hash_join(t@qb_v3_1) */ * from v3;", + "Plan": [ + "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]", + "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27", + "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b", + "│ ├─Sort(Build) 9980.01 root test.t.b", + "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#26)]", + "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26", + "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]", + "│ │ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25", + "│ │ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ │ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ │ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ │ └─TableReader(Probe) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─Sort(Probe) 9990.00 root test.t1.b", + "│ └─TableReader 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join", + "[planner:1815]Optimizer aggregation hints are conflicted" + ] + }, + { + "SQL": "explain with d1 as (\n select a from (\n select a from (\n select /*+ qb_name(qb, v4) use_index(t4@qb, idx_a) */ a from v4 where a < 10\n ) as t0 where a < 9\n ) as t1 where a < 8\n), d2 as (select /*+ qb_name(qb2, v4) use_index(t4@qb2, idx_b) */ a from v4 where b < 10)\n\nselect * from (select * from d1) as t0 join (select * from d2) as t1;", + "Plan": [ + "HashJoin_41 6944.44 root CARTESIAN inner join", + "├─IndexLookUp_50(Build) 83.33 root ", + "│ ├─IndexRangeScan_47(Build) 250.00 cop[tikv] table:t4, index:idx_b(b) range:(3,10), keep order:false, stats:pseudo", + "│ └─Selection_49(Probe) 83.33 cop[tikv] gt(test.t4.a, 2)", + "│ └─TableRowIDScan_48 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + "└─IndexLookUp_46(Probe) 83.33 root ", + " ├─IndexRangeScan_43(Build) 250.00 cop[tikv] table:t4, index:idx_a(a) range:(2,8), keep order:false, stats:pseudo", + " └─Selection_45(Probe) 83.33 cop[tikv] gt(test.t4.b, 3)", + " └─TableRowIDScan_44 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain with d1 as (\n select a from (\n select a from (\n select a from v4 where a < 10\n ) as t0 where a < 9\n ) as t1 where a < 8\n), d2 as (select a from v4 where b < 10)\n\nselect /*+ qb_name(qb, v4@sel_4) use_index(t4@qb, idx_a) qb_name(qb2, v4@sel_5) use_index(t4@qb, idx_b) */ * from (select * from d1) as t0 join (select * from d2) as t1;", + "Plan": [ + "HashJoin_41 6944.44 root CARTESIAN inner join", + "├─TableReader_53(Build) 83.33 root data:Selection_52", + "│ └─Selection_52 83.33 cop[tikv] gt(test.t4.a, 2), gt(test.t4.b, 3), lt(test.t4.b, 10)", + "│ └─TableFullScan_51 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + "└─IndexLookUp_46(Probe) 83.33 root ", + " ├─IndexRangeScan_43(Build) 250.00 cop[tikv] table:t4, index:idx_a(a) range:(2,8), keep order:false, stats:pseudo", + " └─Selection_45(Probe) 83.33 cop[tikv] gt(test.t4.b, 3)", + " └─TableRowIDScan_44 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain with d1 as (\n select a from (\n select a from (\n select /*+ qb_name(qb, v5) use_index(t4@qb, idx_a) */ a from v4 where a < 10\n ) as t0 where a < 9\n ) as t1 where a < 8\n), d2 as (select /*+ qb_name(qb2, v4) use_index(t4@qb2, idx_b) */ a from v4 where b < 10)\n\nselect * from (select * from d1) as t0 join (select * from d2) as t1;", + "Plan": [ + "HashJoin_41 6944.44 root CARTESIAN inner join", + "├─IndexLookUp_57(Build) 83.33 root ", + "│ ├─IndexRangeScan_54(Build) 250.00 cop[tikv] table:t4, index:idx_b(b) range:(3,10), keep order:false, stats:pseudo", + "│ └─Selection_56(Probe) 83.33 cop[tikv] gt(test.t4.a, 2)", + "│ └─TableRowIDScan_55 250.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + "└─TableReader_45(Probe) 83.33 root data:Selection_44", + " └─Selection_44 83.33 cop[tikv] gt(test.t4.a, 2), gt(test.t4.b, 3), lt(test.t4.a, 10), lt(test.t4.a, 8), lt(test.t4.a, 9)", + " └─TableFullScan_43 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" + ], + "Warn": [ + "The qb_name hint qb is unused, please check whether the table list in the qb_name hint qb is correct" + ] + } + ] + }, + { + "Name": "TestAllViewHintType", + "Cases": [ + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 v, t2) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(v@qb_v1, t2@qb_v1) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 t3, t2) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(t3@qb_v1, t2@qb_v1) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), qb_name(qb_v, v1.v), leading(t2@qb_v1, t@qb_v) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "Only one query block name is allowed in a view hint, otherwise the hint will be invalid" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(@qb_v1 v, t2) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(t2@qb_v1, t3@qb_v1) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t3.a)]", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(@qb_v1 v) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─Projection(Probe) 12475.01 root test.t2.a, test.t2.b, test.t3.a", + " └─HashJoin 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(t2@qb_v1) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t3.a)]", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(@qb_v1 v) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─Projection(Probe) 12475.01 root test.t2.a, test.t2.b, test.t3.a", + " └─HashJoin 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join_build(t2@qb_v1) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t3.a)]", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(@qb_v1 v) */ * from v1;", + "Plan": [ + "MergeJoin 19492.21 root inner join, left key:test.t3.a, right key:test.t.a", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─Sort(Probe) 12475.01 root test.t3.a", + " └─Projection 12475.01 root test.t2.a, test.t2.b, test.t3.a", + " └─HashJoin 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(t2@qb_v1) */ * from v1;", + "Plan": [ + "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t3.a)]", + "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo", + "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo", + "└─MergeJoin(Probe) 12475.01 root inner join, left key:test.t2.b, right key:test.t3.b", + " ├─Sort(Build) 9980.01 root test.t3.b", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─Sort(Probe) 9990.00 root test.t2.b", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(@qb_v t) */ * from v;", + "Plan": [ + "IndexJoin 12500.00 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t.a, equal cond:eq(test.t1.a, test.t.a)", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12500.00 root ", + " ├─IndexRangeScan(Build) 12500.00 cop[tikv] table:t, index:idx_a(a) range: decided by [eq(test.t.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12500.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(t@qb_v) */ * from v;", + "Plan": [ + "IndexJoin 12500.00 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t.a, equal cond:eq(test.t1.a, test.t.a)", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12500.00 root ", + " ├─IndexRangeScan(Build) 12500.00 cop[tikv] table:t, index:idx_a(a) range: decided by [eq(test.t.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12500.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), hash_agg(@qb_v2) */ * from v2;", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, Column#19)]", + "├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ └─HashJoin 24365.26 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]", + "│ ├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + "│ ├─TableReader(Build) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), stream_agg(@qb_v2) */ * from v2;", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, Column#19)]", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#19", + "│ └─Sort 24365.26 root test.t2.a", + "│ └─HashJoin 24365.26 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]", + "│ ├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t2.b, test.t1.b)]", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]", + "│ ├─TableReader(Build) 9980.01 root data:Selection", + "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(t5@qb_v3, idx_a) */ * from v3;", + "Plan": [ + "IndexLookUp 1107.78 root ", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo", + "└─Selection(Probe) 1107.78 cop[tikv] lt(test.t5.b, 2)", + " └─TableRowIDScan 3333.33 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(@qb_v3 t5, idx_b) */ * from v3;", + "Plan": [ + "IndexLookUp 1107.78 root ", + "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo", + "└─Selection(Probe) 1107.78 cop[tikv] gt(test.t5.a, 1)", + " └─TableRowIDScan 3323.33 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(t5@qb_v3, idx_a) */ * from v3;", + "Plan": [ + "IndexLookUp 1107.78 root ", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo", + "└─Selection(Probe) 1107.78 cop[tikv] lt(test.t5.b, 2)", + " └─TableRowIDScan 3333.33 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(@qb_v3 t5, idx_b) */ * from v3;", + "Plan": [ + "IndexLookUp 1107.78 root ", + "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo", + "└─Selection(Probe) 1107.78 cop[tikv] gt(test.t5.a, 1)", + " └─TableRowIDScan 3323.33 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(t5@qb_v3, idx_a) */ * from v3;", + "Plan": [ + "TableReader 1107.78 root data:Selection", + "└─Selection 1107.78 cop[tikv] gt(test.t5.a, 1), lt(test.t5.b, 2)", + " └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(@qb_v3 t5, idx_b) */ * from v3;", + "Plan": [ + "TableReader 1107.78 root data:Selection", + "└─Selection 1107.78 cop[tikv] gt(test.t5.a, 1), lt(test.t5.b, 2)", + " └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(t5@qb_v4, idx_a, idx_b) */ * from v4;", + "Plan": [ + "IndexMerge 5548.89 root type: union", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 5548.89 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(@qb_v4 t5, idx_b, idx_a) */ * from v4;", + "Plan": [ + "IndexMerge 5548.89 root type: union", + "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo", + "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 5548.89 cop[tikv] table:t5 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), READ_FROM_STORAGE(TIFLASH[t@qb_v], TIKV[t1@qb_v]) */ * from v;", + "Plan": [ + "HashJoin 12500.00 root inner join, equal:[eq(test.t.a, test.t1.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v5, v5.@sel_2), SEMI_JOIN_REWRITE(@qb_v5) */ * from v5;", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t.b, test.t1.b)]", + "├─HashAgg(Build) 7992.00 root group by:test.t1.b, funcs:firstrow(test.t1.b)->test.t1.b", + "│ └─TableReader 7992.00 root data:HashAgg", + "│ └─HashAgg 7992.00 cop[tikv] group by:test.t1.b, ", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v6, v6.@sel_2), NO_DECORRELATE(@qb_v6) */ * from v6;", + "Plan": [ + "Projection 10000.00 root test.t1.a, test.t1.b", + "└─Apply 10000.00 root CARTESIAN inner join, other cond:lt(cast(test.t1.a, decimal(10,0) BINARY), Column#7)", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─MaxOneRow(Probe) 10000.00 root ", + " └─StreamAgg 10000.00 root funcs:sum(Column#9)->Column#7", + " └─TableReader 10000.00 root data:StreamAgg", + " └─StreamAgg 10000.00 cop[tikv] funcs:sum(test.t2.a)->Column#9", + " └─Selection 100000.00 cop[tikv] eq(test.t2.b, test.t1.b)", + " └─TableFullScan 100000000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v7, v7), merge(@qb_v7) */ * from v7;", + "Plan": [ + "TableReader 3544.89 root data:ExchangeSender", + "└─ExchangeSender 3544.89 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 3544.89 mpp[tiflash] Column#14, Column#15", + " └─HashAgg 3544.89 mpp[tiflash] group by:Column#14, Column#15, funcs:firstrow(Column#14)->Column#14, funcs:firstrow(Column#15)->Column#15", + " └─ExchangeReceiver 3544.89 mpp[tiflash] ", + " └─ExchangeSender 3544.89 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#14, collate: binary], [name: Column#15, collate: binary]", + " └─HashAgg 3544.89 mpp[tiflash] group by:Column#14, Column#15, ", + " └─Union 4431.11 mpp[tiflash] ", + " ├─Projection 3323.33 mpp[tiflash] cast(test.t.a, int(11) BINARY)->Column#14, test.t.b", + " │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 18), lt(test.t.a, 60)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─Projection 1107.78 mpp[tiflash] cast(test.t.a, int(11) BINARY)->Column#14, test.t.b", + " └─Selection 1107.78 mpp[tiflash] gt(test.t.b, 1), lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v8, v8), merge(@qb_v8) */ * from v8;", + "Plan": [ + "HashAgg 16000.00 root group by:Column#21, funcs:firstrow(Column#21)->Column#21", + "└─Union 1000000010000.00 root ", + " ├─HashJoin 1000000000000.00 root CARTESIAN inner join", + " │ ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " │ └─CTEFullScan(Probe) 100000000.00 root CTE:cte2 data:CTE_1", + " └─TableReader 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "CTE_1 100000000.00 root Non-Recursive CTE", + "└─HashJoin(Seed Part) 100000000.00 root CARTESIAN inner join", + " ├─CTEFullScan(Build) 10000.00 root CTE:cte4 data:CTE_3", + " └─CTEFullScan(Probe) 10000.00 root CTE:cte3 data:CTE_2", + "CTE_3 10000.00 root Non-Recursive CTE", + "└─IndexReader(Seed Part) 10000.00 root index:IndexFullScan", + " └─IndexFullScan 10000.00 cop[tikv] table:t3, index:idx_a(a) keep order:false, stats:pseudo", + "CTE_2 10000.00 root Non-Recursive CTE", + "└─IndexReader(Seed Part) 10000.00 root index:IndexFullScan", + " └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_a(a) keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;", + "Plan": [ + "StreamAgg 1.00 root funcs:sum(Column#7)->Column#4", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:sum(Column#9)->Column#7", + " └─Projection 10000.00 batchCop[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#9", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb_v10, v10), LIMIT_TO_COP(@qb_v10) */ * from v10;", + "Plan": [ + "TopN 1.00 root test.t.b, offset:0, count:1", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TopN 1.00 mpp[tiflash] test.t.b, offset:0, count:1", + " └─Selection 3333.33 mpp[tiflash] gt(test.t.a, 10)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb, v11) read_from_storage(tiflash[t@qb]), MPP_1PHASE_AGG(@qb) */ * from v11;", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#4", + " └─Projection 8000.00 mpp[tiflash] Column#4, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#9, funcs:sum(Column#7)->Column#4, funcs:firstrow(Column#8)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#7, test.t.a, test.t.a", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb, v11) read_from_storage(tiflash[t@qb]), MPP_2PHASE_AGG(@qb) */ * from v11;", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#4", + " └─Projection 8000.00 mpp[tiflash] Column#4, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, funcs:sum(Column#9)->Column#4, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#12, funcs:sum(Column#11)->Column#9", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#11, test.t.a", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb, v12) read_from_storage(tiflash[t1@qb, t@qb]), shuffle_join(t1@qb, t@qb) */ * from v12;", + "Plan": [ + "TableReader 12500.00 root data:ExchangeSender", + "└─ExchangeSender 12500.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12500.00 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ qb_name(qb, v12) read_from_storage(tiflash[t1@qb, t@qb]), broadcast_join(t1@qb, t@qb) */ * from v12;", + "Plan": [ + "TableReader 12500.00 root data:ExchangeSender", + "└─ExchangeSender 12500.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12500.00 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + }, + { + "Name": "TestReadFromStorageHintAndIsolationRead", + "Cases": [ + { + "SQL": "desc format = 'brief' select /*+ read_from_storage(tikv[t], tiflash[t]) */ avg(a) from t", + "Plan": [ + "HashAgg 1.00 root funcs:avg(Column#5, Column#6)->Column#4", + "└─IndexReader 1.00 root index:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(test.t.a)->Column#5, funcs:sum(test.t.a)->Column#6", + " └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Storage hints are conflict, you can only specify one storage type of table test.t" + ] + }, + { + "SQL": "desc format = 'brief' select /*+ read_from_storage(tikv[t]) */ avg(a) from t", + "Plan": [ + "HashAgg 1.00 root funcs:avg(Column#5, Column#6)->Column#4", + "└─IndexReader 1.00 root index:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(test.t.a)->Column#5, funcs:sum(test.t.a)->Column#6", + " └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "desc format = 'brief' select /*+ read_from_storage(tiflash[t]) */ avg(a) from t", + "Plan": [ + "HashAgg 1.00 root funcs:avg(Column#5, Column#6)->Column#4", + "└─IndexReader 1.00 root index:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(test.t.a)->Column#5, funcs:sum(test.t.a)->Column#6", + " └─IndexFullScan 10000.00 cop[tikv] table:t, index:ia(a) keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]No available path for table test.t with the store type tiflash of the hint /*+ read_from_storage */, please check the status of the table replica and variable value of tidb_isolation_read_engines(map[0:{}])" + ] + } + ] + }, + { + "Name": "TestIsolationReadDoNotFilterSystemDB", + "Cases": [ + { + "SQL": "desc format = 'brief' select * from metrics_schema.tidb_query_duration where time >= '2019-12-23 16:10:13' and time <= '2019-12-23 16:30:13'", + "Plan": [ + "MemTableScan 10000.00 root table:tidb_query_duration PromQL:histogram_quantile(0.9, sum(rate(tidb_server_handle_query_duration_seconds_bucket{}[60s])) by (le,sql_type,instance)), start_time:2019-12-23 16:10:13, end_time:2019-12-23 16:30:13, step:1m0s" + ] + }, + { + "SQL": "desc format = 'brief' select * from information_schema.tables", + "Plan": [ + "MemTableScan 10000.00 root table:TABLES " + ] + }, + { + "SQL": "desc format = 'brief' select * from mysql.stats_meta", + "Plan": [ + "TableReader 10000.00 root data:TableFullScan", + "└─TableFullScan 10000.00 cop[tikv] table:stats_meta keep order:false, stats:pseudo" + ] + } + ] + }, + { + "Name": "TestIsolationReadTiFlashNotChoosePointGet", + "Cases": [ + { + "SQL": "explain format = 'brief' select * from t where t.a = 1", + "Result": [ + "TableReader 1.00 root data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TableRangeScan 1.00 mpp[tiflash] table:t range:[1,1], keep order:false, stats:pseudo" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where t.a in (1, 2)", + "Result": [ + "TableReader 2.00 root data:ExchangeSender", + "└─ExchangeSender 2.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TableRangeScan 2.00 mpp[tiflash] table:t range:[1,1], [2,2], keep order:false, stats:pseudo" + ] + } + ] + }, + { + "Name": "TestIsolationReadTiFlashUseIndexHint", + "Cases": [ + { + "SQL": "explain format = 'brief' select * from t", + "Plan": [ + "TableReader 10000.00 root data:ExchangeSender", + "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select * from t use index();", + "Plan": [ + "TableReader 10000.00 root data:ExchangeSender", + "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "explain format = 'brief' select /*+ use_index(t, idx)*/ * from t", + "Plan": [ + "TableReader 10000.00 root data:ExchangeSender", + "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "TiDB doesn't support index in the isolation read engines(value: 'tiflash')" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ use_index(t)*/ * from t", + "Plan": [ + "TableReader 10000.00 root data:ExchangeSender", + "└─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + } + ] + }, + { + "Name": "TestIssue20710", + "Cases": [ + { + "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.b", + "Plan": [ + "IndexJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.s.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.s.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.b = s.a", + "Plan": [ + "IndexJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12475.01 cop[tikv] not(isnull(test.s.a))", + " │ └─IndexRangeScan 12487.50 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:s keep order:false, stats:pseudo" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ inl_join(s) */ * from t join s on t.a=s.a and t.a = s.b", + "Plan": [ + "IndexJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)", + "├─TableReader(Build) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.s.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.s.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.b", + "Plan": [ + "IndexHashJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.b)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.s.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.s.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.b = s.a", + "Plan": [ + "IndexHashJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.b, test.s.a)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12475.01 cop[tikv] not(isnull(test.s.a))", + " │ └─IndexRangeScan 12487.50 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:s keep order:false, stats:pseudo" + ] + }, + { + "SQL": "explain format = 'brief' select /*+ inl_hash_join(s) */ * from t join s on t.a=s.a and t.a = s.b", + "Plan": [ + "IndexHashJoin 12475.01 root inner join, inner:IndexLookUp, outer key:test.t.a, inner key:test.s.a, equal cond:eq(test.t.a, test.s.a), eq(test.t.a, test.s.b)", + "├─TableReader(Build) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.s.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.s.b))", - " └─TableRowIDScan 1.25 cop[tikv] table:s keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.s.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:s, index:a(a) range: decided by [eq(test.s.a, test.t.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.s.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:s keep order:false, stats:pseudo" ] } ] @@ -4675,11 +7057,11 @@ "SQL": "desc format = 'brief' select * from t right join (select id-2 as b from t) A on A.b=t.id", "Plan": [ "HashJoin 12487.50 root right outer join, equal:[eq(test.t.id, Column#25)]", - "├─TableReader(Build) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.id))", + "├─TableReader(Build) 10000.00 root data:Projection", + "│ └─Projection 10000.00 cop[tikv] minus(test.t.id, 2)->Column#25", "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "└─TableReader(Probe) 10000.00 root data:Projection", - " └─Projection 10000.00 cop[tikv] minus(test.t.id, 2)->Column#25", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.id))", " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ] }, @@ -4785,7 +7167,7 @@ "HashAgg 1.00 root funcs:count(Column#16)->Column#14", "└─TableReader 1.00 root data:ExchangeSender", " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#16", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t._tidb_rowid)->Column#16", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, @@ -4803,33 +7185,30 @@ { "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from (select id + 1 as b from t)A", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#18)->Column#14", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(Column#19)->Column#18", - " └─Projection 10000.00 mpp[tiflash] plus(test.t.id, 1)->Column#19", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg 1.00 root funcs:count(Column#16)->Column#14", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(Column#19)->Column#16", + " └─Projection 10000.00 batchCop[tiflash] plus(test.t.id, 1)->Column#19", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from (select id + 1 as b from t)A", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#17)->Column#14", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#17", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg 1.00 root funcs:count(Column#15)->Column#14", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(test.t._tidb_rowid)->Column#15", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from (select id + 1 as b from t)A", "Plan": [ - "HashAgg 1.00 root funcs:sum(Column#18)->Column#14", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#19)->Column#18", - " └─Projection 10000.00 mpp[tiflash] cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#19", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg 1.00 root funcs:sum(Column#16)->Column#14", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:sum(Column#19)->Column#16", + " └─Projection 10000.00 batchCop[tiflash] cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#19", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -4879,13 +7258,13 @@ "SQL": "desc format = 'brief' select * from t right join (select id-2 as b from t) A on A.b=t.id", "Plan": [ "HashJoin 12487.50 root right outer join, equal:[eq(test.t.id, Column#25)]", - "├─TableReader(Build) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tiflash] not(isnull(test.t.id))", - "│ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", - "└─TableReader(Probe) 10000.00 root data:ExchangeSender", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection 10000.00 mpp[tiflash] minus(test.t.id, 2)->Column#25", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "├─TableReader(Build) 10000.00 root data:ExchangeSender", + "│ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + "│ └─Projection 10000.00 mpp[tiflash] minus(test.t.id, 2)->Column#25", + "│ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tiflash] not(isnull(test.t.id))", + " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -4946,7 +7325,7 @@ "Name": "TestPushDownProjectionForTiFlash", "Cases": [ { - "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(b) from (select id + 1 as b from t)A", + "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", "Plan": [ "HashAgg 1.00 root funcs:count(Column#8)->Column#6", "└─TableReader 1.00 root data:HashAgg", @@ -4956,16 +7335,16 @@ ] }, { - "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) from (select id + 1 as b from t)A", + "SQL": "desc format = 'brief' select /*+ hash_agg()*/ count(*) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", "Plan": [ "HashAgg 1.00 root funcs:count(Column#7)->Column#6", "└─TableReader 1.00 root data:HashAgg", - " └─HashAgg 1.00 batchCop[tiflash] funcs:count(1)->Column#7", + " └─HashAgg 1.00 batchCop[tiflash] funcs:count(test.t._tidb_rowid)->Column#7", " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { - "SQL": "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from (select id + 1 as b from t)A", + "SQL": "desc format = 'brief' select /*+ hash_agg()*/ sum(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", "Plan": [ "HashAgg 1.00 root funcs:sum(Column#8)->Column#6", "└─TableReader 1.00 root data:HashAgg", @@ -4975,7 +7354,7 @@ ] }, { - "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from (select id + 1 as b from t)A", + "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", "Plan": [ "StreamAgg 1.00 root funcs:count(Column#8)->Column#6", "└─TableReader 1.00 root data:StreamAgg", @@ -4985,16 +7364,16 @@ ] }, { - "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from (select id + 1 as b from t)A", + "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", "Plan": [ "StreamAgg 1.00 root funcs:count(Column#7)->Column#6", "└─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(1)->Column#7", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(test.t._tidb_rowid)->Column#7", " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { - "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from (select id + 1 as b from t)A", + "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from (select /*+ read_from_storage(tiflash[t]) */ id + 1 as b from t)A", "Plan": [ "StreamAgg 1.00 root funcs:sum(Column#8)->Column#6", "└─TableReader 1.00 root data:StreamAgg", @@ -5046,11 +7425,11 @@ "SQL": "desc format = 'brief' select * from t right join (select id-2 as b from t) A on A.b=t.id", "Plan": [ "HashJoin 12487.50 root right outer join, equal:[eq(test.t.id, Column#9)]", - "├─TableReader(Build) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tiflash] not(isnull(test.t.id))", + "├─Projection(Build) 10000.00 root minus(test.t.id, 2)->Column#9", + "│ └─TableReader 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo", - "└─Projection(Probe) 10000.00 root minus(test.t.id, 2)->Column#9", - " └─TableReader 10000.00 root data:TableFullScan", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tiflash] not(isnull(test.t.id))", " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ] }, @@ -5121,7 +7500,7 @@ "HashAgg 1.00 root funcs:count(Column#8)->Column#6", "└─TableReader 1.00 root data:ExchangeSender", " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#8", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t._tidb_rowid)->Column#8", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, @@ -5139,33 +7518,30 @@ { "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(b) from (select id + 1 as b from t)A", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#10)->Column#6", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(Column#11)->Column#10", - " └─Projection 10000.00 mpp[tiflash] plus(test.t.id, 1)->Column#11", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg 1.00 root funcs:count(Column#8)->Column#6", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(Column#11)->Column#8", + " └─Projection 10000.00 batchCop[tiflash] plus(test.t.id, 1)->Column#11", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { "SQL": "desc format = 'brief' select /*+ stream_agg()*/ count(*) from (select id + 1 as b from t)A", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#9)->Column#6", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#9", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg 1.00 root funcs:count(Column#7)->Column#6", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(test.t._tidb_rowid)->Column#7", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { "SQL": "desc format = 'brief' select /*+ stream_agg()*/ sum(b) from (select id + 1 as b from t)A", "Plan": [ - "HashAgg 1.00 root funcs:sum(Column#10)->Column#6", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#11)->Column#10", - " └─Projection 10000.00 mpp[tiflash] cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#11", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg 1.00 root funcs:sum(Column#8)->Column#6", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:sum(Column#11)->Column#8", + " └─Projection 10000.00 batchCop[tiflash] cast(plus(test.t.id, 1), decimal(20,0) BINARY)->Column#11", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5278,12 +7654,13 @@ "└─TableReader 8000.00 root data:ExchangeSender", " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 8000.00 mpp[tiflash] mul(Column#5, 2)->Column#6, test.t.id", - " └─Projection 8000.00 mpp[tiflash] div(Column#5, cast(case(eq(Column#19, 0), 1, Column#19), decimal(20,0) BINARY))->Column#5, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:Column#27, funcs:count(Column#24)->Column#19, funcs:sum(Column#25)->Column#5, funcs:firstrow(Column#26)->test.t.id", - " └─Projection 10000.00 mpp[tiflash] plus(test.t.value, 2)->Column#24, plus(test.t.value, 2)->Column#25, test.t.id, test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─Projection 8000.00 mpp[tiflash] div(Column#5, cast(case(eq(Column#20, 0), 1, Column#20), decimal(20,0) BINARY))->Column#5, test.t.id", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#21)->Column#20, funcs:sum(Column#22)->Column#5, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#26, funcs:count(Column#24)->Column#21, funcs:sum(Column#25)->Column#22", + " └─Projection 10000.00 mpp[tiflash] plus(test.t.value, 2)->Column#24, plus(test.t.value, 2)->Column#25, test.t.id", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5307,10 +7684,11 @@ "└─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: PassThrough", " └─Selection 6400.00 mpp[tiflash] gt(test.t.id, Column#5)", " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#5, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#12)->Column#5, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#12", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5428,20 +7806,22 @@ " │ └─ExchangeSender 7976.02 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: Column#58, collate: binary], [name: test.t.c5, collate: binary]", " │ └─Projection 7976.02 mpp[tiflash] Column#7, test.t.c1, test.t.c2, test.t.c5, cast(test.t.c2, decimal(10,5))->Column#58", " │ └─Projection 7976.02 mpp[tiflash] Column#7, test.t.c1, test.t.c2, test.t.c5", - " │ └─HashAgg 7976.02 mpp[tiflash] group by:test.t.c1, test.t.c2, test.t.c5, funcs:count(1)->Column#7, funcs:firstrow(test.t.c1)->test.t.c1, funcs:firstrow(test.t.c2)->test.t.c2, funcs:firstrow(test.t.c5)->test.t.c5", - " │ └─ExchangeReceiver 9970.03 mpp[tiflash] ", - " │ └─ExchangeSender 9970.03 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: test.t.c2, collate: binary], [name: test.t.c5, collate: binary]", - " │ └─Selection 9970.03 mpp[tiflash] not(isnull(test.t.c1)), not(isnull(test.t.c2)), not(isnull(test.t.c5))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7976.02 mpp[tiflash] group by:test.t.c1, test.t.c2, test.t.c5, funcs:sum(Column#15)->Column#7, funcs:firstrow(test.t.c1)->test.t.c1, funcs:firstrow(test.t.c2)->test.t.c2, funcs:firstrow(test.t.c5)->test.t.c5", + " │ └─ExchangeReceiver 7976.02 mpp[tiflash] ", + " │ └─ExchangeSender 7976.02 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c1, collate: binary], [name: test.t.c2, collate: binary], [name: test.t.c5, collate: binary]", + " │ └─HashAgg 7976.02 mpp[tiflash] group by:test.t.c1, test.t.c2, test.t.c5, funcs:count(1)->Column#15", + " │ └─Selection 9970.03 mpp[tiflash] not(isnull(test.t.c1)), not(isnull(test.t.c2)), not(isnull(test.t.c5))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─ExchangeReceiver(Probe) 7984.01 mpp[tiflash] ", " └─ExchangeSender 7984.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: Column#59, collate: binary], [name: Column#60, collate: binary]", " └─Projection 7984.01 mpp[tiflash] Column#14, test.t.c1, test.t.c2, test.t.c3, cast(test.t.c3, decimal(10,5))->Column#59, cast(test.t.c1, decimal(40,20))->Column#60", " └─Projection 7984.01 mpp[tiflash] Column#14, test.t.c1, test.t.c2, test.t.c3", - " └─HashAgg 7984.01 mpp[tiflash] group by:test.t.c1, test.t.c2, test.t.c3, funcs:count(1)->Column#14, funcs:firstrow(test.t.c1)->test.t.c1, funcs:firstrow(test.t.c2)->test.t.c2, funcs:firstrow(test.t.c3)->test.t.c3", - " └─ExchangeReceiver 9980.01 mpp[tiflash] ", - " └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: test.t.c3, collate: binary], [name: test.t.c1, collate: binary]", - " └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.c1)), not(isnull(test.t.c2))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─HashAgg 7984.01 mpp[tiflash] group by:test.t.c1, test.t.c2, test.t.c3, funcs:sum(Column#23)->Column#14, funcs:firstrow(test.t.c1)->test.t.c1, funcs:firstrow(test.t.c2)->test.t.c2, funcs:firstrow(test.t.c3)->test.t.c3", + " └─ExchangeReceiver 7984.01 mpp[tiflash] ", + " └─ExchangeSender 7984.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c2, collate: binary], [name: test.t.c3, collate: binary], [name: test.t.c1, collate: binary]", + " └─HashAgg 7984.01 mpp[tiflash] group by:test.t.c1, test.t.c2, test.t.c3, funcs:count(1)->Column#23", + " └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.c1)), not(isnull(test.t.c2))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5574,6 +7954,63 @@ } ] }, + { + "Name": "TestMppJoinExchangeColumnPrune", + "Cases": [ + { + "SQL": "desc format = 'brief' select * from tt t1 where exists (select * from t t2 where t1.b1 = t2.c3 and t2.c1 < t2.c2)", + "Plan": [ + "TableReader 7992.00 root data:ExchangeSender", + "└─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 7992.00 mpp[tiflash] semi join, equal:[eq(test.tt.b1, test.t.c3)]", + " ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c3, collate: binary]", + " │ └─Projection 8000.00 mpp[tiflash] test.t.c3", + " │ └─Selection 8000.00 mpp[tiflash] lt(test.t.c1, test.t.c2)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.tt.b1, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.tt.b1))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ] + } + ] + }, + { + "Name": "TestMppFineGrainedJoinAndAgg", + "Cases": [ + { + "SQL": "desc format = 'brief' select * from tt t1 where exists (select * from t t2 where t1.b1 = t2.c3 and t2.c1 < t2.c2)", + "Plan": [ + "TableReader 7992.00 root data:ExchangeSender", + "└─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 7992.00 mpp[tiflash] semi join, equal:[eq(test.tt.b1, test.t.c3)], stream_count: 8", + " ├─ExchangeReceiver(Build) 8000.00 mpp[tiflash] stream_count: 8", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.c3, collate: binary], stream_count: 8", + " │ └─Projection 8000.00 mpp[tiflash] test.t.c3", + " │ └─Selection 8000.00 mpp[tiflash] lt(test.t.c1, test.t.c2)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.tt.b1, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.tt.b1))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ] + }, + { + "SQL": "desc format = 'brief' select count(*) from tt group by b1", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] Column#3", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.tt.b1, funcs:sum(Column#7)->Column#3, stream_count: 8", + " └─ExchangeReceiver 8000.00 mpp[tiflash] stream_count: 8", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.tt.b1, collate: binary], stream_count: 8", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.tt.b1, funcs:count(1)->Column#7", + " └─TableFullScan 10000.00 mpp[tiflash] table:tt keep order:false, stats:pseudo" + ] + } + ] + }, { "Name": "TestPushDownAggForMPP", "Cases": [ @@ -5594,7 +8031,7 @@ "HashAgg 1.00 root funcs:count(Column#7)->Column#5", "└─TableReader 1.00 root data:ExchangeSender", " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#7", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t._tidb_rowid)->Column#7", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, @@ -5612,11 +8049,10 @@ { "SQL": "desc format = 'brief' select count(*) from t", "Plan": [ - "HashAgg 1.00 root funcs:count(Column#6)->Column#4", - "└─TableReader 1.00 root data:ExchangeSender", - " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#6", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg 1.00 root funcs:count(Column#7)->Column#4", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 batchCop[tiflash] funcs:count(test.t._tidb_rowid)->Column#7", + " └─TableFullScan 10000.00 batchCop[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5625,10 +8061,11 @@ "TableReader 8000.00 root data:ExchangeSender", "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 8000.00 mpp[tiflash] Column#4, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#4, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#11)->Column#4, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#11", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5653,11 +8090,12 @@ "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.id, test.t.id)]", " ├─Projection(Build) 7992.00 mpp[tiflash] Column#7, test.t.id", - " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#7, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#8)->Column#7, funcs:firstrow(test.t.id)->test.t.id", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#8", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", @@ -5671,7 +8109,7 @@ "├─HashAgg(Build) 1.00 root funcs:count(Column#11)->Column#7", "│ └─TableReader 1.00 root data:ExchangeSender", "│ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - "│ └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#11", + "│ └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t._tidb_rowid)->Column#11", "│ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tiflash] not(isnull(test.t.id))", @@ -5683,11 +8121,12 @@ "Plan": [ "TableReader 8000.00 root data:ExchangeSender", "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#16, 0), 1, Column#16), decimal(20,0) BINARY))->Column#4, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#16, funcs:sum(test.t.value)->Column#4, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#17, 0), 1, Column#17), decimal(20,0) BINARY))->Column#4, test.t.id", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#18)->Column#17, funcs:sum(Column#19)->Column#4, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#18, funcs:sum(test.t.value)->Column#19", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5697,11 +8136,12 @@ "└─TableReader 1.00 root data:ExchangeSender", " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#4)->Column#18", - " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#14, 0), 1, Column#14), decimal(20,0) BINARY))->Column#4", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#14, funcs:sum(test.t.value)->Column#4", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#15, 0), 1, Column#15), decimal(20,0) BINARY))->Column#4", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#16)->Column#15, funcs:sum(Column#17)->Column#4", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#16, funcs:sum(test.t.value)->Column#17", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5711,11 +8151,12 @@ "└─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 6400.00 mpp[tiflash] test.t.id", " └─Selection 6400.00 mpp[tiflash] gt(Column#4, 0)", - " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#17, 0), 1, Column#17), decimal(20,0) BINARY))->Column#4, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#17, funcs:sum(test.t.value)->Column#4, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#18, 0), 1, Column#18), decimal(20,0) BINARY))->Column#4, test.t.id", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#19)->Column#18, funcs:sum(Column#20)->Column#4, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#19, funcs:sum(test.t.value)->Column#20", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5724,11 +8165,12 @@ "TableReader 6400.00 root data:ExchangeSender", "└─ExchangeSender 6400.00 mpp[tiflash] ExchangeType: PassThrough", " └─Selection 6400.00 mpp[tiflash] gt(Column#4, 0)", - " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#18, 0), 1, Column#18), decimal(20,0) BINARY))->Column#4, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#18, funcs:sum(test.t.value)->Column#4, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#19, 0), 1, Column#19), decimal(20,0) BINARY))->Column#4, test.t.id", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#20)->Column#19, funcs:sum(Column#21)->Column#4, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#20, funcs:sum(test.t.value)->Column#21", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5737,11 +8179,12 @@ "TableReader 8000.00 root data:ExchangeSender", "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 8000.00 mpp[tiflash] plus(Column#4, 1)->Column#5, test.t.id", - " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#18, 0), 1, Column#18), decimal(20,0) BINARY))->Column#4, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#18, funcs:sum(test.t.value)->Column#4, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─Projection 8000.00 mpp[tiflash] div(Column#4, cast(case(eq(Column#19, 0), 1, Column#19), decimal(20,0) BINARY))->Column#4, test.t.id", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#20)->Column#19, funcs:sum(Column#21)->Column#4, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(test.t.value)->Column#20, funcs:sum(test.t.value)->Column#21", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -5771,20 +8214,22 @@ " └─HashJoin 7992.00 mpp[tiflash] inner join, equal:[eq(test.t.id, test.t.id)]", " ├─Projection(Build) 7992.00 mpp[tiflash] test.t.id", " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, ", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Projection(Probe) 7992.00 mpp[tiflash] Column#11, test.t.id", " └─HashAgg 7992.00 mpp[tiflash] group by:Column#39, funcs:sum(Column#37)->Column#11, funcs:firstrow(Column#38)->test.t.id", " └─Projection 9990.00 mpp[tiflash] cast(test.t.id, decimal(10,0) BINARY)->Column#37, test.t.id, test.t.id", " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.id, test.t.id)]", " ├─Projection(Build) 7992.00 mpp[tiflash] test.t.id, Column#13", - " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id, funcs:count(1)->Column#13", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id, funcs:sum(Column#17)->Column#13", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#17", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", @@ -5838,12 +8283,13 @@ "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.id, test.t.id)]", " ├─Projection(Build) 7992.00 mpp[tiflash] Column#7, test.t.id", - " │ └─HashAgg 7992.00 mpp[tiflash] group by:Column#20, funcs:count(Column#18)->Column#7, funcs:firstrow(Column#19)->test.t.id", - " │ └─Projection 9990.00 mpp[tiflash] div(1, test.t.value)->Column#18, test.t.id, test.t.id", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#8)->Column#7, funcs:firstrow(test.t.id)->test.t.id", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:Column#19, funcs:count(Column#18)->Column#8", + " │ └─Projection 9990.00 mpp[tiflash] div(1, test.t.value)->Column#18, test.t.id", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", @@ -5877,11 +8323,12 @@ " └─Selection 8000.00 mpp[tiflash] gt(plus(test.t.id, 1), ifnull(Column#7, 0))", " └─HashJoin 10000.00 mpp[tiflash] left outer join, equal:[eq(test.t.id, test.t.id) eq(test.t.value, test.t.value)]", " ├─Projection(Build) 7984.01 mpp[tiflash] Column#7, test.t.id, test.t.value", - " │ └─HashAgg 7984.01 mpp[tiflash] group by:test.t.id, test.t.value, funcs:count(1)->Column#7, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.value)->test.t.value", - " │ └─ExchangeReceiver 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.id)), not(isnull(test.t.value))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7984.01 mpp[tiflash] group by:test.t.id, test.t.value, funcs:sum(Column#24)->Column#7, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.value)->test.t.value", + " │ └─ExchangeReceiver 7984.01 mpp[tiflash] ", + " │ └─ExchangeSender 7984.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7984.01 mpp[tiflash] group by:test.t.id, test.t.value, funcs:count(1)->Column#24", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.id)), not(isnull(test.t.value))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─ExchangeReceiver(Probe) 10000.00 mpp[tiflash] ", " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", " └─TableFullScan 10000.00 mpp[tiflash] table:B keep order:false, stats:pseudo" @@ -5951,11 +8398,12 @@ " ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash] ", " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast", " │ └─Projection 7992.00 mpp[tiflash] Column#7, test.t.id", - " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#7, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#8)->Column#7, funcs:firstrow(test.t.id)->test.t.id", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#8", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.id))", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] @@ -5971,10 +8419,11 @@ " │ └─Projection 6400.00 mpp[tiflash] plus(Column#7, test.t.id)->Column#8", " │ └─Selection 6400.00 mpp[tiflash] not(isnull(plus(Column#7, test.t.id)))", " │ └─Projection 8000.00 mpp[tiflash] Column#7, test.t.id", - " │ └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#7, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#11)->Column#7, funcs:firstrow(test.t.id)->test.t.id", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#11", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.id))", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] @@ -5990,11 +8439,12 @@ " │ └─ExchangeSender 6393.60 mpp[tiflash] ExchangeType: Broadcast", " │ └─Selection 6393.60 mpp[tiflash] lt(plus(test.t.value, cast(Column#7, decimal(20,0) BINARY)), 10)", " │ └─Projection 7992.00 mpp[tiflash] Column#7, test.t.id, test.t.value", - " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, test.t.value, funcs:count(1)->Column#7, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.value)->test.t.value", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.value, collate: binary], [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, test.t.value, funcs:sum(Column#10)->Column#7, funcs:firstrow(test.t.id)->test.t.id, funcs:firstrow(test.t.value)->test.t.value", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.value, collate: binary], [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, test.t.value, funcs:count(1)->Column#10", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.id))", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] @@ -6006,7 +8456,7 @@ "├─HashAgg(Build) 1.00 root funcs:count(Column#10)->Column#7", "│ └─TableReader 1.00 root data:ExchangeSender", "│ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", - "│ └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#10", + "│ └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t._tidb_rowid)->Column#10", "│ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tiflash] not(isnull(test.t.id))", @@ -6042,16 +8492,18 @@ " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast", " │ └─Projection 7992.00 mpp[tiflash] test.t.id", " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, ", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Projection(Probe) 7992.00 mpp[tiflash] Column#7, test.t.id", - " └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:sum(test.t.value)->Column#7, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:sum(Column#9)->Column#7, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:sum(test.t.value)->Column#9", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -6064,10 +8516,11 @@ " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast", " │ └─Projection 7992.00 mpp[tiflash] test.t.id", " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, ", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Projection(Probe) 7992.00 mpp[tiflash] Column#11, test.t.id", " └─HashAgg 7992.00 mpp[tiflash] group by:Column#34, funcs:sum(Column#32)->Column#11, funcs:firstrow(Column#33)->test.t.id", " └─Projection 9990.00 mpp[tiflash] cast(test.t.id, decimal(10,0) BINARY)->Column#32, test.t.id, test.t.id", @@ -6077,11 +8530,12 @@ " ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash] ", " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast", " │ └─Projection 7992.00 mpp[tiflash] test.t.id, Column#13", - " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id, funcs:count(1)->Column#13", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id, funcs:sum(Column#16)->Column#13", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:count(1)->Column#16", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.id))", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] @@ -6125,7 +8579,7 @@ { "SQL": "desc format = 'brief' select count(*) from (select t.id, t.value v1 from t join t t1 on t.id = t1.id order by t.value limit 20) v group by v.v1", "Plan": [ - "HashAgg 20.00 root group by:test.t.value, funcs:count(1)->Column#7", + "StreamAgg 20.00 root group by:test.t.value, funcs:count(1)->Column#7", "└─TopN 20.00 root test.t.value, offset:0, count:20", " └─TableReader 20.00 root data:ExchangeSender", " └─ExchangeSender 20.00 mpp[tiflash] ExchangeType: PassThrough", @@ -6196,7 +8650,7 @@ { "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where a =1 or (b=1 and b+2>1)", "Plan": [ - "IndexMerge 8.00 root ", + "IndexMerge 8.00 root type: union", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false", "├─Selection(Build) 1.00 cop[tikv] 1", "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false", @@ -6207,7 +8661,7 @@ { "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where a =1 or (b=1 and length(b)=1)", "Plan": [ - "IndexMerge 8.00 root ", + "IndexMerge 8.00 root type: union", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false", "├─Selection(Build) 1.00 cop[tikv] 1", "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false", @@ -6218,7 +8672,7 @@ { "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where (a=1 and length(a)=1) or (b=1 and length(b)=1)", "Plan": [ - "IndexMerge 8.00 root ", + "IndexMerge 8.00 root type: union", "├─Selection(Build) 1.00 cop[tikv] 1", "│ └─IndexRangeScan 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false", "├─Selection(Build) 1.00 cop[tikv] 1", @@ -6230,7 +8684,7 @@ { "SQL": "desc format='brief' select /*+ use_index_merge(t) */ * from t where (a=1 and length(b)=1) or (b=1 and length(a)=1)", "Plan": [ - "IndexMerge 0.29 root ", + "IndexMerge 0.29 root type: union", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:a(a) range:[1,1], keep order:false", "├─IndexRangeScan(Build) 1.00 cop[tikv] table:t, index:b(b) range:[1,1], keep order:false", "└─Selection(Probe) 0.29 cop[tikv] or(and(eq(test.t.a, 1), eq(length(cast(test.t.b, var_string(20))), 1)), and(eq(test.t.b, 1), eq(length(cast(test.t.a, var_string(20))), 1)))", @@ -6246,22 +8700,22 @@ { "SQL": "desc format = 'brief' select * from t where a = 1 and b > 2 and b < 10 and d = 10 order by b,c limit 10", "Plan": [ - "TopN 0.00 root test.t.b, test.t.c, offset:0, count:10", - "└─IndexLookUp 0.00 root ", - " ├─IndexRangeScan(Build) 2.50 cop[tikv] table:t, index:idx(a, b, c) range:(1 2,1 10), keep order:false, stats:pseudo", - " └─TopN(Probe) 0.00 cop[tikv] test.t.b, test.t.c, offset:0, count:10", - " └─Selection 0.00 cop[tikv] eq(test.t.d, 10)", + "Limit 0.00 root offset:0, count:10", + "└─Projection 0.00 root test.t.a, test.t.b, test.t.c, test.t.d", + " └─IndexLookUp 0.00 root ", + " ├─IndexRangeScan(Build) 2.50 cop[tikv] table:t, index:idx(a, b, c) range:(1 2,1 10), keep order:true, stats:pseudo", + " └─Selection(Probe) 0.00 cop[tikv] eq(test.t.d, 10)", " └─TableRowIDScan 2.50 cop[tikv] table:t keep order:false, stats:pseudo" ] }, { "SQL": "desc format = 'brief' select * from t where a = 1 and b > 2 and b < 10 and d = 10 order by b desc, c desc limit 10", "Plan": [ - "TopN 0.00 root test.t.b:desc, test.t.c:desc, offset:0, count:10", - "└─IndexLookUp 0.00 root ", - " ├─IndexRangeScan(Build) 2.50 cop[tikv] table:t, index:idx(a, b, c) range:(1 2,1 10), keep order:false, stats:pseudo", - " └─TopN(Probe) 0.00 cop[tikv] test.t.b:desc, test.t.c:desc, offset:0, count:10", - " └─Selection 0.00 cop[tikv] eq(test.t.d, 10)", + "Limit 0.00 root offset:0, count:10", + "└─Projection 0.00 root test.t.a, test.t.b, test.t.c, test.t.d", + " └─IndexLookUp 0.00 root ", + " ├─IndexRangeScan(Build) 2.50 cop[tikv] table:t, index:idx(a, b, c) range:(1 2,1 10), keep order:true, desc, stats:pseudo", + " └─Selection(Probe) 0.00 cop[tikv] eq(test.t.d, 10)", " └─TableRowIDScan 2.50 cop[tikv] table:t keep order:false, stats:pseudo" ] } @@ -6280,11 +8734,11 @@ " └─Apply 10000.00 root CARTESIAN left outer join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - " └─Projection(Probe) 1.00 root 1->Column#25", - " └─Limit 1.00 root offset:0, count:1", - " └─TableReader 1.00 root data:Limit", - " └─Limit 1.00 cop[tikv] offset:0, count:1", - " └─TableFullScan 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─Projection(Probe) 10000.00 root 1->Column#25", + " └─Limit 10000.00 root offset:0, count:1", + " └─TableReader 10000.00 root data:Limit", + " └─Limit 10000.00 cop[tikv] offset:0, count:1", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Res": [ "1", @@ -7054,10 +9508,11 @@ " └─TableReader 8000.00 root data:ExchangeSender", " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.id", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, test.t.name, funcs:count(1)->Column#5, funcs:firstrow(test.t.id)->test.t.id", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin], [name: test.t.id, collate: binary]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, test.t.name, funcs:sum(Column#7)->Column#5, funcs:firstrow(test.t.id)->test.t.id", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin], [name: test.t.id, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, test.t.name, funcs:count(1)->Column#7", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -7067,10 +9522,11 @@ "└─TableReader 8000.00 root data:ExchangeSender", " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 8000.00 mpp[tiflash] Column#5", - " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.name, funcs:count(1)->Column#5", - " └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin]", - " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.name, funcs:sum(Column#8)->Column#5", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin]", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.name, funcs:count(1)->Column#8", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] }, { @@ -7101,10 +9557,11 @@ " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast", " │ └─Projection 7992.00 mpp[tiflash] test.t.id", " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.id, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.id, ", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.id))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.id))", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ] @@ -7146,10 +9603,11 @@ " ├─Projection 8000.00 mpp[tiflash] cast(Column#12, bigint(21) BINARY)->Column#12", " │ └─Projection 8000.00 mpp[tiflash] Column#5", " │ └─Projection 8000.00 mpp[tiflash] Column#5, test.t.id", - " │ └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, test.t.name, funcs:count(1)->Column#5, funcs:firstrow(test.t.id)->test.t.id", - " │ └─ExchangeReceiver 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin], [name: test.t.id, collate: binary]", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, test.t.name, funcs:sum(Column#19)->Column#5, funcs:firstrow(test.t.id)->test.t.id", + " │ └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " │ └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.name, collate: utf8mb4_bin], [name: test.t.id, collate: binary]", + " │ └─HashAgg 8000.00 mpp[tiflash] group by:test.t.id, test.t.name, funcs:count(1)->Column#19", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", " └─Projection 10000.00 mpp[tiflash] cast(Column#11, bigint(21) BINARY)->Column#12", " └─Projection 10000.00 mpp[tiflash] plus(test.t.id, 1)->Column#11", " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" @@ -7294,11 +9752,12 @@ " └─ExchangeReceiver 2666.67 mpp[tiflash] stream_count: 8", " └─ExchangeSender 2666.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c2, collate: binary], stream_count: 8", " └─Projection 2666.67 mpp[tiflash] Column#4, test.t1.c2", - " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c1, funcs:count(test.t1.c2)->Column#4, funcs:firstrow(test.t1.c2)->test.t1.c2", - " └─ExchangeReceiver 3333.33 mpp[tiflash] ", - " └─ExchangeSender 3333.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary]", - " └─Selection 3333.33 mpp[tiflash] gt(test.t1.c1, 10)", - " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c1, funcs:sum(Column#9)->Column#4, funcs:firstrow(Column#10)->test.t1.c2", + " └─ExchangeReceiver 2666.67 mpp[tiflash] ", + " └─ExchangeSender 2666.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary]", + " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c1, funcs:count(test.t1.c2)->Column#9, funcs:firstrow(test.t1.c2)->Column#10", + " └─Selection 3333.33 mpp[tiflash] gt(test.t1.c1, 10)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" ] }, { @@ -7312,11 +9771,12 @@ " └─ExchangeReceiver 2666.67 mpp[tiflash] stream_count: 8", " └─ExchangeSender 2666.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary], stream_count: 8", " └─Projection 2666.67 mpp[tiflash] Column#4, test.t1.c1, test.t1.c2", - " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c2, funcs:count(test.t1.c1)->Column#4, funcs:firstrow(test.t1.c1)->test.t1.c1, funcs:firstrow(test.t1.c2)->test.t1.c2", - " └─ExchangeReceiver 3333.33 mpp[tiflash] ", - " └─ExchangeSender 3333.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c2, collate: binary]", - " └─Selection 3333.33 mpp[tiflash] gt(test.t1.c2, 10)", - " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c2, funcs:sum(Column#9)->Column#4, funcs:firstrow(Column#10)->test.t1.c1, funcs:firstrow(test.t1.c2)->test.t1.c2", + " └─ExchangeReceiver 2666.67 mpp[tiflash] ", + " └─ExchangeSender 2666.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c2, collate: binary]", + " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c2, funcs:count(test.t1.c1)->Column#9, funcs:firstrow(test.t1.c1)->Column#10", + " └─Selection 3333.33 mpp[tiflash] gt(test.t1.c2, 10)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" ] }, { @@ -7382,11 +9842,12 @@ " └─Window 2666.67 mpp[tiflash] row_number()->Column#6 over(partition by test.t1.c1 order by test.t1.c2 rows between current row and current row)", " └─Sort 2666.67 mpp[tiflash] test.t1.c1, test.t1.c2", " └─Projection 2666.67 mpp[tiflash] Column#4, test.t1.c1, test.t1.c2", - " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c1, funcs:count(test.t1.c2)->Column#4, funcs:firstrow(test.t1.c1)->test.t1.c1, funcs:firstrow(test.t1.c2)->test.t1.c2", - " └─ExchangeReceiver 3333.33 mpp[tiflash] ", - " └─ExchangeSender 3333.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary]", - " └─Selection 3333.33 mpp[tiflash] gt(test.t1.c1, 10)", - " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c1, funcs:sum(Column#9)->Column#4, funcs:firstrow(test.t1.c1)->test.t1.c1, funcs:firstrow(Column#11)->test.t1.c2", + " └─ExchangeReceiver 2666.67 mpp[tiflash] ", + " └─ExchangeSender 2666.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t1.c1, collate: binary]", + " └─HashAgg 2666.67 mpp[tiflash] group by:test.t1.c1, funcs:count(test.t1.c2)->Column#9, funcs:firstrow(test.t1.c2)->Column#11", + " └─Selection 3333.33 mpp[tiflash] gt(test.t1.c1, 10)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" ] } ] @@ -7406,11 +9867,11 @@ "├─TableReader(Build) 9980.01 root data:Selection", "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.e)), not(isnull(test.t2.g))", "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 0.00 root ", - " ├─Selection(Build) 0.03 cop[tikv] not(isnull(test.t1.b))", - " │ └─IndexRangeScan 0.03 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) eq(test.t1.d, test.t2.g) in(test.t1.a, 1, 3) in(test.t1.c, aaa, bbb)], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.00 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\"), not(isnull(test.t1.d))", - " └─TableRowIDScan 0.03 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 0.50 root ", + " ├─Selection(Build) 249.50 cop[tikv] not(isnull(test.t1.b)), not(isnull(test.t1.d))", + " │ └─IndexRangeScan 250.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) eq(test.t1.d, test.t2.g) in(test.t1.a, 1, 3) in(test.t1.c, aaa, bbb)], keep order:false, stats:pseudo", + " └─Selection(Probe) 0.50 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\")", + " └─TableRowIDScan 249.50 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": null }, @@ -7426,11 +9887,11 @@ "├─TableReader(Build) 9980.01 root data:Selection", "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.e)), not(isnull(test.t2.g))", "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 0.00 root ", - " ├─Selection(Build) 0.03 cop[tikv] not(isnull(test.t1.b))", - " │ └─IndexRangeScan 0.03 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) in(test.t1.a, 1, 3) in(test.t1.c, aaa, bbb)], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.00 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\"), not(isnull(test.t1.d))", - " └─TableRowIDScan 0.03 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 0.50 root ", + " ├─Selection(Build) 249.50 cop[tikv] not(isnull(test.t1.b)), not(isnull(test.t1.d))", + " │ └─IndexRangeScan 250.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) in(test.t1.a, 1, 3) in(test.t1.c, aaa, bbb)], keep order:false, stats:pseudo", + " └─Selection(Probe) 0.50 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\")", + " └─TableRowIDScan 249.50 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": [ "Memory capacity of 2900 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen" @@ -7448,11 +9909,11 @@ "├─TableReader(Build) 9980.01 root data:Selection", "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.e)), not(isnull(test.t2.g))", "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 0.00 root ", - " ├─Selection(Build) 0.03 cop[tikv] not(isnull(test.t1.b))", - " │ └─IndexRangeScan 0.03 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) in(test.t1.a, 1, 3)], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.00 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\"), not(isnull(test.t1.d))", - " └─TableRowIDScan 0.03 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 0.50 root ", + " ├─Selection(Build) 249.50 cop[tikv] not(isnull(test.t1.b)), not(isnull(test.t1.d))", + " │ └─IndexRangeScan 250.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.b, test.t2.e) in(test.t1.a, 1, 3)], keep order:false, stats:pseudo", + " └─Selection(Probe) 0.50 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\")", + " └─TableRowIDScan 249.50 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": [ "Memory capacity of 2300 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen" @@ -7468,10 +9929,10 @@ "Plan": [ "HashJoin 0.05 root inner join, equal:[eq(test.t1.b, test.t2.e) eq(test.t1.d, test.t2.g)]", "├─IndexLookUp(Build) 0.04 root ", - "│ ├─Selection(Build) 19.98 cop[tikv] not(isnull(test.t1.b))", + "│ ├─Selection(Build) 19.96 cop[tikv] not(isnull(test.t1.b)), not(isnull(test.t1.d))", "│ │ └─IndexRangeScan 20.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range:[1,1], [3,3], keep order:false, stats:pseudo", - "│ └─Selection(Probe) 0.04 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\"), not(isnull(test.t1.d))", - "│ └─TableRowIDScan 19.98 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─Selection(Probe) 0.04 cop[tikv] in(test.t1.c, \"aaa\", \"bbb\")", + "│ └─TableRowIDScan 19.96 cop[tikv] table:t1 keep order:false, stats:pseudo", "└─TableReader(Probe) 9980.01 root data:Selection", " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.e)), not(isnull(test.t2.g))", " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" @@ -7493,10 +9954,10 @@ "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.e))", "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 0.03 root ", - " ├─Selection(Build) 0.03 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 0.03 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e) gt(test.t1.b, 1) lt(test.t1.b, 10)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 0.03 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 312.19 root ", + " ├─Selection(Build) 312.19 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 312.50 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e) gt(test.t1.b, 1) lt(test.t1.b, 10)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 312.19 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": null }, @@ -7512,10 +9973,10 @@ "├─TableReader(Build) 9990.00 root data:Selection", "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.e))", "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 0.03 root ", - " ├─Selection(Build) 0.03 cop[tikv] gt(test.t1.b, 1), lt(test.t1.b, 10), not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 0.03 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 312.19 root ", + " ├─Selection(Build) 312.19 cop[tikv] gt(test.t1.b, 1), lt(test.t1.b, 10), not(isnull(test.t1.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 312.19 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": [ "Memory capacity of 300 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen" @@ -7533,10 +9994,10 @@ "├─TableReader(Build) 9980.01 root data:Selection", "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.e)), not(isnull(test.t2.f))", "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e) gt(test.t1.b, test.t2.f) lt(test.t1.b, plus(test.t2.f, 10))], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12475.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e) gt(test.t1.b, test.t2.f) lt(test.t1.b, plus(test.t2.f, 10))], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": null }, @@ -7552,15 +10013,217 @@ "├─TableReader(Build) 9980.01 root data:Selection", "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.e)), not(isnull(test.t2.f))", "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12475.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(test.t1.a, test.t2.e)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 12475.01 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warn": [ "Memory capacity of 300 bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen" ] } ] + }, + { + "Name": "TestNullConditionForPrefixIndex", + "Cases": [ + { + "SQL": "select count(1) from t1 where c1 = '0xfff' and c2 is not null", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader 1.00 root index:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan 99.90 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" -inf,\"0xfff\" +inf], keep order:false, stats:pseudo" + ], + "Result": [ + "3" + ] + }, + { + "SQL": "select count(1) from t1 where c1 = '0xfff' and c2 is null", + "Plan": [ + "StreamAgg 1.00 root funcs:count(1)->Column#5", + "└─IndexReader 0.10 root index:IndexRangeScan", + " └─IndexRangeScan 0.10 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" NULL,\"0xfff\" NULL], keep order:false, stats:pseudo" + ], + "Result": [ + "1" + ] + }, + { + "SQL": "select count(1) from t1 where c1 >= '0xfff' and c2 is not null", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#6)->Column#5", + "└─IndexReader 1.00 root index:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#6", + " └─Selection 3330.00 cop[tikv] not(isnull(test.t1.c2))", + " └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo" + ], + "Result": [ + "3" + ] + }, + { + "SQL": "select count(1) from t1 where c1 >= '0xfff' and c2 is null", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader 1.00 root index:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#7", + " └─Selection 3.33 cop[tikv] isnull(test.t1.c2)", + " └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo" + ], + "Result": [ + "1" + ] + }, + { + "SQL": "select count(1) from t1 where c1 = '0xfff' and (c2 + 1) is not null", + "Plan": [ + "StreamAgg 1.00 root funcs:count(1)->Column#5", + "└─IndexLookUp 8.00 root ", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:idx1(c1) range:[\"0xfff\",\"0xfff\"], keep order:false, stats:pseudo", + " └─Selection(Probe) 8.00 cop[tikv] not(isnull(plus(cast(test.t1.c2, double BINARY), 1)))", + " └─TableRowIDScan 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "3" + ] + }, + { + "SQL": "select count(1) from t1 where c1 = '0xfff' and (c2 + 1) is null", + "Plan": [ + "StreamAgg 1.00 root funcs:count(1)->Column#5", + "└─IndexLookUp 8.00 root ", + " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:idx1(c1) range:[\"0xfff\",\"0xfff\"], keep order:false, stats:pseudo", + " └─Selection(Probe) 8.00 cop[tikv] isnull(plus(cast(test.t1.c2, double BINARY), 1))", + " └─TableRowIDScan 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1" + ] + }, + { + "SQL": "select c2 from t1 use index(idx2) where c1 = '0xfff' and c2 is not null", + "Plan": [ + "Projection 99.90 root test.t1.c2", + "└─IndexLookUp 99.90 root ", + " ├─IndexRangeScan(Build) 99.90 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" -inf,\"0xfff\" +inf], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 99.90 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "", + "111111", + "22 " + ] + }, + { + "SQL": "select c2 from t1 use index(idx2) where c1 = '0xfff' and c2 is null", + "Plan": [ + "Projection 0.10 root test.t1.c2", + "└─IndexLookUp 0.10 root ", + " ├─IndexRangeScan(Build) 0.10 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\" NULL,\"0xfff\" NULL], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 0.10 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "" + ] + }, + { + "SQL": "select c2 from t1 use index(idx2) where c1 >= '0xfff' and c2 is not null", + "Plan": [ + "Projection 3330.00 root test.t1.c2", + "└─IndexLookUp 3330.00 root ", + " ├─Selection(Build) 3330.00 cop[tikv] not(isnull(test.t1.c2))", + " │ └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 3330.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "", + "111111", + "22 " + ] + }, + { + "SQL": "select c2 from t1 use index(idx2) where c1 >= '0xfff' and c2 is null", + "Plan": [ + "Projection 3.33 root test.t1.c2", + "└─IndexLookUp 3.33 root ", + " ├─Selection(Build) 3.33 cop[tikv] isnull(test.t1.c2)", + " │ └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:idx2(c1, c2) range:[\"0xfff\",+inf], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 3.33 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "" + ] + }, + { + "SQL": "select count(1) from t2 use index(idx) where b is not null", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#5)->Column#4", + "└─IndexReader 1.00 root index:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#5", + " └─IndexFullScan 9990.00 cop[tikv] table:t2, index:idx(b) keep order:false, stats:pseudo" + ], + "Result": [ + "3" + ] + }, + { + "SQL": "select count(1) from t2 use index(idx) where b is null", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#6)->Column#4", + "└─IndexReader 1.00 root index:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan 10.00 cop[tikv] table:t2, index:idx(b) range:[NULL,NULL], keep order:false, stats:pseudo" + ], + "Result": [ + "1" + ] + }, + { + "SQL": "select b from t2 use index(idx) where b is not null", + "Plan": [ + "IndexLookUp 9990.00 root ", + "├─IndexFullScan(Build) 9990.00 cop[tikv] table:t2, index:idx(b) keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 9990.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "", + "aaaaaa", + "bb " + ] + }, + { + "SQL": "select b from t2 use index(idx) where b is null", + "Plan": [ + "IndexLookUp 10.00 root ", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t2, index:idx(b) range:[NULL,NULL], keep order:false, stats:pseudo", + "└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "" + ] + }, + { + "SQL": "select b from t3 where a = 1 and b is not null", + "Plan": [ + "Projection 10.00 root test.t3.b", + "└─TableReader 10.00 root data:TableRangeScan", + " └─TableRangeScan 10.00 cop[tikv] table:t3 range:[1,1], keep order:false, stats:pseudo" + ], + "Result": [ + "", + "aaaaaa", + "bb " + ] + }, + { + "SQL": "select b from t3 where a = 1 and b is null", + "Plan": [ + "TableDual 0.00 root rows:0" + ], + "Result": null + } + ] } ] diff --git a/planner/core/testdata/join_reorder_suite_out.json b/planner/core/testdata/join_reorder_suite_out.json index 41ed45dcb3cd4..e2a6c562726d4 100644 --- a/planner/core/testdata/join_reorder_suite_out.json +++ b/planner/core/testdata/join_reorder_suite_out.json @@ -381,11 +381,11 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.a, test.t1.a)]", - " ├─TableReader(Build) 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─IndexReader(Probe) 9990.00 root index:IndexFullScan", - " └─IndexFullScan 9990.00 cop[tikv] table:t, index:a(a) keep order:false, stats:pseudo" + " ├─IndexReader(Build) 9990.00 root index:IndexFullScan", + " │ └─IndexFullScan 9990.00 cop[tikv] table:t, index:a(a) keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": null }, @@ -413,11 +413,11 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.a, test.t1.a)]", - " ├─TableReader(Build) 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─IndexReader(Probe) 9990.00 root index:IndexFullScan", - " └─IndexFullScan 9990.00 cop[tikv] table:t, index:a(a) keep order:false, stats:pseudo" + " ├─IndexReader(Build) 9990.00 root index:IndexFullScan", + " │ └─IndexFullScan 9990.00 cop[tikv] table:t, index:a(a) keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": null }, @@ -508,12 +508,12 @@ " ├─IndexReader(Build) 9990.00 root index:IndexFullScan", " │ └─IndexFullScan 9990.00 cop[tikv] table:t, index:a(a) keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.b, test.t2.b)]", - " ├─TableReader(Build) 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": null }, @@ -540,12 +540,12 @@ " ├─IndexReader(Build) 9990.00 root index:IndexFullScan", " │ └─IndexFullScan 9990.00 cop[tikv] table:t, index:a(a) keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]", - " ├─TableReader(Build) 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " ├─TableReader(Build) 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": null }, @@ -1561,12 +1561,12 @@ " │ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", " │ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - " │ ├─TableReader(Build) 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ ├─TableReader(Build) 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ └─TableReader(Probe) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", " └─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1594,12 +1594,12 @@ " │ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", " │ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - " │ ├─TableReader(Build) 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ ├─TableReader(Build) 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ └─TableReader(Probe) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", " └─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t4.a, test.t8.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t8.a))", @@ -1626,12 +1626,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1661,12 +1661,12 @@ " │ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", " │ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - " │ ├─TableReader(Build) 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ ├─TableReader(Build) 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ └─TableReader(Probe) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", " └─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1694,12 +1694,12 @@ " │ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", " │ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - " │ ├─TableReader(Build) 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ ├─TableReader(Build) 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ └─TableReader(Probe) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", " └─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t4.a, test.t8.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t8.a))", @@ -1726,12 +1726,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1761,12 +1761,12 @@ " │ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", " │ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - " │ ├─TableReader(Build) 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ ├─TableReader(Build) 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + " │ └─TableReader(Probe) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", " └─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1793,12 +1793,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1828,11 +1828,11 @@ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t5.a, test.t6.a)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─IndexReader(Probe) 9990.00 root index:IndexFullScan", - "│ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", + "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", + "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1859,12 +1859,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1955,12 +1955,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -1989,12 +1989,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -2023,12 +2023,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -2057,12 +2057,12 @@ "│ ├─IndexReader(Build) 9990.00 root index:IndexFullScan", "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t5, index:a(a) keep order:false, stats:pseudo", "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t6.b, test.t7.b)]", - "│ ├─TableReader(Build) 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ ├─TableReader(Build) 9990.00 root data:Selection", + "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t7.b))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t7 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t6.a)), not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -2136,11 +2136,11 @@ " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - " └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t1.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": null }, @@ -2205,11 +2205,11 @@ " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - " └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t1.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": null }, @@ -2279,11 +2279,11 @@ " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - " └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t1.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": null } @@ -2533,60 +2533,60 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", - " │ ├─PartitionUnion(Build) 39960.00 root ", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", - " │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49950.00 root ", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49950.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39960.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -2608,60 +2608,60 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", - " │ ├─PartitionUnion(Build) 39960.00 root ", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", - " │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49950.00 root ", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49950.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39960.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -2683,60 +2683,60 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", - " │ ├─PartitionUnion(Build) 39960.00 root ", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", - " │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49950.00 root ", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49950.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39960.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -2758,60 +2758,60 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", - " │ ├─PartitionUnion(Build) 39960.00 root ", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", - " │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49950.00 root ", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49950.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39960.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -2833,60 +2833,60 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", - " │ ├─PartitionUnion(Build) 39960.00 root ", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9990.00 root data:Selection", - " │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", - " │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49950.00 root ", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49950.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root left outer join, equal:[eq(test.t.a, test.t1.a)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t.a, test.t4.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39960.00 root ", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9990.00 root data:Selection", + " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -2985,56 +2985,56 @@ "SQL": "select /*+ leading(t2, t3) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", "Plan": [ "HashJoin 58476.62 root left outer join, equal:[eq(test.t2.b, test.t1.b)]", - "├─Projection(Build) 46781.30 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - "│ └─HashJoin 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - "│ ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - "│ │ ├─PartitionUnion(Build) 29940.03 root ", - "│ │ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", - "│ │ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", - "│ │ │ └─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", - "│ │ └─PartitionUnion(Probe) 39920.04 root ", - "│ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - "│ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - "│ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - "│ │ └─TableReader 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - "│ └─PartitionUnion(Probe) 39960.00 root ", - "│ ├─TableReader 9990.00 root data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - "│ ├─TableReader 9990.00 root data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - "│ ├─TableReader 9990.00 root data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - "│ └─TableReader 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - "└─PartitionUnion(Probe) 50000.00 root ", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + "├─PartitionUnion(Build) 50000.00 root ", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + "│ └─TableReader 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + "└─Projection(Probe) 46781.30 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + " └─HashJoin 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39920.04 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", @@ -3045,56 +3045,56 @@ "SQL": "select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", "Plan": [ "HashJoin 58476.62 root left outer join, equal:[eq(test.t2.b, test.t1.b)]", - "├─Projection(Build) 46781.30 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - "│ └─HashJoin 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - "│ ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - "│ │ ├─PartitionUnion(Build) 29940.03 root ", - "│ │ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", - "│ │ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", - "│ │ │ └─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", - "│ │ └─PartitionUnion(Probe) 39920.04 root ", - "│ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - "│ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - "│ │ ├─TableReader 9980.01 root data:Selection", - "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - "│ │ └─TableReader 9980.01 root data:Selection", - "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - "│ └─PartitionUnion(Probe) 39960.00 root ", - "│ ├─TableReader 9990.00 root data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - "│ ├─TableReader 9990.00 root data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - "│ ├─TableReader 9990.00 root data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - "│ └─TableReader 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - "└─PartitionUnion(Probe) 50000.00 root ", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 10000.00 root data:TableFullScan", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + "├─PartitionUnion(Build) 50000.00 root ", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + "│ ├─TableReader 10000.00 root data:TableFullScan", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + "│ └─TableReader 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + "└─Projection(Probe) 46781.30 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + " └─HashJoin 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39920.04 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -3859,60 +3859,60 @@ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t1.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - " │ │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", - " │ │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", - " │ │ │ └─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", - " │ │ └─PartitionUnion(Probe) 39920.04 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49900.05 root ", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49900.05 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39920.04 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -3951,60 +3951,60 @@ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t1.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - " │ │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", - " │ │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", - " │ │ │ └─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", - " │ │ └─PartitionUnion(Probe) 39920.04 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49900.05 root ", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49900.05 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39920.04 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -4043,60 +4043,60 @@ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo", " └─HashJoin(Probe) 58476.62 root inner join, equal:[eq(test.t1.b, test.t2.b)]", - " ├─HashJoin(Build) 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - " │ │ ├─PartitionUnion(Build) 29940.03 root ", - " │ │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", - " │ │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", - " │ │ │ └─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", - " │ │ └─PartitionUnion(Probe) 39920.04 root ", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", - " │ │ ├─TableReader 9980.01 root data:Selection", - " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", - " │ │ └─TableReader 9980.01 root data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", - " │ └─PartitionUnion(Probe) 39960.00 root ", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", - " │ ├─TableReader 9990.00 root data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", - " │ └─TableReader 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo", - " └─PartitionUnion(Probe) 49900.05 root ", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", - " ├─TableReader 9980.01 root data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", - " └─TableReader 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo" + " ├─PartitionUnion(Build) 49900.05 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 46781.30 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─HashJoin(Build) 37425.04 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " │ ├─PartitionUnion(Build) 29940.03 root ", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo", + " │ │ ├─TableReader 9980.01 root data:Selection", + " │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo", + " │ │ └─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo", + " │ └─PartitionUnion(Probe) 39920.04 root ", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo", + " │ ├─TableReader 9980.01 root data:Selection", + " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo", + " │ └─TableReader 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo", + " └─PartitionUnion(Probe) 39960.00 root ", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo", + " ├─TableReader 9990.00 root data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -5320,11 +5320,11 @@ "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", "└─HashJoin(Probe) 12487.50 root right outer join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", @@ -6297,12 +6297,12 @@ "Projection 1.00 root test.t1.a, Column#14", "└─Apply 1.00 root CARTESIAN left outer join", " ├─StreamAgg(Build) 1.00 root funcs:min(test.t1.a)->Column#10, funcs:firstrow(test.t1.a)->test.t1.a", - " │ └─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + " │ └─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " │ ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " │ └─IndexReader(Probe) 1.25 root index:Selection", - " │ └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + " │ └─IndexReader(Probe) 3.75 root index:Selection", + " │ └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", " └─MaxOneRow(Probe) 1.00 root ", " └─Projection 2.00 root Column#10", " └─IndexReader 2.00 root index:Selection", @@ -6316,8 +6316,9 @@ "Plan": [ "HashJoin 4.69 root inner join, equal:[eq(test.t1.a, test.t3.a)]", "├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ └─IndexReader 3.00 root index:IndexFullScan", - "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + "│ └─IndexReader 3.00 root index:StreamAgg", + "│ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -6332,8 +6333,8 @@ "SQL": "select /*+ straight_join() */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -6428,12 +6429,12 @@ "SQL": "select /*+ straight_join() */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": null }, @@ -6915,12 +6916,12 @@ "Projection 1.00 root test.t1.a, Column#14", "└─Apply 1.00 root CARTESIAN left outer join", " ├─StreamAgg(Build) 1.00 root funcs:min(test.t1.a)->Column#10, funcs:firstrow(test.t1.a)->test.t1.a", - " │ └─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + " │ └─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " │ ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " │ └─IndexReader(Probe) 1.25 root index:Selection", - " │ └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + " │ └─IndexReader(Probe) 3.75 root index:Selection", + " │ └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", " └─MaxOneRow(Probe) 1.00 root ", " └─Projection 2.00 root Column#10", " └─IndexReader 2.00 root index:Selection", @@ -6935,12 +6936,12 @@ "Projection 1.00 root test.t1.a, Column#14", "└─Apply 1.00 root CARTESIAN left outer join", " ├─StreamAgg(Build) 1.00 root funcs:min(test.t1.a)->Column#10, funcs:firstrow(test.t1.a)->test.t1.a", - " │ └─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + " │ └─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " │ ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " │ └─IndexReader(Probe) 1.25 root index:Selection", - " │ └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + " │ └─IndexReader(Probe) 3.75 root index:Selection", + " │ └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", " └─MaxOneRow(Probe) 1.00 root ", " └─Projection 2.00 root Column#10", " └─IndexReader 2.00 root index:Selection", @@ -6957,12 +6958,12 @@ "Projection 1.00 root test.t1.a, Column#14", "└─Apply 1.00 root CARTESIAN left outer join", " ├─StreamAgg(Build) 1.00 root funcs:min(test.t1.a)->Column#10, funcs:firstrow(test.t1.a)->test.t1.a", - " │ └─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + " │ └─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " │ ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " │ └─IndexReader(Probe) 1.25 root index:Selection", - " │ └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + " │ └─IndexReader(Probe) 3.75 root index:Selection", + " │ └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", " └─MaxOneRow(Probe) 1.00 root ", " └─Projection 2.00 root Column#10", " └─IndexReader 2.00 root index:Selection", @@ -6979,12 +6980,12 @@ "Projection 1.00 root test.t1.a, Column#14", "└─Apply 1.00 root CARTESIAN left outer join", " ├─StreamAgg(Build) 1.00 root funcs:min(test.t1.a)->Column#10, funcs:firstrow(test.t1.a)->test.t1.a", - " │ └─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + " │ └─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " │ ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " │ └─IndexReader(Probe) 1.25 root index:Selection", - " │ └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + " │ └─IndexReader(Probe) 3.75 root index:Selection", + " │ └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", " └─MaxOneRow(Probe) 1.00 root ", " └─Projection 2.00 root Column#10", " └─IndexReader 2.00 root index:Selection", @@ -7002,12 +7003,12 @@ "Projection 1.00 root test.t1.a, Column#14", "└─Apply 1.00 root CARTESIAN left outer join", " ├─StreamAgg(Build) 1.00 root funcs:min(test.t1.a)->Column#10, funcs:firstrow(test.t1.a)->test.t1.a", - " │ └─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + " │ └─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " │ ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " │ └─IndexReader(Probe) 1.25 root index:Selection", - " │ └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + " │ └─IndexReader(Probe) 3.75 root index:Selection", + " │ └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", " └─MaxOneRow(Probe) 1.00 root ", " └─Projection 2.00 root Column#10", " └─IndexReader 2.00 root index:Selection", @@ -7024,12 +7025,12 @@ "Projection 1.00 root test.t1.a, Column#14", "└─Apply 1.00 root CARTESIAN left outer join", " ├─StreamAgg(Build) 1.00 root funcs:min(test.t1.a)->Column#10, funcs:firstrow(test.t1.a)->test.t1.a", - " │ └─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + " │ └─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " │ ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " │ └─IndexReader(Probe) 1.25 root index:Selection", - " │ └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + " │ └─IndexReader(Probe) 3.75 root index:Selection", + " │ └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", " └─MaxOneRow(Probe) 1.00 root ", " └─Projection 2.00 root Column#10", " └─IndexReader 2.00 root index:Selection", @@ -7045,22 +7046,22 @@ "SQL": "select /*+ leading(t4, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a = (select max(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "HashJoin 4.69 root inner join, equal:[eq(test.t1.b, test.t4.b)]", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "│ ├─IndexJoin(Build) 3.00 root inner join, inner:IndexLookUp, outer key:Column#13, inner key:test.t1.a, equal cond:eq(Column#13, test.t1.a), eq(test.t3.b, test.t1.b)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "│ ├─IndexHashJoin(Build) 3.00 root inner join, inner:IndexLookUp, outer key:Column#13, inner key:test.t1.a, equal cond:eq(Column#13, test.t1.a), eq(test.t3.b, test.t1.b)", "│ │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", "│ │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:max(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", "│ │ │ └─TableReader 3.00 root data:Selection", "│ │ │ └─Selection 3.00 cop[tikv] not(isnull(test.t3.b))", "│ │ │ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", - "│ │ └─IndexLookUp(Probe) 1.25 root ", - "│ │ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, Column#13)], keep order:false, stats:pseudo", - "│ │ └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - "│ │ └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─IndexLookUp(Probe) 3.00 root ", + "│ │ ├─Selection(Build) 3.00 cop[tikv] not(isnull(test.t1.a))", + "│ │ │ └─IndexRangeScan 3.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, Column#13)], keep order:false, stats:pseudo", + "│ │ └─Selection(Probe) 3.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableRowIDScan 3.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t2.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t2 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" @@ -7074,7 +7075,7 @@ "SQL": "select /*+ leading(t4) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a = (select max(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "Projection 4.69 root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t4.a, test.t4.b", - "└─IndexJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "└─IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", " ├─HashJoin(Build) 3.75 root inner join, equal:[eq(test.t1.b, test.t3.b) eq(test.t1.a, Column#13)]", " │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", " │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:max(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", @@ -7088,10 +7089,10 @@ " │ └─TableReader(Probe) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 4.69 root ", + " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": null }, @@ -7099,22 +7100,22 @@ "SQL": "select /*+ leading(t3@sel_2) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a = (select max(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "HashJoin 4.69 root inner join, equal:[eq(test.t1.b, test.t4.b)]", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "│ ├─IndexJoin(Build) 3.00 root inner join, inner:IndexLookUp, outer key:Column#13, inner key:test.t1.a, equal cond:eq(Column#13, test.t1.a), eq(test.t3.b, test.t1.b)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "│ ├─IndexHashJoin(Build) 3.00 root inner join, inner:IndexLookUp, outer key:Column#13, inner key:test.t1.a, equal cond:eq(Column#13, test.t1.a), eq(test.t3.b, test.t1.b)", "│ │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", "│ │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:max(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", "│ │ │ └─TableReader 3.00 root data:Selection", "│ │ │ └─Selection 3.00 cop[tikv] not(isnull(test.t3.b))", "│ │ │ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", - "│ │ └─IndexLookUp(Probe) 1.25 root ", - "│ │ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, Column#13)], keep order:false, stats:pseudo", - "│ │ └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - "│ │ └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─IndexLookUp(Probe) 3.00 root ", + "│ │ ├─Selection(Build) 3.00 cop[tikv] not(isnull(test.t1.a))", + "│ │ │ └─IndexRangeScan 3.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, Column#13)], keep order:false, stats:pseudo", + "│ │ └─Selection(Probe) 3.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableRowIDScan 3.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t2.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t2 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" @@ -7127,22 +7128,22 @@ "SQL": "select /*+ leading(t3@sel_2, t2) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a = (select max(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "HashJoin 4.69 root inner join, equal:[eq(test.t1.b, test.t4.b)]", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "│ ├─IndexJoin(Build) 3.00 root inner join, inner:IndexLookUp, outer key:Column#13, inner key:test.t1.a, equal cond:eq(Column#13, test.t1.a), eq(test.t3.b, test.t1.b)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "│ ├─IndexHashJoin(Build) 3.00 root inner join, inner:IndexLookUp, outer key:Column#13, inner key:test.t1.a, equal cond:eq(Column#13, test.t1.a), eq(test.t3.b, test.t1.b)", "│ │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", "│ │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:max(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", "│ │ │ └─TableReader 3.00 root data:Selection", "│ │ │ └─Selection 3.00 cop[tikv] not(isnull(test.t3.b))", "│ │ │ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", - "│ │ └─IndexLookUp(Probe) 1.25 root ", - "│ │ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, Column#13)], keep order:false, stats:pseudo", - "│ │ └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - "│ │ └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ │ └─IndexLookUp(Probe) 3.00 root ", + "│ │ ├─Selection(Build) 3.00 cop[tikv] not(isnull(test.t1.a))", + "│ │ │ └─IndexRangeScan 3.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, Column#13)], keep order:false, stats:pseudo", + "│ │ └─Selection(Probe) 3.00 cop[tikv] not(isnull(test.t1.b))", + "│ │ └─TableRowIDScan 3.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t2.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t2 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" @@ -7156,7 +7157,7 @@ "SQL": "select /*+ leading(t4, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a > (select min(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "HashJoin 4.69 root inner join, equal:[eq(test.t1.b, test.t4.b)]", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", "│ ├─HashJoin(Build) 3.00 root inner join, equal:[eq(test.t3.b, test.t1.b)], other cond:gt(test.t1.a, Column#13)", "│ │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", "│ │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:min(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", @@ -7166,10 +7167,10 @@ "│ │ └─TableReader(Probe) 9980.01 root data:Selection", "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t2.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t2 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" @@ -7183,7 +7184,7 @@ "SQL": "select /*+ leading(t4) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a > (select min(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "Projection 4.69 root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t4.a, test.t4.b", - "└─IndexJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "└─IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", " ├─HashJoin(Build) 3.75 root inner join, equal:[eq(test.t1.b, test.t3.b)], other cond:gt(test.t1.a, Column#13)", " │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", " │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:min(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", @@ -7197,10 +7198,10 @@ " │ └─TableReader(Probe) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 4.69 root ", + " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": null }, @@ -7208,7 +7209,7 @@ "SQL": "select /*+ leading(t3@sel_2) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a > (select min(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "HashJoin 4.69 root inner join, equal:[eq(test.t1.b, test.t4.b)]", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", "│ ├─HashJoin(Build) 3.00 root inner join, equal:[eq(test.t3.b, test.t1.b)], other cond:gt(test.t1.a, Column#13)", "│ │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", "│ │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:min(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", @@ -7218,10 +7219,10 @@ "│ │ └─TableReader(Probe) 9980.01 root data:Selection", "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t2.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t2 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" @@ -7234,7 +7235,7 @@ "SQL": "select /*+ leading(t3@sel_2, t2) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a > (select min(t3.a) from t3 where t1.b = t3.b)", "Plan": [ "HashJoin 4.69 root inner join, equal:[eq(test.t1.b, test.t4.b)]", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", "│ ├─HashJoin(Build) 3.00 root inner join, equal:[eq(test.t3.b, test.t1.b)], other cond:gt(test.t1.a, Column#13)", "│ │ ├─Selection(Build) 2.40 root not(isnull(Column#13))", "│ │ │ └─HashAgg 3.00 root group by:test.t3.b, funcs:min(test.t3.a)->Column#13, funcs:firstrow(test.t3.b)->test.t3.b", @@ -7244,10 +7245,10 @@ "│ │ └─TableReader(Probe) 9980.01 root data:Selection", "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t2.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t2 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" @@ -7261,11 +7262,12 @@ "SQL": "select /*+ leading(t4) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a in (select t3.a from t3)", "Plan": [ "Projection 5.86 root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t4.a, test.t4.b", - "└─IndexJoin 5.86 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "└─IndexHashJoin 5.86 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", " ├─HashJoin(Build) 4.69 root inner join, equal:[eq(test.t1.a, test.t3.a)]", " │ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - " │ │ └─IndexReader 3.00 root index:IndexFullScan", - " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + " │ │ └─IndexReader 3.00 root index:StreamAgg", + " │ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + " │ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t4.b, test.t1.b)]", " │ ├─TableReader(Build) 9980.01 root data:Selection", " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", @@ -7273,48 +7275,50 @@ " │ └─TableReader(Probe) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 5.86 root ", + " ├─Selection(Build) 5.86 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 5.87 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 5.86 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": null }, { "SQL": "select /*+ leading(t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "IndexJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", "│ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ │ └─IndexReader 3.00 root index:IndexFullScan", - "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + "│ │ └─IndexReader 3.00 root index:StreamAgg", + "│ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t1.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 4.69 root ", + " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": null }, { "SQL": "select /*+ leading(t2, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "IndexJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", "│ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ │ └─IndexReader 3.00 root index:IndexFullScan", - "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + "│ │ └─IndexReader 3.00 root index:StreamAgg", + "│ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t1.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 4.69 root ", + " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -7323,19 +7327,20 @@ { "SQL": "select /*+ leading(t1, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "IndexJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", "│ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ │ └─IndexReader 3.00 root index:IndexFullScan", - "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + "│ │ └─IndexReader 3.00 root index:StreamAgg", + "│ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t1.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 4.69 root ", + " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -7344,19 +7349,20 @@ { "SQL": "select /*+ leading(t3@sel_2, t2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "IndexJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", "│ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ │ └─IndexReader 3.00 root index:IndexFullScan", - "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + "│ │ └─IndexReader 3.00 root index:StreamAgg", + "│ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t1.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 4.69 root ", + " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -7365,19 +7371,20 @@ { "SQL": "select /*+ leading(t3@sel_2, t1) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ - "IndexJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", - "├─IndexJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "IndexHashJoin 4.69 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─IndexHashJoin(Build) 3.75 root inner join, inner:IndexLookUp, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", "│ ├─StreamAgg(Build) 3.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ │ └─IndexReader 3.00 root index:IndexFullScan", - "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t2.a))", - " │ └─IndexRangeScan 1.25 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t2 keep order:false, stats:pseudo" + "│ │ └─IndexReader 3.00 root index:StreamAgg", + "│ │ └─StreamAgg 3.00 cop[tikv] group by:test.t3.a, ", + "│ │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:true", + "│ └─IndexLookUp(Probe) 3.75 root ", + "│ ├─Selection(Build) 3.75 cop[tikv] not(isnull(test.t1.a))", + "│ │ └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo", + "│ └─TableRowIDScan(Probe) 3.75 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 4.69 root ", + " ├─Selection(Build) 4.69 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 4.69 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 4.69 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -7387,8 +7394,8 @@ "SQL": "select /*+ leading(t4) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 12475.01 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─Projection(Probe) 15593.77 root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t4.a, test.t4.b", " └─HashJoin 15593.77 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", @@ -7408,8 +7415,8 @@ "SQL": "select /*+ leading(t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7426,8 +7433,8 @@ "SQL": "select /*+ leading(t2, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7445,8 +7452,8 @@ "SQL": "select /*+ leading(t1, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7464,8 +7471,8 @@ "SQL": "select /*+ leading(t3@sel_2, t2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7483,8 +7490,8 @@ "SQL": "select /*+ leading(t3@sel_2, t1) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7711,12 +7718,12 @@ "SQL": "select /*+ leading(t1) */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": null }, @@ -7724,12 +7731,12 @@ "SQL": "select /*+ leading(t1, t2@sel_2) */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t2) in optimizer hint /*+ LEADING(t1, t2) */. Maybe you can use the table alias name", @@ -7740,12 +7747,12 @@ "SQL": "select /*+ leading(t1, t3) */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": null }, @@ -7753,12 +7760,12 @@ "SQL": "select /*+ leading(t2@sel_2, t1) */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t2) in optimizer hint /*+ LEADING(t2, t1) */. Maybe you can use the table alias name", @@ -7769,12 +7776,12 @@ "SQL": "select /*+ leading(t2@sel_2, t3) */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t2) in optimizer hint /*+ LEADING(t2, t3) */. Maybe you can use the table alias name", @@ -7785,12 +7792,12 @@ "SQL": "select /*+ leading(t1, t2@sel_2) */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t2) in optimizer hint /*+ LEADING(t1, t2) */. Maybe you can use the table alias name", @@ -7801,12 +7808,12 @@ "SQL": "select /*+ leading(t3, t2@sel_2) */ t1.a, (select min(t2.a) from t2) from t1 join t3 on t1.a = t3.a;", "Plan": [ "Projection 3.75 root test.t1.a, ->Column#14", - "└─IndexJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", + "└─IndexHashJoin 3.75 root inner join, inner:IndexReader, outer key:test.t3.a, inner key:test.t1.a, equal cond:eq(test.t3.a, test.t1.a)", " ├─IndexReader(Build) 3.00 root index:IndexFullScan", " │ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", - " └─IndexReader(Probe) 1.25 root index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 3.75 root index:Selection", + " └─Selection 3.75 cop[tikv] not(isnull(test.t1.a))", + " └─IndexRangeScan 3.75 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t3.a)], keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t2) in optimizer hint /*+ LEADING(t3, t2) */. Maybe you can use the table alias name", @@ -8522,11 +8529,11 @@ "│ ├─TableReader(Build) 9990.00 root data:Selection", "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "│ └─IndexLookUp(Probe) 1.25 root ", - "│ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - "│ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", - "│ └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - "│ └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─IndexLookUp(Probe) 12475.01 root ", + "│ ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t1.a))", + "│ │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", + "│ └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t1.b))", + "│ └─TableRowIDScan 12487.50 cop[tikv] table:t1 keep order:false, stats:pseudo", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t2.b, test.t3.b)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", @@ -8570,11 +8577,11 @@ " │ ├─TableReader(Build) 9990.00 root data:Selection", " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", " │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - " │ └─IndexLookUp(Probe) 1.25 root ", - " │ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", - " │ └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - " │ └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", + " │ └─IndexLookUp(Probe) 12475.01 root ", + " │ ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t1.a))", + " │ │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", + " │ └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableRowIDScan 12487.50 cop[tikv] table:t1 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t3.b, test.t2.b)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", @@ -8729,11 +8736,11 @@ " └─Sort(Probe) 12487.50 root test.t1.b", " └─HashJoin 12487.50 root right outer join, equal:[eq(test.t.a, test.t1.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warning": null }, @@ -8753,11 +8760,11 @@ " └─Sort(Probe) 12487.50 root test.t1.b", " └─HashJoin 12487.50 root right outer join, equal:[eq(test.t.a, test.t1.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warning": null }, @@ -8776,11 +8783,11 @@ " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12487.50 root right outer join, equal:[eq(test.t.a, test.t1.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check the join type or the join algorithm hint" @@ -8821,11 +8828,11 @@ " │ ├─TableReader(Build) 9990.00 root data:Selection", " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", " │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - " │ └─IndexLookUp(Probe) 1.25 root ", - " │ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.t1.a))", - " │ │ └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", - " │ └─Selection(Probe) 1.25 cop[tikv] not(isnull(test.t1.b))", - " │ └─TableRowIDScan 1.25 cop[tikv] table:t1 keep order:false, stats:pseudo", + " │ └─IndexLookUp(Probe) 12475.01 root ", + " │ ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t1.a))", + " │ │ └─IndexRangeScan 12500.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t.a)], keep order:false, stats:pseudo", + " │ └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableRowIDScan 12487.50 cop[tikv] table:t1 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t2.b, test.t3.b)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", @@ -8866,12 +8873,12 @@ "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", "└─HashJoin(Probe) 12475.01 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t3) in optimizer hint /*+ LEADING(t3) */. Maybe you can use the table alias name" @@ -9194,12 +9201,12 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t3) in optimizer hint /*+ LEADING(t3) */. Maybe you can use the table alias name" @@ -9220,12 +9227,12 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t3) in optimizer hint /*+ LEADING(t3, t1) */. Maybe you can use the table alias name", @@ -9247,12 +9254,12 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t3) in optimizer hint /*+ LEADING(t4, t3) */. Maybe you can use the table alias name", @@ -9299,12 +9306,12 @@ " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", " └─HashJoin(Probe) 12475.01 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9980.01 root data:Selection", - " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " ├─TableReader(Build) 9980.01 root data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t3) in optimizer hint /*+ LEADING(t3) */. Maybe you can use the table alias name" @@ -9342,9 +9349,10 @@ "Plan": [ "Projection 15593.77 root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t4.a, test.t4.b", "└─HashJoin 15593.77 root inner join, equal:[eq(test.t1.a, test.t3.a)]", - " ├─HashAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - " │ └─IndexReader 9990.00 root index:IndexFullScan", - " │ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:false, stats:pseudo", + " ├─StreamAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + " │ └─IndexReader 7992.00 root index:StreamAgg", + " │ └─StreamAgg 7992.00 cop[tikv] group by:test.t3.a, ", + " │ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:true, stats:pseudo", " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -9363,16 +9371,17 @@ "SQL": "select /*+ leading(t3@sel_2) */ * from t1 left join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ "HashJoin 12487.50 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - "├─TableReader(Build) 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─HashJoin(Probe) 9990.00 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - " ├─HashAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - " │ └─IndexReader 9990.00 root index:IndexFullScan", - " │ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "├─HashJoin(Build) 9990.00 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + "│ ├─StreamAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + "│ │ └─IndexReader 7992.00 root index:StreamAgg", + "│ │ └─StreamAgg 7992.00 cop[tikv] group by:test.t3.a, ", + "│ │ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:true, stats:pseudo", + "│ └─TableReader(Probe) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], "Warning": null }, @@ -9380,9 +9389,10 @@ "SQL": "select /*+ leading(t2, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a in (select t3.a from t3)", "Plan": [ "HashJoin 12487.50 root inner join, equal:[eq(test.t1.a, test.t3.a)]", - "├─HashAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", - "│ └─IndexReader 9990.00 root index:IndexFullScan", - "│ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:false, stats:pseudo", + "├─StreamAgg(Build) 7992.00 root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t3.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t3, index:a(a) keep order:true, stats:pseudo", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -9550,11 +9560,11 @@ "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", "└─HashJoin(Probe) 12487.50 root right outer join, equal:[eq(test.t4.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", " └─TableReader(Probe) 9990.00 root data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 There are no matching table names for (t4) in optimizer hint /*+ LEADING(t2, t4) */. Maybe you can use the table alias name" diff --git a/planner/core/testdata/json_plan_suite_in.json b/planner/core/testdata/json_plan_suite_in.json new file mode 100644 index 0000000000000..9d006cc16396b --- /dev/null +++ b/planner/core/testdata/json_plan_suite_in.json @@ -0,0 +1,12 @@ +[ + { + "name": "TestJSONPlanInExplain", + "cases": [ + "explain format = tidb_json update t2 set id = 1 where id =2", + "explain format = tidb_json insert into t1 values(1)", + "explain format = tidb_json select count(*) from t1", + "explain format = tidb_json select * from t1", + "explain analyze format = tidb_json select * from t1, t2 where t1.id = t2.id" + ] + } +] diff --git a/planner/core/testdata/json_plan_suite_out.json b/planner/core/testdata/json_plan_suite_out.json new file mode 100644 index 0000000000000..10ba3c93ad7fb --- /dev/null +++ b/planner/core/testdata/json_plan_suite_out.json @@ -0,0 +1,165 @@ +[ + { + "Name": "TestJSONPlanInExplain", + "Cases": [ + { + "SQL": "explain format = tidb_json update t2 set id = 1 where id =2", + "JSONPlan": [ + { + "id": "Update_4", + "estRows": "N/A", + "taskType": "root", + "operatorInfo": "N/A", + "subOperators": [ + { + "id": "IndexReader_7", + "estRows": "10.00", + "taskType": "root", + "operatorInfo": "index:IndexRangeScan_6", + "subOperators": [ + { + "id": "IndexRangeScan_6", + "estRows": "10.00", + "taskType": "cop[tikv]", + "accessObject": "table:t2, index:id(id)", + "operatorInfo": "range:[2,2], keep order:false, stats:pseudo" + } + ] + } + ] + } + ] + }, + { + "SQL": "explain format = tidb_json insert into t1 values(1)", + "JSONPlan": [ + { + "id": "Insert_1", + "estRows": "N/A", + "taskType": "root", + "operatorInfo": "N/A" + } + ] + }, + { + "SQL": "explain format = tidb_json select count(*) from t1", + "JSONPlan": [ + { + "id": "HashAgg_12", + "estRows": "1.00", + "taskType": "root", + "operatorInfo": "funcs:count(Column#5)->Column#3", + "subOperators": [ + { + "id": "TableReader_13", + "estRows": "1.00", + "taskType": "root", + "operatorInfo": "data:HashAgg_5", + "subOperators": [ + { + "id": "HashAgg_5", + "estRows": "1.00", + "taskType": "cop[tikv]", + "operatorInfo": "funcs:count(test.t1._tidb_rowid)->Column#5", + "subOperators": [ + { + "id": "TableFullScan_10", + "estRows": "10000.00", + "taskType": "cop[tikv]", + "accessObject": "table:t1", + "operatorInfo": "keep order:false, stats:pseudo" + } + ] + } + ] + } + ] + } + ] + }, + { + "SQL": "explain format = tidb_json select * from t1", + "JSONPlan": [ + { + "id": "IndexReader_7", + "estRows": "10000.00", + "taskType": "root", + "operatorInfo": "index:IndexFullScan_6", + "subOperators": [ + { + "id": "IndexFullScan_6", + "estRows": "10000.00", + "taskType": "cop[tikv]", + "accessObject": "table:t1, index:id(id)", + "operatorInfo": "keep order:false, stats:pseudo" + } + ] + } + ] + }, + { + "SQL": "explain analyze format = tidb_json select * from t1, t2 where t1.id = t2.id", + "JSONPlan": [ + { + "id": "MergeJoin_8", + "estRows": "12487.50", + "actRows": "0", + "taskType": "root", + "executeInfo": "time:3.5ms, loops:1", + "operatorInfo": "inner join, left key:test.t1.id, right key:test.t2.id", + "memoryInfo": "760 Bytes", + "diskInfo": "0 Bytes", + "subOperators": [ + { + "id": "IndexReader_36(Build)", + "estRows": "9990.00", + "actRows": "0", + "taskType": "root", + "executeInfo": "time:3.47ms, loops:1, cop_task: {num: 1, max: 3.38ms, proc_keys: 0, tot_proc: 3ms, rpc_num: 1, rpc_time: 3.34ms, copr_cache_hit_ratio: 0.00, distsql_concurrency: 15}", + "operatorInfo": "index:IndexFullScan_35", + "memoryInfo": "171 Bytes", + "diskInfo": "N/A", + "subOperators": [ + { + "id": "IndexFullScan_35", + "estRows": "9990.00", + "actRows": "0", + "taskType": "cop[tikv]", + "accessObject": "table:t2, index:id(id)", + "executeInfo": "tikv_task:{time:3.3ms, loops:0}", + "operatorInfo": "keep order:true, stats:pseudo", + "memoryInfo": "N/A", + "diskInfo": "N/A" + } + ] + }, + { + "id": "IndexReader_34(Probe)", + "estRows": "9990.00", + "actRows": "0", + "taskType": "root", + "executeInfo": "time:14µs, loops:1, cop_task: {num: 1, max: 772.9µs, proc_keys: 0, rpc_num: 1, rpc_time: 735.7µs, copr_cache_hit_ratio: 0.00, distsql_concurrency: 15}", + "operatorInfo": "index:IndexFullScan_33", + "memoryInfo": "166 Bytes", + "diskInfo": "N/A", + "subOperators": [ + { + "id": "IndexFullScan_33", + "estRows": "9990.00", + "actRows": "0", + "taskType": "cop[tikv]", + "accessObject": "table:t1, index:id(id)", + "executeInfo": "tikv_task:{time:168.4µs, loops:0}", + "operatorInfo": "keep order:true, stats:pseudo", + "memoryInfo": "N/A", + "diskInfo": "N/A" + } + ] + } + ] + } + ] + } + ] + } +] diff --git a/planner/core/testdata/ordered_result_mode_suite_out.json b/planner/core/testdata/ordered_result_mode_suite_out.json index 1d724eae8eca5..f56ac82c7861d 100644 --- a/planner/core/testdata/ordered_result_mode_suite_out.json +++ b/planner/core/testdata/ordered_result_mode_suite_out.json @@ -86,11 +86,11 @@ { "Plan": [ "Sort_9 12500.00 root test.t.a, test.t.a", - "└─HashJoin_30 12500.00 root inner join, equal:[eq(test.t.a, test.t.a)]", - " ├─IndexReader_43(Build) 10000.00 root index:IndexFullScan_42", - " │ └─IndexFullScan_42 10000.00 cop[tikv] table:t2, index:b(b) keep order:false, stats:pseudo", - " └─IndexReader_39(Probe) 10000.00 root index:IndexFullScan_38", - " └─IndexFullScan_38 10000.00 cop[tikv] table:t1, index:b(b) keep order:false, stats:pseudo" + "└─MergeJoin_11 12500.00 root inner join, left key:test.t.a, right key:test.t.a", + " ├─TableReader_35(Build) 10000.00 root data:TableFullScan_34", + " │ └─TableFullScan_34 10000.00 cop[tikv] table:t2 keep order:true, stats:pseudo", + " └─TableReader_33(Probe) 10000.00 root data:TableFullScan_32", + " └─TableFullScan_32 10000.00 cop[tikv] table:t1 keep order:true, stats:pseudo" ] }, { @@ -183,12 +183,13 @@ { "Plan": [ "Sort_11 9990.00 root test.t1.a, test.t1.b, test.t1.c, test.t1.d", - "└─HashJoin_23 9990.00 root inner join, equal:[eq(test.t1.a, test.t2.b)]", - " ├─HashAgg_36(Build) 7992.00 root group by:test.t2.b, funcs:firstrow(test.t2.b)->test.t2.b", - " │ └─IndexReader_43 9990.00 root index:IndexFullScan_42", - " │ └─IndexFullScan_42 9990.00 cop[tikv] table:t2, index:b(b) keep order:false, stats:pseudo", - " └─TableReader_47(Probe) 10000.00 root data:TableFullScan_46", - " └─TableFullScan_46 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─MergeJoin_13 9990.00 root inner join, left key:test.t1.a, right key:test.t2.b", + " ├─StreamAgg_30(Build) 7992.00 root group by:test.t2.b, funcs:firstrow(test.t2.b)->test.t2.b", + " │ └─IndexReader_31 7992.00 root index:StreamAgg_27", + " │ └─StreamAgg_27 7992.00 cop[tikv] group by:test.t2.b, ", + " │ └─IndexFullScan_29 9990.00 cop[tikv] table:t2, index:b(b) keep order:true, stats:pseudo", + " └─TableReader_26(Probe) 10000.00 root data:TableFullScan_25", + " └─TableFullScan_25 10000.00 cop[tikv] table:t1 keep order:true, stats:pseudo" ] }, { @@ -309,11 +310,11 @@ { "Plan": [ "Sort_8 12500.00 root test.t1.a, test.t1.b, test.t1.c, test.t1.d", - "└─HashJoin_20 12500.00 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─IndexReader_31(Build) 10000.00 root index:IndexFullScan_30", - " │ └─IndexFullScan_30 10000.00 cop[tikv] table:t2, index:b(b) keep order:false, stats:pseudo", - " └─TableReader_27(Probe) 10000.00 root data:TableFullScan_26", - " └─TableFullScan_26 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "└─MergeJoin_10 12500.00 root left outer join, left key:test.t1.a, right key:test.t2.a", + " ├─TableReader_25(Build) 10000.00 root data:TableFullScan_24", + " │ └─TableFullScan_24 10000.00 cop[tikv] table:t2 keep order:true, stats:pseudo", + " └─TableReader_23(Probe) 10000.00 root data:TableFullScan_22", + " └─TableFullScan_22 10000.00 cop[tikv] table:t1 keep order:true, stats:pseudo" ] }, { diff --git a/planner/core/testdata/partition_pruner_out.json b/planner/core/testdata/partition_pruner_out.json index 7692aec35cd31..e4647840aa220 100644 --- a/planner/core/testdata/partition_pruner_out.json +++ b/planner/core/testdata/partition_pruner_out.json @@ -823,9 +823,9 @@ " ├─IndexReader(Build) 4.00 root partition:p0 index:Selection", " │ └─Selection 4.00 cop[tikv] not(isnull(test_partition.t6.b))", " │ └─IndexRangeScan 4.00 cop[tikv] table:t6, index:a(a, b) range:[1 1,1 1], [1 6,1 6], [2 1,2 1], [2 6,2 6], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 1.25 root partition:p0,p1 index:Selection", - " └─Selection 1.25 cop[tikv] in(test_partition.t5.b, 1, 6), not(isnull(test_partition.t5.b))", - " └─IndexRangeScan 625.00 cop[tikv] table:t5, index:a(a, b) range: decided by [eq(test_partition.t5.b, test_partition.t6.b) in(test_partition.t5.a, 1, 6)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 5.00 root partition:p0,p1 index:Selection", + " └─Selection 5.00 cop[tikv] in(test_partition.t5.b, 1, 6), not(isnull(test_partition.t5.b))", + " └─IndexRangeScan 2497.50 cop[tikv] table:t5, index:a(a, b) range: decided by [eq(test_partition.t5.b, test_partition.t6.b) in(test_partition.t5.a, 1, 6)], keep order:false, stats:pseudo" ] }, { @@ -839,17 +839,17 @@ " ├─IndexReader(Build) 4.00 root partition:p0 index:Selection", " │ └─Selection 4.00 cop[tikv] not(isnull(test_partition.t6.b))", " │ └─IndexRangeScan 4.00 cop[tikv] table:t6, index:a(a, b) range:[1 1,1 1], [1 6,1 6], [2 1,2 1], [2 6,2 6], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 1.25 root partition:p0,p1 index:Selection", - " └─Selection 1.25 cop[tikv] in(test_partition.t5.b, 1, 6), not(isnull(test_partition.t5.b))", - " └─IndexRangeScan 625.00 cop[tikv] table:t5, index:a(a, b) range: decided by [eq(test_partition.t5.b, test_partition.t6.b) in(test_partition.t5.a, 1, 6)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 5.00 root partition:p0,p1 index:Selection", + " └─Selection 5.00 cop[tikv] in(test_partition.t5.b, 1, 6), not(isnull(test_partition.t5.b))", + " └─IndexRangeScan 2497.50 cop[tikv] table:t5, index:a(a, b) range: decided by [eq(test_partition.t5.b, test_partition.t6.b) in(test_partition.t5.a, 1, 6)], keep order:false, stats:pseudo" ] }, { "SQL": "select * from t7 where a is null or a > 0 order by a;", "Result": [ - "", "1", - "2" + "2", + "" ], "Plan": [ "Sort 3343.33 root test_partition.t7.a", @@ -866,8 +866,8 @@ { "SQL": "select * from t1 order by id,a", "Result": [ - " 10 ", "1 1 1", + "10 10 10", "2 2 2", "3 3 3", "4 4 4", @@ -876,7 +876,7 @@ "7 7 7", "8 8 8", "9 9 9", - "10 10 10" + " 10 " ], "Plan": [ "Sort 10000.00 root test_partition.t1.id, test_partition.t1.a", @@ -897,17 +897,17 @@ "Plan": [ "Projection 1.00 root Column#5", "└─Sort 1.00 root test_partition.t1.id, test_partition.t1.a", - " └─StreamAgg 1.00 root funcs:count(Column#10)->Column#5, funcs:firstrow(Column#11)->test_partition.t1.id, funcs:firstrow(Column#12)->test_partition.t1.a", - " └─TableReader 1.00 root partition:all data:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#10, funcs:firstrow(test_partition.t1.id)->Column#11, funcs:firstrow(test_partition.t1.a)->Column#12", + " └─HashAgg 1.00 root funcs:count(Column#7)->Column#5, funcs:firstrow(Column#8)->test_partition.t1.id, funcs:firstrow(Column#9)->test_partition.t1.a", + " └─TableReader 1.00 root partition:all data:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#7, funcs:firstrow(test_partition.t1.id)->Column#8, funcs:firstrow(test_partition.t1.a)->Column#9", " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "IndexPlan": [ "Projection 1.00 root Column#5", "└─Sort 1.00 root test_partition_1.t1.id, test_partition_1.t1.a", - " └─StreamAgg 1.00 root funcs:count(Column#13)->Column#5, funcs:firstrow(Column#14)->test_partition_1.t1.id, funcs:firstrow(Column#15)->test_partition_1.t1.a", - " └─IndexReader 1.00 root partition:all index:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#13, funcs:firstrow(test_partition_1.t1.id)->Column#14, funcs:firstrow(test_partition_1.t1.a)->Column#15", + " └─HashAgg 1.00 root funcs:count(Column#8)->Column#5, funcs:firstrow(Column#9)->test_partition_1.t1.id, funcs:firstrow(Column#10)->test_partition_1.t1.a", + " └─IndexReader 1.00 root partition:all index:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#8, funcs:firstrow(test_partition_1.t1.id)->Column#9, funcs:firstrow(test_partition_1.t1.a)->Column#10", " └─IndexFullScan 10000.00 cop[tikv] table:t1, index:a(a, b, id) keep order:false, stats:pseudo" ] }, @@ -1341,8 +1341,8 @@ { "SQL": "select * from t1 where a = 1 or true order by id,a", "Result": [ - " 10 ", "1 1 1", + "10 10 10", "2 2 2", "3 3 3", "4 4 4", @@ -1351,7 +1351,7 @@ "7 7 7", "8 8 8", "9 9 9", - "10 10 10" + " 10 " ], "Plan": [ "Sort 10000.00 root test_partition.t1.id, test_partition.t1.a", @@ -1651,9 +1651,9 @@ " │ └─IndexReader 159.84 root partition:p0 index:HashAgg", " │ └─HashAgg 159.84 cop[tikv] group by:test_partition_1.t2.b, ", " │ └─IndexRangeScan 199.80 cop[tikv] table:t2, index:a(a, b, id) range:[1 -inf,1 +inf], [2 -inf,2 +inf], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 1.25 root partition:p0,p1 index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test_partition_1.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t2.b)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 199.80 root partition:p0,p1 index:Selection", + " └─Selection 199.80 cop[tikv] not(isnull(test_partition_1.t1.a))", + " └─IndexRangeScan 200.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t2.b)], keep order:false, stats:pseudo" ] }, { @@ -1681,9 +1681,9 @@ " │ └─IndexReader 159.84 root partition:p0 index:HashAgg", " │ └─HashAgg 159.84 cop[tikv] group by:test_partition_1.t1.b, ", " │ └─IndexRangeScan 199.80 cop[tikv] table:t1, index:a(a, b, id) range:[1 -inf,1 +inf], [2 -inf,2 +inf], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 1.25 root partition:p0,p1 index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test_partition_1.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t1.b)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 199.80 root partition:p0,p1 index:Selection", + " └─Selection 199.80 cop[tikv] not(isnull(test_partition_1.t1.a))", + " └─IndexRangeScan 200.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t1.b)], keep order:false, stats:pseudo" ] }, { @@ -1804,9 +1804,9 @@ " ├─IndexReader(Build) 0.40 root partition:p0 index:Selection", " │ └─Selection 0.40 cop[tikv] not(isnull(test_partition_1.t2.b))", " │ └─IndexRangeScan 0.40 cop[tikv] table:t2, index:a(a, b, id) range:[1 1,1 1], [1 6,1 6], [2 1,2 1], [2 6,2 6], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 0.32 root partition:p0,p1 index:Selection", - " └─Selection 0.32 cop[tikv] in(test_partition_1.t1.b, 1, 6), not(isnull(test_partition_1.t1.b))", - " └─IndexRangeScan 160.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 0.13 root partition:p0,p1 index:Selection", + " └─Selection 0.13 cop[tikv] in(test_partition_1.t1.b, 1, 6), not(isnull(test_partition_1.t1.b))", + " └─IndexRangeScan 63.94 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" ] }, { @@ -1830,9 +1830,9 @@ " ├─IndexReader(Build) 0.40 root partition:p0 index:Selection", " │ └─Selection 0.40 cop[tikv] not(isnull(test_partition_1.t2.b))", " │ └─IndexRangeScan 0.40 cop[tikv] table:t2, index:a(a, b, id) range:[1 1,1 1], [1 6,1 6], [2 1,2 1], [2 6,2 6], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 0.32 root partition:p0,p1 index:Selection", - " └─Selection 0.32 cop[tikv] in(test_partition_1.t1.b, 6, 1), not(isnull(test_partition_1.t1.b))", - " └─IndexRangeScan 160.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 0.13 root partition:p0,p1 index:Selection", + " └─Selection 0.13 cop[tikv] in(test_partition_1.t1.b, 6, 1), not(isnull(test_partition_1.t1.b))", + " └─IndexRangeScan 63.94 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" ] }, { @@ -1856,9 +1856,9 @@ " ├─IndexReader(Build) 0.60 root partition:dual index:Selection", " │ └─Selection 0.60 cop[tikv] not(isnull(test_partition_1.t2.b))", " │ └─IndexRangeScan 0.60 cop[tikv] table:t2, index:a(a, b, id) range:[1 6,1 6], [1 9,1 9], [1 100,1 100], [2 6,2 6], [2 9,2 9], [2 100,2 100], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 0.48 root partition:p1 index:Selection", - " └─Selection 0.48 cop[tikv] in(test_partition_1.t1.b, 100, 9, 6), not(isnull(test_partition_1.t1.b))", - " └─IndexRangeScan 160.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 0.29 root partition:p1 index:Selection", + " └─Selection 0.29 cop[tikv] in(test_partition_1.t1.b, 100, 9, 6), not(isnull(test_partition_1.t1.b))", + " └─IndexRangeScan 95.90 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" ] }, { @@ -1882,9 +1882,9 @@ " ├─IndexReader(Build) 0.80 root partition:p0 index:Selection", " │ └─Selection 0.80 cop[tikv] not(isnull(test_partition_1.t2.b))", " │ └─IndexRangeScan 0.80 cop[tikv] table:t2, index:a(a, b, id) range:[1 1,1 1], [1 6,1 6], [1 9,1 9], [1 100,1 100], [2 1,2 1], [2 6,2 6], [2 9,2 9], [2 100,2 100], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 0.64 root partition:p0,p1 index:Selection", - " └─Selection 0.64 cop[tikv] in(test_partition_1.t1.b, 100, 9, 6, 1), not(isnull(test_partition_1.t1.b))", - " └─IndexRangeScan 160.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 0.51 root partition:p0,p1 index:Selection", + " └─Selection 0.51 cop[tikv] in(test_partition_1.t1.b, 100, 9, 6, 1), not(isnull(test_partition_1.t1.b))", + " └─IndexRangeScan 127.87 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.b, test_partition_1.t2.b) in(test_partition_1.t1.a, 1, 6)], keep order:false, stats:pseudo" ] }, { @@ -1941,16 +1941,16 @@ "1" ], "Plan": [ - "StreamAgg 1.00 root funcs:count(Column#7)->Column#5", - "└─TableReader 1.00 root partition:p0 data:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#7", + "HashAgg 1.00 root funcs:count(Column#6)->Column#5", + "└─TableReader 1.00 root partition:p0 data:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#6", " └─Selection 5542.21 cop[tikv] or(lt(test_partition.t1.a, 1), lt(test_partition.t1.b, 2))", " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "IndexPlan": [ - "StreamAgg 1.00 root funcs:count(Column#10)->Column#5", - "└─IndexReader 1.00 root partition:p0 index:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#10", + "HashAgg 1.00 root funcs:count(Column#7)->Column#5", + "└─IndexReader 1.00 root partition:p0 index:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#7", " └─Selection 5542.21 cop[tikv] or(lt(test_partition_1.t1.a, 1), lt(test_partition_1.t1.b, 2))", " └─IndexFullScan 10000.00 cop[tikv] table:t1, index:a(a, b, id) keep order:false, stats:pseudo" ] @@ -1973,13 +1973,13 @@ "SQL": "select * from t1 where a < 3 or b > 4", "Result": [ "1 1 1", + "10 10 10", "2 2 2", "5 5 5", "6 6 6", "7 7 7", "8 8 8", - "9 9 9", - "10 10 10" + "9 9 9" ], "Plan": [ "TableReader 5548.89 root partition:p0,p1 data:Selection", @@ -2059,11 +2059,11 @@ "SQL": "select * from t1 where (a<=1 and b<=1) or (a >=6 and b>=6)", "Result": [ "1 1 1", + "10 10 10", "6 6 6", "7 7 7", "8 8 8", - "9 9 9", - "10 10 10" + "9 9 9" ], "Plan": [ "TableReader 2092.85 root partition:p0,p1 data:Selection", @@ -2080,6 +2080,7 @@ "SQL": "select * from t1 where a <= 100 and b <= 100", "Result": [ "1 1 1", + "10 10 10", "2 2 2", "3 3 3", "4 4 4", @@ -2087,8 +2088,7 @@ "6 6 6", "7 7 7", "8 8 8", - "9 9 9", - "10 10 10" + "9 9 9" ], "Plan": [ "TableReader 1104.45 root partition:p0,p1 data:Selection", @@ -2126,10 +2126,10 @@ { "SQL": "select * from t1 left join t2 on true where (t1.a <=1 or t1.a <= 3 and (t1.b >=3 and t1.b <= 5)) and (t2.a >= 6 and t2.a <= 8) and t2.b>=7 and t2.id>=7 order by t1.id,t1.a", "Result": [ - "1 1 1 8 8 8", "1 1 1 7 7 7", - "3 3 3 8 8 8", - "3 3 3 7 7 7" + "1 1 1 8 8 8", + "3 3 3 7 7 7", + "3 3 3 8 8 8" ], "Plan": [ "Sort 93855.70 root test_partition.t1.id, test_partition.t1.a", @@ -2326,8 +2326,8 @@ { "SQL": "select * from t1 where a = 3 or true order by id,a", "Result": [ - " 10 ", "1 1 1", + "10 10 10", "2 2 2", "3 3 3", "4 4 4", @@ -2336,7 +2336,7 @@ "7 7 7", "8 8 8", "9 9 9", - "10 10 10" + " 10 " ], "Plan": [ "Sort 10000.00 root test_partition.t1.id, test_partition.t1.a", @@ -2463,6 +2463,7 @@ "SQL": "select * from t1 where (a >= 1 and a <= 6) or (a>=3 and b >=3)", "Result": [ "1 1 1", + "10 10 10", "2 2 2", "3 3 3", "4 4 4", @@ -2470,8 +2471,7 @@ "6 6 6", "7 7 7", "8 8 8", - "9 9 9", - "10 10 10" + "9 9 9" ], "Plan": [ "TableReader 1333.33 root partition:p0,p1 data:Selection", @@ -2664,15 +2664,15 @@ ], "IndexPlan": [ "Sort 249.75 root test_partition_1.t1.a", - "└─IndexJoin 249.75 root inner join, inner:IndexReader, outer key:test_partition_1.t2.b, inner key:test_partition_1.t1.a, equal cond:eq(test_partition_1.t2.b, test_partition_1.t1.a)", + "└─IndexHashJoin 249.75 root inner join, inner:IndexReader, outer key:test_partition_1.t2.b, inner key:test_partition_1.t1.a, equal cond:eq(test_partition_1.t2.b, test_partition_1.t1.a)", " ├─HashAgg(Build) 199.80 root group by:test_partition_1.t2.b, funcs:firstrow(test_partition_1.t2.b)->test_partition_1.t2.b", " │ └─IndexReader 199.80 root partition:p0 index:HashAgg", " │ └─HashAgg 199.80 cop[tikv] group by:test_partition_1.t2.b, ", " │ └─Selection 249.75 cop[tikv] not(isnull(test_partition_1.t2.b))", " │ └─IndexRangeScan 250.00 cop[tikv] table:t2, index:a(a, b, id) range:[1,2], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 1.25 root partition:p0,p1 index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test_partition_1.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t2.b)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 249.75 root partition:p0,p1 index:Selection", + " └─Selection 249.75 cop[tikv] not(isnull(test_partition_1.t1.a))", + " └─IndexRangeScan 250.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t2.b)], keep order:false, stats:pseudo" ] }, { @@ -2695,15 +2695,15 @@ ], "IndexPlan": [ "Sort 249.75 root test_partition_1.t1.a", - "└─IndexJoin 249.75 root inner join, inner:IndexReader, outer key:test_partition_1.t1.b, inner key:test_partition_1.t1.a, equal cond:eq(test_partition_1.t1.b, test_partition_1.t1.a)", + "└─IndexHashJoin 249.75 root inner join, inner:IndexReader, outer key:test_partition_1.t1.b, inner key:test_partition_1.t1.a, equal cond:eq(test_partition_1.t1.b, test_partition_1.t1.a)", " ├─HashAgg(Build) 199.80 root group by:test_partition_1.t1.b, funcs:firstrow(test_partition_1.t1.b)->test_partition_1.t1.b", " │ └─IndexReader 199.80 root partition:p0 index:HashAgg", " │ └─HashAgg 199.80 cop[tikv] group by:test_partition_1.t1.b, ", " │ └─Selection 249.75 cop[tikv] not(isnull(test_partition_1.t1.b))", " │ └─IndexRangeScan 250.00 cop[tikv] table:t1, index:a(a, b, id) range:[1,2], keep order:false, stats:pseudo", - " └─IndexReader(Probe) 1.25 root partition:p0,p1 index:Selection", - " └─Selection 1.25 cop[tikv] not(isnull(test_partition_1.t1.a))", - " └─IndexRangeScan 1.25 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t1.b)], keep order:false, stats:pseudo" + " └─IndexReader(Probe) 249.75 root partition:p0,p1 index:Selection", + " └─Selection 249.75 cop[tikv] not(isnull(test_partition_1.t1.a))", + " └─IndexRangeScan 250.00 cop[tikv] table:t1, index:a(a, b, id) range: decided by [eq(test_partition_1.t1.a, test_partition_1.t1.b)], keep order:false, stats:pseudo" ] }, { diff --git a/planner/core/testdata/plan_normalized_suite_in.json b/planner/core/testdata/plan_normalized_suite_in.json index f79b7a1ed3733..81c65932f82a3 100644 --- a/planner/core/testdata/plan_normalized_suite_in.json +++ b/planner/core/testdata/plan_normalized_suite_in.json @@ -29,7 +29,14 @@ "select * from t3 where a=4", "select * from t3 where a=30", "select * from t4 where a=10", - "select * from t4 where a=20" + "select * from t4 where a=20", + "update t6 set id=id+1, id3=id2+1 where id = 1", + "insert into t6 values (1,1,1)", + "delete from t6", + "delete from t5 where id > 1", + "update t5 set id=id+1, id2=id2+1 where id = 1", + "update t5 set id=id+1, id2=id2+1, id3=id3+1 where id = 1", + "insert into t5 values (1,1,1) on duplicate key update id = 100, id3=100" ] }, { diff --git a/planner/core/testdata/plan_normalized_suite_out.json b/planner/core/testdata/plan_normalized_suite_out.json index 7acfd3c2858c1..0f4218ba2649a 100644 --- a/planner/core/testdata/plan_normalized_suite_out.json +++ b/planner/core/testdata/plan_normalized_suite_out.json @@ -56,7 +56,7 @@ "Plan": [ " Projection root test.t1.a, test.t1.b, test.t1.c", " └─Apply root semi join, equal:eq(?, ?)", - " ├─Projection root cast(test.t1.a, decimal(20,0) BINARY), test.t1.a, test.t1.b, test.t1.c", + " ├─Projection root cast(test.t1.a, decimal(10,0) BINARY), test.t1.a, test.t1.b, test.t1.c", " │ └─TableReader root ", " │ └─Selection cop gt(test.t1.b, ?)", " │ └─TableFullScan cop table:t1, range:[?,?], keep order:false", @@ -231,6 +231,52 @@ " ├─IndexRangeScan cop table:t4, partition:?, index:a(a), range:[?,?], keep order:false", " └─TableRowIDScan cop table:t4, partition:?, keep order:false" ] + }, + { + "SQL": "update t6 set id=id+1, id3=id2+1 where id = 1", + "Plan": [ + " IndexLookUp root ", + " ├─IndexRangeScan cop table:t6, index:idx_id(id), range:[?,?], keep order:false", + " └─TableRowIDScan cop table:t6, keep order:false" + ] + }, + { + "SQL": "insert into t6 values (1,1,1)", + "Plan": [ + "" + ] + }, + { + "SQL": "delete from t6", + "Plan": [ + " TableReader root ", + " └─TableFullScan cop table:t6, range:[?,?], keep order:false" + ] + }, + { + "SQL": "delete from t5 where id > 1", + "Plan": [ + " TableReader root ", + " └─TableRangeScan cop table:t5, range:[?,?], keep order:false" + ] + }, + { + "SQL": "update t5 set id=id+1, id2=id2+1 where id = 1", + "Plan": [ + " Point_Get root table:t5, handle:?" + ] + }, + { + "SQL": "update t5 set id=id+1, id2=id2+1, id3=id3+1 where id = 1", + "Plan": [ + " Point_Get root table:t5, handle:?" + ] + }, + { + "SQL": "insert into t5 values (1,1,1) on duplicate key update id = 100, id3=100", + "Plan": [ + "" + ] } ] }, diff --git a/planner/core/testdata/plan_suite_in.json b/planner/core/testdata/plan_suite_in.json index ba2755b54837a..d433f5dd88dbe 100644 --- a/planner/core/testdata/plan_suite_in.json +++ b/planner/core/testdata/plan_suite_in.json @@ -1,4 +1,73 @@ [ + { + "name": "TestMPPHints", + "cases": [ + "select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + // READ_FROM_STORAGE hint + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + // Join hint + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t2) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + + // AGG hint + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), hash_agg() */ a, sum(b) from t group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), stream_agg() */ a, sum(b) from t group by a, c", + + // Index hint + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), use_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), ignore_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), force_index(t, idx_b) */ a, sum(b) from t where b < 2 group by a, c", + "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), index_merge(t, idx_b, idx_a) */ a, sum(b) from t where b < 2 or a > 2 group by a, c", + + // Join Order hint + "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), straight_join() */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), leading(t3, t1) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), straight_join() */ * from t t2, t t1, t t3 where t1.a=t2.a and t2.b=t3.b", + "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), leading(t2, t3) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + + // View Hint + "select /*+ qb_name(qb, v), MPP_1PHASE_AGG(@qb) */ * from v", + "select /*+ qb_name(qb, v), MPP_2PHASE_AGG(@qb) */ * from v", + "select /*+ qb_name(qb, v1), shuffle_join(t1@qb, t2@qb) */ * from v1", + "select /*+ qb_name(qb, v1), broadcast_join(t1@qb, t2@qb) */ * from v1", + + // Subquery hint + "SELECT /*+ shuffle_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE */ 1 FROM t t1 WHERE t1.b = t.b);", + "SELECT /*+ broadcast_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE */ 1 FROM t t1 WHERE t1.b = t.b);", + "select * from t t1 where t1.a < (select /*+ MPP_1PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + "select * from t t1 where t1.a < (select /*+ MPP_2PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + + // CTE + "WITH CTE AS (SELECT /*+ MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "WITH CTE AS (SELECT /*+ MERGE(), broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;" + ] + }, { "name": "TestHintScope", "cases": [ @@ -359,7 +428,7 @@ ] }, { - "name": "TestRefine", + "name": "TestRefine", "cases": [ "select a from t where c is not null", "select a from t where c >= 4", @@ -808,7 +877,7 @@ { "name": "TestIssue28316", "cases": [ - "select * from t where t.a < 3 and t.a < 3" + "select * from t where t.a < 3 and t.a < 3" ] }, { @@ -1085,5 +1154,37 @@ "SELECT ta.NAME FROM ta WHERE EXISTS (select /*+ no_decorrelate() */ 1 from tb where ta.code = tb.code and tb.NAME LIKE 'chad9%') AND (select /*+ no_decorrelate() */ max(id) from tc where ta.name=tc.name and tc.name like 'chad99%') > 100 and (select /*+ no_decorrelate() */ max(id) from td where ta.id=td.id and td.name like 'chad999%') > 100" ] + }, + { + "name": "TestCountStarForTikv", + "cases": [ + "select count(*) from t", + "select count(1), count(3.1415), count(0), count(null) from t -- shouldn't be rewritten", + "select count(*) from t where a=1", + "select count(*) from t_pick_row_id", + "select t.b, t.c from (select count(*) as c from t) a, t where a.c=t.a -- shouldn't be rewritten", + "select * from t out where out.a > (select count(*) from t inn where inn.a = out.b) -- shouldn't be rewritten", + "select count(*) from t t1, t t2 where t1.a=t2.e -- shouldn't be rewritten", + "select count(distinct 1) from t -- shouldn't be rewritten", + "select count(1), count(a), count(b) from t -- shouldn't be rewritten", + "select a, count(*) from t group by a -- shouldn't be rewritten", + "select sum(a) from t -- sum shouldn't be rewritten" + ] + }, + { + "name": "TestCountStarForTiFlash", + "cases": [ + "select count(*) from t", + "select count(1), count(3.1415), count(0), count(null) from t -- every count but count(null) can be rewritten", + "select count(*) from t where a=1", + "select count(*) from t_pick_row_id", + "select t.b, t.c from (select count(*) as c from t) a, t where a.c=t.a -- test recursive", + "select * from t out where out.a > (select count(*) from t inn where inn.a = out.b) -- shouldn't be rewritten for correlated sub query", + "select count(*) from t t1, t t2 where t1.a=t2.e -- shouldn't be rewritten when join under agg", + "select count(distinct 1) from t -- shouldn't be rewritten", + "select count(1), count(a), count(b) from t -- keep count(1)", + "select a, count(*) from t group by a -- shouldn't be rewritten", + "select sum(a) from t -- sum shouldn't be rewritten" + ] } ] diff --git a/planner/core/testdata/plan_suite_out.json b/planner/core/testdata/plan_suite_out.json index 18e4396e16de6..31964823e95f2 100644 --- a/planner/core/testdata/plan_suite_out.json +++ b/planner/core/testdata/plan_suite_out.json @@ -1,4 +1,860 @@ [ + { + "Name": "TestMPPHints", + "Cases": [ + { + "SQL": "select /*+ MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a, test.t.a, test.t.c", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#10)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, Column#14, funcs:sum(Column#12)->Column#10", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#12, test.t.a, test.t.c", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a, test.t.a, test.t.c", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#10)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, Column#14, funcs:sum(Column#12)->Column#10", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#12, test.t.a, test.t.c", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_build(t1) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_build(t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), hash_join_probe(t1) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), hash_join_probe(t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), merge_join(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), shuffle_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2]), broadcast_join(t1, t2), INL_JOIN(t1, t2) */ * from t t1, t t2 where t1.a=t2.a", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]Join hints are conflict, you can only specify one type of join" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), hash_agg() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a, test.t.a, test.t.c", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), stream_agg() */ a, sum(b) from t group by a, c", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#6)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#9, funcs:sum(Column#8)->Column#6", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a, test.t.c", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), use_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "Plan": [ + "Projection 2666.67 root test.t.a, Column#5", + "└─HashAgg 2666.67 root group by:test.t.a, test.t.c, funcs:sum(Column#7)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─IndexLookUp 2666.67 root ", + " ├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo", + " └─HashAgg(Probe) 2666.67 cop[tikv] group by:test.t.a, test.t.c, funcs:sum(test.t.b)->Column#7", + " └─TableRowIDScan 3333.33 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]No available path for table test.t with the store type tiflash of the hint /*+ read_from_storage */, please check the status of the table replica and variable value of tidb_isolation_read_engines(map[0:{} 1:{} 2:{}])", + "[planner:1815]The agg can not push down to the MPP side, the MPP_1PHASE_AGG() hint is invalid" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_1PHASE_AGG(), ignore_index(t, idx_a) */ a, sum(b) from t where a > 1 group by a, c", + "Plan": [ + "TableReader 2666.67 root data:ExchangeSender", + "└─ExchangeSender 2666.67 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 2666.67 mpp[tiflash] test.t.a, Column#5", + " └─Projection 2666.67 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 2666.67 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection 3333.33 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a, test.t.a, test.t.c", + " └─ExchangeReceiver 3333.33 mpp[tiflash] ", + " └─ExchangeSender 3333.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─Selection 3333.33 mpp[tiflash] gt(test.t.a, 1)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), force_index(t, idx_b) */ a, sum(b) from t where b < 2 group by a, c", + "Plan": [ + "Projection 2658.67 root test.t.a, Column#5", + "└─HashAgg 2658.67 root group by:test.t.a, test.t.c, funcs:sum(Column#7)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─IndexLookUp 2658.67 root ", + " ├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo", + " └─HashAgg(Probe) 2658.67 cop[tikv] group by:test.t.a, test.t.c, funcs:sum(test.t.b)->Column#7", + " └─TableRowIDScan 3323.33 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]No available path for table test.t with the store type tiflash of the hint /*+ read_from_storage */, please check the status of the table replica and variable value of tidb_isolation_read_engines(map[0:{} 1:{} 2:{}])", + "[planner:1815]The agg can not push down to the MPP side, the MPP_2PHASE_AGG() hint is invalid" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t]), MPP_2PHASE_AGG(), index_merge(t, idx_b, idx_a) */ a, sum(b) from t where b < 2 or a > 2 group by a, c", + "Plan": [ + "TableReader 4439.11 root data:ExchangeSender", + "└─ExchangeSender 4439.11 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 4439.11 mpp[tiflash] test.t.a, Column#5", + " └─Projection 4439.11 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 4439.11 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#13)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 4439.11 mpp[tiflash] ", + " └─ExchangeSender 4439.11 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 4439.11 mpp[tiflash] group by:Column#16, Column#17, funcs:sum(Column#15)->Column#13", + " └─Projection 5548.89 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#15, test.t.a, test.t.c", + " └─Selection 5548.89 mpp[tiflash] or(lt(test.t.b, 2), gt(test.t.a, 2))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[parser:8061]Optimizer hint index_merge is not supported by TiDB and is ignored" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), straight_join() */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 15593.77 root data:ExchangeSender", + "└─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash] ", + " └─ExchangeSender 12475.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " └─HashJoin 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), shuffle_join(t1, t2, t3), leading(t3, t1) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 15593.77 root data:ExchangeSender", + "└─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash] ", + " └─ExchangeSender 12475.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " └─HashJoin 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]leading hint is inapplicable, check the join type or the join algorithm hint", + "[planner:1815]leading hint is inapplicable, check the join type or the join algorithm hint" + ] + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), straight_join() */ * from t t2, t t1, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 15593.77 root data:ExchangeSender", + "└─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ read_from_storage(tiflash[t1, t2, t3]), broadcast_join(t1, t2, t3), leading(t2, t3) */ * from t t1, t t2, t t3 where t1.a=t2.a and t2.b=t3.b", + "Plan": [ + "TableReader 15593.77 root data:ExchangeSender", + "└─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.a)), not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]leading hint is inapplicable, check the join type or the join algorithm hint", + "[planner:1815]leading hint is inapplicable, check the join type or the join algorithm hint" + ] + }, + { + "SQL": "select /*+ qb_name(qb, v), MPP_1PHASE_AGG(@qb) */ * from v", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#10, Column#11, funcs:sum(Column#8)->Column#5, funcs:firstrow(Column#9)->test.t.a", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#8, test.t.a, test.t.a, test.t.c", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ qb_name(qb, v), MPP_2PHASE_AGG(@qb) */ * from v", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#5", + " └─Projection 8000.00 mpp[tiflash] Column#5, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, test.t.c, funcs:sum(Column#10)->Column#5, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 8000.00 mpp[tiflash] ", + " └─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary], [name: test.t.c, collate: binary]", + " └─HashAgg 8000.00 mpp[tiflash] group by:Column#13, Column#14, funcs:sum(Column#12)->Column#10", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.b, decimal(10,0) BINARY)->Column#12, test.t.a, test.t.c", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ qb_name(qb, v1), shuffle_join(t1@qb, t2@qb) */ * from v1", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12487.50 mpp[tiflash] test.t.a", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select /*+ qb_name(qb, v1), broadcast_join(t1@qb, t2@qb) */ * from v1", + "Plan": [ + "TableReader 12487.50 root data:ExchangeSender", + "└─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 12487.50 mpp[tiflash] test.t.a", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "SELECT /*+ shuffle_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE */ 1 FROM t t1 WHERE t1.b = t.b);", + "Plan": [ + "TableReader 7992.00 root data:ExchangeSender", + "└─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 7992.00 mpp[tiflash] semi join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]There are no matching table names for (t) in optimizer hint /*+ SHUFFLE_JOIN(t) */ or /*+ SHUFFLE_JOIN(t) */. Maybe you can use the table alias name", + "[parser:1064]Optimizer hint syntax error at line 1 column 109 near \"\" " + ] + }, + { + "SQL": "SELECT /*+ broadcast_join(t) */ * FROM t WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE */ 1 FROM t t1 WHERE t1.b = t.b);", + "Plan": [ + "TableReader 7992.00 root data:ExchangeSender", + "└─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin 7992.00 mpp[tiflash] semi join, equal:[eq(test.t.b, test.t.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]There are no matching table names for (t) in optimizer hint /*+ BROADCAST_JOIN(t) */ or /*+ TIDB_BCJ(t) */. Maybe you can use the table alias name", + "[parser:1064]Optimizer hint syntax error at line 1 column 111 near \"\" " + ] + }, + { + "SQL": "select * from t t1 where t1.a < (select /*+ MPP_1PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + "Plan": [ + "TableReader 9990.00 root data:ExchangeSender", + "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 9990.00 mpp[tiflash] test.t.a, test.t.b, test.t.c", + " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)], other cond:lt(cast(test.t.a, decimal(10,0) BINARY), Column#9)", + " ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Projection 7992.00 mpp[tiflash] Column#9, test.t.b", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:Column#26, funcs:sum(Column#24)->Column#9, funcs:firstrow(Column#25)->test.t.b", + " │ └─Projection 9990.00 mpp[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#24, test.t.b, test.t.b", + " │ └─ExchangeReceiver 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "select * from t t1 where t1.a < (select /*+ MPP_2PHASE_AGG() */ sum(t2.a) from t t2 where t2.b = t1.b);", + "Plan": [ + "TableReader 9990.00 root data:ExchangeSender", + "└─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 9990.00 mpp[tiflash] test.t.a, test.t.b, test.t.c", + " └─HashJoin 9990.00 mpp[tiflash] inner join, equal:[eq(test.t.b, test.t.b)], other cond:lt(cast(test.t.a, decimal(10,0) BINARY), Column#9)", + " ├─ExchangeReceiver(Build) 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Projection 7992.00 mpp[tiflash] Column#9, test.t.b", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:test.t.b, funcs:sum(Column#13)->Column#9, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 7992.00 mpp[tiflash] ", + " │ └─ExchangeSender 7992.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─HashAgg 7992.00 mpp[tiflash] group by:Column#29, funcs:sum(Column#28)->Column#13", + " │ └─Projection 9990.00 mpp[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#28, test.t.b", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 3403.09 root group by:Column#10, Column#11, funcs:firstrow(Column#10)->Column#10, funcs:firstrow(Column#11)->Column#11", + "└─Union 3403.09 root ", + " ├─Selection 1701.55 root lt(Column#6, 18)", + " │ └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + " └─Selection 1701.55 root gt(test.t.b, 1)", + " └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + "CTE_0 2126.93 root Non-Recursive CTE", + "└─TableReader(Seed Part) 2126.93 root data:ExchangeSender", + " └─ExchangeSender 2126.93 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 2126.93 mpp[tiflash] or(lt(Column#5, 18), gt(test.t.b, 1))", + " └─Projection 2658.67 mpp[tiflash] Column#5, test.t.b", + " └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#5, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 3323.33 mpp[tiflash] ", + " └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 3403.09 root group by:Column#10, Column#11, funcs:firstrow(Column#10)->Column#10, funcs:firstrow(Column#11)->Column#11", + "└─Union 3403.09 root ", + " ├─Selection 1701.55 root lt(Column#6, 18)", + " │ └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + " └─Selection 1701.55 root gt(test.t.b, 1)", + " └─CTEFullScan 2126.93 root CTE:cte data:CTE_0", + "CTE_0 2126.93 root Non-Recursive CTE", + "└─TableReader(Seed Part) 2126.93 root data:ExchangeSender", + " └─ExchangeSender 2126.93 mpp[tiflash] ExchangeType: PassThrough", + " └─Selection 2126.93 mpp[tiflash] or(lt(Column#5, 18), gt(test.t.b, 1))", + " └─Projection 2658.67 mpp[tiflash] Column#5, test.t.b", + " └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:sum(Column#22)->Column#5, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 2658.67 mpp[tiflash] ", + " └─ExchangeSender 2658.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#22", + " └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 7095.48 root group by:Column#13, Column#14, funcs:firstrow(Column#13)->Column#13, funcs:firstrow(Column#14)->Column#14", + "└─Union 11086.68 root ", + " ├─Selection 5543.34 root lt(test.t.a, 18)", + " │ └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + " └─Selection 5543.34 root gt(test.t.b, 1)", + " └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + "CTE_0 6929.18 root Non-Recursive CTE", + "└─TableReader(Seed Part) 6929.18 root data:ExchangeSender", + " └─ExchangeSender 6929.18 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 6929.18 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 6929.18 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)], other cond:or(lt(test.t.a, 18), gt(test.t.b, 1))", + " ├─ExchangeReceiver(Build) 5543.34 mpp[tiflash] ", + " │ └─ExchangeSender 5543.34 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 5543.34 mpp[tiflash] not(isnull(test.t.a)), or(lt(test.t.a, 18), gt(test.t.b, 1))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "HashAgg 7095.48 root group by:Column#13, Column#14, funcs:firstrow(Column#13)->Column#13, funcs:firstrow(Column#14)->Column#14", + "└─Union 11086.68 root ", + " ├─Selection 5543.34 root lt(test.t.a, 18)", + " │ └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + " └─Selection 5543.34 root gt(test.t.b, 1)", + " └─CTEFullScan 6929.18 root CTE:cte data:CTE_0", + "CTE_0 6929.18 root Non-Recursive CTE", + "└─TableReader(Seed Part) 6929.18 root data:ExchangeSender", + " └─ExchangeSender 6929.18 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 6929.18 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 6929.18 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)], other cond:or(lt(test.t.a, 18), gt(test.t.b, 1))", + " ├─ExchangeReceiver(Build) 5543.34 mpp[tiflash] ", + " │ └─ExchangeSender 5543.34 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 5543.34 mpp[tiflash] not(isnull(test.t.a)), or(lt(test.t.a, 18), gt(test.t.b, 1))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), MPP_1PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 3013.16 root data:ExchangeSender", + "└─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 3013.16 mpp[tiflash] Column#20, Column#21", + " └─HashAgg 3013.16 mpp[tiflash] group by:Column#20, Column#21, funcs:firstrow(Column#20)->Column#20, funcs:firstrow(Column#21)->Column#21", + " └─ExchangeReceiver 3013.16 mpp[tiflash] ", + " └─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#20, collate: binary], [name: Column#21, collate: binary]", + " └─Union 3013.16 mpp[tiflash] ", + " ├─Projection 2126.93 mpp[tiflash] cast(Column#12, bigint(21) BINARY)->Column#20, test.t.b", + " │ └─Selection 2126.93 mpp[tiflash] lt(Column#12, 18)", + " │ └─Projection 2658.67 mpp[tiflash] Column#12, test.t.b", + " │ └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#12, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 3323.33 mpp[tiflash] ", + " │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─Projection 886.22 mpp[tiflash] cast(Column#20, bigint(21) BINARY)->Column#20, Column#21", + " └─Projection 886.22 mpp[tiflash] Column#19, test.t.b", + " └─HashAgg 886.22 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#19, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 1107.78 mpp[tiflash] ", + " └─ExchangeSender 1107.78 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " └─Selection 1107.78 mpp[tiflash] gt(test.t.b, 1), lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), MPP_2PHASE_AGG() */ count(*) as a, b FROM t WHERE t.a < 60 group by b) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 3013.16 root data:ExchangeSender", + "└─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 3013.16 mpp[tiflash] Column#20, Column#21", + " └─HashAgg 3013.16 mpp[tiflash] group by:Column#20, Column#21, funcs:firstrow(Column#20)->Column#20, funcs:firstrow(Column#21)->Column#21", + " └─ExchangeReceiver 3013.16 mpp[tiflash] ", + " └─ExchangeSender 3013.16 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#20, collate: binary], [name: Column#21, collate: binary]", + " └─Union 3013.16 mpp[tiflash] ", + " ├─Projection 2126.93 mpp[tiflash] cast(Column#12, bigint(21) BINARY)->Column#20, test.t.b", + " │ └─Selection 2126.93 mpp[tiflash] lt(Column#12, 18)", + " │ └─Projection 2658.67 mpp[tiflash] Column#12, test.t.b", + " │ └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:sum(Column#32)->Column#12, funcs:firstrow(test.t.b)->test.t.b", + " │ └─ExchangeReceiver 2658.67 mpp[tiflash] ", + " │ └─ExchangeSender 2658.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " │ └─HashAgg 2658.67 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#32", + " │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 60)", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─Projection 886.22 mpp[tiflash] cast(Column#20, bigint(21) BINARY)->Column#20, Column#21", + " └─Projection 886.22 mpp[tiflash] Column#19, test.t.b", + " └─HashAgg 886.22 mpp[tiflash] group by:test.t.b, funcs:sum(Column#46)->Column#19, funcs:firstrow(test.t.b)->test.t.b", + " └─ExchangeReceiver 886.22 mpp[tiflash] ", + " └─ExchangeSender 886.22 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.b, collate: binary]", + " └─HashAgg 886.22 mpp[tiflash] group by:test.t.b, funcs:count(1)->Column#46", + " └─Selection 1107.78 mpp[tiflash] gt(test.t.b, 1), lt(test.t.a, 60)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warn": null + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), shuffle_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 5322.67 root data:ExchangeSender", + "└─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 5322.67 mpp[tiflash] Column#29, Column#30", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, funcs:firstrow(Column#29)->Column#29, funcs:firstrow(Column#30)->Column#30", + " └─ExchangeReceiver 5322.67 mpp[tiflash] ", + " └─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#29, collate: binary], [name: Column#30, collate: binary]", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, ", + " └─Union 8316.67 mpp[tiflash] ", + " ├─Projection 4154.17 mpp[tiflash] test.t.a, test.t.b", + " │ └─HashJoin 4154.17 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " │ ├─ExchangeReceiver(Build) 3323.33 mpp[tiflash] ", + " │ │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─ExchangeReceiver(Probe) 3323.33 mpp[tiflash] ", + " │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Projection 4162.50 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 4162.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 3330.00 mpp[tiflash] ", + " │ └─ExchangeSender 3330.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " │ └─Selection 3330.00 mpp[tiflash] gt(test.t.b, 1), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]There are no matching table names for (t1, t) in optimizer hint /*+ SHUFFLE_JOIN(t1, t, t1, t) */ or /*+ SHUFFLE_JOIN(t1, t, t1, t) */. Maybe you can use the table alias name", + "[planner:1815]There are no matching table names for (t1, t, t1, t) in optimizer hint /*+ SHUFFLE_JOIN(t1, t, t1, t, t1, t) */ or /*+ SHUFFLE_JOIN(t1, t, t1, t, t1, t) */. Maybe you can use the table alias name" + ] + }, + { + "SQL": "WITH CTE AS (SELECT /*+ MERGE(), broadcast_join(t1, t) */ t.a, t.b FROM t join t t1 where t.a = t1.a) SELECT * FROM CTE WHERE CTE.a <18 union select * from cte where cte.b > 1;", + "Plan": [ + "TableReader 5322.67 root data:ExchangeSender", + "└─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 5322.67 mpp[tiflash] Column#29, Column#30", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, funcs:firstrow(Column#29)->Column#29, funcs:firstrow(Column#30)->Column#30", + " └─ExchangeReceiver 5322.67 mpp[tiflash] ", + " └─ExchangeSender 5322.67 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#29, collate: binary], [name: Column#30, collate: binary]", + " └─HashAgg 5322.67 mpp[tiflash] group by:Column#29, Column#30, ", + " └─Union 8316.67 mpp[tiflash] ", + " ├─Projection 4154.17 mpp[tiflash] test.t.a, test.t.b", + " │ └─HashJoin 4154.17 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " │ ├─ExchangeReceiver(Build) 3323.33 mpp[tiflash] ", + " │ │ └─ExchangeSender 3323.33 mpp[tiflash] ExchangeType: Broadcast", + " │ │ └─Selection 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " │ └─Selection(Probe) 3323.33 mpp[tiflash] lt(test.t.a, 18), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Projection 4162.50 mpp[tiflash] test.t.a, test.t.b", + " └─HashJoin 4162.50 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 3330.00 mpp[tiflash] ", + " │ └─ExchangeSender 3330.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection 3330.00 mpp[tiflash] gt(test.t.b, 1), not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + ], + "Warn": [ + "[planner:1815]There are no matching table names for (t1, t) in optimizer hint /*+ BROADCAST_JOIN(t1, t, t1, t) */ or /*+ TIDB_BCJ(t1, t, t1, t) */. Maybe you can use the table alias name", + "[planner:1815]There are no matching table names for (t1, t, t1, t) in optimizer hint /*+ BROADCAST_JOIN(t1, t, t1, t, t1, t) */ or /*+ TIDB_BCJ(t1, t, t1, t, t1, t) */. Maybe you can use the table alias name" + ] + } + ] + }, { "Name": "TestHintScope", "Cases": [ @@ -44,11 +900,11 @@ }, { "SQL": "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", - "Best": "IndexJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + "Best": "IndexJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" }, { "SQL": "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", - "Best": "RightHashJoin{TableReader(Table(t))->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" + "Best": "RightHashJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->IndexReader(Index(t.c_d_e)[[NULL,+inf]])}(test.t.a,test.t.c)}(test.t.a,test.t.a)" }, { "SQL": "select /*+ HASH_JOIN(@sel_2 t1@sel_2, t2@sel_2), MERGE_JOIN(@sel_1 t1@sel_1, t2@sel_1) */ * from (select t1.a, t1.b from t t1, t t2 where t1.a = t2.a) t1, t t2 where t1.b = t2.b", @@ -286,9 +1142,9 @@ }, { "SQL": "select /*+ USE_INDEX_MERGE(t1, c_d_e, f_g) */ * from t where c < 1 or f > 2", - "Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f)[(2,+inf]]], TablePlan->Table(t))", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))", "HasWarn": true, - "Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f`)" + "Hints": "use_index(@`sel_1` `test`.`t` )" }, { "SQL": "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2", @@ -304,15 +1160,15 @@ }, { "SQL": "select /*+ USE_INDEX_MERGE(db2.t) */ * from t where c < 1 or f > 2", - "Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f)[(2,+inf]]], TablePlan->Table(t))", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))", "HasWarn": true, - "Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f`)" + "Hints": "use_index(@`sel_1` `test`.`t` )" }, { "SQL": "select /*+ USE_INDEX_MERGE(db2.t, c_d_e, f_g) */ * from t where c < 1 or f > 2", - "Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f)[(2,+inf]]], TablePlan->Table(t))", + "Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))", "HasWarn": true, - "Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f`)" + "Hints": "use_index(@`sel_1` `test`.`t` )" } ] }, @@ -333,7 +1189,7 @@ }, { "SQL": "select * from t where (t.c > 0 and t.c < 2) or (t.c > 4 and t.c < 6) or (t.c > 8 and t.c < 10) or (t.c > 12 and t.c < 14) or (t.c > 16 and t.c < 18)", - "Best": "IndexLookUp(Index(t.c_d_e)[[1,1] [5,5] [9,9] [13,13] [17,17]], Table(t))" + "Best": "TableReader(Table(t)->Sel([or(or(and(gt(test.t.c, 0), lt(test.t.c, 2)), and(gt(test.t.c, 4), lt(test.t.c, 6))), or(and(gt(test.t.c, 8), lt(test.t.c, 10)), or(and(gt(test.t.c, 12), lt(test.t.c, 14)), and(gt(test.t.c, 16), lt(test.t.c, 18)))))]))" }, { "SQL": "select * from t where (t.c > 0 and t.c < 1) or (t.c > 2 and t.c < 3) or (t.c > 4 and t.c < 5) or (t.c > 6 and t.c < 7) or (t.c > 9 and t.c < 10)", @@ -413,7 +1269,7 @@ }, { "SQL": "select c from t where t.c = 1 and t.d = 1 order by t.a limit 1", - "Best": "IndexReader(Index(t.c_d_e)[[1 1,1 1]])->TopN([test.t.a],0,1)->Projection" + "Best": "IndexReader(Index(t.c_d_e)[[1 1,1 1]]->TopN([test.t.a],0,1))->TopN([test.t.a],0,1)->Projection" }, { "SQL": "select * from t where t.c = 1 and t.a > 1 order by t.d limit 1", @@ -474,7 +1330,7 @@ }, { "SQL": "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.a = t3.a", - "Best": "LeftHashJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)" + "Best": "MergeInnerJoin{MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)" }, { "SQL": "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.b = t3.a", @@ -510,7 +1366,7 @@ }, { "SQL": "select * from t t1 left outer join t t2 on t1.a = t2.a right outer join t t3 on t1.a = t3.a", - "Best": "RightHashJoin{MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)" + "Best": "MergeRightOuterJoin{MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)" }, { "SQL": "select * from t t1 join t t2 on t1.a = t2.a join t t3 on t1.a = t3.a and t1.b = 1 and t3.c = 1", @@ -614,7 +1470,7 @@ }, { "SQL": "select /*+ TIDB_INLJ(t2) */ * from t t1 where t1.a in (select a from t t2)", - "Best": "LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)" + "Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)" }, { "SQL": "select /*+ TIDB_INLJ(t1) */ * from t t1 where t1.a in (select a from t t2)", @@ -679,7 +1535,7 @@ }, { "SQL": "select * from t where a in (select a from t) order by b", - "Best": "LeftHashJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Sort" + "Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Sort" }, { "SQL": "select t.c in (select count(*) from t s, t t1 where s.a = t.a and s.a = t1.a) from t", @@ -687,7 +1543,7 @@ }, { "SQL": "select (select count(*) from t s, t t1 where s.a = t.a and s.a = t1.a) from t", - "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)->Projection}(test.t.a,test.t.a)->Projection" + "Best": "MergeLeftOuterJoin{TableReader(Table(t))->MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Projection}(test.t.a,test.t.a)->Projection" }, { "SQL": "select (select count(*) from t s, t t1 where s.a = t.a and s.a = t1.a) from t order by t.a", @@ -831,14 +1687,47 @@ }, { "Name": "TestDAGPlanBuilderUnionScan", - "Cases": null + "Cases": [ + { + "SQL": "select * from t", + "Best": "TableReader(Table(t))->UnionScan([])->Projection" + }, + { + "SQL": "select * from t where b = 1", + "Best": "TableReader(Table(t)->Sel([eq(test.t.b, 1)]))->UnionScan([eq(test.t.b, 1)])->Projection" + }, + { + "SQL": "select * from t where a = 1", + "Best": "TableReader(Table(t)->Sel([eq(test.t.a, 1)]))->UnionScan([eq(test.t.a, 1)])->Projection" + }, + { + "SQL": "select * from t where a = 1 order by a", + "Best": "TableReader(Table(t)->Sel([eq(test.t.a, 1)]))->UnionScan([eq(test.t.a, 1)])->Projection->Sort" + }, + { + "SQL": "select * from t where a = 1 order by b", + "Best": "TableReader(Table(t)->Sel([eq(test.t.a, 1)]))->UnionScan([eq(test.t.a, 1)])->Projection->Sort" + }, + { + "SQL": "select * from t where a = 1 limit 1", + "Best": "TableReader(Table(t)->Sel([eq(test.t.a, 1)]))->UnionScan([eq(test.t.a, 1)])->Limit" + }, + { + "SQL": "select * from t where c = 1", + "Best": "TableReader(Table(t)->Sel([eq(test.t.c, 1)]))->UnionScan([eq(test.t.c, 1)])->Projection" + }, + { + "SQL": "select c from t where c = 1", + "Best": "TableReader(Table(t)->Sel([eq(test.t.c, 1)]))->UnionScan([eq(test.t.c, 1)])->Projection" + } + ] }, { "Name": "TestDAGPlanBuilderAgg", "Cases": [ { "SQL": "select distinct b from t", - "Best": "TableReader(Table(t))->HashAgg" + "Best": "TableReader(Table(t)->HashAgg)->HashAgg" }, { "SQL": "select count(*) from (select * from t order by b) t group by b", @@ -862,15 +1751,15 @@ }, { "SQL": "select sum(e), avg(e + c) from t where c = 1 group by c", - "Best": "IndexReader(Index(t.c_d_e)[[1,1]]->StreamAgg)->StreamAgg" + "Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection->StreamAgg" }, { "SQL": "select sum(e), avg(e + c) from t where c = 1 group by e", - "Best": "IndexReader(Index(t.c_d_e)[[1,1]]->HashAgg)->HashAgg" + "Best": "IndexReader(Index(t.c_d_e)[[1,1]])->Projection->HashAgg" }, { "SQL": "select sum(e), avg(b + c) from t where c = 1 and e = 1 group by d", - "Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t))->Projection->HashAgg" + "Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t))->Projection->Projection->StreamAgg" }, { "SQL": "select sum(e), avg(b + c) from t where c = 1 and b = 1", @@ -878,11 +1767,11 @@ }, { "SQL": "select sum(e) as k, avg(b + c) from t where c = 1 and b = 1 and e = 1 group by d order by k", - "Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t)->Sel([eq(test.t.b, 1)]))->Projection->HashAgg->Sort" + "Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t)->Sel([eq(test.t.b, 1)]))->Projection->Projection->StreamAgg->Sort" }, { "SQL": "select sum(e) as k, avg(b + c) from t where c = 1 and b = 1 and e = 1 group by c order by k", - "Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t)->Sel([eq(test.t.b, 1)]))->Projection->HashAgg->Sort" + "Best": "IndexLookUp(Index(t.c_d_e)[[1,1]]->Sel([eq(test.t.e, 1)]), Table(t)->Sel([eq(test.t.b, 1)]))->Projection->Projection->StreamAgg->Sort" }, { "SQL": "select sum(to_base64(e)) from t where c = 1", @@ -890,7 +1779,7 @@ }, { "SQL": "select (select count(1) k from t s where s.a = t.a having k != 0) from t", - "Best": "LeftHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexReader(Index(t.f)[[NULL,+inf]])->Projection}(test.t.a,test.t.a)->Projection" + "Best": "MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))->Projection}(test.t.a,test.t.a)->Projection" }, { "SQL": "select sum(to_base64(e)) from t group by e,d,c order by c", @@ -1007,7 +1896,7 @@ }, { "SQL": "select b from t where c = 1 or c = 2 or c = 3 or c = 4 or c = 5", - "Best": "IndexLookUp(Index(t.c_d_e)[[1,5]], Table(t))->Projection" + "Best": "TableReader(Table(t)->Sel([or(or(eq(test.t.c, 1), eq(test.t.c, 2)), or(eq(test.t.c, 3), or(eq(test.t.c, 4), eq(test.t.c, 5))))]))->Projection" }, { "SQL": "select a from t where c = 5", @@ -1172,7 +2061,7 @@ }, { "SQL": "select max(a), b from t;", - "Best": "TableReader(Table(t)->StreamAgg)->StreamAgg" + "Best": "TableReader(Table(t)->HashAgg)->HashAgg" }, { "SQL": "select max(a+1) from t;", @@ -1180,11 +2069,11 @@ }, { "SQL": "select max(a), min(a) from t;", - "Best": "LeftHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}" + "Best": "RightHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}" }, { "SQL": "select max(a), min(a) from t where a > 10", - "Best": "LeftHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}" + "Best": "RightHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->TableReader(Table(t)->Limit)->Limit->StreamAgg}" }, { "SQL": "select max(d), min(d) from t where c = 1 and d > 10", @@ -1192,19 +2081,19 @@ }, { "SQL": "select max(a), max(c), min(f) from t", - "Best": "LeftHashJoin{LeftHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Limit)->Limit->StreamAgg}->IndexReader(Index(t.f)[[NULL,+inf]]->Limit)->Limit->StreamAgg}" + "Best": "LeftHashJoin{RightHashJoin{TableReader(Table(t)->Limit)->Limit->StreamAgg->IndexReader(Index(t.c_d_e)[[NULL,+inf]]->Limit)->Limit->StreamAgg}->IndexReader(Index(t.f)[[NULL,+inf]]->Limit)->Limit->StreamAgg}" }, { "SQL": "select max(a), max(b) from t", - "Best": "TableReader(Table(t)->StreamAgg)->StreamAgg" + "Best": "TableReader(Table(t)->HashAgg)->HashAgg" }, { "SQL": "select max(a), max(c) from t where c > 10", - "Best": "IndexReader(Index(t.c_d_e)[(10,+inf]]->StreamAgg)->StreamAgg" + "Best": "IndexReader(Index(t.c_d_e)[(10,+inf]]->HashAgg)->HashAgg" }, { "SQL": "select max(a), min(a) from t where a * 3 + 10 < 100", - "Best": "IndexReader(Index(t.f)[[NULL,+inf]]->Sel([lt(plus(mul(test.t.a, 3), 10), 100)])->StreamAgg)->StreamAgg" + "Best": "IndexReader(Index(t.f)[[NULL,+inf]]->Sel([lt(plus(mul(test.t.a, 3), 10), 100)])->HashAgg)->HashAgg" }, { "SQL": "select max(a) from t group by b;", @@ -1246,15 +2135,15 @@ "Cases": [ { "SQL": "select /*+ TIDB_INLJ(t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;", - "Best": "RightHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)}(test.t.a,test.t.a)->Projection", + "Best": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)}(test.t.a,test.t.a)->Projection", "Warning": "", - "Hints": "use_index(@`sel_1` `test`.`t3` `f`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` `f`), inl_join(@`sel_1` `test`.`t1`), hash_join(@`sel_1` `test`.`t3`)" + "Hints": "use_index(@`sel_1` `test`.`t3` ), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` ), inl_join(@`sel_1` `test`.`t1`), merge_join(@`sel_1` `test`.`t3`)" }, { "SQL": "select /*+ TIDB_INLJ(test.t1) */ t1.a, t2.a, t3.a from t t1, t t2, t t3 where t1.a = t2.a and t2.a = t3.a;", - "Best": "RightHashJoin{IndexReader(Index(t.f)[[NULL,+inf]])->IndexJoin{TableReader(Table(t))->IndexReader(Index(t.f)[[NULL,+inf]])}(test.t.a,test.t.a)}(test.t.a,test.t.a)->Projection", + "Best": "MergeInnerJoin{TableReader(Table(t))->IndexJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)}(test.t.a,test.t.a)->Projection", "Warning": "", - "Hints": "use_index(@`sel_1` `test`.`t3` `f`), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` `f`), inl_join(@`sel_1` `test`.`t1`), hash_join(@`sel_1` `test`.`t3`)" + "Hints": "use_index(@`sel_1` `test`.`t3` ), use_index(@`sel_1` `test`.`t1` ), use_index(@`sel_1` `test`.`t2` ), inl_join(@`sel_1` `test`.`t1`), merge_join(@`sel_1` `test`.`t3`)" }, { "SQL": "select /*+ TIDB_INLJ(t1) */ t1.b, t2.a from t t1, t t2 where t1.b = t2.a;", @@ -1403,9 +2292,9 @@ "├─UnionScan(Build) 10000.00 root ", "│ └─TableReader 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─UnionScan(Probe) 1.00 root ", - " └─TableReader 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:false, stats:pseudo" + "└─UnionScan(Probe) 10000.00 root ", + " └─TableReader 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t.a], keep order:false, stats:pseudo" ] }, { @@ -1431,13 +2320,13 @@ ], "Plan": [ "HashJoin 12487.50 root inner join, equal:[eq(test.t.a, test.t.b)]", - "├─UnionScan(Build) 9990.00 root not(isnull(test.t.b))", - "│ └─TableReader 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.b))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─UnionScan(Probe) 10000.00 root ", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + "├─UnionScan(Build) 10000.00 root ", + "│ └─TableReader 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─UnionScan(Probe) 9990.00 root not(isnull(test.t.b))", + " └─TableReader 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ] }, { @@ -1512,11 +2401,11 @@ }, { "SQL": "select /*+ inl_merge_join(t2) */ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g", - "Plan": "IndexMergeJoin{IndexReader(Index(t.g_3)[[NULL,+inf]])->IndexReader(Index(t.g_2)[[NULL,NULL]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)" + "Plan": "IndexMergeJoin{IndexReader(Index(t.g_2)[[NULL,+inf]])->IndexReader(Index(t.g_2)[[NULL,NULL]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)" }, { "SQL": "select /*+inl_merge_join(t2)*/ t1.a, t2.a from t t1 left join t t2 use index(g_2) on t1.g=t2.g order by t1.a", - "Plan": "IndexMergeJoin{IndexReader(Index(t.g_3)[[NULL,+inf]])->IndexReader(Index(t.g_2)[[NULL,NULL]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)->Sort" + "Plan": "IndexMergeJoin{IndexReader(Index(t.g_2)[[NULL,+inf]])->IndexReader(Index(t.g_2)[[NULL,NULL]]->Sel([not(isnull(test.t.g))]))}(test.t.g,test.t.g)->Sort" } ] }, @@ -1563,9 +2452,10 @@ "SQL": "select * from tn where a = 1 and b > 10 and b < 20 and c > 50 order by d limit 1", "Plan": [ "TopN 0.83 root test.tn.d, offset:0, count:1", - "└─IndexReader 0.83 root index:Selection", - " └─Selection 0.83 cop[tikv] gt(test.tn.c, 50)", - " └─IndexRangeScan 2.50 cop[tikv] table:tn, index:a(a, b, c, d) range:(1 10,1 20), keep order:false, stats:pseudo" + "└─IndexReader 0.83 root index:TopN", + " └─TopN 0.83 cop[tikv] test.tn.d, offset:0, count:1", + " └─Selection 0.83 cop[tikv] gt(test.tn.c, 50)", + " └─IndexRangeScan 2.50 cop[tikv] table:tn, index:a(a, b, c, d) range:(1 10,1 20), keep order:false, stats:pseudo" ], "Warning": null }, @@ -1897,8 +2787,9 @@ "Plan": [ "HashJoin 80000000.00 root CARTESIAN inner join", "├─HashAgg(Build) 8000.00 root group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a", - "│ └─TableReader 10000.00 root data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "│ └─TableReader 8000.00 root data:HashAgg", + "│ └─HashAgg 8000.00 cop[tikv] group by:test.t.a, ", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", "└─TableReader(Probe) 10000.00 root data:TableFullScan", " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ], @@ -2323,13 +3214,13 @@ "HashAgg 16000.00 root group by:Column#5, funcs:firstrow(Column#6)->Column#3", "└─PartitionUnion 16000.00 root ", " ├─HashAgg 8000.00 root group by:Column#7, funcs:firstrow(Column#7)->Column#6, funcs:firstrow(Column#7)->Column#5", - " │ └─TableReader 8000.00 root data:HashAgg", + " │ └─IndexReader 8000.00 root index:HashAgg", " │ └─HashAgg 8000.00 cop[tikv] group by:date_format(test.tc.timestamp, \"%Y-%m-%d %H\"), ", - " │ └─TableFullScan 10000.00 cop[tikv] table:tc, partition:p2020072312 keep order:false, stats:pseudo", + " │ └─IndexFullScan 10000.00 cop[tikv] table:tc, partition:p2020072312, index:idx_timestamp(timestamp) keep order:false, stats:pseudo", " └─HashAgg 8000.00 root group by:Column#10, funcs:firstrow(Column#10)->Column#6, funcs:firstrow(Column#10)->Column#5", - " └─TableReader 8000.00 root data:HashAgg", + " └─IndexReader 8000.00 root index:HashAgg", " └─HashAgg 8000.00 cop[tikv] group by:date_format(test.tc.timestamp, \"%Y-%m-%d %H\"), ", - " └─TableFullScan 10000.00 cop[tikv] table:tc, partition:p2020072313 keep order:false, stats:pseudo" + " └─IndexFullScan 10000.00 cop[tikv] table:tc, partition:p2020072313, index:idx_timestamp(timestamp) keep order:false, stats:pseudo" ], "Result": null } @@ -2506,13 +3397,13 @@ "HashAgg 16000.00 root group by:Column#5, funcs:firstrow(Column#6)->Column#3", "└─PartitionUnion 16000.00 root ", " ├─HashAgg 8000.00 root group by:Column#7, funcs:firstrow(Column#7)->Column#6, funcs:firstrow(Column#7)->Column#5", - " │ └─TableReader 8000.00 root data:HashAgg", + " │ └─IndexReader 8000.00 root index:HashAgg", " │ └─HashAgg 8000.00 cop[tikv] group by:date_format(test.tc.timestamp, \"%Y-%m-%d %H\"), ", - " │ └─TableFullScan 10000.00 cop[tikv] table:tc, partition:p2020072312 keep order:false, stats:pseudo", + " │ └─IndexFullScan 10000.00 cop[tikv] table:tc, partition:p2020072312, index:idx_timestamp(timestamp) keep order:false, stats:pseudo", " └─HashAgg 8000.00 root group by:Column#10, funcs:firstrow(Column#10)->Column#6, funcs:firstrow(Column#10)->Column#5", - " └─TableReader 8000.00 root data:HashAgg", + " └─IndexReader 8000.00 root index:HashAgg", " └─HashAgg 8000.00 cop[tikv] group by:date_format(test.tc.timestamp, \"%Y-%m-%d %H\"), ", - " └─TableFullScan 10000.00 cop[tikv] table:tc, partition:p2020072313 keep order:false, stats:pseudo" + " └─IndexFullScan 10000.00 cop[tikv] table:tc, partition:p2020072313, index:idx_timestamp(timestamp) keep order:false, stats:pseudo" ], "Result": null } @@ -2889,8 +3780,8 @@ "IndexMergeJoin 12500.00 root left outer join, inner:TableReader, outer key:test.t1.a, inner key:test.t2.a, other cond:eq(test.t1.b, test.t2.b)", "├─TableReader(Build) 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:true, stats:pseudo" + "└─TableReader(Probe) 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:true, stats:pseudo" ], "Result": [ "1 1", @@ -2903,8 +3794,8 @@ "IndexHashJoin 12500.00 root left outer join, inner:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b)", "├─TableReader(Build) 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo" + "└─TableReader(Probe) 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo" ], "Result": [ "1 1", @@ -2917,8 +3808,8 @@ "IndexJoin 12500.00 root left outer join, inner:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), eq(test.t1.b, test.t2.b)", "├─TableReader(Build) 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo" + "└─TableReader(Probe) 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [test.t1.a], keep order:false, stats:pseudo" ], "Result": [ "1 1", @@ -2965,12 +3856,12 @@ " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─Selection(Probe) 0.80 root not(isnull(test.t1.a))", - " └─MaxOneRow 1.00 root ", - " └─IndexLookUp 0.00 root ", - " ├─IndexRangeScan(Build) 1.00 cop[tikv] table:t1, index:idx_a(a) range:[NULL,NULL], keep order:false, stats:pseudo", - " └─Selection(Probe) 0.00 cop[tikv] eq(test.t1.b, test.t2.b)", - " └─TableRowIDScan 1.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " └─Selection(Probe) 7992.00 root not(isnull(test.t1.a))", + " └─MaxOneRow 9990.00 root ", + " └─IndexLookUp 9.99 root ", + " ├─IndexRangeScan(Build) 9990.00 cop[tikv] table:t1, index:idx_a(a) range:[NULL,NULL], keep order:false, stats:pseudo", + " └─Selection(Probe) 9.99 cop[tikv] eq(test.t1.b, test.t2.b)", + " └─TableRowIDScan 9990.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Result": null }, @@ -2982,10 +3873,10 @@ " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─Selection(Probe) 0.80 root not(isnull(test.t3.a))", - " └─MaxOneRow 1.00 root ", - " └─IndexReader 2.00 root index:IndexRangeScan", - " └─IndexRangeScan 2.00 cop[tikv] table:t3, index:idx_abc(a, b, c) range: decided by [eq(test.t3.a, test.t2.a)], keep order:false, stats:pseudo" + " └─Selection(Probe) 7992.00 root not(isnull(test.t3.a))", + " └─MaxOneRow 9990.00 root ", + " └─IndexReader 19980.00 root index:IndexRangeScan", + " └─IndexRangeScan 19980.00 cop[tikv] table:t3, index:idx_abc(a, b, c) range: decided by [eq(test.t3.a, test.t2.a)], keep order:false, stats:pseudo" ], "Result": null } @@ -3264,11 +4155,11 @@ "SQL": "select date_format(d,'%Y') as df, sum(a), count(b), count(distinct c) from t group by date_format(d,'%Y')", "Plan": [ "Projection 8000.00 root date_format(test.t.d, %Y)->Column#9, Column#6, cast(Column#13, bigint(21) BINARY)->Column#7, Column#8", - "└─HashAgg 8000.00 root group by:Column#29, funcs:sum(Column#25)->Column#6, funcs:sum(Column#26)->Column#13, funcs:count(Column#27)->Column#8, funcs:firstrow(Column#28)->test.t.d", - " └─Projection 8000.00 root Column#11, cast(Column#12, decimal(20,0) BINARY)->Column#26, test.t.c, test.t.d, date_format(test.t.d, %Y)->Column#29", - " └─HashAgg 8000.00 root group by:Column#23, Column#24, funcs:sum(Column#19)->Column#11, funcs:count(Column#20)->Column#12, funcs:firstrow(Column#21)->test.t.c, funcs:firstrow(Column#22)->test.t.d", - " └─Projection 10000.00 root cast(test.t.a, decimal(10,0) BINARY)->Column#19, test.t.b, test.t.c, test.t.d, date_format(test.t.d, %Y)->Column#23, test.t.c", - " └─TableReader 10000.00 root data:TableFullScan", + "└─HashAgg 8000.00 root group by:Column#23, funcs:sum(Column#19)->Column#6, funcs:sum(Column#20)->Column#13, funcs:count(Column#21)->Column#8, funcs:firstrow(Column#22)->test.t.d", + " └─Projection 8000.00 root Column#11, cast(Column#12, decimal(20,0) BINARY)->Column#20, test.t.c, test.t.d, date_format(test.t.d, %Y)->Column#23", + " └─HashAgg 8000.00 root group by:Column#14, test.t.c, funcs:sum(Column#15)->Column#11, funcs:count(Column#16)->Column#12, funcs:firstrow(test.t.c)->test.t.c, funcs:firstrow(Column#18)->test.t.d", + " └─TableReader 8000.00 root data:HashAgg", + " └─HashAgg 8000.00 cop[tikv] group by:date_format(test.t.d, \"%Y\"), test.t.c, funcs:sum(test.t.a)->Column#15, funcs:count(test.t.b)->Column#16, funcs:firstrow(test.t.d)->Column#18", " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ] }, @@ -3278,9 +4169,10 @@ "Projection 8000.00 root test.t.d, test.t.a, cast(Column#10, bigint(21) BINARY)->Column#6, cast(Column#12, bigint(21) BINARY)->Column#7, Column#8", "└─HashAgg 8000.00 root group by:Column#23, Column#24, funcs:sum(Column#18)->Column#10, funcs:sum(Column#19)->Column#12, funcs:count(Column#20)->Column#8, funcs:firstrow(Column#21)->test.t.a, funcs:firstrow(Column#22)->test.t.d", " └─Projection 8000.00 root cast(Column#9, decimal(20,0) BINARY)->Column#18, cast(Column#11, decimal(20,0) BINARY)->Column#19, test.t.c, test.t.a, test.t.d, test.t.d, test.t.a", - " └─HashAgg 8000.00 root group by:test.t.a, test.t.c, test.t.d, funcs:count(1)->Column#9, funcs:count(test.t.b)->Column#11, funcs:firstrow(test.t.c)->test.t.c, funcs:firstrow(test.t.a)->test.t.a, funcs:firstrow(test.t.d)->test.t.d", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + " └─HashAgg 8000.00 root group by:test.t.a, test.t.c, test.t.d, funcs:count(Column#13)->Column#9, funcs:count(Column#14)->Column#11, funcs:firstrow(test.t.c)->test.t.c, funcs:firstrow(test.t.a)->test.t.a, funcs:firstrow(test.t.d)->test.t.d", + " └─TableReader 8000.00 root data:HashAgg", + " └─HashAgg 8000.00 cop[tikv] group by:test.t.a, test.t.c, test.t.d, funcs:count(1)->Column#13, funcs:count(test.t.b)->Column#14", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" ] }, { @@ -3776,9 +4668,10 @@ "Plan": [ "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, test.t.a)]", "├─HashAgg(Build) 7992.00 root group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a", - "│ └─TableReader 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader 7992.00 root data:HashAgg", + "│ └─HashAgg 7992.00 cop[tikv] group by:test.t.a, ", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" @@ -3790,9 +4683,10 @@ "Plan": [ "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, test.t.a)]", "├─HashAgg(Build) 7992.00 root group by:test.t.a, funcs:firstrow(test.t.a)->test.t.a", - "│ └─TableReader 9990.00 root data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "│ └─TableReader 7992.00 root data:HashAgg", + "│ └─HashAgg 7992.00 cop[tikv] group by:test.t.a, ", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", "└─TableReader(Probe) 9990.00 root data:Selection", " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" @@ -5069,9 +5963,10 @@ "SQL": "SELECT /*+ hash_join_probe(t1) */ * FROM t1 WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE() */ 1 FROM t2 WHERE t2.a = t1.a);", "Plan": [ "HashJoin 10000.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", - "├─HashAgg(Build) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - "│ └─TableReader 10000.00 root data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "├─StreamAgg(Build) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 8000.00 root data:StreamAgg", + "│ └─StreamAgg 8000.00 cop[tikv] group by:test.t2.a, ", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:true, stats:pseudo", "└─TableReader(Probe) 10000.00 root data:TableFullScan", " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], @@ -5087,9 +5982,10 @@ "HashJoin 10000.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", "├─TableReader(Build) 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─HashAgg(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + "└─StreamAgg(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─TableReader 8000.00 root data:StreamAgg", + " └─StreamAgg 8000.00 cop[tikv] group by:test.t2.a, ", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:true, stats:pseudo" ], "Result": [ "1 1", @@ -5137,9 +6033,10 @@ "HashJoin 10000.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", "├─TableReader(Build) 10000.00 root data:TableFullScan", "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - "└─HashAgg(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - " └─TableReader 10000.00 root data:TableFullScan", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + "└─StreamAgg(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─TableReader 8000.00 root data:StreamAgg", + " └─StreamAgg 8000.00 cop[tikv] group by:test.t2.a, ", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:true, stats:pseudo" ], "Result": [ "1 1", @@ -5151,9 +6048,10 @@ "SQL": "SELECT /*+ hash_join_build(t2@sel_2) */ * FROM t1 WHERE EXISTS (SELECT /*+ SEMI_JOIN_REWRITE() */ 1 FROM t2 WHERE t2.a = t1.a);", "Plan": [ "HashJoin 10000.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", - "├─HashAgg(Build) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", - "│ └─TableReader 10000.00 root data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "├─StreamAgg(Build) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 8000.00 root data:StreamAgg", + "│ └─StreamAgg 8000.00 cop[tikv] group by:test.t2.a, ", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:true, stats:pseudo", "└─TableReader(Probe) 10000.00 root data:TableFullScan", " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], @@ -5781,9 +6679,9 @@ " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9.99 root data:Selection", - " └─Selection 9.99 cop[tikv] not(isnull(test.t2.b))", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" + " └─TableReader(Probe) 99800.10 root data:Selection", + " └─Selection 99800.10 cop[tikv] not(isnull(test.t2.b))", + " └─TableRangeScan 9990.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" ], "Result": [ "1" @@ -5814,8 +6712,8 @@ " └─Apply 10000.00 root CARTESIAN left outer semi join, other cond:eq(test.t1.a, test.t2.b)", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─TableReader(Probe) 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" + " └─TableReader(Probe) 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" ], "Result": [ "1" @@ -5829,10 +6727,10 @@ "└─Apply 10000.00 root CARTESIAN inner join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:max(Column#14)->Column#8, funcs:count(distinct Column#15)->Column#9, funcs:sum(Column#16)->Column#10, funcs:count(1)->Column#11", - " └─Projection 1.00 root test.t2.b, test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#16", - " └─TableReader 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:max(Column#14)->Column#8, funcs:count(distinct Column#15)->Column#9, funcs:sum(Column#16)->Column#10, funcs:count(1)->Column#11", + " └─Projection 10000.00 root test.t2.b, test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#16", + " └─TableReader 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" ], "Result": [ "1 0", @@ -5847,10 +6745,10 @@ "└─Apply 10000.00 root CARTESIAN inner join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:max(Column#14)->Column#8, funcs:count(distinct Column#15)->Column#9, funcs:sum(Column#16)->Column#10, funcs:count(1)->Column#11", - " └─Projection 1.00 root test.t2.b, test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#16", - " └─TableReader 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:max(Column#14)->Column#8, funcs:count(distinct Column#15)->Column#9, funcs:sum(Column#16)->Column#10, funcs:count(1)->Column#11", + " └─Projection 10000.00 root test.t2.b, test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#16", + " └─TableReader 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" ], "Result": [ "1 0", @@ -5865,10 +6763,10 @@ "└─Apply 10000.00 root CARTESIAN inner join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:max(Column#19)->Column#8, funcs:sum(Column#20)->Column#9, funcs:count(1)->Column#10", - " └─Projection 1.00 root test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#20", - " └─TableReader 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:max(Column#19)->Column#8, funcs:sum(Column#20)->Column#9, funcs:count(1)->Column#10", + " └─Projection 10000.00 root test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#20", + " └─TableReader 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" ], "Result": [ "1 0", @@ -5883,10 +6781,10 @@ "└─Apply 10000.00 root CARTESIAN inner join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─StreamAgg(Probe) 1.00 root funcs:max(Column#19)->Column#8, funcs:sum(Column#20)->Column#9, funcs:count(1)->Column#10", - " └─Projection 1.00 root test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#20", - " └─TableReader 1.00 root data:TableRangeScan", - " └─TableRangeScan 1.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" + " └─StreamAgg(Probe) 10000.00 root funcs:max(Column#19)->Column#8, funcs:sum(Column#20)->Column#9, funcs:count(1)->Column#10", + " └─Projection 10000.00 root test.t2.b, cast(isnull(test.t2.b), decimal(20,0) BINARY)->Column#20", + " └─TableReader 10000.00 root data:TableRangeScan", + " └─TableRangeScan 10000.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" ], "Result": [ "1 0", @@ -5916,9 +6814,9 @@ "└─Apply 10000.00 root CARTESIAN left outer join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─MaxOneRow(Probe) 1.00 root ", - " └─TableReader 0.20 root data:TableRangeScan", - " └─TableRangeScan 0.20 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" + " └─MaxOneRow(Probe) 10000.00 root ", + " └─TableReader 2000.00 root data:TableRangeScan", + " └─TableRangeScan 2000.00 cop[tikv] table:t2 range: decided by [eq(test.t2.a, test.t1.b)], keep order:false, stats:pseudo" ], "Result": [ "1 1", @@ -5980,11 +6878,11 @@ "└─Apply 10000.00 root CARTESIAN left outer semi join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─Limit(Probe) 2.00 root offset:0, count:2", - " └─TableReader 2.00 root data:Limit", - " └─Limit 2.00 cop[tikv] offset:0, count:2", - " └─Selection 2.00 cop[tikv] eq(test.t3.a, test.t1.b)", - " └─TableFullScan 2000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" + " └─Limit(Probe) 20000.00 root offset:0, count:2", + " └─TableReader 20000.00 root data:Limit", + " └─Limit 20000.00 cop[tikv] offset:0, count:2", + " └─Selection 20000.00 cop[tikv] eq(test.t3.a, test.t1.b)", + " └─TableFullScan 20000000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" ], "Result": [ "1", @@ -5998,9 +6896,9 @@ "Projection 1.00 root test.t1.a, Column#6", "└─HashJoin 1.00 root CARTESIAN left outer join", " ├─Point_Get(Build) 1.00 root table:t2 handle:10", - " └─StreamAgg(Probe) 1.00 root funcs:sum(Column#15)->Column#6, funcs:firstrow(Column#16)->test.t1.a", - " └─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:sum(test.t1.a)->Column#15, funcs:firstrow(test.t1.a)->Column#16", + " └─HashAgg(Probe) 1.00 root funcs:sum(Column#13)->Column#6, funcs:firstrow(Column#14)->test.t1.a", + " └─TableReader 1.00 root data:HashAgg", + " └─HashAgg 1.00 cop[tikv] funcs:sum(test.t1.a)->Column#13, funcs:firstrow(test.t1.a)->Column#14", " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Result": [ @@ -6052,12 +6950,12 @@ "└─Apply 10000.00 root CARTESIAN left outer join", " ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─MaxOneRow(Probe) 1.00 root ", - " └─StreamAgg 1.00 root funcs:count(Column#12)->Column#10", - " └─TableReader 1.00 root data:StreamAgg", - " └─StreamAgg 1.00 cop[tikv] funcs:count(test.t3.a)->Column#12", - " └─Selection 10.00 cop[tikv] eq(test.t3.b, test.t1.b)", - " └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" + " └─MaxOneRow(Probe) 10000.00 root ", + " └─StreamAgg 10000.00 root funcs:count(Column#12)->Column#10", + " └─TableReader 10000.00 root data:StreamAgg", + " └─StreamAgg 10000.00 cop[tikv] funcs:count(test.t3.a)->Column#12", + " └─Selection 100000.00 cop[tikv] eq(test.t3.b, test.t1.b)", + " └─TableFullScan 100000000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" ], "Result": [ "0", @@ -6069,9 +6967,9 @@ "SQL": "SELECT ta.NAME,(SELECT sum(tb.CODE) FROM tb WHERE ta.id = tb.id) tb_sum_code FROM ta WHERE ta.NAME LIKE 'chad999%'", "Plan": [ "HashJoin 250.00 root left outer join, equal:[eq(test.ta.id, test.tb.id)]", - "├─IndexLookUp(Build) 250.00 root ", - "│ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:ta, index:idx_ta_name(name) range:[\"chad999\",\"chad99:\"), keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 250.00 cop[tikv] table:ta keep order:false, stats:pseudo", + "├─TableReader(Build) 250.00 root data:Selection", + "│ └─Selection 250.00 cop[tikv] like(test.ta.name, \"chad999%\", 92)", + "│ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", "└─HashAgg(Probe) 7992.00 root group by:test.tb.id, funcs:sum(Column#19)->Column#13, funcs:firstrow(test.tb.id)->test.tb.id", " └─TableReader 7992.00 root data:HashAgg", " └─HashAgg 7992.00 cop[tikv] group by:test.tb.id, funcs:sum(test.tb.code)->Column#19", @@ -6086,15 +6984,15 @@ "Plan": [ "Projection 250.00 root test.ta.name, Column#13", "└─Apply 250.00 root CARTESIAN left outer join", - " ├─IndexLookUp(Build) 250.00 root ", - " │ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:ta, index:idx_ta_name(name) range:[\"chad999\",\"chad99:\"), keep order:false, stats:pseudo", - " │ └─TableRowIDScan(Probe) 250.00 cop[tikv] table:ta keep order:false, stats:pseudo", - " └─MaxOneRow(Probe) 1.00 root ", - " └─StreamAgg 1.00 root funcs:sum(Column#21)->Column#13", - " └─Projection 10.00 root cast(test.tb.code, decimal(10,0) BINARY)->Column#21", - " └─IndexLookUp 10.00 root ", - " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", - " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:tb keep order:false, stats:pseudo" + " ├─TableReader(Build) 250.00 root data:Selection", + " │ └─Selection 250.00 cop[tikv] like(test.ta.name, \"chad999%\", 92)", + " │ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", + " └─MaxOneRow(Probe) 250.00 root ", + " └─StreamAgg 250.00 root funcs:sum(Column#21)->Column#13", + " └─Projection 2500.00 root cast(test.tb.code, decimal(10,0) BINARY)->Column#21", + " └─IndexLookUp 2500.00 root ", + " ├─IndexRangeScan(Build) 2500.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 2500.00 cop[tikv] table:tb keep order:false, stats:pseudo" ], "Result": null, "Warning": null @@ -6103,9 +7001,9 @@ "SQL": "SELECT ta.NAME,(SELECT sum(tb.CODE) FROM tb WHERE ta.id = tb.id and exists (select 1 from tc where tb.name=tc.name and tc.`code` like '999%')) tb_sum_code FROM ta WHERE ta.NAME LIKE 'chad999%'", "Plan": [ "HashJoin 250.00 root left outer join, equal:[eq(test.ta.id, test.tb.id)]", - "├─IndexLookUp(Build) 250.00 root ", - "│ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:ta, index:idx_ta_name(name) range:[\"chad999\",\"chad99:\"), keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 250.00 cop[tikv] table:ta keep order:false, stats:pseudo", + "├─TableReader(Build) 250.00 root data:Selection", + "│ └─Selection 250.00 cop[tikv] like(test.ta.name, \"chad999%\", 92)", + "│ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", "└─HashAgg(Probe) 6387.21 root group by:Column#39, funcs:sum(Column#37)->Column#18, funcs:firstrow(Column#38)->test.tb.id", " └─Projection 7984.01 root cast(test.tb.code, decimal(10,0) BINARY)->Column#37, test.tb.id, test.tb.id", " └─HashJoin 7984.01 root semi join, equal:[eq(test.tb.name, test.tc.name)]", @@ -6124,22 +7022,22 @@ "Plan": [ "Projection 250.00 root test.ta.name, Column#18", "└─Apply 250.00 root CARTESIAN left outer join", - " ├─IndexLookUp(Build) 250.00 root ", - " │ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:ta, index:idx_ta_name(name) range:[\"chad999\",\"chad99:\"), keep order:false, stats:pseudo", - " │ └─TableRowIDScan(Probe) 250.00 cop[tikv] table:ta keep order:false, stats:pseudo", - " └─MaxOneRow(Probe) 1.00 root ", - " └─StreamAgg 1.00 root funcs:sum(Column#33)->Column#18", - " └─Projection 7.99 root cast(test.tb.code, decimal(10,0) BINARY)->Column#33", - " └─IndexJoin 7.99 root semi join, inner:IndexLookUp, outer key:test.tb.name, inner key:test.tc.name, equal cond:eq(test.tb.name, test.tc.name)", - " ├─IndexLookUp(Build) 9.99 root ", - " │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9.99 cop[tikv] not(isnull(test.tb.name))", - " │ └─TableRowIDScan 10.00 cop[tikv] table:tb keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 1.25 root ", - " ├─Selection(Build) 1.56 cop[tikv] not(isnull(test.tc.name))", - " │ └─IndexRangeScan 1.56 cop[tikv] table:tc, index:idx_tc_name(name) range: decided by [eq(test.tc.name, test.tb.name)], keep order:false, stats:pseudo", - " └─Selection(Probe) 1.25 cop[tikv] like(cast(test.tc.code, var_string(20)), \"999%\", 92)", - " └─TableRowIDScan 1.56 cop[tikv] table:tc keep order:false, stats:pseudo" + " ├─TableReader(Build) 250.00 root data:Selection", + " │ └─Selection 250.00 cop[tikv] like(test.ta.name, \"chad999%\", 92)", + " │ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", + " └─MaxOneRow(Probe) 250.00 root ", + " └─StreamAgg 250.00 root funcs:sum(Column#33)->Column#18", + " └─Projection 1998.00 root cast(test.tb.code, decimal(10,0) BINARY)->Column#33", + " └─IndexHashJoin 1998.00 root semi join, inner:IndexLookUp, outer key:test.tb.name, inner key:test.tc.name, equal cond:eq(test.tb.name, test.tc.name)", + " ├─IndexLookUp(Build) 2497.50 root ", + " │ ├─IndexRangeScan(Build) 2500.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", + " │ └─Selection(Probe) 2497.50 cop[tikv] not(isnull(test.tb.name))", + " │ └─TableRowIDScan 2500.00 cop[tikv] table:tb keep order:false, stats:pseudo", + " └─IndexLookUp(Probe) 3121.87 root ", + " ├─Selection(Build) 3902.34 cop[tikv] not(isnull(test.tc.name))", + " │ └─IndexRangeScan 3906.25 cop[tikv] table:tc, index:idx_tc_name(name) range: decided by [eq(test.tc.name, test.tb.name)], keep order:false, stats:pseudo", + " └─Selection(Probe) 3121.87 cop[tikv] like(cast(test.tc.code, var_string(20)), \"999%\", 92)", + " └─TableRowIDScan 3902.34 cop[tikv] table:tc keep order:false, stats:pseudo" ], "Result": null, "Warning": null @@ -6148,19 +7046,19 @@ "SQL": "SELECT ta.NAME,(SELECT sum(tb.CODE) FROM tb WHERE ta.id = tb.id and exists (select /*+ no_decorrelate() */ 1 from tc where tb.name=tc.name and tc.`code` like '999%')) tb_sum_code FROM ta WHERE ta.NAME LIKE 'chad999%'", "Plan": [ "HashJoin 250.00 root left outer join, equal:[eq(test.ta.id, test.tb.id)]", - "├─IndexLookUp(Build) 250.00 root ", - "│ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:ta, index:idx_ta_name(name) range:[\"chad999\",\"chad99:\"), keep order:false, stats:pseudo", - "│ └─TableRowIDScan(Probe) 250.00 cop[tikv] table:ta keep order:false, stats:pseudo", + "├─TableReader(Build) 250.00 root data:Selection", + "│ └─Selection 250.00 cop[tikv] like(test.ta.name, \"chad999%\", 92)", + "│ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", "└─HashAgg(Probe) 7992.00 root group by:Column#28, funcs:sum(Column#26)->Column#18, funcs:firstrow(Column#27)->test.tb.id", " └─Projection 9990.00 root cast(test.tb.code, decimal(10,0) BINARY)->Column#26, test.tb.id, test.tb.id", " └─Apply 9990.00 root CARTESIAN semi join", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.tb.id))", " │ └─TableFullScan 10000.00 cop[tikv] table:tb keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 8.00 root ", - " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tc, index:idx_tc_name(name) range: decided by [eq(test.tb.name, test.tc.name)], keep order:false, stats:pseudo", - " └─Selection(Probe) 8.00 cop[tikv] like(cast(test.tc.code, var_string(20)), \"999%\", 92)", - " └─TableRowIDScan 10.00 cop[tikv] table:tc keep order:false, stats:pseudo" + " └─IndexLookUp(Probe) 79920.00 root ", + " ├─IndexRangeScan(Build) 99900.00 cop[tikv] table:tc, index:idx_tc_name(name) range: decided by [eq(test.tb.name, test.tc.name)], keep order:false, stats:pseudo", + " └─Selection(Probe) 79920.00 cop[tikv] like(cast(test.tc.code, var_string(20)), \"999%\", 92)", + " └─TableRowIDScan 99900.00 cop[tikv] table:tc keep order:false, stats:pseudo" ], "Result": null, "Warning": null @@ -6170,20 +7068,20 @@ "Plan": [ "Projection 250.00 root test.ta.name, Column#18", "└─Apply 250.00 root CARTESIAN left outer join", - " ├─IndexLookUp(Build) 250.00 root ", - " │ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:ta, index:idx_ta_name(name) range:[\"chad999\",\"chad99:\"), keep order:false, stats:pseudo", - " │ └─TableRowIDScan(Probe) 250.00 cop[tikv] table:ta keep order:false, stats:pseudo", - " └─MaxOneRow(Probe) 1.00 root ", - " └─StreamAgg 1.00 root funcs:sum(Column#22)->Column#18", - " └─Projection 10.00 root cast(test.tb.code, decimal(10,0) BINARY)->Column#22", - " └─Apply 10.00 root CARTESIAN semi join", - " ├─IndexLookUp(Build) 10.00 root ", - " │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", - " │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:tb keep order:false, stats:pseudo", - " └─IndexLookUp(Probe) 8.00 root ", - " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tc, index:idx_tc_name(name) range: decided by [eq(test.tb.name, test.tc.name)], keep order:false, stats:pseudo", - " └─Selection(Probe) 8.00 cop[tikv] like(cast(test.tc.code, var_string(20)), \"999%\", 92)", - " └─TableRowIDScan 10.00 cop[tikv] table:tc keep order:false, stats:pseudo" + " ├─TableReader(Build) 250.00 root data:Selection", + " │ └─Selection 250.00 cop[tikv] like(test.ta.name, \"chad999%\", 92)", + " │ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", + " └─MaxOneRow(Probe) 250.00 root ", + " └─StreamAgg 250.00 root funcs:sum(Column#22)->Column#18", + " └─Projection 2500.00 root cast(test.tb.code, decimal(10,0) BINARY)->Column#22", + " └─Apply 2500.00 root CARTESIAN semi join", + " ├─IndexLookUp(Build) 2500.00 root ", + " │ ├─IndexRangeScan(Build) 2500.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", + " │ └─TableRowIDScan(Probe) 2500.00 cop[tikv] table:tb keep order:false, stats:pseudo", + " └─IndexLookUp(Probe) 20000.00 root ", + " ├─IndexRangeScan(Build) 25000.00 cop[tikv] table:tc, index:idx_tc_name(name) range: decided by [eq(test.tb.name, test.tc.name)], keep order:false, stats:pseudo", + " └─Selection(Probe) 20000.00 cop[tikv] like(cast(test.tc.code, var_string(20)), \"999%\", 92)", + " └─TableRowIDScan 25000.00 cop[tikv] table:tc keep order:false, stats:pseudo" ], "Result": null, "Warning": null @@ -6215,15 +7113,15 @@ " ├─IndexLookUp(Build) 10.00 root ", " │ ├─IndexRangeScan(Build) 10.00 cop[tikv] table:ta, index:idx_ta_name(name) range:[\"chad999\",\"chad999\"], keep order:false, stats:pseudo", " │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:ta keep order:false, stats:pseudo", - " └─Selection(Probe) 0.80 root gt(Column#9, 900)", - " └─MaxOneRow 1.00 root ", - " └─StreamAgg 1.00 root funcs:max(test.tb.code)->Column#9", - " └─TopN 1.00 root test.tb.code:desc, offset:0, count:1", - " └─IndexLookUp 1.00 root ", - " ├─IndexRangeScan(Build) 10.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", - " └─TopN(Probe) 1.00 cop[tikv] test.tb.code:desc, offset:0, count:1", - " └─Selection 9.99 cop[tikv] not(isnull(test.tb.code))", - " └─TableRowIDScan 10.00 cop[tikv] table:tb keep order:false, stats:pseudo" + " └─Selection(Probe) 8.00 root gt(Column#9, 900)", + " └─MaxOneRow 10.00 root ", + " └─StreamAgg 10.00 root funcs:max(test.tb.code)->Column#9", + " └─TopN 10.00 root test.tb.code:desc, offset:0, count:1", + " └─IndexLookUp 10.00 root ", + " ├─IndexRangeScan(Build) 100.00 cop[tikv] table:tb, index:idx_tb_id(id) range: decided by [eq(test.ta.id, test.tb.id)], keep order:false, stats:pseudo", + " └─TopN(Probe) 10.00 cop[tikv] test.tb.code:desc, offset:0, count:1", + " └─Selection 99.90 cop[tikv] not(isnull(test.tb.code))", + " └─TableRowIDScan 100.00 cop[tikv] table:tb keep order:false, stats:pseudo" ], "Result": null, "Warning": null @@ -6233,24 +7131,22 @@ "Plan": [ "HashJoin 159.84 root inner join, equal:[eq(test.ta.id, test.td.id)]", "├─Selection(Build) 159.84 root gt(Column#19, 100)", - "│ └─HashAgg 199.80 root group by:test.td.id, funcs:max(Column#36)->Column#19, funcs:firstrow(test.td.id)->test.td.id", - "│ └─IndexLookUp 199.80 root ", - "│ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:td, index:idx_tc_name(name) range:[\"chad999\",\"chad99:\"), keep order:false, stats:pseudo", - "│ └─HashAgg(Probe) 199.80 cop[tikv] group by:test.td.id, funcs:max(test.td.id)->Column#36", - "│ └─Selection 249.75 cop[tikv] not(isnull(test.td.id))", - "│ └─TableRowIDScan 250.00 cop[tikv] table:td keep order:false, stats:pseudo", + "│ └─HashAgg 199.80 root group by:test.td.id, funcs:max(Column#32)->Column#19, funcs:firstrow(test.td.id)->test.td.id", + "│ └─TableReader 199.80 root data:HashAgg", + "│ └─HashAgg 199.80 cop[tikv] group by:test.td.id, funcs:max(test.td.id)->Column#32", + "│ └─Selection 249.75 cop[tikv] like(test.td.name, \"chad999%\", 92), not(isnull(test.td.id))", + "│ └─TableFullScan 10000.00 cop[tikv] table:td keep order:false, stats:pseudo", "└─HashJoin(Probe) 200.00 root inner join, equal:[eq(test.ta.name, test.tc.name)]", " ├─Selection(Build) 160.00 root gt(Column#14, 100)", - " │ └─HashAgg 200.00 root group by:test.tc.name, funcs:max(Column#27)->Column#14, funcs:firstrow(test.tc.name)->test.tc.name", - " │ └─IndexLookUp 200.00 root ", - " │ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:tc, index:idx_tc_name(name) range:[\"chad99\",\"chad9:\"), keep order:false, stats:pseudo", - " │ └─HashAgg(Probe) 200.00 cop[tikv] group by:test.tc.name, funcs:max(test.tc.id)->Column#27", - " │ └─TableRowIDScan 250.00 cop[tikv] table:tc keep order:false, stats:pseudo", + " │ └─HashAgg 200.00 root group by:test.tc.name, funcs:max(Column#24)->Column#14, funcs:firstrow(test.tc.name)->test.tc.name", + " │ └─TableReader 200.00 root data:HashAgg", + " │ └─HashAgg 200.00 cop[tikv] group by:test.tc.name, funcs:max(test.tc.id)->Column#24", + " │ └─Selection 250.00 cop[tikv] like(test.tc.name, \"chad99%\", 92), not(isnull(test.tc.name))", + " │ └─TableFullScan 10000.00 cop[tikv] table:tc keep order:false, stats:pseudo", " └─HashJoin(Probe) 7976.02 root semi join, equal:[eq(test.ta.code, test.tb.code)]", - " ├─IndexLookUp(Build) 249.75 root ", - " │ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:tb, index:idx_tb_name(name) range:[\"chad9\",\"chad:\"), keep order:false, stats:pseudo", - " │ └─Selection(Probe) 249.75 cop[tikv] not(isnull(test.tb.code))", - " │ └─TableRowIDScan 250.00 cop[tikv] table:tb keep order:false, stats:pseudo", + " ├─TableReader(Build) 249.75 root data:Selection", + " │ └─Selection 249.75 cop[tikv] like(test.tb.name, \"chad9%\", 92), not(isnull(test.tb.code))", + " │ └─TableFullScan 10000.00 cop[tikv] table:tb keep order:false, stats:pseudo", " └─TableReader(Probe) 9970.03 root data:Selection", " └─Selection 9970.03 cop[tikv] not(isnull(test.ta.code)), not(isnull(test.ta.id)), not(isnull(test.ta.name))", " └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo" @@ -6264,36 +7160,35 @@ "Projection 249.75 root test.ta.name", "└─Apply 249.75 root CARTESIAN inner join", " ├─Apply(Build) 249.75 root CARTESIAN inner join", - " │ ├─IndexJoin(Build) 249.75 root inner join, inner:IndexLookUp, outer key:test.tb.code, inner key:test.ta.code, equal cond:eq(test.tb.code, test.ta.code)", + " │ ├─IndexHashJoin(Build) 249.75 root inner join, inner:IndexLookUp, outer key:test.tb.code, inner key:test.ta.code, equal cond:eq(test.tb.code, test.ta.code)", " │ │ ├─HashAgg(Build) 199.80 root group by:test.tb.code, funcs:firstrow(test.tb.code)->test.tb.code", - " │ │ │ └─IndexLookUp 249.75 root ", - " │ │ │ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:tb, index:idx_tb_name(name) range:[\"chad9\",\"chad:\"), keep order:false, stats:pseudo", - " │ │ │ └─Selection(Probe) 249.75 cop[tikv] not(isnull(test.tb.code))", - " │ │ │ └─TableRowIDScan 250.00 cop[tikv] table:tb keep order:false, stats:pseudo", - " │ │ └─IndexLookUp(Probe) 1.25 root ", - " │ │ ├─Selection(Build) 1.25 cop[tikv] not(isnull(test.ta.code))", - " │ │ │ └─IndexRangeScan 1.25 cop[tikv] table:ta, index:idx_ta_code(code) range: decided by [eq(test.ta.code, test.tb.code)], keep order:false, stats:pseudo", - " │ │ └─TableRowIDScan(Probe) 1.25 cop[tikv] table:ta keep order:false, stats:pseudo", - " │ └─Selection(Probe) 0.80 root gt(Column#14, 100)", - " │ └─MaxOneRow 1.00 root ", - " │ └─StreamAgg 1.00 root funcs:max(test.tc.id)->Column#14", - " │ └─TopN 0.25 root test.tc.id:desc, offset:0, count:1", - " │ └─IndexLookUp 0.25 root ", - " │ ├─Selection(Build) 0.25 cop[tikv] eq(test.ta.name, test.tc.name)", - " │ │ └─IndexRangeScan 250.00 cop[tikv] table:tc, index:idx_tc_name(name) range:[\"chad99\",\"chad9:\"), keep order:false, stats:pseudo", - " │ └─TopN(Probe) 0.25 cop[tikv] test.tc.id:desc, offset:0, count:1", - " │ └─Selection 0.25 cop[tikv] not(isnull(test.tc.id))", - " │ └─TableRowIDScan 0.25 cop[tikv] table:tc keep order:false, stats:pseudo", - " └─Selection(Probe) 0.80 root gt(Column#19, 100)", - " └─MaxOneRow 1.00 root ", - " └─StreamAgg 1.00 root funcs:max(test.td.id)->Column#19", - " └─Limit 0.25 root offset:0, count:1", - " └─Projection 0.25 root test.td.id, test.td.name", - " └─IndexLookUp 0.25 root ", - " ├─Selection(Build) 9.99 cop[tikv] eq(test.ta.id, test.td.id)", - " │ └─IndexFullScan 9990.00 cop[tikv] table:td, index:idx_tc_id(id) keep order:true, desc, stats:pseudo", - " └─Selection(Probe) 0.25 cop[tikv] like(test.td.name, \"chad999%\", 92)", - " └─TableRowIDScan 9.99 cop[tikv] table:td keep order:false, stats:pseudo" + " │ │ │ └─TableReader 249.75 root data:Selection", + " │ │ │ └─Selection 249.75 cop[tikv] like(test.tb.name, \"chad9%\", 92), not(isnull(test.tb.code))", + " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:tb keep order:false, stats:pseudo", + " │ │ └─IndexLookUp(Probe) 249.75 root ", + " │ │ ├─Selection(Build) 249.75 cop[tikv] not(isnull(test.ta.code))", + " │ │ │ └─IndexRangeScan 250.00 cop[tikv] table:ta, index:idx_ta_code(code) range: decided by [eq(test.ta.code, test.tb.code)], keep order:false, stats:pseudo", + " │ │ └─TableRowIDScan(Probe) 249.75 cop[tikv] table:ta keep order:false, stats:pseudo", + " │ └─Selection(Probe) 199.80 root gt(Column#14, 100)", + " │ └─MaxOneRow 249.75 root ", + " │ └─StreamAgg 249.75 root funcs:max(test.tc.id)->Column#14", + " │ └─TopN 62.38 root test.tc.id:desc, offset:0, count:1", + " │ └─IndexLookUp 62.38 root ", + " │ ├─Selection(Build) 62.44 cop[tikv] eq(test.ta.name, test.tc.name)", + " │ │ └─IndexRangeScan 62437.50 cop[tikv] table:tc, index:idx_tc_name(name) range:[\"chad99\",\"chad9:\"), keep order:false, stats:pseudo", + " │ └─TopN(Probe) 62.38 cop[tikv] test.tc.id:desc, offset:0, count:1", + " │ └─Selection 62.38 cop[tikv] not(isnull(test.tc.id))", + " │ └─TableRowIDScan 62.44 cop[tikv] table:tc keep order:false, stats:pseudo", + " └─Selection(Probe) 199.80 root gt(Column#19, 100)", + " └─MaxOneRow 249.75 root ", + " └─StreamAgg 249.75 root funcs:max(test.td.id)->Column#19", + " └─Limit 62.38 root offset:0, count:1", + " └─Projection 62.38 root test.td.id, test.td.name", + " └─IndexLookUp 62.38 root ", + " ├─Selection(Build) 2495.00 cop[tikv] eq(test.ta.id, test.td.id)", + " │ └─IndexFullScan 2495002.50 cop[tikv] table:td, index:idx_tc_id(id) keep order:true, desc, stats:pseudo", + " └─Selection(Probe) 62.38 cop[tikv] like(test.td.name, \"chad999%\", 92)", + " └─TableRowIDScan 2495.00 cop[tikv] table:td keep order:false, stats:pseudo" ], "Result": null, "Warning": null @@ -6307,34 +7202,304 @@ " │ ├─Apply(Build) 10000.00 root CARTESIAN semi join", " │ │ ├─TableReader(Build) 10000.00 root data:TableFullScan", " │ │ │ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", - " │ │ └─IndexLookUp(Probe) 0.25 root ", - " │ │ ├─IndexRangeScan(Build) 250.00 cop[tikv] table:tb, index:idx_tb_name(name) range:[\"chad9\",\"chad:\"), keep order:false, stats:pseudo", - " │ │ └─Selection(Probe) 0.25 cop[tikv] eq(test.ta.code, test.tb.code)", - " │ │ └─TableRowIDScan 250.00 cop[tikv] table:tb keep order:false, stats:pseudo", - " │ └─Selection(Probe) 0.80 root gt(Column#14, 100)", - " │ └─MaxOneRow 1.00 root ", - " │ └─StreamAgg 1.00 root funcs:max(test.tc.id)->Column#14", - " │ └─TopN 0.25 root test.tc.id:desc, offset:0, count:1", - " │ └─IndexLookUp 0.25 root ", - " │ ├─Selection(Build) 0.25 cop[tikv] eq(test.ta.name, test.tc.name)", - " │ │ └─IndexRangeScan 250.00 cop[tikv] table:tc, index:idx_tc_name(name) range:[\"chad99\",\"chad9:\"), keep order:false, stats:pseudo", - " │ └─TopN(Probe) 0.25 cop[tikv] test.tc.id:desc, offset:0, count:1", - " │ └─Selection 0.25 cop[tikv] not(isnull(test.tc.id))", - " │ └─TableRowIDScan 0.25 cop[tikv] table:tc keep order:false, stats:pseudo", - " └─Selection(Probe) 0.80 root gt(Column#19, 100)", - " └─MaxOneRow 1.00 root ", - " └─StreamAgg 1.00 root funcs:max(test.td.id)->Column#19", - " └─Limit 0.25 root offset:0, count:1", - " └─Projection 0.25 root test.td.id, test.td.name", - " └─IndexLookUp 0.25 root ", - " ├─Selection(Build) 9.99 cop[tikv] eq(test.ta.id, test.td.id)", - " │ └─IndexFullScan 9990.00 cop[tikv] table:td, index:idx_tc_id(id) keep order:true, desc, stats:pseudo", - " └─Selection(Probe) 0.25 cop[tikv] like(test.td.name, \"chad999%\", 92)", - " └─TableRowIDScan 9.99 cop[tikv] table:td keep order:false, stats:pseudo" + " │ │ └─TableReader(Probe) 2500.00 root data:Selection", + " │ │ └─Selection 2500.00 cop[tikv] eq(test.ta.code, test.tb.code), like(test.tb.name, \"chad9%\", 92)", + " │ │ └─TableFullScan 100000000.00 cop[tikv] table:tb keep order:false, stats:pseudo", + " │ └─Selection(Probe) 8000.00 root gt(Column#14, 100)", + " │ └─MaxOneRow 10000.00 root ", + " │ └─StreamAgg 10000.00 root funcs:max(test.tc.id)->Column#14", + " │ └─TopN 2497.50 root test.tc.id:desc, offset:0, count:1", + " │ └─IndexLookUp 2497.50 root ", + " │ ├─Selection(Build) 2500.00 cop[tikv] eq(test.ta.name, test.tc.name)", + " │ │ └─IndexRangeScan 2500000.00 cop[tikv] table:tc, index:idx_tc_name(name) range:[\"chad99\",\"chad9:\"), keep order:false, stats:pseudo", + " │ └─TopN(Probe) 2497.50 cop[tikv] test.tc.id:desc, offset:0, count:1", + " │ └─Selection 2497.50 cop[tikv] not(isnull(test.tc.id))", + " │ └─TableRowIDScan 2500.00 cop[tikv] table:tc keep order:false, stats:pseudo", + " └─Selection(Probe) 8000.00 root gt(Column#19, 100)", + " └─MaxOneRow 10000.00 root ", + " └─StreamAgg 10000.00 root funcs:max(test.td.id)->Column#19", + " └─Limit 2497.50 root offset:0, count:1", + " └─Projection 2497.50 root test.td.id, test.td.name", + " └─IndexLookUp 2497.50 root ", + " ├─Selection(Build) 99900.00 cop[tikv] eq(test.ta.id, test.td.id)", + " │ └─IndexFullScan 99900000.00 cop[tikv] table:td, index:idx_tc_id(id) keep order:true, desc, stats:pseudo", + " └─Selection(Probe) 2497.50 cop[tikv] like(test.td.name, \"chad999%\", 92)", + " └─TableRowIDScan 99900.00 cop[tikv] table:td keep order:false, stats:pseudo" ], "Result": null, "Warning": null } ] + }, + { + "Name": "TestCountStarForTikv", + "Cases": [ + { + "SQL": "select count(*) from t", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#12)->Column#10", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#12", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(1), count(3.1415), count(0), count(null) from t -- shouldn't be rewritten", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#18)->Column#10, funcs:count(Column#19)->Column#11, funcs:count(Column#20)->Column#12, funcs:count(Column#21)->Column#13", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#18, funcs:count(3.1415)->Column#19, funcs:count(0)->Column#20, funcs:count(NULL)->Column#21", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t where a=1", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#12)->Column#10", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#12", + " └─Selection 10.00 cop[tikv] eq(test.t.a, 1)", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t_pick_row_id", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#5)->Column#3", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#5", + " └─TableFullScan 10000.00 cop[tikv] table:t_pick_row_id keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select t.b, t.c from (select count(*) as c from t) a, t where a.c=t.a -- shouldn't be rewritten", + "Plan": [ + "HashJoin 1.25 root inner join, equal:[eq(test.t.a, Column#10)]", + "├─StreamAgg(Build) 1.00 root funcs:count(Column#21)->Column#10", + "│ └─TableReader 1.00 root data:StreamAgg", + "│ └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#21", + "│ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select * from t out where out.a > (select count(*) from t inn where inn.a = out.b) -- shouldn't be rewritten", + "Plan": [ + "Projection 10000.00 root test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.f, test.t.g, test.t.h", + "└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(test.t.a, Column#19)", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:out keep order:false, stats:pseudo", + " └─StreamAgg(Probe) 10000.00 root funcs:count(Column#21)->Column#19", + " └─TableReader 10000.00 root data:StreamAgg", + " └─StreamAgg 10000.00 cop[tikv] funcs:count(1)->Column#21", + " └─Selection 80000000.00 cop[tikv] eq(cast(test.t.a, double BINARY), cast(test.t.b, double BINARY))", + " └─TableFullScan 100000000.00 cop[tikv] table:inn keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t t1, t t2 where t1.a=t2.e -- shouldn't be rewritten", + "Plan": [ + "HashAgg 1.00 root funcs:count(1)->Column#19", + "└─HashJoin 12500.00 root inner join, equal:[eq(test.t.a, test.t.e)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(distinct 1) from t -- shouldn't be rewritten", + "Plan": [ + "StreamAgg 1.00 root funcs:count(distinct 1)->Column#10", + "└─TableReader 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(1), count(a), count(b) from t -- shouldn't be rewritten", + "Plan": [ + "StreamAgg 1.00 root funcs:count(Column#16)->Column#10, funcs:count(Column#17)->Column#11, funcs:count(Column#18)->Column#12", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:count(1)->Column#16, funcs:count(test.t.a)->Column#17, funcs:count(test.t.b)->Column#18", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select a, count(*) from t group by a -- shouldn't be rewritten", + "Plan": [ + "Projection 8000.00 root test.t.a, Column#10", + "└─HashAgg 8000.00 root group by:test.t.a, funcs:count(1)->Column#10, funcs:firstrow(test.t.a)->test.t.a", + " └─TableReader 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select sum(a) from t -- sum shouldn't be rewritten", + "Plan": [ + "StreamAgg 1.00 root funcs:sum(Column#12)->Column#10", + "└─TableReader 1.00 root data:StreamAgg", + " └─StreamAgg 1.00 cop[tikv] funcs:sum(test.t.a)->Column#12", + " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo" + ], + "Warning": null + } + ] + }, + { + "Name": "TestCountStarForTiFlash", + "Cases": [ + { + "SQL": "select count(*) from t", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#12)->Column#10", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t.d)->Column#12", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(1), count(3.1415), count(0), count(null) from t -- every count but count(null) can be rewritten", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#18)->Column#10, funcs:count(Column#19)->Column#11, funcs:count(Column#20)->Column#12, funcs:count(Column#21)->Column#13", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t.d)->Column#18, funcs:count(test.t.d)->Column#19, funcs:count(test.t.d)->Column#20, funcs:count(NULL)->Column#21", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t where a=1", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#12)->Column#10", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#12", + " └─Selection 10.00 mpp[tiflash] eq(test.t.a, 1)", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t_pick_row_id", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#5)->Column#3", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t_pick_row_id._tidb_rowid)->Column#5", + " └─TableFullScan 10000.00 mpp[tiflash] table:t_pick_row_id keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select t.b, t.c from (select count(*) as c from t) a, t where a.c=t.a -- test recursive", + "Plan": [ + "HashJoin 1.25 root inner join, equal:[eq(test.t.a, Column#10)]", + "├─HashAgg(Build) 1.00 root funcs:count(Column#22)->Column#10", + "│ └─TableReader 1.00 root data:ExchangeSender", + "│ └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + "│ └─HashAgg 1.00 mpp[tiflash] funcs:count(test.t.d)->Column#22", + "│ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select * from t out where out.a > (select count(*) from t inn where inn.a = out.b) -- shouldn't be rewritten for correlated sub query", + "Plan": [ + "Projection 10000.00 root test.t.a, test.t.b, test.t.c, test.t.d, test.t.e, test.t.f, test.t.g, test.t.h", + "└─Apply 10000.00 root CARTESIAN inner join, other cond:gt(test.t.a, Column#19)", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tiflash] table:out keep order:false, stats:pseudo", + " └─HashAgg(Probe) 10000.00 root funcs:count(Column#21)->Column#19", + " └─TableReader 10000.00 root data:ExchangeSender", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 10000.00 mpp[tiflash] funcs:count(1)->Column#21", + " └─Selection 80000000.00 mpp[tiflash] eq(cast(test.t.a, double BINARY), cast(test.t.b, double BINARY))", + " └─TableFullScan 100000000.00 mpp[tiflash] table:inn keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(*) from t t1, t t2 where t1.a=t2.e -- shouldn't be rewritten when join under agg", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#20)->Column#19", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#20", + " └─HashJoin 12500.00 mpp[tiflash] inner join, equal:[eq(test.t.a, test.t.e)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: Broadcast", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(distinct 1) from t -- shouldn't be rewritten", + "Plan": [ + "TableReader 1.00 root data:ExchangeSender", + "└─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 1.00 mpp[tiflash] Column#10", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(distinct Column#12)->Column#10", + " └─ExchangeReceiver 1.00 mpp[tiflash] ", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] group by:1, ", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select count(1), count(a), count(b) from t -- keep count(1)", + "Plan": [ + "HashAgg 1.00 root funcs:count(Column#16)->Column#10, funcs:count(Column#17)->Column#11, funcs:count(Column#18)->Column#12", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:count(1)->Column#16, funcs:count(test.t.a)->Column#17, funcs:count(test.t.b)->Column#18", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select a, count(*) from t group by a -- shouldn't be rewritten", + "Plan": [ + "TableReader 8000.00 root data:ExchangeSender", + "└─ExchangeSender 8000.00 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection 8000.00 mpp[tiflash] test.t.a, Column#10", + " └─Projection 8000.00 mpp[tiflash] Column#10, test.t.a", + " └─HashAgg 8000.00 mpp[tiflash] group by:test.t.a, funcs:count(1)->Column#10, funcs:firstrow(test.t.a)->test.t.a", + " └─ExchangeReceiver 10000.00 mpp[tiflash] ", + " └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t.a, collate: binary]", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select sum(a) from t -- sum shouldn't be rewritten", + "Plan": [ + "HashAgg 1.00 root funcs:sum(Column#12)->Column#10", + "└─TableReader 1.00 root data:ExchangeSender", + " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#15)->Column#12", + " └─Projection 10000.00 mpp[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#15", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" + ], + "Warning": null + } + ] } ] diff --git a/planner/core/testdata/stats_suite_out.json b/planner/core/testdata/stats_suite_out.json index 26f0f2fe5a193..03af4766d0995 100644 --- a/planner/core/testdata/stats_suite_out.json +++ b/planner/core/testdata/stats_suite_out.json @@ -184,9 +184,9 @@ " └─Apply 4.00 root CARTESIAN left outer join", " ├─IndexReader(Build) 4.00 root index:IndexFullScan", " │ └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:true", - " └─MaxOneRow(Probe) 1.00 root ", - " └─IndexReader 2.00 root index:IndexRangeScan", - " └─IndexRangeScan 2.00 cop[tikv] table:t2, index:a(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false" + " └─MaxOneRow(Probe) 4.00 root ", + " └─IndexReader 8.00 root index:IndexRangeScan", + " └─IndexRangeScan 8.00 cop[tikv] table:t2, index:a(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false" ] }, { @@ -196,10 +196,10 @@ "└─Apply 4.00 root left outer semi join, equal:[eq(test.t1.b, test.t2.b)]", " ├─IndexReader(Build) 4.00 root index:IndexFullScan", " │ └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:true", - " └─Limit(Probe) 3.00 root offset:0, count:3", - " └─IndexReader 3.00 root index:Limit", - " └─Limit 3.00 cop[tikv] offset:0, count:3", - " └─IndexRangeScan 3.00 cop[tikv] table:t2, index:a(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false" + " └─Limit(Probe) 12.00 root offset:0, count:3", + " └─IndexReader 12.00 root index:Limit", + " └─Limit 12.00 cop[tikv] offset:0, count:3", + " └─IndexRangeScan 12.00 cop[tikv] table:t2, index:a(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false" ] }, { @@ -209,32 +209,32 @@ "└─Apply 4.00 root anti left outer semi join, equal:[eq(test.t1.b, test.t2.b)]", " ├─IndexReader(Build) 4.00 root index:IndexFullScan", " │ └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:true", - " └─Limit(Probe) 3.00 root offset:0, count:3", - " └─IndexReader 3.00 root index:Limit", - " └─Limit 3.00 cop[tikv] offset:0, count:3", - " └─IndexRangeScan 3.00 cop[tikv] table:t2, index:a(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false" + " └─Limit(Probe) 12.00 root offset:0, count:3", + " └─IndexReader 12.00 root index:Limit", + " └─Limit 12.00 cop[tikv] offset:0, count:3", + " └─IndexRangeScan 12.00 cop[tikv] table:t2, index:a(a, b) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false" ] }, { "SQL": "select count(1) from t1 left join t2 on t1.a = t2.a group by t1.a, t1.b", "Plan": [ "HashAgg 4.00 root group by:test.t1.a, test.t1.b, funcs:count(1)->Column#7", - "└─HashJoin 12.00 root left outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─TableReader(Build) 4.00 root data:TableFullScan", - " │ └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false", - " └─TableReader(Probe) 9.00 root data:TableFullScan", - " └─TableFullScan 9.00 cop[tikv] table:t2 keep order:false" + "└─MergeJoin 12.00 root left outer join, left key:test.t1.a, right key:test.t2.a", + " ├─IndexReader(Build) 9.00 root index:IndexFullScan", + " │ └─IndexFullScan 9.00 cop[tikv] table:t2, index:a(a, b) keep order:true", + " └─IndexReader(Probe) 4.00 root index:IndexFullScan", + " └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:true" ] }, { "SQL": "select count(1) from t1 right join t2 on t1.a = t2.a group by t2.a, t2.b", "Plan": [ "HashAgg 9.00 root group by:test.t2.a, test.t2.b, funcs:count(1)->Column#7", - "└─HashJoin 12.00 root right outer join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─TableReader(Build) 4.00 root data:TableFullScan", - " │ └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false", - " └─TableReader(Probe) 9.00 root data:TableFullScan", - " └─TableFullScan 9.00 cop[tikv] table:t2 keep order:false" + "└─MergeJoin 12.00 root right outer join, left key:test.t1.a, right key:test.t2.a", + " ├─IndexReader(Build) 4.00 root index:IndexFullScan", + " │ └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:true", + " └─IndexReader(Probe) 9.00 root index:IndexFullScan", + " └─IndexFullScan 9.00 cop[tikv] table:t2, index:a(a, b) keep order:true" ] }, { @@ -242,10 +242,10 @@ "Plan": [ "HashAgg 4.00 root group by:test.t1.a, test.t1.b, funcs:count(Column#10)->Column#11", "└─HashJoin 4.00 root left outer semi join, equal:[eq(test.t1.b, test.t2.b)], other cond:gt(test.t2.a, test.t1.a)", - " ├─TableReader(Build) 9.00 root data:TableFullScan", - " │ └─TableFullScan 9.00 cop[tikv] table:t2 keep order:false", - " └─TableReader(Probe) 4.00 root data:TableFullScan", - " └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false" + " ├─IndexReader(Build) 9.00 root index:IndexFullScan", + " │ └─IndexFullScan 9.00 cop[tikv] table:t2, index:a(a, b) keep order:false", + " └─IndexReader(Probe) 4.00 root index:IndexFullScan", + " └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:false" ] }, { @@ -253,10 +253,10 @@ "Plan": [ "HashAgg 4.00 root group by:test.t1.a, test.t1.b, funcs:count(Column#10)->Column#11", "└─HashJoin 4.00 root anti left outer semi join, equal:[eq(test.t1.b, test.t2.b)], other cond:gt(test.t2.a, test.t1.a)", - " ├─TableReader(Build) 9.00 root data:TableFullScan", - " │ └─TableFullScan 9.00 cop[tikv] table:t2 keep order:false", - " └─TableReader(Probe) 4.00 root data:TableFullScan", - " └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false" + " ├─IndexReader(Build) 9.00 root index:IndexFullScan", + " │ └─IndexFullScan 9.00 cop[tikv] table:t2, index:a(a, b) keep order:false", + " └─IndexReader(Probe) 4.00 root index:IndexFullScan", + " └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:false" ] }, { @@ -276,8 +276,8 @@ "Plan": [ "HashAgg 4.00 root group by:test.t1.a, test.t1.b, funcs:count(Column#5)->Column#6", "└─Window 4.00 root sum(cast(test.t1.a, decimal(10,0) BINARY))->Column#5 over()", - " └─TableReader 4.00 root data:TableFullScan", - " └─TableFullScan 4.00 cop[tikv] table:t1 keep order:false" + " └─IndexReader 4.00 root index:IndexFullScan", + " └─IndexFullScan 4.00 cop[tikv] table:t1, index:a(a, b) keep order:false" ] } ] diff --git a/planner/core/testdata/window_push_down_suite_out.json b/planner/core/testdata/window_push_down_suite_out.json index e4b3aa37c09a6..395c9e4ff61b6 100644 --- a/planner/core/testdata/window_push_down_suite_out.json +++ b/planner/core/testdata/window_push_down_suite_out.json @@ -343,11 +343,12 @@ "TableReader_84 8000.00 root data:ExchangeSender_83", "└─ExchangeSender_83 8000.00 mpp[tiflash] ExchangeType: PassThrough", " └─Window_82 8000.00 mpp[tiflash] row_number()->Column#7 over(rows between current row and current row)", - " └─Projection_19 8000.00 mpp[tiflash] Column#5", - " └─HashAgg_12 8000.00 mpp[tiflash] group by:test.employee.deptid, funcs:count(test.employee.empid)->Column#5", - " └─ExchangeReceiver_18 10000.00 mpp[tiflash] ", - " └─ExchangeSender_17 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.employee.deptid, collate: binary]", - " └─TableFullScan_16 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + " └─Projection_21 8000.00 mpp[tiflash] Column#5", + " └─HashAgg_22 8000.00 mpp[tiflash] group by:test.employee.deptid, funcs:sum(Column#8)->Column#5", + " └─ExchangeReceiver_24 8000.00 mpp[tiflash] ", + " └─ExchangeSender_23 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.employee.deptid, collate: binary]", + " └─HashAgg_13 8000.00 mpp[tiflash] group by:test.employee.deptid, funcs:count(test.employee.empid)->Column#8", + " └─TableFullScan_20 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" ], "Warn": null }, @@ -378,12 +379,13 @@ "TableReader_61 8000.00 root data:ExchangeSender_60", "└─ExchangeSender_60 8000.00 mpp[tiflash] ExchangeType: PassThrough", " └─Window_59 8000.00 mpp[tiflash] row_number()->Column#7 over(partition by test.employee.deptid rows between current row and current row)", - " └─Sort_18 8000.00 mpp[tiflash] test.employee.deptid", - " └─Projection_17 8000.00 mpp[tiflash] Column#5, test.employee.deptid", - " └─HashAgg_12 8000.00 mpp[tiflash] group by:test.employee.deptid, funcs:count(test.employee.empid)->Column#5, funcs:firstrow(test.employee.deptid)->test.employee.deptid", - " └─ExchangeReceiver_16 10000.00 mpp[tiflash] ", - " └─ExchangeSender_15 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.employee.deptid, collate: binary]", - " └─TableFullScan_14 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + " └─Sort_24 8000.00 mpp[tiflash] test.employee.deptid", + " └─Projection_20 8000.00 mpp[tiflash] Column#5, test.employee.deptid", + " └─HashAgg_21 8000.00 mpp[tiflash] group by:test.employee.deptid, funcs:sum(Column#8)->Column#5, funcs:firstrow(test.employee.deptid)->test.employee.deptid", + " └─ExchangeReceiver_23 8000.00 mpp[tiflash] ", + " └─ExchangeSender_22 8000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.employee.deptid, collate: binary]", + " └─HashAgg_13 8000.00 mpp[tiflash] group by:test.employee.deptid, funcs:count(test.employee.empid)->Column#8", + " └─TableFullScan_19 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" ], "Warn": null }, @@ -413,7 +415,7 @@ " └─HashAgg_43 1.00 mpp[tiflash] funcs:count(distinct test.employee.empid)->Column#9", " └─ExchangeReceiver_45 1.00 mpp[tiflash] ", " └─ExchangeSender_44 1.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.employee.empid, collate: binary]", - " └─HashAgg_41 1.00 mpp[tiflash] group by:test.employee.empid, ", + " └─HashAgg_41 1.00 mpp[tiflash] group by:test.employee.empid, , stream_count: 8", " └─Window_27 10000.00 mpp[tiflash] row_number()->Column#6 over(partition by test.employee.deptid rows between current row and current row), stream_count: 8", " └─Sort_18 10000.00 mpp[tiflash] test.employee.deptid, stream_count: 8", " └─ExchangeReceiver_17 10000.00 mpp[tiflash] stream_count: 8", @@ -441,15 +443,16 @@ "Plan": [ "TableReader_54 10000.00 root data:ExchangeSender_53", "└─ExchangeSender_53 10000.00 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection_48 10000.00 mpp[tiflash] Column#7", - " └─HashAgg_46 10000.00 mpp[tiflash] group by:Column#6, funcs:count(test.employee.empid)->Column#7", - " └─ExchangeReceiver_32 10000.00 mpp[tiflash] ", - " └─ExchangeSender_31 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#6, collate: binary]", - " └─Window_30 10000.00 mpp[tiflash] row_number()->Column#6 over(partition by test.employee.deptid rows between current row and current row), stream_count: 8", - " └─Sort_21 10000.00 mpp[tiflash] test.employee.deptid, stream_count: 8", - " └─ExchangeReceiver_20 10000.00 mpp[tiflash] stream_count: 8", - " └─ExchangeSender_19 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.employee.deptid, collate: binary], stream_count: 8", - " └─TableFullScan_18 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" + " └─Projection_49 10000.00 mpp[tiflash] Column#7", + " └─HashAgg_50 10000.00 mpp[tiflash] group by:Column#6, funcs:sum(Column#10)->Column#7", + " └─ExchangeReceiver_52 10000.00 mpp[tiflash] ", + " └─ExchangeSender_51 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: Column#6, collate: binary]", + " └─HashAgg_47 10000.00 mpp[tiflash] group by:Column#6, funcs:count(test.employee.empid)->Column#10, stream_count: 8", + " └─Window_36 10000.00 mpp[tiflash] row_number()->Column#6 over(partition by test.employee.deptid rows between current row and current row), stream_count: 8", + " └─Sort_21 10000.00 mpp[tiflash] test.employee.deptid, stream_count: 8", + " └─ExchangeReceiver_20 10000.00 mpp[tiflash] stream_count: 8", + " └─ExchangeSender_19 10000.00 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.employee.deptid, collate: binary], stream_count: 8", + " └─TableFullScan_18 10000.00 mpp[tiflash] table:employee keep order:false, stats:pseudo" ], "Warn": null }, diff --git a/planner/core/util.go b/planner/core/util.go index 845d061047cc8..5dc8d93d92efe 100644 --- a/planner/core/util.go +++ b/planner/core/util.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/util/ranger" "github.com/pingcap/tidb/util/set" "github.com/pingcap/tidb/util/size" "golang.org/x/exp/slices" @@ -233,6 +232,9 @@ func (s *baseSchemaProducer) MemoryUsage() (sum int64) { if s.schema != nil { sum += s.schema.MemoryUsage() } + for _, name := range s.names { + sum += name.MemoryUsage() + } return } @@ -393,38 +395,6 @@ func tableHasDirtyContent(ctx sessionctx.Context, tableInfo *model.TableInfo) bo return false } -func cloneExprs(exprs []expression.Expression) []expression.Expression { - cloned := make([]expression.Expression, 0, len(exprs)) - for _, e := range exprs { - cloned = append(cloned, e.Clone()) - } - return cloned -} - -func cloneCols(cols []*expression.Column) []*expression.Column { - cloned := make([]*expression.Column, 0, len(cols)) - for _, c := range cols { - cloned = append(cloned, c.Clone().(*expression.Column)) - } - return cloned -} - -func cloneColInfos(cols []*model.ColumnInfo) []*model.ColumnInfo { - cloned := make([]*model.ColumnInfo, 0, len(cols)) - for _, c := range cols { - cloned = append(cloned, c.Clone()) - } - return cloned -} - -func cloneRanges(ranges []*ranger.Range) []*ranger.Range { - cloned := make([]*ranger.Range, 0, len(ranges)) - for _, r := range ranges { - cloned = append(cloned, r.Clone()) - } - return cloned -} - func clonePhysicalPlan(plans []PhysicalPlan) ([]PhysicalPlan, error) { cloned := make([]PhysicalPlan, 0, len(plans)) for _, p := range plans { diff --git a/planner/core/window_push_down_test.go b/planner/core/window_push_down_test.go index 599fe113ff1c5..0d8538fa19ca0 100644 --- a/planner/core/window_push_down_test.go +++ b/planner/core/window_push_down_test.go @@ -110,6 +110,7 @@ func TestWindowPlanWithOtherOperators(t *testing.T) { dom := domain.GetDomain(tk.Session()) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists employee") tk.MustExec("create table employee (empid int, deptid int, salary decimal(10,2))") SetTiFlashReplica(t, dom, "test", "employee") diff --git a/planner/funcdep/extract_fd_test.go b/planner/funcdep/extract_fd_test.go index 92a924df6c0be..b2ca19de369c3 100644 --- a/planner/funcdep/extract_fd_test.go +++ b/planner/funcdep/extract_fd_test.go @@ -210,6 +210,7 @@ func TestFDSet_ExtractFD(t *testing.T) { ctx := context.TODO() is := testGetIS(t, tk.Session()) + is = &infoschema.SessionExtendedInfoSchema{InfoSchema: is} for i, tt := range tests { comment := fmt.Sprintf("case:%v sql:%s", i, tt.sql) require.NoError(t, tk.Session().PrepareTxnCtx(context.TODO())) @@ -218,7 +219,7 @@ func TestFDSet_ExtractFD(t *testing.T) { require.NoError(t, err, comment) tk.Session().GetSessionVars().PlanID = 0 tk.Session().GetSessionVars().PlanColumnID = 0 - err = plannercore.Preprocess(tk.Session(), stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: is})) + err = plannercore.Preprocess(context.Background(), tk.Session(), stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: is})) require.NoError(t, err) require.NoError(t, sessiontxn.GetTxnManager(tk.Session()).AdviseWarmup()) builder, _ := plannercore.NewPlanBuilder().Init(tk.Session(), is, &hint.BlockHintProcessor{}) @@ -308,6 +309,7 @@ func TestFDSet_ExtractFDForApply(t *testing.T) { ctx := context.TODO() is := testGetIS(t, tk.Session()) + is = &infoschema.SessionExtendedInfoSchema{InfoSchema: is} for i, tt := range tests { require.NoError(t, tk.Session().PrepareTxnCtx(context.TODO())) require.NoError(t, sessiontxn.GetTxnManager(tk.Session()).OnStmtStart(context.TODO(), nil)) @@ -316,7 +318,7 @@ func TestFDSet_ExtractFDForApply(t *testing.T) { require.NoError(t, err, comment) tk.Session().GetSessionVars().PlanID = 0 tk.Session().GetSessionVars().PlanColumnID = 0 - err = plannercore.Preprocess(tk.Session(), stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: is})) + err = plannercore.Preprocess(context.Background(), tk.Session(), stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: is})) require.NoError(t, err, comment) require.NoError(t, sessiontxn.GetTxnManager(tk.Session()).AdviseWarmup()) builder, _ := plannercore.NewPlanBuilder().Init(tk.Session(), is, &hint.BlockHintProcessor{}) @@ -342,7 +344,7 @@ func TestFDSet_MakeOuterJoin(t *testing.T) { tk.MustExec("set @@session.tidb_enable_new_only_full_group_by_check = 'on';") tk.MustExec("CREATE TABLE X (a INT PRIMARY KEY, b INT, c INT, d INT, e INT)") tk.MustExec("CREATE UNIQUE INDEX uni ON X (b, c)") - tk.MustExec("CREATE TABLE Y (m INT, n INT, p INT, q INT, PRIMARY KEY (m, n))") + tk.MustExec("CREATE TABLE Y (m INT, n INT, p INT, q INT, PRIMARY KEY (m, n) NONCLUSTERED)") tests := []struct { sql string @@ -364,7 +366,7 @@ func TestFDSet_MakeOuterJoin(t *testing.T) { require.NoError(t, err, comment) tk.Session().GetSessionVars().PlanID = 0 tk.Session().GetSessionVars().PlanColumnID = 0 - err = plannercore.Preprocess(tk.Session(), stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: is})) + err = plannercore.Preprocess(context.Background(), tk.Session(), stmt, plannercore.WithPreprocessorReturn(&plannercore.PreprocessorReturn{InfoSchema: is})) require.NoError(t, err, comment) require.NoError(t, sessiontxn.GetTxnManager(tk.Session()).AdviseWarmup()) builder, _ := plannercore.NewPlanBuilder().Init(tk.Session(), is, &hint.BlockHintProcessor{}) diff --git a/planner/funcdep/main_test.go b/planner/funcdep/main_test.go index e1e8cd745f387..6d95dd208e1b7 100644 --- a/planner/funcdep/main_test.go +++ b/planner/funcdep/main_test.go @@ -25,7 +25,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/planner/implementation/main_test.go b/planner/implementation/main_test.go index 4c2b1efb962ce..57f40ea9f20ac 100644 --- a/planner/implementation/main_test.go +++ b/planner/implementation/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/planner/memo/main_test.go b/planner/memo/main_test.go index 0fcbd9568d818..28382d1c818ec 100644 --- a/planner/memo/main_test.go +++ b/planner/memo/main_test.go @@ -25,7 +25,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/planner/optimize.go b/planner/optimize.go index 85a35533ffbf8..295d68b92f5a2 100644 --- a/planner/optimize.go +++ b/planner/optimize.go @@ -73,23 +73,30 @@ func matchSQLBinding(sctx sessionctx.Context, stmtNode ast.StmtNode) (bindRecord return bindRecord, scope, true } -// getPlanFromGeneralPlanCache tries to get an available cached plan from the General Plan Cache for this stmt. -func getPlanFromGeneralPlanCache(ctx context.Context, sctx sessionctx.Context, stmt ast.StmtNode, is infoschema.InfoSchema) (core.Plan, types.NameSlice, bool, error) { +// getPlanFromNonPreparedPlanCache tries to get an available cached plan from the NonPrepared Plan Cache for this stmt. +func getPlanFromNonPreparedPlanCache(ctx context.Context, sctx sessionctx.Context, stmt ast.StmtNode, is infoschema.InfoSchema) (p core.Plan, ns types.NameSlice, ok bool, err error) { if sctx.GetSessionVars().StmtCtx.InPreparedPlanBuilding || // already in cached plan rebuilding phase - !core.GeneralPlanCacheableWithCtx(sctx, stmt, is) { + !core.NonPreparedPlanCacheableWithCtx(sctx, stmt, is) { return nil, nil, false, nil } - paramSQL, params, err := core.ParameterizeAST(sctx, stmt) + paramSQL, params, err := core.ParameterizeAST(ctx, sctx, stmt) if err != nil { return nil, nil, false, err } - val := sctx.GetSessionVars().GetGeneralPlanCacheStmt(paramSQL) + defer func() { + if err != nil { + // keep the stmt unchanged if err so that it can fallback to the normal optimization path. + // TODO: add metrics + err = core.RestoreASTWithParams(ctx, sctx, stmt, params) + } + }() + val := sctx.GetSessionVars().GetNonPreparedPlanCacheStmt(paramSQL) if val == nil { - cachedStmt, _, _, err := core.GeneratePlanCacheStmtWithAST(ctx, sctx, stmt) + cachedStmt, _, _, err := core.GeneratePlanCacheStmtWithAST(ctx, sctx, paramSQL, stmt) if err != nil { return nil, nil, false, err } - sctx.GetSessionVars().AddGeneralPlanCacheStmt(paramSQL, cachedStmt) + sctx.GetSessionVars().AddNonPreparedPlanCacheStmt(paramSQL, cachedStmt) val = cachedStmt } cachedStmt := val.(*core.PlanCacheStmt) @@ -176,11 +183,11 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in node = stmtNode } - // try to get Plan from the General Plan Cache - if sctx.GetSessionVars().EnableGeneralPlanCache && + // try to get Plan from the NonPrepared Plan Cache + if sctx.GetSessionVars().EnableNonPreparedPlanCache && isStmtNode && !useBinding { // TODO: support binding - cachedPlan, names, ok, err := getPlanFromGeneralPlanCache(ctx, sctx, stmtNode, is) + cachedPlan, names, ok, err := getPlanFromNonPreparedPlanCache(ctx, sctx, stmtNode, is) if err != nil { return nil, nil, err } @@ -208,6 +215,13 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in hint.BindHint(stmtNode, binding.Hint) curStmtHints, _, curWarns := handleStmtHints(binding.Hint.GetFirstTableHints()) sessVars.StmtCtx.StmtHints = curStmtHints + // update session var by hint /set_var/ + for name, val := range sessVars.StmtCtx.StmtHints.SetVars { + err := sessVars.SetStmtVar(name, val) + if err != nil { + sessVars.StmtCtx.AppendWarning(err) + } + } plan, curNames, cost, err := optimize(ctx, sctx, node, is) if err != nil { binding.Status = bindinfo.Invalid @@ -234,6 +248,8 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in sessVars.FoundInBinding = true if sessVars.StmtCtx.InVerboseExplain { sessVars.StmtCtx.AppendNote(errors.Errorf("Using the bindSQL: %v", chosenBinding.BindSQL)) + } else { + sessVars.StmtCtx.AppendExtraNote(errors.Errorf("Using the bindSQL: %v", chosenBinding.BindSQL)) } } // Restore the hint to avoid changing the stmt node. @@ -289,6 +305,25 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in return bestPlan, names, nil } +// OptimizeForForeignKeyCascade does optimization and creates a Plan for foreign key cascade. +// The node must be prepared first. +// Compare to Optimize, OptimizeForForeignKeyCascade only build plan by StmtNode, +// doesn't consider plan cache and plan binding, also doesn't do privilege check. +func OptimizeForForeignKeyCascade(ctx context.Context, sctx sessionctx.Context, node ast.StmtNode, is infoschema.InfoSchema) (core.Plan, error) { + builder := planBuilderPool.Get().(*core.PlanBuilder) + defer planBuilderPool.Put(builder.ResetForReuse()) + hintProcessor := &hint.BlockHintProcessor{Ctx: sctx} + builder.Init(sctx, is, hintProcessor) + p, err := builder.Build(ctx, node) + if err != nil { + return nil, err + } + if err := core.CheckTableLock(sctx, is, builder.GetVisitInfo()); err != nil { + return nil, err + } + return p, nil +} + func allowInReadOnlyMode(sctx sessionctx.Context, node ast.Node) (bool, error) { pm := privilege.GetPrivilegeManager(sctx) if pm == nil { @@ -356,6 +391,7 @@ func optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in // build logical plan hintProcessor := &hint.BlockHintProcessor{Ctx: sctx} node.Accept(hintProcessor) + defer hintProcessor.HandleUnusedViewHints() builder := planBuilderPool.Get().(*core.PlanBuilder) defer planBuilderPool.Put(builder.ResetForReuse()) builder.Init(sctx, is, hintProcessor) @@ -395,6 +431,8 @@ func optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in beginOpt := time.Now() finalPlan, cost, err := core.DoOptimize(ctx, sctx, builder.GetOptFlag(), logic) + // TODO: capture plan replayer here if it matches sql and plan digest + sctx.GetSessionVars().DurationOptimization = time.Since(beginOpt) return finalPlan, names, cost, err } @@ -414,7 +452,7 @@ func OptimizeExecStmt(ctx context.Context, sctx sessionctx.Context, if !ok { return nil, nil, errors.Errorf("invalid result plan type, should be Execute") } - plan, names, err := core.GetPlanFromSessionPlanCache(ctx, sctx, execAst.FromGeneralStmt, is, exec.PrepStmt, exec.Params) + plan, names, err := core.GetPlanFromSessionPlanCache(ctx, sctx, false, is, exec.PrepStmt, exec.Params) if err != nil { return nil, nil, err } @@ -441,7 +479,11 @@ func buildLogicalPlan(ctx context.Context, sctx sessionctx.Context, node ast.Nod return nil, err } sctx.GetSessionVars().RewritePhaseInfo.DurationRewrite = time.Since(beginRewrite) - sctx.GetSessionVars().StmtCtx.Tables = builder.GetDBTableInfo() + if exec, ok := p.(*core.Execute); ok && exec.PrepStmt != nil { + sctx.GetSessionVars().StmtCtx.Tables = core.GetDBTableInfo(exec.PrepStmt.VisitInfos) + } else { + sctx.GetSessionVars().StmtCtx.Tables = core.GetDBTableInfo(builder.GetVisitInfo()) + } return p, nil } @@ -541,12 +583,14 @@ func handleEvolveTasks(ctx context.Context, sctx sessionctx.Context, br *bindinf return } charset, collation := sctx.GetSessionVars().GetCharsetInfo() + _, sqlDigestWithDB := parser.NormalizeDigest(utilparser.RestoreWithDefaultDB(stmtNode, br.Db, br.OriginalSQL)) binding := bindinfo.Binding{ BindSQL: bindSQL, Status: bindinfo.PendingVerify, Charset: charset, Collation: collation, Source: bindinfo.Evolve, + SQLDigest: sqlDigestWithDB.String(), } globalHandle := domain.GetDomain(sctx).BindHandle() globalHandle.AddEvolvePlanTask(br.OriginalSQL, br.Db, binding) diff --git a/planner/util/BUILD.bazel b/planner/util/BUILD.bazel index aae63a58c8fcb..50f4512126508 100644 --- a/planner/util/BUILD.bazel +++ b/planner/util/BUILD.bazel @@ -4,6 +4,7 @@ go_library( name = "util", srcs = [ "byitem.go", + "misc.go", "path.go", ], importpath = "github.com/pingcap/tidb/planner/util", @@ -18,6 +19,7 @@ go_library( "//util/collate", "//util/ranger", "//util/size", + "@org_golang_x_exp//slices", ], ) diff --git a/planner/util/main_test.go b/planner/util/main_test.go index 1cb1f40846368..7f62901b5534c 100644 --- a/planner/util/main_test.go +++ b/planner/util/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/planner/util/misc.go b/planner/util/misc.go new file mode 100644 index 0000000000000..bd67cbbe17b5c --- /dev/null +++ b/planner/util/misc.go @@ -0,0 +1,61 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import ( + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/util/ranger" +) + +// CloneExprs uses Expression.Clone to clone a slice of Expression. +func CloneExprs(exprs []expression.Expression) []expression.Expression { + cloned := make([]expression.Expression, 0, len(exprs)) + for _, e := range exprs { + cloned = append(cloned, e.Clone()) + } + return cloned +} + +// CloneCols uses (*Column).Clone to clone a slice of *Column. +func CloneCols(cols []*expression.Column) []*expression.Column { + cloned := make([]*expression.Column, 0, len(cols)) + for _, c := range cols { + if c == nil { + cloned = append(cloned, nil) + continue + } + cloned = append(cloned, c.Clone().(*expression.Column)) + } + return cloned +} + +// CloneColInfos uses (*ColumnInfo).Clone to clone a slice of *ColumnInfo. +func CloneColInfos(cols []*model.ColumnInfo) []*model.ColumnInfo { + cloned := make([]*model.ColumnInfo, 0, len(cols)) + for _, c := range cols { + cloned = append(cloned, c.Clone()) + } + return cloned +} + +// CloneRanges uses (*Range).Clone to clone a slice of *Range. +func CloneRanges(ranges []*ranger.Range) []*ranger.Range { + cloned := make([]*ranger.Range, 0, len(ranges)) + for _, r := range ranges { + cloned = append(cloned, r.Clone()) + } + return cloned +} diff --git a/planner/util/path.go b/planner/util/path.go index c283c6ffb3278..68b11bbf5751f 100644 --- a/planner/util/path.go +++ b/planner/util/path.go @@ -23,6 +23,7 @@ import ( "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/ranger" + "golang.org/x/exp/slices" ) // AccessPath indicates the way we access a table: by using single index, or by using multiple indexes, @@ -49,6 +50,12 @@ type AccessPath struct { // PartialIndexPaths store all index access paths. // If there are extra filters, store them in TableFilters. PartialIndexPaths []*AccessPath + // IndexMergeIsIntersection means whether it's intersection type or union type IndexMerge path. + // It's only valid for a IndexMerge path. + // Intersection type is for expressions connected by `AND` and union type is for `OR`. + IndexMergeIsIntersection bool + // IndexMergeAccessMVIndex indicates whether this IndexMerge path accesses a MVIndex. + IndexMergeAccessMVIndex bool StoreType kv.StoreType @@ -58,7 +65,9 @@ type AccessPath struct { IsIntHandlePath bool IsCommonHandlePath bool // Forced means this path is generated by `use/force index()`. - Forced bool + Forced bool + ForceKeepOrder bool + ForceNoKeepOrder bool // IsSingleScan indicates whether the path is a single index/table scan or table access after index scan. IsSingleScan bool @@ -66,6 +75,43 @@ type AccessPath struct { IsUkShardIndexPath bool } +// Clone returns a deep copy of the original AccessPath. +// Note that we rely on the Expression.Clone(), (*IndexInfo).Clone() and (*Range).Clone() in this method, so there are +// some fields like FieldType are not deep-copied. +func (path *AccessPath) Clone() *AccessPath { + ret := &AccessPath{ + Index: path.Index.Clone(), + FullIdxCols: CloneCols(path.FullIdxCols), + FullIdxColLens: slices.Clone(path.FullIdxColLens), + IdxCols: CloneCols(path.IdxCols), + IdxColLens: slices.Clone(path.IdxColLens), + ConstCols: slices.Clone(path.ConstCols), + Ranges: CloneRanges(path.Ranges), + CountAfterAccess: path.CountAfterAccess, + CountAfterIndex: path.CountAfterIndex, + AccessConds: CloneExprs(path.AccessConds), + EqCondCount: path.EqCondCount, + EqOrInCondCount: path.EqOrInCondCount, + IndexFilters: CloneExprs(path.IndexFilters), + TableFilters: CloneExprs(path.TableFilters), + IndexMergeIsIntersection: path.IndexMergeIsIntersection, + PartialIndexPaths: nil, + StoreType: path.StoreType, + IsDNFCond: path.IsDNFCond, + IsIntHandlePath: path.IsIntHandlePath, + IsCommonHandlePath: path.IsCommonHandlePath, + Forced: path.Forced, + ForceKeepOrder: path.ForceKeepOrder, + ForceNoKeepOrder: path.ForceNoKeepOrder, + IsSingleScan: path.IsSingleScan, + IsUkShardIndexPath: path.IsUkShardIndexPath, + } + for _, partialPath := range path.PartialIndexPaths { + ret.PartialIndexPaths = append(ret.PartialIndexPaths, partialPath.Clone()) + } + return ret +} + // IsTablePath returns true if it's IntHandlePath or CommonHandlePath. func (path *AccessPath) IsTablePath() bool { return path.IsIntHandlePath || path.IsCommonHandlePath diff --git a/plugin/conn_ip_example/conn_ip_example.go b/plugin/conn_ip_example/conn_ip_example.go index f6d09ffc5c612..082a7b4cdc04b 100644 --- a/plugin/conn_ip_example/conn_ip_example.go +++ b/plugin/conn_ip_example/conn_ip_example.go @@ -66,7 +66,7 @@ func OnInit(ctx context.Context, manifest *plugin.Manifest) error { // (Optional) the SetGlobal function is called when a global variable is changed. // This will only be called on the TiDB server that the change is made on, // and not on the tidb-server peers which will also update their global variable eventually. - SetGlobal: func(vars *variable.SessionVars, value string) error { + SetGlobal: func(_ context.Context, vars *variable.SessionVars, value string) error { fmt.Println("The set global function was called") return nil }, diff --git a/plugin/conn_ip_example/main_test.go b/plugin/conn_ip_example/main_test.go index 4847a1b134245..33e3beaa207d4 100644 --- a/plugin/conn_ip_example/main_test.go +++ b/plugin/conn_ip_example/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/plugin/main_test.go b/plugin/main_test.go index 6d55a790de4de..9c7fbeda0f42e 100644 --- a/plugin/main_test.go +++ b/plugin/main_test.go @@ -26,6 +26,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("time.Sleep"), diff --git a/privilege/BUILD.bazel b/privilege/BUILD.bazel index ec4d5d50cbe89..d85b91614612e 100644 --- a/privilege/BUILD.bazel +++ b/privilege/BUILD.bazel @@ -9,6 +9,7 @@ go_library( "//parser/auth", "//parser/mysql", "//sessionctx", + "//sessionctx/variable", "//types", ], ) diff --git a/privilege/privilege.go b/privilege/privilege.go index b557ce2f1ca8b..3229c1e3bb26f 100644 --- a/privilege/privilege.go +++ b/privilege/privilege.go @@ -15,11 +15,10 @@ package privilege import ( - "crypto/tls" - "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" ) @@ -29,6 +28,16 @@ func (k keyType) String() string { return "privilege-key" } +// VerificationInfo records some information returned by Manager.ConnectionVerification +type VerificationInfo struct { + // InSandBoxMode indicates that the session will enter sandbox mode, and only execute statement for resetting password. + InSandBoxMode bool + // FailedDueToWrongPassword indicates that the verification failed due to wrong password. + FailedDueToWrongPassword bool + // ResourceGroupName records the resource group name for the user. + ResourceGroupName string +} + // Manager is the interface for providing privilege related operations. type Manager interface { // ShowGrants shows granted privileges for user. @@ -58,9 +67,18 @@ type Manager interface { // RequestDynamicVerificationWithUser verifies a DYNAMIC privilege for a specific user. RequestDynamicVerificationWithUser(privName string, grantable bool, user *auth.UserIdentity) bool + // VerifyAccountAutoLockInMemory automatically unlock when the time comes. + VerifyAccountAutoLockInMemory(user string, host string) (bool, error) + + // IsAccountAutoLockEnabled verifies whether the account has enabled Failed-Login Tracking and Temporary Account Locking. + IsAccountAutoLockEnabled(user string, host string) bool + // ConnectionVerification verifies user privilege for connection. // Requires exact match on user name and host name. - ConnectionVerification(user *auth.UserIdentity, authUser, authHost string, auth, salt []byte, tlsState *tls.ConnectionState) error + ConnectionVerification(user *auth.UserIdentity, authUser, authHost string, auth, salt []byte, sessionVars *variable.SessionVars) (VerificationInfo, error) + + // AuthSuccess records auth success state + AuthSuccess(authUser, authHost string) // GetAuthWithoutVerification uses to get auth name without verification. // Requires exact match on user name and host name. @@ -69,6 +87,9 @@ type Manager interface { // MatchIdentity matches an identity MatchIdentity(user, host string, skipNameResolve bool) (string, string, bool) + // MatchUserResourceGroupName matches a user with specified resource group name + MatchUserResourceGroupName(resourceGroupName string) (string, bool) + // DBIsVisible returns true is the database is visible to current user. DBIsVisible(activeRole []*auth.RoleIdentity, db string) bool @@ -91,7 +112,10 @@ type Manager interface { // IsDynamicPrivilege returns if a privilege is in the list of privileges. IsDynamicPrivilege(privNameInUpper string) bool - // Get the authentication plugin for a user + // GetAuthPluginForConnection gets the authentication plugin used in connection establishment. + GetAuthPluginForConnection(user, host string) (string, error) + + // GetAuthPlugin gets the authentication plugin for the account identified by the user and host GetAuthPlugin(user, host string) (string, error) } diff --git a/privilege/privileges/BUILD.bazel b/privilege/privileges/BUILD.bazel index 462e8950e5076..25f85025647ab 100644 --- a/privilege/privileges/BUILD.bazel +++ b/privilege/privileges/BUILD.bazel @@ -6,11 +6,13 @@ go_library( "cache.go", "errors.go", "privileges.go", + "tidb_auth_token.go", ], importpath = "github.com/pingcap/tidb/privilege/privileges", visibility = ["//visibility:public"], deps = [ "//errno", + "//extension", "//infoschema", "//kv", "//parser/ast", @@ -19,6 +21,7 @@ go_library( "//parser/terror", "//privilege", "//sessionctx", + "//sessionctx/sessionstates", "//sessionctx/variable", "//types", "//util", @@ -26,9 +29,14 @@ go_library( "//util/dbterror", "//util/hack", "//util/logutil", + "//util/mathutil", "//util/sem", "//util/sqlexec", "//util/stringutil", + "@com_github_lestrrat_go_jwx_v2//jwk", + "@com_github_lestrrat_go_jwx_v2//jws", + "@com_github_lestrrat_go_jwx_v2//jwt", + "@com_github_lestrrat_go_jwx_v2//jwt/openid", "@com_github_pingcap_errors//:errors", "@org_golang_x_exp//slices", "@org_uber_go_zap//:zap", @@ -42,11 +50,12 @@ go_test( "cache_test.go", "main_test.go", "privileges_test.go", + "tidb_auth_token_test.go", ], + embed = [":privileges"], flaky = True, shard_count = 50, deps = [ - ":privileges", "//config", "//errno", "//executor", @@ -58,13 +67,20 @@ go_test( "//privilege", "//session", "//sessionctx", + "//sessionctx/sessionstates", "//sessionctx/variable", "//testkit", "//testkit/testsetup", "//testkit/testutil", "//util", + "//util/hack", "//util/sem", "//util/sqlexec", + "@com_github_lestrrat_go_jwx_v2//jwa", + "@com_github_lestrrat_go_jwx_v2//jwk", + "@com_github_lestrrat_go_jwx_v2//jws", + "@com_github_lestrrat_go_jwx_v2//jwt", + "@com_github_lestrrat_go_jwx_v2//jwt/openid", "@com_github_stretchr_testify//require", "@org_uber_go_goleak//:goleak", ], diff --git a/privilege/privileges/cache.go b/privilege/privileges/cache.go index 18eea6e7bf7a5..9159777340b67 100644 --- a/privilege/privileges/cache.go +++ b/privilege/privileges/cache.go @@ -66,7 +66,7 @@ const ( References_priv,Alter_priv,Execute_priv,Index_priv,Create_view_priv,Show_view_priv, Create_role_priv,Drop_role_priv,Create_tmp_table_priv,Lock_tables_priv,Create_routine_priv, Alter_routine_priv,Event_priv,Shutdown_priv,Reload_priv,File_priv,Config_priv,Repl_client_priv,Repl_slave_priv, - account_locked,plugin FROM mysql.user` + Account_locked,Plugin,Token_issuer,User_attributes,password_expired,password_last_changed,password_lifetime FROM mysql.user` sqlLoadGlobalGrantsTable = `SELECT HIGH_PRIORITY Host,User,Priv,With_Grant_Option FROM mysql.global_grants` ) @@ -92,14 +92,31 @@ type baseRecord struct { hostIPNet *net.IPNet } +// MetadataInfo is the User_attributes->>"$.metadata". +type MetadataInfo struct { + Email string +} + +// UserAttributesInfo is the 'User_attributes' in privilege cache. +type UserAttributesInfo struct { + MetadataInfo + PasswordLocking +} + // UserRecord is used to represent a user record in privilege cache. type UserRecord struct { baseRecord + UserAttributesInfo AuthenticationString string Privileges mysql.PrivilegeType AccountLocked bool // A role record when this field is true AuthPlugin string + AuthTokenIssuer string + PasswordExpired bool + PasswordLastChanged time.Time + PasswordLifeTime int64 + ResourceGroup string } // NewUserRecord return a UserRecord, only use for unit test. @@ -654,6 +671,61 @@ func (p *MySQLPrivilege) decodeUserTableRow(row chunk.Row, fs []*ast.ResultField } else { value.AuthPlugin = mysql.AuthNativePassword } + case f.ColumnAsName.L == "token_issuer": + value.AuthTokenIssuer = row.GetString(i) + case f.ColumnAsName.L == "user_attributes": + if row.IsNull(i) { + continue + } + bj := row.GetJSON(i) + pathExpr, err := types.ParseJSONPathExpr("$.metadata.email") + if err != nil { + return err + } + if emailBJ, found := bj.Extract([]types.JSONPathExpression{pathExpr}); found { + email, err := emailBJ.Unquote() + if err != nil { + return err + } + value.Email = email + } + pathExpr, err = types.ParseJSONPathExpr("$.resource_group") + if err != nil { + return err + } + if resourceGroup, found := bj.Extract([]types.JSONPathExpression{pathExpr}); found { + resourceGroup, err := resourceGroup.Unquote() + if err != nil { + return err + } + value.ResourceGroup = resourceGroup + } + passwordLocking := PasswordLocking{} + if err := passwordLocking.ParseJSON(bj); err != nil { + return err + } + value.FailedLoginAttempts = passwordLocking.FailedLoginAttempts + value.PasswordLockTimeDays = passwordLocking.PasswordLockTimeDays + value.FailedLoginCount = passwordLocking.FailedLoginCount + value.AutoLockedLastChanged = passwordLocking.AutoLockedLastChanged + value.AutoAccountLocked = passwordLocking.AutoAccountLocked + case f.ColumnAsName.L == "password_expired": + if row.GetEnum(i).String() == "Y" { + value.PasswordExpired = true + } + case f.ColumnAsName.L == "password_last_changed": + t := row.GetTime(i) + gotime, err := t.GoTime(time.Local) + if err != nil { + return err + } + value.PasswordLastChanged = gotime + case f.ColumnAsName.L == "password_lifetime": + if row.IsNull(i) { + value.PasswordLifeTime = -1 + continue + } + value.PasswordLifeTime = row.GetInt64(i) case f.Column.GetType() == mysql.TypeEnum: if row.GetEnum(i).String() != "Y" { continue @@ -942,6 +1014,17 @@ func (p *MySQLPrivilege) matchIdentity(user, host string, skipNameResolve bool) return nil } +// matchResoureGroup finds an identity to match resource group. +func (p *MySQLPrivilege) matchResoureGroup(resourceGroupName string) *UserRecord { + for i := 0; i < len(p.User); i++ { + record := &p.User[i] + if record.ResourceGroup == resourceGroupName { + return record + } + } + return nil +} + // connectionVerification verifies the username + hostname according to exact // match from the mysql.user privilege table. call matchIdentity() first if you // do not have an exact match yet. diff --git a/privilege/privileges/cache_test.go b/privilege/privileges/cache_test.go index 4670e5391f791..0feefaafa6bff 100644 --- a/privilege/privileges/cache_test.go +++ b/privilege/privileges/cache_test.go @@ -17,6 +17,7 @@ package privileges_test import ( "fmt" "testing" + "time" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/mysql" @@ -42,6 +43,9 @@ func TestLoadUserTable(t *testing.T) { tk.MustExec(`INSERT INTO mysql.user (Host, User, authentication_string, Insert_priv) VALUES ("%", "root1", "admin", "Y")`) tk.MustExec(`INSERT INTO mysql.user (Host, User, authentication_string, Update_priv, Show_db_priv, References_priv) VALUES ("%", "root11", "", "Y", "Y", "Y")`) tk.MustExec(`INSERT INTO mysql.user (Host, User, authentication_string, Create_user_priv, Index_priv, Execute_priv, Create_view_priv, Show_view_priv, Show_db_priv, Super_priv, Trigger_priv) VALUES ("%", "root111", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) + tk.MustExec(`INSERT INTO mysql.user (Host, User, user_attributes, token_issuer) VALUES ("%", "root1111", "{\"metadata\": {\"email\": \"user@pingcap.com\"}}", "")`) + tk.MustExec(`INSERT INTO mysql.user (Host, User, password_expired, password_last_changed, password_lifetime) VALUES ("%", "root2", "Y", "2022-10-10 12:00:00", 3)`) + tk.MustExec(`INSERT INTO mysql.user (Host, User, password_expired, password_last_changed) VALUES ("%", "root3", "N", "2022-10-10 12:00:00")`) p = privileges.MySQLPrivilege{} require.NoError(t, p.LoadUserTable(tk.Session())) @@ -53,6 +57,14 @@ func TestLoadUserTable(t *testing.T) { require.Equal(t, mysql.InsertPriv, user[1].Privileges) require.Equal(t, mysql.UpdatePriv|mysql.ShowDBPriv|mysql.ReferencesPriv, user[2].Privileges) require.Equal(t, mysql.CreateUserPriv|mysql.IndexPriv|mysql.ExecutePriv|mysql.CreateViewPriv|mysql.ShowViewPriv|mysql.ShowDBPriv|mysql.SuperPriv|mysql.TriggerPriv, user[3].Privileges) + require.Equal(t, "user@pingcap.com", user[4].Email) + require.Equal(t, "", user[4].AuthTokenIssuer) + require.Equal(t, true, user[5].PasswordExpired) + require.Equal(t, time.Date(2022, 10, 10, 12, 0, 0, 0, time.Local), user[5].PasswordLastChanged) + require.Equal(t, int64(3), user[5].PasswordLifeTime) + require.Equal(t, false, user[6].PasswordExpired) + require.Equal(t, time.Date(2022, 10, 10, 12, 0, 0, 0, time.Local), user[6].PasswordLastChanged) + require.Equal(t, int64(-1), user[6].PasswordLifeTime) } func TestLoadGlobalPrivTable(t *testing.T) { @@ -409,10 +421,14 @@ func TestAbnormalMySQLTable(t *testing.T) { max_user_connections int(11) unsigned NOT NULL DEFAULT '0', plugin char(64) COLLATE utf8_bin DEFAULT 'mysql_native_password', authentication_string text COLLATE utf8_bin, - password_expired enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + token_issuer varchar(255), + user_attributes json, + password_expired ENUM('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + password_last_changed TIMESTAMP DEFAULT CURRENT_TIMESTAMP(), + password_lifetime SMALLINT UNSIGNED, PRIMARY KEY (Host,User) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';`) - tk.MustExec(`INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'mysql_native_password','','N'); + tk.MustExec(`INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'mysql_native_password','', '', 'null', 'N', current_timestamp(), null); `) var p privileges.MySQLPrivilege require.NoError(t, p.LoadUserTable(tk.Session())) diff --git a/privilege/privileges/errors.go b/privilege/privileges/errors.go index 4b9ecd48417ca..8ec5d9401e3c9 100644 --- a/privilege/privileges/errors.go +++ b/privilege/privileges/errors.go @@ -21,9 +21,11 @@ import ( // error definitions. var ( - errInvalidPrivilegeType = dbterror.ClassPrivilege.NewStd(mysql.ErrInvalidPrivilegeType) - ErrNonexistingGrant = dbterror.ClassPrivilege.NewStd(mysql.ErrNonexistingGrant) - errLoadPrivilege = dbterror.ClassPrivilege.NewStd(mysql.ErrLoadPrivilege) - ErrAccessDenied = dbterror.ClassPrivilege.NewStd(mysql.ErrAccessDenied) - errAccountHasBeenLocked = dbterror.ClassPrivilege.NewStd(mysql.ErrAccountHasBeenLocked) + errInvalidPrivilegeType = dbterror.ClassPrivilege.NewStd(mysql.ErrInvalidPrivilegeType) + ErrNonexistingGrant = dbterror.ClassPrivilege.NewStd(mysql.ErrNonexistingGrant) + errLoadPrivilege = dbterror.ClassPrivilege.NewStd(mysql.ErrLoadPrivilege) + ErrAccessDenied = dbterror.ClassPrivilege.NewStd(mysql.ErrAccessDenied) + errAccountHasBeenLocked = dbterror.ClassPrivilege.NewStd(mysql.ErrAccountHasBeenLocked) + ErUserAccessDeniedForUserAccountBlockedByPasswordLock = dbterror.ClassPrivilege.NewStd(mysql.ErUserAccessDeniedForUserAccountBlockedByPasswordLock) + ErrMustChangePasswordLogin = dbterror.ClassPrivilege.NewStd(mysql.ErrMustChangePasswordLogin) ) diff --git a/privilege/privileges/main_test.go b/privilege/privileges/main_test.go index efe96d5784161..f591389958fd5 100644 --- a/privilege/privileges/main_test.go +++ b/privilege/privileges/main_test.go @@ -25,10 +25,12 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("net/http.(*persistConn).writeLoop"), goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), + goleak.IgnoreTopFunction("github.com/pingcap/tidb/privilege/privileges.(*JWKSImpl).LoadJWKS4AuthToken.func1"), } testsetup.SetupForCommonTest() diff --git a/privilege/privileges/privileges.go b/privilege/privileges/privileges.go index 534b31ed77d57..9fc73fc26fab0 100644 --- a/privilege/privileges/privileges.go +++ b/privilege/privileges/privileges.go @@ -19,17 +19,27 @@ import ( "crypto/x509" "errors" "fmt" + "math" + "strconv" "strings" "sync" + "time" + jwtRepo "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/lestrrat-go/jwx/v2/jwt/openid" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/sessionstates" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/sem" "go.uber.org/zap" ) @@ -53,8 +63,10 @@ var dynamicPrivs = []string{ "RESTRICTED_USER_ADMIN", // User can not have their access revoked by SUPER users. "RESTRICTED_CONNECTION_ADMIN", // Can not be killed by PROCESS/CONNECTION_ADMIN privilege "RESTRICTED_REPLICA_WRITER_ADMIN", // Can write to the sever even when tidb_restriced_read_only is turned on. + "RESOURCE_GROUP_ADMIN", // Create/Drop/Alter RESOURCE GROUP } var dynamicPrivLock sync.Mutex +var defaultTokenLife = 15 * time.Minute // UserPrivileges implements privilege.Manager interface. // This is used to check privilege for the current user. @@ -62,6 +74,15 @@ type UserPrivileges struct { user string host string *Handle + extensionAccessCheckFuncs []extension.AccessCheckFunc +} + +// NewUserPrivileges creates a new UserPrivileges +func NewUserPrivileges(handle *Handle, extension *extension.Extensions) *UserPrivileges { + return &UserPrivileges{ + Handle: handle, + extensionAccessCheckFuncs: extension.GetAccessCheckFuncs(), + } } // RequestDynamicVerificationWithUser implements the Manager interface. @@ -122,7 +143,8 @@ func (p *UserPrivileges) RequestVerification(activeRoles []*auth.RoleIdentity, d tblLowerName := strings.ToLower(table) // If SEM is enabled and the user does not have the RESTRICTED_TABLES_ADMIN privilege // There are some hard rules which overwrite system tables and schemas as read-only at most. - if sem.IsEnabled() && !p.RequestDynamicVerification(activeRoles, "RESTRICTED_TABLES_ADMIN", false) { + semEnabled := sem.IsEnabled() + if semEnabled && !p.RequestDynamicVerification(activeRoles, "RESTRICTED_TABLES_ADMIN", false) { if sem.IsInvisibleTable(dbLowerName, tblLowerName) { return false } @@ -152,6 +174,14 @@ func (p *UserPrivileges) RequestVerification(activeRoles []*auth.RoleIdentity, d } } + for _, fn := range p.extensionAccessCheckFuncs { + for _, dynPriv := range fn(db, table, column, priv, semEnabled) { + if !p.RequestDynamicVerification(activeRoles, dynPriv, false) { + return false + } + } + } + mysqlPriv := p.Handle.Get() return mysqlPriv.RequestVerification(activeRoles, p.user, p.host, db, table, column, priv) } @@ -182,31 +212,28 @@ func (p *UserPrivileges) isValidHash(record *UserRecord) bool { if pwd == "" { return true } - if record.AuthPlugin == mysql.AuthNativePassword { + switch record.AuthPlugin { + case mysql.AuthNativePassword: if len(pwd) == mysql.PWDHashLen+1 { return true } logutil.BgLogger().Error("the password from the mysql.user table does not match the definition of a mysql_native_password", zap.String("user", record.User), zap.String("plugin", record.AuthPlugin), zap.Int("hash_length", len(pwd))) return false - } - - if record.AuthPlugin == mysql.AuthCachingSha2Password { + case mysql.AuthCachingSha2Password: if len(pwd) == mysql.SHAPWDHashLen { return true } logutil.BgLogger().Error("the password from the mysql.user table does not match the definition of a caching_sha2_password", zap.String("user", record.User), zap.String("plugin", record.AuthPlugin), zap.Int("hash_length", len(pwd))) return false - } - - if record.AuthPlugin == mysql.AuthTiDBSM3Password { + case mysql.AuthTiDBSM3Password: if len(pwd) == mysql.SM3PWDHashLen { return true } logutil.BgLogger().Error("the password from the mysql.user table does not match the definition of a tidb_sm3_password", zap.String("user", record.User), zap.String("plugin", record.AuthPlugin), zap.Int("hash_length", len(pwd))) return false - } - - if record.AuthPlugin == mysql.AuthSocket { + case mysql.AuthSocket: + return true + case mysql.AuthTiDBAuthToken: return true } @@ -229,8 +256,8 @@ func (p *UserPrivileges) GetEncodedPassword(user, host string) string { return "" } -// GetAuthPlugin gets the authentication plugin for the account identified by the user and host -func (p *UserPrivileges) GetAuthPlugin(user, host string) (string, error) { +// GetAuthPluginForConnection gets the authentication plugin used in connection establishment. +func (p *UserPrivileges) GetAuthPluginForConnection(user, host string) (string, error) { if SkipWithGrant { return mysql.AuthNativePassword, nil } @@ -240,6 +267,9 @@ func (p *UserPrivileges) GetAuthPlugin(user, host string) (string, error) { if record == nil { return "", errors.New("Failed to get user record") } + if record.AuthPlugin == mysql.AuthTiDBAuthToken { + return record.AuthPlugin, nil + } // zero-length auth string means no password for native and caching_sha2 auth. // but for auth_socket it means there should be a 1-to-1 mapping between the TiDB user // and the OS user. @@ -252,6 +282,22 @@ func (p *UserPrivileges) GetAuthPlugin(user, host string) (string, error) { return "", errors.New("Failed to get plugin for user") } +// GetAuthPlugin gets the authentication plugin for the account identified by the user and host +func (p *UserPrivileges) GetAuthPlugin(user, host string) (string, error) { + if SkipWithGrant { + return mysql.AuthNativePassword, nil + } + mysqlPriv := p.Handle.Get() + record := mysqlPriv.connectionVerification(user, host) + if record == nil { + return "", errors.New("Failed to get user record") + } + if !p.isValidHash(record) { + return "", errors.New("Failed to get plugin for user") + } + return record.AuthPlugin, nil +} + // MatchIdentity implements the Manager interface. func (p *UserPrivileges) MatchIdentity(user, host string, skipNameResolve bool) (u string, h string, success bool) { if SkipWithGrant { @@ -265,6 +311,16 @@ func (p *UserPrivileges) MatchIdentity(user, host string, skipNameResolve bool) return "", "", false } +// MatchUserResourceGroupName implements the Manager interface. +func (p *UserPrivileges) MatchUserResourceGroupName(resourceGroupName string) (u string, success bool) { + mysqlPriv := p.Handle.Get() + record := mysqlPriv.matchResoureGroup(resourceGroupName) + if record != nil { + return record.User, true + } + return "", false +} + // GetAuthWithoutVerification implements the Manager interface. func (p *UserPrivileges) GetAuthWithoutVerification(user, host string) (success bool) { if SkipWithGrant { @@ -288,51 +344,244 @@ func (p *UserPrivileges) GetAuthWithoutVerification(user, host string) (success return } +func checkAuthTokenClaims(claims map[string]interface{}, record *UserRecord, tokenLife time.Duration) error { + if sub, ok := claims[jwtRepo.SubjectKey]; !ok { + return errors.New("lack 'sub'") + } else if sub != record.User { + return fmt.Errorf("Wrong 'sub': %s", sub) + } + + if email, ok := claims[openid.EmailKey]; !ok { + return errors.New("lack 'email'") + } else if email != record.Email { + return fmt.Errorf("Wrong 'email': %s", email) + } + + now := time.Now() + val, ok := claims[jwtRepo.IssuedAtKey] + if !ok { + return errors.New("lack 'iat'") + } else if iat, ok := val.(time.Time); !ok { + return fmt.Errorf("iat: %v is not a value of time.Time", val) + } else if now.After(iat.Add(tokenLife)) { + return errors.New("the token has been out of its life time") + } else if now.Before(iat) { + return errors.New("the token is issued at a future time") + } + + if val, ok = claims[jwtRepo.ExpirationKey]; !ok { + return errors.New("lack 'exp'") + } else if exp, ok := val.(time.Time); !ok { + return fmt.Errorf("exp: %v is not a value of time.Time", val) + } else if now.After(exp) { + return errors.New("the token has been expired") + } + + // `iss` is not required if `token_issuer` is empty in `mysql.user` + if iss, ok := claims[jwtRepo.IssuerKey]; ok && iss != record.AuthTokenIssuer { + return fmt.Errorf("Wrong 'iss': %s", iss) + } else if !ok && len(record.AuthTokenIssuer) > 0 { + return errors.New("lack 'iss'") + } + + return nil +} + +// CheckPasswordExpired checks whether the password has been expired. +func (*UserPrivileges) CheckPasswordExpired(sessionVars *variable.SessionVars, record *UserRecord) (bool, error) { + isSandBoxModeEnabled := variable.IsSandBoxModeEnabled.Load() + if record.PasswordExpired { + if isSandBoxModeEnabled { + return true, nil + } + return false, ErrMustChangePasswordLogin.GenWithStackByArgs() + } + if record.PasswordLifeTime != 0 { + lifeTime := record.PasswordLifeTime + if lifeTime == -1 { + pwdLifeTimeStr, err := sessionVars.GlobalVarsAccessor.GetGlobalSysVar(variable.DefaultPasswordLifetime) + if err != nil { + return false, err + } + lifeTime, err = strconv.ParseInt(pwdLifeTimeStr, 10, 64) + if err != nil { + return false, err + } + } + if lifeTime > 0 && record.PasswordLastChanged.AddDate(0, 0, int(lifeTime)).Before(time.Now()) { + if isSandBoxModeEnabled { + return true, nil + } + return false, ErrMustChangePasswordLogin.GenWithStackByArgs() + } + } + return false, nil +} + +// GenerateAccountAutoLockErr implements the Manager interface. +func GenerateAccountAutoLockErr(failedLoginAttempts int64, + user, host, lockTime, remainTime string) error { + logutil.BgLogger().Error(fmt.Sprintf("Access denied for user '%s'@'%s'."+ + " Account is blocked for %s day(s) (%s day(s) remaining) due to %d "+ + "consecutive failed logins.", user, host, lockTime, + remainTime, failedLoginAttempts)) + return ErUserAccessDeniedForUserAccountBlockedByPasswordLock.FastGenByArgs(user, host, + lockTime, remainTime, failedLoginAttempts) +} + +// VerifyAccountAutoLockInMemory implements the Manager interface. +func (p *UserPrivileges) VerifyAccountAutoLockInMemory(user string, host string) (bool, error) { + mysqlPriv := p.Handle.Get() + record := mysqlPriv.matchUser(user, host) + if record == nil { + logutil.BgLogger().Error("get authUser privilege record fail", + zap.String("authUser", user), zap.String("authHost", host)) + return false, ErrAccessDenied.FastGenByArgs(user, host) + } + + if record.AutoAccountLocked { + // If it is locked, need to check whether it can be automatically unlocked. + lockTime := record.PasswordLockTimeDays + if lockTime == -1 { + return record.AutoAccountLocked, GenerateAccountAutoLockErr(record.FailedLoginAttempts, user, host, "unlimited", "unlimited") + } + lastChanged := record.AutoLockedLastChanged + d := time.Now().Unix() - lastChanged + if d > lockTime*24*60*60 { + return record.AutoAccountLocked, nil + } + lds := strconv.FormatInt(lockTime, 10) + rds := strconv.FormatInt(int64(math.Ceil(float64(lockTime)-float64(d)/(24*60*60))), 10) + return record.AutoAccountLocked, GenerateAccountAutoLockErr(record.FailedLoginAttempts, user, host, lds, rds) + } + return record.AutoAccountLocked, nil +} + +// IsAccountAutoLockEnabled implements the Manager interface. +func (p *UserPrivileges) IsAccountAutoLockEnabled(user string, host string) bool { + // If the service is started using skip-grant-tables, the system ignores whether + // to enable the automatic account locking feature after continuous login failure. + if SkipWithGrant { + p.user = user + p.host = host + return false + } + mysqlPriv := p.Handle.Get() + record := mysqlPriv.matchUser(user, host) + if record == nil { + return false + } + // For failed-login tracking and temporary locking to occur, an account's FAILED_LOGIN_ATTEMPTS + // and PASSWORD_LOCK_TIME options both must be nonzero. + // https://dev.mysql.com/doc/refman/8.0/en/create-user.html + if record.FailedLoginAttempts == 0 || record.PasswordLockTimeDays == 0 { + return false + } + return true +} + +// BuildSuccessPasswordLockingJSON builds success PasswordLocking JSON string. +func BuildSuccessPasswordLockingJSON(failedLoginAttempts, passwordLockTimeDays int64) string { + return BuildPasswordLockingJSON(failedLoginAttempts, passwordLockTimeDays, "N", 0, time.Now().Format(time.UnixDate)) +} + +// BuildPasswordLockingJSON builds PasswordLocking JSON string. +func BuildPasswordLockingJSON(failedLoginAttempts int64, + passwordLockTimeDays int64, autoAccountLocked string, failedLoginCount int64, autoLockedLastChanged string) string { + var passwordLockingArray []string + passwordLockingArray = append(passwordLockingArray, fmt.Sprintf("\"failed_login_count\": %d", failedLoginCount)) + passwordLockingArray = append(passwordLockingArray, fmt.Sprintf("\"failed_login_attempts\": %d", failedLoginAttempts)) + passwordLockingArray = append(passwordLockingArray, fmt.Sprintf("\"password_lock_time_days\": %d", passwordLockTimeDays)) + if autoAccountLocked != "" { + passwordLockingArray = append(passwordLockingArray, fmt.Sprintf("\"auto_account_locked\": \"%s\"", autoAccountLocked)) + } + if autoLockedLastChanged != "" { + passwordLockingArray = append(passwordLockingArray, fmt.Sprintf("\"auto_locked_last_changed\": \"%s\"", autoLockedLastChanged)) + } + + newAttributesStr := fmt.Sprintf("{\"Password_locking\": {%s}}", strings.Join(passwordLockingArray, ",")) + return newAttributesStr +} + // ConnectionVerification implements the Manager interface. -func (p *UserPrivileges) ConnectionVerification(user *auth.UserIdentity, authUser, authHost string, authentication, salt []byte, tlsState *tls.ConnectionState) error { +func (p *UserPrivileges) ConnectionVerification(user *auth.UserIdentity, authUser, authHost string, authentication, salt []byte, sessionVars *variable.SessionVars) (info privilege.VerificationInfo, err error) { hasPassword := "YES" if len(authentication) == 0 { hasPassword = "NO" } + + mysqlPriv := p.Handle.Get() + record := mysqlPriv.connectionVerification(authUser, authHost) + if SkipWithGrant { p.user = authUser p.host = authHost - return nil + // special handling to existing users or root user initialized with insecure + if record == nil || record.ResourceGroup == "" { + info.ResourceGroupName = "default" + } else { + info.ResourceGroupName = record.ResourceGroup + } + return } - mysqlPriv := p.Handle.Get() - record := mysqlPriv.connectionVerification(authUser, authHost) if record == nil { logutil.BgLogger().Error("get authUser privilege record fail", zap.String("authUser", authUser), zap.String("authHost", authHost)) - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } globalPriv := mysqlPriv.matchGlobalPriv(authUser, authHost) if globalPriv != nil { - if !p.checkSSL(globalPriv, tlsState) { + if !p.checkSSL(globalPriv, sessionVars.TLSConnectionState) { logutil.BgLogger().Error("global priv check ssl fail", zap.String("authUser", authUser), zap.String("authHost", authHost)) - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } } pwd := record.AuthenticationString if !p.isValidHash(record) { - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } - if len(pwd) > 0 && len(authentication) > 0 { + // If the user uses session token to log in, skip checking record.AuthPlugin. + if user.AuthPlugin == mysql.AuthTiDBSessionToken { + if err = sessionstates.ValidateSessionToken(authentication, user.Username); err != nil { + logutil.BgLogger().Warn("verify session token failed", zap.String("username", user.Username), zap.Error(err)) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + } + } else if record.AuthPlugin == mysql.AuthTiDBAuthToken { + if len(authentication) == 0 { + logutil.BgLogger().Error("empty authentication") + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + } + tokenString := string(hack.String(authentication[:len(authentication)-1])) + var ( + claims map[string]interface{} + ) + if claims, err = GlobalJWKS.checkSigWithRetry(tokenString, 1); err != nil { + logutil.BgLogger().Error("verify JWT failed", zap.Error(err)) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + } + if err = checkAuthTokenClaims(claims, record, defaultTokenLife); err != nil { + logutil.BgLogger().Error("check claims failed", zap.Error(err)) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + } + } else if len(pwd) > 0 && len(authentication) > 0 { switch record.AuthPlugin { + // NOTE: If the checking of the clear-text password fails, please set `info.FailedDueToWrongPassword = true`. case mysql.AuthNativePassword: hpwd, err := auth.DecodePassword(pwd) if err != nil { logutil.BgLogger().Error("decode password string failed", zap.Error(err)) - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + info.FailedDueToWrongPassword = true + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } if !auth.CheckScrambledPassword(salt, hpwd, authentication) { - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + info.FailedDueToWrongPassword = true + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } case mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password: authok, err := auth.CheckHashingPassword([]byte(pwd), string(authentication), record.AuthPlugin) @@ -341,22 +590,24 @@ func (p *UserPrivileges) ConnectionVerification(user *auth.UserIdentity, authUse } if !authok { - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + info.FailedDueToWrongPassword = true + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } case mysql.AuthSocket: if string(authentication) != authUser && string(authentication) != pwd { logutil.BgLogger().Error("Failed socket auth", zap.String("authUser", authUser), zap.String("socket_user", string(authentication)), zap.String("authentication_string", pwd)) - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } default: logutil.BgLogger().Error("unknown authentication plugin", zap.String("authUser", authUser), zap.String("plugin", record.AuthPlugin)) - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } } else if len(pwd) > 0 || len(authentication) > 0 { if record.AuthPlugin != mysql.AuthSocket { - return ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) + info.FailedDueToWrongPassword = true + return info, ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } } @@ -364,12 +615,27 @@ func (p *UserPrivileges) ConnectionVerification(user *auth.UserIdentity, authUse locked := record.AccountLocked if locked { logutil.BgLogger().Error(fmt.Sprintf("Access denied for authUser '%s'@'%s'. Account is locked.", authUser, authHost)) - return errAccountHasBeenLocked.FastGenByArgs(user.Username, user.Hostname) + return info, errAccountHasBeenLocked.FastGenByArgs(user.Username, user.Hostname) + } + + // special handling to existing users or root user initialized with insecure + if record.ResourceGroup == "" { + info.ResourceGroupName = "default" + } else { + info.ResourceGroupName = record.ResourceGroup + } + // Skip checking password expiration if the session is migrated from another session. + // Otherwise, the user cannot log in or execute statements after migration. + if user.AuthPlugin != mysql.AuthTiDBSessionToken { + info.InSandBoxMode, err = p.CheckPasswordExpired(sessionVars, record) } + return +} +// AuthSuccess is to make the permission take effect. +func (p *UserPrivileges) AuthSuccess(authUser, authHost string) { p.user = authUser - p.host = record.Host - return nil + p.host = authHost } type checkResult int @@ -639,6 +905,10 @@ func (p *UserPrivileges) IsDynamicPrivilege(privName string) bool { // RegisterDynamicPrivilege is used by plugins to add new privileges to TiDB func RegisterDynamicPrivilege(privName string) error { + if len(privName) == 0 { + return errors.New("privilege name should not be empty") + } + privNameInUpper := strings.ToUpper(privName) if len(privNameInUpper) > 32 { return errors.New("privilege name is longer than 32 characters") @@ -664,3 +934,119 @@ func GetDynamicPrivileges() []string { copy(privCopy, dynamicPrivs) return privCopy } + +// RemoveDynamicPrivilege is used for test only +func RemoveDynamicPrivilege(privName string) bool { + privNameInUpper := strings.ToUpper(privName) + dynamicPrivLock.Lock() + defer dynamicPrivLock.Unlock() + for idx, priv := range dynamicPrivs { + if privNameInUpper == priv { + dynamicPrivs = append(dynamicPrivs[:idx], dynamicPrivs[idx+1:]...) + return true + } + } + return false +} + +func init() { + extension.RegisterDynamicPrivilege = RegisterDynamicPrivilege + extension.RemoveDynamicPrivilege = RemoveDynamicPrivilege +} + +// PasswordLocking is the User_attributes->>"$.Password_locking". +// It records information about failed-login tracking and temporary account locking. +type PasswordLocking struct { + FailedLoginCount int64 + PasswordLockTimeDays int64 + AutoAccountLocked bool + AutoLockedLastChanged int64 + FailedLoginAttempts int64 +} + +// ParseJSON parses information about PasswordLocking. +func (passwordLocking *PasswordLocking) ParseJSON(passwordLockingJSON types.BinaryJSON) error { + var err error + + passwordLocking.FailedLoginAttempts, err = + extractInt64FromJSON(passwordLockingJSON, "$.Password_locking.failed_login_attempts") + if err != nil { + return err + } + passwordLocking.FailedLoginAttempts = mathutil.Min(passwordLocking.FailedLoginAttempts, math.MaxInt16) + passwordLocking.FailedLoginAttempts = mathutil.Max(passwordLocking.FailedLoginAttempts, 0) + + passwordLocking.PasswordLockTimeDays, err = + extractInt64FromJSON(passwordLockingJSON, "$.Password_locking.password_lock_time_days") + if err != nil { + return err + } + passwordLocking.PasswordLockTimeDays = mathutil.Min(passwordLocking.PasswordLockTimeDays, math.MaxInt16) + passwordLocking.PasswordLockTimeDays = mathutil.Max(passwordLocking.PasswordLockTimeDays, -1) + + passwordLocking.FailedLoginCount, err = + extractInt64FromJSON(passwordLockingJSON, "$.Password_locking.failed_login_count") + if err != nil { + return err + } + + passwordLocking.AutoLockedLastChanged, err = + extractTimeUnixFromJSON(passwordLockingJSON, "$.Password_locking.auto_locked_last_changed") + if err != nil { + return err + } + + passwordLocking.AutoAccountLocked, err = + extractBoolFromJSON(passwordLockingJSON, "$.Password_locking.auto_account_locked") + if err != nil { + return err + } + return nil +} + +func extractInt64FromJSON(json types.BinaryJSON, pathExpr string) (val int64, err error) { + jsonPath, err := types.ParseJSONPathExpr(pathExpr) + if err != nil { + return 0, err + } + if BJ, found := json.Extract([]types.JSONPathExpression{jsonPath}); found { + return BJ.GetInt64(), nil + } + return 0, nil +} + +func extractTimeUnixFromJSON(json types.BinaryJSON, pathExpr string) (int64, error) { + jsonPath, err := types.ParseJSONPathExpr(pathExpr) + if err != nil { + return -1, err + } + if BJ, found := json.Extract([]types.JSONPathExpression{jsonPath}); found { + value, err := BJ.Unquote() + if err != nil { + return -1, err + } + t, err := time.ParseInLocation(time.UnixDate, value, time.Local) + if err != nil { + return -1, err + } + return t.Unix(), nil + } + return 0, nil +} + +func extractBoolFromJSON(json types.BinaryJSON, pathExpr string) (bool, error) { + jsonPath, err := types.ParseJSONPathExpr(pathExpr) + if err != nil { + return false, err + } + if BJ, found := json.Extract([]types.JSONPathExpression{jsonPath}); found { + value, err := BJ.Unquote() + if err != nil { + return false, err + } + if value == "Y" { + return true, nil + } + } + return false, nil +} diff --git a/privilege/privileges/privileges_test.go b/privilege/privileges/privileges_test.go index 210e524385e16..9c0cfa2f84dd2 100644 --- a/privilege/privileges/privileges_test.go +++ b/privilege/privileges/privileges_test.go @@ -20,11 +20,14 @@ import ( "crypto/tls" "crypto/x509" "crypto/x509/pkix" + "encoding/json" "fmt" "net/url" "os" + "path/filepath" "strings" "testing" + "time" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/errno" @@ -38,6 +41,7 @@ import ( "github.com/pingcap/tidb/privilege/privileges" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/sessionstates" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/testutil" @@ -514,6 +518,14 @@ func TestAlterUserStmt(t *testing.T) { tk.MustExec("GRANT RESTRICTED_USER_ADMIN ON *.* TO semuser1, semuser2, semuser3") tk.MustExec("GRANT SYSTEM_USER ON *.* to semuser3") // user is both restricted + has SYSTEM_USER (or super) + tk.MustExec("set global tidb_enable_resource_control = 'on'") + tk.MustExec("CREATE RESOURCE GROUP rg1 rru_per_sec=1000 wru_per_sec=2000") + tk.MustExec(`ALTER USER 'semuser1' RESOURCE GROUP rg1`) + tk.MustQuery(`SELECT User_attributes FROM mysql.user WHERE User = "semuser1"`).Check(testkit.Rows("{\"resource_group\": \"rg1\"}")) + + tk.MustExec(`ALTER USER 'semuser1' COMMENT 'comment1'`) + tk.MustQuery(`SELECT User_attributes FROM mysql.user WHERE User = "semuser1"`).Check(testkit.Rows("{\"metadata\": {\"comment\": \"comment1\"}, \"resource_group\": \"rg1\"}")) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "superuser2", Hostname: "localhost"}, nil, nil)) tk.MustExec("ALTER USER 'nobodyuser2' IDENTIFIED BY 'newpassword'") tk.MustExec("ALTER USER 'nobodyuser2' IDENTIFIED BY ''") @@ -1123,6 +1135,16 @@ func TestCreateDropUser(t *testing.T) { tk.MustExec(`SET ROLE tcd2;`) tk.MustExec(`CREATE USER tcd3`) tk.MustExec(`DROP USER tcd3`) + + tk.MustExec(`CREATE USER usr1`) + tk.MustQuery(`SELECT User_attributes FROM mysql.user WHERE User = "usr1"`).Check(testkit.Rows("{\"resource_group\": \"default\"}")) + tk.MustExec(`DROP USER usr1`) + + tk.MustExec("set global tidb_enable_resource_control = 'on'") + tk.MustExec("CREATE RESOURCE GROUP rg1 rru_per_sec=1000 wru_per_sec=2000") + tk.MustExec(`CREATE USER usr1 RESOURCE GROUP rg1`) + tk.MustQuery(`SELECT User_attributes FROM mysql.user WHERE User = "usr1"`).Check(testkit.Rows("{\"resource_group\": \"rg1\"}")) + tk.MustExec(`DROP USER usr1`) } func TestConfigPrivilege(t *testing.T) { @@ -2554,6 +2576,46 @@ func TestPlacementPolicyStmt(t *testing.T) { tk.MustExec(dropStmt) } +func TestResourceGroupAdminDynamicPriv(t *testing.T) { + store := createStoreAndPrepareDB(t) + + tk1 := testkit.NewTestKit(t, store) + // tk1 is the root user, create a new user for test. + tk1.Session().Auth(&auth.UserIdentity{ + Username: "root", + Hostname: "localhost", + }, nil, nil) + tk1.MustExec("CREATE USER resource_group_user") + tk1.MustExec("set @@global.tidb_enable_resource_control = 1") + + // tk2 is the new user. + tk2 := testkit.NewTestKit(t, store) + tk2.Session().Auth(&auth.UserIdentity{ + Username: "resource_group_user", + Hostname: "localhost", + }, nil, nil) + err := tk2.ExecToErr("CREATE RESOURCE GROUP test RRU_PER_SEC = 666") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or RESOURCE_GROUP_ADMIN privilege(s) for this operation") + + // grant the RESOURCE_GROUP_ADMIN dynamic privilege to the user. + tk1.MustExec("GRANT RESOURCE_GROUP_ADMIN ON *.* TO resource_group_user") + tk1.MustQuery("SHOW GRANTS FOR resource_group_user").Check(testkit.Rows( + `GRANT USAGE ON *.* TO 'resource_group_user'@'%'`, + `GRANT RESOURCE_GROUP_ADMIN ON *.* TO 'resource_group_user'@'%'`)) + + tk2.MustExec("CREATE RESOURCE GROUP test RRU_PER_SEC = 666") + tk2.MustExec("CREATE RESOURCE GROUP test2 WRU_PER_SEC = 999") + + tk2.MustExec("ALTER RESOURCE GROUP test2 WRU_PER_SEC = 1000") + tk2.MustExec("DROP RESOURCE GROUP test2") + + tk1.MustExec("REVOKE RESOURCE_GROUP_ADMIN ON *.* FROM resource_group_user") + err = tk2.ExecToErr("ALTER RESOURCE GROUP test RRU_PER_SEC = 667") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or RESOURCE_GROUP_ADMIN privilege(s) for this operation") + err = tk2.ExecToErr("DROP RESOURCE GROUP test") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or RESOURCE_GROUP_ADMIN privilege(s) for this operation") +} + func TestDBNameCaseSensitivityInTableLevel(t *testing.T) { store := createStoreAndPrepareDB(t) tk := testkit.NewTestKit(t, store) @@ -2963,3 +3025,183 @@ func TestIssue37488(t *testing.T) { tk.MustQuery("select current_user()").Check(testkit.Rows("dba_test@192.168.%")) tk.MustExec("DROP TABLE IF EXISTS a;") // succ } + +func TestCheckPasswordExpired(t *testing.T) { + sessionVars := variable.NewSessionVars(nil) + sessionVars.GlobalVarsAccessor = variable.NewMockGlobalAccessor4Tests() + record := privileges.NewUserRecord("%", "root") + userPrivilege := privileges.NewUserPrivileges(privileges.NewHandle(), nil) + + record.PasswordExpired = true + _, err := userPrivilege.CheckPasswordExpired(sessionVars, &record) + require.ErrorContains(t, err, "Your password has expired. To log in you must change it using a client that supports expired passwords") + + record.PasswordExpired = false + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.DefaultPasswordLifetime, "2") + require.NoError(t, err) + // use default_password_lifetime + record.PasswordLifeTime = -1 + record.PasswordLastChanged = time.Now().AddDate(0, 0, -2) + time.Sleep(time.Second) + _, err = userPrivilege.CheckPasswordExpired(sessionVars, &record) + require.ErrorContains(t, err, "Your password has expired. To log in you must change it using a client that supports expired passwords") + record.PasswordLastChanged = time.Now().AddDate(0, 0, -1) + _, err = userPrivilege.CheckPasswordExpired(sessionVars, &record) + require.NoError(t, err) + + // never expire + record.PasswordLifeTime = 0 + record.PasswordLastChanged = time.Now().AddDate(0, 0, -10) + _, err = userPrivilege.CheckPasswordExpired(sessionVars, &record) + require.NoError(t, err) + + // expire with the specified time + record.PasswordLifeTime = 3 + record.PasswordLastChanged = time.Now().AddDate(0, 0, -3) + time.Sleep(time.Second) + _, err = userPrivilege.CheckPasswordExpired(sessionVars, &record) + require.ErrorContains(t, err, "Your password has expired. To log in you must change it using a client that supports expired passwords") + record.PasswordLastChanged = time.Now().AddDate(0, 0, -2) + _, err = userPrivilege.CheckPasswordExpired(sessionVars, &record) + require.NoError(t, err) +} + +func TestPasswordExpireWithoutSandBoxMode(t *testing.T) { + store := createStoreAndPrepareDB(t) + rootTk := testkit.NewTestKit(t, store) + rootTk.MustExec(`CREATE USER 'testuser'@'localhost' PASSWORD EXPIRE`) + + // PASSWORD EXPIRE + user := &auth.UserIdentity{Username: "testuser", Hostname: "localhost"} + tk := testkit.NewTestKit(t, store) + err := tk.Session().Auth(user, nil, nil) + require.ErrorContains(t, err, "Your password has expired") + + // PASSWORD EXPIRE NEVER + rootTk.MustExec(`ALTER USER 'testuser'@'localhost' IDENTIFIED BY '' PASSWORD EXPIRE NEVER`) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + + // PASSWORD EXPIRE INTERVAL N DAY + rootTk.MustExec(`ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE INTERVAL 2 DAY`) + rootTk.MustExec(`UPDATE mysql.user SET password_last_changed = (now() - INTERVAL 1 DAY) where user='testuser'`) + rootTk.MustExec(`FLUSH PRIVILEGES`) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + rootTk.MustExec(`UPDATE mysql.user SET password_last_changed = (now() - INTERVAL 2 DAY) where user='testuser'`) + rootTk.MustExec(`FLUSH PRIVILEGES`) + time.Sleep(2 * time.Second) + err = tk.Session().Auth(user, nil, nil) + require.ErrorContains(t, err, "Your password has expired") + + // PASSWORD EXPIRE DEFAULT + rootTk.MustExec(`ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE DEFAULT`) + rootTk.MustExec(`SET GLOBAL default_password_lifetime = 2`) + err = tk.Session().Auth(user, nil, nil) + require.ErrorContains(t, err, "Your password has expired") + rootTk.MustExec(`SET GLOBAL default_password_lifetime = 3`) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) +} + +func TestPasswordExpireWithSandBoxMode(t *testing.T) { + store := createStoreAndPrepareDB(t) + rootTk := testkit.NewTestKit(t, store) + rootTk.MustExec(`CREATE USER 'testuser'@'localhost' PASSWORD EXPIRE`) + variable.IsSandBoxModeEnabled.Store(true) + + // PASSWORD EXPIRE + user := &auth.UserIdentity{Username: "testuser", Hostname: "localhost"} + tk := testkit.NewTestKit(t, store) + err := tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + require.True(t, tk.Session().InSandBoxMode()) + tk.Session().DisableSandBoxMode() + + // PASSWORD EXPIRE NEVER + rootTk.MustExec(`ALTER USER 'testuser'@'localhost' IDENTIFIED BY '' PASSWORD EXPIRE NEVER`) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + require.False(t, tk.Session().InSandBoxMode()) + + // PASSWORD EXPIRE INTERVAL N DAY + rootTk.MustExec(`ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE INTERVAL 2 DAY`) + rootTk.MustExec(`UPDATE mysql.user SET password_last_changed = (now() - INTERVAL 1 DAY) where user='testuser'`) + rootTk.MustExec(`FLUSH PRIVILEGES`) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + require.False(t, tk.Session().InSandBoxMode()) + rootTk.MustExec(`UPDATE mysql.user SET password_last_changed = (now() - INTERVAL 2 DAY) where user='testuser'`) + rootTk.MustExec(`FLUSH PRIVILEGES`) + time.Sleep(2 * time.Second) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + require.True(t, tk.Session().InSandBoxMode()) + tk.Session().DisableSandBoxMode() + + // PASSWORD EXPIRE DEFAULT + rootTk.MustExec(`ALTER USER 'testuser'@'localhost' PASSWORD EXPIRE DEFAULT`) + rootTk.MustExec(`SET GLOBAL default_password_lifetime = 2`) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + require.True(t, tk.Session().InSandBoxMode()) + tk.Session().DisableSandBoxMode() + rootTk.MustExec(`SET GLOBAL default_password_lifetime = 3`) + err = tk.Session().Auth(user, nil, nil) + require.NoError(t, err) + require.False(t, tk.Session().InSandBoxMode()) +} + +func TestVerificationInfoWithSessionTokenPlugin(t *testing.T) { + // prepare signing certs + tempDir := t.TempDir() + certPath := filepath.Join(tempDir, "test1_cert.pem") + keyPath := filepath.Join(tempDir, "test1_key.pem") + err := util.CreateCertificates(certPath, keyPath, 4096, x509.RSA, x509.UnknownSignatureAlgorithm) + require.NoError(t, err) + sessionstates.SetKeyPath(keyPath) + sessionstates.SetCertPath(certPath) + + // prepare user + store := createStoreAndPrepareDB(t) + rootTk := testkit.NewTestKit(t, store) + rootTk.MustExec(`CREATE USER 'testuser'@'localhost' PASSWORD EXPIRE`) + // prepare session token + token, err := sessionstates.CreateSessionToken("testuser") + require.NoError(t, err) + tokenBytes, err := json.Marshal(token) + require.NoError(t, err) + + // Test password expiration without sandbox. + user := &auth.UserIdentity{Username: "testuser", Hostname: "localhost", AuthPlugin: mysql.AuthTiDBSessionToken} + tk := testkit.NewTestKit(t, store) + err = tk.Session().Auth(user, tokenBytes, nil) + require.NoError(t, err) + require.False(t, tk.Session().InSandBoxMode()) + + // Test password expiration with sandbox. + variable.IsSandBoxModeEnabled.Store(true) + err = tk.Session().Auth(user, tokenBytes, nil) + require.NoError(t, err) + require.False(t, tk.Session().InSandBoxMode()) + + // Disable resource group. + require.Equal(t, "", tk.Session().GetSessionVars().ResourceGroupName) + + // Enable resource group. + variable.EnableResourceControl.Store(true) + err = tk.Session().Auth(user, tokenBytes, nil) + require.NoError(t, err) + require.Equal(t, "default", tk.Session().GetSessionVars().ResourceGroupName) + + // Non-default resource group. + rootTk.MustExec("CREATE RESOURCE GROUP rg1 WRU_PER_SEC = 999") + rootTk.MustExec(`ALTER USER 'testuser'@'localhost' RESOURCE GROUP rg1`) + err = tk.Session().Auth(user, tokenBytes, nil) + require.NoError(t, err) + require.Equal(t, "rg1", tk.Session().GetSessionVars().ResourceGroupName) + + // Wrong token + err = tk.Session().Auth(user, nil, nil) + require.ErrorContains(t, err, "Access denied") +} diff --git a/privilege/privileges/tidb_auth_token.go b/privilege/privileges/tidb_auth_token.go new file mode 100644 index 0000000000000..db15f469f841c --- /dev/null +++ b/privilege/privileges/tidb_auth_token.go @@ -0,0 +1,117 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package privileges + +import ( + "context" + "encoding/json" + "strings" + "sync" + "sync/atomic" + "time" + "unsafe" + + jwkRepo "github.com/lestrrat-go/jwx/v2/jwk" + jwsRepo "github.com/lestrrat-go/jwx/v2/jws" + jwtRepo "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/pingcap/errors" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" +) + +// JWKSImpl contains a JSON Web Key Set (JWKS), and a filepath that stores the JWKS +type JWKSImpl struct { + set unsafe.Pointer // *jwkRepo.Set + filepath string +} + +// GlobalJWKS is the global JWKS for tidb-server +var GlobalJWKS JWKSImpl + +func (jwks *JWKSImpl) load() error { + cur, err := jwkRepo.ReadFile(jwks.filepath) + if err == nil { + atomic.StorePointer(&jwks.set, unsafe.Pointer(&cur)) + } + return err +} + +func (jwks *JWKSImpl) verify(tokenBytes []byte) (payload []byte, err error) { + s := (*jwkRepo.Set)(atomic.LoadPointer(&jwks.set)) + if s == nil { + return nil, errors.New("No valid JWKS yet") + } + return jwsRepo.Verify(tokenBytes, jwsRepo.WithKeySet(*s)) +} + +// LoadJWKS4AuthToken reload the jwks every auth-token-refresh-interval. +func (jwks *JWKSImpl) LoadJWKS4AuthToken(ctx context.Context, wg *sync.WaitGroup, jwksPath string, interval time.Duration) error { + jwks.filepath = jwksPath + if ctx != nil && wg != nil { + go func() { + ticker := time.Tick(interval) + wg.Add(1) + for { + select { + case <-ctx.Done(): + wg.Done() + return + case <-ticker: + } + if err := jwks.load(); err != nil { + logutil.BgLogger().Error("Fail to load JWKS", zap.String("path", jwksPath), zap.Duration("interval", interval)) + } + } + }() + } + return jwks.load() +} + +// checkSigWithRetry verifies the signature in the jwt, and returns the claims. +func (jwks *JWKSImpl) checkSigWithRetry(tokenString string, retryTime int) (map[string]interface{}, error) { + var ( + verifiedPayload []byte + err error + ) + parts := strings.Split(tokenString, ".") + if len(parts) != 3 { + err = errors.New("Invalid JWT") + return nil, err + } + for retryTime >= 0 { + retryTime-- + + // verify signature + verifiedPayload, err = jwks.verify(([]byte)(tokenString)) + if err != nil { + if err1 := jwks.load(); err1 != nil { + return nil, err1 + } + continue + } + + jwt := jwtRepo.New() + if err = jwt.(json.Unmarshaler).UnmarshalJSON(verifiedPayload); err != nil { + continue + } + claims, err := jwt.AsMap(context.Background()) + if err != nil { + continue + } + return claims, nil + } + err = errors.Annotate(err, "Retry time has been spent out") + return nil, err +} diff --git a/privilege/privileges/tidb_auth_token_test.go b/privilege/privileges/tidb_auth_token_test.go new file mode 100644 index 0000000000000..4e036f00995d0 --- /dev/null +++ b/privilege/privileges/tidb_auth_token_test.go @@ -0,0 +1,414 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package privileges + +import ( + "crypto/rsa" + "encoding/json" + "fmt" + "log" + "os" + "strings" + "testing" + "time" + + jwaRepo "github.com/lestrrat-go/jwx/v2/jwa" + jwkRepo "github.com/lestrrat-go/jwx/v2/jwk" + jwsRepo "github.com/lestrrat-go/jwx/v2/jws" + jwtRepo "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/lestrrat-go/jwx/v2/jwt/openid" + "github.com/pingcap/tidb/util/hack" + "github.com/stretchr/testify/require" +) + +var ( + privateKeyStrings = []string{`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAq8G5n9XBidxmBMVJKLOBsmdOHrCqGf17y9+VUXingwDUZxRp +2XbuLZLbJtLgcln1lC0L9BsogrWf7+pDhAzWovO6Ai4Aybu00tJ2u0g4j1aLiDds +y0gyvSb5FBoL08jFIH7t/JzMt4JpF487AjzvITwZZcnsrB9a9sdn2E5B/aZmpDGi +2+Isf5osnlw0zvveTwiMo9ba416VIzjntAVEvqMFHK7vyHqXbfqUPAyhjLO+iee9 +9Tg5AlGfjo1s6FjeML4xX7sAMGEy8FVBWNfpRU7ryTWoSn2adzyA/FVmtBvJNQBC +MrrAhXDTMJ5FNi8zHhvzyBKHU0kBTS1UNUbP9wIDAQABAoIBAFF0sbz82imwje2L +RvP3lfXvClyBulpTHigFJEKcLw1xEkrEoqKQxcp1UFvsPKfexBn+9yFQ0/iRfIWC +m3x/vjdP0ZKBELybudkWGVsemDxadhgm+QC7f9y3I/+FjsBlAiA0MlfQYUJSpdaX +hgu8rEgdwYnFpunGgRRyY2xxSNirEAzA6aTa1PkNU6W7nF5trOUOfdUSNZuPsS4y +rQjZJZDxB4SW+biuTqNAOKPPnnFY3PdntQx9uhcSm+qiDP2yQXoXuDK/TAN4euOK +vR5POnnDNKhFizGnR8xjW8GSmfg9ILxw/BpNFoIkvZo5xLtt7lNM2VPJaLzXEse2 +axOpKckCgYEA2g8GWQOmqH8M4LaOxZcy+4dvoOou4vv+V5Bn4TDtmRaQd40BqfOZ +jyi9sci7iGYVsHdSpLlLFcXedx97QKstJZZ8RKQZv/wBZ7JH6Hn80ipGnJ3a7S9+ +JY99iVDF6hOroR2fbnrqa/Dx8pPdMy9ZOXZvh3Q527j8u4m9zXUXfVUCgYEAyaRG +dSEt/AJxoecZqa450H8rlOQVDC0DcQcxGlEP7L2wQRinnJkfZ6+r7jhfu4SikOZO +MdXDF/ILGxSXw6+0xHwq9XfSlNhgTTcBNZOYfchMi6mvUxe/r4TsMXEcbRPSsuWo +EZJ1oZLHxdw9B96R9blnxk54VvILG60rrwbaOBsCgYEAz8EQ4y4/Urn5ov9L96We +xVa8XCvCkDBWm0bSMhNTzE9bRQvrUejtnR/L297MDaB1ebO14YtIpm3nDsfHvk1Y +rj86FovinK+VBx8ss6nF3ta4f+9F7kUZgt+7U2DJr8Md+lsm0zP4tO7TFbMbRPEP +qVfV2tA5b8ZHxMXvOBkfUCECgYAZbFvx0rAgkRJQrnme2jex4QbWq/c3ZMmFS7nW +LphKahQ58OjZJrk98nlD/NmdI/j3OgJr6B7D+yGJVYxZAONSzrD/6A6l864YrjG5 +1pUobsOv7EINwPXLJIA/L5q86f3rzmblaEjqiT4k5ULQpjBTAgBikWw80iGyaKAU +XlHPNwKBgQDC45gv8aRxJXwSjpCXHnnzoWAJHBOXIpTbQOVdGbuMRr5RAh4CVFsp +6rnNlannpnE8EMkLtAmPLNqmsP0XCRo2TpHU86PRO3OGH/3KEtU/X3ij9sts2OlM +03m9HNt6/h9glwk7NYwbGgOlKhRxr/DUTkumu0tdfYN+tLU83mBeNw== +-----END RSA PRIVATE KEY-----`, `-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAywV8/DH1vLyuTOu9MBiAF2DLlZi0SOMEUznXVSRbt0+YVfsr +o67+66B7ATnB2a5BCyOGaFJ9aIwfTWILMTJo91hVk4gHdvsSYeiS3gnSQtKYEdAX +ZgL2apGP1s08XQfluTF57fxVn8RpKieox6Ea68JSGMuh0AEr2MuJzaTcxzQ5UpIi +K2vUuBXNMzZwbZKvssfsyoZ6zIEeco4BCGXXmJUyxFb6MLV8DWKwmUQjhV/EjDem +vE0vrUziY1afo2J9Ngk03mPHqprDZEa8u2wwtm2ghuCaislKh9X7vl31Yj5lcPCU +iacBupV6/bhMjPTAgIAOEcsLVZMK2P+snREDjwIDAQABAoIBACiu/93V8SWSNeeK +Mg5KSpjkt8dRo4cbnwlChQk10P9J/v/z5knVzpXPQfb76QHDLpuZ0dxj82eY9Mjg +Bdgk/u3aEMQQtVY9d/CQ16WRGEZ1xy2Cor25iEHQy59C337RD1LuPD3ZnBr5FA3z +hpoCic+G0EbRv6pcIbo/B21jRS7Rx+w13CNZQD1fL5vEc1CTR+WL/DeCTugGcj8i +wiaUb6eu2Z4YFoJqCWGhTfz1HL4i+y12HfAlezfYae9Lhm0r/mLMos6O7gHWqW24 +EbmeQZy+TGjd7SBw1wsEv7ZO+MFsfvbBvZidmK/FcxUqiyfsvhsTuRbgv6+GiMep +rF+acgkCgYEA6C7dg6GtBydIGq1iE7ty2pUcW4YPL2BVjTK7Fntt1ToVzUKZAulG +Av0+kukeReDLGxrNMhHDzGuLboA2v/PNcMnoJWnzg2+tMByyLWEvIvp9fngbSwRr +JEdDbUDQZbpEkyEC8fDAO3l3EmoHaGBEshZ0tDl0fui36vM1w8lhZDUCgYEA39jW +bsHHny4QUwwsXu/dvg8meYP2rCjBxjM7PIz1FKut+oftUmYCVhRvhZl5ydpO9/2f +VQYqHnDMlmAzjCovKvjFFMXJl2QucUHR+S94sobmTj6tfY9VzAq8uZaMi9jq5uRL +WZvmTPtj3U7KequCqCN7w14o7JkFxOGquFy5eTMCgYANr42BD8uaK1eVsvif/yGS +/s0QHAPTIBOK4h2jAp2Dvwu/8JgCUuu8i17f2/vb1JdEPr0voVpwNzqdxdL0V5OZ +fV1Ar1EaQz/rIRXjlOHpZuh0xvGc52LFXan8y6A9DtCx93Ur+6vpFYzOOg+7uEj0 +UlyIrwZN4LvOjo1xv/IMrQKBgQCfsFAhSUqAa1sn87o/q/zTlnlLHPI/lP/PxkKP +CrvYGDWQUaHjM3SdNgztETUJ5ByL27nr7O7lMnExIcYESx/FFx15mTQcNVLQZzVF +ADGpooTv8tTPiw6Y9lv2RclUBtZlCx4Z+hbMelaezZOy+WHHUzD6idTGHNA5yQeC +aFvEcwKBgQC+QzEkoG7IDqrFL62x+H607juYF4IY4kXo7zsrfY4uWffC7Mf5XaYs +qkX9+ouK/CROAKO+UdMEs8PWHF1CHmgV3t/EF2+xfkGvVr/RlgtMHgQe8lX9a+sK +1xpqDpqmXTST37cy+lQGPXmWrJsTulWQj0F1LV4i4qt7Ph4JK4kzvA== +-----END RSA PRIVATE KEY----- +`, `-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAoaJsIxrUBKPW/dogPpUxxhiL8cpUt8uWlclOrmUSHFZzY50r +wsCt2ndnZRHE/HD+X7oCo28pdYTySZWnsiY/K2HeyYdsRzUH71Mx0Z+a1uBa0k6B +VHY8vrPObLCPFEmxnqml+Wj74zocsR23/puCz8Vgm+0VF49vu+ab90lc2iLJtElv +eRnLrSkaudCUndmn+aVftwnpDxJ4Z0rRlJkhyeZMN4+EMse5+0hAhg5UiPHE6pG8 +RI3zYnp0EYKvN+M9/cdNntyuKCCCvOCi4b4d4wpGOrDuiA/moh2J9zwPBMiyvIFo +zUMmqAQV3zuUxx+jAAjrc9ReQLnoExhuhfrU5wIDAQABAoIBAC62PgI3MqbUosFi +VIdBnszdMzSBgNJNKAvJzc9grkc6RMa5GXiDLrtAXsU6yW8bSKhpnXGWIqkv7sWN +VpWJsB/dfQFI/eXmUZC8vl0SfzEyTY0R2xaJxSxn0nRe4jq+wXJVHP5jdMhKdxhI +um/+iWN6a10kuz+/2E65asGglhEEHxzm9ux9PGbhOR7NVAiReRfEKN0UgmD9jWHL +nR2uBsS3BsPBURKBERzYOqGmxMgOq9Y07Jf6d4Ln33SfkKsD/ibTPoUyTsvwG0g1 +J7wVmqZRxG7GLGxLjjs+s16LWjRKUCbHOf7VIMKkYj2HBgzMZOG6/f579mejB//D +K5rSwuECgYEA0doT9iTVq9ZbpYKfLH5HzqoTuZeP5Q5acO2ZM2Bat6Xdk/ZgOgh4 +Gvzgfi33kl03Pp2ZhQX9m1k1eicTcDPvNQZ3JeTI7bgO3ZQXt8PkCL/pPCZyfusB +C9sP4zhhmieLuX7SZmkWpJvy1XtjvJsyhnnZz2s51nvCKKAe6JVFatUCgYEAxS3f +yFOBzRAyuPWUF4pGTAVfysM47Zl0alDcZgM30ARhqhsfHOo26xeU6TEWucCh30fS +tehXlQDlygHN1+CxkqH6mv0Nlp1j/1YV9mZIEZ++jIggAgsit29YtoQMIe6/lv0+ ++aivyNJrCtbgm9ZA4+OOie3Cvjf/6qnqnBSFpssCgYBWkfyCIpfzF68fDE/V7xJ4 +czlH6vp1qAIvbBUzWKCT+lz6WT1BM5U4rPF/nD7xpnrP3fwjIGGK4LZq+gvO0d3w +pgYpH8S0LKYVSq6uJKXB5km1grbhHNmFpo1bUzsQeRfvIh5yGRA6QAthflGa0Pt6 +9nGgW7+0d8GVONkHYe0NMQKBgAJU64uL6UIKif8D8G9i1Df77EkSi+7LXMQRFroi +GZvdIWaIkZKe9m1LRxiG2xTxQTjJuaUrDTYW36DG6q892fu47KS+j1WToOYZF4Nl +bD7BG9i/l1lO1mdC6tKltxsDnsJjVkZPh1yhmGB1cAyHuRa4zyu0YxQqx1z4C20z +FO2HAoGBALp9nGqbK6N96LYgef8GpP6o5pz3D1Jtj18iYyn3oz6z9t3dqNbpf2vh +cYnDqCQWSX5rfDRMbuhEJB+GvHYKVY/yVJ2ZWu1cKsB+2gzsITWewfxTS/ns+4Qk +RfViImdNIa19f7cmeC8RjhaSWBmb9JJk+p75e4XpgD1bG9U7DjiH +-----END RSA PRIVATE KEY----- +`} + + publicKeyStrings = []string{`-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8G5n9XBidxmBMVJKLOB +smdOHrCqGf17y9+VUXingwDUZxRp2XbuLZLbJtLgcln1lC0L9BsogrWf7+pDhAzW +ovO6Ai4Aybu00tJ2u0g4j1aLiDdsy0gyvSb5FBoL08jFIH7t/JzMt4JpF487Ajzv +ITwZZcnsrB9a9sdn2E5B/aZmpDGi2+Isf5osnlw0zvveTwiMo9ba416VIzjntAVE +vqMFHK7vyHqXbfqUPAyhjLO+iee99Tg5AlGfjo1s6FjeML4xX7sAMGEy8FVBWNfp +RU7ryTWoSn2adzyA/FVmtBvJNQBCMrrAhXDTMJ5FNi8zHhvzyBKHU0kBTS1UNUbP +9wIDAQAB +-----END PUBLIC KEY-----`, `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAywV8/DH1vLyuTOu9MBiA +F2DLlZi0SOMEUznXVSRbt0+YVfsro67+66B7ATnB2a5BCyOGaFJ9aIwfTWILMTJo +91hVk4gHdvsSYeiS3gnSQtKYEdAXZgL2apGP1s08XQfluTF57fxVn8RpKieox6Ea +68JSGMuh0AEr2MuJzaTcxzQ5UpIiK2vUuBXNMzZwbZKvssfsyoZ6zIEeco4BCGXX +mJUyxFb6MLV8DWKwmUQjhV/EjDemvE0vrUziY1afo2J9Ngk03mPHqprDZEa8u2ww +tm2ghuCaislKh9X7vl31Yj5lcPCUiacBupV6/bhMjPTAgIAOEcsLVZMK2P+snRED +jwIDAQAB +-----END PUBLIC KEY-----`, `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoaJsIxrUBKPW/dogPpUx +xhiL8cpUt8uWlclOrmUSHFZzY50rwsCt2ndnZRHE/HD+X7oCo28pdYTySZWnsiY/ +K2HeyYdsRzUH71Mx0Z+a1uBa0k6BVHY8vrPObLCPFEmxnqml+Wj74zocsR23/puC +z8Vgm+0VF49vu+ab90lc2iLJtElveRnLrSkaudCUndmn+aVftwnpDxJ4Z0rRlJkh +yeZMN4+EMse5+0hAhg5UiPHE6pG8RI3zYnp0EYKvN+M9/cdNntyuKCCCvOCi4b4d +4wpGOrDuiA/moh2J9zwPBMiyvIFozUMmqAQV3zuUxx+jAAjrc9ReQLnoExhuhfrU +5wIDAQAB +-----END PUBLIC KEY-----`} + + priKeys []*rsa.PrivateKey + pubKeys []*rsa.PublicKey + jwkArray []jwkRepo.Key + path [3]string // path[0] contains jwkArray[0], path[1] contains jwkArray[0:2], path[2] contains jwkArray[2] + + email1 = "user1@pingcap.com" + email2 = "user2@pingcap.com" + issuer1 = "issuer1" + issuer2 = "issuer2" +) + +type pair struct { + name string + value interface{} +} + +func init() { + for i := range publicKeyStrings { + if v, rest, err := jwkRepo.DecodePEM(([]byte)(privateKeyStrings[i])); err != nil { + log.Println(err.Error()) + log.Fatal("Error in decode private key") + } else if len(rest) > 0 { + log.Fatal("Rest in decode private key") + } else if priKey, ok := v.(*rsa.PrivateKey); !ok { + log.Fatal("Wrong type of private key") + } else { + priKeys = append(priKeys, priKey) + } + if v, rest, err := jwkRepo.DecodePEM(([]byte)(publicKeyStrings[i])); err != nil { + log.Println(err.Error()) + log.Fatal("Error in decode public key") + } else if len(rest) > 0 { + log.Fatal("Rest in decode public key") + } else if pubKey, ok := v.(*rsa.PublicKey); !ok { + log.Fatal("Wrong type of public key") + } else { + pubKeys = append(pubKeys, pubKey) + jwk, err := jwkRepo.FromRaw(pubKey) + if err != nil { + log.Fatal("Error when generate jwk") + } + keyAttributes := []pair{ + {jwkRepo.AlgorithmKey, jwaRepo.RS256}, + {jwkRepo.KeyIDKey, fmt.Sprintf("the-key-id-%d", i)}, + {jwkRepo.KeyUsageKey, "sig"}, + } + for _, keyAttribute := range keyAttributes { + if err = jwk.Set(keyAttribute.name, keyAttribute.value); err != nil { + log.Println(err.Error()) + log.Fatalf("Error when set %s for key %d", keyAttribute.name, i) + } + } + jwkArray = append(jwkArray, jwk) + } + } + + for i := range path { + path[i] = fmt.Sprintf("%s%cjwks%d.json", os.TempDir(), os.PathSeparator, i) + file, err := os.Create(path[i]) + if err != nil { + log.Fatal("Fail to create temp file") + } + jwks := jwkRepo.NewSet() + var rawJSON []byte + if i == 2 { + jwks.AddKey(jwkArray[i]) + } else { + for j := 0; j <= i; j++ { + jwks.AddKey(jwkArray[j]) + } + } + if rawJSON, err = json.MarshalIndent(jwks, "", " "); err != nil { + log.Fatal("Error when marshaler json") + } + if n, err := file.Write(rawJSON); err != nil { + log.Fatal("Error when writing json") + } else if n != len(rawJSON) { + log.Fatal("Lack byte when writing json") + } + } +} + +func getSignedTokenString(priKey *rsa.PrivateKey, pairs map[string]interface{}) (string, error) { + jwt := jwtRepo.New() + header := jwsRepo.NewHeaders() + headerPairs := []pair{ + {jwsRepo.AlgorithmKey, jwaRepo.RS256}, + {jwsRepo.TypeKey, "JWT"}, + } + for _, pair := range headerPairs { + if err := header.Set(pair.name, pair.value); err != nil { + log.Fatal("Error when set header") + } + } + for k, v := range pairs { + switch k { + case jwsRepo.KeyIDKey: + if err := header.Set(k, v); err != nil { + log.Fatal("Error when set header") + } + case jwtRepo.SubjectKey, jwtRepo.IssuedAtKey, jwtRepo.ExpirationKey, jwtRepo.IssuerKey, openid.EmailKey: + if err := jwt.Set(k, v); err != nil { + log.Fatal("Error when set payload") + } + } + } + bytes, err := jwtRepo.Sign(jwt, jwtRepo.WithKey(jwaRepo.RS256, priKey, jwsRepo.WithProtectedHeaders(header))) + if err != nil { + return "", err + } + return string(hack.String(bytes)), nil +} + +func TestAuthTokenClaims(t *testing.T) { + var jwksImpl JWKSImpl + now := time.Now() + require.NoError(t, jwksImpl.LoadJWKS4AuthToken(nil, nil, path[0], time.Hour), path[0]) + claims := map[string]interface{}{ + jwsRepo.KeyIDKey: "the-key-id-0", + jwtRepo.SubjectKey: email1, + openid.EmailKey: email1, + jwtRepo.IssuedAtKey: now.Unix(), + jwtRepo.ExpirationKey: now.Add(100 * time.Hour).Unix(), + jwtRepo.IssuerKey: issuer1, + } + signedTokenString, err := getSignedTokenString(priKeys[0], claims) + require.NoError(t, err) + verifiedClaims, err := jwksImpl.checkSigWithRetry(signedTokenString, 0) + require.NoError(t, err) + for k, v := range claims { + switch k { + case jwtRepo.SubjectKey, openid.EmailKey, jwtRepo.IssuerKey: + require.Equal(t, v, verifiedClaims[k]) + case jwtRepo.IssuedAtKey, jwtRepo.ExpirationKey: + require.Equal(t, v, verifiedClaims[k].(time.Time).Unix()) + } + } + record := &UserRecord{ + baseRecord: baseRecord{ + User: email1, + }, + AuthTokenIssuer: issuer1, + UserAttributesInfo: UserAttributesInfo{ + MetadataInfo: MetadataInfo{ + Email: email1, + }, + }, + } + + // Success + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.NoError(t, err) + + // test 'sub' + verifiedClaims[jwtRepo.SubjectKey] = email2 + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "Wrong 'sub'") + delete(verifiedClaims, jwtRepo.SubjectKey) + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "lack 'sub'") + verifiedClaims[jwtRepo.SubjectKey] = email1 + + // test 'email' + verifiedClaims[openid.EmailKey] = email2 + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "Wrong 'email'") + delete(verifiedClaims, openid.EmailKey) + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "lack 'email'") + verifiedClaims[openid.EmailKey] = email1 + + // test 'iat' + delete(verifiedClaims, jwtRepo.IssuedAtKey) + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "lack 'iat'") + verifiedClaims[jwtRepo.IssuedAtKey] = "abc" + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "iat: abc is not a value of time.Time") + time.Sleep(2 * time.Second) + verifiedClaims[jwtRepo.IssuedAtKey] = now + err = checkAuthTokenClaims(verifiedClaims, record, time.Second) + require.ErrorContains(t, err, "the token has been out of its life time") + verifiedClaims[jwtRepo.IssuedAtKey] = now.Add(time.Hour) + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "the token is issued at a future time") + verifiedClaims[jwtRepo.IssuedAtKey] = now + + // test 'exp' + delete(verifiedClaims, jwtRepo.ExpirationKey) + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "lack 'exp'") + verifiedClaims[jwtRepo.ExpirationKey] = "abc" + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "exp: abc is not a value of time.Time") + verifiedClaims[jwtRepo.ExpirationKey] = now + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "the token has been expired") + verifiedClaims[jwtRepo.ExpirationKey] = now.Add(100 * time.Hour) + + // test token_issuer + delete(verifiedClaims, jwtRepo.IssuerKey) + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "lack 'iss'") + verifiedClaims[jwtRepo.IssuerKey] = issuer1 + record.AuthTokenIssuer = issuer2 + err = checkAuthTokenClaims(verifiedClaims, record, defaultTokenLife) + require.ErrorContains(t, err, "Wrong 'iss") +} + +func TestJWKSImpl(t *testing.T) { + var jwksImpl JWKSImpl + + // Set wrong path of JWKS + require.Error(t, jwksImpl.LoadJWKS4AuthToken(nil, nil, "wrong-jwks-path", time.Hour)) + require.Error(t, jwksImpl.load()) + _, err := jwksImpl.checkSigWithRetry("invalid tokenString", 4) + require.Error(t, err) + _, err = jwksImpl.verify(([]byte)("invalid tokenString")) + require.Error(t, err) + + require.NoError(t, jwksImpl.LoadJWKS4AuthToken(nil, nil, path[0], time.Hour), path[0]) + now := time.Now() + claims := map[string]interface{}{ + jwsRepo.KeyIDKey: "the-key-id-0", + jwtRepo.SubjectKey: email1, + openid.EmailKey: email1, + jwtRepo.IssuedAtKey: now.Unix(), + jwtRepo.ExpirationKey: now.Add(100 * time.Hour).Unix(), + jwtRepo.IssuerKey: issuer1, + } + signedTokenString, err := getSignedTokenString(priKeys[0], claims) + require.NoError(t, err) + parts := strings.Split(signedTokenString, ".") + + // Wrong encoded JWT format + _, err = jwksImpl.checkSigWithRetry(parts[0]+"."+parts[1], 0) + require.ErrorContains(t, err, "Invalid JWT") + _, err = jwksImpl.checkSigWithRetry(signedTokenString+"."+parts[1], 0) + require.ErrorContains(t, err, "Invalid JWT") + + // Wrong signature + _, err = jwksImpl.checkSigWithRetry(signedTokenString+"A", 0) + require.ErrorContains(t, err, "could not verify message using any of the signatures or keys") + + // Wrong signature, and fail to reload JWKS + jwksImpl.filepath = "wrong-path" + _, err = jwksImpl.checkSigWithRetry(signedTokenString+"A", 0) + require.ErrorContains(t, err, "open wrong-path: no such file or directory") + jwksImpl.filepath = path[0] + + require.NoError(t, jwksImpl.LoadJWKS4AuthToken(nil, nil, path[0], time.Hour), path[0]) + _, err = jwksImpl.checkSigWithRetry(signedTokenString, 0) + require.NoError(t, err) + + // Wrong kid + claims[jwsRepo.KeyIDKey] = "the-key-id-1" + signedTokenString, err = getSignedTokenString(priKeys[0], claims) + require.NoError(t, err) + _, err = jwksImpl.checkSigWithRetry(signedTokenString, 0) + require.Error(t, err) + claims[jwsRepo.KeyIDKey] = "the-key-id-0" + signedTokenString, err = getSignedTokenString(priKeys[0], claims) + require.NoError(t, err) + require.NoError(t, jwksImpl.LoadJWKS4AuthToken(nil, nil, path[1], time.Hour), path[1]) + _, err = jwksImpl.checkSigWithRetry(signedTokenString, 0) + require.NoError(t, err) + require.NoError(t, jwksImpl.LoadJWKS4AuthToken(nil, nil, path[2], time.Hour), path[2]) + _, err = jwksImpl.checkSigWithRetry(signedTokenString, 0) + require.Error(t, err) +} diff --git a/resourcemanager/BUILD.bazel b/resourcemanager/BUILD.bazel new file mode 100644 index 0000000000000..c6e7983df34be --- /dev/null +++ b/resourcemanager/BUILD.bazel @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "resourcemanager", + srcs = [ + "rm.go", + "schedule.go", + ], + importpath = "github.com/pingcap/tidb/resourcemanager", + visibility = ["//visibility:public"], + deps = [ + "//resourcemanager/scheduler", + "//resourcemanager/util", + "//util", + "//util/cpu", + "@com_github_google_uuid//:uuid", + "@com_github_pingcap_log//:log", + "@org_uber_go_zap//:zap", + ], +) diff --git a/resourcemanager/pooltask/BUILD.bazel b/resourcemanager/pooltask/BUILD.bazel new file mode 100644 index 0000000000000..151a0ddfdec02 --- /dev/null +++ b/resourcemanager/pooltask/BUILD.bazel @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "pooltask", + srcs = [ + "task.go", + "task_manager.go", + ], + importpath = "github.com/pingcap/tidb/resourcemanager/pooltask", + visibility = ["//visibility:public"], + deps = ["@org_uber_go_atomic//:atomic"], +) + +go_test( + name = "pooltask_test", + srcs = ["task_test.go"], + embed = [":pooltask"], + deps = ["@com_github_stretchr_testify//require"], +) diff --git a/resourcemanager/pooltask/task.go b/resourcemanager/pooltask/task.go new file mode 100644 index 0000000000000..e166e24f76b4c --- /dev/null +++ b/resourcemanager/pooltask/task.go @@ -0,0 +1,169 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pooltask + +import ( + "sync" + "sync/atomic" +) + +// Context is a interface that can be used to create a context. +type Context[T any] interface { + GetContext() T +} + +// NilContext is to create a nil as context +type NilContext struct{} + +// GetContext is to get a nil as context +func (NilContext) GetContext() any { + return nil +} + +const ( + // PendingTask is a task waiting to start. + PendingTask int32 = iota + // RunningTask is a task running. + RunningTask + // StopTask is a stop task. + StopTask +) + +// TaskBox is a box which contains all info about pool task. +type TaskBox[T any, U any, C any, CT any, TF Context[CT]] struct { + constArgs C + contextFunc TF + wg *sync.WaitGroup + task chan Task[T] + resultCh chan U + taskID uint64 + status atomic.Int32 // task manager is able to make this task stop, wait or running +} + +// GetStatus is to get the status of task. +func (t *TaskBox[T, U, C, CT, TF]) GetStatus() int32 { + return t.status.Load() +} + +// SetStatus is to set the status of task. +func (t *TaskBox[T, U, C, CT, TF]) SetStatus(s int32) { + t.status.Store(s) +} + +// NewTaskBox is to create a task box for pool. +func NewTaskBox[T any, U any, C any, CT any, TF Context[CT]](constArgs C, contextFunc TF, wg *sync.WaitGroup, taskCh chan Task[T], resultCh chan U, taskID uint64) TaskBox[T, U, C, CT, TF] { + // We still need to do some work after a TaskBox finishes. + // So we need to add 1 to waitgroup. After we finish the work, we need to call TaskBox.Finish() + wg.Add(1) + return TaskBox[T, U, C, CT, TF]{ + constArgs: constArgs, + contextFunc: contextFunc, + wg: wg, + task: taskCh, + resultCh: resultCh, + taskID: taskID, + } +} + +// TaskID is to get the task id. +func (t *TaskBox[T, U, C, CT, TF]) TaskID() uint64 { + return t.taskID +} + +// ConstArgs is to get the const args. +func (t *TaskBox[T, U, C, CT, TF]) ConstArgs() C { + return t.constArgs +} + +// GetTaskCh is to get the task channel. +func (t *TaskBox[T, U, C, CT, TF]) GetTaskCh() chan Task[T] { + return t.task +} + +// GetResultCh is to get result channel +func (t *TaskBox[T, U, C, CT, TF]) GetResultCh() chan U { + return t.resultCh +} + +// GetContextFunc is to get context func. +func (t *TaskBox[T, U, C, CT, TF]) GetContextFunc() TF { + return t.contextFunc +} + +// Done is to set the pooltask status to complete. +func (t *TaskBox[T, U, C, CT, TF]) Done() { + t.wg.Done() +} + +// Finish is to set the TaskBox finish status. +func (t *TaskBox[T, U, C, CT, TF]) Finish() { + t.wg.Done() +} + +// Clone is to copy the box +func (t *TaskBox[T, U, C, CT, TF]) Clone() *TaskBox[T, U, C, CT, TF] { + newBox := NewTaskBox[T, U, C, CT, TF](t.constArgs, t.contextFunc, t.wg, t.task, t.resultCh, t.taskID) + return &newBox +} + +// GPool is a goroutine pool. +type GPool[T any, U any, C any, CT any, TF Context[CT]] interface { + Tune(size int) + DeleteTask(id uint64) + StopTask(id uint64) +} + +// TaskController is a controller that can control or watch the pool. +type TaskController[T any, U any, C any, CT any, TF Context[CT]] struct { + pool GPool[T, U, C, CT, TF] + close chan struct{} + wg *sync.WaitGroup + taskID uint64 + resultCh chan U +} + +// NewTaskController create a controller to deal with pooltask's status. +func NewTaskController[T any, U any, C any, CT any, TF Context[CT]](p GPool[T, U, C, CT, TF], taskID uint64, closeCh chan struct{}, wg *sync.WaitGroup, resultCh chan U) TaskController[T, U, C, CT, TF] { + return TaskController[T, U, C, CT, TF]{ + pool: p, + taskID: taskID, + close: closeCh, + wg: wg, + resultCh: resultCh, + } +} + +// Wait is to wait the pool task to stop. +func (t *TaskController[T, U, C, CT, TF]) Wait() { + <-t.close + t.wg.Wait() + close(t.resultCh) + t.pool.DeleteTask(t.taskID) +} + +// Stop is to send stop command to the task. But you still need to wait the task to stop. +func (t *TaskController[T, U, C, CT, TF]) Stop() { + t.pool.StopTask(t.TaskID()) +} + +// TaskID is to get the task id. +func (t *TaskController[T, U, C, CT, TF]) TaskID() uint64 { + return t.taskID +} + +// Task is a task that can be executed. +type Task[T any] struct { + Task T +} diff --git a/resourcemanager/pooltask/task_manager.go b/resourcemanager/pooltask/task_manager.go new file mode 100644 index 0000000000000..25ce9e8ad1b4b --- /dev/null +++ b/resourcemanager/pooltask/task_manager.go @@ -0,0 +1,150 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pooltask + +import ( + "container/list" + "sync" + "time" + + "go.uber.org/atomic" +) + +const shard int = 8 + +func getShardID(id uint64) uint64 { + return id % uint64(shard) +} + +type tContainer[T any, U any, C any, CT any, TF Context[CT]] struct { + task *TaskBox[T, U, C, CT, TF] +} + +type meta struct { + stats *list.List + createTS time.Time + origin int32 + running int32 +} + +func newStats(concurrency int32) *meta { + s := &meta{ + createTS: time.Now(), + stats: list.New(), + origin: concurrency, + } + return s +} + +func (m *meta) getOriginConcurrency() int32 { + return m.origin +} + +// TaskStatusContainer is a container that can control or watch the pool. +type TaskStatusContainer[T any, U any, C any, CT any, TF Context[CT]] struct { + stats map[uint64]*meta + rw sync.RWMutex +} + +// TaskManager is a manager that can control or watch the pool. +type TaskManager[T any, U any, C any, CT any, TF Context[CT]] struct { + task []TaskStatusContainer[T, U, C, CT, TF] + running atomic.Int32 + concurrency int32 +} + +// NewTaskManager create a new pooltask manager. +func NewTaskManager[T any, U any, C any, CT any, TF Context[CT]](c int32) TaskManager[T, U, C, CT, TF] { + task := make([]TaskStatusContainer[T, U, C, CT, TF], shard) + for i := 0; i < shard; i++ { + task[i] = TaskStatusContainer[T, U, C, CT, TF]{ + stats: make(map[uint64]*meta), + } + } + return TaskManager[T, U, C, CT, TF]{ + task: task, + concurrency: c, + } +} + +// RegisterTask register a task to the manager. +func (t *TaskManager[T, U, C, CT, TF]) RegisterTask(taskID uint64, concurrency int32) { + id := getShardID(taskID) + t.task[id].rw.Lock() + t.task[id].stats[taskID] = newStats(concurrency) + t.task[id].rw.Unlock() +} + +// DeleteTask delete a task from the manager. +func (t *TaskManager[T, U, C, CT, TF]) DeleteTask(taskID uint64) { + shardID := getShardID(taskID) + t.task[shardID].rw.Lock() + delete(t.task[shardID].stats, taskID) + t.task[shardID].rw.Unlock() +} + +// hasTask check if the task is in the manager. +func (t *TaskManager[T, U, C, CT, TF]) hasTask(taskID uint64) bool { + shardID := getShardID(taskID) + t.task[shardID].rw.Lock() + defer t.task[shardID].rw.Unlock() + _, ok := t.task[shardID].stats[taskID] + return ok +} + +// AddSubTask AddTask add a task to the manager. +func (t *TaskManager[T, U, C, CT, TF]) AddSubTask(taskID uint64, task *TaskBox[T, U, C, CT, TF]) { + shardID := getShardID(taskID) + tc := tContainer[T, U, C, CT, TF]{ + task: task, + } + t.running.Inc() + t.task[shardID].rw.Lock() + t.task[shardID].stats[taskID].stats.PushBack(tc) + t.task[shardID].stats[taskID].running++ // running job in this task + t.task[shardID].rw.Unlock() +} + +// ExitSubTask is to exit a task, and it will decrease the count of running pooltask. +func (t *TaskManager[T, U, C, CT, TF]) ExitSubTask(taskID uint64) { + shardID := getShardID(taskID) + t.running.Dec() // total running tasks + t.task[shardID].rw.Lock() + t.task[shardID].stats[taskID].running-- // running job in this task + t.task[shardID].rw.Unlock() +} + +// Running return the count of running job in this task. +func (t *TaskManager[T, U, C, CT, TF]) Running(taskID uint64) int32 { + shardID := getShardID(taskID) + t.task[shardID].rw.Lock() + defer t.task[shardID].rw.Unlock() + return t.task[shardID].stats[taskID].running +} + +// StopTask is to stop a task by TaskID. +func (t *TaskManager[T, U, C, CT, TF]) StopTask(taskID uint64) { + shardID := getShardID(taskID) + t.task[shardID].rw.Lock() + defer t.task[shardID].rw.Unlock() + // When call the StopTask, the task may have been deleted from the manager. + s, ok := t.task[shardID].stats[taskID] + if ok { + l := s.stats + for e := l.Front(); e != nil; e = e.Next() { + e.Value.(tContainer[T, U, C, CT, TF]).task.SetStatus(StopTask) + } + } +} diff --git a/resourcemanager/pooltask/task_test.go b/resourcemanager/pooltask/task_test.go new file mode 100644 index 0000000000000..b4f189fb14525 --- /dev/null +++ b/resourcemanager/pooltask/task_test.go @@ -0,0 +1,40 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pooltask + +import ( + "sync" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTaskManager(t *testing.T) { + size := 32 + taskConcurrency := 8 + tm := NewTaskManager[int, int, int, any, NilContext](int32(size)) + tm.RegisterTask(1, int32(taskConcurrency)) + for i := 0; i < taskConcurrency; i++ { + tid := NewTaskBox[int, int, int, any, NilContext](1, NilContext{}, &sync.WaitGroup{}, make(chan Task[int]), make(chan int), 1) + tm.AddSubTask(1, &tid) + } + for i := 0; i < taskConcurrency; i++ { + tm.ExitSubTask(1) + } + require.Equal(t, int32(0), tm.Running(1)) + require.True(t, tm.hasTask(1)) + tm.DeleteTask(1) + require.False(t, tm.hasTask(1)) +} diff --git a/resourcemanager/rm.go b/resourcemanager/rm.go new file mode 100644 index 0000000000000..e6e48de2059cd --- /dev/null +++ b/resourcemanager/rm.go @@ -0,0 +1,98 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resourcemanager + +import ( + "time" + + "github.com/google/uuid" + "github.com/pingcap/tidb/resourcemanager/scheduler" + "github.com/pingcap/tidb/resourcemanager/util" + tidbutil "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/cpu" +) + +// InstanceResourceManager is a local instance resource manager +var InstanceResourceManager = NewResourceManger() + +// RandomName is to get a random name for register pool. It is just for test. +func RandomName() string { + return uuid.New().String() +} + +// ResourceManager is a resource manager +type ResourceManager struct { + poolMap *util.ShardPoolMap + scheduler []scheduler.Scheduler + cpuObserver *cpu.Observer + exitCh chan struct{} + wg tidbutil.WaitGroupWrapper +} + +// NewResourceManger is to create a new resource manager +func NewResourceManger() *ResourceManager { + sc := make([]scheduler.Scheduler, 0, 1) + sc = append(sc, scheduler.NewCPUScheduler()) + return &ResourceManager{ + cpuObserver: cpu.NewCPUObserver(), + exitCh: make(chan struct{}), + poolMap: util.NewShardPoolMap(), + scheduler: sc, + } +} + +// Start is to start resource manager +func (r *ResourceManager) Start() { + r.wg.Run(r.cpuObserver.Start) + r.wg.Run(func() { + tick := time.NewTicker(100 * time.Millisecond) + defer tick.Stop() + for { + select { + case <-tick.C: + r.schedule() + case <-r.exitCh: + return + } + } + }) +} + +// Stop is to stop resource manager +func (r *ResourceManager) Stop() { + r.cpuObserver.Stop() + close(r.exitCh) + r.wg.Wait() +} + +// Register is to register pool into resource manager +func (r *ResourceManager) Register(pool util.GorotinuePool, name string, component util.Component) error { + p := util.PoolContainer{Pool: pool, Component: component} + return r.registerPool(name, &p) +} + +func (r *ResourceManager) registerPool(name string, pool *util.PoolContainer) error { + return r.poolMap.Add(name, pool) +} + +// Unregister is to unregister pool into resource manager. +func (r *ResourceManager) Unregister(name string) { + r.poolMap.Del(name) +} + +// Reset is to Reset resource manager. it is just for test. +func (r *ResourceManager) Reset() { + r.poolMap = util.NewShardPoolMap() +} diff --git a/resourcemanager/schedule.go b/resourcemanager/schedule.go new file mode 100644 index 0000000000000..f6ac691e09b15 --- /dev/null +++ b/resourcemanager/schedule.go @@ -0,0 +1,69 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resourcemanager + +import ( + "time" + + "github.com/pingcap/log" + "github.com/pingcap/tidb/resourcemanager/scheduler" + "github.com/pingcap/tidb/resourcemanager/util" + "go.uber.org/zap" +) + +func (r *ResourceManager) schedule() { + r.poolMap.Iter(func(pool *util.PoolContainer) { + cmd := r.schedulePool(pool) + r.exec(pool, cmd) + }) +} + +func (r *ResourceManager) schedulePool(pool *util.PoolContainer) scheduler.Command { + for _, sch := range r.scheduler { + cmd := sch.Tune(pool.Component, pool.Pool) + switch cmd { + case scheduler.Hold: + continue + default: + return cmd + } + } + return scheduler.Hold +} + +func (*ResourceManager) exec(pool *util.PoolContainer, cmd scheduler.Command) { + if cmd == scheduler.Hold { + return + } + if time.Since(pool.Pool.LastTunerTs()) > util.MinSchedulerInterval.Load() { + con := pool.Pool.Cap() + switch cmd { + case scheduler.Downclock: + concurrency := con - 1 + log.Info("downclock goroutine pool", + zap.Int("origin concurrency", con), + zap.Int("concurrency", concurrency), + zap.String("name", pool.Pool.Name())) + pool.Pool.Tune(concurrency) + case scheduler.Overclock: + concurrency := con + 1 + log.Info("overclock goroutine pool", + zap.Int("origin concurrency", con), + zap.Int("concurrency", concurrency), + zap.String("name", pool.Pool.Name())) + pool.Pool.Tune(concurrency) + } + } +} diff --git a/resourcemanager/scheduler/BUILD.bazel b/resourcemanager/scheduler/BUILD.bazel new file mode 100644 index 0000000000000..39bd88f030372 --- /dev/null +++ b/resourcemanager/scheduler/BUILD.bazel @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "scheduler", + srcs = [ + "cpu_scheduler.go", + "scheduler.go", + ], + importpath = "github.com/pingcap/tidb/resourcemanager/scheduler", + visibility = ["//visibility:public"], + deps = [ + "//resourcemanager/util", + "//util/cpu", + ], +) diff --git a/resourcemanager/scheduler/cpu_scheduler.go b/resourcemanager/scheduler/cpu_scheduler.go new file mode 100644 index 0000000000000..c84fcf36fb697 --- /dev/null +++ b/resourcemanager/scheduler/cpu_scheduler.go @@ -0,0 +1,44 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scheduler + +import ( + "time" + + "github.com/pingcap/tidb/resourcemanager/util" + "github.com/pingcap/tidb/util/cpu" +) + +// CPUScheduler is a cpu scheduler +type CPUScheduler struct{} + +// NewCPUScheduler is to create a new cpu scheduler +func NewCPUScheduler() *CPUScheduler { + return &CPUScheduler{} +} + +// Tune is to tune the goroutine pool +func (*CPUScheduler) Tune(_ util.Component, pool util.GorotinuePool) Command { + if time.Since(pool.LastTunerTs()) < util.MinSchedulerInterval.Load() { + return Hold + } + if cpu.GetCPUUsage() < 0.5 { + return Overclock + } + if cpu.GetCPUUsage() > 0.7 { + return Downclock + } + return Hold +} diff --git a/resourcemanager/scheduler/scheduler.go b/resourcemanager/scheduler/scheduler.go new file mode 100644 index 0000000000000..3af8e6aff5b0b --- /dev/null +++ b/resourcemanager/scheduler/scheduler.go @@ -0,0 +1,36 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package scheduler + +import ( + "github.com/pingcap/tidb/resourcemanager/util" +) + +// Command is the command for scheduler +type Command int + +const ( + // Downclock is to reduce the number of concurrency. + Downclock Command = iota + // Hold is to hold the number of concurrency. + Hold + // Overclock is to increase the number of concurrency. + Overclock +) + +// Scheduler is a scheduler interface +type Scheduler interface { + Tune(component util.Component, p util.GorotinuePool) Command +} diff --git a/resourcemanager/util/BUILD.bazel b/resourcemanager/util/BUILD.bazel new file mode 100644 index 0000000000000..1c5396db6049b --- /dev/null +++ b/resourcemanager/util/BUILD.bazel @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "util", + srcs = [ + "mock_gpool.go", + "shard_pool_map.go", + "util.go", + ], + importpath = "github.com/pingcap/tidb/resourcemanager/util", + visibility = ["//visibility:public"], + deps = [ + "@com_github_pingcap_errors//:errors", + "@org_uber_go_atomic//:atomic", + ], +) + +go_test( + name = "util_test", + srcs = ["shard_pool_map_test.go"], + embed = [":util"], + deps = ["@com_github_stretchr_testify//require"], +) diff --git a/resourcemanager/util/mock_gpool.go b/resourcemanager/util/mock_gpool.go new file mode 100644 index 0000000000000..9697d2942d6ee --- /dev/null +++ b/resourcemanager/util/mock_gpool.go @@ -0,0 +1,97 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import "time" + +// MockGPool is only for test +type MockGPool struct { + name string +} + +// NewMockGPool is only for test +func NewMockGPool(name string) *MockGPool { + return &MockGPool{name: name} +} + +// ReleaseAndWait is only for test +func (*MockGPool) ReleaseAndWait() { + panic("implement me") +} + +// Tune is only for test +func (*MockGPool) Tune(_ int) { + panic("implement me") +} + +// LastTunerTs is only for test +func (*MockGPool) LastTunerTs() time.Time { + panic("implement me") +} + +// MaxInFlight is only for test +func (*MockGPool) MaxInFlight() int64 { + panic("implement me") +} + +// InFlight is only for test +func (*MockGPool) InFlight() int64 { + panic("implement me") +} + +// MinRT is only for test +func (*MockGPool) MinRT() uint64 { + panic("implement me") +} + +// MaxPASS is only for test +func (*MockGPool) MaxPASS() uint64 { + panic("implement me") +} + +// Cap is only for test +func (*MockGPool) Cap() int { + panic("implement me") +} + +// LongRTT is to represent the baseline latency by tracking a measurement of the long term, less volatile RTT. +func (*MockGPool) LongRTT() float64 { + panic("implement me") +} + +// UpdateLongRTT is only for test +func (*MockGPool) UpdateLongRTT(_ func(float64) float64) { + panic("implement me") +} + +// ShortRTT is to represent the current system latency by tracking a measurement of the short time, and more volatile RTT. +func (*MockGPool) ShortRTT() uint64 { + panic("implement me") +} + +// GetQueueSize is only for test +func (*MockGPool) GetQueueSize() int64 { + panic("implement me") +} + +// Running is only for test +func (*MockGPool) Running() int { + panic("implement me") +} + +// Name is only for test +func (m *MockGPool) Name() string { + return m.name +} diff --git a/resourcemanager/util/shard_pool_map.go b/resourcemanager/util/shard_pool_map.go new file mode 100644 index 0000000000000..371365af031e1 --- /dev/null +++ b/resourcemanager/util/shard_pool_map.go @@ -0,0 +1,91 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import ( + "sync" + + "github.com/pingcap/errors" +) + +const shard = 8 + +func hash(key string) int { + return int(key[0]) % shard +} + +// ShardPoolMap is a map with shard +type ShardPoolMap struct { + pools [shard]poolMap +} + +// NewShardPoolMap creates a shard pool map +func NewShardPoolMap() *ShardPoolMap { + var result ShardPoolMap + for i := 0; i < shard; i++ { + result.pools[i] = newPoolMap() + } + return &result +} + +// Add adds a pool to the map +func (s *ShardPoolMap) Add(key string, pool *PoolContainer) error { + return s.pools[hash(key)].Add(key, pool) +} + +// Del deletes a pool to the map. +func (s *ShardPoolMap) Del(key string) { + s.pools[hash(key)].Del(key) +} + +// Iter iterates the map +func (s *ShardPoolMap) Iter(fn func(pool *PoolContainer)) { + for i := 0; i < shard; i++ { + s.pools[i].Iter(fn) + } +} + +type poolMap struct { + mu sync.RWMutex + poolMap map[string]*PoolContainer +} + +func newPoolMap() poolMap { + return poolMap{poolMap: make(map[string]*PoolContainer)} +} + +func (p *poolMap) Add(key string, pool *PoolContainer) error { + p.mu.Lock() + defer p.mu.Unlock() + if _, contain := p.poolMap[key]; contain { + return errors.New("pool is already exist") + } + p.poolMap[key] = pool + return nil +} + +func (p *poolMap) Del(key string) { + p.mu.Lock() + defer p.mu.Unlock() + delete(p.poolMap, key) +} + +func (p *poolMap) Iter(fn func(pool *PoolContainer)) { + p.mu.RLock() + defer p.mu.RUnlock() + for _, pool := range p.poolMap { + fn(pool) + } +} diff --git a/resourcemanager/util/shard_pool_map_test.go b/resourcemanager/util/shard_pool_map_test.go new file mode 100644 index 0000000000000..bb09e2fbd8a24 --- /dev/null +++ b/resourcemanager/util/shard_pool_map_test.go @@ -0,0 +1,50 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import ( + "strconv" + "sync/atomic" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestShardPoolMap(t *testing.T) { + rc := 10 + pm := NewShardPoolMap() + for i := 0; i < rc; i++ { + id := strconv.FormatInt(int64(i), 10) + require.NoError(t, pm.Add(id, &PoolContainer{Pool: NewMockGPool(id), Component: DDL})) + } + require.Error(t, pm.Add("1", &PoolContainer{Pool: NewMockGPool("1"), Component: DDL})) + var cnt atomic.Int32 + pm.Iter(func(pool *PoolContainer) { + cnt.Add(1) + }) + require.Equal(t, rc, int(cnt.Load())) + + for i := 0; i < rc; i++ { + id := strconv.FormatInt(int64(i), 10) + pm.Del(id) + } + cnt.Store(0) + pm.Iter(func(pool *PoolContainer) { + cnt.Add(1) + }) + require.Equal(t, 0, int(cnt.Load())) + id := strconv.FormatInt(int64(0), 10) + pm.Del(id) +} diff --git a/resourcemanager/util/util.go b/resourcemanager/util/util.go new file mode 100644 index 0000000000000..4d433975fabb7 --- /dev/null +++ b/resourcemanager/util/util.go @@ -0,0 +1,52 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import ( + "time" + + "go.uber.org/atomic" +) + +var ( + // MinSchedulerInterval is the minimum interval between two scheduling. + MinSchedulerInterval = atomic.NewDuration(200 * time.Millisecond) +) + +// GorotinuePool is a pool interface +type GorotinuePool interface { + ReleaseAndWait() + Tune(size int) + LastTunerTs() time.Time + Cap() int + Running() int + Name() string +} + +// PoolContainer is a pool container +type PoolContainer struct { + Pool GorotinuePool + Component Component +} + +// Component is ID for difference component +type Component int + +const ( + // UNKNOWN is for unknown component. It is only for test + UNKNOWN Component = iota + // DDL is for ddl component + DDL +) diff --git a/roadmap.md b/roadmap.md index 92de0e67c7f34..a8b57db5440df 100644 --- a/roadmap.md +++ b/roadmap.md @@ -2,6 +2,8 @@ This roadmap brings you what's coming in the 1-year future, so you can see the new features or improvements in advance, follow the progress, learn about the key milestones on the way, and give feedback as the development work goes on. In the course of development, this roadmap is subject to change based on user needs and feedback. If you have a feature request or want to prioritize a feature, please file an issue on [GitHub](https://github.com/pingcap/tidb/issues). +✅: The feature or improvement is already available in TiDB. + > **Safe harbor statement:** > > *Any unreleased features discussed or referenced in our documents, roadmaps, blogs, websites, press releases, or public statements that are not currently available ("unreleased features") are subject to change at our discretion and may not be delivered as planned or at all. Customers acknowledge that purchase decisions are solely based on features and functions that are currently available, and that PingCAP is not obliged to deliver aforementioned unreleased features as part of the contractual agreement unless otherwise stated.* @@ -19,7 +21,7 @@ This roadmap brings you what's coming in the 1-year future, so you can see the n - + @@ -31,37 +33,39 @@ This roadmap brings you what's coming in the 1-year future, so you can see the n - - + + - + - + - + + + + + + + + + - + - + - - - - - @@ -82,9 +86,13 @@ This roadmap brings you what's coming in the 1-year future, so you can see the n - - - + + + + + + +
Scalability & StabilitySupport resource management framework.
  • ✅ Optimize resource isolation in heavy read scenarios.
  • ✅ Optimize resource isolation in heavy (batch) write scenarios.
  • Provide resource management capability for background process.
  • Support resource management framework.
  • Provide a basic resource management and control framework to effectively control the resource squeeze of background tasks on front-end tasks (user operations), and improve cluster stability.
  • Refine resource management in the multi-service aggregation scenario.
Support dynamic region size adjustment (heterogeneous) and huge region size for scenarios with fast business growth and a large amount of data.
SQLSupport the JSON function.
  • Expression index
  • Multi-value index
  • Partial index
  • -
SQLSupport the JSON function.
  • ✅ Expression index
  • Multi-value index
  • ✅ TiFlash supports JSON function pushdown
In business scenarios that require flexible schema definitions, the application can use JSON to store information for ODS, transaction indicators, commodities, game characters, and props.
Support cluster-level flashback.
  • ✅ Support cluster-level flashback.
  • ✅ Support database-level flashback.
In game rollback scenarios, the flashback can be used to achieve a fast rollback of the current cluster. This solves the common problems in the gaming industry such as version errors and bugs.
Support time to live (TTL).✅ Support time to live (TTL). This feature enables automatic data cleanup in limited data archiving scenarios.
Implement a DDL parallel execution framework.Support foreign key constraints.Supports foreign key constraints compatible with MySQL syntax, and provides DB-level referential integrity check capabilities.
✅ Support non-transactional DML for insert and update operations.
  • Implement a DDL parallel execution framework.
  • Provide DDL pause/resume capability.
Implement a distributed parallel DDL execution framework, so that DDL tasks executed by only one TiDB Owner node can be coordinated and executed by all TiDB nodes in the cluster. Improve the execution speed of DDL tasks and cluster resource utilization.
By converting the execution of DDL tasks to distributed mode, this feature accelerates the execution speed of DDL tasks and improves the utilization of computing resources in the entire cluster. At present, DDL tasks that need to improve the speed include large table indexing and lossy column type modification tasks.
Hybrid Transactional and Analytical Processing (HTAP)Support TiFlash result write-back.✅ Support TiFlash result write-back.

Support INSERT INTO SELECT.

  • Easily write analysis results in TiFlash back to TiDB.
  • Provide complete ACID transactions, more convenient and reliable than general ETL solutions.
  • Set a hard limit on the threshold of intermediate result size, and report an error if the threshold is exceeded.
  • Support fully distributed transactions, and remove or relax the limit on the intermediate result size.

These features combined enable a way to materialize intermediate results. The analysis results can be easily reused, which reduces unnecessary ad-hoc queries, improves the performance of BI and other applications (by pulling results directly) and reduces system load (by avoiding duplicated computation), thereby improving the overall data pipeline efficiency and reducing costs. It will make TiFlash an online service.

Support FastScan for TiFlash.✅ Support FastScan for TiFlash.
  • FastScan provides weak consistency but faster table scan capability.
  • Further optimize the join order, shuffle, and exchange algorithms to improve computing efficiency and boost performance for complex queries.
  • Add a fine-grained data sharding mechanism to optimize the COUNT(DISTINCT) function and high cardinality aggregation.

This feature improves the basic computing capability of TiFlash, and optimizes the performance and reliability of the underlying algorithms of the columnar storage and MPP engine.

ProxySupport TiDB proxy.Implement automatic load balancing so that upgrading a cluster or modifying configurations does not affect the application. After scaling out or scaling in the cluster, the application can automatically rebalance the connection without reconnecting.
In scenarios such as upgrades and configuration changes, TiDB proxy is more business-friendly.
Maintenance Support rule-based SQL blocklist.
SQL tuning for HTAP workloads
  • Provide SQL execution information from the perspective of applications.
  • Provide suggestions on optimizing SQL for TiFlash and TiKV in HTAP workloads.
  • Provide a dashboard that displays a SQL execution overview from the perspective of applications in HTAP workloads.
  • For one or several HTAP scenarios, provide suggestions on SQL optimization.
SQL tuning for HTAP workloadsProvide SQL execution information from the perspective of applications.Provide a dashboard that displays a SQL execution overview from the perspective of applications in HTAP workloads.
Provide suggestions on optimizing SQL for TiFlash and TiKV in HTAP workloads.For one or several HTAP scenarios, provide suggestions on SQL optimization.
@@ -112,17 +120,17 @@ This roadmap brings you what's coming in the 1-year future, so you can see the n Data replication to downstream systems via TiCDC - Reduce TiCDC replication latency in daily operations. - When TiKV, TiDB, PD, or TiCDC nodes are offline in a planned maintenance window, the replication latency of TiCDC can be reduced to less than 10 seconds. + Improve TiCDC scalability and reduce replication latency. + Increase TiCDC's scalability by spanning data changes for single table to multiple TiCDC nodes and reduce replication latency by removing sorting stage. - Support replicating data to object storage such as S3. + ✅ Support replicating data to object storage such as S3. TiCDC supports replicating data changes to common object storage services. Data migration - TiDB Lightning supports table-level and partition-level online data import. - TiDB Lightning provides comprehensive table-level and partition-level data import capabilities. + ✅ Continuous data verification during data migration. + DM supports online data verification during migration from MySQL compatible database to TiDB. @@ -138,25 +146,30 @@ This roadmap brings you what's coming in the 1-year future, so you can see the n - - Log redaction -
  • Support data redaction in execution plans in TiDB Dashboard.
  • Enhance data redaction in TiDB-related logs.
- Redact sensitive information in execution plans and various logs to enhance the security of user data. - Password complexity check - A strong password is required. + ✅ A strong password is required. To improve security, empty passwords and weak passwords are not allowed.
The required password length is not less than 8. The password must contain an uppercase letter, a lowercase letter, a number, and a character. Password expiration - TiDB provides password expiration management and requires users to change passwords regularly. + ✅ TiDB provides password expiration management and requires users to change passwords regularly. Reduce the security risk of password cracking or leakage caused by using the same password for a long time. - Password policy management - TiDB provides a password reuse mechanism and brute-force cracking prevention capabilities. - TiDB supports password policy management to protect password security. + Password reuse policy + ✅ TiDB provides a password reuse policy. + Restrict password reuse and improve password security. + + + Password anti-brute force cracking + ✅ Accounts will be locked in case of consecutive incorrect passwords. + Lock the account under continuous wrong passwords to prevent the password from being cracked by brute force. + + + Log redaction +
  • Support data redaction in execution plans in TiDB Dashboard.
  • Enhance data redaction in TiDB-related logs.
+ Redact sensitive information in execution plans and various logs to enhance the security of user data. Column-level access control diff --git a/server/BUILD.bazel b/server/BUILD.bazel index 9045b932c7f61..0d1303bf53993 100644 --- a/server/BUILD.bazel +++ b/server/BUILD.bazel @@ -9,6 +9,7 @@ go_library( "conn_stmt.go", "driver.go", "driver_tidb.go", + "extension.go", "http_handler.go", "http_status.go", "mock_conn.go", @@ -25,6 +26,7 @@ go_library( importpath = "github.com/pingcap/tidb/server", visibility = ["//visibility:public"], deps = [ + "//autoid_service", "//config", "//ddl", "//domain", @@ -32,6 +34,7 @@ go_library( "//errno", "//executor", "//expression", + "//extension", "//infoschema", "//kv", "//meta", @@ -55,6 +58,8 @@ go_library( "//sessionctx/stmtctx", "//sessionctx/variable", "//sessiontxn", + "//statistics/handle", + "//store", "//store/driver/error", "//store/gcworker", "//store/helper", @@ -77,6 +82,7 @@ go_library( "//util/memory", "//util/pdapi", "//util/printer", + "//util/replayer", "//util/sqlexec", "//util/sys/linux", "//util/timeutil", @@ -86,11 +92,13 @@ go_library( "//util/topsql/stmtstats", "//util/versioninfo", "@com_github_blacktear23_go_proxyprotocol//:go-proxyprotocol", + "@com_github_burntsushi_toml//:toml", "@com_github_gorilla_mux//:mux", "@com_github_opentracing_opentracing_go//:opentracing-go", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_fn//:fn", + "@com_github_pingcap_kvproto//pkg/autoid", "@com_github_pingcap_kvproto//pkg/coprocessor", "@com_github_pingcap_kvproto//pkg/diagnosticspb", "@com_github_pingcap_kvproto//pkg/kvrpcpb", @@ -117,7 +125,7 @@ go_library( go_test( name = "server_test", - timeout = "short", + timeout = "moderate", srcs = [ "column_test.go", "conn_stmt_test.go", @@ -151,6 +159,7 @@ go_test( "//errno", "//executor", "//expression", + "//extension", "//infoschema", "//kv", "//meta", @@ -168,6 +177,7 @@ go_test( "//sessionctx/binloginfo", "//sessionctx/stmtctx", "//sessionctx/variable", + "//sessiontxn", "//statistics/handle", "//store/helper", "//store/mockstore", @@ -187,6 +197,8 @@ go_test( "//util/plancodec", "//util/resourcegrouptag", "//util/rowcodec", + "//util/sqlexec", + "//util/syncutil", "//util/topsql", "//util/topsql/collector", "//util/topsql/collector/mock", diff --git a/server/conn.go b/server/conn.go index 478f86a821860..4d4300c099ecb 100644 --- a/server/conn.go +++ b/server/conn.go @@ -61,6 +61,7 @@ import ( "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" @@ -74,7 +75,6 @@ import ( "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/sessionctx/sessionstates" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" @@ -196,6 +196,7 @@ type clientConn struct { *TiDBContext // an interface to execute sql statements. } attrs map[string]string // attributes parsed from client handshake response, not used for now. + serverHost string // server host peerHost string // peer host peerPort string // peer port status int32 // dispatching/reading/shutdown/waitshutdown @@ -212,6 +213,7 @@ type clientConn struct { sync.RWMutex cancelFunc context.CancelFunc } + extensions *extension.SessionExtensions } func (cc *clientConn) getCtx() *TiDBContext { @@ -402,7 +404,7 @@ func (cc *clientConn) writeInitialHandshake(ctx context.Context) error { return err } } - defAuthPlugin, err := cc.ctx.GetSessionVars().GetGlobalSystemVar(variable.DefaultAuthPlugin) + defAuthPlugin, err := cc.ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.DefaultAuthPlugin) if err != nil { return err } @@ -678,6 +680,8 @@ func (cc *clientConn) readOptionalSSLRequestAndHandshakeResponse(ctx context.Con case mysql.AuthNativePassword: case mysql.AuthSocket: case mysql.AuthTiDBSessionToken: + case mysql.AuthTiDBAuthToken: + case mysql.AuthMySQLClearPassword: default: return errors.New("Unknown auth plugin") } @@ -706,6 +710,7 @@ func (cc *clientConn) handleAuthPlugin(ctx context.Context, resp *handshakeRespo case mysql.AuthNativePassword: case mysql.AuthSocket: case mysql.AuthTiDBSessionToken: + case mysql.AuthMySQLClearPassword: default: logutil.Logger(ctx).Warn("Unknown Auth Plugin", zap.String("plugin", resp.AuthPlugin)) } @@ -792,7 +797,7 @@ func (cc *clientConn) openSession() error { tlsState := cc.tlsConn.ConnectionState() tlsStatePtr = &tlsState } - ctx, err := cc.server.driver.OpenCtx(cc.connectionID, cc.capability, cc.collation, cc.dbname, tlsStatePtr) + ctx, err := cc.server.driver.OpenCtx(cc.connectionID, cc.capability, cc.collation, cc.dbname, tlsStatePtr, cc.extensions) if err != nil { return err } @@ -827,16 +832,8 @@ func (cc *clientConn) openSessionAndDoAuth(authData []byte, authPlugin string) e return errAccessDeniedNoPassword.FastGenByArgs(cc.user, host) } - userIdentity := &auth.UserIdentity{Username: cc.user, Hostname: host} - if authPlugin == mysql.AuthTiDBSessionToken { - if !cc.ctx.AuthWithoutVerification(userIdentity) { - return errAccessDenied.FastGenByArgs(cc.user, host, hasPassword) - } - if err = sessionstates.ValidateSessionToken(authData, cc.user); err != nil { - logutil.BgLogger().Warn("verify session token failed", zap.String("username", cc.user), zap.Error(err)) - return errAccessDenied.FastGenByArgs(cc.user, host, hasPassword) - } - } else if err = cc.ctx.Auth(userIdentity, authData, cc.salt); err != nil { + userIdentity := &auth.UserIdentity{Username: cc.user, Hostname: host, AuthPlugin: authPlugin} + if err = cc.ctx.Auth(userIdentity, authData, cc.salt); err != nil { return err } cc.ctx.SetPort(port) @@ -922,6 +919,9 @@ func (cc *clientConn) checkAuthPlugin(ctx context.Context, resp *handshakeRespon // method send by the client (*authPlugin) then we need to switch the authentication // method to match the one configured for that specific user. if (cc.authPlugin != userplugin) || (cc.authPlugin != resp.AuthPlugin) { + if userplugin == mysql.AuthTiDBAuthToken { + userplugin = mysql.AuthMySQLClearPassword + } if resp.Capability&mysql.ClientPluginAuth > 0 { authData, err := cc.authSwitchRequest(ctx, userplugin) if err != nil { @@ -945,6 +945,7 @@ func (cc *clientConn) PeerHost(hasPassword string) (host, port string, err error host = variable.DefHostname if cc.isUnixSocket { cc.peerHost = host + cc.serverHost = host return } addr := cc.bufReadConn.RemoteAddr().String() @@ -955,6 +956,15 @@ func (cc *clientConn) PeerHost(hasPassword string) (host, port string, err error } cc.peerHost = host cc.peerPort = port + + serverAddr := cc.bufReadConn.LocalAddr().String() + serverHost, _, err := net.SplitHostPort(serverAddr) + if err != nil { + err = errAccessDenied.GenWithStackByArgs(cc.user, addr, hasPassword) + return + } + cc.serverHost = serverHost + return } @@ -971,7 +981,7 @@ func (cc *clientConn) skipInitConnect() bool { // initResultEncoder initialize the result encoder for current connection. func (cc *clientConn) initResultEncoder(ctx context.Context) { - chs, err := cc.ctx.GetSessionVars().GetSessionOrGlobalSystemVar(variable.CharacterSetResults) + chs, err := cc.ctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), variable.CharacterSetResults) if err != nil { chs = "" logutil.Logger(ctx).Warn("get character_set_results system variable failed", zap.Error(err)) @@ -980,7 +990,7 @@ func (cc *clientConn) initResultEncoder(ctx context.Context) { } func (cc *clientConn) initInputEncoder(ctx context.Context) { - chs, err := cc.ctx.GetSessionVars().GetSessionOrGlobalSystemVar(variable.CharacterSetClient) + chs, err := cc.ctx.GetSessionVars().GetSessionOrGlobalSystemVar(context.Background(), variable.CharacterSetClient) if err != nil { chs = "" logutil.Logger(ctx).Warn("get character_set_client system variable failed", zap.Error(err)) @@ -1102,6 +1112,7 @@ func (cc *clientConn) Run(ctx context.Context) { startTime := time.Now() err = cc.dispatch(ctx, data) + cc.ctx.GetSessionVars().ClearAlloc(&cc.chunkAlloc, err != nil) cc.chunkAlloc.Reset() if err != nil { cc.audit(plugin.Error) // tell the plugin API there was a dispatch error @@ -1335,11 +1346,6 @@ func (cc *clientConn) dispatch(ctx context.Context, data []byte) error { } switch cmd { - case mysql.ComSleep: - // TODO: According to mysql document, this command is supposed to be used only internally. - // So it's just a temp fix, not sure if it's done right. - // Investigate this command and write test case later. - return nil case mysql.ComQuit: return io.EOF case mysql.ComInitDB: @@ -1376,6 +1382,11 @@ func (cc *clientConn) dispatch(ctx context.Context, data []byte) error { return cc.handleChangeUser(ctx, data) // ComBinlogDump, ComTableDump, ComConnectOut, ComRegisterSlave case mysql.ComStmtPrepare: + // For issue 39132, same as ComQuery + if len(data) > 0 && data[len(data)-1] == 0 { + data = data[:len(data)-1] + dataStr = string(hack.String(data)) + } return cc.handleStmtPrepare(ctx, dataStr) case mysql.ComStmtExecute: return cc.handleStmtExecute(ctx, data) @@ -1584,90 +1595,6 @@ func (cc *clientConn) writeReq(ctx context.Context, filePath string) error { return cc.flush(ctx) } -func insertDataWithCommit(ctx context.Context, prevData, - curData []byte, loadDataInfo *executor.LoadDataInfo) ([]byte, error) { - var err error - var reachLimit bool - for { - prevData, reachLimit, err = loadDataInfo.InsertData(ctx, prevData, curData) - if err != nil { - return nil, err - } - if !reachLimit { - break - } - // push into commit task queue - err = loadDataInfo.EnqOneTask(ctx) - if err != nil { - return prevData, err - } - curData = prevData - prevData = nil - } - return prevData, nil -} - -// processStream process input stream from network -func processStream(ctx context.Context, cc *clientConn, loadDataInfo *executor.LoadDataInfo, wg *sync.WaitGroup) { - var err error - var shouldBreak bool - var prevData, curData []byte - defer func() { - r := recover() - if r != nil { - logutil.Logger(ctx).Error("process routine panicked", - zap.Reflect("r", r), - zap.Stack("stack")) - } - if err != nil || r != nil { - loadDataInfo.ForceQuit() - } else { - loadDataInfo.CloseTaskQueue() - } - wg.Done() - }() - for { - curData, err = cc.readPacket() - if err != nil { - if terror.ErrorNotEqual(err, io.EOF) { - logutil.Logger(ctx).Error("read packet failed", zap.Error(err)) - break - } - } - if len(curData) == 0 { - loadDataInfo.Drained = true - shouldBreak = true - if len(prevData) == 0 { - break - } - } - select { - case <-loadDataInfo.QuitCh: - err = errors.New("processStream forced to quit") - default: - } - if err != nil { - break - } - // prepare batch and enqueue task - prevData, err = insertDataWithCommit(ctx, prevData, curData, loadDataInfo) - if err != nil { - break - } - if shouldBreak { - break - } - } - if err != nil { - logutil.Logger(ctx).Error("load data process stream error", zap.Error(err)) - return - } - if err = loadDataInfo.EnqOneTask(ctx); err != nil { - logutil.Logger(ctx).Error("load data process stream error", zap.Error(err)) - return - } -} - // handleLoadData does the additional work after processing the 'load data' query. // It sends client a file path, then reads the file content from client, inserts data into database. func (cc *clientConn) handleLoadData(ctx context.Context, loadDataInfo *executor.LoadDataInfo) error { @@ -1678,29 +1605,13 @@ func (cc *clientConn) handleLoadData(ctx context.Context, loadDataInfo *executor if loadDataInfo == nil { return errors.New("load data info is empty") } - if !loadDataInfo.Table.Meta().IsBaseTable() { - return errors.New("can only load data into base tables") - } + err := cc.writeReq(ctx, loadDataInfo.Path) if err != nil { return err } - loadDataInfo.InitQueues() - loadDataInfo.SetMaxRowsInBatch(uint64(loadDataInfo.Ctx.GetSessionVars().DMLBatchSize)) - loadDataInfo.StartStopWatcher() - // let stop watcher goroutine quit - defer loadDataInfo.ForceQuit() - err = sessiontxn.NewTxn(ctx, loadDataInfo.Ctx) - if err != nil { - return err - } - // processStream process input data, enqueue commit task - wg := new(sync.WaitGroup) - wg.Add(1) - go processStream(ctx, cc, loadDataInfo, wg) - err = loadDataInfo.CommitWork(ctx) - wg.Wait() + err = loadDataInfo.Load(ctx, cc.readPacket) if err != nil { if !loadDataInfo.Drained { logutil.Logger(ctx).Info("not drained yet, try reading left data from client connection") @@ -1849,10 +1760,13 @@ func (cc *clientConn) audit(eventType plugin.GeneralEvent) { // Query `load stats` does not return result either. func (cc *clientConn) handleQuery(ctx context.Context, sql string) (err error) { defer trace.StartRegion(ctx, "handleQuery").End() - sc := cc.ctx.GetSessionVars().StmtCtx + sessVars := cc.ctx.GetSessionVars() + sc := sessVars.StmtCtx prevWarns := sc.GetWarnings() var stmts []ast.StmtNode + cc.ctx.GetSessionVars().SetAlloc(cc.chunkAlloc) if stmts, err = cc.ctx.Parse(ctx, sql); err != nil { + cc.onExtensionSQLParseFailed(sql, err) return err } @@ -1889,14 +1803,30 @@ func (cc *clientConn) handleQuery(ctx context.Context, sql string) (err error) { // Only pre-build point plans for multi-statement query pointPlans, err = cc.prefetchPointPlanKeys(ctx, stmts) if err != nil { + for _, stmt := range stmts { + cc.onExtensionStmtEnd(stmt, false, err) + } return err } + metrics.NumOfMultiQueryHistogram.Observe(float64(len(stmts))) } if len(pointPlans) > 0 { defer cc.ctx.ClearValue(plannercore.PointPlanKey) } var retryable bool + var lastStmt ast.StmtNode + var expiredStmtTaskID uint64 for i, stmt := range stmts { + if lastStmt != nil { + cc.onExtensionStmtEnd(lastStmt, true, nil) + } + lastStmt = stmt + + // expiredTaskID is the task ID of the previous statement. When executing a stmt, + // the StmtCtx will be reinit and the TaskID will change. We can compare the StmtCtx.TaskID + // with the previous one to determine whether StmtCtx has been inited for the current stmt. + expiredStmtTaskID = sessVars.StmtCtx.TaskID + if len(pointPlans) > 0 { // Save the point plan in Session, so we don't need to build the point plan again. cc.ctx.SetValue(plannercore.PointPlanKey, plannercore.PointPlanVal{Plan: pointPlans[i]}) @@ -1936,6 +1866,11 @@ func (cc *clientConn) handleQuery(ctx context.Context, sql string) (err error) { } } } + + if lastStmt != nil { + cc.onExtensionStmtEnd(lastStmt, sessVars.StmtCtx.TaskID != expiredStmtTaskID, err) + } + return err } @@ -1976,7 +1911,7 @@ func (cc *clientConn) prefetchPointPlanKeys(ctx context.Context, stmts []ast.Stm } // TODO: the preprocess is run twice, we should find some way to avoid do it again. // TODO: handle the PreprocessorReturn. - if err = plannercore.Preprocess(cc.getCtx(), stmt); err != nil { + if err = plannercore.Preprocess(ctx, cc.getCtx(), stmt); err != nil { return nil, err } p := plannercore.TryFastPlan(cc.ctx.Session, stmt) @@ -2448,8 +2383,19 @@ func (cc *clientConn) handleChangeUser(ctx context.Context, data []byte) error { } pass := data[:passLen] data = data[passLen:] - dbName, _ := parseNullTermString(data) + dbName, data := parseNullTermString(data) cc.dbname = string(hack.String(dbName)) + pluginName := "" + if len(data) > 0 { + // skip character set + if cc.capability&mysql.ClientProtocol41 > 0 && len(data) >= 2 { + data = data[2:] + } + if cc.capability&mysql.ClientPluginAuth > 0 && len(data) > 0 { + pluginNameB, _ := parseNullTermString(data) + pluginName = string(hack.String(pluginNameB)) + } + } if err := cc.ctx.Close(); err != nil { logutil.Logger(ctx).Debug("close old context failed", zap.Error(err)) @@ -2460,7 +2406,24 @@ func (cc *clientConn) handleChangeUser(ctx context.Context, data []byte) error { if err != nil { return err } - if err := cc.openSessionAndDoAuth(pass, ""); err != nil { + fakeResp := &handshakeResponse41{ + Auth: pass, + AuthPlugin: pluginName, + Capability: cc.capability, + } + if fakeResp.AuthPlugin != "" { + failpoint.Inject("ChangeUserAuthSwitch", func(val failpoint.Value) { + failpoint.Return(errors.Errorf("%v", val)) + }) + newpass, err := cc.checkAuthPlugin(ctx, fakeResp) + if err != nil { + return err + } + if len(newpass) > 0 { + fakeResp.Auth = newpass + } + } + if err := cc.openSessionAndDoAuth(fakeResp.Auth, fakeResp.AuthPlugin); err != nil { return err } return cc.handleCommonConnectionReset(ctx) @@ -2477,7 +2440,7 @@ func (cc *clientConn) handleResetConnection(ctx context.Context) error { tlsState := cc.tlsConn.ConnectionState() tlsStatePtr = &tlsState } - tidbCtx, err := cc.server.driver.OpenCtx(cc.connectionID, cc.capability, cc.collation, cc.dbname, tlsStatePtr) + tidbCtx, err := cc.server.driver.OpenCtx(cc.connectionID, cc.capability, cc.collation, cc.dbname, tlsStatePtr, cc.extensions) if err != nil { return err } @@ -2497,8 +2460,10 @@ func (cc *clientConn) handleResetConnection(ctx context.Context) error { } func (cc *clientConn) handleCommonConnectionReset(ctx context.Context) error { - cc.ctx.GetSessionVars().ConnectionInfo = cc.connectInfo() + connectionInfo := cc.connectInfo() + cc.ctx.GetSessionVars().ConnectionInfo = connectionInfo + cc.onExtensionConnEvent(extension.ConnReset, nil) err := plugin.ForeachPlugin(plugin.Audit, func(p *plugin.Plugin) error { authPlugin := plugin.DeclareAuditManifest(p.Manifest) if authPlugin.OnConnectionEvent != nil { diff --git a/server/conn_stmt.go b/server/conn_stmt.go index ef92ea85abaf0..acb12ae660b94 100644 --- a/server/conn_stmt.go +++ b/server/conn_stmt.go @@ -158,6 +158,13 @@ func (cc *clientConn) handleStmtExecute(ctx context.Context, data []byte) (err e return mysql.NewErrf(mysql.ErrUnknown, "unsupported flag: CursorTypeScrollable", nil) } + if useCursor { + cc.ctx.GetSessionVars().SetStatusFlag(mysql.ServerStatusCursorExists, true) + defer cc.ctx.GetSessionVars().SetStatusFlag(mysql.ServerStatusCursorExists, false) + } else { + // not using streaming ,can reuse chunk + cc.ctx.GetSessionVars().SetAlloc(cc.chunkAlloc) + } // skip iteration-count, always 1 pos += 4 @@ -200,7 +207,15 @@ func (cc *clientConn) handleStmtExecute(ctx context.Context, data []byte) (err e return errors.Annotate(err, cc.preparedStmt2String(stmtID)) } } - return cc.executePlanCacheStmt(ctx, stmt, args, useCursor) + + sessVars := cc.ctx.GetSessionVars() + // expiredTaskID is the task ID of the previous statement. When executing a stmt, + // the StmtCtx will be reinit and the TaskID will change. We can compare the StmtCtx.TaskID + // with the previous one to determine whether StmtCtx has been inited for the current stmt. + expiredTaskID := sessVars.StmtCtx.TaskID + err = cc.executePlanCacheStmt(ctx, stmt, args, useCursor) + cc.onExtensionBinaryExecuteEnd(stmt, args, sessVars.StmtCtx.TaskID != expiredTaskID, err) + return err } func (cc *clientConn) executePlanCacheStmt(ctx context.Context, stmt interface{}, args []expression.Expression, useCursor bool) (err error) { @@ -239,7 +254,8 @@ func (cc *clientConn) executePlanCacheStmt(ctx context.Context, stmt interface{} // The first return value indicates whether the call of executePreparedStmtAndWriteResult has no side effect and can be retried. // Currently the first return value is used to fallback to TiKV when TiFlash is down. func (cc *clientConn) executePreparedStmtAndWriteResult(ctx context.Context, stmt PreparedStatement, args []expression.Expression, useCursor bool) (bool, error) { - prepStmt, err := (&cc.ctx).GetSessionVars().GetPreparedStmtByID(uint32(stmt.ID())) + vars := (&cc.ctx).GetSessionVars() + prepStmt, err := vars.GetPreparedStmtByID(uint32(stmt.ID())) if err != nil { return true, errors.Annotate(err, cc.preparedStmt2String(uint32(stmt.ID()))) } @@ -252,9 +268,14 @@ func (cc *clientConn) executePreparedStmtAndWriteResult(ctx context.Context, stm return true, errors.Annotate(err, cc.preparedStmt2String(uint32(stmt.ID()))) } if rs == nil { + if useCursor { + vars.SetStatusFlag(mysql.ServerStatusCursorExists, false) + } return false, cc.writeOK(ctx) } - if result, ok := rs.(*tidbResultSet); ok { + // since there are multiple implementations of ResultSet (the rs might be wrapped), we have to unwrap the rs before + // casting it to *tidbResultSet. + if result, ok := unwrapResultSet(rs).(*tidbResultSet); ok { if planCacheStmt, ok := prepStmt.(*plannercore.PlanCacheStmt); ok { result.preparedStmt = planCacheStmt } @@ -266,6 +287,12 @@ func (cc *clientConn) executePreparedStmtAndWriteResult(ctx context.Context, stm if useCursor { cc.initResultEncoder(ctx) defer cc.rsEncoder.clean() + // fix https://github.com/pingcap/tidb/issues/39447. we need to hold the start-ts here because the process info + // will be set to sleep after fetch returned. + if pi := cc.ctx.ShowProcess(); pi != nil && pi.ProtectedTSList != nil && pi.CurTxnStartTS > 0 { + unhold := pi.HoldTS(pi.CurTxnStartTS) + rs = &rsWithHooks{ResultSet: rs, onClosed: unhold} + } stmt.StoreResultSet(rs) if err = cc.writeColumnInfo(rs.Columns()); err != nil { return false, err @@ -274,7 +301,7 @@ func (cc *clientConn) executePreparedStmtAndWriteResult(ctx context.Context, stm cl.OnFetchReturned() } // explicitly flush columnInfo to client. - err = cc.writeEOF(ctx, cc.ctx.Status()|mysql.ServerStatusCursorExists) + err = cc.writeEOF(ctx, cc.ctx.Status()) if err != nil { return false, err } @@ -295,6 +322,9 @@ const ( func (cc *clientConn) handleStmtFetch(ctx context.Context, data []byte) (err error) { cc.ctx.GetSessionVars().StartTime = time.Now() + cc.ctx.GetSessionVars().ClearAlloc(nil, false) + cc.ctx.GetSessionVars().SetStatusFlag(mysql.ServerStatusCursorExists, true) + defer cc.ctx.GetSessionVars().SetStatusFlag(mysql.ServerStatusCursorExists, false) stmtID, fetchSize, err := parseStmtFetchCmd(data) if err != nil { @@ -323,7 +353,7 @@ func (cc *clientConn) handleStmtFetch(ctx context.Context, data []byte) (err err strconv.FormatUint(uint64(stmtID), 10), "stmt_fetch_rs"), cc.preparedStmt2String(stmtID)) } - _, err = cc.writeResultset(ctx, rs, true, cc.ctx.Status()|mysql.ServerStatusCursorExists, int(fetchSize)) + _, err = cc.writeResultset(ctx, rs, true, cc.ctx.Status(), int(fetchSize)) if err != nil { return errors.Annotate(err, cc.preparedStmt2String(stmtID)) } diff --git a/server/conn_stmt_test.go b/server/conn_stmt_test.go index 1b8ea55e61c35..366e5c54ac222 100644 --- a/server/conn_stmt_test.go +++ b/server/conn_stmt_test.go @@ -15,12 +15,16 @@ package server import ( + "bytes" + "context" + "encoding/binary" "testing" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" ) @@ -251,3 +255,145 @@ func TestParseStmtFetchCmd(t *testing.T) { require.Equal(t, tc.err, err) } } + +func TestCursorReadHoldTS(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + srv := CreateMockServer(t, store) + srv.SetDomain(dom) + defer srv.Close() + + appendUint32 := binary.LittleEndian.AppendUint32 + ctx := context.Background() + c := CreateMockConn(t, srv) + tk := testkit.NewTestKitWithSession(t, store, c.Context().Session) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int primary key)") + tk.MustExec("insert into t values (1), (2), (3), (4), (5), (6), (7), (8)") + tk.MustQuery("select count(*) from t").Check(testkit.Rows("8")) + + stmt, _, _, err := c.Context().Prepare("select * from t") + require.NoError(t, err) + require.Zero(t, tk.Session().ShowProcess().GetMinStartTS(0)) + + // should hold ts after executing stmt with cursor + require.NoError(t, c.Dispatch(ctx, append( + appendUint32([]byte{mysql.ComStmtExecute}, uint32(stmt.ID())), + mysql.CursorTypeReadOnly, 0x1, 0x0, 0x0, 0x0, + ))) + ts := tk.Session().ShowProcess().GetMinStartTS(0) + require.Positive(t, ts) + // should unhold ts when result set exhausted + require.NoError(t, c.Dispatch(ctx, appendUint32(appendUint32([]byte{mysql.ComStmtFetch}, uint32(stmt.ID())), 5))) + require.Equal(t, ts, tk.Session().ShowProcess().GetMinStartTS(0)) + require.Equal(t, ts, srv.GetMinStartTS(0)) + require.NoError(t, c.Dispatch(ctx, appendUint32(appendUint32([]byte{mysql.ComStmtFetch}, uint32(stmt.ID())), 5))) + require.Equal(t, ts, tk.Session().ShowProcess().GetMinStartTS(0)) + require.Equal(t, ts, srv.GetMinStartTS(0)) + require.NoError(t, c.Dispatch(ctx, appendUint32(appendUint32([]byte{mysql.ComStmtFetch}, uint32(stmt.ID())), 5))) + require.Zero(t, tk.Session().ShowProcess().GetMinStartTS(0)) + + // should hold ts after executing stmt with cursor + require.NoError(t, c.Dispatch(ctx, append( + appendUint32([]byte{mysql.ComStmtExecute}, uint32(stmt.ID())), + mysql.CursorTypeReadOnly, 0x1, 0x0, 0x0, 0x0, + ))) + require.Positive(t, tk.Session().ShowProcess().GetMinStartTS(0)) + // should unhold ts when stmt reset + require.NoError(t, c.Dispatch(ctx, appendUint32([]byte{mysql.ComStmtReset}, uint32(stmt.ID())))) + require.Zero(t, tk.Session().ShowProcess().GetMinStartTS(0)) + + // should hold ts after executing stmt with cursor + require.NoError(t, c.Dispatch(ctx, append( + appendUint32([]byte{mysql.ComStmtExecute}, uint32(stmt.ID())), + mysql.CursorTypeReadOnly, 0x1, 0x0, 0x0, 0x0, + ))) + require.Positive(t, tk.Session().ShowProcess().GetMinStartTS(0)) + // should unhold ts when stmt closed + require.NoError(t, c.Dispatch(ctx, appendUint32([]byte{mysql.ComStmtClose}, uint32(stmt.ID())))) + require.Zero(t, tk.Session().ShowProcess().GetMinStartTS(0)) + + // create another 2 stmts and execute them + stmt1, _, _, err := c.Context().Prepare("select * from t") + require.NoError(t, err) + require.NoError(t, c.Dispatch(ctx, append( + appendUint32([]byte{mysql.ComStmtExecute}, uint32(stmt1.ID())), + mysql.CursorTypeReadOnly, 0x1, 0x0, 0x0, 0x0, + ))) + ts1 := tk.Session().ShowProcess().GetMinStartTS(0) + require.Positive(t, ts1) + stmt2, _, _, err := c.Context().Prepare("select * from t") + require.NoError(t, err) + require.NoError(t, c.Dispatch(ctx, append( + appendUint32([]byte{mysql.ComStmtExecute}, uint32(stmt2.ID())), + mysql.CursorTypeReadOnly, 0x1, 0x0, 0x0, 0x0, + ))) + ts2 := tk.Session().ShowProcess().GetMinStartTS(ts1) + require.Positive(t, ts2) + + require.Less(t, ts1, ts2) + require.Equal(t, ts1, srv.GetMinStartTS(0)) + require.Equal(t, ts2, srv.GetMinStartTS(ts1)) + require.Zero(t, srv.GetMinStartTS(ts2)) + + // should unhold all when session closed + c.Close() + require.Zero(t, tk.Session().ShowProcess().GetMinStartTS(0)) + require.Zero(t, srv.GetMinStartTS(0)) +} + +func TestCursorExistsFlag(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + srv := CreateMockServer(t, store) + srv.SetDomain(dom) + defer srv.Close() + + appendUint32 := binary.LittleEndian.AppendUint32 + ctx := context.Background() + c := CreateMockConn(t, srv).(*mockConn) + out := new(bytes.Buffer) + c.pkt.bufWriter.Reset(out) + c.capability |= mysql.ClientDeprecateEOF | mysql.ClientProtocol41 + tk := testkit.NewTestKitWithSession(t, store, c.Context().Session) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int primary key)") + tk.MustExec("insert into t values (1), (2), (3), (4), (5), (6), (7), (8)") + tk.MustQuery("select count(*) from t").Check(testkit.Rows("8")) + + getLastStatus := func() uint16 { + raw := out.Bytes() + return binary.LittleEndian.Uint16(raw[len(raw)-4 : len(raw)-2]) + } + + stmt, _, _, err := c.Context().Prepare("select * from t") + require.NoError(t, err) + + require.NoError(t, c.Dispatch(ctx, append( + appendUint32([]byte{mysql.ComStmtExecute}, uint32(stmt.ID())), + mysql.CursorTypeReadOnly, 0x1, 0x0, 0x0, 0x0, + ))) + require.True(t, mysql.HasCursorExistsFlag(getLastStatus())) + + // fetch first 5 + require.NoError(t, c.Dispatch(ctx, appendUint32(appendUint32([]byte{mysql.ComStmtFetch}, uint32(stmt.ID())), 5))) + require.True(t, mysql.HasCursorExistsFlag(getLastStatus())) + + // COM_QUERY during fetch + require.NoError(t, c.Dispatch(ctx, append([]byte{mysql.ComQuery}, "select * from t"...))) + require.False(t, mysql.HasCursorExistsFlag(getLastStatus())) + + // fetch last 3 + require.NoError(t, c.Dispatch(ctx, appendUint32(appendUint32([]byte{mysql.ComStmtFetch}, uint32(stmt.ID())), 5))) + require.True(t, mysql.HasCursorExistsFlag(getLastStatus())) + + // final fetch with no row retured + // (tidb doesn't unset cursor-exists flag in the previous response like mysql, one more fetch is needed) + require.NoError(t, c.Dispatch(ctx, appendUint32(appendUint32([]byte{mysql.ComStmtFetch}, uint32(stmt.ID())), 5))) + require.False(t, mysql.HasCursorExistsFlag(getLastStatus())) + require.True(t, getLastStatus()&mysql.ServerStatusLastRowSend > 0) + + // COM_QUERY after fetch + require.NoError(t, c.Dispatch(ctx, append([]byte{mysql.ComQuery}, "select * from t"...))) + require.False(t, mysql.HasCursorExistsFlag(getLastStatus())) +} diff --git a/server/conn_test.go b/server/conn_test.go index 3c6edcf30bba7..9f8033cd1f98d 100644 --- a/server/conn_test.go +++ b/server/conn_test.go @@ -31,8 +31,10 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/session" @@ -351,7 +353,7 @@ func TestDispatch(t *testing.T) { { com: mysql.ComSleep, in: nil, - err: nil, + err: mysql.NewErrf(mysql.ErrUnknown, "command %d not supported now", nil, mysql.ComSleep), out: nil, }, { @@ -470,7 +472,7 @@ func TestDispatchClientProtocol41(t *testing.T) { { com: mysql.ComSleep, in: nil, - err: nil, + err: mysql.NewErrf(mysql.ErrUnknown, "command %d not supported now", nil, mysql.ComSleep), out: nil, }, { @@ -582,6 +584,33 @@ func TestDispatchClientProtocol41(t *testing.T) { testDispatch(t, inputs, mysql.ClientProtocol41) } +func TestQueryEndWithZero(t *testing.T) { + inputs := []dispatchInput{ + { + com: mysql.ComStmtPrepare, + in: append([]byte("select 1"), 0x0), + err: nil, + out: []byte{ + 0xc, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, + 0x0, 0x0, 0x1, 0x3, 0x64, 0x65, 0x66, 0x0, 0x0, 0x0, 0x1, 0x31, 0x1, 0x31, 0xc, 0x3f, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x8, 0x81, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, 0xfe, + }, + }, + { + com: mysql.ComQuery, + in: append([]byte("select 1"), 0x0), + err: nil, + out: []byte{ + 0x1, 0x0, 0x0, 0x3, 0x1, 0x18, 0x0, 0x0, 0x4, 0x3, 0x64, 0x65, 0x66, 0x0, 0x0, 0x0, + 0x1, 0x31, 0x1, 0x31, 0xc, 0x3f, 0x0, 0x1, 0x0, 0x0, 0x0, 0x8, 0x81, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x5, 0xfe, 0x2, 0x0, 0x0, 0x6, 0x1, 0x31, 0x1, 0x0, 0x0, 0x7, 0xfe, + }, + }, + } + + testDispatch(t, inputs, 0) +} + func testDispatch(t *testing.T, inputs []dispatchInput, capability uint32) { store := testkit.CreateMockStore(t) @@ -727,6 +756,11 @@ func TestConnExecutionTimeout(t *testing.T) { err = cc.handleQuery(context.Background(), "select /*+ MAX_EXECUTION_TIME(100)*/ * FROM testTable2 WHERE SLEEP(1);") require.NoError(t, err) + + tk.MustExec("set @@max_execution_time = 500;") + + err = cc.handleQuery(context.Background(), "alter table testTable2 add index idx(age);") + require.NoError(t, err) } func TestShutDown(t *testing.T) { @@ -851,6 +885,7 @@ func TestTiFlashFallback(t *testing.T) { cc.setCtx(&TiDBContext{Session: tk.Session(), stmts: make(map[int]*TiDBStatement)}) tk.MustExec("drop table if exists t") + tk.MustExec("set tidb_cost_model_version=1") tk.MustExec("create table t(a int not null primary key, b int not null)") tk.MustExec("alter table t set tiflash replica 1") tb := external.GetTableByName(t, tk, "test", "t") @@ -1358,6 +1393,56 @@ func TestHandleAuthPlugin(t *testing.T) { require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/server/FakeUser")) } +func TestChangeUserAuth(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("create user user1") + + cfg := newTestConfig() + cfg.Port = 0 + cfg.Status.StatusPort = 0 + + drv := NewTiDBDriver(store) + srv, err := NewServer(cfg, drv) + require.NoError(t, err) + + cc := &clientConn{ + connectionID: 1, + alloc: arena.NewAllocator(1024), + chunkAlloc: chunk.NewAllocator(), + peerHost: "localhost", + collation: mysql.DefaultCollationID, + capability: defaultCapability, + pkt: &packetIO{ + bufWriter: bufio.NewWriter(bytes.NewBuffer(nil)), + }, + server: srv, + user: "root", + } + ctx := context.Background() + se, _ := session.CreateSession4Test(store) + tc := &TiDBContext{ + Session: se, + stmts: make(map[int]*TiDBStatement), + } + cc.setCtx(tc) + + data := []byte{} + data = append(data, "user1"...) + data = append(data, 0) + data = append(data, 1) + data = append(data, 0) + data = append(data, "test"...) + data = append(data, 0) + data = append(data, 0, 0) + data = append(data, "unknown"...) + data = append(data, 0) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/server/ChangeUserAuthSwitch", fmt.Sprintf("return(\"%s\")", t.Name()))) + err = cc.handleChangeUser(ctx, data) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/server/ChangeUserAuthSwitch")) + require.EqualError(t, err, t.Name()) +} + func TestAuthPlugin2(t *testing.T) { store := testkit.CreateMockStore(t) @@ -1399,31 +1484,32 @@ func TestAuthPlugin2(t *testing.T) { require.NoError(t, err) } -func TestAuthTokenPlugin(t *testing.T) { - store := testkit.CreateMockStore(t) +func TestAuthSessionTokenPlugin(t *testing.T) { + // create the cert + tempDir := t.TempDir() + certPath := filepath.Join(tempDir, "test1_cert.pem") + keyPath := filepath.Join(tempDir, "test1_key.pem") + err := util.CreateCertificates(certPath, keyPath, 1024, x509.RSA, x509.UnknownSignatureAlgorithm) + require.NoError(t, err) - cfg := newTestConfig() + cfg := config.GetGlobalConfig() + cfg.Security.SessionTokenSigningCert = certPath + cfg.Security.SessionTokenSigningKey = keyPath cfg.Port = 0 cfg.Status.StatusPort = 0 + + // The global config is read during creating the store. + store := testkit.CreateMockStore(t) drv := NewTiDBDriver(store) srv, err := NewServer(cfg, drv) require.NoError(t, err) ctx := context.Background() - // create the cert - tempDir := t.TempDir() - certPath := filepath.Join(tempDir, "test1_cert.pem") - keyPath := filepath.Join(tempDir, "test1_key.pem") - err = util.CreateCertificates(certPath, keyPath, 4096, x509.RSA, x509.UnknownSignatureAlgorithm) - require.NoError(t, err) - tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER auth_session_token") tk.MustExec("CREATE USER another_user") - tk.MustExec(fmt.Sprintf("set global %s='%s'", variable.TiDBAuthSigningCert, certPath)) - tk.MustExec(fmt.Sprintf("set global %s='%s'", variable.TiDBAuthSigningKey, keyPath)) - tc, err := drv.OpenCtx(uint64(0), 0, uint8(mysql.DefaultCollationID), "", nil) + tc, err := drv.OpenCtx(uint64(0), 0, uint8(mysql.DefaultCollationID), "", nil, nil) require.NoError(t, err) cc := &clientConn{ connectionID: 1, @@ -1442,8 +1528,7 @@ func TestAuthTokenPlugin(t *testing.T) { tk1 := testkit.NewTestKitWithSession(t, store, tc.Session) tc.Session.GetSessionVars().ConnectionInfo = cc.connectInfo() tk1.Session().Auth(&auth.UserIdentity{Username: "auth_session_token", Hostname: "localhost"}, nil, nil) - err = tk1.QueryToErr("show session_states") - require.ErrorContains(t, err, "secure transport") + tk1.MustQuery("show session_states") // create a token with TLS cc.tlsConn = &tls.Conn{} @@ -1470,6 +1555,13 @@ func TestAuthTokenPlugin(t *testing.T) { err = cc.openSessionAndDoAuth(resp.Auth, resp.AuthPlugin) require.NoError(t, err) + // login succeeds even if the password expires now + tk.MustExec("ALTER USER auth_session_token PASSWORD EXPIRE") + err = cc.openSessionAndDoAuth([]byte{}, mysql.AuthNativePassword) + require.ErrorContains(t, err, "Your password has expired") + err = cc.openSessionAndDoAuth(resp.Auth, resp.AuthPlugin) + require.NoError(t, err) + // wrong token should fail tokenBytes[0] ^= 0xff err = cc.openSessionAndDoAuth(resp.Auth, resp.AuthPlugin) @@ -1583,3 +1675,134 @@ func TestOkEof(t *testing.T) { require.Equal(t, mysql.EOFHeader, outBuffer.Bytes()[4]) require.Equal(t, []byte{0x7, 0x0, 0x0, 0x1, 0xfe, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, outBuffer.Bytes()) } + +func TestExtensionChangeUser(t *testing.T) { + defer extension.Reset() + extension.Reset() + + logged := false + var logTp extension.ConnEventTp + var logInfo *extension.ConnEventInfo + require.NoError(t, extension.Register("test", extension.WithSessionHandlerFactory(func() *extension.SessionHandler { + return &extension.SessionHandler{ + OnConnectionEvent: func(tp extension.ConnEventTp, info *extension.ConnEventInfo) { + require.False(t, logged) + logTp = tp + logInfo = info + logged = true + }, + } + }))) + + extensions, err := extension.GetExtensions() + require.NoError(t, err) + + store := testkit.CreateMockStore(t) + + var outBuffer bytes.Buffer + tidbdrv := NewTiDBDriver(store) + cfg := newTestConfig() + cfg.Port, cfg.Status.StatusPort = 0, 0 + cfg.Status.ReportStatus = false + server, err := NewServer(cfg, tidbdrv) + require.NoError(t, err) + defer server.Close() + + cc := &clientConn{ + connectionID: 1, + salt: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14}, + server: server, + pkt: &packetIO{ + bufWriter: bufio.NewWriter(&outBuffer), + }, + collation: mysql.DefaultCollationID, + peerHost: "localhost", + alloc: arena.NewAllocator(512), + chunkAlloc: chunk.NewAllocator(), + capability: mysql.ClientProtocol41, + extensions: extensions.NewSessionExtensions(), + } + + tk := testkit.NewTestKit(t, store) + ctx := &TiDBContext{Session: tk.Session()} + cc.setCtx(ctx) + tk.MustExec("create user user1") + tk.MustExec("create user user2") + tk.MustExec("create database db1") + tk.MustExec("create database db2") + tk.MustExec("grant select on db1.* to user1@'%'") + tk.MustExec("grant select on db2.* to user2@'%'") + + // change user. + doDispatch := func(req dispatchInput) { + inBytes := append([]byte{req.com}, req.in...) + err = cc.dispatch(context.Background(), inBytes) + require.Equal(t, req.err, err) + if err == nil { + err = cc.flush(context.TODO()) + require.NoError(t, err) + require.Equal(t, req.out, outBuffer.Bytes()) + } else { + _ = cc.flush(context.TODO()) + } + outBuffer.Reset() + } + + expectedConnInfo := extension.ConnEventInfo{ + ConnectionInfo: cc.connectInfo(), + ActiveRoles: []*auth.RoleIdentity{}, + } + expectedConnInfo.User = "user1" + expectedConnInfo.DB = "db1" + + require.False(t, logged) + userData := append([]byte("user1"), 0x0, 0x0) + userData = append(userData, []byte("db1")...) + userData = append(userData, 0x0) + doDispatch(dispatchInput{ + com: mysql.ComChangeUser, + in: userData, + err: nil, + out: []byte{0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, + }) + require.True(t, logged) + require.Equal(t, extension.ConnReset, logTp) + require.Equal(t, expectedConnInfo.ActiveRoles, logInfo.ActiveRoles) + require.Equal(t, expectedConnInfo.Error, logInfo.Error) + require.Equal(t, *(expectedConnInfo.ConnectionInfo), *(logInfo.ConnectionInfo)) + + logged = false + logTp = 0 + logInfo = nil + expectedConnInfo.User = "user2" + expectedConnInfo.DB = "db2" + userData = append([]byte("user2"), 0x0, 0x0) + userData = append(userData, []byte("db2")...) + userData = append(userData, 0x0) + doDispatch(dispatchInput{ + com: mysql.ComChangeUser, + in: userData, + err: nil, + out: []byte{0x7, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, + }) + require.True(t, logged) + require.Equal(t, extension.ConnReset, logTp) + require.Equal(t, expectedConnInfo.ActiveRoles, logInfo.ActiveRoles) + require.Equal(t, expectedConnInfo.Error, logInfo.Error) + require.Equal(t, *(expectedConnInfo.ConnectionInfo), *(logInfo.ConnectionInfo)) + + logged = false + logTp = 0 + logInfo = nil + doDispatch(dispatchInput{ + com: mysql.ComResetConnection, + in: nil, + err: nil, + out: []byte{0x7, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, + }) + require.True(t, logged) + require.Equal(t, extension.ConnReset, logTp) + require.Equal(t, expectedConnInfo.ActiveRoles, logInfo.ActiveRoles) + require.Equal(t, expectedConnInfo.Error, logInfo.Error) + require.Equal(t, *(expectedConnInfo.ConnectionInfo), *(logInfo.ConnectionInfo)) +} diff --git a/server/driver.go b/server/driver.go index a805e531f056a..a4a59f4cba2b5 100644 --- a/server/driver.go +++ b/server/driver.go @@ -19,13 +19,14 @@ import ( "crypto/tls" "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/util/chunk" ) // IDriver opens IContext. type IDriver interface { // OpenCtx opens an IContext with connection id, client capability, collation, dbname and optionally the tls state. - OpenCtx(connID uint64, capability uint32, collation uint8, dbname string, tlsState *tls.ConnectionState) (*TiDBContext, error) + OpenCtx(connID uint64, capability uint32, collation uint8, dbname string, tlsState *tls.ConnectionState, extensions *extension.SessionExtensions) (*TiDBContext, error) } // PreparedStatement is the interface to use a prepared statement. diff --git a/server/driver_tidb.go b/server/driver_tidb.go index ff70903c01045..7b25a998d618b 100644 --- a/server/driver_tidb.go +++ b/server/driver_tidb.go @@ -23,6 +23,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/charset" @@ -191,7 +192,7 @@ func (ts *TiDBStatement) Close() error { } // OpenCtx implements IDriver. -func (qd *TiDBDriver) OpenCtx(connID uint64, capability uint32, collation uint8, dbname string, tlsState *tls.ConnectionState) (*TiDBContext, error) { +func (qd *TiDBDriver) OpenCtx(connID uint64, capability uint32, collation uint8, dbname string, tlsState *tls.ConnectionState, extensions *extension.SessionExtensions) (*TiDBContext, error) { se, err := session.CreateSession(qd.store) if err != nil { return nil, err @@ -208,6 +209,7 @@ func (qd *TiDBDriver) OpenCtx(connID uint64, capability uint32, collation uint8, stmts: make(map[int]*TiDBStatement), } se.SetSessionStatesHandler(sessionstates.StatePrepareStmt, tc) + se.SetExtensions(extensions) return tc, nil } @@ -221,12 +223,26 @@ func (tc *TiDBContext) WarningCount() uint16 { return tc.GetSessionVars().StmtCtx.WarningCount() } +func (tc *TiDBContext) checkSandBoxMode(stmt ast.StmtNode) error { + if !tc.Session.GetSessionVars().InRestrictedSQL && tc.InSandBoxMode() { + switch stmt.(type) { + case *ast.SetPwdStmt, *ast.AlterUserStmt: + default: + return errMustChangePassword.GenWithStackByArgs() + } + } + return nil +} + // ExecuteStmt implements QueryCtx interface. func (tc *TiDBContext) ExecuteStmt(ctx context.Context, stmt ast.StmtNode) (ResultSet, error) { var rs sqlexec.RecordSet var err error - if s, ok := stmt.(*ast.NonTransactionalDeleteStmt); ok { - rs, err = session.HandleNonTransactionalDelete(ctx, s, tc.Session) + if err = tc.checkSandBoxMode(stmt); err != nil { + return nil, err + } + if s, ok := stmt.(*ast.NonTransactionalDMLStmt); ok { + rs, err = session.HandleNonTransactionalDML(ctx, s, tc.Session) } else { rs, err = tc.Session.ExecuteStmt(ctx, stmt) } @@ -464,6 +480,46 @@ func (trs *tidbResultSet) Columns() []*ColumnInfo { return trs.columns } +// rsWithHooks wraps a ResultSet with some hooks (currently only onClosed). +type rsWithHooks struct { + ResultSet + onClosed func() +} + +// Close implements ResultSet#Close +func (rs *rsWithHooks) Close() error { + closed := rs.IsClosed() + err := rs.ResultSet.Close() + if !closed && rs.onClosed != nil { + rs.onClosed() + } + return err +} + +// OnFetchReturned implements fetchNotifier#OnFetchReturned +func (rs *rsWithHooks) OnFetchReturned() { + if impl, ok := rs.ResultSet.(fetchNotifier); ok { + impl.OnFetchReturned() + } +} + +// Unwrap returns the underlying result set +func (rs *rsWithHooks) Unwrap() ResultSet { + return rs.ResultSet +} + +// unwrapResultSet likes errors.Cause but for ResultSet +func unwrapResultSet(rs ResultSet) ResultSet { + var unRS ResultSet + if u, ok := rs.(interface{ Unwrap() ResultSet }); ok { + unRS = u.Unwrap() + } + if unRS == nil { + return rs + } + return unwrapResultSet(unRS) +} + func convertColumnInfo(fld *ast.ResultField) (ci *ColumnInfo) { ci = &ColumnInfo{ Name: fld.ColumnAsName.O, diff --git a/server/driver_tidb_test.go b/server/driver_tidb_test.go index b5f7e670aded0..b56632937e078 100644 --- a/server/driver_tidb_test.go +++ b/server/driver_tidb_test.go @@ -22,6 +22,7 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/sqlexec" "github.com/stretchr/testify/require" ) @@ -95,3 +96,27 @@ func TestConvertColumnInfo(t *testing.T) { colInfo = convertColumnInfo(&resultField) require.Equal(t, uint32(4), colInfo.ColumnLength) } + +func TestRSWithHooks(t *testing.T) { + closeCount := 0 + rs := &rsWithHooks{ + ResultSet: &tidbResultSet{recordSet: new(sqlexec.SimpleRecordSet)}, + onClosed: func() { closeCount++ }, + } + require.Equal(t, 0, closeCount) + rs.Close() + require.Equal(t, 1, closeCount) + rs.Close() + require.Equal(t, 1, closeCount) +} + +func TestUnwrapRS(t *testing.T) { + var nilRS ResultSet + require.Nil(t, unwrapResultSet(nilRS)) + rs0 := new(tidbResultSet) + rs1 := &rsWithHooks{ResultSet: rs0} + rs2 := &rsWithHooks{ResultSet: rs1} + for _, rs := range []ResultSet{rs0, rs1, rs2} { + require.Equal(t, rs0, unwrapResultSet(rs)) + } +} diff --git a/server/extension.go b/server/extension.go new file mode 100644 index 0000000000000..c7cf018eb85a8 --- /dev/null +++ b/server/extension.go @@ -0,0 +1,247 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "fmt" + + "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/extension" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/types" +) + +func (cc *clientConn) onExtensionConnEvent(tp extension.ConnEventTp, err error) { + if cc.extensions == nil { + return + } + + var connInfo *variable.ConnectionInfo + var activeRoles []*auth.RoleIdentity + if ctx := cc.getCtx(); ctx != nil { + sessVars := ctx.GetSessionVars() + connInfo = sessVars.ConnectionInfo + activeRoles = sessVars.ActiveRoles + } + + if connInfo == nil { + connInfo = cc.connectInfo() + } + + info := &extension.ConnEventInfo{ + ConnectionInfo: connInfo, + ActiveRoles: activeRoles, + Error: err, + } + + cc.extensions.OnConnectionEvent(tp, info) +} + +func (cc *clientConn) onExtensionStmtEnd(node interface{}, stmtCtxValid bool, err error, args ...expression.Expression) { + if !cc.extensions.HasStmtEventListeners() { + return + } + + ctx := cc.getCtx() + if ctx == nil { + return + } + + tp := extension.StmtSuccess + if err != nil { + tp = extension.StmtError + } + + sessVars := ctx.GetSessionVars() + info := &stmtEventInfo{ + sessVars: sessVars, + err: err, + } + + switch stmt := node.(type) { + case *ast.ExecuteStmt: + info.executeStmt = stmt + info.stmtNode = stmt + case PreparedStatement: + info.executeStmtID = uint32(stmt.ID()) + prepared, _ := sessVars.GetPreparedStmtByID(info.executeStmtID) + info.executeStmt = &ast.ExecuteStmt{ + PrepStmt: prepared, + BinaryArgs: args, + } + info.stmtNode = info.executeStmt + case ast.StmtNode: + info.stmtNode = stmt + } + + if stmtCtxValid { + info.sc = sessVars.StmtCtx + } else { + info.sc = &stmtctx.StatementContext{} + } + cc.extensions.OnStmtEvent(tp, info) +} + +// onSQLParseFailed will be called when sql parse failed +func (cc *clientConn) onExtensionSQLParseFailed(sql string, err error) { + if !cc.extensions.HasStmtEventListeners() { + return + } + + cc.extensions.OnStmtEvent(extension.StmtError, &stmtEventInfo{ + sessVars: cc.getCtx().GetSessionVars(), + err: err, + failedParseText: sql, + }) +} + +func (cc *clientConn) onExtensionBinaryExecuteEnd(prep PreparedStatement, args []expression.Expression, stmtCtxValid bool, err error) { + cc.onExtensionStmtEnd(prep, stmtCtxValid, err, args...) +} + +type stmtEventInfo struct { + sessVars *variable.SessionVars + sc *stmtctx.StatementContext + stmtNode ast.StmtNode + // execute info + executeStmtID uint32 + executeStmt *ast.ExecuteStmt + executePreparedCached bool + executePreparedCache *core.PlanCacheStmt + // error will only be valid when the stmt is failed + err error + // failedParseText will only present on parse failed + failedParseText string +} + +func (e *stmtEventInfo) ConnectionInfo() *variable.ConnectionInfo { + return e.sessVars.ConnectionInfo +} + +func (e *stmtEventInfo) StmtNode() ast.StmtNode { + return e.stmtNode +} + +func (e *stmtEventInfo) ExecuteStmtNode() *ast.ExecuteStmt { + return e.executeStmt +} + +func (e *stmtEventInfo) ExecutePreparedStmt() ast.StmtNode { + if cache := e.ensureExecutePreparedCache(); cache != nil { + return cache.PreparedAst.Stmt + } + return nil +} + +func (e *stmtEventInfo) PreparedParams() []types.Datum { + return e.sessVars.PreparedParams +} + +func (e *stmtEventInfo) OriginalText() string { + if sql := e.ensureStmtContextOriginalSQL(); sql != "" { + return sql + } + + if e.executeStmtID != 0 { + return binaryExecuteStmtText(e.executeStmtID) + } + + return e.failedParseText +} + +func (e *stmtEventInfo) SQLDigest() (normalized string, digest *parser.Digest) { + if sql := e.ensureStmtContextOriginalSQL(); sql != "" { + return e.sc.SQLDigest() + } + + if e.executeStmtID != 0 { + return binaryExecuteStmtText(e.executeStmtID), nil + } + + return e.failedParseText, nil +} + +func (e *stmtEventInfo) User() *auth.UserIdentity { + return e.sessVars.User +} + +func (e *stmtEventInfo) ActiveRoles() []*auth.RoleIdentity { + return e.sessVars.ActiveRoles +} + +func (e *stmtEventInfo) CurrentDB() string { + return e.sessVars.CurrentDB +} + +func (e *stmtEventInfo) AffectedRows() uint64 { + if e.sc == nil || e.err != nil { + return 0 + } + return e.sc.AffectedRows() +} + +func (e *stmtEventInfo) RelatedTables() []stmtctx.TableEntry { + if e.sc == nil { + return nil + } + return e.sc.Tables +} + +func (e *stmtEventInfo) GetError() error { + return e.err +} + +func (e *stmtEventInfo) ensureExecutePreparedCache() *core.PlanCacheStmt { + if e.executeStmt == nil { + return nil + } + + if !e.executePreparedCached { + e.executePreparedCache, _ = core.GetPreparedStmt(e.executeStmt, e.sessVars) + e.executePreparedCached = true + } + + return e.executePreparedCache +} + +func (e *stmtEventInfo) ensureStmtContextOriginalSQL() string { + if e.sc == nil { + return "" + } + + if sql := e.sc.OriginalSQL; sql != "" { + return sql + } + + if planCache := e.ensureExecutePreparedCache(); planCache != nil { + e.sc.OriginalSQL = planCache.PreparedAst.Stmt.Text() + e.sc.InitSQLDigest(planCache.NormalizedSQL, planCache.SQLDigest) + } + + if e.sc.OriginalSQL == "" && e.executeStmtID == 0 { + e.sc.OriginalSQL = e.stmtNode.Text() + } + + return e.sc.OriginalSQL +} + +func binaryExecuteStmtText(id uint32) string { + return fmt.Sprintf("BINARY EXECUTE (ID %d)", id) +} diff --git a/server/http_handler.go b/server/http_handler.go index 82d9ec051c722..6044f82861386 100644 --- a/server/http_handler.go +++ b/server/http_handler.go @@ -72,21 +72,22 @@ import ( ) const ( - pDBName = "db" - pHexKey = "hexKey" - pIndexName = "index" - pHandle = "handle" - pRegionID = "regionID" - pStartTS = "startTS" - pTableName = "table" - pTableID = "tableID" - pColumnID = "colID" - pColumnTp = "colTp" - pColumnFlag = "colFlag" - pColumnLen = "colLen" - pRowBin = "rowBin" - pSnapshot = "snapshot" - pFileName = "filename" + pDBName = "db" + pHexKey = "hexKey" + pIndexName = "index" + pHandle = "handle" + pRegionID = "regionID" + pStartTS = "startTS" + pTableName = "table" + pTableID = "tableID" + pColumnID = "colID" + pColumnTp = "colTp" + pColumnFlag = "colFlag" + pColumnLen = "colLen" + pRowBin = "rowBin" + pSnapshot = "snapshot" + pFileName = "filename" + pDumpPartitionStats = "dumpPartitionStats" ) // For query string @@ -658,9 +659,9 @@ func (h settingsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { switch asyncCommit { case "0": - err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBEnableAsyncCommit, variable.Off) + err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBEnableAsyncCommit, variable.Off) case "1": - err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBEnableAsyncCommit, variable.On) + err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBEnableAsyncCommit, variable.On) default: writeError(w, errors.New("illegal argument")) return @@ -680,9 +681,9 @@ func (h settingsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { switch onePC { case "0": - err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBEnable1PC, variable.Off) + err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBEnable1PC, variable.Off) case "1": - err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBEnable1PC, variable.On) + err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBEnable1PC, variable.On) default: writeError(w, errors.New("illegal argument")) return @@ -747,9 +748,9 @@ func (h settingsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { switch mutationChecker { case "0": - err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBEnableMutationChecker, variable.Off) + err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBEnableMutationChecker, variable.Off) case "1": - err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBEnableMutationChecker, variable.On) + err = s.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBEnableMutationChecker, variable.On) default: writeError(w, errors.New("illegal argument")) return @@ -799,14 +800,22 @@ func (h binlogRecover) ServeHTTP(w http.ResponseWriter, req *http.Request) { case "reset": binloginfo.ResetSkippedCommitterCounter() case "nowait": - binloginfo.DisableSkipBinlogFlag() + err := binloginfo.DisableSkipBinlogFlag() + if err != nil { + writeError(w, err) + return + } case "status": default: sec, err := strconv.ParseInt(req.FormValue(qSeconds), 10, 64) if sec <= 0 || err != nil { sec = 1800 } - binloginfo.DisableSkipBinlogFlag() + err = binloginfo.DisableSkipBinlogFlag() + if err != nil { + writeError(w, err) + return + } timeout := time.Duration(sec) * time.Second err = binloginfo.WaitBinlogRecover(timeout) if err != nil { @@ -971,10 +980,12 @@ func (h flashReplicaHandler) handleStatusReport(w http.ResponseWriter, req *http writeError(w, err) } if available { - err = infosync.DeleteTiFlashTableSyncProgress(status.ID) + var tableInfo model.TableInfo + tableInfo.ID = status.ID + err = infosync.DeleteTiFlashTableSyncProgress(&tableInfo) } else { - progress := types.TruncateFloatToString(float64(status.FlashRegionCount)/float64(status.RegionCount), 2) - err = infosync.UpdateTiFlashTableSyncProgress(context.Background(), status.ID, progress) + progress := float64(status.FlashRegionCount) / float64(status.RegionCount) + err = infosync.UpdateTiFlashProgressCache(status.ID, progress) } if err != nil { writeError(w, err) diff --git a/server/http_handler_serial_test.go b/server/http_handler_serial_test.go index c6a07c90760a1..cfc542443c000 100644 --- a/server/http_handler_serial_test.go +++ b/server/http_handler_serial_test.go @@ -16,6 +16,7 @@ package server import ( "bytes" + "context" "database/sql" "encoding/json" "fmt" @@ -65,10 +66,10 @@ func TestPostSettings(t *testing.T) { require.Equal(t, zap.ErrorLevel, log.GetLevel()) require.Equal(t, "error", config.GetGlobalConfig().Log.Level) require.True(t, variable.ProcessGeneralLog.Load()) - val, err := se.GetSessionVars().GetGlobalSystemVar(variable.TiDBEnableAsyncCommit) + val, err := se.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBEnableAsyncCommit) require.NoError(t, err) require.Equal(t, variable.On, val) - val, err = se.GetSessionVars().GetGlobalSystemVar(variable.TiDBEnable1PC) + val, err = se.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBEnable1PC) require.NoError(t, err) require.Equal(t, variable.On, val) @@ -84,10 +85,10 @@ func TestPostSettings(t *testing.T) { require.False(t, variable.ProcessGeneralLog.Load()) require.Equal(t, zap.FatalLevel, log.GetLevel()) require.Equal(t, "fatal", config.GetGlobalConfig().Log.Level) - val, err = se.GetSessionVars().GetGlobalSystemVar(variable.TiDBEnableAsyncCommit) + val, err = se.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBEnableAsyncCommit) require.NoError(t, err) require.Equal(t, variable.Off, val) - val, err = se.GetSessionVars().GetGlobalSystemVar(variable.TiDBEnable1PC) + val, err = se.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBEnable1PC) require.NoError(t, err) require.Equal(t, variable.Off, val) form.Set("log_level", os.Getenv("log_level")) @@ -309,13 +310,13 @@ func TestTiFlashReplica(t *testing.T) { require.Equal(t, "a,b", strings.Join(data[0].LocationLabels, ",")) require.Equal(t, false, data[0].Available) - resp, err = ts.postStatus("/tiflash/replica-deprecated", "application/json", bytes.NewBuffer([]byte(`{"id":84,"region_count":3,"flash_region_count":3}`))) + resp, err = ts.postStatus("/tiflash/replica-deprecated", "application/json", bytes.NewBuffer([]byte(`{"id":184,"region_count":3,"flash_region_count":3}`))) require.NoError(t, err) require.NotNil(t, resp) body, err := io.ReadAll(resp.Body) require.NoError(t, err) require.NoError(t, resp.Body.Close()) - require.Equal(t, "[schema:1146]Table which ID = 84 does not exist.", string(body)) + require.Equal(t, "[schema:1146]Table which ID = 184 does not exist.", string(body)) tbl, err := ts.domain.InfoSchema().TableByName(model.NewCIStr("tidb"), model.NewCIStr("test")) require.NoError(t, err) diff --git a/server/http_status.go b/server/http_status.go index 5c815b8ed1886..b32237c376f7a 100644 --- a/server/http_status.go +++ b/server/http_status.go @@ -38,10 +38,13 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/fn" + pb "github.com/pingcap/kvproto/pkg/autoid" + autoid "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/store" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/cpuprofile" "github.com/pingcap/tidb/util/logutil" @@ -457,6 +460,37 @@ func (s *Server) startStatusServerAndRPCServer(serverMux *http.ServeMux) { statusServer := &http.Server{Addr: s.statusAddr, Handler: CorsHandler{handler: serverMux, cfg: s.cfg}} grpcServer := NewRPCServer(s.cfg, s.dom, s) service.RegisterChannelzServiceToServer(grpcServer) + if s.cfg.Store == "tikv" { + keyspaceName := config.GetGlobalKeyspaceName() + for { + var fullPath string + if keyspaceName == "" { + fullPath = fmt.Sprintf("%s://%s", s.cfg.Store, s.cfg.Path) + } else { + fullPath = fmt.Sprintf("%s://%s?keyspaceName=%s", s.cfg.Store, s.cfg.Path, keyspaceName) + } + store, err := store.New(fullPath) + if err != nil { + logutil.BgLogger().Error("new tikv store fail", zap.Error(err)) + break + } + ebd, ok := store.(kv.EtcdBackend) + if !ok { + break + } + etcdAddr, err := ebd.EtcdAddrs() + if err != nil { + logutil.BgLogger().Error("tikv store not etcd background", zap.Error(err)) + break + } + selfAddr := fmt.Sprintf("%s:%d", s.cfg.AdvertiseAddress, s.cfg.Status.StatusPort) + service := autoid.New(selfAddr, etcdAddr, store, ebd.TLSConfig()) + logutil.BgLogger().Info("register auto service at", zap.String("addr", selfAddr)) + pb.RegisterAutoIDAllocServer(grpcServer, service) + s.autoIDService = service + break + } + } s.statusServer = statusServer s.grpcServer = grpcServer diff --git a/server/main_test.go b/server/main_test.go index bff47f0dd7706..cdf12551934db 100644 --- a/server/main_test.go +++ b/server/main_test.go @@ -58,6 +58,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("time.Sleep"), goleak.IgnoreTopFunction("database/sql.(*Tx).awaitDone"), goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), diff --git a/server/mock_conn.go b/server/mock_conn.go index c6c6579618074..36ad6503db812 100644 --- a/server/mock_conn.go +++ b/server/mock_conn.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/auth" tmysql "github.com/pingcap/tidb/parser/mysql" @@ -94,8 +95,11 @@ func CreateMockServer(t *testing.T, store kv.Storage) *Server { // CreateMockConn creates a mock connection together with a session. func CreateMockConn(t *testing.T, server *Server) MockConn { + extensions, err := extension.GetExtensions() + require.NoError(t, err) + connID := rand.Uint64() - tc, err := server.driver.OpenCtx(connID, 0, uint8(tmysql.DefaultCollationID), "", nil) + tc, err := server.driver.OpenCtx(connID, 0, uint8(tmysql.DefaultCollationID), "", nil, extensions.NewSessionExtensions()) require.NoError(t, err) cc := &clientConn{ @@ -108,12 +112,14 @@ func CreateMockConn(t *testing.T, server *Server) MockConn { pkt: &packetIO{ bufWriter: bufio.NewWriter(bytes.NewBuffer(nil)), }, + extensions: tc.GetExtensions(), } cc.setCtx(tc) cc.server.rwlock.Lock() server.clients[cc.connectionID] = cc cc.server.rwlock.Unlock() tc.Session.SetSessionManager(server) + tc.Session.GetSessionVars().ConnectionInfo = cc.connectInfo() err = tc.Session.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil) require.NoError(t, err) return &mockConn{ diff --git a/server/plan_replayer.go b/server/plan_replayer.go index 30a00e4eda112..30f7c4ae821c1 100644 --- a/server/plan_replayer.go +++ b/server/plan_replayer.go @@ -15,26 +15,39 @@ package server import ( + "archive/zip" + "bytes" + "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "os" "path/filepath" + "strconv" + "strings" + "github.com/BurntSushi/toml" "github.com/gorilla/mux" + "github.com/pingcap/errors" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/domain/infosync" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/statistics/handle" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/replayer" "go.uber.org/zap" ) // PlanReplayerHandler is the handler for dumping plan replayer file. type PlanReplayerHandler struct { - infoGetter *infosync.InfoSyncer - address string - statusPort uint + is infoschema.InfoSchema + statsHandle *handle.Handle + infoGetter *infosync.InfoSyncer + address string + statusPort uint } func (s *Server) newPlanReplayerHandler() *PlanReplayerHandler { @@ -46,6 +59,12 @@ func (s *Server) newPlanReplayerHandler() *PlanReplayerHandler { if s.dom != nil && s.dom.InfoSyncer() != nil { prh.infoGetter = s.dom.InfoSyncer() } + if s.dom != nil && s.dom.InfoSchema() != nil { + prh.is = s.dom.InfoSchema() + } + if s.dom != nil && s.dom.StatsHandle() != nil { + prh.statsHandle = s.dom.StatsHandle() + } return prh } @@ -53,7 +72,7 @@ func (prh PlanReplayerHandler) ServeHTTP(w http.ResponseWriter, req *http.Reques params := mux.Vars(req) name := params[pFileName] handler := downloadFileHandler{ - filePath: filepath.Join(domain.GetPlanReplayerDirName(), name), + filePath: filepath.Join(replayer.GetPlanReplayerDirName(), name), fileName: name, infoGetter: prh.infoGetter, address: prh.address, @@ -61,6 +80,8 @@ func (prh PlanReplayerHandler) ServeHTTP(w http.ResponseWriter, req *http.Reques urlPath: fmt.Sprintf("plan_replayer/dump/%s", name), downloadedFilename: "plan_replayer", scheme: util.InternalHTTPSchema(), + statsHandle: prh.statsHandle, + is: prh.is, } handleDownloadFile(handler, w, req) } @@ -83,7 +104,7 @@ func handleDownloadFile(handler downloadFileHandler, w http.ResponseWriter, req writeError(w, err) return } - content, err := ioutil.ReadAll(file) + content, err := io.ReadAll(file) if err != nil { writeError(w, err) return @@ -93,6 +114,13 @@ func handleDownloadFile(handler downloadFileHandler, w http.ResponseWriter, req writeError(w, err) return } + if handler.downloadedFilename == "plan_replayer" { + content, err = handlePlanReplayerCaptureFile(content, path, handler) + if err != nil { + writeError(w, err) + return + } + } _, err = w.Write(content) if err != nil { writeError(w, err) @@ -137,7 +165,7 @@ func handleDownloadFile(handler downloadFileHandler, w http.ResponseWriter, req zap.String("remote-addr", remoteAddr), zap.Int("status-code", resp.StatusCode)) continue } - content, err := ioutil.ReadAll(resp.Body) + content, err := io.ReadAll(resp.Body) if err != nil { writeError(w, err) return @@ -175,6 +203,9 @@ type downloadFileHandler struct { statusPort uint urlPath string downloadedFilename string + + statsHandle *handle.Handle + is infoschema.InfoSchema } func isExists(path string) (bool, error) { @@ -187,3 +218,162 @@ func isExists(path string) (bool, error) { } return true, nil } + +func handlePlanReplayerCaptureFile(content []byte, path string, handler downloadFileHandler) ([]byte, error) { + if !strings.HasPrefix(handler.filePath, "capture_replayer") { + return content, nil + } + b := bytes.NewReader(content) + zr, err := zip.NewReader(b, int64(len(content))) + if err != nil { + return nil, err + } + startTS, err := loadSQLMetaFile(zr) + if err != nil { + return nil, err + } + if startTS == 0 { + return content, nil + } + tbls, err := loadSchemaMeta(zr, handler.is) + if err != nil { + return nil, err + } + for _, tbl := range tbls { + jsonStats, err := handler.statsHandle.DumpHistoricalStatsBySnapshot(tbl.dbName, tbl.info, startTS) + if err != nil { + return nil, err + } + tbl.jsonStats = jsonStats + } + newPath, err := dumpJSONStatsIntoZip(tbls, content, path) + if err != nil { + return nil, err + } + //nolint: gosec + file, err := os.Open(newPath) + if err != nil { + return nil, err + } + content, err = io.ReadAll(file) + if err != nil { + return nil, err + } + err = file.Close() + if err != nil { + return nil, err + } + return content, nil +} + +func loadSQLMetaFile(z *zip.Reader) (uint64, error) { + for _, zipFile := range z.File { + if zipFile.Name == domain.PlanReplayerSQLMetaFile { + varMap := make(map[string]string) + v, err := zipFile.Open() + if err != nil { + return 0, errors.AddStack(err) + } + //nolint: errcheck,all_revive + defer v.Close() + _, err = toml.DecodeReader(v, &varMap) + if err != nil { + return 0, errors.AddStack(err) + } + startTS, err := strconv.ParseUint(varMap[domain.PlanReplayerSQLMetaStartTS], 10, 64) + if err != nil { + return 0, err + } + return startTS, nil + } + } + return 0, nil +} + +func loadSchemaMeta(z *zip.Reader, is infoschema.InfoSchema) (map[int64]*tblInfo, error) { + r := make(map[int64]*tblInfo, 0) + for _, zipFile := range z.File { + if zipFile.Name == fmt.Sprintf("schema/%v", domain.PlanReplayerSchemaMetaFile) { + v, err := zipFile.Open() + if err != nil { + return nil, errors.AddStack(err) + } + //nolint: errcheck,all_revive + defer v.Close() + buf := new(bytes.Buffer) + _, err = buf.ReadFrom(v) + if err != nil { + return nil, errors.AddStack(err) + } + rows := strings.Split(buf.String(), "\n") + for _, row := range rows { + s := strings.Split(row, ";") + databaseName := s[0] + tableName := s[1] + t, err := is.TableByName(model.NewCIStr(databaseName), model.NewCIStr(tableName)) + if err != nil { + return nil, err + } + r[t.Meta().ID] = &tblInfo{ + info: t.Meta(), + dbName: databaseName, + tblName: tableName, + } + } + break + } + } + return r, nil +} + +func dumpJSONStatsIntoZip(tbls map[int64]*tblInfo, content []byte, path string) (string, error) { + zr, err := zip.NewReader(bytes.NewReader(content), int64(len(content))) + if err != nil { + return "", err + } + newPath := strings.Replace(path, "capture_replayer", "copy_capture_replayer", 1) + zf, err := os.Create(newPath) + if err != nil { + return "", err + } + zw := zip.NewWriter(zf) + for _, f := range zr.File { + err = zw.Copy(f) + if err != nil { + logutil.BgLogger().Error("copy plan replayer zip file failed", zap.Error(err)) + return "", err + } + } + for _, tbl := range tbls { + w, err := zw.Create(fmt.Sprintf("stats/%v.%v.json", tbl.dbName, tbl.tblName)) + if err != nil { + return "", err + } + data, err := json.Marshal(tbl.jsonStats) + if err != nil { + return "", err + } + _, err = w.Write(data) + if err != nil { + return "", err + } + } + err = zw.Close() + if err != nil { + logutil.BgLogger().Error("Closing file failed", zap.Error(err)) + return "", err + } + err = zf.Close() + if err != nil { + logutil.BgLogger().Error("Closing file failed", zap.Error(err)) + return "", err + } + return newPath, nil +} + +type tblInfo struct { + info *model.TableInfo + jsonStats *handle.JSONTable + dbName string + tblName string +} diff --git a/server/plan_replayer_test.go b/server/plan_replayer_test.go index 2a00bc0db04de..2f2308efdd1a9 100644 --- a/server/plan_replayer_test.go +++ b/server/plan_replayer_test.go @@ -18,7 +18,6 @@ import ( "bytes" "database/sql" "io" - "io/ioutil" "os" "path/filepath" "testing" @@ -69,7 +68,7 @@ func TestDumpPlanReplayerAPI(t *testing.T) { require.NoError(t, resp0.Body.Close()) }() - body, err := ioutil.ReadAll(resp0.Body) + body, err := io.ReadAll(resp0.Body) require.NoError(t, err) path := "/tmp/plan_replayer.zip" diff --git a/server/rpc_server.go b/server/rpc_server.go index 7053872f19aa7..f92deaf802d64 100644 --- a/server/rpc_server.go +++ b/server/rpc_server.go @@ -27,6 +27,7 @@ import ( "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/privilege/privileges" "github.com/pingcap/tidb/session" @@ -55,6 +56,12 @@ func NewRPCServer(config *config.Config, dom *domain.Domain, sm util.SessionMana Time: time.Duration(config.Status.GRPCKeepAliveTime) * time.Second, Timeout: time.Duration(config.Status.GRPCKeepAliveTimeout) * time.Second, }), + grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ + // Allow clients send consecutive pings in every 5 seconds. + // The default value of MinTime is 5 minutes, + // which is too long compared with 10 seconds of TiDB's keepalive time. + MinTime: 5 * time.Second, + }), grpc.MaxConcurrentStreams(uint32(config.Status.GRPCConcurrentStreams)), grpc.InitialWindowSize(int32(config.Status.GRPCInitialWindowSize)), grpc.MaxSendMsgSize(config.Status.GRPCMaxSendMsgSize), @@ -192,7 +199,7 @@ func (s *rpcServer) handleCopRequest(ctx context.Context, req *coprocessor.Reque defer func() { sc := se.GetSessionVars().StmtCtx if sc.MemTracker != nil { - sc.MemTracker.DetachFromGlobalTracker() + sc.MemTracker.Detach() } se.Close() }() @@ -210,11 +217,13 @@ func (s *rpcServer) createSession() (session.Session, error) { if err != nil { return nil, err } + extensions, err := extension.GetExtensions() + if err != nil { + return nil, err + } do := domain.GetDomain(se) is := do.InfoSchema() - pm := &privileges.UserPrivileges{ - Handle: do.PrivilegeHandle(), - } + pm := privileges.NewUserPrivileges(do.PrivilegeHandle(), extensions) privilege.BindPrivilegeManager(se, pm) vars := se.GetSessionVars() vars.TxnCtx.InfoSchema = is @@ -222,13 +231,12 @@ func (s *rpcServer) createSession() (session.Session, error) { // TODO: remove this. vars.SetHashAggPartialConcurrency(1) vars.SetHashAggFinalConcurrency(1) - vars.StmtCtx.InitMemTracker(memory.LabelForSQLText, vars.MemQuotaQuery) - vars.StmtCtx.MemTracker.AttachToGlobalTracker(executor.GlobalMemoryUsageTracker) + vars.StmtCtx.InitMemTracker(memory.LabelForSQLText, -1) + vars.StmtCtx.MemTracker.AttachTo(vars.MemTracker) switch variable.OOMAction.Load() { case variable.OOMActionCancel: action := &memory.PanicOnExceed{} - action.SetLogHook(domain.GetDomain(se).ExpensiveQueryHandle().LogOnQueryExceedMemQuota) - vars.StmtCtx.MemTracker.SetActionOnExceed(action) + vars.MemTracker.SetActionOnExceed(action) } se.SetSessionManager(s.sm) return se, nil diff --git a/server/server.go b/server/server.go index 7602fec4e05ba..42031fce9ffa1 100644 --- a/server/server.go +++ b/server/server.go @@ -41,6 +41,7 @@ import ( _ "net/http/pprof" // #nosec G108 "os" "os/user" + "strconv" "sync" "sync/atomic" "time" @@ -48,14 +49,19 @@ import ( "github.com/blacktear23/go-proxyprotocol" "github.com/pingcap/errors" + autoid "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/plugin" + "github.com/pingcap/tidb/privilege/privileges" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/session/txninfo" "github.com/pingcap/tidb/sessionctx/variable" @@ -104,6 +110,7 @@ var ( errNewAbortingConnection = dbterror.ClassServer.NewStd(errno.ErrNewAbortingConnection) errNotSupportedAuthMode = dbterror.ClassServer.NewStd(errno.ErrNotSupportedAuthMode) errNetPacketTooLarge = dbterror.ClassServer.NewStd(errno.ErrNetPacketTooLarge) + errMustChangePassword = dbterror.ClassServer.NewStd(errno.ErrMustChangePassword) ) // DefaultCapability is the capability of the server when it is created using the default configuration. @@ -134,8 +141,11 @@ type Server struct { grpcServer *grpc.Server inShutdownMode bool - sessionMapMutex sync.Mutex - internalSessions map[interface{}]struct{} + sessionMapMutex sync.Mutex + internalSessions map[interface{}]struct{} + autoIDService *autoid.Service + authTokenCancelFunc context.CancelFunc + wg sync.WaitGroup } // ConnectionCount gets current connection count. @@ -241,7 +251,7 @@ func NewServer(cfg *config.Config, driver IDriver) (*Server, error) { } if s.cfg.Host != "" && (s.cfg.Port != 0 || RunInGoTest) { - addr := fmt.Sprintf("%s:%d", s.cfg.Host, s.cfg.Port) + addr := net.JoinHostPort(s.cfg.Host, strconv.Itoa(int(s.cfg.Port))) tcpProto := "tcp" if s.cfg.EnableTCP4Only { tcpProto = "tcp4" @@ -297,6 +307,24 @@ func NewServer(cfg *config.Config, driver IDriver) (*Server, error) { } } + // Automatically reload JWKS for tidb_auth_token. + if len(s.cfg.Security.AuthTokenJWKS) > 0 { + var ( + timeInterval time.Duration + err error + ctx context.Context + ) + if timeInterval, err = time.ParseDuration(s.cfg.Security.AuthTokenRefreshInterval); err != nil { + logutil.BgLogger().Error("Fail to parse security.auth-token-refresh-interval. Use default value", + zap.String("security.auth-token-refresh-interval", s.cfg.Security.AuthTokenRefreshInterval)) + timeInterval = config.DefAuthTokenRefreshInterval + } + ctx, s.authTokenCancelFunc = context.WithCancel(context.Background()) + if err = privileges.GlobalJWKS.LoadJWKS4AuthToken(ctx, &s.wg, s.cfg.Security.AuthTokenJWKS, timeInterval); err != nil { + logutil.BgLogger().Error("Fail to load JWKS from the path", zap.String("jwks", s.cfg.Security.AuthTokenJWKS)) + } + } + // Init rand seed for randomBuf() rand.Seed(time.Now().UTC().UnixNano()) @@ -494,13 +522,46 @@ func (s *Server) Close() { s.grpcServer.Stop() s.grpcServer = nil } + if s.autoIDService != nil { + s.autoIDService.Close() + } + if s.authTokenCancelFunc != nil { + s.authTokenCancelFunc() + } + s.wg.Wait() metrics.ServerEventCounter.WithLabelValues(metrics.EventClose).Inc() } // onConn runs in its own goroutine, handles queries from this connection. func (s *Server) onConn(conn *clientConn) { + // init the connInfo + _, _, err := conn.PeerHost("") + if err != nil { + logutil.BgLogger().With(zap.Uint64("conn", conn.connectionID)). + Error("get peer host failed", zap.Error(err)) + terror.Log(conn.Close()) + return + } + + extensions, err := extension.GetExtensions() + if err != nil { + logutil.BgLogger().With(zap.Uint64("conn", conn.connectionID)). + Error("error in get extensions", zap.Error(err)) + terror.Log(conn.Close()) + return + } + + if sessExtensions := extensions.NewSessionExtensions(); sessExtensions != nil { + conn.extensions = sessExtensions + conn.onExtensionConnEvent(extension.ConnConnected, nil) + defer func() { + conn.onExtensionConnEvent(extension.ConnDisconnected, nil) + }() + } + ctx := logutil.WithConnID(context.Background(), conn.connectionID) if err := conn.handshake(ctx); err != nil { + conn.onExtensionConnEvent(extension.ConnHandshakeRejected, err) if plugin.IsEnable(plugin.Audit) && conn.getCtx() != nil { conn.getCtx().GetSessionVars().ConnectionInfo = conn.connectInfo() err = plugin.ForeachPlugin(plugin.Audit, func(p *plugin.Plugin) error { @@ -548,7 +609,8 @@ func (s *Server) onConn(conn *clientConn) { sessionVars := conn.ctx.GetSessionVars() sessionVars.ConnectionInfo = conn.connectInfo() - err := plugin.ForeachPlugin(plugin.Audit, func(p *plugin.Plugin) error { + conn.onExtensionConnEvent(extension.ConnHandshakeAccepted, nil) + err = plugin.ForeachPlugin(plugin.Audit, func(p *plugin.Plugin) error { authPlugin := plugin.DeclareAuditManifest(p.Manifest) if authPlugin.OnConnectionEvent != nil { return authPlugin.OnConnectionEvent(context.Background(), plugin.Connected, sessionVars.ConnectionInfo) @@ -592,6 +654,7 @@ func (cc *clientConn) connectInfo() *variable.ConnectionInfo { ClientIP: cc.peerHost, ClientPort: cc.peerPort, ServerID: 1, + ServerIP: cc.serverHost, ServerPort: int(cc.server.cfg.Port), User: cc.user, ServerOSLoginUser: osUser, @@ -670,6 +733,11 @@ func (s *Server) GetProcessInfo(id uint64) (*util.ProcessInfo, bool) { conn, ok := s.clients[id] s.rwlock.RUnlock() if !ok { + if s.dom != nil { + if pinfo, ok2 := s.dom.SysProcTracker().GetSysProcessList()[id]; ok2 { + return pinfo, true + } + } return &util.ProcessInfo{}, false } return conn.ctx.ShowProcess(), ok @@ -722,6 +790,17 @@ func killConn(conn *clientConn) { } } +// KillSysProcesses kill sys processes such as auto analyze. +func (s *Server) KillSysProcesses() { + if s.dom == nil { + return + } + sysProcTracker := s.dom.SysProcTracker() + for connID := range sysProcTracker.GetSysProcessList() { + sysProcTracker.KillSysProcess(connID) + } +} + // KillAllConnections kills all connections when server is not gracefully shutdown. func (s *Server) KillAllConnections() { logutil.BgLogger().Info("[server] kill all connections.") @@ -736,12 +815,7 @@ func (s *Server) KillAllConnections() { killConn(conn) } - if s.dom != nil { - sysProcTracker := s.dom.SysProcTracker() - for connID := range sysProcTracker.GetSysProcessList() { - sysProcTracker.KillSysProcess(connID) - } - } + s.KillSysProcesses() } var gracefulCloseConnectionsTimeout = 15 * time.Second @@ -882,3 +956,62 @@ func (s *Server) CheckOldRunningTxn(job2ver map[int64]int64, job2ids map[int64]s } } } + +// KillNonFlashbackClusterConn implements SessionManager interface. +func (s *Server) KillNonFlashbackClusterConn() { + s.rwlock.RLock() + connIDs := make([]uint64, 0, len(s.clients)) + for _, client := range s.clients { + if client.ctx.Session != nil { + processInfo := client.ctx.Session.ShowProcess() + ddl, ok := processInfo.StmtCtx.GetPlan().(*core.DDL) + if !ok { + connIDs = append(connIDs, client.connectionID) + continue + } + _, ok = ddl.Statement.(*ast.FlashBackToTimestampStmt) + if !ok { + connIDs = append(connIDs, client.connectionID) + continue + } + } + } + s.rwlock.RUnlock() + for _, id := range connIDs { + s.Kill(id, false) + } +} + +// GetMinStartTS implements SessionManager interface. +func (s *Server) GetMinStartTS(lowerBound uint64) (ts uint64) { + // sys processes + if s.dom != nil { + for _, pi := range s.dom.SysProcTracker().GetSysProcessList() { + if thisTS := pi.GetMinStartTS(lowerBound); thisTS > lowerBound && (thisTS < ts || ts == 0) { + ts = thisTS + } + } + } + // user sessions + func() { + s.rwlock.RLock() + defer s.rwlock.RUnlock() + for _, client := range s.clients { + if thisTS := client.ctx.ShowProcess().GetMinStartTS(lowerBound); thisTS > lowerBound && (thisTS < ts || ts == 0) { + ts = thisTS + } + } + }() + // internal sessions + func() { + s.sessionMapMutex.Lock() + defer s.sessionMapMutex.Unlock() + analyzeProcID := util.GetAutoAnalyzeProcID(s.ServerID) + for se := range s.internalSessions { + if thisTS, processInfoID := session.GetStartTSFromSession(se); processInfoID != analyzeProcID && thisTS > lowerBound && (thisTS < ts || ts == 0) { + ts = thisTS + } + } + }() + return +} diff --git a/server/server_test.go b/server/server_test.go index 8639f98076232..623a4d3313628 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -626,8 +626,8 @@ func (cli *testServerClient) runTestLoadDataForListPartition(t *testing.T) { dbt.MustExec(fmt.Sprintf("load data local infile %q into table t", path)) rows = dbt.MustQuery("show warnings") cli.checkRows(t, rows, - "Warning 1062 Duplicate entry '1' for key 'idx'", - "Warning 1062 Duplicate entry '2' for key 'idx'") + "Warning 1062 Duplicate entry '1' for key 't.idx'", + "Warning 1062 Duplicate entry '2' for key 't.idx'") require.NoError(t, rows.Close()) rows = dbt.MustQuery("select * from t order by id") cli.checkRows(t, rows, "1 a", "2 b", "3 c", "4 e", "7 a") @@ -680,8 +680,8 @@ func (cli *testServerClient) runTestLoadDataForListPartition2(t *testing.T) { dbt.MustExec(fmt.Sprintf("load data local infile %q into table t (id,name)", path)) rows = dbt.MustQuery("show warnings") cli.checkRows(t, rows, - "Warning 1062 Duplicate entry '1-2' for key 'idx'", - "Warning 1062 Duplicate entry '2-2' for key 'idx'") + "Warning 1062 Duplicate entry '1-2' for key 't.idx'", + "Warning 1062 Duplicate entry '2-2' for key 't.idx'") require.NoError(t, rows.Close()) rows = dbt.MustQuery("select id,name from t order by id") cli.checkRows(t, rows, "1 a", "2 b", "3 c", "4 e", "7 a") @@ -735,8 +735,8 @@ func (cli *testServerClient) runTestLoadDataForListColumnPartition(t *testing.T) dbt.MustExec(fmt.Sprintf("load data local infile %q into table t", path)) rows = dbt.MustQuery("show warnings") cli.checkRows(t, rows, - "Warning 1062 Duplicate entry '1' for key 'idx'", - "Warning 1062 Duplicate entry '2' for key 'idx'") + "Warning 1062 Duplicate entry '1' for key 't.idx'", + "Warning 1062 Duplicate entry '2' for key 't.idx'") require.NoError(t, rows.Close()) rows = dbt.MustQuery("select * from t order by id") cli.checkRows(t, rows, "1 a", "2 b", "3 c", "4 e", "7 a") @@ -789,7 +789,7 @@ func (cli *testServerClient) runTestLoadDataForListColumnPartition2(t *testing.T require.NoError(t, err) require.NoError(t, rows.Close()) rows = dbt.MustQuery("show warnings") - cli.checkRows(t, rows, "Warning 1062 Duplicate entry 'w-1' for key 'idx'") + cli.checkRows(t, rows, "Warning 1062 Duplicate entry 'w-1' for key 't.idx'") require.NoError(t, rows.Close()) rows = dbt.MustQuery("select * from t order by id") cli.checkRows(t, rows, "w 1 1", "w 2 2", "e 5 5", "n 9 9") @@ -807,7 +807,7 @@ func (cli *testServerClient) runTestLoadDataForListColumnPartition2(t *testing.T rows = dbt.MustQuery("show warnings") cli.checkRows(t, rows, "Warning 1526 Table has no partition for value from column_list", - "Warning 1062 Duplicate entry 'w-1' for key 'idx'") + "Warning 1062 Duplicate entry 'w-1' for key 't.idx'") require.NoError(t, rows.Close()) rows = dbt.MustQuery("select * from t order by id") cli.checkRows(t, rows, "w 1 1", "w 2 2", "w 3 3", "e 5 5", "e 8 8", "n 9 9") diff --git a/server/statistics_handler.go b/server/statistics_handler.go index 8d7818bedac52..1844905e0a782 100644 --- a/server/statistics_handler.go +++ b/server/statistics_handler.go @@ -15,7 +15,9 @@ package server import ( + "fmt" "net/http" + "strconv" "time" "github.com/gorilla/mux" @@ -23,8 +25,8 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/util/gcutil" "github.com/tikv/client-go/v2/oracle" ) @@ -53,11 +55,21 @@ func (sh StatsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { is := sh.do.InfoSchema() h := sh.do.StatsHandle() + var err error + dumpPartitionStats := true + dumpParams := req.URL.Query()[pDumpPartitionStats] + if len(dumpParams) > 0 && len(dumpParams[0]) > 0 { + dumpPartitionStats, err = strconv.ParseBool(dumpParams[0]) + if err != nil { + writeError(w, err) + return + } + } tbl, err := is.TableByName(model.NewCIStr(params[pDBName]), model.NewCIStr(params[pTableName])) if err != nil { writeError(w, err) } else { - js, err := h.DumpStatsToJSON(params[pDBName], tbl.Meta(), nil) + js, err := h.DumpStatsToJSON(params[pDBName], tbl.Meta(), nil, dumpPartitionStats) if err != nil { writeError(w, err) } else { @@ -94,6 +106,15 @@ func (sh StatsHistoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request return } defer se.Close() + enabeld, err := sh.do.StatsHandle().CheckHistoricalStatsEnable() + if err != nil { + writeError(w, err) + return + } + if !enabeld { + writeError(w, fmt.Errorf("%v should be enabled", variable.TiDBEnableHistoricalStats)) + return + } se.GetSessionVars().StmtCtx.TimeZone = time.Local t, err := types.ParseTime(se.GetSessionVars().StmtCtx, params[pSnapshot], mysql.TypeTimestamp, 6) @@ -107,12 +128,6 @@ func (sh StatsHistoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request return } snapshot := oracle.GoTimeToTS(t1) - err = gcutil.ValidateSnapshot(se, snapshot) - if err != nil { - writeError(w, err) - return - } - is, err := sh.do.GetSnapshotInfoSchema(snapshot) if err != nil { writeError(w, err) @@ -124,7 +139,7 @@ func (sh StatsHistoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request writeError(w, err) return } - js, err := h.DumpStatsToJSONBySnapshot(params[pDBName], tbl.Meta(), snapshot) + js, err := h.DumpHistoricalStatsBySnapshot(params[pDBName], tbl.Meta(), snapshot) if err != nil { writeError(w, err) } else { diff --git a/server/statistics_handler_test.go b/server/statistics_handler_test.go index 8c239a73d9240..e0ecc7ba853f0 100644 --- a/server/statistics_handler_test.go +++ b/server/statistics_handler_test.go @@ -16,6 +16,7 @@ package server import ( "database/sql" + "encoding/json" "fmt" "io" "os" @@ -24,6 +25,7 @@ import ( "github.com/go-sql-driver/mysql" "github.com/gorilla/mux" + "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/statistics/handle" "github.com/pingcap/tidb/testkit" @@ -58,6 +60,10 @@ func TestDumpStatsAPI(t *testing.T) { statsHandler := &StatsHandler{dom} prepareData(t, client, statsHandler) + tableInfo, err := dom.InfoSchema().TableByName(model.NewCIStr("tidb"), model.NewCIStr("test")) + require.NoError(t, err) + err = dom.GetHistoricalStatsWorker().DumpHistoricalStats(tableInfo.Meta().ID, dom.StatsHandle()) + require.NoError(t, err) router := mux.NewRouter() router.Handle("/stats/dump/{db}/{table}", statsHandler) @@ -119,6 +125,33 @@ func TestDumpStatsAPI(t *testing.T) { _, err = fp1.Write(js) require.NoError(t, err) checkData(t, path1, client) + + testDumpPartitionTableStats(t, client, statsHandler) +} + +func testDumpPartitionTableStats(t *testing.T, client *testServerClient, handler *StatsHandler) { + preparePartitionData(t, client, handler) + check := func(dumpStats bool) { + expectedLen := 1 + if dumpStats { + expectedLen = 2 + } + url := fmt.Sprintf("/stats/dump/test/test2?dumpPartitionStats=%v", dumpStats) + resp0, err := client.fetchStatus(url) + require.NoError(t, err) + defer func() { + resp0.Body.Close() + }() + b, err := io.ReadAll(resp0.Body) + require.NoError(t, err) + jsonTable := &handle.JSONTable{} + err = json.Unmarshal(b, jsonTable) + require.NoError(t, err) + require.NotNil(t, jsonTable.Partitions["global"]) + require.Len(t, jsonTable.Partitions, expectedLen) + } + check(false) + check(true) } func prepareData(t *testing.T, client *testServerClient, statHandle *StatsHandler) { @@ -140,12 +173,30 @@ func prepareData(t *testing.T, client *testServerClient, statHandle *StatsHandle tk.MustExec("insert test values (1, 's')") require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) tk.MustExec("analyze table test") + tk.MustExec("set global tidb_enable_historical_stats = 1") tk.MustExec("insert into test(a,b) values (1, 'v'),(3, 'vvv'),(5, 'vv')") is := statHandle.do.InfoSchema() require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) require.NoError(t, h.Update(is)) } +func preparePartitionData(t *testing.T, client *testServerClient, statHandle *StatsHandler) { + db, err := sql.Open("mysql", client.getDSN()) + require.NoError(t, err, "Error connecting") + defer func() { + err := db.Close() + require.NoError(t, err) + }() + h := statHandle.do.StatsHandle() + tk := testkit.NewDBTestKit(t, db) + tk.MustExec("create table test2(a int) PARTITION BY RANGE ( a ) (PARTITION p0 VALUES LESS THAN (6))") + tk.MustExec("insert into test2 (a) values (1)") + tk.MustExec("analyze table test2") + is := statHandle.do.InfoSchema() + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.Update(is)) +} + func prepare4DumpHistoryStats(t *testing.T, client *testServerClient) { db, err := sql.Open("mysql", client.getDSN()) require.NoError(t, err, "Error connecting") diff --git a/server/tidb_library_test.go b/server/tidb_library_test.go index 8d895aa692e95..9c9e9b3d8110e 100644 --- a/server/tidb_library_test.go +++ b/server/tidb_library_test.go @@ -21,6 +21,7 @@ import ( "github.com/docker/go-units" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/store/mockstore" + "github.com/pingcap/tidb/util/syncutil" "github.com/stretchr/testify/require" ) @@ -47,5 +48,9 @@ func TestMemoryLeak(t *testing.T) { runtime.GC() runtime.ReadMemStats(&memStat) // before the fix, initAndCloseTiDB for 20 times will cost 900 MB memory, so we test for a quite loose upper bound. - require.Less(t, memStat.HeapInuse-oldHeapInUse, uint64(300*units.MiB)) + if syncutil.EnableDeadlock { + require.Less(t, memStat.HeapInuse-oldHeapInUse, uint64(1100*units.MiB)) + } else { + require.Less(t, memStat.HeapInuse-oldHeapInUse, uint64(300*units.MiB)) + } } diff --git a/server/tidb_serial_test.go b/server/tidb_serial_test.go index 600ac32bbae07..1648d1f2e4d80 100644 --- a/server/tidb_serial_test.go +++ b/server/tidb_serial_test.go @@ -359,7 +359,7 @@ func TestErrorNoRollback(t *testing.T) { func TestPrepareCount(t *testing.T) { ts := createTidbTestSuite(t) - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) prepareCnt := atomic.LoadInt64(&variable.PreparedStmtCount) ctx := context.Background() @@ -382,7 +382,7 @@ func TestPrepareCount(t *testing.T) { func TestPrepareExecute(t *testing.T) { ts := createTidbTestSuite(t) - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) ctx := context.Background() @@ -424,7 +424,7 @@ func TestDefaultCharacterAndCollation(t *testing.T) { // issue #21194 // 255 is the collation id of mysql client 8 default collation_connection - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(255), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(255), "test", nil, nil) require.NoError(t, err) testCase := []struct { variable string diff --git a/server/tidb_test.go b/server/tidb_test.go index c951a677f9c99..e8ffadc4fcdfa 100644 --- a/server/tidb_test.go +++ b/server/tidb_test.go @@ -43,11 +43,15 @@ import ( "github.com/pingcap/tidb/config" ddlutil "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/auth" tmysql "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/store/mockstore/unistore" "github.com/pingcap/tidb/testkit" @@ -921,7 +925,7 @@ func TestCreateTableFlen(t *testing.T) { ts := createTidbTestSuite(t) // issue #4540 - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) _, err = Execute(context.Background(), qctx, "use test;") require.NoError(t, err) @@ -993,7 +997,7 @@ func Execute(ctx context.Context, qc *TiDBContext, sql string) (ResultSet, error func TestShowTablesFlen(t *testing.T) { ts := createTidbTestSuite(t) - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) ctx := context.Background() _, err = Execute(ctx, qctx, "use test;") @@ -1023,7 +1027,7 @@ func checkColNames(t *testing.T, columns []*ColumnInfo, names ...string) { func TestFieldList(t *testing.T) { ts := createTidbTestSuite(t) - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) _, err = Execute(context.Background(), qctx, "use test;") require.NoError(t, err) @@ -1121,7 +1125,7 @@ func TestSumAvg(t *testing.T) { func TestNullFlag(t *testing.T) { ts := createTidbTestSuite(t) - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) ctx := context.Background() @@ -1195,7 +1199,7 @@ func TestNO_DEFAULT_VALUEFlag(t *testing.T) { ts := createTidbTestSuite(t) // issue #21465 - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) ctx := context.Background() @@ -1257,7 +1261,7 @@ func TestGracefulShutdown(t *testing.T) { func TestPessimisticInsertSelectForUpdate(t *testing.T) { ts := createTidbTestSuite(t) - qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) require.NoError(t, err) defer qctx.Close() ctx := context.Background() @@ -1667,7 +1671,7 @@ func TestTopSQLCPUProfile(t *testing.T) { dbt.MustExec("alter table t drop index if exists idx_b") _, err := db.Exec(addIndexStr) require.NotNil(t, err) - require.Equal(t, "Error 1062: Duplicate entry '1' for key 'idx_b'", err.Error()) + require.Equal(t, "Error 1062: Duplicate entry '1' for key 't.idx_b'", err.Error()) } check = func() { checkFn(addIndexStr, "") @@ -2632,6 +2636,65 @@ func TestRcReadCheckTSConflict(t *testing.T) { tk.MustExec("drop table t") } +func TestRcReadCheckTSConflictExtra(t *testing.T) { + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/sessiontxn/isolation/CallOnStmtRetry", "return")) + defer func() { + defer require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/sessiontxn/isolation/CallOnStmtRetry")) + }() + store := testkit.CreateMockStore(t) + + ctx := context.Background() + cc := &clientConn{ + alloc: arena.NewAllocator(1024), + chunkAlloc: chunk.NewAllocator(), + pkt: &packetIO{ + bufWriter: bufio.NewWriter(bytes.NewBuffer(nil)), + }, + } + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set global tidb_rc_read_check_ts = ON") + + se := tk.Session() + cc.setCtx(&TiDBContext{Session: se, stmts: make(map[int]*TiDBStatement)}) + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(id1 int, id2 int, id3 int, PRIMARY KEY(id1), UNIQUE KEY udx_id2 (id2))") + tk.MustExec("insert into t1 values (1, 1, 1)") + tk.MustExec("insert into t1 values (10, 10, 10)") + require.Equal(t, "ON", tk.MustQuery("show variables like 'tidb_rc_read_check_ts'").Rows()[0][1]) + + tk.MustExec("set transaction_isolation = 'READ-COMMITTED'") + tk2.MustExec("set transaction_isolation = 'READ-COMMITTED'") + + // Execute in text protocol + se.SetValue(sessiontxn.CallOnStmtRetryCount, 0) + tk.MustExec("begin pessimistic") + tk2.MustExec("update t1 set id3 = id3 + 1 where id1 = 1") + err := cc.handleQuery(ctx, "select * from t1 where id1 = 1") + require.NoError(t, err) + tk.MustExec("commit") + count, ok := se.Value(sessiontxn.CallOnStmtRetryCount).(int) + require.Equal(t, true, ok) + require.Equal(t, 1, count) + + // Execute in prepare binary protocol + se.SetValue(sessiontxn.CallOnStmtRetryCount, 0) + tk.MustExec("begin pessimistic") + tk2.MustExec("update t1 set id3 = id3 + 1 where id1 = 1") + require.NoError(t, cc.handleStmtPrepare(ctx, "select * from t1 where id1 = 1")) + require.NoError(t, cc.handleStmtExecute(ctx, []byte{0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0})) + tk.MustExec("commit") + count, ok = se.Value(sessiontxn.CallOnStmtRetryCount).(int) + require.Equal(t, true, ok) + require.Equal(t, 1, count) + + tk.MustExec("drop table t1") +} + func TestRcReadCheckTS(t *testing.T) { ts := createTidbTestSuite(t) @@ -2691,3 +2754,199 @@ func TestRcReadCheckTS(t *testing.T) { // As the `defaultLockTTL` is 3s and it's difficult to change it here, the lock // test is implemented in the uft test cases. } + +type connEventLogs struct { + sync.Mutex + types []extension.ConnEventTp + infos []extension.ConnEventInfo +} + +func (l *connEventLogs) add(tp extension.ConnEventTp, info *extension.ConnEventInfo) { + l.Lock() + defer l.Unlock() + l.types = append(l.types, tp) + l.infos = append(l.infos, *info) +} + +func (l *connEventLogs) reset() { + l.Lock() + defer l.Unlock() + l.types = l.types[:0] + l.infos = l.infos[:0] +} + +func (l *connEventLogs) check(fn func()) { + l.Lock() + defer l.Unlock() + fn() +} + +func (l *connEventLogs) waitEvent(tp extension.ConnEventTp) error { + totalSleep := 0 + for { + l.Lock() + if l.types[len(l.types)-1] == tp { + l.Unlock() + return nil + } + l.Unlock() + if totalSleep >= 10000 { + break + } + time.Sleep(time.Millisecond * 100) + totalSleep += 100 + } + return errors.New("timeout") +} + +func TestExtensionConnEvent(t *testing.T) { + defer extension.Reset() + extension.Reset() + + logs := &connEventLogs{} + require.NoError(t, extension.Register("test", extension.WithSessionHandlerFactory(func() *extension.SessionHandler { + return &extension.SessionHandler{ + OnConnectionEvent: logs.add, + } + }))) + require.NoError(t, extension.Setup()) + + ts := createTidbTestSuite(t) + // createTidbTestSuite create an inner connection, so wait the previous connection closed + require.NoError(t, logs.waitEvent(extension.ConnDisconnected)) + + // test for login success + logs.reset() + db, err := sql.Open("mysql", ts.getDSN()) + require.NoError(t, err) + defer func() { + require.NoError(t, db.Close()) + }() + + conn, err := db.Conn(context.Background()) + require.NoError(t, err) + defer func() { + _ = conn.Close() + }() + + var expectedConn2 variable.ConnectionInfo + require.NoError(t, logs.waitEvent(extension.ConnHandshakeAccepted)) + logs.check(func() { + require.Equal(t, []extension.ConnEventTp{ + extension.ConnConnected, + extension.ConnHandshakeAccepted, + }, logs.types) + conn1 := logs.infos[0] + require.Equal(t, "127.0.0.1", conn1.ClientIP) + require.Equal(t, "127.0.0.1", conn1.ServerIP) + require.Empty(t, conn1.User) + require.Empty(t, conn1.DB) + require.Equal(t, int(ts.port), conn1.ServerPort) + require.NotEqual(t, conn1.ServerPort, conn1.ClientPort) + require.NotEmpty(t, conn1.ConnectionID) + require.Nil(t, conn1.ActiveRoles) + require.NoError(t, conn1.Error) + + expectedConn2 = *(conn1.ConnectionInfo) + expectedConn2.User = "root" + expectedConn2.DB = "test" + require.Equal(t, []*auth.RoleIdentity{}, logs.infos[1].ActiveRoles) + require.Nil(t, logs.infos[1].Error) + require.Equal(t, expectedConn2, *(logs.infos[1].ConnectionInfo)) + }) + + _, err = conn.ExecContext(context.TODO(), "create role r1@'%'") + require.NoError(t, err) + _, err = conn.ExecContext(context.TODO(), "grant r1 TO root") + require.NoError(t, err) + _, err = conn.ExecContext(context.TODO(), "set role all") + require.NoError(t, err) + + require.NoError(t, conn.Close()) + require.NoError(t, db.Close()) + require.NoError(t, logs.waitEvent(extension.ConnDisconnected)) + logs.check(func() { + require.Equal(t, 3, len(logs.infos)) + require.Equal(t, 1, len(logs.infos[2].ActiveRoles)) + require.Equal(t, auth.RoleIdentity{ + Username: "r1", + Hostname: "%", + }, *logs.infos[2].ActiveRoles[0]) + require.Nil(t, logs.infos[2].Error) + require.Equal(t, expectedConn2, *(logs.infos[2].ConnectionInfo)) + }) + + // test for login failed + logs.reset() + cfg := mysql.NewConfig() + cfg.User = "noexist" + cfg.Net = "tcp" + cfg.Addr = fmt.Sprintf("127.0.0.1:%d", ts.port) + cfg.DBName = "test" + + db, err = sql.Open("mysql", cfg.FormatDSN()) + require.NoError(t, err) + defer func() { + require.NoError(t, db.Close()) + }() + + _, err = db.Conn(context.Background()) + require.Error(t, err) + require.NoError(t, logs.waitEvent(extension.ConnDisconnected)) + logs.check(func() { + require.Equal(t, []extension.ConnEventTp{ + extension.ConnConnected, + extension.ConnHandshakeRejected, + extension.ConnDisconnected, + }, logs.types) + conn1 := logs.infos[0] + require.Equal(t, "127.0.0.1", conn1.ClientIP) + require.Equal(t, "127.0.0.1", conn1.ServerIP) + require.Empty(t, conn1.User) + require.Empty(t, conn1.DB) + require.Equal(t, int(ts.port), conn1.ServerPort) + require.NotEqual(t, conn1.ServerPort, conn1.ClientPort) + require.NotEmpty(t, conn1.ConnectionID) + require.Nil(t, conn1.ActiveRoles) + require.NoError(t, conn1.Error) + + expectedConn2 = *(conn1.ConnectionInfo) + expectedConn2.User = "noexist" + expectedConn2.DB = "test" + require.Equal(t, []*auth.RoleIdentity{}, logs.infos[1].ActiveRoles) + require.EqualError(t, logs.infos[1].Error, "[server:1045]Access denied for user 'noexist'@'127.0.0.1' (using password: NO)") + require.Equal(t, expectedConn2, *(logs.infos[1].ConnectionInfo)) + }) +} + +func TestSandBoxMode(t *testing.T) { + ts := createTidbTestSuite(t) + qctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil, nil) + require.NoError(t, err) + _, err = Execute(context.Background(), qctx, "create user testuser;") + require.NoError(t, err) + qctx.Session.GetSessionVars().User = &auth.UserIdentity{Username: "testuser", AuthUsername: "testuser", AuthHostname: "%"} + + alterPwdStmts := []string{ + "set password = '1234';", + "alter user testuser identified by '1234';", + "alter user current_user() identified by '1234';", + } + + for _, alterPwdStmt := range alterPwdStmts { + require.False(t, qctx.Session.InSandBoxMode()) + _, err = Execute(context.Background(), qctx, "select 1;") + require.NoError(t, err) + + qctx.Session.EnableSandBoxMode() + require.True(t, qctx.Session.InSandBoxMode()) + _, err = Execute(context.Background(), qctx, "select 1;") + require.Error(t, err) + _, err = Execute(context.Background(), qctx, "alter user testuser identified with 'mysql_native_password';") + require.Error(t, err) + _, err = Execute(context.Background(), qctx, alterPwdStmt) + require.NoError(t, err) + _, err = Execute(context.Background(), qctx, "select 1;") + require.NoError(t, err) + } +} diff --git a/session/BUILD.bazel b/session/BUILD.bazel index 73d83cf663cc8..8e567503a6377 100644 --- a/session/BUILD.bazel +++ b/session/BUILD.bazel @@ -6,7 +6,6 @@ go_library( "advisory_locks.go", "bootstrap.go", "nontransactional.go", - "schema_amender.go", "session.go", "tidb.go", "txn.go", @@ -25,6 +24,8 @@ go_library( "//errno", "//executor", "//expression", + "//extension", + "//extension/extensionimpl", "//infoschema", "//kv", "//meta", @@ -63,6 +64,7 @@ go_library( "//table/temptable", "//tablecodec", "//telemetry", + "//ttl/ttlworker", "//types", "//types/parser_driver", "//util", @@ -76,10 +78,10 @@ go_library( "//util/mathutil", "//util/memory", "//util/parser", - "//util/rowcodec", "//util/sem", "//util/sli", "//util/sqlexec", + "//util/syncutil", "//util/tableutil", "//util/timeutil", "//util/topsql", @@ -91,11 +93,11 @@ go_library( "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_kvproto//pkg/kvrpcpb", "@com_github_pingcap_tipb//go-binlog", + "@com_github_prometheus_client_golang//prometheus", "@com_github_tikv_client_go_v2//error", "@com_github_tikv_client_go_v2//kv", "@com_github_tikv_client_go_v2//oracle", "@com_github_tikv_client_go_v2//tikv", - "@com_github_tikv_client_go_v2//txnkv/transaction", "@com_github_tikv_client_go_v2//util", "@io_etcd_go_etcd_client_v3//concurrency", "@org_uber_go_zap//:zap", @@ -104,7 +106,7 @@ go_library( go_test( name = "session_test", - timeout = "short", + timeout = "moderate", srcs = [ "bench_test.go", "bootstrap_test.go", @@ -113,7 +115,6 @@ go_test( "index_usage_sync_lease_test.go", "main_test.go", "nontransactional_test.go", - "schema_amender_test.go", "schema_test.go", "session_test.go", "tidb_test.go", @@ -124,8 +125,10 @@ go_test( race = "on", shard_count = 50, deps = [ + "//autoid_service", "//bindinfo", "//config", + "//ddl", "//domain", "//errno", "//executor", @@ -135,16 +138,13 @@ go_test( "//parser/ast", "//parser/auth", "//parser/model", - "//parser/mysql", "//parser/terror", "//planner/core", "//server", "//sessionctx", "//sessionctx/variable", - "//sessiontxn", "//statistics", "//store/mockstore", - "//table", "//tablecodec", "//telemetry", "//testkit", @@ -158,17 +158,13 @@ go_test( "//util/chunk", "//util/collate", "//util/logutil", - "//util/rowcodec", "//util/sqlexec", "@com_github_pingcap_failpoint//:failpoint", - "@com_github_pingcap_kvproto//pkg/kvrpcpb", "@com_github_pingcap_log//:log", "@com_github_stretchr_testify//require", "@com_github_tikv_client_go_v2//testutils", "@com_github_tikv_client_go_v2//tikv", - "@com_github_tikv_client_go_v2//txnkv/transaction", "@com_github_tikv_client_go_v2//util", - "@org_golang_x_exp//slices", "@org_uber_go_atomic//:atomic", "@org_uber_go_goleak//:goleak", "@org_uber_go_zap//:zap", diff --git a/session/advisory_locks.go b/session/advisory_locks.go index f51bb061a119c..aff3d80ed7e88 100644 --- a/session/advisory_locks.go +++ b/session/advisory_locks.go @@ -50,7 +50,7 @@ func (a *advisoryLock) DecrReferences() { a.referenceCount-- } -// References returns the current reference count for the advisory lock. +// ReferenceCount returns the current reference count for the advisory lock. func (a *advisoryLock) ReferenceCount() int { return a.referenceCount } diff --git a/session/bench_test.go b/session/bench_test.go index 47cad404d68a5..04c86b9227f8d 100644 --- a/session/bench_test.go +++ b/session/bench_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/pingcap/log" + _ "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" @@ -492,6 +493,26 @@ func BenchmarkSort(b *testing.B) { b.StopTimer() } +func BenchmarkSort2(b *testing.B) { + ctx := context.Background() + se, do, st := prepareBenchSession() + defer func() { + se.Close() + do.Close() + st.Close() + }() + prepareSortBenchData(se, "int", "%v", 1000000) + b.ResetTimer() + for i := 0; i < b.N; i++ { + rs, err := se.Execute(ctx, "select * from t order by col") + if err != nil { + b.Fatal(err) + } + readResult(ctx, rs[0], 1000000) + } + b.StopTimer() +} + func BenchmarkJoin(b *testing.B) { ctx := context.Background() se, do, st := prepareBenchSession() @@ -1835,6 +1856,22 @@ func BenchmarkCompileStmt(b *testing.B) { b.StopTimer() } +func BenchmarkAutoIncrement(b *testing.B) { + se, do, st := prepareBenchSession() + defer func() { + se.Close() + do.Close() + st.Close() + }() + mustExecute(se, "create table auto_inc (id int unsigned key nonclustered auto_increment) shard_row_id_bits=4 auto_id_cache 1;") + mustExecute(se, "set @@tidb_enable_mutation_checker = false") + b.ResetTimer() + for i := 0; i < b.N; i++ { + mustExecute(se, "insert into auto_inc values ()") + } + b.StopTimer() +} + // TestBenchDaily collects the daily benchmark test result and generates a json output file. // The format of the json output is described by the BenchOutput. // Used by this command in the Makefile @@ -1867,5 +1904,6 @@ func TestBenchDaily(t *testing.T) { BenchmarkHashPartitionPruningMultiSelect, BenchmarkInsertIntoSelect, BenchmarkCompileStmt, + BenchmarkAutoIncrement, ) } diff --git a/session/bootstrap.go b/session/bootstrap.go index 1a9c79170615f..639ce2c5192bb 100644 --- a/session/bootstrap.go +++ b/session/bootstrap.go @@ -23,6 +23,7 @@ import ( "encoding/hex" "flag" "fmt" + "io/ioutil" osuser "os/user" "runtime/debug" "strconv" @@ -37,6 +38,7 @@ import ( "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/owner" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/auth" @@ -59,6 +61,10 @@ import ( const ( // CreateUserTable is the SQL statement creates User table in system db. + // WARNING: There are some limitations on altering the schema of mysql.user table. + // Adding columns that are nullable or have default values is permitted. + // But operations like dropping or renaming columns may break the compatibility with BR. + // REFERENCE ISSUE: https://github.com/pingcap/tidb/issues/38785 CreateUserTable = `CREATE TABLE IF NOT EXISTS mysql.user ( Host CHAR(255), User CHAR(32), @@ -97,6 +103,13 @@ const ( FILE_priv ENUM('N','Y') NOT NULL DEFAULT 'N', Config_priv ENUM('N','Y') NOT NULL DEFAULT 'N', Create_Tablespace_Priv ENUM('N','Y') NOT NULL DEFAULT 'N', + Password_reuse_history smallint unsigned DEFAULT NULL, + Password_reuse_time smallint unsigned DEFAULT NULL, + User_attributes json, + Token_issuer VARCHAR(255), + Password_expired ENUM('N','Y') NOT NULL DEFAULT 'N', + Password_last_changed TIMESTAMP DEFAULT CURRENT_TIMESTAMP(), + Password_lifetime SMALLINT UNSIGNED DEFAULT NULL, PRIMARY KEY (Host, User));` // CreateGlobalPrivTable is the SQL statement creates Global scope privilege table in system db. CreateGlobalPrivTable = "CREATE TABLE IF NOT EXISTS mysql.global_priv (" + @@ -262,6 +275,8 @@ const ( charset TEXT NOT NULL, collation TEXT NOT NULL, source VARCHAR(10) NOT NULL DEFAULT 'unknown', + sql_digest varchar(64), + plan_digest varchar(64), INDEX sql_index(original_sql(700),default_db(68)) COMMENT "accelerate the speed when add global binding query", INDEX time_index(update_time) COMMENT "accelerate the speed when querying with last update time" ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;` @@ -398,6 +413,7 @@ const ( modify_count bigint(64) NOT NULL, count bigint(64) NOT NULL, version bigint(64) NOT NULL comment 'stats version which corresponding to stats:version in EXPLAIN', + source varchar(40) NOT NULL, create_time datetime(6) NOT NULL, UNIQUE KEY table_version (table_id, version), KEY table_create_time (table_id, create_time) @@ -428,11 +444,88 @@ const ( CreateMDLView = `CREATE OR REPLACE VIEW mysql.tidb_mdl_view as ( select JOB_ID, DB_NAME, TABLE_NAME, QUERY, SESSION_ID, TxnStart, TIDB_DECODE_SQL_DIGESTS(ALL_SQL_DIGESTS, 4096) AS SQL_DIGESTS from information_schema.ddl_jobs, information_schema.CLUSTER_TIDB_TRX, information_schema.CLUSTER_PROCESSLIST where ddl_jobs.STATE = 'running' and find_in_set(ddl_jobs.table_id, CLUSTER_TIDB_TRX.RELATED_TABLE_IDS) and CLUSTER_TIDB_TRX.SESSION_ID=CLUSTER_PROCESSLIST.ID );` + + // CreatePlanReplayerStatusTable is a table about plan replayer status + CreatePlanReplayerStatusTable = `CREATE TABLE IF NOT EXISTS mysql.plan_replayer_status ( + sql_digest VARCHAR(128), + plan_digest VARCHAR(128), + origin_sql TEXT, + token VARCHAR(128), + update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fail_reason TEXT, + instance VARCHAR(512) NOT NULL comment 'address of the TiDB instance executing the plan replayer job');` + + // CreatePlanReplayerTaskTable is a table about plan replayer capture task + CreatePlanReplayerTaskTable = `CREATE TABLE IF NOT EXISTS mysql.plan_replayer_task ( + sql_digest VARCHAR(128) NOT NULL, + plan_digest VARCHAR(128) NOT NULL, + update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (sql_digest,plan_digest));` + + // CreateStatsTableLocked stores the locked tables + CreateStatsTableLocked = `CREATE TABLE IF NOT EXISTS mysql.stats_table_locked( + table_id bigint(64) NOT NULL, + modify_count bigint(64) NOT NULL DEFAULT 0, + count bigint(64) NOT NULL DEFAULT 0, + version bigint(64) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (table_id));` + + // CreatePasswordHistory is a table save history passwd. + CreatePasswordHistory = `CREATE TABLE IF NOT EXISTS mysql.password_history ( + Host char(255) NOT NULL DEFAULT '', + User char(32) NOT NULL DEFAULT '', + Password_timestamp timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + Password text, + PRIMARY KEY (Host,User,Password_timestamp ) + ) COMMENT='Password history for user accounts' ` + + // CreateTTLTableStatus is a table about TTL job schedule + CreateTTLTableStatus = `CREATE TABLE IF NOT EXISTS mysql.tidb_ttl_table_status ( + table_id bigint(64) PRIMARY KEY, + parent_table_id bigint(64), + table_statistics text DEFAULT NULL, + last_job_id varchar(64) DEFAULT NULL, + last_job_start_time timestamp NULL DEFAULT NULL, + last_job_finish_time timestamp NULL DEFAULT NULL, + last_job_ttl_expire timestamp NULL DEFAULT NULL, + last_job_summary text DEFAULT NULL, + current_job_id varchar(64) DEFAULT NULL, + current_job_owner_id varchar(64) DEFAULT NULL, + current_job_owner_addr varchar(256) DEFAULT NULL, + current_job_owner_hb_time timestamp, + current_job_start_time timestamp NULL DEFAULT NULL, + current_job_ttl_expire timestamp NULL DEFAULT NULL, + current_job_state text DEFAULT NULL, + current_job_status varchar(64) DEFAULT NULL, + current_job_status_update_time timestamp NULL DEFAULT NULL);` + + // CreateTTLTask is a table about parallel ttl tasks + CreateTTLTask = `CREATE TABLE IF NOT EXISTS mysql.tidb_ttl_task ( + job_id varchar(64) NOT NULL, + table_id bigint(64) NOT NULL, + scan_id int NOT NULL, + scan_range_start BLOB, + scan_range_end BLOB, + expire_time timestamp NOT NULL, + owner_id varchar(64) DEFAULT NULL, + owner_addr varchar(64) DEFAULT NULL, + owner_hb_time timestamp DEFAULT NULL, + status varchar(64) DEFAULT 'waiting', + status_update_time timestamp NULL DEFAULT NULL, + state text, + created_time timestamp NOT NULL, + primary key(job_id, scan_id), + key(created_time));` ) // bootstrap initiates system DB for a store. func bootstrap(s Session) { startTime := time.Now() + err := InitMDLVariableForBootstrap(s.GetStore()) + if err != nil { + logutil.BgLogger().Fatal("init metadata lock error", + zap.Error(err)) + } dom := domain.GetDomain(s) for { b, err := checkBootstrapped(s) @@ -452,6 +545,7 @@ func bootstrap(s Session) { if dom.DDL().OwnerManager().IsOwner() { doDDLWorks(s) doDMLWorks(s) + runBootstrapSQLFile = true logutil.BgLogger().Info("bootstrap successful", zap.Duration("take time", time.Since(startTime))) return @@ -632,15 +726,51 @@ const ( // version93 converts oom-use-tmp-storage to a sysvar version93 = 93 version94 = 94 + // version95 add a column `User_attributes` to `mysql.user` + version95 = 95 + // version97 sets tidb_opt_range_max_size to 0 when a cluster upgrades from some version lower than v6.4.0 to v6.4.0+. + // It promises the compatibility of building ranges behavior. + version97 = 97 + // version98 add a column `Token_issuer` to `mysql.user` + version98 = 98 + version99 = 99 + // version100 converts server-memory-quota to a sysvar + version100 = 100 + // version101 add mysql.plan_replayer_status table + version101 = 101 + // version102 add mysql.plan_replayer_task table + version102 = 102 + // version103 adds the tables mysql.stats_table_locked + version103 = 103 + // version104 add `sql_digest` and `plan_digest` to `bind_info` + version104 = 104 + // version105 insert "tidb_cost_model_version|1" to mysql.GLOBAL_VARIABLES if there is no tidb_cost_model_version. + // This will only happens when we upgrade a cluster before 6.0. + version105 = 105 + // version106 add mysql.password_history, and Password_reuse_history, Password_reuse_time into mysql.user. + version106 = 106 + // version107 add columns related to password expiration into mysql.user + version107 = 107 + // version108 adds the table tidb_ttl_table_status + version108 = 108 + // version109 add column source to mysql.stats_meta_history + version109 = 109 + // version110 sets tidb_enable_gc_aware_memory_track to off when a cluster upgrades from some version lower than v6.5.0. + version110 = 110 + // version111 adds the table tidb_ttl_task + version111 = 111 ) // currentBootstrapVersion is defined as a variable, so we can modify its value for testing. // please make sure this is the largest version -var currentBootstrapVersion int64 = version94 +var currentBootstrapVersion int64 = version111 // DDL owner key's expired time is ManagerSessionTTL seconds, we should wait the time and give more time to have a chance to finish it. var internalSQLTimeout = owner.ManagerSessionTTL + 15 +// whether to run the sql file in bootstrap. +var runBootstrapSQLFile = false + var ( bootstrapVersion = []func(Session, int64){ upgradeToVer2, @@ -736,6 +866,22 @@ var ( upgradeToVer91, upgradeToVer93, upgradeToVer94, + upgradeToVer95, + // We will redo upgradeToVer96 in upgradeToVer100, it is skipped here. + upgradeToVer97, + upgradeToVer98, + upgradeToVer100, + upgradeToVer101, + upgradeToVer102, + upgradeToVer103, + upgradeToVer104, + upgradeToVer105, + upgradeToVer106, + upgradeToVer107, + upgradeToVer108, + upgradeToVer109, + upgradeToVer110, + upgradeToVer111, } ) @@ -807,7 +953,7 @@ func upgrade(s Session) { if ver < version92 { useConcurrentDDL, err := checkOwnerVersion(context.Background(), domain.GetDomain(s)) if err != nil { - logutil.BgLogger().Fatal("[Upgrade] upgrade failed", zap.Error(err)) + logutil.BgLogger().Fatal("[upgrade] upgrade failed", zap.Error(err)) } if !useConcurrentDDL { // Use another variable DDLForce2Queue but not EnableConcurrentDDL since in upgrade it may set global variable, the initial step will @@ -816,20 +962,26 @@ func upgrade(s Session) { } } // Do upgrade works then update bootstrap version. + isNull, err := InitMDLVariableForUpgrade(s.GetStore()) + if err != nil { + logutil.BgLogger().Fatal("[upgrade] init metadata lock failed", zap.Error(err)) + } + + if isNull { + upgradeToVer99Before(s) + } for _, upgrade := range bootstrapVersion { upgrade(s, ver) } + if isNull { + upgradeToVer99After(s) + } variable.DDLForce2Queue.Store(false) updateBootstrapVer(s) ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap) _, err = s.ExecuteInternal(ctx, "COMMIT") - if err == nil && ver <= version92 { - logutil.BgLogger().Info("start migrate DDLs") - err = domain.GetDomain(s).DDL().MoveJobFromQueue2Table(true) - } - if err != nil { sleepTime := 1 * time.Second logutil.BgLogger().Info("update bootstrap ver failed", @@ -844,7 +996,7 @@ func upgrade(s Session) { // It is already bootstrapped/upgraded by a higher version TiDB server. return } - logutil.BgLogger().Fatal("[Upgrade] upgrade failed", + logutil.BgLogger().Fatal("[upgrade] upgrade failed", zap.Int64("from", ver), zap.Int64("to", currentBootstrapVersion), zap.Error(err)) @@ -1498,7 +1650,8 @@ func initBindInfoTable(s Session) { } func insertBuiltinBindInfoRow(s Session) { - mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.bind_info VALUES (%?, %?, "mysql", %?, "0000-00-00 00:00:00", "0000-00-00 00:00:00", "", "", %?)`, + mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.bind_info(original_sql, bind_sql, default_db, status, create_time, update_time, charset, collation, source) + VALUES (%?, %?, "mysql", %?, "0000-00-00 00:00:00", "0000-00-00 00:00:00", "", "", %?)`, bindinfo.BuiltinPseudoSQL4BindLock, bindinfo.BuiltinPseudoSQL4BindLock, bindinfo.Builtin, bindinfo.Builtin, ) } @@ -1931,6 +2084,163 @@ func upgradeToVer94(s Session, ver int64) { mustExecute(s, CreateMDLView) } +func upgradeToVer95(s Session, ver int64) { + if ver >= version95 { + return + } + doReentrantDDL(s, "ALTER TABLE mysql.user ADD COLUMN IF NOT EXISTS `User_attributes` JSON") +} + +func upgradeToVer97(s Session, ver int64) { + if ver >= version97 { + return + } + // Check if tidb_opt_range_max_size exists in mysql.GLOBAL_VARIABLES. + // If not, insert "tidb_opt_range_max_size | 0" since this is the old behavior before we introduce this variable. + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap) + rs, err := s.ExecuteInternal(ctx, "SELECT VARIABLE_VALUE FROM %n.%n WHERE VARIABLE_NAME=%?;", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBOptRangeMaxSize) + terror.MustNil(err) + req := rs.NewChunk(nil) + err = rs.Next(ctx, req) + terror.MustNil(err) + if req.NumRows() != 0 { + return + } + + mustExecute(s, "INSERT HIGH_PRIORITY IGNORE INTO %n.%n VALUES (%?, %?);", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBOptRangeMaxSize, 0) +} + +func upgradeToVer98(s Session, ver int64) { + if ver >= version98 { + return + } + doReentrantDDL(s, "ALTER TABLE mysql.user ADD COLUMN IF NOT EXISTS `Token_issuer` varchar(255)") +} + +func upgradeToVer99Before(s Session) { + mustExecute(s, "INSERT HIGH_PRIORITY IGNORE INTO %n.%n VALUES (%?, %?);", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBEnableMDL, 0) +} + +func upgradeToVer99After(s Session) { + sql := fmt.Sprintf("UPDATE HIGH_PRIORITY %[1]s.%[2]s SET VARIABLE_VALUE = %[4]d WHERE VARIABLE_NAME = '%[3]s'", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBEnableMDL, 1) + mustExecute(s, sql) + err := kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), s.GetStore(), true, func(ctx context.Context, txn kv.Transaction) error { + t := meta.NewMeta(txn) + return t.SetMetadataLock(true) + }) + terror.MustNil(err) +} + +func upgradeToVer100(s Session, ver int64) { + if ver >= version100 { + return + } + valStr := strconv.Itoa(int(config.GetGlobalConfig().Performance.ServerMemoryQuota)) + importConfigOption(s, "performance.server-memory-quota", variable.TiDBServerMemoryLimit, valStr) +} + +func upgradeToVer101(s Session, ver int64) { + if ver >= version101 { + return + } + doReentrantDDL(s, CreatePlanReplayerStatusTable) +} + +func upgradeToVer102(s Session, ver int64) { + if ver >= version102 { + return + } + doReentrantDDL(s, CreatePlanReplayerTaskTable) +} + +func upgradeToVer103(s Session, ver int64) { + if ver >= version103 { + return + } + doReentrantDDL(s, CreateStatsTableLocked) +} + +func upgradeToVer104(s Session, ver int64) { + if ver >= version104 { + return + } + + doReentrantDDL(s, "ALTER TABLE mysql.bind_info ADD COLUMN IF NOT EXISTS `sql_digest` varchar(64)") + doReentrantDDL(s, "ALTER TABLE mysql.bind_info ADD COLUMN IF NOT EXISTS `plan_digest` varchar(64)") +} + +// For users that upgrade TiDB from a pre-6.0 version, we want to disable tidb cost model2 by default to keep plans unchanged. +func upgradeToVer105(s Session, ver int64) { + if ver >= version105 { + return + } + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap) + rs, err := s.ExecuteInternal(ctx, "SELECT VARIABLE_VALUE FROM %n.%n WHERE VARIABLE_NAME=%?;", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBCostModelVersion) + terror.MustNil(err) + req := rs.NewChunk(nil) + err = rs.Next(ctx, req) + terror.MustNil(err) + if req.NumRows() != 0 { + return + } + + mustExecute(s, "INSERT HIGH_PRIORITY IGNORE INTO %n.%n VALUES (%?, %?);", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBCostModelVersion, "1") +} + +func upgradeToVer106(s Session, ver int64) { + if ver >= version106 { + return + } + doReentrantDDL(s, CreatePasswordHistory) + doReentrantDDL(s, "Alter table mysql.user add COLUMN IF NOT EXISTS `Password_reuse_history` smallint unsigned DEFAULT NULL AFTER `Create_Tablespace_Priv` ") + doReentrantDDL(s, "Alter table mysql.user add COLUMN IF NOT EXISTS `Password_reuse_time` smallint unsigned DEFAULT NULL AFTER `Password_reuse_history`") +} + +func upgradeToVer107(s Session, ver int64) { + if ver >= version107 { + return + } + doReentrantDDL(s, "ALTER TABLE mysql.user ADD COLUMN IF NOT EXISTS `Password_expired` ENUM('N','Y') NOT NULL DEFAULT 'N'") + doReentrantDDL(s, "ALTER TABLE mysql.user ADD COLUMN IF NOT EXISTS `Password_last_changed` TIMESTAMP DEFAULT CURRENT_TIMESTAMP()") + doReentrantDDL(s, "ALTER TABLE mysql.user ADD COLUMN IF NOT EXISTS `Password_lifetime` SMALLINT UNSIGNED DEFAULT NULL") +} + +func upgradeToVer108(s Session, ver int64) { + if ver >= version108 { + return + } + doReentrantDDL(s, CreateTTLTableStatus) +} + +func upgradeToVer109(s Session, ver int64) { + if ver >= version109 { + return + } + doReentrantDDL(s, "ALTER TABLE mysql.stats_meta_history ADD COLUMN IF NOT EXISTS `source` varchar(40) NOT NULL after `version`;") +} + +// For users that upgrade TiDB from a 6.2-6.4 version, we want to disable tidb gc_aware_memory_track by default. +func upgradeToVer110(s Session, ver int64) { + if ver >= version110 { + return + } + mustExecute(s, "REPLACE HIGH_PRIORITY INTO %n.%n VALUES (%?, %?);", + mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBEnableGCAwareMemoryTrack, 0) +} + +func upgradeToVer111(s Session, ver int64) { + if ver >= version111 { + return + } + doReentrantDDL(s, CreateTTLTask) +} + func writeOOMAction(s Session) { comment := "oom-action is `log` by default in v3.0.x, `cancel` by default in v4.0.11+" mustExecute(s, `INSERT HIGH_PRIORITY INTO %n.%n VALUES (%?, %?, %?) ON DUPLICATE KEY UPDATE VARIABLE_VALUE= %?`, @@ -1966,6 +2276,8 @@ func doDDLWorks(s Session) { mustExecute(s, "CREATE DATABASE IF NOT EXISTS %n", mysql.SystemDB) // Create user table. mustExecute(s, CreateUserTable) + // Create password history. + mustExecute(s, CreatePasswordHistory) // Create privilege tables. mustExecute(s, CreateGlobalPrivTable) mustExecute(s, CreateDBPrivTable) @@ -2027,6 +2339,48 @@ func doDDLWorks(s Session) { mustExecute(s, CreateAdvisoryLocks) // Create mdl view. mustExecute(s, CreateMDLView) + // Create plan_replayer_status table + mustExecute(s, CreatePlanReplayerStatusTable) + // Create plan_replayer_task table + mustExecute(s, CreatePlanReplayerTaskTable) + // Create stats_meta_table_locked table + mustExecute(s, CreateStatsTableLocked) + // Create tidb_ttl_table_status table + mustExecute(s, CreateTTLTableStatus) + // Create tidb_ttl_task table + mustExecute(s, CreateTTLTask) +} + +// doBootstrapSQLFile executes SQL commands in a file as the last stage of bootstrap. +// It is useful for setting the initial value of GLOBAL variables. +func doBootstrapSQLFile(s Session) { + sqlFile := config.GetGlobalConfig().InitializeSQLFile + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap) + if sqlFile == "" { + return + } + logutil.BgLogger().Info("executing -initialize-sql-file", zap.String("file", sqlFile)) + b, err := ioutil.ReadFile(sqlFile) //nolint:gosec + if err != nil { + logutil.BgLogger().Fatal("unable to read InitializeSQLFile", zap.Error(err)) + } + stmts, err := s.Parse(ctx, string(b)) + if err != nil { + logutil.BgLogger().Fatal("unable to parse InitializeSQLFile", zap.Error(err)) + } + for _, stmt := range stmts { + rs, err := s.ExecuteStmt(ctx, stmt) + if err != nil { + logutil.BgLogger().Warn("InitializeSQLFile error", zap.Error(err)) + } + if rs != nil { + // I don't believe we need to drain the result-set in bootstrap mode + // but if required we can do this here in future. + if err := rs.Close(); err != nil { + logutil.BgLogger().Fatal("unable to close result", zap.Error(err)) + } + } + } } // inTestSuite checks if we are bootstrapping in the context of tests. @@ -2047,11 +2401,15 @@ func doDMLWorks(s Session) { if err != nil { logutil.BgLogger().Fatal("failed to read current user. unable to secure bootstrap.", zap.Error(err)) } - mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user VALUES - ("localhost", "root", %?, "auth_socket", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y")`, u.Username) + mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user (Host,User,authentication_string,plugin,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Process_priv,Grant_priv,References_priv,Alter_priv,Show_db_priv, + Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Index_priv,Create_user_priv,Event_priv,Repl_slave_priv,Repl_client_priv,Trigger_priv,Create_role_priv,Drop_role_priv,Account_locked, + Shutdown_priv,Reload_priv,FILE_priv,Config_priv,Create_Tablespace_Priv,User_attributes,Token_issuer) VALUES + ("localhost", "root", %?, "auth_socket", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y", null, "")`, u.Username) } else { - mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user VALUES - ("%", "root", "", "mysql_native_password", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y")`) + mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user (Host,User,authentication_string,plugin,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Process_priv,Grant_priv,References_priv,Alter_priv,Show_db_priv, + Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Index_priv,Create_user_priv,Event_priv,Repl_slave_priv,Repl_client_priv,Trigger_priv,Create_role_priv,Drop_role_priv,Account_locked, + Shutdown_priv,Reload_priv,FILE_priv,Config_priv,Create_Tablespace_Priv,User_attributes,Token_issuer) VALUES + ("%", "root", "", "mysql_native_password", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y", null, "")`) } // For GLOBAL scoped system variables, insert the initial value @@ -2113,8 +2471,6 @@ func doDMLWorks(s Session) { writeNewCollationParameter(s, config.GetGlobalConfig().NewCollationsEnabledOnFirstBootstrap) - writeDefaultExprPushDownBlacklist(s) - writeStmtSummaryVars(s) ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap) @@ -2161,7 +2517,7 @@ func oldPasswordUpgrade(pass string) (string, error) { // rebuildAllPartitionValueMapAndSorted rebuilds all value map and sorted info for list column partitions with InfoSchema. func rebuildAllPartitionValueMapAndSorted(s *session) { type partitionExpr interface { - PartitionExpr() (*tables.PartitionExpr, error) + PartitionExpr() *tables.PartitionExpr } p := parser.New() @@ -2173,12 +2529,9 @@ func rebuildAllPartitionValueMapAndSorted(s *session) { continue } - pe, err := t.(partitionExpr).PartitionExpr() - if err != nil { - panic("partition table gets partition expression failed") - } + pe := t.(partitionExpr).PartitionExpr() for _, cp := range pe.ColPrunes { - if err = cp.RebuildPartitionValueMapAndSorted(p); err != nil { + if err := cp.RebuildPartitionValueMapAndSorted(p, pi.Definitions); err != nil { logutil.BgLogger().Warn("build list column partition value map and sorted failed") break } diff --git a/session/bootstrap_test.go b/session/bootstrap_test.go index 68ce4e8d3ac44..a010daf32b14c 100644 --- a/session/bootstrap_test.go +++ b/session/bootstrap_test.go @@ -17,11 +17,14 @@ package session import ( "context" "fmt" + "os" "strconv" "strings" "testing" + "time" "github.com/pingcap/tidb/bindinfo" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/meta" "github.com/pingcap/tidb/parser/auth" @@ -45,7 +48,7 @@ func TestBootstrap(t *testing.T) { se := createSessionAndSetID(t, store) mustExec(t, se, "set global tidb_txn_mode=''") mustExec(t, se, "use mysql") - r := mustExec(t, se, "select * from user") + r := mustExecToRecodeSet(t, se, "select * from user") require.NotNil(t, r) ctx := context.Background() @@ -55,7 +58,7 @@ func TestBootstrap(t *testing.T) { require.NotEqual(t, 0, req.NumRows()) rows := statistics.RowToDatums(req.GetRow(0), r.Fields()) - match(t, rows, `%`, "root", "", "mysql_native_password", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y") + match(t, rows, `%`, "root", "", "mysql_native_password", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y", nil, nil, nil, "", "N", time.Now(), nil) r.Close() require.NoError(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "anyhost"}, []byte(""), []byte(""))) @@ -63,25 +66,21 @@ func TestBootstrap(t *testing.T) { mustExec(t, se, "use test") // Check privilege tables. - rs := mustExec(t, se, "SELECT * from mysql.global_priv") - require.NoError(t, rs.Close()) - rs = mustExec(t, se, "SELECT * from mysql.db") - require.NoError(t, rs.Close()) - rs = mustExec(t, se, "SELECT * from mysql.tables_priv") - require.NoError(t, rs.Close()) - rs = mustExec(t, se, "SELECT * from mysql.columns_priv") - require.NoError(t, rs.Close()) - rs = mustExec(t, se, "SELECT * from mysql.global_grants") - require.NoError(t, rs.Close()) + mustExec(t, se, "SELECT * from mysql.global_priv") + mustExec(t, se, "SELECT * from mysql.db") + mustExec(t, se, "SELECT * from mysql.tables_priv") + mustExec(t, se, "SELECT * from mysql.columns_priv") + mustExec(t, se, "SELECT * from mysql.global_grants") // Check privilege tables. - r = mustExec(t, se, "SELECT COUNT(*) from mysql.global_variables") + r = mustExecToRecodeSet(t, se, "SELECT COUNT(*) from mysql.global_variables") require.NotNil(t, r) req = r.NewChunk(nil) err = r.Next(ctx, req) require.NoError(t, err) require.Equal(t, globalVarsCount(), req.GetRow(0).GetInt64(0)) + require.NoError(t, r.Close()) // Check a storage operations are default autocommit after the second start. mustExec(t, se, "USE test") @@ -98,7 +97,7 @@ func TestBootstrap(t *testing.T) { se, err = CreateSession4Test(store) require.NoError(t, err) mustExec(t, se, "USE test") - r = mustExec(t, se, "select * from t") + r = mustExecToRecodeSet(t, se, "select * from t") require.NotNil(t, r) req = r.NewChunk(nil) @@ -114,6 +113,12 @@ func TestBootstrap(t *testing.T) { se, err = CreateSession4Test(store) require.NoError(t, err) doDMLWorks(se) + r = mustExecToRecodeSet(t, se, "select * from mysql.expr_pushdown_blacklist where name = 'date_add'") + req = r.NewChunk(nil) + err = r.Next(ctx, req) + require.NoError(t, err) + require.Equal(t, 0, req.NumRows()) + se.Close() } func globalVarsCount() int64 { @@ -171,7 +176,7 @@ func TestBootstrapWithError(t *testing.T) { se := createSessionAndSetID(t, store) mustExec(t, se, "USE mysql") - r := mustExec(t, se, `select * from user`) + r := mustExecToRecodeSet(t, se, `select * from user`) req := r.NewChunk(nil) err = r.Next(ctx, req) require.NoError(t, err) @@ -179,20 +184,20 @@ func TestBootstrapWithError(t *testing.T) { row := req.GetRow(0) rows := statistics.RowToDatums(row, r.Fields()) - match(t, rows, `%`, "root", "", "mysql_native_password", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y") + match(t, rows, `%`, "root", "", "mysql_native_password", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y", nil, nil, nil, "", "N", time.Now(), nil) require.NoError(t, r.Close()) mustExec(t, se, "USE test") // Check privilege tables. - mustExec(t, se, "SELECT * from mysql.global_priv").Close() - mustExec(t, se, "SELECT * from mysql.db").Close() - mustExec(t, se, "SELECT * from mysql.tables_priv").Close() - mustExec(t, se, "SELECT * from mysql.columns_priv").Close() + mustExec(t, se, "SELECT * from mysql.global_priv") + mustExec(t, se, "SELECT * from mysql.db") + mustExec(t, se, "SELECT * from mysql.tables_priv") + mustExec(t, se, "SELECT * from mysql.columns_priv") // Check role tables. - mustExec(t, se, "SELECT * from mysql.role_edges").Close() - mustExec(t, se, "SELECT * from mysql.default_roles").Close() + mustExec(t, se, "SELECT * from mysql.role_edges") + mustExec(t, se, "SELECT * from mysql.default_roles") // Check global variables. - r = mustExec(t, se, "SELECT COUNT(*) from mysql.global_variables") + r = mustExecToRecodeSet(t, se, "SELECT COUNT(*) from mysql.global_variables") req = r.NewChunk(nil) err = r.Next(ctx, req) require.NoError(t, err) @@ -200,7 +205,7 @@ func TestBootstrapWithError(t *testing.T) { require.Equal(t, globalVarsCount(), v.GetInt64(0)) require.NoError(t, r.Close()) - r = mustExec(t, se, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="bootstrapped"`) + r = mustExecToRecodeSet(t, se, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="bootstrapped"`) req = r.NewChunk(nil) err = r.Next(ctx, req) require.NoError(t, err) @@ -209,6 +214,9 @@ func TestBootstrapWithError(t *testing.T) { require.Equal(t, 1, row.Len()) require.Equal(t, []byte("True"), row.GetBytes(0)) require.NoError(t, r.Close()) + + // Check tidb_ttl_table_status table + mustExec(t, se, "SELECT * from mysql.tidb_ttl_table_status") } // TestUpgrade tests upgrading @@ -222,7 +230,7 @@ func TestUpgrade(t *testing.T) { mustExec(t, se, "USE mysql") // bootstrap with currentBootstrapVersion - r := mustExec(t, se, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="tidb_server_version"`) + r := mustExecToRecodeSet(t, se, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="tidb_server_version"`) req := r.NewChunk(nil) err := r.Next(ctx, req) row := req.GetRow(0) @@ -251,7 +259,7 @@ func TestUpgrade(t *testing.T) { mustExec(t, se1, `commit`) unsetStoreBootstrapped(store.UUID()) // Make sure the version is downgraded. - r = mustExec(t, se1, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="tidb_server_version"`) + r = mustExecToRecodeSet(t, se1, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="tidb_server_version"`) req = r.NewChunk(nil) err = r.Next(ctx, req) require.NoError(t, err) @@ -267,7 +275,7 @@ func TestUpgrade(t *testing.T) { require.NoError(t, err) se2 := createSessionAndSetID(t, store) - r = mustExec(t, se2, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="tidb_server_version"`) + r = mustExecToRecodeSet(t, se2, `SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME="tidb_server_version"`) req = r.NewChunk(nil) err = r.Next(ctx, req) require.NoError(t, err) @@ -282,7 +290,7 @@ func TestUpgrade(t *testing.T) { require.Equal(t, currentBootstrapVersion, ver) // Verify that 'new_collation_enabled' is false. - r = mustExec(t, se2, fmt.Sprintf(`SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME='%s'`, tidbNewCollationEnabled)) + r = mustExecToRecodeSet(t, se2, fmt.Sprintf(`SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME='%s'`, tidbNewCollationEnabled)) req = r.NewChunk(nil) err = r.Next(ctx, req) require.NoError(t, err) @@ -320,7 +328,7 @@ func TestIssue17979_1(t *testing.T) { ver, err = getBootstrapVersion(seV4) require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - r := mustExec(t, seV4, "select variable_value from mysql.tidb where variable_name='default_oom_action'") + r := mustExecToRecodeSet(t, seV4, "select variable_value from mysql.tidb where variable_name='default_oom_action'") req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, variable.OOMActionLog, req.GetRow(0).GetString(0)) @@ -357,7 +365,7 @@ func TestIssue17979_2(t *testing.T) { ver, err = getBootstrapVersion(seV4) require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - r := mustExec(t, seV4, "select variable_value from mysql.tidb where variable_name='default_oom_action'") + r := mustExecToRecodeSet(t, seV4, "select variable_value from mysql.tidb where variable_name='default_oom_action'") req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, 0, req.NumRows()) @@ -398,12 +406,12 @@ func TestIssue20900_2(t *testing.T) { ver, err = getBootstrapVersion(seV4) require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - r := mustExec(t, seV4, "select @@tidb_mem_quota_query") + r := mustExecToRecodeSet(t, seV4, "select @@tidb_mem_quota_query") req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, "1073741824", req.GetRow(0).GetString(0)) require.Equal(t, int64(1073741824), seV4.GetSessionVars().MemQuotaQuery) - r = mustExec(t, seV4, "select variable_value from mysql.tidb where variable_name='default_memory_quota_query'") + r = mustExecToRecodeSet(t, seV4, "select variable_value from mysql.tidb where variable_name='default_memory_quota_query'") req = r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, 0, req.NumRows()) @@ -465,7 +473,7 @@ func TestStmtSummary(t *testing.T) { defer dom.Close() se := createSessionAndSetID(t, store) - r := mustExec(t, se, "select variable_value from mysql.global_variables where variable_name='tidb_enable_stmt_summary'") + r := mustExecToRecodeSet(t, se, "select variable_value from mysql.global_variables where variable_name='tidb_enable_stmt_summary'") req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) row := req.GetRow(0) @@ -515,6 +523,9 @@ func TestUpdateBindInfo(t *testing.T) { defer func() { require.NoError(t, store.Close()) }() defer dom.Close() se := createSessionAndSetID(t, store) + + mustExec(t, se, "alter table mysql.bind_info drop column if exists plan_digest") + mustExec(t, se, "alter table mysql.bind_info drop column if exists sql_digest") for _, bindCase := range bindCases { sql := fmt.Sprintf("insert into mysql.bind_info values('%s', '%s', '%s', 'enabled', '2021-01-04 14:50:58.257', '2021-01-04 14:50:58.257', 'utf8', 'utf8_general_ci', 'manual')", bindCase.originText, @@ -524,7 +535,7 @@ func TestUpdateBindInfo(t *testing.T) { mustExec(t, se, sql) upgradeToVer67(se, version66) - r := mustExec(t, se, `select original_sql, bind_sql, default_db, status from mysql.bind_info where source != 'builtin'`) + r := mustExecToRecodeSet(t, se, `select original_sql, bind_sql, default_db, status from mysql.bind_info where source != 'builtin'`) req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) row := req.GetRow(0) @@ -535,7 +546,7 @@ func TestUpdateBindInfo(t *testing.T) { require.NoError(t, r.Close()) sql = fmt.Sprintf("drop global binding for %s", bindCase.deleteText) mustExec(t, se, sql) - r = mustExec(t, se, `select original_sql, bind_sql, status from mysql.bind_info where source != 'builtin'`) + r = mustExecToRecodeSet(t, se, `select original_sql, bind_sql, status from mysql.bind_info where source != 'builtin'`) require.NoError(t, r.Next(ctx, req)) row = req.GetRow(0) require.Equal(t, bindCase.originWithDB, row.GetString(0)) @@ -553,6 +564,9 @@ func TestUpdateDuplicateBindInfo(t *testing.T) { defer func() { require.NoError(t, store.Close()) }() defer dom.Close() se := createSessionAndSetID(t, store) + mustExec(t, se, "alter table mysql.bind_info drop column if exists plan_digest") + mustExec(t, se, "alter table mysql.bind_info drop column if exists sql_digest") + mustExec(t, se, `insert into mysql.bind_info values('select * from t', 'select /*+ use_index(t, idx_a)*/ * from t', 'test', 'enabled', '2021-01-04 14:50:58.257', '2021-01-04 14:50:58.257', 'utf8', 'utf8_general_ci', 'manual')`) // The latest one. mustExec(t, se, `insert into mysql.bind_info values('select * from test . t', 'select /*+ use_index(t, idx_b)*/ * from test.t', 'test', 'enabled', '2021-01-04 14:50:58.257', '2021-01-09 14:50:58.257', 'utf8', 'utf8_general_ci', 'manual')`) @@ -564,7 +578,7 @@ func TestUpdateDuplicateBindInfo(t *testing.T) { upgradeToVer67(se, version66) - r := mustExec(t, se, `select original_sql, bind_sql, default_db, status, create_time from mysql.bind_info where source != 'builtin' order by create_time`) + r := mustExecToRecodeSet(t, se, `select original_sql, bind_sql, default_db, status, create_time from mysql.bind_info where source != 'builtin' order by create_time`) req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, 3, req.NumRows()) @@ -620,13 +634,13 @@ func TestUpgradeClusteredIndexDefaultValue(t *testing.T) { require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - r := mustExec(t, seV68, `select @@global.tidb_enable_clustered_index, @@session.tidb_enable_clustered_index`) + r := mustExecToRecodeSet(t, seV68, `select @@global.tidb_enable_clustered_index, @@session.tidb_enable_clustered_index`) req := r.NewChunk(nil) require.NoError(t, r.Next(context.Background(), req)) require.Equal(t, 1, req.NumRows()) row := req.GetRow(0) - require.Equal(t, "INT_ONLY", row.GetString(0)) - require.Equal(t, "INT_ONLY", row.GetString(1)) + require.Equal(t, "ON", row.GetString(0)) + require.Equal(t, "ON", row.GetString(1)) domV68.Close() } @@ -657,7 +671,7 @@ func TestUpgradeVersion66(t *testing.T) { ver, err = getBootstrapVersion(seV66) require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - r := mustExec(t, seV66, `select @@global.tidb_track_aggregate_memory_usage, @@session.tidb_track_aggregate_memory_usage`) + r := mustExecToRecodeSet(t, seV66, `select @@global.tidb_track_aggregate_memory_usage, @@session.tidb_track_aggregate_memory_usage`) req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, 1, req.NumRows()) @@ -707,7 +721,7 @@ func TestUpgradeVersion74(t *testing.T) { ver, err = getBootstrapVersion(seV74) require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - r := mustExec(t, seV74, `SELECT @@global.tidb_stmt_summary_max_stmt_count`) + r := mustExecToRecodeSet(t, seV74, `SELECT @@global.tidb_stmt_summary_max_stmt_count`) req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, 1, req.NumRows()) @@ -740,7 +754,7 @@ func TestUpgradeVersion75(t *testing.T) { ver, err := getBootstrapVersion(seV74) require.NoError(t, err) require.Equal(t, int64(74), ver) - r := mustExec(t, seV74, `desc mysql.user`) + r := mustExecToRecodeSet(t, seV74, `desc mysql.user`) req := r.NewChunk(nil) row := req.GetRow(0) require.NoError(t, r.Next(ctx, req)) @@ -754,7 +768,7 @@ func TestUpgradeVersion75(t *testing.T) { ver, err = getBootstrapVersion(seV75) require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - r = mustExec(t, seV75, `desc mysql.user`) + r = mustExecToRecodeSet(t, seV75, `desc mysql.user`) req = r.NewChunk(nil) row = req.GetRow(0) require.NoError(t, r.Next(ctx, req)) @@ -836,7 +850,7 @@ func TestAnalyzeVersionUpgradeFrom300To500(t *testing.T) { require.Equal(t, int64(ver300), ver) // We are now in 3.0.0, check tidb_analyze_version should not exist. - res := mustExec(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBAnalyzeVersion)) + res := mustExecToRecodeSet(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBAnalyzeVersion)) chk := res.NewChunk(nil) err = res.Next(ctx, chk) require.NoError(t, err) @@ -851,7 +865,7 @@ func TestAnalyzeVersionUpgradeFrom300To500(t *testing.T) { require.Equal(t, currentBootstrapVersion, ver) // We are now in version no lower than 5.x, tidb_enable_index_merge should be 1. - res = mustExec(t, seCurVer, "select @@tidb_analyze_version") + res = mustExecToRecodeSet(t, seCurVer, "select @@tidb_analyze_version") chk = res.NewChunk(nil) err = res.Next(ctx, chk) require.NoError(t, err) @@ -874,7 +888,7 @@ func TestIndexMergeInNewCluster(t *testing.T) { // In a new created cluster(above 5.4+), tidb_enable_index_merge is 1 by default. mustExec(t, se, "use test;") - r := mustExec(t, se, "select @@tidb_enable_index_merge;") + r := mustExecToRecodeSet(t, se, "select @@tidb_enable_index_merge;") require.NotNil(t, r) ctx := context.Background() @@ -911,7 +925,7 @@ func TestIndexMergeUpgradeFrom300To540(t *testing.T) { require.Equal(t, int64(ver300), ver) // We are now in 3.0.0, check tidb_enable_index_merge shoudle not exist. - res := mustExec(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableIndexMerge)) + res := mustExecToRecodeSet(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableIndexMerge)) chk := res.NewChunk(nil) err = res.Next(ctx, chk) require.NoError(t, err) @@ -926,7 +940,7 @@ func TestIndexMergeUpgradeFrom300To540(t *testing.T) { require.Equal(t, currentBootstrapVersion, ver) // We are now in 5.x, tidb_enable_index_merge should be off. - res = mustExec(t, seCurVer, "select @@tidb_enable_index_merge") + res = mustExecToRecodeSet(t, seCurVer, "select @@tidb_enable_index_merge") chk = res.NewChunk(nil) err = res.Next(ctx, chk) require.NoError(t, err) @@ -962,7 +976,7 @@ func TestIndexMergeUpgradeFrom400To540(t *testing.T) { require.Equal(t, int64(ver400), ver) // We are now in 4.0.0, tidb_enable_index_merge is off. - res := mustExec(t, seV4, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableIndexMerge)) + res := mustExecToRecodeSet(t, seV4, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableIndexMerge)) chk := res.NewChunk(nil) err = res.Next(ctx, chk) require.NoError(t, err) @@ -988,7 +1002,7 @@ func TestIndexMergeUpgradeFrom400To540(t *testing.T) { require.Equal(t, currentBootstrapVersion, ver) // We are now in 5.x, tidb_enable_index_merge should be on because we enable it in 4.0.0. - res = mustExec(t, seCurVer, "select @@tidb_enable_index_merge") + res = mustExecToRecodeSet(t, seCurVer, "select @@tidb_enable_index_merge") chk = res.NewChunk(nil) err = res.Next(ctx, chk) require.NoError(t, err) @@ -1010,6 +1024,9 @@ func TestUpgradeToVer85(t *testing.T) { defer func() { require.NoError(t, store.Close()) }() defer dom.Close() se := createSessionAndSetID(t, store) + mustExec(t, se, "alter table mysql.bind_info drop column if exists plan_digest") + mustExec(t, se, "alter table mysql.bind_info drop column if exists sql_digest") + mustExec(t, se, `insert into mysql.bind_info values('select * from t', 'select /*+ use_index(t, idx_a)*/ * from t', 'test', 'using', '2021-01-04 14:50:58.257', '2021-01-04 14:50:58.257', 'utf8', 'utf8_general_ci', 'manual')`) mustExec(t, se, `insert into mysql.bind_info values('select * from t1', 'select /*+ use_index(t1, idx_a)*/ * from t1', 'test', 'enabled', '2021-01-05 14:50:58.257', '2021-01-05 14:50:58.257', 'utf8', 'utf8_general_ci', 'manual')`) mustExec(t, se, `insert into mysql.bind_info values('select * from t2', 'select /*+ use_index(t2, idx_a)*/ * from t2', 'test', 'disabled', '2021-01-06 14:50:58.257', '2021-01-06 14:50:58.257', 'utf8', 'utf8_general_ci', 'manual')`) @@ -1017,7 +1034,7 @@ func TestUpgradeToVer85(t *testing.T) { mustExec(t, se, `insert into mysql.bind_info values('select * from t4', 'select /*+ use_index(t4, idx_a)*/ * from t4', 'test', 'invalid', '2021-01-08 14:50:58.257', '2021-01-08 14:50:58.257', 'utf8', 'utf8_general_ci', 'manual')`) upgradeToVer85(se, version84) - r := mustExec(t, se, `select count(*) from mysql.bind_info where status = 'enabled'`) + r := mustExecToRecodeSet(t, se, `select count(*) from mysql.bind_info where status = 'enabled'`) req := r.NewChunk(nil) require.NoError(t, r.Next(ctx, req)) require.Equal(t, 1, req.NumRows()) @@ -1028,6 +1045,60 @@ func TestUpgradeToVer85(t *testing.T) { mustExec(t, se, "delete from mysql.bind_info where default_db = 'test'") } +func TestInitializeSQLFile(t *testing.T) { + // We create an initialize-sql-file and then bootstrap the server with it. + // The observed behavior should be that tidb_enable_noop_variables is now + // disabled, and the feature works as expected. + initializeSQLFile, err := os.CreateTemp("", "init.sql") + require.NoError(t, err) + defer func() { + path := initializeSQLFile.Name() + err = initializeSQLFile.Close() + require.NoError(t, err) + err = os.Remove(path) + require.NoError(t, err) + }() + // Implicitly test multi-line init files + _, err = initializeSQLFile.WriteString( + "CREATE DATABASE initsqlfiletest;\n" + + "SET GLOBAL tidb_enable_noop_variables = OFF;\n") + require.NoError(t, err) + + // Create a mock store + // Set the config parameter for initialize sql file + store, err := mockstore.NewMockStore() + require.NoError(t, err) + config.GetGlobalConfig().InitializeSQLFile = initializeSQLFile.Name() + defer func() { + require.NoError(t, store.Close()) + config.GetGlobalConfig().InitializeSQLFile = "" + }() + + // Bootstrap with the InitializeSQLFile config option + dom, err := BootstrapSession(store) + require.NoError(t, err) + defer dom.Close() + se := createSessionAndSetID(t, store) + ctx := context.Background() + r, err := exec(se, `SHOW VARIABLES LIKE 'query_cache_type'`) + require.NoError(t, err) + req := r.NewChunk(nil) + err = r.Next(ctx, req) + require.NoError(t, err) + require.Equal(t, 0, req.NumRows()) // not shown in noopvariables mode + require.NoError(t, r.Close()) + + r, err = exec(se, `SHOW VARIABLES LIKE 'tidb_enable_noop_variables'`) + require.NoError(t, err) + req = r.NewChunk(nil) + err = r.Next(ctx, req) + require.NoError(t, err) + require.Equal(t, 1, req.NumRows()) + row := req.GetRow(0) + require.Equal(t, []byte("OFF"), row.GetBytes(1)) + require.NoError(t, r.Close()) +} + func TestTiDBEnablePagingVariable(t *testing.T) { store, dom := createStoreAndBootstrap(t) se := createSessionAndSetID(t, store) @@ -1038,7 +1109,7 @@ func TestTiDBEnablePagingVariable(t *testing.T) { "select @@global.tidb_enable_paging", "select @@session.tidb_enable_paging", } { - r := mustExec(t, se, sql) + r := mustExecToRecodeSet(t, se, sql) require.NotNil(t, r) req := r.NewChunk(nil) @@ -1055,3 +1126,259 @@ func TestTiDBEnablePagingVariable(t *testing.T) { r.Close() } } + +func TestTiDBOptRangeMaxSizeWhenUpgrading(t *testing.T) { + ctx := context.Background() + store, dom := createStoreAndBootstrap(t) + defer func() { require.NoError(t, store.Close()) }() + + // Upgrade from v6.3.0 to v6.4.0+. + ver94 := 94 + seV630 := createSessionAndSetID(t, store) + txn, err := store.Begin() + require.NoError(t, err) + m := meta.NewMeta(txn) + err = m.FinishBootstrap(int64(ver94)) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + mustExec(t, seV630, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver94)) + mustExec(t, seV630, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBOptRangeMaxSize)) + mustExec(t, seV630, "commit") + unsetStoreBootstrapped(store.UUID()) + ver, err := getBootstrapVersion(seV630) + require.NoError(t, err) + require.Equal(t, int64(ver94), ver) + + // We are now in 6.3.0, check tidb_opt_range_max_size should not exist. + res := mustExecToRecodeSet(t, seV630, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBOptRangeMaxSize)) + chk := res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 0, chk.NumRows()) + dom.Close() + domCurVer, err := BootstrapSession(store) + require.NoError(t, err) + defer domCurVer.Close() + seCurVer := createSessionAndSetID(t, store) + ver, err = getBootstrapVersion(seCurVer) + require.NoError(t, err) + require.Equal(t, currentBootstrapVersion, ver) + + // We are now in version no lower than v6.4.0, tidb_opt_range_max_size should be 0. + res = mustExecToRecodeSet(t, seCurVer, "select @@session.tidb_opt_range_max_size") + chk = res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row := chk.GetRow(0) + require.Equal(t, 1, row.Len()) + require.Equal(t, "0", row.GetString(0)) + + res = mustExecToRecodeSet(t, seCurVer, "select @@global.tidb_opt_range_max_size") + chk = res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row = chk.GetRow(0) + require.Equal(t, 1, row.Len()) + require.Equal(t, "0", row.GetString(0)) +} + +func TestTiDBCostModelInNewCluster(t *testing.T) { + store, err := mockstore.NewMockStore() + require.NoError(t, err) + // Indicates we are in a new cluster. + require.Equal(t, int64(notBootstrapped), getStoreBootstrapVersion(store)) + dom, err := BootstrapSession(store) + require.NoError(t, err) + defer func() { require.NoError(t, store.Close()) }() + defer dom.Close() + se := createSessionAndSetID(t, store) + + // In a new created cluster(above 6.5+), tidb_cost_model_version is 2 by default. + mustExec(t, se, "use test;") + r := mustExecToRecodeSet(t, se, "select @@tidb_cost_model_version;") + require.NotNil(t, r) + + ctx := context.Background() + chk := r.NewChunk(nil) + err = r.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row := chk.GetRow(0) + require.Equal(t, 1, row.Len()) + require.Equal(t, "2", row.GetString(0)) +} + +func TestTiDBCostModelUpgradeFrom300To650(t *testing.T) { + ctx := context.Background() + store, _ := createStoreAndBootstrap(t) + defer func() { require.NoError(t, store.Close()) }() + + // Upgrade from 3.0.0 to 6.5+. + ver300 := 33 + seV3 := createSessionAndSetID(t, store) + txn, err := store.Begin() + require.NoError(t, err) + m := meta.NewMeta(txn) + err = m.FinishBootstrap(int64(ver300)) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + mustExec(t, seV3, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver300)) + mustExec(t, seV3, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBCostModelVersion)) + mustExec(t, seV3, "commit") + unsetStoreBootstrapped(store.UUID()) + ver, err := getBootstrapVersion(seV3) + require.NoError(t, err) + require.Equal(t, int64(ver300), ver) + + // We are now in 3.0.0, check TiDBCostModelVersion should not exist. + res := mustExecToRecodeSet(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBCostModelVersion)) + chk := res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 0, chk.NumRows()) + + domCurVer, err := BootstrapSession(store) + require.NoError(t, err) + defer domCurVer.Close() + seCurVer := createSessionAndSetID(t, store) + ver, err = getBootstrapVersion(seCurVer) + require.NoError(t, err) + require.Equal(t, currentBootstrapVersion, ver) + + // We are now in 6.5+, TiDBCostModelVersion should be 1. + res = mustExecToRecodeSet(t, seCurVer, "select @@tidb_cost_model_version") + chk = res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row := chk.GetRow(0) + require.Equal(t, 1, row.Len()) + require.Equal(t, "1", row.GetString(0)) +} + +func TestTiDBCostModelUpgradeFrom610To650(t *testing.T) { + for i := 0; i < 2; i++ { + func() { + ctx := context.Background() + store, dom := createStoreAndBootstrap(t) + defer func() { require.NoError(t, store.Close()) }() + + // upgrade from 6.1 to 6.5+. + ver61 := 91 + seV61 := createSessionAndSetID(t, store) + txn, err := store.Begin() + require.NoError(t, err) + m := meta.NewMeta(txn) + err = m.FinishBootstrap(int64(ver61)) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + mustExec(t, seV61, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver61)) + mustExec(t, seV61, fmt.Sprintf("update mysql.GLOBAL_VARIABLES set variable_value='%s' where variable_name='%s'", "1", variable.TiDBCostModelVersion)) + mustExec(t, seV61, "commit") + unsetStoreBootstrapped(store.UUID()) + ver, err := getBootstrapVersion(seV61) + require.NoError(t, err) + require.Equal(t, int64(ver61), ver) + + // We are now in 6.1, tidb_cost_model_version is 1. + res := mustExecToRecodeSet(t, seV61, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBCostModelVersion)) + chk := res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row := chk.GetRow(0) + require.Equal(t, 2, row.Len()) + require.Equal(t, "1", row.GetString(1)) + res.Close() + + if i == 0 { + // For the first time, We set tidb_cost_model_version to 2. + // And after upgrade to 6.5, tidb_cost_model_version should be 2. + // For the second it should be 1. + mustExec(t, seV61, "set global tidb_cost_model_version = 2") + } + dom.Close() + // Upgrade to 6.5. + domCurVer, err := BootstrapSession(store) + require.NoError(t, err) + defer domCurVer.Close() + seCurVer := createSessionAndSetID(t, store) + ver, err = getBootstrapVersion(seCurVer) + require.NoError(t, err) + require.Equal(t, currentBootstrapVersion, ver) + + // We are now in 6.5. + res = mustExecToRecodeSet(t, seCurVer, "select @@tidb_cost_model_version") + chk = res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row = chk.GetRow(0) + require.Equal(t, 1, row.Len()) + if i == 0 { + require.Equal(t, "2", row.GetString(0)) + } else { + require.Equal(t, "1", row.GetString(0)) + } + res.Close() + }() + } +} + +func TestTiDBGCAwareUpgradeFrom630To650(t *testing.T) { + ctx := context.Background() + store, _ := createStoreAndBootstrap(t) + defer func() { require.NoError(t, store.Close()) }() + + // upgrade from 6.3 to 6.5+. + ver63 := version93 + seV63 := createSessionAndSetID(t, store) + txn, err := store.Begin() + require.NoError(t, err) + m := meta.NewMeta(txn) + err = m.FinishBootstrap(int64(ver63)) + require.NoError(t, err) + err = txn.Commit(context.Background()) + require.NoError(t, err) + mustExec(t, seV63, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver63)) + mustExec(t, seV63, fmt.Sprintf("update mysql.GLOBAL_VARIABLES set variable_value='%s' where variable_name='%s'", "1", variable.TiDBEnableGCAwareMemoryTrack)) + mustExec(t, seV63, "commit") + unsetStoreBootstrapped(store.UUID()) + ver, err := getBootstrapVersion(seV63) + require.NoError(t, err) + require.Equal(t, int64(ver63), ver) + + // We are now in 6.3, tidb_enable_gc_aware_memory_track is ON. + res := mustExecToRecodeSet(t, seV63, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableGCAwareMemoryTrack)) + chk := res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row := chk.GetRow(0) + require.Equal(t, 2, row.Len()) + require.Equal(t, "1", row.GetString(1)) + + // Upgrade to 6.5. + domCurVer, err := BootstrapSession(store) + require.NoError(t, err) + defer domCurVer.Close() + seCurVer := createSessionAndSetID(t, store) + ver, err = getBootstrapVersion(seCurVer) + require.NoError(t, err) + require.Equal(t, currentBootstrapVersion, ver) + + // We are now in 6.5. + res = mustExecToRecodeSet(t, seCurVer, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableGCAwareMemoryTrack)) + chk = res.NewChunk(nil) + err = res.Next(ctx, chk) + require.NoError(t, err) + require.Equal(t, 1, chk.NumRows()) + row = chk.GetRow(0) + require.Equal(t, 2, row.Len()) + require.Equal(t, "0", row.GetString(1)) +} diff --git a/session/bootstrap_upgrade_test.go b/session/bootstrap_upgrade_test.go index 27a5c34a2eb7f..59cdddf218a2d 100644 --- a/session/bootstrap_upgrade_test.go +++ b/session/bootstrap_upgrade_test.go @@ -72,14 +72,15 @@ func TestUpgradeVersion84(t *testing.T) { {"modify_count", "bigint(64)"}, {"count", "bigint(64)"}, {"version", "bigint(64)"}, + {"source", "varchar(40)"}, {"create_time", "datetime(6)"}, } rStatsHistoryTbl, err := tk.Exec(`desc mysql.stats_meta_history`) require.NoError(t, err) req := rStatsHistoryTbl.NewChunk(nil) require.NoError(t, rStatsHistoryTbl.Next(ctx, req)) - require.Equal(t, 5, req.NumRows()) - for i := 0; i < 5; i++ { + require.Equal(t, 6, req.NumRows()) + for i := 0; i < 6; i++ { row := req.GetRow(i) require.Equal(t, statsHistoryTblFields[i].field, strings.ToLower(row.GetString(0))) require.Equal(t, statsHistoryTblFields[i].tp, strings.ToLower(row.GetString(1))) diff --git a/session/clustered_index_test.go b/session/clustered_index_test.go index eb9675dfea4ba..969dc3b5f6017 100644 --- a/session/clustered_index_test.go +++ b/session/clustered_index_test.go @@ -64,6 +64,7 @@ func TestClusteredPrefixColumn(t *testing.T) { store := testkit.CreateMockStore(t) tk := createTestKit(t, store) + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("drop table if exists t") tk.MustExec("create table t1(cb varchar(12), ci int, v int, primary key(cb(1)), key idx_1(cb))") tk.MustExec("insert into t1 values('PvtYW2', 1, 1)") @@ -285,7 +286,7 @@ func TestClusteredPrefixingPrimaryKey(t *testing.T) { tk.MustGetErrCode("update t set name = 'aaaaa' where name = 'bbb'", errno.ErrDupEntry) tk.MustExec("update ignore t set name = 'aaaaa' where name = 'bbb'") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'aaaaa' for key 'PRIMARY'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'aaaaa' for key 't.PRIMARY'")) tk.MustExec("admin check table t;") tk.MustExec("drop table if exists t1, t2") diff --git a/session/main_test.go b/session/main_test.go index a54a3378a4d8a..1841bbbdd3570 100644 --- a/session/main_test.go +++ b/session/main_test.go @@ -56,6 +56,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ // TODO: figure the reason and shorten this list goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/internal/retry.newBackoffFn.func1"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/v3.waitRetryBackoff"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), @@ -98,7 +99,15 @@ func createSessionAndSetID(t *testing.T, store kv.Storage) Session { return se } -func mustExec(t *testing.T, se Session, sql string, args ...interface{}) sqlexec.RecordSet { +func mustExec(t *testing.T, se Session, sql string, args ...interface{}) { + rs, err := exec(se, sql, args...) + require.NoError(t, err) + if rs != nil { + require.NoError(t, rs.Close()) + } +} + +func mustExecToRecodeSet(t *testing.T, se Session, sql string, args ...interface{}) sqlexec.RecordSet { rs, err := exec(se, sql, args...) require.NoError(t, err) return rs @@ -128,8 +137,12 @@ func exec(se Session, sql string, args ...interface{}) (sqlexec.RecordSet, error func match(t *testing.T, row []types.Datum, expected ...interface{}) { require.Len(t, row, len(expected)) for i := range row { + if _, ok := expected[i].(time.Time); ok { + // Since password_last_changed is set to default current_timestamp, we pass this check. + continue + } got := fmt.Sprintf("%v", row[i].GetValue()) need := fmt.Sprintf("%v", expected[i]) - require.Equal(t, need, got) + require.Equal(t, need, got, i) } } diff --git a/session/nontransactional.go b/session/nontransactional.go index ef8adb541203e..83a660f827ab6 100644 --- a/session/nontransactional.go +++ b/session/nontransactional.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/errno" - "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/ast" @@ -34,6 +33,7 @@ import ( "github.com/pingcap/tidb/parser/opcode" "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/types" driver "github.com/pingcap/tidb/types/parser_driver" "github.com/pingcap/tidb/util/chunk" @@ -43,12 +43,19 @@ import ( "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/sqlexec" + "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" ) // ErrNonTransactionalJobFailure is the error when a non-transactional job fails. The error is returned and following jobs are canceled. var ErrNonTransactionalJobFailure = dbterror.ClassSession.NewStd(errno.ErrNonTransactionalJobFailure) +var ( + nonTransactionalDeleteCount = metrics.NonTransactionalDMLCount.With(prometheus.Labels{metrics.LblType: "delete"}) + nonTransactionalInsertCount = metrics.NonTransactionalDMLCount.With(prometheus.Labels{metrics.LblType: "insert"}) + nonTransactionalUpdateCount = metrics.NonTransactionalDMLCount.With(prometheus.Labels{metrics.LblType: "update"}) +) + // job: handle keys in [start, end] type job struct { start types.Datum @@ -61,7 +68,7 @@ type job struct { // statementBuildInfo contains information that is needed to build the split statement in a job type statementBuildInfo struct { - stmt *ast.NonTransactionalDeleteStmt + stmt *ast.NonTransactionalDMLStmt shardColumnType types.FieldType shardColumnRefer *ast.ResultField originalCondition ast.ExprNode @@ -74,34 +81,48 @@ func (j job) String(redacted bool) string { return fmt.Sprintf("job id: %d, estimated size: %d, sql: %s", j.jobID, j.jobSize, j.sql) } -// HandleNonTransactionalDelete is the entry point for a non-transactional delete -func HandleNonTransactionalDelete(ctx context.Context, stmt *ast.NonTransactionalDeleteStmt, se Session) (sqlexec.RecordSet, error) { - err := core.Preprocess(se, stmt) +// HandleNonTransactionalDML is the entry point for a non-transactional DML statement +func HandleNonTransactionalDML(ctx context.Context, stmt *ast.NonTransactionalDMLStmt, se Session) (sqlexec.RecordSet, error) { + sessVars := se.GetSessionVars() + originalReadStaleness := se.GetSessionVars().ReadStaleness + // NT-DML is a write operation, and should not be affected by read_staleness that is supposed to affect only SELECT. + sessVars.ReadStaleness = 0 + defer func() { + sessVars.ReadStaleness = originalReadStaleness + }() + err := core.Preprocess(ctx, se, stmt) if err != nil { return nil, err } if err := checkConstraint(stmt, se); err != nil { return nil, err } - metrics.NonTransactionalDeleteCount.Inc() - tableName, selectSQL, shardColumnInfo, err := buildSelectSQL(stmt, se) + + tableName, selectSQL, shardColumnInfo, tableSources, err := buildSelectSQL(stmt, se) if err != nil { return nil, err } + + if err := checkConstraintWithShardColumn(se, stmt, tableName, shardColumnInfo, tableSources); err != nil { + return nil, err + } + if stmt.DryRun == ast.DryRunQuery { return buildDryRunResults(stmt.DryRun, []string{selectSQL}, se.GetSessionVars().BatchSize.MaxChunkSize) } // TODO: choose an appropriate quota. // Use the mem-quota-query as a workaround. As a result, a NT-DML may consume 2x of the memory quota. - memTracker := setMemTracker(se) - defer memTracker.DetachFromGlobalTracker() + memTracker := memory.NewTracker(memory.LabelForNonTransactionalDML, -1) + memTracker.AttachTo(se.GetSessionVars().MemTracker) + se.GetSessionVars().MemTracker.SetBytesLimit(se.GetSessionVars().MemQuotaQuery) + defer memTracker.Detach() jobs, err := buildShardJobs(ctx, stmt, se, selectSQL, shardColumnInfo, memTracker) if err != nil { return nil, err } - splitStmts, err := splitDeleteWorker(ctx, jobs, stmt, tableName, se, stmt.DeleteStmt.Where) + splitStmts, err := runJobs(ctx, jobs, stmt, tableName, se, stmt.DMLStmt.WhereExpr()) if err != nil { return nil, err } @@ -111,25 +132,61 @@ func HandleNonTransactionalDelete(ctx context.Context, stmt *ast.NonTransactiona return buildExecuteResults(ctx, jobs, se.GetSessionVars().BatchSize.MaxChunkSize, se.GetSessionVars().EnableRedactLog) } -func setMemTracker(se Session) *memory.Tracker { - memTracker := memory.NewTracker(memory.LabelForNonTransactionalDML, se.GetSessionVars().MemQuotaQuery) - switch variable.OOMAction.Load() { - case variable.OOMActionCancel: - action := &memory.PanicOnExceed{ConnID: se.GetSessionVars().ConnectionID} - action.SetLogHook(domain.GetDomain(se).ExpensiveQueryHandle().LogOnQueryExceedMemQuota) - memTracker.SetActionOnExceed(action) - case variable.OOMActionLog: - fallthrough +// we require: +// (1) in an update statement, shard column cannot be updated +// +// Note: this is not a comprehensive check. +// We do this to help user prevent some easy mistakes, at an acceptable maintenance cost. +func checkConstraintWithShardColumn(se Session, stmt *ast.NonTransactionalDMLStmt, + tableName *ast.TableName, shardColumnInfo *model.ColumnInfo, tableSources []*ast.TableSource) error { + switch s := stmt.DMLStmt.(type) { + case *ast.UpdateStmt: + if err := checkUpdateShardColumn(se, s.List, shardColumnInfo, tableName, tableSources, true); err != nil { + return err + } + case *ast.InsertStmt: + // FIXME: is it possible to happen? + // `insert into t select * from t on duplicate key update id = id + 1` will return an ambiguous column error? + if err := checkUpdateShardColumn(se, s.OnDuplicate, shardColumnInfo, tableName, tableSources, false); err != nil { + return err + } default: - action := &memory.LogOnExceed{ConnID: se.GetSessionVars().ConnectionID} - action.SetLogHook(domain.GetDomain(se).ExpensiveQueryHandle().LogOnQueryExceedMemQuota) - memTracker.SetActionOnExceed(action) } - memTracker.AttachToGlobalTracker(executor.GlobalMemoryUsageTracker) - return memTracker + return nil +} + +// shard column should not be updated. +func checkUpdateShardColumn(se Session, assignments []*ast.Assignment, shardColumnInfo *model.ColumnInfo, + tableName *ast.TableName, tableSources []*ast.TableSource, isUpdate bool) error { + // if the table has alias, the alias is used in assignments, and we should use aliased name to compare + aliasedShardColumnTableName := tableName.Name.L + for _, tableSource := range tableSources { + if tableSource.Source.(*ast.TableName).Name.L == aliasedShardColumnTableName && tableSource.AsName.L != "" { + aliasedShardColumnTableName = tableSource.AsName.L + } + } + + if shardColumnInfo == nil { + return nil + } + for _, assignment := range assignments { + sameDB := (assignment.Column.Schema.L == tableName.Schema.L) || + (assignment.Column.Schema.L == "" && tableName.Schema.L == se.GetSessionVars().CurrentDB) + if !sameDB { + continue + } + sameTable := (assignment.Column.Table.L == aliasedShardColumnTableName) || (isUpdate && len(tableSources) == 1) + if !sameTable { + continue + } + if assignment.Column.Name.L == shardColumnInfo.Name.L { + return errors.New("Non-transactional DML, shard column cannot be updated") + } + } + return nil } -func checkConstraint(stmt *ast.NonTransactionalDeleteStmt, se Session) error { +func checkConstraint(stmt *ast.NonTransactionalDMLStmt, se Session) error { sessVars := se.GetSessionVars() if !(sessVars.IsAutocommit() && !sessVars.InTxn()) { return errors.Errorf("non-transactional DML can only run in auto-commit mode. auto-commit:%v, inTxn:%v", @@ -146,23 +203,67 @@ func checkConstraint(stmt *ast.NonTransactionalDeleteStmt, se Session) error { return errors.New("can't do non-transactional DML when tidb_snapshot is set") } - if stmt.DeleteStmt.TableRefs == nil || stmt.DeleteStmt.TableRefs.TableRefs == nil || stmt.DeleteStmt.TableRefs.TableRefs.Left == nil { + switch s := stmt.DMLStmt.(type) { + case *ast.DeleteStmt: + if err := checkTableRef(s.TableRefs, true); err != nil { + return err + } + if err := checkReadClauses(s.Limit, s.Order); err != nil { + return err + } + nonTransactionalDeleteCount.Inc() + case *ast.UpdateStmt: + if err := checkTableRef(s.TableRefs, true); err != nil { + return err + } + if err := checkReadClauses(s.Limit, s.Order); err != nil { + return err + } + nonTransactionalUpdateCount.Inc() + case *ast.InsertStmt: + if s.Select == nil { + return errors.New("Non-transactional insert supports insert select stmt only") + } + selectStmt, ok := s.Select.(*ast.SelectStmt) + if !ok { + return errors.New("Non-transactional insert doesn't support non-select source") + } + if err := checkTableRef(selectStmt.From, true); err != nil { + return err + } + if err := checkReadClauses(selectStmt.Limit, selectStmt.OrderBy); err != nil { + return err + } + nonTransactionalInsertCount.Inc() + default: + return errors.New("Unsupported DML type for non-transactional DML") + } + + return nil +} + +func checkTableRef(t *ast.TableRefsClause, allowMultipleTables bool) error { + if t == nil || t.TableRefs == nil || t.TableRefs.Left == nil { return errors.New("table reference is nil") } - if stmt.DeleteStmt.TableRefs.TableRefs.Right != nil { - return errors.New("Non-transactional delete doesn't support multiple tables") + if !allowMultipleTables && t.TableRefs.Right != nil { + return errors.New("Non-transactional statements don't support multiple tables") } - if stmt.DeleteStmt.Limit != nil { - return errors.New("Non-transactional delete doesn't support limit") + return nil +} + +func checkReadClauses(limit *ast.Limit, order *ast.OrderByClause) error { + if limit != nil { + return errors.New("Non-transactional statements don't support limit") } - if stmt.DeleteStmt.Order != nil { - return errors.New("Non-transactional delete doesn't support order by") + if order != nil { + return errors.New("Non-transactional statements don't support order by") } return nil } // single-threaded worker. work on the key range [start, end] -func splitDeleteWorker(ctx context.Context, jobs []job, stmt *ast.NonTransactionalDeleteStmt, +func runJobs(ctx context.Context, jobs []job, stmt *ast.NonTransactionalDMLStmt, tableName *ast.TableName, se Session, originalCondition ast.ExprNode) ([]string, error) { // prepare for the construction of statement var shardColumnRefer *ast.ResultField @@ -179,7 +280,7 @@ func splitDeleteWorker(ctx context.Context, jobs []job, stmt *ast.NonTransaction } } if shardColumnRefer == nil && stmt.ShardColumn.Name.L != model.ExtraHandleName.L { - return nil, errors.New("Non-transactional delete, column not found") + return nil, errors.New("Non-transactional DML, shard column not found") } splitStmts := make([]string, 0, len(jobs)) @@ -193,10 +294,10 @@ func splitDeleteWorker(ctx context.Context, jobs []job, stmt *ast.NonTransaction } } if len(failedJobs) == 0 { - logutil.Logger(ctx).Warn("Non-transactional delete worker exit because context canceled. No errors", + logutil.Logger(ctx).Warn("Non-transactional DML worker exit because context canceled. No errors", zap.Int("finished", i), zap.Int("total", len(jobs))) } else { - logutil.Logger(ctx).Warn("Non-transactional delete worker exit because context canceled. Errors found", + logutil.Logger(ctx).Warn("Non-transactional DML worker exit because context canceled. Errors found", zap.Int("finished", i), zap.Int("total", len(jobs)), zap.Strings("errors found", failedJobs)) } return nil, ctx.Err() @@ -293,56 +394,56 @@ func doOneJob(ctx context.Context, job *job, totalJobCount int, options statemen } if options.originalCondition == nil { - options.stmt.DeleteStmt.Where = whereCondition + options.stmt.DMLStmt.SetWhereExpr(whereCondition) } else { - options.stmt.DeleteStmt.Where = &ast.BinaryOperationExpr{ + options.stmt.DMLStmt.SetWhereExpr(&ast.BinaryOperationExpr{ Op: opcode.LogicAnd, L: whereCondition, R: options.originalCondition, - } + }) } var sb strings.Builder - err := options.stmt.DeleteStmt.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags| + err := options.stmt.DMLStmt.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags| format.RestoreNameBackQuotes| format.RestoreSpacesAroundBinaryOperation| format.RestoreBracketAroundBinaryOperation| format.RestoreStringWithoutCharset, &sb)) if err != nil { - logutil.Logger(ctx).Error("Non-transactional delete, failed to restore the delete statement", zap.Error(err)) - job.err = errors.New("Failed to restore the delete statement, probably because of unsupported type of the shard column") + logutil.Logger(ctx).Error("Non-transactional DML, failed to restore the DML statement", zap.Error(err)) + job.err = errors.New("Failed to restore the DML statement, probably because of unsupported type of the shard column") return "" } - deleteSQL := sb.String() + dmlSQL := sb.String() if dryRun { - return deleteSQL + return dmlSQL } - job.sql = deleteSQL - logutil.Logger(ctx).Info("start a Non-transactional delete", + job.sql = dmlSQL + logutil.Logger(ctx).Info("start a Non-transactional DML", zap.String("job", job.String(se.GetSessionVars().EnableRedactLog)), zap.Int("totalJobCount", totalJobCount)) - var deleteSQLInLog string + var dmlSQLInLog string if se.GetSessionVars().EnableRedactLog { - deleteSQLInLog = parser.Normalize(deleteSQL) + dmlSQLInLog = parser.Normalize(dmlSQL) } else { - deleteSQLInLog = deleteSQL + dmlSQLInLog = dmlSQL } - options.stmt.DeleteStmt.SetText(nil, fmt.Sprintf("/* job %v/%v */ %s", job.jobID, totalJobCount, deleteSQL)) - rs, err := se.ExecuteStmt(ctx, options.stmt.DeleteStmt) + options.stmt.DMLStmt.SetText(nil, fmt.Sprintf("/* job %v/%v */ %s", job.jobID, totalJobCount, dmlSQL)) + rs, err := se.ExecuteStmt(ctx, options.stmt.DMLStmt) // collect errors - failpoint.Inject("batchDeleteError", func(val failpoint.Value) { + failpoint.Inject("batchDMLError", func(val failpoint.Value) { if val.(bool) { - err = errors.New("injected batch delete error") + err = errors.New("injected batch(non-transactional) DML error") } }) if err != nil { - logutil.Logger(ctx).Error("Non-transactional delete SQL failed", zap.String("job", deleteSQLInLog), zap.Error(err), zap.Int("jobID", job.jobID), zap.Int("jobSize", job.jobSize)) + logutil.Logger(ctx).Error("Non-transactional DML SQL failed", zap.String("job", dmlSQLInLog), zap.Error(err), zap.Int("jobID", job.jobID), zap.Int("jobSize", job.jobSize)) job.err = err } else { - logutil.Logger(ctx).Info("Non-transactional delete SQL finished successfully", zap.Int("jobID", job.jobID), - zap.Int("jobSize", job.jobSize), zap.String("deleteSQL", deleteSQLInLog)) + logutil.Logger(ctx).Info("Non-transactional DML SQL finished successfully", zap.Int("jobID", job.jobID), + zap.Int("jobSize", job.jobSize), zap.String("dmlSQL", dmlSQLInLog)) } if rs != nil { _ = rs.Close() @@ -350,7 +451,7 @@ func doOneJob(ctx context.Context, job *job, totalJobCount int, options statemen return "" } -func buildShardJobs(ctx context.Context, stmt *ast.NonTransactionalDeleteStmt, se Session, +func buildShardJobs(ctx context.Context, stmt *ast.NonTransactionalDMLStmt, se Session, selectSQL string, shardColumnInfo *model.ColumnInfo, memTracker *memory.Tracker) ([]job, error) { var shardColumnCollate string if shardColumnInfo != nil { @@ -363,17 +464,14 @@ func buildShardJobs(ctx context.Context, stmt *ast.NonTransactionalDeleteStmt, s originalSelectLimit := se.GetSessionVars().SelectLimit se.GetSessionVars().SelectLimit = math.MaxUint64 // NT-DML is a write operation, and should not be affected by read_staleness that is supposed to affect only SELECT. - originalReadStaleness := se.GetSessionVars().ReadStaleness - se.GetSessionVars().ReadStaleness = 0 rss, err := se.Execute(ctx, selectSQL) se.GetSessionVars().SelectLimit = originalSelectLimit - se.GetSessionVars().ReadStaleness = originalReadStaleness if err != nil { return nil, err } if len(rss) != 1 { - return nil, errors.Errorf("Non-transactional delete, expecting 1 record set, but got %d", len(rss)) + return nil, errors.Errorf("Non-transactional DML, expecting 1 record set, but got %d", len(rss)) } rs := rss[0] defer func() { @@ -382,7 +480,7 @@ func buildShardJobs(ctx context.Context, stmt *ast.NonTransactionalDeleteStmt, s batchSize := int(stmt.Limit) if batchSize <= 0 { - return nil, errors.New("Non-transactional delete, batch size should be positive") + return nil, errors.New("Non-transactional DML, batch size should be positive") } jobCount := 0 jobs := make([]job, 0) @@ -448,35 +546,42 @@ func appendNewJob(jobs []job, id int, start types.Datum, end types.Datum, size i return jobs } -func buildSelectSQL(stmt *ast.NonTransactionalDeleteStmt, se Session) (*ast.TableName, string, *model.ColumnInfo, error) { +func buildSelectSQL(stmt *ast.NonTransactionalDMLStmt, se Session) ( + *ast.TableName, string, *model.ColumnInfo, []*ast.TableSource, error) { // only use the first table - tableSource, ok := stmt.DeleteStmt.TableRefs.TableRefs.Left.(*ast.TableSource) + join, ok := stmt.DMLStmt.TableRefsJoin() if !ok { - return nil, "", nil, errors.New("Non-transactional delete, table source not found") + return nil, "", nil, nil, errors.New("Non-transactional DML, table source not found") + } + tableSources := make([]*ast.TableSource, 0) + tableSources, err := collectTableSourcesInJoin(join, tableSources) + if err != nil { + return nil, "", nil, nil, err } - tableName, ok := tableSource.Source.(*ast.TableName) + if len(tableSources) == 0 { + return nil, "", nil, nil, errors.New("Non-transactional DML, no tables found in table refs") + } + leftMostTableSource := tableSources[0] + leftMostTableName, ok := leftMostTableSource.Source.(*ast.TableName) if !ok { - return nil, "", nil, errors.New("Non-transactional delete, table name not found") + return nil, "", nil, nil, errors.New("Non-transactional DML, table name not found") } - // the shard column must be indexed - indexed, shardColumnInfo, err := selectShardColumn(stmt, se, tableName, tableSource.AsName) + shardColumnInfo, tableName, err := selectShardColumn(stmt, se, tableSources, leftMostTableName, leftMostTableSource) if err != nil { - return nil, "", nil, err - } - if !indexed { - return nil, "", nil, errors.Errorf("Non-transactional delete, shard column %s is not indexed", stmt.ShardColumn.Name.L) + return nil, "", nil, nil, err } var sb strings.Builder - if stmt.DeleteStmt.Where != nil { - err := stmt.DeleteStmt.Where.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags| + if stmt.DMLStmt.WhereExpr() != nil { + err := stmt.DMLStmt.WhereExpr().Restore(format.NewRestoreCtx(format.DefaultRestoreFlags| format.RestoreNameBackQuotes| format.RestoreSpacesAroundBinaryOperation| format.RestoreBracketAroundBinaryOperation| - format.RestoreStringWithoutCharset, &sb)) + format.RestoreStringWithoutCharset, &sb), + ) if err != nil { - return nil, "", nil, errors.Annotate(err, "Failed to restore where clause in non-transactional delete") + return nil, "", nil, nil, errors.Annotate(err, "Failed to restore where clause in non-transactional DML") } } else { sb.WriteString("TRUE") @@ -484,57 +589,131 @@ func buildSelectSQL(stmt *ast.NonTransactionalDeleteStmt, se Session) (*ast.Tabl // assure NULL values are placed first selectSQL := fmt.Sprintf("SELECT `%s` FROM `%s`.`%s` WHERE %s ORDER BY IF(ISNULL(`%s`),0,1),`%s`", stmt.ShardColumn.Name.O, tableName.DBInfo.Name.O, tableName.Name.O, sb.String(), stmt.ShardColumn.Name.O, stmt.ShardColumn.Name.O) - return tableName, selectSQL, shardColumnInfo, nil + return tableName, selectSQL, shardColumnInfo, tableSources, nil } -// it attempts to auto-select a shard column from handle if not specified, and fills back the corresponding info in the stmt, -// making it transparent to following steps -func selectShardColumn(stmt *ast.NonTransactionalDeleteStmt, se Session, tableName *ast.TableName, tableAsName model.CIStr) (indexed bool, shardColumnInfo *model.ColumnInfo, err error) { - tbl, err := domain.GetDomain(se).InfoSchema().TableByName(tableName.Schema, tableName.Name) - if err != nil { - return false, nil, err - } - tableInfo := tbl.Meta() +func selectShardColumn(stmt *ast.NonTransactionalDMLStmt, se Session, tableSources []*ast.TableSource, + leftMostTableName *ast.TableName, leftMostTableSource *ast.TableSource) ( + *model.ColumnInfo, *ast.TableName, error) { + var indexed bool + var shardColumnInfo *model.ColumnInfo + var selectedTableName *ast.TableName - var shardColumnName string - if stmt.ShardColumn == nil { - // auto-detect shard column - if tbl.Meta().PKIsHandle { - shardColumnInfo = tableInfo.GetPkColInfo() - } else if tableInfo.IsCommonHandle { - for _, index := range tableInfo.Indices { - if index.Primary { - if len(index.Columns) == 1 { - shardColumnInfo = tableInfo.Columns[index.Columns[0].Offset] - break - } - // if the clustered index contains multiple columns, we cannot automatically choose a column as the shard column - return false, nil, errors.New("Non-transactional delete, the clustered index contains multiple columns. Please specify a shard column") + if len(tableSources) == 1 { + // single table + leftMostTable, err := domain.GetDomain(se).InfoSchema().TableByName(leftMostTableName.Schema, leftMostTableName.Name) + if err != nil { + return nil, nil, err + } + selectedTableName = leftMostTableName + indexed, shardColumnInfo, err = selectShardColumnFromTheOnlyTable( + stmt, leftMostTableName, leftMostTableSource.AsName, leftMostTable) + if err != nil { + return nil, nil, err + } + } else { + // multi table join + if stmt.ShardColumn == nil { + leftMostTable, err := domain.GetDomain(se).InfoSchema().TableByName(leftMostTableName.Schema, leftMostTableName.Name) + if err != nil { + return nil, nil, err + } + selectedTableName = leftMostTableName + indexed, shardColumnInfo, err = selectShardColumnAutomatically(stmt, leftMostTable, leftMostTableName, leftMostTableSource.AsName) + if err != nil { + return nil, nil, err + } + } else if stmt.ShardColumn.Schema.L != "" && stmt.ShardColumn.Table.L != "" && stmt.ShardColumn.Name.L != "" { + specifiedDbName := stmt.ShardColumn.Schema + specifiedTableName := stmt.ShardColumn.Table + specifiedColName := stmt.ShardColumn.Name + + // the specified table must be in the join + tableInJoin := false + var chosenTableName model.CIStr + for _, tableSource := range tableSources { + tableSourceName := tableSource.Source.(*ast.TableName) + tableSourceFinalTableName := tableSource.AsName // precedence: alias name, then table name + if tableSourceFinalTableName.O == "" { + tableSourceFinalTableName = tableSourceName.Name + } + if tableSourceName.Schema.L == specifiedDbName.L && tableSourceFinalTableName.L == specifiedTableName.L { + tableInJoin = true + selectedTableName = tableSourceName + chosenTableName = tableSourceName.Name + break } } - if shardColumnInfo == nil { - return false, nil, errors.New("Non-transactional delete, the clustered index is not found") + if !tableInJoin { + return nil, nil, + errors.Errorf( + "Non-transactional DML, shard column %s.%s.%s is not in the tables involved in the join", + specifiedDbName.L, specifiedTableName.L, specifiedColName.L, + ) } - } - shardColumnName := model.ExtraHandleName.L - if shardColumnInfo != nil { - shardColumnName = shardColumnInfo.Name.L + tbl, err := domain.GetDomain(se).InfoSchema().TableByName(specifiedDbName, chosenTableName) + if err != nil { + return nil, nil, err + } + indexed, shardColumnInfo, err = selectShardColumnByGivenName(specifiedColName.L, tbl) + if err != nil { + return nil, nil, err + } + } else { + return nil, nil, errors.New( + "Non-transactional DML, shard column must be fully specified (i.e. `BATCH ON dbname.tablename.colname`) when multiple tables are involved", + ) } + } + if !indexed { + return nil, nil, errors.Errorf("Non-transactional DML, shard column %s is not indexed", stmt.ShardColumn.Name.L) + } + return shardColumnInfo, selectedTableName, nil +} - outputTableName := tableName.Name - if tableAsName.L != "" { - outputTableName = tableAsName +func collectTableSourcesInJoin(node ast.ResultSetNode, tableSources []*ast.TableSource) ([]*ast.TableSource, error) { + if node == nil { + return tableSources, nil + } + switch x := node.(type) { + case *ast.Join: + var err error + tableSources, err = collectTableSourcesInJoin(x.Left, tableSources) + if err != nil { + return nil, err } - stmt.ShardColumn = &ast.ColumnName{ - Schema: tableName.Schema, - Table: outputTableName, // so that table alias works - Name: model.NewCIStr(shardColumnName), + tableSources, err = collectTableSourcesInJoin(x.Right, tableSources) + if err != nil { + return nil, err } - return true, shardColumnInfo, nil + case *ast.TableSource: + // assert it's a table name + if _, ok := x.Source.(*ast.TableName); !ok { + return nil, errors.New("Non-transactional DML, table name not found in join") + } + tableSources = append(tableSources, x) + default: + return nil, errors.Errorf("Non-transactional DML, unknown type %T in table refs", node) } - shardColumnName = stmt.ShardColumn.Name.L + return tableSources, nil +} +// it attempts to auto-select a shard column from handle if not specified, and fills back the corresponding info in the stmt, +// making it transparent to following steps +func selectShardColumnFromTheOnlyTable(stmt *ast.NonTransactionalDMLStmt, tableName *ast.TableName, + tableAsName model.CIStr, tbl table.Table) ( + indexed bool, shardColumnInfo *model.ColumnInfo, err error) { + if stmt.ShardColumn == nil { + return selectShardColumnAutomatically(stmt, tbl, tableName, tableAsName) + } + + return selectShardColumnByGivenName(stmt.ShardColumn.Name.L, tbl) +} + +func selectShardColumnByGivenName(shardColumnName string, tbl table.Table) ( + indexed bool, shardColumnInfo *model.ColumnInfo, err error) { + tableInfo := tbl.Meta() if shardColumnName == model.ExtraHandleName.L && !tableInfo.HasClusteredIndex() { return true, nil, nil } @@ -567,6 +746,46 @@ func selectShardColumn(stmt *ast.NonTransactionalDeleteStmt, se Session, tableNa return indexed, shardColumnInfo, nil } +func selectShardColumnAutomatically(stmt *ast.NonTransactionalDMLStmt, tbl table.Table, + tableName *ast.TableName, tableAsName model.CIStr) (bool, *model.ColumnInfo, error) { + // auto-detect shard column + var shardColumnInfo *model.ColumnInfo + tableInfo := tbl.Meta() + if tbl.Meta().PKIsHandle { + shardColumnInfo = tableInfo.GetPkColInfo() + } else if tableInfo.IsCommonHandle { + for _, index := range tableInfo.Indices { + if index.Primary { + if len(index.Columns) == 1 { + shardColumnInfo = tableInfo.Columns[index.Columns[0].Offset] + break + } + // if the clustered index contains multiple columns, we cannot automatically choose a column as the shard column + return false, nil, errors.New("Non-transactional DML, the clustered index contains multiple columns. Please specify a shard column") + } + } + if shardColumnInfo == nil { + return false, nil, errors.New("Non-transactional DML, the clustered index is not found") + } + } + + shardColumnName := model.ExtraHandleName.L + if shardColumnInfo != nil { + shardColumnName = shardColumnInfo.Name.L + } + + outputTableName := tableName.Name + if tableAsName.L != "" { + outputTableName = tableAsName + } + stmt.ShardColumn = &ast.ColumnName{ + Schema: tableName.Schema, + Table: outputTableName, // so that table alias works + Name: model.NewCIStr(shardColumnName), + } + return true, shardColumnInfo, nil +} + func buildDryRunResults(dryRunOption int, results []string, maxChunkSize int) (sqlexec.RecordSet, error) { var fieldName string if dryRunOption == ast.DryRunSplitDml { @@ -636,7 +855,7 @@ func buildExecuteResults(ctx context.Context, jobs []job, maxChunkSize int, reda errStr := sb.String() // log errors here in case the output is too long. There can be thousands of errors. - logutil.Logger(ctx).Error("Non-transactional delete failed", + logutil.Logger(ctx).Error("Non-transactional DML failed", zap.Int("num_failed_jobs", len(failedJobs)), zap.String("failed_jobs", errStr)) return nil, fmt.Errorf("%d/%d jobs failed in the non-transactional DML: %s, ...(more in logs)", diff --git a/session/nontransactional_test.go b/session/nontransactional_test.go index f75df6aec3acc..9eea25e46bfbb 100644 --- a/session/nontransactional_test.go +++ b/session/nontransactional_test.go @@ -26,7 +26,7 @@ import ( tikvutil "github.com/tikv/client-go/v2/util" ) -func TestNonTransactionalDeleteShardingOnInt(t *testing.T) { +func TestNonTransactionalDMLShardingOnInt(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") @@ -42,10 +42,10 @@ func TestNonTransactionalDeleteShardingOnInt(t *testing.T) { "create table t(a int, b int, unique key(a, b))", "create table t(a int, b int, unique key(a))", } - testSharding(tables, tk) + testSharding(tables, tk, "int") } -func TestNonTransactionalDeleteShardingOnVarchar(t *testing.T) { +func TestNonTransactionalDMLShardingOnVarchar(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") @@ -61,112 +61,349 @@ func TestNonTransactionalDeleteShardingOnVarchar(t *testing.T) { "create table t(a varchar(30), b int, unique key(a, b))", "create table t(a varchar(30), b int, unique key(a))", } - testSharding(tables, tk) + testSharding(tables, tk, "varchar(30)") } -func testSharding(tables []string, tk *testkit.TestKit) { - tableSizes := []int{0, 1, 30, 35, 40, 100} - batchSizes := []int{25, 35, 50, 80, 120} +func testSharding(tables []string, tk *testkit.TestKit, tp string) { + compositions := []struct{ tableSize, batchSize int }{ + {0, 10}, + {1, 1}, + {1, 2}, + {30, 25}, + {30, 35}, + {35, 25}, + {35, 35}, + {35, 40}, + {40, 25}, + {40, 35}, + {100, 25}, + {100, 40}, + } + tk.MustExec("drop table if exists t2") + tk.MustExec(fmt.Sprintf("create table t2(a %s, b int, primary key(a) clustered)", tp)) for _, table := range tables { - tk.MustExec("drop table if exists t") + tk.MustExec("drop table if exists t, t1") tk.MustExec(table) - for _, tableSize := range tableSizes { - for _, batchSize := range batchSizes { - for i := 0; i < tableSize; i++ { - tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) - } - tk.MustQuery(fmt.Sprintf("batch on a limit %d delete from t", batchSize)).Check(testkit.Rows(fmt.Sprintf("%d all succeeded", (tableSize+batchSize-1)/batchSize))) - tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) + tk.MustExec(strings.Replace(table, "create table t", "create table t1", 1)) + for _, c := range compositions { + tk.MustExec("truncate t2") + rows := make([]string, 0, c.tableSize) + for i := 0; i < c.tableSize; i++ { + tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) + tk.MustExec(fmt.Sprintf("insert into t2 values ('%d', %d)", i, i)) + rows = append(rows, fmt.Sprintf("%d %d", i, i*2)) } + tk.MustExec("truncate t1") + tk.MustQuery( + fmt.Sprintf("batch on a limit %d insert into t1 select * from t", c.batchSize), + ).Check(testkit.Rows(fmt.Sprintf("%d all succeeded", (c.tableSize+c.batchSize-1)/c.batchSize))) + tk.MustQuery("select a, b from t1 order by b"). + Check(testkit.Rows(rows...)) + tk.MustQuery( + fmt.Sprintf("batch on a limit %d insert into t2 select * from t on duplicate key update t2.b = t.b", c.batchSize), + ).Check(testkit.Rows(fmt.Sprintf("%d all succeeded", (c.tableSize+c.batchSize-1)/c.batchSize))) + tk.MustQuery("select a, b from t2 order by b"). + Check(testkit.Rows(rows...)) + tk.MustQuery( + fmt.Sprintf( + "batch on a limit %d update t set b = b * 2", c.batchSize, + ), + ).Check(testkit.Rows(fmt.Sprintf("%d all succeeded", (c.tableSize+c.batchSize-1)/c.batchSize))) + tk.MustQuery("select coalesce(sum(b), 0) from t").Check( + testkit.Rows( + fmt.Sprintf( + "%d", (c.tableSize-1)*c.tableSize*2, + ), + ), + ) + tk.MustQuery( + fmt.Sprintf( + "batch on a limit %d delete from t", c.batchSize, + ), + ).Check(testkit.Rows(fmt.Sprintf("%d all succeeded", (c.tableSize+c.batchSize-1)/c.batchSize))) + tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) } } } -func TestNonTransactionalDeleteDryRun(t *testing.T) { +func TestNonTransactionalDMLDryRun(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, primary key(a, b) clustered)") + tk.MustExec("create table t1(a int, b int, primary key(a, b) clustered)") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) } - rows := tk.MustQuery("batch on a limit 3 dry run delete from t").Rows() + rows := tk.MustQuery("batch on a limit 3 dry run insert into t1 select * from t").Rows() + for _, row := range rows { + col := row[0].(string) + require.True(t, strings.HasPrefix(col, + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `a` BETWEEN"), col) + } + rows = tk.MustQuery("batch on a limit 3 dry run insert into t1 select * from t on duplicate key update t1.b=t.b").Rows() + for _, row := range rows { + col := row[0].(string) + require.True(t, strings.HasPrefix(col, + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `a` BETWEEN"), col) + require.True(t, strings.HasSuffix(col, + "ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`"), col) + } + rows = tk.MustQuery("batch on a limit 3 dry run delete from t").Rows() + for _, row := range rows { + col := row[0].(string) + require.True(t, strings.HasPrefix(col, "DELETE FROM `test`.`t` WHERE `a` BETWEEN"), col) + } + rows = tk.MustQuery("batch on a limit 3 dry run update t set b = b + 42").Rows() for _, row := range rows { - require.True(t, strings.HasPrefix(row[0].(string), "DELETE FROM `test`.`t` WHERE `a` BETWEEN")) + col := row[0].(string) + require.True(t, strings.HasPrefix(col, "UPDATE `test`.`t` SET `b`=(`b` + 42) WHERE `a` BETWEEN"), col) } - tk.MustQuery("batch on a limit 3 dry run query delete from t").Check(testkit.Rows( - "SELECT `a` FROM `test`.`t` WHERE TRUE ORDER BY IF(ISNULL(`a`),0,1),`a`")) + querySQL := "SELECT `a` FROM `test`.`t` WHERE TRUE ORDER BY IF(ISNULL(`a`),0,1),`a`" + tk.MustQuery("batch on a limit 3 dry run query insert into t1 select * from t").Check(testkit.Rows(querySQL)) + tk.MustQuery("batch on a limit 3 dry run query insert into t1 select * from t on duplicate key update t1.b=t.b"). + Check(testkit.Rows(querySQL)) + tk.MustQuery("batch on a limit 3 dry run query delete from t").Check(testkit.Rows(querySQL)) + tk.MustQuery("batch on a limit 3 dry run query update t set b = b + 42").Check(testkit.Rows(querySQL)) tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) + tk.MustQuery("select sum(b) from t").Check(testkit.Rows("9900")) } -func TestNonTransactionalDeleteErrorMessage(t *testing.T) { +func TestNonTransactionalDMLErrorMessage(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("use test") tk.MustExec("create table t(a int, b int, primary key(a, b) clustered)") + tk.MustExec("create table t1(a int, b int, primary key(a, b) clustered)") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) } tk.MustExec("set @@tidb_nontransactional_ignore_error=1") - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/session/batchDeleteError", `return(true)`)) - defer failpoint.Disable("github.com/pingcap/tidb/session/batchDeleteError") - err := tk.ExecToErr("batch on a limit 3 delete from t") - require.EqualError(t, err, "Early return: error occurred in the first job. All jobs are canceled: injected batch delete error") + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `return(true)`)) + defer failpoint.Disable("github.com/pingcap/tidb/session/batchDMLError") + err := tk.ExecToErr("batch on a limit 3 insert into t1 select * from t") + require.EqualError( + t, err, + "Early return: error occurred in the first job. All jobs are canceled: injected batch(non-transactional) DML error", + ) + err = tk.ExecToErr("batch on a limit 3 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.EqualError( + t, err, + "Early return: error occurred in the first job. All jobs are canceled: injected batch(non-transactional) DML error", + ) + err = tk.ExecToErr("batch on a limit 3 delete from t") + require.EqualError( + t, err, + "Early return: error occurred in the first job. All jobs are canceled: injected batch(non-transactional) DML error", + ) + err = tk.ExecToErr("batch on a limit 3 update t set b = 42") + require.EqualError( + t, err, + "Early return: error occurred in the first job. All jobs are canceled: injected batch(non-transactional) DML error", + ) tk.MustExec("truncate t") + tk.MustExec("truncate t1") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) } tk.MustExec("set @@tidb_nontransactional_ignore_error=1") - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/session/batchDeleteError", `1*return(false)->return(true)`)) + + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) + err = tk.ExecToErr("batch on a limit 3 insert into t1 select * from t") + require.ErrorContains( + t, err, + "33/34 jobs failed in the non-transactional DML: job id: 2, estimated size: 3, sql: INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5, injected batch(non-transactional) DML error;\n", + ) + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) + err = tk.ExecToErr("batch on a limit 3 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.ErrorContains( + t, err, + "33/34 jobs failed in the non-transactional DML: job id: 2, estimated size: 3, sql: INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5 ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`, injected batch(non-transactional) DML error;\n", + ) + + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) + err = tk.ExecToErr("batch on a limit 3 update t set b = 42") + require.ErrorContains( + t, err, + "33/34 jobs failed in the non-transactional DML: job id: 2, estimated size: 3, sql: UPDATE `test`.`t` SET `b`=42 WHERE `a` BETWEEN 3 AND 5, injected batch(non-transactional) DML error;\n", + ) + + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) err = tk.ExecToErr("batch on a limit 3 delete from t") - require.ErrorContains(t, err, "33/34 jobs failed in the non-transactional DML: job id: 2, estimated size: 3, sql: DELETE FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5, injected batch delete error;\n") + require.ErrorContains( + t, err, + "33/34 jobs failed in the non-transactional DML: job id: 2, estimated size: 3, sql: DELETE FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5, injected batch(non-transactional) DML error;\n", + ) tk.MustExec("truncate t") + tk.MustExec("truncate t1") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) } tk.MustExec("set @@tidb_nontransactional_ignore_error=0") - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/session/batchDeleteError", `1*return(false)->return(true)`)) + + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) + err = tk.ExecToErr("batch on a limit 3 insert into t1 select * from t") + require.EqualError( + t, err, + "[session:8143]non-transactional job failed, job id: 2, total jobs: 34. job range: [KindInt64 3, KindInt64 5], job sql: job id: 2, estimated size: 3, sql: INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5, err: injected batch(non-transactional) DML error", + ) + + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) + err = tk.ExecToErr("batch on a limit 3 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.EqualError( + t, err, + "[session:8143]non-transactional job failed, job id: 2, total jobs: 34. job range: [KindInt64 3, KindInt64 5], job sql: job id: 2, estimated size: 3, sql: INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5 ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`, err: injected batch(non-transactional) DML error", + ) + + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) + err = tk.ExecToErr("batch on a limit 3 update t set b = b + 42") + require.EqualError( + t, err, + "[session:8143]non-transactional job failed, job id: 2, total jobs: 34. job range: [KindInt64 3, KindInt64 5], job sql: job id: 2, estimated size: 3, sql: UPDATE `test`.`t` SET `b`=(`b` + 42) WHERE `a` BETWEEN 3 AND 5, err: injected batch(non-transactional) DML error", + ) + + require.NoError( + t, failpoint.Enable("github.com/pingcap/tidb/session/batchDMLError", `1*return(false)->return(true)`), + ) err = tk.ExecToErr("batch on a limit 3 delete from t") - require.EqualError(t, err, "[session:8143]non-transactional job failed, job id: 2, total jobs: 34. job range: [KindInt64 3, KindInt64 5], job sql: job id: 2, estimated size: 3, sql: DELETE FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5, err: injected batch delete error") + require.EqualError( + t, err, + "[session:8143]non-transactional job failed, job id: 2, total jobs: 34. job range: [KindInt64 3, KindInt64 5], job sql: job id: 2, estimated size: 3, sql: DELETE FROM `test`.`t` WHERE `a` BETWEEN 3 AND 5, err: injected batch(non-transactional) DML error", + ) } -func TestNonTransactionalDeleteSplitOnTiDBRowID(t *testing.T) { +func TestNonTransactionalDMLShardingOnTiDBRowID(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("use test") tk.MustExec("create table t(a int, b int)") + tk.MustExec("create table t1(a int, b int, unique key(a))") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) } // auto select results in full col name - tk.MustQuery("batch limit 3 dry run delete from t").Check(testkit.Rows( - "DELETE FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 1 AND 3", - "DELETE FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 100 AND 100", - )) + tk.MustQuery("batch limit 3 dry run delete from t").Check( + testkit.Rows( + "DELETE FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 1 AND 3", + "DELETE FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch limit 3 dry run update t set b = 42").Check( + testkit.Rows( + "UPDATE `test`.`t` SET `b`=42 WHERE `test`.`t`.`_tidb_rowid` BETWEEN 1 AND 3", + "UPDATE `test`.`t` SET `b`=42 WHERE `test`.`t`.`_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch limit 3 dry run insert into t1 select * from t").Check( + testkit.Rows( + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 1 AND 3", + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch limit 3 dry run insert into t1 select * from t on duplicate key update t1.b=t.b").Check( + testkit.Rows( + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 1 AND 3"+ + " ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`", + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `test`.`t`.`_tidb_rowid` BETWEEN 100 AND 100"+ + " ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`", + ), + ) + // otherwise the name is the same as what is given - tk.MustQuery("batch on _tidb_rowid limit 3 dry run delete from t").Check(testkit.Rows( - "DELETE FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 1 AND 3", - "DELETE FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 100 AND 100", - )) - tk.MustQuery("batch on t._tidb_rowid limit 3 dry run delete from t").Check(testkit.Rows( - "DELETE FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 1 AND 3", - "DELETE FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 100 AND 100", - )) + tk.MustQuery("batch on _tidb_rowid limit 3 dry run delete from t").Check( + testkit.Rows( + "DELETE FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 1 AND 3", + "DELETE FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch on t._tidb_rowid limit 3 dry run delete from t").Check( + testkit.Rows( + "DELETE FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 1 AND 3", + "DELETE FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch on _tidb_rowid limit 3 dry run update t set b = 42").Check( + testkit.Rows( + "UPDATE `test`.`t` SET `b`=42 WHERE `_tidb_rowid` BETWEEN 1 AND 3", + "UPDATE `test`.`t` SET `b`=42 WHERE `_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch on t._tidb_rowid limit 3 dry run update t set b = 42").Check( + testkit.Rows( + "UPDATE `test`.`t` SET `b`=42 WHERE `t`.`_tidb_rowid` BETWEEN 1 AND 3", + "UPDATE `test`.`t` SET `b`=42 WHERE `t`.`_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch on _tidb_rowid limit 3 dry run insert into t1 select * from t").Check( + testkit.Rows( + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 1 AND 3", + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch on t._tidb_rowid limit 3 dry run insert into t1 select * from t").Check( + testkit.Rows( + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 1 AND 3", + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 100 AND 100", + ), + ) + tk.MustQuery("batch on _tidb_rowid limit 3 dry run insert into t1 select * from t on duplicate key update t1.b=t.b").Check( + testkit.Rows( + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 1 AND 3"+ + " ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`", + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `_tidb_rowid` BETWEEN 100 AND 100"+ + " ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`", + ), + ) + tk.MustQuery("batch on t._tidb_rowid limit 3 dry run insert into t1 select * from t on duplicate key update t1.b=t.b").Check( + testkit.Rows( + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 1 AND 3"+ + " ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`", + "INSERT INTO `test`.`t1` SELECT * FROM `test`.`t` WHERE `t`.`_tidb_rowid` BETWEEN 100 AND 100"+ + " ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`", + ), + ) + + tk.MustExec("batch on _tidb_rowid limit 3 insert into t1 select * from t") + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) + tk.MustExec("update t1 set b = 0") + tk.MustExec("batch on _tidb_rowid limit 3 insert into t1 select * from t on duplicate key update t1.b=t.b") + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) + tk.MustExec("batch on _tidb_rowid limit 3 update t set b = 42") + tk.MustQuery("select sum(b) from t").Check(testkit.Rows("4200")) tk.MustExec("batch on _tidb_rowid limit 3 delete from t") tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) } -func TestNonTransactionalDeleteNull(t *testing.T) { +func TestNonTransactionalWithNull(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, key(a))") + tk.MustExec("create table t1(a int, b int, key(a))") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) tk.MustExec("insert into t values (null, null)") @@ -179,39 +416,70 @@ func TestNonTransactionalDeleteNull(t *testing.T) { for i := 0; i < 100; i++ { tk.MustExec("insert into t values (null, null)") } + tk.MustExec("batch on a limit 3 insert into t1 select * from t") + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) + tk.MustExec("batch on a limit 3 insert into t1 select * from t on duplicate key update t1.b=t.b") + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("200")) tk.MustExec("batch on a limit 3 delete from t") tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) } -func TestNonTransactionalDeleteSmallBatch(t *testing.T) { +func TestNonTransactionalWithSmallBatch(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=1024") tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, key(a))") + tk.MustExec("create table t1(a int, b int, unique key(a))") for i := 0; i < 10; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) tk.MustExec("insert into t values (null, null)") } require.Equal(t, 1, len(tk.MustQuery("batch on a limit 1000 dry run delete from t").Rows())) + require.Equal(t, 1, len(tk.MustQuery("batch on a limit 1000 dry run insert into t1 select * from t").Rows())) + require.Equal(t, 1, len(tk.MustQuery("batch on a limit 1000 dry run insert into t1 select * from t on duplicate key update t1.b=t.b").Rows())) + tk.MustExec("batch on a limit 1000 insert into t1 select * from t") + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) + tk.MustExec("update t1 set b = a") + // non-null rows will be updated, and null rows will be duplicated + tk.MustExec("batch on a limit 1000 insert into t1 select * from t on duplicate key update t1.b=t.b") + tk.MustQuery("select * from t1 where a is not null order by a"). + Check(tk.MustQuery("select * from t where a is not null order by a").Rows()) + tk.MustQuery("select count(*) from t1 where a is null").Check(testkit.Rows("20")) tk.MustExec("batch on a limit 1000 delete from t") tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) } -func TestNonTransactionalDeleteShardOnGeneratedColumn(t *testing.T) { +func TestNonTransactionalWithShardOnGeneratedColumn(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, c double as (sqrt(a * a + b * b)), key(c))") + tk.MustExec("create table t1(a int, b int, c double as (sqrt(a * a + b * b)), unique key(c))") for i := 0; i < 1000; i++ { tk.MustExec(fmt.Sprintf("insert into t values (%d, %d, default)", i, i*2)) } + tk.MustExec("batch on c limit 10 insert into t1(a, b) select a, b from t") + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) + // swap a and b + tk.MustExec("update t1 set a=b, b=a") + tk.MustQuery("select b, a from t1 order by a"). + Check(tk.MustQuery("select a, b from t order by a").Rows()) + tk.MustExec("batch on c limit 10 insert into t1(a, b) select a, b from t on duplicate key update t1.a=t.a, t1.b=t.b") + // insert on duplicate key update should swap back a and b + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) tk.MustExec("batch on c limit 10 delete from t") tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) } -func TestNonTransactionalDeleteAutoDetectShardColumn(t *testing.T) { +func TestNonTransactionalWithAutoDetectShardColumn(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") @@ -231,12 +499,17 @@ func TestNonTransactionalDeleteAutoDetectShardColumn(t *testing.T) { } testFunc := func(table string, expectSuccess bool) { - tk.MustExec("drop table if exists t") + tk.MustExec("drop table if exists t, t1") tk.MustExec(table) + tk.MustExec(strings.Replace(table, "create table t", "create table t1", 1)) for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) } - _, err := tk.Exec("batch limit 3 delete from t") + _, err := tk.Exec("batch limit 3 insert into t1 select * from t") + require.Equal(t, expectSuccess, err == nil) + _, err = tk.Exec("batch limit 3 insert into t1 select * from t on duplicate key update t1.a=t.a, t1.b=t.b") + require.Equal(t, expectSuccess, err == nil) + _, err = tk.Exec("batch limit 3 delete from t") require.Equal(t, expectSuccess, err == nil) } @@ -248,67 +521,118 @@ func TestNonTransactionalDeleteAutoDetectShardColumn(t *testing.T) { } } -func TestNonTransactionalDeleteInvisibleIndex(t *testing.T) { +func TestNonTransactionalWithInvisibleIndex(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int)") + tk.MustExec("create table t1(a int, b int)") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values (%d, %d)", i, i*2)) } - err := tk.ExecToErr("batch on a limit 10 delete from t") + err := tk.ExecToErr("batch on a limit 10 insert into t1 select * from t") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 delete from t") require.Error(t, err) tk.MustExec("CREATE UNIQUE INDEX c1 ON t (a) INVISIBLE") + tk.MustExec("CREATE UNIQUE INDEX c1 ON t1 (a) INVISIBLE") + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.Error(t, err) err = tk.ExecToErr("batch on a limit 10 delete from t") require.Error(t, err) tk.MustExec("CREATE UNIQUE INDEX c2 ON t (a)") + tk.MustExec("CREATE UNIQUE INDEX c2 ON t1 (a)") + tk.MustExec("batch on a limit 10 insert into t1 select * from t") + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) + tk.MustExec("update t1 set b=a") + tk.MustExec("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + tk.MustQuery("select * from t1 order by a"). + Check(tk.MustQuery("select * from t order by a").Rows()) tk.MustExec("batch on a limit 10 delete from t") tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) } -func TestNonTransactionalDeleteIgnoreSelectLimit(t *testing.T) { +func TestNonTransactionalWithIgnoreSelectLimit(t *testing.T) { store := testkit.CreateMockStore(t) + checkTk := testkit.NewTestKit(t, store) + checkTk.MustExec("use test") tk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("set @@sql_select_limit=3") tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, key(a))") + tk.MustExec("create table t1(a int, b int, unique key(a))") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values (%d, %d)", i, i*2)) } + tk.MustExec("batch on a limit 10 insert into t1 select * from t") + checkTk.MustQuery("select * from t1 order by a"). + Check(checkTk.MustQuery("select * from t order by a").Rows()) + tk.MustExec("update t1 set b=a") + tk.MustExec("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + checkTk.MustQuery("select * from t1 order by a"). + Check(checkTk.MustQuery("select * from t order by a").Rows()) tk.MustExec("batch on a limit 10 delete from t") - tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) + checkTk.MustQuery("select * from t").Check(testkit.Rows()) } -func TestNonTransactionalDeleteReadStaleness(t *testing.T) { +func TestNonTransactionalWithReadStaleness(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) + checkTk := testkit.NewTestKit(t, store) tk.MustExec("set @@tidb_max_chunk_size=35") tk.MustExec("set @@tidb_read_staleness=-100") tk.MustExec("use test") + checkTk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, key(a))") + tk.MustExec("create table t1(a int, b int, unique key(a))") + rows := make([]string, 0, 100) for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values (%d, %d)", i, i*2)) + rows = append(rows, fmt.Sprintf("%d %d", i, i*2)) } + tk.MustExec("batch on a limit 10 insert into t1 select * from t") + checkTk.MustQuery("select * from t1 order by a").Check(testkit.Rows(rows...)) + checkTk.MustExec("update t1 set b=a") + tk.MustExec("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") tk.MustExec("batch on a limit 10 delete from t") tk.MustExec("set @@tidb_read_staleness=0") - tk.MustQuery("select count(*) from t").Check(testkit.Rows("0")) + tk.MustQuery("select * from t").Check(testkit.Rows()) + tk.MustQuery("select * from t1 order by a").Check(testkit.Rows(rows...)) } -func TestNonTransactionalDeleteCheckConstraint(t *testing.T) { +func TestNonTransactionalWithCheckConstraint(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, key(a))") + tk.MustExec("create table t1(a int, b int, key(a))") + + checkFn := func() { + tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0")) + } // For mocked tikv, safe point is not initialized, we manually insert it for snapshot to use. safePointName := "tikv_gc_safe_point" now := time.Now() safePointValue := now.Format(tikvutil.GCTimeFormat) safePointComment := "All versions after safe point can be accessed. (DO NOT EDIT)" - updateSafePoint := fmt.Sprintf("INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s') ON DUPLICATE KEY UPDATE variable_value = '%[2]s', comment = '%[3]s'", safePointName, safePointValue, safePointComment) + updateSafePoint := fmt.Sprintf( + "INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s') ON DUPLICATE KEY UPDATE variable_value = '%[2]s', comment = '%[3]s'", + safePointName, safePointValue, safePointComment, + ) tk.MustExec(updateSafePoint) tk.MustExec("set @@tidb_max_chunk_size=35") @@ -318,86 +642,138 @@ func TestNonTransactionalDeleteCheckConstraint(t *testing.T) { tk.MustExec(fmt.Sprintf("insert into t values (%d, %d)", i, i*2)) } tk.MustExec("set @@tidb_snapshot=@a") - err := tk.ExecToErr("batch on a limit 10 delete from t") + err := tk.ExecToErr("batch on a limit 10 insert into t1 select * from t") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 delete from t") require.Error(t, err) tk.MustExec("set @@tidb_snapshot=''") - tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) + checkFn() tk.MustExec("set @@tidb_read_consistency=weak") + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.Error(t, err) err = tk.ExecToErr("batch on a limit 10 delete from t") require.Error(t, err) - tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) tk.MustExec("set @@tidb_read_consistency=strict") + checkFn() tk.MustExec("set autocommit=0") + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.Error(t, err) err = tk.ExecToErr("batch on a limit 10 delete from t") require.Error(t, err) - tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) + tk.MustExec("commit") tk.MustExec("set autocommit=1") + checkFn() tk.MustExec("begin") + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.Error(t, err) err = tk.ExecToErr("batch on a limit 10 delete from t") require.Error(t, err) - tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) tk.MustExec("commit") + checkFn() tk.MustExec("SET GLOBAL tidb_enable_batch_dml = 1") tk.MustExec("SET tidb_batch_insert = 1") tk.MustExec("SET tidb_dml_batch_size = 1") + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t") + require.Error(t, err) + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b") + require.Error(t, err) err = tk.ExecToErr("batch on a limit 10 delete from t") require.Error(t, err) - tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) tk.MustExec("SET GLOBAL tidb_enable_batch_dml = 0") tk.MustExec("SET tidb_batch_insert = 0") tk.MustExec("SET tidb_dml_batch_size = 0") + checkFn() + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t limit 10") + require.EqualError(t, err, "Non-transactional statements don't support limit") + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t limit 10 on duplicate key update t1.b=t.b") + require.EqualError(t, err, "Non-transactional statements don't support limit") err = tk.ExecToErr("batch on a limit 10 delete from t limit 10") - require.EqualError(t, err, "Non-transactional delete doesn't support limit") - tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) + require.EqualError(t, err, "Non-transactional statements don't support limit") + checkFn() + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t order by a") + require.EqualError(t, err, "Non-transactional statements don't support order by") + err = tk.ExecToErr("batch on a limit 10 insert into t1 select * from t order by a on duplicate key update t1.b=t.b") + require.EqualError(t, err, "Non-transactional statements don't support order by") err = tk.ExecToErr("batch on a limit 10 delete from t order by a") - require.EqualError(t, err, "Non-transactional delete doesn't support order by") - tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) + require.EqualError(t, err, "Non-transactional statements don't support order by") + checkFn() + err = tk.ExecToErr("prepare nt FROM 'batch limit 1 insert into t1 select * from t'") + require.EqualError(t, err, "[executor:1295]This command is not supported in the prepared statement protocol yet") + err = tk.ExecToErr("prepare nt FROM 'batch on a limit 10 insert into t1 select * from t on duplicate key update t1.b=t.b'") + require.EqualError(t, err, "[executor:1295]This command is not supported in the prepared statement protocol yet") err = tk.ExecToErr("prepare nt FROM 'batch limit 1 delete from t'") require.EqualError(t, err, "[executor:1295]This command is not supported in the prepared statement protocol yet") + + err = tk.ExecToErr("batch limit 1 insert into t select 1, 1") + require.EqualError(t, err, "table reference is nil") + err = tk.ExecToErr("batch limit 1 insert into t select * from (select 1, 2) tmp") + require.EqualError(t, err, "Non-transactional DML, table name not found in join") } -func TestNonTransactionalDeleteOptimizerHints(t *testing.T) { +func TestNonTransactionalWithOptimizerHints(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t(a int, b int, key(a))") + tk.MustExec("create table t1(a int, b int, key(a))") for i := 0; i < 10; i++ { tk.MustExec(fmt.Sprintf("insert into t values ('%d', %d)", i, i*2)) } - result := tk.MustQuery("batch on a limit 10 dry run delete /*+ USE_INDEX(t) */ from t").Rows()[0][0].(string) + result := tk.MustQuery("batch on a limit 10 dry run insert into t1 select /*+ USE_INDEX(t) */ * from t").Rows()[0][0].(string) + require.Equal(t, result, "INSERT INTO `test`.`t1` SELECT /*+ USE_INDEX(`t` )*/ * FROM `test`.`t` WHERE `a` BETWEEN 0 AND 9") + result = tk.MustQuery("batch on a limit 10 dry run insert into t1 select /*+ USE_INDEX(t) */ * from t on duplicate key update t1.b=t.b").Rows()[0][0].(string) + require.Equal(t, result, "INSERT INTO `test`.`t1` SELECT /*+ USE_INDEX(`t` )*/ * FROM `test`.`t` WHERE `a` BETWEEN 0 AND 9 ON DUPLICATE KEY UPDATE `t1`.`b`=`t`.`b`") + result = tk.MustQuery("batch on a limit 10 dry run delete /*+ USE_INDEX(t) */ from t").Rows()[0][0].(string) require.Equal(t, result, "DELETE /*+ USE_INDEX(`t` )*/ FROM `test`.`t` WHERE `a` BETWEEN 0 AND 9") } -func TestNonTransactionalDeleteMultiTables(t *testing.T) { +func TestNonTransactionalWithMultiTables(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1, t2") tk.MustExec("create table t(a int, b int, key(a))") + tk.MustExec("create table t1(a int, b int, key(a))") + tk.MustExec("create table t2(a int, b int, key(a))") for i := 0; i < 100; i++ { tk.MustExec(fmt.Sprintf("insert into t values (%d, %d)", i, i*2)) } - - tk.MustExec("create table t1(a int, b int, key(a))") tk.MustExec("insert into t1 values (1, 1)") - err := tk.ExecToErr("batch limit 1 delete t, t1 from t, t1 where t.a = t1.a") + + err := tk.ExecToErr("batch limit 1 insert into t2 select t.a, t1.b from t, t1 where t.a = t1.a") + require.Error(t, err) + tk.MustQuery("select count(*) from t2").Check(testkit.Rows("0")) + err = tk.ExecToErr("batch limit 1 insert into t2 select t.a, t1.b from t, t1 where t.a = t1.a on duplicate key update t2.b=t.b") + require.Error(t, err) + tk.MustQuery("select count(*) from t2").Check(testkit.Rows("0")) + err = tk.ExecToErr("batch limit 1 delete t, t1 from t, t1 where t.a = t1.a") require.Error(t, err) tk.MustQuery("select count(*) from t").Check(testkit.Rows("100")) tk.MustQuery("select count(*) from t1").Check(testkit.Rows("1")) } -func TestNonTransactionalDeleteAlias(t *testing.T) { +func TestNonTransactionalWithAlias(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) - goodBatchStmts := []string{ + goodBatchDeletes := []string{ "batch on test.t1.a limit 5 delete t1.* from test.t as t1", "batch on a limit 5 delete t1.* from test.t as t1", "batch on _tidb_rowid limit 5 delete from test.t as t1", @@ -406,17 +782,35 @@ func TestNonTransactionalDeleteAlias(t *testing.T) { "batch limit 5 delete from test.t as t1", // auto assigns table name to be the alias } - badBatchStmts := []string{ + badBatchDeletes := []string{ "batch on test.t.a limit 5 delete t1.* from test.t as t1", "batch on t.a limit 5 delete t1.* from test.t as t1", "batch on t._tidb_rowid limit 5 delete from test.t as t1", "batch on test.t._tidb_rowid limit 5 delete from test.t as t1", } + goodBatchInserts := []string{ + "batch on test.t1.a limit 5 insert into test.s select t1.* from test.t as t1", + "batch on a limit 5 insert into test.s select t1.* from test.t as t1", + "batch on _tidb_rowid limit 5 insert into test.s select t1.* from test.t as t1", + "batch on t1._tidb_rowid limit 5 insert into test.s select t1.* from test.t as t1", + "batch on test.t1._tidb_rowid limit 5 insert into test.s select t1.* from test.t as t1", + "batch limit 5 insert into test.s select t1.* from test.t as t1", // auto assigns table name to be the alias + } + + badBatchInserts := []string{ + "batch on test.t.a limit 5 insert into test.s select t1.* from test.t as t1", + "batch on t.a limit 5 insert into test.s select t1.* from test.t as t1", + "batch on t._tidb_rowid limit 5 insert into test.s select t1.* from test.t as t1", + "batch on test.t._tidb_rowid limit 5 insert into test.s select t1.* from test.t as t1", + } + + tk.MustExec("drop table if exists test.t, test.s, test.t2") tk.MustExec("create table test.t(a int, b int, key(a))") + tk.MustExec("create table test.s(a int, b int, unique key(a))") tk.MustExec("create table test.t2(a int, b int, key(a))") - for _, sql := range goodBatchStmts { + for _, sql := range goodBatchDeletes { for i := 0; i < 5; i++ { tk.MustExec(fmt.Sprintf("insert into test.t values (%d, %d)", i, i*2)) } @@ -424,30 +818,197 @@ func TestNonTransactionalDeleteAlias(t *testing.T) { tk.MustQuery("select count(*) from test.t").Check(testkit.Rows("0")) } + rows := make([]string, 0, 5) for i := 0; i < 5; i++ { tk.MustExec(fmt.Sprintf("insert into test.t values (%d, %d)", i, i*2)) + rows = append(rows, fmt.Sprintf("%d %d", i, i*2)) } - for _, sql := range badBatchStmts { + + for _, sql := range goodBatchInserts { + tk.MustExec(sql) + tk.MustQuery("select * from test.s order by a").Check(testkit.Rows(rows...)) + tk.MustExec("update test.s set b=a") + tk.MustExec(sql + " on duplicate key update s.b=t1.b") + tk.MustQuery("select * from test.s order by a").Check(testkit.Rows(rows...)) + tk.MustExec("truncate test.s") + } + + for _, sql := range badBatchDeletes { err := tk.ExecToErr(sql) require.Error(t, err) tk.MustQuery("select count(*) from test.t").Check(testkit.Rows("5")) } + + for _, sql := range badBatchInserts { + err := tk.ExecToErr(sql) + require.Error(t, err) + tk.MustQuery("select count(*) from test.s").Check(testkit.Rows("0")) + } } -func TestNonTransactionalDeleteShardOnUnsupportedTypes(t *testing.T) { +func TestNonTransactionalWithShardOnUnsupportedTypes(t *testing.T) { // When some day the test fail because such types are supported, we can update related docs and consider remove the test. store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1, t2") tk.MustExec("create table t(a set('e0', 'e1', 'e2'), b int, primary key(a) clustered, key(b))") + tk.MustExec("create table t1(a set('e0', 'e1', 'e2'), b int, primary key(a) clustered, key(b))") tk.MustExec("insert into t values ('e2,e0', 3)") - err := tk.ExecToErr("batch limit 1 delete from t where a = 'e0,e2'") + err := tk.ExecToErr("batch limit 1 insert into t1 select * from t where a = 'e0,e2'") + require.Error(t, err) + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0")) + err = tk.ExecToErr("batch limit 1 insert into t1 select * from t where a = 'e0,e2' on duplicate key update t1.b=t.b") + require.Error(t, err) + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0")) + err = tk.ExecToErr("batch limit 1 delete from t where a = 'e0,e2'") require.Error(t, err) tk.MustQuery("select count(*) from t").Check(testkit.Rows("1")) tk.MustExec("create table t2(a enum('e0', 'e1', 'e2'), b int, key(a))") tk.MustExec("insert into t2 values ('e0', 1)") + err = tk.ExecToErr("batch on a limit 1 insert into t1 select * from t2") + require.Error(t, err) + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0")) + err = tk.ExecToErr("batch on a limit 1 insert into t1 select * from t2 on duplicate key update t1.b=t2.b") + require.Error(t, err) + tk.MustQuery("select count(*) from t1").Check(testkit.Rows("0")) err = tk.ExecToErr("batch on a limit 1 delete from t2") require.Error(t, err) tk.MustQuery("select count(*) from t2").Check(testkit.Rows("1")) } + +func TestNonTransactionalWithJoin(t *testing.T) { + // insert + // BATCH ON t2.id LIMIT 10000 insert into t1 select id, name from t2 inner join t3 on t2.id = t3.id; + // insert into t1 select id, name from t2 inner join t3 on t2.id = t3.id where t2.id between 1 and 10000 + + // replace + // BATCH ON t1.id LIMIT 10000 replace into t3 + // select * from t1 left join t2 on t1.id = t2.id; + + // update + // BATCH ON t1.id LIMIT 10000 update t1 join t2 on t1.a=t2.a set t1.a=t1.a*1000; + // update t1 join t2 on t1.a=t2.a set t1.a=t1.a*1000 where t1.id between 1 and 10000; + + // delete + // BATCH ON pa.id LIMIT 10000 DELETE pa + // FROM pets_activities pa JOIN pets p ON pa.id = p.pet_id + // WHERE p.order > :order AND p.pet_id = :pet_id + // delete pa + // from pets_activities pa join pets p on pa.id = p.pet_id + // WHERE p.order > :order AND p.pet_id = :pet_id and pa.id between 1 and 10000; + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int, v1 int, v2 int, unique key (id))") + tk.MustExec("create table t2(id int, v int, key i1(id))") + tk.MustExec("create table t3(id int, v int, key i1(id))") + tk.MustExec("insert into t2 values (1, 2), (2, 3), (3, 4)") + tk.MustExec("insert into t3 values (1, 4), (2, 5), (4, 6)") + + tk.MustExec("batch on test.t2.id limit 1 insert into t select t2.id, t2.v, t3.v from t2 join t3 on t2.id=t3.id") + tk.MustQuery("select * from t").Check(testkit.Rows("1 2 4", "2 3 5")) + + tk.MustContainErrMsg( + "batch on id limit 1 insert into t select t2.id, t2.v, t3.v from t2 join t3 on t2.id=t3.id", + "Non-transactional DML, shard column must be fully specified", + ) + tk.MustContainErrMsg( + "batch on test.t1.id limit 1 insert into t select t2.id, t2.v, t3.v from t2 join t3 on t2.id=t3.id", + "shard column test.t1.id is not in the tables involved in the join", + ) + + tk.MustExec("batch on test.t2.id limit 1 update t2 join t3 on t2.id=t3.id set t2.v=t2.v*100, t3.v=t3.v*200") + tk.MustQuery("select * from t2").Check(testkit.Rows("1 200", "2 300", "3 4")) + tk.MustQuery("select * from t3").Check(testkit.Rows("1 800", "2 1000", "4 6")) + + tk.MustExec("batch limit 1 delete t2 from t2 join t3 on t2.id=t3.id") + tk.MustQuery("select * from t2").Check(testkit.Rows("3 4")) + + tk.MustExec("insert into t2 values (1, 11), (2, 22)") + tk.MustExec("batch limit 1 replace into t select t2.id, t2.v, t3.v from t2 join t3 on t2.id=t3.id") + tk.MustQuery("select * from t").Check(testkit.Rows("1 11 800", "2 22 1000")) +} + +func TestAnomalousNontransactionalDML(t *testing.T) { + // some weird and error-prone behavior + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int, v int)") + + // self-insert, this is allowed but can be dangerous + tk.MustExec("insert into t values (1, 1)") + tk.MustExec("batch limit 1 insert into t select * from t") + tk.MustQuery("select * from t").Check(testkit.Rows("1 1", "1 1")) + tk.MustExec("drop table t") + + tk.MustExec("create table t(id int, v int, key(id))") + tk.MustExec("create table t2(id int, v int, key(id))") + tk.MustExec("insert into t values (1, 1), (2, 2), (3, 3)") + tk.MustExec("insert into t2 values (1, 1), (2, 2), (4, 4)") + + tk.MustExec("batch on test.t.id limit 1 update t join t2 on t.id=t2.id set t2.id = t2.id+1") + tk.MustQuery("select * from t2").Check(testkit.Rows("4 1", "4 2", "4 4")) +} + +func TestAlias(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int, v1 int, v2 int, unique key (id))") + tk.MustExec("create table t2(id int, v int, key (id))") + tk.MustExec("create table t3(id int, v int, key (id))") + tk.MustExec("insert into t values (1, 1, 1), (2, 2, 2), (3, 3, 3)") + tk.MustExec("insert into t2 values (1, 1), (2, 20), (4, 40)") + tk.MustExec("insert into t3 values (2, 21), (4, 41), (5, 50)") + tk.MustExec("update t as t1 set v1 = test.t1.id + 1") + tk.MustQuery("select * from t").Check(testkit.Rows("1 2 1", "2 3 2", "3 4 3")) + + tk.MustExec("batch on test.tt2.id limit 1 replace into t select tt2.id, tt2.v, t3.v from t2 as tt2 join t3 on tt2.id=t3.id") + tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 2 1", "2 20 21", "3 4 3", "4 40 41")) +} + +func TestUpdatingShardColumn(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int, v int, unique key(id))") + tk.MustExec("create table t2(id int, v int, unique key(id))") + tk.MustExec("insert into t values (1, 1), (2, 2), (3, 3)") + tk.MustExec("insert into t2 values (1, 1), (2, 2), (4, 4)") + + // update stmt + tk.MustContainErrMsg("batch on id limit 1 update t set id=id+1", "Non-transactional DML, shard column cannot be updated") + // insert on dup update + tk.MustContainErrMsg("batch on id limit 1 insert into t select * from t on duplicate key update t.id=t.id+10", "Non-transactional DML, shard column cannot be updated") + // update with table alias + tk.MustContainErrMsg("batch on id limit 1 update t as t1 set t1.id=t1.id+1", "Non-transactional DML, shard column cannot be updated") + // insert on dup update with table alias + tk.MustContainErrMsg("batch on id limit 1 insert into t select * from t as t1 on duplicate key update t1.id=t1.id+10", "Non-transactional DML, shard column cannot be updated") + // update stmt, multiple table + tk.MustContainErrMsg("batch on test.t.id limit 1 update t join t2 on t.id=t2.id set t.id=t.id+1", "Non-transactional DML, shard column cannot be updated") + // update stmt, multiple table, alias + tk.MustContainErrMsg("batch on test.tt.id limit 1 update t as tt join t2 as tt2 on tt.id=tt2.id set tt.id=tt.id+10", "Non-transactional DML, shard column cannot be updated") +} + +func TestNameAmbiguity(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int, v1 int, v2 int, unique key (id))") + tk.MustExec("create table t2(id int, v int, key (id))") + tk.MustExec("create table t3(id int, v int, key (id))") + + tk.MustExec("create database test2") + tk.MustExec("use test2") + tk.MustExec("create table t(id int, v1 int, v2 int, unique key (id))") + tk.MustExec("create table t2(id int, v int, key (id))") + tk.MustExec("create table t3(id int, v int, key (id))") + tk.MustExec("insert into t values (1, 1, 1), (2, 2, 2)") + + tk.MustExec("use test") + tk.MustExec("batch on id limit 1 insert into t select * from test2.t") + tk.MustQuery("select * from t").Check(testkit.Rows("1 1 1", "2 2 2")) +} diff --git a/session/schema_amender.go b/session/schema_amender.go deleted file mode 100644 index 955d30cc42ada..0000000000000 --- a/session/schema_amender.go +++ /dev/null @@ -1,713 +0,0 @@ -// Copyright 2020 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package session - -import ( - "bytes" - "context" - "encoding/hex" - "fmt" - "reflect" - - "github.com/pingcap/errors" - "github.com/pingcap/kvproto/pkg/kvrpcpb" - "github.com/pingcap/tidb/executor" - "github.com/pingcap/tidb/expression" - "github.com/pingcap/tidb/infoschema" - "github.com/pingcap/tidb/kv" - "github.com/pingcap/tidb/parser/model" - "github.com/pingcap/tidb/parser/mysql" - "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/table" - "github.com/pingcap/tidb/table/tables" - "github.com/pingcap/tidb/tablecodec" - "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/util/chunk" - "github.com/pingcap/tidb/util/logutil" - "github.com/pingcap/tidb/util/rowcodec" - "github.com/tikv/client-go/v2/tikv" - "github.com/tikv/client-go/v2/txnkv/transaction" - "go.uber.org/zap" -) - -const amendableType = nonMemAmendType | memBufAmendType -const nonMemAmendType = (1 << model.ActionAddColumn) | (1 << model.ActionDropColumn) | (1 << model.ActionDropIndex) -const memBufAmendType = uint64(1< 0 -} - -func needCollectIndexOps(actionType uint64) bool { - return actionType&(1< idxInfoAtStart.Meta().State { - amendOpType = ConstOpAddIndex[idxInfoAtStart.Meta().State][idxInfoAtCommit.Meta().State] - } - if amendOpType != AmendNone { - opInfo := &amendOperationAddIndexInfo{} - opInfo.AmendOpType = amendOpType - opInfo.tblInfoAtStart = tblAtStart - opInfo.tblInfoAtCommit = tblAtCommit - opInfo.indexInfoAtStart = idxInfoAtStart - opInfo.indexInfoAtCommit = idxInfoAtCommit - for _, idxCol := range idxInfoAtCommit.Meta().Columns { - colID := tblAtCommit.Meta().Columns[idxCol.Offset].ID - oldColInfo := findColByID(tblAtStart, colID) - // TODO: now index column MUST be found in old table columns, generated column is not supported. - if oldColInfo == nil || oldColInfo.IsGenerated() || oldColInfo.Hidden { - return nil, errors.Trace(errors.Errorf("amend index column=%v id=%v is not found or generated in table=%v", - idxCol.Name, colID, tblAtCommit.Meta().Name.String())) - } - opInfo.relatedOldIdxCols = append(opInfo.relatedOldIdxCols, oldColInfo) - } - opInfo.schemaAndDecoder = newSchemaAndDecoder(sctx, tblAtStart.Meta()) - fieldTypes := make([]*types.FieldType, 0, len(tblAtStart.Meta().Columns)) - for _, col := range tblAtStart.Meta().Columns { - fieldTypes = append(fieldTypes, &(col.FieldType)) - } - opInfo.chk = chunk.NewChunkWithCapacity(fieldTypes, 4) - addNewIndexOp := &amendOperationAddIndex{ - info: opInfo, - insertedNewIndexKeys: make(map[string]struct{}), - deletedOldIndexKeys: make(map[string]struct{}), - } - res = append(res, addNewIndexOp) - } - } - return res, nil -} - -// collectTblAmendOps collects amend operations for each table using the schema diff between startTS and commitTS. -func (a *amendCollector) collectTblAmendOps(sctx sessionctx.Context, phyTblID int64, - tblInfoAtStart, tblInfoAtCommit table.Table, actionType uint64) error { - if _, ok := a.tblAmendOpMap[phyTblID]; !ok { - a.tblAmendOpMap[phyTblID] = make([]amendOp, 0, 4) - } - if needCollectModifyColOps(actionType) { - _, err := a.collectModifyColAmendOps(tblInfoAtStart, tblInfoAtCommit) - if err != nil { - return err - } - } - if needCollectIndexOps(actionType) { - // TODO: currently only "add index" is considered. - ops, err := a.collectIndexAmendOps(sctx, tblInfoAtStart, tblInfoAtCommit) - if err != nil { - return err - } - a.tblAmendOpMap[phyTblID] = append(a.tblAmendOpMap[phyTblID], ops...) - } - return nil -} - -// mayGenDelIndexRowKeyOp returns if the row key op could generate Op_Del index key mutations. -func mayGenDelIndexRowKeyOp(keyOp kvrpcpb.Op) bool { - return keyOp == kvrpcpb.Op_Del || keyOp == kvrpcpb.Op_Put -} - -// mayGenPutIndexRowKeyOp returns if the row key op could generate Op_Put/Op_Insert index key mutations. -func mayGenPutIndexRowKeyOp(keyOp kvrpcpb.Op) bool { - return keyOp == kvrpcpb.Op_Put || keyOp == kvrpcpb.Op_Insert -} - -// amendOp is an amend operation for a specific schema change, new mutations will be generated using input ones. -type amendOp interface { - genMutations(ctx context.Context, sctx sessionctx.Context, commitMutations transaction.CommitterMutations, kvMap *rowKvMap, - resultMutations *transaction.PlainMutations) error -} - -// amendOperationAddIndex represents one amend operation related to a specific add index change. -type amendOperationAddIndexInfo struct { - AmendOpType int - tblInfoAtStart table.Table - tblInfoAtCommit table.Table - indexInfoAtStart table.Index - indexInfoAtCommit table.Index - relatedOldIdxCols []*table.Column - - schemaAndDecoder *schemaAndDecoder - chk *chunk.Chunk -} - -// amendOperationAddIndex represents the add operation will be performed on new key values for add index amend. -type amendOperationAddIndex struct { - info *amendOperationAddIndexInfo - - // insertedNewIndexKeys is used to check duplicates for new index generated by unique key. - insertedNewIndexKeys map[string]struct{} - // deletedOldIndexKeys is used to check duplicates for deleted old index keys. - deletedOldIndexKeys map[string]struct{} -} - -func (a *amendOperationAddIndexInfo) String() string { - var colStr string - colStr += "[" - for _, colInfo := range a.relatedOldIdxCols { - colStr += fmt.Sprintf(" %s ", colInfo.Name) - } - colStr += "]" - res := fmt.Sprintf("AmenedOpType=%d phyTblID=%d idxID=%d columns=%v", a.AmendOpType, a.indexInfoAtCommit.Meta().ID, - a.indexInfoAtCommit.Meta().ID, colStr) - return res -} - -func (a *amendOperationAddIndex) genMutations(ctx context.Context, sctx sessionctx.Context, commitMutations transaction.CommitterMutations, - kvMap *rowKvMap, resAddMutations *transaction.PlainMutations) error { - // There should be no duplicate keys in deletedOldIndexKeys and insertedNewIndexKeys. - deletedMutations := transaction.NewPlainMutations(32) - insertedMutations := transaction.NewPlainMutations(32) - for i, key := range commitMutations.GetKeys() { - if tablecodec.IsIndexKey(key) || tablecodec.DecodeTableID(key) != a.info.tblInfoAtCommit.Meta().ID { - continue - } - var newIdxMutation *transaction.PlainMutation - var oldIdxMutation *transaction.PlainMutation - var err error - keyOp := commitMutations.GetOp(i) - if addIndexNeedRemoveOp(a.info.AmendOpType) { - if mayGenDelIndexRowKeyOp(keyOp) { - oldIdxMutation, err = a.genOldIdxKey(ctx, sctx, key, kvMap.oldRowKvMap) - if err != nil { - return err - } - } - } - if addIndexNeedAddOp(a.info.AmendOpType) { - if mayGenPutIndexRowKeyOp(keyOp) { - newIdxMutation, err = a.genNewIdxKey(ctx, sctx, key, kvMap.newRowKvMap) - if err != nil { - return err - } - } - } - skipMerge := false - if a.info.AmendOpType == AmendNeedAddDeleteAndInsert { - // If the old index key is the same with new index key, then the index related row value - // is not changed in this row, we don't need to add or remove index keys for this row. - if oldIdxMutation != nil && newIdxMutation != nil { - if bytes.Equal(oldIdxMutation.Key, newIdxMutation.Key) { - skipMerge = true - } - } - } - if !skipMerge { - if oldIdxMutation != nil { - deletedMutations.AppendMutation(*oldIdxMutation) - } - if newIdxMutation != nil { - insertedMutations.AppendMutation(*newIdxMutation) - } - } - } - // For unique index, there may be conflicts on the same unique index key from different rows.Consider a update statement, - // "Op_Del" on row_key = 3, row_val = 4, the "Op_Del" unique_key_4 -> nil will be generated. - // "Op_Put" on row_key = 0, row_val = 4, the "Op_Insert" unique_key_4 -> 0 will be generated. - // The "Op_Insert" should cover the "Op_Del" otherwise the new put row value will not have a correspond index value. - if a.info.indexInfoAtCommit.Meta().Unique { - for i := 0; i < len(deletedMutations.GetKeys()); i++ { - key := deletedMutations.GetKeys()[i] - if _, ok := a.insertedNewIndexKeys[string(key)]; !ok { - resAddMutations.Push(deletedMutations.GetOps()[i], key, deletedMutations.GetValues()[i], deletedMutations.IsPessimisticLock(i), - deletedMutations.IsAssertExists(i), deletedMutations.IsAssertNotExist(i), deletedMutations.NeedConstraintCheckInPrewrite(i)) - } - } - for i := 0; i < len(insertedMutations.GetKeys()); i++ { - key := insertedMutations.GetKeys()[i] - destKeyOp := kvrpcpb.Op_Insert - if _, ok := a.deletedOldIndexKeys[string(key)]; ok { - destKeyOp = kvrpcpb.Op_Put - } - resAddMutations.Push(destKeyOp, key, insertedMutations.GetValues()[i], insertedMutations.IsPessimisticLock(i), - insertedMutations.IsAssertExists(i), insertedMutations.IsAssertNotExist(i), insertedMutations.NeedConstraintCheckInPrewrite(i)) - } - } else { - resAddMutations.MergeMutations(deletedMutations) - resAddMutations.MergeMutations(insertedMutations) - } - return nil -} - -func getCommonHandleDatum(tbl table.Table, row chunk.Row) []types.Datum { - if !tbl.Meta().IsCommonHandle { - return nil - } - datumBuf := make([]types.Datum, 0, 4) - for _, col := range tbl.Cols() { - if mysql.HasPriKeyFlag(col.GetFlag()) { - datumBuf = append(datumBuf, row.GetDatum(col.Offset, &col.FieldType)) - } - } - return datumBuf -} - -func (a *amendOperationAddIndexInfo) genIndexKeyValue(ctx context.Context, sctx sessionctx.Context, kvMap map[string][]byte, - key []byte, kvHandle kv.Handle, keyOnly bool) ([]byte, []byte, error) { - chk := a.chk - chk.Reset() - val, ok := kvMap[string(key)] - if !ok { - // The Op_Put may not exist in old value kv map. - if keyOnly { - return nil, nil, nil - } - return nil, nil, errors.Errorf("key=%v is not found in new row kv map", kv.Key(key).String()) - } - err := executor.DecodeRowValToChunk(sctx, a.schemaAndDecoder.schema, a.tblInfoAtStart.Meta(), kvHandle, val, chk, a.schemaAndDecoder.decoder) - if err != nil { - logutil.Logger(ctx).Warn("amend decode value to chunk failed", zap.Error(err)) - return nil, nil, errors.Trace(err) - } - idxVals := make([]types.Datum, 0, len(a.indexInfoAtCommit.Meta().Columns)) - for _, oldCol := range a.relatedOldIdxCols { - idxVals = append(idxVals, chk.GetRow(0).GetDatum(oldCol.Offset, &oldCol.FieldType)) - } - - rsData := tables.TryGetHandleRestoredDataWrapper(a.tblInfoAtCommit, getCommonHandleDatum(a.tblInfoAtCommit, chk.GetRow(0)), nil, a.indexInfoAtCommit.Meta()) - - // Generate index key buf. - newIdxKey, distinct, err := tablecodec.GenIndexKey(sctx.GetSessionVars().StmtCtx, - a.tblInfoAtCommit.Meta(), a.indexInfoAtCommit.Meta(), a.tblInfoAtCommit.Meta().ID, idxVals, kvHandle, nil) - if err != nil { - logutil.Logger(ctx).Warn("amend generate index key failed", zap.Error(err)) - return nil, nil, errors.Trace(err) - } - if keyOnly { - return newIdxKey, []byte{}, nil - } - - // Generate index value buf. - needRsData := tables.NeedRestoredData(a.indexInfoAtCommit.Meta().Columns, a.tblInfoAtCommit.Meta().Columns) - newIdxVal, err := tablecodec.GenIndexValuePortal(sctx.GetSessionVars().StmtCtx, a.tblInfoAtCommit.Meta(), a.indexInfoAtCommit.Meta(), needRsData, distinct, false, idxVals, kvHandle, 0, rsData) - if err != nil { - logutil.Logger(ctx).Warn("amend generate index values failed", zap.Error(err)) - return nil, nil, errors.Trace(err) - } - return newIdxKey, newIdxVal, nil -} - -func (a *amendOperationAddIndex) genNewIdxKey(ctx context.Context, sctx sessionctx.Context, key []byte, - kvMap map[string][]byte) (*transaction.PlainMutation, error) { - kvHandle, err := tablecodec.DecodeRowKey(key) - if err != nil { - logutil.Logger(ctx).Error("decode key error", zap.String("key", hex.EncodeToString(key)), zap.Error(err)) - return nil, errors.Trace(err) - } - - newIdxKey, newIdxValue, err := a.info.genIndexKeyValue(ctx, sctx, kvMap, key, kvHandle, false) - if err != nil { - return nil, errors.Trace(err) - } - newIndexOp := kvrpcpb.Op_Put - isPessimisticLock := false - if _, ok := a.insertedNewIndexKeys[string(newIdxKey)]; ok { - return nil, errors.Trace(errors.Errorf("amend process key same key=%v found for index=%v in table=%v", - newIdxKey, a.info.indexInfoAtCommit.Meta().Name, a.info.tblInfoAtCommit.Meta().Name)) - } - if a.info.indexInfoAtCommit.Meta().Unique { - newIndexOp = kvrpcpb.Op_Insert - isPessimisticLock = true - } - a.insertedNewIndexKeys[string(newIdxKey)] = struct{}{} - var flags transaction.CommitterMutationFlags - if isPessimisticLock { - flags |= transaction.MutationFlagIsPessimisticLock - } - newMutation := &transaction.PlainMutation{KeyOp: newIndexOp, Key: newIdxKey, Value: newIdxValue, Flags: flags} - return newMutation, nil -} - -func (a *amendOperationAddIndex) genOldIdxKey(ctx context.Context, sctx sessionctx.Context, key []byte, - oldValKvMap map[string][]byte) (*transaction.PlainMutation, error) { - kvHandle, err := tablecodec.DecodeRowKey(key) - if err != nil { - logutil.Logger(ctx).Error("decode key error", zap.String("key", hex.EncodeToString(key)), zap.Error(err)) - return nil, errors.Trace(err) - } - // Generated delete index key value. - newIdxKey, emptyVal, err := a.info.genIndexKeyValue(ctx, sctx, oldValKvMap, key, kvHandle, true) - if err != nil { - return nil, errors.Trace(err) - } - // For Op_Put the key may not exist in old key value map. - if len(newIdxKey) > 0 { - isPessimisticLock := false - if _, ok := a.deletedOldIndexKeys[string(newIdxKey)]; ok { - return nil, errors.Trace(errors.Errorf("amend process key same key=%v found for index=%v in table=%v", - newIdxKey, a.info.indexInfoAtCommit.Meta().Name, a.info.tblInfoAtCommit.Meta().Name)) - } - if a.info.indexInfoAtCommit.Meta().Unique { - isPessimisticLock = true - } - a.deletedOldIndexKeys[string(newIdxKey)] = struct{}{} - var flags transaction.CommitterMutationFlags - if isPessimisticLock { - flags |= transaction.MutationFlagIsPessimisticLock - } - return &transaction.PlainMutation{KeyOp: kvrpcpb.Op_Del, Key: newIdxKey, Value: emptyVal, Flags: flags}, nil - } - return nil, nil -} - -// SchemaAmender is used to amend pessimistic transactions for schema change. -type SchemaAmender struct { - sess *session -} - -// NewSchemaAmenderForTikvTxn creates a schema amender for tikvTxn type. -func NewSchemaAmenderForTikvTxn(sess *session) *SchemaAmender { - amender := &SchemaAmender{sess: sess} - return amender -} - -func (s *SchemaAmender) getAmendableKeys(commitMutations transaction.CommitterMutations, info *amendCollector) ([]kv.Key, []kv.Key) { - addKeys := make([]kv.Key, 0, len(commitMutations.GetKeys())) - removeKeys := make([]kv.Key, 0, len(commitMutations.GetKeys())) - for i, byteKey := range commitMutations.GetKeys() { - if tablecodec.IsIndexKey(byteKey) || !info.keyHasAmendOp(byteKey) { - continue - } - keyOp := commitMutations.GetOp(i) - switch keyOp { - case kvrpcpb.Op_Put: - addKeys = append(addKeys, byteKey) - removeKeys = append(removeKeys, byteKey) - case kvrpcpb.Op_Insert: - addKeys = append(addKeys, byteKey) - case kvrpcpb.Op_Del: - removeKeys = append(removeKeys, byteKey) - } - } - return addKeys, removeKeys -} - -type rowKvMap struct { - oldRowKvMap map[string][]byte - newRowKvMap map[string][]byte -} - -func (s *SchemaAmender) prepareKvMap(ctx context.Context, commitMutations transaction.CommitterMutations, info *amendCollector) (*rowKvMap, error) { - // Get keys need to be considered for the amend operation, currently only row keys. - addKeys, removeKeys := s.getAmendableKeys(commitMutations, info) - - // BatchGet the new key values, the Op_Put and Op_Insert type keys in memory buffer. - txn, err := s.sess.Txn(true) - if err != nil { - return nil, errors.Trace(err) - } - newValKvMap, err := txn.BatchGet(ctx, addKeys) - if err != nil { - logutil.Logger(ctx).Warn("amend failed to batch get kv new keys", zap.Error(err)) - return nil, errors.Trace(err) - } - if len(newValKvMap) != len(addKeys) { - logutil.Logger(ctx).Error("amend failed to batch get results invalid", - zap.Int("addKeys len", len(addKeys)), zap.Int("newValKvMap", len(newValKvMap))) - return nil, errors.Errorf("add keys has %v values but result kvMap has %v", len(addKeys), len(newValKvMap)) - } - // BatchGet the old key values, the Op_Del and Op_Put types keys in storage using forUpdateTS, the Op_put type is for - // row update using the same row key, it may not exist. - snapshot := s.sess.GetStore().GetSnapshot(kv.Version{Ver: s.sess.sessionVars.TxnCtx.GetForUpdateTS()}) - oldValKvMap, err := snapshot.BatchGet(ctx, removeKeys) - if err != nil { - logutil.Logger(ctx).Warn("amend failed to batch get kv old keys", zap.Error(err)) - return nil, errors.Trace(err) - } - - res := &rowKvMap{ - oldRowKvMap: oldValKvMap, - newRowKvMap: newValKvMap, - } - return res, nil -} - -func (s *SchemaAmender) checkDupKeys(ctx context.Context, mutations transaction.CommitterMutations) error { - // Check if there are duplicate key entries. - checkMap := make(map[string]kvrpcpb.Op) - for i := 0; i < mutations.Len(); i++ { - key := mutations.GetKey(i) - keyOp := mutations.GetOp(i) - keyVal := mutations.GetValue(i) - if foundOp, ok := checkMap[string(key)]; ok { - logutil.Logger(ctx).Error("duplicate key found in amend result mutations", - zap.Stringer("key", kv.Key(key)), - zap.Stringer("foundKeyOp", foundOp), - zap.Stringer("thisKeyOp", keyOp), - zap.Stringer("thisKeyValue", kv.Key(keyVal))) - return errors.Trace(errors.Errorf("duplicate key=%s is found in mutations", kv.Key(key).String())) - } - checkMap[string(key)] = keyOp - } - return nil -} - -// genAllAmendMutations generates CommitterMutations for all tables and related amend operations. -func (s *SchemaAmender) genAllAmendMutations(ctx context.Context, commitMutations transaction.CommitterMutations, - info *amendCollector) (*transaction.PlainMutations, error) { - rowKvMap, err := s.prepareKvMap(ctx, commitMutations, info) - if err != nil { - return nil, err - } - // Do generate add/remove mutations processing each key. - resultNewMutations := transaction.NewPlainMutations(32) - for _, amendOps := range info.tblAmendOpMap { - for _, curOp := range amendOps { - err := curOp.genMutations(ctx, s.sess, commitMutations, rowKvMap, &resultNewMutations) - if err != nil { - return nil, err - } - } - } - err = s.checkDupKeys(ctx, &resultNewMutations) - if err != nil { - return nil, err - } - return &resultNewMutations, nil -} - -// AmendTxn does check and generate amend mutations based on input infoSchema and mutations, mutations need to prewrite -// are returned, the input commitMutations will not be changed. -func (s *SchemaAmender) AmendTxn(ctx context.Context, startInfoSchema tikv.SchemaVer, change *transaction.RelatedSchemaChange, - commitMutations transaction.CommitterMutations) (transaction.CommitterMutations, error) { - // Get info schema meta - infoSchemaAtStart := startInfoSchema.(infoschema.InfoSchema) - infoSchemaAtCheck := change.LatestInfoSchema.(infoschema.InfoSchema) - - // Collect amend operations for each table by physical table ID. - var needAmendMem bool - amendCollector := newAmendCollector() - for i, tblID := range change.PhyTblIDS { - actionType := change.ActionTypes[i] - // Check amendable flags, return if not supported flags exist. - if actionType&(^amendableType) != 0 { - logutil.Logger(ctx).Info("amend action type not supported for txn", zap.Int64("tblID", tblID), zap.Uint64("actionType", actionType)) - return nil, errors.Trace(table.ErrUnsupportedOp) - } - // Partition table is not supported now. - tblInfoAtStart, ok := infoSchemaAtStart.TableByID(tblID) - if !ok { - return nil, errors.Trace(errors.Errorf("tableID=%d is not found in infoSchema", tblID)) - } - if tblInfoAtStart.Meta().Partition != nil { - logutil.Logger(ctx).Info("Amend for partition table is not supported", - zap.String("tableName", tblInfoAtStart.Meta().Name.String()), zap.Int64("tableID", tblID)) - return nil, errors.Trace(table.ErrUnsupportedOp) - } - tblInfoAtCommit, ok := infoSchemaAtCheck.TableByID(tblID) - if !ok { - return nil, errors.Trace(errors.Errorf("tableID=%d is not found in infoSchema", tblID)) - } - if actionType&(memBufAmendType) != 0 { - needAmendMem = true - err := amendCollector.collectTblAmendOps(s.sess, tblID, tblInfoAtStart, tblInfoAtCommit, actionType) - if err != nil { - return nil, err - } - } - } - // After amend operations collect, generate related new mutations based on input commitMutations - if needAmendMem { - return s.genAllAmendMutations(ctx, commitMutations, amendCollector) - } - return nil, nil -} - -func newSchemaAndDecoder(ctx sessionctx.Context, tbl *model.TableInfo) *schemaAndDecoder { - schema := expression.NewSchema(make([]*expression.Column, 0, len(tbl.Columns))...) - for _, col := range tbl.Columns { - colExpr := &expression.Column{ - RetType: &col.FieldType, - ID: col.ID, - } - if col.IsGenerated() && !col.GeneratedStored { - // This will not be used since generated column is rejected in collectIndexAmendOps. - colExpr.VirtualExpr = &expression.Constant{} - } - schema.Append(colExpr) - } - return &schemaAndDecoder{schema, executor.NewRowDecoder(ctx, schema, tbl)} -} diff --git a/session/schema_amender_test.go b/session/schema_amender_test.go deleted file mode 100644 index e82faba8e6e56..0000000000000 --- a/session/schema_amender_test.go +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright 2020 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package session - -import ( - "bytes" - "context" - "fmt" - "strconv" - "testing" - - "github.com/pingcap/kvproto/pkg/kvrpcpb" - "github.com/pingcap/tidb/domain" - "github.com/pingcap/tidb/kv" - "github.com/pingcap/tidb/parser/model" - "github.com/pingcap/tidb/parser/mysql" - "github.com/pingcap/tidb/planner/core" - "github.com/pingcap/tidb/sessionctx/variable" - "github.com/pingcap/tidb/sessiontxn" - "github.com/pingcap/tidb/store/mockstore" - "github.com/pingcap/tidb/table" - "github.com/pingcap/tidb/tablecodec" - "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/util/logutil" - "github.com/pingcap/tidb/util/rowcodec" - "github.com/stretchr/testify/require" - "github.com/tikv/client-go/v2/txnkv/transaction" - "go.uber.org/zap" - "golang.org/x/exp/slices" -) - -func initTblColIdxID(metaInfo *model.TableInfo) { - for i, col := range metaInfo.Columns { - col.ID = int64(i + 1) - } - for i, idx := range metaInfo.Indices { - idx.ID = int64(i + 1) - if idx.Name.L == "f_g" { - idx.Unique = true - } else { - idx.Unique = false - } - } - metaInfo.ID = 1 - metaInfo.State = model.StatePublic -} - -func mutationsEqual(res *transaction.PlainMutations, expected *transaction.PlainMutations, t *testing.T) { - require.Len(t, res.GetKeys(), len(expected.GetKeys())) - for i := 0; i < len(res.GetKeys()); i++ { - foundIdx := -1 - for j := 0; j < len(expected.GetKeys()); j++ { - if bytes.Equal(res.GetKeys()[i], expected.GetKeys()[j]) { - foundIdx = j - break - } - } - require.GreaterOrEqual(t, foundIdx, 0) - require.Equal(t, expected.GetOps()[foundIdx], res.GetOps()[i]) - require.Equal(t, expected.IsPessimisticLock(foundIdx), res.IsPessimisticLock(i)) - require.Equal(t, expected.GetKeys()[foundIdx], res.GetKeys()[i]) - require.Equal(t, expected.GetValues()[foundIdx], res.GetValues()[i]) - } -} - -type data struct { - ops []kvrpcpb.Op - keys [][]byte - values [][]byte - rowValue [][]types.Datum -} - -// Generate exist old data and new data in transaction to be amended. Also generate the expected amend mutations -// according to the old and new data and the full generated expected mutations. -func prepareTestData( - se *session, - mutations *transaction.PlainMutations, - oldTblInfo table.Table, - newTblInfo table.Table, - expectedAmendOps []amendOp, - t *testing.T, -) (*data, transaction.PlainMutations) { - var err error - // Generated test data. - colIds := make([]int64, len(oldTblInfo.Meta().Columns)) - basicRowValue := make([]types.Datum, len(oldTblInfo.Meta().Columns)) - for i, col := range oldTblInfo.Meta().Columns { - colIds[i] = oldTblInfo.Meta().Columns[col.Offset].ID - if col.FieldType.GetType() == mysql.TypeLong { - basicRowValue[i] = types.NewIntDatum(int64(col.Offset)) - } else { - basicRowValue[i] = types.NewStringDatum(strconv.Itoa(col.Offset)) - } - } - KeyOps := []kvrpcpb.Op{kvrpcpb.Op_Put, kvrpcpb.Op_Del, kvrpcpb.Op_Lock, kvrpcpb.Op_Insert, kvrpcpb.Op_Put, - kvrpcpb.Op_Del, kvrpcpb.Op_Insert, kvrpcpb.Op_Lock} - numberOfRows := len(KeyOps) - oldRowValues := make([][]types.Datum, numberOfRows) - newRowValues := make([][]types.Datum, numberOfRows) - rd := rowcodec.Encoder{Enable: true} - oldData := &data{} - expectedMutations := transaction.NewPlainMutations(8) - oldRowKvMap := make(map[string][]types.Datum) - newRowKvMap := make(map[string][]types.Datum) - - // colIdx: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. - // column: a, b, c, d, e, c_str, d_str, e_str, f, g. - // Generate old data. - for i := 0; i < numberOfRows; i++ { - keyOp := KeyOps[i] - thisRowValue := make([]types.Datum, len(basicRowValue)) - copy(thisRowValue, basicRowValue) - thisRowValue[0] = types.NewIntDatum(int64(i + 1)) - thisRowValue[4] = types.NewIntDatum(int64(i + 1 + 4)) - // f_g has a unique index. - thisRowValue[8] = types.NewIntDatum(int64(i + 1 + 8)) - - // Save old data, they will be put into db first. - rowKey := tablecodec.EncodeRowKeyWithHandle(oldTblInfo.Meta().ID, kv.IntHandle(int64(i+1))) - var rowValue []byte - rowValue, err = rd.Encode(se.sessionVars.StmtCtx, colIds, thisRowValue, nil) - require.NoError(t, err) - if keyOp == kvrpcpb.Op_Del || keyOp == kvrpcpb.Op_Put || keyOp == kvrpcpb.Op_Lock { - // Skip the last Op_put, it has no old row value. - if i == 4 { - oldRowValues[i] = nil - continue - } - oldData.keys = append(oldData.keys, rowKey) - oldData.values = append(oldData.values, rowValue) - oldData.ops = append(oldData.ops, keyOp) - oldData.rowValue = append(oldData.rowValue, thisRowValue) - if keyOp == kvrpcpb.Op_Del { - mutations.Push(keyOp, rowKey, []byte{}, true, false, false, false) - } - } - oldRowValues[i] = thisRowValue - oldRowKvMap[string(rowKey)] = thisRowValue - } - - // Generate new data. - for i := 0; i < numberOfRows; i++ { - keyOp := KeyOps[i] - thisRowValue := make([]types.Datum, len(basicRowValue)) - copy(thisRowValue, basicRowValue) - thisRowValue[0] = types.NewIntDatum(int64(i + 1)) - // New column e value should be different from old row values. - thisRowValue[4] = types.NewIntDatum(int64(i+1+4) * 20) - // New column f value should be different since it has a related unique index. - thisRowValue[8] = types.NewIntDatum(int64(i+1+4) * 20) - - var rowValue []byte - // Save new data. - rowKey := tablecodec.EncodeRowKeyWithHandle(oldTblInfo.Meta().ID, kv.IntHandle(int64(i+1))) - if keyOp == kvrpcpb.Op_Insert { - rowValue, err = tablecodec.EncodeOldRow(se.sessionVars.StmtCtx, thisRowValue, colIds, nil, nil) - } else { - rowValue, err = rd.Encode(se.sessionVars.StmtCtx, colIds, thisRowValue, nil) - } - require.NoError(t, err) - if keyOp == kvrpcpb.Op_Put || keyOp == kvrpcpb.Op_Insert { - mutations.Push(keyOp, rowKey, rowValue, true, false, false, false) - } else if keyOp == kvrpcpb.Op_Lock { - mutations.Push(keyOp, rowKey, []byte{}, true, false, false, false) - } - newRowValues[i] = thisRowValue - newRowKvMap[string(rowKey)] = thisRowValue - } - - // Prepare expected result mutations. - for _, op := range expectedAmendOps { - var info *amendOperationAddIndexInfo - expectedOp, ok := op.(*amendOperationAddIndex) - require.True(t, ok) - info = expectedOp.info - var idxVal []byte - genIndexKV := func(inputRow []types.Datum) ([]byte, []byte) { - indexDatums := make([]types.Datum, len(info.relatedOldIdxCols)) - for colIdx, col := range info.relatedOldIdxCols { - indexDatums[colIdx] = inputRow[col.Offset] - } - kvHandle := kv.IntHandle(inputRow[0].GetInt64()) - idxKey, _, err := tablecodec.GenIndexKey(se.sessionVars.StmtCtx, newTblInfo.Meta(), - info.indexInfoAtCommit.Meta(), newTblInfo.Meta().ID, indexDatums, kvHandle, nil) - require.NoError(t, err) - idxVal, err = tablecodec.GenIndexValuePortal(se.sessionVars.StmtCtx, newTblInfo.Meta(), info.indexInfoAtCommit.Meta(), false, info.indexInfoAtCommit.Meta().Unique, false, indexDatums, kvHandle, 0, nil) - require.NoError(t, err) - return idxKey, idxVal - } - for i := 0; i < len(mutations.GetKeys()); i++ { - oldIdxKeyMutation := transaction.PlainMutations{} - newIdxKeyMutation := transaction.PlainMutations{} - key := mutations.GetKeys()[i] - keyOp := mutations.GetOps()[i] - if addIndexNeedRemoveOp(info.AmendOpType) && mayGenDelIndexRowKeyOp(keyOp) { - thisRowValue := oldRowKvMap[string(key)] - if len(thisRowValue) > 0 { - idxKey, _ := genIndexKV(thisRowValue) - isPessimisticLock := false - if info.indexInfoAtCommit.Meta().Unique { - isPessimisticLock = true - } - oldIdxKeyMutation.Push(kvrpcpb.Op_Del, idxKey, []byte{}, isPessimisticLock, false, false, false) - } - } - if addIndexNeedAddOp(info.AmendOpType) && mayGenPutIndexRowKeyOp(keyOp) { - thisRowValue := newRowKvMap[string(key)] - idxKey, idxVal := genIndexKV(thisRowValue) - mutOp := kvrpcpb.Op_Put - isPessimisticLock := false - if info.indexInfoAtCommit.Meta().Unique { - mutOp = kvrpcpb.Op_Insert - isPessimisticLock = true - } - newIdxKeyMutation.Push(mutOp, idxKey, idxVal, isPessimisticLock, false, false, false) - } - skipMerge := false - if info.AmendOpType == AmendNeedAddDeleteAndInsert { - if len(oldIdxKeyMutation.GetKeys()) > 0 && len(newIdxKeyMutation.GetKeys()) > 0 { - if bytes.Equal(oldIdxKeyMutation.GetKeys()[0], newIdxKeyMutation.GetKeys()[0]) { - skipMerge = true - } - } - } - if !skipMerge { - if len(oldIdxKeyMutation.GetKeys()) > 0 { - expectedMutations.MergeMutations(oldIdxKeyMutation) - } - if len(newIdxKeyMutation.GetKeys()) > 0 { - expectedMutations.MergeMutations(newIdxKeyMutation) - } - } - } - } - - return oldData, expectedMutations -} - -func TestAmendCollectAndGenMutations(t *testing.T) { - ctx := context.Background() - store, err := mockstore.NewMockStore() - require.NoError(t, err) - defer func() { require.NoError(t, store.Close()) }() - se := &session{ - store: store, - sessionVars: variable.NewSessionVars(nil), - } - se.mu.values = make(map[fmt.Stringer]interface{}) - domain.BindDomain(se, domain.NewMockDomain()) - startStates := []model.SchemaState{model.StateNone, model.StateDeleteOnly, model.StateWriteOnly, model.StateWriteReorganization} - for _, startState := range startStates { - endStatMap := ConstOpAddIndex[startState] - var endStates []model.SchemaState - for st := range endStatMap { - endStates = append(endStates, st) - } - slices.Sort(endStates) - for _, endState := range endStates { - logutil.BgLogger().Info("[TEST]>>>>>>new round test", zap.Stringer("start", startState), zap.Stringer("end", endState)) - // column: a, b, c, d, e, c_str, d_str, e_str, f, g. - // PK: a. - // indices: c_d_e, e, f, g, f_g, c_d_e_str, c_d_e_str_prefix. - oldTblMeta := core.MockSignedTable() - initTblColIdxID(oldTblMeta) - // Indices[0] does not exist at the start. - oldTblMeta.Indices = oldTblMeta.Indices[1:] - oldTbInfo, err := table.TableFromMeta(nil, oldTblMeta) - require.NoError(t, err) - oldTblMeta.Indices[0].State = startState - oldTblMeta.Indices[2].State = endState - oldTblMeta.Indices[3].State = startState - - newTblMeta := core.MockSignedTable() - initTblColIdxID(newTblMeta) - // colh is newly added. - colh := &model.ColumnInfo{ - State: model.StatePublic, - Offset: 12, - Name: model.NewCIStr("b"), - FieldType: *(types.NewFieldType(mysql.TypeLong)), - ID: 13, - } - newTblMeta.Columns = append(newTblMeta.Columns, colh) - // The last index "c_d_e_str_prefix is dropped. - newTblMeta.Indices = newTblMeta.Indices[:len(newTblMeta.Indices)-1] - newTblMeta.Indices[0].Unique = false - newTblInfo, err := table.TableFromMeta(nil, newTblMeta) - require.NoError(t, err) - newTblMeta.Indices[0].State = endState - // Indices[1] is newly created. - newTblMeta.Indices[1].State = endState - // Indices[3] is dropped - newTblMeta.Indices[3].State = startState - // Indices[4] is newly created unique index. - newTblMeta.Indices[4].State = endState - - // Only the add index amend operations is collected in the results. - collector := newAmendCollector() - tblID := int64(1) - err = collector.collectTblAmendOps(se, tblID, oldTbInfo, newTblInfo, 1< 0 { s.txn.SetOption(kv.KVFilter, temporaryTableKVFilter(tables)) } + s.txn.SetOption(kv.TxnSource, sessVars.CDCWriteSource) if tables := sessVars.TxnCtx.CachedTables; len(tables) > 0 { c := cachedTableRenewLease{tables: tables} now := time.Now() @@ -1255,10 +1270,10 @@ func (s *session) retry(ctx context.Context, maxCnt uint) (err error) { } s.txn.onStmtEnd() if err != nil { - s.StmtRollback() + s.StmtRollback(ctx, false) break } - s.StmtCommit() + s.StmtCommit(ctx) } logutil.Logger(ctx).Warn("transaction association", zap.Uint64("retrying txnStartTS", s.GetSessionVars().TxnCtx.StartTS), @@ -1340,6 +1355,10 @@ func createSessionFunc(store kv.Storage) pools.Factory { if err != nil { return nil, errors.Trace(err) } + err = se.sessionVars.SetSystemVar(variable.TiDBConstraintCheckInPlacePessimistic, variable.On) + if err != nil { + return nil, errors.Trace(err) + } se.sessionVars.CommonGlobalLoaded = true se.sessionVars.InRestrictedSQL = true // Internal session uses default format to prevent memory leak problem. @@ -1366,6 +1385,10 @@ func createSessionWithDomainFunc(store kv.Storage) func(*domain.Domain) (pools.R if err != nil { return nil, errors.Trace(err) } + err = se.sessionVars.SetSystemVar(variable.TiDBConstraintCheckInPlacePessimistic, variable.On) + if err != nil { + return nil, errors.Trace(err) + } se.sessionVars.CommonGlobalLoaded = true se.sessionVars.InRestrictedSQL = true // Internal session uses default format to prevent memory leak problem. @@ -1414,13 +1437,13 @@ func (s *session) getTableValue(ctx context.Context, tblName string, varName str // replaceGlobalVariablesTableValue executes restricted sql updates the variable value // It will then notify the etcd channel that the value has changed. -func (s *session) replaceGlobalVariablesTableValue(ctx context.Context, varName, val string) error { +func (s *session) replaceGlobalVariablesTableValue(ctx context.Context, varName, val string, updateLocal bool) error { ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnSysVar) _, _, err := s.ExecRestrictedSQL(ctx, nil, `REPLACE INTO %n.%n (variable_name, variable_value) VALUES (%?, %?)`, mysql.SystemDB, mysql.GlobalVariablesTable, varName, val) if err != nil { return err } - domain.GetDomain(s).NotifyUpdateSysVarCache() + domain.GetDomain(s).NotifyUpdateSysVarCache(updateLocal) return err } @@ -1465,7 +1488,7 @@ func (s *session) GetGlobalSysVar(name string) (string, error) { // SetGlobalSysVar implements GlobalVarAccessor.SetGlobalSysVar interface. // it is called (but skipped) when setting instance scope -func (s *session) SetGlobalSysVar(name, value string) (err error) { +func (s *session) SetGlobalSysVar(ctx context.Context, name string, value string) (err error) { sv := variable.GetSysVar(name) if sv == nil { return variable.ErrUnknownSystemVar.GenWithStackByArgs(name) @@ -1473,7 +1496,7 @@ func (s *session) SetGlobalSysVar(name, value string) (err error) { if value, err = sv.Validate(s.sessionVars, value, variable.ScopeGlobal); err != nil { return err } - if err = sv.SetGlobalFromHook(s.sessionVars, value, false); err != nil { + if err = sv.SetGlobalFromHook(ctx, s.sessionVars, value, false); err != nil { return err } if sv.HasInstanceScope() { // skip for INSTANCE scope @@ -1482,23 +1505,24 @@ func (s *session) SetGlobalSysVar(name, value string) (err error) { if sv.GlobalConfigName != "" { domain.GetDomain(s).NotifyGlobalConfigChange(sv.GlobalConfigName, variable.OnOffToTrueFalse(value)) } - return s.replaceGlobalVariablesTableValue(context.TODO(), sv.Name, value) + return s.replaceGlobalVariablesTableValue(context.TODO(), sv.Name, value, true) } // SetGlobalSysVarOnly updates the sysvar, but does not call the validation function or update aliases. // This is helpful to prevent duplicate warnings being appended from aliases, or recursion. -func (s *session) SetGlobalSysVarOnly(name, value string) (err error) { +// updateLocal indicates whether to rebuild the local SysVar Cache. This is helpful to prevent recursion. +func (s *session) SetGlobalSysVarOnly(ctx context.Context, name string, value string, updateLocal bool) (err error) { sv := variable.GetSysVar(name) if sv == nil { return variable.ErrUnknownSystemVar.GenWithStackByArgs(name) } - if err = sv.SetGlobalFromHook(s.sessionVars, value, true); err != nil { + if err = sv.SetGlobalFromHook(ctx, s.sessionVars, value, true); err != nil { return err } if sv.HasInstanceScope() { // skip for INSTANCE scope return nil } - return s.replaceGlobalVariablesTableValue(context.TODO(), sv.Name, value) + return s.replaceGlobalVariablesTableValue(ctx, sv.Name, value, updateLocal) } // SetTiDBTableValue implements GlobalVarAccessor.SetTiDBTableValue interface. @@ -1560,17 +1584,20 @@ func (s *session) SetProcessInfo(sql string, t time.Time, command byte, maxExecu Command: command, Plan: p, PlanExplainRows: plannercore.GetExplainRowsForPlan(p), - CurrentAnalyzeRows: s.getCurrentAnalyzePlan, RuntimeStatsColl: s.sessionVars.StmtCtx.RuntimeStatsColl, Time: t, State: s.Status(), Info: sql, CurTxnStartTS: curTxnStartTS, StmtCtx: s.sessionVars.StmtCtx, - OOMAlarmVariablesInfo: s.getOomAlarmVariablesInfo(), + RefCountOfStmtCtx: &s.sessionVars.RefCountOfStmtCtx, + MemTracker: s.sessionVars.MemTracker, + DiskTracker: s.sessionVars.DiskTracker, StatsInfo: plannercore.GetStatsInfo, + OOMAlarmVariablesInfo: s.getOomAlarmVariablesInfo(), MaxExecutionTime: maxExecutionTime, RedactSQL: s.sessionVars.EnableRedactLog, + ProtectedTSList: &s.sessionVars.ProtectedTSList, } oldPi := s.ShowProcess() if p == nil { @@ -1604,20 +1631,10 @@ func (s *session) getOomAlarmVariablesInfo() util.OOMAlarmVariablesInfo { return util.OOMAlarmVariablesInfo{ SessionAnalyzeVersion: s.sessionVars.AnalyzeVersion, SessionEnabledRateLimitAction: s.sessionVars.EnabledRateLimitAction, + SessionMemQuotaQuery: s.sessionVars.MemQuotaQuery, } } -func (s *session) getCurrentAnalyzePlan(p interface{}, runtimeStatsColl *execdetails.RuntimeStatsColl) [][]string { - explain := &plannercore.Explain{ - TargetPlan: p.(plannercore.Plan), - Format: types.ExplainFormatROW, - Analyze: false, - RuntimeStatsColl: runtimeStatsColl, - } - explain.SetSCtx(s) - return plannercore.GetExplainAnalyzeRowsForPlan(explain) -} - func (s *session) SetDiskFullOpt(level kvrpcpb.DiskFullOpt) { s.diskFullOpt = level } @@ -1796,10 +1813,11 @@ func (s *session) GetAdvisoryLock(lockName string, timeout int64) error { lock.IncrReferences() return nil } - sess, err := createSession(s.GetStore()) + sess, err := createSession(s.store) if err != nil { return err } + infosync.StoreInternalSession(sess) lock := &advisoryLock{session: sess, ctx: context.TODO()} err = lock.GetLock(lockName, timeout) if err != nil { @@ -1821,6 +1839,7 @@ func (s *session) ReleaseAdvisoryLock(lockName string) (released bool) { if lock.ReferenceCount() <= 0 { lock.Close() delete(s.advisoryLocks, lockName) + infosync.DeleteInternalSession(lock.session) } return true } @@ -1837,10 +1856,36 @@ func (s *session) ReleaseAllAdvisoryLocks() int { lock.Close() count += lock.ReferenceCount() delete(s.advisoryLocks, lockName) + infosync.DeleteInternalSession(lock.session) } return count } +// GetExtensions returns the `*extension.SessionExtensions` object +func (s *session) GetExtensions() *extension.SessionExtensions { + return s.extensions +} + +// SetExtensions sets the `*extension.SessionExtensions` object +func (s *session) SetExtensions(extensions *extension.SessionExtensions) { + s.extensions = extensions +} + +// InSandBoxMode indicates that this session is in sandbox mode +func (s *session) InSandBoxMode() bool { + return s.sandBoxMode +} + +// EnableSandBoxMode enable the sandbox mode. +func (s *session) EnableSandBoxMode() { + s.sandBoxMode = true +} + +// DisableSandBoxMode enable the sandbox mode. +func (s *session) DisableSandBoxMode() { + s.sandBoxMode = false +} + // ParseWithParams4Test wrapper (s *session) ParseWithParams for test func ParseWithParams4Test(ctx context.Context, s Session, sql string, args ...interface{}) (ast.StmtNode, error) { @@ -1941,6 +1986,7 @@ func (s *session) useCurrentSession(execOption sqlexec.ExecOption) (*session, fu s.sessionVars.StmtCtx.OriginalSQL = prevSQL s.sessionVars.StmtCtx.StmtType = prevStmtType s.sessionVars.StmtCtx.Tables = prevTables + s.sessionVars.MemTracker.Detach() }, nil } @@ -2002,6 +2048,7 @@ func (s *session) getInternalSession(execOption sqlexec.ExecOption) (*session, f se.sessionVars.PartitionPruneMode.Store(prePruneMode) se.sessionVars.OptimizerUseInvisibleIndexes = false se.sessionVars.InspectionTableCache = nil + se.sessionVars.MemTracker.Detach() s.sysSessionPool().Put(tmp) }, nil } @@ -2042,7 +2089,7 @@ func (s *session) ExecRestrictedSQL(ctx context.Context, opts []sqlexec.OptionFu metrics.SessionRestrictedSQLCounter.Inc() ctx = context.WithValue(ctx, execdetails.StmtExecDetailKey, &execdetails.StmtExecDetails{}) ctx = context.WithValue(ctx, tikvutil.ExecDetailsKey, &tikvutil.ExecDetails{}) - rs, err := se.ExecuteStmt(ctx, stmt) + rs, err := se.ExecuteInternalStmt(ctx, stmt) if err != nil { se.sessionVars.StmtCtx.AppendError(err) } @@ -2064,6 +2111,18 @@ func (s *session) ExecRestrictedSQL(ctx context.Context, opts []sqlexec.OptionFu }) } +// ExecuteInternalStmt execute internal stmt +func (s *session) ExecuteInternalStmt(ctx context.Context, stmtNode ast.StmtNode) (sqlexec.RecordSet, error) { + origin := s.sessionVars.InRestrictedSQL + s.sessionVars.InRestrictedSQL = true + defer func() { + s.sessionVars.InRestrictedSQL = origin + // Restore the goroutine label by using the original ctx after execution is finished. + pprof.SetGoroutineLabels(ctx) + }() + return s.ExecuteStmt(ctx, stmtNode) +} + func (s *session) ExecuteStmt(ctx context.Context, stmtNode ast.StmtNode) (sqlexec.RecordSet, error) { if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { span1 := span.Tracer().StartSpan("session.ExecuteStmt", opentracing.ChildOf(span.Context())) @@ -2079,7 +2138,8 @@ func (s *session) ExecuteStmt(ctx context.Context, stmtNode ast.StmtNode) (sqlex return nil, err } - s.sessionVars.StartTime = time.Now() + sessVars := s.sessionVars + sessVars.StartTime = time.Now() // Some executions are done in compile stage, so we reset them before compile. if err := executor.ResetContextOfStmt(s, stmtNode); err != nil { @@ -2118,10 +2178,6 @@ func (s *session) ExecuteStmt(ctx context.Context, stmtNode ast.StmtNode) (sqlex // Transform abstract syntax tree to a physical plan(stored in executor.ExecStmt). compiler := executor.Compiler{Ctx: s} stmt, err := compiler.Compile(ctx, stmtNode) - if err == nil { - err = sessiontxn.OptimizeWithPlanAndThenWarmUp(s, stmt.Plan) - } - if err != nil { s.rollbackOnError(ctx) @@ -2193,7 +2249,7 @@ func (s *session) onTxnManagerStmtStartOrRetry(ctx context.Context, node ast.Stm func (s *session) validateStatementReadOnlyInStaleness(stmtNode ast.StmtNode) error { vars := s.GetSessionVars() - if !vars.TxnCtx.IsStaleness && vars.TxnReadTS.PeakTxnReadTS() == 0 { + if !vars.TxnCtx.IsStaleness && vars.TxnReadTS.PeakTxnReadTS() == 0 && !vars.EnableExternalTSRead || vars.InRestrictedSQL { return nil } errMsg := "only support read-only statement during read-only staleness transactions" @@ -2301,7 +2357,7 @@ func runStmt(ctx context.Context, se *session, s sqlexec.Statement) (rs sqlexec. if rs != nil { if se.GetSessionVars().StmtCtx.IsExplainAnalyzeDML { if !sessVars.InTxn() { - se.StmtCommit() + se.StmtCommit(ctx) if err := se.CommitTxn(ctx); err != nil { return nil, err } @@ -2394,22 +2450,6 @@ func (s *session) rollbackOnError(ctx context.Context) { } } -// CacheGeneralStmt parses the sql, generates the corresponding PlanCacheStmt and cache it. -// The sql have to be parameterized, e.g. select * from t where a>?. -func (s *session) CacheGeneralStmt(sql string) (interface{}, error) { - if stmt := s.sessionVars.GetGeneralPlanCacheStmt(sql); stmt != nil { - // skip this step if there is already a PlanCacheStmt for this ql - return stmt, nil - } - - prepareExec := executor.NewPrepareExec(s, sql) - prepareExec.IsGeneralStmt = true - if err := prepareExec.Next(context.Background(), nil); err != nil { - return nil, err - } - return prepareExec.Stmt, nil -} - // PrepareStmt is used for executing prepare statement in binary protocol func (s *session) PrepareStmt(sql string) (stmtID uint32, paramCount int, fields []*ast.ResultField, err error) { if s.sessionVars.TxnCtx.InfoSchema == nil { @@ -2422,7 +2462,6 @@ func (s *session) PrepareStmt(sql string) (stmtID uint32, paramCount int, fields } ctx := context.Background() - inTxn := s.GetSessionVars().InTxn() // NewPrepareExec may need startTS to build the executor, for example prepare statement has subquery in int. // So we have to call PrepareTxnCtx here. if err = s.PrepareTxnCtx(ctx); err != nil { @@ -2439,13 +2478,12 @@ func (s *session) PrepareStmt(sql string) (stmtID uint32, paramCount int, fields } prepareExec := executor.NewPrepareExec(s, sql) err = prepareExec.Next(ctx, nil) + // Rollback even if err is nil. + s.rollbackOnError(ctx) + if err != nil { return } - if !inTxn { - // We could start a transaction to build the prepare executor before, we should rollback it here. - s.RollbackTxn(ctx) - } return prepareExec.ID, prepareExec.ParamCount, prepareExec.Fields, nil } @@ -2482,6 +2520,7 @@ func (s *session) Txn(active bool) (kv.Transaction, error) { return &s.txn, nil } _, err := sessiontxn.GetTxnManager(s).ActivateTxn() + s.SetMemoryFootprintChangeHook() return &s.txn, err } @@ -2542,6 +2581,9 @@ func (s *session) Close() { s.stmtStats.SetFinished() } s.ClearDiskFullOpt() + if s.preparedPlanCache != nil { + s.preparedPlanCache.Close() + } } // GetSessionVars implements the context.Context interface. @@ -2551,7 +2593,7 @@ func (s *session) GetSessionVars() *variable.SessionVars { func (s *session) AuthPluginForUser(user *auth.UserIdentity) (string, error) { pm := privilege.GetPrivilegeManager(s) - authplugin, err := pm.GetAuthPlugin(user.Username, user.Hostname) + authplugin, err := pm.GetAuthPluginForConnection(user.Username, user.Hostname) if err != nil { return "", err } @@ -2561,7 +2603,7 @@ func (s *session) AuthPluginForUser(user *auth.UserIdentity) (string, error) { // Auth validates a user using an authentication string and salt. // If the password fails, it will keep trying other users until exhausted. // This means it can not be refactored to use MatchIdentity yet. -func (s *session) Auth(user *auth.UserIdentity, authentication []byte, salt []byte) error { +func (s *session) Auth(user *auth.UserIdentity, authentication, salt []byte) error { hasPassword := "YES" if len(authentication) == 0 { hasPassword = "NO" @@ -2571,9 +2613,107 @@ func (s *session) Auth(user *auth.UserIdentity, authentication []byte, salt []by if err != nil { return privileges.ErrAccessDenied.FastGenByArgs(user.Username, user.Hostname, hasPassword) } - if err = pm.ConnectionVerification(user, authUser.Username, authUser.Hostname, authentication, salt, s.sessionVars.TLSConnectionState); err != nil { + // Check whether continuous login failure is enabled to lock the account. + // If enabled, determine whether to unlock the account and notify TiDB to update the cache. + enableAutoLock := pm.IsAccountAutoLockEnabled(authUser.Username, authUser.Hostname) + if enableAutoLock { + err = failedLoginTrackingBegin(s) + if err != nil { + return err + } + lockStatusChanged, err := verifyAccountAutoLock(s, authUser.Username, authUser.Hostname) + if err != nil { + rollbackErr := failedLoginTrackingRollback(s) + if rollbackErr != nil { + return rollbackErr + } + return err + } + err = failedLoginTrackingCommit(s) + if err != nil { + rollbackErr := failedLoginTrackingRollback(s) + if rollbackErr != nil { + return rollbackErr + } + return err + } + if lockStatusChanged { + // Notification auto unlock. + err = domain.GetDomain(s).NotifyUpdatePrivilege() + if err != nil { + return err + } + } + } + + info, err := pm.ConnectionVerification(user, authUser.Username, authUser.Hostname, authentication, salt, s.sessionVars) + if err != nil { + if info.FailedDueToWrongPassword { + // when user enables the account locking function for consecutive login failures, + // the system updates the login failure count and determines whether to lock the account when authentication fails. + if enableAutoLock { + err := failedLoginTrackingBegin(s) + if err != nil { + return err + } + lockStatusChanged, passwordLocking, trackingErr := authFailedTracking(s, authUser.Username, authUser.Hostname) + if trackingErr != nil { + if rollBackErr := failedLoginTrackingRollback(s); rollBackErr != nil { + return rollBackErr + } + return trackingErr + } + if err := failedLoginTrackingCommit(s); err != nil { + if rollBackErr := failedLoginTrackingRollback(s); rollBackErr != nil { + return rollBackErr + } + return err + } + if lockStatusChanged { + // Notification auto lock. + err := autolockAction(s, passwordLocking, authUser.Username, authUser.Hostname) + if err != nil { + return err + } + } + } + } return err } + + // If tidb_resource_control_enable is disabled, set resource group to empty + if variable.EnableResourceControl.Load() { + s.sessionVars.ResourceGroupName = strings.ToLower(info.ResourceGroupName) + } else { + s.sessionVars.ResourceGroupName = "" + } + + if info.InSandBoxMode { + // Enter sandbox mode, only execute statement for resetting password. + s.EnableSandBoxMode() + } + if enableAutoLock { + err := failedLoginTrackingBegin(s) + if err != nil { + return err + } + // The password is correct. If the account is not locked, the number of login failure statistics will be cleared. + err = authSuccessClearCount(s, authUser.Username, authUser.Hostname) + if err != nil { + if rollBackErr := failedLoginTrackingRollback(s); rollBackErr != nil { + return rollBackErr + } + return err + } + err = failedLoginTrackingCommit(s) + if err != nil { + if rollBackErr := failedLoginTrackingRollback(s); rollBackErr != nil { + return rollBackErr + } + return err + } + } + pm.AuthSuccess(authUser.Username, authUser.Hostname) user.AuthUsername = authUser.Username user.AuthHostname = authUser.Hostname s.sessionVars.User = user @@ -2581,6 +2721,217 @@ func (s *session) Auth(user *auth.UserIdentity, authentication []byte, salt []by return nil } +func authSuccessClearCount(s *session, user string, host string) error { + // Obtain accurate lock status and failure count information. + passwordLocking, err := getFailedLoginUserAttributes(s, user, host) + if err != nil { + return err + } + // If the account is locked, it may be caused by the untimely update of the cache, + // directly report the account lock. + if passwordLocking.AutoAccountLocked { + if passwordLocking.PasswordLockTimeDays == -1 { + return privileges.GenerateAccountAutoLockErr(passwordLocking.FailedLoginAttempts, user, host, + "unlimited", "unlimited") + } + + lds := strconv.FormatInt(passwordLocking.PasswordLockTimeDays, 10) + return privileges.GenerateAccountAutoLockErr(passwordLocking.FailedLoginAttempts, user, host, lds, lds) + } + if passwordLocking.FailedLoginCount != 0 { + // If the number of account login failures is not zero, it will be updated to 0. + passwordLockingJSON := privileges.BuildSuccessPasswordLockingJSON(passwordLocking.FailedLoginAttempts, + passwordLocking.PasswordLockTimeDays) + if passwordLockingJSON != "" { + if err := s.passwordLocking(user, host, passwordLockingJSON); err != nil { + return err + } + } + } + return nil +} + +func verifyAccountAutoLock(s *session, user, host string) (bool, error) { + pm := privilege.GetPrivilegeManager(s) + // Use the cache to determine whether to unlock the account. + // If the account needs to be unlocked, read the database information to determine whether + // the account needs to be unlocked. Otherwise, an error message is displayed. + lockStatusInMemory, err := pm.VerifyAccountAutoLockInMemory(user, host) + if err != nil { + return false, err + } + // If the lock status in the cache is Unlock, the automatic unlock is skipped. + // If memory synchronization is slow and there is a lock in the database, it will be processed upon successful login. + if !lockStatusInMemory { + return false, nil + } + lockStatusChanged := false + var plJSON string + // After checking the cache, obtain the latest data from the database and determine + // whether to automatically unlock the database to prevent repeated unlock errors. + pl, err := getFailedLoginUserAttributes(s, user, host) + if err != nil { + return false, err + } + if pl.AutoAccountLocked { + // If it is locked, need to check whether it can be automatically unlocked. + lockTimeDay := pl.PasswordLockTimeDays + if lockTimeDay == -1 { + return false, privileges.GenerateAccountAutoLockErr(pl.FailedLoginAttempts, user, host, "unlimited", "unlimited") + } + lastChanged := pl.AutoLockedLastChanged + d := time.Now().Unix() - lastChanged + if d > lockTimeDay*24*60*60 { + // Generate unlock json string. + plJSON = privileges.BuildPasswordLockingJSON(pl.FailedLoginAttempts, + pl.PasswordLockTimeDays, "N", 0, time.Now().Format(time.UnixDate)) + } else { + lds := strconv.FormatInt(lockTimeDay, 10) + rds := strconv.FormatInt(int64(math.Ceil(float64(lockTimeDay)-float64(d)/(24*60*60))), 10) + return false, privileges.GenerateAccountAutoLockErr(pl.FailedLoginAttempts, user, host, lds, rds) + } + } + if plJSON != "" { + lockStatusChanged = true + if err = s.passwordLocking(user, host, plJSON); err != nil { + return false, err + } + } + return lockStatusChanged, nil +} + +func authFailedTracking(s *session, user string, host string) (bool, *privileges.PasswordLocking, error) { + // Obtain the number of consecutive password login failures. + passwordLocking, err := getFailedLoginUserAttributes(s, user, host) + if err != nil { + return false, nil, err + } + // Consecutive wrong password login failure times +1, + // If the lock condition is satisfied, the lock status is updated and the update cache is notified. + lockStatusChanged, err := userAutoAccountLocked(s, user, host, passwordLocking) + if err != nil { + return false, nil, err + } + return lockStatusChanged, passwordLocking, nil +} + +func autolockAction(s *session, passwordLocking *privileges.PasswordLocking, user, host string) error { + // Don't want to update the cache frequently, and only trigger the update cache when the lock status is updated. + err := domain.GetDomain(s).NotifyUpdatePrivilege() + if err != nil { + return err + } + // The number of failed login attempts reaches FAILED_LOGIN_ATTEMPTS. + // An error message is displayed indicating permission denial and account lock. + if passwordLocking.PasswordLockTimeDays == -1 { + return privileges.GenerateAccountAutoLockErr(passwordLocking.FailedLoginAttempts, user, host, + "unlimited", "unlimited") + } + lds := strconv.FormatInt(passwordLocking.PasswordLockTimeDays, 10) + return privileges.GenerateAccountAutoLockErr(passwordLocking.FailedLoginAttempts, user, host, lds, lds) +} + +func (s *session) passwordLocking(user string, host string, newAttributesStr string) error { + sql := new(strings.Builder) + sqlexec.MustFormatSQL(sql, "UPDATE %n.%n SET ", mysql.SystemDB, mysql.UserTable) + sqlexec.MustFormatSQL(sql, "user_attributes=json_merge_patch(coalesce(user_attributes, '{}'), %?)", newAttributesStr) + sqlexec.MustFormatSQL(sql, " WHERE Host=%? and User=%?;", host, user) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) + _, err := s.ExecuteInternal(ctx, sql.String()) + return err +} + +func failedLoginTrackingBegin(s *session) error { + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) + _, err := s.ExecuteInternal(ctx, "BEGIN PESSIMISTIC") + return err +} + +func failedLoginTrackingCommit(s *session) error { + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) + _, err := s.ExecuteInternal(ctx, "COMMIT") + if err != nil { + _, rollBackErr := s.ExecuteInternal(ctx, "ROLLBACK") + if rollBackErr != nil { + return rollBackErr + } + } + return err +} + +func failedLoginTrackingRollback(s *session) error { + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) + _, err := s.ExecuteInternal(ctx, "ROLLBACK") + return err +} + +// getFailedLoginUserAttributes queries the exact number of consecutive password login failures (concurrency is not allowed). +func getFailedLoginUserAttributes(s *session, user string, host string) (*privileges.PasswordLocking, error) { + passwordLocking := &privileges.PasswordLocking{} + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnPrivilege) + rs, err := s.ExecuteInternal(ctx, `SELECT user_attributes from mysql.user WHERE USER = %? AND HOST = %? for update`, user, host) + if err != nil { + return passwordLocking, err + } + defer func() { + if closeErr := rs.Close(); closeErr != nil { + err = closeErr + } + }() + req := rs.NewChunk(nil) + iter := chunk.NewIterator4Chunk(req) + err = rs.Next(ctx, req) + if err != nil { + return passwordLocking, err + } + if req.NumRows() == 0 { + return passwordLocking, fmt.Errorf("user_attributes by `%s`@`%s` not found", user, host) + } + row := iter.Begin() + if !row.IsNull(0) { + passwordLockingJSON := row.GetJSON(0) + return passwordLocking, passwordLocking.ParseJSON(passwordLockingJSON) + } + return passwordLocking, fmt.Errorf("user_attributes by `%s`@`%s` not found", user, host) +} + +func userAutoAccountLocked(s *session, user string, host string, pl *privileges.PasswordLocking) (bool, error) { + // Indicates whether the user needs to update the lock status change. + lockStatusChanged := false + // The number of consecutive login failures is stored in the database. + // If the current login fails, one is added to the number of consecutive login failures + // stored in the database to determine whether the user needs to be locked and the number of update failures. + failedLoginCount := pl.FailedLoginCount + 1 + // If the cache is not updated, but it is already locked, it will report that the account is locked. + if pl.AutoAccountLocked { + if pl.PasswordLockTimeDays == -1 { + return false, privileges.GenerateAccountAutoLockErr(pl.FailedLoginAttempts, user, host, + "unlimited", "unlimited") + } + lds := strconv.FormatInt(pl.PasswordLockTimeDays, 10) + return false, privileges.GenerateAccountAutoLockErr(pl.FailedLoginAttempts, user, host, lds, lds) + } + + autoAccountLocked := "N" + autoLockedLastChanged := "" + if pl.FailedLoginAttempts == 0 || pl.PasswordLockTimeDays == 0 { + return false, nil + } + + if failedLoginCount >= pl.FailedLoginAttempts { + autoLockedLastChanged = time.Now().Format(time.UnixDate) + autoAccountLocked = "Y" + lockStatusChanged = true + } + + newAttributesStr := privileges.BuildPasswordLockingJSON(pl.FailedLoginAttempts, + pl.PasswordLockTimeDays, autoAccountLocked, failedLoginCount, autoLockedLastChanged) + if newAttributesStr != "" { + return lockStatusChanged, s.passwordLocking(user, host, newAttributesStr) + } + return lockStatusChanged, nil +} + // MatchIdentity finds the matching username + password in the MySQL privilege tables // for a username + hostname, since MySQL can have wildcards. func (s *session) MatchIdentity(username, remoteHost string) (*auth.UserIdentity, error) { @@ -2684,9 +3035,11 @@ func CreateSessionWithOpt(store kv.Storage, opt *Opt) (Session, error) { if err != nil { return nil, err } - pm := &privileges.UserPrivileges{ - Handle: do.PrivilegeHandle(), + extensions, err := extension.GetExtensions() + if err != nil { + return nil, err } + pm := privileges.NewUserPrivileges(do.PrivilegeHandle(), extensions) privilege.BindPrivilegeManager(s, pm) // Add stats collector, and it will be freed by background stats worker @@ -2718,61 +3071,103 @@ func loadCollationParameter(ctx context.Context, se *session) (bool, error) { return false, nil } +type tableBasicInfo struct { + SQL string + id int64 +} + var ( errResultIsEmpty = dbterror.ClassExecutor.NewStd(errno.ErrResultIsEmpty) // DDLJobTables is a list of tables definitions used in concurrent DDL. - DDLJobTables = []struct { - SQL string - id int64 - }{ + DDLJobTables = []tableBasicInfo{ {ddl.JobTableSQL, ddl.JobTableID}, {ddl.ReorgTableSQL, ddl.ReorgTableID}, {ddl.HistoryTableSQL, ddl.HistoryTableID}, } + // BackfillTables is a list of tables definitions used in dist reorg DDL. + BackfillTables = []tableBasicInfo{ + {ddl.BackfillTableSQL, ddl.BackfillTableID}, + {ddl.BackfillHistoryTableSQL, ddl.BackfillHistoryTableID}, + } mdlTable = "create table mysql.tidb_mdl_info(job_id BIGINT NOT NULL PRIMARY KEY, version BIGINT NOT NULL, table_ids text(65535));" ) -// InitDDLJobTables is to create tidb_ddl_job, tidb_ddl_reorg and tidb_ddl_history. +func splitAndScatterTable(store kv.Storage, tableIDs []int64) { + if s, ok := store.(kv.SplittableStore); ok && atomic.LoadUint32(&ddl.EnableSplitTableRegion) == 1 { + ctxWithTimeout, cancel := context.WithTimeout(context.Background(), variable.DefWaitSplitRegionTimeout*time.Second) + var regionIDs []uint64 + for _, id := range tableIDs { + regionIDs = append(regionIDs, ddl.SplitRecordRegion(ctxWithTimeout, s, id, variable.DefTiDBScatterRegion)) + } + if variable.DefTiDBScatterRegion { + ddl.WaitScatterRegionFinish(ctxWithTimeout, s, regionIDs...) + } + cancel() + } +} + +// InitDDLJobTables is to create tidb_ddl_job, tidb_ddl_reorg, tidb_ddl_history, tidb_ddl_backfill and tidb_ddl_backfill_history. func InitDDLJobTables(store kv.Storage) error { return kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, true, func(ctx context.Context, txn kv.Transaction) error { t := meta.NewMeta(txn) exists, err := t.CheckDDLTableExists() - if err != nil || exists { + if err != nil { return errors.Trace(err) } dbID, err := t.CreateMySQLDatabaseIfNotExists() if err != nil { return err } - p := parser.New() - for _, tbl := range DDLJobTables { - id, err := t.GetGlobalID() - if err != nil { - return errors.Trace(err) - } - if id >= meta.MaxGlobalID { - return errors.Errorf("It is unreasonable that the global ID grows such a big value: %d, please contact TiDB team", id) - } - stmt, err := p.ParseOneStmt(tbl.SQL, "", "") - if err != nil { - return errors.Trace(err) - } - tblInfo, err := ddl.BuildTableInfoFromAST(stmt.(*ast.CreateTableStmt)) - if err != nil { - return errors.Trace(err) - } - tblInfo.State = model.StatePublic - tblInfo.ID = tbl.id - tblInfo.UpdateTS = t.StartTS - err = t.CreateTableOrView(dbID, tblInfo) - if err != nil { - return errors.Trace(err) - } + if exists { + return initBackfillJobTables(store, t, dbID) + } + + if err = createAndSplitTables(store, t, dbID, DDLJobTables); err != nil { + return err + } + if err = initBackfillJobTables(store, t, dbID); err != nil { + return err } return t.SetDDLTables() }) } +// initBackfillJobTables is to create tidb_ddl_backfill and tidb_ddl_backfill_history. +func initBackfillJobTables(store kv.Storage, t *meta.Meta, dbID int64) error { + tblExist, err := t.CheckTableExists(dbID, BackfillTables[0].id) + if err != nil || tblExist { + return errors.Trace(err) + } + return createAndSplitTables(store, t, dbID, BackfillTables) +} + +func createAndSplitTables(store kv.Storage, t *meta.Meta, dbID int64, tables []tableBasicInfo) error { + tableIDs := make([]int64, 0, len(tables)) + for _, tbl := range tables { + tableIDs = append(tableIDs, tbl.id) + } + splitAndScatterTable(store, tableIDs) + p := parser.New() + for _, tbl := range tables { + stmt, err := p.ParseOneStmt(tbl.SQL, "", "") + if err != nil { + return errors.Trace(err) + } + tblInfo, err := ddl.BuildTableInfoFromAST(stmt.(*ast.CreateTableStmt)) + if err != nil { + return errors.Trace(err) + } + tblInfo.State = model.StatePublic + tblInfo.ID = tbl.id + tblInfo.UpdateTS = t.StartTS + err = t.CreateTableOrView(dbID, tblInfo) + if err != nil { + return errors.Trace(err) + } + } + return nil +} + // InitMDLTable is to create tidb_mdl_info, which is used for metadata lock. func InitMDLTable(store kv.Storage) error { return kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, true, func(ctx context.Context, txn kv.Transaction) error { @@ -2785,14 +3180,8 @@ func InitMDLTable(store kv.Storage) error { if err != nil { return err } + splitAndScatterTable(store, []int64{ddl.MDLTableID}) p := parser.New() - id, err := t.GetGlobalID() - if err != nil { - return errors.Trace(err) - } - if id >= meta.MaxGlobalID { - return errors.Errorf("It is unreasonable that the global ID grows such a big value: %d, please contact TiDB team", id) - } stmt, err := p.ParseOneStmt(mdlTable, "", "") if err != nil { return errors.Trace(err) @@ -2813,6 +3202,66 @@ func InitMDLTable(store kv.Storage) error { }) } +// InitMDLVariableForBootstrap initializes the metadata lock variable. +func InitMDLVariableForBootstrap(store kv.Storage) error { + err := kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, true, func(ctx context.Context, txn kv.Transaction) error { + t := meta.NewMeta(txn) + return t.SetMetadataLock(true) + }) + if err != nil { + return err + } + variable.EnableMDL.Store(true) + return nil +} + +// InitMDLVariableForUpgrade initializes the metadata lock variable. +func InitMDLVariableForUpgrade(store kv.Storage) (bool, error) { + isNull := false + enable := false + var err error + err = kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, true, func(ctx context.Context, txn kv.Transaction) error { + t := meta.NewMeta(txn) + enable, isNull, err = t.GetMetadataLock() + if err != nil { + return err + } + return nil + }) + if isNull || !enable { + variable.EnableMDL.Store(false) + } else { + variable.EnableMDL.Store(true) + } + return isNull, err +} + +// InitMDLVariable initializes the metadata lock variable. +func InitMDLVariable(store kv.Storage) error { + isNull := false + enable := false + var err error + err = kv.RunInNewTxn(kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL), store, true, func(ctx context.Context, txn kv.Transaction) error { + t := meta.NewMeta(txn) + enable, isNull, err = t.GetMetadataLock() + if err != nil { + return err + } + if isNull { + // Workaround for version: nightly-2022-11-07 to nightly-2022-11-17. + enable = true + logutil.BgLogger().Warn("metadata lock is null") + err = t.SetMetadataLock(true) + if err != nil { + return err + } + } + return nil + }) + variable.EnableMDL.Store(enable) + return err +} + // BootstrapSession runs the first time when the TiDB server start. func BootstrapSession(store kv.Storage) (*domain.Domain, error) { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap) @@ -2839,10 +3288,16 @@ func BootstrapSession(store kv.Storage) (*domain.Domain, error) { runInBootstrapSession(store, bootstrap) } else if ver < currentBootstrapVersion { runInBootstrapSession(store, upgrade) + } else { + err = InitMDLVariable(store) + if err != nil { + return nil, err + } } + analyzeConcurrencyQuota := int(config.GetGlobalConfig().Performance.AnalyzePartitionConcurrencyQuota) concurrency := int(config.GetGlobalConfig().Performance.StatsLoadConcurrency) - ses, err := createSessions(store, 7+concurrency) + ses, err := createSessions(store, 10) if err != nil { return nil, err } @@ -2887,6 +3342,18 @@ func BootstrapSession(store kv.Storage) (*domain.Domain, error) { return nil, err } + if config.GetGlobalConfig().DisaggregatedTiFlash { + // Invalid client-go tiflash_compute store cache if necessary. + err = dom.WatchTiFlashComputeNodeChange() + if err != nil { + return nil, err + } + } + + if err = extensionimpl.Bootstrap(context.Background(), dom); err != nil { + return nil, err + } + if len(cfg.Instance.PluginLoad) > 0 { err := plugin.Init(context.Background(), plugin.Config{EtcdClient: dom.GetEtcdClient()}) if err != nil { @@ -2906,24 +3373,85 @@ func BootstrapSession(store kv.Storage) (*domain.Domain, error) { if dom.GetEtcdClient() != nil { // We only want telemetry data in production-like clusters. When TiDB is deployed over other engines, // for example, unistore engine (used for local tests), we just skip it. Its etcd client is nil. - go func() { - dom.TelemetryReportLoop(ses[5]) - dom.TelemetryRotateSubWindowLoop(ses[5]) - }() + if config.GetGlobalConfig().EnableTelemetry { + // There is no way to turn telemetry on with global variable `tidb_enable_telemetry` + // when it is disabled in config. See IsTelemetryEnabled function in telemetry/telemetry.go + go func() { + dom.TelemetryReportLoop(ses[5]) + dom.TelemetryRotateSubWindowLoop(ses[5]) + }() + } } + planReplayerWorkerCnt := config.GetGlobalConfig().Performance.PlanReplayerDumpWorkerConcurrency + planReplayerWorkersSctx := make([]sessionctx.Context, planReplayerWorkerCnt) + pworkerSes, err := createSessions(store, int(planReplayerWorkerCnt)) + if err != nil { + return nil, err + } + for i := 0; i < int(planReplayerWorkerCnt); i++ { + planReplayerWorkersSctx[i] = pworkerSes[i] + } + // setup plan replayer handle + dom.SetupPlanReplayerHandle(ses[6], planReplayerWorkersSctx) + dom.StartPlanReplayerHandle() + // setup dumpFileGcChecker + dom.SetupDumpFileGCChecker(ses[7]) + dom.DumpFileGcCheckerLoop() + // setup historical stats worker + dom.SetupHistoricalStatsWorker(ses[8]) + dom.StartHistoricalStatsWorker() + if runBootstrapSQLFile { + pm := &privileges.UserPrivileges{ + Handle: dom.PrivilegeHandle(), + } + privilege.BindPrivilegeManager(ses[9], pm) + doBootstrapSQLFile(ses[9]) + } // A sub context for update table stats, and other contexts for concurrent stats loading. cnt := 1 + concurrency + syncStatsCtxs, err := createSessions(store, cnt) + if err != nil { + return nil, err + } subCtxs := make([]sessionctx.Context, cnt) for i := 0; i < cnt; i++ { - subCtxs[i] = sessionctx.Context(ses[6+i]) + subCtxs[i] = sessionctx.Context(syncStatsCtxs[i]) + } + initStatsCtx, err := createSession(store) + if err != nil { + return nil, err } - if err = dom.LoadAndUpdateStatsLoop(subCtxs); err != nil { + if err = dom.LoadAndUpdateStatsLoop(subCtxs, initStatsCtx); err != nil { return nil, err } - dom.DumpFileGcCheckerLoop() - dom.LoadSigningCertLoop() + // start TTL job manager after setup stats collector + // because TTL could modify a lot of columns, and need to trigger auto analyze + ttlworker.AttachStatsCollector = func(s sqlexec.SQLExecutor) sqlexec.SQLExecutor { + if s, ok := s.(*session); ok { + return attachStatsCollector(s, dom) + } + return s + } + ttlworker.DetachStatsCollector = func(s sqlexec.SQLExecutor) sqlexec.SQLExecutor { + if s, ok := s.(*session); ok { + return detachStatsCollector(s) + } + return s + } + dom.StartTTLJobManager() + + analyzeCtxs, err := createSessions(store, analyzeConcurrencyQuota) + if err != nil { + return nil, err + } + subCtxs2 := make([]sessionctx.Context, analyzeConcurrencyQuota) + for i := 0; i < analyzeConcurrencyQuota; i++ { + subCtxs2[i] = analyzeCtxs[i] + } + dom.SetupAnalyzeExec(subCtxs2) + dom.LoadSigningCertLoop(cfg.Security.SessionTokenSigningCert, cfg.Security.SessionTokenSigningKey) if raw, ok := store.(kv.EtcdBackend); ok { err = raw.StartGCWorker() @@ -2976,6 +3504,10 @@ func createSessions(store kv.Storage, cnt int) ([]*session, error) { return ses, nil } +// createSession creates a new session. +// Please note that such a session is not tracked by the internal session list. +// This means the min ts reporter is not aware of it and may report a wrong min start ts. +// In most cases you should use a session pool in domain instead. func createSession(store kv.Storage) (*session, error) { return createSessionWithOpt(store, nil) } @@ -3009,12 +3541,32 @@ func createSessionWithOpt(store kv.Storage, opt *Opt) (*session, error) { s.sessionVars.BinlogClient = binloginfo.GetPumpsClient() s.txn.init() - sessionBindHandle := bindinfo.NewSessionBindHandle(parser.New()) + sessionBindHandle := bindinfo.NewSessionBindHandle() s.SetValue(bindinfo.SessionBindInfoKeyType, sessionBindHandle) s.SetSessionStatesHandler(sessionstates.StateBinding, sessionBindHandle) return s, nil } +// attachStatsCollector attaches the stats collector in the dom for the session +func attachStatsCollector(s *session, dom *domain.Domain) *session { + if dom.StatsHandle() != nil && dom.StatsUpdating() { + s.statsCollector = dom.StatsHandle().NewSessionStatsCollector() + if GetIndexUsageSyncLease() > 0 { + s.idxUsageCollector = dom.StatsHandle().NewSessionIndexUsageCollector() + } + } + + return s +} + +// detachStatsCollector removes the stats collector in the session +func detachStatsCollector(s *session) *session { + s.statsCollector = nil + s.idxUsageCollector = nil + + return s +} + // CreateSessionWithDomain creates a new Session and binds it with a Domain. // We need this because when we start DDL in Domain, the DDL need a session // to change some system tables. But at that time, we have been already in @@ -3424,7 +3976,8 @@ func (s *session) GetInfoSchema() sessionctx.InfoschemaMetaVersion { func (s *session) GetDomainInfoSchema() sessionctx.InfoschemaMetaVersion { is := domain.GetDomain(s).InfoSchema() - return temptable.AttachLocalTemporaryTableInfoSchema(s, is) + extIs := &infoschema.SessionExtendedInfoSchema{InfoSchema: is} + return temptable.AttachLocalTemporaryTableInfoSchema(s, extIs) } func getSnapshotInfoSchema(s sessionctx.Context, snapshotTS uint64) (infoschema.InfoSchema, error) { @@ -3454,11 +4007,19 @@ func (s *session) updateTelemetryMetric(es *executor.ExecStmt) { telemetryCTEUsageNotCTE.Inc() } + if ti.UseIndexMerge { + telemetryIndexMerge.Inc() + } + if ti.UseMultiSchemaChange { telemetryMultiSchemaChangeUsage.Inc() } - if ti.UesExchangePartition { + if ti.UseFlashbackToCluster { + telemetryFlashbackClusterUsage.Inc() + } + + if ti.UseExchangePartition { telemetryExchangePartitionUsage.Inc() } @@ -3500,6 +4061,12 @@ func (s *session) updateTelemetryMetric(es *executor.ExecStmt) { if ti.PartitionTelemetry.UseDropIntervalPartition { telemetryTablePartitionDropIntervalUsage.Inc() } + if ti.PartitionTelemetry.UseCompactTablePartition { + telemetryTableCompactPartitionUsage.Inc() + } + if ti.PartitionTelemetry.UseReorganizePartition { + telemetryReorganizePartitionUsage.Inc() + } } if ti.AccountLockTelemetry != nil { @@ -3531,6 +4098,25 @@ func (s *session) GetStmtStats() *stmtstats.StatementStats { return s.stmtStats } +// SetMemoryFootprintChangeHook sets the hook that is called when the memdb changes its size. +// Call this after s.txn becomes valid, since TxnInfo is initialized when the txn becomes valid. +func (s *session) SetMemoryFootprintChangeHook() { + if config.GetGlobalConfig().Performance.TxnTotalSizeLimit != config.DefTxnTotalSizeLimit { + // if the user manually specifies the config, don't involve the new memory tracker mechanism, let the old config + // work as before. + return + } + hook := func(mem uint64) { + if s.sessionVars.MemDBFootprint == nil { + tracker := memory.NewTracker(memory.LabelForMemDB, -1) + tracker.AttachTo(s.sessionVars.MemTracker) + s.sessionVars.MemDBFootprint = tracker + } + s.sessionVars.MemDBFootprint.ReplaceBytesUsed(int64(mem)) + } + s.txn.SetMemoryFootprintChangeHook(hook) +} + // EncodeSessionStates implements SessionStatesHandler.EncodeSessionStates interface. func (s *session) EncodeSessionStates(ctx context.Context, sctx sessionctx.Context, sessionStates *sessionstates.SessionStates) error { // Transaction status is hard to encode, so we do not support it. @@ -3556,6 +4142,10 @@ func (s *session) EncodeSessionStates(ctx context.Context, sctx sessionctx.Conte if len(s.lockedTables) > 0 { return sessionstates.ErrCannotMigrateSession.GenWithStackByArgs("session has locked tables") } + // It's insecure to migrate sandBoxMode because users can fake it. + if s.InSandBoxMode() { + return sessionstates.ErrCannotMigrateSession.GenWithStackByArgs("session is in sandbox mode") + } if err := s.sessionVars.EncodeSessionStates(ctx, sessionStates); err != nil { return err @@ -3622,23 +4212,26 @@ func (s *session) setRequestSource(ctx context.Context, stmtLabel string, stmtNo } else { s.sessionVars.RequestSourceType = stmtLabel } - } else { - if source := ctx.Value(kv.RequestSourceKey); source != nil { - s.sessionVars.RequestSourceType = source.(kv.RequestSource).RequestSourceType - } else { - // panic in test mode in case there are requests without source in the future. - // log warnings in production mode. - if flag.Lookup("test.v") != nil || flag.Lookup("check.v") != nil { - panic("unexpected no source type context, if you see this error, " + - "the `RequestSourceTypeKey` is missing in your context") - } else { - logutil.Logger(ctx).Warn("unexpected no source type context, if you see this warning, "+ - "the `RequestSourceTypeKey` is missing in the context", - zap.Bool("internal", s.isInternal()), - zap.String("sql", stmtNode.Text())) - } + return + } + if source := ctx.Value(kv.RequestSourceKey); source != nil { + requestSource := source.(kv.RequestSource) + if requestSource.RequestSourceType != "" { + s.sessionVars.RequestSourceType = requestSource.RequestSourceType + return } } + // panic in test mode in case there are requests without source in the future. + // log warnings in production mode. + if flag.Lookup("test.v") != nil || flag.Lookup("check.v") != nil { + panic("unexpected no source type context, if you see this error, " + + "the `RequestSourceTypeKey` is missing in your context") + } else { + logutil.Logger(ctx).Warn("unexpected no source type context, if you see this warning, "+ + "the `RequestSourceTypeKey` is missing in the context", + zap.Bool("internal", s.isInternal()), + zap.String("sql", stmtNode.Text())) + } } // RemoveLockDDLJobs removes the DDL jobs which doesn't get the metadata lock from job2ver. diff --git a/session/session_test.go b/session/session_test.go index 825cdf79c0139..530aee66d4ead 100644 --- a/session/session_test.go +++ b/session/session_test.go @@ -15,10 +15,14 @@ package session_test import ( + "fmt" "reflect" + "sync/atomic" "testing" + "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/external" "github.com/stretchr/testify/require" @@ -51,3 +55,31 @@ func TestInitMetaTable(t *testing.T) { require.True(t, reflect.DeepEqual(metaInMySQL, metaInTest)) } } + +func TestMetaTableRegion(t *testing.T) { + enableSplitTableRegionVal := atomic.LoadUint32(&ddl.EnableSplitTableRegion) + atomic.StoreUint32(&ddl.EnableSplitTableRegion, 1) + defer atomic.StoreUint32(&ddl.EnableSplitTableRegion, enableSplitTableRegionVal) + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + + ddlReorgTableRegionID := tk.MustQuery("show table mysql.tidb_ddl_reorg regions").Rows()[0][0] + ddlReorgTableRegionStartKey := tk.MustQuery("show table mysql.tidb_ddl_reorg regions").Rows()[0][1] + require.Equal(t, ddlReorgTableRegionStartKey, fmt.Sprintf("%s_%d_", tablecodec.TablePrefix(), ddl.ReorgTableID)) + + ddlJobTableRegionID := tk.MustQuery("show table mysql.tidb_ddl_job regions").Rows()[0][0] + ddlJobTableRegionStartKey := tk.MustQuery("show table mysql.tidb_ddl_job regions").Rows()[0][1] + require.Equal(t, ddlJobTableRegionStartKey, fmt.Sprintf("%s_%d_", tablecodec.TablePrefix(), ddl.JobTableID)) + + require.NotEqual(t, ddlJobTableRegionID, ddlReorgTableRegionID) + + ddlBackfillTableRegionID := tk.MustQuery("show table mysql.tidb_ddl_backfill regions").Rows()[0][0] + ddlBackfillTableRegionStartKey := tk.MustQuery("show table mysql.tidb_ddl_backfill regions").Rows()[0][1] + require.Equal(t, ddlBackfillTableRegionStartKey, fmt.Sprintf("%s_%d_", tablecodec.TablePrefix(), ddl.BackfillTableID)) + ddlBackfillHistoryTableRegionID := tk.MustQuery("show table mysql.tidb_ddl_backfill_history regions").Rows()[0][0] + ddlBackfillHistoryTableRegionStartKey := tk.MustQuery("show table mysql.tidb_ddl_backfill_history regions").Rows()[0][1] + require.Equal(t, ddlBackfillHistoryTableRegionStartKey, fmt.Sprintf("%s_%d_", tablecodec.TablePrefix(), ddl.BackfillHistoryTableID)) + + require.NotEqual(t, ddlBackfillTableRegionID, ddlBackfillHistoryTableRegionID) +} diff --git a/session/session_test/main_test.go b/session/session_test/main_test.go index 855ce6133f79c..849904506a0db 100644 --- a/session/session_test/main_test.go +++ b/session/session_test/main_test.go @@ -40,6 +40,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ // TODO: figure the reason and shorten this list goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/internal/retry.newBackoffFn.func1"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/v3.waitRetryBackoff"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), diff --git a/session/session_test/session_test.go b/session/session_test/session_test.go index b58e78ede9c23..3f8a57be18f75 100644 --- a/session/session_test/session_test.go +++ b/session/session_test/session_test.go @@ -946,7 +946,7 @@ func TestLocalTemporaryTableInsertIgnore(t *testing.T) { // test outside transaction tk.MustExec("insert ignore into tmp1 values(1, 100, 1000)") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'PRIMARY'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'tmp1.PRIMARY'")) tk.MustQuery("select * from tmp1 where id=1").Check(testkit.Rows("1 11 101")) tk.MustExec("insert ignore into tmp1 values(5, 15, 105)") tk.MustQuery("show warnings").Check(testkit.Rows()) @@ -955,13 +955,13 @@ func TestLocalTemporaryTableInsertIgnore(t *testing.T) { // test in transaction and rollback tk.MustExec("begin") tk.MustExec("insert ignore into tmp1 values(1, 100, 1000)") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'PRIMARY'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'tmp1.PRIMARY'")) tk.MustQuery("select * from tmp1 where id=1").Check(testkit.Rows("1 11 101")) tk.MustExec("insert ignore into tmp1 values(3, 13, 103)") tk.MustQuery("show warnings").Check(testkit.Rows()) tk.MustQuery("select * from tmp1 where id=3").Check(testkit.Rows("3 13 103")) tk.MustExec("insert ignore into tmp1 values(3, 100, 1000)") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '3' for key 'PRIMARY'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '3' for key 'tmp1.PRIMARY'")) tk.MustQuery("select * from tmp1 where id=3").Check(testkit.Rows("3 13 103")) tk.MustExec("rollback") tk.MustQuery("select * from tmp1").Check(testkit.Rows("1 11 101", "2 12 102", "5 15 105")) @@ -969,11 +969,11 @@ func TestLocalTemporaryTableInsertIgnore(t *testing.T) { // test commit tk.MustExec("begin") tk.MustExec("insert ignore into tmp1 values(1, 100, 1000)") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'PRIMARY'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 'tmp1.PRIMARY'")) tk.MustExec("insert ignore into tmp1 values(3, 13, 103)") tk.MustQuery("show warnings").Check(testkit.Rows()) tk.MustExec("insert ignore into tmp1 values(3, 100, 1000)") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '3' for key 'PRIMARY'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '3' for key 'tmp1.PRIMARY'")) tk.MustExec("commit") tk.MustQuery("select * from tmp1").Check(testkit.Rows("1 11 101", "2 12 102", "3 13 103", "5 15 105")) } @@ -989,7 +989,7 @@ func TestLocalTemporaryTableInsertOnDuplicateKeyUpdate(t *testing.T) { // test outside transaction tk.MustExec("insert ignore into tmp1 values(1, 100, 1000) on duplicate key update u=12") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '12' for key 'u'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '12' for key 'tmp1.u'")) tk.MustQuery("select * from tmp1 where id=1").Check(testkit.Rows("1 11 101")) tk.MustExec("insert into tmp1 values(2, 100, 1000) on duplicate key update v=202") tk.MustQuery("show warnings").Check(testkit.Rows()) @@ -1001,7 +1001,7 @@ func TestLocalTemporaryTableInsertOnDuplicateKeyUpdate(t *testing.T) { // test in transaction and rollback tk.MustExec("begin") tk.MustExec("insert ignore into tmp1 values(1, 100, 1000) on duplicate key update u=12") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '12' for key 'u'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '12' for key 'tmp1.u'")) tk.MustQuery("select * from tmp1 where id=1").Check(testkit.Rows("1 11 101")) tk.MustExec("insert into tmp1 values(2, 100, 1000) on duplicate key update v=302") tk.MustQuery("show warnings").Check(testkit.Rows()) @@ -1015,7 +1015,7 @@ func TestLocalTemporaryTableInsertOnDuplicateKeyUpdate(t *testing.T) { // test commit tk.MustExec("begin") tk.MustExec("insert ignore into tmp1 values(1, 100, 1000) on duplicate key update u=12") - tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '12' for key 'u'")) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '12' for key 'tmp1.u'")) tk.MustExec("insert into tmp1 values(2, 100, 1000) on duplicate key update v=302") tk.MustExec("insert into tmp1 values(4, 14, 104) on duplicate key update v=204") tk.MustExec("commit") @@ -1574,8 +1574,8 @@ func TestKVVars(t *testing.T) { require.Nil(t, failpoint.Enable("tikvclient/probeSetVars", `return(true)`)) tk.MustExec("select * from kvvars where a = 1") require.Nil(t, failpoint.Disable("tikvclient/probeSetVars")) - require.True(t, transaction.SetSuccess) - transaction.SetSuccess = false + require.True(t, transaction.SetSuccess.Load()) + transaction.SetSuccess.Store(false) } func TestTxnRetryErrMsg(t *testing.T) { @@ -2112,9 +2112,10 @@ func TestSetEnableRateLimitAction(t *testing.T) { result.Check(testkit.Rows("1")) tk.MustExec("use test") tk.MustExec("create table tmp123(id int)") - tk.MustQuery("select * from tmp123;") + rs, err := tk.Exec("select * from tmp123;") + require.NoError(t, err) haveRateLimitAction := false - action := tk.Session().GetSessionVars().StmtCtx.MemTracker.GetFallbackForTest(false) + action := tk.Session().GetSessionVars().MemTracker.GetFallbackForTest(false) for ; action != nil; action = action.GetFallback() { if action.GetPriority() == memory.DefRateLimitPriority { haveRateLimitAction = true @@ -2122,6 +2123,8 @@ func TestSetEnableRateLimitAction(t *testing.T) { } } require.True(t, haveRateLimitAction) + err = rs.Close() + require.NoError(t, err) // assert set sys variable tk.MustExec("set global tidb_enable_rate_limit_action= '0';") @@ -2132,7 +2135,7 @@ func TestSetEnableRateLimitAction(t *testing.T) { result.Check(testkit.Rows("0")) haveRateLimitAction = false - action = tk.Session().GetSessionVars().StmtCtx.MemTracker.GetFallbackForTest(false) + action = tk.Session().GetSessionVars().MemTracker.GetFallbackForTest(false) for ; action != nil; action = action.GetFallback() { if action.GetPriority() == memory.DefRateLimitPriority { haveRateLimitAction = true @@ -2151,29 +2154,29 @@ func TestStmtHints(t *testing.T) { // Test MEMORY_QUOTA hint tk.MustExec("select /*+ MEMORY_QUOTA(1 MB) */ 1;") val := int64(1) * 1024 * 1024 - require.True(t, tk.Session().GetSessionVars().StmtCtx.MemTracker.CheckBytesLimit(val)) + require.True(t, tk.Session().GetSessionVars().MemTracker.CheckBytesLimit(val)) tk.MustExec("select /*+ MEMORY_QUOTA(1 GB) */ 1;") val = int64(1) * 1024 * 1024 * 1024 - require.True(t, tk.Session().GetSessionVars().StmtCtx.MemTracker.CheckBytesLimit(val)) + require.True(t, tk.Session().GetSessionVars().MemTracker.CheckBytesLimit(val)) tk.MustExec("select /*+ MEMORY_QUOTA(1 GB), MEMORY_QUOTA(1 MB) */ 1;") val = int64(1) * 1024 * 1024 require.Len(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings(), 1) - require.True(t, tk.Session().GetSessionVars().StmtCtx.MemTracker.CheckBytesLimit(val)) + require.True(t, tk.Session().GetSessionVars().MemTracker.CheckBytesLimit(val)) tk.MustExec("select /*+ MEMORY_QUOTA(0 GB) */ 1;") val = int64(0) require.Len(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings(), 1) - require.True(t, tk.Session().GetSessionVars().StmtCtx.MemTracker.CheckBytesLimit(val)) + require.True(t, tk.Session().GetSessionVars().MemTracker.CheckBytesLimit(val)) require.EqualError(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings()[0].Err, "Setting the MEMORY_QUOTA to 0 means no memory limit") tk.MustExec("use test") tk.MustExec("create table t1(a int);") tk.MustExec("insert /*+ MEMORY_QUOTA(1 MB) */ into t1 (a) values (1);") val = int64(1) * 1024 * 1024 - require.True(t, tk.Session().GetSessionVars().StmtCtx.MemTracker.CheckBytesLimit(val)) + require.True(t, tk.Session().GetSessionVars().MemTracker.CheckBytesLimit(val)) tk.MustExec("insert /*+ MEMORY_QUOTA(1 MB) */ into t1 select /*+ MEMORY_QUOTA(3 MB) */ * from t1;") val = int64(1) * 1024 * 1024 - require.True(t, tk.Session().GetSessionVars().StmtCtx.MemTracker.CheckBytesLimit(val)) + require.True(t, tk.Session().GetSessionVars().MemTracker.CheckBytesLimit(val)) require.Len(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings(), 1) require.EqualError(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings()[0].Err, "[util:3126]Hint MEMORY_QUOTA(`3145728`) is ignored as conflicting/duplicated.") @@ -2958,6 +2961,7 @@ func TestIgnoreForeignKey(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set @@foreign_key_checks=0") sqlText := `CREATE TABLE address ( id bigint(20) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, @@ -3170,12 +3174,12 @@ func TestUnique(t *testing.T) { require.Error(t, err) // Check error type and error message require.True(t, terror.ErrorEqual(err, kv.ErrKeyExists), fmt.Sprintf("err %v", err)) - require.Equal(t, "previous statement: insert into test(id, val) values(1, 1);: [kv:1062]Duplicate entry '1' for key 'PRIMARY'", err.Error()) + require.Equal(t, "previous statement: insert into test(id, val) values(1, 1);: [kv:1062]Duplicate entry '1' for key 'test.PRIMARY'", err.Error()) _, err = tk1.Exec("commit") require.Error(t, err) require.True(t, terror.ErrorEqual(err, kv.ErrKeyExists), fmt.Sprintf("err %v", err)) - require.Equal(t, "previous statement: insert into test(id, val) values(2, 2);: [kv:1062]Duplicate entry '2' for key 'val'", err.Error()) + require.Equal(t, "previous statement: insert into test(id, val) values(2, 2);: [kv:1062]Duplicate entry '2' for key 'test.val'", err.Error()) // Test for https://github.com/pingcap/tidb/issues/463 tk.MustExec("drop table test;") @@ -3700,7 +3704,7 @@ func TestGlobalVarAccessor(t *testing.T) { require.NoError(t, err) require.Equal(t, varValue, v) // Set global var to another value - err = se.SetGlobalSysVar(varName, varValue1) + err = se.SetGlobalSysVar(context.Background(), varName, varValue1) require.NoError(t, err) v, err = se.GetGlobalSysVar(varName) require.NoError(t, err) @@ -3713,7 +3717,7 @@ func TestGlobalVarAccessor(t *testing.T) { v, err = se1.GetGlobalSysVar(varName) require.NoError(t, err) require.Equal(t, varValue0, v) - err = se1.SetGlobalSysVar(varName, varValue2) + err = se1.SetGlobalSysVar(context.Background(), varName, varValue2) require.NoError(t, err) v, err = se1.GetGlobalSysVar(varName) require.NoError(t, err) @@ -3775,7 +3779,7 @@ func TestUpgradeSysvars(t *testing.T) { // i.e. implying that it was set from an earlier version of TiDB. tk.MustExec(`REPLACE INTO mysql.global_variables (variable_name, variable_value) VALUES ('tidb_enable_noop_functions', '0')`) - domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache() // update cache + domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache(true) // update cache v, err := se.GetGlobalSysVar("tidb_enable_noop_functions") require.NoError(t, err) require.Equal(t, "OFF", v) @@ -3786,7 +3790,7 @@ func TestUpgradeSysvars(t *testing.T) { // to handle upgrade/downgrade issues correctly. tk.MustExec(`REPLACE INTO mysql.global_variables (variable_name, variable_value) VALUES ('rpl_semi_sync_slave_enabled', '')`) - domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache() // update cache + domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache(true) // update cache v, err = se.GetGlobalSysVar("rpl_semi_sync_slave_enabled") require.NoError(t, err) require.Equal(t, "OFF", v) // the default value is restored. @@ -3797,7 +3801,7 @@ func TestUpgradeSysvars(t *testing.T) { // This further helps for https://github.com/pingcap/tidb/pull/28842 tk.MustExec(`REPLACE INTO mysql.global_variables (variable_name, variable_value) VALUES ('tidb_executor_concurrency', '999')`) - domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache() // update cache + domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache(true) // update cache v, err = se.GetGlobalSysVar("tidb_executor_concurrency") require.NoError(t, err) require.Equal(t, "256", v) // the max value is restored. @@ -3806,7 +3810,7 @@ func TestUpgradeSysvars(t *testing.T) { // This could be the case if an ENUM sysvar removes a value. tk.MustExec(`REPLACE INTO mysql.global_variables (variable_name, variable_value) VALUES ('tidb_enable_noop_functions', 'SOMEVAL')`) - domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache() // update cache + domain.GetDomain(tk.Session()).NotifyUpdateSysVarCache(true) // update cache v, err = se.GetGlobalSysVar("tidb_enable_noop_functions") require.NoError(t, err) require.Equal(t, "OFF", v) // the default value is restored. @@ -3835,7 +3839,7 @@ func TestSetInstanceSysvarBySetGlobalSysVar(t *testing.T) { // but GetGlobalSysVar could not access TiDBGeneralLog's GetGlobal. // set to "1" - err = se.SetGlobalSysVar(varName, "ON") + err = se.SetGlobalSysVar(context.Background(), varName, "ON") require.NoError(t, err) v, err = se.GetGlobalSysVar(varName) tk.MustQuery("select @@global.tidb_general_log").Check(testkit.Rows("1")) @@ -3843,7 +3847,7 @@ func TestSetInstanceSysvarBySetGlobalSysVar(t *testing.T) { require.Equal(t, defaultValue, v) // set back to "0" - err = se.SetGlobalSysVar(varName, defaultValue) + err = se.SetGlobalSysVar(context.Background(), varName, defaultValue) require.NoError(t, err) v, err = se.GetGlobalSysVar(varName) tk.MustQuery("select @@global.tidb_general_log").Check(testkit.Rows("0")) diff --git a/session/tidb.go b/session/tidb.go index fd4411a18518c..41b866da8ff85 100644 --- a/session/tidb.go +++ b/session/tidb.go @@ -42,11 +42,12 @@ import ( "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/sqlexec" + "github.com/pingcap/tidb/util/syncutil" "go.uber.org/zap" ) type domainMap struct { - mu sync.Mutex + mu syncutil.Mutex domains map[string]*domain.Domain } @@ -81,10 +82,7 @@ func (dm *domainMap) Get(store kv.Storage) (d *domain.Domain, err error) { zap.Stringer("index usage sync lease", idxUsageSyncLease)) factory := createSessionFunc(store) sysFactory := createSessionWithDomainFunc(store) - onClose := func() { - dm.Delete(store) - } - d = domain.NewDomain(store, ddlLease, statisticLease, idxUsageSyncLease, planReplayerGCLease, factory, onClose) + d = domain.NewDomain(store, ddlLease, statisticLease, idxUsageSyncLease, planReplayerGCLease, factory) var ddlInjector func(ddl.DDL) *schematracker.Checker if injector, ok := store.(schematracker.StorageDDLInjector); ok { @@ -102,8 +100,10 @@ func (dm *domainMap) Get(store kv.Storage) (d *domain.Domain, err error) { if err != nil { return nil, err } - dm.domains[key] = d + d.SetOnClose(func() { + dm.Delete(store) + }) return } @@ -240,9 +240,9 @@ func finishStmt(ctx context.Context, se *session, meetsErr error, sql sqlexec.St // Handle the stmt commit/rollback. if se.txn.Valid() { if meetsErr != nil { - se.StmtRollback() + se.StmtRollback(ctx, false) } else { - se.StmtCommit() + se.StmtCommit(ctx) } } } diff --git a/session/txn.go b/session/txn.go index 18464073da2d1..e81dfcc578930 100644 --- a/session/txn.go +++ b/session/txn.go @@ -20,7 +20,6 @@ import ( "fmt" "runtime/trace" "strings" - "sync" "sync/atomic" "time" @@ -33,9 +32,11 @@ import ( "github.com/pingcap/tidb/session/txninfo" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/binloginfo" + "github.com/pingcap/tidb/sessiontxn" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/sli" + "github.com/pingcap/tidb/util/syncutil" "github.com/pingcap/tipb/go-binlog" "github.com/tikv/client-go/v2/oracle" "github.com/tikv/client-go/v2/tikv" @@ -59,12 +60,14 @@ type LazyTxn struct { mutations map[int64]*binlog.TableMutation writeSLI sli.TxnWriteThroughputSLI + enterAggressiveLockingOnValid bool + // TxnInfo is added for the lock view feature, the data is frequent modified but // rarely read (just in query select * from information_schema.tidb_trx). // The data in this session would be query by other sessions, so Mutex is necessary. // Since read is rare, the reader can copy-on-read to get a data snapshot. mu struct { - sync.RWMutex + syncutil.RWMutex txninfo.TxnInfo } @@ -151,7 +154,6 @@ func (txn *LazyTxn) cleanupStmtBuf() { txn.mu.Lock() defer txn.mu.Unlock() txn.mu.TxnInfo.EntriesCount = uint64(txn.Transaction.Len()) - txn.mu.TxnInfo.EntriesSize = uint64(txn.Transaction.Size()) } // resetTxnInfo resets the transaction info. @@ -159,8 +161,7 @@ func (txn *LazyTxn) cleanupStmtBuf() { func (txn *LazyTxn) resetTxnInfo( startTS uint64, state txninfo.TxnRunningState, - entriesCount, - entriesSize uint64, + entriesCount uint64, currentSQLDigest string, allSQLDigests []string, ) { @@ -178,7 +179,7 @@ func (txn *LazyTxn) resetTxnInfo( txninfo.TxnStatusEnteringCounter(state).Inc() txn.mu.TxnInfo.LastStateChangeTime = time.Now() txn.mu.TxnInfo.EntriesCount = entriesCount - txn.mu.TxnInfo.EntriesSize = entriesSize + txn.mu.TxnInfo.CurrentSQLDigest = currentSQLDigest txn.mu.TxnInfo.AllSQLDigests = allSQLDigests } @@ -191,6 +192,22 @@ func (txn *LazyTxn) Size() int { return txn.Transaction.Size() } +// Mem implements the MemBuffer interface. +func (txn *LazyTxn) Mem() uint64 { + if txn.Transaction == nil { + return 0 + } + return txn.Transaction.Mem() +} + +// SetMemoryFootprintChangeHook sets the hook to be called when the memory footprint of this transaction changes. +func (txn *LazyTxn) SetMemoryFootprintChangeHook(hook func(uint64)) { + if txn.Transaction == nil { + return + } + txn.Transaction.SetMemoryFootprintChangeHook(hook) +} + // Valid implements the kv.Transaction interface. func (txn *LazyTxn) Valid() bool { return txn.Transaction != nil && txn.Transaction.Valid() @@ -209,7 +226,11 @@ func (txn *LazyTxn) String() string { return txn.Transaction.String() } if txn.txnFuture != nil { - return "txnFuture" + res := "txnFuture" + if txn.enterAggressiveLockingOnValid { + res += " (pending aggressive locking)" + } + return res } return "invalid transaction" } @@ -268,6 +289,14 @@ func (txn *LazyTxn) changePendingToValid(ctx context.Context) error { txn.Transaction = t txn.initStmtBuf() + if txn.enterAggressiveLockingOnValid { + txn.enterAggressiveLockingOnValid = false + err = txn.Transaction.StartAggressiveLocking() + if err != nil { + return err + } + } + // The txnInfo may already recorded the first statement (usually "begin") when it's pending, so keep them. txn.mu.Lock() defer txn.mu.Unlock() @@ -275,7 +304,6 @@ func (txn *LazyTxn) changePendingToValid(ctx context.Context) error { t.StartTS(), txninfo.TxnIdle, uint64(txn.Transaction.Len()), - uint64(txn.Transaction.Size()), txn.mu.TxnInfo.CurrentSQLDigest, txn.mu.TxnInfo.AllSQLDigests) @@ -290,6 +318,8 @@ func (txn *LazyTxn) changeToInvalid() { txn.Transaction = nil txn.txnFuture = nil + txn.enterAggressiveLockingOnValid = false + txn.mu.Lock() lastState := txn.mu.TxnInfo.State lastStateChangeTime := txn.mu.TxnInfo.LastStateChangeTime @@ -413,8 +443,13 @@ func (txn *LazyTxn) RollbackMemDBToCheckpoint(savepoint *tikv.MemDBCheckpoint) { txn.cleanup() } -// LockKeys Wrap the inner transaction's `LockKeys` to record the status +// LockKeys wraps the inner transaction's `LockKeys` to record the status func (txn *LazyTxn) LockKeys(ctx context.Context, lockCtx *kv.LockCtx, keys ...kv.Key) error { + return txn.LockKeysFunc(ctx, lockCtx, nil, keys...) +} + +// LockKeysFunc Wrap the inner transaction's `LockKeys` to record the status +func (txn *LazyTxn) LockKeysFunc(ctx context.Context, lockCtx *kv.LockCtx, fn func(), keys ...kv.Key) error { failpoint.Inject("beforeLockKeys", func() {}) t := time.Now() @@ -425,16 +460,94 @@ func (txn *LazyTxn) LockKeys(ctx context.Context, lockCtx *kv.LockCtx, keys ...k txn.mu.TxnInfo.BlockStartTime.Valid = true txn.mu.TxnInfo.BlockStartTime.Time = t txn.mu.Unlock() + lockFunc := func() { + if fn != nil { + fn() + } + txn.mu.Lock() + defer txn.mu.Unlock() + txn.updateState(originState) + txn.mu.TxnInfo.BlockStartTime.Valid = false + txn.mu.TxnInfo.EntriesCount = uint64(txn.Transaction.Len()) + } + return txn.Transaction.LockKeysFunc(ctx, lockCtx, lockFunc, keys...) +} - err := txn.Transaction.LockKeys(ctx, lockCtx, keys...) +// StartAggressiveLocking wraps the inner transaction to support using aggressive locking with lazy initialization. +func (txn *LazyTxn) StartAggressiveLocking() error { + if txn.Valid() { + return txn.Transaction.StartAggressiveLocking() + } else if txn.pending() { + txn.enterAggressiveLockingOnValid = true + } else { + err := errors.New("trying to start aggressive locking on a transaction in invalid state") + logutil.BgLogger().Error("unexpected error when starting aggressive locking", zap.Error(err), zap.Stringer("txn", txn)) + return err + } + return nil +} - txn.mu.Lock() - defer txn.mu.Unlock() - txn.updateState(originState) - txn.mu.TxnInfo.BlockStartTime.Valid = false - txn.mu.TxnInfo.EntriesCount = uint64(txn.Transaction.Len()) - txn.mu.TxnInfo.EntriesSize = uint64(txn.Transaction.Size()) - return err +// RetryAggressiveLocking wraps the inner transaction to support using aggressive locking with lazy initialization. +func (txn *LazyTxn) RetryAggressiveLocking(ctx context.Context) error { + if txn.Valid() { + return txn.Transaction.RetryAggressiveLocking(ctx) + } else if !txn.pending() { + err := errors.New("trying to retry aggressive locking on a transaction in invalid state") + logutil.BgLogger().Error("unexpected error when retrying aggressive locking", zap.Error(err), zap.Stringer("txnStartTS", txn)) + return err + } + return nil +} + +// CancelAggressiveLocking wraps the inner transaction to support using aggressive locking with lazy initialization. +func (txn *LazyTxn) CancelAggressiveLocking(ctx context.Context) error { + if txn.Valid() { + return txn.Transaction.CancelAggressiveLocking(ctx) + } else if txn.pending() { + if txn.enterAggressiveLockingOnValid { + txn.enterAggressiveLockingOnValid = false + } else { + err := errors.New("trying to cancel aggressive locking when it's not started") + logutil.BgLogger().Error("unexpected error when cancelling aggressive locking", zap.Error(err), zap.Stringer("txnStartTS", txn)) + return err + } + } else { + err := errors.New("trying to cancel aggressive locking on a transaction in invalid state") + logutil.BgLogger().Error("unexpected error when cancelling aggressive locking", zap.Error(err), zap.Stringer("txnStartTS", txn)) + return err + } + return nil +} + +// DoneAggressiveLocking wraps the inner transaction to support using aggressive locking with lazy initialization. +func (txn *LazyTxn) DoneAggressiveLocking(ctx context.Context) error { + if txn.Valid() { + return txn.Transaction.DoneAggressiveLocking(ctx) + } else if txn.pending() { + if txn.enterAggressiveLockingOnValid { + txn.enterAggressiveLockingOnValid = false + } else { + err := errors.New("trying to finish aggressive locking when it's not started") + logutil.BgLogger().Error("unexpected error when finishing aggressive locking") + return err + } + } else { + err := errors.New("trying to cancel aggressive locking on a transaction in invalid state") + logutil.BgLogger().Error("unexpected error when finishing aggressive locking") + return err + } + return nil +} + +// IsInAggressiveLockingMode wraps the inner transaction to support using aggressive locking with lazy initialization. +func (txn *LazyTxn) IsInAggressiveLockingMode() bool { + if txn.Valid() { + return txn.Transaction.IsInAggressiveLockingMode() + } else if txn.pending() { + return txn.enterAggressiveLockingOnValid + } else { + return false + } } func (txn *LazyTxn) reset() { @@ -586,11 +699,17 @@ func (s *session) HasDirtyContent(tid int64) bool { } // StmtCommit implements the sessionctx.Context interface. -func (s *session) StmtCommit() { +func (s *session) StmtCommit(ctx context.Context) { defer func() { s.txn.cleanup() }() + txnManager := sessiontxn.GetTxnManager(s) + err := txnManager.OnStmtCommit(ctx) + if err != nil { + logutil.Logger(ctx).Error("txnManager failed to handle OnStmtCommit", zap.Error(err)) + } + st := &s.txn st.flushStmtBuf() @@ -602,7 +721,12 @@ func (s *session) StmtCommit() { } // StmtRollback implements the sessionctx.Context interface. -func (s *session) StmtRollback() { +func (s *session) StmtRollback(ctx context.Context, isForPessimisticRetry bool) { + txnManager := sessiontxn.GetTxnManager(s) + err := txnManager.OnStmtRollback(ctx, isForPessimisticRetry) + if err != nil { + logutil.Logger(ctx).Error("txnManager failed to handle OnStmtRollback", zap.Error(err)) + } s.txn.cleanup() } diff --git a/session/txninfo/txn_info.go b/session/txninfo/txn_info.go index 640e16474b4bd..31e4d338eb623 100644 --- a/session/txninfo/txn_info.go +++ b/session/txninfo/txn_info.go @@ -161,8 +161,6 @@ type TxnInfo struct { } // How many entries are in MemDB EntriesCount uint64 - // MemDB used memory - EntriesSize uint64 // The following fields will be filled in `session` instead of `LazyTxn` @@ -208,9 +206,6 @@ var columnValueGetterMap = map[string]func(*TxnInfo) types.Datum{ MemBufferKeysStr: func(info *TxnInfo) types.Datum { return types.NewDatum(info.EntriesCount) }, - MemBufferBytesStr: func(info *TxnInfo) types.Datum { - return types.NewDatum(info.EntriesSize) - }, SessionIDStr: func(info *TxnInfo) types.Datum { return types.NewDatum(info.ConnectionID) }, diff --git a/session/txnmanager.go b/session/txnmanager.go index 65652428f7481..6916fbf42bb75 100644 --- a/session/txnmanager.go +++ b/session/txnmanager.go @@ -51,7 +51,7 @@ type txnManager struct { ctxProvider sessiontxn.TxnContextProvider // We always reuse the same OptimisticTxnContextProvider in one session to reduce memory allocation cost for every new txn. - reservedOptimisticProvider isolation.OptimisticTxnContextProvider + reservedOptimisticProviders [2]isolation.OptimisticTxnContextProvider } func newTxnManager(sctx sessionctx.Context) *txnManager { @@ -175,6 +175,15 @@ func (m *txnManager) OnStmtStart(ctx context.Context, node ast.StmtNode) error { return m.ctxProvider.OnStmtStart(ctx, m.stmtNode) } +// OnHandlePessimisticStmtStart is the hook that should be called when starts handling a pessimistic DML or +// a pessimistic select-for-update statements. +func (m *txnManager) OnHandlePessimisticStmtStart(ctx context.Context) error { + if m.ctxProvider == nil { + return errors.New("context provider not set") + } + return m.ctxProvider.OnHandlePessimisticStmtStart(ctx) +} + // OnStmtErrorForNextAction is the hook that should be called when a new statement get an error func (m *txnManager) OnStmtErrorForNextAction(point sessiontxn.StmtErrorHandlePoint, err error) (sessiontxn.StmtErrorAction, error) { if m.ctxProvider == nil { @@ -199,6 +208,22 @@ func (m *txnManager) OnStmtRetry(ctx context.Context) error { return m.ctxProvider.OnStmtRetry(ctx) } +// OnStmtCommit is the hook that should be called when a statement is executed successfully. +func (m *txnManager) OnStmtCommit(ctx context.Context) error { + if m.ctxProvider == nil { + return errors.New("context provider not set") + } + return m.ctxProvider.OnStmtCommit(ctx) +} + +// OnStmtRollback is the hook that should be called when a statement fails to execute. +func (m *txnManager) OnStmtRollback(ctx context.Context, isForPessimisticRetry bool) error { + if m.ctxProvider == nil { + return errors.New("context provider not set") + } + return m.ctxProvider.OnStmtRollback(ctx, isForPessimisticRetry) +} + // OnLocalTemporaryTableCreated is the hook that should be called when a temporary table created. // The provider will update its state then func (m *txnManager) OnLocalTemporaryTableCreated() { @@ -241,8 +266,13 @@ func (m *txnManager) newProviderWithRequest(r *sessiontxn.EnterNewTxnRequest) (s switch txnMode { case "", ast.Optimistic: // When txnMode is 'OPTIMISTIC' or '', the transaction should be optimistic - m.reservedOptimisticProvider.ResetForNewTxn(m.sctx, r.CausalConsistencyOnly) - return &m.reservedOptimisticProvider, nil + provider := &m.reservedOptimisticProviders[0] + if old, ok := m.ctxProvider.(*isolation.OptimisticTxnContextProvider); ok && old == provider { + // We should make sure the new provider is not the same with the old one + provider = &m.reservedOptimisticProviders[1] + } + provider.ResetForNewTxn(m.sctx, r.CausalConsistencyOnly) + return provider, nil case ast.Pessimistic: // When txnMode is 'PESSIMISTIC', the provider should be determined by the isolation level switch sessVars.IsolationLevelForNewTxn() { diff --git a/sessionctx/BUILD.bazel b/sessionctx/BUILD.bazel index 10d02bd931b66..800001fd426b3 100644 --- a/sessionctx/BUILD.bazel +++ b/sessionctx/BUILD.bazel @@ -6,6 +6,7 @@ go_library( importpath = "github.com/pingcap/tidb/sessionctx", visibility = ["//visibility:public"], deps = [ + "//extension", "//kv", "//metrics", "//parser/model", @@ -32,6 +33,7 @@ go_test( ], embed = [":sessionctx"], flaky = True, + race = "on", deps = [ "//testkit/testsetup", "@com_github_stretchr_testify//require", diff --git a/sessionctx/binloginfo/BUILD.bazel b/sessionctx/binloginfo/BUILD.bazel index 6d5a600b9e68c..7a843495273ea 100644 --- a/sessionctx/binloginfo/BUILD.bazel +++ b/sessionctx/binloginfo/BUILD.bazel @@ -33,6 +33,7 @@ go_test( embed = [":binloginfo"], flaky = True, deps = [ + "//autoid_service", "//ddl", "//domain", "//kv", diff --git a/sessionctx/binloginfo/binloginfo.go b/sessionctx/binloginfo/binloginfo.go index 5b29dd91c5b6b..d871c10eed2ef 100644 --- a/sessionctx/binloginfo/binloginfo.go +++ b/sessionctx/binloginfo/binloginfo.go @@ -119,9 +119,15 @@ func EnableSkipBinlogFlag() { } // DisableSkipBinlogFlag disable the skipBinlog flag. -func DisableSkipBinlogFlag() { +func DisableSkipBinlogFlag() error { + if err := statusListener(BinlogStatusOn); err != nil { + logutil.BgLogger().Warn("update binlog status failed", zap.Error(err)) + return errors.Trace(err) + } + atomic.StoreUint32(&skipBinlog, 0) logutil.BgLogger().Warn("[binloginfo] disable the skipBinlog flag") + return nil } // IsBinlogSkipped gets the skipBinlog flag. diff --git a/sessionctx/binloginfo/binloginfo_test.go b/sessionctx/binloginfo/binloginfo_test.go index 3c777a9436234..28235b5184b68 100644 --- a/sessionctx/binloginfo/binloginfo_test.go +++ b/sessionctx/binloginfo/binloginfo_test.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" + _ "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" diff --git a/sessionctx/binloginfo/main_test.go b/sessionctx/binloginfo/main_test.go index a6d097b6a99c5..0459507352310 100644 --- a/sessionctx/binloginfo/main_test.go +++ b/sessionctx/binloginfo/main_test.go @@ -27,6 +27,7 @@ func TestMain(m *testing.M) { goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), } goleak.VerifyTestMain(m, opts...) } diff --git a/sessionctx/context.go b/sessionctx/context.go index 7be92f102e56c..0999b2396cae0 100644 --- a/sessionctx/context.go +++ b/sessionctx/context.go @@ -21,6 +21,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/kvproto/pkg/kvrpcpb" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser/model" @@ -51,14 +52,15 @@ type SessionStatesHandler interface { DecodeSessionStates(context.Context, Context, *sessionstates.SessionStates) error } -// PlanCache is an interface for prepare and general plan cache +// PlanCache is an interface for prepare and non-prepared plan cache type PlanCache interface { - Get(key kvcache.Key, paramTypes []*types.FieldType) (value kvcache.Value, ok bool) - Put(key kvcache.Key, value kvcache.Value, paramTypes []*types.FieldType) + Get(key kvcache.Key, paramTypes []*types.FieldType, limitParams []uint64) (value kvcache.Value, ok bool) + Put(key kvcache.Key, value kvcache.Value, paramTypes []*types.FieldType, limitParams []uint64) Delete(key kvcache.Key) DeleteAll() Size() int SetCapacity(capacity uint) error + Close() } // Context is an interface for transaction and executive args environment. @@ -118,8 +120,8 @@ type Context interface { GetStore() kv.Storage // GetPlanCache returns the cache of the physical plan. - // generalPlanCache indicates to return the general plan cache or the prepared plan cache. - GetPlanCache(isGeneralPlanCache bool) PlanCache + // isNonPrepared indicates to return the non-prepared plan cache or the prepared plan cache. + GetPlanCache(isNonPrepared bool) PlanCache // StoreQueryFeedback stores the query feedback. StoreQueryFeedback(feedback interface{}) @@ -132,9 +134,10 @@ type Context interface { HasDirtyContent(tid int64) bool // StmtCommit flush all changes by the statement to the underlying transaction. - StmtCommit() - // StmtRollback provides statement level rollback. - StmtRollback() + StmtCommit(ctx context.Context) + // StmtRollback provides statement level rollback. The parameter `forPessimisticRetry` should be true iff it's used + // for auto-retrying execution of DMLs in pessimistic transactions. + StmtRollback(ctx context.Context, isForPessimisticRetry bool) // StmtGetMutation gets the binlog mutation for current statement. StmtGetMutation(int64) *binlog.TableMutation // IsDDLOwner checks whether this session is DDL owner. @@ -178,6 +181,15 @@ type Context interface { ReleaseAdvisoryLock(string) bool // ReleaseAllAdvisoryLocks releases all advisory locks that this session holds. ReleaseAllAdvisoryLocks() int + // GetExtensions returns the `*extension.SessionExtensions` object + GetExtensions() *extension.SessionExtensions + // InSandBoxMode indicates that this Session is in sandbox mode + // Ref about sandbox mode: https://dev.mysql.com/doc/refman/8.0/en/expired-password-handling.html + InSandBoxMode() bool + // EnableSandBoxMode enable the sandbox mode of this Session + EnableSandBoxMode() + // DisableSandBoxMode enable the sandbox mode of this Session + DisableSandBoxMode() } // TxnFuture is an interface where implementations have a kv.Transaction field and after diff --git a/sessionctx/main_test.go b/sessionctx/main_test.go index ecaf2dcebe95a..e6c2bc990a57e 100644 --- a/sessionctx/main_test.go +++ b/sessionctx/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/sessionctx/sessionstates/session_states.go b/sessionctx/sessionstates/session_states.go index 36ea0b22455d7..c9e1652a9c1df 100644 --- a/sessionctx/sessionstates/session_states.go +++ b/sessionctx/sessionstates/session_states.go @@ -15,8 +15,6 @@ package sessionstates import ( - "time" - "github.com/pingcap/tidb/errno" ptypes "github.com/pingcap/tidb/parser/types" "github.com/pingcap/tidb/sessionctx/stmtctx" @@ -79,7 +77,6 @@ type SessionStates struct { FoundInPlanCache bool `json:"in-plan-cache,omitempty"` FoundInBinding bool `json:"in-binding,omitempty"` SequenceLatestValues map[int64]int64 `json:"seq-values,omitempty"` - MPPStoreLastFailTime map[string]time.Time `json:"store-fail-time,omitempty"` LastAffectedRows int64 `json:"affected-rows,omitempty"` LastInsertID uint64 `json:"last-insert-id,omitempty"` Warnings []stmtctx.SQLWarn `json:"warnings,omitempty"` diff --git a/sessionctx/sessionstates/session_states_test.go b/sessionctx/sessionstates/session_states_test.go index 5910d6b18e071..4d1541cc9443d 100644 --- a/sessionctx/sessionstates/session_states_test.go +++ b/sessionctx/sessionstates/session_states_test.go @@ -20,9 +20,7 @@ import ( "fmt" "strconv" "strings" - "sync" "testing" - "time" "github.com/pingcap/errors" "github.com/pingcap/tidb/config" @@ -133,7 +131,7 @@ func TestSystemVars(t *testing.T) { { // sem invisible variable inSessionStates: false, - varName: variable.TiDBAllowRemoveAutoInc, + varName: variable.TiDBConfig, }, { // noop variables @@ -378,23 +376,6 @@ func TestSessionCtx(t *testing.T) { tk.MustQuery("select nextval(test.s)").Check(testkit.Rows("2")) }, }, - { - // check MPPStoreLastFailTime - setFunc: func(tk *testkit.TestKit) any { - m := sync.Map{} - m.Store("store1", time.Now()) - tk.Session().GetSessionVars().MPPStoreLastFailTime = &m - return tk.Session().GetSessionVars().MPPStoreLastFailTime - }, - checkFunc: func(tk *testkit.TestKit, param any) { - failTime := tk.Session().GetSessionVars().MPPStoreLastFailTime - tm, ok := failTime.Load("store1") - require.True(t, ok) - v, ok := (param.(*sync.Map)).Load("store1") - require.True(t, ok) - require.True(t, tm.(time.Time).Equal(v.(time.Time))) - }, - }, { // check FoundInPlanCache setFunc: func(tk *testkit.TestKit) any { @@ -1271,6 +1252,16 @@ func TestShowStateFail(t *testing.T) { tk.MustExec("drop table test.t1") }, }, + { + // enable sandbox mode + setFunc: func(tk *testkit.TestKit, conn server.MockConn) { + tk.Session().EnableSandBoxMode() + }, + showErr: errno.ErrCannotMigrateSession, + cleanFunc: func(tk *testkit.TestKit) { + tk.Session().DisableSandBoxMode() + }, + }, { // after COM_STMT_SEND_LONG_DATA setFunc: func(tk *testkit.TestKit, conn server.MockConn) { diff --git a/sessionctx/sessionstates/session_token.go b/sessionctx/sessionstates/session_token.go index 4faa6eae7f41b..3724a7aafa853 100644 --- a/sessionctx/sessionstates/session_token.go +++ b/sessionctx/sessionstates/session_token.go @@ -159,10 +159,8 @@ type certInfo struct { expireTime time.Time } -// We cannot guarantee that the cert and key paths are set at the same time because they are set through system variables. func (sc *signingCert) setCertPath(certPath string) { sc.Lock() - // Just in case of repeatedly loading global variables, we check the path to avoid useless loading. if certPath != sc.certPath { sc.certPath = certPath // It may fail expectedly because the key path is not set yet. diff --git a/sessionctx/stmtctx/BUILD.bazel b/sessionctx/stmtctx/BUILD.bazel index b42939f7ec324..a2e12d1e860e1 100644 --- a/sessionctx/stmtctx/BUILD.bazel +++ b/sessionctx/stmtctx/BUILD.bazel @@ -6,6 +6,7 @@ go_library( importpath = "github.com/pingcap/tidb/sessionctx/stmtctx", visibility = ["//visibility:public"], deps = [ + "//errno", "//parser", "//parser/ast", "//parser/model", diff --git a/sessionctx/stmtctx/main_test.go b/sessionctx/stmtctx/main_test.go index d9ea6f6a898e7..ba36da8e5c6b8 100644 --- a/sessionctx/stmtctx/main_test.go +++ b/sessionctx/stmtctx/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/sessionctx/stmtctx/stmtctx.go b/sessionctx/stmtctx/stmtctx.go index 81905683dc0ab..01ead10e580fc 100644 --- a/sessionctx/stmtctx/stmtctx.go +++ b/sessionctx/stmtctx/stmtctx.go @@ -24,6 +24,7 @@ import ( "time" "github.com/pingcap/errors" + "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" @@ -101,6 +102,42 @@ func (warn *SQLWarn) UnmarshalJSON(data []byte) error { return nil } +// ReferenceCount indicates the reference count of StmtCtx. +type ReferenceCount int32 + +const ( + // ReferenceCountIsFrozen indicates the current StmtCtx is resetting, it'll refuse all the access from other sessions. + ReferenceCountIsFrozen int32 = -1 + // ReferenceCountNoReference indicates the current StmtCtx is not accessed by other sessions. + ReferenceCountNoReference int32 = 0 +) + +// TryIncrease tries to increase the reference count. +// There is a small chance that TryIncrease returns true while TryFreeze and +// UnFreeze are invoked successfully during the execution of TryIncrease. +func (rf *ReferenceCount) TryIncrease() bool { + refCnt := atomic.LoadInt32((*int32)(rf)) + for ; refCnt != ReferenceCountIsFrozen && !atomic.CompareAndSwapInt32((*int32)(rf), refCnt, refCnt+1); refCnt = atomic.LoadInt32((*int32)(rf)) { + } + return refCnt != ReferenceCountIsFrozen +} + +// Decrease decreases the reference count. +func (rf *ReferenceCount) Decrease() { + for refCnt := atomic.LoadInt32((*int32)(rf)); !atomic.CompareAndSwapInt32((*int32)(rf), refCnt, refCnt-1); refCnt = atomic.LoadInt32((*int32)(rf)) { + } +} + +// TryFreeze tries to freeze the StmtCtx to frozen before resetting the old StmtCtx. +func (rf *ReferenceCount) TryFreeze() bool { + return atomic.LoadInt32((*int32)(rf)) == ReferenceCountNoReference && atomic.CompareAndSwapInt32((*int32)(rf), ReferenceCountNoReference, ReferenceCountIsFrozen) +} + +// UnFreeze unfreeze the frozen StmtCtx thus the other session can access this StmtCtx. +func (rf *ReferenceCount) UnFreeze() { + atomic.StoreInt32((*int32)(rf), ReferenceCountNoReference) +} + // StatementContext contains variables for a statement. // It should be reset before executing a statement. type StatementContext struct { @@ -109,37 +146,37 @@ type StatementContext struct { // IsDDLJobInQueue is used to mark whether the DDL job is put into the queue. // If IsDDLJobInQueue is true, it means the DDL job is in the queue of storage, and it can be handled by the DDL worker. - IsDDLJobInQueue bool - DDLJobID int64 - InInsertStmt bool - InUpdateStmt bool - InDeleteStmt bool - InSelectStmt bool - InLoadDataStmt bool - InExplainStmt bool - InCreateOrAlterStmt bool - InSetSessionStatesStmt bool - InPreparedPlanBuilding bool - IgnoreTruncate bool - IgnoreZeroInDate bool - NoZeroDate bool - DupKeyAsWarning bool - BadNullAsWarning bool - DividedByZeroAsWarning bool - TruncateAsWarning bool - OverflowAsWarning bool - InShowWarning bool - UseCache bool - BatchCheck bool - InNullRejectCheck bool - AllowInvalidDate bool - IgnoreNoPartition bool - SkipPlanCache bool - IgnoreExplainIDSuffix bool - SkipUTF8Check bool - SkipASCIICheck bool - SkipUTF8MB4Check bool - MultiSchemaInfo *model.MultiSchemaInfo + IsDDLJobInQueue bool + DDLJobID int64 + InInsertStmt bool + InUpdateStmt bool + InDeleteStmt bool + InSelectStmt bool + InLoadDataStmt bool + InExplainStmt bool + InCreateOrAlterStmt bool + InSetSessionStatesStmt bool + InPreparedPlanBuilding bool + IgnoreTruncate bool + IgnoreZeroInDate bool + NoZeroDate bool + DupKeyAsWarning bool + BadNullAsWarning bool + DividedByZeroAsWarning bool + TruncateAsWarning bool + OverflowAsWarning bool + ErrAutoincReadFailedAsWarning bool + InShowWarning bool + UseCache bool + BatchCheck bool + InNullRejectCheck bool + AllowInvalidDate bool + IgnoreNoPartition bool + IgnoreExplainIDSuffix bool + SkipUTF8Check bool + SkipASCIICheck bool + SkipUTF8MB4Check bool + MultiSchemaInfo *model.MultiSchemaInfo // If the select statement was like 'select * from t as of timestamp ...' or in a stale read transaction // or is affected by the tidb_read_staleness session variable, then the statement will be makred as isStaleness // in stmtCtx @@ -172,11 +209,17 @@ type StatementContext struct { copied uint64 touched uint64 - message string - warnings []SQLWarn - errorCount uint16 + message string + warnings []SQLWarn + // extraWarnings record the extra warnings and are only used by the slow log only now. + // If a warning is expected to be output only under some conditions (like in EXPLAIN or EXPLAIN VERBOSE) but it's + // not under such conditions now, it is considered as an extra warning. + // extraWarnings would not be printed through SHOW WARNINGS, but we want to always output them through the slow + // log to help diagnostics, so we store them here separately. + extraWarnings []SQLWarn + execDetails execdetails.ExecDetails - allExecDetails []*execdetails.ExecDetails + allExecDetails []*execdetails.DetailsNeedP90 } // PrevAffectedRows is the affected-rows value(DDL is 0, DML is the number of affected rows). PrevAffectedRows int64 @@ -263,8 +306,6 @@ type StatementContext struct { LogOnExceed [2]memory.LogOnExceed } - // OptimInfo maps Plan.ID() to optimization information when generating Plan. - OptimInfo map[int]string // InVerboseExplain indicates the statement is "explain format='verbose' ...". InVerboseExplain bool @@ -296,8 +337,6 @@ type StatementContext struct { NeededItems []model.TableItemID // ResultCh to receive stats loading results ResultCh chan StatsLoadResult - // Fallback indicates if the planner uses full-loaded stats or fallback all to pseudo/simple. - Fallback bool // LoadStartTime is to record the load start time to calculate latency LoadStartTime time.Time } @@ -329,6 +368,28 @@ type StatementContext struct { // IsExplainAnalyzeDML is true if the statement is "explain analyze DML executors", before responding the explain // results to the client, the transaction should be committed first. See issue #37373 for more details. IsExplainAnalyzeDML bool + + // InHandleForeignKeyTrigger indicates currently are handling foreign key trigger. + InHandleForeignKeyTrigger bool + + // ForeignKeyTriggerCtx is the contain information for foreign key cascade execution. + ForeignKeyTriggerCtx struct { + // The SavepointName is use to do rollback when handle foreign key cascade failed. + SavepointName string + HasFKCascades bool + } + + // MPPQueryInfo stores some id and timestamp of current MPP query statement. + MPPQueryInfo struct { + QueryID atomic2.Uint64 + QueryTS atomic2.Uint64 + AllocatedMPPTaskID atomic2.Int64 + } + + // TableStats stores the visited runtime table stats by table id during query + TableStats map[int64]interface{} + // useChunkAlloc indicates whether statement use chunk alloc + useChunkAlloc bool } // StmtHints are SessionVars related sql hints. @@ -372,6 +433,8 @@ const ( StmtNowTsCacheKey StmtCacheKey = iota // StmtSafeTSCacheKey is a variable for safeTS calculation/cache of one stmt. StmtSafeTSCacheKey + // StmtExternalTSCacheKey is a variable for externalTS calculation/cache of one stmt. + StmtExternalTSCacheKey ) // GetOrStoreStmtCache gets the cached value of the given key if it exists, otherwise stores the value. @@ -387,6 +450,23 @@ func (sc *StatementContext) GetOrStoreStmtCache(key StmtCacheKey, value interfac return sc.stmtCache.data[key] } +// GetOrEvaluateStmtCache gets the cached value of the given key if it exists, otherwise calculate the value. +func (sc *StatementContext) GetOrEvaluateStmtCache(key StmtCacheKey, valueEvaluator func() (interface{}, error)) (interface{}, error) { + sc.stmtCache.mu.Lock() + defer sc.stmtCache.mu.Unlock() + if sc.stmtCache.data == nil { + sc.stmtCache.data = make(map[StmtCacheKey]interface{}) + } + if _, ok := sc.stmtCache.data[key]; !ok { + value, err := valueEvaluator() + if err != nil { + return nil, err + } + sc.stmtCache.data[key] = value + } + return sc.stmtCache.data[key], nil +} + // ResetInStmtCache resets the cache of given key. func (sc *StatementContext) ResetInStmtCache(key StmtCacheKey) { sc.stmtCache.mu.Lock() @@ -473,6 +553,21 @@ func (sc *StatementContext) GetResourceGroupTagger() tikvrpc.ResourceGroupTagger } } +// SetUseChunkAlloc set use chunk alloc status +func (sc *StatementContext) SetUseChunkAlloc() { + sc.useChunkAlloc = true +} + +// ClearUseChunkAlloc clear useChunkAlloc status +func (sc *StatementContext) ClearUseChunkAlloc() { + sc.useChunkAlloc = false +} + +// GetUseChunkAllocStatus returns useChunkAlloc status +func (sc *StatementContext) GetUseChunkAllocStatus() bool { + return sc.useChunkAlloc +} + // SetPlanDigest sets the normalized plan and plan digest. func (sc *StatementContext) SetPlanDigest(normalized string, planDigest *parser.Digest) { if planDigest != nil { @@ -513,6 +608,15 @@ func (sc *StatementContext) SetPlanHint(hint string) { sc.planHint = hint } +// SetSkipPlanCache sets to skip the plan cache and records the reason. +func (sc *StatementContext) SetSkipPlanCache(reason error) { + if !sc.UseCache { + return // avoid unnecessary warnings + } + sc.UseCache = false + sc.AppendWarning(reason) +} + // TableEntry presents table in db. type TableEntry struct { DB string @@ -521,6 +625,10 @@ type TableEntry struct { // AddAffectedRows adds affected rows. func (sc *StatementContext) AddAffectedRows(rows uint64) { + if sc.InHandleForeignKeyTrigger { + // For compatibility with MySQL, not add the affected row cause by the foreign key trigger. + return + } sc.mu.Lock() defer sc.mu.Unlock() sc.mu.affectedRows += rows @@ -642,9 +750,7 @@ func (sc *StatementContext) SetMessage(msg string) { func (sc *StatementContext) GetWarnings() []SQLWarn { sc.mu.Lock() defer sc.mu.Unlock() - warns := make([]SQLWarn, len(sc.mu.warnings)) - copy(warns, sc.mu.warnings) - return warns + return sc.mu.warnings } // TruncateWarnings truncates warnings begin from start and returns the truncated warnings. @@ -675,7 +781,11 @@ func (sc *StatementContext) WarningCount() uint16 { func (sc *StatementContext) NumErrorWarnings() (ec uint16, wc int) { sc.mu.Lock() defer sc.mu.Unlock() - ec = sc.mu.errorCount + for _, w := range sc.mu.warnings { + if w.Level == WarnLevelError { + ec++ + } + } wc = len(sc.mu.warnings) return } @@ -685,12 +795,6 @@ func (sc *StatementContext) SetWarnings(warns []SQLWarn) { sc.mu.Lock() defer sc.mu.Unlock() sc.mu.warnings = warns - sc.mu.errorCount = 0 - for _, w := range warns { - if w.Level == WarnLevelError { - sc.mu.errorCount++ - } - } } // AppendWarning appends a warning with level 'Warning'. @@ -726,7 +830,47 @@ func (sc *StatementContext) AppendError(warn error) { defer sc.mu.Unlock() if len(sc.mu.warnings) < math.MaxUint16 { sc.mu.warnings = append(sc.mu.warnings, SQLWarn{WarnLevelError, warn}) - sc.mu.errorCount++ + } +} + +// GetExtraWarnings gets extra warnings. +func (sc *StatementContext) GetExtraWarnings() []SQLWarn { + sc.mu.Lock() + defer sc.mu.Unlock() + return sc.mu.extraWarnings +} + +// SetExtraWarnings sets extra warnings. +func (sc *StatementContext) SetExtraWarnings(warns []SQLWarn) { + sc.mu.Lock() + defer sc.mu.Unlock() + sc.mu.extraWarnings = warns +} + +// AppendExtraWarning appends an extra warning with level 'Warning'. +func (sc *StatementContext) AppendExtraWarning(warn error) { + sc.mu.Lock() + defer sc.mu.Unlock() + if len(sc.mu.extraWarnings) < math.MaxUint16 { + sc.mu.extraWarnings = append(sc.mu.extraWarnings, SQLWarn{WarnLevelWarning, warn}) + } +} + +// AppendExtraNote appends an extra warning with level 'Note'. +func (sc *StatementContext) AppendExtraNote(warn error) { + sc.mu.Lock() + defer sc.mu.Unlock() + if len(sc.mu.extraWarnings) < math.MaxUint16 { + sc.mu.extraWarnings = append(sc.mu.extraWarnings, SQLWarn{WarnLevelNote, warn}) + } +} + +// AppendExtraError appends an extra warning with level 'Error'. +func (sc *StatementContext) AppendExtraError(warn error) { + sc.mu.Lock() + defer sc.mu.Unlock() + if len(sc.mu.extraWarnings) < math.MaxUint16 { + sc.mu.extraWarnings = append(sc.mu.extraWarnings, SQLWarn{WarnLevelError, warn}) } } @@ -737,6 +881,21 @@ func (sc *StatementContext) HandleTruncate(err error) error { if err == nil { return nil } + + err = errors.Cause(err) + if e, ok := err.(*errors.Error); !ok || + (e.Code() != errno.ErrTruncatedWrongValue && + e.Code() != errno.ErrDataTooLong && + e.Code() != errno.ErrTruncatedWrongValueForField && + e.Code() != errno.ErrWarnDataOutOfRange && + e.Code() != errno.ErrDataOutOfRange && + e.Code() != errno.ErrBadNumber && + e.Code() != errno.ErrWrongValueForType && + e.Code() != errno.ErrDatetimeFunctionOverflow && + e.Code() != errno.WarnDataTruncated) { + return err + } + if sc.IgnoreTruncate { return nil } @@ -772,10 +931,9 @@ func (sc *StatementContext) resetMuForRetry() { sc.mu.copied = 0 sc.mu.touched = 0 sc.mu.message = "" - sc.mu.errorCount = 0 sc.mu.warnings = nil sc.mu.execDetails = execdetails.ExecDetails{} - sc.mu.allExecDetails = make([]*execdetails.ExecDetails, 0, 4) + sc.mu.allExecDetails = make([]*execdetails.DetailsNeedP90, 0, 4) } // ResetForRetry resets the changed states during execution. @@ -799,7 +957,13 @@ func (sc *StatementContext) MergeExecDetails(details *execdetails.ExecDetails, c sc.mu.execDetails.RequestCount++ sc.MergeScanDetail(details.ScanDetail) sc.MergeTimeDetail(details.TimeDetail) - sc.mu.allExecDetails = append(sc.mu.allExecDetails, details) + sc.mu.allExecDetails = append(sc.mu.allExecDetails, + &execdetails.DetailsNeedP90{ + BackoffSleep: details.BackoffSleep, + BackoffTimes: details.BackoffTimes, + CalleeAddress: details.CalleeAddress, + TimeDetail: details.TimeDetail, + }) } if commitDetails != nil { if sc.mu.execDetails.CommitDetail == nil { @@ -918,14 +1082,14 @@ func (sc *StatementContext) CopTasksDetails() *CopTasksDetails { d.AvgProcessTime = sc.mu.execDetails.TimeDetail.ProcessTime / time.Duration(n) d.AvgWaitTime = sc.mu.execDetails.TimeDetail.WaitTime / time.Duration(n) - slices.SortFunc(sc.mu.allExecDetails, func(i, j *execdetails.ExecDetails) bool { + slices.SortFunc(sc.mu.allExecDetails, func(i, j *execdetails.DetailsNeedP90) bool { return i.TimeDetail.ProcessTime < j.TimeDetail.ProcessTime }) d.P90ProcessTime = sc.mu.allExecDetails[n*9/10].TimeDetail.ProcessTime d.MaxProcessTime = sc.mu.allExecDetails[n-1].TimeDetail.ProcessTime d.MaxProcessAddress = sc.mu.allExecDetails[n-1].CalleeAddress - slices.SortFunc(sc.mu.allExecDetails, func(i, j *execdetails.ExecDetails) bool { + slices.SortFunc(sc.mu.allExecDetails, func(i, j *execdetails.DetailsNeedP90) bool { return i.TimeDetail.WaitTime < j.TimeDetail.WaitTime }) d.P90WaitTime = sc.mu.allExecDetails[n*9/10].TimeDetail.WaitTime @@ -998,7 +1162,9 @@ func (sc *StatementContext) GetLockWaitStartTime() time.Time { func (sc *StatementContext) RecordRangeFallback(rangeMaxSize int64) { // If range fallback happens, it means ether the query is unreasonable(for example, several long IN lists) or tidb_opt_range_max_size is too small // and the generated plan is probably suboptimal. In that case we don't put it into plan cache. - sc.SkipPlanCache = true + if sc.UseCache { + sc.SetSkipPlanCache(errors.Errorf("skip plan-cache: in-list is too long")) + } if !sc.RangeFallback { sc.AppendWarning(errors.Errorf("Memory capacity of %v bytes for 'tidb_opt_range_max_size' exceeded when building ranges. Less accurate ranges such as full range are chosen", rangeMaxSize)) sc.RangeFallback = true diff --git a/sessionctx/stmtctx/stmtctx_test.go b/sessionctx/stmtctx/stmtctx_test.go index cc21b3e4812c7..67520c36e7b80 100644 --- a/sessionctx/stmtctx/stmtctx_test.go +++ b/sessionctx/stmtctx/stmtctx_test.go @@ -36,12 +36,14 @@ func TestCopTasksDetails(t *testing.T) { backoffs := []string{"tikvRPC", "pdRPC", "regionMiss"} for i := 0; i < 100; i++ { d := &execdetails.ExecDetails{ - CalleeAddress: fmt.Sprintf("%v", i+1), - BackoffSleep: make(map[string]time.Duration), - BackoffTimes: make(map[string]int), - TimeDetail: util.TimeDetail{ - ProcessTime: time.Second * time.Duration(i+1), - WaitTime: time.Millisecond * time.Duration(i+1), + DetailsNeedP90: execdetails.DetailsNeedP90{ + CalleeAddress: fmt.Sprintf("%v", i+1), + BackoffSleep: make(map[string]time.Duration), + BackoffTimes: make(map[string]int), + TimeDetail: util.TimeDetail{ + ProcessTime: time.Second * time.Duration(i+1), + WaitTime: time.Millisecond * time.Duration(i+1), + }, }, } for _, backoff := range backoffs { diff --git a/sessionctx/variable/BUILD.bazel b/sessionctx/variable/BUILD.bazel index 3a9eb1439ce2c..b178ccf0a95da 100644 --- a/sessionctx/variable/BUILD.bazel +++ b/sessionctx/variable/BUILD.bazel @@ -32,7 +32,7 @@ go_library( "//parser/types", "//sessionctx/sessionstates", "//sessionctx/stmtctx", - "//sessionctx/variable/featuretag/concurrencyddl", + "//sessionctx/variable/featuretag/distributereorg", "//tidb-binlog/pump_client", "//types", "//types/parser_driver", @@ -40,6 +40,7 @@ go_library( "//util/chunk", "//util/collate", "//util/dbterror", + "//util/disk", "//util/execdetails", "//util/gctuner", "//util/kvcache", @@ -47,7 +48,9 @@ go_library( "//util/mathutil", "//util/memory", "//util/paging", + "//util/replayer", "//util/rowcodec", + "//util/size", "//util/stmtsummary", "//util/stringutil", "//util/tableutil", @@ -83,6 +86,7 @@ go_test( ], embed = [":variable"], flaky = True, + shard_count = 2, deps = [ "//config", "//kv", @@ -95,8 +99,12 @@ go_test( "//testkit", "//testkit/testsetup", "//types", + "//util/chunk", "//util/execdetails", + "//util/gctuner", + "//util/memory", "//util/mock", + "@com_github_pingcap_failpoint//:failpoint", "@com_github_stretchr_testify//require", "@com_github_tikv_client_go_v2//util", "@io_opencensus_go//stats/view", diff --git a/sessionctx/variable/error.go b/sessionctx/variable/error.go index 60928932f0f06..f760cba8bfcd5 100644 --- a/sessionctx/variable/error.go +++ b/sessionctx/variable/error.go @@ -39,6 +39,7 @@ var ( errLocalVariable = dbterror.ClassVariable.NewStd(mysql.ErrLocalVariable) errValueNotSupportedWhen = dbterror.ClassVariable.NewStdErr(mysql.ErrNotSupportedYet, pmysql.Message("%s = OFF is not supported when %s = ON", nil)) ErrStmtNotFound = dbterror.ClassOptimizer.NewStd(mysql.ErrPreparedStmtNotFound) + ErrNotValidPassword = dbterror.ClassExecutor.NewStd(mysql.ErrNotValidPassword) // ErrFunctionsNoopImpl is an error to say the behavior is protected by the tidb_enable_noop_functions sysvar. // This is copied from expression.ErrFunctionsNoopImpl to prevent circular dependencies. // It needs to be public for tests. diff --git a/sessionctx/variable/featuretag/concurrencyddl/BUILD.bazel b/sessionctx/variable/featuretag/distributereorg/BUILD.bazel similarity index 80% rename from sessionctx/variable/featuretag/concurrencyddl/BUILD.bazel rename to sessionctx/variable/featuretag/distributereorg/BUILD.bazel index 44c1cede3c2b7..153ce052ecbb2 100644 --- a/sessionctx/variable/featuretag/concurrencyddl/BUILD.bazel +++ b/sessionctx/variable/featuretag/distributereorg/BUILD.bazel @@ -1,11 +1,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( - name = "concurrencyddl", + name = "distributereorg", srcs = [ "default.go", "non_default.go", ], - importpath = "github.com/pingcap/tidb/sessionctx/variable/featuretag/concurrencyddl", + importpath = "github.com/pingcap/tidb/sessionctx/variable/featuretag/distributereorg", visibility = ["//visibility:public"], ) diff --git a/sessionctx/variable/featuretag/concurrencyddl/default.go b/sessionctx/variable/featuretag/distributereorg/default.go similarity index 84% rename from sessionctx/variable/featuretag/concurrencyddl/default.go rename to sessionctx/variable/featuretag/distributereorg/default.go index 8aca4924268f0..910629adde825 100644 --- a/sessionctx/variable/featuretag/concurrencyddl/default.go +++ b/sessionctx/variable/featuretag/distributereorg/default.go @@ -14,7 +14,7 @@ //go:build !featuretag -package concurrencyddl +package distributereorg -// TiDBEnableConcurrentDDL is a feature tag -const TiDBEnableConcurrentDDL bool = true +// TiDBEnableDistributeReorg is a feature tag +const TiDBEnableDistributeReorg bool = false diff --git a/sessionctx/variable/featuretag/concurrencyddl/non_default.go b/sessionctx/variable/featuretag/distributereorg/non_default.go similarity index 84% rename from sessionctx/variable/featuretag/concurrencyddl/non_default.go rename to sessionctx/variable/featuretag/distributereorg/non_default.go index 72218abe958a3..f6286ba5b3409 100644 --- a/sessionctx/variable/featuretag/concurrencyddl/non_default.go +++ b/sessionctx/variable/featuretag/distributereorg/non_default.go @@ -14,7 +14,7 @@ //go:build featuretag -package concurrencyddl +package distributereorg -// TiDBEnableConcurrentDDL is a feature tag -const TiDBEnableConcurrentDDL bool = false +// TiDBEnableDistributeReorg is a feature tag +const TiDBEnableDistributeReorg bool = true diff --git a/sessionctx/variable/main_test.go b/sessionctx/variable/main_test.go index f3edec39107f0..c5eca2f3d1658 100644 --- a/sessionctx/variable/main_test.go +++ b/sessionctx/variable/main_test.go @@ -25,7 +25,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/sessionctx/variable/mock_globalaccessor.go b/sessionctx/variable/mock_globalaccessor.go index c4bb86748e9fd..5477c054257e4 100644 --- a/sessionctx/variable/mock_globalaccessor.go +++ b/sessionctx/variable/mock_globalaccessor.go @@ -14,6 +14,8 @@ package variable +import "context" + // MockGlobalAccessor implements GlobalVarAccessor interface. it's used in tests type MockGlobalAccessor struct { SessionVars *SessionVars // can be overwritten if needed for correctness. @@ -69,7 +71,7 @@ func (m *MockGlobalAccessor) GetGlobalSysVar(name string) (string, error) { } // SetGlobalSysVar implements GlobalVarAccessor.SetGlobalSysVar interface. -func (m *MockGlobalAccessor) SetGlobalSysVar(name string, value string) (err error) { +func (m *MockGlobalAccessor) SetGlobalSysVar(ctx context.Context, name string, value string) (err error) { sv := GetSysVar(name) if sv == nil { return ErrUnknownSystemVar.GenWithStackByArgs(name) @@ -77,7 +79,7 @@ func (m *MockGlobalAccessor) SetGlobalSysVar(name string, value string) (err err if value, err = sv.Validate(m.SessionVars, value, ScopeGlobal); err != nil { return err } - if err = sv.SetGlobalFromHook(m.SessionVars, value, false); err != nil { + if err = sv.SetGlobalFromHook(ctx, m.SessionVars, value, false); err != nil { return err } m.vals[name] = value @@ -85,7 +87,7 @@ func (m *MockGlobalAccessor) SetGlobalSysVar(name string, value string) (err err } // SetGlobalSysVarOnly implements GlobalVarAccessor.SetGlobalSysVarOnly interface. -func (m *MockGlobalAccessor) SetGlobalSysVarOnly(name string, value string) error { +func (m *MockGlobalAccessor) SetGlobalSysVarOnly(ctx context.Context, name string, value string, _ bool) error { sv := GetSysVar(name) if sv == nil { return ErrUnknownSystemVar.GenWithStackByArgs(name) diff --git a/sessionctx/variable/mock_globalaccessor_test.go b/sessionctx/variable/mock_globalaccessor_test.go index 57ed4931a342d..76f4b1d39b608 100644 --- a/sessionctx/variable/mock_globalaccessor_test.go +++ b/sessionctx/variable/mock_globalaccessor_test.go @@ -15,6 +15,7 @@ package variable import ( + "context" "testing" "github.com/stretchr/testify/require" @@ -33,19 +34,19 @@ func TestMockAPI(t *testing.T) { require.Error(t, err) // invalid option name - err = mock.SetGlobalSysVar("illegalopt", "val") + err = mock.SetGlobalSysVar(context.Background(), "illegalopt", "val") require.Error(t, err) - err = mock.SetGlobalSysVarOnly("illegalopt", "val") + err = mock.SetGlobalSysVarOnly(context.Background(), "illegalopt", "val", true) require.Error(t, err) // valid option, invalid value - err = mock.SetGlobalSysVar(DefaultAuthPlugin, "invalidvalue") + err = mock.SetGlobalSysVar(context.Background(), DefaultAuthPlugin, "invalidvalue") require.Error(t, err) // valid option, valid value - err = mock.SetGlobalSysVar(DefaultAuthPlugin, "mysql_native_password") + err = mock.SetGlobalSysVar(context.Background(), DefaultAuthPlugin, "mysql_native_password") require.NoError(t, err) - err = mock.SetGlobalSysVarOnly(DefaultAuthPlugin, "mysql_native_password") + err = mock.SetGlobalSysVarOnly(context.Background(), DefaultAuthPlugin, "mysql_native_password", true) require.NoError(t, err) // Test GetTiDBTableValue diff --git a/sessionctx/variable/noop.go b/sessionctx/variable/noop.go index 398ea09f3ec92..4c61a88c51820 100644 --- a/sessionctx/variable/noop.go +++ b/sessionctx/variable/noop.go @@ -58,8 +58,6 @@ var noopSysVars = []*SysVar{ {Scope: ScopeGlobal | ScopeSession, Name: BigTables, Value: Off, Type: TypeBool}, {Scope: ScopeNone, Name: "skip_external_locking", Value: "1"}, {Scope: ScopeNone, Name: "innodb_sync_array_size", Value: "1"}, - {Scope: ScopeGlobal, Name: ValidatePasswordCheckUserName, Value: Off, Type: TypeBool}, - {Scope: ScopeGlobal, Name: ValidatePasswordNumberCount, Value: "1", Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxUint64}, {Scope: ScopeSession, Name: "gtid_next", Value: ""}, {Scope: ScopeGlobal, Name: "ndb_show_foreign_key_mock_tables", Value: ""}, {Scope: ScopeNone, Name: "multi_range_count", Value: "256"}, @@ -117,7 +115,6 @@ var noopSysVars = []*SysVar{ {Scope: ScopeNone, Name: "innodb_log_group_home_dir", Value: "./"}, {Scope: ScopeNone, Name: "performance_schema_events_statements_history_size", Value: "10"}, {Scope: ScopeGlobal, Name: GeneralLog, Value: Off, Type: TypeBool}, - {Scope: ScopeGlobal, Name: "validate_password_dictionary_file", Value: ""}, {Scope: ScopeGlobal, Name: BinlogOrderCommits, Value: On, Type: TypeBool}, {Scope: ScopeGlobal, Name: "key_cache_division_limit", Value: "100"}, {Scope: ScopeGlobal | ScopeSession, Name: "max_insert_delayed_threads", Value: "20"}, @@ -170,11 +167,10 @@ var noopSysVars = []*SysVar{ {Scope: ScopeGlobal | ScopeSession, Name: MaxUserConnections, Value: "0", Type: TypeUnsigned, MinValue: 0, MaxValue: 4294967295}, {Scope: ScopeNone, Name: "performance_schema_max_thread_classes", Value: "50"}, {Scope: ScopeGlobal, Name: "innodb_api_trx_level", Value: "0"}, - {Scope: ScopeNone, Name: "disconnect_on_expired_password", Value: "1"}, {Scope: ScopeNone, Name: "performance_schema_max_file_classes", Value: "50"}, {Scope: ScopeGlobal, Name: "expire_logs_days", Value: "0"}, {Scope: ScopeGlobal | ScopeSession, Name: BinlogRowQueryLogEvents, Value: Off, Type: TypeBool}, - {Scope: ScopeGlobal, Name: "default_password_lifetime", Value: ""}, + {Scope: ScopeGlobal, Name: DefaultPasswordLifetime, Value: "0", Type: TypeInt, MinValue: 0, MaxValue: math.MaxUint16}, {Scope: ScopeNone, Name: "pid_file", Value: "/usr/local/mysql/data/localhost.pid"}, {Scope: ScopeNone, Name: "innodb_undo_tablespaces", Value: "0"}, {Scope: ScopeGlobal, Name: InnodbStatusOutputLocks, Value: Off, Type: TypeBool, AutoConvertNegativeBool: true}, @@ -463,7 +459,6 @@ var noopSysVars = []*SysVar{ {Scope: ScopeGlobal | ScopeSession, Name: "eq_range_index_dive_limit", Value: "200", IsHintUpdatable: true}, {Scope: ScopeNone, Name: "performance_schema_events_stages_history_size", Value: "10"}, {Scope: ScopeGlobal | ScopeSession, Name: "ndb_join_pushdown", Value: ""}, - {Scope: ScopeGlobal, Name: "validate_password_special_char_count", Value: "1"}, {Scope: ScopeNone, Name: "performance_schema_max_thread_instances", Value: "402"}, {Scope: ScopeGlobal | ScopeSession, Name: "ndbinfo_show_hidden", Value: ""}, {Scope: ScopeGlobal | ScopeSession, Name: "net_read_timeout", Value: "30"}, @@ -472,7 +467,6 @@ var noopSysVars = []*SysVar{ {Scope: ScopeGlobal, Name: "sync_relay_log_info", Value: "10000"}, {Scope: ScopeGlobal | ScopeSession, Name: "optimizer_trace_limit", Value: "1"}, {Scope: ScopeNone, Name: "innodb_ft_max_token_size", Value: "84"}, - {Scope: ScopeGlobal, Name: ValidatePasswordLength, Value: "8", Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxUint64}, {Scope: ScopeGlobal, Name: "ndb_log_binlog_index", Value: ""}, {Scope: ScopeGlobal, Name: "innodb_api_bk_commit_interval", Value: "5"}, {Scope: ScopeNone, Name: "innodb_undo_directory", Value: "."}, diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index 4d3d16f351965..0b6e7ef0cb0d0 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -19,6 +19,7 @@ import ( "context" "crypto/tls" "encoding/binary" + "encoding/json" "fmt" "math" "math/rand" @@ -46,9 +47,12 @@ import ( pumpcli "github.com/pingcap/tidb/tidb-binlog/pump_client" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/disk" "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/kvcache" "github.com/pingcap/tidb/util/mathutil" + "github.com/pingcap/tidb/util/memory" + "github.com/pingcap/tidb/util/replayer" "github.com/pingcap/tidb/util/rowcodec" "github.com/pingcap/tidb/util/stringutil" "github.com/pingcap/tidb/util/tableutil" @@ -94,6 +98,12 @@ type RetryInfo struct { LastRcReadTS uint64 } +// ReuseChunkPool save Alloc object +type ReuseChunkPool struct { + mu sync.Mutex + Alloc chunk.Allocator +} + // Clean does some clean work. func (r *RetryInfo) Clean() { r.autoIncrementIDs.clean() @@ -188,7 +198,6 @@ type TxnCtxNoNeedToRestore struct { ShardStep int shardRemain int currentShard int64 - shardRand *rand.Rand // unchangedRowKeys is used to store the unchanged rows that needs to lock for pessimistic transaction. unchangedRowKeys map[string]struct{} @@ -238,21 +247,22 @@ type SavepointRecord struct { } // GetCurrentShard returns the shard for the next `count` IDs. -func (tc *TransactionContext) GetCurrentShard(count int) int64 { - if tc.shardRand == nil { - tc.shardRand = rand.New(rand.NewSource(int64(tc.StartTS))) // #nosec G404 +func (s *SessionVars) GetCurrentShard(count int) int64 { + tc := s.TxnCtx + if s.shardRand == nil { + s.shardRand = rand.New(rand.NewSource(int64(tc.StartTS))) // #nosec G404 } if tc.shardRemain <= 0 { - tc.updateShard() + tc.updateShard(s.shardRand) tc.shardRemain = tc.ShardStep } tc.shardRemain -= count return tc.currentShard } -func (tc *TransactionContext) updateShard() { +func (tc *TransactionContext) updateShard(shardRand *rand.Rand) { var buf [8]byte - binary.LittleEndian.PutUint64(buf[:], tc.shardRand.Uint64()) + binary.LittleEndian.PutUint64(buf[:], shardRand.Uint64()) tc.currentShard = int64(murmur3.Sum32(buf[:])) } @@ -630,8 +640,8 @@ type SessionVars struct { SysWarningCount int // SysErrorCount is the system variable "error_count", because it is on the hot path, so we extract it from the systems SysErrorCount uint16 - // generalPlanCacheStmts stores PlanCacheStmts for general plan cache. - generalPlanCacheStmts *kvcache.SimpleLRUCache + // nonPreparedPlanCacheStmts stores PlanCacheStmts for non-prepared plan cache. + nonPreparedPlanCacheStmts *kvcache.SimpleLRUCache // PreparedStmts stores prepared statement. PreparedStmts map[uint32]interface{} PreparedStmtNameToID map[string]uint32 @@ -662,13 +672,6 @@ type SessionVars struct { value string } - // mppTaskIDAllocator is used to allocate mpp task id for a session. - mppTaskIDAllocator struct { - mu sync.Mutex - lastTS uint64 - taskID int64 - } - // Status stands for the session status. e.g. in transaction or not, auto commit is on or off, and so on. Status uint16 @@ -734,6 +737,11 @@ type SessionVars struct { // StmtCtx holds variables for current executing statement. StmtCtx *stmtctx.StatementContext + // RefCountOfStmtCtx indicates the reference count of StmtCtx. When the + // StmtCtx is accessed by other sessions, e.g. oom-alarm-handler/expensive-query-handler, add one first. + // Note: this variable should be accessed and updated by atomic operations. + RefCountOfStmtCtx stmtctx.ReferenceCount + // AllowAggPushDown can be set to false to forbid aggregation push down. AllowAggPushDown bool @@ -1033,6 +1041,10 @@ type SessionVars struct { // MetricSchemaStep indicates the step when query metric schema. MetricSchemaStep int64 + + // CDCWriteSource indicates the following data is written by TiCDC if it is not 0. + CDCWriteSource uint64 + // MetricSchemaRangeDuration indicates the step when query metric schema. MetricSchemaRangeDuration int64 @@ -1084,9 +1096,6 @@ type SessionVars struct { // ShardAllocateStep indicates the max size of continuous rowid shard in one transaction. ShardAllocateStep int64 - // EnableAmendPessimisticTxn indicates if schema change amend is enabled for pessimistic transactions. - EnableAmendPessimisticTxn bool - // LastTxnInfo keeps track the info of last committed transaction. LastTxnInfo string @@ -1153,20 +1162,14 @@ type SessionVars struct { // TemporaryTableData stores committed kv values for temporary table for current session. TemporaryTableData TemporaryTableData - // MPPStoreLastFailTime records the lastest fail time that a TiFlash store failed. It maps store address(string) to fail time(time.Time). - MPPStoreLastFailTime *sync.Map - // MPPStoreFailTTL indicates the duration that protect TiDB from sending task to a new recovered TiFlash. MPPStoreFailTTL string // ReadStaleness indicates the staleness duration for the following query ReadStaleness time.Duration - // cached is used to optimze the object allocation. - cached struct { - curr int8 - data [2]stmtctx.StatementContext - } + // cachedStmtCtx is used to optimze the object allocation. + cachedStmtCtx [2]stmtctx.StatementContext // Rng stores the rand_seed1 and rand_seed2 for Rand() function Rng *mathutil.MysqlRng @@ -1196,6 +1199,9 @@ type SessionVars struct { EnableNewCostInterface bool // CostModelVersion is a internal switch to indicates the Cost Model Version. CostModelVersion int + // IndexJoinDoubleReadPenaltyCostRate indicates whether to add some penalty cost to IndexJoin and how much of it. + IndexJoinDoubleReadPenaltyCostRate float64 + // BatchPendingTiFlashCount shows the threshold of pending TiFlash tables when batch adding. BatchPendingTiFlashCount int // RcWriteCheckTS indicates whether some special write statements don't get latest tso from PD at RC @@ -1241,14 +1247,17 @@ type SessionVars struct { // EnablePreparedPlanCache indicates whether to enable prepared plan cache. EnablePreparedPlanCache bool - // GeneralPlanCacheSize controls the size of general plan cache. + // PreparedPlanCacheSize controls the size of prepared plan cache. PreparedPlanCacheSize uint64 - // EnableGeneralPlanCache indicates whether to enable general plan cache. - EnableGeneralPlanCache bool + // PreparedPlanCacheMonitor indicates whether to enable prepared plan cache monitor. + EnablePreparedPlanCacheMemoryMonitor bool + + // EnableNonPreparedPlanCache indicates whether to enable non-prepared plan cache. + EnableNonPreparedPlanCache bool - // GeneralPlanCacheSize controls the size of general plan cache. - GeneralPlanCacheSize uint64 + // NonPreparedPlanCacheSize controls the size of non-prepared plan cache. + NonPreparedPlanCacheSize uint64 // ConstraintCheckInPlacePessimistic controls whether to skip the locking of some keys in pessimistic transactions. // Postpone the conflict check and constraint check to prewrite or later pessimistic locking requests. @@ -1271,7 +1280,140 @@ type SessionVars struct { // LastPlanReplayerToken indicates the last plan replayer token LastPlanReplayerToken string + // AnalyzePartitionConcurrency indicates concurrency for partitions in Analyze + AnalyzePartitionConcurrency int + // AnalyzePartitionMergeConcurrency indicates concurrency for merging partition stats + AnalyzePartitionMergeConcurrency int + + // EnableExternalTSRead indicates whether to enable read through external ts + EnableExternalTSRead bool + HookContext + + // MemTracker indicates the memory tracker of current session. + MemTracker *memory.Tracker + // MemDBDBFootprint tracks the memory footprint of memdb, and is attached to `MemTracker` + MemDBFootprint *memory.Tracker + DiskTracker *memory.Tracker + + // OptPrefixIndexSingleScan indicates whether to do some optimizations to avoid double scan for prefix index. + // When set to true, `col is (not) null`(`col` is index prefix column) is regarded as index filter rather than table filter. + OptPrefixIndexSingleScan bool + + // ChunkPool Several chunks and columns are cached + ChunkPool ReuseChunkPool + // EnableReuseCheck indicates request chunk whether use chunk alloc + EnableReuseCheck bool + + // preuseChunkAlloc indicates whether pre statement use chunk alloc + // like select @@last_sql_use_alloc + preUseChunkAlloc bool + + // EnablePlanReplayerCapture indicates whether enabled plan replayer capture + EnablePlanReplayerCapture bool + + // EnablePlanReplayedContinuesCapture indicates whether enabled plan replayer continues capture + EnablePlanReplayedContinuesCapture bool + + // PlanReplayerFinishedTaskKey used to record the finished plan replayer task key in order not to record the + // duplicate task in plan replayer continues capture + PlanReplayerFinishedTaskKey map[replayer.PlanReplayerTaskKey]struct{} + + // StoreBatchSize indicates the batch size limit of store batch, set this field to 0 to disable store batch. + StoreBatchSize int + + // shardRand is used by TxnCtx, for the GetCurrentShard() method. + shardRand *rand.Rand + + // Resource group name + ResourceGroupName string + + // ProtectedTSList holds a list of timestamps that should delay GC. + ProtectedTSList protectedTSList + + // PessimisticTransactionAggressiveLocking controls whether aggressive locking for pessimistic transaction + // is enabled. + PessimisticTransactionAggressiveLocking bool +} + +// planReplayerSessionFinishedTaskKeyLen is used to control the max size for the finished plan replayer task key in session +// in order to control the used memory +const planReplayerSessionFinishedTaskKeyLen = 128 + +// AddPlanReplayerFinishedTaskKey record finished task key in session +func (s *SessionVars) AddPlanReplayerFinishedTaskKey(key replayer.PlanReplayerTaskKey) { + if len(s.PlanReplayerFinishedTaskKey) >= planReplayerSessionFinishedTaskKeyLen { + s.initializePlanReplayerFinishedTaskKey() + } + s.PlanReplayerFinishedTaskKey[key] = struct{}{} +} + +func (s *SessionVars) initializePlanReplayerFinishedTaskKey() { + s.PlanReplayerFinishedTaskKey = make(map[replayer.PlanReplayerTaskKey]struct{}, planReplayerSessionFinishedTaskKeyLen) +} + +// CheckPlanReplayerFinishedTaskKey check whether the key exists +func (s *SessionVars) CheckPlanReplayerFinishedTaskKey(key replayer.PlanReplayerTaskKey) bool { + if s.PlanReplayerFinishedTaskKey == nil { + s.initializePlanReplayerFinishedTaskKey() + return false + } + _, ok := s.PlanReplayerFinishedTaskKey[key] + return ok +} + +// IsPlanReplayerCaptureEnabled indicates whether capture or continues capture enabled +func (s *SessionVars) IsPlanReplayerCaptureEnabled() bool { + return s.EnablePlanReplayerCapture || s.EnablePlanReplayedContinuesCapture +} + +// GetNewChunkWithCapacity Attempt to request memory from the chunk pool +// thread safety +func (s *SessionVars) GetNewChunkWithCapacity(fields []*types.FieldType, capacity int, maxCachesize int, pool chunk.Allocator) *chunk.Chunk { + if pool == nil { + return chunk.New(fields, capacity, maxCachesize) + } + s.ChunkPool.mu.Lock() + defer s.ChunkPool.mu.Unlock() + if pool.CheckReuseAllocSize() && (!s.GetUseChunkAlloc()) { + s.StmtCtx.SetUseChunkAlloc() + } + chk := pool.Alloc(fields, capacity, maxCachesize) + return chk +} + +// ExchangeChunkStatus give the status to preUseChunkAlloc +func (s *SessionVars) ExchangeChunkStatus() { + s.preUseChunkAlloc = s.GetUseChunkAlloc() +} + +// GetUseChunkAlloc return useChunkAlloc status +func (s *SessionVars) GetUseChunkAlloc() bool { + return s.StmtCtx.GetUseChunkAllocStatus() +} + +// SetAlloc Attempt to set the buffer pool address +func (s *SessionVars) SetAlloc(alloc chunk.Allocator) { + if !s.EnableReuseCheck { + return + } + s.ChunkPool.Alloc = alloc +} + +// ClearAlloc indicates stop reuse chunk +func (s *SessionVars) ClearAlloc(alloc *chunk.Allocator, b bool) { + if !b { + s.ChunkPool.Alloc = nil + return + } + + // If an error is reported, re-apply for alloc + // Prevent the goroutine left before, affecting the execution of the next sql + // issuse 38918 + s.ChunkPool.mu.Lock() + s.ChunkPool.Alloc = nil + s.ChunkPool.mu.Unlock() + *alloc = chunk.NewAllocator() } // GetPreparedStmtByName returns the prepared statement specified by stmtName. @@ -1294,23 +1436,17 @@ func (s *SessionVars) GetPreparedStmtByID(stmtID uint32) (interface{}, error) { // InitStatementContext initializes a StatementContext, the object is reused to reduce allocation. func (s *SessionVars) InitStatementContext() *stmtctx.StatementContext { - s.cached.curr = (s.cached.curr + 1) % 2 - s.cached.data[s.cached.curr] = stmtctx.StatementContext{} - return &s.cached.data[s.cached.curr] -} - -// AllocMPPTaskID allocates task id for mpp tasks. It will reset the task id if the query's -// startTs is different. -func (s *SessionVars) AllocMPPTaskID(startTS uint64) int64 { - s.mppTaskIDAllocator.mu.Lock() - defer s.mppTaskIDAllocator.mu.Unlock() - if s.mppTaskIDAllocator.lastTS == startTS { - s.mppTaskIDAllocator.taskID++ - return s.mppTaskIDAllocator.taskID + sc := &s.cachedStmtCtx[0] + if sc == s.StmtCtx { + sc = &s.cachedStmtCtx[1] + } + if s.RefCountOfStmtCtx.TryFreeze() { + *sc = stmtctx.StatementContext{} + s.RefCountOfStmtCtx.UnFreeze() + } else { + sc = &stmtctx.StatementContext{} } - s.mppTaskIDAllocator.lastTS = startTS - s.mppTaskIDAllocator.taskID = 1 - return 1 + return sc } // IsMPPAllowed returns whether mpp execution is allowed. @@ -1327,8 +1463,13 @@ func (s *SessionVars) IsMPPEnforced() bool { // TODO: Confirm whether this function will be inlined and // omit the overhead of string construction when calling with false condition. func (s *SessionVars) RaiseWarningWhenMPPEnforced(warning string) { - if s.IsMPPEnforced() && s.StmtCtx.InExplainStmt { + if !s.IsMPPEnforced() { + return + } + if s.StmtCtx.InExplainStmt { s.StmtCtx.AppendWarning(errors.New(warning)) + } else { + s.StmtCtx.AppendExtraWarning(errors.New(warning)) } } @@ -1431,6 +1572,7 @@ type ConnectionInfo struct { ClientIP string ClientPort string ServerID int + ServerIP string ServerPort int Duration float64 User string @@ -1540,7 +1682,6 @@ func NewSessionVars(hctx HookContext) *SessionVars { EnableClusteredIndex: DefTiDBEnableClusteredIndex, EnableParallelApply: DefTiDBEnableParallelApply, ShardAllocateStep: DefTiDBShardAllocateStep, - EnableAmendPessimisticTxn: DefTiDBEnableAmendPessimisticTxn, PartitionPruneMode: *atomic2.NewString(DefTiDBPartitionPruneMode), TxnScope: kv.NewDefaultTxnScopeVar(), EnabledRateLimitAction: DefTiDBEnableRateLimitAction, @@ -1552,7 +1693,6 @@ func NewSessionVars(hctx HookContext) *SessionVars { AllowFallbackToTiKV: make(map[kv.StoreType]struct{}), CTEMaxRecursionDepth: DefCTEMaxRecursionDepth, TMPTableSize: DefTiDBTmpTableMaxSize, - MPPStoreLastFailTime: new(sync.Map), MPPStoreFailTTL: DefTiDBMPPStoreFailTTL, Rng: mathutil.NewWithTime(), StatsLoadSyncWait: StatsLoadSyncWait.Load(), @@ -1565,21 +1705,25 @@ func NewSessionVars(hctx HookContext) *SessionVars { EnableTiFlashReadForWriteStmt: DefTiDBEnableTiFlashReadForWriteStmt, ForeignKeyChecks: DefTiDBForeignKeyChecks, HookContext: hctx, + EnableReuseCheck: DefTiDBEnableReusechunk, + preUseChunkAlloc: DefTiDBUseAlloc, + ChunkPool: ReuseChunkPool{Alloc: nil}, } vars.KVVars = tikvstore.NewVariables(&vars.Killed) vars.Concurrency = Concurrency{ - indexLookupConcurrency: DefIndexLookupConcurrency, - indexSerialScanConcurrency: DefIndexSerialScanConcurrency, - indexLookupJoinConcurrency: DefIndexLookupJoinConcurrency, - hashJoinConcurrency: DefTiDBHashJoinConcurrency, - projectionConcurrency: DefTiDBProjectionConcurrency, - distSQLScanConcurrency: DefDistSQLScanConcurrency, - hashAggPartialConcurrency: DefTiDBHashAggPartialConcurrency, - hashAggFinalConcurrency: DefTiDBHashAggFinalConcurrency, - windowConcurrency: DefTiDBWindowConcurrency, - mergeJoinConcurrency: DefTiDBMergeJoinConcurrency, - streamAggConcurrency: DefTiDBStreamAggConcurrency, - ExecutorConcurrency: DefExecutorConcurrency, + indexLookupConcurrency: DefIndexLookupConcurrency, + indexSerialScanConcurrency: DefIndexSerialScanConcurrency, + indexLookupJoinConcurrency: DefIndexLookupJoinConcurrency, + hashJoinConcurrency: DefTiDBHashJoinConcurrency, + projectionConcurrency: DefTiDBProjectionConcurrency, + distSQLScanConcurrency: DefDistSQLScanConcurrency, + hashAggPartialConcurrency: DefTiDBHashAggPartialConcurrency, + hashAggFinalConcurrency: DefTiDBHashAggFinalConcurrency, + windowConcurrency: DefTiDBWindowConcurrency, + mergeJoinConcurrency: DefTiDBMergeJoinConcurrency, + streamAggConcurrency: DefTiDBStreamAggConcurrency, + indexMergeIntersectionConcurrency: DefTiDBIndexMergeIntersectionConcurrency, + ExecutorConcurrency: DefExecutorConcurrency, } vars.MemQuota = MemQuota{ MemQuotaQuery: DefTiDBMemQuotaQuery, @@ -1600,6 +1744,9 @@ func NewSessionVars(hctx HookContext) *SessionVars { vars.enforceMPPExecution = DefTiDBEnforceMPPExecution vars.TiFlashMaxThreads = DefTiFlashMaxThreads vars.MPPStoreFailTTL = DefTiDBMPPStoreFailTTL + vars.DiskTracker = disk.NewTracker(memory.LabelForSession, -1) + vars.MemTracker = memory.NewTracker(memory.LabelForSession, vars.MemQuotaQuery) + vars.MemTracker.IsRootTrackerOfSess = true for _, engine := range config.GetGlobalConfig().IsolationRead.Engines { switch engine { @@ -1740,7 +1887,7 @@ func (s *SessionVars) GetCharsetInfo() (charset, collation string) { // GetParseParams gets the parse parameters from session variables. func (s *SessionVars) GetParseParams() []parser.ParseParam { chs, coll := s.GetCharsetInfo() - cli, err := s.GetSessionOrGlobalSystemVar(CharacterSetClient) + cli, err := s.GetSessionOrGlobalSystemVar(context.Background(), CharacterSetClient) if err != nil { cli = "" } @@ -1917,31 +2064,27 @@ func (k planCacheStmtKey) Hash() []byte { return []byte(k) } -// AddGeneralPlanCacheStmt adds this PlanCacheStmt into general-plan-cache-stmt cache -func (s *SessionVars) AddGeneralPlanCacheStmt(sql string, stmt interface{}) { - if s.generalPlanCacheStmts == nil { - s.generalPlanCacheStmts = kvcache.NewSimpleLRUCache(uint(s.GeneralPlanCacheSize), 0, 0) +// AddNonPreparedPlanCacheStmt adds this PlanCacheStmt into non-preapred plan-cache stmt cache +func (s *SessionVars) AddNonPreparedPlanCacheStmt(sql string, stmt interface{}) { + if s.nonPreparedPlanCacheStmts == nil { + s.nonPreparedPlanCacheStmts = kvcache.NewSimpleLRUCache(uint(s.NonPreparedPlanCacheSize), 0, 0) } - s.generalPlanCacheStmts.Put(planCacheStmtKey(sql), stmt) + s.nonPreparedPlanCacheStmts.Put(planCacheStmtKey(sql), stmt) } -// GetGeneralPlanCacheStmt gets the PlanCacheStmt. -func (s *SessionVars) GetGeneralPlanCacheStmt(sql string) interface{} { - if s.generalPlanCacheStmts == nil { +// GetNonPreparedPlanCacheStmt gets the PlanCacheStmt. +func (s *SessionVars) GetNonPreparedPlanCacheStmt(sql string) interface{} { + if s.nonPreparedPlanCacheStmts == nil { return nil } - stmt, _ := s.generalPlanCacheStmts.Get(planCacheStmtKey(sql)) + stmt, _ := s.nonPreparedPlanCacheStmts.Get(planCacheStmtKey(sql)) return stmt } // AddPreparedStmt adds prepareStmt to current session and count in global. func (s *SessionVars) AddPreparedStmt(stmtID uint32, stmt interface{}) error { if _, exists := s.PreparedStmts[stmtID]; !exists { - valStr, _ := s.GetSystemVar(MaxPreparedStmtCount) - maxPreparedStmtCount, err := strconv.ParseInt(valStr, 10, 64) - if err != nil { - maxPreparedStmtCount = DefMaxPreparedStmtCount - } + maxPreparedStmtCount := MaxPreparedStmtCountValue.Load() newPreparedStmtCount := atomic.AddInt64(&PreparedStmtCount, 1) if maxPreparedStmtCount >= 0 && newPreparedStmtCount > maxPreparedStmtCount { atomic.AddInt64(&PreparedStmtCount, -1) @@ -1988,7 +2131,7 @@ func (s *SessionVars) ClearStmtVars() { // GetSessionOrGlobalSystemVar gets a system variable. // If it is a session only variable, use the default value defined in code. // Returns error if there is no such variable. -func (s *SessionVars) GetSessionOrGlobalSystemVar(name string) (string, error) { +func (s *SessionVars) GetSessionOrGlobalSystemVar(ctx context.Context, name string) (string, error) { sv := GetSysVar(name) if sv == nil { return "", ErrUnknownSystemVar.GenWithStackByArgs(name) @@ -2014,7 +2157,7 @@ func (s *SessionVars) GetSessionOrGlobalSystemVar(name string) (string, error) { } return sv.GetSessionFromHook(s) } - return sv.GetGlobalFromHook(s) + return sv.GetGlobalFromHook(ctx, s) } // GetSessionStatesSystemVar gets the session variable value for session states. @@ -2041,12 +2184,12 @@ func (s *SessionVars) GetSessionStatesSystemVar(name string) (string, bool, erro } // GetGlobalSystemVar gets a global system variable. -func (s *SessionVars) GetGlobalSystemVar(name string) (string, error) { +func (s *SessionVars) GetGlobalSystemVar(ctx context.Context, name string) (string, error) { sv := GetSysVar(name) if sv == nil { return "", ErrUnknownSystemVar.GenWithStackByArgs(name) } - return sv.GetGlobalFromHook(s) + return sv.GetGlobalFromHook(ctx, s) } // SetStmtVar sets system variable and updates SessionVars states. @@ -2172,12 +2315,6 @@ func (s *SessionVars) EncodeSessionStates(ctx context.Context, sessionStates *se } sessionStates.LastFoundRows = s.LastFoundRows sessionStates.SequenceLatestValues = s.SequenceState.GetAllStates() - sessionStates.MPPStoreLastFailTime = make(map[string]time.Time, 0) - s.MPPStoreLastFailTime.Range( - func(key, value interface{}) bool { - sessionStates.MPPStoreLastFailTime[key.(string)] = value.(time.Time) - return true - }) sessionStates.FoundInPlanCache = s.PrevFoundInPlanCache sessionStates.FoundInBinding = s.PrevFoundInBinding @@ -2213,9 +2350,6 @@ func (s *SessionVars) DecodeSessionStates(ctx context.Context, sessionStates *se } s.LastFoundRows = sessionStates.LastFoundRows s.SequenceState.SetAllStates(sessionStates.SequenceLatestValues) - for k, v := range sessionStates.MPPStoreLastFailTime { - s.MPPStoreLastFailTime.Store(k, v) - } s.FoundInPlanCache = sessionStates.FoundInPlanCache s.FoundInBinding = sessionStates.FoundInBinding @@ -2262,7 +2396,6 @@ type Concurrency struct { indexLookupJoinConcurrency int // distSQLScanConcurrency is the number of concurrent dist SQL scan worker. - // distSQLScanConcurrency is deprecated, use ExecutorConcurrency instead. distSQLScanConcurrency int // hashJoinConcurrency is the number of concurrent hash join outer worker. @@ -2292,6 +2425,10 @@ type Concurrency struct { // streamAggConcurrency is deprecated, use ExecutorConcurrency instead. streamAggConcurrency int + // indexMergeIntersectionConcurrency is the number of indexMergeProcessWorker + // Only meaningful for dynamic pruned partition table. + indexMergeIntersectionConcurrency int + // indexSerialScanConcurrency is the number of concurrent index serial scan worker. indexSerialScanConcurrency int @@ -2352,6 +2489,11 @@ func (c *Concurrency) SetStreamAggConcurrency(n int) { c.streamAggConcurrency = n } +// SetIndexMergeIntersectionConcurrency set the number of concurrent intersection process worker. +func (c *Concurrency) SetIndexMergeIntersectionConcurrency(n int) { + c.indexMergeIntersectionConcurrency = n +} + // SetIndexSerialScanConcurrency set the number of concurrent index serial scan worker. func (c *Concurrency) SetIndexSerialScanConcurrency(n int) { c.indexSerialScanConcurrency = n @@ -2434,6 +2576,14 @@ func (c *Concurrency) StreamAggConcurrency() int { return c.ExecutorConcurrency } +// IndexMergeIntersectionConcurrency return the number of concurrent process worker. +func (c *Concurrency) IndexMergeIntersectionConcurrency() int { + if c.indexMergeIntersectionConcurrency != ConcurrencyUnset { + return c.indexMergeIntersectionConcurrency + } + return c.ExecutorConcurrency +} + // IndexSerialScanConcurrency return the number of concurrent index serial scan worker. // This option is not sync with ExecutorConcurrency since it's used by Analyze table. func (c *Concurrency) IndexSerialScanConcurrency() int { @@ -2589,6 +2739,9 @@ const ( SlowLogBackoffDetail = "Backoff_Detail" // SlowLogResultRows is the row count of the SQL result. SlowLogResultRows = "Result_rows" + // SlowLogWarnings is the warnings generated during executing the statement. + // Note that some extra warnings would also be printed through slow log. + SlowLogWarnings = "Warnings" // SlowLogIsExplicitTxn is used to indicate whether this sql execute in explicit transaction or not. SlowLogIsExplicitTxn = "IsExplicitTxn" // SlowLogIsWriteCacheTable is used to indicate whether writing to the cache table need to wait for the read lock to expire. @@ -2601,6 +2754,15 @@ const ( // It's controlled by the global variable `tidb_generate_binary_plan`. var GenerateBinaryPlan atomic2.Bool +// JSONSQLWarnForSlowLog helps to print the SQLWarn through the slow log in JSON format. +type JSONSQLWarnForSlowLog struct { + Level string + Message string + // IsExtra means this SQL Warn is expected to be recorded only under some conditions (like in EXPLAIN) and should + // haven't been recorded as a warning now, but we recorded it anyway to help diagnostics. + IsExtra bool `json:",omitempty"` +} + // SlowQueryLogItems is a collection of items that should be included in the // slow query log. type SlowQueryLogItems struct { @@ -2640,6 +2802,7 @@ type SlowQueryLogItems struct { // table -> name -> status StatsLoadStatus map[string]map[string]string IsSyncStatsFailed bool + Warnings []JSONSQLWarnForSlowLog } // SlowLogFormat uses for formatting slow log. @@ -2805,6 +2968,16 @@ func (s *SessionVars) SlowLogFormat(logItems *SlowQueryLogItems) string { writeSlowLogItem(&buf, SlowLogBackoffTotal, strconv.FormatFloat(logItems.BackoffTotal.Seconds(), 'f', -1, 64)) writeSlowLogItem(&buf, SlowLogWriteSQLRespTotal, strconv.FormatFloat(logItems.WriteSQLRespTotal.Seconds(), 'f', -1, 64)) writeSlowLogItem(&buf, SlowLogResultRows, strconv.FormatInt(logItems.ResultRows, 10)) + if len(logItems.Warnings) > 0 { + buf.WriteString(SlowLogRowPrefixStr + SlowLogWarnings + SlowLogSpaceMarkStr) + jsonEncoder := json.NewEncoder(&buf) + jsonEncoder.SetEscapeHTML(false) + // Note that the Encode() will append a '\n' so we don't need to add another. + err := jsonEncoder.Encode(logItems.Warnings) + if err != nil { + buf.WriteString(err.Error()) + } + } writeSlowLogItem(&buf, SlowLogSucc, strconv.FormatBool(logItems.Succ)) writeSlowLogItem(&buf, SlowLogIsExplicitTxn, strconv.FormatBool(logItems.IsExplicitTxn)) writeSlowLogItem(&buf, SlowLogIsSyncStatsFailed, strconv.FormatBool(logItems.IsSyncStatsFailed)) @@ -3020,3 +3193,53 @@ func (s *SessionVars) GetRelatedTableForMDL() *sync.Map { func (s *SessionVars) EnableForceInlineCTE() bool { return s.enableForceInlineCTE } + +// protectedTSList implements util/processinfo#ProtectedTSList +type protectedTSList struct { + sync.Mutex + items map[uint64]int +} + +// HoldTS holds the timestamp to prevent its data from being GCed. +func (lst *protectedTSList) HoldTS(ts uint64) (unhold func()) { + lst.Lock() + if lst.items == nil { + lst.items = map[uint64]int{} + } + lst.items[ts] += 1 + lst.Unlock() + var once sync.Once + return func() { + once.Do(func() { + lst.Lock() + if lst.items != nil { + if lst.items[ts] > 1 { + lst.items[ts] -= 1 + } else { + delete(lst.items, ts) + } + } + lst.Unlock() + }) + } +} + +// GetMinProtectedTS returns the minimum protected timestamp that greater than `lowerBound` (0 if no such one). +func (lst *protectedTSList) GetMinProtectedTS(lowerBound uint64) (ts uint64) { + lst.Lock() + for k, v := range lst.items { + if v > 0 && k > lowerBound && (k < ts || ts == 0) { + ts = k + } + } + lst.Unlock() + return +} + +// Size returns the number of protected timestamps (exported for test). +func (lst *protectedTSList) Size() (size int) { + lst.Lock() + size = len(lst.items) + lst.Unlock() + return +} diff --git a/sessionctx/variable/session_test.go b/sessionctx/variable/session_test.go index 91f1394499c97..5df5e187088d0 100644 --- a/sessionctx/variable/session_test.go +++ b/sessionctx/variable/session_test.go @@ -23,10 +23,13 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/parser/mysql" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" @@ -127,16 +130,9 @@ func TestSession(t *testing.T) { func TestAllocMPPID(t *testing.T) { ctx := mock.NewContext() - - seVar := ctx.GetSessionVars() - require.NotNil(t, seVar) - - require.Equal(t, int64(1), seVar.AllocMPPTaskID(1)) - require.Equal(t, int64(2), seVar.AllocMPPTaskID(1)) - require.Equal(t, int64(3), seVar.AllocMPPTaskID(1)) - require.Equal(t, int64(1), seVar.AllocMPPTaskID(2)) - require.Equal(t, int64(2), seVar.AllocMPPTaskID(2)) - require.Equal(t, int64(3), seVar.AllocMPPTaskID(2)) + require.Equal(t, int64(1), plannercore.AllocMPPTaskID(ctx)) + require.Equal(t, int64(2), plannercore.AllocMPPTaskID(ctx)) + require.Equal(t, int64(3), plannercore.AllocMPPTaskID(ctx)) } func TestSlowLogFormat(t *testing.T) { @@ -161,9 +157,11 @@ func TestSlowLogFormat(t *testing.T) { ProcessedKeys: 20001, TotalKeys: 10000, }, - TimeDetail: util.TimeDetail{ - ProcessTime: time.Second * time.Duration(2), - WaitTime: time.Minute, + DetailsNeedP90: execdetails.DetailsNeedP90{ + TimeDetail: util.TimeDetail{ + ProcessTime: time.Second * time.Duration(2), + WaitTime: time.Minute, + }, }, } statsInfos := make(map[string]uint64) @@ -393,21 +391,21 @@ func TestTransactionContextSavepoint(t *testing.T) { require.Equal(t, 0, len(tc.Savepoints)) } -func TestGeneralPlanCacheStmt(t *testing.T) { +func TestNonPreparedPlanCacheStmt(t *testing.T) { sessVars := variable.NewSessionVars(nil) - sessVars.GeneralPlanCacheSize = 100 + sessVars.NonPreparedPlanCacheSize = 100 sql1 := "select * from t where a>?" sql2 := "select * from t where a 0) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { val := "0" if EnablePProfSQLCPU.Load() { val = "1" } return val, nil }}, - {Scope: ScopeInstance, Name: TiDBDDLSlowOprThreshold, Value: strconv.Itoa(DefTiDBDDLSlowOprThreshold), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeInstance, Name: TiDBDDLSlowOprThreshold, Value: strconv.Itoa(DefTiDBDDLSlowOprThreshold), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { atomic.StoreUint32(&DDLSlowOprThreshold, uint32(tidbOptPositiveInt32(val, DefTiDBDDLSlowOprThreshold))) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatUint(uint64(atomic.LoadUint32(&DDLSlowOprThreshold)), 10), nil }}, - {Scope: ScopeInstance, Name: TiDBForcePriority, Value: mysql.Priority2Str[DefTiDBForcePriority], Type: TypeEnum, PossibleValues: []string{"NO_PRIORITY", "LOW_PRIORITY", "HIGH_PRIORITY", "DELAYED"}, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeInstance, Name: TiDBForcePriority, Value: mysql.Priority2Str[DefTiDBForcePriority], Type: TypeEnum, PossibleValues: []string{"NO_PRIORITY", "LOW_PRIORITY", "HIGH_PRIORITY", "DELAYED"}, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { atomic.StoreInt32(&ForcePriority, int32(mysql.Str2Priority(val))) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return mysql.Priority2Str[mysql.PriorityEnum(atomic.LoadInt32(&ForcePriority))], nil }}, - {Scope: ScopeInstance, Name: TiDBExpensiveQueryTimeThreshold, Value: strconv.Itoa(DefTiDBExpensiveQueryTimeThreshold), Type: TypeUnsigned, MinValue: int64(MinExpensiveQueryTimeThreshold), MaxValue: math.MaxInt32, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeInstance, Name: TiDBExpensiveQueryTimeThreshold, Value: strconv.Itoa(DefTiDBExpensiveQueryTimeThreshold), Type: TypeUnsigned, MinValue: int64(MinExpensiveQueryTimeThreshold), MaxValue: math.MaxInt32, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { atomic.StoreUint64(&ExpensiveQueryTimeThreshold, uint64(tidbOptPositiveInt32(val, DefTiDBExpensiveQueryTimeThreshold))) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatUint(atomic.LoadUint64(&ExpensiveQueryTimeThreshold), 10), nil }}, - {Scope: ScopeInstance, Name: TiDBEnableCollectExecutionInfo, Value: BoolToOnOff(DefTiDBEnableCollectExecutionInfo), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeInstance, Name: TiDBEnableCollectExecutionInfo, Value: BoolToOnOff(DefTiDBEnableCollectExecutionInfo), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { oldConfig := config.GetGlobalConfig() newValue := TiDBOptOn(val) if oldConfig.Instance.EnableCollectExecutionInfo.Load() != newValue { @@ -435,23 +442,23 @@ var defaultSysVars = []*SysVar{ config.StoreGlobalConfig(&newConfig) } return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(config.GetGlobalConfig().Instance.EnableCollectExecutionInfo.Load()), nil }}, - {Scope: ScopeInstance, Name: PluginLoad, Value: "", ReadOnly: true, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeInstance, Name: PluginLoad, Value: "", ReadOnly: true, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return config.GetGlobalConfig().Instance.PluginLoad, nil }}, - {Scope: ScopeInstance, Name: PluginDir, Value: "/data/deploy/plugin", ReadOnly: true, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeInstance, Name: PluginDir, Value: "/data/deploy/plugin", ReadOnly: true, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return config.GetGlobalConfig().Instance.PluginDir, nil }}, - {Scope: ScopeInstance, Name: MaxConnections, Value: strconv.FormatUint(uint64(config.GetGlobalConfig().Instance.MaxConnections), 10), Type: TypeUnsigned, MinValue: 0, MaxValue: 100000, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeInstance, Name: MaxConnections, Value: strconv.FormatUint(uint64(config.GetGlobalConfig().Instance.MaxConnections), 10), Type: TypeUnsigned, MinValue: 0, MaxValue: 100000, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { config.GetGlobalConfig().Instance.MaxConnections = uint32(TidbOptInt64(val, 0)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatUint(uint64(config.GetGlobalConfig().Instance.MaxConnections), 10), nil }}, {Scope: ScopeInstance, Name: TiDBEnableDDL, Value: BoolToOnOff(config.GetGlobalConfig().Instance.TiDBEnableDDL.Load()), Type: TypeBool, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { oldVal, newVal := config.GetGlobalConfig().Instance.TiDBEnableDDL.Load(), TiDBOptOn(val) if oldVal != newVal { err := switchDDL(newVal) @@ -460,19 +467,27 @@ var defaultSysVars = []*SysVar{ } return nil }, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(config.GetGlobalConfig().Instance.TiDBEnableDDL.Load()), nil }, }, - {Scope: ScopeInstance, Name: TiDBRCReadCheckTS, Value: BoolToOnOff(DefRCReadCheckTS), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeInstance, Name: TiDBRCReadCheckTS, Value: BoolToOnOff(DefRCReadCheckTS), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { EnableRCReadCheckTS.Store(TiDBOptOn(val)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(EnableRCReadCheckTS.Load()), nil }}, /* The system variables below have GLOBAL scope */ - {Scope: ScopeGlobal, Name: MaxPreparedStmtCount, Value: strconv.FormatInt(DefMaxPreparedStmtCount, 10), Type: TypeInt, MinValue: -1, MaxValue: 1048576}, + {Scope: ScopeGlobal, Name: MaxPreparedStmtCount, Value: strconv.FormatInt(DefMaxPreparedStmtCount, 10), Type: TypeInt, MinValue: -1, MaxValue: 1048576, + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + num, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return errors.Trace(err) + } + MaxPreparedStmtCountValue.Store(num) + return nil + }}, {Scope: ScopeGlobal, Name: InitConnect, Value: "", Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { p := parser.New() p.SetSQLMode(vars.SQLMode) @@ -483,25 +498,117 @@ var defaultSysVars = []*SysVar{ } return normalizedValue, nil }}, + {Scope: ScopeGlobal, Name: ValidatePasswordEnable, Value: Off, Type: TypeBool}, + {Scope: ScopeGlobal, Name: ValidatePasswordPolicy, Value: "MEDIUM", Type: TypeEnum, PossibleValues: []string{"LOW", "MEDIUM", "STRONG"}}, + {Scope: ScopeGlobal, Name: ValidatePasswordCheckUserName, Value: On, Type: TypeBool}, + {Scope: ScopeGlobal, Name: ValidatePasswordLength, Value: "8", Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, + Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + numberCount, specialCharCount, mixedCaseCount := PasswordValidtaionNumberCount.Load(), PasswordValidationSpecialCharCount.Load(), PasswordValidationMixedCaseCount.Load() + length, err := strconv.ParseInt(normalizedValue, 10, 32) + if err != nil { + return "", err + } + if minLength := numberCount + specialCharCount + 2*mixedCaseCount; int32(length) < minLength { + return strconv.FormatInt(int64(minLength), 10), nil + } + return normalizedValue, nil + }, + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + PasswordValidationLength.Store(int32(TidbOptInt64(val, 8))) + return nil + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatInt(int64(PasswordValidationLength.Load()), 10), nil + }, + }, + {Scope: ScopeGlobal, Name: ValidatePasswordMixedCaseCount, Value: "1", Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, + Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + length, numberCount, specialCharCount := PasswordValidationLength.Load(), PasswordValidtaionNumberCount.Load(), PasswordValidationSpecialCharCount.Load() + mixedCaseCount, err := strconv.ParseInt(normalizedValue, 10, 32) + if err != nil { + return "", err + } + if minLength := numberCount + specialCharCount + 2*int32(mixedCaseCount); length < minLength { + err = updatePasswordValidationLength(vars, minLength) + if err != nil { + return "", err + } + } + return normalizedValue, nil + }, + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + PasswordValidationMixedCaseCount.Store(int32(TidbOptInt64(val, 1))) + return nil + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatInt(int64(PasswordValidationMixedCaseCount.Load()), 10), nil + }, + }, + {Scope: ScopeGlobal, Name: ValidatePasswordNumberCount, Value: "1", Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, + Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + length, specialCharCount, mixedCaseCount := PasswordValidationLength.Load(), PasswordValidationSpecialCharCount.Load(), PasswordValidationMixedCaseCount.Load() + numberCount, err := strconv.ParseInt(normalizedValue, 10, 32) + if err != nil { + return "", err + } + if minLength := int32(numberCount) + specialCharCount + 2*mixedCaseCount; length < minLength { + err = updatePasswordValidationLength(vars, minLength) + if err != nil { + return "", err + } + } + return normalizedValue, nil + }, + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + PasswordValidtaionNumberCount.Store(int32(TidbOptInt64(val, 1))) + return nil + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatInt(int64(PasswordValidtaionNumberCount.Load()), 10), nil + }, + }, + {Scope: ScopeGlobal, Name: ValidatePasswordSpecialCharCount, Value: "1", Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, + Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + length, numberCount, mixedCaseCount := PasswordValidationLength.Load(), PasswordValidtaionNumberCount.Load(), PasswordValidationMixedCaseCount.Load() + specialCharCount, err := strconv.ParseInt(normalizedValue, 10, 32) + if err != nil { + return "", err + } + if minLength := numberCount + int32(specialCharCount) + 2*mixedCaseCount; length < minLength { + err = updatePasswordValidationLength(vars, minLength) + if err != nil { + return "", err + } + } + return normalizedValue, nil + }, + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + PasswordValidationSpecialCharCount.Store(int32(TidbOptInt64(val, 1))) + return nil + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatInt(int64(PasswordValidationSpecialCharCount.Load()), 10), nil + }, + }, + {Scope: ScopeGlobal, Name: ValidatePasswordDictionary, Value: "", Type: TypeStr}, + {Scope: ScopeGlobal, Name: DisconnectOnExpiredPassword, Value: On, Type: TypeBool, ReadOnly: true, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return BoolToOnOff(!IsSandBoxModeEnabled.Load()), nil + }}, /* TiDB specific variables */ {Scope: ScopeGlobal, Name: TiDBTSOClientBatchMaxWaitTime, Value: strconv.FormatFloat(DefTiDBTSOClientBatchMaxWaitTime, 'f', -1, 64), Type: TypeFloat, MinValue: 0, MaxValue: 10, - GetGlobal: func(sv *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, sv *SessionVars) (string, error) { return strconv.FormatFloat(MaxTSOBatchWaitInterval.Load(), 'f', -1, 64), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { (*SetPDClientDynamicOption.Load())(TiDBTSOClientBatchMaxWaitTime, val) return nil }}, - {Scope: ScopeGlobal, Name: TiDBEnableTSOFollowerProxy, Value: BoolToOnOff(DefTiDBEnableTSOFollowerProxy), Type: TypeBool, GetGlobal: func(sv *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBEnableTSOFollowerProxy, Value: BoolToOnOff(DefTiDBEnableTSOFollowerProxy), Type: TypeBool, GetGlobal: func(_ context.Context, sv *SessionVars) (string, error) { return BoolToOnOff(EnableTSOFollowerProxy.Load()), nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { (*SetPDClientDynamicOption.Load())(TiDBEnableTSOFollowerProxy, val) return nil }}, - {Scope: ScopeGlobal, Name: TiDBEnableLocalTxn, Value: BoolToOnOff(DefTiDBEnableLocalTxn), Hidden: true, Type: TypeBool, GetGlobal: func(sv *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBEnableLocalTxn, Value: BoolToOnOff(DefTiDBEnableLocalTxn), Hidden: true, Type: TypeBool, GetGlobal: func(_ context.Context, sv *SessionVars) (string, error) { return BoolToOnOff(EnableLocalTxn.Load()), nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { oldVal := EnableLocalTxn.Load() newVal := TiDBOptOn(val) // Make sure the TxnScope is always Global when disable the Local Txn. @@ -515,82 +622,82 @@ var defaultSysVars = []*SysVar{ {Scope: ScopeGlobal, Name: TiDBAutoAnalyzeRatio, Value: strconv.FormatFloat(DefAutoAnalyzeRatio, 'f', -1, 64), Type: TypeFloat, MinValue: 0, MaxValue: math.MaxUint64}, {Scope: ScopeGlobal, Name: TiDBAutoAnalyzeStartTime, Value: DefAutoAnalyzeStartTime, Type: TypeTime}, {Scope: ScopeGlobal, Name: TiDBAutoAnalyzeEndTime, Value: DefAutoAnalyzeEndTime, Type: TypeTime}, - {Scope: ScopeGlobal, Name: TiDBMemQuotaBindingCache, Value: strconv.FormatInt(DefTiDBMemQuotaBindingCache, 10), Type: TypeUnsigned, MaxValue: math.MaxInt32, GetGlobal: func(sv *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBMemQuotaBindingCache, Value: strconv.FormatInt(DefTiDBMemQuotaBindingCache, 10), Type: TypeUnsigned, MaxValue: math.MaxInt32, GetGlobal: func(_ context.Context, sv *SessionVars) (string, error) { return strconv.FormatInt(MemQuotaBindingCache.Load(), 10), nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { MemQuotaBindingCache.Store(TidbOptInt64(val, DefTiDBMemQuotaBindingCache)) return nil }}, - {Scope: ScopeGlobal, Name: TiDBDDLFlashbackConcurrency, Value: strconv.Itoa(DefTiDBDDLFlashbackConcurrency), Type: TypeUnsigned, MinValue: 1, MaxValue: MaxConfigurableConcurrency, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBDDLFlashbackConcurrency, Value: strconv.Itoa(DefTiDBDDLFlashbackConcurrency), Type: TypeUnsigned, MinValue: 1, MaxValue: MaxConfigurableConcurrency, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { SetDDLFlashbackConcurrency(int32(tidbOptPositiveInt32(val, DefTiDBDDLFlashbackConcurrency))) return nil }}, - {Scope: ScopeGlobal, Name: TiDBDDLReorgWorkerCount, Value: strconv.Itoa(DefTiDBDDLReorgWorkerCount), Type: TypeUnsigned, MinValue: 1, MaxValue: MaxConfigurableConcurrency, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBDDLReorgWorkerCount, Value: strconv.Itoa(DefTiDBDDLReorgWorkerCount), Type: TypeUnsigned, MinValue: 1, MaxValue: MaxConfigurableConcurrency, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { SetDDLReorgWorkerCounter(int32(tidbOptPositiveInt32(val, DefTiDBDDLReorgWorkerCount))) return nil }}, - {Scope: ScopeGlobal, Name: TiDBDDLReorgBatchSize, Value: strconv.Itoa(DefTiDBDDLReorgBatchSize), Type: TypeUnsigned, MinValue: int64(MinDDLReorgBatchSize), MaxValue: uint64(MaxDDLReorgBatchSize), SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBDDLReorgBatchSize, Value: strconv.Itoa(DefTiDBDDLReorgBatchSize), Type: TypeUnsigned, MinValue: int64(MinDDLReorgBatchSize), MaxValue: uint64(MaxDDLReorgBatchSize), SetGlobal: func(_ context.Context, s *SessionVars, val string) error { SetDDLReorgBatchSize(int32(tidbOptPositiveInt32(val, DefTiDBDDLReorgBatchSize))) return nil }}, - {Scope: ScopeGlobal, Name: TiDBDDLErrorCountLimit, Value: strconv.Itoa(DefTiDBDDLErrorCountLimit), Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxInt64, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBDDLErrorCountLimit, Value: strconv.Itoa(DefTiDBDDLErrorCountLimit), Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxInt64, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { SetDDLErrorCountLimit(TidbOptInt64(val, DefTiDBDDLErrorCountLimit)) return nil }}, - {Scope: ScopeGlobal, Name: TiDBMaxDeltaSchemaCount, Value: strconv.Itoa(DefTiDBMaxDeltaSchemaCount), Type: TypeUnsigned, MinValue: 100, MaxValue: 16384, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBMaxDeltaSchemaCount, Value: strconv.Itoa(DefTiDBMaxDeltaSchemaCount), Type: TypeUnsigned, MinValue: 100, MaxValue: 16384, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { // It's a global variable, but it also wants to be cached in server. SetMaxDeltaSchemaCount(TidbOptInt64(val, DefTiDBMaxDeltaSchemaCount)) return nil }}, {Scope: ScopeGlobal, Name: TiDBScatterRegion, Value: BoolToOnOff(DefTiDBScatterRegion), Type: TypeBool}, {Scope: ScopeGlobal, Name: TiDBEnableStmtSummary, Value: BoolToOnOff(DefTiDBEnableStmtSummary), Type: TypeBool, AllowEmpty: true, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return stmtsummary.StmtSummaryByDigestMap.SetEnabled(TiDBOptOn(val)) }}, {Scope: ScopeGlobal, Name: TiDBStmtSummaryInternalQuery, Value: BoolToOnOff(DefTiDBStmtSummaryInternalQuery), Type: TypeBool, AllowEmpty: true, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return stmtsummary.StmtSummaryByDigestMap.SetEnabledInternalQuery(TiDBOptOn(val)) }}, {Scope: ScopeGlobal, Name: TiDBStmtSummaryRefreshInterval, Value: strconv.Itoa(DefTiDBStmtSummaryRefreshInterval), Type: TypeInt, MinValue: 1, MaxValue: math.MaxInt32, AllowEmpty: true, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { // convert val to int64 return stmtsummary.StmtSummaryByDigestMap.SetRefreshInterval(TidbOptInt64(val, DefTiDBStmtSummaryRefreshInterval)) }}, {Scope: ScopeGlobal, Name: TiDBStmtSummaryHistorySize, Value: strconv.Itoa(DefTiDBStmtSummaryHistorySize), Type: TypeInt, MinValue: 0, MaxValue: math.MaxUint8, AllowEmpty: true, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return stmtsummary.StmtSummaryByDigestMap.SetHistorySize(TidbOptInt(val, DefTiDBStmtSummaryHistorySize)) }}, {Scope: ScopeGlobal, Name: TiDBStmtSummaryMaxStmtCount, Value: strconv.Itoa(DefTiDBStmtSummaryMaxStmtCount), Type: TypeInt, MinValue: 1, MaxValue: math.MaxInt16, AllowEmpty: true, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return stmtsummary.StmtSummaryByDigestMap.SetMaxStmtCount(uint(TidbOptInt(val, DefTiDBStmtSummaryMaxStmtCount))) }}, {Scope: ScopeGlobal, Name: TiDBStmtSummaryMaxSQLLength, Value: strconv.Itoa(DefTiDBStmtSummaryMaxSQLLength), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, AllowEmpty: true, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return stmtsummary.StmtSummaryByDigestMap.SetMaxSQLLength(TidbOptInt(val, DefTiDBStmtSummaryMaxSQLLength)) }}, {Scope: ScopeGlobal, Name: TiDBCapturePlanBaseline, Value: DefTiDBCapturePlanBaseline, Type: TypeBool, AllowEmptyAll: true}, {Scope: ScopeGlobal, Name: TiDBEvolvePlanTaskMaxTime, Value: strconv.Itoa(DefTiDBEvolvePlanTaskMaxTime), Type: TypeInt, MinValue: -1, MaxValue: math.MaxInt64}, {Scope: ScopeGlobal, Name: TiDBEvolvePlanTaskStartTime, Value: DefTiDBEvolvePlanTaskStartTime, Type: TypeTime}, {Scope: ScopeGlobal, Name: TiDBEvolvePlanTaskEndTime, Value: DefTiDBEvolvePlanTaskEndTime, Type: TypeTime}, - {Scope: ScopeGlobal, Name: TiDBStoreLimit, Value: strconv.FormatInt(atomic.LoadInt64(&config.GetGlobalConfig().TiKVClient.StoreLimit), 10), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt64, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBStoreLimit, Value: strconv.FormatInt(atomic.LoadInt64(&config.GetGlobalConfig().TiKVClient.StoreLimit), 10), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt64, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatInt(tikvstore.StoreLimit.Load(), 10), nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { tikvstore.StoreLimit.Store(TidbOptInt64(val, DefTiDBStoreLimit)) return nil }}, {Scope: ScopeGlobal, Name: TiDBTxnCommitBatchSize, Value: strconv.FormatUint(tikvstore.DefTxnCommitBatchSize, 10), Type: TypeUnsigned, MinValue: 1, MaxValue: 1 << 30, - GetGlobal: func(sv *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, sv *SessionVars) (string, error) { return strconv.FormatUint(tikvstore.TxnCommitBatchSize.Load(), 10), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { tikvstore.TxnCommitBatchSize.Store(uint64(TidbOptInt64(val, int64(tikvstore.DefTxnCommitBatchSize)))) return nil }}, - {Scope: ScopeGlobal, Name: TiDBRestrictedReadOnly, Value: BoolToOnOff(DefTiDBRestrictedReadOnly), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBRestrictedReadOnly, Value: BoolToOnOff(DefTiDBRestrictedReadOnly), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { on := TiDBOptOn(val) // For user initiated SET GLOBAL, also change the value of TiDBSuperReadOnly if on && s.StmtCtx.StmtType == "Set" { - err := s.GlobalVarsAccessor.SetGlobalSysVar(TiDBSuperReadOnly, "ON") + err := s.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), TiDBSuperReadOnly, "ON") if err != nil { return err } @@ -610,11 +717,11 @@ var defaultSysVars = []*SysVar{ } } return normalizedValue, nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { VarTiDBSuperReadOnly.Store(TiDBOptOn(val)) return nil }}, - {Scope: ScopeGlobal, Name: TiDBEnableGOGCTuner, Value: BoolToOnOff(DefTiDBEnableGOGCTuner), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBEnableGOGCTuner, Value: BoolToOnOff(DefTiDBEnableGOGCTuner), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { on := TiDBOptOn(val) gctuner.EnableGOGCTuner.Store(on) if !on { @@ -626,28 +733,28 @@ var defaultSysVars = []*SysVar{ {Scope: ScopeGlobal, Name: TiDBEnableTelemetry, Value: BoolToOnOff(DefTiDBEnableTelemetry), Type: TypeBool}, {Scope: ScopeGlobal, Name: TiDBEnableHistoricalStats, Value: Off, Type: TypeBool}, /* tikv gc metrics */ - {Scope: ScopeGlobal, Name: TiDBGCEnable, Value: On, Type: TypeBool, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBGCEnable, Value: On, Type: TypeBool, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return getTiDBTableValue(s, "tikv_gc_enable", On) - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return setTiDBTableValue(s, "tikv_gc_enable", val, "Current GC enable status") }}, - {Scope: ScopeGlobal, Name: TiDBGCRunInterval, Value: "10m0s", Type: TypeDuration, MinValue: int64(time.Minute * 10), MaxValue: uint64(time.Hour * 24 * 365), GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBGCRunInterval, Value: "10m0s", Type: TypeDuration, MinValue: int64(time.Minute * 10), MaxValue: uint64(time.Hour * 24 * 365), GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return getTiDBTableValue(s, "tikv_gc_run_interval", "10m0s") - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return setTiDBTableValue(s, "tikv_gc_run_interval", val, "GC run interval, at least 10m, in Go format.") }}, - {Scope: ScopeGlobal, Name: TiDBGCLifetime, Value: "10m0s", Type: TypeDuration, MinValue: int64(time.Minute * 10), MaxValue: uint64(time.Hour * 24 * 365), GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBGCLifetime, Value: "10m0s", Type: TypeDuration, MinValue: int64(time.Minute * 10), MaxValue: uint64(time.Hour * 24 * 365), GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return getTiDBTableValue(s, "tikv_gc_life_time", "10m0s") - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return setTiDBTableValue(s, "tikv_gc_life_time", val, "All versions within life time will not be collected by GC, at least 10m, in Go format.") }}, - {Scope: ScopeGlobal, Name: TiDBGCConcurrency, Value: "-1", Type: TypeInt, MinValue: 1, MaxValue: MaxConfigurableConcurrency, AllowAutoValue: true, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBGCConcurrency, Value: "-1", Type: TypeInt, MinValue: 1, MaxValue: MaxConfigurableConcurrency, AllowAutoValue: true, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { autoConcurrencyVal, err := getTiDBTableValue(s, "tikv_gc_auto_concurrency", On) if err == nil && autoConcurrencyVal == On { return "-1", nil // convention for "AUTO" } return getTiDBTableValue(s, "tikv_gc_concurrency", "-1") - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { autoConcurrency := Off if val == "-1" { autoConcurrency = On @@ -658,16 +765,16 @@ var defaultSysVars = []*SysVar{ } return setTiDBTableValue(s, "tikv_gc_concurrency", val, "How many goroutines used to do GC parallel, [1, 256], default 2") }}, - {Scope: ScopeGlobal, Name: TiDBGCScanLockMode, Value: "LEGACY", Type: TypeEnum, PossibleValues: []string{"PHYSICAL", "LEGACY"}, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBGCScanLockMode, Value: "LEGACY", Type: TypeEnum, PossibleValues: []string{"PHYSICAL", "LEGACY"}, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return getTiDBTableValue(s, "tikv_gc_scan_lock_mode", "LEGACY") - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return setTiDBTableValue(s, "tikv_gc_scan_lock_mode", val, "Mode of scanning locks, \"physical\" or \"legacy\"") }}, - {Scope: ScopeGlobal, Name: TiDBGCMaxWaitTime, Value: strconv.Itoa(DefTiDBGCMaxWaitTime), Type: TypeInt, MinValue: 600, MaxValue: 31536000, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBGCMaxWaitTime, Value: strconv.Itoa(DefTiDBGCMaxWaitTime), Type: TypeInt, MinValue: 600, MaxValue: 31536000, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { GCMaxWaitTime.Store(TidbOptInt64(val, DefTiDBGCMaxWaitTime)) return nil }}, - {Scope: ScopeGlobal, Name: TiDBTableCacheLease, Value: strconv.Itoa(DefTiDBTableCacheLease), Type: TypeUnsigned, MinValue: 1, MaxValue: 10, SetGlobal: func(s *SessionVars, sVal string) error { + {Scope: ScopeGlobal, Name: TiDBTableCacheLease, Value: strconv.Itoa(DefTiDBTableCacheLease), Type: TypeUnsigned, MinValue: 1, MaxValue: 10, SetGlobal: func(_ context.Context, s *SessionVars, sVal string) error { var val int64 val, err := strconv.ParseInt(sVal, 10, 64) if err != nil { @@ -679,7 +786,7 @@ var defaultSysVars = []*SysVar{ {Scope: ScopeGlobal, Name: TiDBAutoAnalyzePartitionBatchSize, Value: strconv.Itoa(DefTiDBAutoAnalyzePartitionBatchSize), Type: TypeUnsigned, MinValue: 1, MaxValue: 1024, - SetGlobal: func(vars *SessionVars, s string) error { + SetGlobal: func(_ context.Context, vars *SessionVars, s string) error { var val int64 val, err := strconv.ParseInt(s, 10, 64) if err != nil { @@ -693,9 +800,10 @@ var defaultSysVars = []*SysVar{ // TopSQL enable only be controlled by TopSQL pub/sub sinker. // This global variable only uses to update the global config which store in PD(ETCD). {Scope: ScopeGlobal, Name: TiDBEnableTopSQL, Value: BoolToOnOff(topsqlstate.DefTiDBTopSQLEnable), Type: TypeBool, AllowEmpty: true, GlobalConfigName: GlobalConfigEnableTopSQL}, - {Scope: ScopeGlobal, Name: TiDBTopSQLMaxTimeSeriesCount, Value: strconv.Itoa(topsqlstate.DefTiDBTopSQLMaxTimeSeriesCount), Type: TypeInt, MinValue: 1, MaxValue: 5000, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBSourceID, Value: "1", Type: TypeInt, MinValue: 1, MaxValue: 15, GlobalConfigName: GlobalConfigSourceID}, + {Scope: ScopeGlobal, Name: TiDBTopSQLMaxTimeSeriesCount, Value: strconv.Itoa(topsqlstate.DefTiDBTopSQLMaxTimeSeriesCount), Type: TypeInt, MinValue: 1, MaxValue: 5000, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatInt(topsqlstate.GlobalState.MaxStatementCount.Load(), 10), nil - }, SetGlobal: func(vars *SessionVars, s string) error { + }, SetGlobal: func(_ context.Context, vars *SessionVars, s string) error { val, err := strconv.ParseInt(s, 10, 64) if err != nil { return err @@ -703,9 +811,9 @@ var defaultSysVars = []*SysVar{ topsqlstate.GlobalState.MaxStatementCount.Store(val) return nil }}, - {Scope: ScopeGlobal, Name: TiDBTopSQLMaxMetaCount, Value: strconv.Itoa(topsqlstate.DefTiDBTopSQLMaxMetaCount), Type: TypeInt, MinValue: 1, MaxValue: 10000, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBTopSQLMaxMetaCount, Value: strconv.Itoa(topsqlstate.DefTiDBTopSQLMaxMetaCount), Type: TypeInt, MinValue: 1, MaxValue: 10000, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatInt(topsqlstate.GlobalState.MaxCollect.Load(), 10), nil - }, SetGlobal: func(vars *SessionVars, s string) error { + }, SetGlobal: func(_ context.Context, vars *SessionVars, s string) error { val, err := strconv.ParseInt(s, 10, 64) if err != nil { return err @@ -716,56 +824,91 @@ var defaultSysVars = []*SysVar{ {Scope: ScopeGlobal, Name: SkipNameResolve, Value: Off, Type: TypeBool}, {Scope: ScopeGlobal, Name: DefaultAuthPlugin, Value: mysql.AuthNativePassword, Type: TypeEnum, PossibleValues: []string{mysql.AuthNativePassword, mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password}}, {Scope: ScopeGlobal, Name: TiDBPersistAnalyzeOptions, Value: BoolToOnOff(DefTiDBPersistAnalyzeOptions), Type: TypeBool, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(PersistAnalyzeOptions.Load()), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { PersistAnalyzeOptions.Store(TiDBOptOn(val)) return nil }, }, {Scope: ScopeGlobal, Name: TiDBEnableAutoAnalyze, Value: BoolToOnOff(DefTiDBEnableAutoAnalyze), Type: TypeBool, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(RunAutoAnalyze.Load()), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { RunAutoAnalyze.Store(TiDBOptOn(val)) return nil }, }, - {Scope: ScopeGlobal, Name: TiDBServerMemoryLimit, Value: strconv.FormatUint(DefTiDBServerMemoryLimit, 10), Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxUint64, - GetGlobal: func(s *SessionVars) (string, error) { - return memory.ServerMemoryLimit.String(), nil + {Scope: ScopeGlobal, Name: TiDBGOGCTunerThreshold, Value: strconv.FormatFloat(DefTiDBGOGCTunerThreshold, 'f', -1, 64), Type: TypeFloat, MinValue: 0, MaxValue: math.MaxUint64, + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatFloat(GOGCTunerThreshold.Load(), 'f', -1, 64), nil }, Validation: func(s *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { - intVal, err := strconv.ParseUint(normalizedValue, 10, 64) + floatValue := tidbOptFloat64(normalizedValue, DefTiDBGOGCTunerThreshold) + globalMemoryLimitTuner := gctuner.GlobalMemoryLimitTuner.GetPercentage() + if floatValue < 0 && floatValue > 0.9 { + return "", ErrWrongValueForVar.GenWithStackByArgs(TiDBGOGCTunerThreshold, normalizedValue) + } + // globalMemoryLimitTuner must not be 0. it will be 0 when tidb_server_memory_limit_gc_trigger is not set during startup. + if globalMemoryLimitTuner != 0 && globalMemoryLimitTuner < floatValue+0.05 { + return "", errors.New("tidb_gogc_tuner_threshold should be less than tidb_server_memory_limit_gc_trigger - 0.05") + } + return strconv.FormatFloat(floatValue, 'f', -1, 64), nil + }, + SetGlobal: func(_ context.Context, s *SessionVars, val string) (err error) { + factor := tidbOptFloat64(val, DefTiDBGOGCTunerThreshold) + GOGCTunerThreshold.Store(factor) + memTotal := memory.ServerMemoryLimit.Load() + if memTotal == 0 { + memTotal, err = memory.MemTotal() + if err != nil { + return err + } + } + if factor > 0 { + threshold := float64(memTotal) * factor + gctuner.Tuning(uint64(threshold)) + } + return nil + }, + }, + {Scope: ScopeGlobal, Name: TiDBServerMemoryLimit, Value: DefTiDBServerMemoryLimit, Type: TypeStr, + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return memory.ServerMemoryLimitOriginText.Load(), nil + }, + Validation: func(s *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + _, str, err := parseMemoryLimit(s, normalizedValue, originalValue) if err != nil { return "", err } - if intVal > 0 && intVal < (512<<20) { // 512 MB - s.StmtCtx.AppendWarning(ErrTruncatedWrongValue.GenWithStackByArgs(TiDBServerMemoryLimit, originalValue)) - intVal = 512 << 20 - } - return strconv.FormatUint(intVal, 10), nil + return str, nil }, - SetGlobal: func(s *SessionVars, val string) error { - intVal, err := strconv.ParseUint(val, 10, 64) + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + bt, str, err := parseMemoryLimit(s, val, val) if err != nil { return err } - memory.ServerMemoryLimit.Store(intVal) + memory.ServerMemoryLimitOriginText.Store(str) + memory.ServerMemoryLimit.Store(bt) gctuner.GlobalMemoryLimitTuner.UpdateMemoryLimit() return nil }, }, - {Scope: ScopeGlobal, Name: TiDBServerMemoryLimitSessMinSize, Value: strconv.FormatUint(DefTiDBServerMemoryLimitSessMinSize, 10), Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxUint64, - GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBServerMemoryLimitSessMinSize, Value: strconv.FormatUint(DefTiDBServerMemoryLimitSessMinSize, 10), Type: TypeStr, + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return memory.ServerMemoryLimitSessMinSize.String(), nil }, Validation: func(s *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { intVal, err := strconv.ParseUint(normalizedValue, 10, 64) if err != nil { - return "", err + bt, str := parseByteSize(normalizedValue) + if str != "" { + intVal = bt + } else { + return "", err + } } if intVal > 0 && intVal < 128 { // 128 Bytes s.StmtCtx.AppendWarning(ErrTruncatedWrongValue.GenWithStackByArgs(TiDBServerMemoryLimitSessMinSize, originalValue)) @@ -773,7 +916,7 @@ var defaultSysVars = []*SysVar{ } return strconv.FormatUint(intVal, 10), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { intVal, err := strconv.ParseUint(val, 10, 64) if err != nil { return err @@ -782,22 +925,32 @@ var defaultSysVars = []*SysVar{ return nil }, }, - {Scope: ScopeGlobal, Name: TiDBServerMemoryLimitGCTrigger, Value: strconv.FormatFloat(DefTiDBServerMemoryLimitGCTrigger, 'f', -1, 64), Type: TypeFloat, MinValue: 0, MaxValue: math.MaxUint64, - GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBServerMemoryLimitGCTrigger, Value: strconv.FormatFloat(DefTiDBServerMemoryLimitGCTrigger, 'f', -1, 64), Type: TypeStr, + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatFloat(gctuner.GlobalMemoryLimitTuner.GetPercentage(), 'f', -1, 64), nil }, Validation: func(s *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { floatValue, err := strconv.ParseFloat(normalizedValue, 64) if err != nil { - return "", err + perc, str := parsePercentage(normalizedValue) + if len(str) != 0 { + floatValue = float64(perc) / 100 + } else { + return "", err + } + } + gogcTunerThreshold := GOGCTunerThreshold.Load() + if floatValue < 0.51 || floatValue > 1 { // 51% ~ 100% + return "", ErrWrongValueForVar.GenWithStackByArgs(TiDBServerMemoryLimitGCTrigger, normalizedValue) } - if floatValue < 0.51 && floatValue > 1 { // 51% ~ 100% - s.StmtCtx.AppendWarning(ErrTruncatedWrongValue.GenWithStackByArgs(TiDBServerMemoryLimitGCTrigger, originalValue)) - floatValue = DefTiDBServerMemoryLimitGCTrigger + // gogcTunerThreshold must not be 0. it will be 0 when tidb_gogc_tuner_threshold is not set during startup. + if gogcTunerThreshold != 0 && floatValue < gogcTunerThreshold+0.05 { + return "", errors.New("tidb_server_memory_limit_gc_trigger should be greater than tidb_gogc_tuner_threshold + 0.05") } + return strconv.FormatFloat(floatValue, 'f', -1, 64), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { floatValue, err := strconv.ParseFloat(val, 64) if err != nil { return err @@ -807,9 +960,9 @@ var defaultSysVars = []*SysVar{ return nil }, }, - {Scope: ScopeGlobal, Name: TiDBEnableColumnTracking, Value: BoolToOnOff(DefTiDBEnableColumnTracking), Type: TypeBool, GetGlobal: func(s *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBEnableColumnTracking, Value: BoolToOnOff(DefTiDBEnableColumnTracking), Type: TypeBool, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(EnableColumnTracking.Load()), nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { v := TiDBOptOn(val) // If this is a user initiated statement, // we log that column tracking is disabled. @@ -824,10 +977,10 @@ var defaultSysVars = []*SysVar{ return nil }}, {Scope: ScopeGlobal, Name: RequireSecureTransport, Value: BoolToOnOff(DefRequireSecureTransport), Type: TypeBool, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(tls.RequireSecureTransport.Load()), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { tls.RequireSecureTransport.Store(TiDBOptOn(val)) return nil }, Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { @@ -842,25 +995,25 @@ var defaultSysVars = []*SysVar{ }, }, {Scope: ScopeGlobal, Name: TiDBStatsLoadPseudoTimeout, Value: BoolToOnOff(DefTiDBStatsLoadPseudoTimeout), Type: TypeBool, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(StatsLoadPseudoTimeout.Load()), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { StatsLoadPseudoTimeout.Store(TiDBOptOn(val)) return nil }, }, - {Scope: ScopeGlobal, Name: TiDBEnableBatchDML, Value: BoolToOnOff(DefTiDBEnableBatchDML), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBEnableBatchDML, Value: BoolToOnOff(DefTiDBEnableBatchDML), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { EnableBatchDML.Store(TiDBOptOn(val)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(EnableBatchDML.Load()), nil }}, {Scope: ScopeGlobal, Name: TiDBStatsCacheMemQuota, Value: strconv.Itoa(DefTiDBStatsCacheMemQuota), MinValue: 0, MaxValue: MaxTiDBStatsCacheMemQuota, Type: TypeInt, - GetGlobal: func(vars *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, vars *SessionVars) (string, error) { return strconv.FormatInt(StatsCacheMemQuota.Load(), 10), nil - }, SetGlobal: func(vars *SessionVars, s string) error { + }, SetGlobal: func(_ context.Context, vars *SessionVars, s string) error { v := TidbOptInt64(s, DefTiDBStatsCacheMemQuota) oldv := StatsCacheMemQuota.Load() if v != oldv { @@ -870,25 +1023,25 @@ var defaultSysVars = []*SysVar{ return nil }, }, - {Scope: ScopeGlobal, Name: TiDBQueryLogMaxLen, Value: strconv.Itoa(DefTiDBQueryLogMaxLen), Type: TypeInt, MinValue: 0, MaxValue: 1073741824, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBQueryLogMaxLen, Value: strconv.Itoa(DefTiDBQueryLogMaxLen), Type: TypeInt, MinValue: 0, MaxValue: 1073741824, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { QueryLogMaxLen.Store(int32(TidbOptInt64(val, DefTiDBQueryLogMaxLen))) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return fmt.Sprint(QueryLogMaxLen.Load()), nil }}, - {Scope: ScopeGlobal, Name: TiDBCommitterConcurrency, Value: strconv.Itoa(DefTiDBCommitterConcurrency), Type: TypeInt, MinValue: 1, MaxValue: 10000, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBCommitterConcurrency, Value: strconv.Itoa(DefTiDBCommitterConcurrency), Type: TypeInt, MinValue: 1, MaxValue: 10000, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { tikvutil.CommitterConcurrency.Store(int32(TidbOptInt64(val, DefTiDBCommitterConcurrency))) cfg := config.GetGlobalConfig().GetTiKVConfig() tikvcfg.StoreGlobalConfig(cfg) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return fmt.Sprint(tikvutil.CommitterConcurrency.Load()), nil }}, {Scope: ScopeGlobal, Name: TiDBMemQuotaAnalyze, Value: strconv.Itoa(DefTiDBMemQuotaAnalyze), Type: TypeInt, MinValue: -1, MaxValue: math.MaxInt64, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatInt(GetMemQuotaAnalyze(), 10), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { SetMemQuotaAnalyze(TidbOptInt64(val, DefTiDBMemQuotaAnalyze)) return nil }, @@ -904,39 +1057,43 @@ var defaultSysVars = []*SysVar{ } return err }}, - {Scope: ScopeGlobal, Name: TiDBPrepPlanCacheMemoryGuardRatio, Value: strconv.FormatFloat(DefTiDBPrepPlanCacheMemoryGuardRatio, 'f', -1, 64), Type: TypeFloat, MinValue: 0.0, MaxValue: 1.0, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnablePrepPlanCacheMemoryMonitor, Value: BoolToOnOff(DefTiDBEnablePrepPlanCacheMemoryMonitor), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { + s.EnablePreparedPlanCacheMemoryMonitor = TiDBOptOn(val) + return nil + }}, + {Scope: ScopeGlobal, Name: TiDBPrepPlanCacheMemoryGuardRatio, Value: strconv.FormatFloat(DefTiDBPrepPlanCacheMemoryGuardRatio, 'f', -1, 64), Type: TypeFloat, MinValue: 0.0, MaxValue: 1.0, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { f, err := strconv.ParseFloat(val, 64) if err == nil { PreparedPlanCacheMemoryGuardRatio.Store(f) } return err - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatFloat(PreparedPlanCacheMemoryGuardRatio.Load(), 'f', -1, 64), nil }}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableGeneralPlanCache, Value: BoolToOnOff(DefTiDBEnableGeneralPlanCache), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { - s.EnableGeneralPlanCache = TiDBOptOn(val) + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableNonPreparedPlanCache, Value: BoolToOnOff(DefTiDBEnableNonPreparedPlanCache), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { + s.EnableNonPreparedPlanCache = TiDBOptOn(val) return nil }}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBGeneralPlanCacheSize, Value: strconv.FormatUint(uint64(DefTiDBGeneralPlanCacheSize), 10), Type: TypeUnsigned, MinValue: 1, MaxValue: 100000, SetSession: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal | ScopeSession, Name: TiDBNonPreparedPlanCacheSize, Value: strconv.FormatUint(uint64(DefTiDBNonPreparedPlanCacheSize), 10), Type: TypeUnsigned, MinValue: 1, MaxValue: 100000, SetSession: func(s *SessionVars, val string) error { uVal, err := strconv.ParseUint(val, 10, 64) if err == nil { - s.GeneralPlanCacheSize = uVal + s.NonPreparedPlanCacheSize = uVal } return err }}, {Scope: ScopeGlobal, Name: TiDBMemOOMAction, Value: DefTiDBMemOOMAction, PossibleValues: []string{"CANCEL", "LOG"}, Type: TypeEnum, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return OOMAction.Load(), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { OOMAction.Store(val) return nil }}, {Scope: ScopeGlobal, Name: TiDBMaxAutoAnalyzeTime, Value: strconv.Itoa(DefTiDBMaxAutoAnalyzeTime), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatInt(MaxAutoAnalyzeTime.Load(), 10), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { num, err := strconv.ParseInt(val, 10, 64) if err == nil { MaxAutoAnalyzeTime.Store(num) @@ -944,19 +1101,7 @@ var defaultSysVars = []*SysVar{ return err }, }, - {Scope: ScopeGlobal, Name: TiDBEnableConcurrentDDL, Value: BoolToOnOff(DefTiDBEnableConcurrentDDL), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { - if EnableConcurrentDDL.Load() != TiDBOptOn(val) { - err := SwitchConcurrentDDL(TiDBOptOn(val)) - if err != nil { - return err - } - EnableConcurrentDDL.Store(TiDBOptOn(val)) - } - return nil - }, GetGlobal: func(s *SessionVars) (string, error) { - return BoolToOnOff(EnableConcurrentDDL.Load()), nil - }}, - {Scope: ScopeGlobal, Name: TiDBEnableMDL, Value: BoolToOnOff(DefTiDBEnableMDL), Type: TypeBool, SetGlobal: func(vars *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBEnableMDL, Value: BoolToOnOff(DefTiDBEnableMDL), Type: TypeBool, SetGlobal: func(_ context.Context, vars *SessionVars, val string) error { if EnableMDL.Load() != TiDBOptOn(val) { err := SwitchMDL(TiDBOptOn(val)) if err != nil { @@ -964,50 +1109,102 @@ var defaultSysVars = []*SysVar{ } } return nil - }, GetGlobal: func(vars *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, vars *SessionVars) (string, error) { return BoolToOnOff(EnableMDL.Load()), nil }}, - {Scope: ScopeGlobal, Name: TiDBEnableNoopVariables, Value: BoolToOnOff(DefTiDBEnableNoopVariables), Type: TypeEnum, PossibleValues: []string{Off, On}, SetGlobal: func(s *SessionVars, val string) error { - EnableNoopVariables.Store(TiDBOptOn(val)) - return nil - }, GetGlobal: func(s *SessionVars) (string, error) { - return BoolToOnOff(EnableNoopVariables.Load()), nil - }}, - {Scope: ScopeGlobal, Name: TiDBAuthSigningCert, Value: "", Type: TypeStr, SetGlobal: func(s *SessionVars, val string) error { - sessionstates.SetCertPath(val) + {Scope: ScopeGlobal, Name: TiDBDDLEnableDistributeReorg, Value: BoolToOnOff(DefTiDBDDLEnableDistributeReorg), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + if DDLEnableDistributeReorg.Load() != TiDBOptOn(val) { + DDLEnableDistributeReorg.Store(TiDBOptOn(val)) + } return nil + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return BoolToOnOff(DDLEnableDistributeReorg.Load()), nil }}, - {Scope: ScopeGlobal, Name: TiDBAuthSigningKey, Value: "", Type: TypeStr, SetGlobal: func(s *SessionVars, val string) error { - sessionstates.SetKeyPath(val) + {Scope: ScopeGlobal, Name: TiDBEnableNoopVariables, Value: BoolToOnOff(DefTiDBEnableNoopVariables), Type: TypeEnum, PossibleValues: []string{Off, On}, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + EnableNoopVariables.Store(TiDBOptOn(val)) return nil + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return BoolToOnOff(EnableNoopVariables.Load()), nil }}, - {Scope: ScopeGlobal, Name: TiDBEnableGCAwareMemoryTrack, Value: BoolToOnOff(DefEnableTiDBGCAwareMemoryTrack), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBEnableGCAwareMemoryTrack, Value: BoolToOnOff(DefEnableTiDBGCAwareMemoryTrack), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { memory.EnableGCAwareMemoryTrack.Store(TiDBOptOn(val)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(memory.EnableGCAwareMemoryTrack.Load()), nil }}, - {Scope: ScopeGlobal, Name: TiDBEnableTmpStorageOnOOM, Value: BoolToOnOff(DefTiDBEnableTmpStorageOnOOM), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBEnableTmpStorageOnOOM, Value: BoolToOnOff(DefTiDBEnableTmpStorageOnOOM), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { EnableTmpStorageOnOOM.Store(TiDBOptOn(val)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(EnableTmpStorageOnOOM.Load()), nil }}, - {Scope: ScopeGlobal, Name: TiDBMemoryUsageAlarmRatio, Value: strconv.FormatFloat(DefMemoryUsageAlarmRatio, 'f', -1, 64), Type: TypeFloat, MinValue: 0.0, MaxValue: 1.0, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBAutoBuildStatsConcurrency, Value: strconv.Itoa(DefTiDBAutoBuildStatsConcurrency), Type: TypeInt, MinValue: 1, MaxValue: MaxConfigurableConcurrency}, + {Scope: ScopeGlobal, Name: TiDBSysProcScanConcurrency, Value: strconv.Itoa(DefTiDBSysProcScanConcurrency), Type: TypeInt, MinValue: 1, MaxValue: MaxConfigurableConcurrency}, + {Scope: ScopeGlobal, Name: TiDBMemoryUsageAlarmRatio, Value: strconv.FormatFloat(DefMemoryUsageAlarmRatio, 'f', -1, 64), Type: TypeFloat, MinValue: 0.0, MaxValue: 1.0, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { MemoryUsageAlarmRatio.Store(tidbOptFloat64(val, DefMemoryUsageAlarmRatio)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return fmt.Sprintf("%g", MemoryUsageAlarmRatio.Load()), nil }}, - {Scope: ScopeGlobal, Name: TiDBMemoryUsageAlarmKeepRecordNum, Value: strconv.Itoa(DefMemoryUsageAlarmKeepRecordNum), Type: TypeInt, MinValue: 1, MaxValue: 10000, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBMemoryUsageAlarmKeepRecordNum, Value: strconv.Itoa(DefMemoryUsageAlarmKeepRecordNum), Type: TypeInt, MinValue: 1, MaxValue: 10000, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { MemoryUsageAlarmKeepRecordNum.Store(TidbOptInt64(val, DefMemoryUsageAlarmKeepRecordNum)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { - return fmt.Sprintf("%d", MemoryUsageAlarmKeepRecordNum.Load()), nil + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatInt(MemoryUsageAlarmKeepRecordNum.Load(), 10), nil + }}, + {Scope: ScopeGlobal, Name: PasswordReuseHistory, Value: strconv.Itoa(DefPasswordReuseHistory), Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxUint32, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatInt(PasswordHistory.Load(), 10), nil + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + PasswordHistory.Store(TidbOptInt64(val, DefPasswordReuseHistory)) + return nil + }}, + {Scope: ScopeGlobal, Name: PasswordReuseTime, Value: strconv.Itoa(DefPasswordReuseTime), Type: TypeUnsigned, MinValue: 0, MaxValue: math.MaxUint32, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { + return strconv.FormatInt(PasswordReuseInterval.Load(), 10), nil + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { + PasswordReuseInterval.Store(TidbOptInt64(val, DefPasswordReuseTime)) + return nil }}, + {Scope: ScopeGlobal, Name: TiDBEnableHistoricalStatsForCapture, Value: BoolToOnOff(DefTiDBEnableHistoricalStatsForCapture), Type: TypeBool, + SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + EnableHistoricalStatsForCapture.Store(TiDBOptOn(s)) + return nil + }, + GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + return BoolToOnOff(EnableHistoricalStatsForCapture.Load()), nil + }, + }, + {Scope: ScopeGlobal, Name: TiDBHistoricalStatsDuration, Value: DefTiDBHistoricalStatsDuration.String(), Type: TypeDuration, MinValue: int64(time.Minute * 10), MaxValue: uint64(time.Hour * 24 * 365), + GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + return HistoricalStatsDuration.Load().String(), nil + }, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + d, err := time.ParseDuration(s) + if err != nil { + return err + } + HistoricalStatsDuration.Store(d) + return nil + }}, /* The system variables below have GLOBAL and SESSION scope */ - {Scope: ScopeGlobal | ScopeSession, Name: TiDBRowFormatVersion, Value: strconv.Itoa(DefTiDBRowFormatV1), Type: TypeUnsigned, MinValue: 1, MaxValue: 2, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnablePlanReplayerContinuesCapture, Value: BoolToOnOff(false), Type: TypeBool, + SetSession: func(s *SessionVars, val string) error { + s.EnablePlanReplayedContinuesCapture = TiDBOptOn(val) + return nil + }, + GetSession: func(vars *SessionVars) (string, error) { + return BoolToOnOff(vars.EnablePlanReplayedContinuesCapture), nil + }, + }, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnablePlanReplayerCapture, Value: BoolToOnOff(true), Type: TypeBool, + SetSession: func(s *SessionVars, val string) error { + s.EnablePlanReplayerCapture = TiDBOptOn(val) + return nil + }, + GetSession: func(vars *SessionVars) (string, error) { + return BoolToOnOff(vars.EnablePlanReplayerCapture), nil + }, + }, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBRowFormatVersion, Value: strconv.Itoa(DefTiDBRowFormatV1), Type: TypeUnsigned, MinValue: 1, MaxValue: 2, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { SetDDLReorgRowFormat(TidbOptInt64(val, DefTiDBRowFormatV2)) return nil }, SetSession: func(s *SessionVars, val string) error { @@ -1085,10 +1282,10 @@ var defaultSysVars = []*SysVar{ } return normalizedValue, ErrWrongValueForVar.GenWithStackByArgs(ForeignKeyChecks, originalValue) }}, - {Scope: ScopeGlobal, Name: TiDBEnableForeignKey, Value: BoolToOnOff(false), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBEnableForeignKey, Value: BoolToOnOff(true), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { EnableForeignKey.Store(TiDBOptOn(val)) return nil - }, GetGlobal: func(s *SessionVars) (string, error) { + }, GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return BoolToOnOff(EnableForeignKey.Load()), nil }}, {Scope: ScopeGlobal | ScopeSession, Name: CollationDatabase, Value: mysql.DefaultCollationName, skipInit: true, Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { @@ -1454,6 +1651,13 @@ var defaultSysVars = []*SysVar{ appendDeprecationWarning(vars, TiDBStreamAggConcurrency, TiDBExecutorConcurrency) return normalizedValue, nil }}, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBIndexMergeIntersectionConcurrency, Value: strconv.Itoa(DefTiDBIndexMergeIntersectionConcurrency), Type: TypeInt, MinValue: 1, MaxValue: MaxConfigurableConcurrency, AllowAutoValue: true, SetSession: func(s *SessionVars, val string) error { + s.indexMergeIntersectionConcurrency = tidbOptPositiveInt32(val, ConcurrencyUnset) + return nil + }, Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + appendDeprecationWarning(vars, TiDBIndexMergeIntersectionConcurrency, TiDBExecutorConcurrency) + return normalizedValue, nil + }}, {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableParallelApply, Value: BoolToOnOff(DefTiDBEnableParallelApply), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { s.EnableParallelApply = TiDBOptOn(val) return nil @@ -1579,7 +1783,7 @@ var defaultSysVars = []*SysVar{ s.NoopFuncsMode = TiDBOptOnOffWarn(val) return nil }}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBReplicaRead, Value: "leader", Type: TypeEnum, PossibleValues: []string{"leader", "follower", "leader-and-follower", "closest-replicas", "closest-adaptive"}, SetSession: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal | ScopeSession, Name: TiDBReplicaRead, Value: "leader", Type: TypeEnum, PossibleValues: []string{"leader", "follower", "leader-and-follower", "closest-replicas", "closest-adaptive", "learner"}, SetSession: func(s *SessionVars, val string) error { if strings.EqualFold(val, "follower") { s.SetReplicaRead(kv.ReplicaReadFollower) } else if strings.EqualFold(val, "leader-and-follower") { @@ -1590,6 +1794,8 @@ var defaultSysVars = []*SysVar{ s.SetReplicaRead(kv.ReplicaReadClosest) } else if strings.EqualFold(val, "closest-adaptive") { s.SetReplicaRead(kv.ReplicaReadClosestAdaptive) + } else if strings.EqualFold(val, "learner") { + s.SetReplicaRead(kv.ReplicaReadLearner) } return nil }}, @@ -1622,7 +1828,7 @@ var defaultSysVars = []*SysVar{ s.AllowAutoRandExplicitInsert = TiDBOptOn(val) return nil }}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableClusteredIndex, Value: IntOnly, Type: TypeEnum, PossibleValues: []string{Off, On, IntOnly}, Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableClusteredIndex, Value: On, Type: TypeEnum, PossibleValues: []string{Off, On, IntOnly}, Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { if normalizedValue == IntOnly { vars.StmtCtx.AppendWarning(errWarnDeprecatedSyntax.FastGenByArgs(normalizedValue, fmt.Sprintf("'%s' or '%s'", On, Off))) } @@ -1647,7 +1853,7 @@ var defaultSysVars = []*SysVar{ } s.PartitionPruneMode.Store(newMode) return nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { newMode := strings.ToLower(strings.TrimSpace(val)) if PartitionPruneMode(newMode) == Dynamic { s.StmtCtx.AppendWarning(errors.New("Please analyze all partition tables again for consistency between partition and global stats")) @@ -1663,14 +1869,6 @@ var defaultSysVars = []*SysVar{ s.ShardAllocateStep = TidbOptInt64(val, DefTiDBShardAllocateStep) return nil }}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableAmendPessimisticTxn, Value: BoolToOnOff(DefTiDBEnableAmendPessimisticTxn), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { - enableAmend := TiDBOptOn(val) - if enableAmend && EnableFastReorg.Load() { - return errors.Errorf("amend pessimistic transactions is not compatible with tidb_ddl_enable_fast_reorg") - } - s.EnableAmendPessimisticTxn = enableAmend - return nil - }}, {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableAsyncCommit, Value: BoolToOnOff(DefTiDBEnableAsyncCommit), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { s.EnableAsyncCommit = TiDBOptOn(val) return nil @@ -1740,7 +1938,7 @@ var defaultSysVars = []*SysVar{ {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnablePaging, Value: BoolToOnOff(DefTiDBEnablePaging), Type: TypeBool, Hidden: true, SetSession: func(s *SessionVars, val string) error { s.EnablePaging = TiDBOptOn(val) return nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { s.EnablePaging = TiDBOptOn(val) return nil }}, @@ -1753,10 +1951,10 @@ var defaultSysVars = []*SysVar{ s.StatsLoadSyncWait = TidbOptInt64(val, DefTiDBStatsLoadSyncWait) return nil }, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return strconv.FormatInt(StatsLoadSyncWait.Load(), 10), nil }, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { StatsLoadSyncWait.Store(TidbOptInt64(val, DefTiDBStatsLoadSyncWait)) return nil }, @@ -1810,6 +2008,12 @@ var defaultSysVars = []*SysVar{ return nil }, }, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBIndexJoinDoubleReadPenaltyCostRate, Value: strconv.Itoa(0), Hidden: false, Type: TypeFloat, MinValue: 0, MaxValue: math.MaxUint64, + SetSession: func(vars *SessionVars, s string) error { + vars.IndexJoinDoubleReadPenaltyCostRate = tidbOptFloat64(s, 0) + return nil + }, + }, {Scope: ScopeGlobal | ScopeSession, Name: TiDBRCWriteCheckTs, Type: TypeBool, Value: BoolToOnOff(DefTiDBRcWriteCheckTs), SetSession: func(s *SessionVars, val string) error { s.RcWriteCheckTS = TiDBOptOn(val) return nil @@ -1820,6 +2024,7 @@ var defaultSysVars = []*SysVar{ }}, {Scope: ScopeGlobal | ScopeSession, Name: TiDBMemQuotaQuery, Value: strconv.Itoa(DefTiDBMemQuotaQuery), Type: TypeInt, MinValue: -1, MaxValue: math.MaxInt64, SetSession: func(s *SessionVars, val string) error { s.MemQuotaQuery = TidbOptInt64(val, DefTiDBMemQuotaQuery) + s.MemTracker.SetBytesLimit(s.MemQuotaQuery) return nil }, Validation: func(vars *SessionVars, normalizedValue string, originalValue string, scope ScopeFlag) (string, error) { intVal := TidbOptInt64(normalizedValue, DefTiDBMemQuotaQuery) @@ -1846,7 +2051,7 @@ var defaultSysVars = []*SysVar{ return nil }}, {Scope: ScopeGlobal, Name: TiDBSimplifiedMetrics, Value: BoolToOnOff(DefTiDBSimplifiedMetrics), Type: TypeBool, - SetGlobal: func(vars *SessionVars, s string) error { + SetGlobal: func(_ context.Context, vars *SessionVars, s string) error { metrics.ToggleSimplifiedMode(TiDBOptOn(s)) return nil }}, @@ -1874,7 +2079,7 @@ var defaultSysVars = []*SysVar{ s.EnableAnalyzeSnapshot = TiDBOptOn(val) return nil }}, - {Scope: ScopeGlobal, Name: TiDBGenerateBinaryPlan, Value: BoolToOnOff(DefTiDBGenerateBinaryPlan), Type: TypeBool, SetGlobal: func(s *SessionVars, val string) error { + {Scope: ScopeGlobal, Name: TiDBGenerateBinaryPlan, Value: BoolToOnOff(DefTiDBGenerateBinaryPlan), Type: TypeBool, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { GenerateBinaryPlan.Store(TiDBOptOn(val)) return nil }}, @@ -1883,20 +2088,20 @@ var defaultSysVars = []*SysVar{ s.DefaultStrMatchSelectivity = tidbOptFloat64(val, DefTiDBDefaultStrMatchSelectivity) return nil }}, - {Scope: ScopeGlobal, Name: TiDBDDLEnableFastReorg, Value: BoolToOnOff(DefTiDBEnableFastReorg), Type: TypeBool, GetGlobal: func(sv *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBDDLEnableFastReorg, Value: BoolToOnOff(DefTiDBEnableFastReorg), Type: TypeBool, GetGlobal: func(_ context.Context, sv *SessionVars) (string, error) { return BoolToOnOff(EnableFastReorg.Load()), nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { EnableFastReorg.Store(TiDBOptOn(val)) return nil }}, // This system var is set disk quota for lightning sort dir, from 100 GB to 1PB. - {Scope: ScopeGlobal, Name: TiDBDDLDiskQuota, Value: strconv.Itoa(DefTiDBDDLDiskQuota), Type: TypeInt, MinValue: DefTiDBDDLDiskQuota, MaxValue: 1024 * 1024 * DefTiDBDDLDiskQuota / 100, GetGlobal: func(sv *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBDDLDiskQuota, Value: strconv.Itoa(DefTiDBDDLDiskQuota), Type: TypeInt, MinValue: DefTiDBDDLDiskQuota, MaxValue: 1024 * 1024 * DefTiDBDDLDiskQuota / 100, GetGlobal: func(_ context.Context, sv *SessionVars) (string, error) { return strconv.FormatUint(DDLDiskQuota.Load(), 10), nil - }, SetGlobal: func(s *SessionVars, val string) error { + }, SetGlobal: func(_ context.Context, s *SessionVars, val string) error { DDLDiskQuota.Store(TidbOptUint64(val, DefTiDBDDLDiskQuota)) return nil }}, - {Scope: ScopeGlobal | ScopeSession, Name: TiDBConstraintCheckInPlacePessimistic, Value: BoolToOnOff(DefTiDBConstraintCheckInPlacePessimistic), Type: TypeBool, + {Scope: ScopeSession, Name: TiDBConstraintCheckInPlacePessimistic, Value: BoolToOnOff(config.GetGlobalConfig().PessimisticTxn.ConstraintCheckInPlacePessimistic), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { s.ConstraintCheckInPlacePessimistic = TiDBOptOn(val) if !s.ConstraintCheckInPlacePessimistic { @@ -1916,6 +2121,152 @@ var defaultSysVars = []*SysVar{ s.RangeMaxSize = TidbOptInt64(val, DefTiDBOptRangeMaxSize) return nil }}, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBAnalyzePartitionConcurrency, Value: strconv.FormatInt(DefTiDBAnalyzePartitionConcurrency, 10), + MinValue: 1, MaxValue: uint64(config.GetGlobalConfig().Performance.AnalyzePartitionConcurrencyQuota), SetSession: func(s *SessionVars, val string) error { + s.AnalyzePartitionConcurrency = int(TidbOptInt64(val, DefTiDBAnalyzePartitionConcurrency)) + return nil + }}, + { + Scope: ScopeGlobal | ScopeSession, Name: TiDBMergePartitionStatsConcurrency, Value: strconv.FormatInt(DefTiDBMergePartitionStatsConcurrency, 10), Type: TypeInt, MinValue: 1, MaxValue: MaxConfigurableConcurrency, + SetSession: func(s *SessionVars, val string) error { + s.AnalyzePartitionMergeConcurrency = TidbOptInt(val, DefTiDBMergePartitionStatsConcurrency) + return nil + }, + }, + + {Scope: ScopeGlobal | ScopeSession, Name: TiDBOptPrefixIndexSingleScan, Value: BoolToOnOff(DefTiDBOptPrefixIndexSingleScan), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { + s.OptPrefixIndexSingleScan = TiDBOptOn(val) + return nil + }}, + {Scope: ScopeGlobal, Name: TiDBExternalTS, Value: strconv.FormatInt(DefTiDBExternalTS, 10), SetGlobal: func(ctx context.Context, s *SessionVars, val string) error { + ts, err := parseTSFromNumberOrTime(s, val) + if err != nil { + return err + } + return SetExternalTimestamp(ctx, ts) + }, GetGlobal: func(ctx context.Context, s *SessionVars) (string, error) { + ts, err := GetExternalTimestamp(ctx) + if err != nil { + return "", err + } + return strconv.Itoa(int(ts)), err + }}, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableExternalTSRead, Value: BoolToOnOff(false), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { + s.EnableExternalTSRead = TiDBOptOn(val) + return nil + }}, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableReusechunk, Value: BoolToOnOff(DefTiDBEnableReusechunk), Type: TypeBool, + SetSession: func(s *SessionVars, val string) error { + s.EnableReuseCheck = TiDBOptOn(val) + return nil + }}, + {Scope: ScopeGlobal, Name: TiDBTTLJobEnable, Value: BoolToOnOff(DefTiDBTTLJobEnable), Type: TypeBool, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + EnableTTLJob.Store(TiDBOptOn(s)) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + return BoolToOnOff(EnableTTLJob.Load()), nil + }}, + {Scope: ScopeGlobal, Name: TiDBTTLScanBatchSize, Value: strconv.Itoa(DefTiDBTTLScanBatchSize), Type: TypeInt, MinValue: DefTiDBTTLScanBatchMinSize, MaxValue: DefTiDBTTLScanBatchMaxSize, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + val, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + TTLScanBatchSize.Store(val) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + val := TTLScanBatchSize.Load() + return strconv.FormatInt(val, 10), nil + }}, + {Scope: ScopeGlobal, Name: TiDBTTLDeleteBatchSize, Value: strconv.Itoa(DefTiDBTTLDeleteBatchSize), Type: TypeInt, MinValue: DefTiDBTTLDeleteBatchMinSize, MaxValue: DefTiDBTTLDeleteBatchMaxSize, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + val, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + TTLDeleteBatchSize.Store(val) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + val := TTLDeleteBatchSize.Load() + return strconv.FormatInt(val, 10), nil + }}, + {Scope: ScopeGlobal, Name: TiDBTTLDeleteRateLimit, Value: strconv.Itoa(DefTiDBTTLDeleteRateLimit), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt64, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + val, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + TTLDeleteRateLimit.Store(val) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + val := TTLDeleteRateLimit.Load() + return strconv.FormatInt(val, 10), nil + }}, + { + Scope: ScopeGlobal | ScopeSession, Name: TiDBStoreBatchSize, Value: strconv.FormatInt(DefTiDBStoreBatchSize, 10), + Type: TypeInt, MinValue: 0, MaxValue: 25000, SetSession: func(s *SessionVars, val string) error { + s.StoreBatchSize = TidbOptInt(val, DefTiDBStoreBatchSize) + return nil + }, + }, + { + Scope: ScopeGlobal, Name: TiDBTTLJobScheduleWindowStartTime, Value: DefTiDBTTLJobScheduleWindowStartTime, Type: TypeTime, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + startTime, err := time.ParseInLocation(FullDayTimeFormat, s, time.UTC) + if err != nil { + return err + } + TTLJobScheduleWindowStartTime.Store(startTime) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + startTime := TTLJobScheduleWindowStartTime.Load() + return startTime.Format(FullDayTimeFormat), nil + }, + }, + { + Scope: ScopeGlobal, Name: TiDBTTLJobScheduleWindowEndTime, Value: DefTiDBTTLJobScheduleWindowEndTime, Type: TypeTime, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + endTime, err := time.ParseInLocation(FullDayTimeFormat, s, time.UTC) + if err != nil { + return err + } + TTLJobScheduleWindowEndTime.Store(endTime) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + endTime := TTLJobScheduleWindowEndTime.Load() + return endTime.Format(FullDayTimeFormat), nil + }, + }, + { + Scope: ScopeGlobal, Name: TiDBTTLScanWorkerCount, Value: strconv.Itoa(DefTiDBTTLScanWorkerCount), Type: TypeUnsigned, MinValue: 1, MaxValue: 256, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + val, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + TTLScanWorkerCount.Store(int32(val)) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + return strconv.Itoa(int(TTLScanWorkerCount.Load())), nil + }, + }, + { + Scope: ScopeGlobal, Name: TiDBTTLDeleteWorkerCount, Value: strconv.Itoa(DefTiDBTTLDeleteWorkerCount), Type: TypeUnsigned, MinValue: 1, MaxValue: 256, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + val, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + TTLDeleteWorkerCount.Store(int32(val)) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + return strconv.Itoa(int(TTLDeleteWorkerCount.Load())), nil + }, + }, + {Scope: ScopeGlobal, Name: TiDBEnableResourceControl, Value: BoolToOnOff(DefTiDBEnableResourceControl), Type: TypeBool, SetGlobal: func(ctx context.Context, vars *SessionVars, s string) error { + EnableResourceControl.Store(TiDBOptOn(s)) + (*SetGlobalResourceControl.Load())(TiDBOptOn(s)) + return nil + }, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) { + return BoolToOnOff(EnableResourceControl.Load()), nil + }}, + {Scope: ScopeGlobal | ScopeSession, Name: TiDBPessimisticTransactionAggressiveLocking, Value: BoolToOnOff(DefTiDBPessimisticTransactionAggressiveLocking), Type: TypeBool, SetSession: func(s *SessionVars, val string) error { + s.PessimisticTransactionAggressiveLocking = TiDBOptOn(val) + return nil + }}, } // FeedbackProbability points to the FeedbackProbability in statistics package. @@ -2016,6 +2367,10 @@ const ( WarningCount = "warning_count" // ErrorCount is the name for 'error_count' system variable. ErrorCount = "error_count" + // DefaultPasswordLifetime is the name for 'default_password_lifetime' system variable. + DefaultPasswordLifetime = "default_password_lifetime" + // DisconnectOnExpiredPassword is the name for 'disconnect_on_expired_password' system variable. + DisconnectOnExpiredPassword = "disconnect_on_expired_password" // SQLSelectLimit is the name for 'sql_select_limit' system variable. SQLSelectLimit = "sql_select_limit" // MaxConnectErrors is the name for 'max_connect_errors' system variable. @@ -2032,10 +2387,6 @@ const ( BlockEncryptionMode = "block_encryption_mode" // WaitTimeout is the name for 'wait_timeout' system variable. WaitTimeout = "wait_timeout" - // ValidatePasswordNumberCount is the name of 'validate_password_number_count' system variable. - ValidatePasswordNumberCount = "validate_password_number_count" - // ValidatePasswordLength is the name of 'validate_password_length' system variable. - ValidatePasswordLength = "validate_password_length" // Version is the name of 'version' system variable. Version = "version" // VersionComment is the name of 'version_comment' system variable. @@ -2058,8 +2409,6 @@ const ( BinlogOrderCommits = "binlog_order_commits" // MasterVerifyChecksum is the name for 'master_verify_checksum' system variable. MasterVerifyChecksum = "master_verify_checksum" - // ValidatePasswordCheckUserName is the name for 'validate_password_check_user_name' system variable. - ValidatePasswordCheckUserName = "validate_password_check_user_name" // SuperReadOnly is the name for 'super_read_only' system variable. SuperReadOnly = "super_read_only" // SQLNotes is the name for 'sql_notes' system variable. @@ -2226,4 +2575,21 @@ const ( RandSeed2 = "rand_seed2" // SQLRequirePrimaryKey is the name of `sql_require_primary_key` system variable. SQLRequirePrimaryKey = "sql_require_primary_key" + // ValidatePasswordEnable turns on/off the validation of password. + ValidatePasswordEnable = "validate_password.enable" + // ValidatePasswordPolicy specifies the password policy enforced by validate_password. + ValidatePasswordPolicy = "validate_password.policy" + // ValidatePasswordCheckUserName controls whether validate_password compares passwords to the user name part of + // the effective user account for the current session + ValidatePasswordCheckUserName = "validate_password.check_user_name" + // ValidatePasswordLength specified the minimum number of characters that validate_password requires passwords to have + ValidatePasswordLength = "validate_password.length" + // ValidatePasswordMixedCaseCount specified the minimum number of lowercase and uppercase characters that validate_password requires + ValidatePasswordMixedCaseCount = "validate_password.mixed_case_count" + // ValidatePasswordNumberCount specified the minimum number of numeric (digit) characters that validate_password requires + ValidatePasswordNumberCount = "validate_password.number_count" + // ValidatePasswordSpecialCharCount specified the minimum number of nonalphanumeric characters that validate_password requires + ValidatePasswordSpecialCharCount = "validate_password.special_char_count" + // ValidatePasswordDictionary specified the dictionary that validate_password uses for checking passwords. Each word is separated by semicolon (;). + ValidatePasswordDictionary = "validate_password.dictionary" ) diff --git a/sessionctx/variable/sysvar_test.go b/sessionctx/variable/sysvar_test.go index a1b996d7468a8..cf879d3ec4344 100644 --- a/sessionctx/variable/sysvar_test.go +++ b/sessionctx/variable/sysvar_test.go @@ -15,16 +15,21 @@ package variable import ( + "context" "encoding/json" "fmt" "math" "strconv" "sync/atomic" "testing" + "time" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/util/gctuner" + "github.com/pingcap/tidb/util/memory" "github.com/stretchr/testify/require" ) @@ -160,7 +165,7 @@ func TestTxnIsolation(t *testing.T) { require.Equal(t, "[variable:8048]The isolation level 'READ-UNCOMMITTED' is not supported. Set tidb_skip_isolation_level_check=1 to skip this error", err.Error()) // Enable global skip isolation check doesn't affect current session - require.Nil(t, GetSysVar(TiDBSkipIsolationLevelCheck).SetGlobalFromHook(vars, "ON", true)) + require.Nil(t, GetSysVar(TiDBSkipIsolationLevelCheck).SetGlobalFromHook(context.Background(), vars, "ON", true)) _, err = sv.Validate(vars, "Serializable", ScopeSession) require.Equal(t, "[variable:8048]The isolation level 'SERIALIZABLE' is not supported. Set tidb_skip_isolation_level_check=1 to skip this error", err.Error()) @@ -232,10 +237,10 @@ func TestReadOnlyNoop(t *testing.T) { require.Equal(t, "[variable:1235]function READ ONLY has only noop implementation in tidb now, use tidb_enable_noop_functions to enable these functions", err.Error()) } require.Equal(t, "OFF", val) - require.NoError(t, vars.GlobalVarsAccessor.SetGlobalSysVar(TiDBEnableNoopFuncs, "ON")) + require.NoError(t, vars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), TiDBEnableNoopFuncs, "ON")) _, err = sv.Validate(vars, "on", ScopeGlobal) require.NoError(t, err) - require.NoError(t, vars.GlobalVarsAccessor.SetGlobalSysVar(TiDBEnableNoopFuncs, "OFF")) + require.NoError(t, vars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), TiDBEnableNoopFuncs, "OFF")) } } @@ -255,40 +260,40 @@ func TestSkipInit(t *testing.T) { func TestSessionGetterFuncs(t *testing.T) { vars := NewSessionVars(nil) - val, err := vars.GetSessionOrGlobalSystemVar(TiDBCurrentTS) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBCurrentTS) require.NoError(t, err) require.Equal(t, fmt.Sprintf("%d", vars.TxnCtx.StartTS), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBLastTxnInfo) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBLastTxnInfo) require.NoError(t, err) require.Equal(t, vars.LastTxnInfo, val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBLastQueryInfo) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBLastQueryInfo) require.NoError(t, err) info, err := json.Marshal(vars.LastQueryInfo) require.NoError(t, err) require.Equal(t, string(info), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBFoundInPlanCache) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBFoundInPlanCache) require.NoError(t, err) require.Equal(t, BoolToOnOff(vars.PrevFoundInPlanCache), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBFoundInBinding) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBFoundInBinding) require.NoError(t, err) require.Equal(t, BoolToOnOff(vars.PrevFoundInBinding), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBTxnScope) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBTxnScope) require.NoError(t, err) require.Equal(t, vars.TxnScope.GetVarValue(), val) } func TestInstanceScopedVars(t *testing.T) { vars := NewSessionVars(nil) - val, err := vars.GetSessionOrGlobalSystemVar(TiDBGeneralLog) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBGeneralLog) require.NoError(t, err) require.Equal(t, BoolToOnOff(ProcessGeneralLog.Load()), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBPProfSQLCPU) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBPProfSQLCPU) require.NoError(t, err) expected := "0" if EnablePProfSQLCPU.Load() { @@ -296,66 +301,66 @@ func TestInstanceScopedVars(t *testing.T) { } require.Equal(t, expected, val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBExpensiveQueryTimeThreshold) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBExpensiveQueryTimeThreshold) require.NoError(t, err) require.Equal(t, fmt.Sprintf("%d", atomic.LoadUint64(&ExpensiveQueryTimeThreshold)), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBMemoryUsageAlarmRatio) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBMemoryUsageAlarmRatio) require.NoError(t, err) require.Equal(t, fmt.Sprintf("%g", MemoryUsageAlarmRatio.Load()), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBMemoryUsageAlarmKeepRecordNum) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBMemoryUsageAlarmKeepRecordNum) require.NoError(t, err) require.Equal(t, fmt.Sprintf("%d", MemoryUsageAlarmKeepRecordNum.Load()), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBForcePriority) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBForcePriority) require.NoError(t, err) require.Equal(t, mysql.Priority2Str[mysql.PriorityEnum(atomic.LoadInt32(&ForcePriority))], val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBDDLSlowOprThreshold) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBDDLSlowOprThreshold) require.NoError(t, err) require.Equal(t, strconv.FormatUint(uint64(atomic.LoadUint32(&DDLSlowOprThreshold)), 10), val) - val, err = vars.GetSessionOrGlobalSystemVar(PluginDir) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), PluginDir) require.NoError(t, err) require.Equal(t, config.GetGlobalConfig().Instance.PluginDir, val) - val, err = vars.GetSessionOrGlobalSystemVar(PluginLoad) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), PluginLoad) require.NoError(t, err) require.Equal(t, config.GetGlobalConfig().Instance.PluginLoad, val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBSlowLogThreshold) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBSlowLogThreshold) require.NoError(t, err) require.Equal(t, strconv.FormatUint(atomic.LoadUint64(&config.GetGlobalConfig().Instance.SlowThreshold), 10), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBRecordPlanInSlowLog) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBRecordPlanInSlowLog) require.NoError(t, err) enabled := atomic.LoadUint32(&config.GetGlobalConfig().Instance.RecordPlanInSlowLog) == 1 require.Equal(t, BoolToOnOff(enabled), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBEnableSlowLog) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBEnableSlowLog) require.NoError(t, err) require.Equal(t, BoolToOnOff(config.GetGlobalConfig().Instance.EnableSlowLog.Load()), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBCheckMb4ValueInUTF8) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBCheckMb4ValueInUTF8) require.NoError(t, err) require.Equal(t, BoolToOnOff(config.GetGlobalConfig().Instance.CheckMb4ValueInUTF8.Load()), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBEnableCollectExecutionInfo) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBEnableCollectExecutionInfo) require.NoError(t, err) require.Equal(t, BoolToOnOff(config.GetGlobalConfig().Instance.EnableCollectExecutionInfo.Load()), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBConfig) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBConfig) require.NoError(t, err) expected, err = config.GetJSONConfig() require.NoError(t, err) require.Equal(t, expected, val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBLogFileMaxDays) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBLogFileMaxDays) require.NoError(t, err) require.Equal(t, fmt.Sprint(GlobalLogMaxDays.Load()), val) - val, err = vars.GetSessionOrGlobalSystemVar(TiDBRCReadCheckTS) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBRCReadCheckTS) require.NoError(t, err) require.Equal(t, BoolToOnOff(EnableRCReadCheckTS.Load()), val) } @@ -406,29 +411,29 @@ func TestSQLAutoIsNull(t *testing.T) { func TestLastInsertID(t *testing.T) { vars := NewSessionVars(nil) - val, err := vars.GetSessionOrGlobalSystemVar(LastInsertID) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), LastInsertID) require.NoError(t, err) require.Equal(t, val, "0") vars.StmtCtx.PrevLastInsertID = 21 - val, err = vars.GetSessionOrGlobalSystemVar(LastInsertID) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), LastInsertID) require.NoError(t, err) require.Equal(t, val, "21") } func TestTimestamp(t *testing.T) { vars := NewSessionVars(nil) - val, err := vars.GetSessionOrGlobalSystemVar(Timestamp) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), Timestamp) require.NoError(t, err) require.NotEqual(t, "", val) vars.systems[Timestamp] = "10" - val, err = vars.GetSessionOrGlobalSystemVar(Timestamp) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), Timestamp) require.NoError(t, err) require.Equal(t, "10", val) vars.systems[Timestamp] = "0" // set to default - val, err = vars.GetSessionOrGlobalSystemVar(Timestamp) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), Timestamp) require.NoError(t, err) require.NotEqual(t, "", val) require.NotEqual(t, "10", val) @@ -454,12 +459,12 @@ func TestTimestamp(t *testing.T) { func TestIdentity(t *testing.T) { vars := NewSessionVars(nil) - val, err := vars.GetSessionOrGlobalSystemVar(Identity) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), Identity) require.NoError(t, err) require.Equal(t, val, "0") vars.StmtCtx.PrevLastInsertID = 21 - val, err = vars.GetSessionOrGlobalSystemVar(Identity) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), Identity) require.NoError(t, err) require.Equal(t, val, "21") } @@ -480,7 +485,7 @@ func TestLcMessages(t *testing.T) { require.NoError(t, err) err = sv.SetSessionFromHook(vars, "zh_CN") require.NoError(t, err) - val, err := vars.GetSessionOrGlobalSystemVar("lc_messages") + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), "lc_messages") require.NoError(t, err) require.Equal(t, val, "zh_CN") } @@ -513,10 +518,10 @@ func TestDDLWorkers(t *testing.T) { func TestDefaultCharsetAndCollation(t *testing.T) { vars := NewSessionVars(nil) - val, err := vars.GetSessionOrGlobalSystemVar(CharacterSetConnection) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), CharacterSetConnection) require.NoError(t, err) require.Equal(t, val, mysql.DefaultCharset) - val, err = vars.GetSessionOrGlobalSystemVar(CollationConnection) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), CollationConnection) require.NoError(t, err) require.Equal(t, val, mysql.DefaultCollationName) } @@ -524,7 +529,7 @@ func TestDefaultCharsetAndCollation(t *testing.T) { func TestIndexMergeSwitcher(t *testing.T) { vars := NewSessionVars(nil) vars.GlobalVarsAccessor = NewMockGlobalAccessor4Tests() - val, err := vars.GetSessionOrGlobalSystemVar(TiDBEnableIndexMerge) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBEnableIndexMerge) require.NoError(t, err) require.Equal(t, DefTiDBEnableIndexMerge, true) require.Equal(t, BoolToOnOff(DefTiDBEnableIndexMerge), val) @@ -662,20 +667,41 @@ func TestTiDBDDLFlashbackConcurrency(t *testing.T) { func TestDefaultMemoryDebugModeValue(t *testing.T) { vars := NewSessionVars(nil) - val, err := vars.GetSessionOrGlobalSystemVar(TiDBMemoryDebugModeMinHeapInUse) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBMemoryDebugModeMinHeapInUse) require.NoError(t, err) require.Equal(t, val, "0") - val, err = vars.GetSessionOrGlobalSystemVar(TiDBMemoryDebugModeAlarmRatio) + val, err = vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBMemoryDebugModeAlarmRatio) require.NoError(t, err) require.Equal(t, val, "0") } +func TestSetTIDBDistributeReorg(t *testing.T) { + vars := NewSessionVars(nil) + mock := NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + + // Set to on + err := mock.SetGlobalSysVar(context.Background(), TiDBDDLEnableDistributeReorg, On) + require.NoError(t, err) + val, err := mock.GetGlobalSysVar(TiDBDDLEnableDistributeReorg) + require.NoError(t, err) + require.Equal(t, On, val) + + // Set to off + err = mock.SetGlobalSysVar(context.Background(), TiDBDDLEnableDistributeReorg, Off) + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBDDLEnableDistributeReorg) + require.NoError(t, err) + require.Equal(t, Off, val) +} + func TestDefaultPartitionPruneMode(t *testing.T) { vars := NewSessionVars(nil) mock := NewMockGlobalAccessor4Tests() mock.SessionVars = vars vars.GlobalVarsAccessor = mock - val, err := vars.GetSessionOrGlobalSystemVar(TiDBPartitionPruneMode) + val, err := vars.GetSessionOrGlobalSystemVar(context.Background(), TiDBPartitionPruneMode) require.NoError(t, err) require.Equal(t, "dynamic", val) require.Equal(t, "dynamic", DefTiDBPartitionPruneMode) @@ -688,18 +714,18 @@ func TestSetTIDBFastDDL(t *testing.T) { vars.GlobalVarsAccessor = mock fastDDL := GetSysVar(TiDBDDLEnableFastReorg) - // Default off - require.Equal(t, fastDDL.Value, Off) + // Default true + require.Equal(t, fastDDL.Value, On) // Set to On - err := mock.SetGlobalSysVar(TiDBDDLEnableFastReorg, On) + err := mock.SetGlobalSysVar(context.Background(), TiDBDDLEnableFastReorg, On) require.NoError(t, err) val, err1 := mock.GetGlobalSysVar(TiDBDDLEnableFastReorg) require.NoError(t, err1) require.Equal(t, On, val) // Set to off - err = mock.SetGlobalSysVar(TiDBDDLEnableFastReorg, Off) + err = mock.SetGlobalSysVar(context.Background(), TiDBDDLEnableFastReorg, Off) require.NoError(t, err) val, err1 = mock.GetGlobalSysVar(TiDBDDLEnableFastReorg) require.NoError(t, err1) @@ -722,35 +748,35 @@ func TestSetTIDBDiskQuota(t *testing.T) { require.Equal(t, diskQuota.Value, strconv.FormatInt(100*gb, 10)) // MinValue is 100 GB, set to 50 Gb is not allowed - err = mock.SetGlobalSysVar(TiDBDDLDiskQuota, strconv.FormatInt(50*gb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBDDLDiskQuota, strconv.FormatInt(50*gb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBDDLDiskQuota) require.NoError(t, err) require.Equal(t, strconv.FormatInt(100*gb, 10), val) // Set to 100 GB - err = mock.SetGlobalSysVar(TiDBDDLDiskQuota, strconv.FormatInt(100*gb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBDDLDiskQuota, strconv.FormatInt(100*gb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBDDLDiskQuota) require.NoError(t, err) require.Equal(t, strconv.FormatInt(100*gb, 10), val) // Set to 200 GB - err = mock.SetGlobalSysVar(TiDBDDLDiskQuota, strconv.FormatInt(200*gb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBDDLDiskQuota, strconv.FormatInt(200*gb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBDDLDiskQuota) require.NoError(t, err) require.Equal(t, strconv.FormatInt(200*gb, 10), val) // Set to 1 Pb - err = mock.SetGlobalSysVar(TiDBDDLDiskQuota, strconv.FormatInt(pb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBDDLDiskQuota, strconv.FormatInt(pb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBDDLDiskQuota) require.NoError(t, err) require.Equal(t, strconv.FormatInt(pb, 10), val) // MaxValue is 1 PB, set to 2 Pb is not allowed, it will set back to 1 PB max allowed value. - err = mock.SetGlobalSysVar(TiDBDDLDiskQuota, strconv.FormatInt(2*pb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBDDLDiskQuota, strconv.FormatInt(2*pb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBDDLDiskQuota) require.NoError(t, err) @@ -770,31 +796,31 @@ func TestTiDBServerMemoryLimit(t *testing.T) { // Test tidb_server_memory_limit serverMemoryLimit := GetSysVar(TiDBServerMemoryLimit) // Check default value - require.Equal(t, serverMemoryLimit.Value, strconv.FormatUint(DefTiDBServerMemoryLimit, 10)) + require.Equal(t, serverMemoryLimit.Value, DefTiDBServerMemoryLimit) // MinValue is 512 MB - err = mock.SetGlobalSysVar(TiDBServerMemoryLimit, strconv.FormatUint(100*mb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, strconv.FormatUint(100*mb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) require.NoError(t, err) - require.Equal(t, strconv.FormatUint(512*mb, 10), val) + require.Equal(t, "512MB", val) // Test Close - err = mock.SetGlobalSysVar(TiDBServerMemoryLimit, strconv.FormatUint(0, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, strconv.FormatUint(0, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) require.NoError(t, err) - require.Equal(t, strconv.FormatUint(0, 10), val) + require.Equal(t, "0", val) // Test MaxValue - err = mock.SetGlobalSysVar(TiDBServerMemoryLimit, strconv.FormatUint(math.MaxUint64, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, strconv.FormatUint(math.MaxUint64, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) require.NoError(t, err) require.Equal(t, strconv.FormatUint(math.MaxUint64, 10), val) // Test Normal Value - err = mock.SetGlobalSysVar(TiDBServerMemoryLimit, strconv.FormatUint(1024*mb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, strconv.FormatUint(1024*mb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) require.NoError(t, err) @@ -806,30 +832,326 @@ func TestTiDBServerMemoryLimit(t *testing.T) { require.Equal(t, serverMemoryLimitSessMinSize.Value, strconv.FormatUint(DefTiDBServerMemoryLimitSessMinSize, 10)) // MinValue is 128 Bytes - err = mock.SetGlobalSysVar(TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(100, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(100, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitSessMinSize) require.NoError(t, err) require.Equal(t, strconv.FormatUint(128, 10), val) // Test Close - err = mock.SetGlobalSysVar(TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(0, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(0, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitSessMinSize) require.NoError(t, err) require.Equal(t, strconv.FormatUint(0, 10), val) // Test MaxValue - err = mock.SetGlobalSysVar(TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(math.MaxUint64, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(math.MaxUint64, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitSessMinSize) require.NoError(t, err) require.Equal(t, strconv.FormatUint(math.MaxUint64, 10), val) // Test Normal Value - err = mock.SetGlobalSysVar(TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(200*mb, 10)) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitSessMinSize, strconv.FormatUint(200*mb, 10)) require.NoError(t, err) val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitSessMinSize) require.NoError(t, err) require.Equal(t, strconv.FormatUint(200*mb, 10), val) } + +func TestTiDBServerMemoryLimit2(t *testing.T) { + vars := NewSessionVars(nil) + mock := NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + var ( + err error + val string + ) + // Test tidb_server_memory_limit + serverMemoryLimit := GetSysVar(TiDBServerMemoryLimit) + // Check default value + require.Equal(t, serverMemoryLimit.Value, DefTiDBServerMemoryLimit) + + total := memory.GetMemTotalIgnoreErr() + if total > 0 { + // Can use percentage format when TiDB can obtain physical memory + // Test Percentage Format + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "1%") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + if total/100 > uint64(512<<20) { + require.Equal(t, memory.ServerMemoryLimit.Load(), total/100) + require.Equal(t, "1%", val) + } else { + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(512<<20)) + require.Equal(t, "512MB", val) + } + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "0%") + require.Error(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "100%") + require.Error(t, err) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "75%") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, "75%", val) + require.Equal(t, memory.ServerMemoryLimit.Load(), total/100*75) + } + // Test can't obtain physical memory + require.Nil(t, failpoint.Enable("github.com/pingcap/tidb/util/memory/GetMemTotalError", `return(true)`)) + require.Error(t, mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "75%")) + require.Nil(t, failpoint.Disable("github.com/pingcap/tidb/util/memory/GetMemTotalError")) + + // Test byteSize format + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "1234") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(512<<20)) + require.Equal(t, "512MB", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "1234567890123") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(1234567890123)) + require.Equal(t, "1234567890123", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "10KB") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(512<<20)) + require.Equal(t, "512MB", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "12345678KB") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(12345678<<10)) + require.Equal(t, "12345678KB", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "10MB") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(512<<20)) + require.Equal(t, "512MB", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "700MB") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(700<<20)) + require.Equal(t, "700MB", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "20GB") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(20<<30)) + require.Equal(t, "20GB", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "2TB") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimit) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimit.Load(), uint64(2<<40)) + require.Equal(t, "2TB", val) + + // Test error + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "123aaa123") + require.Error(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "700MBaa") + require.Error(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimit, "a700MB") + require.Error(t, err) +} + +func TestTiDBServerMemoryLimitSessMinSize(t *testing.T) { + vars := NewSessionVars(nil) + mock := NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + + var ( + err error + val string + ) + + serverMemroyLimitSessMinSize := GetSysVar(TiDBServerMemoryLimitSessMinSize) + // Check default value + require.Equal(t, serverMemroyLimitSessMinSize.Value, strconv.FormatInt(DefTiDBServerMemoryLimitSessMinSize, 10)) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitSessMinSize, "123456") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitSessMinSize) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimitSessMinSize.Load(), uint64(123456)) + require.Equal(t, "123456", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitSessMinSize, "100") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitSessMinSize) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimitSessMinSize.Load(), uint64(128)) + require.Equal(t, "128", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitSessMinSize, "123MB") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitSessMinSize) + require.NoError(t, err) + require.Equal(t, memory.ServerMemoryLimitSessMinSize.Load(), uint64(123<<20)) + require.Equal(t, "128974848", val) +} + +func TestTiDBServerMemoryLimitGCTrigger(t *testing.T) { + vars := NewSessionVars(nil) + mock := NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + + var ( + err error + val string + ) + + serverMemroyLimitGCTrigger := GetSysVar(TiDBServerMemoryLimitGCTrigger) + // Check default value + require.Equal(t, serverMemroyLimitGCTrigger.Value, strconv.FormatFloat(DefTiDBServerMemoryLimitGCTrigger, 'f', -1, 64)) + defer func() { + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, strconv.FormatFloat(DefTiDBServerMemoryLimitGCTrigger, 'f', -1, 64)) + require.NoError(t, err) + }() + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, "0.8") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitGCTrigger) + require.NoError(t, err) + require.Equal(t, gctuner.GlobalMemoryLimitTuner.GetPercentage(), 0.8) + require.Equal(t, "0.8", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, "90%") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBServerMemoryLimitGCTrigger) + require.NoError(t, err) + require.Equal(t, gctuner.GlobalMemoryLimitTuner.GetPercentage(), 0.9) + require.Equal(t, "0.9", val) + + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, "100%") + require.Error(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, "101%") + require.Error(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, "99%") + require.NoError(t, err) + + err = mock.SetGlobalSysVar(context.Background(), TiDBGOGCTunerThreshold, "0.4") + require.NoError(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, "49%") + require.Error(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBServerMemoryLimitGCTrigger, "51%") + require.NoError(t, err) +} + +func TestSetAggPushDownGlobally(t *testing.T) { + vars := NewSessionVars(nil) + mock := NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + + val, err := mock.GetGlobalSysVar(TiDBOptAggPushDown) + require.NoError(t, err) + require.Equal(t, "OFF", val) + err = mock.SetGlobalSysVar(context.Background(), TiDBOptAggPushDown, "ON") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBOptAggPushDown) + require.NoError(t, err) + require.Equal(t, "ON", val) +} + +func TestSetJobScheduleWindow(t *testing.T) { + vars := NewSessionVars(nil) + mock := NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + + // default value + val, err := mock.GetGlobalSysVar(TiDBTTLJobScheduleWindowStartTime) + require.NoError(t, err) + require.Equal(t, "00:00 +0000", val) + + // set and get variable in UTC + vars.TimeZone = time.UTC + err = mock.SetGlobalSysVar(context.Background(), TiDBTTLJobScheduleWindowStartTime, "16:11") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBTTLJobScheduleWindowStartTime) + require.NoError(t, err) + require.Equal(t, "16:11 +0000", val) + + // set variable in UTC, get it in Asia/Shanghai + vars.TimeZone = time.UTC + err = mock.SetGlobalSysVar(context.Background(), TiDBTTLJobScheduleWindowStartTime, "16:11") + require.NoError(t, err) + vars.TimeZone, err = time.LoadLocation("Asia/Shanghai") + require.NoError(t, err) + val, err = mock.GetGlobalSysVar(TiDBTTLJobScheduleWindowStartTime) + require.NoError(t, err) + require.Equal(t, "16:11 +0000", val) + + // set variable in Asia/Shanghai, get it it UTC + vars.TimeZone, err = time.LoadLocation("Asia/Shanghai") + require.NoError(t, err) + err = mock.SetGlobalSysVar(context.Background(), TiDBTTLJobScheduleWindowStartTime, "16:11") + require.NoError(t, err) + vars.TimeZone = time.UTC + val, err = mock.GetGlobalSysVar(TiDBTTLJobScheduleWindowStartTime) + require.NoError(t, err) + require.Equal(t, "16:11 +0800", val) +} + +func TestTiDBEnableResourceControl(t *testing.T) { + // setup the hooks for test + enable := false + EnableGlobalResourceControlFunc = func() { enable = true } + DisableGlobalResourceControlFunc = func() { enable = false } + setGlobalResourceControlFunc := func(enable bool) { + if enable { + EnableGlobalResourceControlFunc() + } else { + DisableGlobalResourceControlFunc() + } + } + SetGlobalResourceControl.Store(&setGlobalResourceControlFunc) + + vars := NewSessionVars(nil) + mock := NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + resourceControlEnabled := GetSysVar(TiDBEnableResourceControl) + + // Default false + require.Equal(t, resourceControlEnabled.Value, Off) + require.Equal(t, enable, false) + + // Set to On + err := mock.SetGlobalSysVar(context.Background(), TiDBEnableResourceControl, On) + + require.NoError(t, err) + val, err1 := mock.GetGlobalSysVar(TiDBEnableResourceControl) + require.NoError(t, err1) + require.Equal(t, On, val) + require.Equal(t, enable, true) + + // Set to off + err = mock.SetGlobalSysVar(context.Background(), TiDBEnableResourceControl, Off) + require.NoError(t, err) + val, err1 = mock.GetGlobalSysVar(TiDBEnableResourceControl) + require.NoError(t, err1) + require.Equal(t, Off, val) + require.Equal(t, enable, false) +} diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index 9ebdd9ecc61be..c147fdda69ba7 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -15,14 +15,17 @@ package variable import ( + "context" + "fmt" "math" + "time" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/parser/mysql" - "github.com/pingcap/tidb/sessionctx/variable/featuretag/concurrencyddl" - "github.com/pingcap/tidb/util/mathutil" + "github.com/pingcap/tidb/sessionctx/variable/featuretag/distributereorg" "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/paging" + "github.com/pingcap/tidb/util/size" "go.uber.org/atomic" ) @@ -251,6 +254,9 @@ const ( // TiDBEnableTiFlashReadForWriteStmt indicates whether to enable TiFlash to read for write statements. TiDBEnableTiFlashReadForWriteStmt = "tidb_enable_tiflash_read_for_write_stmt" + + // TiDBUseAlloc indicates whether the last statement used chunk alloc + TiDBUseAlloc = "last_sql_use_alloc" ) // TiDB system variable names that both in session and global scope. @@ -421,6 +427,9 @@ const ( // tidb_stream_agg_concurrency is deprecated, use tidb_executor_concurrency instead. TiDBStreamAggConcurrency = "tidb_streamagg_concurrency" + // TiDBIndexMergeIntersectionConcurrency is used for parallel worker of index merge intersection. + TiDBIndexMergeIntersectionConcurrency = "tidb_index_merge_intersection_concurrency" + // TiDBEnableParallelApply is used for parallel apply. TiDBEnableParallelApply = "tidb_enable_parallel_apply" @@ -551,6 +560,9 @@ const ( // TiDBMetricSchemaStep indicates the step when query metric schema. TiDBMetricSchemaStep = "tidb_metric_query_step" + // TiDBCDCWriteSource indicates the following data is written by TiCDC if it is not 0. + TiDBCDCWriteSource = "tidb_cdc_write_source" + // TiDBMetricSchemaRangeDuration indicates the range duration when query metric schema. TiDBMetricSchemaRangeDuration = "tidb_metric_query_range_duration" @@ -580,9 +592,6 @@ const ( // TiDBEnableTelemetry indicates that whether usage data report to PingCAP is enabled. TiDBEnableTelemetry = "tidb_enable_telemetry" - // TiDBEnableAmendPessimisticTxn indicates if amend pessimistic transactions is enabled. - TiDBEnableAmendPessimisticTxn = "tidb_enable_amend_pessimistic_txn" - // TiDBMemoryUsageAlarmRatio indicates the alarm threshold when memory usage of the tidb-server exceeds. TiDBMemoryUsageAlarmRatio = "tidb_memory_usage_alarm_ratio" @@ -623,6 +632,9 @@ const ( // TiDBEnableTopSQL indicates whether the top SQL is enabled. TiDBEnableTopSQL = "tidb_enable_top_sql" + // TiDBSourceID indicates the source ID of the TiDB server. + TiDBSourceID = "tidb_source_id" + // TiDBTopSQLMaxTimeSeriesCount indicates the max number of statements been collected in each time series. TiDBTopSQLMaxTimeSeriesCount = "tidb_top_sql_max_time_series_count" @@ -685,6 +697,12 @@ const ( // TiDBCostModelVersion is a internal switch to indicates the cost model version. TiDBCostModelVersion = "tidb_cost_model_version" + // TiDBIndexJoinDoubleReadPenaltyCostRate indicates whether to add some penalty cost to IndexJoin and how much of it. + // IndexJoin can cause plenty of extra double read tasks, which consume lots of resources and take a long time. + // Since the number of double read tasks is hard to estimated accurately, we leave this variable to let us can adjust this + // part of cost manually. + TiDBIndexJoinDoubleReadPenaltyCostRate = "tidb_index_join_double_read_penalty_cost_rate" + // TiDBBatchPendingTiFlashCount indicates the maximum count of non-available TiFlash tables. TiDBBatchPendingTiFlashCount = "tidb_batch_pending_tiflash_count" @@ -732,11 +750,13 @@ const ( TiDBEnablePrepPlanCache = "tidb_enable_prepared_plan_cache" // TiDBPrepPlanCacheSize indicates the number of cached statements. TiDBPrepPlanCacheSize = "tidb_prepared_plan_cache_size" + // TiDBEnablePrepPlanCacheMemoryMonitor indicates whether to enable prepared plan cache monitor + TiDBEnablePrepPlanCacheMemoryMonitor = "tidb_enable_prepared_plan_cache_memory_monitor" - // TiDBEnableGeneralPlanCache indicates whether to enable general plan cache. - TiDBEnableGeneralPlanCache = "tidb_enable_general_plan_cache" - // TiDBGeneralPlanCacheSize controls the size of general plan cache. - TiDBGeneralPlanCacheSize = "tidb_general_plan_cache_size" + // TiDBEnableNonPreparedPlanCache indicates whether to enable non-prepared plan cache. + TiDBEnableNonPreparedPlanCache = "tidb_enable_non_prepared_plan_cache" + // TiDBNonPreparedPlanCacheSize controls the size of non-prepared plan cache. + TiDBNonPreparedPlanCacheSize = "tidb_non_prepared_plan_cache_size" // TiDBConstraintCheckInPlacePessimistic controls whether to skip certain kinds of pessimistic locks. TiDBConstraintCheckInPlacePessimistic = "tidb_constraint_check_in_place_pessimistic" @@ -749,6 +769,33 @@ const ( // ranges would exceed the limit, it chooses less accurate ranges such as full range. 0 indicates that there is no memory // limit for ranges. TiDBOptRangeMaxSize = "tidb_opt_range_max_size" + + // TiDBAnalyzePartitionConcurrency indicates concurrency for save/read partitions stats in Analyze + TiDBAnalyzePartitionConcurrency = "tidb_analyze_partition_concurrency" + // TiDBMergePartitionStatsConcurrency indicates the concurrency when merge partition stats into global stats + TiDBMergePartitionStatsConcurrency = "tidb_merge_partition_stats_concurrency" + + // TiDBOptPrefixIndexSingleScan indicates whether to do some optimizations to avoid double scan for prefix index. + // When set to true, `col is (not) null`(`col` is index prefix column) is regarded as index filter rather than table filter. + TiDBOptPrefixIndexSingleScan = "tidb_opt_prefix_index_single_scan" + + // TiDBEnableExternalTSRead indicates whether to enable read through an external ts + TiDBEnableExternalTSRead = "tidb_enable_external_ts_read" + + // TiDBEnablePlanReplayerCapture indicates whether to enable plan replayer capture + TiDBEnablePlanReplayerCapture = "tidb_enable_plan_replayer_capture" + + // TiDBEnablePlanReplayerContinuesCapture indicates whether to enable continues capture + TiDBEnablePlanReplayerContinuesCapture = "tidb_enable_plan_replayer_continues_capture" + // TiDBEnableReusechunk indicates whether to enable chunk alloc + TiDBEnableReusechunk = "tidb_enable_reuse_chunk" + + // TiDBStoreBatchSize indicates the batch size of coprocessor in the same store. + TiDBStoreBatchSize = "tidb_store_batch_size" + + // TiDBPessimisticTransactionAggressiveLocking controls whether aggressive locking for pessimistic transaction + // is enabled. + TiDBPessimisticTransactionAggressiveLocking = "tidb_pessimistic_txn_aggressive_locking" ) // TiDB vars that have only global scope @@ -804,12 +851,8 @@ const ( // TiDBMaxAutoAnalyzeTime is the max time that auto analyze can run. If auto analyze runs longer than the value, it // will be killed. 0 indicates that there is no time limit. TiDBMaxAutoAnalyzeTime = "tidb_max_auto_analyze_time" - // TiDBEnableConcurrentDDL indicates whether to enable the new DDL framework. - TiDBEnableConcurrentDDL = "tidb_enable_concurrent_ddl" - // TiDBAuthSigningCert indicates the path of the signing certificate to do token-based authentication. - TiDBAuthSigningCert = "tidb_auth_signing_cert" - // TiDBAuthSigningKey indicates the path of the signing key to do token-based authentication. - TiDBAuthSigningKey = "tidb_auth_signing_key" + // TiDBDDLEnableDistributeReorg indicates whether to enable the new Reorg framework. + TiDBDDLEnableDistributeReorg = "tidb_ddl_distribute_reorg" // TiDBGenerateBinaryPlan indicates whether binary plan should be generated in slow log and statements summary. TiDBGenerateBinaryPlan = "tidb_generate_binary_plan" // TiDBEnableGCAwareMemoryTrack indicates whether to turn-on GC-aware memory track. @@ -821,6 +864,10 @@ const ( TiDBDDLEnableFastReorg = "tidb_ddl_enable_fast_reorg" // TiDBDDLDiskQuota used to set disk quota for lightning add index. TiDBDDLDiskQuota = "tidb_ddl_disk_quota" + // TiDBAutoBuildStatsConcurrency is used to set the build concurrency of auto-analyze. + TiDBAutoBuildStatsConcurrency = "tidb_auto_build_stats_concurrency" + // TiDBSysProcScanConcurrency is used to set the scan concurrency of for backend system processes, like auto-analyze. + TiDBSysProcScanConcurrency = "tidb_sysproc_scan_concurrency" // TiDBServerMemoryLimit indicates the memory limit of the tidb-server instance. TiDBServerMemoryLimit = "tidb_server_memory_limit" // TiDBServerMemoryLimitSessMinSize indicates the minimal memory used of a session, that becomes a candidate for session kill. @@ -829,6 +876,36 @@ const ( TiDBServerMemoryLimitGCTrigger = "tidb_server_memory_limit_gc_trigger" // TiDBEnableGOGCTuner is to enable GOGC tuner. it can tuner GOGC TiDBEnableGOGCTuner = "tidb_enable_gogc_tuner" + // TiDBGOGCTunerThreshold is to control the threshold of GOGC tuner. + TiDBGOGCTunerThreshold = "tidb_gogc_tuner_threshold" + // TiDBExternalTS is the ts to read through when the `TiDBEnableExternalTsRead` is on + TiDBExternalTS = "tidb_external_ts" + // TiDBTTLJobEnable is used to enable/disable scheduling ttl job + TiDBTTLJobEnable = "tidb_ttl_job_enable" + // TiDBTTLScanBatchSize is used to control the batch size in the SELECT statement for TTL jobs + TiDBTTLScanBatchSize = "tidb_ttl_scan_batch_size" + // TiDBTTLDeleteBatchSize is used to control the batch size in the DELETE statement for TTL jobs + TiDBTTLDeleteBatchSize = "tidb_ttl_delete_batch_size" + // TiDBTTLDeleteRateLimit is used to control the delete rate limit for TTL jobs in each node + TiDBTTLDeleteRateLimit = "tidb_ttl_delete_rate_limit" + // TiDBTTLJobScheduleWindowStartTime is used to restrict the start time of the time window of scheduling the ttl jobs. + TiDBTTLJobScheduleWindowStartTime = "tidb_ttl_job_schedule_window_start_time" + // TiDBTTLJobScheduleWindowEndTime is used to restrict the end time of the time window of scheduling the ttl jobs. + TiDBTTLJobScheduleWindowEndTime = "tidb_ttl_job_schedule_window_end_time" + // TiDBTTLScanWorkerCount indicates the count of the scan workers in each TiDB node + TiDBTTLScanWorkerCount = "tidb_ttl_scan_worker_count" + // TiDBTTLDeleteWorkerCount indicates the count of the delete workers in each TiDB node + TiDBTTLDeleteWorkerCount = "tidb_ttl_delete_worker_count" + // PasswordReuseHistory limit a few passwords to reuse. + PasswordReuseHistory = "password_history" + // PasswordReuseTime limit how long passwords can be reused. + PasswordReuseTime = "password_reuse_interval" + // TiDBHistoricalStatsDuration indicates the duration to remain tidb historical stats + TiDBHistoricalStatsDuration = "tidb_historical_stats_duration" + // TiDBEnableHistoricalStatsForCapture indicates whether use historical stats in plan replayer capture + TiDBEnableHistoricalStatsForCapture = "tidb_enable_historical_stats_for_capture" + // TiDBEnableResourceControl indicates whether resource control feature is enabled + TiDBEnableResourceControl = "tidb_enable_resource_control" ) // TiDB intentional limits @@ -903,7 +980,7 @@ const ( DefBroadcastJoinThresholdCount = 10 * 1024 DefTiDBOptimizerSelectivityLevel = 0 DefTiDBOptimizerEnableNewOFGB = false - DefTiDBEnableOuterJoinReorder = false + DefTiDBEnableOuterJoinReorder = true DefTiDBEnableNAAJ = false DefTiDBAllowBatchCop = 1 DefTiDBAllowMPPExecution = true @@ -962,7 +1039,6 @@ const ( DefTiDBShardAllocateStep = math.MaxInt64 DefTiDBEnableTelemetry = true DefTiDBEnableParallelApply = false - DefTiDBEnableAmendPessimisticTxn = false DefTiDBPartitionPruneMode = "dynamic" DefTiDBEnableRateLimitAction = false DefTiDBEnableAsyncCommit = false @@ -996,7 +1072,7 @@ const ( DefTiDBTableCacheLease = 3 // 3s DefTiDBPersistAnalyzeOptions = true DefTiDBEnableColumnTracking = false - DefTiDBStatsLoadSyncWait = 0 + DefTiDBStatsLoadSyncWait = 100 DefTiDBStatsLoadPseudoTimeout = true DefSysdateIsNow = false DefTiDBEnableMutationChecker = false @@ -1024,8 +1100,9 @@ const ( DefTiDBMaxAutoAnalyzeTime = 12 * 60 * 60 DefTiDBEnablePrepPlanCache = true DefTiDBPrepPlanCacheSize = 100 + DefTiDBEnablePrepPlanCacheMemoryMonitor = true DefTiDBPrepPlanCacheMemoryGuardRatio = 0.1 - DefTiDBEnableConcurrentDDL = concurrencyddl.TiDBEnableConcurrentDDL + DefTiDBDDLEnableDistributeReorg = distributereorg.TiDBEnableDistributeReorg DefTiDBSimplifiedMetrics = false DefTiDBEnablePaging = true DefTiFlashFineGrainedShuffleStreamCount = 0 @@ -1034,31 +1111,62 @@ const ( DefAdaptiveClosestReadThreshold = 4096 DefTiDBEnableAnalyzeSnapshot = false DefTiDBGenerateBinaryPlan = true - DefEnableTiDBGCAwareMemoryTrack = true + DefEnableTiDBGCAwareMemoryTrack = false DefTiDBDefaultStrMatchSelectivity = 0.8 DefTiDBEnableTmpStorageOnOOM = true - DefTiDBEnableMDL = false + DefTiDBEnableMDL = true DefTiFlashFastScan = false DefMemoryUsageAlarmRatio = 0.7 DefMemoryUsageAlarmKeepRecordNum = 5 - DefTiDBEnableFastReorg = false + DefTiDBEnableFastReorg = true DefTiDBDDLDiskQuota = 100 * 1024 * 1024 * 1024 // 100GB DefExecutorConcurrency = 5 - DefTiDBEnableGeneralPlanCache = false - DefTiDBGeneralPlanCacheSize = 100 + DefTiDBEnableNonPreparedPlanCache = false + DefTiDBNonPreparedPlanCacheSize = 100 DefTiDBEnableTiFlashReadForWriteStmt = false // MaxDDLReorgBatchSize is exported for testing. - MaxDDLReorgBatchSize int32 = 10240 - MinDDLReorgBatchSize int32 = 32 - MinExpensiveQueryTimeThreshold uint64 = 10 // 10s - DefTiDBRcWriteCheckTs = false - DefTiDBConstraintCheckInPlacePessimistic = true - DefTiDBForeignKeyChecks = false - DefTiDBOptRangeMaxSize = 0 - DefTiDBCostModelVer = 1 - DefTiDBServerMemoryLimitSessMinSize = 128 << 20 - DefTiDBServerMemoryLimitGCTrigger = 0.7 - DefTiDBEnableGOGCTuner = true + MaxDDLReorgBatchSize int32 = 10240 + MinDDLReorgBatchSize int32 = 32 + MinExpensiveQueryTimeThreshold uint64 = 10 // 10s + DefTiDBAutoBuildStatsConcurrency = 1 + DefTiDBSysProcScanConcurrency = 1 + DefTiDBRcWriteCheckTs = false + DefTiDBForeignKeyChecks = true + DefTiDBAnalyzePartitionConcurrency = 1 + DefTiDBOptRangeMaxSize = 64 * int64(size.MB) // 64 MB + DefTiDBCostModelVer = 2 + DefTiDBServerMemoryLimitSessMinSize = 128 << 20 + DefTiDBMergePartitionStatsConcurrency = 1 + DefTiDBServerMemoryLimitGCTrigger = 0.7 + DefTiDBEnableGOGCTuner = true + // DefTiDBGOGCTunerThreshold is to limit TiDBGOGCTunerThreshold. + DefTiDBGOGCTunerThreshold float64 = 0.6 + DefTiDBOptPrefixIndexSingleScan = true + DefTiDBExternalTS = 0 + DefTiDBEnableExternalTSRead = false + DefTiDBEnableReusechunk = true + DefTiDBUseAlloc = false + DefTiDBEnablePlanReplayerCapture = false + DefTiDBIndexMergeIntersectionConcurrency = ConcurrencyUnset + DefTiDBTTLJobEnable = true + DefTiDBTTLScanBatchSize = 500 + DefTiDBTTLScanBatchMaxSize = 10240 + DefTiDBTTLScanBatchMinSize = 1 + DefTiDBTTLDeleteBatchSize = 100 + DefTiDBTTLDeleteBatchMaxSize = 10240 + DefTiDBTTLDeleteBatchMinSize = 1 + DefTiDBTTLDeleteRateLimit = 0 + DefPasswordReuseHistory = 0 + DefPasswordReuseTime = 0 + DefTiDBStoreBatchSize = 0 + DefTiDBHistoricalStatsDuration = 7 * 24 * time.Hour + DefTiDBEnableHistoricalStatsForCapture = false + DefTiDBTTLJobScheduleWindowStartTime = "00:00 +0000" + DefTiDBTTLJobScheduleWindowEndTime = "23:59 +0000" + DefTiDBTTLScanWorkerCount = 4 + DefTiDBTTLDeleteWorkerCount = 4 + DefTiDBEnableResourceControl = false + DefTiDBPessimisticTransactionAggressiveLocking = false ) // Process global variables. @@ -1100,22 +1208,42 @@ var ( MaxAutoAnalyzeTime = atomic.NewInt64(DefTiDBMaxAutoAnalyzeTime) // variables for plan cache PreparedPlanCacheMemoryGuardRatio = atomic.NewFloat64(DefTiDBPrepPlanCacheMemoryGuardRatio) - EnableConcurrentDDL = atomic.NewBool(DefTiDBEnableConcurrentDDL) + DDLEnableDistributeReorg = atomic.NewBool(DefTiDBDDLEnableDistributeReorg) DDLForce2Queue = atomic.NewBool(false) EnableNoopVariables = atomic.NewBool(DefTiDBEnableNoopVariables) - EnableMDL = atomic.NewBool(DefTiDBEnableMDL) + EnableMDL = atomic.NewBool(false) AutoAnalyzePartitionBatchSize = atomic.NewInt64(DefTiDBAutoAnalyzePartitionBatchSize) // EnableFastReorg indicates whether to use lightning to enhance DDL reorg performance. EnableFastReorg = atomic.NewBool(DefTiDBEnableFastReorg) // DDLDiskQuota is the temporary variable for set disk quota for lightning DDLDiskQuota = atomic.NewUint64(DefTiDBDDLDiskQuota) // EnableForeignKey indicates whether to enable foreign key feature. - EnableForeignKey = atomic.NewBool(false) + EnableForeignKey = atomic.NewBool(true) EnableRCReadCheckTS = atomic.NewBool(false) // DefTiDBServerMemoryLimit indicates the default value of TiDBServerMemoryLimit(TotalMem * 80%). // It should be a const and shouldn't be modified after tidb is started. - DefTiDBServerMemoryLimit = mathutil.Max(memory.GetMemTotalIgnoreErr()/10*8, 512<<20) + DefTiDBServerMemoryLimit = serverMemoryLimitDefaultValue() + GOGCTunerThreshold = atomic.NewFloat64(DefTiDBGOGCTunerThreshold) + PasswordValidationLength = atomic.NewInt32(8) + PasswordValidationMixedCaseCount = atomic.NewInt32(1) + PasswordValidtaionNumberCount = atomic.NewInt32(1) + PasswordValidationSpecialCharCount = atomic.NewInt32(1) + EnableTTLJob = atomic.NewBool(DefTiDBTTLJobEnable) + TTLScanBatchSize = atomic.NewInt64(DefTiDBTTLScanBatchSize) + TTLDeleteBatchSize = atomic.NewInt64(DefTiDBTTLDeleteBatchSize) + TTLDeleteRateLimit = atomic.NewInt64(DefTiDBTTLDeleteRateLimit) + TTLJobScheduleWindowStartTime = atomic.NewTime(mustParseTime(FullDayTimeFormat, DefTiDBTTLJobScheduleWindowStartTime)) + TTLJobScheduleWindowEndTime = atomic.NewTime(mustParseTime(FullDayTimeFormat, DefTiDBTTLJobScheduleWindowEndTime)) + TTLScanWorkerCount = atomic.NewInt32(DefTiDBTTLScanWorkerCount) + TTLDeleteWorkerCount = atomic.NewInt32(DefTiDBTTLDeleteWorkerCount) + PasswordHistory = atomic.NewInt64(DefPasswordReuseHistory) + PasswordReuseInterval = atomic.NewInt64(DefPasswordReuseTime) + IsSandBoxModeEnabled = atomic.NewBool(false) + MaxPreparedStmtCountValue = atomic.NewInt64(DefMaxPreparedStmtCount) + HistoricalStatsDuration = atomic.NewDuration(DefTiDBHistoricalStatsDuration) + EnableHistoricalStatsForCapture = atomic.NewBool(DefTiDBEnableHistoricalStatsForCapture) + EnableResourceControl = atomic.NewBool(DefTiDBEnableResourceControl) ) var ( @@ -1127,12 +1255,50 @@ var ( SetStatsCacheCapacity atomic.Value // SetPDClientDynamicOption is the func registered by domain SetPDClientDynamicOption atomic.Pointer[func(string, string)] - // SwitchConcurrentDDL is the func registered by DDL to switch concurrent DDL. - SwitchConcurrentDDL func(bool) error = nil // SwitchMDL is the func registered by DDL to switch MDL. SwitchMDL func(bool2 bool) error = nil // EnableDDL is the func registered by ddl to enable running ddl in this instance. EnableDDL func() error = nil // DisableDDL is the func registered by ddl to disable running ddl in this instance. DisableDDL func() error = nil + // SetExternalTimestamp is the func registered by staleread to set externaltimestamp in pd + SetExternalTimestamp func(ctx context.Context, ts uint64) error + // GetExternalTimestamp is the func registered by staleread to get externaltimestamp from pd + GetExternalTimestamp func(ctx context.Context) (uint64, error) + // SetGlobalResourceControl is the func registered by domain to set cluster resource control. + SetGlobalResourceControl atomic.Pointer[func(bool)] ) + +// Hooks functions for Cluster Resource Control. +var ( + // EnableGlobalResourceControlFunc is the function registered by tikv_driver to set cluster resource control. + EnableGlobalResourceControlFunc func() = func() {} + // DisableGlobalResourceControlFunc is the function registered by tikv_driver to unset cluster resource control. + DisableGlobalResourceControlFunc func() = func() {} +) + +func serverMemoryLimitDefaultValue() string { + total, err := memory.MemTotal() + if err == nil && total != 0 { + return "80%" + } + return "0" +} + +func mustParseDuration(str string) time.Duration { + duration, err := time.ParseDuration(str) + if err != nil { + panic(fmt.Sprintf("%s is not a duration", str)) + } + + return duration +} + +func mustParseTime(layout string, str string) time.Time { + time, err := time.ParseInLocation(layout, str, time.UTC) + if err != nil { + panic(fmt.Sprintf("%s is not in %s duration format", str, layout)) + } + + return time +} diff --git a/sessionctx/variable/variable.go b/sessionctx/variable/variable.go index deca51f3e9fa3..48eb86a45c2a2 100644 --- a/sessionctx/variable/variable.go +++ b/sessionctx/variable/variable.go @@ -15,6 +15,7 @@ package variable import ( + "context" "strconv" "strings" "sync" @@ -84,6 +85,7 @@ const ( // Global config name list. const ( GlobalConfigEnableTopSQL = "enable_resource_metering" + GlobalConfigSourceID = "source_id" ) func (s ScopeFlag) String() string { @@ -136,7 +138,7 @@ type SysVar struct { // and will be called on all variables in builtinGlobalVariable, regardless of their scope. SetSession func(*SessionVars, string) error // SetGlobal is called after validation - SetGlobal func(*SessionVars, string) error + SetGlobal func(context.Context, *SessionVars, string) error // IsHintUpdatable indicate whether it's updatable via SET_VAR() hint (optional) IsHintUpdatable bool // Deprecated: Hidden previously meant that the variable still responds to SET but doesn't show up in SHOW VARIABLES @@ -149,7 +151,7 @@ type SysVar struct { // It can be used by instance-scoped variables to overwrite the previously expected value. GetSession func(*SessionVars) (string, error) // GetGlobal is a getter function for global scope. - GetGlobal func(*SessionVars) (string, error) + GetGlobal func(context.Context, *SessionVars) (string, error) // GetStateValue gets the value for session states, which is used for migrating sessions. // We need a function to override GetSession sometimes, because GetSession may not return the real value. GetStateValue func(*SessionVars) (string, bool, error) @@ -163,13 +165,15 @@ type SysVar struct { // If the global variable has the global config name, // it should store the global config into PD(etcd) too when set global variable. GlobalConfigName string + // RequireDynamicPrivileges is a function to return a dynamic privilege list to check the set sysvar privilege + RequireDynamicPrivileges func(isGlobal bool, sem bool) []string } // GetGlobalFromHook calls the GetSession func if it exists. -func (sv *SysVar) GetGlobalFromHook(s *SessionVars) (string, error) { +func (sv *SysVar) GetGlobalFromHook(ctx context.Context, s *SessionVars) (string, error) { // Call the Getter if there is one defined. if sv.GetGlobal != nil { - val, err := sv.GetGlobal(s) + val, err := sv.GetGlobal(ctx, s) if err != nil { return val, err } @@ -240,9 +244,9 @@ func (sv *SysVar) SetSessionFromHook(s *SessionVars, val string) error { } // SetGlobalFromHook calls the SetGlobal func if it exists. -func (sv *SysVar) SetGlobalFromHook(s *SessionVars, val string, skipAliases bool) error { +func (sv *SysVar) SetGlobalFromHook(ctx context.Context, s *SessionVars, val string, skipAliases bool) error { if sv.SetGlobal != nil { - return sv.SetGlobal(s, val) + return sv.SetGlobal(ctx, s, val) } // Call the SetGlobalSysVarOnly function on all the aliases for this sysVar @@ -252,7 +256,7 @@ func (sv *SysVar) SetGlobalFromHook(s *SessionVars, val string, skipAliases bool if !skipAliases && sv.Aliases != nil { for _, aliasName := range sv.Aliases { - if err := s.GlobalVarsAccessor.SetGlobalSysVarOnly(aliasName, val); err != nil { + if err := s.GlobalVarsAccessor.SetGlobalSysVarOnly(ctx, aliasName, val, true); err != nil { return err } } @@ -379,6 +383,10 @@ func (sv *SysVar) checkTimeSystemVar(value string, vars *SessionVars) (string, e if err != nil { return "", err } + // Add a modern date to it, as the timezone shift can differ across the history + // For example, the Asia/Shanghai refers to +08:05 before 1900 + now := time.Now() + t = time.Date(now.Year(), now.Month(), now.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location()) return t.Format(FullDayTimeFormat), nil } @@ -547,7 +555,7 @@ func (sv *SysVar) SkipInit() bool { func (sv *SysVar) SkipSysvarCache() bool { switch sv.Name { case TiDBGCEnable, TiDBGCRunInterval, TiDBGCLifetime, - TiDBGCConcurrency, TiDBGCScanLockMode: + TiDBGCConcurrency, TiDBGCScanLockMode, TiDBExternalTS: return true } return false @@ -621,9 +629,9 @@ type GlobalVarAccessor interface { // GetGlobalSysVar gets the global system variable value for name. GetGlobalSysVar(name string) (string, error) // SetGlobalSysVar sets the global system variable name to value. - SetGlobalSysVar(name string, value string) error + SetGlobalSysVar(ctx context.Context, name string, value string) error // SetGlobalSysVarOnly sets the global system variable without calling the validation function or updating aliases. - SetGlobalSysVarOnly(name string, value string) error + SetGlobalSysVarOnly(ctx context.Context, name string, value string, updateLocal bool) error // GetTiDBTableValue gets a value from mysql.tidb for the key 'name' GetTiDBTableValue(name string) (string, error) // SetTiDBTableValue sets a value+comment for the mysql.tidb key 'name' diff --git a/sessionctx/variable/variable_test.go b/sessionctx/variable/variable_test.go index ff7f5f73ecf9e..b346f5f609e46 100644 --- a/sessionctx/variable/variable_test.go +++ b/sessionctx/variable/variable_test.go @@ -15,6 +15,7 @@ package variable import ( + "context" "encoding/json" "fmt" "runtime" @@ -435,18 +436,22 @@ func TestDefaultValuesAreSettable(t *testing.T) { for _, sv := range GetSysVars() { if sv.HasSessionScope() && !sv.ReadOnly { val, err := sv.Validate(vars, sv.Value, ScopeSession) - require.Equal(t, val, sv.Value) require.NoError(t, err) + require.Equal(t, val, sv.Value) } if sv.HasGlobalScope() && !sv.ReadOnly { val, err := sv.Validate(vars, sv.Value, ScopeGlobal) - require.Equal(t, val, sv.Value) require.NoError(t, err) + require.Equal(t, val, sv.Value) } } } +func TestLimitBetweenVariable(t *testing.T) { + require.Less(t, DefTiDBGOGCTunerThreshold+0.05, DefTiDBServerMemoryLimitGCTrigger) +} + // TestSysVarNameIsLowerCase tests that no new sysvars are added with uppercase characters. // In MySQL variables are always lowercase, and can be set in a case-insensitive way. func TestSysVarNameIsLowerCase(t *testing.T) { @@ -606,10 +611,10 @@ func TestInstanceScope(t *testing.T) { count := len(GetSysVars()) sv := SysVar{Scope: ScopeInstance, Name: "newinstancesysvar", Value: On, Type: TypeBool, - SetGlobal: func(s *SessionVars, val string) error { + SetGlobal: func(_ context.Context, s *SessionVars, val string) error { return fmt.Errorf("set should fail") }, - GetGlobal: func(s *SessionVars) (string, error) { + GetGlobal: func(_ context.Context, s *SessionVars) (string, error) { return "", fmt.Errorf("get should fail") }, } @@ -634,7 +639,7 @@ func TestInstanceScope(t *testing.T) { require.Equal(t, "OFF", normalizedVal) require.NoError(t, err) - err = sysVar.SetGlobalFromHook(vars, "OFF", true) // default is on + err = sysVar.SetGlobalFromHook(context.Background(), vars, "OFF", true) // default is on require.Equal(t, "set should fail", err.Error()) // Test unregistration restores previous count @@ -649,7 +654,7 @@ func TestSetSysVar(t *testing.T) { SetSysVar(SystemTimeZone, "America/New_York") require.Equal(t, "America/New_York", GetSysVar(SystemTimeZone).Value) // Test alternative Get - val, err := GetSysVar(SystemTimeZone).GetGlobalFromHook(vars) + val, err := GetSysVar(SystemTimeZone).GetGlobalFromHook(context.Background(), vars) require.Nil(t, err) require.Equal(t, "America/New_York", val) SetSysVar(SystemTimeZone, originalVal) // restore @@ -664,3 +669,21 @@ func TestSkipSysvarCache(t *testing.T) { require.True(t, GetSysVar(TiDBGCScanLockMode).SkipSysvarCache()) require.False(t, GetSysVar(TiDBEnableAsyncCommit).SkipSysvarCache()) } + +func TestTimeValidationWithTimezone(t *testing.T) { + sv := SysVar{Scope: ScopeSession, Name: "mynewsysvar", Value: "23:59 +0000", Type: TypeTime} + vars := NewSessionVars(nil) + + // In timezone UTC + vars.TimeZone = time.UTC + val, err := sv.Validate(vars, "23:59", ScopeSession) + require.NoError(t, err) + require.Equal(t, "23:59 +0000", val) + + // In timezone Asia/Shanghai + vars.TimeZone, err = time.LoadLocation("Asia/Shanghai") + require.NoError(t, err) + val, err = sv.Validate(vars, "23:59", ScopeSession) + require.NoError(t, err) + require.Equal(t, "23:59 +0800", val) +} diff --git a/sessionctx/variable/varsutil.go b/sessionctx/variable/varsutil.go index 811cf65bb50b6..959bb9fb07e52 100644 --- a/sessionctx/variable/varsutil.go +++ b/sessionctx/variable/varsutil.go @@ -15,7 +15,9 @@ package variable import ( + "context" "fmt" + "io" "strconv" "strings" "sync/atomic" @@ -27,6 +29,7 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/collate" + "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/timeutil" "github.com/tikv/client-go/v2/oracle" "golang.org/x/exp/slices" @@ -382,6 +385,66 @@ func parseTimeZone(s string) (*time.Location, error) { return nil, ErrUnknownTimeZone.GenWithStackByArgs(s) } +func parseMemoryLimit(s *SessionVars, normalizedValue string, originalValue string) (byteSize uint64, normalizedStr string, err error) { + defer func() { + if err == nil && byteSize > 0 && byteSize < (512<<20) { + s.StmtCtx.AppendWarning(ErrTruncatedWrongValue.GenWithStackByArgs(TiDBServerMemoryLimit, originalValue)) + byteSize = 512 << 20 + normalizedStr = "512MB" + } + }() + + // 1. Try parse percentage format: x% + if total := memory.GetMemTotalIgnoreErr(); total != 0 { + perc, str := parsePercentage(normalizedValue) + if perc != 0 { + intVal := total / 100 * perc + return intVal, str, nil + } + } + + // 2. Try parse byteSize format: xKB/MB/GB/TB or byte number + bt, str := parseByteSize(normalizedValue) + if str != "" { + return bt, str, nil + } + + return 0, "", ErrTruncatedWrongValue.GenWithStackByArgs(TiDBServerMemoryLimit, originalValue) +} + +func parsePercentage(s string) (percentage uint64, normalizedStr string) { + defer func() { + if percentage == 0 || percentage >= 100 { + percentage, normalizedStr = 0, "" + } + }() + var endString string + if n, err := fmt.Sscanf(s, "%d%%%s", &percentage, &endString); n == 1 && err == io.EOF { + return percentage, fmt.Sprintf("%d%%", percentage) + } + return 0, "" +} + +func parseByteSize(s string) (byteSize uint64, normalizedStr string) { + var endString string + if n, err := fmt.Sscanf(s, "%d%s", &byteSize, &endString); n == 1 && err == io.EOF { + return byteSize, fmt.Sprintf("%d", byteSize) + } + if n, err := fmt.Sscanf(s, "%dKB%s", &byteSize, &endString); n == 1 && err == io.EOF { + return byteSize << 10, fmt.Sprintf("%dKB", byteSize) + } + if n, err := fmt.Sscanf(s, "%dMB%s", &byteSize, &endString); n == 1 && err == io.EOF { + return byteSize << 20, fmt.Sprintf("%dMB", byteSize) + } + if n, err := fmt.Sscanf(s, "%dGB%s", &byteSize, &endString); n == 1 && err == io.EOF { + return byteSize << 30, fmt.Sprintf("%dGB", byteSize) + } + if n, err := fmt.Sscanf(s, "%dTB%s", &byteSize, &endString); n == 1 && err == io.EOF { + return byteSize << 40, fmt.Sprintf("%dTB", byteSize) + } + return 0, "" +} + func setSnapshotTS(s *SessionVars, sVal string) error { if sVal == "" { s.SnapshotTS = 0 @@ -392,21 +455,25 @@ func setSnapshotTS(s *SessionVars, sVal string) error { return fmt.Errorf("tidb_read_staleness should be clear before setting tidb_snapshot") } + tso, err := parseTSFromNumberOrTime(s, sVal) + s.SnapshotTS = tso + // tx_read_ts should be mutual exclusive with tidb_snapshot + s.TxnReadTS = NewTxnReadTS(0) + return err +} + +func parseTSFromNumberOrTime(s *SessionVars, sVal string) (uint64, error) { if tso, err := strconv.ParseUint(sVal, 10, 64); err == nil { - s.SnapshotTS = tso - return nil + return tso, nil } t, err := types.ParseTime(s.StmtCtx, sVal, mysql.TypeTimestamp, types.MaxFsp) if err != nil { - return err + return 0, err } t1, err := t.GoTime(s.Location()) - s.SnapshotTS = oracle.GoTimeToTS(t1) - // tx_read_ts should be mutual exclusive with tidb_snapshot - s.TxnReadTS = NewTxnReadTS(0) - return err + return oracle.GoTimeToTS(t1), err } func setTxnReadTS(s *SessionVars, sVal string) error { @@ -465,6 +532,15 @@ func collectAllowFuncName4ExpressionIndex() string { return strings.Join(str, ", ") } +func updatePasswordValidationLength(s *SessionVars, length int32) error { + err := s.GlobalVarsAccessor.SetGlobalSysVarOnly(context.Background(), ValidatePasswordLength, strconv.FormatInt(int64(length), 10), false) + if err != nil { + return err + } + PasswordValidationLength.Store(length) + return nil +} + // GAFunction4ExpressionIndex stores functions GA for expression index. var GAFunction4ExpressionIndex = map[string]struct{}{ ast.Lower: {}, diff --git a/sessionctx/variable/varsutil_test.go b/sessionctx/variable/varsutil_test.go index 68e55bc33aea8..1f4cfe603ac8c 100644 --- a/sessionctx/variable/varsutil_test.go +++ b/sessionctx/variable/varsutil_test.go @@ -15,6 +15,7 @@ package variable import ( + "context" "reflect" "strconv" "testing" @@ -73,6 +74,7 @@ func TestNewSessionVars(t *testing.T) { require.Equal(t, DefExecutorConcurrency, vars.HashAggPartialConcurrency()) require.Equal(t, DefExecutorConcurrency, vars.HashAggFinalConcurrency()) require.Equal(t, DefExecutorConcurrency, vars.WindowConcurrency()) + require.Equal(t, DefExecutorConcurrency, vars.IndexMergeIntersectionConcurrency()) require.Equal(t, DefTiDBMergeJoinConcurrency, vars.MergeJoinConcurrency()) require.Equal(t, DefTiDBStreamAggConcurrency, vars.StreamAggConcurrency()) require.Equal(t, DefDistSQLScanConcurrency, vars.DistSQLScanConcurrency()) @@ -108,7 +110,7 @@ func TestVarsutil(t *testing.T) { err := v.SetSystemVar("autocommit", "1") require.NoError(t, err) - val, err := v.GetSessionOrGlobalSystemVar("autocommit") + val, err := v.GetSessionOrGlobalSystemVar(context.Background(), "autocommit") require.NoError(t, err) require.Equal(t, "ON", val) require.NotNil(t, v.SetSystemVar("autocommit", "")) @@ -116,19 +118,19 @@ func TestVarsutil(t *testing.T) { // 0 converts to OFF err = v.SetSystemVar("foreign_key_checks", "0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar("foreign_key_checks") + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), "foreign_key_checks") require.NoError(t, err) require.Equal(t, "OFF", val) err = v.SetSystemVar("foreign_key_checks", "1") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar("foreign_key_checks") + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), "foreign_key_checks") require.NoError(t, err) require.Equal(t, "ON", val) err = v.SetSystemVar("sql_mode", "strict_trans_tables") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar("sql_mode") + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), "sql_mode") require.NoError(t, err) require.Equal(t, "STRICT_TRANS_TABLES", val) require.True(t, v.StrictSQLMode) @@ -225,7 +227,7 @@ func TestVarsutil(t *testing.T) { // Test case for TiDBConfig session variable. err = v.SetSystemVar(TiDBConfig, "abc") require.True(t, terror.ErrorEqual(err, ErrIncorrectScope)) - val, err = v.GetSessionOrGlobalSystemVar(TiDBConfig) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBConfig) require.NoError(t, err) jsonConfig, err := config.GetJSONConfig() require.NoError(t, err) @@ -254,7 +256,7 @@ func TestVarsutil(t *testing.T) { err = v.SetSystemVar(TiDBRetryLimit, "3") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBRetryLimit) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBRetryLimit) require.NoError(t, err) require.Equal(t, "3", val) require.Equal(t, int64(3), v.RetryLimit) @@ -262,7 +264,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, "", v.EnableTablePartition) err = v.SetSystemVar(TiDBEnableTablePartition, "on") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBEnableTablePartition) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBEnableTablePartition) require.NoError(t, err) require.Equal(t, "ON", val) require.Equal(t, "ON", v.EnableTablePartition) @@ -270,7 +272,7 @@ func TestVarsutil(t *testing.T) { require.False(t, v.EnableListTablePartition) err = v.SetSystemVar(TiDBEnableListTablePartition, "on") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBEnableListTablePartition) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBEnableListTablePartition) require.NoError(t, err) require.Equal(t, "ON", val) require.True(t, v.EnableListTablePartition) @@ -278,20 +280,20 @@ func TestVarsutil(t *testing.T) { require.Equal(t, DefTiDBOptJoinReorderThreshold, v.TiDBOptJoinReorderThreshold) err = v.SetSystemVar(TiDBOptJoinReorderThreshold, "5") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptJoinReorderThreshold) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptJoinReorderThreshold) require.NoError(t, err) require.Equal(t, "5", val) require.Equal(t, 5, v.TiDBOptJoinReorderThreshold) err = v.SetSystemVar(TiDBLowResolutionTSO, "1") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBLowResolutionTSO) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBLowResolutionTSO) require.NoError(t, err) require.Equal(t, "ON", val) require.True(t, v.LowResolutionTSO) err = v.SetSystemVar(TiDBLowResolutionTSO, "0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBLowResolutionTSO) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBLowResolutionTSO) require.NoError(t, err) require.Equal(t, "OFF", val) require.False(t, v.LowResolutionTSO) @@ -299,7 +301,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 0.9, v.CorrelationThreshold) err = v.SetSystemVar(TiDBOptCorrelationThreshold, "0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptCorrelationThreshold) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptCorrelationThreshold) require.NoError(t, err) require.Equal(t, "0", val) require.Equal(t, float64(0), v.CorrelationThreshold) @@ -307,7 +309,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 3.0, v.GetCPUFactor()) err = v.SetSystemVar(TiDBOptCPUFactor, "5.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptCPUFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptCPUFactor) require.NoError(t, err) require.Equal(t, "5.0", val) require.Equal(t, 5.0, v.GetCPUFactor()) @@ -315,7 +317,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 3.0, v.GetCopCPUFactor()) err = v.SetSystemVar(TiDBOptCopCPUFactor, "5.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptCopCPUFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptCopCPUFactor) require.NoError(t, err) require.Equal(t, "5.0", val) require.Equal(t, 5.0, v.GetCopCPUFactor()) @@ -323,7 +325,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 24.0, v.CopTiFlashConcurrencyFactor) err = v.SetSystemVar(TiDBOptTiFlashConcurrencyFactor, "5.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptTiFlashConcurrencyFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptTiFlashConcurrencyFactor) require.NoError(t, err) require.Equal(t, "5.0", val) require.Equal(t, 5.0, v.GetCopCPUFactor()) @@ -331,7 +333,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 1.0, v.GetNetworkFactor(nil)) err = v.SetSystemVar(TiDBOptNetworkFactor, "3.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptNetworkFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptNetworkFactor) require.NoError(t, err) require.Equal(t, "3.0", val) require.Equal(t, 3.0, v.GetNetworkFactor(nil)) @@ -339,7 +341,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 1.5, v.GetScanFactor(nil)) err = v.SetSystemVar(TiDBOptScanFactor, "3.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptScanFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptScanFactor) require.NoError(t, err) require.Equal(t, "3.0", val) require.Equal(t, 3.0, v.GetScanFactor(nil)) @@ -347,7 +349,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 3.0, v.GetDescScanFactor(nil)) err = v.SetSystemVar(TiDBOptDescScanFactor, "5.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptDescScanFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptDescScanFactor) require.NoError(t, err) require.Equal(t, "5.0", val) require.Equal(t, 5.0, v.GetDescScanFactor(nil)) @@ -355,7 +357,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 20.0, v.GetSeekFactor(nil)) err = v.SetSystemVar(TiDBOptSeekFactor, "50.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptSeekFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptSeekFactor) require.NoError(t, err) require.Equal(t, "50.0", val) require.Equal(t, 50.0, v.GetSeekFactor(nil)) @@ -363,7 +365,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 0.001, v.GetMemoryFactor()) err = v.SetSystemVar(TiDBOptMemoryFactor, "1.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptMemoryFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptMemoryFactor) require.NoError(t, err) require.Equal(t, "1.0", val) require.Equal(t, 1.0, v.GetMemoryFactor()) @@ -371,7 +373,7 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 1.5, v.GetDiskFactor()) err = v.SetSystemVar(TiDBOptDiskFactor, "1.1") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptDiskFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptDiskFactor) require.NoError(t, err) require.Equal(t, "1.1", val) require.Equal(t, 1.1, v.GetDiskFactor()) @@ -379,33 +381,33 @@ func TestVarsutil(t *testing.T) { require.Equal(t, 3.0, v.GetConcurrencyFactor()) err = v.SetSystemVar(TiDBOptConcurrencyFactor, "5.0") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBOptConcurrencyFactor) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBOptConcurrencyFactor) require.NoError(t, err) require.Equal(t, "5.0", val) require.Equal(t, 5.0, v.GetConcurrencyFactor()) err = v.SetSystemVar(TiDBReplicaRead, "follower") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBReplicaRead) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBReplicaRead) require.NoError(t, err) require.Equal(t, "follower", val) require.Equal(t, kv.ReplicaReadFollower, v.GetReplicaRead()) err = v.SetSystemVar(TiDBReplicaRead, "leader") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBReplicaRead) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBReplicaRead) require.NoError(t, err) require.Equal(t, "leader", val) require.Equal(t, kv.ReplicaReadLeader, v.GetReplicaRead()) err = v.SetSystemVar(TiDBReplicaRead, "leader-and-follower") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBReplicaRead) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBReplicaRead) require.NoError(t, err) require.Equal(t, "leader-and-follower", val) require.Equal(t, kv.ReplicaReadMixed, v.GetReplicaRead()) err = v.SetSystemVar(TiDBRedactLog, "ON") require.NoError(t, err) - val, err = v.GetSessionOrGlobalSystemVar(TiDBRedactLog) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBRedactLog) require.NoError(t, err) require.Equal(t, "ON", val) @@ -435,7 +437,7 @@ func TestVarsutil(t *testing.T) { require.Error(t, err) require.Regexp(t, "'tidb_table_cache_lease' is a GLOBAL variable and should be set with SET GLOBAL", err.Error()) - val, err = v.GetSessionOrGlobalSystemVar(TiDBMinPagingSize) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBMinPagingSize) require.NoError(t, err) require.Equal(t, strconv.Itoa(DefMinPagingSize), val) @@ -443,7 +445,7 @@ func TestVarsutil(t *testing.T) { require.NoError(t, err) require.Equal(t, v.MinPagingSize, 123) - val, err = v.GetSessionOrGlobalSystemVar(TiDBMaxPagingSize) + val, err = v.GetSessionOrGlobalSystemVar(context.Background(), TiDBMaxPagingSize) require.NoError(t, err) require.Equal(t, strconv.Itoa(DefMaxPagingSize), val) @@ -534,9 +536,6 @@ func TestValidate(t *testing.T) { {TiDBShardAllocateStep, "ad", true}, {TiDBShardAllocateStep, "-123", false}, {TiDBShardAllocateStep, "128", false}, - {TiDBEnableAmendPessimisticTxn, "0", false}, - {TiDBEnableAmendPessimisticTxn, "1", false}, - {TiDBEnableAmendPessimisticTxn, "256", true}, {TiDBAllowFallbackToTiKV, "", false}, {TiDBAllowFallbackToTiKV, "tiflash", false}, {TiDBAllowFallbackToTiKV, " tiflash ", false}, diff --git a/sessiontxn/BUILD.bazel b/sessiontxn/BUILD.bazel index e484defb5b0c1..a92e5a81dd92e 100644 --- a/sessiontxn/BUILD.bazel +++ b/sessiontxn/BUILD.bazel @@ -27,6 +27,8 @@ go_test( "txn_rc_tso_optimize_test.go", ], flaky = True, + race = "on", + shard_count = 2, deps = [ ":sessiontxn", "//domain", diff --git a/sessiontxn/failpoint.go b/sessiontxn/failpoint.go index e2a3f29833b42..25c13a3bc80e2 100644 --- a/sessiontxn/failpoint.go +++ b/sessiontxn/failpoint.go @@ -52,6 +52,9 @@ var TsoWaitCount stringutil.StringerStr = "tsoWaitCount" // TsoUseConstantCount is the key for constant tso counter var TsoUseConstantCount stringutil.StringerStr = "tsoUseConstantCount" +// CallOnStmtRetryCount is the key for recording calling OnStmtRetry at RC isolation level +var CallOnStmtRetryCount stringutil.StringerStr = "callOnStmtRetryCount" + // AssertLockErr is used to record the lock errors we encountered // Only for test var AssertLockErr stringutil.StringerStr = "assertLockError" @@ -153,6 +156,17 @@ func TsoUseConstantCountInc(sctx sessionctx.Context) { sctx.SetValue(TsoUseConstantCount, count) } +// OnStmtRetryCountInc is used only for test. +// When it is called, there is calling `(p *PessimisticRCTxnContextProvider) OnStmtRetry`. +func OnStmtRetryCountInc(sctx sessionctx.Context) { + count, ok := sctx.Value(CallOnStmtRetryCount).(int) + if !ok { + count = 0 + } + count++ + sctx.SetValue(CallOnStmtRetryCount, count) +} + // ExecTestHook is used only for test. It consumes hookKey in session wait do what it gets from it. func ExecTestHook(sctx sessionctx.Context, hookKey fmt.Stringer) { c := sctx.Value(hookKey) diff --git a/sessiontxn/interface.go b/sessiontxn/interface.go index 85d9217a90c0f..4c6b50e2e0ae7 100644 --- a/sessiontxn/interface.go +++ b/sessiontxn/interface.go @@ -136,10 +136,17 @@ type TxnContextProvider interface { OnInitialize(ctx context.Context, enterNewTxnType EnterNewTxnType) error // OnStmtStart is the hook that should be called when a new statement started OnStmtStart(ctx context.Context, node ast.StmtNode) error + // OnHandlePessimisticStmtStart is the hook that should be called when starts handling a pessimistic DML or + // a pessimistic select-for-update statements. + OnHandlePessimisticStmtStart(ctx context.Context) error // OnStmtErrorForNextAction is the hook that should be called when a new statement get an error OnStmtErrorForNextAction(point StmtErrorHandlePoint, err error) (StmtErrorAction, error) // OnStmtRetry is the hook that should be called when a statement is retried internally. OnStmtRetry(ctx context.Context) error + // OnStmtCommit is the hook that should be called when a statement is executed successfully. + OnStmtCommit(ctx context.Context) error + // OnStmtRollback is the hook that should be called when a statement fails to execute. + OnStmtRollback(ctx context.Context, isForPessimisticRetry bool) error // OnLocalTemporaryTableCreated is the hook that should be called when a local temporary table created. OnLocalTemporaryTableCreated() // ActivateTxn activates the transaction. @@ -160,8 +167,10 @@ type TxnManager interface { // GetReadReplicaScope returns the read replica scope GetReadReplicaScope() string // GetStmtReadTS returns the read timestamp used by select statement (not for select ... for update) + // Calling this method will activate the txn implicitly if current read is not stale/historical read GetStmtReadTS() (uint64, error) // GetStmtForUpdateTS returns the read timestamp used by update/insert/delete or select ... for update + // Calling this method will activate the txn implicitly if current read is not stale/historical read GetStmtForUpdateTS() (uint64, error) // GetContextProvider returns the current TxnContextProvider GetContextProvider() TxnContextProvider @@ -176,6 +185,9 @@ type TxnManager interface { OnTxnEnd() // OnStmtStart is the hook that should be called when a new statement started OnStmtStart(ctx context.Context, node ast.StmtNode) error + // OnHandlePessimisticStmtStart is the hook that should be called when starts handling a pessimistic DML or + // a pessimistic select-for-update statements. + OnHandlePessimisticStmtStart(ctx context.Context) error // OnStmtErrorForNextAction is the hook that should be called when a new statement get an error // This method is not required to be called for every error in the statement, // it is only required to be called for some errors handled in some specified points given by the parameter `point`. @@ -183,6 +195,10 @@ type TxnManager interface { OnStmtErrorForNextAction(point StmtErrorHandlePoint, err error) (StmtErrorAction, error) // OnStmtRetry is the hook that should be called when a statement retry OnStmtRetry(ctx context.Context) error + // OnStmtCommit is the hook that should be called when a statement is executed successfully. + OnStmtCommit(ctx context.Context) error + // OnStmtRollback is the hook that should be called when a statement fails to execute. + OnStmtRollback(ctx context.Context, isForPessimisticRetry bool) error // OnLocalTemporaryTableCreated is the hook that should be called when a local temporary table created. OnLocalTemporaryTableCreated() // ActivateTxn activates the transaction. diff --git a/sessiontxn/isolation/base.go b/sessiontxn/isolation/base.go index 2db2797ea91e9..41e0e40846aa3 100644 --- a/sessiontxn/isolation/base.go +++ b/sessiontxn/isolation/base.go @@ -143,6 +143,12 @@ func (p *baseTxnContextProvider) GetTxnInfoSchema() infoschema.InfoSchema { if is := p.sctx.GetSessionVars().SnapshotInfoschema; is != nil { return is.(infoschema.InfoSchema) } + if _, ok := p.infoSchema.(*infoschema.SessionExtendedInfoSchema); !ok { + p.infoSchema = &infoschema.SessionExtendedInfoSchema{ + InfoSchema: p.infoSchema, + } + p.sctx.GetSessionVars().TxnCtx.InfoSchema = p.infoSchema + } return p.infoSchema } @@ -201,12 +207,28 @@ func (p *baseTxnContextProvider) OnStmtStart(ctx context.Context, _ ast.StmtNode return nil } +// OnHandlePessimisticStmtStart is the hook that should be called when starts handling a pessimistic DML or +// a pessimistic select-for-update statements. +func (p *baseTxnContextProvider) OnHandlePessimisticStmtStart(_ context.Context) error { + return nil +} + // OnStmtRetry is the hook that should be called when a statement is retried internally. func (p *baseTxnContextProvider) OnStmtRetry(ctx context.Context) error { p.ctx = ctx return nil } +// OnStmtCommit is the hook that should be called when a statement is executed successfully. +func (p *baseTxnContextProvider) OnStmtCommit(_ context.Context) error { + return nil +} + +// OnStmtRollback is the hook that should be called when a statement fails to execute. +func (p *baseTxnContextProvider) OnStmtRollback(_ context.Context, _ bool) error { + return nil +} + // OnLocalTemporaryTableCreated is the hook that should be called when a local temporary table created. func (p *baseTxnContextProvider) OnLocalTemporaryTableCreated() { p.infoSchema = temptable.AttachLocalTemporaryTableInfoSchema(p.sctx, p.infoSchema) @@ -261,6 +283,10 @@ func (p *baseTxnContextProvider) ActivateTxn() (kv.Transaction, error) { sessVars := p.sctx.GetSessionVars() sessVars.TxnCtx.StartTS = txn.StartTS() + if sessVars.MemDBFootprint != nil { + sessVars.MemDBFootprint.Detach() + } + sessVars.MemDBFootprint = nil if p.enterNewTxnType == sessiontxn.EnterNewTxnBeforeStmt && !sessVars.IsAutocommit() && sessVars.SnapshotTS == 0 { sessVars.SetInTxn(true) @@ -474,3 +500,62 @@ type funcFuture func() (uint64, error) func (f funcFuture) Wait() (uint64, error) { return f() } + +// basePessimisticTxnContextProvider extends baseTxnContextProvider with some functionalities that are commonly used in +// pessimistic transactions. +type basePessimisticTxnContextProvider struct { + baseTxnContextProvider +} + +// OnHandlePessimisticStmtStart is the hook that should be called when starts handling a pessimistic DML or +// a pessimistic select-for-update statements. +func (p *basePessimisticTxnContextProvider) OnHandlePessimisticStmtStart(ctx context.Context) error { + if err := p.baseTxnContextProvider.OnHandlePessimisticStmtStart(ctx); err != nil { + return err + } + if p.sctx.GetSessionVars().PessimisticTransactionAggressiveLocking && p.txn != nil { + if err := p.txn.StartAggressiveLocking(); err != nil { + return err + } + } + return nil +} + +// OnStmtRetry is the hook that should be called when a statement is retried internally. +func (p *basePessimisticTxnContextProvider) OnStmtRetry(ctx context.Context) error { + if err := p.baseTxnContextProvider.OnStmtRetry(ctx); err != nil { + return err + } + if p.txn != nil && p.txn.IsInAggressiveLockingMode() { + if err := p.txn.RetryAggressiveLocking(ctx); err != nil { + return err + } + } + return nil +} + +// OnStmtCommit is the hook that should be called when a statement is executed successfully. +func (p *basePessimisticTxnContextProvider) OnStmtCommit(ctx context.Context) error { + if err := p.baseTxnContextProvider.OnStmtCommit(ctx); err != nil { + return err + } + if p.txn != nil && p.txn.IsInAggressiveLockingMode() { + if err := p.txn.DoneAggressiveLocking(ctx); err != nil { + return err + } + } + return nil +} + +// OnStmtRollback is the hook that should be called when a statement fails to execute. +func (p *basePessimisticTxnContextProvider) OnStmtRollback(ctx context.Context, isForPessimisticRetry bool) error { + if err := p.baseTxnContextProvider.OnStmtRollback(ctx, isForPessimisticRetry); err != nil { + return err + } + if !isForPessimisticRetry && p.txn != nil && p.txn.IsInAggressiveLockingMode() { + if err := p.txn.CancelAggressiveLocking(ctx); err != nil { + return err + } + } + return nil +} diff --git a/sessiontxn/isolation/main_test.go b/sessiontxn/isolation/main_test.go index aa8d031f70975..e0b8ace02bce6 100644 --- a/sessiontxn/isolation/main_test.go +++ b/sessiontxn/isolation/main_test.go @@ -39,6 +39,7 @@ func TestMain(m *testing.M) { tikv.EnableFailpoints() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/sessiontxn/isolation/optimistic.go b/sessiontxn/isolation/optimistic.go index 3c60eba09331b..9a1f8d58aabbd 100644 --- a/sessiontxn/isolation/optimistic.go +++ b/sessiontxn/isolation/optimistic.go @@ -114,6 +114,12 @@ func (p *OptimisticTxnContextProvider) AdviseOptimizeWithPlan(plan interface{}) return nil } + if p.txn != nil { + // `p.txn != nil` means the txn has already been activated, we should not optimize the startTS because the startTS + // has already been used. + return nil + } + realPlan, ok := plan.(plannercore.Plan) if !ok { return nil @@ -141,7 +147,7 @@ func (p *OptimisticTxnContextProvider) AdviseOptimizeWithPlan(plan interface{}) zap.Uint64("conn", sessVars.ConnectionID), zap.String("text", sessVars.StmtCtx.OriginalSQL), ) - return nil + return err } p.optimizeWithMaxTS = true diff --git a/sessiontxn/isolation/readcommitted.go b/sessiontxn/isolation/readcommitted.go index 1a9ec05c48f01..ef44834f8bcfb 100644 --- a/sessiontxn/isolation/readcommitted.go +++ b/sessiontxn/isolation/readcommitted.go @@ -16,6 +16,7 @@ package isolation import ( "context" + "time" "github.com/pingcap/errors" "github.com/pingcap/failpoint" @@ -53,7 +54,7 @@ func (s *stmtState) prepareStmt(useStartTS bool) error { // PessimisticRCTxnContextProvider provides txn context for isolation level read-committed type PessimisticRCTxnContextProvider struct { - baseTxnContextProvider + basePessimisticTxnContextProvider stmtState latestOracleTS uint64 // latestOracleTSValid shows whether we have already fetched a ts from pd and whether the ts we fetched is still valid. @@ -65,15 +66,17 @@ type PessimisticRCTxnContextProvider struct { // NewPessimisticRCTxnContextProvider returns a new PessimisticRCTxnContextProvider func NewPessimisticRCTxnContextProvider(sctx sessionctx.Context, causalConsistencyOnly bool) *PessimisticRCTxnContextProvider { provider := &PessimisticRCTxnContextProvider{ - baseTxnContextProvider: baseTxnContextProvider{ - sctx: sctx, - causalConsistencyOnly: causalConsistencyOnly, - onInitializeTxnCtx: func(txnCtx *variable.TransactionContext) { - txnCtx.IsPessimistic = true - txnCtx.Isolation = ast.ReadCommitted - }, - onTxnActiveFunc: func(txn kv.Transaction, _ sessiontxn.EnterNewTxnType) { - txn.SetOption(kv.Pessimistic, true) + basePessimisticTxnContextProvider: basePessimisticTxnContextProvider{ + baseTxnContextProvider: baseTxnContextProvider{ + sctx: sctx, + causalConsistencyOnly: causalConsistencyOnly, + onInitializeTxnCtx: func(txnCtx *variable.TransactionContext) { + txnCtx.IsPessimistic = true + txnCtx.Isolation = ast.ReadCommitted + }, + onTxnActiveFunc: func(txn kv.Transaction, _ sessiontxn.EnterNewTxnType) { + txn.SetOption(kv.Pessimistic, true) + }, }, }, } @@ -90,7 +93,7 @@ func NewPessimisticRCTxnContextProvider(sctx sessionctx.Context, causalConsisten // OnStmtStart is the hook that should be called when a new statement started func (p *PessimisticRCTxnContextProvider) OnStmtStart(ctx context.Context, node ast.StmtNode) error { - if err := p.baseTxnContextProvider.OnStmtStart(ctx, node); err != nil { + if err := p.basePessimisticTxnContextProvider.OnStmtStart(ctx, node); err != nil { return err } @@ -122,15 +125,19 @@ func (p *PessimisticRCTxnContextProvider) OnStmtErrorForNextAction(point session case sessiontxn.StmtErrAfterPessimisticLock: return p.handleAfterPessimisticLockError(err) default: - return p.baseTxnContextProvider.OnStmtErrorForNextAction(point, err) + return p.basePessimisticTxnContextProvider.OnStmtErrorForNextAction(point, err) } } // OnStmtRetry is the hook that should be called when a statement is retried internally. func (p *PessimisticRCTxnContextProvider) OnStmtRetry(ctx context.Context) error { - if err := p.baseTxnContextProvider.OnStmtRetry(ctx); err != nil { + if err := p.basePessimisticTxnContextProvider.OnStmtRetry(ctx); err != nil { return err } + failpoint.Inject("CallOnStmtRetry", func() { + sessiontxn.OnStmtRetryCountInc(p.sctx) + }) + p.latestOracleTSValid = false p.checkTSInWriteStmt = false return p.prepareStmt(false) } @@ -182,9 +189,11 @@ func (p *PessimisticRCTxnContextProvider) getStmtTS() (ts uint64, err error) { } p.prepareStmtTS() + start := time.Now() if ts, err = p.stmtTSFuture.Wait(); err != nil { return 0, err } + p.sctx.GetSessionVars().DurationWaitTS += time.Since(start) txn.SetOption(kv.SnapshotTS, ts) p.stmtTS = ts @@ -199,8 +208,6 @@ func (p *PessimisticRCTxnContextProvider) handleAfterQueryError(queryErr error) return sessiontxn.NoIdea() } - p.latestOracleTSValid = false - rcReadCheckTSWriteConfilictCounter.Inc() logutil.Logger(p.ctx).Info("RC read with ts checking has failed, retry RC read", @@ -209,7 +216,6 @@ func (p *PessimisticRCTxnContextProvider) handleAfterQueryError(queryErr error) } func (p *PessimisticRCTxnContextProvider) handleAfterPessimisticLockError(lockErr error) (sessiontxn.StmtErrorAction, error) { - p.latestOracleTSValid = false txnCtx := p.sctx.GetSessionVars().TxnCtx retryable := false if deadlock, ok := errors.Cause(lockErr).(*tikverr.ErrDeadlock); ok && deadlock.IsRetryable { @@ -316,7 +322,7 @@ func (p *PessimisticRCTxnContextProvider) AdviseOptimizeWithPlan(val interface{} // GetSnapshotWithStmtForUpdateTS gets snapshot with for update ts func (p *PessimisticRCTxnContextProvider) GetSnapshotWithStmtForUpdateTS() (kv.Snapshot, error) { - snapshot, err := p.baseTxnContextProvider.GetSnapshotWithStmtForUpdateTS() + snapshot, err := p.basePessimisticTxnContextProvider.GetSnapshotWithStmtForUpdateTS() if err != nil { return nil, err } @@ -328,7 +334,7 @@ func (p *PessimisticRCTxnContextProvider) GetSnapshotWithStmtForUpdateTS() (kv.S // GetSnapshotWithStmtReadTS gets snapshot with read ts func (p *PessimisticRCTxnContextProvider) GetSnapshotWithStmtReadTS() (kv.Snapshot, error) { - snapshot, err := p.baseTxnContextProvider.GetSnapshotWithStmtForUpdateTS() + snapshot, err := p.basePessimisticTxnContextProvider.GetSnapshotWithStmtForUpdateTS() if err != nil { return nil, err } diff --git a/sessiontxn/isolation/repeatable_read.go b/sessiontxn/isolation/repeatable_read.go index 18fa2ebd8608c..8288ff92bde44 100644 --- a/sessiontxn/isolation/repeatable_read.go +++ b/sessiontxn/isolation/repeatable_read.go @@ -16,6 +16,7 @@ package isolation import ( "context" + "time" "github.com/pingcap/errors" "github.com/pingcap/failpoint" @@ -33,7 +34,7 @@ import ( // PessimisticRRTxnContextProvider provides txn context for isolation level repeatable-read type PessimisticRRTxnContextProvider struct { - baseTxnContextProvider + basePessimisticTxnContextProvider // Used for ForUpdateRead statement forUpdateTS uint64 @@ -46,15 +47,17 @@ type PessimisticRRTxnContextProvider struct { // NewPessimisticRRTxnContextProvider returns a new PessimisticRRTxnContextProvider func NewPessimisticRRTxnContextProvider(sctx sessionctx.Context, causalConsistencyOnly bool) *PessimisticRRTxnContextProvider { provider := &PessimisticRRTxnContextProvider{ - baseTxnContextProvider: baseTxnContextProvider{ - sctx: sctx, - causalConsistencyOnly: causalConsistencyOnly, - onInitializeTxnCtx: func(txnCtx *variable.TransactionContext) { - txnCtx.IsPessimistic = true - txnCtx.Isolation = ast.RepeatableRead - }, - onTxnActiveFunc: func(txn kv.Transaction, _ sessiontxn.EnterNewTxnType) { - txn.SetOption(kv.Pessimistic, true) + basePessimisticTxnContextProvider: basePessimisticTxnContextProvider{ + baseTxnContextProvider: baseTxnContextProvider{ + sctx: sctx, + causalConsistencyOnly: causalConsistencyOnly, + onInitializeTxnCtx: func(txnCtx *variable.TransactionContext) { + txnCtx.IsPessimistic = true + txnCtx.Isolation = ast.RepeatableRead + }, + onTxnActiveFunc: func(txn kv.Transaction, _ sessiontxn.EnterNewTxnType) { + txn.SetOption(kv.Pessimistic, true) + }, }, }, } @@ -83,9 +86,11 @@ func (p *PessimisticRRTxnContextProvider) getForUpdateTs() (ts uint64, err error txnCtx := p.sctx.GetSessionVars().TxnCtx futureTS := newOracleFuture(p.ctx, p.sctx, txnCtx.TxnScope) + start := time.Now() if ts, err = futureTS.Wait(); err != nil { return 0, err } + p.sctx.GetSessionVars().DurationWaitTS += time.Since(start) txnCtx.SetForUpdateTS(ts) txn.SetOption(kv.SnapshotTS, ts) @@ -128,7 +133,7 @@ func (p *PessimisticRRTxnContextProvider) updateForUpdateTS() (err error) { // OnStmtStart is the hook that should be called when a new statement started func (p *PessimisticRRTxnContextProvider) OnStmtStart(ctx context.Context, node ast.StmtNode) error { - if err := p.baseTxnContextProvider.OnStmtStart(ctx, node); err != nil { + if err := p.basePessimisticTxnContextProvider.OnStmtStart(ctx, node); err != nil { return err } @@ -140,7 +145,7 @@ func (p *PessimisticRRTxnContextProvider) OnStmtStart(ctx context.Context, node // OnStmtRetry is the hook that should be called when a statement is retried internally. func (p *PessimisticRRTxnContextProvider) OnStmtRetry(ctx context.Context) (err error) { - if err = p.baseTxnContextProvider.OnStmtRetry(ctx); err != nil { + if err = p.basePessimisticTxnContextProvider.OnStmtRetry(ctx); err != nil { return err } diff --git a/sessiontxn/isolation/repeatable_read_test.go b/sessiontxn/isolation/repeatable_read_test.go index da798f05c2152..085b64c34cc38 100644 --- a/sessiontxn/isolation/repeatable_read_test.go +++ b/sessiontxn/isolation/repeatable_read_test.go @@ -678,3 +678,25 @@ func initializeRepeatableReadProvider(t *testing.T, tk *testkit.TestKit, active require.NoError(t, tk.Session().PrepareTxnCtx(context.TODO())) return assert.CheckAndGetProvider(t) } + +func TestRRWaitTSTimeInSlowLog(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + se := tk.Session() + + tk.MustExec("use test") + tk.MustExec("create table t (id int primary key, v int)") + tk.MustExec("insert into t values (1, 1)") + + tk.MustExec("begin pessimistic") + waitTS1 := se.GetSessionVars().DurationWaitTS + tk.MustExec("update t set v = v + 10 where id = 1") + waitTS2 := se.GetSessionVars().DurationWaitTS + tk.MustExec("delete from t") + waitTS3 := se.GetSessionVars().DurationWaitTS + tk.MustExec("commit") + require.NotEqual(t, waitTS1, waitTS2) + require.NotEqual(t, waitTS1, waitTS3) + require.NotEqual(t, waitTS2, waitTS3) +} diff --git a/sessiontxn/isolation/serializable.go b/sessiontxn/isolation/serializable.go index cff6ffc20fbbb..903b1479af79c 100644 --- a/sessiontxn/isolation/serializable.go +++ b/sessiontxn/isolation/serializable.go @@ -24,22 +24,24 @@ import ( // PessimisticSerializableTxnContextProvider provides txn context for isolation level oracle-like serializable type PessimisticSerializableTxnContextProvider struct { - baseTxnContextProvider + basePessimisticTxnContextProvider } // NewPessimisticSerializableTxnContextProvider returns a new PessimisticSerializableTxnContextProvider func NewPessimisticSerializableTxnContextProvider(sctx sessionctx.Context, causalConsistencyOnly bool) *PessimisticSerializableTxnContextProvider { provider := &PessimisticSerializableTxnContextProvider{ - baseTxnContextProvider{ - sctx: sctx, - causalConsistencyOnly: causalConsistencyOnly, - onInitializeTxnCtx: func(txnCtx *variable.TransactionContext) { - txnCtx.IsPessimistic = true - txnCtx.Isolation = ast.Serializable - }, - onTxnActiveFunc: func(txn kv.Transaction, _ sessiontxn.EnterNewTxnType) { - txn.SetOption(kv.Pessimistic, true) + basePessimisticTxnContextProvider: basePessimisticTxnContextProvider{ + baseTxnContextProvider{ + sctx: sctx, + causalConsistencyOnly: causalConsistencyOnly, + onInitializeTxnCtx: func(txnCtx *variable.TransactionContext) { + txnCtx.IsPessimistic = true + txnCtx.Isolation = ast.Serializable + }, + onTxnActiveFunc: func(txn kv.Transaction, _ sessiontxn.EnterNewTxnType) { + txn.SetOption(kv.Pessimistic, true) + }, }, }, } diff --git a/sessiontxn/staleread/BUILD.bazel b/sessiontxn/staleread/BUILD.bazel index f89148671792f..9c1e11823e32a 100644 --- a/sessiontxn/staleread/BUILD.bazel +++ b/sessiontxn/staleread/BUILD.bazel @@ -21,6 +21,7 @@ go_library( "//parser/ast", "//parser/mysql", "//sessionctx", + "//sessionctx/stmtctx", "//sessionctx/variable", "//sessiontxn", "//sessiontxn/internal", @@ -36,6 +37,7 @@ go_test( name = "staleread_test", timeout = "short", srcs = [ + "externalts_test.go", "main_test.go", "processor_test.go", "provider_test.go", @@ -48,6 +50,7 @@ go_test( "//kv", "//parser", "//parser/ast", + "//parser/auth", "//sessionctx", "//sessiontxn", "//table/temptable", diff --git a/sessiontxn/staleread/externalts_test.go b/sessiontxn/staleread/externalts_test.go new file mode 100644 index 0000000000000..2ee7c6f14f767 --- /dev/null +++ b/sessiontxn/staleread/externalts_test.go @@ -0,0 +1,145 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package staleread_test + +import ( + "context" + "testing" + + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" +) + +func TestReadWriteExternalTimestamp(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustQuery("select @@tidb_external_ts").Check(testkit.Rows("0")) + tk.MustExec("set global tidb_external_ts=19980613") + tk.MustQuery("select @@tidb_external_ts").Check(testkit.Rows("19980613")) + tk.MustExec("set global tidb_external_ts=20220930") + tk.MustQuery("select @@tidb_external_ts").Check(testkit.Rows("20220930")) +} + +func TestExternalTimestampRead(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("create table t (id INT NOT NULL,d double,PRIMARY KEY (id))") + tk.MustExec("insert into t values (0, 100)") + tk.MustExec("insert into t values (1, 100)") + tk.MustExec("insert into t values (2, 100)") + tk.MustExec("insert into t values (3, 100)") + tk.MustQuery("select * from t").Check(testkit.Rows("0 100", "1 100", "2 100", "3 100")) + + tk.MustQuery("select @@tidb_external_ts").Check(testkit.Rows("0")) + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit;") + tk.MustExec("insert into t values (4, 100)") + // as the `tidb_external_ts` is set an old value, the newest row (4, 100) cannot be read + tk.MustExec("set tidb_enable_external_ts_read=ON") + tk.MustQuery("select * from t").Check(testkit.Rows("0 100", "1 100", "2 100", "3 100")) + + tk.MustExec("set tidb_enable_external_ts_read=OFF") + tk.MustQuery("select * from t").Check(testkit.Rows("0 100", "1 100", "2 100", "3 100", "4 100")) +} + +func TestExternalTimestampReadonly(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("create table t (id INT NOT NULL,PRIMARY KEY (id))") + + tk.MustQuery("select @@tidb_external_ts").Check(testkit.Rows("0")) + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit;") + + // with tidb_enable_external_ts_read enabled, this session will be readonly + tk.MustExec("set tidb_enable_external_ts_read=ON") + _, err := tk.Exec("insert into t values (0)") + require.Error(t, err) + + tk.MustExec("set tidb_enable_external_ts_read=OFF") + tk.MustExec("insert into t values (0)") + + // even when tidb_enable_external_ts_read is enabled, internal SQL will not be affected + tk.MustExec("set tidb_enable_external_ts_read=ON") + tk.Session().GetSessionVars().InRestrictedSQL = true + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnOthers) + tk.MustExecWithContext(ctx, "insert into t values (1)") + tk.Session().GetSessionVars().InRestrictedSQL = false +} + +func TestExternalTimestampReadWithTransaction(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("create table t (id INT NOT NULL,PRIMARY KEY (id))") + + tk.MustQuery("select @@tidb_external_ts").Check(testkit.Rows("0")) + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit;") + + tk.MustExec("insert into t values (0)") + tk.MustQuery("select * from t").Check(testkit.Rows("0")) + + tk.MustExec("set tidb_enable_external_ts_read=ON") + tk.MustQuery("select * from t").Check(testkit.Rows()) + tk.MustExec("start transaction") + tk.MustQuery("select * from t").Check(testkit.Rows()) + tk.MustExec("commit") + + tk.MustExec("set tidb_enable_external_ts_read=OFF") + tk.MustExec("start transaction") + tk.MustQuery("select * from t").Check(testkit.Rows("0")) + tk.MustExec("commit") + + tk.MustExec("start transaction") + tk.MustQuery("select * from t").Check(testkit.Rows("0")) + tk.MustExec("set tidb_enable_external_ts_read=ON") + // `tidb_enable_external_ts_read` doesn't affect existing transaction + tk.MustQuery("select * from t").Check(testkit.Rows("0")) + tk.MustExec("set tidb_enable_external_ts_read=OFF") + tk.MustExec("commit") +} + +func TestExternalTimestampNotAffectPrepare(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + + tk.MustExec("use test") + tk.MustExec("create table t (id INT NOT NULL,PRIMARY KEY (id))") + + tk.MustExec("insert into t values (0)") + tk.MustQuery("select * from t").Check(testkit.Rows("0")) + + tk.MustQuery("select @@tidb_external_ts").Check(testkit.Rows("0")) + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit;") + + tk.MustExec("insert into t values (1)") + tk.MustQuery("select * from t").Check(testkit.Rows("0", "1")) + + tk.MustExec("set tidb_enable_external_ts_read=on") + tk.MustExec("prepare my_select from 'select * from t'") + tk.MustQuery("execute my_select").Check(testkit.Rows("0")) + tk.MustExec("set tidb_enable_external_ts_read=off") + + tk.MustQuery("execute my_select").Check(testkit.Rows("0", "1")) +} diff --git a/sessiontxn/staleread/main_test.go b/sessiontxn/staleread/main_test.go index 7ed95c5699c5c..fb4766298666c 100644 --- a/sessiontxn/staleread/main_test.go +++ b/sessiontxn/staleread/main_test.go @@ -26,6 +26,7 @@ func TestMain(m *testing.M) { tikv.EnableFailpoints() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/sessiontxn/staleread/processor.go b/sessiontxn/staleread/processor.go index 887b57f28fb45..2fc7f3806632b 100644 --- a/sessiontxn/staleread/processor.go +++ b/sessiontxn/staleread/processor.go @@ -50,6 +50,7 @@ type Processor interface { } type baseProcessor struct { + ctx context.Context sctx sessionctx.Context txnManager sessiontxn.TxnManager @@ -59,7 +60,8 @@ type baseProcessor struct { is infoschema.InfoSchema } -func (p *baseProcessor) init(sctx sessionctx.Context) { +func (p *baseProcessor) init(ctx context.Context, sctx sessionctx.Context) { + p.ctx = ctx p.sctx = sctx p.txnManager = sessiontxn.GetTxnManager(sctx) } @@ -103,6 +105,16 @@ func (p *baseProcessor) setEvaluatedTS(ts uint64) (err error) { }) } +// setEvaluatedTSWithoutEvaluator sets the ts, but not set the evaluator, so it doesn't affect prepare statement +func (p *baseProcessor) setEvaluatedTSWithoutEvaluator(ts uint64) (err error) { + is, err := GetSessionSnapshotInfoSchema(p.sctx, ts) + if err != nil { + return err + } + + return p.setEvaluatedValues(ts, is, nil) +} + func (p *baseProcessor) setEvaluatedEvaluator(evaluator StalenessTSEvaluator) error { ts, err := evaluator(p.sctx) if err != nil { @@ -135,9 +147,9 @@ type staleReadProcessor struct { } // NewStaleReadProcessor creates a new stale read processor -func NewStaleReadProcessor(sctx sessionctx.Context) Processor { +func NewStaleReadProcessor(ctx context.Context, sctx sessionctx.Context) Processor { p := &staleReadProcessor{} - p.init(sctx) + p.init(ctx, sctx) return p } @@ -155,7 +167,7 @@ func (p *staleReadProcessor) OnSelectTable(tn *ast.TableName) error { } // If `stmtAsOfTS` is not 0, it means we use 'select ... from xxx as of timestamp ...' - stmtAsOfTS, err := parseAndValidateAsOf(p.sctx, tn.AsOf) + stmtAsOfTS, err := parseAndValidateAsOf(p.ctx, p.sctx, tn.AsOf) if err != nil { return err } @@ -204,6 +216,10 @@ func (p *staleReadProcessor) evaluateFromTxn() error { nil, ) } + + // Don't consider external ts, but just set non-stale read directly,because stepping here means + // when the transaction begins, the external ts read hasn't been turned on, but it was turned + // on during the transaction. Ignore it to avoid unexpected stepping back. return p.setAsNonStaleRead() } @@ -234,11 +250,19 @@ func (p *staleReadProcessor) evaluateFromStmtTSOrSysVariable(stmtTS uint64) erro return p.setEvaluatedEvaluator(evaluator) } + ts, err := getTSFromExternalTS(p.ctx, p.sctx) + if err != nil { + return errAsOf.FastGenWithCause(err.Error()) + } + if ts > 0 { + return p.setEvaluatedTSWithoutEvaluator(ts) + } + // Otherwise, it means we should not use stale read. return p.setAsNonStaleRead() } -func parseAndValidateAsOf(sctx sessionctx.Context, asOf *ast.AsOfClause) (uint64, error) { +func parseAndValidateAsOf(ctx context.Context, sctx sessionctx.Context, asOf *ast.AsOfClause) (uint64, error) { if asOf == nil { return 0, nil } @@ -248,7 +272,7 @@ func parseAndValidateAsOf(sctx sessionctx.Context, asOf *ast.AsOfClause) (uint64 return 0, err } - if err = sessionctx.ValidateStaleReadTS(context.TODO(), sctx, ts); err != nil { + if err = sessionctx.ValidateStaleReadTS(ctx, sctx, ts); err != nil { return 0, err } @@ -266,6 +290,18 @@ func getTsEvaluatorFromReadStaleness(sctx sessionctx.Context) StalenessTSEvaluat } } +func getTSFromExternalTS(ctx context.Context, sctx sessionctx.Context) (uint64, error) { + if sctx.GetSessionVars().EnableExternalTSRead && !sctx.GetSessionVars().InRestrictedSQL { + externalTimestamp, err := GetExternalTimestamp(ctx, sctx) + if err != nil { + return 0, err + } + return externalTimestamp, nil + } + + return 0, nil +} + // GetSessionSnapshotInfoSchema returns the session's information schema with specified ts func GetSessionSnapshotInfoSchema(sctx sessionctx.Context, snapshotTS uint64) (infoschema.InfoSchema, error) { is, err := domain.GetDomain(sctx).GetSnapshotInfoSchema(snapshotTS) diff --git a/sessiontxn/staleread/processor_test.go b/sessiontxn/staleread/processor_test.go index 4a98bff0364fc..e0f9d5895e49f 100644 --- a/sessiontxn/staleread/processor_test.go +++ b/sessiontxn/staleread/processor_test.go @@ -15,7 +15,9 @@ package staleread_test import ( + "context" "fmt" + "strconv" "testing" "time" @@ -92,6 +94,14 @@ func astTableWithAsOf(t *testing.T, dt string) *ast.TableName { return sel.From.TableRefs.Left.(*ast.TableSource).Source.(*ast.TableName) } +func getCurrentExternalTimestamp(t *testing.T, tk *testkit.TestKit) uint64 { + externalTimestampStr := tk.MustQuery("select @@tidb_external_ts").Rows()[0][0].(string) + externalTimestamp, err := strconv.ParseUint(externalTimestampStr, 10, 64) + require.NoError(t, err) + + return externalTimestamp +} + func TestStaleReadProcessorWithSelectTable(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -142,12 +152,12 @@ func TestStaleReadProcessorWithSelectTable(t *testing.T) { tk.MustExec("set @@tx_read_ts=''") // `@@tidb_read_staleness` - tk.MustExec("set @@tidb_read_staleness=-5") + tk.MustExec("set @@tidb_read_staleness=-100") processor = createProcessor(t, tk.Session()) err = processor.OnSelectTable(tn) require.True(t, processor.IsStaleness()) require.Equal(t, int64(0), processor.GetStalenessInfoSchema().SchemaMetaVersion()) - expectedTS, err := staleread.CalculateTsWithReadStaleness(tk.Session(), -5*time.Second) + expectedTS, err := staleread.CalculateTsWithReadStaleness(tk.Session(), -100*time.Second) require.NoError(t, err) require.Equal(t, expectedTS, processor.GetStalenessReadTS()) evaluator := processor.GetStalenessTSEvaluatorForPrepare() @@ -159,12 +169,37 @@ func TestStaleReadProcessorWithSelectTable(t *testing.T) { tk.MustExec("do sleep(0.01)") evaluatorTS, err = evaluator(tk.Session()) require.NoError(t, err) - expectedTS2, err := staleread.CalculateTsWithReadStaleness(tk.Session(), -5*time.Second) + expectedTS2, err := staleread.CalculateTsWithReadStaleness(tk.Session(), -100*time.Second) require.NoError(t, err) require.Equal(t, expectedTS2, evaluatorTS) // `@@tidb_read_staleness` will be ignored when `as of` or `@@tx_read_ts` - tk.MustExec("set @@tidb_read_staleness=-5") + tk.MustExec("set @@tidb_read_staleness=-100") + processor = createProcessor(t, tk.Session()) + err = processor.OnSelectTable(p1.tn) + require.NoError(t, err) + p1.checkMatchProcessor(t, processor, true) + + tk.MustExec(fmt.Sprintf("SET TRANSACTION READ ONLY AS OF TIMESTAMP '%s'", p1.dt)) + processor = createProcessor(t, tk.Session()) + err = processor.OnSelectTable(tn) + require.NoError(t, err) + p1.checkMatchProcessor(t, processor, true) + tk.MustExec("set @@tidb_read_staleness=''") + + // `@@tidb_external_ts` + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit") + tk.MustExec("set tidb_enable_external_ts_read=ON") + processor = createProcessor(t, tk.Session()) + err = processor.OnSelectTable(tn) + require.True(t, processor.IsStaleness()) + expectedTS = getCurrentExternalTimestamp(t, tk) + require.Equal(t, expectedTS, processor.GetStalenessReadTS()) + tk.MustExec("set tidb_enable_external_ts_read=OFF") + + // `@@tidb_external_ts` will be ignored when `as of`, `@@tx_read_ts` or `@@tidb_read_staleness` + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit") + tk.MustExec("set tidb_enable_external_ts_read=ON") processor = createProcessor(t, tk.Session()) err = processor.OnSelectTable(p1.tn) require.NoError(t, err) @@ -175,7 +210,22 @@ func TestStaleReadProcessorWithSelectTable(t *testing.T) { err = processor.OnSelectTable(tn) require.NoError(t, err) p1.checkMatchProcessor(t, processor, true) + + tk.MustExec("set @@tidb_read_staleness=-5") + processor = createProcessor(t, tk.Session()) + err = processor.OnSelectTable(tn) + require.True(t, processor.IsStaleness()) + require.Equal(t, int64(0), processor.GetStalenessInfoSchema().SchemaMetaVersion()) + expectedTS, err = staleread.CalculateTsWithReadStaleness(tk.Session(), -5*time.Second) + require.NoError(t, err) + require.Equal(t, expectedTS, processor.GetStalenessReadTS()) + evaluator = processor.GetStalenessTSEvaluatorForPrepare() + evaluatorTS, err = evaluator(tk.Session()) + require.NoError(t, err) + require.Equal(t, expectedTS, evaluatorTS) tk.MustExec("set @@tidb_read_staleness=''") + + tk.MustExec("set tidb_enable_external_ts_read=OFF") } func TestStaleReadProcessorWithExecutePreparedStmt(t *testing.T) { @@ -230,18 +280,18 @@ func TestStaleReadProcessorWithExecutePreparedStmt(t *testing.T) { tk.MustExec("set @@tx_read_ts=''") // `@@tidb_read_staleness` - tk.MustExec("set @@tidb_read_staleness=-5") + tk.MustExec("set @@tidb_read_staleness=-100") processor = createProcessor(t, tk.Session()) err = processor.OnExecutePreparedStmt(nil) require.True(t, processor.IsStaleness()) require.Equal(t, int64(0), processor.GetStalenessInfoSchema().SchemaMetaVersion()) - expectedTS, err := staleread.CalculateTsWithReadStaleness(tk.Session(), -5*time.Second) + expectedTS, err := staleread.CalculateTsWithReadStaleness(tk.Session(), -100*time.Second) require.NoError(t, err) require.Equal(t, expectedTS, processor.GetStalenessReadTS()) tk.MustExec("set @@tidb_read_staleness=''") // `@@tidb_read_staleness` will be ignored when `as of` or `@@tx_read_ts` - tk.MustExec("set @@tidb_read_staleness=-5") + tk.MustExec("set @@tidb_read_staleness=-100") processor = createProcessor(t, tk.Session()) err = processor.OnExecutePreparedStmt(func(sctx sessionctx.Context) (uint64, error) { return p1.ts, nil @@ -255,6 +305,43 @@ func TestStaleReadProcessorWithExecutePreparedStmt(t *testing.T) { require.NoError(t, err) p1.checkMatchProcessor(t, processor, true) tk.MustExec("set @@tidb_read_staleness=''") + + // `@@tidb_external_ts` + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit") + tk.MustExec("set tidb_enable_external_ts_read=ON") + processor = createProcessor(t, tk.Session()) + err = processor.OnExecutePreparedStmt(nil) + require.True(t, processor.IsStaleness()) + expectedTS = getCurrentExternalTimestamp(t, tk) + require.Equal(t, expectedTS, processor.GetStalenessReadTS()) + tk.MustExec("set tidb_enable_external_ts_read=OFF") + + // `@@tidb_external_ts` will be ignored when `as of`, `@@tx_read_ts` or `@@tidb_read_staleness` + tk.MustExec("start transaction;set global tidb_external_ts=@@tidb_current_ts;commit") + tk.MustExec("set tidb_enable_external_ts_read=ON") + + processor = createProcessor(t, tk.Session()) + err = processor.OnSelectTable(p1.tn) + require.NoError(t, err) + p1.checkMatchProcessor(t, processor, true) + + tk.MustExec(fmt.Sprintf("SET TRANSACTION READ ONLY AS OF TIMESTAMP '%s'", p1.dt)) + processor = createProcessor(t, tk.Session()) + err = processor.OnExecutePreparedStmt(nil) + require.NoError(t, err) + p1.checkMatchProcessor(t, processor, true) + + tk.MustExec("set @@tidb_read_staleness=-5") + processor = createProcessor(t, tk.Session()) + err = processor.OnExecutePreparedStmt(nil) + require.True(t, processor.IsStaleness()) + require.Equal(t, int64(0), processor.GetStalenessInfoSchema().SchemaMetaVersion()) + expectedTS, err = staleread.CalculateTsWithReadStaleness(tk.Session(), -5*time.Second) + require.NoError(t, err) + require.Equal(t, expectedTS, processor.GetStalenessReadTS()) + tk.MustExec("set @@tidb_read_staleness=''") + + tk.MustExec("set tidb_enable_external_ts_read=OFF") } func TestStaleReadProcessorInTxn(t *testing.T) { @@ -287,7 +374,7 @@ func TestStaleReadProcessorInTxn(t *testing.T) { require.Error(t, err) require.Equal(t, "[planner:8135]invalid as of timestamp: as of timestamp can't be set in transaction.", err.Error()) - // return an error when execute prepared stmt with ts evaluator + // return an error when execute prepared stmt with as of processor = createProcessor(t, tk.Session()) err = processor.OnExecutePreparedStmt(func(sctx sessionctx.Context) (uint64, error) { return p1.ts, nil @@ -331,7 +418,7 @@ func TestStaleReadProcessorInTxn(t *testing.T) { } func createProcessor(t *testing.T, se sessionctx.Context) staleread.Processor { - processor := staleread.NewStaleReadProcessor(se) + processor := staleread.NewStaleReadProcessor(context.Background(), se) require.False(t, processor.IsStaleness()) require.Equal(t, uint64(0), processor.GetStalenessReadTS()) require.Nil(t, processor.GetStalenessTSEvaluatorForPrepare()) diff --git a/sessiontxn/staleread/provider.go b/sessiontxn/staleread/provider.go index 9bbc4c5593748..f5d8057882167 100644 --- a/sessiontxn/staleread/provider.go +++ b/sessiontxn/staleread/provider.go @@ -164,6 +164,12 @@ func (p *StalenessTxnContextProvider) OnStmtStart(ctx context.Context, _ ast.Stm return nil } +// OnHandlePessimisticStmtStart is the hook that should be called when starts handling a pessimistic DML or +// a pessimistic select-for-update statements. +func (p *StalenessTxnContextProvider) OnHandlePessimisticStmtStart(_ context.Context) error { + return nil +} + // ActivateTxn activates the transaction. func (p *StalenessTxnContextProvider) ActivateTxn() (kv.Transaction, error) { if p.txn != nil { @@ -196,6 +202,16 @@ func (p *StalenessTxnContextProvider) OnStmtRetry(ctx context.Context) error { return nil } +// OnStmtCommit is the hook that should be called when a statement is executed successfully. +func (p *StalenessTxnContextProvider) OnStmtCommit(_ context.Context) error { + return nil +} + +// OnStmtRollback is the hook that should be called when a statement fails to execute. +func (p *StalenessTxnContextProvider) OnStmtRollback(_ context.Context, _ bool) error { + return nil +} + // AdviseWarmup provides warmup for inner state func (p *StalenessTxnContextProvider) AdviseWarmup() error { return nil diff --git a/sessiontxn/staleread/util.go b/sessiontxn/staleread/util.go index 36d0b869e38f7..3fa84f72cae0b 100644 --- a/sessiontxn/staleread/util.go +++ b/sessiontxn/staleread/util.go @@ -15,12 +15,15 @@ package staleread import ( + "context" "time" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" "github.com/tikv/client-go/v2/oracle" ) @@ -65,3 +68,17 @@ func CalculateTsWithReadStaleness(sctx sessionctx.Context, readStaleness time.Du func IsStmtStaleness(sctx sessionctx.Context) bool { return sctx.GetSessionVars().StmtCtx.IsStaleness } + +// GetExternalTimestamp returns the external timestamp in cache, or get and store it in cache +func GetExternalTimestamp(ctx context.Context, sctx sessionctx.Context) (uint64, error) { + // Try to get from the stmt cache to make sure this function is deterministic. + stmtCtx := sctx.GetSessionVars().StmtCtx + externalTimestamp, err := stmtCtx.GetOrEvaluateStmtCache(stmtctx.StmtExternalTSCacheKey, func() (interface{}, error) { + return variable.GetExternalTimestamp(ctx) + }) + + if err != nil { + return 0, errAsOf.FastGenWithCause(err.Error()) + } + return externalTimestamp.(uint64), nil +} diff --git a/sessiontxn/txn_context_test.go b/sessiontxn/txn_context_test.go index 726782fe30088..7ecd85a1db982 100644 --- a/sessiontxn/txn_context_test.go +++ b/sessiontxn/txn_context_test.go @@ -40,6 +40,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/txnkv/transaction.keepAlive"), diff --git a/sessiontxn/txn_rc_tso_optimize_test.go b/sessiontxn/txn_rc_tso_optimize_test.go index 59bbf0de330bc..3e945778ca107 100644 --- a/sessiontxn/txn_rc_tso_optimize_test.go +++ b/sessiontxn/txn_rc_tso_optimize_test.go @@ -105,7 +105,7 @@ func TestRcTSOCmdCountForPrepareExecuteNormal(t *testing.T) { tk.MustExec("commit") } countTsoRequest, countTsoUseConstant, countWaitTsoOracle := getAllTsoCounter(sctx) - require.Equal(t, uint64(398), countTsoRequest.(uint64)) + require.Equal(t, uint64(496), countTsoRequest.(uint64)) require.Equal(t, uint64(594), countTsoUseConstant.(uint64)) require.Equal(t, uint64(198), countWaitTsoOracle.(uint64)) @@ -137,7 +137,7 @@ func TestRcTSOCmdCountForPrepareExecuteNormal(t *testing.T) { tk.MustExec("commit") } count := sctx.Value(sessiontxn.TsoRequestCount) - require.Equal(t, uint64(594), count) + require.Equal(t, uint64(693), count) } func TestRcTSOCmdCountForPrepareExecuteExtra(t *testing.T) { @@ -234,7 +234,7 @@ func TestRcTSOCmdCountForPrepareExecuteExtra(t *testing.T) { tk.MustExec("commit") } countTsoRequest, countTsoUseConstant, countWaitTsoOracle = getAllTsoCounter(sctx) - require.Equal(t, uint64(16), countTsoRequest.(uint64)) + require.Equal(t, uint64(20), countTsoRequest.(uint64)) require.Equal(t, uint64(5), countTsoUseConstant.(uint64)) require.Equal(t, uint64(5), countWaitTsoOracle.(uint64)) @@ -412,7 +412,7 @@ func TestRcTSOCmdCountForPrepareExecuteExtra(t *testing.T) { require.Nil(t, stmt) tk.MustExec("commit") countTsoRequest, countTsoUseConstant, countWaitTsoOracle = getAllTsoCounter(sctx) - require.Equal(t, uint64(3), countTsoRequest.(uint64)) + require.Equal(t, uint64(4), countTsoRequest.(uint64)) require.Equal(t, uint64(2), countTsoUseConstant.(uint64)) require.Equal(t, 0, countWaitTsoOracle.(int)) tk.MustQuery("SELECT * FROM t1 WHERE id1 = 1").Check(testkit.Rows("1 1 1")) @@ -790,3 +790,32 @@ func TestConflictErrorsUseRcWriteCheckTs(t *testing.T) { require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/assertPessimisticLockErr")) } + +func TestRcWaitTSInSlowLog(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("set global transaction_isolation = 'READ-COMMITTED'") + tk.RefreshSession() + sctx := tk.Session() + + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(id1 int, id2 int, id3 int, PRIMARY KEY(id1), UNIQUE KEY udx_id2 (id2))") + tk.MustExec("insert into t1 values (1, 1, 1), (2, 2, 2), (3, 3, 3)") + + res := tk.MustQuery("show variables like 'transaction_isolation'") + require.Equal(t, "READ-COMMITTED", res.Rows()[0][1]) + sctx.SetValue(sessiontxn.TsoRequestCount, 0) + + tk.MustExec("begin pessimistic") + waitTs1 := sctx.GetSessionVars().DurationWaitTS + tk.MustExec("update t1 set id3 = id3 + 10 where id1 = 1") + waitTs2 := sctx.GetSessionVars().DurationWaitTS + tk.MustExec("update t1 set id3 = id3 + 10 where id1 > 3 and id1 < 6") + waitTs3 := sctx.GetSessionVars().DurationWaitTS + tk.MustExec("commit") + require.NotEqual(t, waitTs1, waitTs2) + require.NotEqual(t, waitTs1, waitTs2) + require.NotEqual(t, waitTs2, waitTs3) +} diff --git a/statistics/BUILD.bazel b/statistics/BUILD.bazel index 654c1a56cb602..e6992020197c3 100644 --- a/statistics/BUILD.bazel +++ b/statistics/BUILD.bazel @@ -13,6 +13,7 @@ go_library( "fmsketch.go", "histogram.go", "index.go", + "merge_worker.go", "row_sampler.go", "sample.go", "scalar.go", @@ -41,6 +42,7 @@ go_library( "//util/chunk", "//util/codec", "//util/collate", + "//util/dbterror", "//util/fastrand", "//util/hack", "//util/logutil", @@ -110,6 +112,7 @@ go_test( "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_log//:log", "@com_github_stretchr_testify//require", + "@org_golang_x_exp//slices", "@org_uber_go_goleak//:goleak", "@org_uber_go_zap//:zap", ], diff --git a/statistics/cmsketch.go b/statistics/cmsketch.go index 848a10a653325..31a31db9195c3 100644 --- a/statistics/cmsketch.go +++ b/statistics/cmsketch.go @@ -21,15 +21,19 @@ import ( "reflect" "sort" "strings" + "sync/atomic" + "time" "github.com/pingcap/errors" "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tipb/go-tipb" @@ -40,6 +44,11 @@ import ( // topNThreshold is the minimum ratio of the number of topn elements in CMSketch, 10 means 1 / 10 = 10%. const topNThreshold = uint64(10) +var ( + // ErrQueryInterrupted indicates interrupted + ErrQueryInterrupted = dbterror.ClassExecutor.NewStd(mysql.ErrQueryInterrupted) +) + // CMSketch is used to estimate point queries. // Refer: https://en.wikipedia.org/wiki/Count-min_sketch type CMSketch struct { @@ -729,7 +738,8 @@ func NewTopN(n int) *TopN { // 1. `*TopN` is the final global-level topN. // 2. `[]TopNMeta` is the left topN value from the partition-level TopNs, but is not placed to global-level TopN. We should put them back to histogram latter. // 3. `[]*Histogram` are the partition-level histograms which just delete some values when we merge the global-level topN. -func MergePartTopN2GlobalTopN(sc *stmtctx.StatementContext, version int, topNs []*TopN, n uint32, hists []*Histogram, isIndex bool) (*TopN, []TopNMeta, []*Histogram, error) { +func MergePartTopN2GlobalTopN(loc *time.Location, version int, topNs []*TopN, n uint32, hists []*Histogram, + isIndex bool, kiiled *uint32) (*TopN, []TopNMeta, []*Histogram, error) { if checkEmptyTopNs(topNs) { return nil, nil, hists, nil } @@ -750,6 +760,9 @@ func MergePartTopN2GlobalTopN(sc *stmtctx.StatementContext, version int, topNs [ // The datum is used to find the value in the histogram. datumMap := make(map[hack.MutableString]types.Datum) for i, topN := range topNs { + if atomic.LoadUint32(kiiled) == 1 { + return nil, nil, nil, errors.Trace(ErrQueryInterrupted) + } if topN.TotalCount() == 0 { continue } @@ -781,7 +794,7 @@ func MergePartTopN2GlobalTopN(sc *stmtctx.StatementContext, version int, topNs [ var err error if types.IsTypeTime(hists[0].Tp.GetType()) { // handle datetime values specially since they are encoded to int and we'll get int values if using DecodeOne. - _, d, err = codec.DecodeAsDateTime(val.Encoded, hists[0].Tp.GetType(), sc.TimeZone) + _, d, err = codec.DecodeAsDateTime(val.Encoded, hists[0].Tp.GetType(), loc) } else if types.IsTypeFloat(hists[0].Tp.GetType()) { _, d, err = codec.DecodeAsFloat32(val.Encoded, hists[0].Tp.GetType()) } else { @@ -866,6 +879,22 @@ func checkEmptyTopNs(topNs []*TopN) bool { return count == 0 } +// SortTopnMeta sort topnMeta +func SortTopnMeta(topnMetas []TopNMeta) []TopNMeta { + slices.SortFunc(topnMetas, func(i, j TopNMeta) bool { + if i.Count != j.Count { + return i.Count > j.Count + } + return bytes.Compare(i.Encoded, j.Encoded) < 0 + }) + return topnMetas +} + +// GetMergedTopNFromSortedSlice returns merged topn +func GetMergedTopNFromSortedSlice(sorted []TopNMeta, n uint32) (*TopN, []TopNMeta) { + return getMergedTopNFromSortedSlice(sorted, n) +} + func getMergedTopNFromSortedSlice(sorted []TopNMeta, n uint32) (*TopN, []TopNMeta) { slices.SortFunc(sorted, func(i, j TopNMeta) bool { if i.Count != j.Count { diff --git a/statistics/column.go b/statistics/column.go index 197fc2f5a6794..5ce06b5917854 100644 --- a/statistics/column.go +++ b/statistics/column.go @@ -121,9 +121,6 @@ func (c *Column) IsInvalid(sctx sessionctx.Context, collPseudo bool) bool { } if sctx != nil { stmtctx := sctx.GetSessionVars().StmtCtx - if stmtctx != nil && stmtctx.StatsLoad.Fallback { - return true - } if c.IsLoadNeeded() && stmtctx != nil { if stmtctx.StatsLoad.Timeout > 0 { logutil.BgLogger().Warn("Hist for column should already be loaded as sync but not found.", @@ -141,11 +138,6 @@ func (c *Column) IsInvalid(sctx sessionctx.Context, collPseudo bool) bool { return c.TotalRowCount() == 0 || (!c.IsEssentialStatsLoaded() && c.Histogram.NDV > 0) } -// IsHistNeeded checks if this column needs histogram to be loaded -func (c *Column) IsHistNeeded(collPseudo bool) bool { - return (!collPseudo || !c.NotAccurate()) && c.IsLoadNeeded() -} - func (c *Column) equalRowCount(sctx sessionctx.Context, val types.Datum, encodedVal []byte, realtimeRowCount int64) (float64, error) { if val.IsNull() { return float64(c.NullCount), nil @@ -192,7 +184,7 @@ func (c *Column) equalRowCount(sctx sessionctx.Context, val types.Datum, encoded } // GetColumnRowCount estimates the row count by a slice of Range. -func (c *Column) GetColumnRowCount(sctx sessionctx.Context, ranges []*ranger.Range, realtimeRowCount int64, pkIsHandle bool) (float64, error) { +func (c *Column) GetColumnRowCount(sctx sessionctx.Context, ranges []*ranger.Range, realtimeRowCount, modifyCount int64, pkIsHandle bool) (float64, error) { sc := sctx.GetSessionVars().StmtCtx var rowCount float64 for _, rg := range ranges { @@ -289,11 +281,7 @@ func (c *Column) GetColumnRowCount(sctx sessionctx.Context, ranges []*ranger.Ran // handling the out-of-range part if (c.outOfRange(lowVal) && !lowVal.IsNull()) || c.outOfRange(highVal) { - increaseCount := realtimeRowCount - int64(c.TotalRowCount()) - if increaseCount < 0 { - increaseCount = 0 - } - cnt += c.Histogram.outOfRangeRowCount(&lowVal, &highVal, increaseCount) + cnt += c.Histogram.outOfRangeRowCount(&lowVal, &highVal, modifyCount) } rowCount += cnt diff --git a/statistics/feedback.go b/statistics/feedback.go index ba056d7fe39aa..910d44167a1b0 100644 --- a/statistics/feedback.go +++ b/statistics/feedback.go @@ -82,7 +82,7 @@ func NewQueryFeedback(physicalID int64, hist *Histogram, expected int64, desc bo Expected: expected, desc: desc, } - rs.Valid.Store(true) + rs.Valid.Store(FeedbackProbability.Load() > 0) return rs } diff --git a/statistics/handle/BUILD.bazel b/statistics/handle/BUILD.bazel index bcafe4260eb30..d52847495d539 100644 --- a/statistics/handle/BUILD.bazel +++ b/statistics/handle/BUILD.bazel @@ -9,6 +9,7 @@ go_library( "gc.go", "handle.go", "handle_hist.go", + "historical_stats_handler.go", "lru_cache.go", "statscache.go", "update.go", @@ -41,6 +42,7 @@ go_library( "//util/memory", "//util/ranger", "//util/sqlexec", + "//util/syncutil", "//util/timeutil", "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", @@ -71,6 +73,7 @@ go_test( ], embed = [":handle"], flaky = True, + race = "on", shard_count = 50, deps = [ "//config", diff --git a/statistics/handle/bootstrap.go b/statistics/handle/bootstrap.go index 4aaeb05cf8c53..05e971488b360 100644 --- a/statistics/handle/bootstrap.go +++ b/statistics/handle/bootstrap.go @@ -63,7 +63,7 @@ func (h *Handle) initStatsMeta4Chunk(is infoschema.InfoSchema, cache *statsCache func (h *Handle) initStatsMeta(is infoschema.InfoSchema) (statsCache, error) { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) sql := "select HIGH_PRIORITY version, table_id, modify_count, count from mysql.stats_meta" - rc, err := h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) + rc, err := h.initStatsCtx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) if err != nil { return statsCache{}, errors.Trace(err) } @@ -167,7 +167,7 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, cache *stat func (h *Handle) initStatsHistograms(is infoschema.InfoSchema, cache *statsCache) error { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) sql := "select HIGH_PRIORITY table_id, is_index, hist_id, distinct_count, version, null_count, cm_sketch, tot_col_size, stats_ver, correlation, flag, last_analyze_pos from mysql.stats_histograms" - rc, err := h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) + rc, err := h.initStatsCtx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) if err != nil { return errors.Trace(err) } @@ -214,7 +214,7 @@ func (h *Handle) initStatsTopN4Chunk(cache *statsCache, iter *chunk.Iterator4Chu func (h *Handle) initStatsTopN(cache *statsCache) error { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) sql := "select HIGH_PRIORITY table_id, hist_id, value, count from mysql.stats_top_n where is_index = 1" - rc, err := h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) + rc, err := h.initStatsCtx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) if err != nil { return errors.Trace(err) } @@ -263,7 +263,7 @@ func (h *Handle) initStatsFMSketch4Chunk(cache *statsCache, iter *chunk.Iterator func (h *Handle) initStatsFMSketch(cache *statsCache) error { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) sql := "select HIGH_PRIORITY table_id, is_index, hist_id, value from mysql.stats_fm_sketch" - rc, err := h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) + rc, err := h.initStatsCtx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) if err != nil { return errors.Trace(err) } @@ -357,7 +357,7 @@ func (h *Handle) initTopNCountSum(tableID, colID int64) (int64, error) { func (h *Handle) initStatsBuckets(cache *statsCache) error { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) sql := "select HIGH_PRIORITY table_id, is_index, hist_id, count, repeats, lower_bound, upper_bound, ndv from mysql.stats_buckets order by table_id, is_index, hist_id, bucket_id" - rc, err := h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) + rc, err := h.initStatsCtx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql) if err != nil { return errors.Trace(err) } @@ -398,15 +398,13 @@ func (h *Handle) initStatsBuckets(cache *statsCache) error { func (h *Handle) InitStats(is infoschema.InfoSchema) (err error) { loadFMSketch := config.GetGlobalConfig().Performance.EnableLoadFMSketch ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) - h.mu.Lock() defer func() { - _, err1 := h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, "commit") + _, err1 := h.initStatsCtx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, "commit") if err == nil && err1 != nil { err = err1 } - h.mu.Unlock() }() - _, err = h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, "begin") + _, err = h.initStatsCtx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, "begin") if err != nil { return err } @@ -446,17 +444,6 @@ func (h *Handle) InitStats(is infoschema.InfoSchema) (err error) { } cache.FreshMemUsage() h.updateStatsCache(cache) - v := h.statsCache.Load() - if v == nil { - return nil - } - healthyChange := &statsHealthyChange{} - for _, tbl := range v.(statsCache).Values() { - if healthy, ok := tbl.GetStatsHealthy(); ok { - healthyChange.add(healthy) - } - } - healthyChange.apply() return nil } diff --git a/statistics/handle/ddl.go b/statistics/handle/ddl.go index 88f59fbd3da02..ed09b2d5660c3 100644 --- a/statistics/handle/ddl.go +++ b/statistics/handle/ddl.go @@ -61,6 +61,21 @@ func (h *Handle) HandleDDLEvent(t *util.Event) error { return err } } + case model.ActionReorganizePartition: + for _, def := range t.PartInfo.Definitions { + // TODO: Should we trigger analyze instead of adding 0s? + if err := h.insertTableStats2KV(t.TableInfo, def.ID); err != nil { + return err + } + } + // Update global stats, even though it should not have changed, + // the updated statistics from the newly reorganized partitions may be better + pruneMode := h.CurrentPruneMode() + if pruneMode == variable.Dynamic && t.PartInfo != nil { + if err := h.updateGlobalStats(t.TableInfo); err != nil { + return err + } + } case model.ActionFlashbackCluster: return h.updateStatsVersion() } @@ -156,7 +171,8 @@ func (h *Handle) updateGlobalStats(tblInfo *model.TableInfo) error { for i := 0; i < newColGlobalStats.Num; i++ { hg, cms, topN := newColGlobalStats.Hg[i], newColGlobalStats.Cms[i], newColGlobalStats.TopN[i] // fms for global stats doesn't need to dump to kv. - err = h.SaveStatsToStorage(tableID, newColGlobalStats.Count, 0, hg, cms, topN, 2, 1, false) + err = h.SaveStatsToStorage(tableID, newColGlobalStats.Count, newColGlobalStats.ModifyCount, + 0, hg, cms, topN, 2, 1, false, StatsMetaHistorySourceSchemaChange) if err != nil { return err } @@ -186,7 +202,7 @@ func (h *Handle) updateGlobalStats(tblInfo *model.TableInfo) error { for i := 0; i < newIndexGlobalStats.Num; i++ { hg, cms, topN := newIndexGlobalStats.Hg[i], newIndexGlobalStats.Cms[i], newIndexGlobalStats.TopN[i] // fms for global stats doesn't need to dump to kv. - err = h.SaveStatsToStorage(tableID, newIndexGlobalStats.Count, 1, hg, cms, topN, 2, 1, false) + err = h.SaveStatsToStorage(tableID, newIndexGlobalStats.Count, newIndexGlobalStats.ModifyCount, 1, hg, cms, topN, 2, 1, false, StatsMetaHistorySourceSchemaChange) if err != nil { return err } @@ -221,7 +237,7 @@ func (h *Handle) insertTableStats2KV(info *model.TableInfo, physicalID int64) (e statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(physicalID, statsVer) + h.recordHistoricalStatsMeta(physicalID, statsVer, StatsMetaHistorySourceSchemaChange) } }() h.mu.Lock() @@ -263,7 +279,7 @@ func (h *Handle) insertColStats2KV(physicalID int64, colInfos []*model.ColumnInf statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(physicalID, statsVer) + h.recordHistoricalStatsMeta(physicalID, statsVer, StatsMetaHistorySourceSchemaChange) } }() h.mu.Lock() diff --git a/statistics/handle/dump.go b/statistics/handle/dump.go index 5216622dc9a35..81e982881ee83 100644 --- a/statistics/handle/dump.go +++ b/statistics/handle/dump.go @@ -18,19 +18,24 @@ import ( "bytes" "compress/gzip" "encoding/json" - "io/ioutil" + "fmt" + "io" "time" "github.com/pingcap/errors" "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tipb/go-tipb" + "go.uber.org/zap" ) // JSONTable is used for dumping statistics. @@ -43,6 +48,7 @@ type JSONTable struct { Count int64 `json:"count"` ModifyCount int64 `json:"modify_count"` Partitions map[string]*JSONTable `json:"partitions"` + Version uint64 `json:"version"` } type jsonExtendedStats struct { @@ -119,20 +125,34 @@ func dumpJSONCol(hist *statistics.Histogram, CMSketch *statistics.CMSketch, topn } // DumpStatsToJSON dumps statistic to json. -func (h *Handle) DumpStatsToJSON(dbName string, tableInfo *model.TableInfo, historyStatsExec sqlexec.RestrictedSQLExecutor) (*JSONTable, error) { +func (h *Handle) DumpStatsToJSON(dbName string, tableInfo *model.TableInfo, + historyStatsExec sqlexec.RestrictedSQLExecutor, dumpPartitionStats bool) (*JSONTable, error) { var snapshot uint64 if historyStatsExec != nil { sctx := historyStatsExec.(sessionctx.Context) snapshot = sctx.GetSessionVars().SnapshotTS } - return h.DumpStatsToJSONBySnapshot(dbName, tableInfo, snapshot) + return h.DumpStatsToJSONBySnapshot(dbName, tableInfo, snapshot, dumpPartitionStats) } -// DumpStatsToJSONBySnapshot dumps statistic to json. -func (h *Handle) DumpStatsToJSONBySnapshot(dbName string, tableInfo *model.TableInfo, snapshot uint64) (*JSONTable, error) { +var ( + dumpHistoricalStatsSuccessCounter = metrics.HistoricalStatsCounter.WithLabelValues("dump", "success") + dumpHistoricalStatsFailedCounter = metrics.HistoricalStatsCounter.WithLabelValues("dump", "fail") +) + +// DumpHistoricalStatsBySnapshot dumped json tables from mysql.stats_meta_history and mysql.stats_history +func (h *Handle) DumpHistoricalStatsBySnapshot(dbName string, tableInfo *model.TableInfo, snapshot uint64) (jt *JSONTable, err error) { + defer func() { + if err == nil { + dumpHistoricalStatsSuccessCounter.Inc() + } else { + dumpHistoricalStatsFailedCounter.Inc() + } + }() + pi := tableInfo.GetPartitionInfo() if pi == nil { - return h.tableStatsToJSON(dbName, tableInfo, tableInfo.ID, snapshot) + return h.tableHistoricalStatsToJSON(tableInfo.ID, snapshot) } jsonTbl := &JSONTable{ DatabaseName: dbName, @@ -140,7 +160,7 @@ func (h *Handle) DumpStatsToJSONBySnapshot(dbName string, tableInfo *model.Table Partitions: make(map[string]*JSONTable, len(pi.Definitions)), } for _, def := range pi.Definitions { - tbl, err := h.tableStatsToJSON(dbName, tableInfo, def.ID, snapshot) + tbl, err := h.tableHistoricalStatsToJSON(def.ID, snapshot) if err != nil { return nil, errors.Trace(err) } @@ -149,6 +169,49 @@ func (h *Handle) DumpStatsToJSONBySnapshot(dbName string, tableInfo *model.Table } jsonTbl.Partitions[def.Name.L] = tbl } + h.mu.Lock() + isDynamicMode := variable.PartitionPruneMode(h.mu.ctx.GetSessionVars().PartitionPruneMode.Load()) == variable.Dynamic + h.mu.Unlock() + if isDynamicMode { + tbl, err := h.tableHistoricalStatsToJSON(tableInfo.ID, snapshot) + if err != nil { + logutil.BgLogger().Warn("dump global historical stats failed", + zap.Int64("table-id", tableInfo.ID), + zap.String("table-name", tableInfo.Name.String())) + } else if tbl != nil { + jsonTbl.Partitions["global"] = tbl + } + } + return jsonTbl, nil +} + +// DumpStatsToJSONBySnapshot dumps statistic to json. +func (h *Handle) DumpStatsToJSONBySnapshot(dbName string, tableInfo *model.TableInfo, snapshot uint64, dumpPartitionStats bool) (*JSONTable, error) { + h.mu.Lock() + isDynamicMode := variable.PartitionPruneMode(h.mu.ctx.GetSessionVars().PartitionPruneMode.Load()) == variable.Dynamic + h.mu.Unlock() + pi := tableInfo.GetPartitionInfo() + if pi == nil { + return h.tableStatsToJSON(dbName, tableInfo, tableInfo.ID, snapshot) + } + jsonTbl := &JSONTable{ + DatabaseName: dbName, + TableName: tableInfo.Name.L, + Partitions: make(map[string]*JSONTable, len(pi.Definitions)), + } + // dump partition stats only if in static mode or enable dumpPartitionStats flag in dynamic mode + if !isDynamicMode || dumpPartitionStats { + for _, def := range pi.Definitions { + tbl, err := h.tableStatsToJSON(dbName, tableInfo, def.ID, snapshot) + if err != nil { + return nil, errors.Trace(err) + } + if tbl == nil { + continue + } + jsonTbl.Partitions[def.Name.L] = tbl + } + } // dump its global-stats if existed tbl, err := h.tableStatsToJSON(dbName, tableInfo, tableInfo.ID, snapshot) if err != nil { @@ -160,15 +223,8 @@ func (h *Handle) DumpStatsToJSONBySnapshot(dbName string, tableInfo *model.Table return jsonTbl, nil } -func (h *Handle) tableStatsToJSON(dbName string, tableInfo *model.TableInfo, physicalID int64, snapshot uint64) (*JSONTable, error) { - tbl, err := h.TableStatsFromStorage(tableInfo, physicalID, true, snapshot) - if err != nil || tbl == nil { - return nil, err - } - tbl.Version, tbl.ModifyCount, tbl.Count, err = h.statsMetaByTableIDFromStorage(physicalID, snapshot) - if err != nil { - return nil, err - } +// GenJSONTableFromStats generate jsonTable from tableInfo and stats +func GenJSONTableFromStats(dbName string, tableInfo *model.TableInfo, tbl *statistics.Table) (*JSONTable, error) { jsonTbl := &JSONTable{ DatabaseName: dbName, TableName: tableInfo.Name.L, @@ -176,8 +232,8 @@ func (h *Handle) tableStatsToJSON(dbName string, tableInfo *model.TableInfo, phy Indices: make(map[string]*jsonColumn, len(tbl.Indices)), Count: tbl.Count, ModifyCount: tbl.ModifyCount, + Version: tbl.Version, } - for _, col := range tbl.Columns { sc := &stmtctx.StatementContext{TimeZone: time.UTC} hist, err := col.ConvertTo(sc, types.NewFieldType(mysql.TypeBlob)) @@ -194,6 +250,78 @@ func (h *Handle) tableStatsToJSON(dbName string, tableInfo *model.TableInfo, phy return jsonTbl, nil } +func (h *Handle) tableHistoricalStatsToJSON(physicalID int64, snapshot uint64) (*JSONTable, error) { + reader, err := h.getGlobalStatsReader(0) + if err != nil { + return nil, err + } + defer func() { + err1 := h.releaseGlobalStatsReader(reader) + if err == nil && err1 != nil { + err = err1 + } + }() + + // get meta version + rows, _, err := reader.read("select distinct version from mysql.stats_meta_history where table_id = %? and version <= %? order by version desc limit 1", physicalID, snapshot) + if err != nil { + return nil, errors.AddStack(err) + } + if len(rows) < 1 { + return nil, fmt.Errorf("failed to get records of stats_meta_history for table_id = %v, snapshot = %v", physicalID, snapshot) + } + statsMetaVersion := rows[0].GetInt64(0) + // get stats meta + rows, _, err = reader.read("select modify_count, count from mysql.stats_meta_history where table_id = %? and version = %?", physicalID, statsMetaVersion) + if err != nil { + return nil, errors.AddStack(err) + } + modifyCount, count := rows[0].GetInt64(0), rows[0].GetInt64(1) + + // get stats version + rows, _, err = reader.read("select distinct version from mysql.stats_history where table_id = %? and version <= %? order by version desc limit 1", physicalID, snapshot) + if err != nil { + return nil, errors.AddStack(err) + } + if len(rows) < 1 { + return nil, fmt.Errorf("failed to get record of stats_history for table_id = %v, snapshot = %v", physicalID, snapshot) + } + statsVersion := rows[0].GetInt64(0) + + // get stats + rows, _, err = reader.read("select stats_data from mysql.stats_history where table_id = %? and version = %? order by seq_no", physicalID, statsVersion) + if err != nil { + return nil, errors.AddStack(err) + } + blocks := make([][]byte, 0) + for _, row := range rows { + blocks = append(blocks, row.GetBytes(0)) + } + jsonTbl, err := BlocksToJSONTable(blocks) + if err != nil { + return nil, errors.AddStack(err) + } + jsonTbl.Count = count + jsonTbl.ModifyCount = modifyCount + return jsonTbl, nil +} + +func (h *Handle) tableStatsToJSON(dbName string, tableInfo *model.TableInfo, physicalID int64, snapshot uint64) (*JSONTable, error) { + tbl, err := h.TableStatsFromStorage(tableInfo, physicalID, true, snapshot) + if err != nil || tbl == nil { + return nil, err + } + tbl.Version, tbl.ModifyCount, tbl.Count, err = h.statsMetaByTableIDFromStorage(physicalID, snapshot) + if err != nil { + return nil, err + } + jsonTbl, err := GenJSONTableFromStats(dbName, tableInfo, tbl) + if err != nil { + return nil, err + } + return jsonTbl, nil +} + // LoadStatsFromJSON will load statistic from JSONTable, and save it to the storage. func (h *Handle) LoadStatsFromJSON(is infoschema.InfoSchema, jsonTbl *JSONTable) error { table, err := is.TableByName(model.NewCIStr(jsonTbl.DatabaseName), model.NewCIStr(jsonTbl.TableName)) @@ -236,14 +364,18 @@ func (h *Handle) loadStatsFromJSON(tableInfo *model.TableInfo, physicalID int64, for _, col := range tbl.Columns { // loadStatsFromJSON doesn't support partition table now. - err = h.SaveStatsToStorage(tbl.PhysicalID, tbl.Count, 0, &col.Histogram, col.CMSketch, col.TopN, int(col.StatsVer), 1, false) + // The table level Count and Modify_count would be overridden by the SaveMetaToStorage below, so we don't need + // to care about them here. + err = h.SaveStatsToStorage(tbl.PhysicalID, tbl.Count, 0, 0, &col.Histogram, col.CMSketch, col.TopN, int(col.StatsVer), 1, false, StatsMetaHistorySourceLoadStats) if err != nil { return errors.Trace(err) } } for _, idx := range tbl.Indices { // loadStatsFromJSON doesn't support partition table now. - err = h.SaveStatsToStorage(tbl.PhysicalID, tbl.Count, 1, &idx.Histogram, idx.CMSketch, idx.TopN, int(idx.StatsVer), 1, false) + // The table level Count and Modify_count would be overridden by the SaveMetaToStorage below, so we don't need + // to care about them here. + err = h.SaveStatsToStorage(tbl.PhysicalID, tbl.Count, 0, 1, &idx.Histogram, idx.CMSketch, idx.TopN, int(idx.StatsVer), 1, false, StatsMetaHistorySourceLoadStats) if err != nil { return errors.Trace(err) } @@ -252,7 +384,7 @@ func (h *Handle) loadStatsFromJSON(tableInfo *model.TableInfo, physicalID int64, if err != nil { return errors.Trace(err) } - return h.SaveMetaToStorage(tbl.PhysicalID, tbl.Count, tbl.ModifyCount) + return h.SaveMetaToStorage(tbl.PhysicalID, tbl.Count, tbl.ModifyCount, StatsMetaHistorySourceLoadStats) } // TableStatsFromJSON loads statistic from JSONTable and return the Table of statistic. @@ -388,7 +520,7 @@ func BlocksToJSONTable(blocks [][]byte) (*JSONTable, error) { if err := gzipReader.Close(); err != nil { return nil, err } - jsonStr, err := ioutil.ReadAll(gzipReader) + jsonStr, err := io.ReadAll(gzipReader) if err != nil { return nil, errors.Trace(err) } diff --git a/statistics/handle/dump_test.go b/statistics/handle/dump_test.go index 0e3006604e5cc..165ea999ae25a 100644 --- a/statistics/handle/dump_test.go +++ b/statistics/handle/dump_test.go @@ -90,7 +90,7 @@ func TestConversion(t *testing.T) { tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) - jsonTbl, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil) + jsonTbl, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil, true) require.NoError(t, err) loadTbl, err := handle.TableStatsFromJSON(tableInfo.Meta(), tableInfo.Meta().ID, jsonTbl) require.NoError(t, err) @@ -117,7 +117,7 @@ func getStatsJSON(t *testing.T, dom *domain.Domain, db, tableName string) *handl table, err := is.TableByName(model.NewCIStr(db), model.NewCIStr(tableName)) require.NoError(t, err) tableInfo := table.Meta() - jsonTbl, err := h.DumpStatsToJSON("test", tableInfo, nil) + jsonTbl, err := h.DumpStatsToJSON("test", tableInfo, nil, true) require.NoError(t, err) return jsonTbl } @@ -198,7 +198,7 @@ PARTITION BY RANGE ( a ) ( table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) tableInfo := table.Meta() - jsonTbl, err := h.DumpStatsToJSON("test", tableInfo, nil) + jsonTbl, err := h.DumpStatsToJSON("test", tableInfo, nil, true) require.NoError(t, err) pi := tableInfo.GetPartitionInfo() originTables := make([]*statistics.Table, 0, len(pi.Definitions)) @@ -233,7 +233,7 @@ func TestDumpAlteredTable(t *testing.T) { tk.MustExec("alter table t drop column a") table, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) - _, err = h.DumpStatsToJSON("test", table.Meta(), nil) + _, err = h.DumpStatsToJSON("test", table.Meta(), nil, true) require.NoError(t, err) } @@ -261,7 +261,7 @@ func TestDumpCMSketchWithTopN(t *testing.T) { cms, _, _, _ := statistics.NewCMSketchAndTopN(5, 2048, fakeData, 20, 100) stat := h.GetTableStats(tableInfo) - err = h.SaveStatsToStorage(tableInfo.ID, 1, 0, &stat.Columns[tableInfo.Columns[0].ID].Histogram, cms, nil, statistics.Version2, 1, false) + err = h.SaveStatsToStorage(tableInfo.ID, 1, 0, 0, &stat.Columns[tableInfo.Columns[0].ID].Histogram, cms, nil, statistics.Version2, 1, false, handle.StatsMetaHistorySourceLoadStats) require.NoError(t, err) require.Nil(t, h.Update(is)) @@ -270,7 +270,7 @@ func TestDumpCMSketchWithTopN(t *testing.T) { require.NotNil(t, cmsFromStore) require.True(t, cms.Equal(cmsFromStore)) - jsonTable, err := h.DumpStatsToJSON("test", tableInfo, nil) + jsonTable, err := h.DumpStatsToJSON("test", tableInfo, nil, true) require.NoError(t, err) err = h.LoadStatsFromJSON(is, jsonTable) require.NoError(t, err) @@ -292,7 +292,7 @@ func TestDumpPseudoColumns(t *testing.T) { tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) h := dom.StatsHandle() - _, err = h.DumpStatsToJSON("test", tbl.Meta(), nil) + _, err = h.DumpStatsToJSON("test", tbl.Meta(), nil, true) require.NoError(t, err) } @@ -313,7 +313,7 @@ func TestDumpExtendedStats(t *testing.T) { tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) tbl := h.GetTableStats(tableInfo.Meta()) - jsonTbl, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil) + jsonTbl, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil, true) require.NoError(t, err) loadTbl, err := handle.TableStatsFromJSON(tableInfo.Meta(), tableInfo.Meta().ID, jsonTbl) require.NoError(t, err) @@ -353,7 +353,7 @@ func TestDumpVer2Stats(t *testing.T) { storageTbl, err := h.TableStatsFromStorage(tableInfo.Meta(), tableInfo.Meta().ID, false, 0) require.NoError(t, err) - dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil) + dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil, true) require.NoError(t, err) jsonBytes, err := json.MarshalIndent(dumpJSONTable, "", " ") @@ -405,7 +405,7 @@ func TestLoadStatsForNewCollation(t *testing.T) { storageTbl, err := h.TableStatsFromStorage(tableInfo.Meta(), tableInfo.Meta().ID, false, 0) require.NoError(t, err) - dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil) + dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil, true) require.NoError(t, err) jsonBytes, err := json.MarshalIndent(dumpJSONTable, "", " ") @@ -453,12 +453,12 @@ func TestJSONTableToBlocks(t *testing.T) { tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) - dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil) + dumpJSONTable, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil, true) require.NoError(t, err) jsOrigin, _ := json.Marshal(dumpJSONTable) blockSize := 30 - js, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil) + js, err := h.DumpStatsToJSON("test", tableInfo.Meta(), nil, true) require.NoError(t, err) dumpJSONBlocks, err := handle.JSONTableToBlocks(js, blockSize) require.NoError(t, err) diff --git a/statistics/handle/gc.go b/statistics/handle/gc.go index 1babb4321eb9e..f16e2c9719088 100644 --- a/statistics/handle/gc.go +++ b/statistics/handle/gc.go @@ -22,6 +22,9 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/sqlexec" @@ -50,6 +53,14 @@ func (h *Handle) GCStats(is infoschema.InfoSchema, ddlLease time.Duration) error if err := h.gcTableStats(is, row.GetInt64(0)); err != nil { return errors.Trace(err) } + if err := h.gcHistoryStatsFromKV(row.GetInt64(0)); err != nil { + return errors.Trace(err) + } + } + if err := h.ClearOutdatedHistoryStats(); err != nil { + logutil.BgLogger().Warn("failed to gc outdated historical stats", + zap.Duration("duration", variable.HistoricalStatsDuration.Load()), + zap.Error(err)) } return h.removeDeletedExtendedStats(gcVer) } @@ -138,6 +149,62 @@ func (h *Handle) gcTableStats(is infoschema.InfoSchema, physicalID int64) error return nil } +// ClearOutdatedHistoryStats clear outdated historical stats +func (h *Handle) ClearOutdatedHistoryStats() error { + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + h.mu.Lock() + defer h.mu.Unlock() + exec := h.mu.ctx.(sqlexec.SQLExecutor) + sql := "select count(*) from mysql.stats_meta_history where NOW() - create_time >= %?" + rs, err := exec.ExecuteInternal(ctx, sql, variable.HistoricalStatsDuration.Load().Seconds()) + if err != nil { + return err + } + if rs == nil { + return nil + } + var rows []chunk.Row + defer terror.Call(rs.Close) + if rows, err = sqlexec.DrainRecordSet(ctx, rs, 8); err != nil { + return errors.Trace(err) + } + count := rows[0].GetInt64(0) + if count > 0 { + sql = "delete from mysql.stats_meta_history where NOW() - create_time >= %?" + _, err = exec.ExecuteInternal(ctx, sql, variable.HistoricalStatsDuration.Load().Seconds()) + if err != nil { + return err + } + sql = "delete from mysql.stats_history where NOW() - create_time >= %? " + _, err = exec.ExecuteInternal(ctx, sql, variable.HistoricalStatsDuration.Load().Seconds()) + logutil.BgLogger().Info("clear outdated historical stats") + return err + } + return nil +} + +func (h *Handle) gcHistoryStatsFromKV(physicalID int64) error { + h.mu.Lock() + defer h.mu.Unlock() + exec := h.mu.ctx.(sqlexec.SQLExecutor) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + _, err := exec.ExecuteInternal(ctx, "begin pessimistic") + if err != nil { + return errors.Trace(err) + } + defer func() { + err = finishTransaction(ctx, exec, err) + }() + sql := "delete from mysql.stats_history where table_id = %?" + _, err = exec.ExecuteInternal(ctx, sql, physicalID) + if err != nil { + return errors.Trace(err) + } + sql = "delete from mysql.stats_meta_history where table_id = %?" + _, err = exec.ExecuteInternal(ctx, sql, physicalID) + return err +} + // deleteHistStatsFromKV deletes all records about a column or an index and updates version. func (h *Handle) deleteHistStatsFromKV(physicalID int64, histID int64, isIndex int) (err error) { h.mu.Lock() diff --git a/statistics/handle/handle.go b/statistics/handle/handle.go index 00660c9756a68..fc4f86dc54fb8 100644 --- a/statistics/handle/handle.go +++ b/statistics/handle/handle.go @@ -15,6 +15,7 @@ package handle import ( + "bytes" "context" "encoding/json" "fmt" @@ -28,7 +29,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" - "github.com/pingcap/tidb/ddl/util" + ddlUtil "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" @@ -41,11 +42,13 @@ import ( "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/sqlexec" + "github.com/pingcap/tidb/util/syncutil" "github.com/prometheus/client_golang/prometheus" "github.com/tikv/client-go/v2/oracle" atomic2 "go.uber.org/atomic" @@ -56,15 +59,26 @@ import ( const ( // TiDBGlobalStats represents the global-stats for a partitioned table. TiDBGlobalStats = "global" + + // maxPartitionMergeBatchSize indicates the max batch size for a worker to merge partition stats + maxPartitionMergeBatchSize = 256 ) // Handle can update stats info periodically. type Handle struct { + + // initStatsCtx is the ctx only used for initStats + initStatsCtx sessionctx.Context + mu struct { - sync.RWMutex + syncutil.RWMutex ctx sessionctx.Context // rateMap contains the error rate delta from feedback. rateMap errorRateDeltaMap + } + + schemaMu struct { + sync.RWMutex // pid2tid is the map from partition ID to table ID. pid2tid map[int64]int64 // schemaVersion is the version of information schema when `pid2tid` is built. @@ -83,7 +97,7 @@ type Handle struct { // ddlEventCh is a channel to notify a ddl operation has happened. // It is sent only by owner or the drop stats executor, and read by stats handle. - ddlEventCh chan *util.Event + ddlEventCh chan *ddlUtil.Event // listHead contains all the stats collector required by session. listHead *SessionStatsCollector // globalMap contains all the delta map from collectors when we dump them to KV. @@ -114,6 +128,274 @@ type Handle struct { sysProcTracker sessionctx.SysProcTracker // serverIDGetter is used to get server ID for generating auto analyze ID. serverIDGetter func() uint64 + // tableLocked used to store locked tables + tableLocked []int64 +} + +// GetTableLockedAndClearForTest for unit test only +func (h *Handle) GetTableLockedAndClearForTest() []int64 { + tableLocked := h.tableLocked + h.tableLocked = make([]int64, 0) + return tableLocked +} + +// LoadLockedTables load locked tables from store +func (h *Handle) LoadLockedTables() error { + h.mu.Lock() + defer h.mu.Unlock() + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + rows, _, err := h.execRestrictedSQL(ctx, "select table_id from mysql.stats_table_locked") + if err != nil { + return errors.Trace(err) + } + + h.tableLocked = make([]int64, len(rows)) + for i, row := range rows { + h.tableLocked[i] = row.GetInt64(0) + } + + return nil +} + +// AddLockedTables add locked tables id to store +func (h *Handle) AddLockedTables(tids []int64, pids []int64, tables []*ast.TableName) (string, error) { + h.mu.Lock() + defer h.mu.Unlock() + + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + + exec := h.mu.ctx.(sqlexec.SQLExecutor) + + _, err := exec.ExecuteInternal(ctx, "begin pessimistic") + if err != nil { + return "", err + } + + //load tables to check duplicate when insert + rows, _, err := h.execRestrictedSQL(ctx, "select table_id from mysql.stats_table_locked") + if err != nil { + return "", err + } + + dupTables := make([]string, 0) + tableLocked := make([]int64, 0) + for _, row := range rows { + tableLocked = append(tableLocked, row.GetInt64(0)) + } + + strTids := fmt.Sprintf("%v", tids) + logutil.BgLogger().Info("[stats] lock table ", zap.String("tableIDs", strTids)) + for i, tid := range tids { + _, err = exec.ExecuteInternal(ctx, "insert into mysql.stats_table_locked(table_id) select %? from dual where not exists(select table_id from mysql.stats_table_locked where table_id = %?)", tid, tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when insert mysql.stats_table_locked ", zap.Error(err)) + return "", err + } + // update handle + if !isTableLocked(tableLocked, tid) { + tableLocked = append(tableLocked, tid) + } else { + dupTables = append(dupTables, tables[i].Schema.L+"."+tables[i].Name.L) + } + } + + //insert related partitions while don't warning duplicate partitions + for _, tid := range pids { + _, err = exec.ExecuteInternal(ctx, "insert into mysql.stats_table_locked(table_id) select %? from dual where not exists(select table_id from mysql.stats_table_locked where table_id = %?)", tid, tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when insert mysql.stats_table_locked ", zap.Error(err)) + return "", err + } + if !isTableLocked(tableLocked, tid) { + tableLocked = append(tableLocked, tid) + } + } + + err = finishTransaction(ctx, exec, err) + if err != nil { + return "", err + } + // update handle.tableLocked after transaction success, if txn failed, tableLocked won't be updated + h.tableLocked = tableLocked + + if len(dupTables) > 0 { + tables := dupTables[0] + for i, table := range dupTables { + if i == 0 { + continue + } + tables += ", " + table + } + var msg string + if len(tids) > 1 { + if len(tids) > len(dupTables) { + msg = "skip locking locked tables: " + tables + ", other tables locked successfully" + } else { + msg = "skip locking locked tables: " + tables + } + } else { + msg = "skip locking locked table: " + tables + } + return msg, err + } + return "", err +} + +// getStatsDeltaFromTableLocked get count, modify_count and version for the given table from mysql.stats_table_locked. +func (h *Handle) getStatsDeltaFromTableLocked(ctx context.Context, tableID int64) (int64, int64, uint64, error) { + rows, _, err := h.execRestrictedSQL(ctx, "select count, modify_count, version from mysql.stats_table_locked where table_id = %?", tableID) + if err != nil { + return 0, 0, 0, err + } + + if len(rows) == 0 { + return 0, 0, 0, nil + } + count := rows[0].GetInt64(0) + modifyCount := rows[0].GetInt64(1) + version := rows[0].GetUint64(2) + return count, modifyCount, version, nil +} + +// RemoveLockedTables remove tables from table locked array +func (h *Handle) RemoveLockedTables(tids []int64, pids []int64, tables []*ast.TableName) (string, error) { + h.mu.Lock() + defer h.mu.Unlock() + + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + + exec := h.mu.ctx.(sqlexec.SQLExecutor) + _, err := exec.ExecuteInternal(ctx, "begin pessimistic") + if err != nil { + return "", err + } + + //load tables to check unlock the unlock table + rows, _, err := h.execRestrictedSQL(ctx, "select table_id from mysql.stats_table_locked") + if err != nil { + return "", err + } + + nonlockedTables := make([]string, 0) + tableLocked := make([]int64, 0) + for _, row := range rows { + tableLocked = append(tableLocked, row.GetInt64(0)) + } + + strTids := fmt.Sprintf("%v", tids) + logutil.BgLogger().Info("[stats] unlock table ", zap.String("tableIDs", strTids)) + for i, tid := range tids { + // get stats delta during table locked + count, modifyCount, version, err := h.getStatsDeltaFromTableLocked(ctx, tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when getStatsDeltaFromTableLocked", zap.Error(err)) + return "", err + } + // update stats_meta with stats delta + _, err = exec.ExecuteInternal(ctx, "update mysql.stats_meta set version = %?, count = count + %?, modify_count = modify_count + %? where table_id = %?", version, count, modifyCount, tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when update mysql.stats_meta", zap.Error(err)) + return "", err + } + + _, err = exec.ExecuteInternal(ctx, "delete from mysql.stats_table_locked where table_id = %?", tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when delete from mysql.stats_table_locked ", zap.Error(err)) + return "", err + } + var exist bool + exist, tableLocked = removeIfTableLocked(tableLocked, tid) + if !exist { + nonlockedTables = append(nonlockedTables, tables[i].Schema.L+"."+tables[i].Name.L) + } + } + //delete related partitions while don't warning delete empty partitions + for _, tid := range pids { + // get stats delta during table locked + count, modifyCount, version, err := h.getStatsDeltaFromTableLocked(ctx, tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when getStatsDeltaFromTableLocked", zap.Error(err)) + return "", err + } + // update stats_meta with stats delta + _, err = exec.ExecuteInternal(ctx, "update mysql.stats_meta set version = %?, count = count + %?, modify_count = modify_count + %? where table_id = %?", version, count, modifyCount, tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when update mysql.stats_meta", zap.Error(err)) + return "", err + } + + _, err = exec.ExecuteInternal(ctx, "delete from mysql.stats_table_locked where table_id = %?", tid) + if err != nil { + logutil.BgLogger().Error("[stats] error occurred when delete from mysql.stats_table_locked ", zap.Error(err)) + return "", err + } + _, tableLocked = removeIfTableLocked(tableLocked, tid) + } + + err = finishTransaction(ctx, exec, err) + if err != nil { + return "", err + } + // update handle.tableLocked after transaction success, if txn failed, tableLocked won't be updated + h.tableLocked = tableLocked + + if len(nonlockedTables) > 0 { + tables := nonlockedTables[0] + for i, table := range nonlockedTables { + if i == 0 { + continue + } + tables += ", " + table + } + var msg string + if len(tids) > 1 { + if len(tids) > len(nonlockedTables) { + msg = "skip unlocking non-locked tables: " + tables + ", other tables unlocked successfully" + } else { + msg = "skip unlocking non-locked tables: " + tables + } + } else { + msg = "skip unlocking non-locked table: " + tables + } + return msg, err + } + return "", err +} + +// IsTableLocked check whether table is locked in handle with Handle.Mutex +func (h *Handle) IsTableLocked(tableID int64) bool { + h.mu.RLock() + defer h.mu.RUnlock() + return h.isTableLocked(tableID) +} + +// IsTableLocked check whether table is locked in handle without Handle.Mutex +func (h *Handle) isTableLocked(tableID int64) bool { + return isTableLocked(h.tableLocked, tableID) +} + +// isTableLocked check whether table is locked +func isTableLocked(tableLocked []int64, tableID int64) bool { + return lockTableIndexOf(tableLocked, tableID) > -1 +} + +// lockTableIndexOf get the locked table's index in the array +func lockTableIndexOf(tableLocked []int64, tableID int64) int { + for idx, id := range tableLocked { + if id == tableID { + return idx + } + } + return -1 +} + +// removeIfTableLocked try to remove the table from table locked array +func removeIfTableLocked(tableLocked []int64, tableID int64) (bool, []int64) { + idx := lockTableIndexOf(tableLocked, tableID) + if idx > -1 { + tableLocked = append(tableLocked[:idx], tableLocked[idx+1:]...) + } + return idx > -1, tableLocked } func (h *Handle) withRestrictedSQLExecutor(ctx context.Context, fn func(context.Context, sqlexec.RestrictedSQLExecutor) ([]chunk.Row, []*ast.ResultField, error)) ([]chunk.Row, []*ast.ResultField, error) { @@ -194,16 +476,17 @@ type sessionPool interface { } // NewHandle creates a Handle for update stats. -func NewHandle(ctx sessionctx.Context, lease time.Duration, pool sessionPool, tracker sessionctx.SysProcTracker, serverIDGetter func() uint64) (*Handle, error) { +func NewHandle(ctx, initStatsCtx sessionctx.Context, lease time.Duration, pool sessionPool, tracker sessionctx.SysProcTracker, serverIDGetter func() uint64) (*Handle, error) { cfg := config.GetGlobalConfig() handle := &Handle{ - ddlEventCh: make(chan *util.Event, 100), + ddlEventCh: make(chan *ddlUtil.Event, 1000), listHead: &SessionStatsCollector{mapper: make(tableDeltaMap), rateMap: make(errorRateDeltaMap)}, idxUsageListHead: &SessionIndexUsageCollector{mapper: make(indexUsageMap)}, pool: pool, sysProcTracker: tracker, serverIDGetter: serverIDGetter, } + handle.initStatsCtx = initStatsCtx handle.lease.Store(lease) handle.statsCache.memTracker = memory.NewTracker(memory.LabelForStatsCache, -1) handle.mu.ctx = ctx @@ -257,42 +540,32 @@ var statsHealthyGauges = []prometheus.Gauge{ metrics.StatsHealthyGauge.WithLabelValues("[0,100]"), } -type statsHealthyChange struct { - bucketDelta [5]int -} - -func (c *statsHealthyChange) update(add bool, statsHealthy int64) { - var idx int - if statsHealthy < 50 { - idx = 0 - } else if statsHealthy < 80 { - idx = 1 - } else if statsHealthy < 100 { - idx = 2 - } else { - idx = 3 - } - lastIDX := len(c.bucketDelta) - 1 - if add { - c.bucketDelta[idx]++ - c.bucketDelta[lastIDX]++ - } else { - c.bucketDelta[idx]-- - c.bucketDelta[lastIDX]-- +// UpdateStatsHealthyMetrics updates stats healthy distribution metrics according to stats cache. +func (h *Handle) UpdateStatsHealthyMetrics() { + v := h.statsCache.Load() + if v == nil { + return } -} - -func (c *statsHealthyChange) drop(statsHealthy int64) { - c.update(false, statsHealthy) -} - -func (c *statsHealthyChange) add(statsHealthy int64) { - c.update(true, statsHealthy) -} -func (c *statsHealthyChange) apply() { - for i, val := range c.bucketDelta { - statsHealthyGauges[i].Add(float64(val)) + distribution := make([]int64, 5) + for _, tbl := range v.(statsCache).Values() { + healthy, ok := tbl.GetStatsHealthy() + if !ok { + continue + } + if healthy < 50 { + distribution[0] += 1 + } else if healthy < 80 { + distribution[1] += 1 + } else if healthy < 100 { + distribution[2] += 1 + } else { + distribution[3] += 1 + } + distribution[4] += 1 + } + for i, val := range distribution { + statsHealthyGauges[i].Set(float64(val)) } } @@ -316,7 +589,6 @@ func (h *Handle) Update(is infoschema.InfoSchema, opts ...TableStatsOpt) error { if err != nil { return errors.Trace(err) } - healthyChange := &statsHealthyChange{} option := &tableStatsOption{} for _, opt := range opts { opt(option) @@ -338,8 +610,7 @@ func (h *Handle) Update(is infoschema.InfoSchema, opts ...TableStatsOpt) error { continue } tableInfo := table.Meta() - oldTbl, ok := oldCache.Get(physicalID) - if ok && oldTbl.Version >= version && tableInfo.UpdateTS == oldTbl.TblInfoUpdateTS { + if oldTbl, ok := oldCache.Get(physicalID); ok && oldTbl.Version >= version && tableInfo.UpdateTS == oldTbl.TblInfoUpdateTS { continue } tbl, err := h.TableStatsFromStorage(tableInfo, physicalID, false, 0) @@ -348,9 +619,6 @@ func (h *Handle) Update(is infoschema.InfoSchema, opts ...TableStatsOpt) error { logutil.BgLogger().Error("[stats] error occurred when read table stats", zap.String("table", tableInfo.Name.O), zap.Error(err)) continue } - if oldHealthy, ok := oldTbl.GetStatsHealthy(); ok { - healthyChange.drop(oldHealthy) - } if tbl == nil { deletedTableIDs = append(deletedTableIDs, physicalID) continue @@ -360,15 +628,9 @@ func (h *Handle) Update(is infoschema.InfoSchema, opts ...TableStatsOpt) error { tbl.ModifyCount = modifyCount tbl.Name = getFullTableName(is, tableInfo) tbl.TblInfoUpdateTS = tableInfo.UpdateTS - if newHealthy, ok := tbl.GetStatsHealthy(); ok { - healthyChange.add(newHealthy) - } tables = append(tables, tbl) } - updated := h.updateStatsCache(oldCache.update(tables, deletedTableIDs, lastVersion, opts...)) - if updated { - healthyChange.apply() - } + h.updateStatsCache(oldCache.update(tables, deletedTableIDs, lastVersion, opts...)) return nil } @@ -394,12 +656,13 @@ func (h *Handle) UpdateSessionVar() error { // In the column statistics, the variable `num` is equal to the number of columns in the partition table. // In the index statistics, the variable `num` is always equal to one. type GlobalStats struct { - Num int - Count int64 - Hg []*statistics.Histogram - Cms []*statistics.CMSketch - TopN []*statistics.TopN - Fms []*statistics.FMSketch + Num int + Count int64 + ModifyCount int64 + Hg []*statistics.Histogram + Cms []*statistics.CMSketch + TopN []*statistics.TopN + Fms []*statistics.FMSketch } // MergePartitionStats2GlobalStatsByTableID merge the partition-level stats to global-level stats based on the tableID. @@ -419,20 +682,15 @@ func (h *Handle) MergePartitionStats2GlobalStatsByTableID(sc sessionctx.Context, return h.mergePartitionStats2GlobalStats(sc, opts, is, globalTableInfo, isIndex, histIDs, tablePartitionStats) } -func (h *Handle) loadTablePartitionStats(tableInfo *model.TableInfo, partitionID int64, isIndex int, histIDs []int64) (*statistics.Table, error) { +func (h *Handle) loadTablePartitionStats(tableInfo *model.TableInfo, partitionDef *model.PartitionDefinition) (*statistics.Table, error) { var partitionStats *statistics.Table - partitionStats, err := h.TableStatsFromStorage(tableInfo, partitionID, true, 0) + partitionStats, err := h.TableStatsFromStorage(tableInfo, partitionDef.ID, true, 0) if err != nil { return nil, err } // if the err == nil && partitionStats == nil, it means we lack the partition-level stats which the physicalID is equal to partitionID. if partitionStats == nil { - var errMsg string - if isIndex == 0 { - errMsg = fmt.Sprintf("`%s`", tableInfo.Name.L) - } else { - errMsg = fmt.Sprintf("`%s` index: `%s`", tableInfo.Name.L, tableInfo.FindIndexNameByID(histIDs[0])) - } + errMsg := fmt.Sprintf("table `%s` partition `%s`", tableInfo.Name.L, partitionDef.Name.L) err = types.ErrPartitionStatsMissing.GenWithStackByArgs(errMsg) return nil, err } @@ -483,7 +741,8 @@ func (h *Handle) mergePartitionStats2GlobalStats(sc sessionctx.Context, allFms[i] = make([]*statistics.FMSketch, 0, partitionNum) } - for _, partitionID := range partitionIDs { + for _, def := range globalTableInfo.Partition.Definitions { + partitionID := def.ID h.mu.Lock() partitionTable, ok := h.getTableByPhysicalID(is, partitionID) h.mu.Unlock() @@ -498,7 +757,7 @@ func (h *Handle) mergePartitionStats2GlobalStats(sc sessionctx.Context, } // If pre-load partition stats isn't provided, then we load partition stats directly and set it into allPartitionStats if allPartitionStats == nil || partitionStats == nil || !ok { - partitionStats, err = h.loadTablePartitionStats(tableInfo, partitionID, isIndex, histIDs) + partitionStats, err = h.loadTablePartitionStats(tableInfo, &def) if err != nil { return } @@ -508,21 +767,32 @@ func (h *Handle) mergePartitionStats2GlobalStats(sc sessionctx.Context, allPartitionStats[partitionID] = partitionStats } for i := 0; i < globalStats.Num; i++ { - count, hg, cms, topN, fms := partitionStats.GetStatsInfo(histIDs[i], isIndex == 1) + _, hg, cms, topN, fms, analyzed := partitionStats.GetStatsInfo(histIDs[i], isIndex == 1) + if !analyzed { + var errMsg string + if isIndex == 0 { + errMsg = fmt.Sprintf("table `%s` partition `%s` column `%s`", tableInfo.Name.L, def.Name.L, tableInfo.FindColumnNameByID(histIDs[i])) + } else { + errMsg = fmt.Sprintf("table `%s` partition `%s` index `%s`", tableInfo.Name.L, def.Name.L, tableInfo.FindIndexNameByID(histIDs[i])) + } + err = types.ErrPartitionStatsMissing.GenWithStackByArgs(errMsg) + return + } // partition stats is not empty but column stats(hist, topn) is missing if partitionStats.Count > 0 && (hg == nil || hg.TotalRowCount() <= 0) && (topN == nil || topN.TotalCount() <= 0) { var errMsg string if isIndex == 0 { - errMsg = fmt.Sprintf("`%s` column: `%s`", tableInfo.Name.L, tableInfo.FindColumnNameByID(histIDs[i])) + errMsg = fmt.Sprintf("table `%s` partition `%s` column `%s`", tableInfo.Name.L, def.Name.L, tableInfo.FindColumnNameByID(histIDs[i])) } else { - errMsg = fmt.Sprintf("`%s` index: `%s`", tableInfo.Name.L, tableInfo.FindIndexNameByID(histIDs[i])) + errMsg = fmt.Sprintf("table `%s` partition `%s` index `%s`", tableInfo.Name.L, def.Name.L, tableInfo.FindIndexNameByID(histIDs[i])) } err = types.ErrPartitionColumnStatsMissing.GenWithStackByArgs(errMsg) return } if i == 0 { // In a partition, we will only update globalStats.Count once - globalStats.Count += count + globalStats.Count += partitionStats.Count + globalStats.ModifyCount += partitionStats.ModifyCount } allHg[i] = append(allHg[i], hg) allCms[i] = append(allCms[i], cms) @@ -547,7 +817,8 @@ func (h *Handle) mergePartitionStats2GlobalStats(sc sessionctx.Context, // Because after merging TopN, some numbers will be left. // These remaining topN numbers will be used as a separate bucket for later histogram merging. var popedTopN []statistics.TopNMeta - globalStats.TopN[i], popedTopN, allHg[i], err = statistics.MergePartTopN2GlobalTopN(sc.GetSessionVars().StmtCtx, sc.GetSessionVars().AnalyzeVersion, allTopN[i], uint32(opts[ast.AnalyzeOptNumTopN]), allHg[i], isIndex == 1) + wrapper := statistics.NewStatsWrapper(allHg[i], allTopN[i]) + globalStats.TopN[i], popedTopN, allHg[i], err = h.mergeGlobalStatsTopN(sc, wrapper, sc.GetSessionVars().StmtCtx.TimeZone, sc.GetSessionVars().AnalyzeVersion, uint32(opts[ast.AnalyzeOptNumTopN]), isIndex == 1) if err != nil { return } @@ -579,12 +850,113 @@ func (h *Handle) mergePartitionStats2GlobalStats(sc sessionctx.Context, return } +func (h *Handle) mergeGlobalStatsTopN(sc sessionctx.Context, wrapper *statistics.StatsWrapper, + timeZone *time.Location, version int, n uint32, isIndex bool) (*statistics.TopN, + []statistics.TopNMeta, []*statistics.Histogram, error) { + mergeConcurrency := sc.GetSessionVars().AnalyzePartitionMergeConcurrency + killed := &sc.GetSessionVars().Killed + // use original method if concurrency equals 1 or for version1 + if mergeConcurrency < 2 { + return statistics.MergePartTopN2GlobalTopN(timeZone, version, wrapper.AllTopN, n, wrapper.AllHg, isIndex, killed) + } + batchSize := len(wrapper.AllTopN) / mergeConcurrency + if batchSize < 1 { + batchSize = 1 + } else if batchSize > maxPartitionMergeBatchSize { + batchSize = maxPartitionMergeBatchSize + } + return h.mergeGlobalStatsTopNByConcurrency(mergeConcurrency, batchSize, wrapper, timeZone, version, n, isIndex, killed) +} + +// mergeGlobalStatsTopNByConcurrency merge partition topN by concurrency +// To merge global stats topn by concurrency, we will separate the partition topn in concurrency part and deal it with different worker. +// mergeConcurrency is used to control the total concurrency of the running worker, and mergeBatchSize is sued to control +// the partition size for each worker to solve it +func (h *Handle) mergeGlobalStatsTopNByConcurrency(mergeConcurrency, mergeBatchSize int, wrapper *statistics.StatsWrapper, + timeZone *time.Location, version int, n uint32, isIndex bool, killed *uint32) (*statistics.TopN, + []statistics.TopNMeta, []*statistics.Histogram, error) { + if len(wrapper.AllTopN) < mergeConcurrency { + mergeConcurrency = len(wrapper.AllTopN) + } + tasks := make([]*statistics.TopnStatsMergeTask, 0) + for start := 0; start < len(wrapper.AllTopN); { + end := start + mergeBatchSize + if end > len(wrapper.AllTopN) { + end = len(wrapper.AllTopN) + } + task := statistics.NewTopnStatsMergeTask(start, end) + tasks = append(tasks, task) + start = end + } + var wg util.WaitGroupWrapper + taskNum := len(tasks) + taskCh := make(chan *statistics.TopnStatsMergeTask, taskNum) + respCh := make(chan *statistics.TopnStatsMergeResponse, taskNum) + for i := 0; i < mergeConcurrency; i++ { + worker := statistics.NewTopnStatsMergeWorker(taskCh, respCh, wrapper, killed) + wg.Run(func() { + worker.Run(timeZone, isIndex, n, version) + }) + } + for _, task := range tasks { + taskCh <- task + } + close(taskCh) + wg.Wait() + close(respCh) + resps := make([]*statistics.TopnStatsMergeResponse, 0) + + // handle Error + hasErr := false + for resp := range respCh { + if resp.Err != nil { + hasErr = true + } + resps = append(resps, resp) + } + if hasErr { + errMsg := make([]string, 0) + for _, resp := range resps { + if resp.Err != nil { + errMsg = append(errMsg, resp.Err.Error()) + } + } + return nil, nil, nil, errors.New(strings.Join(errMsg, ",")) + } + + // fetch the response from each worker and merge them into global topn stats + sorted := make([]statistics.TopNMeta, 0, mergeConcurrency) + leftTopn := make([]statistics.TopNMeta, 0) + for _, resp := range resps { + if resp.TopN != nil { + sorted = append(sorted, resp.TopN.TopN...) + } + leftTopn = append(leftTopn, resp.PopedTopn...) + for i, removeTopn := range resp.RemoveVals { + // Remove the value from the Hists. + if len(removeTopn) > 0 { + tmp := removeTopn + slices.SortFunc(tmp, func(i, j statistics.TopNMeta) bool { + cmpResult := bytes.Compare(i.Encoded, j.Encoded) + return cmpResult < 0 + }) + wrapper.AllHg[i].RemoveVals(tmp) + } + } + } + + globalTopN, popedTopn := statistics.GetMergedTopNFromSortedSlice(sorted, n) + return globalTopN, statistics.SortTopnMeta(append(leftTopn, popedTopn...)), wrapper.AllHg, nil +} + func (h *Handle) getTableByPhysicalID(is infoschema.InfoSchema, physicalID int64) (table.Table, bool) { - if is.SchemaMetaVersion() != h.mu.schemaVersion { - h.mu.schemaVersion = is.SchemaMetaVersion() - h.mu.pid2tid = buildPartitionID2TableID(is) + h.schemaMu.Lock() + defer h.schemaMu.Unlock() + if is.SchemaMetaVersion() != h.schemaMu.schemaVersion { + h.schemaMu.schemaVersion = is.SchemaMetaVersion() + h.schemaMu.pid2tid = buildPartitionID2TableID(is) } - if id, ok := h.mu.pid2tid[physicalID]; ok { + if id, ok := h.schemaMu.pid2tid[physicalID]; ok { return is.TableByID(id) } return is.TableByID(physicalID) @@ -620,8 +992,13 @@ func (h *Handle) GetTableStats(tblInfo *model.TableInfo, opts ...TableStatsOpt) // GetPartitionStats retrieves the partition stats from cache. func (h *Handle) GetPartitionStats(tblInfo *model.TableInfo, pid int64, opts ...TableStatsOpt) *statistics.Table { - statsCache := h.statsCache.Load().(statsCache) var tbl *statistics.Table + if h == nil { + tbl = statistics.PseudoTable(tblInfo) + tbl.PhysicalID = pid + return tbl + } + statsCache := h.statsCache.Load().(statsCache) var ok bool option := &tableStatsOption{} for _, opt := range opts { @@ -1240,18 +1617,29 @@ func saveBucketsToStorage(ctx context.Context, exec sqlexec.SQLExecutor, sc *stm } // SaveTableStatsToStorage saves the stats of a table to storage. -func (h *Handle) SaveTableStatsToStorage(results *statistics.AnalyzeResults, needDumpFMS, analyzeSnapshot bool) (err error) { +func (h *Handle) SaveTableStatsToStorage(results *statistics.AnalyzeResults, analyzeSnapshot bool, source string) (err error) { + h.mu.Lock() + defer h.mu.Unlock() + return SaveTableStatsToStorage(h.mu.ctx, results, analyzeSnapshot, source) +} + +// SaveTableStatsToStorage saves the stats of a table to storage. +func SaveTableStatsToStorage(sctx sessionctx.Context, results *statistics.AnalyzeResults, analyzeSnapshot bool, source string) (err error) { + needDumpFMS := results.TableID.IsPartitionTable() tableID := results.TableID.GetStatisticsID() statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(tableID, statsVer) + if err1 := recordHistoricalStatsMeta(sctx, tableID, statsVer, source); err1 != nil { + logutil.BgLogger().Error("record historical stats meta failed", + zap.Int64("table-id", tableID), + zap.Uint64("version", statsVer), + zap.Error(err1)) + } } }() - h.mu.Lock() - defer h.mu.Unlock() ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) - exec := h.mu.ctx.(sqlexec.SQLExecutor) + exec := sctx.(sqlexec.SQLExecutor) _, err = exec.ExecuteInternal(ctx, "begin pessimistic") if err != nil { return err @@ -1259,7 +1647,7 @@ func (h *Handle) SaveTableStatsToStorage(results *statistics.AnalyzeResults, nee defer func() { err = finishTransaction(ctx, exec, err) }() - txn, err := h.mu.ctx.Txn(true) + txn, err := sctx.Txn(true) if err != nil { return err } @@ -1272,7 +1660,7 @@ func (h *Handle) SaveTableStatsToStorage(results *statistics.AnalyzeResults, nee return err } var rows []chunk.Row - rows, err = sqlexec.DrainRecordSet(ctx, rs, h.mu.ctx.GetSessionVars().MaxChunkSize) + rows, err = sqlexec.DrainRecordSet(ctx, rs, sctx.GetSessionVars().MaxChunkSize) if err != nil { return err } @@ -1369,7 +1757,7 @@ func (h *Handle) SaveTableStatsToStorage(results *statistics.AnalyzeResults, nee if _, err = exec.ExecuteInternal(ctx, "delete from mysql.stats_buckets where table_id = %? and is_index = %? and hist_id = %?", tableID, result.IsIndex, hg.ID); err != nil { return err } - sc := h.mu.ctx.GetSessionVars().StmtCtx + sc := sctx.GetSessionVars().StmtCtx var lastAnalyzePos []byte lastAnalyzePos, err = saveBucketsToStorage(ctx, exec, sc, tableID, result.IsIndex, hg) if err != nil { @@ -1414,12 +1802,15 @@ func (h *Handle) SaveTableStatsToStorage(results *statistics.AnalyzeResults, nee } // SaveStatsToStorage saves the stats to storage. +// If count is negative, both count and modify count would not be used and not be written to the table. Unless, corresponding +// fields in the stats_meta table will be updated. // TODO: refactor to reduce the number of parameters -func (h *Handle) SaveStatsToStorage(tableID int64, count int64, isIndex int, hg *statistics.Histogram, cms *statistics.CMSketch, topN *statistics.TopN, statsVersion int, isAnalyzed int64, updateAnalyzeTime bool) (err error) { +func (h *Handle) SaveStatsToStorage(tableID int64, count, modifyCount int64, isIndex int, hg *statistics.Histogram, + cms *statistics.CMSketch, topN *statistics.TopN, statsVersion int, isAnalyzed int64, updateAnalyzeTime bool, source string) (err error) { statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(tableID, statsVer) + h.recordHistoricalStatsMeta(tableID, statsVer, source) } }() h.mu.Lock() @@ -1441,7 +1832,7 @@ func (h *Handle) SaveStatsToStorage(tableID int64, count int64, isIndex int, hg version := txn.StartTS() // If the count is less than 0, then we do not want to update the modify count and count. if count >= 0 { - _, err = exec.ExecuteInternal(ctx, "replace into mysql.stats_meta (version, table_id, count) values (%?, %?, %?)", version, tableID, count) + _, err = exec.ExecuteInternal(ctx, "replace into mysql.stats_meta (version, table_id, count, modify_count) values (%?, %?, %?, %?)", version, tableID, count, modifyCount) } else { _, err = exec.ExecuteInternal(ctx, "update mysql.stats_meta set version = %? where table_id = %?", version, tableID) } @@ -1494,11 +1885,11 @@ func (h *Handle) SaveStatsToStorage(tableID int64, count int64, isIndex int, hg } // SaveMetaToStorage will save stats_meta to storage. -func (h *Handle) SaveMetaToStorage(tableID, count, modifyCount int64) (err error) { +func (h *Handle) SaveMetaToStorage(tableID, count, modifyCount int64, source string) (err error) { statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(tableID, statsVer) + h.recordHistoricalStatsMeta(tableID, statsVer, source) } }() h.mu.Lock() @@ -1539,7 +1930,9 @@ func (h *Handle) histogramFromStorage(reader *statsReader, tableID int64, colID lowerBound = rows[i].GetDatum(2, &fields[2].Column.FieldType) upperBound = rows[i].GetDatum(3, &fields[3].Column.FieldType) } else { - sc := &stmtctx.StatementContext{TimeZone: time.UTC} + // Invalid date values may be inserted into table under some relaxed sql mode. Those values may exist in statistics. + // Hence, when reading statistics, we should skip invalid date check. See #39336. + sc := &stmtctx.StatementContext{TimeZone: time.UTC, AllowInvalidDate: true, IgnoreZeroInDate: true} d := rows[i].GetDatum(2, &fields[2].Column.FieldType) // For new collation data, when storing the bounds of the histogram, we store the collate key instead of the // original value. @@ -1704,7 +2097,7 @@ func (h *Handle) InsertExtendedStats(statsName string, colIDs []int64, tp int, t statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(tableID, statsVer) + h.recordHistoricalStatsMeta(tableID, statsVer, StatsMetaHistorySourceExtendedStats) } }() slices.Sort(colIDs) @@ -1775,7 +2168,7 @@ func (h *Handle) MarkExtendedStatsDeleted(statsName string, tableID int64, ifExi statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(tableID, statsVer) + h.recordHistoricalStatsMeta(tableID, statsVer, StatsMetaHistorySourceExtendedStats) } }() ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) @@ -1988,7 +2381,7 @@ func (h *Handle) SaveExtendedStatsToStorage(tableID int64, extStats *statistics. statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(tableID, statsVer) + h.recordHistoricalStatsMeta(tableID, statsVer, StatsMetaHistorySourceExtendedStats) } }() if extStats == nil || len(extStats.Stats) == 0 { @@ -2196,17 +2589,27 @@ func (h *Handle) GetPredicateColumns(tableID int64) ([]int64, error) { const maxColumnSize = 6 << 20 // RecordHistoricalStatsToStorage records the given table's stats data to mysql.stats_history -func (h *Handle) RecordHistoricalStatsToStorage(dbName string, tableInfo *model.TableInfo) (uint64, error) { +func (h *Handle) RecordHistoricalStatsToStorage(dbName string, tableInfo *model.TableInfo, physicalID int64, isPartition bool) (uint64, error) { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) - js, err := h.DumpStatsToJSON(dbName, tableInfo, nil) + var js *JSONTable + var err error + if isPartition { + js, err = h.tableStatsToJSON(dbName, tableInfo, physicalID, 0) + } else { + js, err = h.DumpStatsToJSON(dbName, tableInfo, nil, true) + } if err != nil { return 0, errors.Trace(err) } version := uint64(0) - for _, value := range js.Columns { - version = uint64(*value.StatsVer) - if version != 0 { - break + if len(js.Partitions) == 0 { + version = js.Version + } else { + for _, p := range js.Partitions { + version = p.Version + if version != 0 { + break + } } } blocks, err := JSONTableToBlocks(js, maxColumnSize) @@ -2227,62 +2630,26 @@ func (h *Handle) RecordHistoricalStatsToStorage(dbName string, tableInfo *model. const sql = "INSERT INTO mysql.stats_history(table_id, stats_data, seq_no, version, create_time) VALUES (%?, %?, %?, %?, %?)" for i := 0; i < len(blocks); i++ { - if _, err := exec.ExecuteInternal(ctx, sql, tableInfo.ID, blocks[i], i, version, ts); err != nil { + if _, err := exec.ExecuteInternal(ctx, sql, physicalID, blocks[i], i, version, ts); err != nil { return version, errors.Trace(err) } } return version, nil } -// CheckHistoricalStatsEnable is used to check whether TiDBEnableHistoricalStats is enabled. -func (h *Handle) CheckHistoricalStatsEnable() (enable bool, err error) { - h.mu.Lock() - defer h.mu.Unlock() - val, err := h.mu.ctx.GetSessionVars().GlobalVarsAccessor.GetGlobalSysVar(variable.TiDBEnableHistoricalStats) +func checkHistoricalStatsEnable(sctx sessionctx.Context) (enable bool, err error) { + val, err := sctx.GetSessionVars().GlobalVarsAccessor.GetGlobalSysVar(variable.TiDBEnableHistoricalStats) if err != nil { return false, errors.Trace(err) } return variable.TiDBOptOn(val), nil } -func (h *Handle) recordHistoricalStatsMeta(tableID int64, version uint64) error { - if tableID == 0 || version == 0 { - return errors.Errorf("tableID %d, version %d are invalid", tableID, version) - } - historicalStatsEnabled, err := h.CheckHistoricalStatsEnable() - if err != nil { - return errors.Errorf("check tidb_enable_historical_stats failed: %v", err) - } - if !historicalStatsEnabled { - return nil - } - - ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) +// CheckHistoricalStatsEnable is used to check whether TiDBEnableHistoricalStats is enabled. +func (h *Handle) CheckHistoricalStatsEnable() (enable bool, err error) { h.mu.Lock() defer h.mu.Unlock() - rows, _, err := h.execRestrictedSQL(ctx, "select modify_count, count from mysql.stats_meta where table_id = %? and version = %?", tableID, version) - if err != nil { - return errors.Trace(err) - } - if len(rows) == 0 { - return errors.New("no historical meta stats can be recorded") - } - modifyCount, count := rows[0].GetInt64(0), rows[0].GetInt64(1) - - exec := h.mu.ctx.(sqlexec.SQLExecutor) - _, err = exec.ExecuteInternal(ctx, "begin pessimistic") - if err != nil { - return errors.Trace(err) - } - defer func() { - err = finishTransaction(ctx, exec, err) - }() - - const sql = "REPLACE INTO mysql.stats_meta_history(table_id, modify_count, count, version, create_time) VALUES (%?, %?, %?, %?, NOW())" - if _, err := exec.ExecuteInternal(ctx, sql, tableID, modifyCount, count, version); err != nil { - return errors.Trace(err) - } - return nil + return checkHistoricalStatsEnable(h.mu.ctx) } // InsertAnalyzeJob inserts analyze job into mysql.analyze_jobs and gets job ID for further updating job. diff --git a/statistics/handle/handle_hist.go b/statistics/handle/handle_hist.go index 1392590130438..ad04d946e3f22 100644 --- a/statistics/handle/handle_hist.go +++ b/statistics/handle/handle_hist.go @@ -59,21 +59,39 @@ type NeededItemTask struct { // SendLoadRequests send neededColumns requests func (h *Handle) SendLoadRequests(sc *stmtctx.StatementContext, neededHistItems []model.TableItemID, timeout time.Duration) error { remainedItems := h.removeHistLoadedColumns(neededHistItems) + + failpoint.Inject("assertSyncLoadItems", func(val failpoint.Value) { + if sc.OptimizeTracer != nil { + count := val.(int) + if len(remainedItems) != count { + panic("remained items count wrong") + } + } + }) + if len(remainedItems) <= 0 { return nil } sc.StatsLoad.Timeout = timeout sc.StatsLoad.NeededItems = remainedItems sc.StatsLoad.ResultCh = make(chan stmtctx.StatsLoadResult, len(remainedItems)) + tasks := make([]*NeededItemTask, 0) for _, item := range remainedItems { task := &NeededItemTask{ TableItemID: item, ToTimeout: time.Now().Local().Add(timeout), ResultCh: sc.StatsLoad.ResultCh, } - err := h.AppendNeededItem(task, timeout) - if err != nil { - return err + tasks = append(tasks, task) + } + timer := time.NewTimer(timeout) + defer timer.Stop() + for _, task := range tasks { + select { + case h.StatsLoad.NeededItemsCh <- task: + continue + case <-timer.C: + return errors.New("sync load stats channel is full and timeout sending task to channel") } } sc.StatsLoad.LoadStartTime = time.Now() @@ -81,9 +99,9 @@ func (h *Handle) SendLoadRequests(sc *stmtctx.StatementContext, neededHistItems } // SyncWaitStatsLoad sync waits loading of neededColumns and return false if timeout -func (h *Handle) SyncWaitStatsLoad(sc *stmtctx.StatementContext) bool { +func (h *Handle) SyncWaitStatsLoad(sc *stmtctx.StatementContext) error { if len(sc.StatsLoad.NeededItems) <= 0 { - return true + return nil } var errorMsgs []string defer func() { @@ -110,15 +128,14 @@ func (h *Handle) SyncWaitStatsLoad(sc *stmtctx.StatementContext) bool { delete(resultCheckMap, result.Item) if len(resultCheckMap) == 0 { metrics.SyncLoadHistogram.Observe(float64(time.Since(sc.StatsLoad.LoadStartTime).Milliseconds())) - return true + return nil } } else { - return false + return errors.New("sync load stats channel closed unexpectedly") } case <-timer.C: metrics.SyncLoadTimeoutCounter.Inc() - logutil.BgLogger().Warn("SyncWaitStatsLoad timeout") - return false + return errors.New("sync load stats timeout") } } } @@ -137,19 +154,23 @@ func (h *Handle) removeHistLoadedColumns(neededItems []model.TableItemID) []mode continue } colHist, ok := tbl.Columns[item.ID] - if !ok { - continue - } - if colHist.IsHistNeeded(tbl.Pseudo) { + if ok && colHist.IsStatsInitialized() && !colHist.IsFullLoad() { remainedItems = append(remainedItems, item) } } return remainedItems } -// AppendNeededItem appends needed columns/indices to ch, if exists, do not append the duplicated one. +// AppendNeededItem appends needed columns/indices to ch, it is only used for test func (h *Handle) AppendNeededItem(task *NeededItemTask, timeout time.Duration) error { - return h.writeToChanWithTimeout(h.StatsLoad.NeededItemsCh, task, timeout) + timer := time.NewTimer(timeout) + defer timer.Stop() + select { + case h.StatsLoad.NeededItemsCh <- task: + case <-timer.C: + return errors.New("Channel is full and timeout writing to channel") + } + return nil } var errExit = errors.New("Stop loading since domain is closed") @@ -161,7 +182,7 @@ type StatsReaderContext struct { } // SubLoadWorker loads hist data for each column -func (h *Handle) SubLoadWorker(ctx sessionctx.Context, exit chan struct{}, exitWg *util.WaitGroupWrapper) { +func (h *Handle) SubLoadWorker(ctx sessionctx.Context, exit chan struct{}, exitWg *util.WaitGroupEnhancedWrapper) { readerCtx := &StatsReaderContext{} defer func() { exitWg.Done() diff --git a/statistics/handle/handle_hist_test.go b/statistics/handle/handle_hist_test.go index cf9f708345d32..8febf5827165d 100644 --- a/statistics/handle/handle_hist_test.go +++ b/statistics/handle/handle_hist_test.go @@ -29,6 +29,28 @@ import ( "github.com/stretchr/testify/require" ) +func TestSyncLoadSkipUnAnalyzedItems(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t(a int)") + tk.MustExec("create table t1(a int)") + h := dom.StatsHandle() + h.SetLease(1) + + // no item would be loaded + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/statistics/handle/assertSyncLoadItems", `return(0)`)) + tk.MustQuery("trace plan select * from t where a > 10") + failpoint.Disable("github.com/pingcap/tidb/statistics/handle/assertSyncLoadItems") + tk.MustExec("analyze table t1") + // one column would be loaded + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/statistics/handle/assertSyncLoadItems", `return(1)`)) + tk.MustQuery("trace plan select * from t1 where a > 10") + failpoint.Disable("github.com/pingcap/tidb/statistics/handle/assertSyncLoadItems") +} + func TestConcurrentLoadHist(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) @@ -66,7 +88,7 @@ func TestConcurrentLoadHist(t *testing.T) { timeout := time.Nanosecond * mathutil.MaxInt h.SendLoadRequests(stmtCtx, neededColumns, timeout) rs := h.SyncWaitStatsLoad(stmtCtx) - require.True(t, rs) + require.Nil(t, rs) stat = h.GetTableStats(tableInfo) hg = stat.Columns[tableInfo.Columns[2].ID].Histogram topn = stat.Columns[tableInfo.Columns[2].ID].TopN @@ -110,7 +132,7 @@ func TestConcurrentLoadHistTimeout(t *testing.T) { } h.SendLoadRequests(stmtCtx, neededColumns, 0) // set timeout to 0 so task will go to timeout channel rs := h.SyncWaitStatsLoad(stmtCtx) - require.False(t, rs) + require.Error(t, rs) stat = h.GetTableStats(tableInfo) hg = stat.Columns[tableInfo.Columns[2].ID].Histogram topn = stat.Columns[tableInfo.Columns[2].ID].TopN diff --git a/statistics/handle/handle_test.go b/statistics/handle/handle_test.go index f8f73b933bd9a..2b0669033f8c9 100644 --- a/statistics/handle/handle_test.go +++ b/statistics/handle/handle_test.go @@ -344,6 +344,7 @@ func TestDurationToTS(t *testing.T) { func TestVersion(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) + testKit2 := testkit.NewTestKit(t, store) testKit := testkit.NewTestKit(t, store) testKit.MustExec("use test") testKit.MustExec("create table t1 (c1 int, c2 int)") @@ -353,7 +354,7 @@ func TestVersion(t *testing.T) { tbl1, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) require.NoError(t, err) tableInfo1 := tbl1.Meta() - h, err := handle.NewHandle(testKit.Session(), time.Millisecond, do.SysSessionPool(), do.SysProcTracker(), do.ServerID) + h, err := handle.NewHandle(testKit.Session(), testKit2.Session(), time.Millisecond, do.SysSessionPool(), do.SysProcTracker(), do.ServerID) require.NoError(t, err) unit := oracle.ComposeTS(1, 0) testKit.MustExec("update mysql.stats_meta set version = ? where table_id = ?", 2*unit, tableInfo1.ID) @@ -1659,6 +1660,7 @@ partition by range (a) ( partition p0 values less than (10), partition p1 values less than (20) )`) + require.NoError(t, dom.StatsHandle().HandleDDLEvent(<-dom.StatsHandle().DDLEventCh())) tk.MustExec("insert into t values (1), (5), (null), (11), (15)") require.NoError(t, dom.StatsHandle().DumpStatsDeltaToKV(handle.DumpAll)) @@ -1694,14 +1696,15 @@ partition by range (a) ( require.NoError(t, err) tableInfo := tbl.Meta() globalStats := h.GetTableStats(tableInfo) - // global.count = p0.count(3) + p1.count(2) + p2.count(2) - // We did not analyze partition p1, so the value here has not changed - require.Equal(t, int64(7), globalStats.Count) + // global.count = p0.count(3) + p1.count(4) + p2.count(2) + // modify count is 2 because we didn't analyze p1 after the second insert + require.Equal(t, int64(9), globalStats.Count) + require.Equal(t, int64(2), globalStats.ModifyCount) tk.MustExec("analyze table t partition p1;") globalStats = h.GetTableStats(tableInfo) // global.count = p0.count(3) + p1.count(4) + p2.count(4) - // The value of p1.Count is correct now. + // The value of modify count is 0 now. require.Equal(t, int64(9), globalStats.Count) require.Equal(t, int64(0), globalStats.ModifyCount) @@ -2155,11 +2158,13 @@ func TestPartitionPruneModeSessionVariable(t *testing.T) { store := testkit.CreateMockStore(t) tk1 := testkit.NewTestKit(t, store) tk1.MustExec("use test") + tk1.MustExec("set tidb_cost_model_version=1") tk1.MustExec("set @@tidb_partition_prune_mode = '" + string(variable.Dynamic) + "'") tk1.MustExec(`set @@tidb_analyze_version=2`) tk2 := testkit.NewTestKit(t, store) tk2.MustExec("use test") + tk2.MustExec("set tidb_cost_model_version=1") tk2.MustExec("set @@tidb_partition_prune_mode = '" + string(variable.Static) + "'") tk2.MustExec(`set @@tidb_analyze_version=2`) @@ -2223,8 +2228,8 @@ func TestFMSWithAnalyzePartition(t *testing.T) { tk.MustQuery("show warnings").Sort().Check(testkit.Rows( "Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p0", "Warning 1105 Ignore columns and options when analyze partition in dynamic mode", - "Warning 8131 Build table: `t` global-level stats failed due to missing partition-level stats", - "Warning 8131 Build table: `t` index: `a` global-level stats failed due to missing partition-level stats", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", + "Warning 8131 Build global-level stats failed due to missing partition-level stats: table `t` partition `p1`", )) tk.MustQuery("select count(*) from mysql.stats_fm_sketch").Check(testkit.Rows("2")) } @@ -2264,7 +2269,7 @@ func TestIndexUsageInformation(t *testing.T) { tk.MustQuery("select b from t_idx where b=0") err = do.StatsHandle().DumpIndexUsageToKV() require.NoError(t, err) - tk.MustQuery(querySQL).Check(testkit.Rows( + tk.MustQuery(querySQL).Sort().Check(testkit.Rows( "test t_idx idx_a 3 2", "test t_idx idx_b 2 2", )) @@ -3295,7 +3300,7 @@ func TestRecordHistoricalStatsToStorage(t *testing.T) { tableInfo, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) - version, err := dom.StatsHandle().RecordHistoricalStatsToStorage("t", tableInfo.Meta()) + version, err := dom.StatsHandle().RecordHistoricalStatsToStorage("t", tableInfo.Meta(), tableInfo.Meta().ID, false) require.NoError(t, err) rows := tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where version = '%d'", version)).Rows() @@ -3423,3 +3428,151 @@ func TestUninitializedStatsStatus(t *testing.T) { tk.MustExec("set @@tidb_enable_pseudo_for_outdated_stats = false") checkStatsPseudo() } + +func TestStatsLockAndUnlockTable(t *testing.T) { + restore := config.RestoreFunc() + defer restore() + config.UpdateGlobal(func(conf *config.Config) { + conf.Performance.EnableStatsCacheMemQuota = true + }) + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@tidb_analyze_version = 1") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b varchar(10), index idx_b (b))") + tk.MustExec("analyze table test.t") + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.Nil(t, err) + + handle := domain.GetDomain(tk.Session()).StatsHandle() + tblStats := handle.GetTableStats(tbl.Meta()) + for _, col := range tblStats.Columns { + require.True(t, col.IsStatsInitialized()) + } + tk.MustExec("lock stats t") + + rows := tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows() + num, _ := strconv.Atoi(rows[0][0].(string)) + require.Equal(t, num, 1) + + tk.MustExec("insert into t(a, b) values(1,'a')") + tk.MustExec("insert into t(a, b) values(2,'b')") + + tk.MustExec("analyze table test.t") + tblStats1 := handle.GetTableStats(tbl.Meta()) + require.Equal(t, tblStats, tblStats1) + + tableLocked1 := handle.GetTableLockedAndClearForTest() + err = handle.LoadLockedTables() + require.Nil(t, err) + tableLocked2 := handle.GetTableLockedAndClearForTest() + require.Equal(t, tableLocked1, tableLocked2) + + tk.MustExec("unlock stats t") + rows = tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows() + num, _ = strconv.Atoi(rows[0][0].(string)) + require.Equal(t, num, 0) + + tk.MustExec("analyze table test.t") + tblStats2 := handle.GetTableStats(tbl.Meta()) + require.Equal(t, int64(2), tblStats2.Count) +} + +func TestStatsLockAndUnlockTables(t *testing.T) { + restore := config.RestoreFunc() + defer restore() + config.UpdateGlobal(func(conf *config.Config) { + conf.Performance.EnableStatsCacheMemQuota = true + }) + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@tidb_analyze_version = 1") + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("drop table if exists t2") + tk.MustExec("create table t1(a int, b varchar(10), index idx_b (b))") + tk.MustExec("create table t2(a int, b varchar(10), index idx_b (b))") + tk.MustExec("analyze table test.t1, test.t2") + tbl1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.Nil(t, err) + tbl2, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t2")) + require.Nil(t, err) + + handle := domain.GetDomain(tk.Session()).StatsHandle() + tbl1Stats := handle.GetTableStats(tbl1.Meta()) + for _, col := range tbl1Stats.Columns { + require.True(t, col.IsStatsInitialized()) + } + tbl2Stats := handle.GetTableStats(tbl2.Meta()) + for _, col := range tbl2Stats.Columns { + require.True(t, col.IsStatsInitialized()) + } + + tk.MustExec("lock stats t1, t2") + + rows := tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows() + num, _ := strconv.Atoi(rows[0][0].(string)) + require.Equal(t, num, 2) + + tk.MustExec("insert into t1(a, b) values(1,'a')") + tk.MustExec("insert into t1(a, b) values(2,'b')") + + tk.MustExec("insert into t2(a, b) values(1,'a')") + tk.MustExec("insert into t2(a, b) values(2,'b')") + + tk.MustExec("analyze table test.t1, test.t2") + tbl1Stats1 := handle.GetTableStats(tbl1.Meta()) + require.Equal(t, tbl1Stats, tbl1Stats1) + tbl2Stats1 := handle.GetTableStats(tbl2.Meta()) + require.Equal(t, tbl2Stats, tbl2Stats1) + + tableLocked1 := handle.GetTableLockedAndClearForTest() + err = handle.LoadLockedTables() + require.Nil(t, err) + tableLocked2 := handle.GetTableLockedAndClearForTest() + require.Equal(t, tableLocked1, tableLocked2) + + tk.MustExec("unlock stats test.t1, test.t2") + rows = tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows() + num, _ = strconv.Atoi(rows[0][0].(string)) + require.Equal(t, num, 0) + + tk.MustExec("analyze table test.t1, test.t2") + tbl1Stats2 := handle.GetTableStats(tbl1.Meta()) + require.Equal(t, int64(2), tbl1Stats2.Count) + tbl2Stats2 := handle.GetTableStats(tbl2.Meta()) + require.Equal(t, int64(2), tbl2Stats2.Count) +} + +func TestIssue39336(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(` +create table t1 ( + a datetime(3) default null, + b int +) partition by range (b) ( + partition p0 values less than (1000), + partition p1 values less than (maxvalue) +)`) + tk.MustExec("set @@sql_mode=''") + tk.MustExec("set @@tidb_analyze_version=2") + tk.MustExec("set @@tidb_partition_prune_mode='dynamic'") + tk.MustExec(` +insert into t1 values +('1000-00-09 00:00:00.000', 1), +('1000-00-06 00:00:00.000', 1), +('1000-00-06 00:00:00.000', 1), +('2022-11-23 14:24:30.000', 1), +('2022-11-23 14:24:32.000', 1), +('2022-11-23 14:24:33.000', 1), +('2022-11-23 14:24:35.000', 1), +('2022-11-23 14:25:08.000', 1001), +('2022-11-23 14:25:09.000', 1001)`) + tk.MustExec("analyze table t1 with 0 topn") + rows := tk.MustQuery("show analyze status where job_info like 'merge global stats%'").Rows() + require.Len(t, rows, 1) + require.Equal(t, "finished", rows[0][7]) +} diff --git a/statistics/handle/historical_stats_handler.go b/statistics/handle/historical_stats_handler.go new file mode 100644 index 0000000000000..c7a683da8b740 --- /dev/null +++ b/statistics/handle/historical_stats_handler.go @@ -0,0 +1,91 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package handle + +import ( + "context" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/sqlexec" + "go.uber.org/zap" +) + +const ( + // StatsMetaHistorySourceAnalyze indicates stats history meta source from analyze + StatsMetaHistorySourceAnalyze = "analyze" + // StatsMetaHistorySourceLoadStats indicates stats history meta source from load stats + StatsMetaHistorySourceLoadStats = "load stats" + // StatsMetaHistorySourceFlushStats indicates stats history meta source from flush stats + StatsMetaHistorySourceFlushStats = "flush stats" + // StatsMetaHistorySourceExtendedStats indicates stats history meta source from extended stats + StatsMetaHistorySourceExtendedStats = "extended stats" + // StatsMetaHistorySourceSchemaChange indicates stats history meta source from schema change + StatsMetaHistorySourceSchemaChange = "schema change" + // StatsMetaHistorySourceFeedBack indicates stats history meta source from feedback + StatsMetaHistorySourceFeedBack = "feedback" +) + +func recordHistoricalStatsMeta(sctx sessionctx.Context, tableID int64, version uint64, source string) error { + if tableID == 0 || version == 0 { + return errors.Errorf("tableID %d, version %d are invalid", tableID, version) + } + historicalStatsEnabled, err := checkHistoricalStatsEnable(sctx) + if err != nil { + return errors.Errorf("check tidb_enable_historical_stats failed: %v", err) + } + if !historicalStatsEnabled { + return nil + } + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats) + exec := sctx.(sqlexec.SQLExecutor) + rexec := sctx.(sqlexec.RestrictedSQLExecutor) + rows, _, err := rexec.ExecRestrictedSQL(ctx, []sqlexec.OptionFuncAlias{sqlexec.ExecOptionUseCurSession}, "select modify_count, count from mysql.stats_meta where table_id = %? and version = %?", tableID, version) + if err != nil { + return errors.Trace(err) + } + if len(rows) == 0 { + return errors.New("no historical meta stats can be recorded") + } + modifyCount, count := rows[0].GetInt64(0), rows[0].GetInt64(1) + + _, err = exec.ExecuteInternal(ctx, "begin pessimistic") + if err != nil { + return errors.Trace(err) + } + defer func() { + err = finishTransaction(ctx, exec, err) + }() + + const sql = "REPLACE INTO mysql.stats_meta_history(table_id, modify_count, count, version, source, create_time) VALUES (%?, %?, %?, %?, %?, NOW())" + if _, err := exec.ExecuteInternal(ctx, sql, tableID, modifyCount, count, version, source); err != nil { + return errors.Trace(err) + } + return nil +} + +func (h *Handle) recordHistoricalStatsMeta(tableID int64, version uint64, source string) { + h.mu.Lock() + defer h.mu.Unlock() + err := recordHistoricalStatsMeta(h.mu.ctx, tableID, version, source) + if err != nil { + logutil.BgLogger().Error("record historical stats meta failed", + zap.Int64("table-id", tableID), + zap.Uint64("version", version), + zap.Error(err)) + } +} diff --git a/statistics/handle/main_test.go b/statistics/handle/main_test.go index b346b095e13cf..5541a01a46aa9 100644 --- a/statistics/handle/main_test.go +++ b/statistics/handle/main_test.go @@ -24,7 +24,9 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } testsetup.SetupForCommonTest() goleak.VerifyTestMain(m, opts...) diff --git a/statistics/handle/update.go b/statistics/handle/update.go index f6b8c31361ff0..e245a3ea0bca5 100644 --- a/statistics/handle/update.go +++ b/statistics/handle/update.go @@ -45,7 +45,6 @@ import ( "github.com/pingcap/tidb/util/ranger" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/timeutil" - "github.com/tikv/client-go/v2/oracle" "go.uber.org/atomic" "go.uber.org/zap" "golang.org/x/exp/slices" @@ -197,6 +196,12 @@ func (s *SessionStatsCollector) StoreQueryFeedback(feedback interface{}, h *Hand if !q.Valid.Load() || q.Hist == nil { return nil } + + // if table locked, skip + if h.IsTableLocked(q.PhysicalID) { + return nil + } + err := h.RecalculateExpectCount(q, enablePseudoForOutdatedStats) if err != nil { return errors.Trace(err) @@ -229,6 +234,9 @@ func (s *SessionStatsCollector) UpdateColStatsUsage(colMap colStatsUsageMap) { // NewSessionStatsCollector allocates a stats collector for a session. func (h *Handle) NewSessionStatsCollector() *SessionStatsCollector { + h.mu.Lock() + defer h.mu.Unlock() + h.listHead.Lock() defer h.listHead.Unlock() newCollector := &SessionStatsCollector{ @@ -307,6 +315,8 @@ func (s *SessionIndexUsageCollector) Delete() { // idxUsageListHead always points to an empty SessionIndexUsageCollector as a sentinel node. So we let idxUsageListHead.next // points to new item. It's helpful to sweepIdxUsageList. func (h *Handle) NewSessionIndexUsageCollector() *SessionIndexUsageCollector { + h.mu.Lock() + defer h.mu.Unlock() h.idxUsageListHead.Lock() defer h.idxUsageListHead.Unlock() newCollector := &SessionIndexUsageCollector{ @@ -514,7 +524,7 @@ func (h *Handle) dumpTableStatCountToKV(id int64, delta variable.TableDelta) (up statsVer := uint64(0) defer func() { if err == nil && statsVer != 0 { - err = h.recordHistoricalStatsMeta(id, statsVer) + h.recordHistoricalStatsMeta(id, statsVer, StatsMetaHistorySourceFlushStats) } }() if delta.Count == 0 { @@ -539,10 +549,19 @@ func (h *Handle) dumpTableStatCountToKV(id int64, delta variable.TableDelta) (up startTS := txn.StartTS() updateStatsMeta := func(id int64) error { var err error - if delta.Delta < 0 { - _, err = exec.ExecuteInternal(ctx, "update mysql.stats_meta set version = %?, count = count - %?, modify_count = modify_count + %? where table_id = %? and count >= %?", startTS, -delta.Delta, delta.Count, id, -delta.Delta) + // This lock is already locked on it so it use isTableLocked without lock. + if h.isTableLocked(id) { + if delta.Delta < 0 { + _, err = exec.ExecuteInternal(ctx, "update mysql.stats_table_locked set version = %?, count = count - %?, modify_count = modify_count + %? where table_id = %? and count >= %?", startTS, -delta.Delta, delta.Count, id, -delta.Delta) + } else { + _, err = exec.ExecuteInternal(ctx, "update mysql.stats_table_locked set version = %?, count = count + %?, modify_count = modify_count + %? where table_id = %?", startTS, delta.Delta, delta.Count, id) + } } else { - _, err = exec.ExecuteInternal(ctx, "update mysql.stats_meta set version = %?, count = count + %?, modify_count = modify_count + %? where table_id = %?", startTS, delta.Delta, delta.Count, id) + if delta.Delta < 0 { + _, err = exec.ExecuteInternal(ctx, "update mysql.stats_meta set version = %?, count = count - %?, modify_count = modify_count + %? where table_id = %? and count >= %?", startTS, -delta.Delta, delta.Count, id, -delta.Delta) + } else { + _, err = exec.ExecuteInternal(ctx, "update mysql.stats_meta set version = %?, count = count + %?, modify_count = modify_count + %? where table_id = %?", startTS, delta.Delta, delta.Count, id) + } } statsVer = startTS return errors.Trace(err) @@ -886,7 +905,7 @@ func (h *Handle) deleteOutdatedFeedback(tableID, histID, isIndex int64) error { func (h *Handle) dumpStatsUpdateToKV(tableID, isIndex int64, q *statistics.QueryFeedback, hist *statistics.Histogram, cms *statistics.CMSketch, topN *statistics.TopN, statsVersion int64) error { hist = statistics.UpdateHistogram(hist, q, int(statsVersion)) // feedback for partition is not ready. - err := h.SaveStatsToStorage(tableID, -1, int(isIndex), hist, cms, topN, int(statsVersion), 0, false) + err := h.SaveStatsToStorage(tableID, -1, 0, int(isIndex), hist, cms, topN, int(statsVersion), 0, false, StatsMetaHistorySourceFeedBack) metrics.UpdateStatsCounter.WithLabelValues(metrics.RetLabel(err)).Inc() return errors.Trace(err) } @@ -981,9 +1000,7 @@ func TableAnalyzed(tbl *statistics.Table) bool { func NeedAnalyzeTable(tbl *statistics.Table, limit time.Duration, autoAnalyzeRatio float64) (bool, string) { analyzed := TableAnalyzed(tbl) if !analyzed { - t := time.UnixMilli(oracle.ExtractPhysical(tbl.Version)) - dur := time.Since(t) - return dur >= limit, fmt.Sprintf("table unanalyzed, time since last updated %v", dur) + return true, "table unanalyzed" } // Auto analyze is disabled. if autoAnalyzeRatio == 0 { @@ -1049,6 +1066,11 @@ func (h *Handle) getAnalyzeSnapshot() (bool, error) { // HandleAutoAnalyze analyzes the newly created table or index. func (h *Handle) HandleAutoAnalyze(is infoschema.InfoSchema) (analyzed bool) { + defer func() { + if r := recover(); r != nil { + logutil.BgLogger().Error("HandleAutoAnalyze panicked", zap.Any("error", r), zap.Stack("stack")) + } + }() err := h.UpdateSessionVar() if err != nil { logutil.BgLogger().Error("[stats] update analyze version for auto analyze session failed", zap.Error(err)) @@ -1088,6 +1110,10 @@ func (h *Handle) HandleAutoAnalyze(is infoschema.InfoSchema) (analyzed bool) { tbls[i], tbls[j] = tbls[j], tbls[i] }) for _, tbl := range tbls { + //if table locked, skip analyze + if h.IsTableLocked(tbl.Meta().ID) { + continue + } tblInfo := tbl.Meta() if tblInfo.IsView() { continue @@ -1449,10 +1475,10 @@ func (h *Handle) RecalculateExpectCount(q *statistics.QueryFeedback, enablePseud expected := 0.0 if isIndex { idx := t.Indices[id] - expected, err = idx.GetRowCount(sctx, nil, ranges, t.Count) + expected, err = idx.GetRowCount(sctx, nil, ranges, t.Count, t.ModifyCount) } else { c := t.Columns[id] - expected, err = c.GetColumnRowCount(sctx, ranges, t.Count, true) + expected, err = c.GetColumnRowCount(sctx, ranges, t.Count, t.ModifyCount, true) } q.Expected = int64(expected) return err diff --git a/statistics/handle/update_test.go b/statistics/handle/update_test.go index 5ae98d32560d2..1e2f9fb228442 100644 --- a/statistics/handle/update_test.go +++ b/statistics/handle/update_test.go @@ -1391,8 +1391,8 @@ func TestNeedAnalyzeTable(t *testing.T) { tbl: &statistics.Table{Version: oracle.GoTimeToTS(time.Now())}, limit: time.Hour, ratio: 0, - result: false, - reason: "", + result: true, + reason: "table unanalyzed", }, // table was already analyzed but auto analyze is disabled { @@ -2398,3 +2398,225 @@ func TestEnableAndDisableColumnTracking(t *testing.T) { tk.MustExec("set global tidb_enable_column_tracking = 0") tk.MustQuery("show column_stats_usage where db_name = 'test' and table_name = 't' and last_used_at is not null").Check(testkit.Rows()) } + +func TestStatsLockUnlockForAutoAnalyze(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + oriStart := tk.MustQuery("select @@tidb_auto_analyze_start_time").Rows()[0][0].(string) + oriEnd := tk.MustQuery("select @@tidb_auto_analyze_end_time").Rows()[0][0].(string) + handle.AutoAnalyzeMinCnt = 0 + defer func() { + handle.AutoAnalyzeMinCnt = 1000 + tk.MustExec(fmt.Sprintf("set global tidb_auto_analyze_start_time='%v'", oriStart)) + tk.MustExec(fmt.Sprintf("set global tidb_auto_analyze_end_time='%v'", oriEnd)) + }() + + h := dom.StatsHandle() + tk.MustExec("use test") + tk.MustExec("create table t (a int)") + require.NoError(t, h.HandleDDLEvent(<-h.DDLEventCh())) + tk.MustExec("insert into t values (1)" + strings.Repeat(", (1)", 19)) + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + is := dom.InfoSchema() + require.NoError(t, h.Update(is)) + // To pass the stats.Pseudo check in autoAnalyzeTable + tk.MustExec("analyze table t") + tk.MustExec("explain select * from t where a = 1") + require.NoError(t, h.LoadNeededHistograms()) + tk.MustExec("set global tidb_auto_analyze_start_time='00:00 +0000'") + tk.MustExec("set global tidb_auto_analyze_end_time='23:59 +0000'") + + tk.MustExec("insert into t values (1)" + strings.Repeat(", (1)", 10)) + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.Update(is)) + require.True(t, h.HandleAutoAnalyze(is)) + + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.Nil(t, err) + + tblStats := h.GetTableStats(tbl.Meta()) + for _, col := range tblStats.Columns { + require.True(t, col.IsStatsInitialized()) + } + + tk.MustExec("lock stats t") + + tk.MustExec("delete from t limit 12") + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.Update(is)) + require.False(t, h.HandleAutoAnalyze(is)) + + tblStats1 := h.GetTableStats(tbl.Meta()) + require.Equal(t, tblStats, tblStats1) + + tk.MustExec("unlock stats t") + + tk.MustExec("delete from t limit 4") + + rows := tk.MustQuery("select count(*) from t").Rows() + num, _ := strconv.Atoi(rows[0][0].(string)) + require.Equal(t, num, 15) + + tk.MustExec("analyze table t") + + tblStats2 := h.GetTableStats(tbl.Meta()) + require.Equal(t, int64(15), tblStats2.Count) +} + +func TestStatsLockForFeedback(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + testKit := testkit.NewTestKit(t, store) + testKit.MustExec("use test") + + // TODO(tiancaiamao): query feedback is broken when paging is on. + testKit.MustExec("set @@tidb_enable_paging = off") + + testKit.MustExec("set @@session.tidb_analyze_version = 0") + testKit.MustExec("create table t (a bigint(64), b bigint(64), primary key(a), index idx(b))") + testKit.MustExec("insert into t values (1,2),(2,2),(4,5)") + testKit.MustExec("analyze table t with 0 topn") + testKit.MustExec("insert into t values (3,4)") + for i := 5; i < 20; i++ { + testKit.MustExec(fmt.Sprintf("insert into t values(%d, %d)", i, i+1)) + } + + h := dom.StatsHandle() + oriProbability := statistics.FeedbackProbability.Load() + oriNumber := statistics.MaxNumberOfRanges + oriMinLogCount := handle.MinLogScanCount.Load() + oriErrorRate := handle.MinLogErrorRate.Load() + defer func() { + statistics.FeedbackProbability.Store(oriProbability) + statistics.MaxNumberOfRanges = oriNumber + handle.MinLogScanCount.Store(oriMinLogCount) + handle.MinLogErrorRate.Store(oriErrorRate) + }() + statistics.FeedbackProbability.Store(1) + handle.MinLogScanCount.Store(0) + handle.MinLogErrorRate.Store(0) + tests := []struct { + sql string + hist string + }{ + { + // test primary key feedback + sql: "select * from t where t.a <= 4 order by a desc", + hist: "column:1 ndv:4 totColSize:0\n" + + "num: 1 lower_bound: -9223372036854775808 upper_bound: 2 repeats: 0 ndv: 0\n" + + "num: 2 lower_bound: 2 upper_bound: 4 repeats: 0 ndv: 0\n" + + "num: 1 lower_bound: 4 upper_bound: 4 repeats: 1 ndv: 0", + }, + //run 1st sql after table locked, hist should not changed + { + sql: "select * from t where t.a <= 8 order by a desc", + hist: "column:1 ndv:4 totColSize:0\n" + + "num: 1 lower_bound: -9223372036854775808 upper_bound: 2 repeats: 0 ndv: 0\n" + + "num: 2 lower_bound: 2 upper_bound: 4 repeats: 0 ndv: 0\n" + + "num: 1 lower_bound: 4 upper_bound: 4 repeats: 1 ndv: 0", + }, + //run 2nd sql after table unlocked, hist should not changed + { + sql: "select * from t where t.a <= 12 order by a desc", + hist: "column:1 ndv:12 totColSize:0\n" + + "num: 1 lower_bound: -9223372036854775808 upper_bound: 2 repeats: 0 ndv: 0\n" + + "num: 2 lower_bound: 2 upper_bound: 4 repeats: 0 ndv: 0\n" + + "num: 9 lower_bound: 4 upper_bound: 12 repeats: 0 ndv: 0", + }, + //run 4th sql after table locked, hist should not changed + { + sql: "select * from t", + hist: "column:1 ndv:12 totColSize:0\n" + + "num: 1 lower_bound: -9223372036854775808 upper_bound: 2 repeats: 0 ndv: 0\n" + + "num: 2 lower_bound: 2 upper_bound: 4 repeats: 0 ndv: 0\n" + + "num: 9 lower_bound: 4 upper_bound: 12 repeats: 0 ndv: 0", + }, + } + is := dom.InfoSchema() + table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + for i, test := range tests { + testKit.MustQuery(test.sql) + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.DumpStatsFeedbackToKV()) + require.NoError(t, h.HandleUpdateStats(dom.InfoSchema())) + require.NoError(t, err) + require.NoError(t, h.Update(is)) + tblInfo := table.Meta() + tbl := h.GetTableStats(tblInfo) + //fmt.Printf("\n i: %d, exp: %s, \nact: %s\n", i, tests[i].hist, tbl.Columns[tblInfo.Columns[0].ID].ToString(0)) + require.Equal(t, tests[i].hist, tbl.Columns[tblInfo.Columns[0].ID].ToString(0)) + // add table lock after 2nd + if i == 0 { + testKit.MustExec("lock stats t") + } else if i == 1 { + testKit.MustExec("unlock stats t") + } else if i == 2 { + testKit.MustExec("lock stats t") + } + } +} + +func TestStatsLockForDelta(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + testKit := testkit.NewTestKit(t, store) + testKit.MustExec("use test") + testKit.MustExec("set @@session.tidb_analyze_version = 1") + testKit.MustExec("create table t1 (c1 int, c2 int)") + testKit.MustExec("create table t2 (c1 int, c2 int)") + + is := dom.InfoSchema() + tbl1, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.NoError(t, err) + tableInfo1 := tbl1.Meta() + h := dom.StatsHandle() + + testKit.MustExec("lock stats t1") + + rowCount1 := 10 + rowCount2 := 20 + for i := 0; i < rowCount1; i++ { + testKit.MustExec("insert into t1 values(1, 2)") + } + for i := 0; i < rowCount2; i++ { + testKit.MustExec("insert into t2 values(1, 2)") + } + + err = h.HandleDDLEvent(<-h.DDLEventCh()) + require.NoError(t, err) + err = h.HandleDDLEvent(<-h.DDLEventCh()) + require.NoError(t, err) + + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.Update(is)) + stats1 := h.GetTableStats(tableInfo1) + require.Equal(t, stats1.Count, int64(0)) + + tbl2, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t2")) + require.NoError(t, err) + tableInfo2 := tbl2.Meta() + stats2 := h.GetTableStats(tableInfo2) + require.Equal(t, int64(rowCount2), stats2.Count) + + testKit.MustExec("analyze table t1") + for i := 0; i < rowCount1; i++ { + testKit.MustExec("insert into t1 values(1, 2)") + } + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.Update(is)) + stats1 = h.GetTableStats(tableInfo1) + require.Equal(t, stats1.Count, int64(0)) + + testKit.MustExec("unlock stats t1") + + testKit.MustExec("analyze table t1") + stats1 = h.GetTableStats(tableInfo1) + require.Equal(t, int64(20), stats1.Count) + + for i := 0; i < rowCount1; i++ { + testKit.MustExec("insert into t1 values(1, 2)") + } + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.Update(is)) + stats1 = h.GetTableStats(tableInfo1) + require.Equal(t, int64(30), stats1.Count) +} diff --git a/statistics/histogram.go b/statistics/histogram.go index 2133ccad3b53b..3cab23f0492d8 100644 --- a/statistics/histogram.go +++ b/statistics/histogram.go @@ -778,7 +778,7 @@ func (hg *Histogram) outOfRange(val types.Datum) bool { // outOfRangeRowCount estimate the row count of part of [lDatum, rDatum] which is out of range of the histogram. // Here we assume the density of data is decreasing from the lower/upper bound of the histogram toward outside. -// The maximum row count it can get is the increaseCount. It reaches the maximum when out-of-range width reaches histogram range width. +// The maximum row count it can get is the modifyCount. It reaches the maximum when out-of-range width reaches histogram range width. // As it shows below. To calculate the out-of-range row count, we need to calculate the percentage of the shaded area. // Note that we assume histL-boundL == histR-histL == boundR-histR here. /* @@ -795,7 +795,7 @@ func (hg *Histogram) outOfRange(val types.Datum) bool { │ │ lDatum rDatum */ -func (hg *Histogram) outOfRangeRowCount(lDatum, rDatum *types.Datum, increaseCount int64) float64 { +func (hg *Histogram) outOfRangeRowCount(lDatum, rDatum *types.Datum, modifyCount int64) float64 { if hg.Len() == 0 { return 0 } @@ -879,8 +879,14 @@ func (hg *Histogram) outOfRangeRowCount(lDatum, rDatum *types.Datum, increaseCou totalPercent = 1 } rowCount := totalPercent * hg.notNullCount() - if rowCount > float64(increaseCount) { - return float64(increaseCount) + + // Use the modifyCount as the upper bound. Note that modifyCount contains insert, delete and update. So this is + // a rather loose upper bound. + // There are some scenarios where we need to handle out-of-range estimation after both insert and delete happen. + // But we don't know how many increases are in the modifyCount. So we have to use this loose bound to ensure it + // can produce a reasonable results in this scenario. + if rowCount > float64(modifyCount) { + return float64(modifyCount) } return rowCount } @@ -997,7 +1003,7 @@ func (coll *HistColl) NewHistCollBySelectivity(sctx sessionctx.Context, statsNod Columns: make(map[int64]*Column), Indices: make(map[int64]*Index), Idx2ColumnIDs: coll.Idx2ColumnIDs, - ColID2IdxID: coll.ColID2IdxID, + ColID2IdxIDs: coll.ColID2IdxIDs, Count: coll.Count, } for _, node := range statsNodes { diff --git a/statistics/index.go b/statistics/index.go index 6b8a88501c30e..40ba2b005843b 100644 --- a/statistics/index.go +++ b/statistics/index.go @@ -216,12 +216,13 @@ func (idx *Index) QueryBytes(d []byte) uint64 { // GetRowCount returns the row count of the given ranges. // It uses the modifyCount to adjust the influence of modifications on the table. -func (idx *Index) GetRowCount(sctx sessionctx.Context, coll *HistColl, indexRanges []*ranger.Range, realtimeRowCount int64) (float64, error) { +func (idx *Index) GetRowCount(sctx sessionctx.Context, coll *HistColl, indexRanges []*ranger.Range, realtimeRowCount, modifyCount int64) (float64, error) { idx.checkStats() sc := sctx.GetSessionVars().StmtCtx totalCount := float64(0) isSingleCol := len(idx.Info.Columns) == 1 for _, indexRange := range indexRanges { + var count float64 lb, err := codec.EncodeKey(sc, nil, indexRange.LowVal...) if err != nil { return 0, err @@ -242,7 +243,7 @@ func (idx *Index) GetRowCount(sctx sessionctx.Context, coll *HistColl, indexRang totalCount++ continue } - count := idx.equalRowCount(lb, realtimeRowCount) + count = idx.equalRowCount(lb, realtimeRowCount) // If the current table row count has changed, we should scale the row count accordingly. count *= idx.GetIncreaseFactor(realtimeRowCount) totalCount += count @@ -262,7 +263,7 @@ func (idx *Index) GetRowCount(sctx sessionctx.Context, coll *HistColl, indexRang r := types.NewBytesDatum(rb) lowIsNull := bytes.Equal(lb, nullKeyBytes) if isSingleCol && lowIsNull { - totalCount += float64(idx.Histogram.NullCount) + count += float64(idx.Histogram.NullCount) } expBackoffSuccess := false // Due to the limitation of calcFraction and convertDatumToScalar, the histogram actually won't estimate anything. @@ -297,24 +298,21 @@ func (idx *Index) GetRowCount(sctx sessionctx.Context, coll *HistColl, indexRang if expBackoffCnt > upperLimit { expBackoffCnt = upperLimit } - totalCount += expBackoffCnt + count += expBackoffCnt } } if !expBackoffSuccess { - totalCount += idx.BetweenRowCount(l, r) + count += idx.BetweenRowCount(l, r) } // If the current table row count has changed, we should scale the row count accordingly. - totalCount *= idx.GetIncreaseFactor(realtimeRowCount) + count *= idx.GetIncreaseFactor(realtimeRowCount) // handling the out-of-range part if (idx.outOfRange(l) && !(isSingleCol && lowIsNull)) || idx.outOfRange(r) { - increaseCount := realtimeRowCount - int64(idx.TotalRowCount()) - if increaseCount < 0 { - increaseCount = 0 - } - totalCount += idx.Histogram.outOfRangeRowCount(&l, &r, increaseCount) + count += idx.Histogram.outOfRangeRowCount(&l, &r, modifyCount) } + totalCount += count } totalCount = mathutil.Clamp(totalCount, 0, float64(realtimeRowCount)) return totalCount, nil @@ -346,14 +344,30 @@ func (idx *Index) expBackoffEstimation(sctx sessionctx.Context, coll *HistColl, } colID := colsIDs[i] var ( - count float64 - err error + count float64 + err error + foundStats bool ) - if anotherIdxID, ok := coll.ColID2IdxID[colID]; ok && anotherIdxID != idx.Histogram.ID { - count, err = coll.GetRowCountByIndexRanges(sctx, anotherIdxID, tmpRan) - } else if col, ok := coll.Columns[colID]; ok && !col.IsInvalid(sctx, coll.Pseudo) { + if col, ok := coll.Columns[colID]; ok && !col.IsInvalid(sctx, coll.Pseudo) { + foundStats = true count, err = coll.GetRowCountByColumnRanges(sctx, colID, tmpRan) - } else { + } + if idxIDs, ok := coll.ColID2IdxIDs[colID]; ok && !foundStats && len(indexRange.LowVal) > 1 { + // Note the `len(indexRange.LowVal) > 1` condition here, it means we only recursively call + // `GetRowCountByIndexRanges()` when the input `indexRange` is a multi-column range. This + // check avoids infinite recursion. + for _, idxID := range idxIDs { + if idxID == idx.Histogram.ID { + continue + } + foundStats = true + count, err = coll.GetRowCountByIndexRanges(sctx, idxID, tmpRan) + if err == nil { + break + } + } + } + if !foundStats { continue } if err != nil { diff --git a/statistics/integration_test.go b/statistics/integration_test.go index c4e4d315c7dbe..a94a029f86381 100644 --- a/statistics/integration_test.go +++ b/statistics/integration_test.go @@ -268,6 +268,7 @@ func TestExpBackoffEstimation(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") + tk.MustExec("set tidb_cost_model_version=2") tk.MustExec("create table exp_backoff(a int, b int, c int, d int, index idx(a, b, c, d))") tk.MustExec("insert into exp_backoff values(1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 2, 3), (1, 2, 2, 4), (1, 2, 3, 5)") tk.MustExec("set @@session.tidb_analyze_version=2") diff --git a/statistics/main_test.go b/statistics/main_test.go index b790b0e63076a..1d19e839a8297 100644 --- a/statistics/main_test.go +++ b/statistics/main_test.go @@ -49,6 +49,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/statistics/merge_worker.go b/statistics/merge_worker.go new file mode 100644 index 0000000000000..efcc40f79eb65 --- /dev/null +++ b/statistics/merge_worker.go @@ -0,0 +1,198 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package statistics + +import ( + "sync/atomic" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/hack" +) + +// StatsWrapper wrapper stats +type StatsWrapper struct { + AllHg []*Histogram + AllTopN []*TopN +} + +// NewStatsWrapper returns wrapper +func NewStatsWrapper(hg []*Histogram, topN []*TopN) *StatsWrapper { + return &StatsWrapper{ + AllHg: hg, + AllTopN: topN, + } +} + +type topnStatsMergeWorker struct { + killed *uint32 + taskCh <-chan *TopnStatsMergeTask + respCh chan<- *TopnStatsMergeResponse + // the stats in the wrapper should only be read during the worker + statsWrapper *StatsWrapper +} + +// NewTopnStatsMergeWorker returns topn merge worker +func NewTopnStatsMergeWorker( + taskCh <-chan *TopnStatsMergeTask, + respCh chan<- *TopnStatsMergeResponse, + wrapper *StatsWrapper, + killed *uint32) *topnStatsMergeWorker { + worker := &topnStatsMergeWorker{ + taskCh: taskCh, + respCh: respCh, + } + worker.statsWrapper = wrapper + worker.killed = killed + return worker +} + +// TopnStatsMergeTask indicates a task for merge topn stats +type TopnStatsMergeTask struct { + start int + end int +} + +// NewTopnStatsMergeTask returns task +func NewTopnStatsMergeTask(start, end int) *TopnStatsMergeTask { + return &TopnStatsMergeTask{ + start: start, + end: end, + } +} + +// TopnStatsMergeResponse indicates topn merge worker response +type TopnStatsMergeResponse struct { + TopN *TopN + PopedTopn []TopNMeta + RemoveVals [][]TopNMeta + Err error +} + +// Run runs topn merge like statistics.MergePartTopN2GlobalTopN +func (worker *topnStatsMergeWorker) Run(timeZone *time.Location, isIndex bool, + n uint32, + version int) { + for task := range worker.taskCh { + start := task.start + end := task.end + checkTopNs := worker.statsWrapper.AllTopN[start:end] + allTopNs := worker.statsWrapper.AllTopN + allHists := worker.statsWrapper.AllHg + resp := &TopnStatsMergeResponse{} + if checkEmptyTopNs(checkTopNs) { + worker.respCh <- resp + return + } + partNum := len(allTopNs) + checkNum := len(checkTopNs) + topNsNum := make([]int, checkNum) + removeVals := make([][]TopNMeta, partNum) + for i, topN := range checkTopNs { + if topN == nil { + topNsNum[i] = 0 + continue + } + topNsNum[i] = len(topN.TopN) + } + // Different TopN structures may hold the same value, we have to merge them. + counter := make(map[hack.MutableString]float64) + // datumMap is used to store the mapping from the string type to datum type. + // The datum is used to find the value in the histogram. + datumMap := make(map[hack.MutableString]types.Datum) + + for i, topN := range checkTopNs { + if atomic.LoadUint32(worker.killed) == 1 { + resp.Err = errors.Trace(ErrQueryInterrupted) + worker.respCh <- resp + return + } + if topN.TotalCount() == 0 { + continue + } + for _, val := range topN.TopN { + encodedVal := hack.String(val.Encoded) + _, exists := counter[encodedVal] + counter[encodedVal] += float64(val.Count) + if exists { + // We have already calculated the encodedVal from the histogram, so just continue to next topN value. + continue + } + // We need to check whether the value corresponding to encodedVal is contained in other partition-level stats. + // 1. Check the topN first. + // 2. If the topN doesn't contain the value corresponding to encodedVal. We should check the histogram. + for j := 0; j < partNum; j++ { + if (j == i && version >= 2) || allTopNs[j].findTopN(val.Encoded) != -1 { + continue + } + // Get the encodedVal from the hists[j] + datum, exists := datumMap[encodedVal] + if !exists { + // If the datumMap does not have the encodedVal datum, + // we should generate the datum based on the encoded value. + // This part is copied from the function MergePartitionHist2GlobalHist. + var d types.Datum + if isIndex { + d.SetBytes(val.Encoded) + } else { + var err error + if types.IsTypeTime(allHists[0].Tp.GetType()) { + // handle datetime values specially since they are encoded to int and we'll get int values if using DecodeOne. + _, d, err = codec.DecodeAsDateTime(val.Encoded, allHists[0].Tp.GetType(), timeZone) + } else if types.IsTypeFloat(allHists[0].Tp.GetType()) { + _, d, err = codec.DecodeAsFloat32(val.Encoded, allHists[0].Tp.GetType()) + } else { + _, d, err = codec.DecodeOne(val.Encoded) + } + if err != nil { + resp.Err = err + worker.respCh <- resp + return + } + } + datumMap[encodedVal] = d + datum = d + } + // Get the row count which the value is equal to the encodedVal from histogram. + count, _ := allHists[j].equalRowCount(datum, isIndex) + if count != 0 { + counter[encodedVal] += count + // Remove the value corresponding to encodedVal from the histogram. + removeVals[j] = append(removeVals[j], TopNMeta{Encoded: datum.GetBytes(), Count: uint64(count)}) + } + } + } + } + // record remove values + resp.RemoveVals = removeVals + + numTop := len(counter) + if numTop == 0 { + worker.respCh <- resp + continue + } + sorted := make([]TopNMeta, 0, numTop) + for value, cnt := range counter { + data := hack.Slice(string(value)) + sorted = append(sorted, TopNMeta{Encoded: data, Count: uint64(cnt)}) + } + globalTopN, leftTopN := getMergedTopNFromSortedSlice(sorted, n) + resp.TopN = globalTopN + resp.PopedTopn = leftTopN + worker.respCh <- resp + } +} diff --git a/statistics/selectivity.go b/statistics/selectivity.go index 45de31365f3d6..99458cc04bea6 100644 --- a/statistics/selectivity.go +++ b/statistics/selectivity.go @@ -498,7 +498,7 @@ func getMaskAndRanges(ctx sessionctx.Context, exprs []expression.Expression, ran var accessConds, remainedConds []expression.Expression switch rangeType { case ranger.ColumnRangeType: - accessConds = ranger.ExtractAccessConditionsForColumn(exprs, cols[0]) + accessConds = ranger.ExtractAccessConditionsForColumn(ctx, exprs, cols[0]) ranges, accessConds, _, err = ranger.BuildColumnRange(accessConds, ctx, cols[0].RetType, types.UnspecifiedLength, ctx.GetSessionVars().RangeMaxSize) case ranger.IndexRangeType: if cachedPath != nil { diff --git a/statistics/selectivity_test.go b/statistics/selectivity_test.go index a71de236c2483..05a7413fa3d09 100644 --- a/statistics/selectivity_test.go +++ b/statistics/selectivity_test.go @@ -44,6 +44,7 @@ import ( "github.com/pingcap/tidb/util/mock" "github.com/pingcap/tidb/util/ranger" "github.com/stretchr/testify/require" + "golang.org/x/exp/slices" ) func TestCollationColumnEstimate(t *testing.T) { @@ -85,7 +86,7 @@ func BenchmarkSelectivity(b *testing.B) { require.NoErrorf(b, err, "error %v, for expr %s", err, exprs) require.Len(b, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoErrorf(b, err, "for %s", exprs) p, _, err := plannercore.BuildLogicalPlanForTest(context.Background(), sctx, stmts[0], ret.InfoSchema) require.NoErrorf(b, err, "error %v, for building plan, expr %s", err, exprs) @@ -127,7 +128,7 @@ func TestOutOfRangeEstimation(t *testing.T) { statsTbl := h.GetTableStats(table.Meta()) sctx := mock.NewContext() col := statsTbl.Columns[table.Meta().Columns[0].ID] - count, err := col.GetColumnRowCount(sctx, getRange(900, 900), statsTbl.Count, false) + count, err := col.GetColumnRowCount(sctx, getRange(900, 900), statsTbl.Count, statsTbl.ModifyCount, false) require.NoError(t, err) // Because the ANALYZE collect data by random sampling, so the result is not an accurate value. // so we use a range here. @@ -146,8 +147,9 @@ func TestOutOfRangeEstimation(t *testing.T) { statsSuiteData := statistics.GetStatsSuiteData() statsSuiteData.LoadTestCases(t, &input, &output) increasedTblRowCount := int64(float64(statsTbl.Count) * 1.5) + modifyCount := int64(float64(statsTbl.Count) * 0.5) for i, ran := range input { - count, err = col.GetColumnRowCount(sctx, getRange(ran.Start, ran.End), increasedTblRowCount, false) + count, err = col.GetColumnRowCount(sctx, getRange(ran.Start, ran.End), increasedTblRowCount, modifyCount, false) require.NoError(t, err) testdata.OnRecord(func() { output[i].Start = ran.Start @@ -159,6 +161,42 @@ func TestOutOfRangeEstimation(t *testing.T) { } } +// TestOutOfRangeEstimationAfterDelete tests the out-of-range estimation after deletion happen. +// The test result doesn't perfectly reflect the actual data distribution, but this is the expected behavior for now. +func TestOutOfRangeEstimationAfterDelete(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + testKit := testkit.NewTestKit(t, store) + h := dom.StatsHandle() + testKit.MustExec("use test") + testKit.MustExec("drop table if exists t") + testKit.MustExec("create table t(a int unsigned)") + require.NoError(t, h.HandleDDLEvent(<-h.DDLEventCh())) + for i := 0; i < 3000; i++ { + testKit.MustExec(fmt.Sprintf("insert into t values (%v)", i/5+300)) // [300, 900) + } + require.Nil(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + testKit.MustExec("analyze table t with 1 samplerate, 0 topn") + testKit.MustExec("delete from t where a < 500") + require.Nil(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.Nil(t, h.Update(dom.InfoSchema())) + var ( + input []string + output []struct { + SQL string + Result []string + } + ) + statsSuiteData := statistics.GetStatsSuiteData() + statsSuiteData.LoadTestCases(t, &input, &output) + for i := range input { + testdata.OnRecord(func() { + output[i].SQL = input[i] + output[i].Result = testdata.ConvertRowsToStrings(testKit.MustQuery(input[i]).Rows()) + }) + testKit.MustQuery(input[i]).Check(testkit.Rows(output[i].Result...)) + } +} + func TestEstimationForUnknownValues(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) testKit := testkit.NewTestKit(t, store) @@ -299,6 +337,7 @@ func TestStatsVer2(t *testing.T) { store := testkit.CreateMockStore(t) testKit := testkit.NewTestKit(t, store) testKit.MustExec("use test") + testKit.MustExec("set tidb_cost_model_version=2") testKit.MustExec("set tidb_analyze_version=2") testKit.MustExec("drop table if exists tint") @@ -527,7 +566,7 @@ func TestSelectivity(t *testing.T) { require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoErrorf(t, err, "for expr %s", tt.exprs) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoErrorf(t, err, "for building plan, expr %s", err, tt.exprs) @@ -542,6 +581,7 @@ func TestSelectivity(t *testing.T) { require.Truef(t, math.Abs(ratio-tt.selectivity) < eps, "for %s, needed: %v, got: %v", tt.exprs, tt.selectivity, ratio) histColl.Count *= 10 + histColl.ModifyCount = histColl.Count * 9 ratio, _, err = histColl.Selectivity(sctx, sel.Conditions, nil) require.NoErrorf(t, err, "for %s", tt.exprs) require.Truef(t, math.Abs(ratio-tt.selectivityAfterIncrease) < eps, "for %s, needed: %v, got: %v", tt.exprs, tt.selectivityAfterIncrease, ratio) @@ -639,7 +679,7 @@ func TestDNFCondSelectivity(t *testing.T) { require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoErrorf(t, err, "error %v, for sql %s", err, tt) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoErrorf(t, err, "error %v, for building plan, sql %s", err, tt) @@ -747,7 +787,7 @@ func TestSmallRangeEstimation(t *testing.T) { statsSuiteData := statistics.GetStatsSuiteData() statsSuiteData.LoadTestCases(t, &input, &output) for i, ran := range input { - count, err := col.GetColumnRowCount(sctx, getRange(ran.Start, ran.End), statsTbl.Count, false) + count, err := col.GetColumnRowCount(sctx, getRange(ran.Start, ran.End), statsTbl.Count, statsTbl.ModifyCount, false) require.NoError(t, err) testdata.OnRecord(func() { output[i].Start = ran.Start @@ -852,7 +892,7 @@ func prepareSelectivity(testKit *testkit.TestKit, dom *domain.Domain) (*statisti return statsTbl, nil } -func getRange(start, end int64) []*ranger.Range { +func getRange(start, end int64) ranger.Ranges { ran := &ranger.Range{ LowVal: []types.Datum{types.NewIntDatum(start)}, HighVal: []types.Datum{types.NewIntDatum(end)}, @@ -861,6 +901,21 @@ func getRange(start, end int64) []*ranger.Range { return []*ranger.Range{ran} } +func getRanges(start, end []int64) (res ranger.Ranges) { + if len(start) != len(end) { + return nil + } + for i := range start { + ran := &ranger.Range{ + LowVal: []types.Datum{types.NewIntDatum(start[i])}, + HighVal: []types.Datum{types.NewIntDatum(end[i])}, + Collators: collate.GetBinaryCollatorSlice(1), + } + res = append(res, ran) + } + return +} + func TestSelectivityGreedyAlgo(t *testing.T) { nodes := make([]*statistics.StatsNode, 3) nodes[0] = statistics.MockStatsNode(1, 3, 2) @@ -990,3 +1045,115 @@ type outputType struct { SQL string Result []string } + +func TestGlobalStatsOutOfRangeEstimationAfterDelete(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + testKit := testkit.NewTestKit(t, store) + h := dom.StatsHandle() + testKit.MustExec("use test") + testKit.MustExec("set @@tidb_partition_prune_mode='dynamic'") + testKit.MustExec("drop table if exists t") + testKit.MustExec("create table t(a int unsigned) " + + "partition by range (a) " + + "(partition p0 values less than (400), " + + "partition p1 values less than (600), " + + "partition p2 values less than (800)," + + "partition p3 values less than (1000)," + + "partition p4 values less than (1200))") + require.NoError(t, h.HandleDDLEvent(<-h.DDLEventCh())) + for i := 0; i < 3000; i++ { + testKit.MustExec(fmt.Sprintf("insert into t values (%v)", i/5+300)) // [300, 900) + } + require.Nil(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + testKit.MustExec("analyze table t with 1 samplerate, 0 topn") + testKit.MustExec("delete from t where a < 500") + require.Nil(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.Nil(t, h.Update(dom.InfoSchema())) + var ( + input []string + output []struct { + SQL string + Result []string + } + ) + statsSuiteData := statistics.GetStatsSuiteData() + statsSuiteData.LoadTestCases(t, &input, &output) + for i := range input { + testdata.OnRecord(func() { + output[i].SQL = input[i] + output[i].Result = testdata.ConvertRowsToStrings(testKit.MustQuery(input[i]).Rows()) + }) + testKit.MustQuery(input[i]).Check(testkit.Rows(output[i].Result...)) + } + testKit.MustExec("analyze table t partition p4 with 1 samplerate, 0 topn") + require.Nil(t, h.Update(dom.InfoSchema())) + for i := range input { + testKit.MustQuery(input[i]).Check(testkit.Rows(output[i].Result...)) + } +} + +func generateMapsForMockStatsTbl(statsTbl *statistics.Table) { + idx2Columns := make(map[int64][]int64) + colID2IdxIDs := make(map[int64][]int64) + for _, idxHist := range statsTbl.Indices { + ids := make([]int64, 0, len(idxHist.Info.Columns)) + for _, idxCol := range idxHist.Info.Columns { + ids = append(ids, int64(idxCol.Offset)) + } + colID2IdxIDs[ids[0]] = append(colID2IdxIDs[ids[0]], idxHist.ID) + idx2Columns[idxHist.ID] = ids + } + for _, idxIDs := range colID2IdxIDs { + slices.Sort(idxIDs) + } + statsTbl.Idx2ColumnIDs = idx2Columns + statsTbl.ColID2IdxIDs = colID2IdxIDs +} + +func TestIssue39593(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + testKit := testkit.NewTestKit(t, store) + + testKit.MustExec("use test") + testKit.MustExec("drop table if exists t") + testKit.MustExec("create table t(a int, b int, index idx(a, b))") + is := dom.InfoSchema() + tb, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + tblInfo := tb.Meta() + + // mock the statistics.Table + statsTbl := mockStatsTable(tblInfo, 540) + colValues, err := generateIntDatum(1, 54) + require.NoError(t, err) + for i := 1; i <= 2; i++ { + statsTbl.Columns[int64(i)] = &statistics.Column{ + Histogram: *mockStatsHistogram(int64(i), colValues, 10, types.NewFieldType(mysql.TypeLonglong)), + Info: tblInfo.Columns[i-1], + StatsLoadedStatus: statistics.NewStatsFullLoadStatus(), + StatsVer: 2, + } + } + idxValues, err := generateIntDatum(2, 3) + require.NoError(t, err) + tp := types.NewFieldType(mysql.TypeBlob) + statsTbl.Indices[1] = &statistics.Index{ + Histogram: *mockStatsHistogram(1, idxValues, 60, tp), + Info: tblInfo.Indices[0], + StatsVer: 2, + } + generateMapsForMockStatsTbl(statsTbl) + + sctx := testKit.Session() + idxID := tblInfo.Indices[0].ID + vals := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} + count, err := statsTbl.GetRowCountByIndexRanges(sctx, idxID, getRanges(vals, vals)) + require.NoError(t, err) + // estimated row count without any changes + require.Equal(t, float64(360), count) + statsTbl.Count *= 10 + count, err = statsTbl.GetRowCountByIndexRanges(sctx, idxID, getRanges(vals, vals)) + require.NoError(t, err) + // estimated row count after mock modify on the table + require.Equal(t, float64(3600), count) +} diff --git a/statistics/table.go b/statistics/table.go index 81cb4e9bf284f..f22699cfdb95b 100644 --- a/statistics/table.go +++ b/statistics/table.go @@ -101,10 +101,10 @@ type HistColl struct { Indices map[int64]*Index // Idx2ColumnIDs maps the index id to its column ids. It's used to calculate the selectivity in planner. Idx2ColumnIDs map[int64][]int64 - // ColID2IdxID maps the column id to index id whose first column is it. It's used to calculate the selectivity in planner. - ColID2IdxID map[int64]int64 - Count int64 - ModifyCount int64 // Total modify count in a table. + // ColID2IdxIDs maps the column id to a list index ids whose first column is it. It's used to calculate the selectivity in planner. + ColID2IdxIDs map[int64][]int64 + Count int64 + ModifyCount int64 // Total modify count in a table. // HavePhysicalID is true means this HistColl is from single table and have its ID's information. // The physical id is used when try to load column stats from storage. @@ -377,19 +377,19 @@ func (t *Table) ColumnByName(colName string) *Column { } // GetStatsInfo returns their statistics according to the ID of the column or index, including histogram, CMSketch, TopN and FMSketch. -func (t *Table) GetStatsInfo(ID int64, isIndex bool) (int64, *Histogram, *CMSketch, *TopN, *FMSketch) { +func (t *Table) GetStatsInfo(ID int64, isIndex bool) (int64, *Histogram, *CMSketch, *TopN, *FMSketch, bool) { if isIndex { if idxStatsInfo, ok := t.Indices[ID]; ok { - return int64(idxStatsInfo.TotalRowCount()), idxStatsInfo.Histogram.Copy(), idxStatsInfo.CMSketch.Copy(), idxStatsInfo.TopN.Copy(), idxStatsInfo.FMSketch.Copy() + return int64(idxStatsInfo.TotalRowCount()), idxStatsInfo.Histogram.Copy(), idxStatsInfo.CMSketch.Copy(), idxStatsInfo.TopN.Copy(), idxStatsInfo.FMSketch.Copy(), true } // newly added index which is not analyzed yet - return 0, nil, nil, nil, nil + return 0, nil, nil, nil, nil, false } if colStatsInfo, ok := t.Columns[ID]; ok { - return int64(colStatsInfo.TotalRowCount()), colStatsInfo.Histogram.Copy(), colStatsInfo.CMSketch.Copy(), colStatsInfo.TopN.Copy(), colStatsInfo.FMSketch.Copy() + return int64(colStatsInfo.TotalRowCount()), colStatsInfo.Histogram.Copy(), colStatsInfo.CMSketch.Copy(), colStatsInfo.TopN.Copy(), colStatsInfo.FMSketch.Copy(), true } // newly added column which is not analyzed yet - return 0, nil, nil, nil, nil + return 0, nil, nil, nil, nil, false } // GetColRowCount tries to get the row count of the a column if possible. @@ -566,7 +566,7 @@ func (coll *HistColl) GetRowCountByIntColumnRanges(sctx sessionctx.Context, colI } return result, nil } - result, err = c.GetColumnRowCount(sctx, intRanges, coll.Count, true) + result, err = c.GetColumnRowCount(sctx, intRanges, coll.Count, coll.ModifyCount, true) if sc.EnableOptimizerCETrace { CETraceRange(sctx, coll.PhysicalID, []string{c.Info.Name.O}, intRanges, "Column Stats", uint64(result)) } @@ -587,7 +587,7 @@ func (coll *HistColl) GetRowCountByColumnRanges(sctx sessionctx.Context, colID i } return result, err } - result, err := c.GetColumnRowCount(sctx, colRanges, coll.Count, false) + result, err := c.GetColumnRowCount(sctx, colRanges, coll.Count, coll.ModifyCount, false) if sc.EnableOptimizerCETrace { CETraceRange(sctx, coll.PhysicalID, []string{c.Info.Name.O}, colRanges, "Column Stats", uint64(result)) } @@ -623,7 +623,7 @@ func (coll *HistColl) GetRowCountByIndexRanges(sctx sessionctx.Context, idxID in if idx.CMSketch != nil && idx.StatsVer == Version1 { result, err = coll.getIndexRowCount(sctx, idxID, indexRanges) } else { - result, err = idx.GetRowCount(sctx, coll, indexRanges, coll.Count) + result, err = idx.GetRowCount(sctx, coll, indexRanges, coll.Count, coll.ModifyCount) } if sc.EnableOptimizerCETrace { CETraceRange(sctx, coll.PhysicalID, colNames, indexRanges, "Index Stats", uint64(result)) @@ -846,7 +846,7 @@ func (coll *HistColl) ID2UniqueID(columns []*expression.Column) *HistColl { return newColl } -// GenerateHistCollFromColumnInfo generates a new HistColl whose ColID2IdxID and IdxID2ColIDs is built from the given parameter. +// GenerateHistCollFromColumnInfo generates a new HistColl whose ColID2IdxIDs and IdxID2ColIDs is built from the given parameter. func (coll *HistColl) GenerateHistCollFromColumnInfo(infos []*model.ColumnInfo, columns []*expression.Column) *HistColl { newColHistMap := make(map[int64]*Column) colInfoID2UniqueID := make(map[int64]int64, len(columns)) @@ -869,7 +869,7 @@ func (coll *HistColl) GenerateHistCollFromColumnInfo(infos []*model.ColumnInfo, } newIdxHistMap := make(map[int64]*Index) idx2Columns := make(map[int64][]int64) - colID2IdxID := make(map[int64]int64) + colID2IdxIDs := make(map[int64][]int64) for _, idxHist := range coll.Indices { ids := make([]int64, 0, len(idxHist.Info.Columns)) for _, idxCol := range idxHist.Info.Columns { @@ -883,10 +883,13 @@ func (coll *HistColl) GenerateHistCollFromColumnInfo(infos []*model.ColumnInfo, if len(ids) == 0 { continue } - colID2IdxID[ids[0]] = idxHist.ID + colID2IdxIDs[ids[0]] = append(colID2IdxIDs[ids[0]], idxHist.ID) newIdxHistMap[idxHist.ID] = idxHist idx2Columns[idxHist.ID] = ids } + for _, idxIDs := range colID2IdxIDs { + slices.Sort(idxIDs) + } newColl := &HistColl{ PhysicalID: coll.PhysicalID, HavePhysicalID: coll.HavePhysicalID, @@ -895,7 +898,7 @@ func (coll *HistColl) GenerateHistCollFromColumnInfo(infos []*model.ColumnInfo, ModifyCount: coll.ModifyCount, Columns: newColHistMap, Indices: newIdxHistMap, - ColID2IdxID: colID2IdxID, + ColID2IdxIDs: colID2IdxIDs, Idx2ColumnIDs: idx2Columns, } return newColl @@ -956,7 +959,7 @@ func (coll *HistColl) crossValidationSelectivity(sctx sessionctx.Context, idx *I Collators: []collate.Collator{idxPointRange.Collators[i]}, } - rowCount, err := col.GetColumnRowCount(sctx, []*ranger.Range{&rang}, coll.Count, col.IsHandle) + rowCount, err := col.GetColumnRowCount(sctx, []*ranger.Range{&rang}, coll.Count, coll.ModifyCount, col.IsHandle) if err != nil { return 0, 0, err } @@ -1028,7 +1031,7 @@ func (coll *HistColl) getIndexRowCount(sctx sessionctx.Context, idxID int64, ind // on single-column index, use previous way as well, because CMSketch does not contain null // values in this case. if rangePosition == 0 || isSingleColIdxNullRange(idx, ran) { - count, err := idx.GetRowCount(sctx, nil, []*ranger.Range{ran}, coll.Count) + count, err := idx.GetRowCount(sctx, nil, []*ranger.Range{ran}, coll.Count, coll.ModifyCount) if err != nil { return 0, errors.Trace(err) } @@ -1084,8 +1087,9 @@ func (coll *HistColl) getIndexRowCount(sctx sessionctx.Context, idxID int64, ind colID = colIDs[rangePosition] } // prefer index stats over column stats - if idx, ok := coll.ColID2IdxID[colID]; ok { - count, err = coll.GetRowCountByIndexRanges(sctx, idx, []*ranger.Range{&rang}) + if idxIDs, ok := coll.ColID2IdxIDs[colID]; ok && len(idxIDs) > 0 { + idxID := idxIDs[0] + count, err = coll.GetRowCountByIndexRanges(sctx, idxID, []*ranger.Range{&rang}) } else { count, err = coll.GetRowCountByColumnRanges(sctx, colID, []*ranger.Range{&rang}) } diff --git a/statistics/testdata/integration_suite_out.json b/statistics/testdata/integration_suite_out.json index 9e39d3c7d2052..229e05cd0db2a 100644 --- a/statistics/testdata/integration_suite_out.json +++ b/statistics/testdata/integration_suite_out.json @@ -7,19 +7,19 @@ "└─IndexRangeScan_5 5.00 cop[tikv] table:exp_backoff, index:idx(a, b, c, d) range:[1,1], keep order:false" ], [ - "TableReader_7 3.00 root data:Selection_6", - "└─Selection_6 3.00 cop[tikv] eq(test.exp_backoff.b, 1)", - " └─TableFullScan_5 5.00 cop[tikv] table:exp_backoff keep order:false" + "IndexReader_10 3.00 root index:Selection_9", + "└─Selection_9 3.00 cop[tikv] eq(test.exp_backoff.b, 1)", + " └─IndexFullScan_8 5.00 cop[tikv] table:exp_backoff, index:idx(a, b, c, d) keep order:false" ], [ - "TableReader_7 2.00 root data:Selection_6", - "└─Selection_6 2.00 cop[tikv] eq(test.exp_backoff.c, 1)", - " └─TableFullScan_5 5.00 cop[tikv] table:exp_backoff keep order:false" + "IndexReader_10 2.00 root index:Selection_9", + "└─Selection_9 2.00 cop[tikv] eq(test.exp_backoff.c, 1)", + " └─IndexFullScan_8 5.00 cop[tikv] table:exp_backoff, index:idx(a, b, c, d) keep order:false" ], [ - "TableReader_7 3.00 root data:Selection_6", - "└─Selection_6 3.00 cop[tikv] ge(test.exp_backoff.d, 3), le(test.exp_backoff.d, 5)", - " └─TableFullScan_5 5.00 cop[tikv] table:exp_backoff keep order:false" + "IndexReader_10 3.00 root index:Selection_9", + "└─Selection_9 3.00 cop[tikv] ge(test.exp_backoff.d, 3), le(test.exp_backoff.d, 5)", + " └─IndexFullScan_8 5.00 cop[tikv] table:exp_backoff, index:idx(a, b, c, d) keep order:false" ], [ "IndexReader_6 1.36 root index:IndexRangeScan_5", @@ -411,7 +411,7 @@ { "SQL": "explain format = 'brief' select * from t where f regexp '.*111.*'", "Result": [ - "Selection 30.70 root regexp(test.t.f, \".*111.*\")", + "Selection 32.00 root regexp(test.t.f, \".*111.*\")", "└─TableReader 40.00 root data:TableFullScan", " └─TableFullScan 40.00 cop[tikv] table:t keep order:false" ] @@ -419,7 +419,7 @@ { "SQL": "explain format = 'brief' select * from t where f not regexp '.*111.*'", "Result": [ - "Selection 6.30 root not(istrue_with_null(regexp(test.t.f, \".*111.*\")))", + "Selection 32.00 root not(regexp(test.t.f, \".*111.*\"))", "└─TableReader 40.00 root data:TableFullScan", " └─TableFullScan 40.00 cop[tikv] table:t keep order:false" ] @@ -435,7 +435,7 @@ { "SQL": "explain format = 'brief' select * from t where a like '%111%' and f rlike '.*111.*'", "Result": [ - "Selection 23.56 root regexp(test.t.f, \".*111.*\")", + "Selection 24.56 root regexp(test.t.f, \".*111.*\")", "└─TableReader 30.70 root data:Selection", " └─Selection 30.70 cop[tikv] like(test.t.a, \"%111%\", 92)", " └─TableFullScan 40.00 cop[tikv] table:t keep order:false" @@ -641,7 +641,7 @@ { "SQL": "explain format = 'brief' select * from t where f regexp '.*111.*'", "Result": [ - "Selection 30.70 root regexp(test.t.f, \".*111.*\")", + "Selection 32.00 root regexp(test.t.f, \".*111.*\")", "└─TableReader 40.00 root data:TableFullScan", " └─TableFullScan 40.00 cop[tikv] table:t keep order:false" ] @@ -649,7 +649,7 @@ { "SQL": "explain format = 'brief' select * from t where f not regexp '.*111.*'", "Result": [ - "Selection 6.30 root not(istrue_with_null(regexp(test.t.f, \".*111.*\")))", + "Selection 32.00 root not(regexp(test.t.f, \".*111.*\"))", "└─TableReader 40.00 root data:TableFullScan", " └─TableFullScan 40.00 cop[tikv] table:t keep order:false" ] @@ -665,7 +665,7 @@ { "SQL": "explain format = 'brief' select * from t where a like '%111%' and f rlike '.*111.*'", "Result": [ - "Selection 23.56 root regexp(test.t.f, \".*111.*\")", + "Selection 24.56 root regexp(test.t.f, \".*111.*\")", "└─TableReader 30.70 root data:Selection", " └─Selection 30.70 cop[tikv] like(test.t.a, \"%111%\", 92)", " └─TableFullScan 40.00 cop[tikv] table:t keep order:false" diff --git a/statistics/testdata/stats_suite_in.json b/statistics/testdata/stats_suite_in.json index ff76b09ac4c15..bf53c6726c974 100644 --- a/statistics/testdata/stats_suite_in.json +++ b/statistics/testdata/stats_suite_in.json @@ -259,5 +259,41 @@ "End": 0 } ] + }, + { + "name": "TestOutOfRangeEstimationAfterDelete", + "cases": [ + "explain format = 'brief' select * from t where a <= 300", + "explain format = 'brief' select * from t where a < 300", + "explain format = 'brief' select * from t where a <= 500", + "explain format = 'brief' select * from t where a >= 300 and a <= 900", + "explain format = 'brief' select * from t where a >= 900", + "explain format = 'brief' select * from t where a > 900", + "explain format = 'brief' select * from t where a >= 300", + "explain format = 'brief' select * from t where a <= 900", + "explain format = 'brief' select * from t where a > 800 and a < 1000", + "explain format = 'brief' select * from t where a > 900 and a < 1000", + "explain format = 'brief' select * from t where a > 900 and a < 1100", + "explain format = 'brief' select * from t where a > 200 and a < 300", + "explain format = 'brief' select * from t where a > 100 and a < 300" + ] + }, + { + "name": "TestGlobalStatsOutOfRangeEstimationAfterDelete", + "cases": [ + "explain format = 'brief' select * from t where a <= 300", + "explain format = 'brief' select * from t where a < 300", + "explain format = 'brief' select * from t where a <= 500", + "explain format = 'brief' select * from t where a >= 300 and a <= 900", + "explain format = 'brief' select * from t where a >= 900", + "explain format = 'brief' select * from t where a > 900", + "explain format = 'brief' select * from t where a >= 300", + "explain format = 'brief' select * from t where a <= 900", + "explain format = 'brief' select * from t where a > 800 and a < 1000", + "explain format = 'brief' select * from t where a > 900 and a < 1000", + "explain format = 'brief' select * from t where a > 900 and a < 1100", + "explain format = 'brief' select * from t where a > 200 and a < 300", + "explain format = 'brief' select * from t where a > 100 and a < 300" + ] } ] diff --git a/statistics/testdata/stats_suite_out.json b/statistics/testdata/stats_suite_out.json index d07b336ccbfbd..fea01ef77bee1 100644 --- a/statistics/testdata/stats_suite_out.json +++ b/statistics/testdata/stats_suite_out.json @@ -170,34 +170,34 @@ " └─TableFullScan_5 8.00 cop[tikv] table:tint keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:singular(a) range:[1,1], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.a, 1)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:singular(a) range:[4,4], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.a, 4)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:singular(a) range:[8,8], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.a, 8)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:singular(a) range:[1.00000000000000000000,1.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.a, 1)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:singular(a) range:[4.00000000000000000000,4.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.a, 4)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:singular(a) range:[8.00000000000000000000,8.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.a, 8)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ "TableReader_7 1.00 root data:Selection_6", @@ -260,34 +260,34 @@ " └─TableFullScan_5 8.00 cop[tikv] table:tint keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:multi(b, c) range:[1 1,1 1], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.b, 1), eq(test.tdouble.c, 1)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:multi(b, c) range:[4 4,4 4], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.b, 4), eq(test.tdouble.c, 4)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:multi(b, c) range:[8 8,8 8], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.b, 8), eq(test.tdouble.c, 8)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:multi(b, c) range:[1.00000000000000000000 1.00000000000000000000,1.00000000000000000000 1.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.b, 1), eq(test.tdecimal.c, 1)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:multi(b, c) range:[4.00000000000000000000 4.00000000000000000000,4.00000000000000000000 4.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.b, 4), eq(test.tdecimal.c, 4)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:multi(b, c) range:[8.00000000000000000000 8.00000000000000000000,8.00000000000000000000 8.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.b, 8), eq(test.tdecimal.c, 8)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ "TableReader_7 1.00 root data:Selection_6", @@ -335,34 +335,34 @@ " └─TableFullScan_5 8.00 cop[tikv] table:tint keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:multi(b, c) range:[1,1], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.b, 1)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:multi(b, c) range:[4,4], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.b, 4)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdouble, index:multi(b, c) range:[8,8], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdouble keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdouble.b, 8)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdouble keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:multi(b, c) range:[1.00000000000000000000,1.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.b, 1)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:multi(b, c) range:[4.00000000000000000000,4.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.b, 4)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ - "IndexLookUp_10 1.00 root ", - "├─IndexRangeScan_8(Build) 1.00 cop[tikv] table:tdecimal, index:multi(b, c) range:[8.00000000000000000000,8.00000000000000000000], keep order:false", - "└─TableRowIDScan_9(Probe) 1.00 cop[tikv] table:tdecimal keep order:false" + "TableReader_7 1.00 root data:Selection_6", + "└─Selection_6 1.00 cop[tikv] eq(test.tdecimal.b, 8)", + " └─TableFullScan_5 8.00 cop[tikv] table:tdecimal keep order:false" ], [ "TableReader_7 1.00 root data:Selection_6", @@ -759,5 +759,223 @@ "Count": 7.5 } ] + }, + { + "Name": "TestOutOfRangeEstimationAfterDelete", + "Cases": [ + { + "SQL": "explain format = 'brief' select * from t where a <= 300", + "Result": [ + "TableReader 1003.33 root data:Selection", + "└─Selection 1003.33 cop[tikv] le(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a < 300", + "Result": [ + "TableReader 1000.00 root data:Selection", + "└─Selection 1000.00 cop[tikv] lt(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a <= 500", + "Result": [ + "TableReader 1670.00 root data:Selection", + "└─Selection 1670.00 cop[tikv] le(test.t.a, 500)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a >= 300 and a <= 900", + "Result": [ + "TableReader 2000.00 root data:Selection", + "└─Selection 2000.00 cop[tikv] ge(test.t.a, 300), le(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a >= 900", + "Result": [ + "TableReader 1000.00 root data:Selection", + "└─Selection 1000.00 cop[tikv] ge(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 900", + "Result": [ + "TableReader 1000.00 root data:Selection", + "└─Selection 1000.00 cop[tikv] gt(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a >= 300", + "Result": [ + "TableReader 2000.00 root data:Selection", + "└─Selection 2000.00 cop[tikv] ge(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a <= 900", + "Result": [ + "TableReader 2000.00 root data:Selection", + "└─Selection 2000.00 cop[tikv] le(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 800 and a < 1000", + "Result": [ + "TableReader 793.13 root data:Selection", + "└─Selection 793.13 cop[tikv] gt(test.t.a, 800), lt(test.t.a, 1000)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 900 and a < 1000", + "Result": [ + "TableReader 458.12 root data:Selection", + "└─Selection 458.12 cop[tikv] gt(test.t.a, 900), lt(test.t.a, 1000)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 900 and a < 1100", + "Result": [ + "TableReader 832.49 root data:Selection", + "└─Selection 832.49 cop[tikv] gt(test.t.a, 900), lt(test.t.a, 1100)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 200 and a < 300", + "Result": [ + "TableReader 458.12 root data:Selection", + "└─Selection 458.12 cop[tikv] gt(test.t.a, 200), lt(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 100 and a < 300", + "Result": [ + "TableReader 832.49 root data:Selection", + "└─Selection 832.49 cop[tikv] gt(test.t.a, 100), lt(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + } + ] + }, + { + "Name": "TestGlobalStatsOutOfRangeEstimationAfterDelete", + "Cases": [ + { + "SQL": "explain format = 'brief' select * from t where a <= 300", + "Result": [ + "TableReader 1003.33 root partition:p0 data:Selection", + "└─Selection 1003.33 cop[tikv] le(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a < 300", + "Result": [ + "TableReader 1000.00 root partition:p0 data:Selection", + "└─Selection 1000.00 cop[tikv] lt(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a <= 500", + "Result": [ + "TableReader 1670.00 root partition:p0,p1 data:Selection", + "└─Selection 1670.00 cop[tikv] le(test.t.a, 500)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a >= 300 and a <= 900", + "Result": [ + "TableReader 2000.00 root partition:p0,p1,p2,p3 data:Selection", + "└─Selection 2000.00 cop[tikv] ge(test.t.a, 300), le(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a >= 900", + "Result": [ + "TableReader 1000.00 root partition:p3,p4 data:Selection", + "└─Selection 1000.00 cop[tikv] ge(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 900", + "Result": [ + "TableReader 1000.00 root partition:p3,p4 data:Selection", + "└─Selection 1000.00 cop[tikv] gt(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a >= 300", + "Result": [ + "TableReader 2000.00 root partition:all data:Selection", + "└─Selection 2000.00 cop[tikv] ge(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a <= 900", + "Result": [ + "TableReader 2000.00 root partition:p0,p1,p2,p3 data:Selection", + "└─Selection 2000.00 cop[tikv] le(test.t.a, 900)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 800 and a < 1000", + "Result": [ + "TableReader 793.20 root partition:p3 data:Selection", + "└─Selection 793.20 cop[tikv] gt(test.t.a, 800), lt(test.t.a, 1000)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 900 and a < 1000", + "Result": [ + "TableReader 458.19 root partition:p3 data:Selection", + "└─Selection 458.19 cop[tikv] gt(test.t.a, 900), lt(test.t.a, 1000)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 900 and a < 1100", + "Result": [ + "TableReader 832.77 root partition:p3,p4 data:Selection", + "└─Selection 832.77 cop[tikv] gt(test.t.a, 900), lt(test.t.a, 1100)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 200 and a < 300", + "Result": [ + "TableReader 459.03 root partition:p0 data:Selection", + "└─Selection 459.03 cop[tikv] gt(test.t.a, 200), lt(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + }, + { + "SQL": "explain format = 'brief' select * from t where a > 100 and a < 300", + "Result": [ + "TableReader 834.45 root partition:p0 data:Selection", + "└─Selection 834.45 cop[tikv] gt(test.t.a, 100), lt(test.t.a, 300)", + " └─TableFullScan 2000.00 cop[tikv] table:t keep order:false" + ] + } + ] } ] diff --git a/store/BUILD.bazel b/store/BUILD.bazel index dc33aa14eea94..bf8faa0dde9b9 100644 --- a/store/BUILD.bazel +++ b/store/BUILD.bazel @@ -10,6 +10,7 @@ go_library( "//util", "//util/logutil", "@com_github_pingcap_errors//:errors", + "@com_github_pingcap_kvproto//pkg/pdpb", "@org_uber_go_zap//:zap", ], ) diff --git a/store/copr/BUILD.bazel b/store/copr/BUILD.bazel index 674ca8f6c54e1..66c62b8e367e5 100644 --- a/store/copr/BUILD.bazel +++ b/store/copr/BUILD.bazel @@ -9,6 +9,7 @@ go_library( "coprocessor_cache.go", "key_ranges.go", "mpp.go", + "mpp_probe.go", "region_cache.go", "store.go", ], @@ -33,9 +34,11 @@ go_library( "//util/trxevents", "@com_github_dgraph_io_ristretto//:ristretto", "@com_github_gogo_protobuf//proto", + "@com_github_opentracing_opentracing_go//:opentracing-go", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_kvproto//pkg/coprocessor", + "@com_github_pingcap_kvproto//pkg/errorpb", "@com_github_pingcap_kvproto//pkg/kvrpcpb", "@com_github_pingcap_kvproto//pkg/metapb", "@com_github_pingcap_kvproto//pkg/mpp", @@ -65,6 +68,7 @@ go_test( "coprocessor_test.go", "key_ranges_test.go", "main_test.go", + "mpp_probe_test.go", ], embed = [":copr"], flaky = True, @@ -74,11 +78,16 @@ go_test( "//store/driver/backoff", "//testkit/testsetup", "//util/paging", + "//util/trxevents", + "@com_github_pingcap_errors//:errors", "@com_github_pingcap_kvproto//pkg/coprocessor", + "@com_github_pingcap_kvproto//pkg/mpp", + "@com_github_stathat_consistent//:consistent", "@com_github_stretchr_testify//require", "@com_github_tikv_client_go_v2//config", "@com_github_tikv_client_go_v2//testutils", "@com_github_tikv_client_go_v2//tikv", + "@com_github_tikv_client_go_v2//tikvrpc", "@org_uber_go_goleak//:goleak", ], ) diff --git a/store/copr/batch_coprocessor.go b/store/copr/batch_coprocessor.go index bfd3bbcc94fdd..9f9d4ef6fb002 100644 --- a/store/copr/batch_coprocessor.go +++ b/store/copr/batch_coprocessor.go @@ -21,6 +21,7 @@ import ( "io" "math" "strconv" + "strings" "sync" "sync/atomic" "time" @@ -29,8 +30,8 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/coprocessor" "github.com/pingcap/kvproto/pkg/kvrpcpb" - "github.com/pingcap/kvproto/pkg/mpp" "github.com/pingcap/log" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/store/driver/backoff" derr "github.com/pingcap/tidb/store/driver/error" @@ -293,12 +294,11 @@ func balanceBatchCopTaskWithContinuity(storeTaskMap map[uint64]*batchCopTask, ca // // The second balance strategy: Not only consider the region count between TiFlash stores, but also try to make the regions' range continuous(stored in TiFlash closely). // If balanceWithContinuity is true, the second balance strategy is enable. -func balanceBatchCopTask(ctx context.Context, kvStore *kvStore, originalTasks []*batchCopTask, mppStoreLastFailTime *sync.Map, ttl time.Duration, balanceWithContinuity bool, balanceContinuousRegionCount int64) []*batchCopTask { +func balanceBatchCopTask(ctx context.Context, kvStore *kvStore, originalTasks []*batchCopTask, isMPP bool, ttl time.Duration, balanceWithContinuity bool, balanceContinuousRegionCount int64) []*batchCopTask { if len(originalTasks) == 0 { log.Info("Batch cop task balancer got an empty task set.") return originalTasks } - isMPP := mppStoreLastFailTime != nil // for mpp, we still need to detect the store availability if len(originalTasks) <= 1 && !isMPP { return originalTasks @@ -323,64 +323,15 @@ func balanceBatchCopTask(ctx context.Context, kvStore *kvStore, originalTasks [] storeTaskMap[taskStoreID] = batchTask } } else { - logutil.BgLogger().Info("detecting available mpp stores") - // decide the available stores stores := cache.RegionCache.GetTiFlashStores() - var wg sync.WaitGroup - var mu sync.Mutex - wg.Add(len(stores)) - cur := time.Now() - for i := range stores { - go func(idx int) { - defer wg.Done() - s := stores[idx] - - var lastAny any - var ok bool - mu.Lock() - if lastAny, ok = mppStoreLastFailTime.Load(s.GetAddr()); ok && cur.Sub(lastAny.(time.Time)) < 100*time.Millisecond { - // The interval time is so short that may happen in a same query, so we needn't to check again. - mu.Unlock() - return - } else if !ok { - lastAny = time.Time{} - } - mu.Unlock() - - resp, err := kvStore.GetTiKVClient().SendRequest(ctx, s.GetAddr(), &tikvrpc.Request{ - Type: tikvrpc.CmdMPPAlive, - StoreTp: tikvrpc.TiFlash, - Req: &mpp.IsAliveRequest{}, - Context: kvrpcpb.Context{}, - }, 2*time.Second) - - if err != nil || !resp.Resp.(*mpp.IsAliveResponse).Available { - errMsg := "store not ready to serve" - if err != nil { - errMsg = err.Error() - } - logutil.BgLogger().Warn("Store is not ready", zap.String("store address", s.GetAddr()), zap.String("err message", errMsg)) - mu.Lock() - mppStoreLastFailTime.Store(s.GetAddr(), time.Now()) - mu.Unlock() - return - } - - if cur.Sub(lastAny.(time.Time)) < ttl { - logutil.BgLogger().Warn("Cannot detect store's availability because the current time has not reached MPPStoreLastFailTime + MPPStoreFailTTL", zap.String("store address", s.GetAddr()), zap.Time("last fail time", lastAny.(time.Time))) - return - } - - mu.Lock() - defer mu.Unlock() - storeTaskMap[s.StoreID()] = &batchCopTask{ - storeAddr: s.GetAddr(), - cmdType: originalTasks[0].cmdType, - ctx: &tikv.RPCContext{Addr: s.GetAddr(), Store: s}, - } - }(i) + aliveStores := filterAliveStores(ctx, stores, ttl, kvStore) + for _, s := range aliveStores { + storeTaskMap[s.StoreID()] = &batchCopTask{ + storeAddr: s.GetAddr(), + cmdType: originalTasks[0].cmdType, + ctx: &tikv.RPCContext{Addr: s.GetAddr(), Store: s}, + } } - wg.Wait() } var candidateRegionInfos []RegionInfo @@ -528,12 +479,34 @@ func balanceBatchCopTask(ctx context.Context, kvStore *kvStore, originalTasks [] return ret } -func buildBatchCopTasksForNonPartitionedTable(bo *backoff.Backoffer, store *kvStore, ranges *KeyRanges, storeType kv.StoreType, mppStoreLastFailTime *sync.Map, ttl time.Duration, balanceWithContinuity bool, balanceContinuousRegionCount int64) ([]*batchCopTask, error) { - return buildBatchCopTasksCore(bo, store, []*KeyRanges{ranges}, storeType, mppStoreLastFailTime, ttl, balanceWithContinuity, balanceContinuousRegionCount) +func buildBatchCopTasksForNonPartitionedTable(bo *backoff.Backoffer, + store *kvStore, + ranges *KeyRanges, + storeType kv.StoreType, + isMPP bool, + ttl time.Duration, + balanceWithContinuity bool, + balanceContinuousRegionCount int64) ([]*batchCopTask, error) { + if config.GetGlobalConfig().DisaggregatedTiFlash { + return buildBatchCopTasksConsistentHash(bo, store, []*KeyRanges{ranges}, storeType, ttl) + } + return buildBatchCopTasksCore(bo, store, []*KeyRanges{ranges}, storeType, isMPP, ttl, balanceWithContinuity, balanceContinuousRegionCount) } -func buildBatchCopTasksForPartitionedTable(bo *backoff.Backoffer, store *kvStore, rangesForEachPhysicalTable []*KeyRanges, storeType kv.StoreType, mppStoreLastFailTime *sync.Map, ttl time.Duration, balanceWithContinuity bool, balanceContinuousRegionCount int64, partitionIDs []int64) ([]*batchCopTask, error) { - batchTasks, err := buildBatchCopTasksCore(bo, store, rangesForEachPhysicalTable, storeType, mppStoreLastFailTime, ttl, balanceWithContinuity, balanceContinuousRegionCount) +func buildBatchCopTasksForPartitionedTable(bo *backoff.Backoffer, + store *kvStore, + rangesForEachPhysicalTable []*KeyRanges, + storeType kv.StoreType, + isMPP bool, + ttl time.Duration, + balanceWithContinuity bool, + balanceContinuousRegionCount int64, + partitionIDs []int64) (batchTasks []*batchCopTask, err error) { + if config.GetGlobalConfig().DisaggregatedTiFlash { + batchTasks, err = buildBatchCopTasksConsistentHash(bo, store, rangesForEachPhysicalTable, storeType, ttl) + } else { + batchTasks, err = buildBatchCopTasksCore(bo, store, rangesForEachPhysicalTable, storeType, isMPP, ttl, balanceWithContinuity, balanceContinuousRegionCount) + } if err != nil { return nil, err } @@ -542,10 +515,158 @@ func buildBatchCopTasksForPartitionedTable(bo *backoff.Backoffer, store *kvStore return batchTasks, nil } +func filterAliveStores(ctx context.Context, stores []*tikv.Store, ttl time.Duration, kvStore *kvStore) []*tikv.Store { + var aliveStores []*tikv.Store + var wg sync.WaitGroup + var mu sync.Mutex + wg.Add(len(stores)) + for i := range stores { + go func(idx int) { + defer wg.Done() + s := stores[idx] + + // Check if store is failed already. + if ok := GlobalMPPFailedStoreProber.IsRecovery(ctx, s.GetAddr(), ttl); !ok { + return + } + + tikvClient := kvStore.GetTiKVClient() + if ok := detectMPPStore(ctx, tikvClient, s.GetAddr(), DetectTimeoutLimit); !ok { + GlobalMPPFailedStoreProber.Add(ctx, s.GetAddr(), tikvClient) + return + } + + mu.Lock() + defer mu.Unlock() + aliveStores = append(aliveStores, s) + }(i) + } + wg.Wait() + + logutil.BgLogger().Info("detecting available mpp stores", zap.Any("total", len(stores)), zap.Any("alive", len(aliveStores))) + return aliveStores +} + +// 1. Split range by region location to build copTasks. +// 2. For each copTask build its rpcCtx , the target tiflash_compute node will be chosen using consistent hash. +// 3. All copTasks that will be sent to one tiflash_compute node are put in one batchCopTask. +func buildBatchCopTasksConsistentHash(bo *backoff.Backoffer, + kvStore *kvStore, + rangesForEachPhysicalTable []*KeyRanges, + storeType kv.StoreType, + ttl time.Duration) (res []*batchCopTask, err error) { + const cmdType = tikvrpc.CmdBatchCop + var retryNum int + cache := kvStore.GetRegionCache() + + for { + retryNum++ + var rangesLen int + tasks := make([]*copTask, 0) + regionIDs := make([]tikv.RegionVerID, 0) + + for i, ranges := range rangesForEachPhysicalTable { + rangesLen += ranges.Len() + locations, err := cache.SplitKeyRangesByLocations(bo, ranges) + if err != nil { + return nil, errors.Trace(err) + } + for _, lo := range locations { + tasks = append(tasks, &copTask{ + region: lo.Location.Region, + ranges: lo.Ranges, + cmdType: cmdType, + storeType: storeType, + partitionIndex: int64(i), + }) + regionIDs = append(regionIDs, lo.Location.Region) + } + } + + stores, err := cache.GetTiFlashComputeStores(bo.TiKVBackoffer()) + if err != nil { + return nil, err + } + stores = filterAliveStores(bo.GetCtx(), stores, ttl, kvStore) + if len(stores) == 0 { + return nil, errors.New("tiflash_compute node is unavailable") + } + + rpcCtxs, err := cache.GetTiFlashComputeRPCContextByConsistentHash(bo.TiKVBackoffer(), regionIDs, stores) + if err != nil { + return nil, err + } + if rpcCtxs == nil { + logutil.BgLogger().Info("buildBatchCopTasksConsistentHash retry because rcpCtx is nil", zap.Int("retryNum", retryNum)) + err := bo.Backoff(tikv.BoTiFlashRPC(), errors.New("Cannot find region with TiFlash peer")) + if err != nil { + return nil, errors.Trace(err) + } + continue + } + if len(rpcCtxs) != len(tasks) { + return nil, errors.Errorf("length should be equal, len(rpcCtxs): %d, len(tasks): %d", len(rpcCtxs), len(tasks)) + } + taskMap := make(map[string]*batchCopTask) + for i, rpcCtx := range rpcCtxs { + regionInfo := RegionInfo{ + // tasks and rpcCtxs are correspond to each other. + Region: tasks[i].region, + Meta: rpcCtx.Meta, + Ranges: tasks[i].ranges, + AllStores: []uint64{rpcCtx.Store.StoreID()}, + PartitionIndex: tasks[i].partitionIndex, + } + if batchTask, ok := taskMap[rpcCtx.Addr]; ok { + batchTask.regionInfos = append(batchTask.regionInfos, regionInfo) + } else { + batchTask := &batchCopTask{ + storeAddr: rpcCtx.Addr, + cmdType: cmdType, + ctx: rpcCtx, + regionInfos: []RegionInfo{regionInfo}, + } + taskMap[rpcCtx.Addr] = batchTask + res = append(res, batchTask) + } + } + logutil.BgLogger().Info("buildBatchCopTasksConsistentHash done", zap.Any("len(tasks)", len(taskMap)), zap.Any("len(tiflash_compute)", len(stores))) + break + } + + failpointCheckForConsistentHash(res) + return res, nil +} + +func failpointCheckForConsistentHash(tasks []*batchCopTask) { + failpoint.Inject("checkOnlyDispatchToTiFlashComputeNodes", func(val failpoint.Value) { + logutil.BgLogger().Debug("in checkOnlyDispatchToTiFlashComputeNodes") + + // This failpoint will be tested in test-infra case, because we needs setup a cluster. + // All tiflash_compute nodes addrs are stored in val, separated by semicolon. + str := val.(string) + addrs := strings.Split(str, ";") + if len(addrs) < 1 { + err := fmt.Sprintf("unexpected length of tiflash_compute node addrs: %v, %s", len(addrs), str) + panic(err) + } + addrMap := make(map[string]struct{}) + for _, addr := range addrs { + addrMap[addr] = struct{}{} + } + for _, batchTask := range tasks { + if _, ok := addrMap[batchTask.storeAddr]; !ok { + err := errors.Errorf("batchCopTask send to node which is not tiflash_compute: %v(tiflash_compute nodes: %s)", batchTask.storeAddr, str) + panic(err) + } + } + }) +} + // When `partitionIDs != nil`, it means that buildBatchCopTasksCore is constructing a batch cop tasks for PartitionTableScan. // At this time, `len(rangesForEachPhysicalTable) == len(partitionIDs)` and `rangesForEachPhysicalTable[i]` is for partition `partitionIDs[i]`. // Otherwise, `rangesForEachPhysicalTable[0]` indicates the range for the single physical table. -func buildBatchCopTasksCore(bo *backoff.Backoffer, store *kvStore, rangesForEachPhysicalTable []*KeyRanges, storeType kv.StoreType, mppStoreLastFailTime *sync.Map, ttl time.Duration, balanceWithContinuity bool, balanceContinuousRegionCount int64) ([]*batchCopTask, error) { +func buildBatchCopTasksCore(bo *backoff.Backoffer, store *kvStore, rangesForEachPhysicalTable []*KeyRanges, storeType kv.StoreType, isMPP bool, ttl time.Duration, balanceWithContinuity bool, balanceContinuousRegionCount int64) ([]*batchCopTask, error) { cache := store.GetRegionCache() start := time.Now() const cmdType = tikvrpc.CmdBatchCop @@ -575,7 +696,6 @@ func buildBatchCopTasksCore(bo *backoff.Backoffer, store *kvStore, rangesForEach storeTaskMap := make(map[string]*batchCopTask) needRetry := false - isMPP := mppStoreLastFailTime != nil for _, task := range tasks { rpcCtx, err := cache.GetTiFlashRPCContext(bo.TiKVBackoffer(), task.region, isMPP) if err != nil { @@ -627,7 +747,7 @@ func buildBatchCopTasksCore(bo *backoff.Backoffer, store *kvStore, rangesForEach logutil.BgLogger().Debug(msg) } balanceStart := time.Now() - batchTasks = balanceBatchCopTask(bo.GetCtx(), store, batchTasks, mppStoreLastFailTime, ttl, balanceWithContinuity, balanceContinuousRegionCount) + batchTasks = balanceBatchCopTask(bo.GetCtx(), store, batchTasks, isMPP, ttl, balanceWithContinuity, balanceContinuousRegionCount) balanceElapsed := time.Since(balanceStart) if log.GetLevel() <= zap.DebugLevel { msg := "After region balance:" @@ -693,10 +813,11 @@ func (c *CopClient) sendBatch(ctx context.Context, req *kv.Request, vars *tikv.V keyRanges = append(keyRanges, NewKeyRanges(pi.KeyRanges)) partitionIDs = append(partitionIDs, pi.ID) } - tasks, err = buildBatchCopTasksForPartitionedTable(bo, c.store.kvStore, keyRanges, req.StoreType, nil, 0, false, 0, partitionIDs) + tasks, err = buildBatchCopTasksForPartitionedTable(bo, c.store.kvStore, keyRanges, req.StoreType, false, 0, false, 0, partitionIDs) } else { - ranges := NewKeyRanges(req.KeyRanges) - tasks, err = buildBatchCopTasksForNonPartitionedTable(bo, c.store.kvStore, ranges, req.StoreType, nil, 0, false, 0) + // TODO: merge the if branch. + ranges := NewKeyRanges(req.KeyRanges.FirstPartitionRange()) + tasks, err = buildBatchCopTasksForNonPartitionedTable(bo, c.store.kvStore, ranges, req.StoreType, false, 0, false, 0) } if err != nil { @@ -843,7 +964,7 @@ func (b *batchCopIterator) retryBatchCopTask(ctx context.Context, bo *backoff.Ba ranges = append(ranges, *ran) }) } - ret, err := buildBatchCopTasksForNonPartitionedTable(bo, b.store, NewKeyRanges(ranges), b.req.StoreType, nil, 0, false, 0) + ret, err := buildBatchCopTasksForNonPartitionedTable(bo, b.store, NewKeyRanges(ranges), b.req.StoreType, false, 0, false, 0) return ret, err } // Retry Partition Table Scan @@ -862,7 +983,7 @@ func (b *batchCopIterator) retryBatchCopTask(ctx context.Context, bo *backoff.Ba } keyRanges = append(keyRanges, NewKeyRanges(ranges)) } - ret, err := buildBatchCopTasksForPartitionedTable(bo, b.store, keyRanges, b.req.StoreType, nil, 0, false, 0, pid) + ret, err := buildBatchCopTasksForPartitionedTable(bo, b.store, keyRanges, b.req.StoreType, false, 0, false, 0, pid) return ret, err } @@ -895,7 +1016,7 @@ func (b *batchCopIterator) handleTaskOnce(ctx context.Context, bo *backoff.Backo if b.req.ResourceGroupTagger != nil { b.req.ResourceGroupTagger(req) } - req.StoreTp = tikvrpc.TiFlash + req.StoreTp = getEndPointType(kv.TiFlash) logutil.BgLogger().Debug("send batch request to ", zap.String("req info", req.String()), zap.Int("cop task len", len(task.regionInfos))) resp, retry, cancel, err := sender.SendReqToAddr(bo, task.ctx, task.regionInfos, req, readTimeoutUltraLong) diff --git a/store/copr/batch_coprocessor_test.go b/store/copr/batch_coprocessor_test.go index aafa19071a392..3e10ce627b1f6 100644 --- a/store/copr/batch_coprocessor_test.go +++ b/store/copr/batch_coprocessor_test.go @@ -22,6 +22,7 @@ import ( "time" "github.com/pingcap/tidb/kv" + "github.com/stathat/consistent" "github.com/stretchr/testify/require" "github.com/tikv/client-go/v2/tikv" ) @@ -119,13 +120,13 @@ func TestBalanceBatchCopTaskWithContinuity(t *testing.T) { func TestBalanceBatchCopTaskWithEmptyTaskSet(t *testing.T) { { var nilTaskSet []*batchCopTask - nilResult := balanceBatchCopTask(nil, nil, nilTaskSet, nil, time.Second, false, 0) + nilResult := balanceBatchCopTask(nil, nil, nilTaskSet, false, time.Second, false, 0) require.True(t, nilResult == nil) } { emptyTaskSet := make([]*batchCopTask, 0) - emptyResult := balanceBatchCopTask(nil, nil, emptyTaskSet, nil, time.Second, false, 0) + emptyResult := balanceBatchCopTask(nil, nil, emptyTaskSet, false, time.Second, false, 0) require.True(t, emptyResult != nil) require.True(t, len(emptyResult) == 0) } @@ -150,3 +151,57 @@ func TestDeepCopyStoreTaskMap(t *testing.T) { require.Equal(t, 2, len(task.regionInfos)) } } + +// Make sure no duplicated ip:addr. +func generateOneAddr() string { + var ip string + for i := 0; i < 4; i++ { + if i != 0 { + ip += "." + } + ip += strconv.Itoa(rand.Intn(255)) + } + return ip + ":" + strconv.Itoa(rand.Intn(65535)) +} + +func generateDifferentAddrs(num int) (res []string) { + addrMap := make(map[string]struct{}) + for len(addrMap) < num { + addr := generateOneAddr() + if _, ok := addrMap[addr]; !ok { + addrMap[addr] = struct{}{} + } + } + for addr := range addrMap { + res = append(res, addr) + } + return +} + +func TestConsistentHash(t *testing.T) { + allAddrs := generateDifferentAddrs(100) + + computeNodes := allAddrs[:30] + storageNodes := allAddrs[30:] + firstRoundMap := make(map[string]string) + for round := 0; round < 100; round++ { + hasher := consistent.New() + rand.Shuffle(len(computeNodes), func(i, j int) { + computeNodes[i], computeNodes[j] = computeNodes[j], computeNodes[i] + }) + for _, computeNode := range computeNodes { + hasher.Add(computeNode) + } + for _, storageNode := range storageNodes { + computeNode, err := hasher.Get(storageNode) + require.NoError(t, err) + if round == 0 { + firstRoundMap[storageNode] = computeNode + } else { + firstRoundAddr, ok := firstRoundMap[storageNode] + require.True(t, ok) + require.Equal(t, firstRoundAddr, computeNode) + } + } + } +} diff --git a/ddl/concurrentddltest/BUILD.bazel b/store/copr/copr_test/BUILD.bazel similarity index 53% rename from ddl/concurrentddltest/BUILD.bazel rename to store/copr/copr_test/BUILD.bazel index 81b86bf3f3856..af7d46d052bf5 100644 --- a/ddl/concurrentddltest/BUILD.bazel +++ b/store/copr/copr_test/BUILD.bazel @@ -1,24 +1,21 @@ load("@io_bazel_rules_go//go:def.bzl", "go_test") go_test( - name = "concurrentddltest_test", - timeout = "short", + name = "copr_test_test", srcs = [ + "coprocessor_test.go", "main_test.go", - "switch_test.go", ], - flaky = True, - race = "on", deps = [ "//config", - "//ddl", "//kv", - "//meta", - "//testkit", + "//store/copr", + "//store/mockstore", + "//testkit/testmain", "//testkit/testsetup", - "//util", "@com_github_stretchr_testify//require", - "@org_uber_go_atomic//:atomic", + "@com_github_tikv_client_go_v2//testutils", + "@com_github_tikv_client_go_v2//tikv", "@org_uber_go_goleak//:goleak", ], ) diff --git a/store/copr/copr_test/coprocessor_test.go b/store/copr/copr_test/coprocessor_test.go new file mode 100644 index 0000000000000..7931fb8432675 --- /dev/null +++ b/store/copr/copr_test/coprocessor_test.go @@ -0,0 +1,169 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package copr_test + +import ( + "context" + "testing" + + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/store/copr" + "github.com/pingcap/tidb/store/mockstore" + "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/testutils" +) + +func TestBuildCopIteratorWithRowCountHint(t *testing.T) { + // nil --- 'g' --- 'n' --- 't' --- nil + // <- 0 -> <- 1 -> <- 2 -> <- 3 -> + store, err := mockstore.NewMockStore( + mockstore.WithClusterInspector(func(c testutils.Cluster) { + mockstore.BootstrapWithMultiRegions(c, []byte("g"), []byte("n"), []byte("t")) + }), + ) + require.NoError(t, err) + defer require.NoError(t, store.Close()) + copClient := store.GetClient().(*copr.CopClient) + ctx := context.Background() + killed := uint32(0) + vars := kv.NewVariables(&killed) + opt := &kv.ClientSendOption{} + + ranges := copr.BuildKeyRanges("a", "c", "d", "e", "h", "x", "y", "z") + req := &kv.Request{ + Tp: kv.ReqTypeDAG, + KeyRanges: kv.NewNonParitionedKeyRangesWithHint(ranges, []int{1, 1, 3, copr.CopSmallTaskRow}), + Concurrency: 15, + } + it, errRes := copClient.BuildCopIterator(ctx, req, vars, opt) + require.Nil(t, errRes) + conc, smallConc := it.GetConcurrency() + rateLimit := it.GetSendRate() + require.Equal(t, conc, 1) + require.Equal(t, smallConc, 1) + require.Equal(t, rateLimit.GetCapacity(), 2) + + ranges = copr.BuildKeyRanges("a", "c", "d", "e", "h", "x", "y", "z") + req = &kv.Request{ + Tp: kv.ReqTypeDAG, + KeyRanges: kv.NewNonParitionedKeyRangesWithHint(ranges, []int{1, 1, 3, 3}), + Concurrency: 15, + } + it, errRes = copClient.BuildCopIterator(ctx, req, vars, opt) + require.Nil(t, errRes) + conc, smallConc = it.GetConcurrency() + rateLimit = it.GetSendRate() + require.Equal(t, conc, 1) + require.Equal(t, smallConc, 2) + require.Equal(t, rateLimit.GetCapacity(), 3) + + // cross-region long range + ranges = copr.BuildKeyRanges("a", "z") + req = &kv.Request{ + Tp: kv.ReqTypeDAG, + KeyRanges: kv.NewNonParitionedKeyRangesWithHint(ranges, []int{10}), + Concurrency: 15, + } + it, errRes = copClient.BuildCopIterator(ctx, req, vars, opt) + require.Nil(t, errRes) + conc, smallConc = it.GetConcurrency() + rateLimit = it.GetSendRate() + require.Equal(t, conc, 1) + require.Equal(t, smallConc, 2) + require.Equal(t, rateLimit.GetCapacity(), 3) + + ranges = copr.BuildKeyRanges("a", "z") + req = &kv.Request{ + Tp: kv.ReqTypeDAG, + KeyRanges: kv.NewNonParitionedKeyRangesWithHint(ranges, []int{copr.CopSmallTaskRow + 1}), + Concurrency: 15, + } + it, errRes = copClient.BuildCopIterator(ctx, req, vars, opt) + require.Nil(t, errRes) + conc, smallConc = it.GetConcurrency() + rateLimit = it.GetSendRate() + require.Equal(t, conc, 4) + require.Equal(t, smallConc, 0) + require.Equal(t, rateLimit.GetCapacity(), 4) +} + +func TestBuildCopIteratorWithBatchStoreCopr(t *testing.T) { + // nil --- 'g' --- 'n' --- 't' --- nil + // <- 0 -> <- 1 -> <- 2 -> <- 3 -> + store, err := mockstore.NewMockStore( + mockstore.WithClusterInspector(func(c testutils.Cluster) { + mockstore.BootstrapWithMultiRegions(c, []byte("g"), []byte("n"), []byte("t")) + }), + ) + require.NoError(t, err) + defer require.NoError(t, store.Close()) + copClient := store.GetClient().(*copr.CopClient) + ctx := context.Background() + killed := uint32(0) + vars := kv.NewVariables(&killed) + opt := &kv.ClientSendOption{} + + ranges := copr.BuildKeyRanges("a", "c", "d", "e", "h", "x", "y", "z") + req := &kv.Request{ + Tp: kv.ReqTypeDAG, + KeyRanges: kv.NewNonParitionedKeyRangesWithHint(ranges, []int{1, 1, 3, 3}), + Concurrency: 15, + StoreBatchSize: 1, + } + it, errRes := copClient.BuildCopIterator(ctx, req, vars, opt) + require.Nil(t, errRes) + tasks := it.GetTasks() + require.Equal(t, len(tasks), 2) + require.Equal(t, len(tasks[0].ToPBBatchTasks()), 1) + require.Equal(t, tasks[0].RowCountHint, 5) + require.Equal(t, len(tasks[1].ToPBBatchTasks()), 1) + require.Equal(t, tasks[1].RowCountHint, 9) + + ranges = copr.BuildKeyRanges("a", "c", "d", "e", "h", "x", "y", "z") + req = &kv.Request{ + Tp: kv.ReqTypeDAG, + KeyRanges: kv.NewNonParitionedKeyRangesWithHint(ranges, []int{1, 1, 3, 3}), + Concurrency: 15, + StoreBatchSize: 3, + } + it, errRes = copClient.BuildCopIterator(ctx, req, vars, opt) + require.Nil(t, errRes) + tasks = it.GetTasks() + require.Equal(t, len(tasks), 1) + require.Equal(t, len(tasks[0].ToPBBatchTasks()), 3) + require.Equal(t, tasks[0].RowCountHint, 14) + + // paging will disable store batch. + ranges = copr.BuildKeyRanges("a", "c", "d", "e", "h", "x", "y", "z") + req = &kv.Request{ + Tp: kv.ReqTypeDAG, + KeyRanges: kv.NewNonParitionedKeyRangesWithHint(ranges, []int{1, 1, 3, 3}), + Concurrency: 15, + StoreBatchSize: 3, + Paging: struct { + Enable bool + MinPagingSize uint64 + MaxPagingSize uint64 + }{ + Enable: true, + MinPagingSize: 1, + MaxPagingSize: 1024, + }, + } + it, errRes = copClient.BuildCopIterator(ctx, req, vars, opt) + require.Nil(t, errRes) + tasks = it.GetTasks() + require.Equal(t, len(tasks), 4) +} diff --git a/store/copr/copr_test/main_test.go b/store/copr/copr_test/main_test.go new file mode 100644 index 0000000000000..9b98a6a9ad944 --- /dev/null +++ b/store/copr/copr_test/main_test.go @@ -0,0 +1,61 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package copr_test + +import ( + "flag" + "testing" + "time" + + "github.com/pingcap/tidb/config" + "github.com/pingcap/tidb/testkit/testmain" + "github.com/pingcap/tidb/testkit/testsetup" + "github.com/tikv/client-go/v2/tikv" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + testmain.ShortCircuitForBench(m) + + testsetup.SetupForCommonTest() + + flag.Parse() + config.UpdateGlobal(func(conf *config.Config) { + conf.TiKVClient.AsyncCommit.SafeWindow = 0 + conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 + }) + tikv.EnableFailpoints() + opts := []goleak.Option{ + // TODO: figure the reason and shorten this list + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/internal/retry.newBackoffFn.func1"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/v3.waitRetryBackoff"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + goleak.IgnoreTopFunction("google.golang.org/grpc.(*addrConn).resetTransport"), + goleak.IgnoreTopFunction("google.golang.org/grpc.(*ccBalancerWrapper).watcher"), + goleak.IgnoreTopFunction("google.golang.org/grpc/internal/transport.(*controlBuffer).get"), + goleak.IgnoreTopFunction("google.golang.org/grpc/internal/transport.(*http2Client).keepalive"), + goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), + goleak.IgnoreTopFunction("net/http.(*persistConn).writeLoop"), + } + callback := func(i int) int { + // wait for MVCCLevelDB to close, MVCCLevelDB will be closed in one second + time.Sleep(time.Second) + return i + } + goleak.VerifyTestMain(testmain.WrapTestingM(m, callback), opts...) +} diff --git a/store/copr/coprocessor.go b/store/copr/coprocessor.go index aa52fa3356c2e..eca0b8037daa6 100644 --- a/store/copr/coprocessor.go +++ b/store/copr/coprocessor.go @@ -15,9 +15,9 @@ package copr import ( - "bytes" "context" "fmt" + "math" "strconv" "strings" "sync" @@ -26,10 +26,13 @@ import ( "unsafe" "github.com/gogo/protobuf/proto" + "github.com/opentracing/opentracing-go" "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/coprocessor" + "github.com/pingcap/kvproto/pkg/errorpb" "github.com/pingcap/kvproto/pkg/kvrpcpb" + "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/kv" @@ -52,7 +55,6 @@ import ( "github.com/tikv/client-go/v2/txnkv/txnsnapshot" "github.com/tikv/client-go/v2/util" "go.uber.org/zap" - "golang.org/x/exp/slices" ) var coprCacheCounterEvict = tidbmetrics.DistSQLCoprCacheCounter.WithLabelValues("evict") @@ -66,6 +68,8 @@ var ( const ( copBuildTaskMaxBackoff = 5000 copNextMaxBackoff = 20000 + CopSmallTaskRow = 32 // 32 is the initial batch size of TiKV + smallTaskSigma = 0.5 ) // CopClient is coprocessor client. @@ -77,9 +81,6 @@ type CopClient struct { // Send builds the request and gets the coprocessor iterator response. func (c *CopClient) Send(ctx context.Context, req *kv.Request, variables interface{}, option *kv.ClientSendOption) kv.Response { - eventCb := option.EventCb - enabledRateLimitAction := option.EnabledRateLimitAction - sessionMemTracker := option.SessionMemTracker vars, ok := variables.(*tikv.Variables) if !ok { return copErrorResponse{errors.Errorf("unsupported variables:%+v", variables)} @@ -88,6 +89,25 @@ func (c *CopClient) Send(ctx context.Context, req *kv.Request, variables interfa logutil.BgLogger().Debug("send batch requests") return c.sendBatch(ctx, req, vars, option) } + ctx = context.WithValue(ctx, tikv.TxnStartKey(), req.StartTs) + ctx = context.WithValue(ctx, util.RequestSourceKey, req.RequestSource) + enabledRateLimitAction := option.EnabledRateLimitAction + sessionMemTracker := option.SessionMemTracker + it, errRes := c.BuildCopIterator(ctx, req, vars, option) + if errRes != nil { + return errRes + } + ctx = context.WithValue(ctx, tikv.RPCCancellerCtxKey{}, it.rpcCancel) + if sessionMemTracker != nil && enabledRateLimitAction { + sessionMemTracker.FallbackOldAndSetNewAction(it.actionOnExceed) + } + it.open(ctx, enabledRateLimitAction, option.EnableCollectExecutionInfo) + return it +} + +// BuildCopIterator builds the iterator without calling `open`. +func (c *CopClient) BuildCopIterator(ctx context.Context, req *kv.Request, vars *tikv.Variables, option *kv.ClientSendOption) (*copIterator, kv.Response) { + eventCb := option.EventCb failpoint.Inject("DisablePaging", func(_ failpoint.Value) { req.Paging.Enable = false }) @@ -99,23 +119,60 @@ func (c *CopClient) Send(ctx context.Context, req *kv.Request, variables interfa // coprocessor request but type is not DAG req.Paging.Enable = false } - failpoint.Inject("checkKeyRangeSortedForPaging", func(_ failpoint.Value) { if req.Paging.Enable { - isSorted := slices.IsSortedFunc(req.KeyRanges, func(i, j kv.KeyRange) bool { - return bytes.Compare(i.StartKey, j.StartKey) < 0 - }) - if !isSorted { + if !req.KeyRanges.IsFullySorted() { logutil.BgLogger().Fatal("distsql request key range not sorted!") } } }) + if req.Tp != kv.ReqTypeDAG || req.StoreType != kv.TiKV { + req.StoreBatchSize = 0 + } + // TODO: support keep-order batch + if req.ReplicaRead != kv.ReplicaReadLeader || req.KeepOrder { + // disable batch copr for follower read + req.StoreBatchSize = 0 + } + // disable batch copr when paging is enabled. + if req.Paging.Enable { + req.StoreBatchSize = 0 + } - ctx = context.WithValue(ctx, tikv.TxnStartKey(), req.StartTs) - ctx = context.WithValue(ctx, util.RequestSourceKey, req.RequestSource) bo := backoff.NewBackofferWithVars(ctx, copBuildTaskMaxBackoff, vars) - ranges := NewKeyRanges(req.KeyRanges) - tasks, err := buildCopTasks(bo, c.store.GetRegionCache(), ranges, req, eventCb) + var ( + tasks []*copTask + err error + ) + tryRowHint := optRowHint(req) + buildOpt := &buildCopTaskOpt{ + req: req, + cache: c.store.GetRegionCache(), + eventCb: eventCb, + respChan: req.KeepOrder, + } + buildTaskFunc := func(ranges []kv.KeyRange, hints []int) error { + keyRanges := NewKeyRanges(ranges) + if tryRowHint { + buildOpt.rowHints = hints + } + tasksFromRanges, err := buildCopTasks(bo, keyRanges, buildOpt) + if err != nil { + return err + } + if len(tasks) == 0 { + tasks = tasksFromRanges + return nil + } + tasks = append(tasks, tasksFromRanges...) + return nil + } + // Here we build the task by partition, not directly by region. + // This is because it's possible that TiDB merge multiple small partition into one region which break some assumption. + // Keep it split by partition would be more safe. + err = req.KeyRanges.ForEachPartitionWithErr(buildTaskFunc) + // only batch store requests in first build. + req.StoreBatchSize = 0 reqType := "null" if req.ClosestReplicaReadAdjuster != nil { reqType = "miss" @@ -125,7 +182,7 @@ func (c *CopClient) Send(ctx context.Context, req *kv.Request, variables interfa } tidbmetrics.DistSQLCoprClosestReadCounter.WithLabelValues(reqType).Inc() if err != nil { - return copErrorResponse{err} + return nil, copErrorResponse{err} } it := &copIterator{ store: c.store, @@ -141,6 +198,13 @@ func (c *CopClient) Send(ctx context.Context, req *kv.Request, variables interfa if it.concurrency > len(tasks) { it.concurrency = len(tasks) } + if tryRowHint { + var smallTasks int + smallTasks, it.smallTaskConcurrency = smallTaskConcurrency(tasks) + if len(tasks)-smallTasks < it.concurrency { + it.concurrency = len(tasks) - smallTasks + } + } if it.concurrency < 1 { // Make sure that there is at least one worker. it.concurrency = 1 @@ -153,7 +217,8 @@ func (c *CopClient) Send(ctx context.Context, req *kv.Request, variables interfa // higher concurrency, the data is just cached and not consumed for a while, this increase the memory usage. // Set concurrency to 2 can reduce the memory usage and I've tested that it does not necessarily // decrease the performance. - if it.concurrency > 2 { + // For ReqTypeAnalyze, we keep its concurrency to avoid slow analyze(see https://github.com/pingcap/tidb/issues/40162 for details). + if it.concurrency > 2 && it.req.Tp != kv.ReqTypeAnalyze { oldConcurrency := it.concurrency it.concurrency = 2 @@ -164,24 +229,22 @@ func (c *CopClient) Send(ctx context.Context, req *kv.Request, variables interfa } }) } - it.sendRate = util.NewRateLimit(2 * it.concurrency) + if it.smallTaskConcurrency > 20 { + it.smallTaskConcurrency = 20 + } + it.sendRate = util.NewRateLimit(2 * (it.concurrency + it.smallTaskConcurrency)) it.respChan = nil } else { it.respChan = make(chan *copResponse) - it.sendRate = util.NewRateLimit(it.concurrency) + it.sendRate = util.NewRateLimit(it.concurrency + it.smallTaskConcurrency) } it.actionOnExceed = newRateLimitAction(uint(it.sendRate.GetCapacity())) - if sessionMemTracker != nil && enabledRateLimitAction { - sessionMemTracker.FallbackOldAndSetNewAction(it.actionOnExceed) - } - - ctx = context.WithValue(ctx, tikv.RPCCancellerCtxKey{}, it.rpcCancel) - it.open(ctx, enabledRateLimitAction, option.EnableCollectExecutionInfo) - return it + return it, nil } // copTask contains a related Region and KeyRange for a kv.Request. type copTask struct { + taskID uint64 region tikv.RegionVerID bucketsVer uint64 ranges *KeyRanges @@ -198,6 +261,15 @@ type copTask struct { partitionIndex int64 // used by balanceBatchCopTask in PartitionTableScan requestSource util.RequestSource + RowCountHint int // used for extra concurrency of small tasks, -1 for unknown row count + batchTaskList map[uint64]*batchedCopTask +} + +type batchedCopTask struct { + task *copTask + region coprocessor.RegionInfo + storeID uint64 + peer *metapb.Peer } func (r *copTask) String() string { @@ -205,17 +277,53 @@ func (r *copTask) String() string { r.region.GetID(), r.region.GetConfVer(), r.region.GetVer(), r.ranges.Len(), r.storeAddr) } +func (r *copTask) ToPBBatchTasks() []*coprocessor.StoreBatchTask { + if len(r.batchTaskList) == 0 { + return nil + } + pbTasks := make([]*coprocessor.StoreBatchTask, 0, len(r.batchTaskList)) + for _, task := range r.batchTaskList { + pbTasks = append(pbTasks, &coprocessor.StoreBatchTask{ + RegionId: task.region.GetRegionId(), + RegionEpoch: task.region.GetRegionEpoch(), + Peer: task.peer, + Ranges: task.region.GetRanges(), + TaskId: task.task.taskID, + }) + } + return pbTasks +} + // rangesPerTask limits the length of the ranges slice sent in one copTask. const rangesPerTask = 25000 -func buildCopTasks(bo *Backoffer, cache *RegionCache, ranges *KeyRanges, req *kv.Request, eventCb trxevents.EventCallback) ([]*copTask, error) { +type buildCopTaskOpt struct { + req *kv.Request + cache *RegionCache + eventCb trxevents.EventCallback + respChan bool + rowHints []int +} + +func buildCopTasks(bo *Backoffer, ranges *KeyRanges, opt *buildCopTaskOpt) ([]*copTask, error) { + req, cache, eventCb, hints := opt.req, opt.cache, opt.eventCb, opt.rowHints start := time.Now() cmdType := tikvrpc.CmdCop if req.StoreType == kv.TiDB { return buildTiDBMemCopTasks(ranges, req) } - rangesLen := ranges.Len() + // something went wrong, disable hints to avoid out of range index. + if hints != nil && len(hints) != rangesLen { + hints = nil + } + + rangesPerTaskLimit := rangesPerTask + failpoint.Inject("setRangesPerTask", func(val failpoint.Value) { + if v, ok := val.(int); ok { + rangesPerTaskLimit = v + } + }) // TODO(youjiali1995): is there any request type that needn't be splitted by buckets? locs, err := cache.SplitKeyRangesByBuckets(bo, ranges) @@ -231,7 +339,13 @@ func buildCopTasks(bo *Backoffer, cache *RegionCache, ranges *KeyRanges, req *kv chanSize = 18 } - var tasks []*copTask + var builder taskBuilder + if req.StoreBatchSize > 0 { + builder = newBatchTaskBuilder(bo, req, cache) + } else { + builder = newLegacyTaskBuilder(len(locs)) + } + origRangeIdx := 0 for _, loc := range locs { // TiKV will return gRPC error if the message is too large. So we need to limit the length of the ranges slice // to make sure the message can be sent successfully. @@ -243,19 +357,49 @@ func buildCopTasks(bo *Backoffer, cache *RegionCache, ranges *KeyRanges, req *kv pagingSize = req.Paging.MinPagingSize } for i := 0; i < rLen; { - nextI := mathutil.Min(i+rangesPerTask, rLen) - tasks = append(tasks, &copTask{ + nextI := mathutil.Min(i+rangesPerTaskLimit, rLen) + hint := -1 + // calculate the row count hint + if hints != nil { + startKey, endKey := loc.Ranges.RefAt(i).StartKey, loc.Ranges.RefAt(nextI-1).EndKey + // move to the previous range if startKey of current range is lower than endKey of previous location. + // In the following example, task1 will move origRangeIdx to region(i, z). + // When counting the row hint for task2, we need to move origRangeIdx back to region(a, h). + // |<- region(a, h) ->| |<- region(i, z) ->| + // |<- task1 ->| |<- task2 ->| ... + if origRangeIdx > 0 && ranges.RefAt(origRangeIdx-1).EndKey.Cmp(startKey) > 0 { + origRangeIdx-- + } + hint = 0 + for nextOrigRangeIdx := origRangeIdx; nextOrigRangeIdx < ranges.Len(); nextOrigRangeIdx++ { + rangeStart := ranges.RefAt(nextOrigRangeIdx).StartKey + if rangeStart.Cmp(endKey) > 0 { + origRangeIdx = nextOrigRangeIdx + break + } + hint += hints[nextOrigRangeIdx] + } + } + task := &copTask{ region: loc.Location.Region, bucketsVer: loc.getBucketVersion(), ranges: loc.Ranges.Slice(i, nextI), - respChan: make(chan *copResponse, chanSize), cmdType: cmdType, storeType: req.StoreType, eventCb: eventCb, paging: req.Paging.Enable, pagingSize: pagingSize, requestSource: req.RequestSource, - }) + RowCountHint: hint, + } + // only keep-order need chan inside task. + // tasks by region error will reuse the channel of parent task. + if req.KeepOrder && opt.respChan { + task.respChan = make(chan *copResponse, chanSize) + } + if err = builder.handle(task); err != nil { + return nil, err + } i = nextI if req.Paging.Enable { pagingSize = paging.GrowPagingSize(pagingSize, req.Paging.MaxPagingSize) @@ -264,18 +408,135 @@ func buildCopTasks(bo *Backoffer, cache *RegionCache, ranges *KeyRanges, req *kv } if req.Desc { - reverseTasks(tasks) + builder.reverse() } - if elapsed := time.Since(start); elapsed > time.Millisecond*500 { + tasks := builder.build() + elapsed := time.Since(start) + if elapsed > time.Millisecond*500 { logutil.BgLogger().Warn("buildCopTasks takes too much time", zap.Duration("elapsed", elapsed), zap.Int("range len", rangesLen), zap.Int("task len", len(tasks))) } - metrics.TxnRegionsNumHistogramWithCoprocessor.Observe(float64(len(tasks))) + if elapsed > time.Millisecond { + ctx := bo.GetCtx() + if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { + span1 := span.Tracer().StartSpan("copr.buildCopTasks", opentracing.ChildOf(span.Context()), opentracing.StartTime(start)) + defer span1.Finish() + } + } + metrics.TxnRegionsNumHistogramWithCoprocessor.Observe(float64(builder.regionNum())) return tasks, nil } +type taskBuilder interface { + handle(*copTask) error + reverse() + build() []*copTask + regionNum() int +} + +type legacyTaskBuilder struct { + tasks []*copTask +} + +func newLegacyTaskBuilder(hint int) *legacyTaskBuilder { + return &legacyTaskBuilder{ + tasks: make([]*copTask, 0, hint), + } +} + +func (b *legacyTaskBuilder) handle(task *copTask) error { + b.tasks = append(b.tasks, task) + return nil +} + +func (b *legacyTaskBuilder) regionNum() int { + return len(b.tasks) +} + +func (b *legacyTaskBuilder) reverse() { + reverseTasks(b.tasks) +} + +func (b *legacyTaskBuilder) build() []*copTask { + return b.tasks +} + +type batchStoreTaskBuilder struct { + bo *Backoffer + req *kv.Request + cache *RegionCache + taskID uint64 + limit int + store2Idx map[uint64]int + tasks []*copTask +} + +func newBatchTaskBuilder(bo *Backoffer, req *kv.Request, cache *RegionCache) *batchStoreTaskBuilder { + return &batchStoreTaskBuilder{ + bo: bo, + req: req, + cache: cache, + taskID: 0, + limit: req.StoreBatchSize, + store2Idx: make(map[uint64]int, 16), + tasks: make([]*copTask, 0, 16), + } +} + +func (b *batchStoreTaskBuilder) handle(task *copTask) (err error) { + b.taskID++ + task.taskID = b.taskID + handled := false + defer func() { + if !handled && err == nil { + // fallback to non-batch way. It's mainly caused by region miss. + b.tasks = append(b.tasks, task) + } + }() + if b.limit <= 0 { + return nil + } + batchedTask, err := b.cache.BuildBatchTask(b.bo, task, b.req.ReplicaRead) + if err != nil { + return err + } + if batchedTask == nil { + return nil + } + if idx, ok := b.store2Idx[batchedTask.storeID]; !ok || len(b.tasks[idx].batchTaskList) >= b.limit { + b.tasks = append(b.tasks, batchedTask.task) + b.store2Idx[batchedTask.storeID] = len(b.tasks) - 1 + } else { + if b.tasks[idx].batchTaskList == nil { + b.tasks[idx].batchTaskList = make(map[uint64]*batchedCopTask, b.limit) + // disable paging for batched task. + b.tasks[idx].paging = false + b.tasks[idx].pagingSize = 0 + } + if task.RowCountHint > 0 { + b.tasks[idx].RowCountHint += task.RowCountHint + } + b.tasks[idx].batchTaskList[task.taskID] = batchedTask + } + handled = true + return nil +} + +func (b *batchStoreTaskBuilder) regionNum() int { + // we allocate b.taskID for each region task, so the final b.taskID is equal to the related region number. + return int(b.taskID) +} + +func (b *batchStoreTaskBuilder) reverse() { + reverseTasks(b.tasks) +} + +func (b *batchStoreTaskBuilder) build() []*copTask { + return b.tasks +} + func buildTiDBMemCopTasks(ranges *KeyRanges, req *kv.Request) ([]*copTask, error) { servers, err := infosync.GetAllServerInfo(context.Background()) if err != nil { @@ -290,11 +551,12 @@ func buildTiDBMemCopTasks(ranges *KeyRanges, req *kv.Request) ([]*copTask, error addr := ser.IP + ":" + strconv.FormatUint(uint64(ser.StatusPort), 10) tasks = append(tasks, &copTask{ - ranges: ranges, - respChan: make(chan *copResponse, 2), - cmdType: cmdType, - storeType: req.StoreType, - storeAddr: addr, + ranges: ranges, + respChan: make(chan *copResponse, 2), + cmdType: cmdType, + storeType: req.StoreType, + storeAddr: addr, + RowCountHint: -1, }) } return tasks, nil @@ -307,11 +569,37 @@ func reverseTasks(tasks []*copTask) { } } +func isSmallTask(task *copTask) bool { + // strictly, only RowCountHint == -1 stands for unknown task rows, + // but when RowCountHint == 0, it may be caused by initialized value, + // to avoid the future bugs, let the tasks with RowCountHint == 0 be non-small tasks. + return task.RowCountHint > 0 && task.RowCountHint <= CopSmallTaskRow +} + +// smallTaskConcurrency counts the small tasks of tasks, +// then returns the task count and extra concurrency for small tasks. +func smallTaskConcurrency(tasks []*copTask) (int, int) { + res := 0 + for _, task := range tasks { + if isSmallTask(task) { + res++ + } + } + if res == 0 { + return 0, 0 + } + // Calculate the extra concurrency for small tasks + // extra concurrency = tasks / (1 + sigma * sqrt(log(tasks ^ 2))) + extraConc := float64(res) / (1 + smallTaskSigma*math.Sqrt(2*math.Log(float64(res)))) + return res, int(extraConc) +} + type copIterator struct { - store *Store - req *kv.Request - concurrency int - finishCh chan struct{} + store *Store + req *kv.Request + concurrency int + smallTaskConcurrency int + finishCh chan struct{} // If keepOrder, results are stored in copTask.respChan, read them out one by one. tasks []*copTask @@ -366,12 +654,13 @@ type copIteratorWorker struct { // copIteratorTaskSender sends tasks to taskCh then wait for the workers to exit. type copIteratorTaskSender struct { - taskCh chan<- *copTask - wg *sync.WaitGroup - tasks []*copTask - finishCh <-chan struct{} - respChan chan<- *copResponse - sendRate *util.RateLimit + taskCh chan<- *copTask + smallTaskCh chan<- *copTask + wg *sync.WaitGroup + tasks []*copTask + finishCh <-chan struct{} + respChan chan<- *copResponse + sendRate *util.RateLimit } type copResponse struct { @@ -458,7 +747,9 @@ func (worker *copIteratorWorker) run(ctx context.Context) { // there is a task finished. worker.sendToRespCh(finCopResp, worker.respChan, false) } - close(task.respChan) + if task.respChan != nil { + close(task.respChan) + } if worker.finished() { return } @@ -468,11 +759,18 @@ func (worker *copIteratorWorker) run(ctx context.Context) { // open starts workers and sender goroutines. func (it *copIterator) open(ctx context.Context, enabledRateLimitAction, enableCollectExecutionInfo bool) { taskCh := make(chan *copTask, 1) - it.wg.Add(it.concurrency) + smallTaskCh := make(chan *copTask, 1) + it.wg.Add(it.concurrency + it.smallTaskConcurrency) // Start it.concurrency number of workers to handle cop requests. - for i := 0; i < it.concurrency; i++ { + for i := 0; i < it.concurrency+it.smallTaskConcurrency; i++ { + var ch chan *copTask + if i < it.concurrency { + ch = taskCh + } else { + ch = smallTaskCh + } worker := &copIteratorWorker{ - taskCh: taskCh, + taskCh: ch, wg: &it.wg, store: it.store, req: it.req, @@ -488,11 +786,12 @@ func (it *copIterator) open(ctx context.Context, enabledRateLimitAction, enableC go worker.run(ctx) } taskSender := &copIteratorTaskSender{ - taskCh: taskCh, - wg: &it.wg, - tasks: it.tasks, - finishCh: it.finishCh, - sendRate: it.sendRate, + taskCh: taskCh, + smallTaskCh: smallTaskCh, + wg: &it.wg, + tasks: it.tasks, + finishCh: it.finishCh, + sendRate: it.sendRate, } taskSender.respChan = it.respChan it.actionOnExceed.setEnabled(enabledRateLimitAction) @@ -517,12 +816,19 @@ func (sender *copIteratorTaskSender) run() { if exit { break } - exit = sender.sendToTaskCh(t) + var sendTo chan<- *copTask + if isSmallTask(t) { + sendTo = sender.smallTaskCh + } else { + sendTo = sender.taskCh + } + exit = sender.sendToTaskCh(t, sendTo) if exit { break } } close(sender.taskCh) + close(sender.smallTaskCh) // Wait for worker goroutines to exit. sender.wg.Wait() @@ -569,9 +875,24 @@ func (it *copIterator) recvFromRespCh(ctx context.Context, respCh <-chan *copRes } } -func (sender *copIteratorTaskSender) sendToTaskCh(t *copTask) (exit bool) { +// GetConcurrency returns the concurrency and small task concurrency. +func (it *copIterator) GetConcurrency() (int, int) { + return it.concurrency, it.smallTaskConcurrency +} + +// GetSendRate returns the rate-limit object. +func (it *copIterator) GetSendRate() *util.RateLimit { + return it.sendRate +} + +// GetTasks returns the built tasks. +func (it *copIterator) GetTasks() []*copTask { + return it.tasks +} + +func (sender *copIteratorTaskSender) sendToTaskCh(t *copTask, sendTo chan<- *copTask) (exit bool) { select { - case sender.taskCh <- t: + case sendTo <- t: case <-sender.finishCh: exit = true } @@ -752,6 +1073,7 @@ func (worker *copIteratorWorker) handleTaskOnce(bo *Backoffer, task *copTask, ch Ranges: task.ranges.ToPBRanges(), SchemaVer: worker.req.SchemaVar, PagingSize: task.pagingSize, + Tasks: task.ToPBBatchTasks(), } var cacheKey []byte @@ -780,13 +1102,14 @@ func (worker *copIteratorWorker) handleTaskOnce(bo *Backoffer, task *copTask, ch } req := tikvrpc.NewReplicaReadRequest(task.cmdType, &copReq, options.GetTiKVReplicaReadType(worker.req.ReplicaRead), &worker.replicaReadSeed, kvrpcpb.Context{ - IsolationLevel: isolationLevelToPB(worker.req.IsolationLevel), - Priority: priorityToPB(worker.req.Priority), - NotFillCache: worker.req.NotFillCache, - RecordTimeStat: true, - RecordScanStat: true, - TaskId: worker.req.TaskID, - RequestSource: task.requestSource.GetRequestSource(), + IsolationLevel: isolationLevelToPB(worker.req.IsolationLevel), + Priority: priorityToPB(worker.req.Priority), + NotFillCache: worker.req.NotFillCache, + RecordTimeStat: true, + RecordScanStat: true, + TaskId: worker.req.TaskID, + RequestSource: task.requestSource.GetRequestSource(), + ResourceGroupName: worker.req.ResourceGroupName, }) if worker.req.ResourceGroupTagger != nil { worker.req.ResourceGroupTagger(req) @@ -937,37 +1260,22 @@ func (worker *copIteratorWorker) handleCopResponse(bo *Backoffer, rpcCtx *tikv.R return nil, errors.Trace(err) } // We may meet RegionError at the first packet, but not during visiting the stream. - return buildCopTasks(bo, worker.store.GetRegionCache(), task.ranges, worker.req, task.eventCb) + remains, err := buildCopTasks(bo, task.ranges, &buildCopTaskOpt{ + req: worker.req, + cache: worker.store.GetRegionCache(), + respChan: false, + eventCb: task.eventCb, + }) + if err != nil { + return remains, err + } + return worker.handleBatchRemainsOnErr(bo, remains, resp.pbResp.GetBatchResponses(), task, ch) } - var resolveLockDetail *util.ResolveLockDetail if lockErr := resp.pbResp.GetLocked(); lockErr != nil { - resolveLockDetail = worker.getLockResolverDetails() - // Be care that we didn't redact the SQL statement because the log is DEBUG level. - if task.eventCb != nil { - task.eventCb(trxevents.WrapCopMeetLock(&trxevents.CopMeetLock{ - LockInfo: lockErr, - })) - } else { - logutil.Logger(bo.GetCtx()).Debug("coprocessor encounters lock", - zap.Stringer("lock", lockErr)) - } - resolveLocksOpts := txnlock.ResolveLocksOptions{ - CallerStartTS: worker.req.StartTs, - Locks: []*txnlock.Lock{txnlock.NewLock(lockErr)}, - Detail: resolveLockDetail, - } - resolveLocksRes, err1 := worker.kvclient.ResolveLocksWithOpts(bo.TiKVBackoffer(), resolveLocksOpts) - err1 = derr.ToTiDBErr(err1) - if err1 != nil { - return nil, errors.Trace(err1) - } - msBeforeExpired := resolveLocksRes.TTL - if msBeforeExpired > 0 { - if err := bo.BackoffWithMaxSleepTxnLockFast(int(msBeforeExpired), errors.New(lockErr.String())); err != nil { - return nil, errors.Trace(err) - } + if err := worker.handleLockErr(bo, lockErr, task); err != nil { + return nil, err } - return []*copTask{task}, nil + return worker.handleBatchRemainsOnErr(bo, []*copTask{task}, resp.pbResp.GetBatchResponses(), task, ch) } if otherErr := resp.pbResp.GetOtherError(); otherErr != "" { err := errors.Errorf("other error: %s", otherErr) @@ -996,7 +1304,7 @@ func (worker *copIteratorWorker) handleCopResponse(bo *Backoffer, rpcCtx *tikv.R } else if task.ranges != nil && task.ranges.Len() > 0 { resp.startKey = task.ranges.At(0).StartKey } - worker.handleCollectExecutionInfo(bo, rpcCtx, resp, resolveLockDetail) + worker.handleCollectExecutionInfo(bo, rpcCtx, resp) resp.respTime = costTime if resp.pbResp.IsCacheHit { coprCacheCounterHit.Add(1) @@ -1054,8 +1362,157 @@ func (worker *copIteratorWorker) handleCopResponse(bo *Backoffer, rpcCtx *tikv.R } } } + batchResps := resp.pbResp.BatchResponses worker.sendToRespCh(resp, ch, true) - return nil, nil + return worker.handleBatchCopResponse(bo, batchResps, task.batchTaskList, ch) +} + +func (worker *copIteratorWorker) handleBatchRemainsOnErr(bo *Backoffer, remains []*copTask, batchResp []*coprocessor.StoreBatchTaskResponse, task *copTask, ch chan<- *copResponse) ([]*copTask, error) { + if len(task.batchTaskList) == 0 { + return remains, nil + } + batchedTasks := task.batchTaskList + task.batchTaskList = nil + batchedRemains, err := worker.handleBatchCopResponse(bo, batchResp, batchedTasks, ch) + if err != nil { + return nil, err + } + return append(remains, batchedRemains...), nil +} + +// handle the batched cop response. +// tasks will be changed, so the input tasks should not be used after calling this function. +func (worker *copIteratorWorker) handleBatchCopResponse(bo *Backoffer, batchResps []*coprocessor.StoreBatchTaskResponse, tasks map[uint64]*batchedCopTask, ch chan<- *copResponse) ([]*copTask, error) { + if len(tasks) == 0 { + return nil, nil + } + var remainTasks []*copTask + appendRemainTasks := func(tasks ...*copTask) { + if remainTasks == nil { + // allocate size fo remain length + remainTasks = make([]*copTask, 0, len(tasks)) + } + remainTasks = append(remainTasks, tasks...) + } + for _, batchResp := range batchResps { + taskID := batchResp.GetTaskId() + batchedTask, ok := tasks[taskID] + if !ok { + return nil, errors.Errorf("task id %d not found", batchResp.GetTaskId()) + } + delete(tasks, taskID) + resp := &copResponse{ + pbResp: &coprocessor.Response{ + Data: batchResp.Data, + }, + } + task := batchedTask.task + failpoint.Inject("batchCopRegionError", func() { + batchResp.RegionError = &errorpb.Error{} + }) + if regionErr := batchResp.GetRegionError(); regionErr != nil { + errStr := fmt.Sprintf("region_id:%v, region_ver:%v, store_type:%s, peer_addr:%s, error:%s", + task.region.GetID(), task.region.GetVer(), task.storeType.Name(), task.storeAddr, regionErr.String()) + if err := bo.Backoff(tikv.BoRegionMiss(), errors.New(errStr)); err != nil { + return nil, errors.Trace(err) + } + remains, err := buildCopTasks(bo, task.ranges, &buildCopTaskOpt{ + req: worker.req, + cache: worker.store.GetRegionCache(), + respChan: false, + eventCb: task.eventCb, + }) + if err != nil { + return nil, err + } + appendRemainTasks(remains...) + continue + } + //TODO: handle locks in batch + if lockErr := batchResp.GetLocked(); lockErr != nil { + if err := worker.handleLockErr(bo, resp.pbResp.GetLocked(), task); err != nil { + return nil, err + } + appendRemainTasks(task) + continue + } + if otherErr := batchResp.GetOtherError(); otherErr != "" { + err := errors.Errorf("other error: %s", otherErr) + + firstRangeStartKey := task.ranges.At(0).StartKey + lastRangeEndKey := task.ranges.At(task.ranges.Len() - 1).EndKey + + logutil.Logger(bo.GetCtx()).Warn("other error", + zap.Uint64("txnStartTS", worker.req.StartTs), + zap.Uint64("regionID", task.region.GetID()), + zap.Uint64("bucketsVer", task.bucketsVer), + // TODO: add bucket version in log + //zap.Uint64("latestBucketsVer", batchResp.GetLatestBucketsVersion()), + zap.Int("rangeNums", task.ranges.Len()), + zap.ByteString("firstRangeStartKey", firstRangeStartKey), + zap.ByteString("lastRangeEndKey", lastRangeEndKey), + zap.String("storeAddr", task.storeAddr), + zap.Error(err)) + if strings.Contains(err.Error(), "write conflict") { + return nil, kv.ErrWriteConflict.FastGen("%s", otherErr) + } + return nil, errors.Trace(err) + } + // TODO: check OOM + worker.sendToRespCh(resp, ch, false) + } + for _, t := range tasks { + task := t.task + // when the error is generated by client, response is empty, skip warning for this case. + if len(batchResps) != 0 { + firstRangeStartKey := task.ranges.At(0).StartKey + lastRangeEndKey := task.ranges.At(task.ranges.Len() - 1).EndKey + logutil.Logger(bo.GetCtx()).Error("response of batched task missing", + zap.Uint64("id", task.taskID), + zap.Uint64("txnStartTS", worker.req.StartTs), + zap.Uint64("regionID", task.region.GetID()), + zap.Uint64("bucketsVer", task.bucketsVer), + zap.Int("rangeNums", task.ranges.Len()), + zap.ByteString("firstRangeStartKey", firstRangeStartKey), + zap.ByteString("lastRangeEndKey", lastRangeEndKey), + zap.String("storeAddr", task.storeAddr)) + } + appendRemainTasks(t.task) + } + return remainTasks, nil +} + +func (worker *copIteratorWorker) handleLockErr(bo *Backoffer, lockErr *kvrpcpb.LockInfo, task *copTask) error { + if lockErr == nil { + return nil + } + resolveLockDetail := worker.getLockResolverDetails() + // Be care that we didn't redact the SQL statement because the log is DEBUG level. + if task.eventCb != nil { + task.eventCb(trxevents.WrapCopMeetLock(&trxevents.CopMeetLock{ + LockInfo: lockErr, + })) + } else { + logutil.Logger(bo.GetCtx()).Debug("coprocessor encounters lock", + zap.Stringer("lock", lockErr)) + } + resolveLocksOpts := txnlock.ResolveLocksOptions{ + CallerStartTS: worker.req.StartTs, + Locks: []*txnlock.Lock{txnlock.NewLock(lockErr)}, + Detail: resolveLockDetail, + } + resolveLocksRes, err1 := worker.kvclient.ResolveLocksWithOpts(bo.TiKVBackoffer(), resolveLocksOpts) + err1 = derr.ToTiDBErr(err1) + if err1 != nil { + return errors.Trace(err1) + } + msBeforeExpired := resolveLocksRes.TTL + if msBeforeExpired > 0 { + if err := bo.BackoffWithMaxSleepTxnLockFast(int(msBeforeExpired), errors.New(lockErr.String())); err != nil { + return errors.Trace(err) + } + } + return nil } func (worker *copIteratorWorker) getLockResolverDetails() *util.ResolveLockDetail { @@ -1065,7 +1522,7 @@ func (worker *copIteratorWorker) getLockResolverDetails() *util.ResolveLockDetai return &util.ResolveLockDetail{} } -func (worker *copIteratorWorker) handleCollectExecutionInfo(bo *Backoffer, rpcCtx *tikv.RPCContext, resp *copResponse, resolveLockDetail *util.ResolveLockDetail) { +func (worker *copIteratorWorker) handleCollectExecutionInfo(bo *Backoffer, rpcCtx *tikv.RPCContext, resp *copResponse) { defer func() { worker.kvclient.Stats = nil }() @@ -1093,9 +1550,6 @@ func (worker *copIteratorWorker) handleCollectExecutionInfo(bo *Backoffer, rpcCt resp.detail.CalleeAddress = rpcCtx.Addr } sd := &util.ScanDetail{} - if resolveLockDetail != nil { - sd.ResolveLock = resolveLockDetail - } td := util.TimeDetail{} if pbDetails := resp.pbResp.ExecDetailsV2; pbDetails != nil { // Take values in `ExecDetailsV2` first. @@ -1308,11 +1762,6 @@ func (e *rateLimitAction) Action(t *memory.Tracker) { }) } -// SetLogHook implements ActionOnExceed.SetLogHook -func (e *rateLimitAction) SetLogHook(hook func(uint64)) { - -} - // GetPriority get the priority of the Action. func (e *rateLimitAction) GetPriority() int64 { return memory.DefRateLimitPriority @@ -1394,3 +1843,30 @@ func isolationLevelToPB(level kv.IsoLevel) kvrpcpb.IsolationLevel { return kvrpcpb.IsolationLevel_SI } } + +// BuildKeyRanges is used for test, quickly build key ranges from paired keys. +func BuildKeyRanges(keys ...string) []kv.KeyRange { + var ranges []kv.KeyRange + for i := 0; i < len(keys); i += 2 { + ranges = append(ranges, kv.KeyRange{ + StartKey: []byte(keys[i]), + EndKey: []byte(keys[i+1]), + }) + } + return ranges +} + +func optRowHint(req *kv.Request) bool { + opt := true + if req.StoreType == kv.TiDB { + return false + } + if req.RequestSource.RequestSourceInternal || req.Tp != kv.ReqTypeDAG { + // disable extra concurrency for internal tasks. + return false + } + failpoint.Inject("disableFixedRowCountHint", func(_ failpoint.Value) { + opt = false + }) + return opt +} diff --git a/store/copr/coprocessor_test.go b/store/copr/coprocessor_test.go index 6e75eeb0a7569..36ae88758bbc5 100644 --- a/store/copr/coprocessor_test.go +++ b/store/copr/coprocessor_test.go @@ -22,11 +22,21 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/store/driver/backoff" "github.com/pingcap/tidb/util/paging" + "github.com/pingcap/tidb/util/trxevents" "github.com/stretchr/testify/require" "github.com/tikv/client-go/v2/testutils" "github.com/tikv/client-go/v2/tikv" ) +func buildTestCopTasks(bo *Backoffer, cache *RegionCache, ranges *KeyRanges, req *kv.Request, eventCb trxevents.EventCallback) ([]*copTask, error) { + return buildCopTasks(bo, ranges, &buildCopTaskOpt{ + req: req, + cache: cache, + eventCb: eventCb, + respChan: true, + }) +} + func TestBuildTasksWithoutBuckets(t *testing.T) { // nil --- 'g' --- 'n' --- 't' --- nil // <- 0 -> <- 1 -> <- 2 -> <- 3 -> @@ -39,7 +49,7 @@ func TestBuildTasksWithoutBuckets(t *testing.T) { }() _, regionIDs, _ := testutils.BootstrapWithMultiRegions(cluster, []byte("g"), []byte("n"), []byte("t")) - pdCli := &tikv.CodecPDClient{Client: pdClient} + pdCli := tikv.NewCodecPDClient(tikv.ModeTxn, pdClient) defer pdCli.Close() cache := NewRegionCache(tikv.NewRegionCache(pdCli)) @@ -50,49 +60,49 @@ func TestBuildTasksWithoutBuckets(t *testing.T) { req := &kv.Request{} flashReq := &kv.Request{} flashReq.StoreType = kv.TiFlash - tasks, err := buildCopTasks(bo, cache, buildCopRanges("a", "c"), req, nil) + tasks, err := buildTestCopTasks(bo, cache, buildCopRanges("a", "c"), req, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "c") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "c"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "c"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "c") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("g", "n"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("g", "n"), req, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[1], 0, "g", "n") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("g", "n"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("g", "n"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[1], 0, "g", "n") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("m", "n"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("m", "n"), req, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[1], 0, "m", "n") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("m", "n"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("m", "n"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[1], 0, "m", "n") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "k"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "k"), req, nil) require.NoError(t, err) require.Len(t, tasks, 2) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "g") taskEqual(t, tasks[1], regionIDs[1], 0, "g", "k") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "k"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "k"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 2) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "g") taskEqual(t, tasks[1], regionIDs[1], 0, "g", "k") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "x"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "x"), req, nil) require.NoError(t, err) require.Len(t, tasks, 4) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "g") @@ -100,7 +110,7 @@ func TestBuildTasksWithoutBuckets(t *testing.T) { taskEqual(t, tasks[2], regionIDs[2], 0, "n", "t") taskEqual(t, tasks[3], regionIDs[3], 0, "t", "x") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "x"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "x"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 4) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "g") @@ -108,45 +118,45 @@ func TestBuildTasksWithoutBuckets(t *testing.T) { taskEqual(t, tasks[2], regionIDs[2], 0, "n", "t") taskEqual(t, tasks[3], regionIDs[3], 0, "t", "x") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "b", "b", "c"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "b", "b", "c"), req, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "b", "b", "c") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "b", "b", "c"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "b", "b", "c"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "b", "b", "c") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "b", "e", "f"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "b", "e", "f"), req, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "b", "e", "f") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "b", "e", "f"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "b", "e", "f"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 1) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "b", "e", "f") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("g", "n", "o", "p"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("g", "n", "o", "p"), req, nil) require.NoError(t, err) require.Len(t, tasks, 2) taskEqual(t, tasks[0], regionIDs[1], 0, "g", "n") taskEqual(t, tasks[1], regionIDs[2], 0, "o", "p") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("g", "n", "o", "p"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("g", "n", "o", "p"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 2) taskEqual(t, tasks[0], regionIDs[1], 0, "g", "n") taskEqual(t, tasks[1], regionIDs[2], 0, "o", "p") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("h", "k", "m", "p"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("h", "k", "m", "p"), req, nil) require.NoError(t, err) require.Len(t, tasks, 2) taskEqual(t, tasks[0], regionIDs[1], 0, "h", "k", "m", "n") taskEqual(t, tasks[1], regionIDs[2], 0, "n", "p") - tasks, err = buildCopTasks(bo, cache, buildCopRanges("h", "k", "m", "p"), flashReq, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("h", "k", "m", "p"), flashReq, nil) require.NoError(t, err) require.Len(t, tasks, 2) taskEqual(t, tasks[0], regionIDs[1], 0, "h", "k", "m", "n") @@ -168,7 +178,7 @@ func TestBuildTasksByBuckets(t *testing.T) { cluster.SplitRegionBuckets(regionIDs[0], [][]byte{{}, {'c'}, {'g'}, {'k'}, {'n'}}, regionIDs[0]) cluster.SplitRegionBuckets(regionIDs[1], [][]byte{{'n'}, {'t'}, {'x'}}, regionIDs[1]) cluster.SplitRegionBuckets(regionIDs[2], [][]byte{{'x'}, {}}, regionIDs[2]) - pdCli := &tikv.CodecPDClient{Client: pdClient} + pdCli := tikv.NewCodecPDClient(tikv.ModeTxn, pdClient) defer pdCli.Close() cache := NewRegionCache(tikv.NewRegionCache(pdCli)) @@ -191,7 +201,7 @@ func TestBuildTasksByBuckets(t *testing.T) { } for _, regionRange := range regionRanges { regionID, ranges := regionRange.regionID, regionRange.ranges - tasks, err := buildCopTasks(bo, cache, buildCopRanges(ranges...), req, nil) + tasks, err := buildTestCopTasks(bo, cache, buildCopRanges(ranges...), req, nil) require.NoError(t, err) require.Len(t, tasks, len(ranges)/2) for i, task := range tasks { @@ -204,7 +214,7 @@ func TestBuildTasksByBuckets(t *testing.T) { for _, regionRange := range regionRanges { allRanges = append(allRanges, regionRange.ranges...) } - tasks, err := buildCopTasks(bo, cache, buildCopRanges(allRanges...), req, nil) + tasks, err := buildTestCopTasks(bo, cache, buildCopRanges(allRanges...), req, nil) require.NoError(t, err) require.Len(t, tasks, len(allRanges)/2) taskIdx := 0 @@ -230,7 +240,7 @@ func TestBuildTasksByBuckets(t *testing.T) { "h", "i", "j", "k", "k", "l", "m", "n", } - tasks, err = buildCopTasks(bo, cache, buildCopRanges(keyRanges...), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges(keyRanges...), req, nil) require.NoError(t, err) require.Len(t, tasks, len(keyRanges)/4) for i, task := range tasks { @@ -251,7 +261,7 @@ func TestBuildTasksByBuckets(t *testing.T) { {"c", "d", "e", "g"}, {"g", "h", "i", "j"}, } - tasks, err = buildCopTasks(bo, cache, buildCopRanges(keyRanges...), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges(keyRanges...), req, nil) require.NoError(t, err) require.Len(t, tasks, len(expectedTaskRanges)) for i, task := range tasks { @@ -277,7 +287,7 @@ func TestBuildTasksByBuckets(t *testing.T) { cluster.SplitRegionBuckets(regionIDs[1], [][]byte{{'n'}, {'q'}, {'r'}, {'t'}, {'u'}, {'v'}, {'x'}}, regionIDs[1]) cache = NewRegionCache(tikv.NewRegionCache(pdCli)) defer cache.Close() - tasks, err = buildCopTasks(bo, cache, buildCopRanges("n", "o", "p", "q", "s", "w"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("n", "o", "p", "q", "s", "w"), req, nil) require.NoError(t, err) require.Len(t, tasks, len(expectedTaskRanges)) for i, task := range tasks { @@ -301,7 +311,7 @@ func TestBuildTasksByBuckets(t *testing.T) { cluster.SplitRegionBuckets(regionIDs[1], [][]byte{{'q'}, {'s'}, {'u'}}, regionIDs[1]) cache = NewRegionCache(tikv.NewRegionCache(pdCli)) defer cache.Close() - tasks, err = buildCopTasks(bo, cache, buildCopRanges("n", "o", "p", "s", "t", "v", "w", "x"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("n", "o", "p", "s", "t", "v", "w", "x"), req, nil) require.NoError(t, err) require.Len(t, tasks, len(expectedTaskRanges)) for i, task := range tasks { @@ -321,7 +331,7 @@ func TestBuildTasksByBuckets(t *testing.T) { cluster.SplitRegionBuckets(regionIDs[1], [][]byte{{'g'}, {'t'}, {'z'}}, regionIDs[1]) cache = NewRegionCache(tikv.NewRegionCache(pdCli)) defer cache.Close() - tasks, err = buildCopTasks(bo, cache, buildCopRanges("o", "p", "u", "w"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("o", "p", "u", "w"), req, nil) require.NoError(t, err) require.Len(t, tasks, len(expectedTaskRanges)) for i, task := range tasks { @@ -343,7 +353,7 @@ func TestBuildTasksByBuckets(t *testing.T) { cluster.SplitRegionBuckets(regionIDs[1], [][]byte{{'n'}, {'q'}, {'r'}, {'x'}}, regionIDs[1]) cache = NewRegionCache(tikv.NewRegionCache(pdCli)) defer cache.Close() - tasks, err = buildCopTasks(bo, cache, buildCopRanges("n", "x"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("n", "x"), req, nil) require.NoError(t, err) require.Len(t, tasks, len(expectedTaskRanges)) for i, task := range tasks { @@ -363,7 +373,7 @@ func TestSplitRegionRanges(t *testing.T) { }() testutils.BootstrapWithMultiRegions(cluster, []byte("g"), []byte("n"), []byte("t")) - pdCli := &tikv.CodecPDClient{Client: pdClient} + pdCli := tikv.NewCodecPDClient(tikv.ModeTxn, pdClient) defer pdCli.Close() cache := NewRegionCache(tikv.NewRegionCache(pdCli)) @@ -371,43 +381,43 @@ func TestSplitRegionRanges(t *testing.T) { bo := backoff.NewBackofferWithVars(context.Background(), 3000, nil) - ranges, err := cache.SplitRegionRanges(bo, buildKeyRanges("a", "c")) + ranges, err := cache.SplitRegionRanges(bo, BuildKeyRanges("a", "c")) require.NoError(t, err) require.Len(t, ranges, 1) rangeEqual(t, ranges, "a", "c") - ranges, err = cache.SplitRegionRanges(bo, buildKeyRanges("h", "y")) + ranges, err = cache.SplitRegionRanges(bo, BuildKeyRanges("h", "y")) require.NoError(t, err) require.Len(t, ranges, 3) rangeEqual(t, ranges, "h", "n", "n", "t", "t", "y") - ranges, err = cache.SplitRegionRanges(bo, buildKeyRanges("s", "z")) + ranges, err = cache.SplitRegionRanges(bo, BuildKeyRanges("s", "z")) require.NoError(t, err) require.Len(t, ranges, 2) rangeEqual(t, ranges, "s", "t", "t", "z") - ranges, err = cache.SplitRegionRanges(bo, buildKeyRanges("s", "s")) + ranges, err = cache.SplitRegionRanges(bo, BuildKeyRanges("s", "s")) require.NoError(t, err) require.Len(t, ranges, 1) rangeEqual(t, ranges, "s", "s") - ranges, err = cache.SplitRegionRanges(bo, buildKeyRanges("t", "t")) + ranges, err = cache.SplitRegionRanges(bo, BuildKeyRanges("t", "t")) require.NoError(t, err) require.Len(t, ranges, 1) rangeEqual(t, ranges, "t", "t") - ranges, err = cache.SplitRegionRanges(bo, buildKeyRanges("t", "u")) + ranges, err = cache.SplitRegionRanges(bo, BuildKeyRanges("t", "u")) require.NoError(t, err) require.Len(t, ranges, 1) rangeEqual(t, ranges, "t", "u") - ranges, err = cache.SplitRegionRanges(bo, buildKeyRanges("u", "z")) + ranges, err = cache.SplitRegionRanges(bo, BuildKeyRanges("u", "z")) require.NoError(t, err) require.Len(t, ranges, 1) rangeEqual(t, ranges, "u", "z") // min --> max - ranges, err = cache.SplitRegionRanges(bo, buildKeyRanges("a", "z")) + ranges, err = cache.SplitRegionRanges(bo, BuildKeyRanges("a", "z")) require.NoError(t, err) require.Len(t, ranges, 4) rangeEqual(t, ranges, "a", "g", "g", "n", "n", "t", "t", "z") @@ -425,14 +435,14 @@ func TestRebuild(t *testing.T) { }() storeID, regionIDs, peerIDs := testutils.BootstrapWithMultiRegions(cluster, []byte("m")) - pdCli := &tikv.CodecPDClient{Client: pdClient} + pdCli := tikv.NewCodecPDClient(tikv.ModeTxn, pdClient) defer pdCli.Close() cache := NewRegionCache(tikv.NewRegionCache(pdCli)) defer cache.Close() bo := backoff.NewBackofferWithVars(context.Background(), 3000, nil) req := &kv.Request{} - tasks, err := buildCopTasks(bo, cache, buildCopRanges("a", "z"), req, nil) + tasks, err := buildTestCopTasks(bo, cache, buildCopRanges("a", "z"), req, nil) require.NoError(t, err) require.Len(t, tasks, 2) taskEqual(t, tasks[0], regionIDs[0], 0, "a", "m") @@ -446,7 +456,7 @@ func TestRebuild(t *testing.T) { cache.InvalidateCachedRegion(tasks[1].region) req.Desc = true - tasks, err = buildCopTasks(bo, cache, buildCopRanges("a", "z"), req, nil) + tasks, err = buildTestCopTasks(bo, cache, buildCopRanges("a", "z"), req, nil) require.NoError(t, err) require.Len(t, tasks, 3) taskEqual(t, tasks[2], regionIDs[0], 0, "a", "m") @@ -454,19 +464,8 @@ func TestRebuild(t *testing.T) { taskEqual(t, tasks[0], regionIDs[2], 0, "q", "z") } -func buildKeyRanges(keys ...string) []kv.KeyRange { - var ranges []kv.KeyRange - for i := 0; i < len(keys); i += 2 { - ranges = append(ranges, kv.KeyRange{ - StartKey: []byte(keys[i]), - EndKey: []byte(keys[i+1]), - }) - } - return ranges -} - func buildCopRanges(keys ...string) *KeyRanges { - return NewKeyRanges(buildKeyRanges(keys...)) + return NewKeyRanges(BuildKeyRanges(keys...)) } func taskEqual(t *testing.T, task *copTask, regionID, bucketsVer uint64, keys ...string) { @@ -499,7 +498,7 @@ func TestBuildPagingTasks(t *testing.T) { }() _, regionIDs, _ := testutils.BootstrapWithMultiRegions(cluster, []byte("g"), []byte("n"), []byte("t")) - pdCli := &tikv.CodecPDClient{Client: pdClient} + pdCli := tikv.NewCodecPDClient(tikv.ModeTxn, pdClient) defer pdCli.Close() cache := NewRegionCache(tikv.NewRegionCache(pdCli)) @@ -512,7 +511,7 @@ func TestBuildPagingTasks(t *testing.T) { req.Paging.MinPagingSize = paging.MinPagingSize flashReq := &kv.Request{} flashReq.StoreType = kv.TiFlash - tasks, err := buildCopTasks(bo, cache, buildCopRanges("a", "c"), req, nil) + tasks, err := buildTestCopTasks(bo, cache, buildCopRanges("a", "c"), req, nil) require.NoError(t, err) require.Len(t, tasks, 1) require.Len(t, tasks, 1) @@ -545,54 +544,54 @@ func TestCalculateRetry(t *testing.T) { // split in one range { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("b", "c")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("b", "c")[0] retry := worker.calculateRetry(NewKeyRanges(ranges), toCopRange(split), false) rangeEqual(t, toRange(retry), "b", "c", "e", "g") } { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("e", "f")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("e", "f")[0] retry := worker.calculateRetry(NewKeyRanges(ranges), toCopRange(split), true) rangeEqual(t, toRange(retry), "a", "c", "e", "f") } // across ranges { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("b", "f")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("b", "f")[0] retry := worker.calculateRetry(NewKeyRanges(ranges), toCopRange(split), false) rangeEqual(t, toRange(retry), "b", "c", "e", "g") } { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("b", "f")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("b", "f")[0] retry := worker.calculateRetry(NewKeyRanges(ranges), toCopRange(split), true) rangeEqual(t, toRange(retry), "a", "c", "e", "f") } // exhaust the ranges { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("a", "g")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("a", "g")[0] retry := worker.calculateRetry(NewKeyRanges(ranges), toCopRange(split), false) rangeEqual(t, toRange(retry), "a", "c", "e", "g") } { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("a", "g")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("a", "g")[0] retry := worker.calculateRetry(NewKeyRanges(ranges), toCopRange(split), true) rangeEqual(t, toRange(retry), "a", "c", "e", "g") } // nil range { - ranges := buildKeyRanges("a", "c", "e", "g") + ranges := BuildKeyRanges("a", "c", "e", "g") retry := worker.calculateRetry(NewKeyRanges(ranges), nil, false) rangeEqual(t, toRange(retry), "a", "c", "e", "g") } { - ranges := buildKeyRanges("a", "c", "e", "g") + ranges := BuildKeyRanges("a", "c", "e", "g") retry := worker.calculateRetry(NewKeyRanges(ranges), nil, true) rangeEqual(t, toRange(retry), "a", "c", "e", "g") } @@ -603,55 +602,141 @@ func TestCalculateRemain(t *testing.T) { // split in one range { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("a", "b")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("a", "b")[0] remain := worker.calculateRemain(NewKeyRanges(ranges), toCopRange(split), false) rangeEqual(t, toRange(remain), "b", "c", "e", "g") } { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("f", "g")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("f", "g")[0] remain := worker.calculateRemain(NewKeyRanges(ranges), toCopRange(split), true) rangeEqual(t, toRange(remain), "a", "c", "e", "f") } // across ranges { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("a", "f")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("a", "f")[0] remain := worker.calculateRemain(NewKeyRanges(ranges), toCopRange(split), false) rangeEqual(t, toRange(remain), "f", "g") } { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("b", "g")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("b", "g")[0] remain := worker.calculateRemain(NewKeyRanges(ranges), toCopRange(split), true) rangeEqual(t, toRange(remain), "a", "b") } // exhaust the ranges { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("a", "g")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("a", "g")[0] remain := worker.calculateRemain(NewKeyRanges(ranges), toCopRange(split), false) require.Equal(t, remain.Len(), 0) } { - ranges := buildKeyRanges("a", "c", "e", "g") - split := buildKeyRanges("a", "g")[0] + ranges := BuildKeyRanges("a", "c", "e", "g") + split := BuildKeyRanges("a", "g")[0] remain := worker.calculateRemain(NewKeyRanges(ranges), toCopRange(split), true) require.Equal(t, remain.Len(), 0) } // nil range { - ranges := buildKeyRanges("a", "c", "e", "g") + ranges := BuildKeyRanges("a", "c", "e", "g") remain := worker.calculateRemain(NewKeyRanges(ranges), nil, false) rangeEqual(t, toRange(remain), "a", "c", "e", "g") } { - ranges := buildKeyRanges("a", "c", "e", "g") + ranges := BuildKeyRanges("a", "c", "e", "g") remain := worker.calculateRemain(NewKeyRanges(ranges), nil, true) rangeEqual(t, toRange(remain), "a", "c", "e", "g") } } + +func TestBasicSmallTaskConc(t *testing.T) { + require.False(t, isSmallTask(&copTask{RowCountHint: -1})) + require.False(t, isSmallTask(&copTask{RowCountHint: 0})) + require.True(t, isSmallTask(&copTask{RowCountHint: 1})) + require.True(t, isSmallTask(&copTask{RowCountHint: 6})) + require.True(t, isSmallTask(&copTask{RowCountHint: CopSmallTaskRow})) + require.False(t, isSmallTask(&copTask{RowCountHint: CopSmallTaskRow + 1})) + _, conc := smallTaskConcurrency([]*copTask{}) + require.GreaterOrEqual(t, conc, 0) +} + +func TestBuildCopTasksWithRowCountHint(t *testing.T) { + // nil --- 'g' --- 'n' --- 't' --- nil + // <- 0 -> <- 1 -> <- 2 -> <- 3 -> + mockClient, cluster, pdClient, err := testutils.NewMockTiKV("", nil) + require.NoError(t, err) + defer func() { + pdClient.Close() + err = mockClient.Close() + require.NoError(t, err) + }() + _, _, _ = testutils.BootstrapWithMultiRegions(cluster, []byte("g"), []byte("n"), []byte("t")) + pdCli := tikv.NewCodecPDClient(tikv.ModeTxn, pdClient) + defer pdCli.Close() + cache := NewRegionCache(tikv.NewRegionCache(pdCli)) + defer cache.Close() + + bo := backoff.NewBackofferWithVars(context.Background(), 3000, nil) + req := &kv.Request{} + ranges := buildCopRanges("a", "c", "d", "e", "h", "x", "y", "z") + tasks, err := buildCopTasks(bo, ranges, &buildCopTaskOpt{ + req: req, + cache: cache, + rowHints: []int{1, 1, 3, CopSmallTaskRow}, + }) + require.Nil(t, err) + require.Equal(t, len(tasks), 4) + // task[0] ["a"-"c", "d"-"e"] + require.Equal(t, tasks[0].RowCountHint, 2) + // task[1] ["h"-"n"] + require.Equal(t, tasks[1].RowCountHint, 3) + // task[2] ["n"-"t"] + require.Equal(t, tasks[2].RowCountHint, 3) + // task[3] ["t"-"x", "y"-"z"] + require.Equal(t, tasks[3].RowCountHint, 3+CopSmallTaskRow) + _, conc := smallTaskConcurrency(tasks) + require.Equal(t, conc, 1) + + ranges = buildCopRanges("a", "c", "d", "e", "h", "x", "y", "z") + tasks, err = buildCopTasks(bo, ranges, &buildCopTaskOpt{ + req: req, + cache: cache, + rowHints: []int{1, 1, 3, 3}, + }) + require.Nil(t, err) + require.Equal(t, len(tasks), 4) + // task[0] ["a"-"c", "d"-"e"] + require.Equal(t, tasks[0].RowCountHint, 2) + // task[1] ["h"-"n"] + require.Equal(t, tasks[1].RowCountHint, 3) + // task[2] ["n"-"t"] + require.Equal(t, tasks[2].RowCountHint, 3) + // task[3] ["t"-"x", "y"-"z"] + require.Equal(t, tasks[3].RowCountHint, 6) + _, conc = smallTaskConcurrency(tasks) + require.Equal(t, conc, 2) + + // cross-region long range + ranges = buildCopRanges("a", "z") + tasks, err = buildCopTasks(bo, ranges, &buildCopTaskOpt{ + req: req, + cache: cache, + rowHints: []int{10}, + }) + require.Nil(t, err) + require.Equal(t, len(tasks), 4) + // task[0] ["a"-"g"] + require.Equal(t, tasks[0].RowCountHint, 10) + // task[1] ["g"-"n"] + require.Equal(t, tasks[1].RowCountHint, 10) + // task[2] ["n"-"t"] + require.Equal(t, tasks[2].RowCountHint, 10) + // task[3] ["t"-"z"] + require.Equal(t, tasks[3].RowCountHint, 10) +} diff --git a/store/copr/key_ranges.go b/store/copr/key_ranges.go index 86dcf036fed4e..67effbbc8b7a1 100644 --- a/store/copr/key_ranges.go +++ b/store/copr/key_ranges.go @@ -58,18 +58,23 @@ func (r *KeyRanges) Len() int { return l } -// At returns the range at the ith position. -func (r *KeyRanges) At(i int) kv.KeyRange { +// RefAt returns the reference at the ith position without copy. +func (r *KeyRanges) RefAt(i int) *kv.KeyRange { if r.first != nil { if i == 0 { - return *r.first + return r.first } i-- } if i < len(r.mid) { - return r.mid[i] + return &r.mid[i] } - return *r.last + return r.last +} + +// At returns the range at the ith position. +func (r *KeyRanges) At(i int) kv.KeyRange { + return *r.RefAt(i) } // Slice returns the sub ranges [from, to). diff --git a/store/copr/main_test.go b/store/copr/main_test.go index 9e9e2a02410e4..456b51156c8be 100644 --- a/store/copr/main_test.go +++ b/store/copr/main_test.go @@ -38,6 +38,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/pingcap/goleveldb/leveldb.(*DB).mpoolDrain"), goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/copr/mpp.go b/store/copr/mpp.go index 5c159bc355ab1..39ab058c223e5 100644 --- a/store/copr/mpp.go +++ b/store/copr/mpp.go @@ -62,7 +62,7 @@ func (c *MPPClient) selectAllTiFlashStore() []kv.MPPTaskMeta { } // ConstructMPPTasks receives ScheduleRequest, which are actually collects of kv ranges. We allocates MPPTaskMeta for them and returns. -func (c *MPPClient) ConstructMPPTasks(ctx context.Context, req *kv.MPPBuildTasksRequest, mppStoreLastFailTime *sync.Map, ttl time.Duration) ([]kv.MPPTaskMeta, error) { +func (c *MPPClient) ConstructMPPTasks(ctx context.Context, req *kv.MPPBuildTasksRequest, ttl time.Duration) ([]kv.MPPTaskMeta, error) { ctx = context.WithValue(ctx, tikv.TxnStartKey(), req.StartTS) bo := backoff.NewBackofferWithVars(ctx, copBuildTaskMaxBackoff, nil) var tasks []*batchCopTask @@ -74,13 +74,13 @@ func (c *MPPClient) ConstructMPPTasks(ctx context.Context, req *kv.MPPBuildTasks rangesForEachPartition[i] = NewKeyRanges(p.KeyRanges) partitionIDs[i] = p.ID } - tasks, err = buildBatchCopTasksForPartitionedTable(bo, c.store, rangesForEachPartition, kv.TiFlash, mppStoreLastFailTime, ttl, true, 20, partitionIDs) + tasks, err = buildBatchCopTasksForPartitionedTable(bo, c.store, rangesForEachPartition, kv.TiFlash, true, ttl, true, 20, partitionIDs) } else { if req.KeyRanges == nil { return c.selectAllTiFlashStore(), nil } ranges := NewKeyRanges(req.KeyRanges) - tasks, err = buildBatchCopTasksForNonPartitionedTable(bo, c.store, ranges, kv.TiFlash, mppStoreLastFailTime, ttl, true, 20) + tasks, err = buildBatchCopTasksForNonPartitionedTable(bo, c.store, ranges, kv.TiFlash, true, ttl, true, 20) } if err != nil { @@ -143,13 +143,15 @@ type mppIterator struct { tasks []*kv.MPPDispatchRequest finishCh chan struct{} - startTs uint64 + startTs uint64 + mppQueryID kv.MPPQueryID respChan chan *mppResponse cancelFunc context.CancelFunc - wg sync.WaitGroup + wg sync.WaitGroup + wgDoneChan chan struct{} closed uint32 @@ -188,6 +190,7 @@ func (m *mppIterator) run(ctx context.Context) { }(task) } m.wg.Wait() + close(m.wgDoneChan) close(m.respChan) } @@ -218,7 +221,8 @@ func (m *mppIterator) handleDispatchReq(ctx context.Context, bo *Backoffer, req } // meta for current task. - taskMeta := &mpp.TaskMeta{StartTs: req.StartTs, TaskId: req.ID, Address: req.Meta.GetAddress()} + taskMeta := &mpp.TaskMeta{StartTs: req.StartTs, QueryTs: req.MppQueryID.QueryTs, LocalQueryId: req.MppQueryID.LocalQueryID, TaskId: req.ID, ServerId: req.MppQueryID.ServerID, + Address: req.Meta.GetAddress()} mppReq := &mpp.DispatchTaskRequest{ Meta: taskMeta, @@ -235,13 +239,15 @@ func (m *mppIterator) handleDispatchReq(ctx context.Context, bo *Backoffer, req } } + disaggregatedTiFlash := config.GetGlobalConfig().DisaggregatedTiFlash wrappedReq := tikvrpc.NewRequest(tikvrpc.CmdMPPTask, mppReq, kvrpcpb.Context{}) - wrappedReq.StoreTp = tikvrpc.TiFlash + wrappedReq.StoreTp = getEndPointType(kv.TiFlash) // TODO: Handle dispatch task response correctly, including retry logic and cancel logic. var rpcResp *tikvrpc.Response var err error var retry bool + // If copTasks is not empty, we should send request according to region distribution. // Or else it's the task without region, which always happens in high layer task without table. // In that case @@ -253,6 +259,9 @@ func (m *mppIterator) handleDispatchReq(ctx context.Context, bo *Backoffer, req // That's a hard job but we can try it in the future. if sender.GetRPCError() != nil { logutil.BgLogger().Warn("mpp dispatch meet io error", zap.String("error", sender.GetRPCError().Error()), zap.Uint64("timestamp", taskMeta.StartTs), zap.Int64("task", taskMeta.TaskId)) + if disaggregatedTiFlash { + m.store.GetRegionCache().InvalidateTiFlashComputeStores() + } // if needTriggerFallback is true, we return timeout to trigger tikv's fallback if m.needTriggerFallback { err = derr.ErrTiFlashServerTimeout @@ -265,6 +274,9 @@ func (m *mppIterator) handleDispatchReq(ctx context.Context, bo *Backoffer, req if errors.Cause(err) == context.Canceled || status.Code(errors.Cause(err)) == codes.Canceled { retry = false } else if err != nil { + if disaggregatedTiFlash { + m.store.GetRegionCache().InvalidateTiFlashComputeStores() + } if bo.Backoff(tikv.BoTiFlashRPC(), err) == nil { retry = true } @@ -324,11 +336,12 @@ func (m *mppIterator) cancelMppTasks() { m.mu.Lock() defer m.mu.Unlock() killReq := &mpp.CancelTaskRequest{ - Meta: &mpp.TaskMeta{StartTs: m.startTs}, + Meta: &mpp.TaskMeta{StartTs: m.startTs, QueryTs: m.mppQueryID.QueryTs, LocalQueryId: m.mppQueryID.LocalQueryID, ServerId: m.mppQueryID.ServerID}, } + disaggregatedTiFlash := config.GetGlobalConfig().DisaggregatedTiFlash wrappedReq := tikvrpc.NewRequest(tikvrpc.CmdMPPCancel, killReq, kvrpcpb.Context{}) - wrappedReq.StoreTp = tikvrpc.TiFlash + wrappedReq.StoreTp = getEndPointType(kv.TiFlash) usedStoreAddrs := make(map[string]bool) for _, task := range m.tasks { @@ -342,6 +355,7 @@ func (m *mppIterator) cancelMppTasks() { } // send cancel cmd to all stores where tasks run + gotErr := atomic.Bool{} wg := util.WaitGroupWrapper{} for addr := range usedStoreAddrs { storeAddr := addr @@ -350,23 +364,33 @@ func (m *mppIterator) cancelMppTasks() { logutil.BgLogger().Debug("cancel task", zap.Uint64("query id ", m.startTs), zap.String("on addr", storeAddr)) if err != nil { logutil.BgLogger().Error("cancel task error", zap.Error(err), zap.Uint64("query id", m.startTs), zap.String("on addr", storeAddr)) + gotErr.CompareAndSwap(false, true) } }) } wg.Wait() + if gotErr.Load() && disaggregatedTiFlash { + m.store.GetRegionCache().InvalidateTiFlashComputeStores() + } } func (m *mppIterator) establishMPPConns(bo *Backoffer, req *kv.MPPDispatchRequest, taskMeta *mpp.TaskMeta) { connReq := &mpp.EstablishMPPConnectionRequest{ SenderMeta: taskMeta, ReceiverMeta: &mpp.TaskMeta{ - StartTs: req.StartTs, - TaskId: -1, + StartTs: req.StartTs, + QueryTs: m.mppQueryID.QueryTs, + LocalQueryId: m.mppQueryID.LocalQueryID, + ServerId: m.mppQueryID.ServerID, + TaskId: -1, }, } + var err error + disaggregatedTiFlash := config.GetGlobalConfig().DisaggregatedTiFlash + wrappedReq := tikvrpc.NewRequest(tikvrpc.CmdMPPConn, connReq, kvrpcpb.Context{}) - wrappedReq.StoreTp = tikvrpc.TiFlash + wrappedReq.StoreTp = getEndPointType(kv.TiFlash) // Drain results from root task. // We don't need to process any special error. When we meet errors, just let it fail. @@ -374,6 +398,9 @@ func (m *mppIterator) establishMPPConns(bo *Backoffer, req *kv.MPPDispatchReques if err != nil { logutil.BgLogger().Warn("establish mpp connection meet error and cannot retry", zap.String("error", err.Error()), zap.Uint64("timestamp", taskMeta.StartTs), zap.Int64("task", taskMeta.TaskId)) + if disaggregatedTiFlash { + m.store.GetRegionCache().InvalidateTiFlashComputeStores() + } // if needTriggerFallback is true, we return timeout to trigger tikv's fallback if m.needTriggerFallback { m.sendError(derr.ErrTiFlashServerTimeout) @@ -428,7 +455,7 @@ func (m *mppIterator) Close() error { close(m.finishCh) } m.cancelFunc() - m.wg.Wait() + <-m.wgDoneChan return nil } @@ -508,16 +535,18 @@ func (m *mppIterator) Next(ctx context.Context) (kv.ResultSubset, error) { } // DispatchMPPTasks dispatches all the mpp task and waits for the responses. -func (c *MPPClient) DispatchMPPTasks(ctx context.Context, variables interface{}, dispatchReqs []*kv.MPPDispatchRequest, needTriggerFallback bool, startTs uint64) kv.Response { +func (c *MPPClient) DispatchMPPTasks(ctx context.Context, variables interface{}, dispatchReqs []*kv.MPPDispatchRequest, needTriggerFallback bool, startTs uint64, mppQueryID kv.MPPQueryID) kv.Response { vars := variables.(*tikv.Variables) ctxChild, cancelFunc := context.WithCancel(ctx) iter := &mppIterator{ store: c.store, tasks: dispatchReqs, finishCh: make(chan struct{}), + wgDoneChan: make(chan struct{}), cancelFunc: cancelFunc, - respChan: make(chan *mppResponse, 4096), + respChan: make(chan *mppResponse), startTs: startTs, + mppQueryID: mppQueryID, vars: vars, needTriggerFallback: needTriggerFallback, enableCollectExecutionInfo: config.GetGlobalConfig().Instance.EnableCollectExecutionInfo.Load(), diff --git a/store/copr/mpp_probe.go b/store/copr/mpp_probe.go new file mode 100644 index 0000000000000..0a0eba286648e --- /dev/null +++ b/store/copr/mpp_probe.go @@ -0,0 +1,270 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package copr + +import ( + "context" + "fmt" + "sync" + "sync/atomic" + "time" + + "github.com/pingcap/kvproto/pkg/kvrpcpb" + "github.com/pingcap/kvproto/pkg/mpp" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/util/logutil" + "github.com/tikv/client-go/v2/tikv" + "github.com/tikv/client-go/v2/tikvrpc" + "go.uber.org/zap" +) + +// GlobalMPPFailedStoreProber mpp failed store probe +var GlobalMPPFailedStoreProber *MPPFailedStoreProber + +const ( + // DetectPeriod detect period + DetectPeriod = 3 * time.Second + // DetectTimeoutLimit detect timeout + DetectTimeoutLimit = 2 * time.Second + // MaxRecoveryTimeLimit wait TiFlash recovery,more than MPPStoreFailTTL + MaxRecoveryTimeLimit = 15 * time.Minute + // MaxObsoletTimeLimit no request for a long time,that might be obsoleted + MaxObsoletTimeLimit = time.Hour +) + +// MPPStoreState the state for MPPStore. +type MPPStoreState struct { + address string // MPPStore TiFlash address + tikvClient tikv.Client + + lock struct { + sync.Mutex + + recoveryTime time.Time + lastLookupTime time.Time + lastDetectTime time.Time + } +} + +// MPPFailedStoreProber use for detecting of failed TiFlash instance +type MPPFailedStoreProber struct { + failedMPPStores *sync.Map + lock *sync.Mutex + isStop *atomic.Bool + wg *sync.WaitGroup + ctx context.Context + cancel context.CancelFunc + + detectPeriod time.Duration + detectTimeoutLimit time.Duration + maxRecoveryTimeLimit time.Duration + maxObsoletTimeLimit time.Duration +} + +func (t *MPPStoreState) detect(ctx context.Context, detectPeriod time.Duration, detectTimeoutLimit time.Duration) { + if time.Since(t.lock.lastDetectTime) < detectPeriod { + return + } + + defer func() { t.lock.lastDetectTime = time.Now() }() + metrics.TiFlashFailedMPPStoreState.WithLabelValues(t.address).Set(0) + ok := detectMPPStore(ctx, t.tikvClient, t.address, detectTimeoutLimit) + if !ok { + metrics.TiFlashFailedMPPStoreState.WithLabelValues(t.address).Set(1) + t.lock.recoveryTime = time.Time{} // if detect failed,reset recovery time to zero. + return + } + + // record the time of the first recovery + if t.lock.recoveryTime.IsZero() { + t.lock.recoveryTime = time.Now() + } +} + +func (t *MPPStoreState) isRecovery(ctx context.Context, recoveryTTL time.Duration) bool { + if !t.lock.TryLock() { + return false + } + defer t.lock.Unlock() + + t.lock.lastLookupTime = time.Now() + if !t.lock.recoveryTime.IsZero() && time.Since(t.lock.recoveryTime) > recoveryTTL { + return true + } + logutil.Logger(ctx).Debug("Cannot detect store's availability "+ + "because the current time has not recovery or wait mppStoreFailTTL", + zap.String("store address", t.address), + zap.Time("recovery time", t.lock.recoveryTime), + zap.Duration("MPPStoreFailTTL", recoveryTTL)) + return false +} + +func (t MPPFailedStoreProber) scan(ctx context.Context) { + defer func() { + if r := recover(); r != nil { + logutil.Logger(ctx).Warn("mpp failed store probe scan error,will restart", zap.Any("recover", r), zap.Stack("stack")) + } + }() + + do := func(k, v any) { + address := fmt.Sprint(k) + state, ok := v.(*MPPStoreState) + if !ok { + logutil.BgLogger().Warn("MPPStoreState struct assert failed,will be clean", + zap.String("address", address)) + t.Delete(address) + return + } + + if !state.lock.TryLock() { + return + } + defer state.lock.Unlock() + + state.detect(ctx, t.detectPeriod, t.detectTimeoutLimit) + + // clean restored store + if !state.lock.recoveryTime.IsZero() && time.Since(state.lock.recoveryTime) > t.maxRecoveryTimeLimit { + t.Delete(address) + // clean store that may be obsolete + } else if state.lock.recoveryTime.IsZero() && time.Since(state.lock.lastLookupTime) > t.maxObsoletTimeLimit { + t.Delete(address) + } + } + + f := func(k, v any) bool { + go do(k, v) + return true + } + + metrics.TiFlashFailedMPPStoreState.WithLabelValues("probe").Set(-1) //probe heartbeat + t.failedMPPStores.Range(f) +} + +// Add add a store when sync probe failed +func (t *MPPFailedStoreProber) Add(ctx context.Context, address string, tikvClient tikv.Client) { + state := MPPStoreState{ + address: address, + tikvClient: tikvClient, + } + state.lock.lastLookupTime = time.Now() + logutil.Logger(ctx).Debug("add mpp store to failed list", zap.String("address", address)) + t.failedMPPStores.Store(address, &state) +} + +// IsRecovery check whether the store is recovery +func (t *MPPFailedStoreProber) IsRecovery(ctx context.Context, address string, recoveryTTL time.Duration) bool { + logutil.Logger(ctx).Debug("check failed store recovery", + zap.String("address", address), zap.Duration("ttl", recoveryTTL)) + v, ok := t.failedMPPStores.Load(address) + if !ok { + // store not in failed map + return true + } + + state, ok := v.(*MPPStoreState) + if !ok { + logutil.BgLogger().Warn("MPPStoreState struct assert failed,will be clean", + zap.String("address", address)) + t.Delete(address) + return false + } + + return state.isRecovery(ctx, recoveryTTL) +} + +// Run a loop of scan +// there can be only one background task +func (t *MPPFailedStoreProber) Run() { + if !t.lock.TryLock() { + return + } + t.wg.Add(1) + t.isStop.Swap(false) + go func() { + defer t.wg.Done() + defer t.lock.Unlock() + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + for { + select { + case <-t.ctx.Done(): + logutil.BgLogger().Debug("ctx.done") + return + case <-ticker.C: + t.scan(t.ctx) + } + } + }() + logutil.BgLogger().Debug("run a background probe process for mpp") +} + +// Stop stop background goroutine +func (t *MPPFailedStoreProber) Stop() { + if !t.isStop.CompareAndSwap(false, true) { + return + } + t.cancel() + t.wg.Wait() + logutil.BgLogger().Debug("stop background task") +} + +// Delete clean store from failed map +func (t *MPPFailedStoreProber) Delete(address string) { + metrics.TiFlashFailedMPPStoreState.DeleteLabelValues(address) + _, ok := t.failedMPPStores.LoadAndDelete(address) + if !ok { + logutil.BgLogger().Warn("Store is deleted", zap.String("address", address)) + } +} + +// MPPStore detect function +func detectMPPStore(ctx context.Context, client tikv.Client, address string, detectTimeoutLimit time.Duration) bool { + resp, err := client.SendRequest(ctx, address, &tikvrpc.Request{ + Type: tikvrpc.CmdMPPAlive, + StoreTp: tikvrpc.TiFlash, + Req: &mpp.IsAliveRequest{}, + Context: kvrpcpb.Context{}, + }, detectTimeoutLimit) + if err != nil || !resp.Resp.(*mpp.IsAliveResponse).Available { + if err == nil { + err = fmt.Errorf("store not ready to serve") + } + logutil.BgLogger().Warn("Store is not ready", + zap.String("store address", address), + zap.String("err message", err.Error())) + return false + } + return true +} + +func init() { + ctx, cancel := context.WithCancel(context.Background()) + isStop := atomic.Bool{} + isStop.Swap(true) + GlobalMPPFailedStoreProber = &MPPFailedStoreProber{ + failedMPPStores: &sync.Map{}, + lock: &sync.Mutex{}, + isStop: &isStop, + ctx: ctx, + cancel: cancel, + wg: &sync.WaitGroup{}, + detectPeriod: DetectPeriod, + detectTimeoutLimit: DetectTimeoutLimit, + maxRecoveryTimeLimit: MaxRecoveryTimeLimit, + maxObsoletTimeLimit: MaxObsoletTimeLimit, + } +} diff --git a/store/copr/mpp_probe_test.go b/store/copr/mpp_probe_test.go new file mode 100644 index 0000000000000..7826c970d3e1e --- /dev/null +++ b/store/copr/mpp_probe_test.go @@ -0,0 +1,177 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package copr + +import ( + "context" + "testing" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/kvproto/pkg/mpp" + "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/tikvrpc" +) + +const ( + testimeout = "timeout" + Error = "error" + Normal = "normal" +) + +type mockDetectClient struct { + errortestype string +} + +func (t *mockDetectClient) CloseAddr(string) error { + return nil +} + +func (t *mockDetectClient) Close() error { + return nil +} + +func (t *mockDetectClient) SendRequest( + ctx context.Context, + addr string, + req *tikvrpc.Request, + timeout time.Duration, +) (*tikvrpc.Response, error) { + if t.errortestype == Error { + return nil, errors.New("store error") + } else if t.errortestype == testimeout { + return &tikvrpc.Response{Resp: &mpp.IsAliveResponse{}}, nil + } + + return &tikvrpc.Response{Resp: &mpp.IsAliveResponse{Available: true}}, nil +} + +type ProbeTest map[string]*mockDetectClient + +func (t ProbeTest) add(ctx context.Context) { + for k, v := range t { + GlobalMPPFailedStoreProber.Add(ctx, k, v) + } +} + +func (t ProbeTest) reSetErrortestype(to string) { + for k, v := range t { + if to == Normal { + v.errortestype = Normal + } else { + v.errortestype = k + } + } +} + +func (t ProbeTest) judge(ctx context.Context, test *testing.T, recoveryTTL time.Duration, need bool) { + for k := range t { + ok := GlobalMPPFailedStoreProber.IsRecovery(ctx, k, recoveryTTL) + require.Equal(test, need, ok) + } +} + +func failedStoreSizeJudge(ctx context.Context, test *testing.T, need int) { + var l int + GlobalMPPFailedStoreProber.scan(ctx) + time.Sleep(time.Second / 10) + GlobalMPPFailedStoreProber.failedMPPStores.Range(func(k, v interface{}) bool { + l++ + return true + }) + require.Equal(test, need, l) +} + +func testFlow(ctx context.Context, probetestest ProbeTest, test *testing.T, flow []string) { + probetestest.add(ctx) + for _, to := range flow { + probetestest.reSetErrortestype(to) + + GlobalMPPFailedStoreProber.scan(ctx) + time.Sleep(time.Second / 10) //wait detect goroutine finish + + var need bool + if to == Normal { + need = true + } + probetestest.judge(ctx, test, 0, need) + probetestest.judge(ctx, test, time.Minute, false) + } + + lastTo := flow[len(flow)-1] + cleanRecover := func(need int) { + GlobalMPPFailedStoreProber.maxRecoveryTimeLimit = 0 - time.Second + failedStoreSizeJudge(ctx, test, need) + GlobalMPPFailedStoreProber.maxRecoveryTimeLimit = MaxRecoveryTimeLimit + } + + cleanObsolet := func(need int) { + GlobalMPPFailedStoreProber.maxObsoletTimeLimit = 0 - time.Second + failedStoreSizeJudge(ctx, test, need) + GlobalMPPFailedStoreProber.maxObsoletTimeLimit = MaxObsoletTimeLimit + } + + if lastTo == Error { + cleanRecover(2) + cleanObsolet(0) + } else if lastTo == Normal { + cleanObsolet(2) + cleanRecover(0) + } +} + +func TestMPPFailedStoreProbe(t *testing.T) { + ctx := context.Background() + + notExistAddress := "not exist address" + + GlobalMPPFailedStoreProber.detectPeriod = 0 - time.Second + + // check not exist address + ok := GlobalMPPFailedStoreProber.IsRecovery(ctx, notExistAddress, 0) + require.True(t, ok) + + GlobalMPPFailedStoreProber.scan(ctx) + + probetestest := map[string]*mockDetectClient{ + testimeout: {errortestype: testimeout}, + Error: {errortestype: Error}, + } + + testFlowFinallyRecover := []string{Error, Normal, Error, Error, Normal} + testFlow(ctx, probetestest, t, testFlowFinallyRecover) + testFlowFinallyDesert := []string{Error, Normal, Normal, Error, Error} + testFlow(ctx, probetestest, t, testFlowFinallyDesert) +} + +func TestMPPFailedStoreProbeGoroutineTask(t *testing.T) { + // Confirm that multiple tasks are not allowed + GlobalMPPFailedStoreProber.lock.Lock() + GlobalMPPFailedStoreProber.Run() + GlobalMPPFailedStoreProber.lock.Unlock() + + GlobalMPPFailedStoreProber.Run() + GlobalMPPFailedStoreProber.Stop() +} + +func TestMPPFailedStoreAssertFailed(t *testing.T) { + ctx := context.Background() + + GlobalMPPFailedStoreProber.failedMPPStores.Store("errorinfo", nil) + GlobalMPPFailedStoreProber.scan(ctx) + + GlobalMPPFailedStoreProber.failedMPPStores.Store("errorinfo", nil) + GlobalMPPFailedStoreProber.IsRecovery(ctx, "errorinfo", 0) +} diff --git a/store/copr/region_cache.go b/store/copr/region_cache.go index 4aa970aa458a4..97c3d705c223b 100644 --- a/store/copr/region_cache.go +++ b/store/copr/region_cache.go @@ -18,9 +18,12 @@ import ( "bytes" "strconv" + "github.com/pingcap/kvproto/pkg/coprocessor" + "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" "github.com/pingcap/tidb/kv" derr "github.com/pingcap/tidb/store/driver/error" + "github.com/pingcap/tidb/store/driver/options" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mathutil" "github.com/tikv/client-go/v2/metrics" @@ -199,3 +202,28 @@ func (c *RegionCache) OnSendFailForBatchRegions(bo *Backoffer, store *tikv.Store c.OnSendFailForTiFlash(bo.TiKVBackoffer(), store, ri.Region, ri.Meta, scheduleReload, err, !(index < 10 || log.GetLevel() <= zap.DebugLevel)) } } + +// BuildBatchTask fetches store and peer info for cop task, wrap it as `batchedCopTask`. +func (c *RegionCache) BuildBatchTask(bo *Backoffer, task *copTask, replicaRead kv.ReplicaReadType) (*batchedCopTask, error) { + rpcContext, err := c.GetTiKVRPCContext(bo.TiKVBackoffer(), task.region, options.GetTiKVReplicaReadType(replicaRead), 0) + if err != nil { + return nil, err + } + // fallback to non-batch path + if rpcContext == nil { + return nil, nil + } + return &batchedCopTask{ + task: task, + region: coprocessor.RegionInfo{ + RegionId: rpcContext.Region.GetID(), + RegionEpoch: &metapb.RegionEpoch{ + ConfVer: rpcContext.Region.GetConfVer(), + Version: rpcContext.Region.GetVer(), + }, + Ranges: task.ranges.ToPBRanges(), + }, + storeID: rpcContext.Store.StoreID(), + peer: rpcContext.Peer, + }, nil +} diff --git a/store/copr/store.go b/store/copr/store.go index ad7ebb5dd9a63..32553961acc67 100644 --- a/store/copr/store.go +++ b/store/copr/store.go @@ -21,6 +21,7 @@ import ( "time" "github.com/pingcap/errors" + tidb_config "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/store/driver/backoff" derr "github.com/pingcap/tidb/store/driver/error" @@ -83,6 +84,7 @@ func NewStore(s *tikv.KVStore, coprCacheConfig *config.CoprocessorCache) (*Store if err != nil { return nil, errors.Trace(err) } + /* #nosec G404 */ return &Store{ kvStore: &kvStore{store: s}, @@ -122,6 +124,9 @@ func getEndPointType(t kv.StoreType) tikvrpc.EndpointType { case kv.TiKV: return tikvrpc.TiKV case kv.TiFlash: + if tidb_config.GetGlobalConfig().DisaggregatedTiFlash { + return tikvrpc.TiFlashCompute + } return tikvrpc.TiFlash case kv.TiDB: return tikvrpc.TiDB diff --git a/store/driver/BUILD.bazel b/store/driver/BUILD.bazel index e3b0480f7e11d..d68f71cd44839 100644 --- a/store/driver/BUILD.bazel +++ b/store/driver/BUILD.bazel @@ -7,6 +7,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//kv", + "//sessionctx/variable", "//store/copr", "//store/driver/error", "//store/driver/txn", @@ -19,6 +20,7 @@ go_library( "@com_github_tikv_client_go_v2//tikv", "@com_github_tikv_client_go_v2//tikvrpc", "@com_github_tikv_client_go_v2//util", + "@com_github_tikv_pd//pkg/mcs/resource_manager/client", "@com_github_tikv_pd_client//:client", "@org_golang_google_grpc//:grpc", "@org_golang_google_grpc//keepalive", diff --git a/store/driver/error/error.go b/store/driver/error/error.go index 1d9543cc1437d..4be6e3628c5cc 100644 --- a/store/driver/error/error.go +++ b/store/driver/error/error.go @@ -102,9 +102,6 @@ func ToTiDBErr(err error) error { var pdServerTimeout *tikverr.ErrPDServerTimeout if stderrs.As(err, &pdServerTimeout) { - if len(pdServerTimeout.Error()) == 0 { - return ErrPDServerTimeout - } return ErrPDServerTimeout.GenWithStackByArgs(pdServerTimeout.Error()) } diff --git a/store/driver/error/error_test.go b/store/driver/error/error_test.go index dde341e8da4f1..f1f2878fb7743 100644 --- a/store/driver/error/error_test.go +++ b/store/driver/error/error_test.go @@ -29,6 +29,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/driver/main_test.go b/store/driver/main_test.go index 0b4cc12bbe62f..e0c805a52a952 100644 --- a/store/driver/main_test.go +++ b/store/driver/main_test.go @@ -41,6 +41,7 @@ func TestMain(m *testing.M) { tikv.EnableFailpoints() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/driver/options/options.go b/store/driver/options/options.go index 1b677ffc348d0..f3d5471aa440f 100644 --- a/store/driver/options/options.go +++ b/store/driver/options/options.go @@ -32,6 +32,8 @@ func GetTiKVReplicaReadType(t kv.ReplicaReadType) storekv.ReplicaReadType { return storekv.ReplicaReadMixed case kv.ReplicaReadClosestAdaptive: return storekv.ReplicaReadMixed + case kv.ReplicaReadLearner: + return storekv.ReplicaReadLearner } return 0 } diff --git a/store/driver/tikv_driver.go b/store/driver/tikv_driver.go index e1ba5d121608f..d732665bb45a4 100644 --- a/store/driver/tikv_driver.go +++ b/store/driver/tikv_driver.go @@ -28,6 +28,7 @@ import ( deadlockpb "github.com/pingcap/kvproto/pkg/deadlock" "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/store/copr" derr "github.com/pingcap/tidb/store/driver/error" txn_driver "github.com/pingcap/tidb/store/driver/txn" @@ -38,6 +39,7 @@ import ( "github.com/tikv/client-go/v2/tikvrpc" "github.com/tikv/client-go/v2/util" pd "github.com/tikv/pd/client" + rmclient "github.com/tikv/pd/pkg/mcs/resource_manager/client" "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/keepalive" @@ -53,6 +55,10 @@ var mc storeCache func init() { mc.cache = make(map[string]*tikvStore) rand.Seed(time.Now().UnixNano()) + + // Setup the Hooks to dynamic control global resource controller. + variable.EnableGlobalResourceControlFunc = tikv.EnableResourceControl + variable.DisableGlobalResourceControlFunc = tikv.DisableResourceControl } // Option is a function that changes some config of Driver @@ -86,8 +92,28 @@ func WithPDClientConfig(client config.PDClient) Option { } } +// TrySetupGlobalResourceController tries to setup global resource controller. +func TrySetupGlobalResourceController(ctx context.Context, serverID uint64, s kv.Storage) error { + var ( + store *tikvStore + ok bool + ) + if store, ok = s.(*tikvStore); !ok { + return errors.New("cannot setup up resource controller, should use tikv storage") + } + + control, err := rmclient.NewResourceGroupController(serverID, store.GetPDClient(), rmclient.DefaultRequestUnitConfig()) + if err != nil { + return err + } + tikv.SetResourceControlInterceptor(control) + control.Start(ctx) + return nil +} + // TiKVDriver implements engine TiKV. type TiKVDriver struct { + keyspaceName string pdConfig config.PDClient security config.Security tikvConfig config.TiKVClient @@ -117,7 +143,7 @@ func (d TiKVDriver) OpenWithOptions(path string, options ...Option) (kv.Storage, mc.Lock() defer mc.Unlock() d.setDefaultAndOptions(options...) - etcdAddrs, disableGC, err := config.ParsePath(path) + etcdAddrs, disableGC, keyspaceName, err := config.ParsePath(path) if err != nil { return nil, errors.Trace(err) } @@ -157,11 +183,39 @@ func (d TiKVDriver) OpenWithOptions(path string, options ...Option) (kv.Storage, return nil, errors.Trace(err) } - pdClient := tikv.CodecPDClient{Client: pdCli} - s, err := tikv.NewKVStore(uuid, &pdClient, spkv, tikv.NewRPCClient(tikv.WithSecurity(d.security))) + // ---------------- keyspace logic ---------------- + var ( + pdClient *tikv.CodecPDClient + ) + + if keyspaceName == "" { + logutil.BgLogger().Info("using API V1.") + pdClient = tikv.NewCodecPDClient(tikv.ModeTxn, pdCli) + } else { + logutil.BgLogger().Info("using API V2.", zap.String("keyspaceName", keyspaceName)) + pdClient, err = tikv.NewCodecPDClientWithKeyspace(tikv.ModeTxn, pdCli, keyspaceName) + if err != nil { + return nil, errors.Trace(err) + } + // If there's setting keyspace-name, then skipped GC worker logic. + // It needs a group of special tidb nodes to execute GC worker logic. + // TODO: remove this restriction while merged keyspace GC worker logic. + disableGC = true + } + + codec := pdClient.GetCodec() + + rpcClient := tikv.NewRPCClient( + tikv.WithSecurity(d.security), + tikv.WithCodec(codec), + ) + + s, err := tikv.NewKVStore(uuid, pdClient, spkv, rpcClient) if err != nil { return nil, errors.Trace(err) } + + // ---------------- keyspace logic ---------------- if d.txnLocalLatches.Enabled { s.EnableTxnLocalLatches(d.txnLocalLatches.Capacity) } @@ -178,6 +232,7 @@ func (d TiKVDriver) OpenWithOptions(path string, options ...Option) (kv.Storage, memCache: kv.NewCacheDB(), enableGC: !disableGC, coprStore: coprStore, + codec: codec, } mc.cache[uuid] = store @@ -192,6 +247,7 @@ type tikvStore struct { enableGC bool gcWorker *gcworker.GCWorker coprStore *copr.Store + codec tikv.Codec } // Name gets the name of the storage engine @@ -343,3 +399,7 @@ func (s *tikvStore) GetLockWaits() ([]*deadlockpb.WaitForEntry, error) { } return result, nil } + +func (s *tikvStore) GetCodec() tikv.Codec { + return s.codec +} diff --git a/store/driver/txn/BUILD.bazel b/store/driver/txn/BUILD.bazel index ab10c88f12c9c..f6e5e46014a97 100644 --- a/store/driver/txn/BUILD.bazel +++ b/store/driver/txn/BUILD.bazel @@ -24,6 +24,7 @@ go_library( "//table/tables", "//tablecodec", "//types", + "//util", "//util/logutil", "@com_github_opentracing_opentracing_go//:opentracing-go", "@com_github_pingcap_errors//:errors", diff --git a/store/driver/txn/error.go b/store/driver/txn/error.go index 8340459f3e64c..80543fe2f8513 100644 --- a/store/driver/txn/error.go +++ b/store/driver/txn/error.go @@ -33,6 +33,7 @@ import ( "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/logutil" tikverr "github.com/tikv/client-go/v2/error" "go.uber.org/zap" @@ -46,7 +47,7 @@ func genKeyExistsError(name string, value string, err error) error { } func extractKeyExistsErrFromHandle(key kv.Key, value []byte, tblInfo *model.TableInfo) error { - const name = "PRIMARY" + name := tblInfo.Name.String() + ".PRIMARY" _, handle, err := tablecodec.DecodeRecordKey(key) if err != nil { return genKeyExistsError(name, key.String(), err) @@ -100,6 +101,9 @@ func extractKeyExistsErrFromHandle(key kv.Key, value []byte, tblInfo *model.Tabl if col.Length > 0 && len(str) > col.Length { str = str[:col.Length] } + if types.IsBinaryStr(&tblInfo.Columns[col.Offset].FieldType) || types.IsTypeBit(&tblInfo.Columns[col.Offset].FieldType) { + str = util.FmtNonASCIIPrintableCharToHex(str) + } valueStr = append(valueStr, str) } return genKeyExistsError(name, strings.Join(valueStr, "-"), nil) @@ -115,7 +119,7 @@ func extractKeyExistsErrFromIndex(key kv.Key, value []byte, tblInfo *model.Table if idxInfo == nil { return genKeyExistsError("UNKNOWN", key.String(), errors.New("cannot find index info")) } - name := idxInfo.Name.String() + name := tblInfo.Name.String() + "." + idxInfo.Name.String() if len(value) == 0 { return genKeyExistsError(name, key.String(), errors.New("missing value")) @@ -136,6 +140,9 @@ func extractKeyExistsErrFromIndex(key kv.Key, value []byte, tblInfo *model.Table if err != nil { return genKeyExistsError(name, key.String(), err) } + if types.IsBinaryStr(colInfo[i].Ft) || types.IsTypeBit(colInfo[i].Ft) { + str = util.FmtNonASCIIPrintableCharToHex(str) + } valueStr = append(valueStr, str) } return genKeyExistsError(name, strings.Join(valueStr, "-"), nil) diff --git a/store/driver/txn/main_test.go b/store/driver/txn/main_test.go index ad777bb5af019..7c5fb240d8958 100644 --- a/store/driver/txn/main_test.go +++ b/store/driver/txn/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/driver/txn/snapshot.go b/store/driver/txn/snapshot.go index 66c82f86eaedb..4adcfcf1b07f8 100644 --- a/store/driver/txn/snapshot.go +++ b/store/driver/txn/snapshot.go @@ -135,6 +135,8 @@ func (s *tikvSnapshot) SetOption(opt int, val interface{}) { if size > 0 { s.KVSnapshot.SetScanBatchSize(size) } + case kv.ResourceGroupName: + s.KVSnapshot.SetResourceGroupName(val.(string)) } } diff --git a/store/driver/txn/txn_driver.go b/store/driver/txn/txn_driver.go index 851e68eac89ef..1892b6674032c 100644 --- a/store/driver/txn/txn_driver.go +++ b/store/driver/txn/txn_driver.go @@ -15,6 +15,7 @@ package txn import ( + "bytes" "context" "sync/atomic" @@ -72,8 +73,22 @@ func (txn *tikvTxn) CacheTableInfo(id int64, info *model.TableInfo) { func (txn *tikvTxn) LockKeys(ctx context.Context, lockCtx *kv.LockCtx, keysInput ...kv.Key) error { keys := toTiKVKeys(keysInput) + txn.exitAggressiveLockingIfInapplicable(ctx, keys) err := txn.KVTxn.LockKeys(ctx, lockCtx, keys...) - return txn.extractKeyErr(err) + if err != nil { + return txn.extractKeyErr(err) + } + return txn.generateWriteConflictForLockedWithConflict(lockCtx) +} + +func (txn *tikvTxn) LockKeysFunc(ctx context.Context, lockCtx *kv.LockCtx, fn func(), keysInput ...kv.Key) error { + keys := toTiKVKeys(keysInput) + txn.exitAggressiveLockingIfInapplicable(ctx, keys) + err := txn.KVTxn.LockKeysFunc(ctx, lockCtx, fn, keys...) + if err != nil { + return txn.extractKeyErr(err) + } + return txn.generateWriteConflictForLockedWithConflict(lockCtx) } func (txn *tikvTxn) Commit(ctx context.Context) error { @@ -218,8 +233,6 @@ func (txn *tikvTxn) SetOption(opt int, val interface{}) { } else { txn.KVTxn.GetSnapshot().SetRuntimeStats(val.(*txnsnapshot.SnapshotRuntimeStats)) } - case kv.SchemaAmender: - txn.SetSchemaAmender(val.(tikv.SchemaAmender)) case kv.SampleStep: txn.KVTxn.GetSnapshot().SetSampleStep(val.(uint32)) case kv.CommitHook: @@ -258,6 +271,10 @@ func (txn *tikvTxn) SetOption(opt int, val interface{}) { txn.KVTxn.SetRequestSourceType(val.(string)) case kv.ReplicaReadAdjuster: txn.KVTxn.GetSnapshot().SetReplicaReadAdjuster(val.(txnkv.ReplicaReadAdjuster)) + case kv.TxnSource: + txn.KVTxn.SetTxnSource(val.(uint64)) + case kv.ResourceGroupName: + txn.KVTxn.SetResourceGroupName(val.(string)) } } @@ -333,6 +350,65 @@ func (txn *tikvTxn) UpdateMemBufferFlags(key []byte, flags ...kv.FlagsOp) { txn.GetUnionStore().GetMemBuffer().UpdateFlags(key, getTiKVFlagsOps(flags)...) } +func (txn *tikvTxn) exitAggressiveLockingIfInapplicable(ctx context.Context, keys [][]byte) { + if len(keys) > 1 && txn.IsInAggressiveLockingMode() { + // Only allow aggressive locking if it only needs to lock one key. Considering that it's possible that a + // statement causes multiple calls to `LockKeys` (which means some keys may have been locked in aggressive + // locking mode), here we exit aggressive locking mode by calling DoneAggressiveLocking instead of cancelling. + // Then the previously-locked keys during execution in this statement (if any) will be turned into the state + // as if they were locked in normal way. + // Note that the issue https://github.com/pingcap/tidb/issues/35682 also exists here. + txn.KVTxn.DoneAggressiveLocking(ctx) + } +} + +func (txn *tikvTxn) generateWriteConflictForLockedWithConflict(lockCtx *kv.LockCtx) error { + if lockCtx.MaxLockedWithConflictTS != 0 { + var bufTableID, bufRest bytes.Buffer + foundKey := false + for k, v := range lockCtx.Values { + if v.LockedWithConflictTS >= lockCtx.MaxLockedWithConflictTS { + foundKey = true + prettyWriteKey(&bufTableID, &bufRest, []byte(k)) + break + } + } + if !foundKey { + bufTableID.WriteString("") + } + // TODO: Primary is not exported here. + primary := " primary=" + primaryRest := "" + return kv.ErrWriteConflict.FastGenByArgs(txn.StartTS(), 0, lockCtx.MaxLockedWithConflictTS, bufTableID.String(), bufRest.String(), primary, primaryRest, "LockedWithConflict") + } + return nil +} + +// StartAggressiveLocking adapts the method signature of `KVTxn` to satisfy kv.AggressiveLockingController. +// TODO: Update the methods' signatures in client-go to avoid this adaptor functions. +func (txn *tikvTxn) StartAggressiveLocking() error { + txn.KVTxn.StartAggressiveLocking() + return nil +} + +// RetryAggressiveLocking adapts the method signature of `KVTxn` to satisfy kv.AggressiveLockingController. +func (txn *tikvTxn) RetryAggressiveLocking(ctx context.Context) error { + txn.KVTxn.RetryAggressiveLocking(ctx) + return nil +} + +// CancelAggressiveLocking adapts the method signature of `KVTxn` to satisfy kv.AggressiveLockingController. +func (txn *tikvTxn) CancelAggressiveLocking(ctx context.Context) error { + txn.KVTxn.CancelAggressiveLocking(ctx) + return nil +} + +// DoneAggressiveLocking adapts the method signature of `KVTxn` to satisfy kv.AggressiveLockingController. +func (txn *tikvTxn) DoneAggressiveLocking(ctx context.Context) error { + txn.KVTxn.DoneAggressiveLocking(ctx) + return nil +} + // TiDBKVFilter is the filter specific to TiDB to filter out KV pairs that needn't be committed. type TiDBKVFilter struct{} diff --git a/store/gcworker/gc_worker.go b/store/gcworker/gc_worker.go index 92c3b535ba5d3..ce1e9fb3ec8fa 100644 --- a/store/gcworker/gc_worker.go +++ b/store/gcworker/gc_worker.go @@ -79,7 +79,7 @@ type GCWorker struct { batchResolveLocks func(locks []*txnlock.Lock, regionID tikv.RegionVerID, safepoint uint64) (ok bool, err error) resolveLocks func(locks []*txnlock.Lock, lowResolutionTS uint64) (int64, error) } - logBackupEnabled bool + logBackupEnabled bool // check log-backup task existed. } // NewGCWorker creates a GCWorker instance. @@ -912,6 +912,10 @@ func needsGCOperationForStore(store *metapb.Store) (bool, error) { // skip physical resolve locks for it. return false, nil + case placement.EngineLabelTiFlashCompute: + logutil.BgLogger().Debug("[gc worker] will ignore gc tiflash_compute node") + return false, nil + case placement.EngineLabelTiKV, "": // If no engine label is set, it should be a TiKV node. return true, nil @@ -1790,7 +1794,7 @@ func (w *GCWorker) checkLeader(ctx context.Context) (bool, error) { se := createSession(w.store) defer se.Close() - w.logBackupEnabled = utils.CheckLogBackupEnabled(se) + w.logBackupEnabled = utils.IsLogBackupInUse(se) _, err := se.ExecuteInternal(ctx, "BEGIN") if err != nil { return false, errors.Trace(err) @@ -2006,6 +2010,10 @@ func (w *GCWorker) doGCPlacementRules(se session.Session, safePoint uint64, dr u if err = historyJob.DecodeArgs(&physicalTableIDs); err != nil { return } + case model.ActionReorganizePartition: + if err = historyJob.DecodeArgs(&physicalTableIDs); err != nil { + return + } } if len(physicalTableIDs) == 0 { @@ -2028,7 +2036,6 @@ func (w *GCWorker) doGCPlacementRules(se session.Session, safePoint uint64, dr u zap.Int64("tableID", id), zap.String("endKey", string(dr.EndKey)), zap.Uint64("safePoint", safePoint)) ruleID := fmt.Sprintf("table-%v-r", id) if err := infosync.DeleteTiFlashPlacementRule(context.Background(), "tiflash", ruleID); err != nil { - // If DeletePlacementRule fails here, the rule will be deleted in `HandlePlacementRuleRoutine`. logutil.BgLogger().Error("delete TiFlash pd rule failed when gc", zap.Error(err), zap.String("ruleID", ruleID), zap.Uint64("safePoint", safePoint)) } else { diff --git a/store/gcworker/gc_worker_test.go b/store/gcworker/gc_worker_test.go index 8d9ae4c9ae377..4fde3dd44cd12 100644 --- a/store/gcworker/gc_worker_test.go +++ b/store/gcworker/gc_worker_test.go @@ -1117,6 +1117,11 @@ func TestRunGCJob(t *testing.T) { pdSafePoint := s.mustGetSafePointFromPd(t) require.Equal(t, safePoint, pdSafePoint) + require.NoError(t, s.gcWorker.saveTime(gcSafePointKey, oracle.GetTimeFromTS(safePoint))) + tikvSafePoint, err := s.gcWorker.loadTime(gcSafePointKey) + require.NoError(t, err) + require.Equal(t, *tikvSafePoint, oracle.GetTimeFromTS(safePoint)) + etcdSafePoint := s.loadEtcdSafePoint(t) require.Equal(t, safePoint, etcdSafePoint) diff --git a/store/gcworker/main_test.go b/store/gcworker/main_test.go index 4451f16783160..df72adb3a8f27 100644 --- a/store/gcworker/main_test.go +++ b/store/gcworker/main_test.go @@ -31,6 +31,7 @@ func TestMain(m *testing.M) { goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), } callback := func(i int) int { // wait for MVCCLevelDB to close, MVCCLevelDB will be closed in one second diff --git a/store/helper/helper.go b/store/helper/helper.go index 995cf0b5fe675..c4fe7c7cc38f0 100644 --- a/store/helper/helper.go +++ b/store/helper/helper.go @@ -78,6 +78,7 @@ type Storage interface { Closed() <-chan struct{} GetMinSafeTS(txnScope string) uint64 GetLockWaits() ([]*deadlockpb.WaitForEntry, error) + GetCodec() tikv.Codec } // Helper is a middleware to get some information from tikv/pd. It can be used for TiDB's http api or mem table. @@ -653,11 +654,11 @@ func newTableWithKeyRange(db *model.DBInfo, table *model.TableInfo) TableInfoWit // NewIndexWithKeyRange constructs TableInfoWithKeyRange for given index, it is exported only for test. func NewIndexWithKeyRange(db *model.DBInfo, table *model.TableInfo, index *model.IndexInfo) TableInfoWithKeyRange { - return newIndexWithKeyRange(db, table, index) + return newIndexWithKeyRange(db, table, index, table.ID) } -func newIndexWithKeyRange(db *model.DBInfo, table *model.TableInfo, index *model.IndexInfo) TableInfoWithKeyRange { - sk, ek := tablecodec.GetTableIndexKeyRange(table.ID, index.ID) +func newIndexWithKeyRange(db *model.DBInfo, table *model.TableInfo, index *model.IndexInfo, physicalID int64) TableInfoWithKeyRange { + sk, ek := tablecodec.GetTableIndexKeyRange(physicalID, index.ID) startKey := bytesKeyToHex(codec.EncodeBytes(nil, sk)) endKey := bytesKeyToHex(codec.EncodeBytes(nil, ek)) return TableInfoWithKeyRange{ @@ -727,7 +728,13 @@ func (*Helper) GetTablesInfoWithKeyRange(schemas []*model.DBInfo) []TableInfoWit tables = append(tables, newTableWithKeyRange(db, table)) } for _, index := range table.Indices { - tables = append(tables, newIndexWithKeyRange(db, table, index)) + if table.Partition == nil || index.Global { + tables = append(tables, newIndexWithKeyRange(db, table, index, table.ID)) + continue + } + for _, partition := range table.Partition.Definitions { + tables = append(tables, newIndexWithKeyRange(db, table, index, partition.ID)) + } } } } @@ -1152,39 +1159,6 @@ func (h *Helper) PostAccelerateSchedule(tableID int64) error { return nil } -// GetPDRegionRecordStats is a helper function calling `/stats/region`. -func (h *Helper) GetPDRegionRecordStats(tableID int64, stats *PDRegionStats) error { - pdAddrs, err := h.GetPDAddr() - if err != nil { - return errors.Trace(err) - } - - startKey := tablecodec.GenTableRecordPrefix(tableID) - endKey := tablecodec.EncodeTablePrefix(tableID + 1) - startKey = codec.EncodeBytes([]byte{}, startKey) - endKey = codec.EncodeBytes([]byte{}, endKey) - - statURL := fmt.Sprintf("%s://%s/pd/api/v1/stats/region?start_key=%s&end_key=%s", - util.InternalHTTPSchema(), - pdAddrs[0], - url.QueryEscape(string(startKey)), - url.QueryEscape(string(endKey))) - - resp, err := util.InternalHTTPClient().Get(statURL) - if err != nil { - return errors.Trace(err) - } - defer func() { - if err = resp.Body.Close(); err != nil { - logutil.BgLogger().Error("err", zap.Error(err)) - } - }() - - dec := json.NewDecoder(resp.Body) - - return dec.Decode(stats) -} - // GetTiFlashTableIDFromEndKey computes tableID from pd rule's endKey. func GetTiFlashTableIDFromEndKey(endKey string) int64 { e, _ := hex.DecodeString(endKey) diff --git a/store/helper/main_test.go b/store/helper/main_test.go index e459f147efedb..3937580027775 100644 --- a/store/helper/main_test.go +++ b/store/helper/main_test.go @@ -25,7 +25,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/store/main_test.go b/store/main_test.go index 3c4d13ad381b8..4d0820e80c89b 100644 --- a/store/main_test.go +++ b/store/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/mockstore/main_test.go b/store/mockstore/main_test.go index daf0e059f2572..aa9718295ad04 100644 --- a/store/mockstore/main_test.go +++ b/store/mockstore/main_test.go @@ -32,6 +32,7 @@ func TestMain(m *testing.M) { } opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/mockstore/mockcopr/main_test.go b/store/mockstore/mockcopr/main_test.go index fa7a0a1e97df9..279862588c465 100644 --- a/store/mockstore/mockcopr/main_test.go +++ b/store/mockstore/mockcopr/main_test.go @@ -27,6 +27,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/mockstore/mockstorage/storage.go b/store/mockstore/mockstorage/storage.go index a85b46166631f..6a05a78fef0ff 100644 --- a/store/mockstore/mockstorage/storage.go +++ b/store/mockstore/mockstorage/storage.go @@ -117,6 +117,12 @@ func (s *mockStorage) Close() error { return s.KVStore.Close() } +func (s *mockStorage) GetCodec() tikv.Codec { + pdClient := s.KVStore.GetPDClient() + pdCodecCli := tikv.NewCodecPDClient(tikv.ModeTxn, pdClient) + return pdCodecCli.GetCodec() +} + // MockLockWaitSetter is used to set the mocked lock wait information, which helps implementing tests that uses the // GetLockWaits function. type MockLockWaitSetter interface { diff --git a/store/mockstore/unistore/BUILD.bazel b/store/mockstore/unistore/BUILD.bazel index 50a04a77f9bfe..c25dad1d5fe6d 100644 --- a/store/mockstore/unistore/BUILD.bazel +++ b/store/mockstore/unistore/BUILD.bazel @@ -32,6 +32,8 @@ go_library( "@com_github_pingcap_kvproto//pkg/metapb", "@com_github_pingcap_kvproto//pkg/mpp", "@com_github_pingcap_kvproto//pkg/pdpb", + "@com_github_pingcap_kvproto//pkg/resource_manager", + "@com_github_tikv_client_go_v2//oracle", "@com_github_tikv_client_go_v2//testutils", "@com_github_tikv_client_go_v2//tikvrpc", "@com_github_tikv_pd_client//:client", diff --git a/store/mockstore/unistore/cophandler/cop_handler.go b/store/mockstore/unistore/cophandler/cop_handler.go index 5f375f2bfdc30..2b32c168329bd 100644 --- a/store/mockstore/unistore/cophandler/cop_handler.go +++ b/store/mockstore/unistore/cophandler/cop_handler.go @@ -401,7 +401,7 @@ func newRowDecoder(columnInfos []*tipb.ColumnInfo, fieldTps []*types.FieldType, if primaryCols != nil { pkCols = primaryCols } else { - pkCols = []int64{0} + pkCols = []int64{-1} } } def := func(i int, chk *chunk.Chunk) error { diff --git a/store/mockstore/unistore/cophandler/main_test.go b/store/mockstore/unistore/cophandler/main_test.go index 0cd6c13b8cba0..5dbab5fb93a5b 100644 --- a/store/mockstore/unistore/cophandler/main_test.go +++ b/store/mockstore/unistore/cophandler/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/mockstore/unistore/lockstore/main_test.go b/store/mockstore/unistore/lockstore/main_test.go index bc28743788d54..09e8ebf061f44 100644 --- a/store/mockstore/unistore/lockstore/main_test.go +++ b/store/mockstore/unistore/lockstore/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/mockstore/unistore/main_test.go b/store/mockstore/unistore/main_test.go index b69415466734e..a2bcc6e1531f9 100644 --- a/store/mockstore/unistore/main_test.go +++ b/store/mockstore/unistore/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/mockstore/unistore/pd.go b/store/mockstore/unistore/pd.go index 9361fcc9ddc07..380707cc166a7 100644 --- a/store/mockstore/unistore/pd.go +++ b/store/mockstore/unistore/pd.go @@ -18,11 +18,16 @@ import ( "context" "errors" "math" + "path" + "strings" "sync" + "sync/atomic" "github.com/pingcap/kvproto/pkg/keyspacepb" "github.com/pingcap/kvproto/pkg/pdpb" + rmpb "github.com/pingcap/kvproto/pkg/resource_manager" us "github.com/pingcap/tidb/store/mockstore/unistore/tikv" + "github.com/tikv/client-go/v2/oracle" pd "github.com/tikv/pd/client" ) @@ -34,6 +39,7 @@ type pdClient struct { serviceSafePoints map[string]uint64 gcSafePointMu sync.Mutex globalConfig map[string]string + externalTimestamp atomic.Uint64 } func newPDClient(pd *us.MockPD) *pdClient { @@ -44,26 +50,24 @@ func newPDClient(pd *us.MockPD) *pdClient { } } -func (c *pdClient) LoadGlobalConfig(ctx context.Context, names []string) ([]pd.GlobalConfigItem, error) { - ret := make([]pd.GlobalConfigItem, len(names)) - for i, name := range names { - if r, ok := c.globalConfig["/global/config/"+name]; ok { - ret[i] = pd.GlobalConfigItem{Name: "/global/config/" + name, Value: r} - } else { - ret[i] = pd.GlobalConfigItem{Name: "/global/config/" + name, Error: errors.New("not found")} +func (c *pdClient) LoadGlobalConfig(ctx context.Context, configPath string) ([]pd.GlobalConfigItem, int64, error) { + ret := make([]pd.GlobalConfigItem, 0) + for k, v := range c.globalConfig { + if strings.HasPrefix(k, configPath) { + ret = append(ret, pd.GlobalConfigItem{Name: k, Value: v}) } } - return ret, nil + return ret, 0, nil } -func (c *pdClient) StoreGlobalConfig(ctx context.Context, items []pd.GlobalConfigItem) error { +func (c *pdClient) StoreGlobalConfig(ctx context.Context, configPath string, items []pd.GlobalConfigItem) error { for _, item := range items { - c.globalConfig["/global/config/"+item.Name] = item.Value + c.globalConfig[path.Join(configPath, item.Name)] = item.Value } return nil } -func (c *pdClient) WatchGlobalConfig(ctx context.Context) (chan []pd.GlobalConfigItem, error) { +func (c *pdClient) WatchGlobalConfig(ctx context.Context, configPath string, revision int64) (chan []pd.GlobalConfigItem, error) { globalConfigWatcherCh := make(chan []pd.GlobalConfigItem, 16) go func() { defer func() { @@ -177,3 +181,63 @@ func (c *pdClient) LoadKeyspace(ctx context.Context, name string) (*keyspacepb.K func (c *pdClient) WatchKeyspaces(ctx context.Context) (chan []*keyspacepb.KeyspaceMeta, error) { return nil, nil } + +func (c *pdClient) UpdateKeyspaceState(ctx context.Context, id uint32, state keyspacepb.KeyspaceState) (*keyspacepb.KeyspaceMeta, error) { + return nil, nil +} + +func (c *pdClient) ListResourceGroups(ctx context.Context) ([]*rmpb.ResourceGroup, error) { + return nil, nil +} + +func (c *pdClient) GetResourceGroup(ctx context.Context, resourceGroupName string) (*rmpb.ResourceGroup, error) { + return nil, nil +} + +func (c *pdClient) AddResourceGroup(ctx context.Context, metaGroup *rmpb.ResourceGroup) (string, error) { + return "", nil +} + +func (c *pdClient) ModifyResourceGroup(ctx context.Context, metaGroup *rmpb.ResourceGroup) (string, error) { + return "", nil +} + +func (c *pdClient) DeleteResourceGroup(ctx context.Context, resourceGroupName string) (string, error) { + return "", nil +} + +func (c *pdClient) WatchResourceGroup(ctx context.Context, revision int64) (chan []*rmpb.ResourceGroup, error) { + return nil, nil +} + +func (c *pdClient) AcquireTokenBuckets(ctx context.Context, request *rmpb.TokenBucketsRequest) ([]*rmpb.TokenBucketResponse, error) { + return nil, nil +} + +func (c *pdClient) SetExternalTimestamp(ctx context.Context, newTimestamp uint64) error { + p, l, err := c.GetTS(ctx) + if err != nil { + return err + } + + currentTSO := oracle.ComposeTS(p, l) + if newTimestamp > currentTSO { + return errors.New("external timestamp is greater than global tso") + } + for { + externalTimestamp := c.externalTimestamp.Load() + if externalTimestamp > newTimestamp { + return errors.New("cannot decrease the external timestamp") + } else if externalTimestamp == newTimestamp { + return nil + } + + if c.externalTimestamp.CompareAndSwap(externalTimestamp, newTimestamp) { + return nil + } + } +} + +func (c *pdClient) GetExternalTimestamp(ctx context.Context) (uint64, error) { + return c.externalTimestamp.Load(), nil +} diff --git a/store/mockstore/unistore/pd_test.go b/store/mockstore/unistore/pd_test.go index 1fa645a3f2e86..a75533c83533e 100644 --- a/store/mockstore/unistore/pd_test.go +++ b/store/mockstore/unistore/pd_test.go @@ -34,50 +34,25 @@ func SetUpSuite() *GlobalConfigTestSuite { return s } -func TestLoad(t *testing.T) { +func TestLoadAndStore(t *testing.T) { s := SetUpSuite() - s.client.StoreGlobalConfig(context.Background(), []pd.GlobalConfigItem{{Name: "LoadOkGlobalConfig", Value: "ok"}}) - res, err := s.client.LoadGlobalConfig(context.Background(), []string{"LoadOkGlobalConfig", "LoadErrGlobalConfig"}) - require.Equal(t, err, nil) - for _, j := range res { - switch j.Name { - case "/global/config/LoadOkGlobalConfig": - require.Equal(t, j.Value, "ok") - - case "/global/config/LoadErrGlobalConfig": - require.Equal(t, j.Value, "") - require.EqualError(t, j.Error, "not found") - default: - require.Equal(t, true, false) - } - } - s.TearDownSuite() -} - -func TestStore(t *testing.T) { - s := SetUpSuite() - - res, err := s.client.LoadGlobalConfig(context.Background(), []string{"NewObject"}) - require.Equal(t, err, nil) - require.EqualError(t, res[0].Error, "not found") + err := s.client.StoreGlobalConfig(context.Background(), "/global/config", []pd.GlobalConfigItem{{Name: "NewObject", Value: "ok"}}) + require.Equal(t, nil, err) - err = s.client.StoreGlobalConfig(context.Background(), []pd.GlobalConfigItem{{Name: "NewObject", Value: "ok"}}) - require.Equal(t, err, nil) - - res, err = s.client.LoadGlobalConfig(context.Background(), []string{"NewObject"}) - require.Equal(t, err, nil) - require.Equal(t, res[0].Error, nil) + res, _, err := s.client.LoadGlobalConfig(context.Background(), "/global/config") + require.Equal(t, nil, err) + require.Equal(t, 1, len(res)) s.TearDownSuite() } func TestWatch(t *testing.T) { s := SetUpSuite() - err := s.client.StoreGlobalConfig(context.Background(), []pd.GlobalConfigItem{{Name: "NewObject", Value: "ok"}}) + err := s.client.StoreGlobalConfig(context.Background(), "/global/config", []pd.GlobalConfigItem{{Name: "NewObject", Value: "ok"}}) require.Equal(t, err, nil) - ch, err := s.client.WatchGlobalConfig(context.Background()) + ch, err := s.client.WatchGlobalConfig(context.Background(), "/global/config", 0) require.Equal(t, err, nil) for i := 0; i < 10; i++ { diff --git a/store/mockstore/unistore/tikv/main_test.go b/store/mockstore/unistore/tikv/main_test.go index 07b836d7fd874..6b242bcddf291 100644 --- a/store/mockstore/unistore/tikv/main_test.go +++ b/store/mockstore/unistore/tikv/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/mockstore/unistore/tikv/mock_region.go b/store/mockstore/unistore/tikv/mock_region.go index efbd48bb612b3..2e3e4fa01ddb1 100644 --- a/store/mockstore/unistore/tikv/mock_region.go +++ b/store/mockstore/unistore/tikv/mock_region.go @@ -36,6 +36,7 @@ import ( "github.com/pingcap/tidb/store/mockstore/unistore/tikv/mvcc" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/util/codec" + "github.com/tikv/client-go/v2/oracle" pdclient "github.com/tikv/pd/client" "golang.org/x/exp/slices" ) @@ -670,6 +671,8 @@ func (rm *MockRegionManager) AddPeer(regionID, storeID, peerID uint64) { type MockPD struct { rm *MockRegionManager gcSafePoint uint64 + + externalTimestamp atomic.Uint64 } // NewMockPD returns a new MockPD. @@ -784,6 +787,30 @@ func (pd *MockPD) UpdateGCSafePoint(ctx context.Context, safePoint uint64) (uint // StoreHeartbeat stores the heartbeat. func (pd *MockPD) StoreHeartbeat(ctx context.Context, stats *pdpb.StoreStats) error { return nil } +// GetExternalTimestamp returns external timestamp +func (pd *MockPD) GetExternalTimestamp(ctx context.Context) (uint64, error) { + return pd.externalTimestamp.Load(), nil +} + +// SetExternalTimestamp sets external timestamp +func (pd *MockPD) SetExternalTimestamp(ctx context.Context, newTimestamp uint64) error { + p, l := GetTS() + currentTSO := oracle.ComposeTS(p, l) + if newTimestamp > currentTSO { + return errors.New("external timestamp is greater than global tso") + } + for { + externalTimestamp := pd.externalTimestamp.Load() + if externalTimestamp > newTimestamp { + return errors.New("cannot decrease the external timestamp") + } + + if pd.externalTimestamp.CompareAndSwap(externalTimestamp, newTimestamp) { + return nil + } + } +} + // Use global variables to prevent pdClients from creating duplicate timestamps. var tsMu = struct { sync.Mutex diff --git a/store/mockstore/unistore/tikv/mvcc.go b/store/mockstore/unistore/tikv/mvcc.go index 753c2e49c709c..7cedfeabbbf1a 100644 --- a/store/mockstore/unistore/tikv/mvcc.go +++ b/store/mockstore/unistore/tikv/mvcc.go @@ -227,6 +227,20 @@ func sortKeys(keys [][]byte) [][]byte { // PessimisticLock will add pessimistic lock on key func (store *MVCCStore) PessimisticLock(reqCtx *requestCtx, req *kvrpcpb.PessimisticLockRequest, resp *kvrpcpb.PessimisticLockResponse) (*lockwaiter.Waiter, error) { + waiter, err := store.pessimisticLockInner(reqCtx, req, resp) + if err != nil && req.GetWakeUpMode() == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeForceLock { + // The execution of `pessimisticLockInner` is broken by error. If resp.Results is not completely set yet, fill it with LockResultFailed. + for len(resp.Results) < len(req.Mutations) { + resp.Results = append(resp.Results, &kvrpcpb.PessimisticLockKeyResult{ + Type: kvrpcpb.PessimisticLockKeyResultType_LockResultFailed, + }) + } + } + + return waiter, err +} + +func (store *MVCCStore) pessimisticLockInner(reqCtx *requestCtx, req *kvrpcpb.PessimisticLockRequest, resp *kvrpcpb.PessimisticLockResponse) (*lockwaiter.Waiter, error) { mutations := req.Mutations if !req.ReturnValues { mutations = sortMutations(req.Mutations) @@ -240,6 +254,9 @@ func (store *MVCCStore) PessimisticLock(reqCtx *requestCtx, req *kvrpcpb.Pessimi if req.LockOnlyIfExists && !req.ReturnValues { return nil, errors.New("LockOnlyIfExists is set for LockKeys but ReturnValues is not set") } + if req.GetWakeUpMode() == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeForceLock && len(req.Mutations) > 1 { + return nil, errors.New("Trying to lock more than one key in WakeUpModeForceLock, which is not supported yet") + } batch := store.dbWriter.NewWriteBatch(startTS, 0, reqCtx.rpcCtx) var dup bool for _, m := range mutations { @@ -273,12 +290,14 @@ func (store *MVCCStore) PessimisticLock(reqCtx *requestCtx, req *kvrpcpb.Pessimi } } items, err := store.getDBItems(reqCtx, mutations) + lockedWithConflictTSList := make([]uint64, 0, len(mutations)) if err != nil { return nil, err } if !dup { for i, m := range mutations { - lock, err1 := store.buildPessimisticLock(m, items[i], req) + lock, lockedWithConflictTS, err1 := store.buildPessimisticLock(m, items[i], req) + lockedWithConflictTSList = append(lockedWithConflictTSList, lockedWithConflictTS) if err1 != nil { return nil, err1 } @@ -301,24 +320,73 @@ func (store *MVCCStore) PessimisticLock(reqCtx *requestCtx, req *kvrpcpb.Pessimi resp.Value = val resp.CommitTs = dbMeta.CommitTS() } - if req.ReturnValues || req.CheckExistence { - for _, item := range items { - if item == nil { + + if req.GetWakeUpMode() == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeNormal { + if req.ReturnValues || req.CheckExistence { + for _, item := range items { + if item == nil { + if req.ReturnValues { + resp.Values = append(resp.Values, nil) + } + resp.NotFounds = append(resp.NotFounds, true) + continue + } + val, err1 := item.ValueCopy(nil) + if err1 != nil { + return nil, err1 + } if req.ReturnValues { - resp.Values = append(resp.Values, nil) + resp.Values = append(resp.Values, val) } - resp.NotFounds = append(resp.NotFounds, true) - continue + resp.NotFounds = append(resp.NotFounds, len(val) == 0) } - val, err1 := item.ValueCopy(nil) - if err1 != nil { - return nil, err1 + } + } else if req.GetWakeUpMode() == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeForceLock { + for i, item := range items { + res := &kvrpcpb.PessimisticLockKeyResult{ + Type: kvrpcpb.PessimisticLockKeyResultType_LockResultNormal, + Value: nil, + Existence: false, + LockedWithConflictTs: 0, } - if req.ReturnValues { - resp.Values = append(resp.Values, val) + + if lockedWithConflictTSList[i] != 0 { + res.Type = kvrpcpb.PessimisticLockKeyResultType_LockResultLockedWithConflict + res.LockedWithConflictTs = lockedWithConflictTSList[i] + if item == nil { + res.Value = nil + res.Existence = false + } else { + val, err1 := item.ValueCopy(nil) + if err1 != nil { + return nil, err1 + } + res.Value = val + res.Existence = len(val) != 0 + } + } else if req.ReturnValues { + if item != nil { + val, err1 := item.ValueCopy(nil) + if err1 != nil { + return nil, err1 + } + res.Value = val + res.Existence = len(val) != 0 + } + } else if req.CheckExistence { + if item != nil { + val, err1 := item.ValueCopy(nil) + if err1 != nil { + return nil, err1 + } + res.Existence = len(val) != 0 + } } - resp.NotFounds = append(resp.NotFounds, len(val) == 0) + + resp.Results = append(resp.Results, res) } + } else { + panic("unreachable") } return nil, err } @@ -575,42 +643,57 @@ func (store *MVCCStore) handleCheckPessimisticErr(startTS uint64, err error, isF return nil, err } +// buildPessimisticLock builds the lock according to the request and the current state of the key. +// Returns the built lock, and the LockedWithConflictTS (if any, otherwise 0). func (store *MVCCStore) buildPessimisticLock(m *kvrpcpb.Mutation, item *badger.Item, - req *kvrpcpb.PessimisticLockRequest) (*mvcc.Lock, error) { + req *kvrpcpb.PessimisticLockRequest) (*mvcc.Lock, uint64, error) { + var lockedWithConflictTS uint64 = 0 + if item != nil { userMeta := mvcc.DBUserMeta(item.UserMeta()) if !req.Force { if userMeta.CommitTS() > req.ForUpdateTs { - return nil, &kverrors.ErrConflict{ - StartTS: req.StartVersion, - ConflictTS: userMeta.StartTS(), - ConflictCommitTS: userMeta.CommitTS(), - Key: item.KeyCopy(nil), - Reason: kvrpcpb.WriteConflict_PessimisticRetry, + if req.GetWakeUpMode() == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeNormal { + return nil, 0, &kverrors.ErrConflict{ + StartTS: req.StartVersion, + ConflictTS: userMeta.StartTS(), + ConflictCommitTS: userMeta.CommitTS(), + Key: item.KeyCopy(nil), + Reason: kvrpcpb.WriteConflict_PessimisticRetry, + } + } else if req.GetWakeUpMode() == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeForceLock { + lockedWithConflictTS = userMeta.CommitTS() + } else { + panic("unreachable") } } } - if m.Assertion == kvrpcpb.Assertion_NotExist && !item.IsEmpty() { - return nil, &kverrors.ErrKeyAlreadyExists{Key: m.Key} + if lockedWithConflictTS == 0 && m.Assertion == kvrpcpb.Assertion_NotExist && !item.IsEmpty() { + return nil, 0, &kverrors.ErrKeyAlreadyExists{Key: m.Key} } } - if ok, err := doesNeedLock(item, req); !ok { + + actualWrittenForUpdateTS := req.ForUpdateTs + if lockedWithConflictTS > 0 { + actualWrittenForUpdateTS = lockedWithConflictTS + } else if ok, err := doesNeedLock(item, req); !ok { if err != nil { - return nil, err + return nil, 0, err } - return nil, nil + return nil, 0, nil } + lock := &mvcc.Lock{ LockHdr: mvcc.LockHdr{ StartTS: req.StartVersion, - ForUpdateTS: req.ForUpdateTs, + ForUpdateTS: actualWrittenForUpdateTS, Op: uint8(kvrpcpb.Op_PessimisticLock), TTL: uint32(req.LockTtl), PrimaryLen: uint16(len(req.PrimaryLock)), }, Primary: req.PrimaryLock, } - return lock, nil + return lock, lockedWithConflictTS, nil } // Prewrite implements the MVCCStore interface. @@ -935,16 +1018,16 @@ func (store *MVCCStore) buildPrewriteLock(reqCtx *requestCtx, m *kvrpcpb.Mutatio lock.Op = uint8(kvrpcpb.Op_Put) } if rowcodec.IsRowKey(m.Key) && lock.Op == uint8(kvrpcpb.Op_Put) { - if rowcodec.IsNewFormat(m.Value) { - reqCtx.buf = m.Value - } else { + if !rowcodec.IsNewFormat(m.Value) { reqCtx.buf, err = encodeFromOldRow(m.Value, reqCtx.buf) if err != nil { log.Error("encode data failed", zap.Binary("value", m.Value), zap.Binary("key", m.Key), zap.Stringer("op", m.Op), zap.Error(err)) return nil, err } + + lock.Value = make([]byte, len(reqCtx.buf)) + copy(lock.Value, reqCtx.buf) } - lock.Value = reqCtx.buf } lock.ForUpdateTS = req.ForUpdateTs diff --git a/store/mockstore/unistore/tikv/server.go b/store/mockstore/unistore/tikv/server.go index 14260ab991e94..d3163d887d6a9 100644 --- a/store/mockstore/unistore/tikv/server.go +++ b/store/mockstore/unistore/tikv/server.go @@ -158,7 +158,7 @@ func (req *requestCtx) finish() { } } -// KvGet implements implements the tikvpb.TikvServer interface. +// KvGet implements the tikvpb.TikvServer interface. func (svr *Server) KvGet(ctx context.Context, req *kvrpcpb.GetRequest) (*kvrpcpb.GetResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvGet") if err != nil { @@ -175,7 +175,7 @@ func (svr *Server) KvGet(ctx context.Context, req *kvrpcpb.GetRequest) (*kvrpcpb }, nil } -// KvScan implements implements the tikvpb.TikvServer interface. +// KvScan implements the tikvpb.TikvServer interface. func (svr *Server) KvScan(ctx context.Context, req *kvrpcpb.ScanRequest) (*kvrpcpb.ScanResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvScan") if err != nil { @@ -191,7 +191,7 @@ func (svr *Server) KvScan(ctx context.Context, req *kvrpcpb.ScanRequest) (*kvrpc }, nil } -// KvPessimisticLock implements implements the tikvpb.TikvServer interface. +// KvPessimisticLock implements the tikvpb.TikvServer interface. func (svr *Server) KvPessimisticLock(ctx context.Context, req *kvrpcpb.PessimisticLockRequest) (*kvrpcpb.PessimisticLockResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "PessimisticLock") if err != nil { @@ -223,11 +223,19 @@ func (svr *Server) KvPessimisticLock(ctx context.Context, req *kvrpcpb.Pessimist WaitChain: result.DeadlockResp.WaitChain, } resp.Errors, resp.RegionError = convertToPBErrors(deadlockErr) + if req.WakeUpMode == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeForceLock { + resp.Results = []*kvrpcpb.PessimisticLockKeyResult{ + { + Type: kvrpcpb.PessimisticLockKeyResultType_LockResultFailed, + }, + } + } return resp, nil } if result.WakeupSleepTime == lockwaiter.WakeUpThisWaiter { - if req.Force { + if req.Force || req.WakeUpMode == kvrpcpb.PessimisticLockWakeUpMode_WakeUpModeForceLock { req.WaitTimeout = lockwaiter.LockNoWait + resp = &kvrpcpb.PessimisticLockResponse{} _, err := svr.mvccStore.PessimisticLock(reqCtx, req, resp) resp.Errors, resp.RegionError = convertToPBErrors(err) if err == nil { @@ -252,7 +260,7 @@ func (svr *Server) KvPessimisticLock(ctx context.Context, req *kvrpcpb.Pessimist return resp, nil } -// KVPessimisticRollback implements implements the tikvpb.TikvServer interface. +// KVPessimisticRollback implements the tikvpb.TikvServer interface. func (svr *Server) KVPessimisticRollback(ctx context.Context, req *kvrpcpb.PessimisticRollbackRequest) (*kvrpcpb.PessimisticRollbackResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "PessimisticRollback") if err != nil { @@ -268,7 +276,7 @@ func (svr *Server) KVPessimisticRollback(ctx context.Context, req *kvrpcpb.Pessi return resp, nil } -// KvTxnHeartBeat implements implements the tikvpb.TikvServer interface. +// KvTxnHeartBeat implements the tikvpb.TikvServer interface. func (svr *Server) KvTxnHeartBeat(ctx context.Context, req *kvrpcpb.TxnHeartBeatRequest) (*kvrpcpb.TxnHeartBeatResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "TxnHeartBeat") if err != nil { @@ -284,7 +292,7 @@ func (svr *Server) KvTxnHeartBeat(ctx context.Context, req *kvrpcpb.TxnHeartBeat return resp, nil } -// KvCheckTxnStatus implements implements the tikvpb.TikvServer interface. +// KvCheckTxnStatus implements the tikvpb.TikvServer interface. func (svr *Server) KvCheckTxnStatus(ctx context.Context, req *kvrpcpb.CheckTxnStatusRequest) (*kvrpcpb.CheckTxnStatusResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvCheckTxnStatus") if err != nil { @@ -309,7 +317,7 @@ func (svr *Server) KvCheckTxnStatus(ctx context.Context, req *kvrpcpb.CheckTxnSt return resp, nil } -// KvCheckSecondaryLocks implements implements the tikvpb.TikvServer interface. +// KvCheckSecondaryLocks implements the tikvpb.TikvServer interface. func (svr *Server) KvCheckSecondaryLocks(ctx context.Context, req *kvrpcpb.CheckSecondaryLocksRequest) (*kvrpcpb.CheckSecondaryLocksResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvCheckSecondaryLocks") if err != nil { @@ -330,7 +338,7 @@ func (svr *Server) KvCheckSecondaryLocks(ctx context.Context, req *kvrpcpb.Check return resp, nil } -// KvPrewrite implements implements the tikvpb.TikvServer interface. +// KvPrewrite implements the tikvpb.TikvServer interface. func (svr *Server) KvPrewrite(ctx context.Context, req *kvrpcpb.PrewriteRequest) (*kvrpcpb.PrewriteResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvPrewrite") if err != nil { @@ -352,7 +360,7 @@ func (svr *Server) KvPrewrite(ctx context.Context, req *kvrpcpb.PrewriteRequest) return resp, nil } -// KvCommit implements implements the tikvpb.TikvServer interface. +// KvCommit implements the tikvpb.TikvServer interface. func (svr *Server) KvCommit(ctx context.Context, req *kvrpcpb.CommitRequest) (*kvrpcpb.CommitResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvCommit") if err != nil { @@ -370,19 +378,19 @@ func (svr *Server) KvCommit(ctx context.Context, req *kvrpcpb.CommitRequest) (*k return resp, nil } -// RawGetKeyTTL implements implements the tikvpb.TikvServer interface. +// RawGetKeyTTL implements the tikvpb.TikvServer interface. func (svr *Server) RawGetKeyTTL(ctx context.Context, req *kvrpcpb.RawGetKeyTTLRequest) (*kvrpcpb.RawGetKeyTTLResponse, error) { // TODO return &kvrpcpb.RawGetKeyTTLResponse{}, nil } -// KvImport implements implements the tikvpb.TikvServer interface. +// KvImport implements the tikvpb.TikvServer interface. func (svr *Server) KvImport(context.Context, *kvrpcpb.ImportRequest) (*kvrpcpb.ImportResponse, error) { // TODO return &kvrpcpb.ImportResponse{}, nil } -// KvCleanup implements implements the tikvpb.TikvServer interface. +// KvCleanup implements the tikvpb.TikvServer interface. func (svr *Server) KvCleanup(ctx context.Context, req *kvrpcpb.CleanupRequest) (*kvrpcpb.CleanupResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvCleanup") if err != nil { @@ -403,7 +411,7 @@ func (svr *Server) KvCleanup(ctx context.Context, req *kvrpcpb.CleanupRequest) ( return resp, nil } -// KvBatchGet implements implements the tikvpb.TikvServer interface. +// KvBatchGet implements the tikvpb.TikvServer interface. func (svr *Server) KvBatchGet(ctx context.Context, req *kvrpcpb.BatchGetRequest) (*kvrpcpb.BatchGetResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvBatchGet") if err != nil { @@ -419,7 +427,7 @@ func (svr *Server) KvBatchGet(ctx context.Context, req *kvrpcpb.BatchGetRequest) }, nil } -// KvBatchRollback implements implements the tikvpb.TikvServer interface. +// KvBatchRollback implements the tikvpb.TikvServer interface. func (svr *Server) KvBatchRollback(ctx context.Context, req *kvrpcpb.BatchRollbackRequest) (*kvrpcpb.BatchRollbackResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvBatchRollback") if err != nil { @@ -435,7 +443,7 @@ func (svr *Server) KvBatchRollback(ctx context.Context, req *kvrpcpb.BatchRollba return resp, nil } -// KvScanLock implements implements the tikvpb.TikvServer interface. +// KvScanLock implements the tikvpb.TikvServer interface. func (svr *Server) KvScanLock(ctx context.Context, req *kvrpcpb.ScanLockRequest) (*kvrpcpb.ScanLockResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvScanLock") if err != nil { @@ -450,7 +458,7 @@ func (svr *Server) KvScanLock(ctx context.Context, req *kvrpcpb.ScanLockRequest) return &kvrpcpb.ScanLockResponse{Error: convertToKeyError(err), Locks: locks}, nil } -// KvResolveLock implements implements the tikvpb.TikvServer interface. +// KvResolveLock implements the tikvpb.TikvServer interface. func (svr *Server) KvResolveLock(ctx context.Context, req *kvrpcpb.ResolveLockRequest) (*kvrpcpb.ResolveLockResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvResolveLock") if err != nil { @@ -478,7 +486,7 @@ func (svr *Server) KvResolveLock(ctx context.Context, req *kvrpcpb.ResolveLockRe return resp, nil } -// KvGC implements implements the tikvpb.TikvServer interface. +// KvGC implements the tikvpb.TikvServer interface. func (svr *Server) KvGC(ctx context.Context, req *kvrpcpb.GCRequest) (*kvrpcpb.GCResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvGC") if err != nil { @@ -489,7 +497,7 @@ func (svr *Server) KvGC(ctx context.Context, req *kvrpcpb.GCRequest) (*kvrpcpb.G return &kvrpcpb.GCResponse{}, nil } -// KvDeleteRange implements implements the tikvpb.TikvServer interface. +// KvDeleteRange implements the tikvpb.TikvServer interface. func (svr *Server) KvDeleteRange(ctx context.Context, req *kvrpcpb.DeleteRangeRequest) (*kvrpcpb.DeleteRangeResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "KvDeleteRange") if err != nil { @@ -508,55 +516,55 @@ func (svr *Server) KvDeleteRange(ctx context.Context, req *kvrpcpb.DeleteRangeRe // RawKV commands. -// RawGet implements implements the tikvpb.TikvServer interface. +// RawGet implements the tikvpb.TikvServer interface. func (svr *Server) RawGet(context.Context, *kvrpcpb.RawGetRequest) (*kvrpcpb.RawGetResponse, error) { return &kvrpcpb.RawGetResponse{}, nil } -// RawPut implements implements the tikvpb.TikvServer interface. +// RawPut implements the tikvpb.TikvServer interface. func (svr *Server) RawPut(context.Context, *kvrpcpb.RawPutRequest) (*kvrpcpb.RawPutResponse, error) { return &kvrpcpb.RawPutResponse{}, nil } -// RawDelete implements implements the tikvpb.TikvServer interface. +// RawDelete implements the tikvpb.TikvServer interface. func (svr *Server) RawDelete(context.Context, *kvrpcpb.RawDeleteRequest) (*kvrpcpb.RawDeleteResponse, error) { return &kvrpcpb.RawDeleteResponse{}, nil } -// RawScan implements implements the tikvpb.TikvServer interface. +// RawScan implements the tikvpb.TikvServer interface. func (svr *Server) RawScan(context.Context, *kvrpcpb.RawScanRequest) (*kvrpcpb.RawScanResponse, error) { return &kvrpcpb.RawScanResponse{}, nil } -// RawBatchDelete implements implements the tikvpb.TikvServer interface. +// RawBatchDelete implements the tikvpb.TikvServer interface. func (svr *Server) RawBatchDelete(context.Context, *kvrpcpb.RawBatchDeleteRequest) (*kvrpcpb.RawBatchDeleteResponse, error) { return &kvrpcpb.RawBatchDeleteResponse{}, nil } -// RawBatchGet implements implements the tikvpb.TikvServer interface. +// RawBatchGet implements the tikvpb.TikvServer interface. func (svr *Server) RawBatchGet(context.Context, *kvrpcpb.RawBatchGetRequest) (*kvrpcpb.RawBatchGetResponse, error) { return &kvrpcpb.RawBatchGetResponse{}, nil } -// RawBatchPut implements implements the tikvpb.TikvServer interface. +// RawBatchPut implements the tikvpb.TikvServer interface. func (svr *Server) RawBatchPut(context.Context, *kvrpcpb.RawBatchPutRequest) (*kvrpcpb.RawBatchPutResponse, error) { return &kvrpcpb.RawBatchPutResponse{}, nil } -// RawBatchScan implements implements the tikvpb.TikvServer interface. +// RawBatchScan implements the tikvpb.TikvServer interface. func (svr *Server) RawBatchScan(context.Context, *kvrpcpb.RawBatchScanRequest) (*kvrpcpb.RawBatchScanResponse, error) { return &kvrpcpb.RawBatchScanResponse{}, nil } -// RawDeleteRange implements implements the tikvpb.TikvServer interface. +// RawDeleteRange implements the tikvpb.TikvServer interface. func (svr *Server) RawDeleteRange(context.Context, *kvrpcpb.RawDeleteRangeRequest) (*kvrpcpb.RawDeleteRangeResponse, error) { return &kvrpcpb.RawDeleteRangeResponse{}, nil } // SQL push down commands. -// Coprocessor implements implements the tikvpb.TikvServer interface. -func (svr *Server) Coprocessor(_ context.Context, req *coprocessor.Request) (*coprocessor.Response, error) { +// Coprocessor implements the tikvpb.TikvServer interface. +func (svr *Server) Coprocessor(ctx context.Context, req *coprocessor.Request) (*coprocessor.Response, error) { reqCtx, err := newRequestCtx(svr, req.Context, "Coprocessor") if err != nil { return &coprocessor.Response{OtherError: convertToKeyError(err).String()}, nil @@ -565,15 +573,71 @@ func (svr *Server) Coprocessor(_ context.Context, req *coprocessor.Request) (*co if reqCtx.regErr != nil { return &coprocessor.Response{RegionError: reqCtx.regErr}, nil } - return cophandler.HandleCopRequest(reqCtx.getDBReader(), svr.mvccStore.lockStore, req), nil + resp := cophandler.HandleCopRequest(reqCtx.getDBReader(), svr.mvccStore.lockStore, req) + resp.BatchResponses = svr.StoreBatchCoprocessor(ctx, req) + return resp, nil +} + +// StoreBatchCoprocessor handle batched tasks in the same store. +func (svr *Server) StoreBatchCoprocessor(ctx context.Context, req *coprocessor.Request) []*coprocessor.StoreBatchTaskResponse { + if len(req.Tasks) == 0 { + return nil + } + tasks := req.Tasks + batchResps := make([]*coprocessor.StoreBatchTaskResponse, 0, len(tasks)) + handleBatchResp := func(task *coprocessor.StoreBatchTask) { + var err error + batchResp := &coprocessor.StoreBatchTaskResponse{ + TaskId: task.TaskId, + } + defer func() { + if err != nil { + batchResp.OtherError = err.Error() + } + batchResps = append(batchResps, batchResp) + }() + bytes, err := req.Marshal() + if err != nil { + return + } + taskReq := &coprocessor.Request{} + // deep clone req + if err = taskReq.Unmarshal(bytes); err != nil { + return + } + taskReq.Tasks = nil + taskReq.IsCacheEnabled = false + taskReq.Ranges = task.Ranges + taskReq.Context.RegionId = task.RegionId + taskReq.Context.RegionEpoch = task.RegionEpoch + taskReq.Context.Peer = task.Peer + resp, err := svr.Coprocessor(ctx, taskReq) + if err != nil { + return + } + batchResp.RegionError = resp.RegionError + batchResp.Locked = resp.Locked + batchResp.OtherError = resp.OtherError + batchResp.ExecDetailsV2 = resp.ExecDetailsV2 + batchResp.Data = resp.Data + } + for _, task := range tasks { + handleBatchResp(task) + } + return batchResps } -// CoprocessorStream implements implements the tikvpb.TikvServer interface. +// CoprocessorStream implements the tikvpb.TikvServer interface. func (svr *Server) CoprocessorStream(*coprocessor.Request, tikvpb.Tikv_CoprocessorStreamServer) error { // TODO return nil } +// GetLockWaitHistory implements the tikvpb.TikvServer interface. +func (svr *Server) GetLockWaitHistory(context.Context, *kvrpcpb.GetLockWaitHistoryRequest) (*kvrpcpb.GetLockWaitHistoryResponse, error) { + return &kvrpcpb.GetLockWaitHistoryResponse{}, nil +} + // RegionError represents a region error type RegionError struct { err *errorpb.Error @@ -584,7 +648,7 @@ func (regionError *RegionError) Error() string { return regionError.err.Message } -// BatchCoprocessor implements implements the tikvpb.TikvServer interface. +// BatchCoprocessor implements the tikvpb.TikvServer interface. func (svr *Server) BatchCoprocessor(req *coprocessor.BatchRequest, batchCopServer tikvpb.Tikv_BatchCoprocessorServer) error { reqCtxs := make([]*requestCtx, 0, len(req.Regions)) defer func() { @@ -628,7 +692,7 @@ func (svr *Server) BatchCoprocessor(req *coprocessor.BatchRequest, batchCopServe return nil } -// RawCoprocessor implements implements the tikvpb.TikvServer interface. +// RawCoprocessor implements the tikvpb.TikvServer interface. func (svr *Server) RawCoprocessor(context.Context, *kvrpcpb.RawCoprocessorRequest) (*kvrpcpb.RawCoprocessorResponse, error) { panic("unimplemented") } @@ -710,7 +774,7 @@ func (svr *Server) executeMPPDispatch(ctx context.Context, req *mpp.DispatchTask return nil } -// DispatchMPPTaskWithStoreID implements implements the tikvpb.TikvServer interface. +// DispatchMPPTaskWithStoreID implements the tikvpb.TikvServer interface. func (svr *Server) DispatchMPPTaskWithStoreID(ctx context.Context, req *mpp.DispatchTaskRequest, storeID uint64) (*mpp.DispatchTaskResponse, error) { mppHandler, err := svr.CreateMPPTaskHandler(req.Meta, storeID) if err != nil { @@ -728,12 +792,12 @@ func (svr *Server) DispatchMPPTaskWithStoreID(ctx context.Context, req *mpp.Disp return resp, nil } -// CancelMPPTask implements implements the tikvpb.TikvServer interface. +// CancelMPPTask implements the tikvpb.TikvServer interface. func (svr *Server) CancelMPPTask(_ context.Context, _ *mpp.CancelTaskRequest) (*mpp.CancelTaskResponse, error) { panic("todo") } -// GetMPPTaskHandler implements implements the tikvpb.TikvServer interface. +// GetMPPTaskHandler implements the tikvpb.TikvServer interface. func (svr *Server) GetMPPTaskHandler(taskID int64, storeID uint64) (*cophandler.MPPTaskHandler, error) { if mrm, ok := svr.regionManager.(*MockRegionManager); ok { set := mrm.getMPPTaskSet(storeID) @@ -750,7 +814,7 @@ func (svr *Server) GetMPPTaskHandler(taskID int64, storeID uint64) (*cophandler. return nil, errors.New("Only mock region mgr supports get mpp task") } -// RemoveMPPTaskHandler implements implements the tikvpb.TikvServer interface. +// RemoveMPPTaskHandler implements the tikvpb.TikvServer interface. func (svr *Server) RemoveMPPTaskHandler(taskID int64, storeID uint64) error { if mrm, ok := svr.regionManager.(*MockRegionManager); ok { err := mrm.removeMPPTaskHandler(taskID, storeID) @@ -759,7 +823,7 @@ func (svr *Server) RemoveMPPTaskHandler(taskID int64, storeID uint64) error { return errors.New("Only mock region mgr supports remove mpp task") } -// CreateMPPTaskHandler implements implements the tikvpb.TikvServer interface. +// CreateMPPTaskHandler implements the tikvpb.TikvServer interface. func (svr *Server) CreateMPPTaskHandler(meta *mpp.TaskMeta, storeID uint64) (*cophandler.MPPTaskHandler, error) { if mrm, ok := svr.regionManager.(*MockRegionManager); ok { set := mrm.getMPPTaskSet(storeID) @@ -782,12 +846,12 @@ func (svr *Server) CreateMPPTaskHandler(meta *mpp.TaskMeta, storeID uint64) (*co return nil, errors.New("Only mock region mgr supports get mpp task") } -// EstablishMPPConnection implements implements the tikvpb.TikvServer interface. +// EstablishMPPConnection implements the tikvpb.TikvServer interface. func (svr *Server) EstablishMPPConnection(*mpp.EstablishMPPConnectionRequest, tikvpb.Tikv_EstablishMPPConnectionServer) error { panic("todo") } -// EstablishMPPConnectionWithStoreID implements implements the tikvpb.TikvServer interface. +// EstablishMPPConnectionWithStoreID implements the tikvpb.TikvServer interface. func (svr *Server) EstablishMPPConnectionWithStoreID(req *mpp.EstablishMPPConnectionRequest, server tikvpb.Tikv_EstablishMPPConnectionServer, storeID uint64) error { var ( mppHandler *cophandler.MPPTaskHandler @@ -840,24 +904,24 @@ func (svr *Server) EstablishMPPConnectionWithStoreID(req *mpp.EstablishMPPConnec // Raft commands (tikv <-> tikv). -// Raft implements implements the tikvpb.TikvServer interface. +// Raft implements the tikvpb.TikvServer interface. func (svr *Server) Raft(stream tikvpb.Tikv_RaftServer) error { return svr.innerServer.Raft(stream) } -// Snapshot implements implements the tikvpb.TikvServer interface. +// Snapshot implements the tikvpb.TikvServer interface. func (svr *Server) Snapshot(stream tikvpb.Tikv_SnapshotServer) error { return svr.innerServer.Snapshot(stream) } -// BatchRaft implements implements the tikvpb.TikvServer interface. +// BatchRaft implements the tikvpb.TikvServer interface. func (svr *Server) BatchRaft(stream tikvpb.Tikv_BatchRaftServer) error { return svr.innerServer.BatchRaft(stream) } // Region commands. -// SplitRegion implements implements the tikvpb.TikvServer interface. +// SplitRegion implements the tikvpb.TikvServer interface. func (svr *Server) SplitRegion(ctx context.Context, req *kvrpcpb.SplitRegionRequest) (*kvrpcpb.SplitRegionResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "SplitRegion") if err != nil { @@ -872,7 +936,7 @@ func (svr *Server) Compact(ctx context.Context, req *kvrpcpb.CompactRequest) (*k panic("unimplemented") } -// ReadIndex implements implements the tikvpb.TikvServer interface. +// ReadIndex implements the tikvpb.TikvServer interface. func (svr *Server) ReadIndex(context.Context, *kvrpcpb.ReadIndexRequest) (*kvrpcpb.ReadIndexResponse, error) { // TODO: return &kvrpcpb.ReadIndexResponse{}, nil @@ -880,7 +944,7 @@ func (svr *Server) ReadIndex(context.Context, *kvrpcpb.ReadIndexRequest) (*kvrpc // transaction debugger commands. -// MvccGetByKey implements implements the tikvpb.TikvServer interface. +// MvccGetByKey implements the tikvpb.TikvServer interface. func (svr *Server) MvccGetByKey(ctx context.Context, req *kvrpcpb.MvccGetByKeyRequest) (*kvrpcpb.MvccGetByKeyResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "MvccGetByKey") if err != nil { @@ -899,7 +963,7 @@ func (svr *Server) MvccGetByKey(ctx context.Context, req *kvrpcpb.MvccGetByKeyRe return resp, nil } -// MvccGetByStartTs implements implements the tikvpb.TikvServer interface. +// MvccGetByStartTs implements the tikvpb.TikvServer interface. func (svr *Server) MvccGetByStartTs(ctx context.Context, req *kvrpcpb.MvccGetByStartTsRequest) (*kvrpcpb.MvccGetByStartTsResponse, error) { reqCtx, err := newRequestCtx(svr, req.Context, "MvccGetByStartTs") if err != nil { @@ -919,7 +983,7 @@ func (svr *Server) MvccGetByStartTs(ctx context.Context, req *kvrpcpb.MvccGetByS return resp, nil } -// UnsafeDestroyRange implements implements the tikvpb.TikvServer interface. +// UnsafeDestroyRange implements the tikvpb.TikvServer interface. func (svr *Server) UnsafeDestroyRange(ctx context.Context, req *kvrpcpb.UnsafeDestroyRangeRequest) (*kvrpcpb.UnsafeDestroyRangeResponse, error) { start, end := req.GetStartKey(), req.GetEndKey() svr.mvccStore.DeleteFileInRange(start, end) @@ -959,32 +1023,32 @@ func (svr *Server) Detect(stream deadlockPb.Deadlock_DetectServer) error { return nil } -// CheckLockObserver implements implements the tikvpb.TikvServer interface. +// CheckLockObserver implements the tikvpb.TikvServer interface. func (svr *Server) CheckLockObserver(context.Context, *kvrpcpb.CheckLockObserverRequest) (*kvrpcpb.CheckLockObserverResponse, error) { // TODO: implement Observer return &kvrpcpb.CheckLockObserverResponse{IsClean: true}, nil } -// PhysicalScanLock implements implements the tikvpb.TikvServer interface. +// PhysicalScanLock implements the tikvpb.TikvServer interface. func (svr *Server) PhysicalScanLock(ctx context.Context, req *kvrpcpb.PhysicalScanLockRequest) (*kvrpcpb.PhysicalScanLockResponse, error) { resp := &kvrpcpb.PhysicalScanLockResponse{} resp.Locks = svr.mvccStore.PhysicalScanLock(req.StartKey, req.MaxTs, int(req.Limit)) return resp, nil } -// RegisterLockObserver implements implements the tikvpb.TikvServer interface. +// RegisterLockObserver implements the tikvpb.TikvServer interface. func (svr *Server) RegisterLockObserver(context.Context, *kvrpcpb.RegisterLockObserverRequest) (*kvrpcpb.RegisterLockObserverResponse, error) { // TODO: implement Observer return &kvrpcpb.RegisterLockObserverResponse{}, nil } -// RemoveLockObserver implements implements the tikvpb.TikvServer interface. +// RemoveLockObserver implements the tikvpb.TikvServer interface. func (svr *Server) RemoveLockObserver(context.Context, *kvrpcpb.RemoveLockObserverRequest) (*kvrpcpb.RemoveLockObserverResponse, error) { // TODO: implement Observer return &kvrpcpb.RemoveLockObserverResponse{}, nil } -// CheckLeader implements implements the tikvpb.TikvServer interface. +// CheckLeader implements the tikvpb.TikvServer interface. func (svr *Server) CheckLeader(context.Context, *kvrpcpb.CheckLeaderRequest) (*kvrpcpb.CheckLeaderResponse, error) { panic("unimplemented") } @@ -1004,7 +1068,7 @@ func (svr *Server) GetLockWaitInfo(context.Context, *kvrpcpb.GetLockWaitInfoRequ panic("unimplemented") } -// RawChecksum implements implements the tikvpb.TikvServer interface. +// RawChecksum implements the tikvpb.TikvServer interface. func (svr *Server) RawChecksum(context.Context, *kvrpcpb.RawChecksumRequest) (*kvrpcpb.RawChecksumResponse, error) { panic("unimplemented") } diff --git a/store/mockstore/unistore/util/lockwaiter/main_test.go b/store/mockstore/unistore/util/lockwaiter/main_test.go index 470e33909b5b0..27b0a5b93bd25 100644 --- a/store/mockstore/unistore/util/lockwaiter/main_test.go +++ b/store/mockstore/unistore/util/lockwaiter/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/store/store.go b/store/store.go index d4b51f025d824..cbc91a4fce259 100644 --- a/store/store.go +++ b/store/store.go @@ -20,6 +20,7 @@ import ( "sync" "github.com/pingcap/errors" + "github.com/pingcap/kvproto/pkg/pdpb" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/logutil" @@ -74,7 +75,7 @@ func newStoreWithRetry(path string, maxRetries int) (kv.Storage, error) { err = util.RunWithRetry(maxRetries, util.RetryInterval, func() (bool, error) { logutil.BgLogger().Info("new store", zap.String("path", path)) s, err = d.Open(path) - return kv.IsTxnRetryableError(err), err + return isNewStoreRetryableError(err), err }) if err == nil { @@ -91,3 +92,32 @@ func loadDriver(name string) (kv.Driver, bool) { d, ok := stores[name] return d, ok } + +// isOpenRetryableError check if the new store operation should be retried under given error +// currently, it should be retried if: +// +// Transaction conflict and is retryable (kv.IsTxnRetryableError) +// PD is not bootstrapped at the time of request +// Keyspace requested does not exist (request prior to PD keyspace pre-split) +func isNewStoreRetryableError(err error) bool { + if err == nil { + return false + } + return kv.IsTxnRetryableError(err) || IsNotBootstrappedError(err) || IsKeyspaceNotExistError(err) +} + +// IsNotBootstrappedError returns true if the error is pd not bootstrapped error. +func IsNotBootstrappedError(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), pdpb.ErrorType_NOT_BOOTSTRAPPED.String()) +} + +// IsKeyspaceNotExistError returns true the error is caused by keyspace not exists. +func IsKeyspaceNotExistError(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), pdpb.ErrorType_ENTRY_NOT_FOUND.String()) +} diff --git a/structure/main_test.go b/structure/main_test.go index 12e8019bf3e47..956a8a8ad93d8 100644 --- a/structure/main_test.go +++ b/structure/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/table/BUILD.bazel b/table/BUILD.bazel index 5f8e425822279..a1f2feab60722 100644 --- a/table/BUILD.bazel +++ b/table/BUILD.bazel @@ -23,6 +23,7 @@ go_library( "//sessionctx", "//sessionctx/stmtctx", "//types", + "//util/chunk", "//util/dbterror", "//util/hack", "//util/logutil", diff --git a/table/column.go b/table/column.go index b814c8927a472..763f2ce3c766d 100644 --- a/table/column.go +++ b/table/column.go @@ -35,6 +35,7 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/timeutil" @@ -322,6 +323,7 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r } err = sc.HandleTruncate(err) + err = sc.HandleOverflow(err, err) if forceIgnoreTruncate { err = nil @@ -536,7 +538,9 @@ func getColDefaultValue(ctx sessionctx.Context, col *model.ColumnInfo, defaultVa return getColDefaultValueFromNil(ctx, col) } - if col.GetType() != mysql.TypeTimestamp && col.GetType() != mysql.TypeDatetime { + switch col.GetType() { + case mysql.TypeTimestamp, mysql.TypeDate, mysql.TypeDatetime: + default: value, err := CastValue(ctx, types.NewDatum(defaultVal), col, false, false) if err != nil { return types.Datum{}, err @@ -670,3 +674,36 @@ func OptionalFsp(fieldType *types.FieldType) string { } return "(" + strconv.Itoa(fsp) + ")" } + +// FillVirtualColumnValue will calculate the virtual column value by evaluating generated +// expression using rows from a chunk, and then fill this value into the chunk. +func FillVirtualColumnValue(virtualRetTypes []*types.FieldType, virtualColumnIndex []int, + expCols []*expression.Column, colInfos []*model.ColumnInfo, sctx sessionctx.Context, req *chunk.Chunk) error { + if len(virtualColumnIndex) == 0 { + return nil + } + + virCols := chunk.NewChunkWithCapacity(virtualRetTypes, req.Capacity()) + iter := chunk.NewIterator4Chunk(req) + for i, idx := range virtualColumnIndex { + for row := iter.Begin(); row != iter.End(); row = iter.Next() { + datum, err := expCols[idx].EvalVirtualColumn(row) + if err != nil { + return err + } + // Because the expression might return different type from + // the generated column, we should wrap a CAST on the result. + castDatum, err := CastValue(sctx, datum, colInfos[idx], false, true) + if err != nil { + return err + } + // Handle the bad null error. + if (mysql.HasNotNullFlag(colInfos[idx].GetFlag()) || mysql.HasPreventNullInsertFlag(colInfos[idx].GetFlag())) && castDatum.IsNull() { + castDatum = GetZeroValue(colInfos[idx]) + } + virCols.AppendDatum(i, &castDatum) + } + req.SetCol(idx, virCols.Column(i)) + } + return nil +} diff --git a/table/index.go b/table/index.go index e45ac40e8f6e9..a33b9c05f0049 100644 --- a/table/index.go +++ b/table/index.go @@ -69,17 +69,27 @@ func WithCtx(ctx context.Context) CreateIdxOptFunc { } } +// IndexIter is index kvs iter. +type IndexIter interface { + Next(kb []byte) ([]byte, []byte, bool, error) + Valid() bool +} + // Index is the interface for index data on KV store. type Index interface { // Meta returns IndexInfo. Meta() *model.IndexInfo + // TableMeta returns TableInfo + TableMeta() *model.TableInfo // Create supports insert into statement. Create(ctx sessionctx.Context, txn kv.Transaction, indexedValues []types.Datum, h kv.Handle, handleRestoreData []types.Datum, opts ...CreateIdxOptFunc) (kv.Handle, error) // Delete supports delete from statement. Delete(sc *stmtctx.StatementContext, txn kv.Transaction, indexedValues []types.Datum, h kv.Handle) error + // GenIndexKVIter generate index key and value for multi-valued index, use iterator to reduce the memory allocation. + GenIndexKVIter(sc *stmtctx.StatementContext, indexedValue []types.Datum, h kv.Handle, handleRestoreData []types.Datum) IndexIter // Exist supports check index exists or not. Exist(sc *stmtctx.StatementContext, txn kv.Transaction, indexedValues []types.Datum, h kv.Handle) (bool, kv.Handle, error) - // GenIndexKey generates an index key. + // GenIndexKey generates an index key. If the index is a multi-valued index, use GenIndexKVIter instead. GenIndexKey(sc *stmtctx.StatementContext, indexedValues []types.Datum, h kv.Handle, buf []byte) (key []byte, distinct bool, err error) // GenIndexValue generates an index value. GenIndexValue(sc *stmtctx.StatementContext, distinct bool, indexedValues []types.Datum, h kv.Handle, restoredData []types.Datum) ([]byte, error) diff --git a/table/main_test.go b/table/main_test.go index 79f1eaa5a9a71..019f53e9f303a 100644 --- a/table/main_test.go +++ b/table/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/table/table.go b/table/table.go index 6aef5ed4497e6..945714af05104 100644 --- a/table/table.go +++ b/table/table.go @@ -196,6 +196,9 @@ type Table interface { // Type returns the type of table Type() Type + + // GetPartitionedTable returns nil if not partitioned + GetPartitionedTable() PartitionedTable } // AllocAutoIncrementValue allocates an auto_increment value for a new row. @@ -206,7 +209,8 @@ func AllocAutoIncrementValue(ctx context.Context, t Table, sctx sessionctx.Conte } increment := sctx.GetSessionVars().AutoIncrementIncrement offset := sctx.GetSessionVars().AutoIncrementOffset - _, max, err := t.Allocators(sctx).Get(autoid.RowIDAllocType).Alloc(ctx, uint64(1), int64(increment), int64(offset)) + alloc := t.Allocators(sctx).Get(autoid.AutoIncrementType) + _, max, err := alloc.Alloc(ctx, uint64(1), int64(increment), int64(offset)) if err != nil { return 0, err } @@ -218,7 +222,8 @@ func AllocAutoIncrementValue(ctx context.Context, t Table, sctx sessionctx.Conte func AllocBatchAutoIncrementValue(ctx context.Context, t Table, sctx sessionctx.Context, N int) (firstID int64, increment int64, err error) { increment = int64(sctx.GetSessionVars().AutoIncrementIncrement) offset := int64(sctx.GetSessionVars().AutoIncrementOffset) - min, max, err := t.Allocators(sctx).Get(autoid.RowIDAllocType).Alloc(ctx, uint64(N), increment, offset) + alloc := t.Allocators(sctx).Get(autoid.AutoIncrementType) + min, max, err := alloc.Alloc(ctx, uint64(N), increment, offset) if err != nil { return min, max, err } @@ -243,6 +248,7 @@ type PartitionedTable interface { GetPartition(physicalID int64) PhysicalTable GetPartitionByRow(sessionctx.Context, []types.Datum) (PhysicalTable, error) GetAllPartitionIDs() []int64 + GetPartitionColumnIDs() []int64 GetPartitionColumnNames() []model.CIStr CheckForExchangePartition(ctx sessionctx.Context, pi *model.PartitionInfo, r []types.Datum, pid int64) error } diff --git a/table/tables/cache_test.go b/table/tables/cache_test.go index 6f8fc2d4345b4..27b90fd7c0159 100644 --- a/table/tables/cache_test.go +++ b/table/tables/cache_test.go @@ -231,7 +231,7 @@ func TestCacheTableBasicReadAndWrite(t *testing.T) { tk.MustQuery("select * from write_tmp1").Check(testkit.Rows("1 101 1001", "2 222 222", "3 113 1003")) tk1.MustExec("update write_tmp1 set v = 3333 where id = 2") for !lastReadFromCache(tk) { - tk.MustQuery("select * from write_tmp1").Check(testkit.Rows("1 101 1001", "2 222 222", "3 113 1003")) + tk.MustQuery("select * from write_tmp1").Check(testkit.Rows("1 101 1001", "2 222 3333", "3 113 1003")) } tk.MustQuery("select * from write_tmp1").Check(testkit.Rows("1 101 1001", "2 222 3333", "3 113 1003")) } diff --git a/table/tables/index.go b/table/tables/index.go index 77811eacc3a8c..29e3964959aa9 100644 --- a/table/tables/index.go +++ b/table/tables/index.go @@ -16,6 +16,7 @@ package tables import ( "context" + "errors" "sync" "github.com/opentracing/opentracing-go" @@ -79,6 +80,11 @@ func (c *index) Meta() *model.IndexInfo { return c.idxInfo } +// TableMeta returns table info. +func (c *index) TableMeta() *model.TableInfo { + return c.tblInfo +} + // GenIndexKey generates storage key for index values. Returned distinct indicates whether the // indexed values should be distinct in storage (i.e. whether handle is encoded in the key). func (c *index) GenIndexKey(sc *stmtctx.StatementContext, indexedValues []types.Datum, h kv.Handle, buf []byte) (key []byte, distinct bool, err error) { @@ -97,10 +103,61 @@ func (c *index) GenIndexValue(sc *stmtctx.StatementContext, distinct bool, index return tablecodec.GenIndexValuePortal(sc, c.tblInfo, c.idxInfo, c.needRestoredData, distinct, false, indexedValues, h, c.phyTblID, restoredData) } +// getIndexedValue will produce the result like: +// 1. If not multi-valued index, return directly. +// 2. (i1, [m1,m2], i2, ...) ==> [(i1, m1, i2, ...), (i1, m2, i2, ...)] +// 3. (i1, null, i2, ...) ==> [(i1, null, i2, ...)] +// 4. (i1, [], i2, ...) ==> nothing. +func (c *index) getIndexedValue(indexedValues []types.Datum) [][]types.Datum { + if !c.idxInfo.MVIndex { + return [][]types.Datum{indexedValues} + } + + vals := make([][]types.Datum, 0, 16) + jsonIdx := 0 + jsonIsNull := false + existsVals := make(map[string]struct{}) + var buf []byte + for !jsonIsNull { + val := make([]types.Datum, 0, len(indexedValues)) + for i, v := range indexedValues { + if !c.tblInfo.Columns[c.idxInfo.Columns[i].Offset].FieldType.IsArray() { + val = append(val, v) + } else { + if v.IsNull() { + val = append(val, v) + jsonIsNull = true + continue + } + elemCount := v.GetMysqlJSON().GetElemCount() + for { + // JSON cannot be indexed, if the value is JSON type, it must be multi-valued index. + if jsonIdx >= elemCount { + goto out + } + binaryJSON := v.GetMysqlJSON().ArrayGetElem(jsonIdx) + jsonIdx++ + buf = buf[:0] + key := string(binaryJSON.HashValue(buf)) + if _, exists := existsVals[key]; exists { + continue + } + existsVals[key] = struct{}{} + val = append(val, types.NewDatum(binaryJSON.GetValue())) + break + } + } + } + vals = append(vals, val) + } +out: + return vals +} + // Create creates a new entry in the kvIndex data. // If the index is unique and there is an existing entry with the same key, // Create will return the existing entry's handle as the first return value, ErrKeyExists as the second return value. -func (c *index) Create(sctx sessionctx.Context, txn kv.Transaction, indexedValues []types.Datum, h kv.Handle, handleRestoreData []types.Datum, opts ...table.CreateIdxOptFunc) (kv.Handle, error) { +func (c *index) Create(sctx sessionctx.Context, txn kv.Transaction, indexedValue []types.Datum, h kv.Handle, handleRestoreData []types.Datum, opts ...table.CreateIdxOptFunc) (kv.Handle, error) { if c.Meta().Unique { txn.CacheTableInfo(c.phyTblID, c.tblInfo) } @@ -108,229 +165,297 @@ func (c *index) Create(sctx sessionctx.Context, txn kv.Transaction, indexedValue for _, fn := range opts { fn(&opt) } + + indexedValues := c.getIndexedValue(indexedValue) + ctx := opt.Ctx + if ctx != nil { + if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { + span1 := span.Tracer().StartSpan("index.Create", opentracing.ChildOf(span.Context())) + defer span1.Finish() + ctx = opentracing.ContextWithSpan(ctx, span1) + } + } else { + ctx = context.TODO() + } vars := sctx.GetSessionVars() writeBufs := vars.GetWriteStmtBufs() skipCheck := vars.StmtCtx.BatchCheck - key, distinct, err := c.GenIndexKey(vars.StmtCtx, indexedValues, h, writeBufs.IndexKeyBuf) - if err != nil { - return nil, err - } - - var ( - tempKey []byte - keyVer byte - keyIsRewritten bool - ) - if !opt.FromBackFill { - key, tempKey, keyVer = genTempIdxKeyByState(c.idxInfo, key) - if keyVer == TempIndexKeyTypeBackfill { - key, tempKey = tempKey, nil - keyIsRewritten = true + for _, value := range indexedValues { + key, distinct, err := c.GenIndexKey(vars.StmtCtx, value, h, writeBufs.IndexKeyBuf) + if err != nil { + return nil, err } - } - ctx := opt.Ctx - if opt.Untouched { - txn, err1 := sctx.Txn(true) - if err1 != nil { - return nil, err1 + var ( + tempKey []byte + keyVer byte + keyIsTempIdxKey bool + ) + if !opt.FromBackFill { + key, tempKey, keyVer = GenTempIdxKeyByState(c.idxInfo, key) + if keyVer == TempIndexKeyTypeBackfill || keyVer == TempIndexKeyTypeDelete { + key, tempKey = tempKey, nil + keyIsTempIdxKey = true + } } - // If the index kv was untouched(unchanged), and the key/value already exists in mem-buffer, - // should not overwrite the key with un-commit flag. - // So if the key exists, just do nothing and return. - v, err := txn.GetMemBuffer().Get(ctx, key) - if err == nil { - if len(v) != 0 { - return nil, nil + + if opt.Untouched { + txn, err1 := sctx.Txn(true) + if err1 != nil { + return nil, err1 } - // The key is marked as deleted in the memory buffer, as the existence check is done lazily - // for optimistic transactions by default. The "untouched" key could still exist in the store, - // it's needed to commit this key to do the existence check so unset the untouched flag. - if !txn.IsPessimistic() { - keyFlags, err := txn.GetMemBuffer().GetFlags(key) - if err != nil { - return nil, err + // If the index kv was untouched(unchanged), and the key/value already exists in mem-buffer, + // should not overwrite the key with un-commit flag. + // So if the key exists, just do nothing and return. + v, err := txn.GetMemBuffer().Get(ctx, key) + if err == nil { + if len(v) != 0 { + continue } - if keyFlags.HasPresumeKeyNotExists() { - opt.Untouched = false + // The key is marked as deleted in the memory buffer, as the existence check is done lazily + // for optimistic transactions by default. The "untouched" key could still exist in the store, + // it's needed to commit this key to do the existence check so unset the untouched flag. + if !txn.IsPessimistic() { + keyFlags, err := txn.GetMemBuffer().GetFlags(key) + if err != nil { + return nil, err + } + if keyFlags.HasPresumeKeyNotExists() { + opt.Untouched = false + } } } } - } - - // save the key buffer to reuse. - writeBufs.IndexKeyBuf = key - c.initNeedRestoreData.Do(func() { - c.needRestoredData = NeedRestoredData(c.idxInfo.Columns, c.tblInfo.Columns) - }) - idxVal, err := tablecodec.GenIndexValuePortal(sctx.GetSessionVars().StmtCtx, c.tblInfo, c.idxInfo, c.needRestoredData, distinct, opt.Untouched, indexedValues, h, c.phyTblID, handleRestoreData) - if err != nil { - return nil, err - } - - opt.IgnoreAssertion = opt.IgnoreAssertion || c.idxInfo.State != model.StatePublic - if !distinct || skipCheck || opt.Untouched { - if keyIsRewritten { - idxVal = append(idxVal, keyVer) - } - err = txn.GetMemBuffer().Set(key, idxVal) + // save the key buffer to reuse. + writeBufs.IndexKeyBuf = key + c.initNeedRestoreData.Do(func() { + c.needRestoredData = NeedRestoredData(c.idxInfo.Columns, c.tblInfo.Columns) + }) + idxVal, err := tablecodec.GenIndexValuePortal(sctx.GetSessionVars().StmtCtx, c.tblInfo, c.idxInfo, c.needRestoredData, distinct, opt.Untouched, value, h, c.phyTblID, handleRestoreData) if err != nil { return nil, err } - if len(tempKey) > 0 { - idxVal = append(idxVal, keyVer) - err = txn.GetMemBuffer().Set(tempKey, idxVal) + + opt.IgnoreAssertion = opt.IgnoreAssertion || c.idxInfo.State != model.StatePublic + + if !distinct || skipCheck || opt.Untouched { + if keyIsTempIdxKey && !opt.Untouched { // Untouched key-values never occur in the storage. + idxVal = tablecodec.EncodeTempIndexValue(idxVal, keyVer) + } + err = txn.GetMemBuffer().Set(key, idxVal) if err != nil { return nil, err } - } - if !opt.IgnoreAssertion && (!opt.Untouched) { - if sctx.GetSessionVars().LazyCheckKeyNotExists() && !txn.IsPessimistic() { - err = txn.SetAssertion(key, kv.SetAssertUnknown) - } else { - err = txn.SetAssertion(key, kv.SetAssertNotExist) + if len(tempKey) > 0 { + if !opt.Untouched { // Untouched key-values never occur in the storage. + idxVal = tablecodec.EncodeTempIndexValue(idxVal, keyVer) + } + err = txn.GetMemBuffer().Set(tempKey, idxVal) + if err != nil { + return nil, err + } } + if !opt.IgnoreAssertion && (!opt.Untouched) { + if sctx.GetSessionVars().LazyCheckKeyNotExists() && !txn.IsPessimistic() { + err = txn.SetAssertion(key, kv.SetAssertUnknown) + } else { + err = txn.SetAssertion(key, kv.SetAssertNotExist) + } + } + if err != nil { + return nil, err + } + continue } - return nil, err - } - - if ctx != nil { - if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil { - span1 := span.Tracer().StartSpan("index.Create", opentracing.ChildOf(span.Context())) - defer span1.Finish() - ctx = opentracing.ContextWithSpan(ctx, span1) - } - } else { - ctx = context.TODO() - } - var value []byte - if c.tblInfo.TempTableType != model.TempTableNone { - // Always check key for temporary table because it does not write to TiKV - value, err = txn.Get(ctx, key) - } else if sctx.GetSessionVars().LazyCheckKeyNotExists() { - value, err = txn.GetMemBuffer().Get(ctx, key) - } else { - value, err = txn.Get(ctx, key) - } - if err != nil && !kv.IsErrNotFound(err) { - return nil, err - } - if err != nil || len(value) == 0 { - lazyCheck := sctx.GetSessionVars().LazyCheckKeyNotExists() && err != nil - if keyIsRewritten { - idxVal = append(idxVal, keyVer) - } - if lazyCheck { - flags := []kv.FlagsOp{kv.SetPresumeKeyNotExists} - if !vars.ConstraintCheckInPlacePessimistic && vars.TxnCtx.IsPessimistic && vars.InTxn() { - flags = append(flags, kv.SetNeedConstraintCheckInPrewrite) - } - err = txn.GetMemBuffer().SetWithFlags(key, idxVal, flags...) + var value []byte + if c.tblInfo.TempTableType != model.TempTableNone { + // Always check key for temporary table because it does not write to TiKV + value, err = txn.Get(ctx, key) + } else if sctx.GetSessionVars().LazyCheckKeyNotExists() { + value, err = txn.GetMemBuffer().Get(ctx, key) } else { - err = txn.GetMemBuffer().Set(key, idxVal) + value, err = txn.Get(ctx, key) } - if err != nil { + if err != nil && !kv.IsErrNotFound(err) { return nil, err } - if len(tempKey) > 0 { - idxVal = append(idxVal, keyVer) + if err != nil || len(value) == 0 || (keyIsTempIdxKey && tablecodec.CheckTempIndexValueIsDelete(value)) { + lazyCheck := sctx.GetSessionVars().LazyCheckKeyNotExists() && err != nil + var needPresumeKey TempIndexKeyState + if keyIsTempIdxKey { + idxVal = tablecodec.EncodeTempIndexValue(idxVal, keyVer) + needPresumeKey, _, err = KeyExistInTempIndex(ctx, txn, key, distinct, h, c.tblInfo.IsCommonHandle) + if err != nil { + return nil, err + } + } else { + if len(tempKey) > 0 { + needPresumeKey, _, err = KeyExistInTempIndex(ctx, txn, tempKey, distinct, h, c.tblInfo.IsCommonHandle) + if err != nil { + return nil, err + } + } + } if lazyCheck { - err = txn.GetMemBuffer().SetWithFlags(tempKey, idxVal, kv.SetPresumeKeyNotExists) + var flags []kv.FlagsOp + if needPresumeKey != KeyInTempIndexIsDeleted { + flags = []kv.FlagsOp{kv.SetPresumeKeyNotExists} + } + if !vars.ConstraintCheckInPlacePessimistic && vars.TxnCtx.IsPessimistic && vars.InTxn() && + !vars.InRestrictedSQL && vars.ConnectionID > 0 { + flags = append(flags, kv.SetNeedConstraintCheckInPrewrite) + } + err = txn.GetMemBuffer().SetWithFlags(key, idxVal, flags...) } else { - err = txn.GetMemBuffer().Set(tempKey, idxVal) + err = txn.GetMemBuffer().Set(key, idxVal) } if err != nil { return nil, err } + if len(tempKey) > 0 { + idxVal = tablecodec.EncodeTempIndexValue(idxVal, keyVer) + if lazyCheck && needPresumeKey != KeyInTempIndexIsDeleted { + err = txn.GetMemBuffer().SetWithFlags(tempKey, idxVal, kv.SetPresumeKeyNotExists) + } else { + err = txn.GetMemBuffer().Set(tempKey, idxVal) + } + if err != nil { + return nil, err + } + } + if opt.IgnoreAssertion { + continue + } + if lazyCheck && !txn.IsPessimistic() { + err = txn.SetAssertion(key, kv.SetAssertUnknown) + } else { + err = txn.SetAssertion(key, kv.SetAssertNotExist) + } + if err != nil { + return nil, err + } + continue } - if opt.IgnoreAssertion { - return nil, nil + + if keyIsTempIdxKey { + value = tablecodec.DecodeTempIndexOriginValue(value) } - if lazyCheck && !txn.IsPessimistic() { - err = txn.SetAssertion(key, kv.SetAssertUnknown) - } else { - err = txn.SetAssertion(key, kv.SetAssertNotExist) + handle, err := tablecodec.DecodeHandleInUniqueIndexValue(value, c.tblInfo.IsCommonHandle) + if err != nil { + return nil, err } - return nil, err - } - - handle, err := tablecodec.DecodeHandleInUniqueIndexValue(value, c.tblInfo.IsCommonHandle) - if err != nil { - return nil, err + return handle, kv.ErrKeyExists } - return handle, kv.ErrKeyExists + return nil, nil } -var ( - // DeleteMarker is a marker that the key is deleted. - DeleteMarker = []byte("delete") - // DeleteMarkerUnique is a marker that the unique index key is deleted. - DeleteMarkerUnique = []byte("deleteu") -) - // Delete removes the entry for handle h and indexedValues from KV index. -func (c *index) Delete(sc *stmtctx.StatementContext, txn kv.Transaction, indexedValues []types.Datum, h kv.Handle) error { - key, distinct, err := c.GenIndexKey(sc, indexedValues, h, nil) - if err != nil { - return err - } +func (c *index) Delete(sc *stmtctx.StatementContext, txn kv.Transaction, indexedValue []types.Datum, h kv.Handle) error { + indexedValues := c.getIndexedValue(indexedValue) + for _, value := range indexedValues { + key, distinct, err := c.GenIndexKey(sc, value, h, nil) + if err != nil { + return err + } - key, tempKey, tempKeyVer := genTempIdxKeyByState(c.idxInfo, key) + key, tempKey, tempKeyVer := GenTempIdxKeyByState(c.idxInfo, key) - if distinct { - if len(key) > 0 { - err = txn.GetMemBuffer().DeleteWithFlags(key, kv.SetNeedLocked) - if err != nil { - return err + if distinct { + if len(key) > 0 { + err = txn.GetMemBuffer().DeleteWithFlags(key, kv.SetNeedLocked) + if err != nil { + return err + } } - } - if len(tempKey) > 0 { - val := make([]byte, 0, len(DeleteMarkerUnique)+1) - val = append(val, DeleteMarkerUnique...) - val = append(val, tempKeyVer) - err = txn.GetMemBuffer().Set(tempKey, val) - if err != nil { - return err + if len(tempKey) > 0 { + tempVal := tablecodec.EncodeTempIndexValueDeletedUnique(h, tempKeyVer) + err = txn.GetMemBuffer().Set(tempKey, tempVal) + if err != nil { + return err + } } - } - } else { - if len(key) > 0 { - err = txn.GetMemBuffer().Delete(key) - if err != nil { - return err + } else { + if len(key) > 0 { + err = txn.GetMemBuffer().Delete(key) + if err != nil { + return err + } } - } - if len(tempKey) > 0 { - val := make([]byte, 0, len(DeleteMarker)+1) - val = append(val, DeleteMarker...) - val = append(val, tempKeyVer) - err = txn.GetMemBuffer().Set(tempKey, val) - if err != nil { - return err + if len(tempKey) > 0 { + tempVal := tablecodec.EncodeTempIndexValueDeleted(tempKeyVer) + err = txn.GetMemBuffer().Set(tempKey, tempVal) + if err != nil { + return err + } } } + if c.idxInfo.State == model.StatePublic { + // If the index is in public state, delete this index means it must exists. + err = txn.SetAssertion(key, kv.SetAssertExist) + } + if err != nil { + return err + } + } + return nil +} + +func (c *index) GenIndexKVIter(sc *stmtctx.StatementContext, indexedValue []types.Datum, h kv.Handle, handleRestoreData []types.Datum) table.IndexIter { + indexedValues := c.getIndexedValue(indexedValue) + return &indexGenerator{ + c: c, + sctx: sc, + indexedVals: indexedValues, + h: h, + handleRestoreData: handleRestoreData, + i: 0, + } +} + +type indexGenerator struct { + c *index + sctx *stmtctx.StatementContext + indexedVals [][]types.Datum + h kv.Handle + handleRestoreData []types.Datum + + i int +} + +func (s *indexGenerator) Next(kb []byte) ([]byte, []byte, bool, error) { + val := s.indexedVals[s.i] + key, distinct, err := s.c.GenIndexKey(s.sctx, val, s.h, kb) + if err != nil { + return nil, nil, false, err } - if c.idxInfo.State == model.StatePublic { - // If the index is in public state, delete this index means it must exists. - err = txn.SetAssertion(key, kv.SetAssertExist) + idxVal, err := s.c.GenIndexValue(s.sctx, distinct, val, s.h, s.handleRestoreData) + if err != nil { + return nil, nil, false, err } - return err + s.i++ + return key, idxVal, distinct, err +} + +func (s *indexGenerator) Valid() bool { + return s.i < len(s.indexedVals) } const ( // TempIndexKeyTypeNone means the key is not a temporary index key. TempIndexKeyTypeNone byte = 0 + // TempIndexKeyTypeDelete indicates this value is written in the delete-only stage. + TempIndexKeyTypeDelete byte = 'd' // TempIndexKeyTypeBackfill indicates this value is written in the backfill stage. TempIndexKeyTypeBackfill byte = 'b' // TempIndexKeyTypeMerge indicates this value is written in the merge stage. TempIndexKeyTypeMerge byte = 'm' ) -// genTempIdxKeyByState is used to get the key version and the temporary key. +// GenTempIdxKeyByState is used to get the key version and the temporary key. // The tempKeyVer means the temp index key/value version. -func genTempIdxKeyByState(indexInfo *model.IndexInfo, indexKey kv.Key) (key, tempKey kv.Key, tempKeyVer byte) { +func GenTempIdxKeyByState(indexInfo *model.IndexInfo, indexKey kv.Key) (key, tempKey kv.Key, tempKeyVer byte) { if indexInfo.State != model.StatePublic { switch indexInfo.BackfillState { case model.BackfillStateInapplicable: @@ -338,6 +463,9 @@ func genTempIdxKeyByState(indexInfo *model.IndexInfo, indexKey kv.Key) (key, tem case model.BackfillStateRunning: // Write to the temporary index. tablecodec.IndexKey2TempIndexKey(indexInfo.ID, indexKey) + if indexInfo.State == model.StateDeleteOnly { + return nil, indexKey, TempIndexKeyTypeDelete + } return nil, indexKey, TempIndexKeyTypeBackfill case model.BackfillStateReadyToMerge, model.BackfillStateMerging: // Double write @@ -350,33 +478,56 @@ func genTempIdxKeyByState(indexInfo *model.IndexInfo, indexKey kv.Key) (key, tem return indexKey, nil, TempIndexKeyTypeNone } -func (c *index) Exist(sc *stmtctx.StatementContext, txn kv.Transaction, indexedValues []types.Datum, h kv.Handle) (bool, kv.Handle, error) { - key, distinct, err := c.GenIndexKey(sc, indexedValues, h, nil) - if err != nil { - return false, nil, err - } +func (c *index) Exist(sc *stmtctx.StatementContext, txn kv.Transaction, indexedValue []types.Datum, h kv.Handle) (bool, kv.Handle, error) { + indexedValues := c.getIndexedValue(indexedValue) + for _, val := range indexedValues { + key, distinct, err := c.GenIndexKey(sc, val, h, nil) + if err != nil { + return false, nil, err + } - value, err := txn.Get(context.TODO(), key) - if kv.IsErrNotFound(err) { - return false, nil, nil - } - if err != nil { - return false, nil, err - } + var ( + tempKey []byte + keyVer byte + ) + // If index current is in creating status and using ingest mode, we need first + // check key exist status in temp index. + key, tempKey, keyVer = GenTempIdxKeyByState(c.idxInfo, key) + if keyVer != TempIndexKeyTypeNone { + KeyExistInfo, h1, err1 := KeyExistInTempIndex(context.TODO(), txn, tempKey, distinct, h, c.tblInfo.IsCommonHandle) + if err1 != nil { + return false, nil, err + } + switch KeyExistInfo { + case KeyInTempIndexNotExist, KeyInTempIndexIsDeleted: + return false, nil, nil + case KeyInTempIndexConflict: + return true, h1, kv.ErrKeyExists + case KeyInTempIndexIsItself: + continue + } + } - // For distinct index, the value of key is handle. - if distinct { - var handle kv.Handle - handle, err := tablecodec.DecodeHandleInUniqueIndexValue(value, c.tblInfo.IsCommonHandle) + value, err := txn.Get(context.TODO(), key) + if kv.IsErrNotFound(err) { + return false, nil, nil + } if err != nil { return false, nil, err } - if !handle.Equal(h) { - return true, handle, kv.ErrKeyExists + + // For distinct index, the value of key is handle. + if distinct { + var handle kv.Handle + handle, err := tablecodec.DecodeHandleInUniqueIndexValue(value, c.tblInfo.IsCommonHandle) + if err != nil { + return false, nil, err + } + if !handle.Equal(h) { + return true, handle, kv.ErrKeyExists + } } - return true, handle, nil } - return true, h, nil } @@ -455,3 +606,57 @@ func TryAppendCommonHandleRowcodecColInfos(colInfo []rowcodec.ColInfo, tblInfo * } return colInfo } + +// TempIndexKeyState is the state of the temporary index key. +type TempIndexKeyState byte + +const ( + // KeyInTempIndexUnknown whether the key exists or not in temp index is unknown. + KeyInTempIndexUnknown TempIndexKeyState = iota + // KeyInTempIndexNotExist the key is not exist in temp index. + KeyInTempIndexNotExist + // KeyInTempIndexIsDeleted the key is marked deleted in temp index. + KeyInTempIndexIsDeleted + // KeyInTempIndexIsItself the key is correlated to itself in temp index. + KeyInTempIndexIsItself + // KeyInTempIndexConflict the key is conflict in temp index. + KeyInTempIndexConflict +) + +// KeyExistInTempIndex is used to check the unique key exist status in temp index. +func KeyExistInTempIndex(ctx context.Context, txn kv.Transaction, key kv.Key, distinct bool, h kv.Handle, IsCommonHandle bool) (TempIndexKeyState, kv.Handle, error) { + // Only check temp index key. + if !tablecodec.IsTempIndexKey(key) { + return KeyInTempIndexUnknown, nil, nil + } + value, err := txn.Get(ctx, key) + if kv.IsErrNotFound(err) { + return KeyInTempIndexNotExist, nil, nil + } + if err != nil { + return KeyInTempIndexUnknown, nil, err + } + + // Since KeyExistInTempIndex only accept temp index key, so the value length should great than 1 for key version. + if len(value) < 1 { + return KeyInTempIndexUnknown, nil, errors.New("temp index value length should great than 1") + } + + if tablecodec.CheckTempIndexValueIsDelete(value) { + return KeyInTempIndexIsDeleted, nil, nil + } + + // Check if handle equal. + var handle kv.Handle + if distinct { + originVal := tablecodec.DecodeTempIndexOriginValue(value) + handle, err = tablecodec.DecodeHandleInUniqueIndexValue(originVal, IsCommonHandle) + if err != nil { + return KeyInTempIndexUnknown, nil, err + } + if !handle.Equal(h) { + return KeyInTempIndexConflict, handle, kv.ErrKeyExists + } + } + return KeyInTempIndexIsItself, handle, nil +} diff --git a/table/tables/main_test.go b/table/tables/main_test.go index f707c7babbf74..d831e57364d33 100644 --- a/table/tables/main_test.go +++ b/table/tables/main_test.go @@ -25,7 +25,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/table/tables/mutation_checker.go b/table/tables/mutation_checker.go index bf6cc2ffb5853..328989d88ad3f 100644 --- a/table/tables/mutation_checker.go +++ b/table/tables/mutation_checker.go @@ -15,7 +15,6 @@ package tables import ( - "bytes" "fmt" "strings" @@ -153,11 +152,11 @@ func checkHandleConsistency(rowInsertion mutation, indexMutations []mutation, in value []byte orgKey []byte indexHandle kv.Handle - err error ) if idxID != m.indexID { - value = append(value, m.value[:len(m.value)-1]...) - if len(value) == 0 || (bytes.Equal(value, []byte("delete")) || bytes.Equal(value, []byte("deleteu"))) { + value = tablecodec.DecodeTempIndexOriginValue(m.value) + if len(value) == 0 { + // Skip the deleted operation values. continue } orgKey = append(orgKey, m.key...) @@ -237,7 +236,7 @@ func checkIndexKeys( } for i, v := range decodedIndexValues { - fieldType := &t.Columns[indexInfo.Columns[i].Offset].FieldType + fieldType := t.Columns[indexInfo.Columns[i].Offset].FieldType.ArrayType() datum, err := tablecodec.DecodeColumnValue(v, fieldType, sessVars.Location()) if err != nil { return errors.Trace(err) @@ -246,7 +245,7 @@ func checkIndexKeys( } // When it is in add index new backfill state. - if len(value) == 0 || (idxID != m.indexID && (bytes.Equal(value, []byte("deleteu")) || bytes.Equal(value, []byte("delete")))) { + if len(value) == 0 || (idxID != m.indexID && (tablecodec.CheckTempIndexValueIsDelete(value))) { err = compareIndexData(sessVars.StmtCtx, t.Columns, indexData, rowToRemove, indexInfo, t.Meta()) } else { err = compareIndexData(sessVars.StmtCtx, t.Columns, indexData, rowToInsert, indexInfo, t.Meta()) @@ -348,7 +347,9 @@ func compareIndexData( cols[indexInfo.Columns[i].Offset].ColumnInfo, ) - comparison, err := decodedMutationDatum.Compare(sc, &expectedDatum, collate.GetCollator(decodedMutationDatum.Collation())) + comparison, err := CompareIndexAndVal(sc, expectedDatum, decodedMutationDatum, + collate.GetCollator(decodedMutationDatum.Collation()), + cols[indexInfo.Columns[i].Offset].ColumnInfo.FieldType.IsArray() && expectedDatum.Kind() == types.KindMysqlJSON) if err != nil { return errors.Trace(err) } @@ -365,6 +366,30 @@ func compareIndexData( return nil } +// CompareIndexAndVal compare index valued and row value. +func CompareIndexAndVal(sctx *stmtctx.StatementContext, rowVal types.Datum, idxVal types.Datum, collator collate.Collator, cmpMVIndex bool) (int, error) { + var cmpRes int + var err error + if cmpMVIndex { + // If it is multi-valued index, we should check the JSON contains the indexed value. + bj := rowVal.GetMysqlJSON() + count := bj.GetElemCount() + for elemIdx := 0; elemIdx < count; elemIdx++ { + jsonDatum := types.NewJSONDatum(bj.ArrayGetElem(elemIdx)) + cmpRes, err = jsonDatum.Compare(sctx, &idxVal, collate.GetBinaryCollator()) + if err != nil { + return 0, errors.Trace(err) + } + if cmpRes == 0 { + break + } + } + } else { + cmpRes, err = idxVal.Compare(sctx, &rowVal, collator) + } + return cmpRes, err +} + // getColumnMaps tries to get the columnMaps from transaction options. If there isn't one, it builds one and stores it. // It saves redundant computations of the map. func getColumnMaps(txn kv.Transaction, t *TableCommon) columnMaps { diff --git a/table/tables/mutation_checker_test.go b/table/tables/mutation_checker_test.go index 658905fcf14e4..43fb35c21a5b6 100644 --- a/table/tables/mutation_checker_test.go +++ b/table/tables/mutation_checker_test.go @@ -332,7 +332,7 @@ func buildIndexKeyValue(index table.Index, rowToInsert []types.Datum, sessVars * if err != nil { return nil, nil, err } - rsData := TryGetHandleRestoredDataWrapper(table, rowToInsert, nil, indexInfo) + rsData := TryGetHandleRestoredDataWrapper(table.meta, rowToInsert, nil, indexInfo) value, err := tablecodec.GenIndexValuePortal( sessVars.StmtCtx, &tableInfo, indexInfo, NeedRestoredData(indexInfo.Columns, tableInfo.Columns), distinct, false, indexedValues, handle, 0, rsData, diff --git a/table/tables/partition.go b/table/tables/partition.go index 6a0b315b856e9..fdc949ce4eb3f 100644 --- a/table/tables/partition.go +++ b/table/tables/partition.go @@ -40,6 +40,7 @@ import ( "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/mock" @@ -67,6 +68,7 @@ var _ table.PartitionedTable = &partitionedTable{} // partition also implements the table.Table interface. type partition struct { TableCommon + table *partitionedTable } // GetPhysicalID implements table.Table GetPhysicalID interface. @@ -74,6 +76,16 @@ func (p *partition) GetPhysicalID() int64 { return p.physicalTableID } +// GetPartitionedTable implements table.Table GetPartitionedTable interface. +func (p *partition) GetPartitionedTable() table.PartitionedTable { + return p.table +} + +// GetPartitionedTable implements table.Table GetPartitionedTable interface. +func (t *partitionedTable) GetPartitionedTable() table.PartitionedTable { + return t +} + // partitionedTable implements the table.PartitionedTable interface. // partitionedTable is a table, it contains many Partitions. type partitionedTable struct { @@ -82,11 +94,24 @@ type partitionedTable struct { partitions map[int64]*partition evalBufferTypes []*types.FieldType evalBufferPool sync.Pool + + // Only used during Reorganize partition + // reorganizePartitions is the currently used partitions that are reorganized + reorganizePartitions map[int64]interface{} + // doubleWriteParittions are the partitions not visible, but we should double write to + doubleWritePartitions map[int64]interface{} + reorgPartitionExpr *PartitionExpr } -func newPartitionedTable(tbl *TableCommon, tblInfo *model.TableInfo) (table.Table, error) { +// TODO: Check which data structures that can be shared between all partitions and which +// needs to be copies +func newPartitionedTable(tbl *TableCommon, tblInfo *model.TableInfo) (table.PartitionedTable, error) { + pi := tblInfo.GetPartitionInfo() + if pi == nil || len(pi.Definitions) == 0 { + return nil, table.ErrUnknownPartition + } ret := &partitionedTable{TableCommon: *tbl} - partitionExpr, err := newPartitionExpr(tblInfo) + partitionExpr, err := newPartitionExpr(tblInfo, pi.Definitions) if err != nil { return nil, errors.Trace(err) } @@ -100,7 +125,6 @@ func newPartitionedTable(tbl *TableCommon, tblInfo *model.TableInfo) (table.Tabl if err := initTableIndices(&ret.TableCommon); err != nil { return nil, errors.Trace(err) } - pi := tblInfo.GetPartitionInfo() partitions := make(map[int64]*partition, len(pi.Definitions)) for _, p := range pi.Definitions { var t partition @@ -108,13 +132,103 @@ func newPartitionedTable(tbl *TableCommon, tblInfo *model.TableInfo) (table.Tabl if err != nil { return nil, errors.Trace(err) } + t.table = ret partitions[p.ID] = &t } ret.partitions = partitions + // In StateWriteReorganization we are using the 'old' partition definitions + // and if any new change happens in DroppingDefinitions, it needs to be done + // also in AddingDefinitions (with new evaluation of the new expression) + // In StateDeleteReorganization we are using the 'new' partition definitions + // and if any new change happens in AddingDefinitions, it needs to be done + // also in DroppingDefinitions (since session running on schema version -1) + // should also see the changes + if pi.DDLState == model.StateDeleteReorganization { + origIdx := setIndexesState(ret, pi.DDLState) + defer unsetIndexesState(ret, origIdx) + ret.reorgPartitionExpr, err = newPartitionExpr(tblInfo, pi.DroppingDefinitions) + if err != nil { + return nil, errors.Trace(err) + } + ret.reorganizePartitions = make(map[int64]interface{}, len(pi.AddingDefinitions)) + for _, def := range pi.AddingDefinitions { + ret.reorganizePartitions[def.ID] = nil + } + // TODO: Test decreasing end range and concurrently insert in the gap + // TODO: Test increasing end range and concurrently insert into the gap + ret.doubleWritePartitions = make(map[int64]interface{}, len(pi.DroppingDefinitions)) + for _, def := range pi.DroppingDefinitions { + p, err := initPartition(ret, def) + if err != nil { + return nil, err + } + partitions[def.ID] = p + ret.doubleWritePartitions[def.ID] = nil + } + } else { + if len(pi.AddingDefinitions) > 0 { + origIdx := setIndexesState(ret, pi.DDLState) + defer unsetIndexesState(ret, origIdx) + ret.reorgPartitionExpr, err = newPartitionExpr(tblInfo, pi.AddingDefinitions) + if err != nil { + return nil, errors.Trace(err) + } + ret.doubleWritePartitions = make(map[int64]interface{}, len(pi.AddingDefinitions)) + for _, def := range pi.AddingDefinitions { + ret.doubleWritePartitions[def.ID] = nil + p, err := initPartition(ret, def) + if err != nil { + return nil, err + } + partitions[def.ID] = p + } + } + if len(pi.DroppingDefinitions) > 0 { + ret.reorganizePartitions = make(map[int64]interface{}, len(pi.DroppingDefinitions)) + for _, def := range pi.DroppingDefinitions { + ret.reorganizePartitions[def.ID] = nil + } + } + } return ret, nil } -func newPartitionExpr(tblInfo *model.TableInfo) (*PartitionExpr, error) { +func setIndexesState(t *partitionedTable, state model.SchemaState) []*model.IndexInfo { + orig := t.meta.Indices + t.meta.Indices = make([]*model.IndexInfo, 0, len(orig)) + for i := range orig { + t.meta.Indices = append(t.meta.Indices, orig[i].Clone()) + if t.meta.Indices[i].State == model.StatePublic { + switch state { + case model.StateDeleteOnly, model.StateNone: + t.meta.Indices[i].State = model.StateDeleteOnly + case model.StatePublic: + // Keep as is + default: + // use the 'StateWriteReorganization' here, since StateDeleteReorganization + // would skip index writes. + t.meta.Indices[i].State = model.StateWriteReorganization + } + } + } + return orig +} + +func unsetIndexesState(t *partitionedTable, orig []*model.IndexInfo) { + t.meta.Indices = orig +} + +func initPartition(t *partitionedTable, def model.PartitionDefinition) (*partition, error) { + var newPart partition + err := initTableCommonWithIndices(&newPart.TableCommon, t.meta, def.ID, t.Columns, t.allocs) + if err != nil { + return nil, err + } + newPart.table = t + return &newPart, nil +} + +func newPartitionExpr(tblInfo *model.TableInfo, defs []model.PartitionDefinition) (*PartitionExpr, error) { // a partitioned table cannot rely on session context/sql modes, so use a default one! ctx := mock.NewContext() dbName := model.NewCIStr(ctx.GetSessionVars().CurrentDB) @@ -125,11 +239,11 @@ func newPartitionExpr(tblInfo *model.TableInfo) (*PartitionExpr, error) { pi := tblInfo.GetPartitionInfo() switch pi.Type { case model.PartitionTypeRange: - return generateRangePartitionExpr(ctx, pi, columns, names) + return generateRangePartitionExpr(ctx, pi, defs, columns, names) case model.PartitionTypeHash: return generateHashPartitionExpr(ctx, pi, columns, names) case model.PartitionTypeList: - return generateListPartitionExpr(ctx, tblInfo, columns, names) + return generateListPartitionExpr(ctx, tblInfo, defs, columns, names) } panic("cannot reach here") } @@ -148,8 +262,6 @@ type PartitionExpr struct { *ForRangeColumnsPruning // ColOffset is the offsets of partition columns. ColumnOffset []int - // InValues: x in (1,2); x in (3,4); x in (5,6), used for list partition. - InValues []expression.Expression *ForListPruning } @@ -182,19 +294,19 @@ type ForRangeColumnsPruning struct { LessThan [][]*expression.Expression } -func dataForRangeColumnsPruning(ctx sessionctx.Context, pi *model.PartitionInfo, schema *expression.Schema, names []*types.FieldName, p *parser.Parser) (*ForRangeColumnsPruning, error) { +func dataForRangeColumnsPruning(ctx sessionctx.Context, defs []model.PartitionDefinition, schema *expression.Schema, names []*types.FieldName, p *parser.Parser) (*ForRangeColumnsPruning, error) { var res ForRangeColumnsPruning - res.LessThan = make([][]*expression.Expression, 0, len(pi.Definitions)) - for i := 0; i < len(pi.Definitions); i++ { - lessThanCols := make([]*expression.Expression, 0, len(pi.Columns)) - for j := range pi.Definitions[i].LessThan { - if strings.EqualFold(pi.Definitions[i].LessThan[j], "MAXVALUE") { + res.LessThan = make([][]*expression.Expression, 0, len(defs)) + for i := 0; i < len(defs); i++ { + lessThanCols := make([]*expression.Expression, 0, len(defs[i].LessThan)) + for j := range defs[i].LessThan { + if strings.EqualFold(defs[i].LessThan[j], "MAXVALUE") { // Use a nil pointer instead of math.MaxInt64 to avoid the corner cases. lessThanCols = append(lessThanCols, nil) // No column after MAXVALUE matters break } - tmp, err := parseSimpleExprWithNames(p, ctx, pi.Definitions[i].LessThan[j], schema, names) + tmp, err := parseSimpleExprWithNames(p, ctx, defs[i].LessThan[j], schema, names) if err != nil { return nil, err } @@ -426,29 +538,29 @@ type ForRangePruning struct { Unsigned bool } -// dataForRangePruning extracts the less than parts from 'partition p0 less than xx ... partitoin p1 less than ...' -func dataForRangePruning(sctx sessionctx.Context, pi *model.PartitionInfo) (*ForRangePruning, error) { +// dataForRangePruning extracts the less than parts from 'partition p0 less than xx ... partition p1 less than ...' +func dataForRangePruning(sctx sessionctx.Context, defs []model.PartitionDefinition) (*ForRangePruning, error) { var maxValue bool var unsigned bool - lessThan := make([]int64, len(pi.Definitions)) - for i := 0; i < len(pi.Definitions); i++ { - if strings.EqualFold(pi.Definitions[i].LessThan[0], "MAXVALUE") { + lessThan := make([]int64, len(defs)) + for i := 0; i < len(defs); i++ { + if strings.EqualFold(defs[i].LessThan[0], "MAXVALUE") { // Use a bool flag instead of math.MaxInt64 to avoid the corner cases. maxValue = true } else { var err error - lessThan[i], err = strconv.ParseInt(pi.Definitions[i].LessThan[0], 10, 64) + lessThan[i], err = strconv.ParseInt(defs[i].LessThan[0], 10, 64) var numErr *strconv.NumError if stderr.As(err, &numErr) && numErr.Err == strconv.ErrRange { var tmp uint64 - tmp, err = strconv.ParseUint(pi.Definitions[i].LessThan[0], 10, 64) + tmp, err = strconv.ParseUint(defs[i].LessThan[0], 10, 64) lessThan[i] = int64(tmp) unsigned = true } if err != nil { - val, ok := fixOldVersionPartitionInfo(sctx, pi.Definitions[i].LessThan[0]) + val, ok := fixOldVersionPartitionInfo(sctx, defs[i].LessThan[0]) if !ok { - logutil.BgLogger().Error("wrong partition definition", zap.String("less than", pi.Definitions[i].LessThan[0])) + logutil.BgLogger().Error("wrong partition definition", zap.String("less than", defs[i].LessThan[0])) return nil, errors.WithStack(err) } lessThan[i] = val @@ -490,40 +602,14 @@ func rangePartitionExprStrings(pi *model.PartitionInfo) []string { } func generateRangePartitionExpr(ctx sessionctx.Context, pi *model.PartitionInfo, - columns []*expression.Column, names types.NameSlice) (*PartitionExpr, error) { + defs []model.PartitionDefinition, columns []*expression.Column, names types.NameSlice) (*PartitionExpr, error) { // The caller should assure partition info is not nil. - locateExprs := make([]expression.Expression, 0, len(pi.Definitions)) - var buf bytes.Buffer p := parser.New() schema := expression.NewSchema(columns...) partStrs := rangePartitionExprStrings(pi) - for i := 0; i < len(pi.Definitions); i++ { - if strings.EqualFold(pi.Definitions[i].LessThan[0], "MAXVALUE") { - // Expr less than maxvalue is always true. - fmt.Fprintf(&buf, "true") - } else { - maxValueFound := false - for j := range partStrs[1:] { - if strings.EqualFold(pi.Definitions[i].LessThan[j+1], "MAXVALUE") { - // if any column will be less than MAXVALUE, so change < to <= of the previous prefix of columns - fmt.Fprintf(&buf, "((%s) <= (%s))", strings.Join(partStrs[:j+1], ","), strings.Join(pi.Definitions[i].LessThan[:j+1], ",")) - maxValueFound = true - break - } - } - if !maxValueFound { - fmt.Fprintf(&buf, "((%s) < (%s))", strings.Join(partStrs, ","), strings.Join(pi.Definitions[i].LessThan, ",")) - } - } - - expr, err := parseSimpleExprWithNames(p, ctx, buf.String(), schema, names) - if err != nil { - // If it got an error here, ddl may hang forever, so this error log is important. - logutil.BgLogger().Error("wrong table partition expression", zap.String("expression", buf.String()), zap.Error(err)) - return nil, errors.Trace(err) - } - locateExprs = append(locateExprs, expr) - buf.Reset() + locateExprs, err := getRangeLocateExprs(ctx, p, defs, partStrs, schema, names) + if err != nil { + return nil, errors.Trace(err) } ret := &PartitionExpr{ UpperBounds: locateExprs, @@ -536,14 +622,14 @@ func generateRangePartitionExpr(ctx sessionctx.Context, pi *model.PartitionInfo, ret.ColumnOffset = offset if len(pi.Columns) < 1 { - tmp, err := dataForRangePruning(ctx, pi) + tmp, err := dataForRangePruning(ctx, defs) if err != nil { return nil, errors.Trace(err) } ret.Expr = partExpr ret.ForRangePruning = tmp } else { - tmp, err := dataForRangeColumnsPruning(ctx, pi, schema, names, p) + tmp, err := dataForRangeColumnsPruning(ctx, defs, schema, names, p) if err != nil { return nil, errors.Trace(err) } @@ -552,6 +638,40 @@ func generateRangePartitionExpr(ctx sessionctx.Context, pi *model.PartitionInfo, return ret, nil } +func getRangeLocateExprs(ctx sessionctx.Context, p *parser.Parser, defs []model.PartitionDefinition, partStrs []string, schema *expression.Schema, names types.NameSlice) ([]expression.Expression, error) { + var buf bytes.Buffer + locateExprs := make([]expression.Expression, 0, len(defs)) + for i := 0; i < len(defs); i++ { + if strings.EqualFold(defs[i].LessThan[0], "MAXVALUE") { + // Expr less than maxvalue is always true. + fmt.Fprintf(&buf, "true") + } else { + maxValueFound := false + for j := range partStrs[1:] { + if strings.EqualFold(defs[i].LessThan[j+1], "MAXVALUE") { + // if any column will be less than MAXVALUE, so change < to <= of the previous prefix of columns + fmt.Fprintf(&buf, "((%s) <= (%s))", strings.Join(partStrs[:j+1], ","), strings.Join(defs[i].LessThan[:j+1], ",")) + maxValueFound = true + break + } + } + if !maxValueFound { + fmt.Fprintf(&buf, "((%s) < (%s))", strings.Join(partStrs, ","), strings.Join(defs[i].LessThan, ",")) + } + } + + expr, err := parseSimpleExprWithNames(p, ctx, buf.String(), schema, names) + if err != nil { + // If it got an error here, ddl may hang forever, so this error log is important. + logutil.BgLogger().Error("wrong table partition expression", zap.String("expression", buf.String()), zap.Error(err)) + return nil, errors.Trace(err) + } + locateExprs = append(locateExprs, expr) + buf.Reset() + } + return locateExprs, nil +} + func getColumnsOffset(cols, columns []*expression.Column) []int { colsOffset := make([]int, len(cols)) for i, col := range columns { @@ -603,7 +723,7 @@ func extractPartitionExprColumns(ctx sessionctx.Context, pi *model.PartitionInfo } func generateListPartitionExpr(ctx sessionctx.Context, tblInfo *model.TableInfo, - columns []*expression.Column, names types.NameSlice) (*PartitionExpr, error) { + defs []model.PartitionDefinition, columns []*expression.Column, names types.NameSlice) (*PartitionExpr, error) { // The caller should assure partition info is not nil. pi := tblInfo.GetPartitionInfo() partExpr, exprCols, offset, err := extractPartitionExprColumns(ctx, pi, columns, names) @@ -612,9 +732,9 @@ func generateListPartitionExpr(ctx sessionctx.Context, tblInfo *model.TableInfo, } listPrune := &ForListPruning{} if len(pi.Columns) == 0 { - err = listPrune.buildListPruner(ctx, tblInfo, exprCols, columns, names) + err = listPrune.buildListPruner(ctx, tblInfo, defs, exprCols, columns, names) } else { - err = listPrune.buildListColumnsPruner(ctx, tblInfo, columns, names) + err = listPrune.buildListColumnsPruner(ctx, tblInfo, defs, columns, names) } if err != nil { return nil, err @@ -627,7 +747,7 @@ func generateListPartitionExpr(ctx sessionctx.Context, tblInfo *model.TableInfo, return ret, nil } -func (lp *ForListPruning) buildListPruner(ctx sessionctx.Context, tblInfo *model.TableInfo, exprCols []*expression.Column, +func (lp *ForListPruning) buildListPruner(ctx sessionctx.Context, tblInfo *model.TableInfo, defs []model.PartitionDefinition, exprCols []*expression.Column, columns []*expression.Column, names types.NameSlice) error { pi := tblInfo.GetPartitionInfo() schema := expression.NewSchema(columns...) @@ -638,7 +758,7 @@ func (lp *ForListPruning) buildListPruner(ctx sessionctx.Context, tblInfo *model logutil.BgLogger().Error("wrong table partition expression", zap.String("expression", pi.Expr), zap.Error(err)) return errors.Trace(err) } - // Since need to change the column index of the expresion, clone the expression first. + // Since need to change the column index of the expression, clone the expression first. lp.LocateExpr = expr.Clone() lp.PruneExprCols = exprCols lp.PruneExpr = expr.Clone() @@ -650,14 +770,15 @@ func (lp *ForListPruning) buildListPruner(ctx sessionctx.Context, tblInfo *model } c.Index = idx } - err = lp.buildListPartitionValueMap(ctx, tblInfo, schema, names, p) + err = lp.buildListPartitionValueMap(ctx, defs, schema, names, p) if err != nil { return err } return nil } -func (lp *ForListPruning) buildListColumnsPruner(ctx sessionctx.Context, tblInfo *model.TableInfo, +func (lp *ForListPruning) buildListColumnsPruner(ctx sessionctx.Context, + tblInfo *model.TableInfo, defs []model.PartitionDefinition, columns []*expression.Column, names types.NameSlice) error { pi := tblInfo.GetPartitionInfo() schema := expression.NewSchema(columns...) @@ -683,7 +804,7 @@ func (lp *ForListPruning) buildListColumnsPruner(ctx sessionctx.Context, tblInfo valueMap: make(map[string]ListPartitionLocation), sorted: btree.NewG[*btreeListColumnItem](btreeDegree, lessBtreeListColumnItem), } - err := colPrune.buildPartitionValueMapAndSorted(p) + err := colPrune.buildPartitionValueMapAndSorted(p, defs) if err != nil { return err } @@ -696,12 +817,11 @@ func (lp *ForListPruning) buildListColumnsPruner(ctx sessionctx.Context, tblInfo // buildListPartitionValueMap builds list partition value map. // The map is column value -> partition index. // colIdx is the column index in the list columns. -func (lp *ForListPruning) buildListPartitionValueMap(ctx sessionctx.Context, tblInfo *model.TableInfo, +func (lp *ForListPruning) buildListPartitionValueMap(ctx sessionctx.Context, defs []model.PartitionDefinition, schema *expression.Schema, names types.NameSlice, p *parser.Parser) error { - pi := tblInfo.GetPartitionInfo() lp.valueMap = map[int64]int{} lp.nullPartitionIdx = -1 - for partitionIdx, def := range pi.Definitions { + for partitionIdx, def := range defs { for _, vs := range def.InValues { expr, err := parseSimpleExprWithNames(p, ctx, vs[0], schema, names) if err != nil { @@ -770,26 +890,27 @@ func (lp *ForListPruning) locateListColumnsPartitionByRow(ctx sessionctx.Context // buildPartitionValueMapAndSorted builds list columns partition value map for the specified column. // It also builds list columns partition value btree for the specified column. // colIdx is the specified column index in the list columns. -func (lp *ForListColumnPruning) buildPartitionValueMapAndSorted(p *parser.Parser) error { +func (lp *ForListColumnPruning) buildPartitionValueMapAndSorted(p *parser.Parser, + defs []model.PartitionDefinition) error { l := len(lp.valueMap) if l != 0 { return nil } - return lp.buildListPartitionValueMapAndSorted(p) + return lp.buildListPartitionValueMapAndSorted(p, defs) } // RebuildPartitionValueMapAndSorted rebuilds list columns partition value map for the specified column. -func (lp *ForListColumnPruning) RebuildPartitionValueMapAndSorted(p *parser.Parser) error { +func (lp *ForListColumnPruning) RebuildPartitionValueMapAndSorted(p *parser.Parser, + defs []model.PartitionDefinition) error { lp.valueMap = make(map[string]ListPartitionLocation, len(lp.valueMap)) lp.sorted.Clear(false) - return lp.buildListPartitionValueMapAndSorted(p) + return lp.buildListPartitionValueMapAndSorted(p, defs) } -func (lp *ForListColumnPruning) buildListPartitionValueMapAndSorted(p *parser.Parser) error { - pi := lp.tblInfo.GetPartitionInfo() +func (lp *ForListColumnPruning) buildListPartitionValueMapAndSorted(p *parser.Parser, defs []model.PartitionDefinition) error { sc := lp.ctx.GetSessionVars().StmtCtx - for partitionIdx, def := range pi.Definitions { + for partitionIdx, def := range defs { for groupIdx, vs := range def.InValues { keyBytes, err := lp.genConstExprKey(lp.ctx, sc, vs[lp.colIdx], lp.schema, lp.names, p) if err != nil { @@ -935,15 +1056,24 @@ func generateHashPartitionExpr(ctx sessionctx.Context, pi *model.PartitionInfo, } // PartitionExpr returns the partition expression. -func (t *partitionedTable) PartitionExpr() (*PartitionExpr, error) { - return t.partitionExpr, nil +func (t *partitionedTable) PartitionExpr() *PartitionExpr { + return t.partitionExpr } -func (t *partitionedTable) GetPartitionColumnNames() []model.CIStr { +func (t *partitionedTable) GetPartitionColumnIDs() []int64 { // PARTITION BY {LIST|RANGE} COLUMNS uses columns directly without expressions pi := t.Meta().Partition if len(pi.Columns) > 0 { - return pi.Columns + colIDs := make([]int64, 0, len(pi.Columns)) + for _, name := range pi.Columns { + col := table.FindColLowerCase(t.Cols(), name.L) + if col == nil { + // For safety, should not happen + continue + } + colIDs = append(colIDs, col.ID) + } + return colIDs } partitionCols := expression.ExtractColumns(t.partitionExpr.Expr) @@ -951,7 +1081,16 @@ func (t *partitionedTable) GetPartitionColumnNames() []model.CIStr { for _, col := range partitionCols { colIDs = append(colIDs, col.ID) } - colNames := make([]model.CIStr, 0, len(partitionCols)) + return colIDs +} + +func (t *partitionedTable) GetPartitionColumnNames() []model.CIStr { + pi := t.Meta().Partition + if len(pi.Columns) > 0 { + return pi.Columns + } + colIDs := t.GetPartitionColumnIDs() + colNames := make([]model.CIStr, 0, len(colIDs)) for _, colID := range colIDs { for _, col := range t.Cols() { if col.ID == colID { @@ -969,7 +1108,7 @@ func PartitionRecordKey(pid int64, handle int64) kv.Key { } func (t *partitionedTable) CheckForExchangePartition(ctx sessionctx.Context, pi *model.PartitionInfo, r []types.Datum, pid int64) error { - defID, err := t.locatePartition(ctx, pi, r) + defID, err := t.locatePartition(ctx, r) if err != nil { return err } @@ -979,36 +1118,59 @@ func (t *partitionedTable) CheckForExchangePartition(ctx sessionctx.Context, pi return nil } -// locatePartition returns the partition ID of the input record. -func (t *partitionedTable) locatePartition(ctx sessionctx.Context, pi *model.PartitionInfo, r []types.Datum) (int64, error) { +// locatePartitionCommon returns the partition idx of the input record. +func (t *partitionedTable) locatePartitionCommon(ctx sessionctx.Context, pi *model.PartitionInfo, partitionExpr *PartitionExpr, r []types.Datum) (int, error) { var err error var idx int switch t.meta.Partition.Type { case model.PartitionTypeRange: if len(pi.Columns) == 0 { - idx, err = t.locateRangePartition(ctx, pi, r) + idx, err = t.locateRangePartition(ctx, partitionExpr, r) } else { - idx, err = t.locateRangeColumnPartition(ctx, pi, r) + idx, err = t.locateRangeColumnPartition(ctx, partitionExpr, r) } case model.PartitionTypeHash: + // Note that only LIST and RANGE supports REORGANIZE PARTITION + // TODO: Add support for ADD PARTITION and COALESCE PARTITION for HASH idx, err = t.locateHashPartition(ctx, pi, r) case model.PartitionTypeList: - idx, err = t.locateListPartition(ctx, pi, r) + idx, err = t.locateListPartition(ctx, partitionExpr, r) } if err != nil { return 0, errors.Trace(err) } + return idx, nil +} + +func (t *partitionedTable) locatePartition(ctx sessionctx.Context, r []types.Datum) (int64, error) { + pi := t.Meta().GetPartitionInfo() + idx, err := t.locatePartitionCommon(ctx, pi, t.partitionExpr, r) + if err != nil { + return 0, errors.Trace(err) + } return pi.Definitions[idx].ID, nil } -func (t *partitionedTable) locateRangeColumnPartition(ctx sessionctx.Context, pi *model.PartitionInfo, r []types.Datum) (int, error) { +func (t *partitionedTable) locateReorgPartition(ctx sessionctx.Context, r []types.Datum) (int64, error) { + pi := t.Meta().GetPartitionInfo() + idx, err := t.locatePartitionCommon(ctx, pi, t.reorgPartitionExpr, r) + if err != nil { + return 0, errors.Trace(err) + } + if pi.DDLState == model.StateDeleteReorganization { + return pi.DroppingDefinitions[idx].ID, nil + } + return pi.AddingDefinitions[idx].ID, nil +} + +func (t *partitionedTable) locateRangeColumnPartition(ctx sessionctx.Context, partitionExpr *PartitionExpr, r []types.Datum) (int, error) { + upperBounds := partitionExpr.UpperBounds var lastError error - partitionExprs := t.partitionExpr.UpperBounds evalBuffer := t.evalBufferPool.Get().(*chunk.MutRow) defer t.evalBufferPool.Put(evalBuffer) - idx := sort.Search(len(partitionExprs), func(i int) bool { + idx := sort.Search(len(upperBounds), func(i int) bool { evalBuffer.SetDatums(r...) - ret, isNull, err := partitionExprs[i].EvalInt(ctx, evalBuffer.ToRow()) + ret, isNull, err := upperBounds[i].EvalInt(ctx, evalBuffer.ToRow()) if err != nil { lastError = err return true // Does not matter, will propagate the last error anyway. @@ -1023,11 +1185,11 @@ func (t *partitionedTable) locateRangeColumnPartition(ctx sessionctx.Context, pi if lastError != nil { return 0, errors.Trace(lastError) } - if idx >= len(partitionExprs) { + if idx >= len(upperBounds) { // The data does not belong to any of the partition returns `table has no partition for value %s`. var valueMsg string - if pi.Expr != "" { - e, err := expression.ParseSimpleExprWithTableInfo(ctx, pi.Expr, t.meta) + if t.meta.Partition.Expr != "" { + e, err := expression.ParseSimpleExprWithTableInfo(ctx, t.meta.Partition.Expr, t.meta) if err == nil { val, _, err := e.EvalInt(ctx, chunk.MutRowFromDatums(r).ToRow()) if err == nil { @@ -1043,15 +1205,15 @@ func (t *partitionedTable) locateRangeColumnPartition(ctx sessionctx.Context, pi return idx, nil } -func (t *partitionedTable) locateListPartition(ctx sessionctx.Context, pi *model.PartitionInfo, r []types.Datum) (int, error) { - lp := t.partitionExpr.ForListPruning +func (t *partitionedTable) locateListPartition(ctx sessionctx.Context, partitionExpr *PartitionExpr, r []types.Datum) (int, error) { + lp := partitionExpr.ForListPruning if len(lp.ColPrunes) == 0 { return lp.locateListPartitionByRow(ctx, r) } return lp.locateListColumnsPartitionByRow(ctx, r) } -func (t *partitionedTable) locateRangePartition(ctx sessionctx.Context, pi *model.PartitionInfo, r []types.Datum) (int, error) { +func (t *partitionedTable) locateRangePartition(ctx sessionctx.Context, partitionExpr *PartitionExpr, r []types.Datum) (int, error) { var ( ret int64 val int64 @@ -1074,7 +1236,7 @@ func (t *partitionedTable) locateRangePartition(ctx sessionctx.Context, pi *mode ret = val } unsigned := mysql.HasUnsignedFlag(t.partitionExpr.Expr.GetType().GetFlag()) - ranges := t.partitionExpr.ForRangePruning + ranges := partitionExpr.ForRangePruning length := len(ranges.LessThan) pos := sort.Search(length, func(i int) bool { if isNull { @@ -1088,8 +1250,8 @@ func (t *partitionedTable) locateRangePartition(ctx sessionctx.Context, pi *mode if pos < 0 || pos >= length { // The data does not belong to any of the partition returns `table has no partition for value %s`. var valueMsg string - if pi.Expr != "" { - e, err := expression.ParseSimpleExprWithTableInfo(ctx, pi.Expr, t.meta) + if t.meta.Partition.Expr != "" { + e, err := expression.ParseSimpleExprWithTableInfo(ctx, t.meta.Partition.Expr, t.meta) if err == nil { val, _, err := e.EvalInt(ctx, chunk.MutRowFromDatums(r).ToRow()) if err == nil { @@ -1147,16 +1309,39 @@ func (t *partitionedTable) locateHashPartition(ctx sessionctx.Context, pi *model func (t *partitionedTable) GetPartition(pid int64) table.PhysicalTable { // Attention, can't simply use `return t.partitions[pid]` here. // Because A nil of type *partition is a kind of `table.PhysicalTable` - p, ok := t.partitions[pid] + part, ok := t.partitions[pid] if !ok { + // Should never happen! return nil } - return p + return part +} + +// GetReorganizedPartitionedTable returns the same table +// but only with the AddingDefinitions used. +func GetReorganizedPartitionedTable(t table.Table) (table.PartitionedTable, error) { + // This is used during Reorganize partitions; All data from DroppingDefinitions + // will be copied to AddingDefinitions, so only setup with AddingDefinitions! + + // Do not change any Definitions of t, but create a new struct. + if t.GetPartitionedTable() == nil { + return nil, dbterror.ErrUnsupportedReorganizePartition.GenWithStackByArgs() + } + tblInfo := t.Meta().Clone() + tblInfo.Partition.Definitions = tblInfo.Partition.AddingDefinitions + tblInfo.Partition.AddingDefinitions = nil + tblInfo.Partition.DroppingDefinitions = nil + var tc TableCommon + initTableCommon(&tc, tblInfo, tblInfo.ID, t.Cols(), t.Allocators(nil)) + + // and rebuild the partitioning structure + + return newPartitionedTable(&tc, tblInfo) } // GetPartitionByRow returns a Table, which is actually a Partition. func (t *partitionedTable) GetPartitionByRow(ctx sessionctx.Context, r []types.Datum) (table.PhysicalTable, error) { - pid, err := t.locatePartition(ctx, t.Meta().GetPartitionInfo(), r) + pid, err := t.locatePartition(ctx, r) if err != nil { return nil, errors.Trace(err) } @@ -1165,7 +1350,7 @@ func (t *partitionedTable) GetPartitionByRow(ctx sessionctx.Context, r []types.D // GetPartitionByRow returns a Table, which is actually a Partition. func (t *partitionTableWithGivenSets) GetPartitionByRow(ctx sessionctx.Context, r []types.Datum) (table.PhysicalTable, error) { - pid, err := t.locatePartition(ctx, t.Meta().GetPartitionInfo(), r) + pid, err := t.locatePartition(ctx, r) if err != nil { return nil, errors.Trace(err) } @@ -1181,8 +1366,7 @@ func (t *partitionedTable) AddRecord(ctx sessionctx.Context, r []types.Datum, op } func partitionedTableAddRecord(ctx sessionctx.Context, t *partitionedTable, r []types.Datum, partitionSelection map[int64]struct{}, opts []table.AddRecordOption) (recordID kv.Handle, err error) { - partitionInfo := t.meta.GetPartitionInfo() - pid, err := t.locatePartition(ctx, partitionInfo, r) + pid, err := t.locatePartition(ctx, r) if err != nil { return nil, errors.Trace(err) } @@ -1193,7 +1377,23 @@ func partitionedTableAddRecord(ctx sessionctx.Context, t *partitionedTable, r [] } } tbl := t.GetPartition(pid) - return tbl.AddRecord(ctx, r, opts...) + recordID, err = tbl.AddRecord(ctx, r, opts...) + if err != nil { + return + } + if _, ok := t.reorganizePartitions[pid]; ok { + // Double write to the ongoing reorganized partition + pid, err = t.locateReorgPartition(ctx, r) + if err != nil { + return nil, errors.Trace(err) + } + tbl = t.GetPartition(pid) + recordID, err = tbl.AddRecord(ctx, r, opts...) + if err != nil { + return + } + } + return } // partitionTableWithGivenSets is used for this kind of grammar: partition (p0,p1) @@ -1230,19 +1430,37 @@ func (t *partitionTableWithGivenSets) GetAllPartitionIDs() []int64 { // RemoveRecord implements table.Table RemoveRecord interface. func (t *partitionedTable) RemoveRecord(ctx sessionctx.Context, h kv.Handle, r []types.Datum) error { - partitionInfo := t.meta.GetPartitionInfo() - pid, err := t.locatePartition(ctx, partitionInfo, r) + pid, err := t.locatePartition(ctx, r) if err != nil { return errors.Trace(err) } tbl := t.GetPartition(pid) - return tbl.RemoveRecord(ctx, h, r) + err = tbl.RemoveRecord(ctx, h, r) + if err != nil { + return errors.Trace(err) + } + + if _, ok := t.reorganizePartitions[pid]; ok { + pid, err = t.locateReorgPartition(ctx, r) + if err != nil { + return errors.Trace(err) + } + tbl = t.GetPartition(pid) + err = tbl.RemoveRecord(ctx, h, r) + if err != nil { + return errors.Trace(err) + } + } + return nil } func (t *partitionedTable) GetAllPartitionIDs() []int64 { ptIDs := make([]int64, 0, len(t.partitions)) for id := range t.partitions { + if _, ok := t.doubleWritePartitions[id]; ok { + continue + } ptIDs = append(ptIDs, id) } return ptIDs @@ -1260,12 +1478,11 @@ func (t *partitionTableWithGivenSets) UpdateRecord(ctx context.Context, sctx ses } func partitionedTableUpdateRecord(gctx context.Context, ctx sessionctx.Context, t *partitionedTable, h kv.Handle, currData, newData []types.Datum, touched []bool, partitionSelection map[int64]struct{}) error { - partitionInfo := t.meta.GetPartitionInfo() - from, err := t.locatePartition(ctx, partitionInfo, currData) + from, err := t.locatePartition(ctx, currData) if err != nil { return errors.Trace(err) } - to, err := t.locatePartition(ctx, partitionInfo, newData) + to, err := t.locatePartition(ctx, newData) if err != nil { return errors.Trace(err) } @@ -1292,16 +1509,100 @@ func partitionedTableUpdateRecord(gctx context.Context, ctx sessionctx.Context, // So this special order is chosen: add record first, errors such as // 'Key Already Exists' will generally happen during step1, errors are // unlikely to happen in step2. + // TODO: check what happens with foreign keys in step 2? err = t.GetPartition(from).RemoveRecord(ctx, h, currData) if err != nil { + // TODO, test this!! I assume that we need to clean this up, + // since there are non-atomic changes in the transaction buffer + // which if committed will cause inconsistencies? + // What to do if something during the cleanup fails? Can we block + // the transaction from ever being committed? logutil.BgLogger().Error("update partition record fails", zap.String("message", "new record inserted while old record is not removed"), zap.Error(err)) return errors.Trace(err) } + // TODO: Test if the update is in different partitions before reorg, + // but is now in the same during the reorg? And vice-versa... + // What if the change is in the same reorged partition?!? + newTo, newFrom := int64(0), int64(0) + if _, ok := t.reorganizePartitions[to]; ok { + newTo, err = t.locateReorgPartition(ctx, newData) + // There might be valid cases when errors should be accepted? + if err != nil { + return errors.Trace(err) + } + } + if _, ok := t.reorganizePartitions[from]; ok { + newFrom, err = t.locateReorgPartition(ctx, currData) + // There might be valid cases when errors should be accepted? + if err != nil { + return errors.Trace(err) + } + } + if newTo == newFrom && newTo != 0 { + // Update needs to be done in StateDeleteOnly as well + tbl := t.GetPartition(newTo) + return tbl.UpdateRecord(gctx, ctx, h, currData, newData, touched) + } + if newTo != 0 && t.Meta().GetPartitionInfo().DDLState != model.StateDeleteOnly { + tbl := t.GetPartition(newTo) + _, err = tbl.AddRecord(ctx, newData) + if err != nil { + return errors.Trace(err) + } + } + if newFrom != 0 { + tbl := t.GetPartition(newFrom) + err = tbl.RemoveRecord(ctx, h, currData) + // How to handle error, which can happen when the data is not yet backfilled + // TODO: Create a test for this!!! + if err != nil { + return errors.Trace(err) + } + } return nil } - tbl := t.GetPartition(to) - return tbl.UpdateRecord(gctx, ctx, h, currData, newData, touched) + err = tbl.UpdateRecord(gctx, ctx, h, currData, newData, touched) + if err != nil { + return errors.Trace(err) + } + if _, ok := t.reorganizePartitions[to]; ok { + // Even if to == from, in the reorganized partitions they may differ + // like in case of a split + newTo, err := t.locateReorgPartition(ctx, newData) + if err != nil { + return errors.Trace(err) + } + newFrom, err := t.locateReorgPartition(ctx, currData) + if err != nil { + return errors.Trace(err) + } + if newTo == newFrom { + // Update needs to be done in StateDeleteOnly as well + tbl = t.GetPartition(newTo) + err = tbl.UpdateRecord(gctx, ctx, h, currData, newData, touched) + if err != nil { + return errors.Trace(err) + } + return nil + } + if t.Meta().GetPartitionInfo().DDLState != model.StateDeleteOnly { + tbl = t.GetPartition(newTo) + _, err = tbl.AddRecord(ctx, newData) + // TODO: Could there be a case where a duplicate unique key could happen here? + if err != nil { + return errors.Trace(err) + } + } + tbl = t.GetPartition(newFrom) + err = tbl.RemoveRecord(ctx, h, currData) + // How to handle error, which can happen when the data is not yet backfilled + // TODO: Create a test for this!!! + if err != nil { + return errors.Trace(err) + } + } + return nil } // FindPartitionByName finds partition in table meta by name. diff --git a/table/tables/partition_test.go b/table/tables/partition_test.go index cc8dd90a44737..0bac493aa7f35 100644 --- a/table/tables/partition_test.go +++ b/table/tables/partition_test.go @@ -273,10 +273,9 @@ func TestGeneratePartitionExpr(t *testing.T) { tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) require.NoError(t, err) type partitionExpr interface { - PartitionExpr() (*tables.PartitionExpr, error) + PartitionExpr() *tables.PartitionExpr } - pe, err := tbl.(partitionExpr).PartitionExpr() - require.NoError(t, err) + pe := tbl.(partitionExpr).PartitionExpr() upperBounds := []string{ "lt(t1.id, 4)", diff --git a/table/tables/tables.go b/table/tables/tables.go index 05724a67fa311..b478478d2c087 100644 --- a/table/tables/tables.go +++ b/table/tables/tables.go @@ -20,6 +20,7 @@ package tables import ( "context" + "fmt" "math" "strconv" "strings" @@ -56,6 +57,7 @@ import ( // TableCommon is shared by both Table and partition. type TableCommon struct { + // TODO: Why do we need tableID, when it is already in meta.ID ? tableID int64 // physicalTableID is a unique int64 to identify a physical table. physicalTableID int64 @@ -84,7 +86,7 @@ func MockTableFromMeta(tblInfo *model.TableInfo) table.Table { } var t TableCommon - initTableCommon(&t, tblInfo, tblInfo.ID, columns, nil) + initTableCommon(&t, tblInfo, tblInfo.ID, columns, autoid.NewAllocators(false)) if tblInfo.TableCacheStatusType != model.TableCacheStatusDisable { ret, err := newCachedTable(&t) if err != nil { @@ -234,6 +236,11 @@ func (t *TableCommon) GetPhysicalID() int64 { return t.physicalTableID } +// GetPartitionedTable implements table.Table GetPhysicalID interface. +func (t *TableCommon) GetPartitionedTable() table.PartitionedTable { + return nil +} + type getColsMode int64 const ( @@ -525,7 +532,12 @@ func (t *TableCommon) rebuildIndices(ctx sessionctx.Context, txn kv.Transaction, break } // If txn is auto commit and index is untouched, no need to write index value. - if untouched && !ctx.GetSessionVars().InTxn() { + // If InHandleForeignKeyTrigger or ForeignKeyTriggerCtx.HasFKCascades is true indicate we may have + // foreign key cascade need to handle later, then we still need to write index value, + // otherwise, the later foreign cascade executor may see data-index inconsistency in txn-mem-buffer. + sessVars := ctx.GetSessionVars() + if untouched && !sessVars.InTxn() && + !sessVars.StmtCtx.InHandleForeignKeyTrigger && !sessVars.StmtCtx.ForeignKeyTriggerCtx.HasFKCascades { continue } newVs, err := idx.FetchValues(newData, nil) @@ -845,7 +857,7 @@ func (t *TableCommon) AddRecord(sctx sessionctx.Context, r []types.Datum, opts . } if err == nil { handleStr := getDuplicateErrorHandleString(t, recordID, r) - return recordID, kv.ErrKeyExists.FastGenByArgs(handleStr, "PRIMARY") + return recordID, kv.ErrKeyExists.FastGenByArgs(handleStr, t.Meta().Name.String()+".PRIMARY") } else if !kv.ErrNotExist.Equal(err) { return recordID, err } @@ -853,7 +865,8 @@ func (t *TableCommon) AddRecord(sctx sessionctx.Context, r []types.Datum, opts . if setPresume { flags := []kv.FlagsOp{kv.SetPresumeKeyNotExists} - if !sessVars.ConstraintCheckInPlacePessimistic && sessVars.TxnCtx.IsPessimistic && sessVars.InTxn() { + if !sessVars.ConstraintCheckInPlacePessimistic && sessVars.TxnCtx.IsPessimistic && sessVars.InTxn() && + !sessVars.InRestrictedSQL && sessVars.ConnectionID > 0 { flags = append(flags, kv.SetNeedConstraintCheckInPrewrite) } err = memBuffer.SetWithFlags(key, value, flags...) @@ -974,10 +987,9 @@ func (t *TableCommon) addIndices(sctx sessionctx.Context, recordID kv.Handle, r if err != nil { return nil, err } - idxMeta := v.Meta() - dupErr = kv.ErrKeyExists.FastGenByArgs(entryKey, idxMeta.Name.String()) + dupErr = kv.ErrKeyExists.FastGenByArgs(entryKey, fmt.Sprintf("%s.%s", v.TableMeta().Name.String(), v.Meta().Name.String())) } - rsData := TryGetHandleRestoredDataWrapper(t, r, nil, v.Meta()) + rsData := TryGetHandleRestoredDataWrapper(t.meta, r, nil, v.Meta()) if dupHandle, err := v.Create(sctx, txn, indexVals, recordID, rsData, opts...); err != nil { if kv.ErrKeyExists.Equal(err) { return dupHandle, dupErr @@ -1298,9 +1310,32 @@ func (t *TableCommon) removeRowData(ctx sessionctx.Context, h kv.Handle) error { } } }) - err = txn.SetAssertion(key, kv.SetAssertExist) - if err != nil { - return err + doAssert := true + p := t.Meta().Partition + if p != nil { + // This disables asserting during Reorganize Partition. + switch ctx.GetSessionVars().AssertionLevel { + case variable.AssertionLevelFast: + // Fast option, just skip assertion for all partitions. + if p.DDLState != model.StateNone && p.DDLState != model.StatePublic { + doAssert = false + } + case variable.AssertionLevelStrict: + // Strict, only disable assertion for intermediate partitions. + // If there were an easy way to get from a TableCommon back to the partitioned table... + for i := range p.AddingDefinitions { + if t.physicalTableID == p.AddingDefinitions[i].ID { + doAssert = false + break + } + } + } + } + if doAssert { + err = txn.SetAssertion(key, kv.SetAssertExist) + if err != nil { + return err + } } return txn.Delete(key) } @@ -1345,7 +1380,7 @@ func (t *TableCommon) buildIndexForRow(ctx sessionctx.Context, h kv.Handle, vals if untouched { opts = append(opts, table.IndexIsUntouched) } - rsData := TryGetHandleRestoredDataWrapper(t, newData, nil, idx.Meta()) + rsData := TryGetHandleRestoredDataWrapper(t.meta, newData, nil, idx.Meta()) if _, err := idx.Create(ctx, txn, vals, h, rsData, opts...); err != nil { if kv.ErrKeyExists.Equal(err) { // Make error message consistent with MySQL. @@ -1355,7 +1390,7 @@ func (t *TableCommon) buildIndexForRow(ctx sessionctx.Context, h kv.Handle, vals return err } - return kv.ErrKeyExists.FastGenByArgs(entryKey, idx.Meta().Name) + return kv.ErrKeyExists.FastGenByArgs(entryKey, fmt.Sprintf("%s.%s", idx.TableMeta().Name.String(), idx.Meta().Name.String())) } return err } @@ -1515,8 +1550,7 @@ func allocHandleIDs(ctx context.Context, sctx sessionctx.Context, t table.Table, // shard = 0010000000000000000000000000000000000000000000000000000000000000 return 0, 0, autoid.ErrAutoincReadFailed } - txnCtx := sctx.GetSessionVars().TxnCtx - shard := txnCtx.GetCurrentShard(int(n)) + shard := sctx.GetSessionVars().GetCurrentShard(int(n)) base = shardFmt.Compose(shard, base) maxID = shardFmt.Compose(shard, maxID) } @@ -1541,7 +1575,7 @@ func (t *TableCommon) Allocators(ctx sessionctx.Context) autoid.Allocators { // Use an independent allocator for global temporary tables. if t.meta.TempTableType == model.TempTableGlobal { if alloc := ctx.GetSessionVars().GetTemporaryTable(t.meta).GetAutoIDAllocator(); alloc != nil { - return autoid.Allocators{alloc} + return autoid.NewAllocators(false, alloc) } // If the session is not in a txn, for example, in "show create table", use the original allocator. // Otherwise the would be a nil pointer dereference. @@ -1551,8 +1585,9 @@ func (t *TableCommon) Allocators(ctx sessionctx.Context) autoid.Allocators { // Replace the row id allocator with the one in session variables. sessAlloc := ctx.GetSessionVars().IDAllocator - retAllocs := make([]autoid.Allocator, 0, len(t.allocs)) - copy(retAllocs, t.allocs) + allocs := t.allocs.Allocs + retAllocs := make([]autoid.Allocator, 0, len(allocs)) + copy(retAllocs, allocs) overwritten := false for i, a := range retAllocs { @@ -1565,7 +1600,7 @@ func (t *TableCommon) Allocators(ctx sessionctx.Context) autoid.Allocators { if !overwritten { retAllocs = append(retAllocs, sessAlloc) } - return retAllocs + return autoid.NewAllocators(t.allocs.SepAutoInc, retAllocs...) } // Type implements table.Table Type interface. @@ -1866,14 +1901,14 @@ func (t *TableCommon) GetSequenceCommon() *sequenceCommon { } // TryGetHandleRestoredDataWrapper tries to get the restored data for handle if needed. The argument can be a slice or a map. -func TryGetHandleRestoredDataWrapper(t table.Table, row []types.Datum, rowMap map[int64]types.Datum, idx *model.IndexInfo) []types.Datum { - if !collate.NewCollationEnabled() || !t.Meta().IsCommonHandle || t.Meta().CommonHandleVersion == 0 { +func TryGetHandleRestoredDataWrapper(tblInfo *model.TableInfo, row []types.Datum, rowMap map[int64]types.Datum, idx *model.IndexInfo) []types.Datum { + if !collate.NewCollationEnabled() || !tblInfo.IsCommonHandle || tblInfo.CommonHandleVersion == 0 { return nil } rsData := make([]types.Datum, 0, 4) - pkIdx := FindPrimaryIndex(t.Meta()) + pkIdx := FindPrimaryIndex(tblInfo) for _, pkIdxCol := range pkIdx.Columns { - pkCol := t.Meta().Columns[pkIdxCol.Offset] + pkCol := tblInfo.Columns[pkIdxCol.Offset] if !types.NeedRestoredData(&pkCol.FieldType) { continue } @@ -1883,28 +1918,37 @@ func TryGetHandleRestoredDataWrapper(t table.Table, row []types.Datum, rowMap ma } else { datum = row[pkCol.Offset] } - // Try to truncate index values. - // Says that primary key(a (8)), - // For index t(a), don't truncate the value. - // For index t(a(9)), truncate to a(9). - // For index t(a(7)), truncate to a(8). - truncateTargetCol := pkIdxCol - for _, idxCol := range idx.Columns { - if idxCol.Offset == pkCol.Offset { - truncateTargetCol = maxIndexLen(pkIdxCol, idxCol) - break - } - } - tablecodec.TruncateIndexValue(&datum, truncateTargetCol, pkCol) - if collate.IsBinCollation(pkCol.GetCollate()) { - rsData = append(rsData, types.NewIntDatum(stringutil.GetTailSpaceCount(datum.GetString()))) - } else { - rsData = append(rsData, datum) - } + TryTruncateRestoredData(&datum, pkCol, pkIdxCol, idx) + ConvertDatumToTailSpaceCount(&datum, pkCol) + rsData = append(rsData, datum) } return rsData } +// TryTruncateRestoredData tries to truncate index values. +// Says that primary key(a (8)), +// For index t(a), don't truncate the value. +// For index t(a(9)), truncate to a(9). +// For index t(a(7)), truncate to a(8). +func TryTruncateRestoredData(datum *types.Datum, pkCol *model.ColumnInfo, + pkIdxCol *model.IndexColumn, idx *model.IndexInfo) { + truncateTargetCol := pkIdxCol + for _, idxCol := range idx.Columns { + if idxCol.Offset == pkIdxCol.Offset { + truncateTargetCol = maxIndexLen(pkIdxCol, idxCol) + break + } + } + tablecodec.TruncateIndexValue(datum, truncateTargetCol, pkCol) +} + +// ConvertDatumToTailSpaceCount converts a string datum to an int datum that represents the tail space count. +func ConvertDatumToTailSpaceCount(datum *types.Datum, col *model.ColumnInfo) { + if collate.IsBinCollation(col.GetCollate()) { + *datum = types.NewIntDatum(stringutil.GetTailSpaceCount(datum.GetString())) + } +} + func maxIndexLen(idxA, idxB *model.IndexColumn) *model.IndexColumn { if idxA.Length == types.UnspecifiedLength { return idxA @@ -1919,7 +1963,7 @@ func maxIndexLen(idxA, idxB *model.IndexColumn) *model.IndexColumn { } func getSequenceAllocator(allocs autoid.Allocators) (autoid.Allocator, error) { - for _, alloc := range allocs { + for _, alloc := range allocs.Allocs { if alloc.GetType() == autoid.SequenceType { return alloc, nil } @@ -1933,7 +1977,7 @@ func BuildTableScanFromInfos(tableInfo *model.TableInfo, columnInfos []*model.Co pkColIds := TryGetCommonPkColumnIds(tableInfo) tsExec := &tipb.TableScan{ TableId: tableInfo.ID, - Columns: util.ColumnsToProto(columnInfos, tableInfo.PKIsHandle), + Columns: util.ColumnsToProto(columnInfos, tableInfo.PKIsHandle, false), PrimaryColumnIds: pkColIds, } if tableInfo.IsCommonHandle { @@ -1947,7 +1991,7 @@ func BuildPartitionTableScanFromInfos(tableInfo *model.TableInfo, columnInfos [] pkColIds := TryGetCommonPkColumnIds(tableInfo) tsExec := &tipb.PartitionTableScan{ TableId: tableInfo.ID, - Columns: util.ColumnsToProto(columnInfos, tableInfo.PKIsHandle), + Columns: util.ColumnsToProto(columnInfos, tableInfo.PKIsHandle, false), PrimaryColumnIds: pkColIds, IsFastScan: &fastScan, } @@ -1957,6 +2001,35 @@ func BuildPartitionTableScanFromInfos(tableInfo *model.TableInfo, columnInfos [] return tsExec } +// SetPBColumnsDefaultValue sets the default values of tipb.ColumnInfo. +func SetPBColumnsDefaultValue(ctx sessionctx.Context, pbColumns []*tipb.ColumnInfo, columns []*model.ColumnInfo) error { + for i, c := range columns { + // For virtual columns, we set their default values to NULL so that TiKV will return NULL properly, + // They real values will be computed later. + if c.IsGenerated() && !c.GeneratedStored { + pbColumns[i].DefaultVal = []byte{codec.NilFlag} + } + if c.GetOriginDefaultValue() == nil { + continue + } + + sessVars := ctx.GetSessionVars() + originStrict := sessVars.StrictSQLMode + sessVars.StrictSQLMode = false + d, err := table.GetColOriginDefaultValue(ctx, c) + sessVars.StrictSQLMode = originStrict + if err != nil { + return err + } + + pbColumns[i].DefaultVal, err = tablecodec.EncodeValue(sessVars.StmtCtx, nil, d) + if err != nil { + return err + } + } + return nil +} + // TemporaryTable is used to store transaction-specific or session-specific information for global / local temporary tables. // For example, stats and autoID should have their own copies of data, instead of being shared by all sessions. type TemporaryTable struct { diff --git a/table/tables/tables_test.go b/table/tables/tables_test.go index 22551620ed538..46981958fbeb5 100644 --- a/table/tables/tables_test.go +++ b/table/tables/tables_test.go @@ -333,7 +333,7 @@ func TestUnsignedPK(t *testing.T) { require.NoError(t, err) require.Equal(t, 2, len(row)) require.Equal(t, types.KindUint64, row[0].Kind()) - tk.Session().StmtCommit() + tk.Session().StmtCommit(context.Background()) txn, err := tk.Session().Txn(true) require.NoError(t, err) require.Nil(t, txn.Commit(context.Background())) @@ -378,18 +378,18 @@ func TestTableFromMeta(t *testing.T) { // For test coverage tbInfo.Columns[0].GeneratedExprString = "a" - _, err = tables.TableFromMeta(nil, tbInfo) + _, err = tables.TableFromMeta(autoid.NewAllocators(false), tbInfo) require.NoError(t, err) tbInfo.Columns[0].GeneratedExprString = "test" - _, err = tables.TableFromMeta(nil, tbInfo) + _, err = tables.TableFromMeta(autoid.NewAllocators(false), tbInfo) require.Error(t, err) tbInfo.Columns[0].State = model.StateNone - tb, err = tables.TableFromMeta(nil, tbInfo) + tb, err = tables.TableFromMeta(autoid.NewAllocators(false), tbInfo) require.Nil(t, tb) require.Error(t, err) tbInfo.State = model.StateNone - tb, err = tables.TableFromMeta(nil, tbInfo) + tb, err = tables.TableFromMeta(autoid.NewAllocators(false), tbInfo) require.Nil(t, tb) require.Error(t, err) @@ -639,7 +639,7 @@ func TestAddRecordWithCtx(t *testing.T) { require.NoError(t, err) require.Equal(t, len(records), i) - tk.Session().StmtCommit() + tk.Session().StmtCommit(context.Background()) txn, err := tk.Session().Txn(true) require.NoError(t, err) require.Nil(t, txn.Commit(context.Background())) @@ -656,7 +656,7 @@ func TestConstraintCheckForUniqueIndex(t *testing.T) { tk.MustExec("insert into ttt(k,c) values(1, 'tidb')") tk.MustExec("insert into ttt(k,c) values(2, 'tidb')") _, err := tk.Exec("update ttt set k=1 where id=2") - require.Equal(t, "[kv:1062]Duplicate entry '1-tidb' for key 'k_1'", err.Error()) + require.Equal(t, "[kv:1062]Duplicate entry '1-tidb' for key 'ttt.k_1'", err.Error()) tk.MustExec("rollback") // no auto-commit @@ -664,13 +664,13 @@ func TestConstraintCheckForUniqueIndex(t *testing.T) { tk.MustExec("set @@tidb_constraint_check_in_place = 0") tk.MustExec("begin") _, err = tk.Exec("update ttt set k=1 where id=2") - require.Equal(t, "[kv:1062]Duplicate entry '1-tidb' for key 'k_1'", err.Error()) + require.Equal(t, "[kv:1062]Duplicate entry '1-tidb' for key 'ttt.k_1'", err.Error()) tk.MustExec("rollback") tk.MustExec("set @@tidb_constraint_check_in_place = 1") tk.MustExec("begin") _, err = tk.Exec("update ttt set k=1 where id=2") - require.Equal(t, "[kv:1062]Duplicate entry '1-tidb' for key 'k_1'", err.Error()) + require.Equal(t, "[kv:1062]Duplicate entry '1-tidb' for key 'ttt.k_1'", err.Error()) tk.MustExec("rollback") // This test check that with @@tidb_constraint_check_in_place = 0, although there is not KV request for the unique index, the pessimistic lock should still be written. diff --git a/table/temptable/BUILD.bazel b/table/temptable/BUILD.bazel index 30c41bd1c55b3..8487a26533b51 100644 --- a/table/temptable/BUILD.bazel +++ b/table/temptable/BUILD.bazel @@ -41,6 +41,7 @@ go_test( deps = [ "//infoschema", "//kv", + "//meta/autoid", "//parser/model", "//parser/mysql", "//sessionctx", diff --git a/table/temptable/ddl.go b/table/temptable/ddl.go index ccad2b7b0214c..d464cb3c48618 100644 --- a/table/temptable/ddl.go +++ b/table/temptable/ddl.go @@ -182,7 +182,7 @@ func newTemporaryTableFromTableInfo(sctx sessionctx.Context, tbInfo *model.Table if alloc != nil { allocs = append(allocs, alloc) } - return tables.TableFromMeta(allocs, tbInfo) + return tables.TableFromMeta(autoid.NewAllocators(false, allocs...), tbInfo) } // GetTemporaryTableDDL gets the temptable.TemporaryTableDDL from session context diff --git a/table/temptable/main_test.go b/table/temptable/main_test.go index 7ee3919b08f60..8c5c4f557e1ae 100644 --- a/table/temptable/main_test.go +++ b/table/temptable/main_test.go @@ -22,6 +22,7 @@ import ( "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/table" @@ -38,6 +39,7 @@ func TestMain(m *testing.M) { goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), } testsetup.SetupForCommonTest() goleak.VerifyTestMain(m, opts...) @@ -85,7 +87,7 @@ func (is *mockedInfoSchema) TableByID(tblID int64) (table.Table, bool) { State: model.StatePublic, } - tbl, err := table.TableFromMeta(nil, tblInfo) + tbl, err := table.TableFromMeta(autoid.NewAllocators(false), tblInfo) require.NoError(is.t, err) return tbl, true diff --git a/tablecodec/main_test.go b/tablecodec/main_test.go index ded843a887c9c..5024acdb32bdf 100644 --- a/tablecodec/main_test.go +++ b/tablecodec/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/tablecodec/rowindexcodec/main_test.go b/tablecodec/rowindexcodec/main_test.go index fed13e1f46a21..11b7963a4bd14 100644 --- a/tablecodec/rowindexcodec/main_test.go +++ b/tablecodec/rowindexcodec/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/tablecodec/tablecodec.go b/tablecodec/tablecodec.go index b9400b0271d41..b3726a414fa26 100644 --- a/tablecodec/tablecodec.go +++ b/tablecodec/tablecodec.go @@ -209,6 +209,15 @@ func EncodeMetaKey(key []byte, field []byte) kv.Key { return ek } +// EncodeMetaKeyPrefix encodes the key prefix into meta key +func EncodeMetaKeyPrefix(key []byte) kv.Key { + ek := make([]byte, 0, len(metaPrefix)+codec.EncodedBytesLength(len(key))+8) + ek = append(ek, metaPrefix...) + ek = codec.EncodeBytes(ek, key) + ek = codec.EncodeUint(ek, uint64(structure.HashData)) + return ek +} + // DecodeMetaKey decodes the key and get the meta key and meta field. func DecodeMetaKey(ek kv.Key) (key []byte, field []byte, err error) { var tp uint64 @@ -1143,6 +1152,114 @@ func TempIndexKey2IndexKey(originIdxID int64, tempIdxKey []byte) { binary.BigEndian.PutUint64(tempIdxKey[prefixLen:], eid) } +// IsTempIndexKey check whether the input key is for a temp index. +func IsTempIndexKey(indexKey []byte) bool { + var ( + indexIDKey []byte + indexID int64 + tempIndexID int64 + ) + // Get encoded indexID from key, Add uint64 8 byte length. + indexIDKey = indexKey[prefixLen : prefixLen+8] + indexID = codec.DecodeCmpUintToInt(binary.BigEndian.Uint64(indexIDKey)) + tempIndexID = int64(TempIndexPrefix) | indexID + return tempIndexID == indexID +} + +// TempIndexValueFlag is the flag of temporary index value. +type TempIndexValueFlag byte + +const ( + // TempIndexValueFlagNormal means the following value is the normal index value. + TempIndexValueFlagNormal TempIndexValueFlag = iota + // TempIndexValueFlagDeleted means this is a representation of a "delete" operation. + TempIndexValueFlagDeleted +) + +// EncodeTempIndexValue encodes the value of temporary index. +// Note: this function changes the input value. +func EncodeTempIndexValue(value []byte, keyVer byte) []byte { + value = append(value, 0) + copy(value[1:], value[:len(value)-1]) + value[0] = byte(TempIndexValueFlagNormal) // normal flag + value + tempKeyVer + value = append(value, keyVer) + return value +} + +// EncodeTempIndexValueDeletedUnique encodes the value of temporary index for unique index. +func EncodeTempIndexValueDeletedUnique(handle kv.Handle, keyVer byte) []byte { + var hEncoded []byte + var hLen int + if handle.IsInt() { + var data [8]byte + binary.BigEndian.PutUint64(data[:], uint64(handle.IntValue())) + hEncoded = data[:] + hLen = 8 + } else { + hEncoded = handle.Encoded() + hLen = len(hEncoded) + } + val := make([]byte, 0, 1+hLen+1) // deleted flag + handle + tempKeyVer + val = append(val, byte(TempIndexValueFlagDeleted)) + val = append(val, hEncoded...) + val = append(val, keyVer) + return val +} + +// EncodeTempIndexValueDeleted encodes the delete operation on origin index to a value for temporary index. +func EncodeTempIndexValueDeleted(keyVer byte) []byte { + // Handle is not needed because it is already in the key. + val := make([]byte, 0, 2) // deleted flag + tempKeyVer + val = append(val, byte(TempIndexValueFlagDeleted)) + val = append(val, keyVer) + return val +} + +// DecodeTempIndexValue decodes the value of temporary index. +func DecodeTempIndexValue(value []byte, isCommonHandle bool) (originVal []byte, handle kv.Handle, isDelete bool, isUnique bool, keyVer byte) { + if len(value) == 0 { + return nil, nil, false, false, 0 + } + switch TempIndexValueFlag(value[0]) { + case TempIndexValueFlagNormal: + originVal = value[1 : len(value)-1] + keyVer = value[len(value)-1] + case TempIndexValueFlagDeleted: + isDelete = true + if len(value) == 2 { + keyVer = value[1] + } else { + isUnique = true + if isCommonHandle { + handle, _ = kv.NewCommonHandle(value[1 : len(value)-1]) + } else { + handle = decodeIntHandleInIndexValue(value[1 : len(value)-1]) + } + keyVer = value[len(value)-1] + } + } + return +} + +// CheckTempIndexValueIsDelete checks whether the value is a delete operation. +func CheckTempIndexValueIsDelete(value []byte) bool { + if len(value) == 0 { + return false + } + return TempIndexValueFlag(value[0]) == TempIndexValueFlagDeleted +} + +// DecodeTempIndexOriginValue decodes the value of origin index from a temp index value. +func DecodeTempIndexOriginValue(value []byte) []byte { + if len(value) == 0 { + return nil + } + if TempIndexValueFlag(value[0]) == TempIndexValueFlagNormal { + return value[1 : len(value)-1] + } + return nil +} + // GenIndexValuePortal is the portal for generating index value. // Value layout: // @@ -1613,3 +1730,30 @@ func IndexKVIsUnique(value []byte) bool { segs := SplitIndexValue(value) return segs.IntHandle != nil || segs.CommonHandle != nil } + +// VerifyTableIDForRanges verifies that all given ranges are valid to decode the table id. +func VerifyTableIDForRanges(keyRanges *kv.KeyRanges) ([]int64, error) { + tids := make([]int64, 0, keyRanges.PartitionNum()) + collectFunc := func(ranges []kv.KeyRange, _ []int) error { + if len(ranges) == 0 { + return nil + } + tid := DecodeTableID(ranges[0].StartKey) + if tid <= 0 { + return errors.New("Incorrect keyRange is constrcuted") + } + tids = append(tids, tid) + for i := 1; i < len(ranges); i++ { + tmpTID := DecodeTableID(ranges[i].StartKey) + if tmpTID <= 0 { + return errors.New("Incorrect keyRange is constrcuted") + } + if tid != tmpTID { + return errors.Errorf("Using multi partition's ranges as single table's") + } + } + return nil + } + err := keyRanges.ForEachPartitionWithErr(collectFunc) + return tids, err +} diff --git a/tablecodec/tablecodec_test.go b/tablecodec/tablecodec_test.go index 6632aaf2c1727..231d58cf18bd3 100644 --- a/tablecodec/tablecodec_test.go +++ b/tablecodec/tablecodec_test.go @@ -610,3 +610,33 @@ func TestTempIndexKey(t *testing.T) { require.Equal(t, tid, tableID) require.Equal(t, indexID, iid) } + +func TestTempIndexValueCodec(t *testing.T) { + // Test encode temp index value. + encodedValue, err := codec.EncodeValue(&stmtctx.StatementContext{TimeZone: time.UTC}, nil, types.NewIntDatum(1)) + require.NoError(t, err) + encodedValueCopy := make([]byte, len(encodedValue)) + copy(encodedValueCopy, encodedValue) + tempIdxVal := EncodeTempIndexValue(encodedValue, 'b') + originVal, handle, isDelete, unique, keyVer := DecodeTempIndexValue(tempIdxVal, false) + require.Nil(t, handle) + require.False(t, isDelete || unique) + require.Equal(t, keyVer, byte('b')) + require.EqualValues(t, encodedValueCopy, originVal) + + tempIdxVal = EncodeTempIndexValueDeletedUnique(kv.IntHandle(100), 'm') + originVal, handle, isDelete, unique, keyVer = DecodeTempIndexValue(tempIdxVal, false) + require.Equal(t, handle.IntValue(), int64(100)) + require.True(t, isDelete) + require.True(t, unique) + require.Equal(t, keyVer, byte('m')) + require.Empty(t, originVal) + + tempIdxVal = EncodeTempIndexValueDeleted('b') + originVal, handle, isDelete, unique, keyVer = DecodeTempIndexValue(tempIdxVal, false) + require.Nil(t, handle) + require.True(t, isDelete) + require.False(t, unique) + require.Equal(t, keyVer, byte('b')) + require.Empty(t, originVal) +} diff --git a/telemetry/BUILD.bazel b/telemetry/BUILD.bazel index 7f11bd1a0289c..1f032aa3f237a 100644 --- a/telemetry/BUILD.bazel +++ b/telemetry/BUILD.bazel @@ -29,6 +29,7 @@ go_library( "//sessionctx", "//sessionctx/variable", "//util/logutil", + "//util/memory", "//util/sqlexec", "@com_github_google_uuid//:uuid", "@com_github_iancoleman_strcase//:strcase", @@ -60,6 +61,7 @@ go_test( embed = [":telemetry"], flaky = True, deps = [ + "//autoid_service", "//config", "//ddl", "//domain", diff --git a/telemetry/cte_test/cte_test.go b/telemetry/cte_test/cte_test.go index 32eed83e8df33..fac26ddb2f403 100644 --- a/telemetry/cte_test/cte_test.go +++ b/telemetry/cte_test/cte_test.go @@ -39,6 +39,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), } goleak.VerifyTestMain(m, opts...) diff --git a/telemetry/data_feature_usage.go b/telemetry/data_feature_usage.go index f50b5ab02c2bb..81bf7a9785a3a 100644 --- a/telemetry/data_feature_usage.go +++ b/telemetry/data_feature_usage.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/sqlexec" "github.com/tikv/client-go/v2/metrics" ) @@ -38,23 +39,27 @@ type featureUsage struct { Txn *TxnUsage `json:"txn"` // cluster index usage information // key is the first 6 characters of sha2(TABLE_NAME, 256) - ClusterIndex *ClusterIndexUsage `json:"clusterIndex"` - NewClusterIndex *NewClusterIndexUsage `json:"newClusterIndex"` - TemporaryTable bool `json:"temporaryTable"` - CTE *m.CTEUsageCounter `json:"cte"` - AccountLock *m.AccountLockCounter `json:"accountLock"` - CachedTable bool `json:"cachedTable"` - AutoCapture bool `json:"autoCapture"` - PlacementPolicyUsage *placementPolicyUsage `json:"placementPolicy"` - NonTransactionalUsage *m.NonTransactionalStmtCounter `json:"nonTransactional"` - GlobalKill bool `json:"globalKill"` - MultiSchemaChange *m.MultiSchemaChangeUsageCounter `json:"multiSchemaChange"` - ExchangePartition *m.ExchangePartitionUsageCounter `json:"exchangePartition"` - TablePartition *m.TablePartitionUsageCounter `json:"tablePartition"` - LogBackup bool `json:"logBackup"` - EnablePaging bool `json:"enablePaging"` - EnableCostModelVer2 bool `json:"enableCostModelVer2"` - DDLUsageCounter *m.DDLUsageCounter `json:"DDLUsageCounter"` + ClusterIndex *ClusterIndexUsage `json:"clusterIndex"` + NewClusterIndex *NewClusterIndexUsage `json:"newClusterIndex"` + TemporaryTable bool `json:"temporaryTable"` + CTE *m.CTEUsageCounter `json:"cte"` + AccountLock *m.AccountLockCounter `json:"accountLock"` + CachedTable bool `json:"cachedTable"` + AutoCapture bool `json:"autoCapture"` + PlacementPolicyUsage *placementPolicyUsage `json:"placementPolicy"` + NonTransactionalUsage *m.NonTransactionalStmtCounter `json:"nonTransactional"` + GlobalKill bool `json:"globalKill"` + MultiSchemaChange *m.MultiSchemaChangeUsageCounter `json:"multiSchemaChange"` + ExchangePartition *m.ExchangePartitionUsageCounter `json:"exchangePartition"` + TablePartition *m.TablePartitionUsageCounter `json:"tablePartition"` + LogBackup bool `json:"logBackup"` + EnablePaging bool `json:"enablePaging"` + EnableCostModelVer2 bool `json:"enableCostModelVer2"` + DDLUsageCounter *m.DDLUsageCounter `json:"DDLUsageCounter"` + EnableGlobalMemoryControl bool `json:"enableGlobalMemoryControl"` + AutoIDNoCache bool `json:"autoIDNoCache"` + IndexMergeUsageCounter *m.IndexMergeUsageCounter `json:"indexMergeUsageCounter"` + ResourceControlUsage *resourceControlUsage `json:"resourceControl"` } type placementPolicyUsage struct { @@ -65,6 +70,11 @@ type placementPolicyUsage struct { NumPartitionWithExplicitPolicies uint64 `json:"numPartitionWithExplicitPolicies"` } +type resourceControlUsage struct { + Enabled bool `json:"resourceControlEnabled"` + NumResourceGroups uint64 `json:"numResourceGroups"` +} + func getFeatureUsage(ctx context.Context, sctx sessionctx.Context) (*featureUsage, error) { var usage featureUsage var err error @@ -103,14 +113,19 @@ func getFeatureUsage(ctx context.Context, sctx sessionctx.Context) (*featureUsag usage.DDLUsageCounter = getDDLUsageInfo(sctx) + usage.EnableGlobalMemoryControl = getGlobalMemoryControl() + + usage.IndexMergeUsageCounter = getIndexMergeUsageInfo() + return &usage, nil } -// collectFeatureUsageFromInfoschema updates the usage for temporary table, cached table and placement policies. +// collectFeatureUsageFromInfoschema updates the usage for temporary table, cached table, placement policies and resource groups. func collectFeatureUsageFromInfoschema(ctx sessionctx.Context, usage *featureUsage) { if usage.PlacementPolicyUsage == nil { usage.PlacementPolicyUsage = &placementPolicyUsage{} } + is := GetDomainInfoSchema(ctx) for _, dbInfo := range is.AllSchemas() { if dbInfo.PlacementPolicyRef != nil { @@ -127,6 +142,9 @@ func collectFeatureUsageFromInfoschema(ctx sessionctx.Context, usage *featureUsa if tbInfo.Meta().PlacementPolicyRef != nil { usage.PlacementPolicyUsage.NumTableWithPolicies++ } + if tbInfo.Meta().AutoIdCache == 1 { + usage.AutoIDNoCache = true + } partitions := tbInfo.Meta().GetPartitionInfo() if partitions == nil { continue @@ -138,8 +156,13 @@ func collectFeatureUsageFromInfoschema(ctx sessionctx.Context, usage *featureUsa } } } - usage.PlacementPolicyUsage.NumPlacementPolicies += uint64(len(is.AllPlacementPolicies())) + + if usage.ResourceControlUsage == nil { + usage.ResourceControlUsage = &resourceControlUsage{} + } + usage.ResourceControlUsage.NumResourceGroups = uint64(len(is.AllResourceGroups())) + usage.ResourceControlUsage.Enabled = variable.EnableResourceControl.Load() } // GetDomainInfoSchema is used by the telemetry package to get the latest schema information @@ -236,33 +259,34 @@ var initialTablePartitionCounter m.TablePartitionUsageCounter var initialSavepointStmtCounter int64 var initialLazyPessimisticUniqueCheckSetCount int64 var initialDDLUsageCounter m.DDLUsageCounter +var initialIndexMergeCounter m.IndexMergeUsageCounter // getTxnUsageInfo gets the usage info of transaction related features. It's exported for tests. func getTxnUsageInfo(ctx sessionctx.Context) *TxnUsage { asyncCommitUsed := false - if val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBEnableAsyncCommit); err == nil { + if val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBEnableAsyncCommit); err == nil { asyncCommitUsed = val == variable.On } onePCUsed := false - if val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBEnable1PC); err == nil { + if val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBEnable1PC); err == nil { onePCUsed = val == variable.On } curr := metrics.GetTxnCommitCounter() diff := curr.Sub(initialTxnCommitCounter) mutationCheckerUsed := false - if val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBEnableMutationChecker); err == nil { + if val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBEnableMutationChecker); err == nil { mutationCheckerUsed = val == variable.On } assertionUsed := "" - if val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBTxnAssertionLevel); err == nil { + if val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBTxnAssertionLevel); err == nil { assertionUsed = val } rcCheckTSUsed := false - if val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBRCReadCheckTS); err == nil { + if val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBRCReadCheckTS); err == nil { rcCheckTSUsed = val == variable.On } rcWriteCheckTSUsed := false - if val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBRCWriteCheckTs); err == nil { + if val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBRCWriteCheckTs); err == nil { rcWriteCheckTSUsed = val == variable.On } currSavepointCount := m.GetSavepointStmtCounter() @@ -346,7 +370,7 @@ func getTablePartitionUsageInfo() *m.TablePartitionUsageCounter { // getAutoCaptureUsageInfo gets the 'Auto Capture' usage func getAutoCaptureUsageInfo(ctx sessionctx.Context) bool { - if val, err := ctx.GetSessionVars().GetGlobalSystemVar(variable.TiDBCapturePlanBaseline); err == nil { + if val, err := ctx.GetSessionVars().GetGlobalSystemVar(context.Background(), variable.TiDBCapturePlanBaseline); err == nil { return val == variable.On } return false @@ -380,6 +404,7 @@ func getCostModelVer2UsageInfo(ctx sessionctx.Context) bool { func getPagingUsageInfo(ctx sessionctx.Context) bool { return ctx.GetSessionVars().EnablePaging } + func getDDLUsageInfo(ctx sessionctx.Context) *m.DDLUsageCounter { curr := m.GetDDLUsageCounter() diff := curr.Sub(initialDDLUsageCounter) @@ -389,3 +414,17 @@ func getDDLUsageInfo(ctx sessionctx.Context) *m.DDLUsageCounter { } return &diff } + +func getGlobalMemoryControl() bool { + return memory.ServerMemoryLimit.Load() > 0 +} + +func postReportIndexMergeUsage() { + initialIndexMergeCounter = m.GetIndexMergeCounter() +} + +func getIndexMergeUsageInfo() *m.IndexMergeUsageCounter { + curr := m.GetIndexMergeCounter() + diff := curr.Sub(initialIndexMergeCounter) + return &diff +} diff --git a/telemetry/data_feature_usage_test.go b/telemetry/data_feature_usage_test.go index 8b2a77ba2ffdc..2895356955c09 100644 --- a/telemetry/data_feature_usage_test.go +++ b/telemetry/data_feature_usage_test.go @@ -18,6 +18,7 @@ import ( "fmt" "testing" + _ "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/sessionctx/variable" @@ -129,6 +130,26 @@ func TestCachedTable(t *testing.T) { require.False(t, usage.CachedTable) } +func TestAutoIDNoCache(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + usage, err := telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.False(t, usage.CachedTable) + tk.MustExec("drop table if exists tele_autoid") + tk.MustExec("create table tele_autoid (id int) auto_id_cache 1") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.True(t, usage.AutoIDNoCache) + tk.MustExec("drop table tele_autoid") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.False(t, usage.AutoIDNoCache) +} + func TestAccountLock(t *testing.T) { store := testkit.CreateMockStore(t) @@ -219,6 +240,7 @@ func TestTablePartition(t *testing.T) { require.Equal(t, int64(0), usage.TablePartition.TablePartitionCreateIntervalPartitionsCnt) require.Equal(t, int64(0), usage.TablePartition.TablePartitionAddIntervalPartitionsCnt) require.Equal(t, int64(0), usage.TablePartition.TablePartitionDropIntervalPartitionsCnt) + require.Equal(t, int64(0), usage.TablePartition.TablePartitionReorganizePartitionCnt) telemetry.PostReportTelemetryDataForTest() tk.MustExec("drop table if exists pt1") @@ -230,6 +252,7 @@ func TestTablePartition(t *testing.T) { "partition p4 values less than (15))") tk.MustExec("alter table pt1 first partition less than (9)") tk.MustExec("alter table pt1 last partition less than (21)") + tk.MustExec("alter table pt1 reorganize partition p4 into (partition p4 values less than (13), partition p5 values less than (15))") tk.MustExec("drop table if exists pt1") tk.MustExec("create table pt1 (d datetime primary key, v varchar(255)) partition by range columns(d)" + " interval (1 day) first partition less than ('2022-01-01') last partition less than ('2022-02-22')") @@ -254,6 +277,7 @@ func TestTablePartition(t *testing.T) { require.Equal(t, int64(1), usage.TablePartition.TablePartitionCreateIntervalPartitionsCnt) require.Equal(t, int64(1), usage.TablePartition.TablePartitionAddIntervalPartitionsCnt) require.Equal(t, int64(1), usage.TablePartition.TablePartitionDropIntervalPartitionsCnt) + require.Equal(t, int64(1), usage.TablePartition.TablePartitionReorganizePartitionCnt) tk.MustExec("drop table if exists pt2") tk.MustExec("create table pt2 (a int,b int) partition by range(a) (" + @@ -266,6 +290,12 @@ func TestTablePartition(t *testing.T) { usage, err = telemetry.GetFeatureUsage(tk.Session()) require.NoError(t, err) require.Equal(t, int64(1), usage.ExchangePartition.ExchangePartitionCnt) + + require.Equal(t, int64(0), usage.TablePartition.TablePartitionComactCnt) + tk.MustExec(`alter table pt2 compact partition p0 tiflash replica;`) + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, int64(1), usage.TablePartition.TablePartitionComactCnt) } func TestPlacementPolicies(t *testing.T) { @@ -310,6 +340,45 @@ func TestPlacementPolicies(t *testing.T) { require.Equal(t, uint64(1), usage.PlacementPolicyUsage.NumPartitionWithExplicitPolicies) } +func TestResourceGroups(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + + usage, err := telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, uint64(0), usage.ResourceControlUsage.NumResourceGroups) + require.Equal(t, false, usage.ResourceControlUsage.Enabled) + + tk.MustExec("set global tidb_enable_resource_control = 'ON'") + tk.MustExec("create resource group x rru_per_sec=100 wru_per_sec=200") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, true, usage.ResourceControlUsage.Enabled) + require.Equal(t, uint64(1), usage.ResourceControlUsage.NumResourceGroups) + + tk.MustExec("create resource group y rru_per_sec=100 wru_per_sec=200") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, uint64(2), usage.ResourceControlUsage.NumResourceGroups) + + tk.MustExec("alter resource group y rru_per_sec=100 wru_per_sec=300") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, uint64(2), usage.ResourceControlUsage.NumResourceGroups) + + tk.MustExec("drop resource group y") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, uint64(1), usage.ResourceControlUsage.NumResourceGroups) + + tk.MustExec("set global tidb_enable_resource_control = 'OFF'") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, uint64(1), usage.ResourceControlUsage.NumResourceGroups) + require.Equal(t, false, usage.ResourceControlUsage.Enabled) +} + func TestAutoCapture(t *testing.T) { store := testkit.CreateMockStore(t) @@ -353,12 +422,18 @@ func TestNonTransactionalUsage(t *testing.T) { usage, err := telemetry.GetFeatureUsage(tk.Session()) require.NoError(t, err) require.Equal(t, int64(0), usage.NonTransactionalUsage.DeleteCount) + require.Equal(t, int64(0), usage.NonTransactionalUsage.UpdateCount) + require.Equal(t, int64(0), usage.NonTransactionalUsage.InsertCount) tk.MustExec("create table t(a int);") tk.MustExec("batch limit 1 delete from t") + tk.MustExec("batch limit 1 update t set a = 1") + tk.MustExec("batch limit 1 insert into t select * from t") usage, err = telemetry.GetFeatureUsage(tk.Session()) require.NoError(t, err) require.Equal(t, int64(1), usage.NonTransactionalUsage.DeleteCount) + require.Equal(t, int64(1), usage.NonTransactionalUsage.UpdateCount) + require.Equal(t, int64(1), usage.NonTransactionalUsage.InsertCount) } func TestGlobalKillUsageInfo(t *testing.T) { @@ -402,7 +477,7 @@ func TestCostModelVer2UsageInfo(t *testing.T) { tk := testkit.NewTestKit(t, store) usage, err := telemetry.GetFeatureUsage(tk.Session()) require.NoError(t, err) - require.False(t, usage.EnableCostModelVer2) + require.Equal(t, usage.EnableCostModelVer2, variable.DefTiDBCostModelVer == 2) tk.Session().GetSessionVars().CostModelVersion = 2 usage, err = telemetry.GetFeatureUsage(tk.Session()) @@ -445,11 +520,28 @@ func TestLazyPessimisticUniqueCheck(t *testing.T) { require.Equal(t, int64(2), usage.LazyUniqueCheckSetCounter) } -func TestAddIndexAccelerationAndMDL(t *testing.T) { - if !variable.EnableConcurrentDDL.Load() { - t.Skipf("test requires concurrent ddl") - } +func TestFlashbackCluster(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk1 := testkit.NewTestKit(t, store) + + usage, err := telemetry.GetFeatureUsage(tk.Session()) + require.Equal(t, int64(0), usage.DDLUsageCounter.FlashbackClusterUsed) + require.NoError(t, err) + + tk.MustExecToErr("flashback cluster to timestamp '2011-12-21 00:00:00'") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.Equal(t, int64(1), usage.DDLUsageCounter.FlashbackClusterUsed) + require.NoError(t, err) + + tk1.MustExec("use test") + tk1.MustExec("create table t(a int)") + usage, err = telemetry.GetFeatureUsage(tk1.Session()) + require.Equal(t, int64(1), usage.DDLUsageCounter.FlashbackClusterUsed) + require.NoError(t, err) +} +func TestAddIndexAccelerationAndMDL(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) usage, err := telemetry.GetFeatureUsage(tk.Session()) @@ -457,7 +549,8 @@ func TestAddIndexAccelerationAndMDL(t *testing.T) { require.NoError(t, err) allow := ddl.IsEnableFastReorg() - require.Equal(t, false, allow) + require.Equal(t, true, allow) + tk.MustExec("set global tidb_enable_metadata_lock = 0") tk.MustExec("use test") tk.MustExec("drop table if exists tele_t") tk.MustExec("create table tele_t(id int, b int)") @@ -465,7 +558,7 @@ func TestAddIndexAccelerationAndMDL(t *testing.T) { tk.MustExec("alter table tele_t add index idx_org(b)") usage, err = telemetry.GetFeatureUsage(tk.Session()) require.NoError(t, err) - require.Equal(t, int64(0), usage.DDLUsageCounter.AddIndexIngestUsed) + require.Equal(t, int64(1), usage.DDLUsageCounter.AddIndexIngestUsed) require.Equal(t, false, usage.DDLUsageCounter.MetadataLockUsed) tk.MustExec("set @@global.tidb_ddl_enable_fast_reorg = on") @@ -474,10 +567,58 @@ func TestAddIndexAccelerationAndMDL(t *testing.T) { require.Equal(t, true, allow) usage, err = telemetry.GetFeatureUsage(tk.Session()) require.NoError(t, err) - require.Equal(t, int64(0), usage.DDLUsageCounter.AddIndexIngestUsed) + require.Equal(t, int64(1), usage.DDLUsageCounter.AddIndexIngestUsed) tk.MustExec("alter table tele_t add index idx_new(b)") usage, err = telemetry.GetFeatureUsage(tk.Session()) require.NoError(t, err) - require.Equal(t, int64(1), usage.DDLUsageCounter.AddIndexIngestUsed) + require.Equal(t, int64(2), usage.DDLUsageCounter.AddIndexIngestUsed) require.Equal(t, true, usage.DDLUsageCounter.MetadataLockUsed) } + +func TestGlobalMemoryControl(t *testing.T) { + store := testkit.CreateMockStore(t) + + tk := testkit.NewTestKit(t, store) + usage, err := telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.True(t, usage.EnableGlobalMemoryControl == (variable.DefTiDBServerMemoryLimit != "0")) + + tk.MustExec("set global tidb_server_memory_limit = 5 << 30") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.True(t, usage.EnableGlobalMemoryControl) + + tk.MustExec("set global tidb_server_memory_limit = 0") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.False(t, usage.EnableGlobalMemoryControl) +} + +func TestIndexMergeUsage(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("create table t1(c1 int, c2 int, index idx1(c1), index idx2(c2))") + res := tk.MustQuery("explain select /*+ use_index_merge(t1, idx1, idx2) */ * from t1 where c1 = 1 and c2 = 1").Rows() + require.Contains(t, res[0][0], "IndexMerge") + + usage, err := telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, usage.IndexMergeUsageCounter.IndexMergeUsed, int64(0)) + + tk.MustExec("select /*+ use_index_merge(t1, idx1, idx2) */ * from t1 where c1 = 1 and c2 = 1") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, int64(1), usage.IndexMergeUsageCounter.IndexMergeUsed) + + tk.MustExec("select /*+ use_index_merge(t1, idx1, idx2) */ * from t1 where c1 = 1 or c2 = 1") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, int64(2), usage.IndexMergeUsageCounter.IndexMergeUsed) + + tk.MustExec("select /*+ no_index_merge() */ * from t1 where c1 = 1 or c2 = 1") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, int64(2), usage.IndexMergeUsageCounter.IndexMergeUsed) +} diff --git a/telemetry/data_window_test.go b/telemetry/data_window_test.go index 94146863ea9bd..0bd171caf3775 100644 --- a/telemetry/data_window_test.go +++ b/telemetry/data_window_test.go @@ -94,9 +94,11 @@ func TestTiflashUsage(t *testing.T) { require.Equal(t, telemetry.CurrentTiflashTableScanCount.String(), "0") require.Equal(t, telemetry.CurrentTiflashTableScanWithFastScanCount.String(), "0") - tk.MustExec("set session tidb_isolation_read_engines='tiflash';select count(*) from t") + tk.MustExec("set session tidb_isolation_read_engines='tiflash';") + tk.MustQuery(`select count(*) from t`) tk.MustExec(`set @@session.tiflash_fastscan=ON`) - tk.MustExec(`set session tidb_isolation_read_engines="tiflash";select count(*) from test.t`) + tk.MustExec(`set session tidb_isolation_read_engines="tiflash";`) + tk.MustQuery(`select count(*) from test.t`) tk.Session().Close() require.Equal(t, telemetry.CurrentTiflashTableScanCount.String(), "2") diff --git a/telemetry/main_test.go b/telemetry/main_test.go index 6d4b5d2c5aaf8..0e8d98b2a4f6c 100644 --- a/telemetry/main_test.go +++ b/telemetry/main_test.go @@ -39,6 +39,8 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) diff --git a/testkit/BUILD.bazel b/testkit/BUILD.bazel index a60f4520dae52..c28ef0614eb04 100644 --- a/testkit/BUILD.bazel +++ b/testkit/BUILD.bazel @@ -20,6 +20,8 @@ go_library( "//kv", "//parser/ast", "//parser/terror", + "//planner/core", + "//resourcemanager", "//session", "//session/txninfo", "//sessionctx/variable", @@ -27,6 +29,9 @@ go_library( "//store/mockstore", "//util", "//util/breakpoint", + "//util/chunk", + "//util/gctuner", + "//util/mathutil", "//util/sqlexec", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", diff --git a/testkit/asynctestkit.go b/testkit/asynctestkit.go index aa0f3fcadf8ef..a875088c82abf 100644 --- a/testkit/asynctestkit.go +++ b/testkit/asynctestkit.go @@ -183,6 +183,21 @@ func (tk *AsyncTestKit) MustExec(ctx context.Context, sql string, args ...interf } } +// MustGetErrMsg executes a sql statement and assert its error message. +func (tk *AsyncTestKit) MustGetErrMsg(ctx context.Context, sql string, errStr string) { + err := tk.ExecToErr(ctx, sql) + tk.require.EqualError(err, errStr) +} + +// ExecToErr executes a sql statement and discard results. +func (tk *AsyncTestKit) ExecToErr(ctx context.Context, sql string, args ...interface{}) error { + res, err := tk.Exec(ctx, sql, args...) + if res != nil { + tk.require.NoError(res.Close()) + } + return err +} + // MustQuery query the statements and returns result rows. // If expected result is set it asserts the query result equals expected result. func (tk *AsyncTestKit) MustQuery(ctx context.Context, sql string, args ...interface{}) *Result { diff --git a/testkit/mocksessionmanager.go b/testkit/mocksessionmanager.go index 5e0325417a0e8..550ff69132d91 100644 --- a/testkit/mocksessionmanager.go +++ b/testkit/mocksessionmanager.go @@ -18,6 +18,9 @@ import ( "crypto/tls" "sync" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/session/txninfo" "github.com/pingcap/tidb/util" @@ -29,6 +32,7 @@ type MockSessionManager struct { PSMu sync.RWMutex SerID uint64 TxnInfo []*txninfo.TxnInfo + Dom *domain.Domain conn map[uint64]session.Session mu sync.Mutex } @@ -66,6 +70,11 @@ func (msm *MockSessionManager) ShowProcessList() map[uint64]*util.ProcessInfo { ret[connID] = pi.ShowProcess() } msm.mu.Unlock() + if msm.Dom != nil { + for connID, pi := range msm.Dom.SysProcTracker().GetSysProcessList() { + ret[connID] = pi + } + } return ret } @@ -78,6 +87,16 @@ func (msm *MockSessionManager) GetProcessInfo(id uint64) (*util.ProcessInfo, boo return item, true } } + msm.mu.Lock() + defer msm.mu.Unlock() + if sess := msm.conn[id]; sess != nil { + return sess.ShowProcess(), true + } + if msm.Dom != nil { + if pinfo, ok := msm.Dom.SysProcTracker().GetSysProcessList()[id]; ok { + return pinfo, true + } + } return &util.ProcessInfo{}, false } @@ -109,7 +128,24 @@ func (*MockSessionManager) GetInternalSessionStartTSList() []uint64 { return nil } -// CheckOldRunningTxn is to get all startTS of every transactions running in the current internal sessions +// KillNonFlashbackClusterConn implement SessionManager interface. +func (msm *MockSessionManager) KillNonFlashbackClusterConn() { + for _, se := range msm.conn { + processInfo := se.ShowProcess() + ddl, ok := processInfo.StmtCtx.GetPlan().(*core.DDL) + if !ok { + msm.Kill(se.GetSessionVars().ConnectionID, false) + continue + } + _, ok = ddl.Statement.(*ast.FlashBackToTimestampStmt) + if !ok { + msm.Kill(se.GetSessionVars().ConnectionID, false) + continue + } + } +} + +// CheckOldRunningTxn implement SessionManager interface. func (msm *MockSessionManager) CheckOldRunningTxn(job2ver map[int64]int64, job2ids map[int64]string) { msm.mu.Lock() for _, se := range msm.conn { @@ -117,3 +153,25 @@ func (msm *MockSessionManager) CheckOldRunningTxn(job2ver map[int64]int64, job2i } msm.mu.Unlock() } + +// GetMinStartTS implements SessionManager interface. +func (msm *MockSessionManager) GetMinStartTS(lowerBound uint64) (ts uint64) { + msm.PSMu.RLock() + defer msm.PSMu.RUnlock() + if len(msm.PS) > 0 { + for _, pi := range msm.PS { + if thisTS := pi.GetMinStartTS(lowerBound); thisTS > lowerBound && (thisTS < ts || ts == 0) { + ts = thisTS + } + } + return + } + msm.mu.Lock() + defer msm.mu.Unlock() + for _, s := range msm.conn { + if thisTS := s.ShowProcess().GetMinStartTS(lowerBound); thisTS > lowerBound && (thisTS < ts || ts == 0) { + ts = thisTS + } + } + return +} diff --git a/testkit/mockstore.go b/testkit/mockstore.go index 7a022570c311c..c0cfb83a53149 100644 --- a/testkit/mockstore.go +++ b/testkit/mockstore.go @@ -24,9 +24,11 @@ import ( "github.com/pingcap/tidb/ddl/schematracker" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/resourcemanager" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/store/driver" "github.com/pingcap/tidb/store/mockstore" + "github.com/pingcap/tidb/util/gctuner" "github.com/stretchr/testify/require" "go.opencensus.io/stats/view" ) @@ -56,6 +58,7 @@ func CreateMockStore(t testing.TB, opts ...mockstore.MockTiKVStoreOption) kv.Sto t.Cleanup(func() { view.Stop() }) + gctuner.GlobalMemoryLimitTuner.Stop() store, _ := CreateMockStoreAndDomain(t, opts...) return store } @@ -67,12 +70,18 @@ func CreateMockStoreAndDomain(t testing.TB, opts ...mockstore.MockTiKVStoreOptio dom := bootstrap(t, store, 500*time.Millisecond) sm := MockSessionManager{} dom.InfoSyncer().SetSessionManager(&sm) + t.Cleanup(func() { + view.Stop() + gctuner.GlobalMemoryLimitTuner.Stop() + }) return schematracker.UnwrapStorage(store), dom } func bootstrap(t testing.TB, store kv.Storage, lease time.Duration) *domain.Domain { session.SetSchemaLease(lease) session.DisableStats4Test() + domain.DisablePlanReplayerBackgroundJob4Test() + domain.DisableDumpHistoricalStats4Test() dom, err := session.BootstrapSession(store) require.NoError(t, err) @@ -83,6 +92,7 @@ func bootstrap(t testing.TB, store kv.Storage, lease time.Duration) *domain.Doma err := store.Close() require.NoError(t, err) view.Stop() + resourcemanager.InstanceResourceManager.Reset() }) return dom } diff --git a/testkit/result.go b/testkit/result.go index 0f7ad0ce53cbc..210d32d4c57b9 100644 --- a/testkit/result.go +++ b/testkit/result.go @@ -49,6 +49,11 @@ func (res *Result) Check(expected [][]interface{}) { res.require.Equal(needBuff.String(), resBuff.String(), res.comment) } +// AddComment adds the extra comment for the Result's output. +func (res *Result) AddComment(c string) { + res.comment += "\n" + c +} + // CheckWithFunc asserts the result match the expected results in the way `f` specifies. func (res *Result) CheckWithFunc(expected [][]interface{}, f func([]string, []interface{}) bool) { res.require.Equal(len(res.rows), len(expected), res.comment+"\nResult length mismatch") diff --git a/testkit/testkit.go b/testkit/testkit.go index 1617b743efa65..56e02fef5e688 100644 --- a/testkit/testkit.go +++ b/testkit/testkit.go @@ -19,6 +19,7 @@ package testkit import ( "context" "fmt" + "runtime" "strings" "sync" "testing" @@ -31,6 +32,8 @@ import ( "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/sqlexec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -48,15 +51,18 @@ type TestKit struct { t testing.TB store kv.Storage session session.Session + alloc chunk.Allocator } // NewTestKit returns a new *TestKit. func NewTestKit(t testing.TB, store kv.Storage) *TestKit { + runtime.GOMAXPROCS(mathutil.Min(16, runtime.GOMAXPROCS(0))) tk := &TestKit{ require: require.New(t), assert: assert.New(t), t: t, store: store, + alloc: chunk.NewAllocator(), } tk.RefreshSession() @@ -86,6 +92,7 @@ func NewTestKitWithSession(t testing.TB, store kv.Storage, se session.Session) * t: t, store: store, session: se, + alloc: chunk.NewAllocator(), } } @@ -110,6 +117,11 @@ func (tk *TestKit) Session() session.Session { // MustExec executes a sql statement and asserts nil error. func (tk *TestKit) MustExec(sql string, args ...interface{}) { + defer func() { + if tk.alloc != nil { + tk.alloc.Reset() + } + }() tk.MustExecWithContext(context.Background(), sql, args...) } @@ -127,6 +139,11 @@ func (tk *TestKit) MustExecWithContext(ctx context.Context, sql string, args ... // MustQuery query the statements and returns result rows. // If expected result is set it asserts the query result equals expected result. func (tk *TestKit) MustQuery(sql string, args ...interface{}) *Result { + defer func() { + if tk.alloc != nil { + tk.alloc.Reset() + } + }() return tk.MustQueryWithContext(context.Background(), sql, args...) } @@ -217,6 +234,29 @@ func (tk *TestKit) HasPlan(sql string, plan string, args ...interface{}) bool { return false } +// HasTiFlashPlan checks if the result execution plan contains TiFlash plan. +func (tk *TestKit) HasTiFlashPlan(sql string, args ...interface{}) bool { + rs := tk.MustQuery("explain "+sql, args...) + for i := range rs.rows { + if strings.Contains(rs.rows[i][2], "tiflash") { + return true + } + } + return false +} + +// HasPlanForLastExecution checks if the execution plan of the last execution contains specific plan. +func (tk *TestKit) HasPlanForLastExecution(plan string) bool { + connID := tk.session.GetSessionVars().ConnectionID + rs := tk.MustQuery(fmt.Sprintf("explain for connection %d", connID)) + for i := range rs.rows { + if strings.Contains(rs.rows[i][0], plan) { + return true + } + } + return false +} + // HasKeywordInOperatorInfo checks if the result execution plan contains specific keyword in the operator info. func (tk *TestKit) HasKeywordInOperatorInfo(sql string, keyword string, args ...interface{}) bool { rs := tk.MustQuery("explain "+sql, args...) @@ -255,7 +295,8 @@ func (tk *TestKit) Exec(sql string, args ...interface{}) (sqlexec.RecordSet, err } // ExecWithContext executes a sql statement using the prepared stmt API -func (tk *TestKit) ExecWithContext(ctx context.Context, sql string, args ...interface{}) (sqlexec.RecordSet, error) { +func (tk *TestKit) ExecWithContext(ctx context.Context, sql string, args ...interface{}) (rs sqlexec.RecordSet, err error) { + defer tk.Session().GetSessionVars().ClearAlloc(&tk.alloc, err != nil) if len(args) == 0 { sc := tk.session.GetSessionVars().StmtCtx prevWarns := sc.GetWarnings() @@ -269,12 +310,13 @@ func (tk *TestKit) ExecWithContext(ctx context.Context, sql string, args ...inte } warns := sc.GetWarnings() parserWarns := warns[len(prevWarns):] + tk.Session().GetSessionVars().SetAlloc(tk.alloc) var rs0 sqlexec.RecordSet for i, stmt := range stmts { var rs sqlexec.RecordSet var err error - if s, ok := stmt.(*ast.NonTransactionalDeleteStmt); ok { - rs, err = session.HandleNonTransactionalDelete(ctx, s, tk.Session()) + if s, ok := stmt.(*ast.NonTransactionalDMLStmt); ok { + rs, err = session.HandleNonTransactionalDML(ctx, s, tk.Session()) } else { rs, err = tk.Session().ExecuteStmt(ctx, stmt) } @@ -297,7 +339,8 @@ func (tk *TestKit) ExecWithContext(ctx context.Context, sql string, args ...inte return nil, errors.Trace(err) } params := expression.Args2Expressions4Test(args...) - rs, err := tk.session.ExecutePreparedStmt(ctx, stmtID, params) + tk.Session().GetSessionVars().SetAlloc(tk.alloc) + rs, err = tk.session.ExecutePreparedStmt(ctx, stmtID, params) if err != nil { return rs, errors.Trace(err) } diff --git a/testkit/testutil/require.go b/testkit/testutil/require.go index 90b157fcb7591..09e8e871312ae 100644 --- a/testkit/testutil/require.go +++ b/testkit/testutil/require.go @@ -17,6 +17,7 @@ package testutil import ( + "math/rand" "testing" "github.com/pingcap/tidb/kv" @@ -75,3 +76,14 @@ func CompareUnorderedStringSlice(a []string, b []string) bool { } return len(m) == 0 } + +var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + +// RandStringRunes generate random string of length n. +func RandStringRunes(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letterRunes[rand.Intn(len(letterRunes))] + } + return string(b) +} diff --git a/tests/graceshutdown/main_test.go b/tests/graceshutdown/main_test.go index b480886282c4b..56da5e1a0590a 100644 --- a/tests/graceshutdown/main_test.go +++ b/tests/graceshutdown/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("syscall.syscall6"), } goleak.VerifyTestMain(m, opts...) diff --git a/tests/readonlytest/main_test.go b/tests/readonlytest/main_test.go index 7cdc72764ebb9..53cdfef25456b 100644 --- a/tests/readonlytest/main_test.go +++ b/tests/readonlytest/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } diff --git a/tests/readonlytest/readonly_test.go b/tests/readonlytest/readonly_test.go index 836debae6ac11..654e2542738e5 100644 --- a/tests/readonlytest/readonly_test.go +++ b/tests/readonlytest/readonly_test.go @@ -158,6 +158,11 @@ func TestRestriction(t *testing.T) { require.Error(t, err) require.Equal(t, err.Error(), PriviledgedErrMsg) + // can't do flashback cluster + _, err = s.udb.Exec("flashback cluster to timestamp ''") + require.Error(t, err) + require.Equal(t, err.Error(), ReadOnlyErrMsg) + // can do some Admin stmts _, err = s.udb.Exec("admin show ddl jobs") require.NoError(t, err) diff --git a/tests/realtikvtest/addindextest/BUILD.bazel b/tests/realtikvtest/addindextest/BUILD.bazel index 99420e080b846..a2e9c9906380b 100644 --- a/tests/realtikvtest/addindextest/BUILD.bazel +++ b/tests/realtikvtest/addindextest/BUILD.bazel @@ -26,17 +26,27 @@ go_test( "add_index_test.go", "concurrent_ddl_test.go", "failpoints_test.go", + "integration_test.go", "main_test.go", - "memory_test.go", "multi_schema_change_test.go", "pitr_test.go", ], embed = [":addindextest"], deps = [ + "//br/pkg/lightning/backend/local", "//config", + "//ddl", "//ddl/ingest", + "//ddl/testutil", + "//domain", + "//errno", + "//parser/model", "//testkit", "//tests/realtikvtest", + "//util/logutil", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//require", + "@org_uber_go_zap//:zap", ], ) diff --git a/tests/realtikvtest/addindextest/add_index_test.go b/tests/realtikvtest/addindextest/add_index_test.go index 7dd4919570594..1c1403f66a922 100644 --- a/tests/realtikvtest/addindextest/add_index_test.go +++ b/tests/realtikvtest/addindextest/add_index_test.go @@ -100,3 +100,29 @@ func TestCreateMultiColsIndex(t *testing.T) { ctx := initTest(t) testTwoColsFrame(ctx, coliIDs, coljIDs, addIndexMultiCols) } + +func TestAddForeignKeyWithAutoCreateIndex(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists fk_index;") + tk.MustExec("create database fk_index;") + tk.MustExec("use fk_index;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=1;`) + tk.MustExec("create table employee (id bigint auto_increment key, pid bigint)") + tk.MustExec("insert into employee (id) values (1),(2),(3),(4),(5),(6),(7),(8)") + for i := 0; i < 14; i++ { + tk.MustExec("insert into employee (pid) select pid from employee") + } + tk.MustExec("update employee set pid=id-1 where id>1") + tk.MustQuery("select count(*) from employee").Check(testkit.Rows("131072")) + tk.MustExec("alter table employee add foreign key fk_1(pid) references employee(id)") + tk.MustExec("alter table employee drop foreign key fk_1") + tk.MustExec("alter table employee drop index fk_1") + tk.MustExec("update employee set pid=0 where id=1") + tk.MustGetErrMsg("alter table employee add foreign key fk_1(pid) references employee(id)", + "[ddl:1452]Cannot add or update a child row: a foreign key constraint fails (`fk_index`.`employee`, CONSTRAINT `fk_1` FOREIGN KEY (`pid`) REFERENCES `employee` (`id`))") + tk.MustExec("update employee set pid=null where id=1") + tk.MustExec("insert into employee (pid) select pid from employee") + tk.MustExec("update employee set pid=id-1 where id>1 and pid is null") + tk.MustExec("alter table employee add foreign key fk_1(pid) references employee(id)") +} diff --git a/tests/realtikvtest/addindextest/integration_test.go b/tests/realtikvtest/addindextest/integration_test.go new file mode 100644 index 0000000000000..07b54089395da --- /dev/null +++ b/tests/realtikvtest/addindextest/integration_test.go @@ -0,0 +1,471 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package addindextest_test + +import ( + "fmt" + "strings" + "sync" + "sync/atomic" + "testing" + + "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/br/pkg/lightning/backend/local" + "github.com/pingcap/tidb/ddl" + "github.com/pingcap/tidb/ddl/ingest" + "github.com/pingcap/tidb/ddl/testutil" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/tests/realtikvtest" + "github.com/pingcap/tidb/util/logutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" +) + +func TestAddIndexIngestMemoryUsage(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + + local.RunInTest = true + + tk.MustExec("create table t (a int, b int, c int);") + var sb strings.Builder + sb.WriteString("insert into t values ") + size := 100 + for i := 0; i < size; i++ { + sb.WriteString(fmt.Sprintf("(%d, %d, %d)", i, i, i)) + if i != size-1 { + sb.WriteString(",") + } + } + sb.WriteString(";") + tk.MustExec(sb.String()) + require.Equal(t, int64(0), ingest.LitMemRoot.CurrentUsage()) + tk.MustExec("alter table t add index idx(a);") + tk.MustExec("alter table t add unique index idx1(b);") + tk.MustExec("admin check table t;") + require.Equal(t, int64(0), ingest.LitMemRoot.CurrentUsage()) + require.NoError(t, local.LastAlloc.CheckRefCnt()) +} + +func TestAddIndexIngestLimitOneBackend(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + tk.MustExec("create table t (a int, b int);") + tk.MustExec("insert into t values (1, 1), (2, 2), (3, 3);") + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use addindexlit;") + tk2.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + tk2.MustExec("create table t2 (a int, b int);") + tk2.MustExec("insert into t2 values (1, 1), (2, 2), (3, 3);") + + // Mock there is a running ingest job. + ingest.LitBackCtxMgr.Store(65535, &ingest.BackendContext{}) + wg := &sync.WaitGroup{} + wg.Add(2) + go func() { + tk.MustExec("alter table t add index idx(a);") + wg.Done() + }() + go func() { + tk2.MustExec("alter table t2 add index idx_b(b);") + wg.Done() + }() + wg.Wait() + rows := tk.MustQuery("admin show ddl jobs 2;").Rows() + require.Len(t, rows, 2) + require.False(t, strings.Contains(rows[0][3].(string) /* job_type */, "ingest")) + require.False(t, strings.Contains(rows[1][3].(string) /* job_type */, "ingest")) + require.Equal(t, rows[0][7].(string) /* row_count */, "3") + require.Equal(t, rows[1][7].(string) /* row_count */, "3") + + // Remove the running ingest job. + ingest.LitBackCtxMgr.Delete(65535) + tk.MustExec("alter table t add index idx_a(a);") + rows = tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + require.True(t, strings.Contains(rows[0][3].(string) /* job_type */, "ingest")) + require.Equal(t, rows[0][7].(string) /* row_count */, "3") +} + +func TestAddIndexIngestWriterCountOnPartitionTable(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + + tk.MustExec("create table t (a int primary key) partition by hash(a) partitions 32;") + var sb strings.Builder + sb.WriteString("insert into t values ") + for i := 0; i < 100; i++ { + sb.WriteString(fmt.Sprintf("(%d)", i)) + if i != 99 { + sb.WriteString(",") + } + } + tk.MustExec(sb.String()) + tk.MustExec("alter table t add index idx(a);") + rows := tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + jobTp := rows[0][3].(string) + require.True(t, strings.Contains(jobTp, "ingest"), jobTp) +} + +func TestIngestMVIndexOnPartitionTable(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + + tk.MustExec("create table t (pk int primary key, a json) partition by hash(pk) partitions 32;") + var sb strings.Builder + sb.WriteString("insert into t values ") + for i := 0; i < 10240; i++ { + sb.WriteString(fmt.Sprintf("(%d, '[%d, %d, %d]')", i, i+1, i+2, i+3)) + if i != 10240-1 { + sb.WriteString(",") + } + } + tk.MustExec(sb.String()) + tk.MustExec("alter table t add index idx((cast(a as signed array)));") + rows := tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + jobTp := rows[0][3].(string) + require.True(t, strings.Contains(jobTp, "ingest"), jobTp) + tk.MustExec("admin check table t") + + tk.MustExec("drop table t") + tk.MustExec("create table t (pk int primary key, a json) partition by hash(pk) partitions 32;") + tk.MustExec(sb.String()) + var wg sync.WaitGroup + wg.Add(1) + go func() { + n := 10240 + internalTK := testkit.NewTestKit(t, store) + internalTK.MustExec("use addindexlit;") + + for i := 0; i < 1024; i++ { + internalTK.MustExec(fmt.Sprintf("insert into t values (%d, '[%d, %d, %d]')", n, n, n+1, n+2)) + internalTK.MustExec(fmt.Sprintf("delete from t where pk = %d", n-10)) + internalTK.MustExec(fmt.Sprintf("update t set a = '[%d, %d, %d]' where pk = %d", n-3, n-2, n+1000, n-5)) + n++ + } + wg.Done() + }() + tk.MustExec("alter table t add index idx((cast(a as signed array)));") + wg.Wait() + tk.MustExec("admin check table t") +} + +func TestAddIndexIngestAdjustBackfillWorker(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + tk.MustExec("set @@global.tidb_ddl_reorg_worker_cnt = 1;") + tk.MustExec("create table t (a int primary key);") + var sb strings.Builder + sb.WriteString("insert into t values ") + for i := 0; i < 20; i++ { + sb.WriteString(fmt.Sprintf("(%d000)", i)) + if i != 19 { + sb.WriteString(",") + } + } + tk.MustExec(sb.String()) + tk.MustQuery("split table t between (0) and (20000) regions 20;").Check(testkit.Rows("19 1")) + + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/checkBackfillWorkerNum", `return(true)`)) + done := make(chan error, 1) + atomic.StoreInt32(&ddl.TestCheckWorkerNumber, 1) + testutil.SessionExecInGoroutine(store, "addindexlit", "alter table t add index idx(a);", done) + checkNum := 0 + + running := true + cnt := [3]int{1, 2, 4} + offset := 0 + for running { + select { + case err := <-done: + require.NoError(t, err) + running = false + case wg := <-ddl.TestCheckWorkerNumCh: + offset = (offset + 1) % 3 + tk.MustExec(fmt.Sprintf("set @@global.tidb_ddl_reorg_worker_cnt=%d", cnt[offset])) + atomic.StoreInt32(&ddl.TestCheckWorkerNumber, int32(cnt[offset])/2+1) + checkNum++ + wg.Done() + } + } + + require.Greater(t, checkNum, 5) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/checkBackfillWorkerNum")) + tk.MustExec("admin check table t;") + rows := tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + jobTp := rows[0][3].(string) + require.True(t, strings.Contains(jobTp, "ingest"), jobTp) + tk.MustExec("set @@global.tidb_ddl_reorg_worker_cnt = 4;") +} + +func TestAddIndexIngestAdjustBackfillWorkerCountFail(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + ingest.ImporterRangeConcurrencyForTest = &atomic.Int32{} + ingest.ImporterRangeConcurrencyForTest.Store(2) + tk.MustExec("set @@global.tidb_ddl_reorg_worker_cnt = 20;") + tk.MustExec("create table t (a int primary key);") + var sb strings.Builder + sb.WriteString("insert into t values ") + for i := 0; i < 20; i++ { + sb.WriteString(fmt.Sprintf("(%d000)", i)) + if i != 19 { + sb.WriteString(",") + } + } + tk.MustExec(sb.String()) + tk.MustQuery("split table t between (0) and (20000) regions 20;").Check(testkit.Rows("19 1")) + tk.MustExec("alter table t add index idx(a);") + rows := tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + jobTp := rows[0][3].(string) + require.True(t, strings.Contains(jobTp, "ingest"), jobTp) + tk.MustExec("set @@global.tidb_ddl_reorg_worker_cnt = 4;") + ingest.ImporterRangeConcurrencyForTest = nil +} + +func TestAddIndexIngestGeneratedColumns(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + assertLastNDDLUseIngest := func(n int) { + tk.MustExec("admin check table t;") + rows := tk.MustQuery(fmt.Sprintf("admin show ddl jobs %d;", n)).Rows() + require.Len(t, rows, n) + for i := 0; i < n; i++ { + jobTp := rows[i][3].(string) + require.True(t, strings.Contains(jobTp, "ingest"), jobTp) + } + } + tk.MustExec("create table t (a int, b int, c int as (b+10), d int as (b+c), primary key (a) clustered);") + tk.MustExec("insert into t (a, b) values (1, 1), (2, 2), (3, 3);") + tk.MustExec("alter table t add index idx(c);") + tk.MustExec("alter table t add index idx1(c, a);") + tk.MustExec("alter table t add index idx2(a);") + tk.MustExec("alter table t add index idx3(d);") + tk.MustExec("alter table t add index idx4(d, c);") + tk.MustQuery("select * from t;").Check(testkit.Rows("1 1 11 12", "2 2 12 14", "3 3 13 16")) + assertLastNDDLUseIngest(5) + + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (a int, b char(10), c char(10) as (concat(b, 'x')), d int, e char(20) as (c));") + tk.MustExec("insert into t (a, b, d) values (1, '1', 1), (2, '2', 2), (3, '3', 3);") + tk.MustExec("alter table t add index idx(c);") + tk.MustExec("alter table t add index idx1(a, c);") + tk.MustExec("alter table t add index idx2(c(7));") + tk.MustExec("alter table t add index idx3(e(5));") + tk.MustQuery("select * from t;").Check(testkit.Rows("1 1 1x 1 1x", "2 2 2x 2 2x", "3 3 3x 3 3x")) + assertLastNDDLUseIngest(4) + + tk.MustExec("drop table if exists t;") + tk.MustExec("create table t (a int, b char(10), c tinyint, d int as (a + c), e bigint as (d - a), primary key(b, a) clustered);") + tk.MustExec("insert into t (a, b, c) values (1, '1', 1), (2, '2', 2), (3, '3', 3);") + tk.MustExec("alter table t add index idx(d);") + tk.MustExec("alter table t add index idx1(b(2), d);") + tk.MustExec("alter table t add index idx2(d, c);") + tk.MustExec("alter table t add index idx3(e);") + tk.MustQuery("select * from t;").Check(testkit.Rows("1 1 1 2 1", "2 2 2 4 2", "3 3 3 6 3")) + assertLastNDDLUseIngest(4) +} + +func TestAddIndexIngestEmptyTable(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec("create table t (a int);") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + tk.MustExec("alter table t add index idx(a);") + + rows := tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + jobTp := rows[0][3].(string) + require.True(t, strings.Contains(jobTp, "ingest"), jobTp) +} + +func TestAddIndexIngestRestoredData(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + + tk.MustExec(` + CREATE TABLE tbl_5 ( + col_21 time DEFAULT '04:48:17', + col_22 varchar(403) COLLATE utf8_unicode_ci DEFAULT NULL, + col_23 year(4) NOT NULL, + col_24 char(182) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL, + col_25 set('Alice','Bob','Charlie','David') COLLATE utf8_unicode_ci DEFAULT NULL, + PRIMARY KEY (col_24(3)) /*T![clustered_index] CLUSTERED */, + KEY idx_10 (col_22) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + `) + tk.MustExec("INSERT INTO tbl_5 VALUES ('15:33:15','&U+x1',2007,'','Bob');") + tk.MustExec("alter table tbl_5 add unique key idx_13 ( col_23 );") + tk.MustExec("admin check table tbl_5;") + rows := tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + jobTp := rows[0][3].(string) + require.True(t, strings.Contains(jobTp, "ingest"), jobTp) +} + +func TestAddIndexIngestPanicOnCopRead(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/MockCopSenderPanic", "return(true)")) + tk.MustExec("create table t (a int, b int, c int, d int, primary key (a) clustered);") + tk.MustExec("insert into t (a, b, c, d) values (1, 1, 1, 1), (2, 2, 2, 2), (3, 3, 3, 3);") + tk.MustExec("alter table t add index idx(b);") + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/MockCopSenderPanic")) + rows := tk.MustQuery("admin show ddl jobs 1;").Rows() + require.Len(t, rows, 1) + jobTp := rows[0][3].(string) + // Fallback to txn-merge process. + require.True(t, strings.Contains(jobTp, "txn-merge"), jobTp) +} + +func TestAddIndexIngestUniqueKey(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + + tk.MustExec("create table t (a int primary key, b int);") + tk.MustExec("insert into t values (1, 1), (10000, 1);") + tk.MustExec("split table t by (5000);") + tk.MustGetErrMsg("alter table t add unique index idx(b);", "[kv:1062]Duplicate entry '1' for key 't.idx'") + + tk.MustExec("drop table t;") + tk.MustExec("create table t (a varchar(255) primary key, b int);") + tk.MustExec("insert into t values ('a', 1), ('z', 1);") + tk.MustExec("split table t by ('m');") + tk.MustGetErrMsg("alter table t add unique index idx(b);", "[kv:1062]Duplicate entry '1' for key 't.idx'") + + tk.MustExec("drop table t;") + tk.MustExec("create table t (a varchar(255) primary key, b int, c char(5));") + tk.MustExec("insert into t values ('a', 1, 'c1'), ('d', 2, 'c1'), ('x', 1, 'c2'), ('z', 1, 'c1');") + tk.MustExec("split table t by ('m');") + tk.MustGetErrMsg("alter table t add unique index idx(b, c);", "[kv:1062]Duplicate entry '1-c1' for key 't.idx'") +} + +func TestAddIndexIngestCancel(t *testing.T) { + store, dom := realtikvtest.CreateMockStoreAndDomainAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("drop database if exists addindexlit;") + tk.MustExec("create database addindexlit;") + tk.MustExec("use addindexlit;") + tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) + tk.MustExec("create table t (a int, b int);") + tk.MustExec("insert into t (a, b) values (1, 1), (2, 2), (3, 3);") + defHook := dom.DDL().GetHook() + customHook := newTestCallBack(t, dom) + cancelled := false + customHook.OnJobRunBeforeExported = func(job *model.Job) { + if cancelled { + return + } + if job.Type == model.ActionAddIndex && job.SchemaState == model.StateWriteReorganization { + idx := findIdxInfo(dom, "addindexlit", "t", "idx") + if idx == nil { + return + } + if idx.BackfillState == model.BackfillStateRunning { + tk2 := testkit.NewTestKit(t, store) + rs, err := tk2.Exec(fmt.Sprintf("admin cancel ddl jobs %d", job.ID)) + assert.NoError(t, err) + assert.NoError(t, rs.Close()) + cancelled = true + } + } + } + dom.DDL().SetHook(customHook) + tk.MustGetErrCode("alter table t add index idx(b);", errno.ErrCancelledDDLJob) + require.True(t, cancelled) + dom.DDL().SetHook(defHook) + require.Empty(t, ingest.LitBackCtxMgr.Keys()) +} + +type testCallback struct { + ddl.Callback + OnJobRunBeforeExported func(job *model.Job) +} + +func newTestCallBack(t *testing.T, dom *domain.Domain) *testCallback { + defHookFactory, err := ddl.GetCustomizedHook("default_hook") + require.NoError(t, err) + return &testCallback{ + Callback: defHookFactory(dom), + } +} + +func (c *testCallback) OnJobRunBefore(job *model.Job) { + if c.OnJobRunBeforeExported != nil { + c.OnJobRunBeforeExported(job) + } +} + +func findIdxInfo(dom *domain.Domain, dbName, tbName, idxName string) *model.IndexInfo { + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(dbName), model.NewCIStr(tbName)) + if err != nil { + logutil.BgLogger().Warn("cannot find table", zap.String("dbName", dbName), zap.String("tbName", tbName)) + return nil + } + return tbl.Meta().FindIndexByName(idxName) +} diff --git a/tests/realtikvtest/addindextest/main_test.go b/tests/realtikvtest/addindextest/main_test.go index 5171b56a48d1a..a308c7831a249 100644 --- a/tests/realtikvtest/addindextest/main_test.go +++ b/tests/realtikvtest/addindextest/main_test.go @@ -18,6 +18,7 @@ import ( "flag" "testing" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/tests/realtikvtest" ) @@ -26,5 +27,8 @@ import ( var FullMode = flag.Bool("full-mode", false, "whether tests run in full mode") func TestMain(m *testing.M) { + config.UpdateGlobal(func(conf *config.Config) { + conf.Store = "tikv" + }) realtikvtest.RunTestMain(m) } diff --git a/tests/realtikvtest/addindextest/memory_test.go b/tests/realtikvtest/addindextest/memory_test.go deleted file mode 100644 index 8e482458d4955..0000000000000 --- a/tests/realtikvtest/addindextest/memory_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2022 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package addindextest - -import ( - "fmt" - "strings" - "testing" - - "github.com/pingcap/tidb/ddl/ingest" - "github.com/pingcap/tidb/testkit" - "github.com/pingcap/tidb/tests/realtikvtest" - "github.com/stretchr/testify/require" -) - -func TestLitAddIndexMemoryUsage(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("drop database if exists addindexlit;") - tk.MustExec("create database addindexlit;") - tk.MustExec("use addindexlit;") - tk.MustExec(`set global tidb_ddl_enable_fast_reorg=on;`) - - tk.MustExec("create table t (a int, b int, c int);") - var sb strings.Builder - sb.WriteString("insert into t values ") - size := 100 - for i := 0; i < size; i++ { - sb.WriteString(fmt.Sprintf("(%d, %d, %d)", i, i, i)) - if i != size-1 { - sb.WriteString(",") - } - } - sb.WriteString(";") - tk.MustExec(sb.String()) - require.Equal(t, int64(0), ingest.LitMemRoot.CurrentUsage()) - tk.MustExec("alter table t add index idx(a);") - tk.MustExec("alter table t add unique index idx1(b);") - tk.MustExec("admin check table t;") - require.Equal(t, int64(0), ingest.LitMemRoot.CurrentUsage()) -} diff --git a/tests/realtikvtest/brietest/BUILD.bazel b/tests/realtikvtest/brietest/BUILD.bazel index f2c70ae0607e2..c3118c4d7a88a 100644 --- a/tests/realtikvtest/brietest/BUILD.bazel +++ b/tests/realtikvtest/brietest/BUILD.bazel @@ -6,23 +6,21 @@ go_test( srcs = [ "backup_restore_test.go", "binlog_test.go", - "flashback_test.go", "main_test.go", ], flaky = True, race = "on", deps = [ "//config", - "//ddl/util", "//parser/mysql", "//sessionctx/binloginfo", "//store/mockstore/mockcopr", "//testkit", + "//testkit/testsetup", "//tests/realtikvtest", - "@com_github_pingcap_failpoint//:failpoint", "@com_github_pingcap_tipb//go-binlog", "@com_github_stretchr_testify//require", - "@com_github_tikv_client_go_v2//oracle", "@org_golang_google_grpc//:grpc", + "@org_uber_go_goleak//:goleak", ], ) diff --git a/tests/realtikvtest/brietest/flashback_test.go b/tests/realtikvtest/brietest/flashback_test.go deleted file mode 100644 index 1f490c30e0a2f..0000000000000 --- a/tests/realtikvtest/brietest/flashback_test.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2022 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package brietest - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/pingcap/failpoint" - ddlutil "github.com/pingcap/tidb/ddl/util" - "github.com/pingcap/tidb/testkit" - "github.com/pingcap/tidb/tests/realtikvtest" - "github.com/stretchr/testify/require" - "github.com/tikv/client-go/v2/oracle" -) - -// MockGC is used to make GC work in the test environment. -func MockGC(tk *testkit.TestKit) (string, string, string, func()) { - originGC := ddlutil.IsEmulatorGCEnable() - resetGC := func() { - if originGC { - ddlutil.EmulatorGCEnable() - } else { - ddlutil.EmulatorGCDisable() - } - } - - // disable emulator GC. - // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. - ddlutil.EmulatorGCDisable() - gcTimeFormat := "20060102-15:04:05 -0700 MST" - timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(gcTimeFormat) - timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(gcTimeFormat) - safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') - ON DUPLICATE KEY - UPDATE variable_value = '%[1]s'` - // clear GC variables first. - tk.MustExec("delete from mysql.tidb where variable_name in ( 'tikv_gc_safe_point','tikv_gc_enable' )") - return timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC -} - -func TestFlashback(t *testing.T) { - t.Skip("skip this test because TestFlashback isn't ready.") - if *realtikvtest.WithRealTiKV { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - - timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) - defer resetGC() - - tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t(a int, index i(a))") - tk.MustExec("insert t values (1), (2), (3)") - - time.Sleep(1 * time.Second) - - ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) - require.NoError(t, err) - - injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) - require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", - fmt.Sprintf("return(%v)", injectSafeTS))) - require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", - fmt.Sprintf("return(%v)", injectSafeTS))) - - tk.MustExec("insert t values (4), (5), (6)") - tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) - - tk.MustExec("admin check table t") - require.Equal(t, tk.MustQuery("select max(a) from t").Rows()[0][0], "3") - require.Equal(t, tk.MustQuery("select max(a) from t use index(i)").Rows()[0][0], "3") - - require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) - require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) - } -} diff --git a/tests/realtikvtest/brietest/main_test.go b/tests/realtikvtest/brietest/main_test.go index 6a022c35323b7..12b7cda9f1d1e 100644 --- a/tests/realtikvtest/brietest/main_test.go +++ b/tests/realtikvtest/brietest/main_test.go @@ -17,9 +17,23 @@ package brietest import ( "testing" + "github.com/pingcap/tidb/testkit/testsetup" "github.com/pingcap/tidb/tests/realtikvtest" + "go.uber.org/goleak" ) func TestMain(m *testing.M) { + opts := []goleak.Option{ + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("google.golang.org/grpc.(*ccBalancerWrapper).watcher"), + goleak.IgnoreTopFunction("google.golang.org/grpc/internal/transport.(*http2Client).keepalive"), + goleak.IgnoreTopFunction("google.golang.org/grpc/internal/transport.(*controlBuffer).get"), + goleak.IgnoreTopFunction("net/http.(*persistConn).writeLoop"), + goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), + } + testsetup.SetupForCommonTest() + goleak.VerifyTestMain(m, opts...) realtikvtest.RunTestMain(m) } diff --git a/tests/realtikvtest/flashbacktest/BUILD.bazel b/tests/realtikvtest/flashbacktest/BUILD.bazel new file mode 100644 index 0000000000000..e2cf7c91cc7c4 --- /dev/null +++ b/tests/realtikvtest/flashbacktest/BUILD.bazel @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "flashbacktest_test", + srcs = [ + "flashback_test.go", + "main_test.go", + ], + flaky = True, + race = "on", + deps = [ + "//ddl/util", + "//errno", + "//parser/model", + "//testkit", + "//testkit/testsetup", + "//tests/realtikvtest", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//oracle", + "@com_github_tikv_client_go_v2//util", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/tests/realtikvtest/flashbacktest/flashback_test.go b/tests/realtikvtest/flashbacktest/flashback_test.go new file mode 100644 index 0000000000000..809750548a4e4 --- /dev/null +++ b/tests/realtikvtest/flashbacktest/flashback_test.go @@ -0,0 +1,561 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flashbacktest + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/pingcap/failpoint" + ddlutil "github.com/pingcap/tidb/ddl/util" + "github.com/pingcap/tidb/errno" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/tests/realtikvtest" + "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/oracle" + tikvutil "github.com/tikv/client-go/v2/util" +) + +// MockGC is used to make GC work in the test environment. +func MockGC(tk *testkit.TestKit) (string, string, string, func()) { + originGC := ddlutil.IsEmulatorGCEnable() + resetGC := func() { + if originGC { + ddlutil.EmulatorGCEnable() + } else { + ddlutil.EmulatorGCDisable() + } + } + + // disable emulator GC. + // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. + ddlutil.EmulatorGCDisable() + timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(tikvutil.GCTimeFormat) + timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(tikvutil.GCTimeFormat) + safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') + ON DUPLICATE KEY + UPDATE variable_value = '%[1]s'` + // clear GC variables first. + tk.MustExec("delete from mysql.tidb where variable_name in ( 'tikv_gc_safe_point','tikv_gc_enable' )") + return timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC +} + +func TestFlashback(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, index i(a))") + tk.MustExec("insert t values (1), (2), (3)") + + time.Sleep(1 * time.Second) + + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + + tk.MustExec("insert t values (4), (5), (6)") + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + require.Equal(t, tk.MustQuery("select max(a) from t").Rows()[0][0], "3") + require.Equal(t, tk.MustQuery("select max(a) from t use index(i)").Rows()[0][0], "3") + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestPrepareFlashbackFailed(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, index i(a))") + tk.MustExec("insert t values (1), (2), (3)") + + time.Sleep(1 * time.Second) + + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/mockPrepareMeetsEpochNotMatch", `return(true)`)) + + tk.MustExec("insert t values (4), (5), (6)") + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + require.Equal(t, tk.MustQuery("select max(a) from t").Rows()[0][0], "3") + require.Equal(t, tk.MustQuery("select max(a) from t use index(i)").Rows()[0][0], "3") + + jobMeta := tk.MustQuery("select job_meta from mysql.tidb_ddl_history order by job_id desc limit 1").Rows()[0][0].(string) + job := model.Job{} + require.NoError(t, job.Decode([]byte(jobMeta))) + require.Equal(t, job.ErrorCount, int64(0)) + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/mockPrepareMeetsEpochNotMatch")) + } +} + +func TestFlashbackAddDropIndex(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, index i(a))") + tk.MustExec("insert t values (1), (2), (3)") + prevGCCount := tk.MustQuery("select count(*) from mysql.gc_delete_range").Rows()[0][0] + + time.Sleep(1 * time.Second) + + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("alter table t add index k(a)") + require.Equal(t, tk.MustQuery("select max(a) from t use index(k)").Rows()[0][0], "3") + tk.MustExec("alter table t drop index i") + tk.MustGetErrCode("select max(a) from t use index(i)", errno.ErrKeyDoesNotExist) + require.Greater(t, tk.MustQuery("select count(*) from mysql.gc_delete_range").Rows()[0][0], prevGCCount) + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + + tk.MustExec("insert t values (4), (5), (6)") + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + require.Equal(t, tk.MustQuery("select max(a) from t use index(i)").Rows()[0][0], "3") + tk.MustGetErrCode("select max(a) from t use index(k)", errno.ErrKeyDoesNotExist) + require.Equal(t, tk.MustQuery("select count(*) from mysql.gc_delete_range").Rows()[0][0], prevGCCount) + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackAddDropModifyColumn(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b int, index i(a))") + tk.MustExec("insert t values (1, 1), (2, 2), (3, 3)") + + time.Sleep(1 * time.Second) + + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("alter table t add column c int") + tk.MustExec("alter table t drop column b") + tk.MustExec("alter table t modify column a tinyint") + require.Equal(t, tk.MustQuery("show create table t").Rows()[0][1], "CREATE TABLE `t` (\n"+ + " `a` tinyint(4) DEFAULT NULL,\n"+ + " `c` int(11) DEFAULT NULL,\n"+ + " KEY `i` (`a`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + + tk.MustExec("insert t values (4, 4), (5, 5), (6, 6)") + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + require.Equal(t, tk.MustQuery("show create table t").Rows()[0][1], "CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` int(11) DEFAULT NULL,\n"+ + " KEY `i` (`a`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin") + require.Equal(t, tk.MustQuery("select max(b) from t").Rows()[0][0], "3") + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackBasicRenameDropCreateTable(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("drop table if exists t, t1, t2, t3") + tk.MustExec("create table t(a int, index i(a))") + tk.MustExec("insert t values (1), (2), (3)") + tk.MustExec("create table t1(a int, index i(a))") + tk.MustExec("insert t1 values (4), (5), (6)") + prevGCCount := tk.MustQuery("select count(*) from mysql.gc_delete_range").Rows()[0][0] + + time.Sleep(1 * time.Second) + + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("rename table t to t3") + tk.MustExec("drop table t1") + tk.MustExec("create table t2(a int, index i(a))") + tk.MustExec("insert t2 values (7), (8), (9)") + + require.Equal(t, tk.MustQuery("select max(a) from t3").Rows()[0][0], "3") + require.Equal(t, tk.MustQuery("select max(a) from t2").Rows()[0][0], "9") + + require.Greater(t, tk.MustQuery("select count(*) from mysql.gc_delete_range").Rows()[0][0], prevGCCount) + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + require.Equal(t, tk.MustQuery("select max(a) from t").Rows()[0][0], "3") + tk.MustExec("admin check table t1") + require.Equal(t, tk.MustQuery("select max(a) from t1").Rows()[0][0], "6") + require.Equal(t, tk.MustQuery("select count(*) from mysql.gc_delete_range").Rows()[0][0], prevGCCount) + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackCreateDropTableWithData(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("create table t(a int)") + + time.Sleep(1 * time.Second) + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("insert into t values (1)") + tk.MustExec("drop table t") + tk.MustExec("create table t(b int)") + tk.MustExec("insert into t(b) values (1)") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + require.Equal(t, tk.MustQuery("select count(a) from t").Rows()[0][0], "0") + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackCreateDropSchema(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("create table t(a int, index k(a))") + tk.MustExec("insert into t values (1),(2)") + + time.Sleep(1 * time.Second) + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("drop schema test") + tk.MustExec("create schema test1") + tk.MustExec("create schema test2") + tk.MustExec("use test1") + tk.MustGetErrCode("use test", errno.ErrBadDB) + tk.MustExec("use test2") + tk.MustExec("drop schema test2") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table test.t") + res := tk.MustQuery("select max(a) from test.t").Rows() + require.Equal(t, res[0][0], "2") + tk.MustGetErrCode("use test1", errno.ErrBadDB) + tk.MustGetErrCode("use test2", errno.ErrBadDB) + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackAutoID(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("create table t(a int auto_increment, primary key(a)) auto_id_cache 100") + tk.MustExec("insert into t values (),()") + + time.Sleep(1 * time.Second) + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("insert into t values (),()") + res := tk.MustQuery("select max(a) from test.t").Rows() + require.Equal(t, res[0][0], "4") + tk.MustExec("drop table t") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + res = tk.MustQuery("select max(a) from t").Rows() + require.Equal(t, res[0][0], "2") + tk.MustExec("insert into t values ()") + res = tk.MustQuery("select max(a) from t").Rows() + require.Equal(t, res[0][0], "101") + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackSequence(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("create sequence seq cache 100") + res := tk.MustQuery("select nextval(seq)").Rows() + require.Equal(t, res[0][0], "1") + + time.Sleep(1 * time.Second) + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + res = tk.MustQuery("select nextval(seq)").Rows() + require.Equal(t, res[0][0], "2") + tk.MustExec("drop sequence seq") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + // flashback schema and skip cached values + res = tk.MustQuery("select nextval(seq)").Rows() + require.Equal(t, res[0][0], "101") + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackPartitionTable(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("create table t(a int) partition by range(`a`) " + + "(partition `a_1` values less than (25), " + + "partition `a_2` values less than (75), " + + "partition `a_3` values less than (200))") + + for i := 0; i < 100; i++ { + tk.MustExec(fmt.Sprintf("insert into t values (%d)", i)) + } + + time.Sleep(1 * time.Second) + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("alter table t drop partition `a_3`") + tk.MustExec("alter table t add partition (partition `a_3` values less than (300))") + res := tk.MustQuery("select max(a) from t").Rows() + require.Equal(t, res[0][0], "74") + tk.MustExec("drop table t") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustExec("admin check table t") + res = tk.MustQuery("select max(a), min(a), count(*) from t").Rows() + require.Equal(t, res[0][0], "99") + require.Equal(t, res[0][1], "0") + require.Equal(t, res[0][2], "100") + tk.MustExec("insert into t values (100), (-1)") + res = tk.MustQuery("select max(a), min(a), count(*) from t").Rows() + require.Equal(t, res[0][0], "100") + require.Equal(t, res[0][1], "-1") + require.Equal(t, res[0][2], "102") + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} + +func TestFlashbackTmpTable(t *testing.T) { + if *realtikvtest.WithRealTiKV { + store := realtikvtest.CreateMockStoreAndSetup(t) + + tk := testkit.NewTestKit(t, store) + + timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk) + defer resetGC() + + tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) + tk.MustExec("use test") + tk.MustExec("create temporary table t(a int)") + + // test flashback tmp table data + time.Sleep(1 * time.Second) + ts, err := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("insert into t values (1), (2), (3)") + + injectSafeTS := oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + res := tk.MustQuery("select max(a) from t").Rows() + require.Equal(t, res[0][0], "3") + + // test flashback tmp table schema + time.Sleep(1 * time.Second) + ts, err = tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{}) + require.NoError(t, err) + + tk.MustExec("drop table t") + + injectSafeTS = oracle.GoTimeToTS(oracle.GetTimeFromTS(ts).Add(100 * time.Second)) + + require.NoError(t, failpoint.Enable("tikvclient/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/expression/injectSafeTS", + fmt.Sprintf("return(%v)", injectSafeTS))) + tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", oracle.GetTimeFromTS(ts))) + + tk.MustGetErrCode("select * from t", errno.ErrNoSuchTable) + + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/expression/injectSafeTS")) + require.NoError(t, failpoint.Disable("tikvclient/injectSafeTS")) + } +} diff --git a/tests/realtikvtest/flashbacktest/main_test.go b/tests/realtikvtest/flashbacktest/main_test.go new file mode 100644 index 0000000000000..d24310861a836 --- /dev/null +++ b/tests/realtikvtest/flashbacktest/main_test.go @@ -0,0 +1,39 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flashbacktest + +import ( + "testing" + + "github.com/pingcap/tidb/testkit/testsetup" + "github.com/pingcap/tidb/tests/realtikvtest" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + opts := []goleak.Option{ + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("google.golang.org/grpc.(*ccBalancerWrapper).watcher"), + goleak.IgnoreTopFunction("google.golang.org/grpc/internal/transport.(*http2Client).keepalive"), + goleak.IgnoreTopFunction("google.golang.org/grpc/internal/transport.(*controlBuffer).get"), + goleak.IgnoreTopFunction("net/http.(*persistConn).writeLoop"), + goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), + } + testsetup.SetupForCommonTest() + goleak.VerifyTestMain(m, opts...) + realtikvtest.RunTestMain(m) +} diff --git a/tests/realtikvtest/pessimistictest/BUILD.bazel b/tests/realtikvtest/pessimistictest/BUILD.bazel index 97890c8b8b70b..201a27a3c26c7 100644 --- a/tests/realtikvtest/pessimistictest/BUILD.bazel +++ b/tests/realtikvtest/pessimistictest/BUILD.bazel @@ -11,6 +11,7 @@ go_test( deps = [ "//config", "//domain", + "//errno", "//expression", "//kv", "//parser", @@ -18,6 +19,7 @@ go_test( "//parser/model", "//parser/mysql", "//parser/terror", + "//planner/core", "//session", "//sessionctx/variable", "//sessiontxn", diff --git a/tests/realtikvtest/pessimistictest/pessimistic_test.go b/tests/realtikvtest/pessimistictest/pessimistic_test.go index bae0baf407be7..a73a36de109cf 100644 --- a/tests/realtikvtest/pessimistictest/pessimistic_test.go +++ b/tests/realtikvtest/pessimistictest/pessimistic_test.go @@ -28,6 +28,7 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser" @@ -35,6 +36,7 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" + plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/sessiontxn" @@ -188,6 +190,7 @@ func TestTxnMode(t *testing.T) { } func TestDeadlock(t *testing.T) { + t.Skip("deadlock") deadlockhistory.GlobalDeadlockHistory.Clear() deadlockhistory.GlobalDeadlockHistory.Resize(10) @@ -359,9 +362,9 @@ func TestInsertOnDup(t *testing.T) { tk.MustExec("drop table if exists dup") tk.MustExec("create table dup (id int primary key, c int)") + tk2.MustExec("insert dup values (1, 1)") tk.MustExec("begin pessimistic") - tk2.MustExec("insert dup values (1, 1)") tk.MustExec("insert dup values (1, 1) on duplicate key update c = c + 1") tk.MustExec("commit") tk.MustQuery("select * from dup").Check(testkit.Rows("1 2")) @@ -379,6 +382,8 @@ func TestPointGetOverflow(t *testing.T) { } func TestPointGetKeyLock(t *testing.T) { + t.Skip("deadlock") + store := realtikvtest.CreateMockStoreAndSetup(t) tk := testkit.NewTestKit(t, store) @@ -396,9 +401,9 @@ func TestPointGetKeyLock(t *testing.T) { go func() { tk2.MustExec("begin pessimistic") _, err1 := tk2.Exec("insert point values (1, 1, 1)") - require.True(t, kv.ErrKeyExists.Equal(err1)) + require.True(t, kv.ErrKeyExists.Equal(err1), "error: %+q", err1) _, err1 = tk2.Exec("insert point values (2, 2, 2)") - require.True(t, kv.ErrKeyExists.Equal(err1)) + require.True(t, kv.ErrKeyExists.Equal(err1), "error: %+q", err1) tk2.MustExec("rollback") <-syncCh }() @@ -1834,105 +1839,6 @@ func TestPointGetWithDeleteInMem(t *testing.T) { tk.MustExec("drop table if exists uk") } -func TestPessimisticTxnWithDDLAddDropColumn(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk.MustExec("use test") - tk2.MustExec("use test") - tk.MustExec("drop table if exists t1") - tk.MustExec("create table t1 (c1 int primary key, c2 int)") - tk.MustExec("insert t1 values (1, 77), (2, 88)") - tk.MustExec("alter table t1 add index k2(c2)") - tk.MustExec("alter table t1 drop index k2") - - // tk2 starts a pessimistic transaction and make some changes on table t1. - // tk executes some ddl statements add/drop column on table t1. - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk.MustExec("begin pessimistic") - tk.MustExec("update t1 set c2 = c1 * 10") - tk2.MustExec("alter table t1 add column c3 int after c1") - tk.MustExec("commit") - tk.MustExec("admin check table t1") - tk.MustQuery("select * from t1").Check(testkit.Rows("1 10", "2 20")) - - tk.MustExec("begin pessimistic") - tk.MustExec("insert into t1 values(5, 5, 5)") - tk2.MustExec("alter table t1 drop column c3") - tk2.MustExec("alter table t1 drop column c2") - tk.MustExec("commit") - tk.MustQuery("select * from t1").Check(testkit.Rows("1", "2", "5")) -} - -func TestPessimisticTxnWithDDLChangeColumn(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk2 := testkit.NewTestKit(t, store) - tk2.MustExec("use test") - - tk.MustExec("drop table if exists t1") - tk.MustExec("create table t1 (c1 int primary key, c2 int, c3 varchar(10))") - tk.MustExec("insert t1 values (1, 77, 'a'), (2, 88, 'b')") - - // Extend column field length is acceptable. - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk.MustExec("begin pessimistic") - tk.MustExec("update t1 set c2 = c1 * 10") - tk2.MustExec("alter table t1 modify column c2 bigint") - tk.MustExec("commit") - tk.MustExec("begin pessimistic") - tk.MustExec("update t1 set c3 = 'aba'") - tk2.MustExec("alter table t1 modify column c3 varchar(30)") - tk.MustExec("commit") - tk2.MustExec("admin check table t1") - tk.MustQuery("select * from t1").Check(testkit.Rows("1 10 aba", "2 20 aba")) - - // Change column from nullable to not null is not allowed by now. - tk.MustExec("begin pessimistic") - tk.MustExec("insert into t1(c1) values(100)") - tk2.MustExec("alter table t1 change column c2 cc2 bigint not null") - require.Error(t, tk.ExecToErr("commit")) - - // Change default value is rejected. - tk2.MustExec("create table ta(a bigint primary key auto_random(3), b varchar(255) default 'old');") - tk2.MustExec("insert into ta(b) values('a')") - tk.MustExec("begin pessimistic") - tk.MustExec("insert into ta values()") - tk2.MustExec("alter table ta modify column b varchar(300) default 'new';") - require.Error(t, tk.ExecToErr("commit")) - tk2.MustQuery("select b from ta").Check(testkit.Rows("a")) - - // Change default value with add index. There is a new MultipleKeyFlag flag on the index key, and the column is changed, - // the flag check will fail. - tk2.MustExec("insert into ta values()") - tk.MustExec("begin pessimistic") - tk.MustExec("insert into ta(b) values('inserted_value')") - tk.MustExec("insert into ta values()") - tk.MustExec("insert into ta values()") - tk2.MustExec("alter table ta add index i1(b)") - tk2.MustExec("alter table ta change column b b varchar(301) default 'newest'") - tk2.MustExec("alter table ta modify column b varchar(301) default 'new'") - require.Error(t, tk.ExecToErr("commit")) - tk2.MustExec("admin check table ta") - tk2.MustQuery("select count(b) from ta use index(i1) where b = 'new'").Check(testkit.Rows("1")) - - // Change default value to now(). - tk2.MustExec("create table tbl_time(c1 int, c_time timestamp)") - tk2.MustExec("insert into tbl_time(c1) values(1)") - tk.MustExec("begin pessimistic") - tk.MustExec("insert into tbl_time(c1) values(2)") - tk2.MustExec("alter table tbl_time modify column c_time timestamp default now()") - tk2.MustExec("insert into tbl_time(c1) values(3)") - tk2.MustExec("insert into tbl_time(c1) values(4)") - require.Error(t, tk.ExecToErr("commit")) - tk2.MustQuery("select count(1) from tbl_time where c_time is not null").Check(testkit.Rows("2")) -} - func TestPessimisticUnionForUpdate(t *testing.T) { store := realtikvtest.CreateMockStoreAndSetup(t) @@ -2133,54 +2039,6 @@ func TestInsertDupKeyAfterLockBatchPointGet(t *testing.T) { require.True(t, terror.ErrorEqual(err, kv.ErrKeyExists)) } -func TestAmendTxnVariable(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk2 := testkit.NewTestKit(t, store) - tk2.MustExec("use test") - tk3 := testkit.NewTestKit(t, store) - tk3.MustExec("use test") - - tk2.MustExec("drop table if exists t1") - tk2.MustExec("create table t1(c1 int primary key, c2 int, c3 int, unique key uk(c2));") - tk2.MustExec("insert into t1 values(1, 1, 1);") - tk2.MustExec("insert into t1 values(2, 2, 2);") - - // Set off the session variable. - tk3.MustExec("set tidb_enable_amend_pessimistic_txn = 0;") - tk3.MustExec("begin pessimistic") - tk3.MustExec("insert into t1 values(3, 3, 3)") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk.MustExec("begin pessimistic") - tk.MustExec("insert into t1 values(4, 4, 4)") - tk2.MustExec("alter table t1 add column new_col int") - require.Error(t, tk3.ExecToErr("commit")) - tk.MustExec("commit") - tk2.MustQuery("select * from t1").Check(testkit.Rows("1 1 1 ", "2 2 2 ", "4 4 4 ")) - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 0;") - - // Set off the global variable. - tk2.MustExec("set global tidb_enable_amend_pessimistic_txn = 0;") - - tk4 := testkit.NewTestKit(t, store) - tk4.MustExec("use test") - - tk4.MustQuery(`show variables like "tidb_enable_amend_pessimistic_txn"`).Check(testkit.Rows("tidb_enable_amend_pessimistic_txn OFF")) - tk4.MustExec("begin pessimistic") - tk4.MustExec("insert into t1 values(5, 5, 5, 5)") - tk2.MustExec("alter table t1 drop column new_col") - require.Error(t, tk4.ExecToErr("commit")) - tk4.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk4.MustExec("begin pessimistic") - tk4.MustExec("insert into t1 values(5, 5, 5)") - tk2.MustExec("alter table t1 add column new_col2 int") - tk4.MustExec("commit") - tk2.MustQuery("select * from t1").Check(testkit.Rows("1 1 1 ", "2 2 2 ", "4 4 4 ", "5 5 5 ")) -} - func TestSelectForUpdateWaitSeconds(t *testing.T) { store := realtikvtest.CreateMockStoreAndSetup(t) @@ -2303,9 +2161,7 @@ func TestAsyncCommitWithSchemaChange(t *testing.T) { tk.MustExec("insert into tk values(1, 1, 1)") tk2 := createAsyncCommitTestKit(t, store) tk3 := createAsyncCommitTestKit(t, store) - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk2.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk3.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") + tk.MustExec("set global tidb_ddl_enable_fast_reorg = 0;") // The txn tk writes something but with failpoint the primary key is not committed. tk.MustExec("begin pessimistic") @@ -2362,12 +2218,6 @@ func Test1PCWithSchemaChange(t *testing.T) { t.Skip("This test is unstable as depending on time.Sleep") } - defer config.RestoreFunc()() - config.UpdateGlobal(func(conf *config.Config) { - conf.TiKVClient.AsyncCommit.SafeWindow = time.Second - conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 - }) - store := realtikvtest.CreateMockStoreAndSetup(t) tk := create1PCTestKit(t, store) @@ -2377,9 +2227,7 @@ func Test1PCWithSchemaChange(t *testing.T) { tk.MustExec("drop table if exists tk") tk.MustExec("create table tk (c1 int primary key, c2 int)") tk.MustExec("insert into tk values (1, 1)") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk2.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - tk3.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") + tk.MustExec("set global tidb_ddl_enable_fast_reorg = 0;") tk.MustExec("begin pessimistic") tk.MustExec("insert into tk values(2, 2)") @@ -2417,302 +2265,6 @@ func Test1PCWithSchemaChange(t *testing.T) { tk3.MustExec("admin check table tk") } -func TestAmendForUniqueIndex(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk2.MustExec("use test") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - - tk2.MustExec("drop table if exists t1") - tk2.MustExec("create table t1(c1 int primary key, c2 int, c3 int, unique key uk(c2));") - tk2.MustExec("insert into t1 values(1, 1, 1);") - tk2.MustExec("insert into t1 values(2, 2, 2);") - - // New value has duplicates. - tk.MustExec("begin pessimistic") - tk.MustExec("insert into t1 values(3, 3, 3)") - tk.MustExec("insert into t1 values(4, 4, 3)") - tk2.MustExec("alter table t1 add unique index uk1(c3)") - require.Error(t, tk.ExecToErr("commit")) - tk2.MustExec("alter table t1 drop index uk1") - tk2.MustExec("admin check table t1") - - // New values has duplicates with old values. - tk.MustExec("begin pessimistic") - tk.MustExec("insert into t1 values(3, 3, 3)") - tk.MustExec("insert into t1 values(4, 4, 1)") - tk2.MustExec("alter table t1 add unique index uk1(c3)") - require.Error(t, tk.ExecToErr("commit")) - tk2.MustExec("admin check table t1") - - // Put new values. - tk2.MustQuery("select * from t1 for update").Check(testkit.Rows("1 1 1", "2 2 2")) - tk2.MustExec("alter table t1 drop index uk1") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t1 add unique index uk1(c3)") - tk.MustExec("insert into t1 values(5, 5, 5)") - tk.MustExec("commit") - tk2.MustExec("admin check table t1") - - // Update the old value with same unique key value, should abort. - tk2.MustExec("drop table if exists t;") - tk2.MustExec("create table t (id int auto_increment primary key, c int);") - tk2.MustExec("insert into t (id, c) values (1, 2), (3, 4);") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t add unique index uk(c);") - tk.MustExec("update t set c = 2 where id = 3;") - require.Error(t, tk.ExecToErr("commit")) - tk2.MustExec("admin check table t") - - // Update the old value with same unique key, but the row key has changed. - tk2.MustExec("drop table if exists t;") - tk2.MustExec("create table t (id int auto_increment primary key, c int);") - tk2.MustExec("insert into t (id, c) values (1, 2), (3, 4);") - tk.MustExec("begin pessimistic") - tk.MustExec("insert into t values (3, 2) on duplicate key update id = values(id) and c = values(c)") - finishCh := make(chan error) - go func() { - err := tk2.ExecToErr("alter table t add unique index uk(c);") - finishCh <- err - }() - time.Sleep(300 * time.Millisecond) - tk.MustExec("commit") - err := <-finishCh - require.NoError(t, err) - tk2.MustExec("admin check table t") - - // Update the old value with same unique key, but the row key has changed. - /* TODO this case could not pass using unistore because of https://github.com/ngaut/unistore/issues/428. - // Reopen it after fix the unistore issue. - tk2.MustExec("drop table if exists t;") - tk2.MustExec("create table t (id int auto_increment primary key, c int);") - tk2.MustExec("insert into t (id, c) values (1, 2), (3, 4);") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t add unique index uk(c);") - tk.MustExec("insert into t values (3, 2) on duplicate key update id = values(id) and c = values(c)") - tk.MustExec("commit") - tk2.MustExec("admin check table t") - */ - - // Test pessimistic retry for unique index amend. - tk2.MustExec("drop table if exists t;") - tk2.MustExec("create table t (id int key, c int);") - tk2.MustExec("insert into t (id, c) values (1, 1), (2, 2);") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t add unique index uk(c)") - tk.MustExec("insert into t values(3, 5)") - tk.MustExec("update t set c = 4 where c = 2") - errCh := make(chan error, 1) - go func() { - var err error - err = tk2.ExecToErr("begin pessimistic") - if err != nil { - errCh <- err - return - } - err = tk2.ExecToErr("insert into t values(5, 5)") - if err != nil { - errCh <- err - return - } - err = tk2.ExecToErr("delete from t where id = 5") - if err != nil { - errCh <- err - return - } - // let commit in tk start. - errCh <- err - time.Sleep(time.Millisecond * 100) - err = tk2.ExecToErr("commit") - errCh <- err - }() - err = <-errCh - require.Equal(t, nil, err) - tk.MustExec("commit") - tk.MustExec("admin check table t") - err = <-errCh - require.Equal(t, nil, err) -} - -func TestAmendWithColumnTypeChange(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk2.MustExec("use test") - - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1;") - - tk2.MustExec("drop table if exists t") - tk2.MustExec("create table t (id int primary key, v varchar(10));") - tk.MustExec("begin pessimistic") - tk.MustExec("insert into t values (1, \"123456789\")") - tk2.MustExec("alter table t modify column v varchar(5);") - require.Error(t, tk.ExecToErr("commit")) -} - -func TestIssue21498(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk2.MustExec("use test") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1") - - for _, partition := range []bool{false, true} { - // RC test - tk.MustExec("drop table if exists t, t1") - createTable := "create table t (id int primary key, v int, index iv (v))" - if partition { - createTable += " partition by range (id) (partition p0 values less than (0),partition p1 values less than (1),partition p2 values less than (2),partition p3 values less than (3),partition pn values less than MAXVALUE)" - } - tk.MustExec(createTable) - tk.MustExec("insert into t values (1, 10), (2, 20), (3, 30), (4, 40)") - tk.MustExec("create table t1(id int)") - tk.MustExec("insert into t1 values(1)") - - tk.MustExec("set tx_isolation = 'READ-COMMITTED'") - tk.MustExec("begin pessimistic") - tk.MustQuery("select * from t where v = 10").Check(testkit.Rows("1 10")) - - tk2.MustExec("alter table t drop index iv") - tk2.MustExec("update t set v = 11 where id = 1") - - tk.MustQuery("select * from t where v = 10").Check(testkit.Rows()) - tk.MustQuery("select * from t where v = 11").Check(testkit.Rows("1 11")) - tk.MustQuery("select * from t where id = 1").Check(testkit.Rows("1 11")) - tk.MustExec("admin check table t") - tk.MustExec("commit") - - tk.MustExec("drop table if exists t") - createTable = "create table t (id int primary key, v int, index iv (v), v2 int)" - if partition { - createTable += " partition by range (id) (partition p0 values less than (0),partition p1 values less than (1),partition p2 values less than (2),partition p3 values less than (3),partition pn values less than MAXVALUE)" - } - tk.MustExec(createTable) - tk.MustExec("insert into t values (1, 10, 100), (2, 20, 200), (3, 30, 300), (4, 40, 400)") - - tk.MustExec("begin pessimistic") - tk.MustQuery("select * from t use index (iv) where v = 10").Check(testkit.Rows("1 10 100")) - tk2.MustExec("alter table t drop index iv") - tk2.MustExec("update t set v = 11 where id = 1") - err := tk.ExecToErr("select * from t use index (iv) where v = 10") - require.Equal(t, "[planner:1176]Key 'iv' doesn't exist in table 't'", err.Error()) - tk.MustQuery("select * from t where v = 10").Check(testkit.Rows()) - tk2.MustExec("update t set id = 5 where id = 1") - err = tk.ExecToErr("select * from t use index (iv) where v = 10") // select with - require.Equal(t, "[planner:1176]Key 'iv' doesn't exist in table 't'", err.Error()) - tk.MustQuery("select * from t where v = 10").Check(testkit.Rows()) - if !partition { - // amend transaction does not support partition table - tk.MustExec("insert into t(id, v, v2) select 6, v + 20, v2 + 200 from t where id = 4") // insert ... select with index unchanged - } - err = tk.ExecToErr("insert into t(id, v, v2) select 7, v + 30, v2 + 300 from t use index (iv) where id = 4") // insert ... select with index changed - require.Equal(t, "[planner:1176]Key 'iv' doesn't exist in table 't'", err.Error()) - tk.MustExec("admin check table t") // check consistency inside txn - tk.MustExec("commit") - if !partition { - tk.MustQuery("select * from t").Check(testkit.Rows("2 20 200", "3 30 300", "4 40 400", "5 11 100", "6 60 600")) - } - tk.MustExec("admin check table t") // check consistency out of txn - - // RR test for non partition - if partition { - continue - } - - tk.MustExec("set tx_isolation = 'REPEATABLE-READ'") - tk2.MustExec("alter table t add unique index iv(v)") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t drop index iv") - tk2.MustExec("update t set v = 21 where v = 20") - tk2.MustExec("update t set v = 31 where v = 30") - tk.MustExec("update t set v = 22 where v = 21") // fast path - tk.CheckExecResult(1, 0) - tk.MustExec("update t set v = 23 where v = 22") - tk.CheckExecResult(1, 0) - tk.MustExec("update t set v = 32 where v >= 31 and v < 40") // common path - tk.CheckExecResult(1, 0) - tk.MustExec("commit") - tk.MustQuery("select * from t").Check(testkit.Rows("2 23 200", "3 32 300", "4 40 400", "5 11 100", "6 60 600")) - - tk2.MustExec("alter table t add unique index iv(v)") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t drop index iv") - tk2.MustExec("update t set v = 24 where v = 23") - tk2.MustExec("update t set v = 41 where v = 40") - // fast path - tk.MustQuery("select * from t where v = 23").Check(testkit.Rows("2 23 200")) - tk.MustQuery("select * from t where v = 24").Check(testkit.Rows()) - tk.MustQuery("select * from t where v = 23 for update").Check(testkit.Rows()) - tk.MustQuery("select * from t where v = 24 for update").Check(testkit.Rows("2 24 200")) - tk.MustQuery("select (select id from t where v = 23), id from t1 for update").Check(testkit.Rows("2 1")) - tk.MustQuery("select (select id from t where v = 24), id from t1 for update").Check(testkit.Rows(" 1")) - tk.MustQuery("select (select id from t where v = 23 for update), id from t1").Check(testkit.Rows(" 1")) - tk.MustQuery("select (select id from t where v = 24 for update), id from t1").Check(testkit.Rows("2 1")) - tk.MustQuery("select (select id + 1 from t where v = 24 for update), id from t1").Check(testkit.Rows("3 1")) - // sub queries - tk.MustQuery("select (select id from (select id from t where v = 24 for update) tmp for update), (select id from t where v = 23), id from t where v = 23").Check(testkit.Rows("2 2 2")) - tk.MustQuery("select (select id + (select id from t where v = 23) from (select id from t where v = 24 for update) tmp), id from t where v = 23").Check(testkit.Rows("4 2")) - tk.MustQuery("select (select id + (select id from t where v = 23) from (select id from t where v = 24 for update) tmp for update), id from t where v = 23").Check(testkit.Rows("4 2")) - tk.MustQuery("select (select id + (select id from t where v = 23 for update) from (select id from t where v = 24 for update) tmp), id from t where v = 23").Check(testkit.Rows(" 2")) - tk.MustQuery("select (select id + (select id from t where v = 23 for update) from (select id from t where v = 24 for update) tmp for update), id from t where v = 23").Check(testkit.Rows(" 2")) - tk.MustQuery("select (select id + (select id from t where v = 23) from (select id from t where v = 23) tmp), id from t where v = 24 for update").Check(testkit.Rows("4 2")) - tk.MustQuery("select (select id + (select id from t where v = 23) from (select id from t where v = 24 for update) tmp), id from t where v = 24 for update").Check(testkit.Rows("4 2")) - tk.MustQuery("select (select id + (select id from t where v = 24 for update) from (select id from t where v = 23) tmp), id from t where v = 24 for update").Check(testkit.Rows("4 2")) - - // test index look up - tk.MustQuery("select * from t s, t t1 where s.v = 23 and s.id = t1.id").Check(testkit.Rows("2 23 200 2 23 200")) - tk.MustQuery("select * from t s, t t1 where s.v = 24 and s.id = t1.id").Check(testkit.Rows()) - tk.MustQuery("select * from t s, t t1 where s.v = 23 and s.id = t1.id for update").Check(testkit.Rows()) - // TODO: Do the same with Partitioned Table!!! Since this query leads to two columns in SelectLocExec.tblID2Handle!!! - tk.MustQuery("select * from t s, t t1 where s.v = 24 and s.id = t1.id for update").Check(testkit.Rows("2 24 200 2 24 200")) - tk.MustExec("delete from t where v = 24") - tk.CheckExecResult(1, 0) - // common path - tk.MustQuery("select * from t where v >= 41 and v < 50").Check(testkit.Rows()) - tk.MustQuery("select * from t where v >= 41 and v < 50 for update").Check(testkit.Rows("4 41 400")) - tk.MustExec("delete from t where v >= 41 and v < 50") - tk.CheckExecResult(1, 0) - tk.MustExec("commit") - tk.MustQuery("select * from t").Check(testkit.Rows("3 32 300", "5 11 100", "6 60 600")) - - tk2.MustExec("alter table t add unique index iv(v)") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t drop index iv") - tk2.MustExec("update t set v = 33 where v = 32") - tk.MustExec("insert into t(id, v, v2) select 3 * id, 3 * v, 3 * v2 from t where v = 33") - tk.CheckExecResult(1, 0) - tk.MustExec("insert into t(id, v, v2) select (select 4 * id from t where v = 32) id, 4 * v, 4 * v2 from t where v = 33") - tk.CheckExecResult(1, 0) - err = tk.ExecToErr("insert into t(id, v, v2) select (select 4 * id from t where v = 33) id, 4 * v, 4 * v2 from t where v = 33") - require.Error(t, err) - require.Equal(t, "[table:1048]Column 'id' cannot be null", err.Error()) - tk.MustExec("commit") - tk.MustQuery("select * from t").Check(testkit.Rows("3 33 300", "5 11 100", "6 60 600", "9 99 900", "12 132 1200")) - - tk2.MustExec("alter table t add unique index iv(v)") - tk2.MustExec("drop table if exists t1") - tk2.MustExec("create table t1(id int primary key, v int, index iv (v), v2 int)") - tk.MustExec("begin pessimistic") - tk2.MustExec("alter table t drop index iv") - tk2.MustExec("update t set v = 34 where v = 33") - tk2.MustExec("update t set v = 12 where v = 11") - tk.MustExec("insert into t1(id, v, v2) select * from t where v = 33") - tk.CheckExecResult(0, 0) - tk.MustExec("insert into t1(id, v, v2) select * from t where v = 12") - tk.CheckExecResult(1, 0) - tk.MustExec("commit") - tk.MustQuery("select * from t1").Check(testkit.Rows("5 12 100")) - } -} - func TestPlanCacheSchemaChange(t *testing.T) { store := realtikvtest.CreateMockStoreAndSetup(t) tmp := testkit.NewTestKit(t, store) @@ -2732,8 +2284,7 @@ func TestPlanCacheSchemaChange(t *testing.T) { tk.MustExec("create table t (id int primary key, v int, unique index iv (v), vv int)") tk.MustExec("insert into t values(1, 1, 1), (2, 2, 2), (4, 4, 4)") - tk.MustExec("set tidb_enable_amend_pessimistic_txn = 1") - tk2.MustExec("set tidb_enable_amend_pessimistic_txn = 1") + tk.MustExec("set global tidb_ddl_enable_fast_reorg = 0") // generate plan cache tk.MustExec("prepare update_stmt from 'update t set vv = vv + 1 where v = ?'") @@ -2806,6 +2357,66 @@ func TestAsyncCommitCalTSFail(t *testing.T) { tk2.MustExec("commit") } +func TestAsyncCommitAndForeignKey(t *testing.T) { + defer config.RestoreFunc()() + config.UpdateGlobal(func(conf *config.Config) { + conf.TiKVClient.AsyncCommit.SafeWindow = time.Second + conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 + }) + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := createAsyncCommitTestKit(t, store) + tk.MustExec("drop table if exists t_parent, t_child") + tk.MustExec("create table t_parent (id int primary key)") + tk.MustExec("create table t_child (id int primary key, pid int, foreign key (pid) references t_parent(id) on delete cascade on update cascade)") + tk.MustExec("insert into t_parent values (1),(2),(3),(4)") + tk.MustExec("insert into t_child values (1,1),(2,2),(3,3)") + tk.MustExec("set tidb_enable_1pc = true") + tk.MustExec("begin pessimistic") + tk.MustExec("delete from t_parent where id in (1,4)") + tk.MustExec("update t_parent set id=22 where id=2") + tk.MustExec("commit") + tk.MustQuery("select * from t_parent order by id").Check(testkit.Rows("3", "22")) + tk.MustQuery("select * from t_child order by id").Check(testkit.Rows("2 22", "3 3")) +} + +func TestTransactionIsolationAndForeignKey(t *testing.T) { + if !*realtikvtest.WithRealTiKV { + t.Skip("The test only support test with tikv.") + } + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2.MustExec("use test") + tk.MustExec("drop table if exists t1,t2") + tk.MustExec("create table t1 (id int primary key)") + tk.MustExec("create table t2 (id int primary key, pid int, foreign key (pid) references t1(id) on delete cascade on update cascade)") + tk.MustExec("insert into t1 values (1)") + tk.MustExec("set tx_isolation = 'READ-COMMITTED'") + tk.MustExec("begin pessimistic") + tk.MustExec("insert into t2 values (1,1)") + tk.MustGetDBError("insert into t2 values (2,2)", plannercore.ErrNoReferencedRow2) + tk2.MustExec("insert into t1 values (2)") + tk.MustQuery("select * from t1").Check(testkit.Rows("1", "2")) + tk.MustExec("insert into t2 values (2,2)") + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + tk2.MustExec("delete from t1 where id=2") + }() + time.Sleep(time.Millisecond * 10) + tk.MustExec("commit") + wg.Wait() + tk.MustQuery("select * from t1").Check(testkit.Rows("1")) + tk.MustQuery("select * from t2").Check(testkit.Rows("1 1")) + tk2.MustExec("delete from t1 where id=1") + tk.MustQuery("select * from t1").Check(testkit.Rows()) + tk.MustQuery("select * from t2").Check(testkit.Rows()) + tk.MustExec("admin check table t1") + tk.MustExec("admin check table t2") +} + func TestChangeLockToPut(t *testing.T) { store := realtikvtest.CreateMockStoreAndSetup(t) @@ -2885,169 +2496,6 @@ func createTable(part bool, columnNames []string, columnTypes []string) string { return str } -func TestAmendForIndexChange(t *testing.T) { - defer config.RestoreFunc()() - config.UpdateGlobal(func(conf *config.Config) { - conf.TiKVClient.AsyncCommit.SafeWindow = 0 - conf.TiKVClient.AsyncCommit.AllowedClockDrift = 0 - }) - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk2.MustExec("use test") - - tk.MustExec("set tidb_enable_amend_pessimistic_txn = ON;") - tk.Session().GetSessionVars().EnableAsyncCommit = false - tk.Session().GetSessionVars().Enable1PC = false - - tk2.MustExec("drop table if exists t1") - - // Add some different column types. - columnNames := []string{"c_int", "c_str", "c_datetime", "c_timestamp", "c_double", "c_decimal", "c_float"} - columnTypes := []string{"int", "varchar(40)", "datetime", "timestamp", "double", "decimal(12, 6)", "float"} - - addIndexFunc := func(idxName string, part bool, a, b int) string { - var str string - str = "alter table t" - if part { - str = "alter table t_part" - } - str += " add index " + idxName + " (" - str += strings.Join(columnNames[a:b], ",") - str += ")" - return str - } - - for i := 0; i < len(columnTypes); i++ { - for j := i + 1; j <= len(columnTypes); j++ { - // Create table and prepare some data. - tk2.MustExec("drop table if exists t") - tk2.MustExec("drop table if exists t_part") - tk2.MustExec(createTable(false, columnNames, columnTypes)) - tk2.MustExec(createTable(true, columnNames, columnTypes)) - tk2.MustExec(`insert into t values(1, "1", "2000-01-01", "2020-01-01", "1.1", "123.321", 1.1)`) - tk2.MustExec(`insert into t values(2, "2", "2000-01-02", "2020-01-02", "2.2", "223.322", 2.2)`) - tk2.MustExec(`insert into t_part values(1, "1", "2000-01-01", "2020-01-01", "1.1", "123.321", 1.1)`) - tk2.MustExec(`insert into t_part values(2, "2", "2000-01-02", "2020-01-02", "2.2", "223.322", 2.2)`) - - // Start a pessimistic transaction, the amend should succeed for common table. - tk.MustExec("begin pessimistic") - tk.MustExec(`insert into t values(5, "555", "2000-01-05", "2020-01-05", "5.5", "555.555", 5.5)`) - idxName := fmt.Sprintf("index%d%d", i, j) - tk2.MustExec(addIndexFunc(idxName, false, i, j)) - tk.MustExec("commit") - tk2.MustExec("admin check table t") - - tk.MustExec("begin pessimistic") - tk.MustExec(`insert into t values(6, "666", "2000-01-06", "2020-01-06", "6.6", "666.666", 6.6)`) - tk2.MustExec(fmt.Sprintf(`alter table t drop index %s`, idxName)) - tk.MustExec("commit") - tk2.MustExec("admin check table t") - tk2.MustQuery("select count(*) from t").Check(testkit.Rows("4")) - - // Start a pessimistic transaction for partition table, the amend should fail. - tk.MustExec("begin pessimistic") - tk.MustExec(`insert into t_part values(5, "555", "2000-01-05", "2020-01-05", "5.5", "555.555", 5.5)`) - tk2.MustExec(addIndexFunc(idxName, true, i, j)) - require.Error(t, tk.ExecToErr("commit")) - tk2.MustExec("admin check table t_part") - - tk.MustExec("begin pessimistic") - tk.MustExec(`insert into t_part values(6, "666", "2000-01-06", "2020-01-06", "6.6", "666.666", 6.6)`) - tk2.MustExec(fmt.Sprintf(`alter table t_part drop index %s`, idxName)) - require.Error(t, tk.ExecToErr("commit")) - tk2.MustExec("admin check table t_part") - tk2.MustQuery("select count(*) from t_part").Check(testkit.Rows("2")) - } - } -} - -func TestAmendForColumnChange(t *testing.T) { - store := realtikvtest.CreateMockStoreAndSetup(t) - - tk := testkit.NewTestKit(t, store) - tk2 := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("set global tidb_enable_metadata_lock=0") - tk2.MustExec("use test") - - tk.MustExec("set tidb_enable_amend_pessimistic_txn = ON;") - tk2.MustExec("drop table if exists t1") - - // Add some different column types. - columnNames := []string{"c_int", "c_str", "c_datetime", "c_timestamp", "c_double", "c_decimal", "c_float"} - columnTypes := []string{"int", "varchar(40)", "datetime", "timestamp", "double", "decimal(12, 6)", "float"} - colChangeDDLs := []string{ - "alter table %s change column c_int c_int bigint", - "alter table %s modify column c_str varchar(55)", - "alter table %s modify column c_datetime datetime", - "alter table %s modify column c_timestamp timestamp", - "alter table %s modify column c_double double default NULL", - "alter table %s modify column c_int bigint(20) default 100", - "alter table %s change column c_float c_float float", - "alter table %s modify column c_int bigint(20)", - } - amendSucc := []bool{ - true, - true, - true, - true, - true, - false, - true, - true, - } - colChangeFunc := func(part bool, i int) string { - var sql string - sql = colChangeDDLs[i] - if part { - sql = fmt.Sprintf(sql, "t_part") - } else { - sql = fmt.Sprintf(sql, "t") - } - return sql - } - - for i := 0; i < len(colChangeDDLs); i++ { - // Create table and prepare some data. - tk2.MustExec("drop table if exists t") - tk2.MustExec("drop table if exists t_part") - tk2.MustExec(createTable(false, columnNames, columnTypes)) - tk2.MustExec(createTable(true, columnNames, columnTypes)) - tk2.MustExec(`insert into t values(1, "1", "2000-01-01", "2020-01-01", "1.1", "123.321", 1.1)`) - tk2.MustExec(`insert into t values(2, "2", "2000-01-02", "2020-01-02", "2.2", "223.322", 2.2)`) - tk2.MustExec(`insert into t_part values(1, "1", "2000-01-01", "2020-01-01", "1.1", "123.321", 1.1)`) - tk2.MustExec(`insert into t_part values(2, "2", "2000-01-02", "2020-01-02", "2.2", "223.322", 2.2)`) - - // Start a pessimistic transaction, the amend should succeed for common table. - tk.MustExec("begin pessimistic") - tk.MustExec(`insert into t values(5, "555", "2000-01-05", "2020-01-05", "5.5", "555.555", 5.5)`) - tk2.MustExec(colChangeFunc(false, i)) - if amendSucc[i] { - tk.MustExec("commit") - } else { - require.Error(t, tk.ExecToErr("commit")) - } - tk2.MustExec("admin check table t") - if amendSucc[i] { - tk2.MustQuery("select count(*) from t").Check(testkit.Rows("3")) - } else { - tk2.MustQuery("select count(*) from t").Check(testkit.Rows("2")) - } - - // Start a pessimistic transaction for partition table, the amend should fail. - tk.MustExec("begin pessimistic") - tk.MustExec(`insert into t_part values(5, "555", "2000-01-05", "2020-01-05", "5.5", "555.555", 5.5)`) - tk2.MustExec(colChangeFunc(true, i)) - require.Error(t, tk.ExecToErr("commit")) - tk2.MustExec("admin check table t_part") - tk2.MustQuery("select count(*) from t_part").Check(testkit.Rows("2")) - } -} - func TestPessimisticAutoCommitTxn(t *testing.T) { store := realtikvtest.CreateMockStoreAndSetup(t) @@ -3056,13 +2504,21 @@ func TestPessimisticAutoCommitTxn(t *testing.T) { tk.MustExec("set tidb_txn_mode = 'pessimistic'") tk.MustExec("drop table if exists t") - tk.MustExec("create table t (i int)") + tk.MustExec("create table t (i int primary key)") tk.MustExec("insert into t values (1)") tk.MustExec("set autocommit = on") rows := tk.MustQuery("explain update t set i = -i").Rows() explain := fmt.Sprintf("%v", rows[1]) require.NotRegexp(t, ".*SelectLock.*", explain) + rows = tk.MustQuery("explain update t set i = -i where i = -1").Rows() + explain = fmt.Sprintf("%v", rows[1]) + require.Regexp(t, ".*handle:-1.*", explain) + require.NotRegexp(t, ".*handle:-1, lock.*", explain) + rows = tk.MustQuery("explain update t set i = -i where i in (-1, 1)").Rows() + explain = fmt.Sprintf("%v", rows[1]) + require.Regexp(t, ".*handle:\\[-1 1\\].*", explain) + require.NotRegexp(t, ".*handle:\\[-1 1\\].*, lock.*", explain) originCfg := config.GetGlobalConfig() defer config.StoreGlobalConfig(originCfg) @@ -3073,6 +2529,12 @@ func TestPessimisticAutoCommitTxn(t *testing.T) { rows = tk.MustQuery("explain update t set i = -i").Rows() explain = fmt.Sprintf("%v", rows[1]) require.Regexp(t, ".*SelectLock.*", explain) + rows = tk.MustQuery("explain update t set i = -i where i = -1").Rows() + explain = fmt.Sprintf("%v", rows[1]) + require.Regexp(t, ".*handle:-1, lock.*", explain) + rows = tk.MustQuery("explain update t set i = -i where i in (-1, 1)").Rows() + explain = fmt.Sprintf("%v", rows[1]) + require.Regexp(t, ".*handle:\\[-1 1\\].*, lock.*", explain) } func TestPessimisticLockOnPartition(t *testing.T) { @@ -3245,7 +2707,7 @@ func TestLazyUniquenessCheck(t *testing.T) { tk.MustExec("insert into t4 values (1, 2), (2, 2)") tk.MustQuery("select * from t4 order by id").Check(testkit.Rows("1 2", "2 2")) err = tk.ExecToErr("delete from t4 where id = 1") - require.ErrorContains(t, err, "transaction aborted because lazy uniqueness check is enabled and an error occurred: [kv:1062]Duplicate entry '1' for key 'PRIMARY'") + require.ErrorContains(t, err, "transaction aborted because lazy uniqueness check is enabled and an error occurred: [kv:1062]Duplicate entry '1' for key 't4.PRIMARY'") tk.MustExec("commit") tk.MustExec("admin check table t4") tk.MustQuery("select * from t4 order by id").Check(testkit.Rows("1 1")) @@ -3266,7 +2728,7 @@ func TestLazyUniquenessCheck(t *testing.T) { tk.MustExec("begin pessimistic") tk.MustExec("insert into t5 values (2, 1)") err = tk.ExecToErr("delete from t5") - require.ErrorContains(t, err, "transaction aborted because lazy uniqueness check is enabled and an error occurred: [kv:1062]Duplicate entry '1' for key 'i1'") + require.ErrorContains(t, err, "transaction aborted because lazy uniqueness check is enabled and an error occurred: [kv:1062]Duplicate entry '1' for key 't5.i1'") require.False(t, tk.Session().GetSessionVars().InTxn()) // case: update unique key, but conflict exists before the txn @@ -3275,7 +2737,7 @@ func TestLazyUniquenessCheck(t *testing.T) { tk.MustExec("begin pessimistic") tk.MustExec("update t5 set uk = 3 where id = 1") err = tk.ExecToErr("commit") - require.ErrorContains(t, err, "Duplicate entry '3' for key 'i1'") + require.ErrorContains(t, err, "Duplicate entry '3' for key 't5.i1'") tk.MustExec("admin check table t5") // case: update unique key, but conflict with concurrent write @@ -3294,7 +2756,7 @@ func TestLazyUniquenessCheck(t *testing.T) { tk.MustExec("begin pessimistic") tk.MustExec("insert into t5 values (3, 1) on duplicate key update uk = 3") err = tk.ExecToErr("commit") - require.ErrorContains(t, err, "Duplicate entry '3' for key 'i1'") + require.ErrorContains(t, err, "Duplicate entry '3' for key 't5.i1'") tk.MustExec("admin check table t5") // case: insert on duplicate update unique key, but conflict with concurrent write @@ -3352,7 +2814,7 @@ func TestLazyUniquenessCheckWithStatementRetry(t *testing.T) { tk2.MustExec("insert into t5 values (2, 3)") err := tk.ExecToErr("update t5 set id = 10 where uk = 3") // write conflict -> unset PresumeKNE -> retry require.ErrorContains(t, err, "transaction aborted because lazy uniqueness") - require.ErrorContains(t, err, "Duplicate entry '3' for key 'i1'") + require.ErrorContains(t, err, "Duplicate entry '3' for key 't5.i1'") require.False(t, tk.Session().GetSessionVars().InTxn()) tk.MustExec("admin check table t5") @@ -3363,7 +2825,7 @@ func TestLazyUniquenessCheckWithStatementRetry(t *testing.T) { tk.MustExec("insert into t5 values (3, 3)") // skip handle=3, uk=3 tk2.MustExec("insert into t5 values (2, 3)") err = tk.ExecToErr("update t5 set id = id + 10") // write conflict -> unset PresumeKNE -> retry - require.ErrorContains(t, err, "Duplicate entry '3' for key 'i1'") + require.ErrorContains(t, err, "Duplicate entry '3' for key 't5.i1'") require.False(t, tk.Session().GetSessionVars().InTxn()) tk.MustExec("admin check table t5") } @@ -3548,7 +3010,7 @@ func TestLazyUniquenessCheckWithInconsistentReadResult(t *testing.T) { tk.MustExec("insert into t2 values (2, 1), (3, 3)") tk.MustQuery("select * from t2 use index(primary) for update").Check(testkit.Rows("1 1", "2 1", "3 3")) err := tk.ExecToErr("commit") - require.ErrorContains(t, err, "Duplicate entry '1' for key 'i1'") + require.ErrorContains(t, err, "Duplicate entry '1' for key 't2.i1'") tk.MustQuery("select * from t2 use index(primary)").Check(testkit.Rows("1 1")) tk.MustExec("admin check table t2") @@ -3571,3 +3033,326 @@ func TestLazyUniquenessCheckWithSavepoint(t *testing.T) { err := tk.ExecToErr("savepoint s1") require.ErrorContains(t, err, "savepoint is not supported in pessimistic transactions when in-place constraint check is disabled") } + +func mustExecAsync(tk *testkit.TestKit, sql string, args ...interface{}) <-chan struct{} { + ch := make(chan struct{}) + go func() { + defer func() { ch <- struct{}{} }() + tk.MustExec(sql, args...) + }() + return ch +} + +func mustQueryAsync(tk *testkit.TestKit, sql string, args ...interface{}) <-chan *testkit.Result { + ch := make(chan *testkit.Result) + go func() { + ch <- tk.MustQuery(sql, args...) + }() + return ch +} + +func mustTimeout[T interface{}](t *testing.T, ch <-chan T, timeout time.Duration) { + select { + case res := <-ch: + require.FailNow(t, fmt.Sprintf("received signal when not expected: %v", res)) + case <-time.After(timeout): + } +} + +func mustRecv[T interface{}](t *testing.T, ch <-chan T) T { + select { + case <-time.After(time.Second): + case res := <-ch: + return res + } + require.FailNow(t, "signal not received after waiting for one second") + panic("unreachable") +} + +func TestAggressiveLockingBasic(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + + // TODO: Check aggressive locking is indeed used and the RPC is avoided when doing pessimistic retry. + + tk.MustExec("set @@tidb_pessimistic_txn_aggressive_locking = 1") + tk.MustExec("create table t (id int primary key, k int unique, v int)") + tk.MustExec("insert into t values (1, 1, 1)") + + // Woken up by a rolled back transaction. + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t set v = v + 1 where id = 1") + res := mustExecAsync(tk, "update t set v = v + 1 where id = 1") + mustTimeout(t, res, time.Millisecond*100) + tk2.MustExec("rollback") + mustRecv(t, res) + tk.MustQuery("select * from t").Check(testkit.Rows("1 1 2")) + tk.MustExec("commit") + tk.MustQuery("select * from t").Check(testkit.Rows("1 1 2")) + + // Woken up by a committed transaction. + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t set v = v + 1 where id = 1") + res = mustExecAsync(tk, "update t set v = v + 1 where id = 1") + mustTimeout(t, res, time.Millisecond*100) + tk2.MustExec("commit") + mustRecv(t, res) + tk.MustQuery("select * from t").Check(testkit.Rows("1 1 4")) + tk.MustExec("commit") + tk.MustQuery("select * from t").Check(testkit.Rows("1 1 4")) + + // Lock conflict occurs on the second LockKeys invocation in one statement. + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t set v = v + 1 where id = 1") + res = mustExecAsync(tk, "update t set v = v + 1 where k = 1") + mustTimeout(t, res, time.Millisecond*100) + tk2.MustExec("commit") + mustRecv(t, res) + tk.MustQuery("select * from t").Check(testkit.Rows("1 1 6")) + tk.MustExec("commit") + tk.MustQuery("select * from t").Check(testkit.Rows("1 1 6")) + + // Lock one key (the row key) in aggressive locking mode, and then falls back due to multiple keys needs to be + // locked then (the unique index keys, one deleted and one added). + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t set v = v + 1 where id = 1") + tk2.MustQuery("select * from t where k = 2 for update").Check(testkit.Rows()) + res = mustExecAsync(tk, "update t set k = k + 1 where id = 1") + mustTimeout(t, res, time.Millisecond*100) + tk2.MustExec("commit") + mustRecv(t, res) + tk.MustQuery("select * from t").Check(testkit.Rows("1 2 7")) + tk.MustExec("commit") + tk.MustQuery("select * from t").Check(testkit.Rows("1 2 7")) + + // Test consistency in the RC behavior of DMLs. + tk3 := testkit.NewTestKit(t, store) + tk3.MustExec("use test") + tk.MustExec("insert into t values (3, 3, 4), (4, 4, 4)") + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t set v = v + 1 where id = 3") + res = mustExecAsync(tk, "with c as (select /*+ MERGE() */ * from t where id = 3 for update) update c join t on c.v = t.v set t.v = t.v + 1") + mustTimeout(t, res, time.Millisecond*100) + tk3.MustExec("insert into t values (5, 5, 5)") + tk2.MustExec("commit") + mustRecv(t, res) + tk.MustExec("commit") + tk.MustQuery("select * from t").Check(testkit.Rows("1 2 7", "3 3 6", "4 4 4", "5 5 6")) + + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("select * from t where id = 4 for update") + res = mustExecAsync(tk, "update t set v = v + 1") + mustTimeout(t, res, time.Millisecond*100) + tk3.MustExec("insert into t values (6, 6, 6)") + tk2.MustExec("commit") + mustRecv(t, res) + tk.MustQuery("select * from t").Check(testkit.Rows("1 2 8", "3 3 7", "4 4 5", "5 5 7", "6 6 7")) + tk.MustExec("commit") +} + +func TestAggressiveLockingInsert(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + + tk.MustExec("set @@tidb_pessimistic_txn_aggressive_locking = 1") + tk.MustExec("create table t (id int primary key, v int)") + + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("insert into t values (1, 20)") + ch := make(chan struct{}) + go func() { + tk.MustGetErrCode("insert into t values (1, 10)", errno.ErrDupEntry) + ch <- struct{}{} + }() + mustTimeout(t, ch, time.Millisecond*100) + tk2.MustExec("commit") + mustRecv(t, ch) + tk.MustExec("rollback") + tk.MustQuery("select * from t").Check(testkit.Rows("1 20")) + + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("delete from t where id = 1") + res := mustExecAsync(tk, "insert into t values (1, 10)") + mustTimeout(t, res, time.Millisecond*100) + tk2.MustExec("commit") + mustRecv(t, res) + tk.MustExec("commit") + tk.MustQuery("select * from t").Check(testkit.Rows("1 10")) +} + +func TestAggressiveLockingLockWithConflictIdempotency(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + // Avoid tk2 being affected by the failpoint (but the failpoint will still be triggered).. + tk2.Session().SetConnectionID(0) + tk2.MustExec("use test") + + tk.MustExec("set @@tidb_pessimistic_txn_aggressive_locking = 1") + tk.MustExec("create table t (id int primary key, v int)") + tk.MustExec("insert into t values (1, 1)") + + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t set v = v + 1 where id = 1") + // It's not sure whether `tk`'s pessimistic lock response or `tk2`'s commit response arrives first, so inject twice. + require.NoError(t, failpoint.Enable("tikvclient/rpcFailOnRecv", "2*return")) + res := mustExecAsync(tk, "update t set v = v + 10 where id = 1") + mustTimeout(t, res, time.Millisecond*100) + tk2.MustExec("commit") + mustRecv(t, res) + require.NoError(t, failpoint.Disable("tikvclient/rpcFailOnRecv")) + tk.MustExec("commit") + tk.MustQuery("select * from t").Check(testkit.Rows("1 12")) +} + +func TestAggressiveLockingRetry(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + + mustLocked := func(stmt string) { + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("begin pessimistic") + tk.MustGetErrCode(stmt, errno.ErrLockAcquireFailAndNoWaitSet) + tk.MustExec("rollback") + } + + tk.MustExec("set @@tidb_pessimistic_txn_aggressive_locking = 1") + tk.MustExec("create table t1 (id int primary key, v int)") + tk.MustExec("create table t2 (id int primary key, v int)") + tk.MustExec("create table t3 (id int primary key, v int, v2 int)") + tk.MustExec("insert into t1 values (1, 10)") + tk.MustExec("insert into t2 values (10, 100), (11, 101)") + tk.MustExec("insert into t3 values (100, 100, 100), (101, 200, 200)") + + // Test the case that the locks to acquire didn't change. + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t3 set v2 = v2 + 1 where id = 100") + // It's rare that a statement causes multiple LockKeys invocation and each involves one single key, but it's + // theoretically possible. CTE makes it simple to construct this kind of test cases. + // Let t1's column `v` points to an `id` in t2, and so do t2 and t3. + // The update part is blocked. + res := mustExecAsync(tk, ` + with + c1 as (select /*+ MERGE() */ * from t1 where id = 1), + c2 as (select /*+ MERGE() */ t2.* from c1 join t2 on c1.v = t2.id for update) + update c2 join t3 on c2.v = t3.id set t3.v = t3.v + 1 + `) + mustTimeout(t, res, time.Millisecond*50) + + // Pause on pessimistic retry. + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/pessimisticSelectForUpdateRetry", "pause")) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/pessimisticDMLRetry", "pause")) + tk2.MustExec("commit") + mustTimeout(t, res, time.Millisecond*50) + + // Check that tk didn't release its lock at the time that the stmt retry begins. + mustLocked("select * from t2 where id = 10 for update nowait") + + // Still locked after the retry. + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/pessimisticSelectForUpdateRetry")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/pessimisticDMLRetry")) + mustRecv(t, res) + mustLocked("select * from t2 where id = 10 for update nowait") + + tk.MustExec("commit") + tk.MustQuery("select * from t3").Check(testkit.Rows("100 101 101", "101 200 200")) + + // Test the case that the locks to acquire changes after retry. This is done be letting `tk2` update table `t1` + // which is not locked by the `tk`. + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t3 set v2 = v2 + 1 where id = 100") + res = mustExecAsync(tk, ` + with + c1 as (select /*+ MERGE() */ * from t1 where id = 1), + c2 as (select /*+ MERGE() */ t2.* from c1 join t2 on c1.v = t2.id for update) + update c2 join t3 on c2.v = t3.id set t3.v = t3.v + 1 + `) + mustTimeout(t, res, time.Millisecond*50) + + tk2.MustExec("update t1 set v = 11 where id = 1") + // Pause on pessimistic retry. + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/pessimisticSelectForUpdateRetry", "pause")) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/executor/pessimisticDMLRetry", "pause")) + tk2.MustExec("commit") + mustTimeout(t, res, time.Millisecond*50) + + // Check that tk didn't release its lock at the time that the stmt retry begins. + mustLocked("select * from t2 where id = 10 for update nowait") + + // The lock is released after the pessimistic retry, but the other row is locked instead. + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/pessimisticSelectForUpdateRetry")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/executor/pessimisticDMLRetry")) + mustRecv(t, res) + tk2.MustExec("begin pessimistic") + tk2.MustQuery("select * from t2 where id = 10 for update").Check(testkit.Rows("10 100")) + tk2.MustExec("rollback") + mustLocked("select * from t2 where id = 11 for update nowait") + + tk.MustExec("commit") + tk.MustQuery("select * from t3").Check(testkit.Rows("100 101 102", "101 201 200")) +} + +func TestIssue40114(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + + tk.MustExec("create table t (id int primary key, v int)") + tk.MustExec("insert into t values (1, 1), (2, 2)") + + require.NoError(t, failpoint.Enable("tikvclient/twoPCRequestBatchSizeLimit", "return")) + require.NoError(t, failpoint.Enable("tikvclient/beforeAsyncPessimisticRollback", `return("skip")`)) + defer func() { + require.NoError(t, failpoint.Disable("tikvclient/twoPCRequestBatchSizeLimit")) + require.NoError(t, failpoint.Disable("tikvclient/beforeAsyncPessimisticRollback")) + }() + + tk.MustExec("set @@innodb_lock_wait_timeout = 1") + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + // tk2 block tk on row 2. + tk2.MustExec("update t set v = v + 1 where id = 2") + // tk wait until timeout. + tk.MustGetErrCode("delete from t where id = 1 or id = 2", mysql.ErrLockWaitTimeout) + tk2.MustExec("commit") + // Now, row 1 should have been successfully locked since it's not in the same batch with row 2 (controlled by + // failpoint `twoPCRequestBatchSizeLimit`); then it's not pessimisticRollback-ed (controlled by failpoint + // `beforeAsyncPessimisticRollback`, which simulates a network fault). + // Ensure the row is still locked. + time.Sleep(time.Millisecond * 50) + tk2.MustExec("begin pessimistic") + tk2.MustGetErrCode("select * from t where id = 1 for update nowait", mysql.ErrLockAcquireFailAndNoWaitSet) + tk2.MustExec("rollback") + + // tk is still in transaction. + tk.MustQuery("select @@tidb_current_ts = 0").Check(testkit.Rows("0")) + // This will unexpectedly succeed in issue 40114. + tk.MustGetErrCode("insert into t values (1, 2)", mysql.ErrDupEntry) + tk.MustExec("commit") + tk.MustExec("admin check table t") + tk.MustQuery("select * from t").Check(testkit.Rows("1 1", "2 3")) +} diff --git a/tests/realtikvtest/sessiontest/session_fail_test.go b/tests/realtikvtest/sessiontest/session_fail_test.go index c9f31a228f43e..a3df51be821c0 100644 --- a/tests/realtikvtest/sessiontest/session_fail_test.go +++ b/tests/realtikvtest/sessiontest/session_fail_test.go @@ -197,3 +197,9 @@ func TestAutoCommitNeedNotLinearizability(t *testing.T) { tk.MustExec("COMMIT") }() } + +func TestKill(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("kill connection_id();") +} diff --git a/tests/realtikvtest/testkit.go b/tests/realtikvtest/testkit.go index 080a25958c508..4b8a749e65c9d 100644 --- a/tests/realtikvtest/testkit.go +++ b/tests/realtikvtest/testkit.go @@ -19,6 +19,7 @@ package realtikvtest import ( "flag" "fmt" + "strings" "sync/atomic" "testing" "time" @@ -55,6 +56,7 @@ func RunTestMain(m *testing.M) { tikv.EnableFailpoints() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/tikv/client-go/v2/internal/retry.newBackoffFn.func1"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/v3.waitRetryBackoff"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), @@ -109,8 +111,12 @@ func CreateMockStoreAndDomainAndSetup(t *testing.T, opts ...mockstore.MockTiKVSt tk.MustExec(fmt.Sprintf("set global innodb_lock_wait_timeout = %d", variable.DefInnodbLockWaitTimeout)) tk.MustExec("use test") rs := tk.MustQuery("show tables") + tables := []string{} for _, row := range rs.Rows() { - tk.MustExec(fmt.Sprintf("drop table %s", row[0])) + tables = append(tables, fmt.Sprintf("`%v`", row[0])) + } + if len(tables) > 0 { + tk.MustExec(fmt.Sprintf("drop table %s", strings.Join(tables, ","))) } } else { store, err = mockstore.NewMockStore(opts...) diff --git a/tests/realtikvtest/txntest/txn_state_test.go b/tests/realtikvtest/txntest/txn_state_test.go index 59049dd129151..b8a687a074964 100644 --- a/tests/realtikvtest/txntest/txn_state_test.go +++ b/tests/realtikvtest/txntest/txn_state_test.go @@ -128,14 +128,30 @@ func TestEntriesCountAndSize(t *testing.T) { tk.MustExec("insert into t(a) values (1);") info := tk.Session().TxnInfo() require.Equal(t, uint64(1), info.EntriesCount) - require.Equal(t, uint64(29), info.EntriesSize) tk.MustExec("insert into t(a) values (2);") info = tk.Session().TxnInfo() require.Equal(t, uint64(2), info.EntriesCount) - require.Equal(t, uint64(58), info.EntriesSize) tk.MustExec("commit;") } +func TestMemDBTracker(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + session := tk.Session() + tk.MustExec("use test") + tk.MustExec("create table t (id int)") + tk.MustExec("begin") + for i := 0; i < (1 << 10); i++ { + tk.MustExec("insert t (id) values (1)") + } + require.Less(t, int64(1<<(10+4)), session.GetSessionVars().MemDBFootprint.BytesConsumed()) + require.Greater(t, int64(1<<(14+4)), session.GetSessionVars().MemDBFootprint.BytesConsumed()) + for i := 0; i < (1 << 14); i++ { + tk.MustExec("insert t (id) values (1)") + } + require.Less(t, int64(1<<(14+4)), session.GetSessionVars().MemDBFootprint.BytesConsumed()) +} + func TestRunning(t *testing.T) { store := realtikvtest.CreateMockStoreAndSetup(t) diff --git a/tests/realtikvtest/txntest/txn_test.go b/tests/realtikvtest/txntest/txn_test.go index 1985dc9d29235..908329d32f618 100644 --- a/tests/realtikvtest/txntest/txn_test.go +++ b/tests/realtikvtest/txntest/txn_test.go @@ -203,3 +203,51 @@ func TestWriteConflictMessage(t *testing.T) { require.Contains(t, err.Error(), "tableName=test.t2, handle={hello}") require.Contains(t, err.Error(), "reason=Optimistic") } + +func TestDuplicateErrorMessage(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set @@tx_isolation='read-committed'") + tk2.MustExec("use test") + tk.MustExec("set @@tidb_constraint_check_in_place_pessimistic=off") + tk.MustExec("create table t (c int primary key, v int)") + tk.MustExec("create table t2 (c int primary key, v int)") + tk.MustExec("begin pessimistic") + tk.MustExec("insert into t values (1, 1)") + tk2.MustExec("insert into t values (1, 1)") + tk2.MustExec("insert into t2 values (1, 2)") + tk.MustContainErrMsg("update t set v = v + 1 where c = 1", "Duplicate entry '1' for key 't.PRIMARY'") + + tk.MustExec("create table t3 (c int, v int, unique key i1(v))") + tk.MustExec("create table t4 (c int, v int, unique key i1(v))") + tk.MustExec("begin pessimistic") + tk.MustExec("insert into t3 values (1, 1)") + tk2.MustExec("insert into t3 values (1, 1)") + tk2.MustExec("insert into t4 values (1, 2)") + tk.MustContainErrMsg("update t3 set c = c + 1 where v = 1", "Duplicate entry '1' for key 't3.i1'") +} + +func TestAssertionWhenPessimisticLockLost(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk1 := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk1.MustExec("set @@tidb_constraint_check_in_place_pessimistic=0") + tk1.MustExec("set @@tidb_txn_assertion_level=strict") + tk2.MustExec("set @@tidb_constraint_check_in_place_pessimistic=0") + tk2.MustExec("set @@tidb_txn_assertion_level=strict") + tk1.MustExec("use test") + tk2.MustExec("use test") + tk1.MustExec("create table t (id int primary key, val text)") + tk1.MustExec("begin pessimistic") + tk1.MustExec("select * from t where id = 1 for update") + tk2.MustExec("begin pessimistic") + tk2.MustExec("insert into t values (1, 'b')") + tk2.MustExec("insert into t values (2, 'b')") + tk2.MustExec("commit") + tk1.MustExec("select * from t where id = 2 for update") + tk1.MustExec("insert into t values (1, 'a') on duplicate key update val = concat(val, 'a')") + err := tk1.ExecToErr("commit") + require.NotContains(t, err.Error(), "assertion") +} diff --git a/tidb-binlog/driver/example/kafkaReader/pom.xml b/tidb-binlog/driver/example/kafkaReader/pom.xml index d71b0558e6f5a..ef87a96a80477 100644 --- a/tidb-binlog/driver/example/kafkaReader/pom.xml +++ b/tidb-binlog/driver/example/kafkaReader/pom.xml @@ -29,7 +29,7 @@ org.apache.kafka kafka_2.12 - 3.1.1 + 3.2.3 diff --git a/tidb-server/BUILD.bazel b/tidb-server/BUILD.bazel index b5594261d3ba0..b918b7e1ca5f8 100644 --- a/tidb-server/BUILD.bazel +++ b/tidb-server/BUILD.bazel @@ -12,6 +12,7 @@ go_library( "//domain", "//domain/infosync", "//executor", + "//extension", "//kv", "//metrics", "//parser/mysql", @@ -20,6 +21,7 @@ go_library( "//planner/core", "//plugin", "//privilege/privileges", + "//resourcemanager", "//server", "//session", "//session/txninfo", @@ -27,16 +29,17 @@ go_library( "//sessionctx/variable", "//statistics", "//store", + "//store/copr", "//store/driver", "//store/mockstore", "//store/mockstore/unistore/metrics", "//tidb-binlog/pump_client", "//util", + "//util/chunk", "//util/cpuprofile", "//util/deadlockhistory", "//util/disk", "//util/domainutil", - "//util/gctuner", "//util/kvcache", "//util/logutil", "//util/memory", @@ -86,12 +89,6 @@ go_binary( visibility = ["//visibility:public"], ) -go_binary( - name = "tidb-server-raw", - embed = [":tidb-server_lib"], - visibility = ["//visibility:public"], -) - go_test( name = "tidb-server_test", timeout = "short", diff --git a/tidb-server/main.go b/tidb-server/main.go index 13d7e59f8e3d1..3c8c37d8cbd06 100644 --- a/tidb-server/main.go +++ b/tidb-server/main.go @@ -37,6 +37,7 @@ import ( "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser/mysql" @@ -45,6 +46,7 @@ import ( plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/plugin" "github.com/pingcap/tidb/privilege/privileges" + "github.com/pingcap/tidb/resourcemanager" "github.com/pingcap/tidb/server" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/session/txninfo" @@ -52,16 +54,17 @@ import ( "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics" kvstore "github.com/pingcap/tidb/store" + "github.com/pingcap/tidb/store/copr" "github.com/pingcap/tidb/store/driver" "github.com/pingcap/tidb/store/mockstore" uni_metrics "github.com/pingcap/tidb/store/mockstore/unistore/metrics" pumpcli "github.com/pingcap/tidb/tidb-binlog/pump_client" "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/cpuprofile" "github.com/pingcap/tidb/util/deadlockhistory" "github.com/pingcap/tidb/util/disk" "github.com/pingcap/tidb/util/domainutil" - "github.com/pingcap/tidb/util/gctuner" "github.com/pingcap/tidb/util/kvcache" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/memory" @@ -117,8 +120,11 @@ const ( nmProxyProtocolHeaderTimeout = "proxy-protocol-header-timeout" nmAffinityCPU = "affinity-cpus" - nmInitializeSecure = "initialize-secure" - nmInitializeInsecure = "initialize-insecure" + nmInitializeSecure = "initialize-secure" + nmInitializeInsecure = "initialize-insecure" + nmInitializeSQLFile = "initialize-sql-file" + nmDisconnectOnExpiredPassword = "disconnect-on-expired-password" + nmKeyspaceName = "keyspace-name" ) var ( @@ -162,9 +168,12 @@ var ( proxyProtocolNetworks = flag.String(nmProxyProtocolNetworks, "", "proxy protocol networks allowed IP or *, empty mean disable proxy protocol support") proxyProtocolHeaderTimeout = flag.Uint(nmProxyProtocolHeaderTimeout, 5, "proxy protocol header read timeout, unit is second. (Deprecated: as proxy protocol using lazy mode, header read timeout no longer used)") - // Security - initializeSecure = flagBoolean(nmInitializeSecure, false, "bootstrap tidb-server in secure mode") - initializeInsecure = flagBoolean(nmInitializeInsecure, true, "bootstrap tidb-server in insecure mode") + // Bootstrap and security + initializeSecure = flagBoolean(nmInitializeSecure, false, "bootstrap tidb-server in secure mode") + initializeInsecure = flagBoolean(nmInitializeInsecure, true, "bootstrap tidb-server in insecure mode") + initializeSQLFile = flag.String(nmInitializeSQLFile, "", "SQL file to execute on first bootstrap") + disconnectOnExpiredPassword = flagBoolean(nmDisconnectOnExpiredPassword, true, "the server disconnects the client when the password is expired") + keyspaceName = flag.String(nmKeyspaceName, "", "keyspace name.") ) func main() { @@ -189,6 +198,8 @@ func main() { checkTempStorageQuota() } setupLog() + setupExtensions() + err := cpuprofile.StartCPUProfiler() terror.MustNil(err) @@ -205,9 +216,16 @@ func main() { printInfo() setupBinlogClient() setupMetrics() - setupGCTuner() - storage, dom := createStoreAndDomain() + + keyspaceName := config.GetGlobalKeyspaceName() + + resourcemanager.InstanceResourceManager.Start() + storage, dom := createStoreAndDomain(keyspaceName) svr := createServer(storage, dom) + err = driver.TrySetupGlobalResourceController(context.Background(), dom.ServerID(), storage) + if err != nil { + logutil.BgLogger().Warn("failed to setup global resource controller", zap.Error(err)) + } // Register error API is not thread-safe, the caller MUST NOT register errors after initialization. // To prevent misuse, set a flag to indicate that register new error will panic immediately. @@ -219,6 +237,7 @@ func main() { svr.Close() cleanup(svr, storage, dom, graceful) cpuprofile.StopCPUProfiler() + resourcemanager.InstanceResourceManager.Stop() close(exited) }) topsql.SetupTopSQL() @@ -296,12 +315,18 @@ func registerMetrics() { } } -func createStoreAndDomain() (kv.Storage, *domain.Domain) { +func createStoreAndDomain(keyspaceName string) (kv.Storage, *domain.Domain) { cfg := config.GetGlobalConfig() - fullPath := fmt.Sprintf("%s://%s", cfg.Store, cfg.Path) + var fullPath string + if keyspaceName == "" { + fullPath = fmt.Sprintf("%s://%s", cfg.Store, cfg.Path) + } else { + fullPath = fmt.Sprintf("%s://%s?keyspaceName=%s", cfg.Store, cfg.Path, keyspaceName) + } var err error storage, err := kvstore.New(fullPath) terror.MustNil(err) + copr.GlobalMPPFailedStoreProber.Run() err = infosync.CheckTiKVVersion(storage, *semver.New(versioninfo.TiKVMinVersion)) terror.MustNil(err) // Bootstrap a session to load information schema. @@ -522,7 +547,7 @@ func overrideConfig(cfg *config.Config) { // Sanity check: can't specify both options if actualFlags[nmInitializeSecure] && actualFlags[nmInitializeInsecure] { - err = fmt.Errorf("the options --initialize-insecure and --initialize-secure are mutually exclusive") + err = fmt.Errorf("the options -initialize-insecure and -initialize-secure are mutually exclusive") terror.MustNil(err) } // The option --initialize-secure=true ensures that a secure bootstrap is used. @@ -534,13 +559,30 @@ func overrideConfig(cfg *config.Config) { if actualFlags[nmInitializeInsecure] { cfg.Security.SecureBootstrap = !*initializeInsecure } + if actualFlags[nmDisconnectOnExpiredPassword] { + cfg.Security.DisconnectOnExpiredPassword = *disconnectOnExpiredPassword + } // Secure bootstrap initializes with Socket authentication // which is not supported on windows. Only the insecure bootstrap // method is supported. if runtime.GOOS == "windows" && cfg.Security.SecureBootstrap { - err = fmt.Errorf("the option --initialize-secure is not supported on Windows") + err = fmt.Errorf("the option -initialize-secure is not supported on Windows") terror.MustNil(err) } + // Initialize SQL File is used to run a set of SQL statements after first bootstrap. + // It is important in the use case that you want to set GLOBAL variables, which + // are persisted to the cluster and not read from a config file. + if actualFlags[nmInitializeSQLFile] { + if _, err := os.Stat(*initializeSQLFile); err != nil { + err = fmt.Errorf("can not access -initialize-sql-file %s", *initializeSQLFile) + terror.MustNil(err) + } + cfg.InitializeSQLFile = *initializeSQLFile + } + + if actualFlags[nmKeyspaceName] { + cfg.KeyspaceName = *keyspaceName + } } func setVersions() { @@ -626,8 +668,13 @@ func setGlobalVars() { } plannercore.AllowCartesianProduct.Store(cfg.Performance.CrossJoin) privileges.SkipWithGrant = cfg.Security.SkipGrantTable - kv.TxnTotalSizeLimit = cfg.Performance.TxnTotalSizeLimit - if cfg.Performance.TxnEntrySizeLimit > 120*1024*1024 { + if cfg.Performance.TxnTotalSizeLimit == config.DefTxnTotalSizeLimit { + // practically deprecate the config, let the new session memory tracker take charge of it. + kv.TxnTotalSizeLimit = config.SuperLargeTxnSize + } else { + kv.TxnTotalSizeLimit = cfg.Performance.TxnTotalSizeLimit + } + if cfg.Performance.TxnEntrySizeLimit > config.MaxTxnEntrySizeLimit { log.Fatal("cannot set txn entry size limit larger than 120M") } kv.TxnEntrySizeLimit = cfg.Performance.TxnEntrySizeLimit @@ -638,6 +685,7 @@ func setGlobalVars() { variable.ProcessGeneralLog.Store(cfg.Instance.TiDBGeneralLog) variable.EnablePProfSQLCPU.Store(cfg.Instance.EnablePProfSQLCPU) variable.EnableRCReadCheckTS.Store(cfg.Instance.TiDBRCReadCheckTS) + variable.IsSandBoxModeEnabled.Store(!cfg.Security.DisconnectOnExpiredPassword) atomic.StoreUint32(&variable.DDLSlowOprThreshold, cfg.Instance.DDLSlowOprThreshold) atomic.StoreUint64(&variable.ExpensiveQueryTimeThreshold, cfg.Instance.ExpensiveQueryTimeThreshold) @@ -669,6 +717,7 @@ func setGlobalVars() { variable.SetSysVar(variable.TiDBIsolationReadEngines, strings.Join(cfg.IsolationRead.Engines, ",")) variable.SetSysVar(variable.TiDBEnforceMPPExecution, variable.BoolToOnOff(config.GetGlobalConfig().Performance.EnforceMPP)) variable.MemoryUsageAlarmRatio.Store(cfg.Instance.MemoryUsageAlarmRatio) + variable.SetSysVar(variable.TiDBConstraintCheckInPlacePessimistic, variable.BoolToOnOff(cfg.PessimisticTxn.ConstraintCheckInPlacePessimistic)) if hostname, err := os.Hostname(); err == nil { variable.SetSysVar(variable.Hostname, hostname) } @@ -714,6 +763,7 @@ func setGlobalVars() { deadlockhistory.GlobalDeadlockHistory.Resize(cfg.PessimisticTxn.DeadlockHistoryCapacity) txninfo.Recorder.ResizeSummaries(cfg.TrxSummary.TransactionSummaryCapacity) txninfo.Recorder.SetMinDuration(time.Duration(cfg.TrxSummary.TransactionIDDigestMinDuration) * time.Millisecond) + chunk.InitChunkAllocSize(cfg.TiDBMaxReuseChunk, cfg.TiDBMaxReuseColumn) } func setupLog() { @@ -725,6 +775,16 @@ func setupLog() { util.InternalHTTPClient() } +func setupExtensions() *extension.Extensions { + err := extension.Setup() + terror.MustNil(err) + + extensions, err := extension.GetExtensions() + terror.MustNil(err) + + return extensions +} + func printInfo() { // Make sure the TiDB info is always printed. level := log.GetLevel() @@ -758,16 +818,7 @@ func setupMetrics() { systimeErrHandler := func() { metrics.TimeJumpBackCounter.Inc() } - callBackCount := 0 - successCallBack := func() { - callBackCount++ - // It is callback by monitor per second, we increase metrics.KeepAliveCounter per 5s. - if callBackCount >= 5 { - callBackCount = 0 - metrics.KeepAliveCounter.Inc() - } - } - go systimemon.StartMonitor(time.Now, systimeErrHandler, successCallBack) + go systimemon.StartMonitor(time.Now, systimeErrHandler) pushMetric(cfg.Status.MetricsAddr, time.Duration(cfg.Status.MetricsInterval)*time.Second) } @@ -783,18 +834,10 @@ func setupTracing() { opentracing.SetGlobalTracer(tracer) } -func setupGCTuner() { - limit, err := memory.MemTotal() - if err != nil { - log.Fatal("setupGCTuner failed", zap.Error(err)) - } - threshold := limit * 7 / 10 - gctuner.Tuning(threshold) -} - func closeDomainAndStorage(storage kv.Storage, dom *domain.Domain) { tikv.StoreShuttingDown(1) dom.Close() + copr.GlobalMPPFailedStoreProber.Stop() err := storage.Close() terror.Log(errors.Trace(err)) } @@ -803,6 +846,9 @@ func cleanup(svr *server.Server, storage kv.Storage, dom *domain.Domain, gracefu if graceful { done := make(chan struct{}) svr.GracefulDown(context.Background(), done) + // Kill sys processes such as auto analyze. Otherwise, tidb-server cannot exit until auto analyze is finished. + // See https://github.com/pingcap/tidb/issues/40038 for details. + svr.KillSysProcesses() } else { svr.TryGracefulDown() } diff --git a/tidb-server/main_test.go b/tidb-server/main_test.go index a6a0003aedc65..cb0c53f4d2443 100644 --- a/tidb-server/main_test.go +++ b/tidb-server/main_test.go @@ -33,7 +33,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/tools/check/check-bazel-prepare.sh b/tools/check/check-bazel-prepare.sh new file mode 100755 index 0000000000000..8e9da57fc824b --- /dev/null +++ b/tools/check/check-bazel-prepare.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Copyright 2022 PingCAP, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# set is used to set the environment variables. +# -e: exit immediately when a command returning a non-zero exit code. +# -u: treat unset variables as an error. +# -o pipefail: sets the exit code of a pipeline to that of the rightmost command to exit with a non-zero status, +# or to zero if all commands of the pipeline exit successfully. +set -euo pipefail + +before_checksum=`find . -type f \( -name *.bazel -o -name *.bzl \) -exec md5sum {} \;| sort -k 2` +make bazel_prepare +after_checksum=`find . -type f \( -name *.bazel -o -name *.bzl \) -exec md5sum {} \;| sort -k 2` +if [ "$before_checksum" != "$after_checksum" ] +then + echo "Please run \`make bazel_prepare\` to update \`.bazel\` files" + diff <(echo "$before_checksum") <(echo "$after_checksum") + exit 1 +fi diff --git a/tools/check/revive.toml b/tools/check/revive.toml index aec448993d8e2..59c0fa9ba1710 100644 --- a/tools/check/revive.toml +++ b/tools/check/revive.toml @@ -29,7 +29,7 @@ warningCode = -1 [rule.var-naming] [rule.package-comments] [rule.range] -[rule.receiver-naming] +#[rule.receiver-naming] [rule.indent-error-flow] [rule.superfluous-else] [rule.modifies-parameter] diff --git a/tools/check/ut.go b/tools/check/ut.go index f957f3ea75e94..08b31d243a157 100644 --- a/tools/check/ut.go +++ b/tools/check/ut.go @@ -906,9 +906,12 @@ func listNewTestCases(pkg string) ([]string, error) { // session.test -test.list Test cmd := exec.Command(exe, "-test.list", "Test") cmd.Dir = path.Join(workDir, pkg) - res, err := cmdToLines(cmd) - if err != nil { - return nil, withTrace(err) + var buf bytes.Buffer + cmd.Stdout = &buf + err := cmd.Run() + res := strings.Split(buf.String(), "\n") + if err != nil && len(res) == 0 { + fmt.Println("err ==", err) } return filter(res, func(s string) bool { return strings.HasPrefix(s, "Test") && s != "TestT" && s != "TestBenchDaily" diff --git a/ttl/cache/BUILD.bazel b/ttl/cache/BUILD.bazel new file mode 100644 index 0000000000000..c926ee231cd93 --- /dev/null +++ b/ttl/cache/BUILD.bazel @@ -0,0 +1,69 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "cache", + srcs = [ + "base.go", + "infoschema.go", + "table.go", + "task.go", + "ttlstatus.go", + ], + importpath = "github.com/pingcap/tidb/ttl/cache", + visibility = ["//visibility:public"], + deps = [ + "//infoschema", + "//kv", + "//parser/ast", + "//parser/model", + "//parser/mysql", + "//parser/terror", + "//sessionctx", + "//table/tables", + "//tablecodec", + "//ttl/session", + "//types", + "//util/chunk", + "//util/codec", + "//util/logutil", + "//util/mathutil", + "@com_github_pingcap_errors//:errors", + "@com_github_tikv_client_go_v2//tikv", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "cache_test", + srcs = [ + "base_test.go", + "infoschema_test.go", + "main_test.go", + "split_test.go", + "table_test.go", + "task_test.go", + "ttlstatus_test.go", + ], + embed = [":cache"], + flaky = True, + deps = [ + "//infoschema", + "//kv", + "//parser/model", + "//server", + "//session", + "//store/helper", + "//tablecodec", + "//testkit", + "//testkit/testsetup", + "//ttl/session", + "//types", + "//util/codec", + "@com_github_pingcap_kvproto//pkg/metapb", + "@com_github_stretchr_testify//assert", + "@com_github_stretchr_testify//require", + "@com_github_tikv_client_go_v2//tikv", + "@com_github_tikv_pd_client//:client", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/ttl/cache/base.go b/ttl/cache/base.go new file mode 100644 index 0000000000000..bf23dd8e14bb1 --- /dev/null +++ b/ttl/cache/base.go @@ -0,0 +1,45 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "time" +) + +type baseCache struct { + interval time.Duration + + updateTime time.Time +} + +func newBaseCache(interval time.Duration) baseCache { + return baseCache{ + interval: interval, + } +} + +// ShouldUpdate returns whether this cache needs update +func (bc *baseCache) ShouldUpdate() bool { + return time.Since(bc.updateTime) > bc.interval +} + +// SetInterval sets the interval of updating cache +func (bc *baseCache) SetInterval(interval time.Duration) { + bc.interval = interval +} + +func (bc *baseCache) GetInterval() time.Duration { + return bc.interval +} diff --git a/ttl/cache/base_test.go b/ttl/cache/base_test.go new file mode 100644 index 0000000000000..838cfbbf55329 --- /dev/null +++ b/ttl/cache/base_test.go @@ -0,0 +1,33 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestBaseCache(t *testing.T) { + baseCache := newBaseCache(time.Nanosecond) + time.Sleep(time.Microsecond) + + assert.True(t, baseCache.ShouldUpdate()) + + baseCache.updateTime = time.Now() + baseCache.SetInterval(time.Hour) + assert.False(t, baseCache.ShouldUpdate()) +} diff --git a/ttl/cache/infoschema.go b/ttl/cache/infoschema.go new file mode 100644 index 0000000000000..f68429f5520d4 --- /dev/null +++ b/ttl/cache/infoschema.go @@ -0,0 +1,107 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "time" + + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" +) + +// InfoSchemaCache is the cache for InfoSchema, it builds a map from physical table id to physical table information +type InfoSchemaCache struct { + baseCache + + schemaVer int64 + Tables map[int64]*PhysicalTable +} + +// NewInfoSchemaCache creates the cache for info schema +func NewInfoSchemaCache(updateInterval time.Duration) *InfoSchemaCache { + return &InfoSchemaCache{ + baseCache: newBaseCache(updateInterval), + Tables: make(map[int64]*PhysicalTable), + } +} + +// Update updates the info schema cache +func (isc *InfoSchemaCache) Update(se session.Session) error { + is := se.GetDomainInfoSchema().(infoschema.InfoSchema) + + if isc.schemaVer == is.SchemaMetaVersion() { + return nil + } + + newTables := make(map[int64]*PhysicalTable, len(isc.Tables)) + for _, db := range is.AllSchemas() { + for _, tbl := range is.SchemaTables(db.Name) { + tblInfo := tbl.Meta() + if tblInfo.TTLInfo == nil || !tblInfo.TTLInfo.Enable || tblInfo.State != model.StatePublic { + continue + } + + logger := logutil.BgLogger().With(zap.String("schema", db.Name.L), zap.Int64("tableID", tblInfo.ID), zap.String("tableName", tblInfo.Name.L)) + + if tblInfo.Partition == nil { + ttlTable, err := isc.newTable(db.Name, tblInfo, nil) + if err != nil { + logger.Warn("fail to build info schema cache", zap.Error(err)) + continue + } + newTables[tblInfo.ID] = ttlTable + continue + } + + for _, par := range tblInfo.Partition.Definitions { + par := par + ttlTable, err := isc.newTable(db.Name, tblInfo, &par) + if err != nil { + logger.Warn("fail to build info schema cache", zap.Int64("partitionID", par.ID), zap.String("partition", par.Name.L), zap.Error(err)) + continue + } + newTables[par.ID] = ttlTable + } + } + } + + isc.schemaVer = is.SchemaMetaVersion() + isc.Tables = newTables + isc.updateTime = time.Now() + return nil +} + +func (isc *InfoSchemaCache) newTable(schema model.CIStr, tblInfo *model.TableInfo, par *model.PartitionDefinition) (*PhysicalTable, error) { + id := tblInfo.ID + if par != nil { + id = par.ID + } + + if isc.Tables != nil { + ttlTable, ok := isc.Tables[id] + if ok && ttlTable.TableInfo == tblInfo { + return ttlTable, nil + } + } + + partitionName := model.NewCIStr("") + if par != nil { + partitionName = par.Name + } + return NewPhysicalTable(schema, tblInfo, partitionName) +} diff --git a/ttl/cache/infoschema_test.go b/ttl/cache/infoschema_test.go new file mode 100644 index 0000000000000..ef428e4399c25 --- /dev/null +++ b/ttl/cache/infoschema_test.go @@ -0,0 +1,73 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache_test + +import ( + "testing" + "time" + + "github.com/pingcap/tidb/server" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/stretchr/testify/assert" +) + +func TestInfoSchemaCache(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + sv := server.CreateMockServer(t, store) + sv.SetDomain(dom) + defer sv.Close() + + conn := server.CreateMockConn(t, sv) + sctx := conn.Context().Session + tk := testkit.NewTestKitWithSession(t, store, sctx) + se := session.NewSession(sctx, sctx, func(_ session.Session) {}) + + isc := cache.NewInfoSchemaCache(time.Hour) + + // test should update + assert.True(t, isc.ShouldUpdate()) + assert.NoError(t, isc.Update(se)) + assert.False(t, isc.ShouldUpdate()) + + // test new tables are synced + assert.Equal(t, 0, len(isc.Tables)) + tk.MustExec("create table test.t(created_at datetime) ttl = created_at + INTERVAL 5 YEAR") + assert.NoError(t, isc.Update(se)) + assert.Equal(t, 1, len(isc.Tables)) + for _, table := range isc.Tables { + assert.Equal(t, "t", table.TableInfo.Name.L) + } + + // test new partitioned table are synced + tk.MustExec("drop table test.t") + tk.MustExec(`create table test.t(created_at datetime) + ttl = created_at + INTERVAL 5 YEAR + partition by range (YEAR(created_at)) ( + partition p0 values less than (1991), + partition p1 values less than (2000) + ) + `) + assert.NoError(t, isc.Update(se)) + assert.Equal(t, 2, len(isc.Tables)) + partitions := []string{} + for id, table := range isc.Tables { + assert.Equal(t, "t", table.TableInfo.Name.L) + assert.Equal(t, id, table.PartitionDef.ID) + partitions = append(partitions, table.PartitionDef.Name.L) + } + assert.ElementsMatch(t, []string{"p0", "p1"}, partitions) +} diff --git a/ttl/cache/main_test.go b/ttl/cache/main_test.go new file mode 100644 index 0000000000000..e3846871bb55b --- /dev/null +++ b/ttl/cache/main_test.go @@ -0,0 +1,33 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache_test + +import ( + "testing" + + "github.com/pingcap/tidb/testkit/testsetup" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + testsetup.SetupForCommonTest() + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + } + goleak.VerifyTestMain(m, opts...) +} diff --git a/ttl/cache/split_test.go b/ttl/cache/split_test.go new file mode 100644 index 0000000000000..35638f1d1f409 --- /dev/null +++ b/ttl/cache/split_test.go @@ -0,0 +1,817 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache_test + +import ( + "context" + "fmt" + "math" + "sort" + "testing" + + "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/store/helper" + "github.com/pingcap/tidb/tablecodec" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/codec" + "github.com/stretchr/testify/require" + "github.com/tikv/client-go/v2/tikv" + pd "github.com/tikv/pd/client" +) + +func newMockRegion(regionID uint64, startKey []byte, endKey []byte) *pd.Region { + leader := &metapb.Peer{ + Id: regionID, + StoreId: 1, + Role: metapb.PeerRole_Voter, + } + + return &pd.Region{ + Meta: &metapb.Region{ + Id: regionID, + StartKey: startKey, + EndKey: endKey, + Peers: []*metapb.Peer{leader}, + }, + Leader: leader, + } +} + +type mockPDClient struct { + t *testing.T + pd.Client + regions []*pd.Region + regionsSorted bool +} + +func (c *mockPDClient) ScanRegions(_ context.Context, key, endKey []byte, limit int) ([]*pd.Region, error) { + if len(c.regions) == 0 { + return []*pd.Region{newMockRegion(1, []byte{}, []byte{0xFF, 0xFF})}, nil + } + + if !c.regionsSorted { + sort.Slice(c.regions, func(i, j int) bool { + return kv.Key(c.regions[i].Meta.StartKey).Cmp(c.regions[j].Meta.StartKey) < 0 + }) + c.regionsSorted = true + } + + regions := []*pd.Region{newMockRegion(1, []byte{}, c.regions[0].Meta.StartKey)} + regions = append(regions, c.regions...) + regions = append(regions, newMockRegion(2, c.regions[len(c.regions)-1].Meta.EndKey, []byte{0xFF, 0xFF, 0xFF})) + + result := make([]*pd.Region, 0) + for _, r := range regions { + if kv.Key(r.Meta.StartKey).Cmp(endKey) >= 0 { + continue + } + + if kv.Key(r.Meta.EndKey).Cmp(key) <= 0 { + continue + } + + if len(result) >= limit { + break + } + + result = append(result, r) + } + return result, nil +} + +func (c *mockPDClient) GetStore(_ context.Context, storeID uint64) (*metapb.Store, error) { + return &metapb.Store{ + Id: storeID, + Address: fmt.Sprintf("127.0.0.%d", storeID), + }, nil +} + +type mockTiKVStore struct { + t *testing.T + helper.Storage + pdClient *mockPDClient + cache *tikv.RegionCache + nextRegionID uint64 +} + +func newMockTiKVStore(t *testing.T) *mockTiKVStore { + pdClient := &mockPDClient{t: t} + s := &mockTiKVStore{ + t: t, + pdClient: pdClient, + cache: tikv.NewRegionCache(pdClient), + nextRegionID: 1000, + } + s.refreshCache() + t.Cleanup(func() { + s.cache.Close() + }) + return s +} + +func (s *mockTiKVStore) addFullTableRegion(tableID ...int64) *mockTiKVStore { + prefix1 := tablecodec.GenTablePrefix(tableID[0]) + prefix2 := tablecodec.GenTablePrefix(tableID[len(tableID)-1]) + return s.addRegion(prefix1, prefix2.PrefixNext()) +} + +func (s *mockTiKVStore) addRegionBeginWithTablePrefix(tableID int64, handle kv.Handle) *mockTiKVStore { + start := tablecodec.GenTablePrefix(tableID) + end := tablecodec.EncodeRowKeyWithHandle(tableID, handle) + return s.addRegion(start, end) +} + +func (s *mockTiKVStore) addRegionEndWithTablePrefix(handle kv.Handle, tableID int64) *mockTiKVStore { + start := tablecodec.EncodeRowKeyWithHandle(tableID, handle) + end := tablecodec.GenTablePrefix(tableID + 1) + return s.addRegion(start, end) +} + +func (s *mockTiKVStore) addRegionWithTablePrefix(tableID int64, start kv.Handle, end kv.Handle) *mockTiKVStore { + startKey := tablecodec.EncodeRowKeyWithHandle(tableID, start) + endKey := tablecodec.EncodeRowKeyWithHandle(tableID, end) + return s.addRegion(startKey, endKey) +} + +func (s *mockTiKVStore) addRegion(key, endKey []byte) *mockTiKVStore { + require.True(s.t, kv.Key(endKey).Cmp(key) > 0) + if len(s.pdClient.regions) > 0 { + lastRegion := s.pdClient.regions[len(s.pdClient.regions)-1] + require.True(s.t, kv.Key(endKey).Cmp(lastRegion.Meta.EndKey) >= 0) + } + + regionID := s.nextRegionID + s.nextRegionID++ + leader := &metapb.Peer{ + Id: regionID, + StoreId: 1, + Role: metapb.PeerRole_Voter, + } + + s.pdClient.regions = append(s.pdClient.regions, &pd.Region{ + Meta: &metapb.Region{ + Id: regionID, + StartKey: key, + EndKey: endKey, + Peers: []*metapb.Peer{leader}, + }, + Leader: leader, + }) + + s.pdClient.regionsSorted = false + s.refreshCache() + return s +} + +func (s *mockTiKVStore) refreshCache() { + _, err := s.cache.LoadRegionsInKeyRange( + tikv.NewBackofferWithVars(context.Background(), 1000, nil), + []byte{}, + []byte{0xFF}, + ) + require.NoError(s.t, err) +} + +func (s *mockTiKVStore) batchAddIntHandleRegions(tblID int64, regionCnt int, regionSize int, offset int64) (end kv.IntHandle) { + for i := 0; i < regionCnt; i++ { + start := kv.IntHandle(offset + int64(i*regionSize)) + end = kv.IntHandle(start.IntValue() + int64(regionSize)) + s.addRegionWithTablePrefix(tblID, start, end) + } + return +} + +func (s *mockTiKVStore) clearRegions() { + s.pdClient.regions = nil + s.cache.Close() + s.cache = tikv.NewRegionCache(s.pdClient) + s.refreshCache() +} + +func (s *mockTiKVStore) newCommonHandle(ds ...types.Datum) *kv.CommonHandle { + encoded, err := codec.EncodeKey(nil, nil, ds...) + require.NoError(s.t, err) + h, err := kv.NewCommonHandle(encoded) + require.NoError(s.t, err) + return h +} + +func (s *mockTiKVStore) GetRegionCache() *tikv.RegionCache { + return s.cache +} + +func bytesHandle(t *testing.T, data []byte) kv.Handle { + encoded, err := codec.EncodeKey(nil, nil, types.NewBytesDatum(data)) + require.NoError(t, err) + h, err := kv.NewCommonHandle(encoded) + require.NoError(t, err) + return h +} + +func createTTLTable(t *testing.T, tk *testkit.TestKit, name string, option string) *cache.PhysicalTable { + if option == "" { + return createTTLTableWithSQL(t, tk, name, fmt.Sprintf("create table test.%s(t timestamp) TTL = `t` + interval 1 day", name)) + } + + return createTTLTableWithSQL(t, tk, name, fmt.Sprintf("create table test.%s(id %s primary key, t timestamp) TTL = `t` + interval 1 day", name, option)) +} + +func create2PKTTLTable(t *testing.T, tk *testkit.TestKit, name string, option string) *cache.PhysicalTable { + return createTTLTableWithSQL(t, tk, name, fmt.Sprintf("create table test.%s(id %s, id2 int, t timestamp, primary key(id, id2)) TTL = `t` + interval 1 day", name, option)) +} + +func createTTLTableWithSQL(t *testing.T, tk *testkit.TestKit, name string, sql string) *cache.PhysicalTable { + tk.MustExec(sql) + is, ok := tk.Session().GetDomainInfoSchema().(infoschema.InfoSchema) + require.True(t, ok) + tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr(name)) + require.NoError(t, err) + ttlTbl, err := cache.NewPhysicalTable(model.NewCIStr("test"), tbl.Meta(), model.NewCIStr("")) + require.NoError(t, err) + return ttlTbl +} + +func checkRange(t *testing.T, r cache.ScanRange, start, end types.Datum) { + if start.IsNull() { + require.Nil(t, r.Start) + } else { + require.Equal(t, 1, len(r.Start)) + require.Equal(t, start.Kind(), r.Start[0].Kind()) + require.Equal(t, start.GetValue(), r.Start[0].GetValue()) + } + + if end.IsNull() { + require.Nil(t, r.End) + } else { + require.Equal(t, 1, len(r.End)) + require.Equal(t, end.Kind(), r.End[0].Kind()) + require.Equal(t, end.GetValue(), r.End[0].GetValue()) + } +} + +func TestSplitTTLScanRangesWithSignedInt(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tbls := []*cache.PhysicalTable{ + createTTLTable(t, tk, "t1", "tinyint"), + createTTLTable(t, tk, "t2", "smallint"), + createTTLTable(t, tk, "t3", "mediumint"), + createTTLTable(t, tk, "t4", "int"), + createTTLTable(t, tk, "t5", "bigint"), + createTTLTable(t, tk, "t6", ""), // no clustered + create2PKTTLTable(t, tk, "t7", "tinyint"), + } + + tikvStore := newMockTiKVStore(t) + for _, tbl := range tbls { + // test only one region + tikvStore.clearRegions() + ranges, err := tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test share regions with other table + tikvStore.clearRegions() + tikvStore.addRegion( + tablecodec.GenTablePrefix(tbl.ID-1), + tablecodec.GenTablePrefix(tbl.ID+1), + ) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test one table has multiple regions + tikvStore.clearRegions() + tikvStore.addRegionBeginWithTablePrefix(tbl.ID, kv.IntHandle(0)) + end := tikvStore.batchAddIntHandleRegions(tbl.ID, 8, 100, 0) + tikvStore.addRegionEndWithTablePrefix(end, tbl.ID) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 4, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.NewIntDatum(200)) + checkRange(t, ranges[1], types.NewIntDatum(200), types.NewIntDatum(500)) + checkRange(t, ranges[2], types.NewIntDatum(500), types.NewIntDatum(700)) + checkRange(t, ranges[3], types.NewIntDatum(700), types.Datum{}) + + // test one table has multiple regions and one table region across 0 + tikvStore.clearRegions() + tikvStore.addRegionBeginWithTablePrefix(tbl.ID, kv.IntHandle(-350)) + end = tikvStore.batchAddIntHandleRegions(tbl.ID, 8, 100, -350) + tikvStore.addRegionEndWithTablePrefix(end, tbl.ID) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 5) + require.NoError(t, err) + require.Equal(t, 5, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.NewIntDatum(-250)) + checkRange(t, ranges[1], types.NewIntDatum(-250), types.NewIntDatum(-50)) + checkRange(t, ranges[2], types.NewIntDatum(-50), types.NewIntDatum(150)) + checkRange(t, ranges[3], types.NewIntDatum(150), types.NewIntDatum(350)) + checkRange(t, ranges[4], types.NewIntDatum(350), types.Datum{}) + } +} + +func TestSplitTTLScanRangesWithUnsignedInt(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tbls := []*cache.PhysicalTable{ + createTTLTable(t, tk, "t1", "tinyint unsigned"), + createTTLTable(t, tk, "t2", "smallint unsigned"), + createTTLTable(t, tk, "t3", "mediumint unsigned"), + createTTLTable(t, tk, "t4", "int unsigned"), + createTTLTable(t, tk, "t5", "bigint unsigned"), + create2PKTTLTable(t, tk, "t6", "tinyint unsigned"), + } + + tikvStore := newMockTiKVStore(t) + for _, tbl := range tbls { + // test only one region + tikvStore.clearRegions() + ranges, err := tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test share regions with other table + tikvStore.clearRegions() + tikvStore.addRegion( + tablecodec.GenTablePrefix(tbl.ID-1), + tablecodec.GenTablePrefix(tbl.ID+1), + ) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test one table has multiple regions: [MinInt64, a) [a, b) [b, 0) [0, c) [c, d) [d, MaxInt64] + tikvStore.clearRegions() + tikvStore.addRegionBeginWithTablePrefix(tbl.ID, kv.IntHandle(-200)) + end := tikvStore.batchAddIntHandleRegions(tbl.ID, 4, 100, -200) + tikvStore.addRegionEndWithTablePrefix(end, tbl.ID) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 6) + require.NoError(t, err) + require.Equal(t, 6, len(ranges)) + checkRange(t, ranges[0], types.NewUintDatum(uint64(math.MaxInt64)+1), types.NewUintDatum(uint64(math.MaxUint64)-199)) + checkRange(t, ranges[1], types.NewUintDatum(uint64(math.MaxUint64)-199), types.NewUintDatum(uint64(math.MaxUint64)-99)) + checkRange(t, ranges[2], types.NewUintDatum(uint64(math.MaxUint64)-99), types.Datum{}) + checkRange(t, ranges[3], types.Datum{}, types.NewUintDatum(100)) + checkRange(t, ranges[4], types.NewUintDatum(100), types.NewUintDatum(200)) + checkRange(t, ranges[5], types.NewUintDatum(200), types.NewUintDatum(uint64(math.MaxInt64)+1)) + + // test one table has multiple regions: [MinInt64, a) [a, b) [b, c) [c, d) [d, MaxInt64], b < 0 < c + tikvStore.clearRegions() + tikvStore.addRegionBeginWithTablePrefix(tbl.ID, kv.IntHandle(-150)) + end = tikvStore.batchAddIntHandleRegions(tbl.ID, 3, 100, -150) + tikvStore.addRegionEndWithTablePrefix(end, tbl.ID) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 5) + require.NoError(t, err) + require.Equal(t, 6, len(ranges)) + checkRange(t, ranges[0], types.NewUintDatum(uint64(math.MaxInt64)+1), types.NewUintDatum(uint64(math.MaxUint64)-149)) + checkRange(t, ranges[1], types.NewUintDatum(uint64(math.MaxUint64)-149), types.NewUintDatum(uint64(math.MaxUint64)-49)) + checkRange(t, ranges[2], types.NewUintDatum(uint64(math.MaxUint64)-49), types.Datum{}) + checkRange(t, ranges[3], types.Datum{}, types.NewUintDatum(50)) + checkRange(t, ranges[4], types.NewUintDatum(50), types.NewUintDatum(150)) + checkRange(t, ranges[5], types.NewUintDatum(150), types.NewUintDatum(uint64(math.MaxInt64)+1)) + } +} + +func TestSplitTTLScanRangesWithBytes(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tbls := []*cache.PhysicalTable{ + createTTLTable(t, tk, "t1", "binary(32)"), + createTTLTable(t, tk, "t2", "char(32) CHARACTER SET BINARY"), + createTTLTable(t, tk, "t3", "varchar(32) CHARACTER SET BINARY"), + createTTLTable(t, tk, "t4", "bit(32)"), + create2PKTTLTable(t, tk, "t5", "binary(32)"), + } + + tikvStore := newMockTiKVStore(t) + for _, tbl := range tbls { + // test only one region + tikvStore.clearRegions() + ranges, err := tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test share regions with other table + tikvStore.clearRegions() + tikvStore.addRegion( + tablecodec.GenTablePrefix(tbl.ID-1), + tablecodec.GenTablePrefix(tbl.ID+1), + ) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test one table has multiple regions + tikvStore.clearRegions() + tikvStore.addRegionBeginWithTablePrefix(tbl.ID, bytesHandle(t, []byte{1, 2, 3})) + tikvStore.addRegionWithTablePrefix(tbl.ID, bytesHandle(t, []byte{1, 2, 3}), bytesHandle(t, []byte{1, 2, 3, 4})) + tikvStore.addRegionWithTablePrefix(tbl.ID, bytesHandle(t, []byte{1, 2, 3, 4}), bytesHandle(t, []byte{1, 2, 3, 4, 5})) + tikvStore.addRegionWithTablePrefix(tbl.ID, bytesHandle(t, []byte{1, 2, 3, 4, 5}), bytesHandle(t, []byte{1, 2, 4})) + tikvStore.addRegionWithTablePrefix(tbl.ID, bytesHandle(t, []byte{1, 2, 4}), bytesHandle(t, []byte{1, 2, 5})) + tikvStore.addRegionEndWithTablePrefix(bytesHandle(t, []byte{1, 2, 5}), tbl.ID) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 4, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.NewBytesDatum([]byte{1, 2, 3, 4})) + checkRange(t, ranges[1], types.NewBytesDatum([]byte{1, 2, 3, 4}), types.NewBytesDatum([]byte{1, 2, 4})) + checkRange(t, ranges[2], types.NewBytesDatum([]byte{1, 2, 4}), types.NewBytesDatum([]byte{1, 2, 5})) + checkRange(t, ranges[3], types.NewBytesDatum([]byte{1, 2, 5}), types.Datum{}) + } +} + +func TestNoTTLSplitSupportTables(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tbls := []*cache.PhysicalTable{ + createTTLTable(t, tk, "t1", "char(32) CHARACTER SET UTF8MB4"), + createTTLTable(t, tk, "t2", "varchar(32) CHARACTER SET UTF8MB4"), + createTTLTable(t, tk, "t4", "decimal(32, 2)"), + create2PKTTLTable(t, tk, "t5", "char(32) CHARACTER SET UTF8MB4"), + } + + tikvStore := newMockTiKVStore(t) + for _, tbl := range tbls { + // test only one region + tikvStore.clearRegions() + ranges, err := tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test share regions with other table + tikvStore.clearRegions() + tikvStore.addRegion( + tablecodec.GenTablePrefix(tbl.ID-1), + tablecodec.GenTablePrefix(tbl.ID+1), + ) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 4) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + + // test one table has multiple regions + tikvStore.clearRegions() + tikvStore.addRegionBeginWithTablePrefix(tbl.ID, bytesHandle(t, []byte{1, 2, 3})) + tikvStore.addRegionWithTablePrefix(tbl.ID, bytesHandle(t, []byte{1, 2, 3}), bytesHandle(t, []byte{1, 2, 3, 4})) + tikvStore.addRegionEndWithTablePrefix(bytesHandle(t, []byte{1, 2, 3, 4}), tbl.ID) + ranges, err = tbl.SplitScanRanges(context.TODO(), tikvStore, 3) + require.NoError(t, err) + require.Equal(t, 1, len(ranges)) + checkRange(t, ranges[0], types.Datum{}, types.Datum{}) + } +} + +func TestGetNextBytesHandleDatum(t *testing.T) { + tblID := int64(7) + buildHandleBytes := func(data []byte) []byte { + handleBytes, err := codec.EncodeKey(nil, nil, types.NewBytesDatum(data)) + require.NoError(t, err) + return handleBytes + } + + buildRowKey := func(handleBytes []byte) kv.Key { + return tablecodec.EncodeRowKey(tblID, handleBytes) + } + + buildBytesRowKey := func(data []byte) kv.Key { + return buildRowKey(buildHandleBytes(data)) + } + + binaryDataStartPos := len(tablecodec.GenTableRecordPrefix(tblID)) + 1 + cases := []struct { + key interface{} + result []byte + isNull bool + }{ + { + key: buildBytesRowKey([]byte{}), + result: []byte{}, + }, + { + key: buildBytesRowKey([]byte{1, 2, 3}), + result: []byte{1, 2, 3}, + }, + { + key: buildBytesRowKey([]byte{1, 2, 3, 0}), + result: []byte{1, 2, 3, 0}, + }, + { + key: buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8}), + result: []byte{1, 2, 3, 4, 5, 6, 7, 8}, + }, + { + key: buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9}), + result: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + { + key: buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 0}), + result: []byte{1, 2, 3, 4, 5, 6, 7, 8, 0}, + }, + { + key: append(buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 0}), 0), + result: []byte{1, 2, 3, 4, 5, 6, 7, 8, 0, 0}, + }, + { + key: append(buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 0}), 1), + result: []byte{1, 2, 3, 4, 5, 6, 7, 8, 0, 0}, + }, + { + key: []byte{}, + result: []byte{}, + }, + { + key: tablecodec.GenTableRecordPrefix(tblID), + result: []byte{}, + }, + { + key: tablecodec.GenTableRecordPrefix(tblID - 1), + result: []byte{}, + }, + { + key: tablecodec.GenTablePrefix(tblID).PrefixNext(), + isNull: true, + }, + { + key: buildRowKey([]byte{0}), + result: []byte{}, + }, + { + key: buildRowKey([]byte{1}), + result: []byte{}, + }, + { + key: buildRowKey([]byte{2}), + isNull: true, + }, + { + // recordPrefix + bytesFlag + [0] + key: buildBytesRowKey([]byte{})[:binaryDataStartPos+1], + result: []byte{}, + }, + { + // recordPrefix + bytesFlag + [0, 0, 0, 0, 0, 0, 0, 0] + key: buildBytesRowKey([]byte{})[:binaryDataStartPos+8], + result: []byte{}, + }, + { + // recordPrefix + bytesFlag + [1] + key: buildBytesRowKey([]byte{1, 2, 3})[:binaryDataStartPos+1], + result: []byte{1}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3] + key: buildBytesRowKey([]byte{1, 2, 3})[:binaryDataStartPos+3], + result: []byte{1, 2, 3}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 0] + key: buildBytesRowKey([]byte{1, 2, 3})[:binaryDataStartPos+4], + result: []byte{1, 2, 3}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 0, 0, 0, 0, 0, 247] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3}) + bs[len(bs)-1] = 247 + return bs + }, + result: []byte{1, 2, 3}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 0, 0, 0, 0, 0, 0] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3}) + bs[len(bs)-1] = 0 + return bs + }, + result: []byte{1, 2, 3}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 8, 254, 9, 0, 0, 0, 0, 0, 0, 0, 248] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9}) + bs[len(bs)-10] = 254 + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7, 8}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 0, 254, 9, 0, 0, 0, 0, 0, 0, 0, 248] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 0, 9}) + bs[len(bs)-10] = 254 + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7, 0}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 0, 253, 9, 0, 0, 0, 0, 0, 0, 0, 248] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 0, 9}) + bs[len(bs)-10] = 253 + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 8, 255, 9, 0, 0, 0, 0, 0, 0, 0, 247] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9}) + bs[len(bs)-1] = 247 + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 8, 255, 9, 0, 0, 0, 0, 0, 0, 0, 0] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9}) + bs[len(bs)-1] = 0 + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 8, 255, 9, 0, 0, 0, 0, 0, 0, 0] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9}) + bs = bs[:len(bs)-1] + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 8, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8}) + bs = bs[:len(bs)-1] + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7, 8}, + }, + { + // recordPrefix + bytesFlag + [1, 2, 3, 4, 5, 6, 7, 8, 255, 0, 0, 0, 0, 0, 0, 0, 0, 246] + key: func() []byte { + bs := buildBytesRowKey([]byte{1, 2, 3, 4, 5, 6, 7, 8}) + bs = bs[:len(bs)-1] + return bs + }, + result: []byte{1, 2, 3, 4, 5, 6, 7, 8}, + }, + } + + for i, c := range cases { + var key kv.Key + switch k := c.key.(type) { + case kv.Key: + key = k + case []byte: + key = k + case func() []byte: + key = k() + case func() kv.Key: + key = k() + default: + require.FailNow(t, "%d", i) + } + + d := cache.GetNextBytesHandleDatum(key, tablecodec.GenTableRecordPrefix(tblID)) + if c.isNull { + require.True(t, d.IsNull(), i) + } else { + require.Equal(t, types.KindBytes, d.Kind(), i) + require.Equal(t, c.result, d.GetBytes(), i) + } + } +} +func TestGetNextIntHandle(t *testing.T) { + tblID := int64(7) + cases := []struct { + key interface{} + result int64 + isNull bool + }{ + { + key: tablecodec.EncodeRowKeyWithHandle(tblID, kv.IntHandle(0)), + result: 0, + }, + { + key: tablecodec.EncodeRowKeyWithHandle(tblID, kv.IntHandle(3)), + result: 3, + }, + { + key: tablecodec.EncodeRowKeyWithHandle(tblID, kv.IntHandle(math.MaxInt64)), + result: math.MaxInt64, + }, + { + key: tablecodec.EncodeRowKeyWithHandle(tblID, kv.IntHandle(math.MinInt64)), + result: math.MinInt64, + }, + { + key: append(tablecodec.EncodeRowKeyWithHandle(tblID, kv.IntHandle(7)), 0), + result: 8, + }, + { + key: append(tablecodec.EncodeRowKeyWithHandle(tblID, kv.IntHandle(math.MaxInt64)), 0), + isNull: true, + }, + { + key: append(tablecodec.EncodeRowKeyWithHandle(tblID, kv.IntHandle(math.MinInt64)), 0), + result: math.MinInt64 + 1, + }, + { + key: []byte{}, + result: math.MinInt64, + }, + { + key: tablecodec.GenTableRecordPrefix(tblID), + result: math.MinInt64, + }, + { + key: tablecodec.GenTableRecordPrefix(tblID - 1), + result: math.MinInt64, + }, + { + key: tablecodec.GenTablePrefix(tblID).PrefixNext(), + isNull: true, + }, + { + key: tablecodec.EncodeRowKey(tblID, []byte{0}), + result: codec.DecodeCmpUintToInt(0), + }, + { + key: tablecodec.EncodeRowKey(tblID, []byte{0, 1, 2, 3}), + result: codec.DecodeCmpUintToInt(0x0001020300000000), + }, + { + key: tablecodec.EncodeRowKey(tblID, []byte{8, 1, 2, 3}), + result: codec.DecodeCmpUintToInt(0x0801020300000000), + }, + { + key: tablecodec.EncodeRowKey(tblID, []byte{0, 1, 2, 3, 4, 5, 6, 7, 0}), + result: codec.DecodeCmpUintToInt(0x0001020304050607) + 1, + }, + { + key: tablecodec.EncodeRowKey(tblID, []byte{8, 1, 2, 3, 4, 5, 6, 7, 0}), + result: codec.DecodeCmpUintToInt(0x0801020304050607) + 1, + }, + { + key: tablecodec.EncodeRowKey(tblID, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}), + result: math.MaxInt64, + }, + { + key: tablecodec.EncodeRowKey(tblID, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0}), + isNull: true, + }, + } + + for i, c := range cases { + var key kv.Key + switch k := c.key.(type) { + case kv.Key: + key = k + case []byte: + key = k + case func() []byte: + key = k() + case func() kv.Key: + key = k() + default: + require.FailNow(t, "%d", i) + } + + v := cache.GetNextIntHandle(key, tablecodec.GenTableRecordPrefix(tblID)) + if c.isNull { + require.Nil(t, v, i) + } else { + require.IsType(t, kv.IntHandle(0), v, i) + require.Equal(t, c.result, v.IntValue()) + } + } +} diff --git a/ttl/cache/table.go b/ttl/cache/table.go new file mode 100644 index 0000000000000..35aca7f8532b2 --- /dev/null +++ b/ttl/cache/table.go @@ -0,0 +1,473 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "context" + "encoding/binary" + "fmt" + "math" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/table/tables" + "github.com/pingcap/tidb/tablecodec" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/mathutil" + "github.com/tikv/client-go/v2/tikv" +) + +func getTableKeyColumns(tbl *model.TableInfo) ([]*model.ColumnInfo, []*types.FieldType, error) { + if tbl.PKIsHandle { + for i, col := range tbl.Columns { + if mysql.HasPriKeyFlag(col.GetFlag()) { + return []*model.ColumnInfo{tbl.Columns[i]}, []*types.FieldType{&tbl.Columns[i].FieldType}, nil + } + } + return nil, nil, errors.Errorf("Cannot find primary key for table: %s", tbl.Name) + } + + if tbl.IsCommonHandle { + idxInfo := tables.FindPrimaryIndex(tbl) + columns := make([]*model.ColumnInfo, len(idxInfo.Columns)) + fieldTypes := make([]*types.FieldType, len(idxInfo.Columns)) + for i, idxCol := range idxInfo.Columns { + columns[i] = tbl.Columns[idxCol.Offset] + fieldTypes[i] = &tbl.Columns[idxCol.Offset].FieldType + } + return columns, fieldTypes, nil + } + + extraHandleColInfo := model.NewExtraHandleColInfo() + return []*model.ColumnInfo{extraHandleColInfo}, []*types.FieldType{&extraHandleColInfo.FieldType}, nil +} + +// ScanRange is the range to scan. The range is: [Start, End) +type ScanRange struct { + Start []types.Datum + End []types.Datum +} + +func newFullRange() ScanRange { + return ScanRange{} +} + +func newDatumRange(start types.Datum, end types.Datum) (r ScanRange) { + if !start.IsNull() { + r.Start = []types.Datum{start} + } + if !end.IsNull() { + r.End = []types.Datum{end} + } + return r +} + +func nullDatum() types.Datum { + d := types.Datum{} + d.SetNull() + return d +} + +// PhysicalTable is used to provide some information for a physical table in TTL job +type PhysicalTable struct { + // ID is the physical ID of the table + ID int64 + // Schema is the database name of the table + Schema model.CIStr + *model.TableInfo + // Partition is the partition name + Partition model.CIStr + // PartitionDef is the partition definition + PartitionDef *model.PartitionDefinition + // KeyColumns is the cluster index key columns for the table + KeyColumns []*model.ColumnInfo + // KeyColumnTypes is the types of the key columns + KeyColumnTypes []*types.FieldType + // TimeColum is the time column used for TTL + TimeColumn *model.ColumnInfo +} + +// NewPhysicalTable create a new PhysicalTable +func NewPhysicalTable(schema model.CIStr, tbl *model.TableInfo, partition model.CIStr) (*PhysicalTable, error) { + if tbl.State != model.StatePublic { + return nil, errors.Errorf("table '%s.%s' is not a public table", schema, tbl.Name) + } + + ttlInfo := tbl.TTLInfo + if ttlInfo == nil { + return nil, errors.Errorf("table '%s.%s' is not a ttl table", schema, tbl.Name) + } + + timeColumn := tbl.FindPublicColumnByName(ttlInfo.ColumnName.L) + if timeColumn == nil { + return nil, errors.Errorf("time column '%s' is not public in ttl table '%s.%s'", ttlInfo.ColumnName, schema, tbl.Name) + } + + keyColumns, keyColumTypes, err := getTableKeyColumns(tbl) + if err != nil { + return nil, err + } + + var physicalID int64 + var partitionDef *model.PartitionDefinition + if tbl.Partition == nil { + if partition.L != "" { + return nil, errors.Errorf("table '%s.%s' is not a partitioned table", schema, tbl.Name) + } + physicalID = tbl.ID + } else { + if partition.L == "" { + return nil, errors.Errorf("partition name is required, table '%s.%s' is a partitioned table", schema, tbl.Name) + } + + for i := range tbl.Partition.Definitions { + def := &tbl.Partition.Definitions[i] + if def.Name.L == partition.L { + partitionDef = def + } + } + + if partitionDef == nil { + return nil, errors.Errorf("partition '%s' is not found in ttl table '%s.%s'", partition.O, schema, tbl.Name) + } + + physicalID = partitionDef.ID + } + + return &PhysicalTable{ + ID: physicalID, + Schema: schema, + TableInfo: tbl, + Partition: partition, + PartitionDef: partitionDef, + KeyColumns: keyColumns, + KeyColumnTypes: keyColumTypes, + TimeColumn: timeColumn, + }, nil +} + +// ValidateKeyPrefix validates a key prefix +func (t *PhysicalTable) ValidateKeyPrefix(key []types.Datum) error { + if len(key) > len(t.KeyColumns) { + return errors.Errorf("invalid key length: %d, expected %d", len(key), len(t.KeyColumns)) + } + return nil +} + +// EvalExpireTime returns the expired time +func (t *PhysicalTable) EvalExpireTime(ctx context.Context, se session.Session, now time.Time) (expire time.Time, err error) { + tz := se.GetSessionVars().Location() + + expireExpr := t.TTLInfo.IntervalExprStr + unit := ast.TimeUnitType(t.TTLInfo.IntervalTimeUnit) + + var rows []chunk.Row + rows, err = se.ExecuteSQL( + ctx, + // FROM_UNIXTIME does not support negative value, so we use `FROM_UNIXTIME(0) + INTERVAL ` to present current time + fmt.Sprintf("SELECT FROM_UNIXTIME(0) + INTERVAL %d SECOND - INTERVAL %s %s", now.Unix(), expireExpr, unit.String()), + ) + + if err != nil { + return + } + + tm := rows[0].GetTime(0) + return tm.CoreTime().GoTime(tz) +} + +// SplitScanRanges split ranges for TTL scan +func (t *PhysicalTable) SplitScanRanges(ctx context.Context, store kv.Storage, splitCnt int) ([]ScanRange, error) { + if len(t.KeyColumns) < 1 || splitCnt <= 1 { + return []ScanRange{newFullRange()}, nil + } + + tikvStore, ok := store.(tikv.Storage) + if !ok { + return []ScanRange{newFullRange()}, nil + } + + ft := t.KeyColumns[0].FieldType + switch ft.GetType() { + case mysql.TypeTiny, mysql.TypeShort, mysql.TypeLong, mysql.TypeLonglong, mysql.TypeInt24: + return t.splitIntRanges(ctx, tikvStore, splitCnt) + case mysql.TypeBit: + return t.splitBinaryRanges(ctx, tikvStore, splitCnt) + case mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar: + if mysql.HasBinaryFlag(ft.GetFlag()) { + return t.splitBinaryRanges(ctx, tikvStore, splitCnt) + } + } + return []ScanRange{newFullRange()}, nil +} + +func unsignedEdge(d types.Datum) types.Datum { + if d.IsNull() { + return types.NewUintDatum(uint64(math.MaxInt64 + 1)) + } + if d.GetInt64() == 0 { + return nullDatum() + } + return types.NewUintDatum(uint64(d.GetInt64())) +} + +func (t *PhysicalTable) splitIntRanges(ctx context.Context, store tikv.Storage, splitCnt int) ([]ScanRange, error) { + recordPrefix := tablecodec.GenTableRecordPrefix(t.ID) + startKey, endKey := tablecodec.GetTableHandleKeyRange(t.ID) + keyRanges, err := t.splitRawKeyRanges(ctx, store, startKey, endKey, splitCnt) + if err != nil { + return nil, err + } + + if len(keyRanges) <= 1 { + return []ScanRange{newFullRange()}, nil + } + + ft := t.KeyColumnTypes[0] + unsigned := mysql.HasUnsignedFlag(ft.GetFlag()) + scanRanges := make([]ScanRange, 0, len(keyRanges)+1) + curScanStart := nullDatum() + for i, keyRange := range keyRanges { + if i != 0 && curScanStart.IsNull() { + break + } + + curScanEnd := nullDatum() + if i < len(keyRanges)-1 { + if val := GetNextIntHandle(keyRange.EndKey, recordPrefix); val != nil { + curScanEnd = types.NewIntDatum(val.IntValue()) + } + } + + if !curScanStart.IsNull() && !curScanEnd.IsNull() && curScanStart.GetInt64() >= curScanEnd.GetInt64() { + continue + } + + if !unsigned { + // primary key is signed or range + scanRanges = append(scanRanges, newDatumRange(curScanStart, curScanEnd)) + } else if !curScanStart.IsNull() && curScanStart.GetInt64() >= 0 { + // primary key is unsigned and range is in the right half side + scanRanges = append(scanRanges, newDatumRange(unsignedEdge(curScanStart), unsignedEdge(curScanEnd))) + } else if !curScanEnd.IsNull() && curScanEnd.GetInt64() <= 0 { + // primary key is unsigned and range is in the left half side + scanRanges = append(scanRanges, newDatumRange(unsignedEdge(curScanStart), unsignedEdge(curScanEnd))) + } else { + // primary key is unsigned and the start > math.MaxInt64 && end < math.MaxInt64 + // we must split it to two ranges + scanRanges = append(scanRanges, + newDatumRange(unsignedEdge(curScanStart), nullDatum()), + newDatumRange(nullDatum(), unsignedEdge(curScanEnd)), + ) + } + curScanStart = curScanEnd + } + return scanRanges, nil +} + +func (t *PhysicalTable) splitBinaryRanges(ctx context.Context, store tikv.Storage, splitCnt int) ([]ScanRange, error) { + recordPrefix := tablecodec.GenTableRecordPrefix(t.ID) + startKey, endKey := recordPrefix, recordPrefix.PrefixNext() + keyRanges, err := t.splitRawKeyRanges(ctx, store, startKey, endKey, splitCnt) + if err != nil { + return nil, err + } + + if len(keyRanges) <= 1 { + return []ScanRange{newFullRange()}, nil + } + + scanRanges := make([]ScanRange, 0, len(keyRanges)) + curScanStart := nullDatum() + for i, keyRange := range keyRanges { + if i != 0 && curScanStart.IsNull() { + break + } + + curScanEnd := nullDatum() + if i != len(keyRanges)-1 { + curScanEnd = GetNextBytesHandleDatum(keyRange.EndKey, recordPrefix) + } + + if !curScanStart.IsNull() && !curScanEnd.IsNull() && kv.Key(curScanStart.GetBytes()).Cmp(curScanEnd.GetBytes()) >= 0 { + continue + } + + scanRanges = append(scanRanges, newDatumRange(curScanStart, curScanEnd)) + curScanStart = curScanEnd + } + return scanRanges, nil +} + +func (t *PhysicalTable) splitRawKeyRanges(ctx context.Context, store tikv.Storage, startKey, endKey kv.Key, splitCnt int) ([]kv.KeyRange, error) { + regionCache := store.GetRegionCache() + regionIDs, err := regionCache.ListRegionIDsInKeyRange(tikv.NewBackofferWithVars(ctx, 20000, nil), startKey, endKey) + if err != nil { + return nil, err + } + + regionsPerRange := len(regionIDs) / splitCnt + oversizeCnt := len(regionIDs) % splitCnt + ranges := make([]kv.KeyRange, 0, mathutil.Min(len(regionIDs), splitCnt)) + for len(regionIDs) > 0 { + startRegion, err := regionCache.LocateRegionByID(tikv.NewBackofferWithVars(ctx, 20000, nil), regionIDs[0]) + if err != nil { + return nil, err + } + + endRegionIdx := regionsPerRange - 1 + if oversizeCnt > 0 { + endRegionIdx++ + } + + endRegion, err := regionCache.LocateRegionByID(tikv.NewBackofferWithVars(ctx, 20000, nil), regionIDs[endRegionIdx]) + if err != nil { + return nil, err + } + + rangeStartKey := kv.Key(startRegion.StartKey) + if rangeStartKey.Cmp(startKey) < 0 { + rangeStartKey = startKey + } + + rangeEndKey := kv.Key(endRegion.EndKey) + if rangeEndKey.Cmp(endKey) > 0 { + rangeEndKey = endKey + } + + ranges = append(ranges, kv.KeyRange{StartKey: rangeStartKey, EndKey: rangeEndKey}) + oversizeCnt-- + regionIDs = regionIDs[endRegionIdx+1:] + } + return ranges, nil +} + +var emptyBytesHandleKey kv.Key + +func init() { + key, err := codec.EncodeKey(nil, nil, types.NewBytesDatum(nil)) + terror.MustNil(err) + emptyBytesHandleKey = key +} + +// GetNextIntHandle is used for int handle tables. It returns the min handle whose encoded key is or after argument `key` +// If it cannot find a valid value, a null datum will be returned. +func GetNextIntHandle(key kv.Key, recordPrefix []byte) kv.Handle { + if key.Cmp(recordPrefix) > 0 && !key.HasPrefix(recordPrefix) { + return nil + } + + if key.Cmp(recordPrefix) <= 0 { + return kv.IntHandle(math.MinInt64) + } + + suffix := key[len(recordPrefix):] + encodedVal := suffix + if len(suffix) < 8 { + encodedVal = make([]byte, 8) + copy(encodedVal, suffix) + } + + findNext := false + if len(suffix) > 8 { + findNext = true + encodedVal = encodedVal[:8] + } + + u := codec.DecodeCmpUintToInt(binary.BigEndian.Uint64(encodedVal)) + if !findNext { + return kv.IntHandle(u) + } + + if u == math.MaxInt64 { + return nil + } + + return kv.IntHandle(u + 1) +} + +// GetNextBytesHandleDatum is used for a table with one binary or string column common handle. +// It returns the minValue whose encoded key is or after argument `key` +// If it cannot find a valid value, a null datum will be returned. +func GetNextBytesHandleDatum(key kv.Key, recordPrefix []byte) (d types.Datum) { + if key.Cmp(recordPrefix) > 0 && !key.HasPrefix(recordPrefix) { + d.SetNull() + return d + } + + if key.Cmp(recordPrefix) <= 0 { + d.SetBytes([]byte{}) + return d + } + + encodedVal := key[len(recordPrefix):] + if encodedVal[0] < emptyBytesHandleKey[0] { + d.SetBytes([]byte{}) + return d + } + + if encodedVal[0] > emptyBytesHandleKey[0] { + d.SetNull() + return d + } + + if remain, v, err := codec.DecodeOne(encodedVal); err == nil { + if len(remain) > 0 { + v.SetBytes(kv.Key(v.GetBytes()).Next()) + } + return v + } + + encodedVal = encodedVal[1:] + brokenGroupEndIdx := len(encodedVal) - 1 + brokenGroupEmptyBytes := len(encodedVal) % 9 + for i := 7; i+1 < len(encodedVal); i += 9 { + if emptyBytes := 255 - int(encodedVal[i+1]); emptyBytes != 0 || i+1 == len(encodedVal)-1 { + brokenGroupEndIdx = i + brokenGroupEmptyBytes = emptyBytes + break + } + } + + for i := 0; i < brokenGroupEmptyBytes; i++ { + if encodedVal[brokenGroupEndIdx] > 0 { + break + } + brokenGroupEndIdx-- + } + + if brokenGroupEndIdx < 0 { + d.SetBytes(nil) + return d + } + + val := make([]byte, 0, len(encodedVal)) + for i := 0; i <= brokenGroupEndIdx; i++ { + if i%9 == 8 { + continue + } + val = append(val, encodedVal[i]) + } + d.SetBytes(val) + return d +} diff --git a/ttl/cache/table_test.go b/ttl/cache/table_test.go new file mode 100644 index 0000000000000..ca280d9b36251 --- /dev/null +++ b/ttl/cache/table_test.go @@ -0,0 +1,216 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache_test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/stretchr/testify/require" +) + +func TestNewTTLTable(t *testing.T) { + cases := []struct { + db string + tbl string + def string + timeCol string + keyCols []string + }{ + { + db: "test", + tbl: "t1", + def: "(a int)", + }, + { + db: "test", + tbl: "ttl1", + def: "(a int, t datetime) ttl = `t` + interval 2 hour", + timeCol: "t", + keyCols: []string{"_tidb_rowid"}, + }, + { + db: "test", + tbl: "ttl2", + def: "(id int primary key, t datetime) ttl = `t` + interval 3 hour", + timeCol: "t", + keyCols: []string{"id"}, + }, + { + db: "test", + tbl: "ttl3", + def: "(a int, b varchar(32), c binary(32), t datetime, primary key (a, b, c)) ttl = `t` + interval 1 month", + timeCol: "t", + keyCols: []string{"a", "b", "c"}, + }, + { + db: "test", + tbl: "ttl4", + def: "(id int primary key, t datetime) " + + "ttl = `t` + interval 1 day " + + "PARTITION BY RANGE (id) (" + + " PARTITION p0 VALUES LESS THAN (10)," + + " PARTITION p1 VALUES LESS THAN (100)," + + " PARTITION p2 VALUES LESS THAN (1000)," + + " PARTITION p3 VALUES LESS THAN MAXVALUE)", + timeCol: "t", + keyCols: []string{"id"}, + }, + { + db: "test", + tbl: "ttl5", + def: "(id int primary key nonclustered, t datetime) ttl = `t` + interval 3 hour", + timeCol: "t", + keyCols: []string{"_tidb_rowid"}, + }, + } + + store, do := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + for _, c := range cases { + tk.MustExec("use " + c.db) + tk.MustExec("create table " + c.tbl + c.def) + } + + for _, c := range cases { + is := do.InfoSchema() + tbl, err := is.TableByName(model.NewCIStr(c.db), model.NewCIStr(c.tbl)) + require.NoError(t, err) + tblInfo := tbl.Meta() + var physicalTbls []*cache.PhysicalTable + if tblInfo.Partition == nil { + ttlTbl, err := cache.NewPhysicalTable(model.NewCIStr(c.db), tblInfo, model.NewCIStr("")) + if c.timeCol == "" { + require.Error(t, err) + continue + } + require.NoError(t, err) + physicalTbls = append(physicalTbls, ttlTbl) + } else { + for _, partition := range tblInfo.Partition.Definitions { + ttlTbl, err := cache.NewPhysicalTable(model.NewCIStr(c.db), tblInfo, partition.Name) + if c.timeCol == "" { + require.Error(t, err) + continue + } + require.NoError(t, err) + physicalTbls = append(physicalTbls, ttlTbl) + } + if c.timeCol == "" { + continue + } + } + + for i, ttlTbl := range physicalTbls { + require.Equal(t, c.db, ttlTbl.Schema.O) + require.Same(t, tblInfo, ttlTbl.TableInfo) + timeColumn := tblInfo.FindPublicColumnByName(c.timeCol) + require.NotNil(t, timeColumn) + require.Same(t, timeColumn, ttlTbl.TimeColumn) + + if tblInfo.Partition == nil { + require.Equal(t, ttlTbl.TableInfo.ID, ttlTbl.ID) + require.Equal(t, "", ttlTbl.Partition.L) + require.Nil(t, ttlTbl.PartitionDef) + } else { + def := tblInfo.Partition.Definitions[i] + require.Equal(t, def.ID, ttlTbl.ID) + require.Equal(t, def.Name.L, ttlTbl.Partition.L) + require.Equal(t, def, *(ttlTbl.PartitionDef)) + } + + require.Equal(t, len(c.keyCols), len(ttlTbl.KeyColumns)) + require.Equal(t, len(c.keyCols), len(ttlTbl.KeyColumnTypes)) + + for j, keyCol := range c.keyCols { + msg := fmt.Sprintf("%s, col: %s", c.tbl, keyCol) + var col *model.ColumnInfo + if keyCol == model.ExtraHandleName.L { + col = model.NewExtraHandleColInfo() + } else { + col = tblInfo.FindPublicColumnByName(keyCol) + } + colJ := ttlTbl.KeyColumns[j] + colFieldJ := ttlTbl.KeyColumnTypes[j] + + require.NotNil(t, col, msg) + require.Equal(t, col.ID, colJ.ID, msg) + require.Equal(t, col.Name.L, colJ.Name.L, msg) + require.Equal(t, col.FieldType, colJ.FieldType, msg) + require.Equal(t, col.FieldType, *colFieldJ, msg) + } + } + } +} + +func TestEvalTTLExpireTime(t *testing.T) { + store, do := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("create table test.t(a int, t datetime) ttl = `t` + interval 1 day") + tk.MustExec("create table test.t2(a int, t datetime) ttl = `t` + interval 3 month") + + tb, err := do.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + tblInfo := tb.Meta() + ttlTbl, err := cache.NewPhysicalTable(model.NewCIStr("test"), tblInfo, model.NewCIStr("")) + require.NoError(t, err) + + tb2, err := do.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t2")) + require.NoError(t, err) + tblInfo2 := tb2.Meta() + ttlTbl2, err := cache.NewPhysicalTable(model.NewCIStr("test"), tblInfo2, model.NewCIStr("")) + require.NoError(t, err) + + se := session.NewSession(tk.Session(), tk.Session(), nil) + + now := time.UnixMilli(0) + tz1, err := time.LoadLocation("Asia/Shanghai") + require.NoError(t, err) + tz2, err := time.LoadLocation("Europe/Berlin") + require.NoError(t, err) + + se.GetSessionVars().TimeZone = tz1 + tm, err := ttlTbl.EvalExpireTime(context.TODO(), se, now) + require.NoError(t, err) + require.Equal(t, now.Add(-time.Hour*24).Unix(), tm.Unix()) + require.Equal(t, "1969-12-31 08:00:00", tm.Format("2006-01-02 15:04:05")) + require.Equal(t, tz1.String(), tm.Location().String()) + + se.GetSessionVars().TimeZone = tz2 + tm, err = ttlTbl.EvalExpireTime(context.TODO(), se, now) + require.NoError(t, err) + require.Equal(t, now.Add(-time.Hour*24).Unix(), tm.Unix()) + require.Equal(t, "1969-12-31 01:00:00", tm.Format("2006-01-02 15:04:05")) + require.Equal(t, tz2.String(), tm.Location().String()) + + se.GetSessionVars().TimeZone = tz1 + tm, err = ttlTbl2.EvalExpireTime(context.TODO(), se, now) + require.NoError(t, err) + require.Equal(t, "1969-10-01 08:00:00", tm.Format("2006-01-02 15:04:05")) + require.Equal(t, tz1.String(), tm.Location().String()) + + se.GetSessionVars().TimeZone = tz2 + tm, err = ttlTbl2.EvalExpireTime(context.TODO(), se, now) + require.NoError(t, err) + require.Equal(t, "1969-10-01 01:00:00", tm.Format("2006-01-02 15:04:05")) + require.Equal(t, tz2.String(), tm.Location().String()) +} diff --git a/ttl/cache/task.go b/ttl/cache/task.go new file mode 100644 index 0000000000000..c88a3fe0abb2e --- /dev/null +++ b/ttl/cache/task.go @@ -0,0 +1,193 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "encoding/json" + "time" + + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/codec" +) + +const selectFromTTLTask = `SELECT LOW_PRIORITY + job_id, + table_id, + scan_id, + scan_range_start, + scan_range_end, + expire_time, + owner_id, + owner_addr, + owner_hb_time, + status, + status_update_time, + state, + created_time FROM mysql.tidb_ttl_task` +const insertIntoTTLTask = `INSERT LOW_PRIORITY INTO mysql.tidb_ttl_task SET + job_id = %?, + table_id = %?, + scan_id = %?, + scan_range_start = %?, + scan_range_end = %?, + expire_time = %?, + created_time = %?` + +// SelectFromTTLTaskWithJobID returns an SQL statement to get all tasks of the specified job in mysql.tidb_ttl_task +func SelectFromTTLTaskWithJobID(jobID string) (string, []interface{}) { + return selectFromTTLTask + " WHERE job_id = %?", []interface{}{jobID} +} + +// SelectFromTTLTaskWithID returns an SQL statement to get all tasks of the specified job and scanID in mysql.tidb_ttl_task +func SelectFromTTLTaskWithID(jobID string, scanID int64) (string, []interface{}) { + return selectFromTTLTask + " WHERE job_id = %? AND scan_id = %?", []interface{}{jobID, scanID} +} + +// PeekWaitingTTLTask returns an SQL statement to get `limit` waiting ttl task +func PeekWaitingTTLTask(limit int, hbExpire time.Time) (string, []interface{}) { + return selectFromTTLTask + " WHERE status = 'waiting' OR owner_hb_time < %? ORDER BY created_time ASC LIMIT %?", []interface{}{hbExpire.Format("2006-01-02 15:04:05"), limit} +} + +// InsertIntoTTLTask returns an SQL statement to insert a ttl task into mysql.tidb_ttl_task +func InsertIntoTTLTask(sctx sessionctx.Context, jobID string, tableID int64, scanID int, scanRangeStart []types.Datum, scanRangeEnd []types.Datum, expireTime time.Time, createdTime time.Time) (string, []interface{}, error) { + rangeStart, err := codec.EncodeKey(sctx.GetSessionVars().StmtCtx, []byte{}, scanRangeStart...) + if err != nil { + return "", nil, err + } + rangeEnd, err := codec.EncodeKey(sctx.GetSessionVars().StmtCtx, []byte{}, scanRangeEnd...) + if err != nil { + return "", nil, err + } + return insertIntoTTLTask, []interface{}{jobID, tableID, int64(scanID), rangeStart, rangeEnd, expireTime, createdTime}, nil +} + +// TaskStatus represents the current status of a task +type TaskStatus string + +const ( + // TaskStatusWaiting means the task hasn't started + TaskStatusWaiting TaskStatus = "waiting" + // TaskStatusRunning means this task is running + TaskStatusRunning = "running" + // TaskStatusFinished means this task has finished + TaskStatusFinished = "finished" +) + +// TTLTask is a row recorded in mysql.tidb_ttl_task +type TTLTask struct { + JobID string + TableID int64 + ScanID int64 + ScanRangeStart []types.Datum + ScanRangeEnd []types.Datum + ExpireTime time.Time + OwnerID string + OwnerAddr string + OwnerHBTime time.Time + Status TaskStatus + StatusUpdateTime time.Time + State *TTLTaskState + CreatedTime time.Time +} + +// TTLTaskState records the internal states of the ttl task +type TTLTaskState struct { + TotalRows uint64 `json:"total_rows"` + SuccessRows uint64 `json:"success_rows"` + ErrorRows uint64 `json:"error_rows"` + + ScanTaskErr string `json:"scan_task_err"` +} + +// RowToTTLTask converts a row into TTL task +func RowToTTLTask(sctx sessionctx.Context, row chunk.Row) (*TTLTask, error) { + var err error + timeZone := sctx.GetSessionVars().Location() + + task := &TTLTask{ + JobID: row.GetString(0), + TableID: row.GetInt64(1), + ScanID: row.GetInt64(2), + } + if !row.IsNull(3) { + scanRangeStartBuf := row.GetBytes(3) + // it's still posibble to be empty even this column is not NULL + if len(scanRangeStartBuf) > 0 { + task.ScanRangeStart, err = codec.Decode(scanRangeStartBuf, len(scanRangeStartBuf)) + if err != nil { + return nil, err + } + } + } + if !row.IsNull(4) { + scanRangeEndBuf := row.GetBytes(4) + // it's still posibble to be empty even this column is not NULL + if len(scanRangeEndBuf) > 0 { + task.ScanRangeEnd, err = codec.Decode(scanRangeEndBuf, len(scanRangeEndBuf)) + if err != nil { + return nil, err + } + } + } + + task.ExpireTime, err = row.GetTime(5).GoTime(timeZone) + if err != nil { + return nil, err + } + + if !row.IsNull(6) { + task.OwnerID = row.GetString(6) + } + if !row.IsNull(7) { + task.OwnerAddr = row.GetString(7) + } + if !row.IsNull(8) { + task.OwnerHBTime, err = row.GetTime(8).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(9) { + status := row.GetString(9) + if len(status) == 0 { + status = "waiting" + } + task.Status = TaskStatus(status) + } + if !row.IsNull(10) { + task.StatusUpdateTime, err = row.GetTime(10).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(11) { + stateStr := row.GetString(11) + state := &TTLTaskState{} + err = json.Unmarshal([]byte(stateStr), state) + if err != nil { + return nil, err + } + task.State = state + } + + task.CreatedTime, err = row.GetTime(12).GoTime(timeZone) + if err != nil { + return nil, err + } + + return task, nil +} diff --git a/ttl/cache/task_test.go b/ttl/cache/task_test.go new file mode 100644 index 0000000000000..ad1f71278b102 --- /dev/null +++ b/ttl/cache/task_test.go @@ -0,0 +1,117 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache_test + +import ( + "context" + "testing" + "time" + + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/codec" + "github.com/stretchr/testify/require" +) + +type taskGetter struct { + ctx context.Context + t *testing.T + tk *testkit.TestKit +} + +func newTaskGetter(ctx context.Context, t *testing.T, tk *testkit.TestKit) *taskGetter { + return &taskGetter{ + ctx, t, tk, + } +} + +func (tg *taskGetter) mustGetTestTask() *cache.TTLTask { + sql, args := cache.SelectFromTTLTaskWithJobID("test-job") + rs, err := tg.tk.Session().ExecuteInternal(tg.ctx, sql, args...) + require.NoError(tg.t, err) + rows, err := session.GetRows4Test(context.Background(), tg.tk.Session(), rs) + require.NoError(tg.t, err) + task, err := cache.RowToTTLTask(tg.tk.Session(), rows[0]) + require.NoError(tg.t, err) + return task +} + +func TestRowToTTLTask(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.Session().GetSessionVars().TimeZone = time.Local + + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnTTL) + tg := newTaskGetter(ctx, t, tk) + + now := time.Now() + now = now.Round(time.Second) + + sql, args, err := cache.InsertIntoTTLTask(tk.Session(), "test-job", 1, 1, nil, nil, now, now) + require.NoError(t, err) + // tk.MustExec cannot handle the NULL parameter, use the `tk.Session().ExecuteInternal` instead here. + _, err = tk.Session().ExecuteInternal(ctx, sql, args...) + require.NoError(t, err) + task := tg.mustGetTestTask() + require.Equal(t, "test-job", task.JobID) + require.Equal(t, int64(1), task.TableID) + require.Equal(t, int64(1), task.ScanID) + require.Nil(t, task.ScanRangeStart) + require.Nil(t, task.ScanRangeEnd) + require.Equal(t, now, task.ExpireTime) + require.Equal(t, now, task.CreatedTime) + + rangeStart, err := codec.EncodeKey(tk.Session().GetSessionVars().StmtCtx, []byte{}, []types.Datum{types.NewDatum(1)}...) + require.NoError(t, err) + rangeEnd, err := codec.EncodeKey(tk.Session().GetSessionVars().StmtCtx, []byte{}, []types.Datum{types.NewDatum(2)}...) + require.NoError(t, err) + tk.MustExec("UPDATE mysql.tidb_ttl_task SET scan_range_start = ?, scan_range_end = ? WHERE job_id = 'test-job'", rangeStart, rangeEnd) + + task = tg.mustGetTestTask() + require.Equal(t, []types.Datum{types.NewDatum(1)}, task.ScanRangeStart) + require.Equal(t, []types.Datum{types.NewDatum(2)}, task.ScanRangeEnd) +} + +func TestInsertIntoTTLTask(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.Session().GetSessionVars().TimeZone = time.Local + + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnTTL) + tg := newTaskGetter(ctx, t, tk) + + rangeStart := []types.Datum{types.NewDatum(1)} + rangeEnd := []types.Datum{types.NewDatum(2)} + + now := time.Now() + now = now.Round(time.Second) + + sql, args, err := cache.InsertIntoTTLTask(tk.Session(), "test-job", 1, 1, rangeStart, rangeEnd, now, now) + require.NoError(t, err) + // tk.MustExec cannot handle the NULL parameter, use the `tk.Session().ExecuteInternal` instead here. + _, err = tk.Session().ExecuteInternal(ctx, sql, args...) + require.NoError(t, err) + task := tg.mustGetTestTask() + require.Equal(t, "test-job", task.JobID) + require.Equal(t, int64(1), task.TableID) + require.Equal(t, int64(1), task.ScanID) + require.Equal(t, []types.Datum{types.NewDatum(1)}, task.ScanRangeStart) + require.Equal(t, []types.Datum{types.NewDatum(2)}, task.ScanRangeEnd) + require.Equal(t, now, task.ExpireTime) + require.Equal(t, now, task.CreatedTime) +} diff --git a/ttl/cache/ttlstatus.go b/ttl/cache/ttlstatus.go new file mode 100644 index 0000000000000..d28bafa5a76c8 --- /dev/null +++ b/ttl/cache/ttlstatus.go @@ -0,0 +1,193 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "context" + "time" + + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/util/chunk" +) + +// JobStatus represents the current status of a job +type JobStatus string + +const ( + // JobStatusWaiting means the job hasn't started + JobStatusWaiting JobStatus = "waiting" + // JobStatusRunning means this job is running + JobStatusRunning = "running" + // JobStatusCancelling means this job is being canceled, but not canceled yet + JobStatusCancelling = "cancelling" + // JobStatusCancelled means this job has been canceled successfully + JobStatusCancelled = "cancelled" + // JobStatusTimeout means this job has timeout + JobStatusTimeout = "timeout" +) + +const selectFromTTLTableStatus = "SELECT LOW_PRIORITY table_id,parent_table_id,table_statistics,last_job_id,last_job_start_time,last_job_finish_time,last_job_ttl_expire,last_job_summary,current_job_id,current_job_owner_id,current_job_owner_addr,current_job_owner_hb_time,current_job_start_time,current_job_ttl_expire,current_job_state,current_job_status,current_job_status_update_time FROM mysql.tidb_ttl_table_status" + +// SelectFromTTLTableStatusWithID returns an SQL statement to get the table status from table id +func SelectFromTTLTableStatusWithID(tableID int64) (string, []interface{}) { + return selectFromTTLTableStatus + " WHERE table_id = %?", []interface{}{tableID} +} + +// TableStatus contains the corresponding information in the system table `mysql.tidb_ttl_table_status` +type TableStatus struct { + TableID int64 + ParentTableID int64 + + TableStatistics string + + LastJobID string + LastJobStartTime time.Time + LastJobFinishTime time.Time + LastJobTTLExpire time.Time + LastJobSummary string + + CurrentJobID string + CurrentJobOwnerID string + CurrentJobOwnerAddr string + CurrentJobOwnerHBTime time.Time + CurrentJobStartTime time.Time + CurrentJobTTLExpire time.Time + + CurrentJobState string + CurrentJobStatus JobStatus + CurrentJobStatusUpdateTime time.Time +} + +// TableStatusCache is the cache for ttl table status, it builds a map from physical table id to the table status +type TableStatusCache struct { + baseCache + + Tables map[int64]*TableStatus +} + +// NewTableStatusCache creates cache for ttl table status +func NewTableStatusCache(updateInterval time.Duration) *TableStatusCache { + return &TableStatusCache{ + baseCache: newBaseCache(updateInterval), + Tables: make(map[int64]*TableStatus), + } +} + +// Update updates the table status cache +func (tsc *TableStatusCache) Update(ctx context.Context, se session.Session) error { + rows, err := se.ExecuteSQL(ctx, selectFromTTLTableStatus) + if err != nil { + return err + } + + newTables := make(map[int64]*TableStatus, len(rows)) + for _, row := range rows { + status, err := RowToTableStatus(se, row) + if err != nil { + return err + } + + newTables[status.TableID] = status + } + tsc.Tables = newTables + tsc.updateTime = time.Now() + return nil +} + +// RowToTableStatus converts a row to table status +func RowToTableStatus(sctx sessionctx.Context, row chunk.Row) (*TableStatus, error) { + var err error + timeZone := sctx.GetSessionVars().Location() + + status := &TableStatus{ + TableID: row.GetInt64(0), + } + if !row.IsNull(1) { + status.ParentTableID = row.GetInt64(1) + } + if !row.IsNull(2) { + status.TableStatistics = row.GetString(2) + } + if !row.IsNull(3) { + status.LastJobID = row.GetString(3) + } + if !row.IsNull(4) { + status.LastJobStartTime, err = row.GetTime(4).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(5) { + status.LastJobFinishTime, err = row.GetTime(5).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(6) { + status.LastJobTTLExpire, err = row.GetTime(6).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(7) { + status.LastJobSummary = row.GetString(7) + } + if !row.IsNull(8) { + status.CurrentJobID = row.GetString(8) + } + if !row.IsNull(9) { + status.CurrentJobOwnerID = row.GetString(9) + } + if !row.IsNull(10) { + status.CurrentJobOwnerAddr = row.GetString(10) + } + if !row.IsNull(11) { + status.CurrentJobOwnerHBTime, err = row.GetTime(11).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(12) { + status.CurrentJobStartTime, err = row.GetTime(12).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(13) { + status.CurrentJobTTLExpire, err = row.GetTime(13).GoTime(timeZone) + if err != nil { + return nil, err + } + } + if !row.IsNull(14) { + status.CurrentJobState = row.GetString(14) + } + if !row.IsNull(15) { + jobStatus := row.GetString(15) + if len(jobStatus) == 0 { + jobStatus = "waiting" + } + status.CurrentJobStatus = JobStatus(jobStatus) + } + if !row.IsNull(16) { + status.CurrentJobStatusUpdateTime, err = row.GetTime(16).GoTime(timeZone) + if err != nil { + return nil, err + } + } + + return status, nil +} diff --git a/ttl/cache/ttlstatus_test.go b/ttl/cache/ttlstatus_test.go new file mode 100644 index 0000000000000..a73d3675d0e6d --- /dev/null +++ b/ttl/cache/ttlstatus_test.go @@ -0,0 +1,181 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache_test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/pingcap/tidb/server" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/stretchr/testify/assert" +) + +func TestTTLStatusCache(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + sv := server.CreateMockServer(t, store) + sv.SetDomain(dom) + defer sv.Close() + + conn := server.CreateMockConn(t, sv) + sctx := conn.Context().Session + tk := testkit.NewTestKitWithSession(t, store, sctx) + ttlSession := session.NewSession(sctx, tk.Session(), func(_ session.Session) {}) + + isc := cache.NewTableStatusCache(time.Hour) + + // test should update + assert.True(t, isc.ShouldUpdate()) + assert.NoError(t, isc.Update(context.Background(), ttlSession)) + assert.False(t, isc.ShouldUpdate()) + + // test new entries are synced + tk.MustExec("insert into mysql.tidb_ttl_table_status(table_id, parent_table_id) values (1, 2)") + assert.NoError(t, isc.Update(context.Background(), ttlSession)) + assert.Equal(t, 1, len(isc.Tables)) + tk.MustExec("delete from mysql.tidb_ttl_table_status where table_id = 1") + assert.NoError(t, isc.Update(context.Background(), ttlSession)) + assert.Equal(t, 0, len(isc.Tables)) + + timeZone := tk.Session().GetSessionVars().TimeZone + + // test every field of tidb_ttl_table_status can be extracted well + testCases := []struct { + columnName string + sqlLiteral string + assert func(table *cache.TableStatus) + }{ + { + "parent_table_id", + "2", + func(table *cache.TableStatus) { assert.Equal(t, int64(2), table.ParentTableID) }, + }, + { + "table_statistics", + "'test str'", + func(table *cache.TableStatus) { assert.Equal(t, "test str", table.TableStatistics) }, + }, + { + "last_job_id", + "'test job id'", + func(table *cache.TableStatus) { assert.Equal(t, "test job id", table.LastJobID) }, + }, + { + "last_job_start_time", + "'2022-12-01 16:49:01'", + func(table *cache.TableStatus) { + expectedTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-12-01 16:49:01", timeZone) + assert.NoError(t, err) + assert.Equal(t, expectedTime, table.LastJobStartTime) + }, + }, + { + "last_job_finish_time", + "'2022-12-01 16:50:01'", + func(table *cache.TableStatus) { + expectedTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-12-01 16:50:01", timeZone) + assert.NoError(t, err) + assert.Equal(t, expectedTime, table.LastJobFinishTime) + }, + }, + { + "last_job_ttl_expire", + "'2022-12-01 16:51:01'", + func(table *cache.TableStatus) { + expectedTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-12-01 16:51:01", timeZone) + assert.NoError(t, err) + assert.Equal(t, expectedTime, table.LastJobTTLExpire) + }, + }, + { + "last_job_summary", + "'test summary'", + func(table *cache.TableStatus) { assert.Equal(t, "test summary", table.LastJobSummary) }, + }, + { + "current_job_id", + "'test current job id'", + func(table *cache.TableStatus) { assert.Equal(t, "test current job id", table.CurrentJobID) }, + }, + { + "current_job_owner_id", + "'test current job owner id'", + func(table *cache.TableStatus) { assert.Equal(t, "test current job owner id", table.CurrentJobOwnerID) }, + }, + { + "current_job_owner_hb_time", + "'2022-12-01 16:52:01'", + func(table *cache.TableStatus) { + expectedTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-12-01 16:52:01", timeZone) + assert.NoError(t, err) + assert.Equal(t, expectedTime, table.CurrentJobOwnerHBTime) + }, + }, + { + "current_job_start_time", + "'2022-12-01 16:53:01'", + func(table *cache.TableStatus) { + expectedTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-12-01 16:53:01", timeZone) + assert.NoError(t, err) + assert.Equal(t, expectedTime, table.CurrentJobStartTime) + }, + }, + { + "current_job_ttl_expire", + "'2022-12-01 16:54:01'", + func(table *cache.TableStatus) { + expectedTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-12-01 16:54:01", timeZone) + assert.NoError(t, err) + assert.Equal(t, expectedTime, table.CurrentJobTTLExpire) + }, + }, + { + "current_job_state", + "'test state'", + func(table *cache.TableStatus) { assert.Equal(t, "test state", table.CurrentJobState) }, + }, + { + "current_job_status", + "'test status'", + func(table *cache.TableStatus) { + assert.Equal(t, cache.JobStatus("test status"), table.CurrentJobStatus) + }, + }, + { + "current_job_status_update_time", + "'2022-12-01 16:55:01'", + func(table *cache.TableStatus) { + expectedTime, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-12-01 16:55:01", timeZone) + assert.NoError(t, err) + assert.Equal(t, expectedTime, table.CurrentJobStatusUpdateTime) + }, + }, + } + for index, testCase := range testCases { + t.Run(testCase.columnName, func(t *testing.T) { + sql := fmt.Sprintf(`insert into mysql.tidb_ttl_table_status (table_id, %s) values (%d, %s)`, + testCase.columnName, index, testCase.sqlLiteral) + + tk.MustExec(sql) + assert.NoError(t, isc.Update(context.Background(), ttlSession)) + assert.Equal(t, index+1, len(isc.Tables)) + testCase.assert(isc.Tables[int64(index)]) + }) + } +} diff --git a/ttl/client/BUILD.bazel b/ttl/client/BUILD.bazel new file mode 100644 index 0000000000000..6f2c7acaae481 --- /dev/null +++ b/ttl/client/BUILD.bazel @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "client", + srcs = ["command.go"], + importpath = "github.com/pingcap/tidb/ttl/client", + visibility = ["//visibility:public"], + deps = [ + "//util/logutil", + "@com_github_google_uuid//:uuid", + "@com_github_pingcap_errors//:errors", + "@io_etcd_go_etcd_client_v3//:client", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "client_test", + srcs = ["command_test.go"], + embed = [":client"], + deps = [ + "@com_github_pingcap_errors//:errors", + "@com_github_stretchr_testify//require", + "@io_etcd_go_etcd_tests_v3//integration", + ], +) diff --git a/ttl/client/command.go b/ttl/client/command.go new file mode 100644 index 0000000000000..bad2d756353cd --- /dev/null +++ b/ttl/client/command.go @@ -0,0 +1,419 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + "context" + "encoding/json" + "strings" + "sync" + "time" + + "github.com/google/uuid" + "github.com/pingcap/errors" + "github.com/pingcap/tidb/util/logutil" + clientv3 "go.etcd.io/etcd/client/v3" + "go.uber.org/zap" +) + +const ( + ttlCmdKeyLeaseSeconds int64 = 60 + ttlCmdKeyRequestPrefix = "/tidb/ttl/cmd/req/" + ttlCmdKeyResponsePrefix = "/tidb/ttl/cmd/resp/" + ttlCmdTypeTriggerTTLJob = "trigger_ttl_job" +) + +// CmdRequest is the request for a TTL command +type CmdRequest struct { + RequestID string `json:"request_id"` + CmdType string `json:"cmd_type"` + Data json.RawMessage `json:"data"` +} + +// GetTriggerTTLJobRequest returns the `TriggerNewTTLJobRequest` object if command type is 'trigger_ttl_job', +// otherwise, (nil, false) will be returned +func (r *CmdRequest) GetTriggerTTLJobRequest() (*TriggerNewTTLJobRequest, bool) { + if r.CmdType != ttlCmdTypeTriggerTTLJob { + return nil, false + } + + var req TriggerNewTTLJobRequest + if err := json.Unmarshal(r.Data, &req); err != nil { + return nil, false + } + return &req, true +} + +type cmdResponse struct { + RequestID string `json:"request_id"` + ErrorMessage string `json:"error_message"` + Data json.RawMessage `json:"data"` +} + +// TriggerNewTTLJobRequest is the command detail to trigger a TTL job +type TriggerNewTTLJobRequest struct { + DBName string `json:"db_name"` + TableName string `json:"table_name"` +} + +// TriggerNewTTLJobTableResult is the table detail of `TriggerNewTTLJobResponse` +type TriggerNewTTLJobTableResult struct { + TableID int64 `json:"table_id"` + DBName string `json:"db_name"` + TableName string `json:"table_name"` + PartitionName string `json:"partition_name,omitempty"` + JobID string `json:"job_id"` + ErrorMessage string `json:"error_message"` +} + +// TriggerNewTTLJobResponse is the response detail for trigger_ttl_job command +type TriggerNewTTLJobResponse struct { + TableResult []*TriggerNewTTLJobTableResult `json:"table_result"` +} + +// CommandClient is an interface used to send and response command of TTL jobs +type CommandClient interface { + // Command sends a command and waits for response. The first value of the return is the requestID, it always not empty. + Command(ctx context.Context, cmdType string, obj interface{}, response interface{}) (string, error) + // WatchCommand watches the commands that are sent + WatchCommand(ctx context.Context) <-chan *CmdRequest + // TakeCommand takes a command to ensure only one can handle the command. + // If the first return value is true, it means you have taken the command successfully, and you should call `ResponseCommand` + // after processed the command. Otherwise, you should not process this command because it is not belong to you. + TakeCommand(ctx context.Context, reqID string) (bool, error) + // ResponseCommand responses the result of the command. `TakeCommand` must be called first before `ResponseCommand` + // obj is the response object to the sender, if obj is an error, the sender will receive an error too. + ResponseCommand(ctx context.Context, reqID string, obj interface{}) error +} + +// TriggerNewTTLJob triggers a new TTL job +func TriggerNewTTLJob(ctx context.Context, cli CommandClient, dbName, tableName string) (*TriggerNewTTLJobResponse, error) { + var resp TriggerNewTTLJobResponse + _, err := cli.Command(ctx, ttlCmdTypeTriggerTTLJob, &TriggerNewTTLJobRequest{ + DBName: dbName, + TableName: tableName, + }, &resp) + + if err != nil { + return nil, err + } + return &resp, nil +} + +type etcdClient struct { + etcdCli *clientv3.Client +} + +// NewEtcdCommandClient creates a client with etcd +func NewEtcdCommandClient(etcdCli *clientv3.Client) CommandClient { + return &etcdClient{ + etcdCli: etcdCli, + } +} + +func (c *etcdClient) sendCmd(ctx context.Context, cmdType string, obj interface{}) (string, error) { + reqID := uuid.New().String() + data, err := json.Marshal(obj) + if err != nil { + return reqID, err + } + + requestJSON, err := json.Marshal(&CmdRequest{ + RequestID: reqID, + CmdType: cmdType, + Data: data, + }) + if err != nil { + return reqID, err + } + + lease, err := c.etcdCli.Grant(ctx, ttlCmdKeyLeaseSeconds) + if err != nil { + return reqID, err + } + + if _, err = c.etcdCli.Put(ctx, ttlCmdKeyRequestPrefix+reqID, string(requestJSON), clientv3.WithLease(lease.ID)); err != nil { + return reqID, err + } + + return reqID, nil +} + +func (c *etcdClient) waitCmdResponse(ctx context.Context, reqID string, obj interface{}) error { + ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(ttlCmdKeyLeaseSeconds)) + defer cancel() + + key := ttlCmdKeyResponsePrefix + reqID + ch := c.etcdCli.Watch(ctx, key) + ticker := time.NewTimer(time.Second) + defer ticker.Stop() + + var respData []byte +loop: + for { + select { + case <-ticker.C: + response, err := c.etcdCli.Get(ctx, key) + if err != nil { + return err + } + + if len(response.Kvs) > 0 { + respData = response.Kvs[0].Value + break loop + } + case resp := <-ch: + for _, event := range resp.Events { + if event.Type == clientv3.EventTypePut { + respData = event.Kv.Value + break loop + } + } + } + } + + var cmdResp cmdResponse + if err := json.Unmarshal(respData, &cmdResp); err != nil { + return err + } + + if cmdResp.ErrorMessage != "" { + return errors.New(cmdResp.ErrorMessage) + } + + return json.Unmarshal(cmdResp.Data, obj) +} + +func (c *etcdClient) Command(ctx context.Context, cmdType string, request interface{}, response interface{}) (string, error) { + requestID, err := c.sendCmd(ctx, cmdType, request) + if err != nil { + return requestID, err + } + return requestID, c.waitCmdResponse(ctx, requestID, &response) +} + +func (c *etcdClient) TakeCommand(ctx context.Context, reqID string) (bool, error) { + resp, err := c.etcdCli.Delete(ctx, ttlCmdKeyRequestPrefix+reqID) + if err != nil { + return false, err + } + return resp.Deleted > 0, nil +} + +func (c *etcdClient) ResponseCommand(ctx context.Context, reqID string, obj interface{}) error { + resp := &cmdResponse{ + RequestID: reqID, + } + + if err, ok := obj.(error); ok { + resp.ErrorMessage = err.Error() + } else { + data, err := json.Marshal(obj) + if err != nil { + return err + } + resp.Data = data + } + + respJSON, err := json.Marshal(resp) + if err != nil { + return err + } + + lease, err := c.etcdCli.Grant(ctx, ttlCmdKeyLeaseSeconds) + if err != nil { + return err + } + + _, err = c.etcdCli.Put(ctx, ttlCmdKeyResponsePrefix+reqID, string(respJSON), clientv3.WithLease(lease.ID)) + return err +} + +func (c *etcdClient) WatchCommand(ctx context.Context) <-chan *CmdRequest { + ch := make(chan *CmdRequest) + go func() { + ctx, cancel := context.WithCancel(ctx) + defer func() { + cancel() + close(ch) + }() + + etcdCh := c.etcdCli.Watch(ctx, ttlCmdKeyRequestPrefix, clientv3.WithPrefix()) + for resp := range etcdCh { + for _, event := range resp.Events { + if event.Type != clientv3.EventTypePut { + continue + } + + var request CmdRequest + if err := json.Unmarshal(event.Kv.Value, &request); err != nil { + logutil.BgLogger().Error( + "failed to parse ttl cmd payload", + zap.Error(err), + zap.ByteString("key", event.Kv.Key), + zap.ByteString("value", event.Kv.Value), + ) + } + + select { + case ch <- &request: + case <-ctx.Done(): + return + } + } + } + }() + + return ch +} + +type mockClient struct { + sync.Mutex + store map[string]interface{} + watchers []chan *CmdRequest +} + +// NewMockCommandClient creates a mock client +func NewMockCommandClient() CommandClient { + return &mockClient{ + store: make(map[string]interface{}), + watchers: make([]chan *CmdRequest, 0, 1), + } +} + +func (c *mockClient) Command(ctx context.Context, cmdType string, request interface{}, response interface{}) (string, error) { + ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(ttlCmdKeyLeaseSeconds)) + defer cancel() + + reqID, err := c.sendCmd(ctx, cmdType, request) + if err != nil { + return reqID, err + } + + responseKey := ttlCmdKeyResponsePrefix + reqID + for ctx.Err() == nil { + c.Lock() + val, ok := c.store[responseKey] + c.Unlock() + + if !ok { + continue + } + + res, ok := val.(*cmdResponse) + if !ok { + return reqID, errors.New("response cannot be casted to *cmdResponse") + } + + if res.ErrorMessage != "" { + return reqID, errors.New(res.ErrorMessage) + } + + if err = json.Unmarshal(res.Data, response); err != nil { + return reqID, err + } + return reqID, nil + } + return reqID, ctx.Err() +} + +func (c *mockClient) sendCmd(ctx context.Context, cmdType string, request interface{}) (string, error) { + reqID := uuid.New().String() + data, err := json.Marshal(request) + if err != nil { + return reqID, err + } + + req := &CmdRequest{ + RequestID: reqID, + CmdType: cmdType, + Data: data, + } + + c.Lock() + defer c.Unlock() + key := ttlCmdKeyRequestPrefix + reqID + c.store[key] = req + for _, ch := range c.watchers { + select { + case <-ctx.Done(): + return reqID, ctx.Err() + case ch <- req: + default: + return reqID, errors.New("watcher channel is blocked") + } + } + return reqID, nil +} + +func (c *mockClient) TakeCommand(_ context.Context, reqID string) (bool, error) { + c.Lock() + defer c.Unlock() + key := ttlCmdKeyRequestPrefix + reqID + if _, ok := c.store[key]; ok { + delete(c.store, key) + return true, nil + } + return false, nil +} + +func (c *mockClient) ResponseCommand(_ context.Context, reqID string, obj interface{}) error { + c.Lock() + defer c.Unlock() + + resp := &cmdResponse{ + RequestID: reqID, + } + + if respErr, ok := obj.(error); ok { + resp.ErrorMessage = respErr.Error() + } else { + jsonData, err := json.Marshal(obj) + if err != nil { + return err + } + resp.Data = jsonData + } + + c.store[ttlCmdKeyResponsePrefix+reqID] = resp + return nil +} + +func (c *mockClient) WatchCommand(ctx context.Context) <-chan *CmdRequest { + c.Lock() + defer c.Unlock() + ch := make(chan *CmdRequest, 16+len(c.store)) + c.watchers = append(c.watchers, ch) + for key, val := range c.store { + if strings.HasPrefix(key, ttlCmdKeyRequestPrefix) { + if req, ok := val.(*CmdRequest); ok { + ch <- req + } + } + } + go func() { + <-ctx.Done() + c.Lock() + defer c.Unlock() + for i, chItem := range c.watchers { + if chItem == ch { + c.watchers = append(c.watchers[:i], c.watchers[i+1:]...) + break + } + } + close(ch) + }() + return ch +} diff --git a/ttl/client/command_test.go b/ttl/client/command_test.go new file mode 100644 index 0000000000000..830137f32904e --- /dev/null +++ b/ttl/client/command_test.go @@ -0,0 +1,139 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + "context" + "encoding/json" + "testing" + "time" + + "github.com/pingcap/errors" + "github.com/stretchr/testify/require" + "go.etcd.io/etcd/tests/v3/integration" +) + +type mockCmdRequest struct { + V1 string `json:"v_1"` + V2 int `json:"v_2"` +} + +type mockCmdResponse struct { + V3 string `json:"v_3"` + V4 int `json:"v_4"` +} + +func TestCommandClient(t *testing.T) { + integration.BeforeTestExternal(t) + + cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) + defer cluster.Terminate(t) + etcd := cluster.RandClient() + + etcdCli := NewEtcdCommandClient(etcd) + mockCli := NewMockCommandClient() + + ctx, cancel := context.WithTimeout(context.TODO(), time.Minute) + defer cancel() + + resCh := make(chan *mockCmdResponse) + defer close(resCh) + + for _, cli := range []CommandClient{etcdCli, mockCli} { + var sendRequestID, recvRequestID string + + // send command + go func() { + var err error + var res mockCmdResponse + defer func() { + resCh <- &res + }() + req := &mockCmdRequest{V1: "1", V2: 2} + sendRequestID, err = cli.Command(ctx, "type1", req, &res) + require.NoError(t, err) + require.NotEmpty(t, sendRequestID) + }() + + // check the received command and send response + watcher := cli.WatchCommand(ctx) + select { + case cmd, ok := <-watcher: + require.True(t, ok) + require.NotNil(t, cmd) + require.Equal(t, "type1", cmd.CmdType) + recvRequestID = cmd.RequestID + var gotReq mockCmdRequest + require.NoError(t, json.Unmarshal(cmd.Data, &gotReq)) + require.Equal(t, "1", gotReq.V1) + require.Equal(t, 2, gotReq.V2) + ok, err := cli.TakeCommand(ctx, recvRequestID) + require.NoError(t, err) + require.True(t, ok) + require.NoError(t, cli.ResponseCommand(ctx, cmd.RequestID, &mockCmdResponse{V3: "3", V4: 4})) + case <-ctx.Done(): + require.FailNow(t, ctx.Err().Error()) + } + + // check received response + select { + case res := <-resCh: + require.NotNil(t, res) + require.Equal(t, recvRequestID, sendRequestID) + require.Equal(t, "3", res.V3) + require.Equal(t, 4, res.V4) + case <-ctx.Done(): + require.FailNow(t, ctx.Err().Error()) + } + + // Take command again should return false, nil + ok, err := cli.TakeCommand(ctx, recvRequestID) + require.NoError(t, err) + require.False(t, ok) + + // send command and expect an error + go func() { + var err error + var res mockCmdResponse + defer func() { + resCh <- &res + }() + req := &mockCmdRequest{V1: "1", V2: 2} + sendRequestID, err = cli.Command(ctx, "type1", req, &res) + require.NotEmpty(t, sendRequestID) + require.EqualError(t, err, "mockErr") + }() + + // response an error + watcher = cli.WatchCommand(ctx) + select { + case cmd, ok := <-watcher: + require.True(t, ok) + require.NotNil(t, cmd) + _, err = cli.TakeCommand(ctx, cmd.RequestID) + require.NoError(t, err) + require.NoError(t, cli.ResponseCommand(ctx, cmd.RequestID, errors.New("mockErr"))) + case <-ctx.Done(): + require.FailNow(t, ctx.Err().Error()) + } + + // wait send goroutine exit + select { + case <-resCh: + case <-ctx.Done(): + require.FailNow(t, ctx.Err().Error()) + } + } +} diff --git a/ttl/metrics/BUILD.bazel b/ttl/metrics/BUILD.bazel new file mode 100644 index 0000000000000..f0666b5c59530 --- /dev/null +++ b/ttl/metrics/BUILD.bazel @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "metrics", + srcs = ["metrics.go"], + importpath = "github.com/pingcap/tidb/ttl/metrics", + visibility = ["//visibility:public"], + deps = [ + "//metrics", + "@com_github_prometheus_client_golang//prometheus", + ], +) + +go_test( + name = "metrics_test", + srcs = ["metrics_test.go"], + embed = [":metrics"], + deps = ["@com_github_stretchr_testify//require"], +) diff --git a/ttl/metrics/metrics.go b/ttl/metrics/metrics.go new file mode 100644 index 0000000000000..8768b0e267388 --- /dev/null +++ b/ttl/metrics/metrics.go @@ -0,0 +1,149 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metrics + +import ( + "context" + "time" + + "github.com/pingcap/tidb/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +// Phases to trace +var ( + PhaseIdle = "idle" + PhaseBeginTxn = "begin_txn" + PhaseCommitTxn = "commit_txn" + PhaseQuery = "query" + PhaseCheckTTL = "check_ttl" + PhaseWaitRetry = "wait_retry" + PhaseDispatch = "dispatch" + PhaseWaitToken = "wait_token" + PhaseOther = "other" +) + +// TTL metrics +var ( + SelectSuccessDuration = metrics.TTLQueryDuration.With(prometheus.Labels{metrics.LblSQLType: "select", metrics.LblResult: metrics.LblOK}) + SelectErrorDuration = metrics.TTLQueryDuration.With(prometheus.Labels{metrics.LblSQLType: "select", metrics.LblResult: metrics.LblError}) + DeleteSuccessDuration = metrics.TTLQueryDuration.With(prometheus.Labels{metrics.LblSQLType: "delete", metrics.LblResult: metrics.LblOK}) + DeleteErrorDuration = metrics.TTLQueryDuration.With(prometheus.Labels{metrics.LblSQLType: "delete", metrics.LblResult: metrics.LblError}) + + ScannedExpiredRows = metrics.TTLProcessedExpiredRowsCounter.With(prometheus.Labels{metrics.LblSQLType: "select", metrics.LblResult: metrics.LblOK}) + DeleteSuccessExpiredRows = metrics.TTLProcessedExpiredRowsCounter.With(prometheus.Labels{metrics.LblSQLType: "delete", metrics.LblResult: metrics.LblOK}) + DeleteErrorExpiredRows = metrics.TTLProcessedExpiredRowsCounter.With(prometheus.Labels{metrics.LblSQLType: "delete", metrics.LblResult: metrics.LblError}) + + RunningJobsCnt = metrics.TTLJobStatus.With(prometheus.Labels{metrics.LblType: "running"}) + CancellingJobsCnt = metrics.TTLJobStatus.With(prometheus.Labels{metrics.LblType: "cancelling"}) +) + +func initWorkerPhases(workerType string) map[string]prometheus.Counter { + return map[string]prometheus.Counter{ + PhaseIdle: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseIdle), + PhaseBeginTxn: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseBeginTxn), + PhaseCommitTxn: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseCommitTxn), + PhaseQuery: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseQuery), + PhaseWaitRetry: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseWaitRetry), + PhaseDispatch: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseDispatch), + PhaseCheckTTL: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseCheckTTL), + PhaseWaitToken: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseWaitToken), + PhaseOther: metrics.TTLPhaseTime.WithLabelValues(workerType, PhaseOther), + } +} + +var scanWorkerPhases = initWorkerPhases("scan_worker") +var deleteWorkerPhases = initWorkerPhases("delete_worker") + +// PhaseTracer is used to tracer the phases duration +type PhaseTracer struct { + getTime func() time.Time + recordDuration func(phase string, duration time.Duration) + + phase string + phaseTime time.Time +} + +// NewScanWorkerPhaseTracer returns a tracer for scan worker +func NewScanWorkerPhaseTracer() *PhaseTracer { + return newPhaseTracer(time.Now, func(status string, duration time.Duration) { + if counter, ok := scanWorkerPhases[status]; ok { + counter.Add(duration.Seconds()) + } + }) +} + +// NewDeleteWorkerPhaseTracer returns a tracer for delete worker +func NewDeleteWorkerPhaseTracer() *PhaseTracer { + return newPhaseTracer(time.Now, func(status string, duration time.Duration) { + if counter, ok := deleteWorkerPhases[status]; ok { + counter.Add(duration.Seconds()) + } + }) +} + +func newPhaseTracer(getTime func() time.Time, recordDuration func(status string, duration time.Duration)) *PhaseTracer { + return &PhaseTracer{ + getTime: getTime, + recordDuration: recordDuration, + phaseTime: getTime(), + } +} + +// Phase returns the current phase +func (t *PhaseTracer) Phase() string { + if t == nil { + return "" + } + return t.phase +} + +// EnterPhase enters into a new phase +func (t *PhaseTracer) EnterPhase(phase string) { + if t == nil { + return + } + + now := t.getTime() + if t.phase != "" { + t.recordDuration(t.phase, now.Sub(t.phaseTime)) + } + + t.phase = phase + t.phaseTime = now +} + +// EndPhase ends the current phase +func (t *PhaseTracer) EndPhase() { + if t == nil { + return + } + t.EnterPhase("") +} + +const ttlPhaseTraceKey = "ttlPhaseTraceKey" + +// CtxWithPhaseTracer create a new context with tracer +func CtxWithPhaseTracer(ctx context.Context, tracer *PhaseTracer) context.Context { + return context.WithValue(ctx, ttlPhaseTraceKey, tracer) +} + +// PhaseTracerFromCtx returns a tracer from a given context +func PhaseTracerFromCtx(ctx context.Context) *PhaseTracer { + if tracer, ok := ctx.Value(ttlPhaseTraceKey).(*PhaseTracer); ok { + return tracer + } + return nil +} diff --git a/ttl/metrics/metrics_test.go b/ttl/metrics/metrics_test.go new file mode 100644 index 0000000000000..68ca303756ce0 --- /dev/null +++ b/ttl/metrics/metrics_test.go @@ -0,0 +1,70 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metrics + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestPhaseTracer(t *testing.T) { + tm := time.Now() + getTime := func() time.Time { + return tm + } + + lastReportStatus := "" + lastReportDuration := time.Duration(0) + resetReport := func() { + lastReportStatus = "" + lastReportDuration = time.Duration(0) + } + + tracer := newPhaseTracer(getTime, func(status string, duration time.Duration) { + require.Equal(t, "", lastReportStatus) + require.Equal(t, int64(0), lastReportDuration.Nanoseconds()) + lastReportStatus = status + lastReportDuration = duration + }) + + resetReport() + tm = tm.Add(time.Second * 2) + tracer.EnterPhase("p1") + require.Equal(t, "", lastReportStatus) + require.Equal(t, int64(0), lastReportDuration.Nanoseconds()) + require.Equal(t, "p1", tracer.Phase()) + + tm = tm.Add(time.Second * 5) + tracer.EnterPhase("p2") + require.Equal(t, "p1", lastReportStatus) + require.Equal(t, time.Second*5, lastReportDuration) + require.Equal(t, "p2", tracer.Phase()) + + resetReport() + tm = tm.Add(time.Second * 10) + tracer.EnterPhase("p2") + require.Equal(t, "p2", lastReportStatus) + require.Equal(t, time.Second*10, lastReportDuration) + require.Equal(t, "p2", tracer.Phase()) + + resetReport() + tm = tm.Add(time.Second * 20) + tracer.EndPhase() + require.Equal(t, "p2", lastReportStatus) + require.Equal(t, time.Second*20, lastReportDuration) + require.Equal(t, "", tracer.Phase()) +} diff --git a/ttl/session/BUILD.bazel b/ttl/session/BUILD.bazel new file mode 100644 index 0000000000000..2c9dae3fc426f --- /dev/null +++ b/ttl/session/BUILD.bazel @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "session", + srcs = ["session.go"], + importpath = "github.com/pingcap/tidb/ttl/session", + visibility = ["//visibility:public"], + deps = [ + "//infoschema", + "//kv", + "//parser/terror", + "//sessionctx", + "//sessionctx/variable", + "//sessiontxn", + "//ttl/metrics", + "//util/chunk", + "//util/sqlexec", + "@com_github_pingcap_errors//:errors", + ], +) + +go_test( + name = "session_test", + srcs = [ + "main_test.go", + "session_test.go", + "sysvar_test.go", + ], + flaky = True, + deps = [ + ":session", + "//sessionctx/variable", + "//testkit", + "//testkit/testsetup", + "@com_github_pingcap_errors//:errors", + "@com_github_stretchr_testify//require", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/ttl/session/main_test.go b/ttl/session/main_test.go new file mode 100644 index 0000000000000..330dcd581dbff --- /dev/null +++ b/ttl/session/main_test.go @@ -0,0 +1,33 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package session_test + +import ( + "testing" + + "github.com/pingcap/tidb/testkit/testsetup" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + testsetup.SetupForCommonTest() + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + } + goleak.VerifyTestMain(m, opts...) +} diff --git a/ttl/session/session.go b/ttl/session/session.go new file mode 100644 index 0000000000000..8fe2d1674e722 --- /dev/null +++ b/ttl/session/session.go @@ -0,0 +1,182 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package session + +import ( + "context" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/sessiontxn" + "github.com/pingcap/tidb/ttl/metrics" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/sqlexec" +) + +// TxnMode represents using optimistic or pessimistic mode in the transaction +type TxnMode int + +const ( + // TxnModeOptimistic means using the optimistic transaction with "BEGIN OPTIMISTIC" + TxnModeOptimistic TxnMode = iota + // TxnModePessimistic means using the pessimistic transaction with "BEGIN PESSIMISTIC" + TxnModePessimistic +) + +// Session is used to execute queries for TTL case +type Session interface { + sessionctx.Context + // SessionInfoSchema returns information schema of current session + SessionInfoSchema() infoschema.InfoSchema + // ExecuteSQL executes the sql + ExecuteSQL(ctx context.Context, sql string, args ...interface{}) ([]chunk.Row, error) + // RunInTxn executes the specified function in a txn + RunInTxn(ctx context.Context, fn func() error, mode TxnMode) (err error) + // ResetWithGlobalTimeZone resets the session time zone to global time zone + ResetWithGlobalTimeZone(ctx context.Context) error + // Close closes the session + Close() + // Now returns the current time in location specified by session var + Now() time.Time +} + +type session struct { + sessionctx.Context + sqlExec sqlexec.SQLExecutor + closeFn func(Session) +} + +// NewSession creates a new Session +func NewSession(sctx sessionctx.Context, sqlExec sqlexec.SQLExecutor, closeFn func(Session)) Session { + return &session{ + Context: sctx, + sqlExec: sqlExec, + closeFn: closeFn, + } +} + +// SessionInfoSchema returns information schema of current session +func (s *session) SessionInfoSchema() infoschema.InfoSchema { + if s.Context == nil { + return nil + } + return sessiontxn.GetTxnManager(s.Context).GetTxnInfoSchema() +} + +// ExecuteSQL executes the sql +func (s *session) ExecuteSQL(ctx context.Context, sql string, args ...interface{}) ([]chunk.Row, error) { + if s.sqlExec == nil { + return nil, errors.New("session is closed") + } + + ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnTTL) + rs, err := s.sqlExec.ExecuteInternal(ctx, sql, args...) + if err != nil { + return nil, err + } + + if rs == nil { + return nil, nil + } + + defer func() { + terror.Log(rs.Close()) + }() + + return sqlexec.DrainRecordSet(ctx, rs, 8) +} + +// RunInTxn executes the specified function in a txn +func (s *session) RunInTxn(ctx context.Context, fn func() error, txnMode TxnMode) (err error) { + tracer := metrics.PhaseTracerFromCtx(ctx) + defer tracer.EnterPhase(tracer.Phase()) + + tracer.EnterPhase(metrics.PhaseBeginTxn) + sql := "BEGIN " + switch txnMode { + case TxnModeOptimistic: + sql += "OPTIMISTIC" + case TxnModePessimistic: + sql += "PESSIMISTIC" + default: + return errors.New("unknown transaction mode") + } + if _, err = s.ExecuteSQL(ctx, sql); err != nil { + return err + } + tracer.EnterPhase(metrics.PhaseOther) + + success := false + defer func() { + if !success { + _, rollbackErr := s.ExecuteSQL(ctx, "ROLLBACK") + terror.Log(rollbackErr) + } + }() + + if err = fn(); err != nil { + return err + } + + tracer.EnterPhase(metrics.PhaseCommitTxn) + if _, err = s.ExecuteSQL(ctx, "COMMIT"); err != nil { + return err + } + tracer.EnterPhase(metrics.PhaseOther) + + success = true + return err +} + +// ResetWithGlobalTimeZone resets the session time zone to global time zone +func (s *session) ResetWithGlobalTimeZone(ctx context.Context) error { + sessVar := s.GetSessionVars() + globalTZ, err := sessVar.GetGlobalSystemVar(ctx, variable.TimeZone) + if err != nil { + return err + } + + tz, err := sessVar.GetSessionOrGlobalSystemVar(ctx, variable.TimeZone) + if err != nil { + return err + } + + if globalTZ == tz { + return nil + } + + _, err = s.ExecuteSQL(ctx, "SET @@time_zone=@@global.time_zone") + return err +} + +// Close closes the session +func (s *session) Close() { + if s.closeFn != nil { + s.closeFn(s) + s.Context = nil + s.sqlExec = nil + s.closeFn = nil + } +} + +// Now returns the current time in the location of time_zone session var +func (s *session) Now() time.Time { + return time.Now().In(s.Context.GetSessionVars().Location()) +} diff --git a/ttl/session/session_test.go b/ttl/session/session_test.go new file mode 100644 index 0000000000000..607c7a2319342 --- /dev/null +++ b/ttl/session/session_test.go @@ -0,0 +1,66 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package session_test + +import ( + "context" + "testing" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/session" + "github.com/stretchr/testify/require" +) + +func TestSessionRunInTxn(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int primary key, v int)") + se := session.NewSession(tk.Session(), tk.Session(), nil) + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + + require.NoError(t, se.RunInTxn(context.TODO(), func() error { + tk.MustExec("insert into t values (1, 10)") + return nil + }, session.TxnModeOptimistic)) + tk2.MustQuery("select * from t order by id asc").Check(testkit.Rows("1 10")) + + err := se.RunInTxn(context.TODO(), func() error { + tk.MustExec("insert into t values (2, 20)") + return errors.New("mockErr") + }, session.TxnModeOptimistic) + require.EqualError(t, err, "mockErr") + tk2.MustQuery("select * from t order by id asc").Check(testkit.Rows("1 10")) + + require.NoError(t, se.RunInTxn(context.TODO(), func() error { + tk.MustExec("insert into t values (3, 30)") + return nil + }, session.TxnModeOptimistic)) + tk2.MustQuery("select * from t order by id asc").Check(testkit.Rows("1 10", "3 30")) +} + +func TestSessionResetTimeZone(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.time_zone='UTC'") + tk.MustExec("set @@time_zone='Asia/Shanghai'") + + se := session.NewSession(tk.Session(), tk.Session(), nil) + tk.MustQuery("select @@time_zone").Check(testkit.Rows("Asia/Shanghai")) + require.NoError(t, se.ResetWithGlobalTimeZone(context.TODO())) + tk.MustQuery("select @@time_zone").Check(testkit.Rows("UTC")) +} diff --git a/ttl/session/sysvar_test.go b/ttl/session/sysvar_test.go new file mode 100644 index 0000000000000..58f61c3cc88bb --- /dev/null +++ b/ttl/session/sysvar_test.go @@ -0,0 +1,125 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package session_test + +import ( + "fmt" + "strconv" + "testing" + + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/testkit" + "github.com/stretchr/testify/require" +) + +func TestSysVarTTLJobEnable(t *testing.T) { + origEnableDDL := variable.EnableTTLJob.Load() + defer func() { + variable.EnableTTLJob.Store(origEnableDDL) + }() + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_ttl_job_enable=0") + require.False(t, variable.EnableTTLJob.Load()) + tk.MustQuery("select @@global.tidb_ttl_job_enable").Check(testkit.Rows("0")) + tk.MustQuery("select @@tidb_ttl_job_enable").Check(testkit.Rows("0")) + + tk.MustExec("set @@global.tidb_ttl_job_enable=1") + require.True(t, variable.EnableTTLJob.Load()) + tk.MustQuery("select @@global.tidb_ttl_job_enable").Check(testkit.Rows("1")) + tk.MustQuery("select @@tidb_ttl_job_enable").Check(testkit.Rows("1")) + + tk.MustExec("set @@global.tidb_ttl_job_enable=0") + require.False(t, variable.EnableTTLJob.Load()) + tk.MustQuery("select @@global.tidb_ttl_job_enable").Check(testkit.Rows("0")) + tk.MustQuery("select @@tidb_ttl_job_enable").Check(testkit.Rows("0")) +} + +func TestSysVarTTLScanBatchSize(t *testing.T) { + origScanBatchSize := variable.TTLScanBatchSize.Load() + defer func() { + variable.TTLScanBatchSize.Store(origScanBatchSize) + }() + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_ttl_scan_batch_size=789") + require.Equal(t, int64(789), variable.TTLScanBatchSize.Load()) + tk.MustQuery("select @@global.tidb_ttl_scan_batch_size").Check(testkit.Rows("789")) + tk.MustQuery("select @@tidb_ttl_scan_batch_size").Check(testkit.Rows("789")) + + tk.MustExec("set @@global.tidb_ttl_scan_batch_size=0") + require.Equal(t, int64(1), variable.TTLScanBatchSize.Load()) + tk.MustQuery("select @@global.tidb_ttl_scan_batch_size").Check(testkit.Rows("1")) + tk.MustQuery("select @@tidb_ttl_scan_batch_size").Check(testkit.Rows("1")) + + maxVal := int64(variable.DefTiDBTTLScanBatchMaxSize) + tk.MustExec(fmt.Sprintf("set @@global.tidb_ttl_scan_batch_size=%d", maxVal+1)) + require.Equal(t, maxVal, variable.TTLScanBatchSize.Load()) + tk.MustQuery("select @@global.tidb_ttl_scan_batch_size").Check(testkit.Rows(strconv.FormatInt(maxVal, 10))) + tk.MustQuery("select @@tidb_ttl_scan_batch_size").Check(testkit.Rows(strconv.FormatInt(maxVal, 10))) +} + +func TestSysVarTTLScanDeleteBatchSize(t *testing.T) { + origScanBatchSize := variable.TTLScanBatchSize.Load() + defer func() { + variable.TTLScanBatchSize.Store(origScanBatchSize) + }() + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@global.tidb_ttl_delete_batch_size=789") + require.Equal(t, int64(789), variable.TTLDeleteBatchSize.Load()) + tk.MustQuery("select @@global.tidb_ttl_delete_batch_size").Check(testkit.Rows("789")) + tk.MustQuery("select @@tidb_ttl_delete_batch_size").Check(testkit.Rows("789")) + + tk.MustExec("set @@global.tidb_ttl_delete_batch_size=0") + require.Equal(t, int64(1), variable.TTLDeleteBatchSize.Load()) + tk.MustQuery("select @@global.tidb_ttl_delete_batch_size").Check(testkit.Rows("1")) + tk.MustQuery("select @@tidb_ttl_delete_batch_size").Check(testkit.Rows("1")) + + maxVal := int64(variable.DefTiDBTTLDeleteBatchMaxSize) + tk.MustExec(fmt.Sprintf("set @@global.tidb_ttl_delete_batch_size=%d", maxVal+1)) + require.Equal(t, maxVal, variable.TTLDeleteBatchSize.Load()) + tk.MustQuery("select @@global.tidb_ttl_delete_batch_size").Check(testkit.Rows(strconv.FormatInt(maxVal, 10))) + tk.MustQuery("select @@tidb_ttl_delete_batch_size").Check(testkit.Rows(strconv.FormatInt(maxVal, 10))) +} + +func TestSysVarTTLScanDeleteLimit(t *testing.T) { + origDeleteLimit := variable.TTLDeleteRateLimit.Load() + defer func() { + variable.TTLDeleteRateLimit.Store(origDeleteLimit) + }() + + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustQuery("select @@global.tidb_ttl_delete_rate_limit").Check(testkit.Rows("0")) + + tk.MustExec("set @@global.tidb_ttl_delete_rate_limit=100000") + require.Equal(t, int64(100000), variable.TTLDeleteRateLimit.Load()) + tk.MustQuery("select @@global.tidb_ttl_delete_rate_limit").Check(testkit.Rows("100000")) + tk.MustQuery("select @@tidb_ttl_delete_rate_limit").Check(testkit.Rows("100000")) + + tk.MustExec("set @@global.tidb_ttl_delete_rate_limit=0") + require.Equal(t, int64(0), variable.TTLDeleteRateLimit.Load()) + tk.MustQuery("select @@global.tidb_ttl_delete_rate_limit").Check(testkit.Rows("0")) + tk.MustQuery("select @@tidb_ttl_delete_rate_limit").Check(testkit.Rows("0")) + + tk.MustExec("set @@global.tidb_ttl_delete_rate_limit=-1") + require.Equal(t, int64(0), variable.TTLDeleteRateLimit.Load()) + tk.MustQuery("select @@global.tidb_ttl_delete_rate_limit").Check(testkit.Rows("0")) + tk.MustQuery("select @@tidb_ttl_delete_rate_limit").Check(testkit.Rows("0")) +} diff --git a/ttl/sqlbuilder/BUILD.bazel b/ttl/sqlbuilder/BUILD.bazel new file mode 100644 index 0000000000000..505e9ffcb3576 --- /dev/null +++ b/ttl/sqlbuilder/BUILD.bazel @@ -0,0 +1,44 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "sqlbuilder", + srcs = ["sql.go"], + importpath = "github.com/pingcap/tidb/ttl/sqlbuilder", + visibility = ["//visibility:public"], + deps = [ + "//parser/ast", + "//parser/format", + "//parser/model", + "//parser/mysql", + "//ttl/cache", + "//types", + "//util/sqlexec", + "@com_github_pkg_errors//:errors", + ], +) + +go_test( + name = "sqlbuilder_test", + srcs = [ + "main_test.go", + "sql_test.go", + ], + flaky = True, + deps = [ + ":sqlbuilder", + "//kv", + "//parser", + "//parser/ast", + "//parser/model", + "//parser/mysql", + "//parser/terror", + "//testkit", + "//testkit/testsetup", + "//ttl/cache", + "//types", + "//util/dbterror", + "//util/sqlexec", + "@com_github_stretchr_testify//require", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/ttl/sqlbuilder/main_test.go b/ttl/sqlbuilder/main_test.go new file mode 100644 index 0000000000000..76cecabaf752c --- /dev/null +++ b/ttl/sqlbuilder/main_test.go @@ -0,0 +1,33 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sqlbuilder_test + +import ( + "testing" + + "github.com/pingcap/tidb/testkit/testsetup" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + testsetup.SetupForCommonTest() + opts := []goleak.Option{ + goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), + goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + } + goleak.VerifyTestMain(m, opts...) +} diff --git a/ttl/sqlbuilder/sql.go b/ttl/sqlbuilder/sql.go new file mode 100644 index 0000000000000..29b0a094026d3 --- /dev/null +++ b/ttl/sqlbuilder/sql.go @@ -0,0 +1,483 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sqlbuilder + +import ( + "encoding/hex" + "fmt" + "io" + "strconv" + "strings" + "time" + + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/format" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/sqlexec" + "github.com/pkg/errors" +) + +const dateTimeFormat = "2006-01-02 15:04:05.999999" + +func writeHex(in io.Writer, d types.Datum) error { + _, err := fmt.Fprintf(in, "x'%s'", hex.EncodeToString(d.GetBytes())) + return err +} + +func writeDatum(restoreCtx *format.RestoreCtx, d types.Datum, ft *types.FieldType) error { + switch ft.GetType() { + case mysql.TypeBit, mysql.TypeBlob, mysql.TypeLongBlob, mysql.TypeTinyBlob: + return writeHex(restoreCtx.In, d) + case mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar, mysql.TypeEnum, mysql.TypeSet: + if mysql.HasBinaryFlag(ft.GetFlag()) { + return writeHex(restoreCtx.In, d) + } + _, err := fmt.Fprintf(restoreCtx.In, "'%s'", sqlexec.EscapeString(d.GetString())) + return err + } + expr := ast.NewValueExpr(d.GetValue(), ft.GetCharset(), ft.GetCollate()) + return expr.Restore(restoreCtx) +} + +// FormatSQLDatum formats the datum to a value string in sql +func FormatSQLDatum(d types.Datum, ft *types.FieldType) (string, error) { + var sb strings.Builder + ctx := format.NewRestoreCtx(format.DefaultRestoreFlags, &sb) + if err := writeDatum(ctx, d, ft); err != nil { + return "", err + } + return sb.String(), nil +} + +type sqlBuilderState int + +const ( + writeBegin sqlBuilderState = iota + writeSelOrDel + writeWhere + writeOrderBy + writeLimit + writeDone +) + +// SQLBuilder is used to build SQLs for TTL +type SQLBuilder struct { + tbl *cache.PhysicalTable + sb strings.Builder + restoreCtx *format.RestoreCtx + state sqlBuilderState + + isReadOnly bool + hasWriteExpireCond bool +} + +// NewSQLBuilder creates a new TTLSQLBuilder +func NewSQLBuilder(tbl *cache.PhysicalTable) *SQLBuilder { + b := &SQLBuilder{tbl: tbl, state: writeBegin} + b.restoreCtx = format.NewRestoreCtx(format.DefaultRestoreFlags, &b.sb) + return b +} + +// Build builds the final sql +func (b *SQLBuilder) Build() (string, error) { + if b.state == writeBegin { + return "", errors.Errorf("invalid state: %v", b.state) + } + + if !b.isReadOnly && !b.hasWriteExpireCond { + // check whether the `timeRow < expire_time` condition has been written to make sure this SQL is safe. + return "", errors.New("expire condition not write") + } + + if b.state != writeDone { + b.state = writeDone + } + + return b.sb.String(), nil +} + +// WriteSelect writes a select statement to select key columns without any condition +func (b *SQLBuilder) WriteSelect() error { + if b.state != writeBegin { + return errors.Errorf("invalid state: %v", b.state) + } + b.restoreCtx.WritePlain("SELECT LOW_PRIORITY ") + b.writeColNames(b.tbl.KeyColumns, false) + b.restoreCtx.WritePlain(" FROM ") + if err := b.writeTblName(); err != nil { + return err + } + if par := b.tbl.PartitionDef; par != nil { + b.restoreCtx.WritePlain(" PARTITION(") + b.restoreCtx.WriteName(par.Name.O) + b.restoreCtx.WritePlain(")") + } + b.state = writeSelOrDel + b.isReadOnly = true + return nil +} + +// WriteDelete writes a delete statement without any condition +func (b *SQLBuilder) WriteDelete() error { + if b.state != writeBegin { + return errors.Errorf("invalid state: %v", b.state) + } + b.restoreCtx.WritePlain("DELETE LOW_PRIORITY FROM ") + if err := b.writeTblName(); err != nil { + return err + } + if par := b.tbl.PartitionDef; par != nil { + b.restoreCtx.WritePlain(" PARTITION(") + b.restoreCtx.WriteName(par.Name.O) + b.restoreCtx.WritePlain(")") + } + b.state = writeSelOrDel + return nil +} + +// WriteCommonCondition writes a new condition +func (b *SQLBuilder) WriteCommonCondition(cols []*model.ColumnInfo, op string, dp []types.Datum) error { + switch b.state { + case writeSelOrDel: + b.restoreCtx.WritePlain(" WHERE ") + b.state = writeWhere + case writeWhere: + b.restoreCtx.WritePlain(" AND ") + default: + return errors.Errorf("invalid state: %v", b.state) + } + + b.writeColNames(cols, len(cols) > 1) + b.restoreCtx.WritePlain(" ") + b.restoreCtx.WritePlain(op) + b.restoreCtx.WritePlain(" ") + return b.writeDataPoint(cols, dp) +} + +// WriteExpireCondition writes a condition with the time column +func (b *SQLBuilder) WriteExpireCondition(expire time.Time) error { + switch b.state { + case writeSelOrDel: + b.restoreCtx.WritePlain(" WHERE ") + b.state = writeWhere + case writeWhere: + b.restoreCtx.WritePlain(" AND ") + default: + return errors.Errorf("invalid state: %v", b.state) + } + + b.writeColNames([]*model.ColumnInfo{b.tbl.TimeColumn}, false) + b.restoreCtx.WritePlain(" < ") + b.restoreCtx.WritePlain("'") + b.restoreCtx.WritePlain(expire.Format(dateTimeFormat)) + b.restoreCtx.WritePlain("'") + b.hasWriteExpireCond = true + return nil +} + +// WriteInCondition writes an IN condition +func (b *SQLBuilder) WriteInCondition(cols []*model.ColumnInfo, dps ...[]types.Datum) error { + switch b.state { + case writeSelOrDel: + b.restoreCtx.WritePlain(" WHERE ") + b.state = writeWhere + case writeWhere: + b.restoreCtx.WritePlain(" AND ") + default: + return errors.Errorf("invalid state: %v", b.state) + } + + b.writeColNames(cols, len(cols) > 1) + b.restoreCtx.WritePlain(" IN ") + b.restoreCtx.WritePlain("(") + first := true + for _, v := range dps { + if first { + first = false + } else { + b.restoreCtx.WritePlain(", ") + } + if err := b.writeDataPoint(cols, v); err != nil { + return err + } + } + b.restoreCtx.WritePlain(")") + return nil +} + +// WriteOrderBy writes order by +func (b *SQLBuilder) WriteOrderBy(cols []*model.ColumnInfo, desc bool) error { + if b.state != writeSelOrDel && b.state != writeWhere { + return errors.Errorf("invalid state: %v", b.state) + } + b.state = writeOrderBy + b.restoreCtx.WritePlain(" ORDER BY ") + b.writeColNames(cols, false) + if desc { + b.restoreCtx.WritePlain(" DESC") + } else { + b.restoreCtx.WritePlain(" ASC") + } + return nil +} + +// WriteLimit writes the limit +func (b *SQLBuilder) WriteLimit(n int) error { + if b.state != writeSelOrDel && b.state != writeWhere && b.state != writeOrderBy { + return errors.Errorf("invalid state: %v", b.state) + } + b.state = writeLimit + b.restoreCtx.WritePlain(" LIMIT ") + b.restoreCtx.WritePlain(strconv.Itoa(n)) + return nil +} + +func (b *SQLBuilder) writeTblName() error { + tn := ast.TableName{Schema: b.tbl.Schema, Name: b.tbl.Name} + return tn.Restore(b.restoreCtx) +} + +func (b *SQLBuilder) writeColName(col *model.ColumnInfo) { + b.restoreCtx.WriteName(col.Name.O) +} + +func (b *SQLBuilder) writeColNames(cols []*model.ColumnInfo, writeBrackets bool) { + if writeBrackets { + b.restoreCtx.WritePlain("(") + } + + first := true + for _, col := range cols { + if first { + first = false + } else { + b.restoreCtx.WritePlain(", ") + } + b.writeColName(col) + } + + if writeBrackets { + b.restoreCtx.WritePlain(")") + } +} + +func (b *SQLBuilder) writeDataPoint(cols []*model.ColumnInfo, dp []types.Datum) error { + writeBrackets := len(cols) > 1 + if len(cols) != len(dp) { + return errors.Errorf("col count not match %d != %d", len(cols), len(dp)) + } + + if writeBrackets { + b.restoreCtx.WritePlain("(") + } + + first := true + for i, d := range dp { + if first { + first = false + } else { + b.restoreCtx.WritePlain(", ") + } + if err := writeDatum(b.restoreCtx, d, &cols[i].FieldType); err != nil { + return err + } + } + + if writeBrackets { + b.restoreCtx.WritePlain(")") + } + + return nil +} + +// ScanQueryGenerator generates SQLs for scan task +type ScanQueryGenerator struct { + tbl *cache.PhysicalTable + expire time.Time + keyRangeStart []types.Datum + keyRangeEnd []types.Datum + stack [][]types.Datum + limit int + firstBuild bool + exhausted bool +} + +// NewScanQueryGenerator creates a new ScanQueryGenerator +func NewScanQueryGenerator(tbl *cache.PhysicalTable, expire time.Time, rangeStart []types.Datum, rangeEnd []types.Datum) (*ScanQueryGenerator, error) { + if err := tbl.ValidateKeyPrefix(rangeStart); err != nil { + return nil, err + } + + if err := tbl.ValidateKeyPrefix(rangeEnd); err != nil { + return nil, err + } + + return &ScanQueryGenerator{ + tbl: tbl, + expire: expire, + keyRangeStart: rangeStart, + keyRangeEnd: rangeEnd, + firstBuild: true, + }, nil +} + +// NextSQL creates next sql of the scan task +func (g *ScanQueryGenerator) NextSQL(continueFromResult [][]types.Datum, nextLimit int) (string, error) { + if g.exhausted { + return "", errors.New("generator is exhausted") + } + + if nextLimit <= 0 { + return "", errors.Errorf("invalid limit '%d'", nextLimit) + } + + defer func() { + g.firstBuild = false + }() + + if g.stack == nil { + g.stack = make([][]types.Datum, 0, len(g.tbl.KeyColumns)) + } + + if len(continueFromResult) >= g.limit { + var continueFromKey []types.Datum + if cnt := len(continueFromResult); cnt > 0 { + continueFromKey = continueFromResult[cnt-1] + } + if err := g.setStack(continueFromKey); err != nil { + return "", err + } + } else { + if l := len(g.stack); l > 0 { + g.stack = g.stack[:l-1] + } + if len(g.stack) == 0 { + g.exhausted = true + } + } + g.limit = nextLimit + return g.buildSQL() +} + +// IsExhausted returns whether the generator is exhausted +func (g *ScanQueryGenerator) IsExhausted() bool { + return g.exhausted +} + +func (g *ScanQueryGenerator) setStack(key []types.Datum) error { + if key == nil { + key = g.keyRangeStart + } + + if key == nil { + g.stack = g.stack[:0] + return nil + } + + if err := g.tbl.ValidateKeyPrefix(key); err != nil { + return err + } + + g.stack = g.stack[:len(key)] + for i := 0; i < len(key); i++ { + g.stack[i] = key[0 : i+1] + } + return nil +} + +func (g *ScanQueryGenerator) buildSQL() (string, error) { + if g.limit <= 0 { + return "", errors.Errorf("invalid limit '%d'", g.limit) + } + + if g.exhausted { + return "", nil + } + + b := NewSQLBuilder(g.tbl) + if err := b.WriteSelect(); err != nil { + return "", err + } + if len(g.stack) > 0 { + for i, d := range g.stack[len(g.stack)-1] { + col := []*model.ColumnInfo{g.tbl.KeyColumns[i]} + val := []types.Datum{d} + var err error + if i < len(g.stack)-1 { + err = b.WriteCommonCondition(col, "=", val) + } else if g.firstBuild { + // When `g.firstBuild == true`, that means we are querying rows after range start, because range is defined + // as [start, end), we should use ">=" to find the rows including start key. + err = b.WriteCommonCondition(col, ">=", val) + } else { + // Otherwise when `g.firstBuild != true`, that means we are continuing with the previous result, we should use + // ">" to exclude the previous row. + err = b.WriteCommonCondition(col, ">", val) + } + if err != nil { + return "", err + } + } + } + + if len(g.keyRangeEnd) > 0 { + if err := b.WriteCommonCondition(g.tbl.KeyColumns[0:len(g.keyRangeEnd)], "<", g.keyRangeEnd); err != nil { + return "", err + } + } + + if err := b.WriteExpireCondition(g.expire); err != nil { + return "", err + } + + if err := b.WriteOrderBy(g.tbl.KeyColumns, false); err != nil { + return "", err + } + + if err := b.WriteLimit(g.limit); err != nil { + return "", err + } + + return b.Build() +} + +// BuildDeleteSQL builds a delete SQL +func BuildDeleteSQL(tbl *cache.PhysicalTable, rows [][]types.Datum, expire time.Time) (string, error) { + if len(rows) == 0 { + return "", errors.New("Cannot build delete SQL with empty rows") + } + + b := NewSQLBuilder(tbl) + if err := b.WriteDelete(); err != nil { + return "", err + } + + if err := b.WriteInCondition(tbl.KeyColumns, rows...); err != nil { + return "", err + } + + if err := b.WriteExpireCondition(expire); err != nil { + return "", err + } + + if err := b.WriteLimit(len(rows)); err != nil { + return "", err + } + + return b.Build() +} diff --git a/ttl/sqlbuilder/sql_test.go b/ttl/sqlbuilder/sql_test.go new file mode 100644 index 0000000000000..76e42e6c5ca18 --- /dev/null +++ b/ttl/sqlbuilder/sql_test.go @@ -0,0 +1,945 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sqlbuilder_test + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/sqlbuilder" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/dbterror" + "github.com/pingcap/tidb/util/sqlexec" + "github.com/stretchr/testify/require" +) + +func TestEscape(t *testing.T) { + tb := &cache.PhysicalTable{ + Schema: model.NewCIStr("testp;\"';123`456"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("tp\"';123`456"), + }, + KeyColumns: []*model.ColumnInfo{ + {Name: model.NewCIStr("col1\"';123`456"), FieldType: *types.NewFieldType(mysql.TypeString)}, + }, + TimeColumn: &model.ColumnInfo{ + Name: model.NewCIStr("time\"';123`456"), + FieldType: *types.NewFieldType(mysql.TypeDatetime), + }, + PartitionDef: &model.PartitionDefinition{ + Name: model.NewCIStr("p1\"';123`456"), + }, + } + + buildSelect := func(d []types.Datum) string { + b := sqlbuilder.NewSQLBuilder(tb) + require.NoError(t, b.WriteSelect()) + require.NoError(t, b.WriteCommonCondition(tb.KeyColumns, ">", d)) + require.NoError(t, b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + s, err := b.Build() + require.NoError(t, err) + return s + } + + buildDelete := func(ds ...[]types.Datum) string { + b := sqlbuilder.NewSQLBuilder(tb) + require.NoError(t, b.WriteDelete()) + require.NoError(t, b.WriteInCondition(tb.KeyColumns, ds...)) + require.NoError(t, b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + s, err := b.Build() + require.NoError(t, err) + return s + } + + cases := []struct { + tp string + ds [][]types.Datum + sql string + }{ + { + tp: "select", + ds: [][]types.Datum{d("key1'\";123`456")}, + sql: "SELECT LOW_PRIORITY `col1\"';123``456` FROM `testp;\"';123``456`.`tp\"';123``456` PARTITION(`p1\"';123``456`) WHERE `col1\"';123``456` > 'key1\\'\\\";123`456' AND `time\"';123``456` < '1970-01-01 00:00:00'", + }, + { + tp: "delete", + ds: [][]types.Datum{d("key2'\";123`456")}, + sql: "DELETE LOW_PRIORITY FROM `testp;\"';123``456`.`tp\"';123``456` PARTITION(`p1\"';123``456`) WHERE `col1\"';123``456` IN ('key2\\'\\\";123`456') AND `time\"';123``456` < '1970-01-01 00:00:00'", + }, + { + tp: "delete", + ds: [][]types.Datum{d("key3'\";123`456"), d("key4'`\"")}, + sql: "DELETE LOW_PRIORITY FROM `testp;\"';123``456`.`tp\"';123``456` PARTITION(`p1\"';123``456`) WHERE `col1\"';123``456` IN ('key3\\'\\\";123`456', 'key4\\'`\\\"') AND `time\"';123``456` < '1970-01-01 00:00:00'", + }, + } + + for _, c := range cases { + switch c.tp { + case "select": + require.Equal(t, 1, len(c.ds)) + require.Equal(t, c.sql, buildSelect(c.ds[0])) + case "delete": + require.Equal(t, c.sql, buildDelete(c.ds...)) + default: + require.FailNow(t, "invalid tp: %s", c.tp) + } + + p := parser.New() + stmts, _, err := p.Parse(c.sql, "", "") + require.Equal(t, 1, len(stmts)) + require.NoError(t, err) + + var tbName *ast.TableName + var keyColumnName, timeColumnName string + var values []string + var timeString string + switch c.tp { + case "select": + stmt, ok := stmts[0].(*ast.SelectStmt) + require.True(t, ok) + tbName = stmt.From.TableRefs.Left.(*ast.TableSource).Source.(*ast.TableName) + and := stmt.Where.(*ast.BinaryOperationExpr) + cond1 := and.L.(*ast.BinaryOperationExpr) + keyColumnName = cond1.L.(*ast.ColumnNameExpr).Name.Name.O + values = []string{cond1.R.(ast.ValueExpr).GetValue().(string)} + cond2 := and.R.(*ast.BinaryOperationExpr) + timeColumnName = cond2.L.(*ast.ColumnNameExpr).Name.Name.O + timeString = cond2.R.(ast.ValueExpr).GetValue().(string) + case "delete": + stmt, ok := stmts[0].(*ast.DeleteStmt) + require.True(t, ok) + tbName = stmt.TableRefs.TableRefs.Left.(*ast.TableSource).Source.(*ast.TableName) + and := stmt.Where.(*ast.BinaryOperationExpr) + cond1 := and.L.(*ast.PatternInExpr) + keyColumnName = cond1.Expr.(*ast.ColumnNameExpr).Name.Name.O + require.Equal(t, len(c.ds), len(cond1.List)) + values = make([]string, 0, len(c.ds)) + for _, expr := range cond1.List { + values = append(values, expr.(ast.ValueExpr).GetValue().(string)) + } + cond2 := and.R.(*ast.BinaryOperationExpr) + timeColumnName = cond2.L.(*ast.ColumnNameExpr).Name.Name.O + timeString = cond2.R.(ast.ValueExpr).GetValue().(string) + default: + require.FailNow(t, "invalid tp: %s", c.tp) + } + + require.Equal(t, tb.Schema.O, tbName.Schema.O) + require.Equal(t, tb.Name.O, tbName.Name.O) + require.Equal(t, 1, len(tbName.PartitionNames)) + require.Equal(t, tb.PartitionDef.Name.O, tbName.PartitionNames[0].O) + require.Equal(t, tb.KeyColumns[0].Name.O, keyColumnName) + require.Equal(t, tb.TimeColumn.Name.O, timeColumnName) + for i, row := range c.ds { + require.Equal(t, row[0].GetString(), values[i]) + } + require.Equal(t, "1970-01-01 00:00:00", timeString) + } +} + +func TestFormatSQLDatum(t *testing.T) { + // invalid pk types contains the types that should not exist in primary keys of a TTL table. + // We do not need to check sqlbuilder.FormatSQLDatum for these types + invalidPKTypes := []struct { + types []string + err *terror.Error + }{ + { + types: []string{"json"}, + err: dbterror.ErrJSONUsedAsKey, + }, + { + types: []string{"blob"}, + err: dbterror.ErrBlobKeyWithoutLength, + }, + { + types: []string{"blob(8)"}, + err: dbterror.ErrBlobKeyWithoutLength, + }, + { + types: []string{"text"}, + err: dbterror.ErrBlobKeyWithoutLength, + }, + { + types: []string{"text(8)"}, + err: dbterror.ErrBlobKeyWithoutLength, + }, + { + types: []string{"int", "json"}, + err: dbterror.ErrJSONUsedAsKey, + }, + { + types: []string{"int", "blob"}, + err: dbterror.ErrBlobKeyWithoutLength, + }, + { + types: []string{"int", "text"}, + err: dbterror.ErrBlobKeyWithoutLength, + }, + { + types: []string{"float"}, + err: dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL, + }, + { + types: []string{"double"}, + err: dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL, + }, + { + types: []string{"int", "float"}, + err: dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL, + }, + { + types: []string{"int", "double"}, + err: dbterror.ErrUnsupportedPrimaryKeyTypeWithTTL, + }, + } + + cases := []struct { + ft string + values []interface{} + hex bool + }{ + { + ft: "int", + values: []interface{}{1, 2, 3, -12}, + }, + { + ft: "decimal(5, 2)", + values: []interface{}{"0.3", "128.71", "-245.32"}, + }, + { + ft: "varchar(32) CHARACTER SET latin1", + values: []interface{}{ + "aa';delete from t where 1;", + string([]byte{0xf1, 0xf2}), + string([]byte{0xf1, 0xf2, 0xf3, 0xf4}), + }, + }, + { + ft: "char(32) CHARACTER SET utf8mb4", + values: []interface{}{ + "demo", + "\n123", + "aa';delete from t where 1;", + "你好👋", + }, + }, + { + ft: "varchar(32) CHARACTER SET utf8mb4", + values: []interface{}{ + "demo", + "aa';delete from t where 1;", + "你好👋", + }, + }, + { + ft: "varchar(32) CHARACTER SET binary", + values: []interface{}{ + string([]byte{0xf1, 0xf2, 0xf3, 0xf4}), + "你好👋", + "abcdef", + }, + hex: true, + }, + { + ft: "binary(8)", + values: []interface{}{ + string([]byte{0xf1, 0xf2}), + string([]byte{0xf1, 0xf2, 0xf3, 0xf4}), + }, + hex: true, + }, + { + ft: "blob", + values: []interface{}{ + string([]byte{0xf1, 0xf2}), + string([]byte{0xf1, 0xf2, 0xf3, 0xf4}), + }, + hex: true, + }, + { + ft: "bit(1)", + values: []interface{}{0, 1}, + hex: true, + }, + { + ft: "date", + values: []interface{}{"2022-01-02", "1900-12-31"}, + }, + { + ft: "time", + values: []interface{}{"00:00", "01:23", "13:51:22"}, + }, + { + ft: "datetime", + values: []interface{}{"2022-01-02 12:11:11", "2022-01-02"}, + }, + { + ft: "datetime(6)", + values: []interface{}{"2022-01-02 12:11:11.123456"}, + }, + { + ft: "timestamp", + values: []interface{}{"2022-01-02 12:11:11", "2022-01-02"}, + }, + { + ft: "timestamp(6)", + values: []interface{}{"2022-01-02 12:11:11.123456"}, + }, + { + ft: "enum('e1', 'e2', \"e3'\", 'e4\"', ';你好👋')", + values: []interface{}{"e1", "e2", "e3'", "e4\"", ";你好👋"}, + }, + { + ft: "set('e1', 'e2', \"e3'\", 'e4\"', ';你好👋')", + values: []interface{}{"", "e1", "e2", "e3'", "e4\"", ";你好👋"}, + }, + } + + store, do := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + for _, c := range invalidPKTypes { + var sb strings.Builder + sb.WriteString("create table t(") + cols := make([]string, 0, len(invalidPKTypes)) + for i, tp := range c.types { + colName := fmt.Sprintf("pk%d", i) + cols = append(cols, colName) + sb.WriteString(colName) + sb.WriteString(" ") + sb.WriteString(tp) + sb.WriteString(", ") + } + sb.WriteString("t timestamp, ") + sb.WriteString("primary key (") + sb.WriteString(strings.Join(cols, ", ")) + sb.WriteString(")) TTL=`t` + INTERVAL 1 DAY") + tk.MustGetDBError(sb.String(), c.err) + } + + // create a table with n columns + var sb strings.Builder + sb.WriteString("CREATE TABLE t (id varchar(32) primary key") + for i, c := range cases { + _, err := fmt.Fprintf(&sb, ",\n col%d %s DEFAULT NULL", i, c.ft) + require.NoError(t, err) + } + sb.WriteString("\n);") + tk.MustExec(sb.String()) + + tbl, err := do.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + + for i, c := range cases { + for j, v := range c.values { + tk.MustExec(fmt.Sprintf("insert into t (id, col%d) values ('%d-%d', ?)", i, i, j), v) + } + } + + ctx := kv.WithInternalSourceType(context.TODO(), kv.InternalTxnOthers) + for i, c := range cases { + for j := range c.values { + rowID := fmt.Sprintf("%d-%d", i, j) + colName := fmt.Sprintf("col%d", i) + exec, ok := tk.Session().(sqlexec.SQLExecutor) + require.True(t, ok) + selectSQL := fmt.Sprintf("select %s from t where id='%s'", colName, rowID) + rs, err := exec.ExecuteInternal(ctx, selectSQL) + require.NoError(t, err, selectSQL) + rows, err := sqlexec.DrainRecordSet(ctx, rs, 1) + require.NoError(t, err, selectSQL) + require.Equal(t, 1, len(rows), selectSQL) + col := tbl.Meta().FindPublicColumnByName(colName) + d := rows[0].GetDatum(0, &col.FieldType) + s, err := sqlbuilder.FormatSQLDatum(d, &col.FieldType) + require.NoError(t, err) + tk.MustQuery("select id from t where " + colName + "=" + s).Check(testkit.Rows(rowID)) + if c.hex { + require.True(t, strings.HasPrefix(s, "x'"), "ft: %s, got: %s", c.ft, s) + } + } + } +} + +func TestSQLBuilder(t *testing.T) { + must := func(err error) { + require.NoError(t, err) + } + + mustBuild := func(b *sqlbuilder.SQLBuilder, str string) { + s, err := b.Build() + require.NoError(t, err) + require.Equal(t, str, s) + } + + var b *sqlbuilder.SQLBuilder + + t1 := &cache.PhysicalTable{ + Schema: model.NewCIStr("test"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("t1"), + }, + KeyColumns: []*model.ColumnInfo{ + {Name: model.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeVarchar)}, + }, + TimeColumn: &model.ColumnInfo{ + Name: model.NewCIStr("time"), + FieldType: *types.NewFieldType(mysql.TypeDatetime), + }, + } + + t2 := &cache.PhysicalTable{ + Schema: model.NewCIStr("test2"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("t2"), + }, + KeyColumns: []*model.ColumnInfo{ + {Name: model.NewCIStr("a"), FieldType: *types.NewFieldType(mysql.TypeVarchar)}, + {Name: model.NewCIStr("b"), FieldType: *types.NewFieldType(mysql.TypeInt24)}, + }, + TimeColumn: &model.ColumnInfo{ + Name: model.NewCIStr("time"), + FieldType: *types.NewFieldType(mysql.TypeDatetime), + }, + } + + tp := &cache.PhysicalTable{ + Schema: model.NewCIStr("testp"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("tp"), + }, + KeyColumns: t1.KeyColumns, + TimeColumn: t1.TimeColumn, + PartitionDef: &model.PartitionDefinition{ + Name: model.NewCIStr("p1"), + }, + } + + // test build select queries + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1`") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t1.KeyColumns, ">", d("a1"))) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > 'a1'") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t1.KeyColumns, ">", d("a1"))) + must(b.WriteCommonCondition(t1.KeyColumns, "<=", d("c3"))) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > 'a1' AND `id` <= 'c3'") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + shLoc, err := time.LoadLocation("Asia/Shanghai") + require.NoError(t, err) + must(b.WriteExpireCondition(time.UnixMilli(0).In(shLoc))) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `time` < '1970-01-01 08:00:00'") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t1.KeyColumns, ">", d("a1"))) + must(b.WriteCommonCondition(t1.KeyColumns, "<=", d("c3"))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > 'a1' AND `id` <= 'c3' AND `time` < '1970-01-01 00:00:00'") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteOrderBy(t1.KeyColumns, false)) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` ORDER BY `id` ASC") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteOrderBy(t1.KeyColumns, true)) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` ORDER BY `id` DESC") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteOrderBy(t1.KeyColumns, false)) + must(b.WriteLimit(128)) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` ORDER BY `id` ASC LIMIT 128") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t1.KeyColumns, ">", d("';``~?%\"\n"))) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > '\\';``~?%\\\"\\n'") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t1.KeyColumns, ">", d("a1';'"))) + must(b.WriteCommonCondition(t1.KeyColumns, "<=", d("a2\""))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + must(b.WriteOrderBy(t1.KeyColumns, false)) + must(b.WriteLimit(128)) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > 'a1\\';\\'' AND `id` <= 'a2\\\"' AND `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 128") + + b = sqlbuilder.NewSQLBuilder(t2) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t2.KeyColumns, ">", d("x1", 20))) + mustBuild(b, "SELECT LOW_PRIORITY `a`, `b` FROM `test2`.`t2` WHERE (`a`, `b`) > ('x1', 20)") + + b = sqlbuilder.NewSQLBuilder(t2) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t2.KeyColumns, "<=", d("x2", 21))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + must(b.WriteOrderBy(t2.KeyColumns, false)) + must(b.WriteLimit(100)) + mustBuild(b, "SELECT LOW_PRIORITY `a`, `b` FROM `test2`.`t2` WHERE (`a`, `b`) <= ('x2', 21) AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b` ASC LIMIT 100") + + b = sqlbuilder.NewSQLBuilder(t2) + must(b.WriteSelect()) + must(b.WriteCommonCondition(t2.KeyColumns[0:1], "=", d("x3"))) + must(b.WriteCommonCondition(t2.KeyColumns[1:2], ">", d(31))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + must(b.WriteOrderBy(t2.KeyColumns, false)) + must(b.WriteLimit(100)) + mustBuild(b, "SELECT LOW_PRIORITY `a`, `b` FROM `test2`.`t2` WHERE `a` = 'x3' AND `b` > 31 AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b` ASC LIMIT 100") + + // test build delete queries + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteDelete()) + _, err = b.Build() + require.EqualError(t, err, "expire condition not write") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteDelete()) + must(b.WriteInCondition(t1.KeyColumns, d("a"))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + mustBuild(b, "DELETE LOW_PRIORITY FROM `test`.`t1` WHERE `id` IN ('a') AND `time` < '1970-01-01 00:00:00'") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteDelete()) + must(b.WriteInCondition(t1.KeyColumns, d("a"), d("b"))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + mustBuild(b, "DELETE LOW_PRIORITY FROM `test`.`t1` WHERE `id` IN ('a', 'b') AND `time` < '1970-01-01 00:00:00'") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteDelete()) + must(b.WriteInCondition(t2.KeyColumns, d("a", 1))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + must(b.WriteLimit(100)) + mustBuild(b, "DELETE LOW_PRIORITY FROM `test`.`t1` WHERE (`a`, `b`) IN (('a', 1)) AND `time` < '1970-01-01 00:00:00' LIMIT 100") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteDelete()) + must(b.WriteInCondition(t2.KeyColumns, d("a", 1), d("b", 2))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + must(b.WriteLimit(100)) + mustBuild(b, "DELETE LOW_PRIORITY FROM `test`.`t1` WHERE (`a`, `b`) IN (('a', 1), ('b', 2)) AND `time` < '1970-01-01 00:00:00' LIMIT 100") + + b = sqlbuilder.NewSQLBuilder(t1) + must(b.WriteDelete()) + must(b.WriteInCondition(t2.KeyColumns, d("a", 1), d("b", 2))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + mustBuild(b, "DELETE LOW_PRIORITY FROM `test`.`t1` WHERE (`a`, `b`) IN (('a', 1), ('b', 2)) AND `time` < '1970-01-01 00:00:00'") + + // test select partition table + b = sqlbuilder.NewSQLBuilder(tp) + must(b.WriteSelect()) + must(b.WriteCommonCondition(tp.KeyColumns, ">", d("a1"))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + mustBuild(b, "SELECT LOW_PRIORITY `id` FROM `testp`.`tp` PARTITION(`p1`) WHERE `id` > 'a1' AND `time` < '1970-01-01 00:00:00'") + + b = sqlbuilder.NewSQLBuilder(tp) + must(b.WriteDelete()) + must(b.WriteInCondition(tp.KeyColumns, d("a"), d("b"))) + must(b.WriteExpireCondition(time.UnixMilli(0).In(time.UTC))) + mustBuild(b, "DELETE LOW_PRIORITY FROM `testp`.`tp` PARTITION(`p1`) WHERE `id` IN ('a', 'b') AND `time` < '1970-01-01 00:00:00'") +} + +func TestScanQueryGenerator(t *testing.T) { + t1 := &cache.PhysicalTable{ + Schema: model.NewCIStr("test"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("t1"), + }, + KeyColumns: []*model.ColumnInfo{ + {Name: model.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeInt24)}, + }, + TimeColumn: &model.ColumnInfo{ + Name: model.NewCIStr("time"), + FieldType: *types.NewFieldType(mysql.TypeDatetime), + }, + } + + t2 := &cache.PhysicalTable{ + Schema: model.NewCIStr("test2"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("t2"), + }, + KeyColumns: []*model.ColumnInfo{ + {Name: model.NewCIStr("a"), FieldType: *types.NewFieldType(mysql.TypeInt24)}, + {Name: model.NewCIStr("b"), FieldType: *types.NewFieldType(mysql.TypeVarchar)}, + {Name: model.NewCIStr("c"), FieldType: types.NewFieldTypeBuilder().SetType(mysql.TypeString).SetFlag(mysql.BinaryFlag).Build()}, + }, + TimeColumn: &model.ColumnInfo{ + Name: model.NewCIStr("time"), + FieldType: *types.NewFieldType(mysql.TypeDatetime), + }, + } + + result := func(last []types.Datum, n int) [][]types.Datum { + ds := make([][]types.Datum, n) + ds[n-1] = last + return ds + } + + cases := []struct { + tbl *cache.PhysicalTable + expire time.Time + rangeStart []types.Datum + rangeEnd []types.Datum + path [][]interface{} + }{ + { + tbl: t1, + expire: time.UnixMilli(0).In(time.UTC), + path: [][]interface{}{ + { + nil, 3, + "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 3", + }, + { + nil, 5, "", + }, + }, + }, + { + tbl: t1, + expire: time.UnixMilli(0).In(time.UTC), + path: [][]interface{}{ + { + nil, 3, + "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 3", + }, + { + [][]types.Datum{}, 5, "", + }, + }, + }, + { + tbl: t1, + expire: time.UnixMilli(0).In(time.UTC), + rangeStart: d(1), + rangeEnd: d(100), + path: [][]interface{}{ + { + nil, 3, + "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` >= 1 AND `id` < 100 AND `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 3", + }, + { + result(d(10), 3), 5, + "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > 10 AND `id` < 100 AND `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 5", + }, + { + result(d(15), 4), 5, + "", + }, + }, + }, + { + tbl: t1, + expire: time.UnixMilli(0).In(time.UTC), + path: [][]interface{}{ + { + nil, 3, + "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 3", + }, + { + result(d(2), 3), 5, + "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > 2 AND `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 5", + }, + { + result(d(4), 5), 6, + "SELECT LOW_PRIORITY `id` FROM `test`.`t1` WHERE `id` > 4 AND `time` < '1970-01-01 00:00:00' ORDER BY `id` ASC LIMIT 6", + }, + { + result(d(7), 5), 5, "", + }, + }, + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + path: [][]interface{}{ + { + nil, 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + nil, 5, "", + }, + }, + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + path: [][]interface{}{ + { + nil, 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + nil, 5, "", + }, + }, + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + path: [][]interface{}{ + { + nil, 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + [][]types.Datum{}, 5, "", + }, + }, + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + path: [][]interface{}{ + { + nil, 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "x", []byte{0xf0}), 4), 5, "", + }, + }, + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + rangeStart: d(1, "x", []byte{0xe}), + rangeEnd: d(100, "z", []byte{0xff}), + path: [][]interface{}{ + { + nil, 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` = 'x' AND `c` >= x'0e' AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "x", []byte{0x1a}), 5), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` = 'x' AND `c` > x'1a' AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "x", []byte{0x20}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` > 'x' AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "y", []byte{0x0a}), 5), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` = 'y' AND `c` > x'0a' AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "y", []byte{0x11}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` > 'y' AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "z", []byte{0x02}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` > 1 AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(3, "a", []byte{0x01}), 5), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 3 AND `b` = 'a' AND `c` > x'01' AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(3, "a", []byte{0x11}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 3 AND `b` > 'a' AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(3, "c", []byte{0x12}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` > 3 AND (`a`, `b`, `c`) < (100, 'z', x'ff') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(5, "e", []byte{0xa1}), 4), 5, "", + }, + }, + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + rangeStart: d(1), + rangeEnd: d(100), + path: [][]interface{}{ + { + nil, 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` >= 1 AND `a` < 100 AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "x", []byte{0x1a}), 5), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` = 'x' AND `c` > x'1a' AND `a` < 100 AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "x", []byte{0x20}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` > 'x' AND `a` < 100 AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "y", []byte{0x0a}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` > 1 AND `a` < 100 AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + }, + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + rangeStart: d(1, "x"), + rangeEnd: d(100, "z"), + path: [][]interface{}{ + { + nil, 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` >= 'x' AND (`a`, `b`) < (100, 'z') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "x", []byte{0x1a}), 5), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` = 'x' AND `c` > x'1a' AND (`a`, `b`) < (100, 'z') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "x", []byte{0x20}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` = 1 AND `b` > 'x' AND (`a`, `b`) < (100, 'z') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + { + result(d(1, "y", []byte{0x0a}), 4), 5, + "SELECT LOW_PRIORITY `a`, `b`, `c` FROM `test2`.`t2` WHERE `a` > 1 AND (`a`, `b`) < (100, 'z') AND `time` < '1970-01-01 00:00:00' ORDER BY `a`, `b`, `c` ASC LIMIT 5", + }, + }, + }, + } + + for i, c := range cases { + g, err := sqlbuilder.NewScanQueryGenerator(c.tbl, c.expire, c.rangeStart, c.rangeEnd) + require.NoError(t, err, fmt.Sprintf("%d", i)) + for j, p := range c.path { + msg := fmt.Sprintf("%d-%d", i, j) + var result [][]types.Datum + require.Equal(t, 3, len(p), msg) + if arg := p[0]; arg != nil { + r, ok := arg.([][]types.Datum) + require.True(t, ok, msg) + result = r + } + limit, ok := p[1].(int) + require.True(t, ok, msg) + sql, ok := p[2].(string) + require.True(t, ok, msg) + s, err := g.NextSQL(result, limit) + require.NoError(t, err, msg) + require.Equal(t, sql, s, msg) + require.Equal(t, s == "", g.IsExhausted(), msg) + } + } +} + +func TestBuildDeleteSQL(t *testing.T) { + t1 := &cache.PhysicalTable{ + Schema: model.NewCIStr("test"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("t1"), + }, + KeyColumns: []*model.ColumnInfo{ + {Name: model.NewCIStr("id"), FieldType: *types.NewFieldType(mysql.TypeInt24)}, + }, + TimeColumn: &model.ColumnInfo{ + Name: model.NewCIStr("time"), + FieldType: *types.NewFieldType(mysql.TypeDatetime), + }, + } + + t2 := &cache.PhysicalTable{ + Schema: model.NewCIStr("test2"), + TableInfo: &model.TableInfo{ + Name: model.NewCIStr("t2"), + }, + KeyColumns: []*model.ColumnInfo{ + {Name: model.NewCIStr("a"), FieldType: *types.NewFieldType(mysql.TypeInt24)}, + {Name: model.NewCIStr("b"), FieldType: *types.NewFieldType(mysql.TypeVarchar)}, + }, + TimeColumn: &model.ColumnInfo{ + Name: model.NewCIStr("time"), + FieldType: *types.NewFieldType(mysql.TypeDatetime), + }, + } + + cases := []struct { + tbl *cache.PhysicalTable + expire time.Time + rows [][]types.Datum + sql string + }{ + { + tbl: t1, + expire: time.UnixMilli(0).In(time.UTC), + rows: [][]types.Datum{d(1)}, + sql: "DELETE LOW_PRIORITY FROM `test`.`t1` WHERE `id` IN (1) AND `time` < '1970-01-01 00:00:00' LIMIT 1", + }, + { + tbl: t1, + expire: time.UnixMilli(0).In(time.UTC), + rows: [][]types.Datum{d(2), d(3), d(4)}, + sql: "DELETE LOW_PRIORITY FROM `test`.`t1` WHERE `id` IN (2, 3, 4) AND `time` < '1970-01-01 00:00:00' LIMIT 3", + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + rows: [][]types.Datum{d(1, "a")}, + sql: "DELETE LOW_PRIORITY FROM `test2`.`t2` WHERE (`a`, `b`) IN ((1, 'a')) AND `time` < '1970-01-01 00:00:00' LIMIT 1", + }, + { + tbl: t2, + expire: time.UnixMilli(0).In(time.UTC), + rows: [][]types.Datum{d(1, "a"), d(2, "b")}, + sql: "DELETE LOW_PRIORITY FROM `test2`.`t2` WHERE (`a`, `b`) IN ((1, 'a'), (2, 'b')) AND `time` < '1970-01-01 00:00:00' LIMIT 2", + }, + } + + for _, c := range cases { + sql, err := sqlbuilder.BuildDeleteSQL(c.tbl, c.rows, c.expire) + require.NoError(t, err) + require.Equal(t, c.sql, sql) + } +} + +func d(vs ...interface{}) []types.Datum { + datums := make([]types.Datum, len(vs)) + for i, v := range vs { + switch val := v.(type) { + case string: + datums[i] = types.NewStringDatum(val) + case int: + datums[i] = types.NewIntDatum(int64(val)) + case []byte: + datums[i] = types.NewBytesDatum(val) + default: + panic(fmt.Sprintf("invalid value type: %T, value: %v", v, v)) + } + } + return datums +} diff --git a/ttl/ttlworker/BUILD.bazel b/ttl/ttlworker/BUILD.bazel new file mode 100644 index 0000000000000..f314eca5c01ed --- /dev/null +++ b/ttl/ttlworker/BUILD.bazel @@ -0,0 +1,85 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "ttlworker", + srcs = [ + "config.go", + "del.go", + "job.go", + "job_manager.go", + "scan.go", + "session.go", + "task_manager.go", + "worker.go", + ], + importpath = "github.com/pingcap/tidb/ttl/ttlworker", + visibility = ["//visibility:public"], + deps = [ + "//kv", + "//parser/duration", + "//parser/terror", + "//sessionctx", + "//sessionctx/variable", + "//ttl/cache", + "//ttl/client", + "//ttl/metrics", + "//ttl/session", + "//ttl/sqlbuilder", + "//types", + "//util", + "//util/chunk", + "//util/logutil", + "//util/sqlexec", + "//util/timeutil", + "@com_github_google_uuid//:uuid", + "@com_github_ngaut_pools//:pools", + "@com_github_pingcap_errors//:errors", + "@com_github_pingcap_failpoint//:failpoint", + "@io_etcd_go_etcd_client_v3//:client", + "@org_golang_x_time//rate", + "@org_uber_go_multierr//:multierr", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "ttlworker_test", + srcs = [ + "del_test.go", + "job_manager_integration_test.go", + "job_manager_test.go", + "scan_test.go", + "session_test.go", + "task_manager_integration_test.go", + "task_manager_test.go", + ], + embed = [":ttlworker"], + flaky = True, + deps = [ + "//domain", + "//infoschema", + "//kv", + "//parser/ast", + "//parser/model", + "//parser/mysql", + "//session", + "//sessionctx", + "//sessionctx/variable", + "//statistics/handle", + "//testkit", + "//ttl/cache", + "//ttl/client", + "//ttl/session", + "//types", + "//util/chunk", + "//util/logutil", + "@com_github_ngaut_pools//:pools", + "@com_github_pingcap_errors//:errors", + "@com_github_pingcap_failpoint//:failpoint", + "@com_github_stretchr_testify//assert", + "@com_github_stretchr_testify//require", + "@org_golang_x_time//rate", + "@org_uber_go_atomic//:atomic", + "@org_uber_go_zap//:zap", + ], +) diff --git a/ttl/ttlworker/config.go b/ttl/ttlworker/config.go new file mode 100644 index 0000000000000..c1774bc667348 --- /dev/null +++ b/ttl/ttlworker/config.go @@ -0,0 +1,62 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "time" + + "github.com/pingcap/failpoint" +) + +const jobManagerLoopTickerInterval = 10 * time.Second + +const updateInfoSchemaCacheInterval = 2 * time.Minute +const updateTTLTableStatusCacheInterval = 2 * time.Minute + +const ttlInternalSQLTimeout = 30 * time.Second +const resizeWorkersInterval = 30 * time.Second +const splitScanCount = 64 +const ttlJobTimeout = 6 * time.Hour + +const taskManagerLoopTickerInterval = time.Minute +const ttlTaskHeartBeatTickerInterval = time.Minute + +func getUpdateInfoSchemaCacheInterval() time.Duration { + failpoint.Inject("update-info-schema-cache-interval", func(val failpoint.Value) time.Duration { + return time.Duration(val.(int)) + }) + return updateInfoSchemaCacheInterval +} + +func getUpdateTTLTableStatusCacheInterval() time.Duration { + failpoint.Inject("update-status-table-cache-interval", func(val failpoint.Value) time.Duration { + return time.Duration(val.(int)) + }) + return updateTTLTableStatusCacheInterval +} + +func getResizeWorkersInterval() time.Duration { + failpoint.Inject("resize-workers-interval", func(val failpoint.Value) time.Duration { + return time.Duration(val.(int)) + }) + return resizeWorkersInterval +} + +func getTaskManagerLoopTickerInterval() time.Duration { + failpoint.Inject("task-manager-loop-interval", func(val failpoint.Value) time.Duration { + return time.Duration(val.(int)) + }) + return taskManagerLoopTickerInterval +} diff --git a/ttl/ttlworker/del.go b/ttl/ttlworker/del.go new file mode 100644 index 0000000000000..a578f75adbd1e --- /dev/null +++ b/ttl/ttlworker/del.go @@ -0,0 +1,298 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "container/list" + "context" + "fmt" + "sync" + "sync/atomic" + "time" + + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/metrics" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/ttl/sqlbuilder" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" + "golang.org/x/time/rate" +) + +const ( + delMaxRetry = 3 + delRetryBufferSize = 128 + delRetryInterval = time.Second * 5 +) + +var globalDelRateLimiter = newDelRateLimiter() + +type delRateLimiter struct { + sync.Mutex + limiter *rate.Limiter + limit atomic.Int64 +} + +func newDelRateLimiter() *delRateLimiter { + limiter := &delRateLimiter{} + limiter.limiter = rate.NewLimiter(0, 1) + limiter.limit.Store(0) + return limiter +} + +func (l *delRateLimiter) Wait(ctx context.Context) error { + limit := l.limit.Load() + if variable.TTLDeleteRateLimit.Load() != limit { + limit = l.reset() + } + + if limit == 0 { + return ctx.Err() + } + + return l.limiter.Wait(ctx) +} + +func (l *delRateLimiter) reset() (newLimit int64) { + l.Lock() + defer l.Unlock() + newLimit = variable.TTLDeleteRateLimit.Load() + if newLimit != l.limit.Load() { + l.limit.Store(newLimit) + l.limiter.SetLimit(rate.Limit(newLimit)) + } + return +} + +type ttlDeleteTask struct { + tbl *cache.PhysicalTable + expire time.Time + rows [][]types.Datum + statistics *ttlStatistics +} + +func (t *ttlDeleteTask) doDelete(ctx context.Context, rawSe session.Session) (retryRows [][]types.Datum) { + tracer := metrics.PhaseTracerFromCtx(ctx) + defer tracer.EnterPhase(tracer.Phase()) + tracer.EnterPhase(metrics.PhaseOther) + + leftRows := t.rows + se := newTableSession(rawSe, t.tbl, t.expire) + for len(leftRows) > 0 { + maxBatch := variable.TTLDeleteBatchSize.Load() + var delBatch [][]types.Datum + if int64(len(leftRows)) < maxBatch { + delBatch = leftRows + leftRows = nil + } else { + delBatch = leftRows[0:maxBatch] + leftRows = leftRows[maxBatch:] + } + + sql, err := sqlbuilder.BuildDeleteSQL(t.tbl, delBatch, t.expire) + if err != nil { + t.statistics.IncErrorRows(len(delBatch)) + logutil.BgLogger().Warn( + "build delete SQL in TTL failed", + zap.Error(err), + zap.String("table", t.tbl.Schema.O+"."+t.tbl.Name.O), + ) + return + } + + tracer.EnterPhase(metrics.PhaseWaitToken) + if err = globalDelRateLimiter.Wait(ctx); err != nil { + t.statistics.IncErrorRows(len(delBatch)) + return + } + tracer.EnterPhase(metrics.PhaseOther) + + sqlStart := time.Now() + _, needRetry, err := se.ExecuteSQLWithCheck(ctx, sql) + sqlInterval := time.Since(sqlStart) + if err != nil { + metrics.DeleteErrorDuration.Observe(sqlInterval.Seconds()) + needRetry = needRetry && ctx.Err() == nil + logutil.BgLogger().Warn( + "delete SQL in TTL failed", + zap.Error(err), + zap.String("SQL", sql), + zap.Bool("needRetry", needRetry), + ) + + if needRetry { + if retryRows == nil { + retryRows = make([][]types.Datum, 0, len(leftRows)+len(delBatch)) + } + retryRows = append(retryRows, delBatch...) + } else { + t.statistics.IncErrorRows(len(delBatch)) + } + continue + } + + metrics.DeleteSuccessDuration.Observe(sqlInterval.Seconds()) + t.statistics.IncSuccessRows(len(delBatch)) + } + return retryRows +} + +type ttlDelRetryItem struct { + task *ttlDeleteTask + retryCnt int + inTime time.Time +} + +type ttlDelRetryBuffer struct { + list *list.List + maxSize int + maxRetry int + retryInterval time.Duration + getTime func() time.Time +} + +func newTTLDelRetryBuffer() *ttlDelRetryBuffer { + return &ttlDelRetryBuffer{ + list: list.New(), + maxSize: delRetryBufferSize, + maxRetry: delMaxRetry, + retryInterval: delRetryInterval, + getTime: time.Now, + } +} + +func (b *ttlDelRetryBuffer) Len() int { + return b.list.Len() +} + +func (b *ttlDelRetryBuffer) RecordTaskResult(task *ttlDeleteTask, retryRows [][]types.Datum) { + b.recordRetryItem(task, retryRows, 0) +} + +func (b *ttlDelRetryBuffer) DoRetry(do func(*ttlDeleteTask) [][]types.Datum) time.Duration { + for b.list.Len() > 0 { + ele := b.list.Front() + item, ok := ele.Value.(*ttlDelRetryItem) + if !ok { + logutil.BgLogger().Error(fmt.Sprintf("invalid retry buffer item type: %T", ele)) + b.list.Remove(ele) + continue + } + + now := b.getTime() + interval := now.Sub(item.inTime) + if interval < b.retryInterval { + return b.retryInterval - interval + } + + b.list.Remove(ele) + if retryRows := do(item.task); len(retryRows) > 0 { + b.recordRetryItem(item.task, retryRows, item.retryCnt+1) + } + } + return b.retryInterval +} + +func (b *ttlDelRetryBuffer) recordRetryItem(task *ttlDeleteTask, retryRows [][]types.Datum, retryCnt int) bool { + if len(retryRows) == 0 { + return false + } + + if retryCnt >= b.maxRetry { + task.statistics.IncErrorRows(len(retryRows)) + return false + } + + for b.list.Len() > 0 && b.list.Len() >= b.maxSize { + ele := b.list.Front() + if item, ok := ele.Value.(*ttlDelRetryItem); ok { + item.task.statistics.IncErrorRows(len(item.task.rows)) + } else { + logutil.BgLogger().Error(fmt.Sprintf("invalid retry buffer item type: %T", ele)) + } + b.list.Remove(b.list.Front()) + } + + newTask := *task + newTask.rows = retryRows + b.list.PushBack(&ttlDelRetryItem{ + task: &newTask, + inTime: b.getTime(), + retryCnt: retryCnt, + }) + return true +} + +type ttlDeleteWorker struct { + baseWorker + delCh <-chan *ttlDeleteTask + sessionPool sessionPool + retryBuffer *ttlDelRetryBuffer +} + +func newDeleteWorker(delCh <-chan *ttlDeleteTask, sessPool sessionPool) *ttlDeleteWorker { + w := &ttlDeleteWorker{ + delCh: delCh, + sessionPool: sessPool, + retryBuffer: newTTLDelRetryBuffer(), + } + w.init(w.loop) + return w +} + +func (w *ttlDeleteWorker) loop() error { + tracer := metrics.NewDeleteWorkerPhaseTracer() + defer func() { + tracer.EndPhase() + logutil.BgLogger().Info("ttlDeleteWorker loop exited.") + }() + + tracer.EnterPhase(metrics.PhaseOther) + se, err := getSession(w.sessionPool) + if err != nil { + return err + } + + ctx := metrics.CtxWithPhaseTracer(w.baseWorker.ctx, tracer) + + doRetry := func(task *ttlDeleteTask) [][]types.Datum { + return task.doDelete(ctx, se) + } + + timer := time.NewTimer(w.retryBuffer.retryInterval) + defer timer.Stop() + + for w.Status() == workerStatusRunning { + tracer.EnterPhase(metrics.PhaseIdle) + select { + case <-ctx.Done(): + return nil + case <-timer.C: + tracer.EnterPhase(metrics.PhaseOther) + nextInterval := w.retryBuffer.DoRetry(doRetry) + timer.Reset(nextInterval) + case task, ok := <-w.delCh: + tracer.EnterPhase(metrics.PhaseOther) + if !ok { + return nil + } + retryRows := task.doDelete(ctx, se) + w.retryBuffer.RecordTaskResult(task, retryRows) + } + } + return nil +} diff --git a/ttl/ttlworker/del_test.go b/ttl/ttlworker/del_test.go new file mode 100644 index 0000000000000..524b45c9c8806 --- /dev/null +++ b/ttl/ttlworker/del_test.go @@ -0,0 +1,389 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "errors" + "strings" + "testing" + "time" + + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/stretchr/testify/require" + "golang.org/x/time/rate" +) + +func TestTTLDelRetryBuffer(t *testing.T) { + createTask := func(name string) (*ttlDeleteTask, [][]types.Datum, *ttlStatistics) { + rows := make([][]types.Datum, 10) + statistics := &ttlStatistics{} + statistics.IncTotalRows(10) + task := &ttlDeleteTask{ + tbl: newMockTTLTbl(t, name), + expire: time.UnixMilli(0), + rows: rows, + statistics: statistics, + } + return task, rows, statistics + } + + shouldNotDoRetry := func(task *ttlDeleteTask) [][]types.Datum { + require.FailNow(t, "should not do retry") + return nil + } + + start := time.UnixMilli(0) + tm := start + buffer := newTTLDelRetryBuffer() + require.Equal(t, delRetryBufferSize, buffer.maxSize) + require.Equal(t, delMaxRetry, buffer.maxRetry) + require.Equal(t, delRetryInterval, buffer.retryInterval) + + buffer.maxSize = 3 + buffer.maxRetry = 2 + buffer.retryInterval = 10 * time.Second + buffer.getTime = func() time.Time { + return tm + } + + // add success task + task1, rows1, statics1 := createTask("t1") + buffer.RecordTaskResult(task1, nil) + require.Equal(t, 0, buffer.Len()) + buffer.DoRetry(shouldNotDoRetry) + require.Equal(t, uint64(0), statics1.ErrorRows.Load()) + + // add a task with 1 failed rows + buffer.RecordTaskResult(task1, rows1[:1]) + require.Equal(t, 1, buffer.Len()) + buffer.DoRetry(shouldNotDoRetry) + require.Equal(t, uint64(0), statics1.ErrorRows.Load()) + + // add another task with 2 failed rows + tm = tm.Add(time.Second) + task2, rows2, statics2 := createTask("t2") + buffer.RecordTaskResult(task2, rows2[:2]) + require.Equal(t, 2, buffer.Len()) + buffer.DoRetry(shouldNotDoRetry) + require.Equal(t, uint64(0), statics2.ErrorRows.Load()) + + // add another task with 3 failed rows + tm = tm.Add(time.Second) + task3, rows3, statics3 := createTask("t3") + buffer.RecordTaskResult(task3, rows3[:3]) + require.Equal(t, 3, buffer.Len()) + buffer.DoRetry(shouldNotDoRetry) + require.Equal(t, uint64(0), statics3.ErrorRows.Load()) + + // add new task will eliminate old tasks + tm = tm.Add(time.Second) + task4, rows4, statics4 := createTask("t4") + buffer.RecordTaskResult(task4, rows4[:4]) + require.Equal(t, 3, buffer.Len()) + buffer.DoRetry(shouldNotDoRetry) + require.Equal(t, uint64(0), statics4.ErrorRows.Load()) + require.Equal(t, uint64(1), statics1.ErrorRows.Load()) + + // poll up-to-date tasks + tm = tm.Add(10*time.Second - time.Millisecond) + tasks := make([]*ttlDeleteTask, 0) + doRetrySuccess := func(task *ttlDeleteTask) [][]types.Datum { + task.statistics.IncSuccessRows(len(task.rows)) + tasks = append(tasks, task) + return nil + } + nextInterval := buffer.DoRetry(doRetrySuccess) + require.Equal(t, time.Millisecond, nextInterval) + require.Equal(t, 2, len(tasks)) + require.Equal(t, "t2", tasks[0].tbl.Name.L) + require.Equal(t, time.UnixMilli(0), tasks[0].expire) + require.Equal(t, 2, len(tasks[0].rows)) + require.Equal(t, uint64(2), statics2.SuccessRows.Load()) + require.Equal(t, uint64(0), statics2.ErrorRows.Load()) + require.Equal(t, "t3", tasks[1].tbl.Name.L) + require.Equal(t, time.UnixMilli(0), tasks[0].expire) + require.Equal(t, 3, len(tasks[1].rows)) + require.Equal(t, 1, buffer.Len()) + require.Equal(t, uint64(3), statics3.SuccessRows.Load()) + require.Equal(t, uint64(0), statics3.ErrorRows.Load()) + require.Equal(t, uint64(0), statics4.SuccessRows.Load()) + require.Equal(t, uint64(0), statics4.ErrorRows.Load()) + + // poll next + tm = tm.Add(time.Millisecond) + tasks = make([]*ttlDeleteTask, 0) + nextInterval = buffer.DoRetry(doRetrySuccess) + require.Equal(t, 10*time.Second, nextInterval) + require.Equal(t, 1, len(tasks)) + require.Equal(t, "t4", tasks[0].tbl.Name.L) + require.Equal(t, time.UnixMilli(0), tasks[0].expire) + require.Equal(t, 4, len(tasks[0].rows)) + require.Equal(t, 0, buffer.Len()) + require.Equal(t, uint64(4), statics4.SuccessRows.Load()) + require.Equal(t, uint64(0), statics4.ErrorRows.Load()) + + // test retry max count + retryCnt := 0 + doRetryFail := func(task *ttlDeleteTask) [][]types.Datum { + retryCnt++ + task.statistics.SuccessRows.Add(1) + return task.rows[1:] + } + task5, rows5, statics5 := createTask("t5") + buffer.RecordTaskResult(task5, rows5[:5]) + require.Equal(t, 1, buffer.Len()) + tm = tm.Add(10 * time.Second) + nextInterval = buffer.DoRetry(doRetryFail) + require.Equal(t, 10*time.Second, nextInterval) + require.Equal(t, uint64(1), statics5.SuccessRows.Load()) + require.Equal(t, uint64(0), statics5.ErrorRows.Load()) + require.Equal(t, 1, retryCnt) + tm = tm.Add(10 * time.Second) + buffer.DoRetry(doRetryFail) + require.Equal(t, uint64(2), statics5.SuccessRows.Load()) + require.Equal(t, uint64(3), statics5.ErrorRows.Load()) + require.Equal(t, 2, retryCnt) + require.Equal(t, 0, buffer.Len()) + + // test task should be immutable + require.Equal(t, 10, len(task5.rows)) +} + +func TestTTLDeleteTaskDoDelete(t *testing.T) { + origBatchSize := variable.TTLDeleteBatchSize.Load() + variable.TTLDeleteBatchSize.Store(3) + defer variable.TTLDeleteBatchSize.Store(origBatchSize) + + t1 := newMockTTLTbl(t, "t1") + t2 := newMockTTLTbl(t, "t2") + t3 := newMockTTLTbl(t, "t3") + t4 := newMockTTLTbl(t, "t4") + s := newMockSession(t) + invokes := 0 + s.executeSQL = func(ctx context.Context, sql string, args ...interface{}) ([]chunk.Row, error) { + invokes++ + s.sessionInfoSchema = newMockInfoSchema(t1.TableInfo, t2.TableInfo, t3.TableInfo, t4.TableInfo) + if strings.Contains(sql, "`t1`") { + return nil, nil + } + + if strings.Contains(sql, "`t2`") { + return nil, errors.New("mockErr") + } + + if strings.Contains(sql, "`t3`") { + s.sessionInfoSchema = newMockInfoSchema() + return nil, nil + } + + if strings.Contains(sql, "`t4`") { + switch invokes { + case 1: + return nil, nil + case 2, 4: + return nil, errors.New("mockErr") + case 3: + s.sessionInfoSchema = newMockInfoSchema() + return nil, nil + } + } + + require.FailNow(t, "") + return nil, nil + } + + nRows := func(n int) [][]types.Datum { + rows := make([][]types.Datum, n) + for i := 0; i < n; i++ { + rows[i] = []types.Datum{ + types.NewIntDatum(int64(i)), + } + } + return rows + } + + delTask := func(t *cache.PhysicalTable) *ttlDeleteTask { + task := &ttlDeleteTask{ + tbl: t, + expire: time.UnixMilli(0), + rows: nRows(10), + statistics: &ttlStatistics{}, + } + task.statistics.TotalRows.Add(10) + return task + } + + cases := []struct { + task *ttlDeleteTask + retryRows []int + successRows int + errorRows int + }{ + { + task: delTask(t1), + retryRows: nil, + successRows: 10, + errorRows: 0, + }, + { + task: delTask(t2), + retryRows: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + successRows: 0, + errorRows: 0, + }, + { + task: delTask(t3), + retryRows: nil, + successRows: 0, + errorRows: 10, + }, + { + task: delTask(t4), + retryRows: []int{3, 4, 5, 9}, + successRows: 3, + errorRows: 3, + }, + } + + for _, c := range cases { + invokes = 0 + retryRows := c.task.doDelete(context.Background(), s) + require.Equal(t, 4, invokes) + if c.retryRows == nil { + require.Nil(t, retryRows) + } + require.Equal(t, len(c.retryRows), len(retryRows)) + for i, row := range retryRows { + require.Equal(t, int64(c.retryRows[i]), row[0].GetInt64()) + } + require.Equal(t, uint64(10), c.task.statistics.TotalRows.Load()) + require.Equal(t, uint64(c.successRows), c.task.statistics.SuccessRows.Load()) + require.Equal(t, uint64(c.errorRows), c.task.statistics.ErrorRows.Load()) + } +} + +func TestTTLDeleteRateLimiter(t *testing.T) { + origDeleteLimit := variable.TTLDeleteRateLimit.Load() + defer func() { + variable.TTLDeleteRateLimit.Store(origDeleteLimit) + }() + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer func() { + if cancel != nil { + cancel() + } + }() + + variable.TTLDeleteRateLimit.Store(100000) + require.NoError(t, globalDelRateLimiter.Wait(ctx)) + require.Equal(t, rate.Limit(100000), globalDelRateLimiter.limiter.Limit()) + require.Equal(t, int64(100000), globalDelRateLimiter.limit.Load()) + + variable.TTLDeleteRateLimit.Store(0) + require.NoError(t, globalDelRateLimiter.Wait(ctx)) + require.Equal(t, rate.Limit(0), globalDelRateLimiter.limiter.Limit()) + require.Equal(t, int64(0), globalDelRateLimiter.limit.Load()) + + // 0 stands for no limit + require.NoError(t, globalDelRateLimiter.Wait(ctx)) + // cancel ctx returns an error + cancel() + cancel = nil + require.EqualError(t, globalDelRateLimiter.Wait(ctx), "context canceled") +} + +func TestTTLDeleteTaskWorker(t *testing.T) { + origBatchSize := variable.TTLDeleteBatchSize.Load() + variable.TTLDeleteBatchSize.Store(3) + defer variable.TTLDeleteBatchSize.Store(origBatchSize) + + t1 := newMockTTLTbl(t, "t1") + t2 := newMockTTLTbl(t, "t2") + t3 := newMockTTLTbl(t, "t3") + s := newMockSession(t) + pool := newMockSessionPool(t) + pool.se = s + + sqlMap := make(map[string]struct{}) + s.executeSQL = func(ctx context.Context, sql string, args ...interface{}) ([]chunk.Row, error) { + pool.lastSession.sessionInfoSchema = newMockInfoSchema(t1.TableInfo, t2.TableInfo, t3.TableInfo) + if strings.Contains(sql, "`t1`") { + return nil, nil + } + + if strings.Contains(sql, "`t2`") { + if _, ok := sqlMap[sql]; ok { + return nil, nil + } + sqlMap[sql] = struct{}{} + return nil, errors.New("mockErr") + } + + if strings.Contains(sql, "`t3`") { + pool.lastSession.sessionInfoSchema = newMockInfoSchema() + return nil, nil + } + + require.FailNow(t, "") + return nil, nil + } + + delCh := make(chan *ttlDeleteTask) + w := newDeleteWorker(delCh, pool) + w.retryBuffer.retryInterval = time.Millisecond + require.Equal(t, workerStatusCreated, w.Status()) + w.Start() + require.Equal(t, workerStatusRunning, w.Status()) + defer func() { + w.Stop() + require.NoError(t, w.WaitStopped(context.TODO(), 10*time.Second)) + }() + + tasks := make([]*ttlDeleteTask, 0) + for _, tbl := range []*cache.PhysicalTable{t1, t2, t3} { + task := &ttlDeleteTask{ + tbl: tbl, + expire: time.UnixMilli(0), + rows: [][]types.Datum{ + {types.NewIntDatum(1)}, + {types.NewIntDatum(2)}, + {types.NewIntDatum(3)}, + }, + statistics: &ttlStatistics{}, + } + task.statistics.TotalRows.Add(3) + tasks = append(tasks, task) + select { + case delCh <- task: + case <-time.After(time.Second): + require.FailNow(t, "") + } + } + + time.Sleep(time.Millisecond * 100) + require.Equal(t, uint64(3), tasks[0].statistics.SuccessRows.Load()) + require.Equal(t, uint64(0), tasks[0].statistics.ErrorRows.Load()) + + require.Equal(t, uint64(3), tasks[1].statistics.SuccessRows.Load()) + require.Equal(t, uint64(0), tasks[1].statistics.ErrorRows.Load()) + + require.Equal(t, uint64(0), tasks[2].statistics.SuccessRows.Load()) + require.Equal(t, uint64(3), tasks[2].statistics.ErrorRows.Load()) +} diff --git a/ttl/ttlworker/job.go b/ttl/ttlworker/job.go new file mode 100644 index 0000000000000..f2a78e7ef0270 --- /dev/null +++ b/ttl/ttlworker/job.go @@ -0,0 +1,96 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "sync" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" +) + +const updateJobCurrentStatusTemplate = "UPDATE mysql.tidb_ttl_table_status SET current_job_status = %? WHERE table_id = %? AND current_job_status = %? AND current_job_id = %?" +const finishJobTemplate = `UPDATE mysql.tidb_ttl_table_status + SET last_job_id = current_job_id, + last_job_start_time = current_job_start_time, + last_job_finish_time = %?, + last_job_ttl_expire = current_job_ttl_expire, + last_job_summary = %?, + current_job_id = NULL, + current_job_owner_id = NULL, + current_job_owner_hb_time = NULL, + current_job_start_time = NULL, + current_job_ttl_expire = NULL, + current_job_state = NULL, + current_job_status = NULL, + current_job_status_update_time = NULL + WHERE table_id = %? AND current_job_id = %?` +const removeTaskForJobTemplate = "DELETE FROM mysql.tidb_ttl_task WHERE job_id = %?" + +func updateJobCurrentStatusSQL(tableID int64, oldStatus cache.JobStatus, newStatus cache.JobStatus, jobID string) (string, []interface{}) { + return updateJobCurrentStatusTemplate, []interface{}{string(newStatus), tableID, string(oldStatus), jobID} +} + +func finishJobSQL(tableID int64, finishTime time.Time, summary string, jobID string) (string, []interface{}) { + return finishJobTemplate, []interface{}{finishTime.Format(timeFormat), summary, tableID, jobID} +} + +func removeTaskForJob(jobID string) (string, []interface{}) { + return removeTaskForJobTemplate, []interface{}{jobID} +} + +type ttlJob struct { + id string + ownerID string + + createTime time.Time + + tbl *cache.PhysicalTable + + // status is the only field which should be protected by a mutex, as `Cancel` may be called at any time, and will + // change the status + statusMutex sync.Mutex + status cache.JobStatus +} + +// finish turns current job into last job, and update the error message and statistics summary +func (job *ttlJob) finish(se session.Session, now time.Time, summary string) { + // at this time, the job.ctx may have been canceled (to cancel this job) + // even when it's canceled, we'll need to update the states, so use another context + err := se.RunInTxn(context.TODO(), func() error { + sql, args := finishJobSQL(job.tbl.ID, now, summary, job.id) + _, err := se.ExecuteSQL(context.TODO(), sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + + sql, args = removeTaskForJob(job.id) + _, err = se.ExecuteSQL(context.TODO(), sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + + return nil + }, session.TxnModeOptimistic) + + if err != nil { + logutil.BgLogger().Error("fail to finish a ttl job", zap.Error(err), zap.Int64("tableID", job.tbl.ID), zap.String("jobID", job.id)) + } +} diff --git a/ttl/ttlworker/job_manager.go b/ttl/ttlworker/job_manager.go new file mode 100644 index 0000000000000..223128b52f26c --- /dev/null +++ b/ttl/ttlworker/job_manager.go @@ -0,0 +1,744 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "encoding/json" + "strings" + "time" + + "github.com/google/uuid" + "github.com/pingcap/errors" + "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/duration" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/client" + "github.com/pingcap/tidb/ttl/metrics" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/timeutil" + clientv3 "go.etcd.io/etcd/client/v3" + "go.uber.org/multierr" + "go.uber.org/zap" +) + +const insertNewTableIntoStatusTemplate = "INSERT INTO mysql.tidb_ttl_table_status (table_id,parent_table_id) VALUES (%?, %?)" +const setTableStatusOwnerTemplate = `UPDATE mysql.tidb_ttl_table_status + SET current_job_id = %?, + current_job_owner_id = %?, + current_job_start_time = %?, + current_job_status = 'waiting', + current_job_status_update_time = %?, + current_job_ttl_expire = %?, + current_job_owner_hb_time = %? + WHERE table_id = %?` +const updateHeartBeatTemplate = "UPDATE mysql.tidb_ttl_table_status SET current_job_owner_hb_time = %? WHERE table_id = %? AND current_job_owner_id = %?" +const taskGCTemplate = `DELETE task FROM + mysql.tidb_ttl_task task + left join + mysql.tidb_ttl_table_status job + ON task.job_id = job.current_job_id + WHERE job.table_id IS NULL` + +const timeFormat = "2006-01-02 15:04:05" + +func insertNewTableIntoStatusSQL(tableID int64, parentTableID int64) (string, []interface{}) { + return insertNewTableIntoStatusTemplate, []interface{}{tableID, parentTableID} +} + +func setTableStatusOwnerSQL(uuid string, tableID int64, now time.Time, currentJobTTLExpire time.Time, id string) (string, []interface{}) { + return setTableStatusOwnerTemplate, []interface{}{uuid, id, now.Format(timeFormat), now.Format(timeFormat), currentJobTTLExpire.Format(timeFormat), now.Format(timeFormat), tableID} +} + +func updateHeartBeatSQL(tableID int64, now time.Time, id string) (string, []interface{}) { + return updateHeartBeatTemplate, []interface{}{now.Format(timeFormat), tableID, id} +} + +// JobManager schedules and manages the ttl jobs on this instance +type JobManager struct { + // the `runningJobs`, `scanWorkers` and `delWorkers` should be protected by mutex: + // `runningJobs` will be shared in the state loop and schedule loop + // `scanWorkers` and `delWorkers` can be modified by setting variables at any time + baseWorker + + sessPool sessionPool + + // id is the ddl id of this instance + id string + + store kv.Storage + cmdCli client.CommandClient + + // infoSchemaCache and tableStatusCache are a cache stores the information from info schema and the tidb_ttl_table_status + // table. They don't need to be protected by mutex, because they are only used in job loop goroutine. + infoSchemaCache *cache.InfoSchemaCache + tableStatusCache *cache.TableStatusCache + + // runningJobs record all ttlJob waiting in local + // when a job for a table is created, it could spawn several scan tasks. If there are too many scan tasks, and they cannot + // be fully consumed by local scan workers, their states should be recorded in the runningJobs, so that we could continue + // to poll scan tasks from the job in the future when there are scan workers in idle. + runningJobs []*ttlJob + + taskManager *taskManager +} + +// NewJobManager creates a new ttl job manager +func NewJobManager(id string, sessPool sessionPool, store kv.Storage, etcdCli *clientv3.Client) (manager *JobManager) { + manager = &JobManager{} + manager.id = id + manager.store = store + manager.sessPool = sessPool + + manager.init(manager.jobLoop) + manager.ctx = logutil.WithKeyValue(manager.ctx, "ttl-worker", "job-manager") + + manager.infoSchemaCache = cache.NewInfoSchemaCache(getUpdateInfoSchemaCacheInterval()) + manager.tableStatusCache = cache.NewTableStatusCache(getUpdateTTLTableStatusCacheInterval()) + + if etcdCli != nil { + manager.cmdCli = client.NewEtcdCommandClient(etcdCli) + } else { + manager.cmdCli = client.NewMockCommandClient() + } + + manager.taskManager = newTaskManager(manager.ctx, sessPool, manager.infoSchemaCache, id) + + return +} + +func (m *JobManager) jobLoop() error { + se, err := getSession(m.sessPool) + if err != nil { + return err + } + + defer func() { + err = multierr.Combine(err, multierr.Combine(m.taskManager.resizeScanWorkers(0), m.taskManager.resizeDelWorkers(0))) + se.Close() + logutil.Logger(m.ctx).Info("ttlJobManager loop exited.") + }() + + infoSchemaCacheUpdateTicker := time.Tick(m.infoSchemaCache.GetInterval()) + tableStatusCacheUpdateTicker := time.Tick(m.tableStatusCache.GetInterval()) + resizeWorkersTicker := time.Tick(getResizeWorkersInterval()) + taskGC := time.Tick(jobManagerLoopTickerInterval) + + scheduleJobTicker := time.Tick(jobManagerLoopTickerInterval) + jobCheckTicker := time.Tick(jobManagerLoopTickerInterval) + updateJobHeartBeatTicker := time.Tick(jobManagerLoopTickerInterval) + + scheduleTaskTicker := time.Tick(getTaskManagerLoopTickerInterval()) + updateTaskHeartBeatTicker := time.Tick(ttlTaskHeartBeatTickerInterval) + taskCheckTicker := time.Tick(getTaskManagerLoopTickerInterval()) + checkScanTaskFinishedTicker := time.Tick(getTaskManagerLoopTickerInterval()) + + cmdWatcher := m.cmdCli.WatchCommand(m.ctx) + m.taskManager.resizeWorkersWithSysVar() + for { + m.reportMetrics() + now := se.Now() + + select { + // misc + case <-m.ctx.Done(): + return nil + case <-infoSchemaCacheUpdateTicker: + err := m.updateInfoSchemaCache(se) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to update info schema cache", zap.Error(err)) + } + case <-tableStatusCacheUpdateTicker: + err := m.updateTableStatusCache(se) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to update table status cache", zap.Error(err)) + } + case <-taskGC: + taskGCCtx, cancel := context.WithTimeout(m.ctx, ttlInternalSQLTimeout) + _, err = se.ExecuteSQL(taskGCCtx, taskGCTemplate) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to gc redundant scan task", zap.Error(err)) + } + cancel() + // Job Schedule loop: + case <-updateJobHeartBeatTicker: + updateHeartBeatCtx, cancel := context.WithTimeout(m.ctx, ttlInternalSQLTimeout) + err = m.updateHeartBeat(updateHeartBeatCtx, se, now) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to update job heart beat", zap.Error(err)) + } + cancel() + case <-jobCheckTicker: + m.checkFinishedJob(se) + m.checkNotOwnJob() + case <-scheduleJobTicker: + m.rescheduleJobs(se, now) + case cmd, ok := <-cmdWatcher: + if !ok { + if m.ctx.Err() != nil { + return nil + } + + logutil.BgLogger().Warn("The TTL cmd watcher is closed unexpectedly, re-watch it again") + cmdWatcher = m.cmdCli.WatchCommand(m.ctx) + continue + } + + if triggerJobCmd, ok := cmd.GetTriggerTTLJobRequest(); ok { + m.triggerTTLJob(cmd.RequestID, triggerJobCmd, se) + m.rescheduleJobs(se, now) + } + + // Task Manager Loop + case <-scheduleTaskTicker: + m.taskManager.rescheduleTasks(se, now) + case <-taskCheckTicker: + m.taskManager.checkInvalidTask(se) + m.taskManager.checkFinishedTask(se, now) + case <-resizeWorkersTicker: + m.taskManager.resizeWorkersWithSysVar() + case <-updateTaskHeartBeatTicker: + updateHeartBeatCtx, cancel := context.WithTimeout(m.ctx, ttlInternalSQLTimeout) + err = m.taskManager.updateHeartBeat(updateHeartBeatCtx, se, now) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to update task heart beat", zap.Error(err)) + } + cancel() + case <-checkScanTaskFinishedTicker: + if m.taskManager.handleScanFinishedTask() { + m.taskManager.rescheduleTasks(se, now) + } + case <-m.taskManager.notifyStateCh: + if m.taskManager.handleScanFinishedTask() { + m.taskManager.rescheduleTasks(se, now) + } + } + } +} + +func (m *JobManager) triggerTTLJob(requestID string, cmd *client.TriggerNewTTLJobRequest, se session.Session) { + if len(m.runningJobs) > 0 { + // sleep 2 seconds to make sure the TiDB without any job running in it to have a higher priority to take a new job. + time.Sleep(2 * time.Second) + } + + ok, err := m.cmdCli.TakeCommand(m.ctx, requestID) + if err != nil { + logutil.BgLogger().Error("failed to take TTL trigger job command", + zap.String("requestID", requestID), + zap.String("database", cmd.DBName), + zap.String("table", cmd.TableName)) + return + } + + if !ok { + return + } + + logutil.BgLogger().Info("Get a command to trigger a new TTL job", + zap.String("requestID", requestID), + zap.String("database", cmd.DBName), + zap.String("table", cmd.TableName)) + + responseErr := func(err error) { + terror.Log(m.cmdCli.ResponseCommand(m.ctx, requestID, err)) + } + + if err = m.infoSchemaCache.Update(se); err != nil { + responseErr(err) + return + } + + if err = m.tableStatusCache.Update(m.ctx, se); err != nil { + responseErr(err) + return + } + + var tables []*cache.PhysicalTable + for _, tbl := range m.infoSchemaCache.Tables { + if tbl.Schema.L == strings.ToLower(cmd.DBName) && tbl.Name.L == strings.ToLower(cmd.TableName) { + tables = append(tables, tbl) + } + } + + if len(tables) == 0 { + responseErr(errors.Errorf("table %s.%s not exists", cmd.DBName, cmd.TableName)) + return + } + + now := time.Now() + tableResults := make([]*client.TriggerNewTTLJobTableResult, 0, len(tables)) + allError := true + var firstError error + for _, ttlTbl := range tables { + tblResult := &client.TriggerNewTTLJobTableResult{ + TableID: ttlTbl.ID, + DBName: cmd.DBName, + TableName: cmd.TableName, + PartitionName: ttlTbl.Partition.O, + } + + job, err := m.lockNewJob(m.ctx, se, ttlTbl, now, true) + if err != nil { + firstError = err + tblResult.ErrorMessage = err.Error() + tableResults = append(tableResults, tblResult) + continue + } + + allError = false + if job != nil { + m.appendJob(job) + tblResult.JobID = job.id + tableResults = append(tableResults, tblResult) + } + } + + if allError { + responseErr(firstError) + return + } + + terror.Log(m.cmdCli.ResponseCommand(m.ctx, requestID, &client.TriggerNewTTLJobResponse{ + TableResult: tableResults, + })) + + tableResultsJSON, _ := json.Marshal(tableResults) + logutil.BgLogger().Info("Done to trigger a new TTL job", + zap.String("requestID", requestID), + zap.String("database", cmd.DBName), + zap.String("table", cmd.TableName), + zap.ByteString("tableResults", tableResultsJSON), + ) +} + +func (m *JobManager) reportMetrics() { + var runningJobs, cancellingJobs float64 + for _, job := range m.runningJobs { + switch job.status { + case cache.JobStatusRunning: + runningJobs++ + case cache.JobStatusCancelling: + cancellingJobs++ + } + } + metrics.RunningJobsCnt.Set(runningJobs) + metrics.CancellingJobsCnt.Set(cancellingJobs) +} + +// checkNotOwnJob removes the job whose current job owner is not yourself +func (m *JobManager) checkNotOwnJob() { + for _, job := range m.runningJobs { + tableStatus := m.tableStatusCache.Tables[job.tbl.ID] + if tableStatus == nil || tableStatus.CurrentJobOwnerID != m.id { + logger := logutil.Logger(m.ctx).With(zap.String("jobID", job.id)) + if tableStatus != nil { + logger.With(zap.String("newJobOwnerID", tableStatus.CurrentJobOwnerID)) + } + logger.Info("job has been taken over by another node") + m.removeJob(job) + } + } +} + +func (m *JobManager) checkFinishedJob(se session.Session) { +j: + for _, job := range m.runningJobs { + timeoutJobCtx, cancel := context.WithTimeout(m.ctx, ttlInternalSQLTimeout) + + sql, args := cache.SelectFromTTLTaskWithJobID(job.id) + rows, err := se.ExecuteSQL(timeoutJobCtx, sql, args...) + cancel() + if err != nil { + logutil.Logger(m.ctx).Warn("fail to execute sql", zap.String("sql", sql), zap.Any("args", args), zap.Error(err)) + continue + } + + allFinished := true + allTasks := make([]*cache.TTLTask, 0, len(rows)) + for _, r := range rows { + task, err := cache.RowToTTLTask(se, r) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to read task", zap.Error(err)) + continue j + } + allTasks = append(allTasks, task) + + if task.Status != "finished" { + allFinished = false + } + } + + if allFinished { + logutil.Logger(m.ctx).Info("job has finished", zap.String("jobID", job.id)) + summary, err := summarizeTaskResult(allTasks) + if err != nil { + logutil.Logger(m.ctx).Info("fail to summarize job", zap.Error(err)) + } + m.removeJob(job) + job.finish(se, se.Now(), summary) + } + cancel() + } +} + +func (m *JobManager) rescheduleJobs(se session.Session, now time.Time) { + if !variable.EnableTTLJob.Load() || !timeutil.WithinDayTimePeriod(variable.TTLJobScheduleWindowStartTime.Load(), variable.TTLJobScheduleWindowEndTime.Load(), now) { + if len(m.runningJobs) > 0 { + for _, job := range m.runningJobs { + logutil.Logger(m.ctx).Info("cancel job because tidb_ttl_job_enable turned off", zap.String("jobID", job.id)) + + summary, err := summarizeErr(errors.New("ttl job is disabled")) + if err != nil { + logutil.Logger(m.ctx).Info("fail to summarize job", zap.Error(err)) + } + m.removeJob(job) + job.finish(se, now, summary) + } + } + return + } + + // don't lock job if there's no free scan workers in local + // it's a mechanism to avoid too many scan tasks waiting in the ttl_tasks table. + if len(m.taskManager.idleScanWorkers()) == 0 { + return + } + + newJobTables := m.readyForNewJobTables(now) + // TODO: also consider to resume tables, but it's fine to left them there, as other nodes will take this job + // when the heart beat is not sent + for _, table := range newJobTables { + logutil.Logger(m.ctx).Info("try lock new job", zap.Int64("tableID", table.ID)) + job, err := m.lockNewJob(m.ctx, se, table, now, false) + if job != nil { + logutil.Logger(m.ctx).Info("append new running job", zap.String("jobID", job.id), zap.Int64("tableID", job.tbl.ID)) + m.appendJob(job) + } + if err != nil { + logutil.Logger(m.ctx).Warn("fail to create new job", zap.Error(err)) + } + } +} + +func (m *JobManager) localJobs() []*ttlJob { + jobs := make([]*ttlJob, 0, len(m.runningJobs)) + for _, job := range m.runningJobs { + status := m.tableStatusCache.Tables[job.tbl.ID] + if status == nil || status.CurrentJobOwnerID != m.id { + // these jobs will be removed in `checkNotOwnJob` + continue + } + + jobs = append(jobs, job) + } + return jobs +} + +// readyForNewJobTables returns all tables which should spawn a TTL job according to cache +func (m *JobManager) readyForNewJobTables(now time.Time) []*cache.PhysicalTable { + tables := make([]*cache.PhysicalTable, 0, len(m.infoSchemaCache.Tables)) + +tblLoop: + for _, table := range m.infoSchemaCache.Tables { + // If this node already has a job for this table, just ignore. + // Actually, the logic should ensure this condition never meet, we still add the check here to keep safety + // (especially when the content of the status table is incorrect) + for _, job := range m.runningJobs { + if job.tbl.ID == table.ID { + continue tblLoop + } + } + + status := m.tableStatusCache.Tables[table.ID] + ok := m.couldTrySchedule(status, table, now, false) + if ok { + tables = append(tables, table) + } + } + + return tables +} + +// couldTrySchedule returns whether a table should be tried to run TTL +func (m *JobManager) couldTrySchedule(tableStatus *cache.TableStatus, table *cache.PhysicalTable, now time.Time, ignoreScheduleInterval bool) bool { + if tableStatus == nil { + // if the table status hasn't been created, return true + return true + } + if table == nil { + // if the table is not recorded in info schema, return false + return false + } + if tableStatus.CurrentJobOwnerID != "" { + // see whether it's heart beat time is expired + hbTime := tableStatus.CurrentJobOwnerHBTime + // a more concrete value is `2 * max(updateTTLTableStatusCacheInterval, jobManagerLoopTickerInterval)`, but the + // `updateTTLTableStatusCacheInterval` is greater than `jobManagerLoopTickerInterval` in most cases. + if hbTime.Add(2 * getUpdateTTLTableStatusCacheInterval()).Before(now) { + logutil.Logger(m.ctx).Info("task heartbeat has stopped", zap.Int64("tableID", table.ID), zap.Time("hbTime", hbTime), zap.Time("now", now)) + return true + } + return false + } + + if ignoreScheduleInterval || tableStatus.LastJobStartTime.IsZero() { + return true + } + + startTime := tableStatus.LastJobStartTime + + interval := table.TTLInfo.JobInterval + d, err := duration.ParseDuration(interval) + if err != nil { + logutil.Logger(m.ctx).Warn("illegal job interval", zap.String("interval", interval)) + return false + } + return startTime.Add(d).Before(now) +} + +// occupyNewJob tries to occupy a new job in the ttl_table_status table. If it locks successfully, it will create a new +// localJob and return it. +// It could be nil, nil, if the table query doesn't return error but the job has been locked by other instances. +func (m *JobManager) lockNewJob(ctx context.Context, se session.Session, table *cache.PhysicalTable, now time.Time, ignoreScheduleInterval bool) (*ttlJob, error) { + var expireTime time.Time + + err := se.RunInTxn(ctx, func() error { + sql, args := cache.SelectFromTTLTableStatusWithID(table.ID) + // use ` FOR UPDATE NOWAIT`, then if the new job has been locked by other nodes, it will return: + // [tikv:3572]Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set. + // Then this tidb node will not waste resource in calculating the ranges. + rows, err := se.ExecuteSQL(ctx, sql+" FOR UPDATE NOWAIT", args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + if len(rows) == 0 { + // cannot find the row, insert the status row + sql, args := insertNewTableIntoStatusSQL(table.ID, table.TableInfo.ID) + _, err = se.ExecuteSQL(ctx, sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + sql, args = cache.SelectFromTTLTableStatusWithID(table.ID) + rows, err = se.ExecuteSQL(ctx, sql+" FOR UPDATE NOWAIT", args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + if len(rows) == 0 { + return errors.New("table status row still doesn't exist after insertion") + } + } + tableStatus, err := cache.RowToTableStatus(se, rows[0]) + if err != nil { + return err + } + if !m.couldTrySchedule(tableStatus, m.infoSchemaCache.Tables[tableStatus.TableID], now, ignoreScheduleInterval) { + return errors.New("couldn't schedule ttl job") + } + + expireTime, err = table.EvalExpireTime(m.ctx, se, now) + if err != nil { + return err + } + + jobID := uuid.New().String() + jobExist := false + if len(tableStatus.CurrentJobID) > 0 { + // don't create new job if there is already one running + // so the running tasks don't need to be cancelled + jobID = tableStatus.CurrentJobID + expireTime = tableStatus.CurrentJobTTLExpire + jobExist = true + } + failpoint.Inject("set-job-uuid", func(val failpoint.Value) { + jobID = val.(string) + }) + + sql, args = setTableStatusOwnerSQL(jobID, table.ID, now, expireTime, m.id) + _, err = se.ExecuteSQL(ctx, sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + + // if the job already exist, don't need to submit scan tasks + if jobExist { + return nil + } + + ranges, err := table.SplitScanRanges(ctx, m.store, splitScanCount) + if err != nil { + return errors.Wrap(err, "split scan ranges") + } + for scanID, r := range ranges { + sql, args, err = cache.InsertIntoTTLTask(se, jobID, table.ID, scanID, r.Start, r.End, expireTime, now) + if err != nil { + return errors.Wrap(err, "encode scan task") + } + _, err = se.ExecuteSQL(ctx, sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + } + + return nil + }, session.TxnModePessimistic) + if err != nil { + return nil, err + } + + // successfully update the table status, will need to refresh the cache. + err = m.updateInfoSchemaCache(se) + if err != nil { + return nil, err + } + err = m.updateTableStatusCache(se) + if err != nil { + return nil, err + } + return m.createNewJob(now, table) +} + +func (m *JobManager) createNewJob(now time.Time, table *cache.PhysicalTable) (*ttlJob, error) { + id := m.tableStatusCache.Tables[table.ID].CurrentJobID + + return &ttlJob{ + id: id, + ownerID: m.id, + + createTime: now, + // at least, the info schema cache and table status cache are consistent in table id, so it's safe to get table + // information from schema cache directly + tbl: table, + + status: cache.JobStatusWaiting, + }, nil +} + +// updateHeartBeat updates the heartbeat for all task with current instance as owner +func (m *JobManager) updateHeartBeat(ctx context.Context, se session.Session, now time.Time) error { + for _, job := range m.localJobs() { + if job.createTime.Add(ttlJobTimeout).Before(now) { + logutil.Logger(m.ctx).Info("job is timeout", zap.String("jobID", job.id)) + summary, err := summarizeErr(errors.New("job is timeout")) + if err != nil { + logutil.Logger(m.ctx).Info("fail to summarize job", zap.Error(err)) + } + m.removeJob(job) + job.finish(se, now, summary) + continue + } + + sql, args := updateHeartBeatSQL(job.tbl.ID, now, m.id) + _, err := se.ExecuteSQL(ctx, sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + } + return nil +} + +// updateInfoSchemaCache updates the cache of information schema +func (m *JobManager) updateInfoSchemaCache(se session.Session) error { + return m.infoSchemaCache.Update(se) +} + +// updateTableStatusCache updates the cache of table status +func (m *JobManager) updateTableStatusCache(se session.Session) error { + cacheUpdateCtx, cancel := context.WithTimeout(m.ctx, ttlInternalSQLTimeout) + defer cancel() + return m.tableStatusCache.Update(cacheUpdateCtx, se) +} + +func (m *JobManager) removeJob(finishedJob *ttlJob) { + for idx, job := range m.runningJobs { + if job.id == finishedJob.id { + if idx+1 < len(m.runningJobs) { + m.runningJobs = append(m.runningJobs[0:idx], m.runningJobs[idx+1:]...) + } else { + m.runningJobs = m.runningJobs[0:idx] + } + return + } + } +} + +func (m *JobManager) appendJob(job *ttlJob) { + m.runningJobs = append(m.runningJobs, job) +} + +// GetCommandCli returns the command client +func (m *JobManager) GetCommandCli() client.CommandClient { + return m.cmdCli +} + +type ttlSummary struct { + TotalRows uint64 `json:"total_rows"` + SuccessRows uint64 `json:"success_rows"` + ErrorRows uint64 `json:"error_rows"` + + TotalScanTask int `json:"total_scan_task"` + ScheduledScanTask int `json:"scheduled_scan_task"` + FinishedScanTask int `json:"finished_scan_task"` + + ScanTaskErr string `json:"scan_task_err,omitempty"` +} + +func summarizeErr(err error) (string, error) { + summary := &ttlSummary{ + ScanTaskErr: err.Error(), + } + + buf, err := json.Marshal(summary) + if err != nil { + return "", err + } + return string(buf), nil +} + +func summarizeTaskResult(tasks []*cache.TTLTask) (string, error) { + summary := &ttlSummary{} + var allErr error + for _, t := range tasks { + if t.State != nil { + summary.TotalRows += t.State.TotalRows + summary.SuccessRows += t.State.SuccessRows + summary.ErrorRows += t.State.ErrorRows + if len(t.State.ScanTaskErr) > 0 { + allErr = multierr.Append(allErr, errors.New(t.State.ScanTaskErr)) + } + } + + summary.TotalScanTask += 1 + if t.Status != cache.TaskStatusWaiting { + summary.ScheduledScanTask += 1 + } + if t.Status == cache.TaskStatusFinished { + summary.FinishedScanTask += 1 + } + } + if allErr != nil { + summary.ScanTaskErr = allErr.Error() + } + + buf, err := json.Marshal(summary) + if err != nil { + return "", err + } + return string(buf), nil +} diff --git a/ttl/ttlworker/job_manager_integration_test.go b/ttl/ttlworker/job_manager_integration_test.go new file mode 100644 index 0000000000000..c763e1363aecd --- /dev/null +++ b/ttl/ttlworker/job_manager_integration_test.go @@ -0,0 +1,425 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker_test + +import ( + "context" + "fmt" + "strconv" + "sync" + "testing" + "time" + + "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/model" + dbsession "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/statistics/handle" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/client" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/ttl/ttlworker" + "github.com/pingcap/tidb/util/logutil" + "github.com/stretchr/testify/require" + "go.uber.org/atomic" + "go.uber.org/zap" +) + +func sessionFactory(t *testing.T, store kv.Storage) func() session.Session { + return func() session.Session { + dbSession, err := dbsession.CreateSession4Test(store) + require.NoError(t, err) + se := session.NewSession(dbSession, dbSession, nil) + + _, err = se.ExecuteSQL(context.Background(), "ROLLBACK") + require.NoError(t, err) + _, err = se.ExecuteSQL(context.Background(), "set tidb_retry_limit=0") + require.NoError(t, err) + + return se + } +} + +func TestParallelLockNewJob(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + waitAndStopTTLManager(t, dom) + + sessionFactory := sessionFactory(t, store) + + testTable := &cache.PhysicalTable{ID: 2, TableInfo: &model.TableInfo{ID: 1, TTLInfo: &model.TTLInfo{IntervalExprStr: "1", IntervalTimeUnit: int(ast.TimeUnitDay), JobInterval: "1h"}}} + // simply lock a new job + m := ttlworker.NewJobManager("test-id", nil, store, nil) + m.InfoSchemaCache().Tables[testTable.ID] = testTable + + se := sessionFactory() + job, err := m.LockNewJob(context.Background(), se, testTable, time.Now(), false) + require.NoError(t, err) + job.Finish(se, time.Now(), "") + + // lock one table in parallel, only one of them should lock successfully + testTimes := 100 + concurrency := 5 + now := time.Now() + for i := 0; i < testTimes; i++ { + successCounter := atomic.NewUint64(0) + successJob := &ttlworker.TTLJob{} + + now = now.Add(time.Hour * 48) + + wg := sync.WaitGroup{} + for j := 0; j < concurrency; j++ { + jobManagerID := fmt.Sprintf("test-ttl-manager-%d", j) + wg.Add(1) + go func() { + m := ttlworker.NewJobManager(jobManagerID, nil, store, nil) + m.InfoSchemaCache().Tables[testTable.ID] = testTable + + se := sessionFactory() + job, err := m.LockNewJob(context.Background(), se, testTable, now, false) + if err == nil { + successCounter.Add(1) + successJob = job + } else { + logutil.BgLogger().Error("lock new job with error", zap.Error(err)) + } + wg.Done() + }() + } + wg.Wait() + + require.Equal(t, uint64(1), successCounter.Load()) + successJob.Finish(se, time.Now(), "") + } +} + +func TestFinishJob(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + waitAndStopTTLManager(t, dom) + tk := testkit.NewTestKit(t, store) + + sessionFactory := sessionFactory(t, store) + + testTable := &cache.PhysicalTable{ID: 2, TableInfo: &model.TableInfo{ID: 1, TTLInfo: &model.TTLInfo{IntervalExprStr: "1", IntervalTimeUnit: int(ast.TimeUnitDay)}}} + + tk.MustExec("insert into mysql.tidb_ttl_table_status(table_id) values (2)") + + // finish with error + m := ttlworker.NewJobManager("test-id", nil, store, nil) + m.InfoSchemaCache().Tables[testTable.ID] = testTable + se := sessionFactory() + job, err := m.LockNewJob(context.Background(), se, testTable, time.Now(), false) + require.NoError(t, err) + + summary := `{"total_rows":0,"scan_task_err":"\"'an error message contains both single and double quote'\""}` + job.Finish(se, time.Now(), summary) + tk.MustQuery("select table_id, last_job_summary from mysql.tidb_ttl_table_status").Check(testkit.Rows(`2 {"total_rows":0,"scan_task_err":"\"'an error message contains both single and double quote'\""}`)) + tk.MustQuery("select * from mysql.tidb_ttl_task").Check(testkit.Rows()) +} + +func TestTTLAutoAnalyze(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/update-info-schema-cache-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/update-info-schema-cache-interval") + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/update-status-table-cache-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/update-status-table-cache-interval") + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/resize-workers-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/resize-workers-interval") + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/task-manager-loop-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/task-manager-loop-interval") + + originAutoAnalyzeMinCnt := handle.AutoAnalyzeMinCnt + handle.AutoAnalyzeMinCnt = 0 + defer func() { + handle.AutoAnalyzeMinCnt = originAutoAnalyzeMinCnt + }() + + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("create table t (id int, created_at datetime) ttl = `created_at` + interval 1 day") + + // insert ten rows, the 2,3,4,6,9,10 of them are expired + for i := 1; i <= 10; i++ { + t := time.Now() + if i%2 == 0 || i%3 == 0 { + t = t.Add(-time.Hour * 48) + } + + tk.MustExec("insert into t values(?, ?)", i, t.Format(time.RFC3339)) + } + // TODO: use a better way to pause and restart ttl worker after analyze the table to make it more stable + // but as the ttl worker takes several seconds to start, it's not too serious. + tk.MustExec("analyze table t") + rows := tk.MustQuery("show stats_meta").Rows() + require.Equal(t, rows[0][4], "0") + require.Equal(t, rows[0][5], "10") + + retryTime := 15 + retryInterval := time.Second * 2 + deleted := false + for retryTime >= 0 { + retryTime-- + time.Sleep(retryInterval) + + rows := tk.MustQuery("select count(*) from t").Rows() + count := rows[0][0].(string) + if count == "3" { + deleted = true + break + } + } + require.True(t, deleted, "ttl should remove expired rows") + + h := dom.StatsHandle() + is := dom.InfoSchema() + require.NoError(t, h.DumpStatsDeltaToKV(handle.DumpAll)) + require.NoError(t, h.Update(is)) + require.True(t, h.HandleAutoAnalyze(is)) +} + +func TestTriggerTTLJob(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/task-manager-loop-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/task-manager-loop-interval") + + ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Minute) + defer cancel() + + store, do := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t(id int primary key, t timestamp) TTL=`t` + INTERVAL 1 DAY") + tbl, err := do.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + tblID := tbl.Meta().ID + require.NoError(t, err) + + // make sure the table had run a job one time to make the test stable + cli := do.TTLJobManager().GetCommandCli() + _, _ = client.TriggerNewTTLJob(ctx, cli, "test", "t") + r := tk.MustQuery("select last_job_id, current_job_id from mysql.tidb_ttl_table_status where table_id=?", tblID) + require.Equal(t, 1, len(r.Rows())) + waitTTLJobFinished(t, tk, tblID) + + now := time.Now() + nowDateStr := now.Format("2006-01-02 15:04:05.999999") + expire := now.Add(-time.Hour * 25) + expreDateStr := expire.Format("2006-01-02 15:04:05.999999") + tk.MustExec("insert into t values(1, ?)", expreDateStr) + tk.MustExec("insert into t values(2, ?)", nowDateStr) + tk.MustExec("insert into t values(3, ?)", expreDateStr) + tk.MustExec("insert into t values(4, ?)", nowDateStr) + + res, err := client.TriggerNewTTLJob(ctx, cli, "test", "t") + require.NoError(t, err) + require.Equal(t, 1, len(res.TableResult)) + tableResult := res.TableResult[0] + require.Equal(t, tblID, tableResult.TableID) + require.NotEmpty(t, tableResult.JobID) + require.Equal(t, "test", tableResult.DBName) + require.Equal(t, "t", tableResult.TableName) + require.Equal(t, "", tableResult.ErrorMessage) + require.Equal(t, "", tableResult.PartitionName) + + waitTTLJobFinished(t, tk, tblID) + tk.MustQuery("select id from t order by id asc").Check(testkit.Rows("2", "4")) +} + +func waitTTLJobFinished(t *testing.T, tk *testkit.TestKit, tableID int64) { + start := time.Now() + for time.Since(start) < time.Minute { + time.Sleep(time.Second) + r := tk.MustQuery("select last_job_id, current_job_id from mysql.tidb_ttl_table_status where table_id=?", tableID) + rows := r.Rows() + if len(rows) == 0 { + continue + } + + if rows[0][0] == "" { + continue + } + + if rows[0][1] != "" { + continue + } + + return + } + require.FailNow(t, "timeout") +} + +func TestTTLJobDisable(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/update-info-schema-cache-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/update-info-schema-cache-interval") + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/update-status-table-cache-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/update-status-table-cache-interval") + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/resize-workers-interval", fmt.Sprintf("return(%d)", time.Second)) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/resize-workers-interval") + + originAutoAnalyzeMinCnt := handle.AutoAnalyzeMinCnt + handle.AutoAnalyzeMinCnt = 0 + defer func() { + handle.AutoAnalyzeMinCnt = originAutoAnalyzeMinCnt + }() + + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("create table t (id int, created_at datetime) ttl = `created_at` + interval 1 day") + + // insert ten rows, the 2,3,4,6,9,10 of them are expired + for i := 1; i <= 10; i++ { + t := time.Now() + if i%2 == 0 || i%3 == 0 { + t = t.Add(-time.Hour * 48) + } + + tk.MustExec("insert into t values(?, ?)", i, t.Format(time.RFC3339)) + } + // turn off the `tidb_ttl_job_enable` + tk.MustExec("set global tidb_ttl_job_enable = 'OFF'") + defer tk.MustExec("set global tidb_ttl_job_enable = 'ON'") + + retryTime := 15 + retryInterval := time.Second * 2 + deleted := false + for retryTime >= 0 { + retryTime-- + time.Sleep(retryInterval) + + rows := tk.MustQuery("select count(*) from t").Rows() + count, err := strconv.Atoi(rows[0][0].(string)) + require.NoError(t, err) + if count < 10 { + deleted = true + break + } + + require.Len(t, dom.TTLJobManager().RunningJobs(), 0) + } + require.False(t, deleted) +} + +func TestRescheduleJobs(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + sessionFactory := sessionFactory(t, store) + + waitAndStopTTLManager(t, dom) + + now := time.Now() + tk.MustExec("create table test.t (id int, created_at datetime) ttl = `created_at` + interval 1 minute ttl_job_interval = '1m'") + table, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnTTL) + + se := sessionFactory() + m := ttlworker.NewJobManager("manager-1", nil, store, nil) + m.TaskManager().ResizeWorkersWithSysVar() + require.NoError(t, m.InfoSchemaCache().Update(se)) + // schedule jobs + m.RescheduleJobs(se, now) + sql, args := cache.SelectFromTTLTableStatusWithID(table.Meta().ID) + rows, err := se.ExecuteSQL(ctx, sql, args...) + require.NoError(t, err) + tableStatus, err := cache.RowToTableStatus(se, rows[0]) + require.NoError(t, err) + + originalJobID := tableStatus.CurrentJobID + require.NotEmpty(t, originalJobID) + require.Equal(t, "manager-1", tableStatus.CurrentJobOwnerID) + // there is already a task + tk.MustQuery("select count(*) from mysql.tidb_ttl_task").Check(testkit.Rows("1")) + + // another manager should get this job, if the heart beat is not updated + anotherManager := ttlworker.NewJobManager("manager-2", nil, store, nil) + anotherManager.TaskManager().ResizeWorkersWithSysVar() + require.NoError(t, anotherManager.InfoSchemaCache().Update(se)) + anotherManager.RescheduleJobs(se, now.Add(time.Hour)) + sql, args = cache.SelectFromTTLTableStatusWithID(table.Meta().ID) + rows, err = se.ExecuteSQL(ctx, sql, args...) + require.NoError(t, err) + tableStatus, err = cache.RowToTableStatus(se, rows[0]) + require.NoError(t, err) + + // but the orignal job should be inherited + require.NotEmpty(t, tableStatus.CurrentJobID) + require.Equal(t, "manager-2", tableStatus.CurrentJobOwnerID) + require.Equal(t, originalJobID, tableStatus.CurrentJobID) + + // if the time leaves the time window, it'll finish the job + tk.MustExec("set global tidb_ttl_job_schedule_window_start_time='23:58'") + tk.MustExec("set global tidb_ttl_job_schedule_window_end_time='23:59'") + anotherManager.RescheduleJobs(se, time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, now.Nanosecond(), now.Location())) + tk.MustQuery("select last_job_summary->>'$.scan_task_err' from mysql.tidb_ttl_table_status").Check(testkit.Rows("ttl job is disabled")) +} + +func TestJobTimeout(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + sessionFactory := sessionFactory(t, store) + + waitAndStopTTLManager(t, dom) + + now := time.Now() + tk.MustExec("create table test.t (id int, created_at datetime) ttl = `created_at` + interval 1 minute ttl_job_interval = '1m'") + table, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnTTL) + + se := sessionFactory() + m := ttlworker.NewJobManager("manager-1", nil, store, nil) + m.TaskManager().ResizeWorkersWithSysVar() + require.NoError(t, m.InfoSchemaCache().Update(se)) + // schedule jobs + m.RescheduleJobs(se, now) + // set the worker to be empty, so none of the tasks will be scheduled + m.TaskManager().SetScanWorkers4Test([]ttlworker.Worker{}) + + sql, args := cache.SelectFromTTLTableStatusWithID(table.Meta().ID) + rows, err := se.ExecuteSQL(ctx, sql, args...) + require.NoError(t, err) + tableStatus, err := cache.RowToTableStatus(se, rows[0]) + require.NoError(t, err) + + require.NotEmpty(t, tableStatus.CurrentJobID) + require.Equal(t, "manager-1", tableStatus.CurrentJobOwnerID) + // there is already a task + tk.MustQuery("select count(*) from mysql.tidb_ttl_task").Check(testkit.Rows("1")) + + // the timeout will be checked while updating heartbeat + require.NoError(t, m.UpdateHeartBeat(ctx, se, now.Add(7*time.Hour))) + tk.MustQuery("select last_job_summary->>'$.scan_task_err' from mysql.tidb_ttl_table_status").Check(testkit.Rows("job is timeout")) + tk.MustQuery("select count(*) from mysql.tidb_ttl_task").Check(testkit.Rows("0")) +} + +func waitAndStopTTLManager(t *testing.T, dom *domain.Domain) { + maxWaitTime := 30 + for { + maxWaitTime-- + if maxWaitTime < 0 { + require.Fail(t, "fail to stop ttl manager") + } + if dom.TTLJobManager() != nil { + dom.TTLJobManager().Stop() + require.NoError(t, dom.TTLJobManager().WaitStopped(context.Background(), time.Second*10)) + return + } + time.Sleep(time.Second) + continue + } +} diff --git a/ttl/ttlworker/job_manager_test.go b/ttl/ttlworker/job_manager_test.go new file mode 100644 index 0000000000000..9e0211410591b --- /dev/null +++ b/ttl/ttlworker/job_manager_test.go @@ -0,0 +1,454 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "testing" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func newTTLTableStatusRows(status ...*cache.TableStatus) []chunk.Row { + c := chunk.NewChunkWithCapacity([]*types.FieldType{ + types.NewFieldType(mysql.TypeLonglong), // table_id + types.NewFieldType(mysql.TypeLonglong), // parent_table_id + types.NewFieldType(mysql.TypeString), // table_statistics + types.NewFieldType(mysql.TypeString), // last_job_id + types.NewFieldType(mysql.TypeDatetime), // last_job_start_time + types.NewFieldType(mysql.TypeDatetime), // last_job_finish_time + types.NewFieldType(mysql.TypeDatetime), // last_job_ttl_expire + types.NewFieldType(mysql.TypeString), // last_job_summary + types.NewFieldType(mysql.TypeString), // current_job_id + types.NewFieldType(mysql.TypeString), // current_job_owner_id + types.NewFieldType(mysql.TypeString), // current_job_owner_addr + types.NewFieldType(mysql.TypeDatetime), // current_job_hb_time + types.NewFieldType(mysql.TypeDatetime), // current_job_start_time + types.NewFieldType(mysql.TypeDatetime), // current_job_ttl_expire + types.NewFieldType(mysql.TypeString), // current_job_state + types.NewFieldType(mysql.TypeString), // current_job_status + types.NewFieldType(mysql.TypeDatetime), // current_job_status_update_time + }, len(status)) + var rows []chunk.Row + + for _, s := range status { + tableID := types.NewDatum(s.TableID) + c.AppendDatum(0, &tableID) + parentTableID := types.NewDatum(s.ParentTableID) + c.AppendDatum(1, &parentTableID) + if s.TableStatistics == "" { + c.AppendNull(2) + } else { + tableStatistics := types.NewDatum(s.TableStatistics) + c.AppendDatum(2, &tableStatistics) + } + + if s.LastJobID == "" { + c.AppendNull(3) + } else { + lastJobID := types.NewDatum(s.LastJobID) + c.AppendDatum(3, &lastJobID) + } + + lastJobStartTime := types.NewDatum(types.NewTime(types.FromGoTime(s.LastJobStartTime), mysql.TypeDatetime, types.MaxFsp)) + c.AppendDatum(4, &lastJobStartTime) + lastJobFinishTime := types.NewDatum(types.NewTime(types.FromGoTime(s.LastJobFinishTime), mysql.TypeDatetime, types.MaxFsp)) + c.AppendDatum(5, &lastJobFinishTime) + lastJobTTLExpire := types.NewDatum(types.NewTime(types.FromGoTime(s.LastJobTTLExpire), mysql.TypeDatetime, types.MaxFsp)) + c.AppendDatum(6, &lastJobTTLExpire) + + if s.LastJobSummary == "" { + c.AppendNull(7) + } else { + lastJobSummary := types.NewDatum(s.LastJobSummary) + c.AppendDatum(7, &lastJobSummary) + } + if s.CurrentJobID == "" { + c.AppendNull(8) + } else { + currentJobID := types.NewDatum(s.CurrentJobID) + c.AppendDatum(8, ¤tJobID) + } + if s.CurrentJobOwnerID == "" { + c.AppendNull(9) + } else { + currentJobOwnerID := types.NewDatum(s.CurrentJobOwnerID) + c.AppendDatum(9, ¤tJobOwnerID) + } + if s.CurrentJobOwnerAddr == "" { + c.AppendNull(10) + } else { + currentJobOwnerAddr := types.NewDatum(s.CurrentJobOwnerAddr) + c.AppendDatum(10, ¤tJobOwnerAddr) + } + + currentJobOwnerHBTime := types.NewDatum(types.NewTime(types.FromGoTime(s.CurrentJobOwnerHBTime), mysql.TypeDatetime, types.MaxFsp)) + c.AppendDatum(11, ¤tJobOwnerHBTime) + currentJobStartTime := types.NewDatum(types.NewTime(types.FromGoTime(s.CurrentJobStartTime), mysql.TypeDatetime, types.MaxFsp)) + c.AppendDatum(12, ¤tJobStartTime) + currentJobTTLExpire := types.NewDatum(types.NewTime(types.FromGoTime(s.CurrentJobTTLExpire), mysql.TypeDatetime, types.MaxFsp)) + c.AppendDatum(13, ¤tJobTTLExpire) + + if s.CurrentJobState == "" { + c.AppendNull(14) + } else { + currentJobState := types.NewDatum(s.CurrentJobState) + c.AppendDatum(14, ¤tJobState) + } + if s.CurrentJobStatus == "" { + c.AppendNull(15) + } else { + currentJobStatus := types.NewDatum(s.CurrentJobStatus) + c.AppendDatum(15, ¤tJobStatus) + } + + currentJobStatusUpdateTime := types.NewDatum(types.NewTime(types.FromGoTime(s.CurrentJobStatusUpdateTime), mysql.TypeDatetime, types.MaxFsp)) + c.AppendDatum(16, ¤tJobStatusUpdateTime) + } + + iter := chunk.NewIterator4Chunk(c) + for row := iter.Begin(); row != iter.End(); row = iter.Next() { + rows = append(rows, row) + } + return rows +} + +var updateStatusSQL = "SELECT LOW_PRIORITY table_id,parent_table_id,table_statistics,last_job_id,last_job_start_time,last_job_finish_time,last_job_ttl_expire,last_job_summary,current_job_id,current_job_owner_id,current_job_owner_addr,current_job_owner_hb_time,current_job_start_time,current_job_ttl_expire,current_job_state,current_job_status,current_job_status_update_time FROM mysql.tidb_ttl_table_status" + +// TTLJob exports the ttlJob for test +type TTLJob = ttlJob + +// LockNewJob is an exported version of lockNewJob for test +func (m *JobManager) LockNewJob(ctx context.Context, se session.Session, table *cache.PhysicalTable, now time.Time, ignoreScheduleInterval bool) (*TTLJob, error) { + return m.lockNewJob(ctx, se, table, now, ignoreScheduleInterval) +} + +// RunningJobs returns the running jobs inside ttl job manager +func (m *JobManager) RunningJobs() []*TTLJob { + return m.runningJobs +} + +// InfoSchemaCache is an exported getter of infoSchemaCache for test +func (m *JobManager) InfoSchemaCache() *cache.InfoSchemaCache { + return m.infoSchemaCache +} + +// RescheduleJobs is an exported version of rescheduleJobs for test +func (m *JobManager) RescheduleJobs(se session.Session, now time.Time) { + m.rescheduleJobs(se, now) +} + +// TaskManager is an exported getter of task manager for test +func (m *JobManager) TaskManager() *taskManager { + return m.taskManager +} + +// UpdateHeartBeat is an exported version of updateHeartBeat for test +func (m *JobManager) UpdateHeartBeat(ctx context.Context, se session.Session, now time.Time) error { + return m.updateHeartBeat(ctx, se, now) +} + +func (j *ttlJob) Finish(se session.Session, now time.Time, summary string) { + j.finish(se, now, summary) +} + +func (j *ttlJob) ID() string { + return j.id +} + +func newMockTTLJob(tbl *cache.PhysicalTable, status cache.JobStatus) *ttlJob { + return &ttlJob{tbl: tbl, status: status} +} + +func TestReadyForNewJobTables(t *testing.T) { + tbl := newMockTTLTbl(t, "t1") + m := NewJobManager("test-id", nil, nil, nil) + m.sessPool = newMockSessionPool(t, tbl) + se := newMockSession(t, tbl) + + tblWithDailyInterval := newMockTTLTbl(t, "t2") + tblWithDailyInterval.TTLInfo.JobInterval = "1d" + + cases := []struct { + name string + infoSchemaTables []*cache.PhysicalTable + tableStatus []*cache.TableStatus + shouldSchedule bool + }{ + // for a newly inserted table, it'll always be scheduled + {"newly created", []*cache.PhysicalTable{tbl}, []*cache.TableStatus{{TableID: tbl.ID, ParentTableID: tbl.ID}}, true}, + // table only in the table status cache will not be scheduled + {"proper subset", []*cache.PhysicalTable{}, []*cache.TableStatus{{TableID: tbl.ID, ParentTableID: tbl.ID}}, false}, + // table whose current job owner id is not empty, and heart beat time is long enough will not be scheduled + {"current job not empty", []*cache.PhysicalTable{tbl}, []*cache.TableStatus{{TableID: tbl.ID, ParentTableID: tbl.ID, CurrentJobOwnerID: "test-another-id", CurrentJobOwnerHBTime: time.Now()}}, false}, + // table whose current job owner id is not empty, but heart beat time is expired will be scheduled + {"hb time expired", []*cache.PhysicalTable{tbl}, []*cache.TableStatus{{TableID: tbl.ID, ParentTableID: tbl.ID, CurrentJobOwnerID: "test-another-id", CurrentJobOwnerHBTime: time.Now().Add(-time.Hour)}}, true}, + // if the last finished time is too near, it will also not be scheduled + {"last start time too near", []*cache.PhysicalTable{tbl}, []*cache.TableStatus{{TableID: tbl.ID, ParentTableID: tbl.ID, LastJobStartTime: time.Now()}}, false}, + // if the last finished time is expired, it will be scheduled + {"last start time expired", []*cache.PhysicalTable{tbl}, []*cache.TableStatus{{TableID: tbl.ID, ParentTableID: tbl.ID, LastJobStartTime: time.Now().Add(-time.Hour * 2)}}, true}, + // if the interval is 24h, and the last finished time is near, it will not be scheduled + {"last start time too near for 24h", []*cache.PhysicalTable{tblWithDailyInterval}, []*cache.TableStatus{{TableID: tblWithDailyInterval.ID, ParentTableID: tblWithDailyInterval.ID, LastJobStartTime: time.Now().Add(-time.Hour * 2)}}, false}, + // if the interval is 24h, and the last finished time is far enough, it will be scheduled + {"last start time far enough for 24h", []*cache.PhysicalTable{tblWithDailyInterval}, []*cache.TableStatus{{TableID: tblWithDailyInterval.ID, ParentTableID: tblWithDailyInterval.ID, LastJobStartTime: time.Now().Add(-time.Hour * 25)}}, true}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + m.infoSchemaCache.Tables = make(map[int64]*cache.PhysicalTable) + for _, ist := range c.infoSchemaTables { + m.infoSchemaCache.Tables[ist.ID] = ist + } + m.tableStatusCache.Tables = make(map[int64]*cache.TableStatus) + for _, st := range c.tableStatus { + m.tableStatusCache.Tables[st.TableID] = st + } + + tables := m.readyForNewJobTables(se.Now()) + if c.shouldSchedule { + assert.Len(t, tables, 1) + assert.Equal(t, int64(0), tables[0].ID) + assert.Equal(t, int64(0), tables[0].TableInfo.ID) + } else { + assert.Len(t, tables, 0) + } + }) + } +} + +func TestLockNewTable(t *testing.T) { + now, err := time.Parse(timeFormat, "2022-12-05 17:13:05") + assert.NoError(t, err) + expireTime := now + + testPhysicalTable := &cache.PhysicalTable{ID: 1, TableInfo: &model.TableInfo{ID: 1, TTLInfo: &model.TTLInfo{ColumnName: model.NewCIStr("test"), IntervalExprStr: "5 Year", JobInterval: "1h"}}} + + type executeInfo struct { + sql string + args []interface{} + } + getExecuteInfo := func(sql string, args []interface{}) executeInfo { + return executeInfo{ + sql, + args, + } + } + getExecuteInfoForUpdate := func(sql string, args []interface{}) executeInfo { + return executeInfo{ + sql + " FOR UPDATE NOWAIT", + args, + } + } + getExecuteInfoWithErr := func(sql string, args []interface{}, err error) executeInfo { + require.NoError(t, err) + return executeInfo{ + sql, + args, + } + } + failpoint.Enable("github.com/pingcap/tidb/ttl/ttlworker/set-job-uuid", `return("test-job-id")`) + defer failpoint.Disable("github.com/pingcap/tidb/ttl/ttlworker/set-job-uuid") + + type sqlExecute struct { + executeInfo + + rows []chunk.Row + err error + } + cases := []struct { + name string + table *cache.PhysicalTable + sqls []sqlExecute + hasJob bool + hasError bool + }{ + {"normal lock table", testPhysicalTable, []sqlExecute{ + { + getExecuteInfoForUpdate(cache.SelectFromTTLTableStatusWithID(1)), + newTTLTableStatusRows(&cache.TableStatus{TableID: 1}), nil, + }, + { + getExecuteInfo(setTableStatusOwnerSQL("test-job-id", 1, now, expireTime, "test-id")), + nil, nil, + }, + { + getExecuteInfoWithErr(cache.InsertIntoTTLTask(newMockSession(t), "test-job-id", 1, 0, nil, nil, expireTime, now)), + nil, nil, + }, + { + getExecuteInfo(updateStatusSQL, nil), + newTTLTableStatusRows(&cache.TableStatus{TableID: 1}), nil, + }, + }, true, false}, + {"select nothing", testPhysicalTable, []sqlExecute{ + { + getExecuteInfoForUpdate(cache.SelectFromTTLTableStatusWithID(1)), + nil, nil, + }, + { + getExecuteInfo(insertNewTableIntoStatusSQL(1, 1)), + nil, nil, + }, + { + getExecuteInfoForUpdate(cache.SelectFromTTLTableStatusWithID(1)), + newTTLTableStatusRows(&cache.TableStatus{TableID: 1}), nil, + }, + { + getExecuteInfo(setTableStatusOwnerSQL("test-job-id", 1, now, expireTime, "test-id")), + nil, nil, + }, + { + getExecuteInfoWithErr(cache.InsertIntoTTLTask(newMockSession(t), "test-job-id", 1, 0, nil, nil, expireTime, now)), + nil, nil, + }, + { + getExecuteInfo(updateStatusSQL, nil), + newTTLTableStatusRows(&cache.TableStatus{TableID: 1}), nil, + }, + }, true, false}, + {"return error", testPhysicalTable, []sqlExecute{ + { + getExecuteInfoForUpdate(cache.SelectFromTTLTableStatusWithID(1)), + newTTLTableStatusRows(&cache.TableStatus{TableID: 1}), nil, + }, + { + getExecuteInfo(setTableStatusOwnerSQL("test-job-id", 1, now, expireTime, "test-id")), + nil, errors.New("test error message"), + }, + { + getExecuteInfoWithErr(cache.InsertIntoTTLTask(newMockSession(t), "test-job-id", 1, 0, nil, nil, expireTime, now)), + nil, nil, + }, + }, false, true}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + m := NewJobManager("test-id", newMockSessionPool(t), nil, nil) + m.infoSchemaCache.Tables[c.table.ID] = c.table + sqlCounter := 0 + se := newMockSession(t) + se.executeSQL = func(ctx context.Context, sql string, args ...interface{}) (rows []chunk.Row, err error) { + assert.Less(t, sqlCounter, len(c.sqls)) + assert.Equal(t, c.sqls[sqlCounter].sql, sql) + assert.Equal(t, c.sqls[sqlCounter].args, args) + + rows = c.sqls[sqlCounter].rows + err = c.sqls[sqlCounter].err + sqlCounter += 1 + return + } + se.evalExpire = now + + job, err := m.lockNewJob(context.Background(), se, c.table, now, false) + if c.hasJob { + assert.NotNil(t, job) + } else { + assert.Nil(t, job) + } + if c.hasError { + assert.NotNil(t, err) + } else { + assert.Nil(t, err) + } + }) + } +} + +func TestLocalJobs(t *testing.T) { + tbl1 := newMockTTLTbl(t, "t1") + tbl1.ID = 1 + tbl2 := newMockTTLTbl(t, "t2") + tbl2.ID = 2 + m := NewJobManager("test-id", nil, nil, nil) + m.sessPool = newMockSessionPool(t, tbl1, tbl2) + + m.runningJobs = []*ttlJob{{tbl: tbl1, id: "1"}, {tbl: tbl2, id: "2"}} + m.tableStatusCache.Tables = map[int64]*cache.TableStatus{ + tbl1.ID: { + CurrentJobOwnerID: m.id, + }, + tbl2.ID: { + CurrentJobOwnerID: "another-id", + }, + } + assert.Len(t, m.localJobs(), 1) + assert.Equal(t, m.localJobs()[0].id, "1") +} + +func TestRescheduleJobsOutOfWindow(t *testing.T) { + // TODO: use failpoint to mock return job, and schedule + + tbl := newMockTTLTbl(t, "t1") + se := newMockSession(t, tbl) + + scanWorker1 := NewMockScanWorker(t) + scanWorker1.Start() + scanWorker1.setOneRowResult(tbl, 2022) + scanWorker2 := NewMockScanWorker(t) + scanWorker2.Start() + scanWorker2.setOneRowResult(tbl, 2022) + + m := NewJobManager("test-id", nil, nil, nil) + m.sessPool = newMockSessionPool(t, tbl) + m.taskManager.SetScanWorkers4Test([]worker{ + scanWorker1, + scanWorker2, + }) + + // jobs will not be scheduled + m.tableStatusCache.Tables = map[int64]*cache.TableStatus{ + tbl.ID: { + CurrentJobOwnerID: m.id, + }, + } + m.runningJobs = []*ttlJob{newMockTTLJob(tbl, cache.JobStatusWaiting)} + savedttlJobScheduleWindowStartTime := variable.TTLJobScheduleWindowStartTime.Load() + savedttlJobScheduleWindowEndTime := variable.TTLJobScheduleWindowEndTime.Load() + ttlJobScheduleWindowStartTime, _ := time.ParseInLocation(variable.FullDayTimeFormat, "12:00 +0000", time.UTC) + variable.TTLJobScheduleWindowStartTime.Store(ttlJobScheduleWindowStartTime) + ttlJobScheduleWindowEndTime, _ := time.ParseInLocation(variable.FullDayTimeFormat, "12:05 +0000", time.UTC) + variable.TTLJobScheduleWindowEndTime.Store(ttlJobScheduleWindowEndTime) + defer func() { + variable.TTLJobScheduleWindowStartTime.Store(savedttlJobScheduleWindowStartTime) + variable.TTLJobScheduleWindowEndTime.Store(savedttlJobScheduleWindowEndTime) + }() + + now, _ := time.ParseInLocation(variable.FullDayTimeFormat, "12:06 +0000", time.UTC) + m.rescheduleJobs(se, now) + scanWorker1.checkWorkerStatus(workerStatusRunning, true, nil) + scanWorker1.checkPollResult(false, "") + scanWorker2.checkWorkerStatus(workerStatusRunning, true, nil) + scanWorker2.checkPollResult(false, "") + + // jobs will be scheduled within the time window + now, _ = time.ParseInLocation(variable.FullDayTimeFormat, "12:02 +0000", time.UTC) + m.rescheduleJobs(se, now) + //scanWorker1.checkWorkerStatus(workerStatusRunning, false, m.runningJobs[0].tasks[0]) + scanWorker1.checkPollResult(false, "") + scanWorker2.checkWorkerStatus(workerStatusRunning, true, nil) + scanWorker2.checkPollResult(false, "") +} diff --git a/ttl/ttlworker/scan.go b/ttl/ttlworker/scan.go new file mode 100644 index 0000000000000..ac1c1cd85ab50 --- /dev/null +++ b/ttl/ttlworker/scan.go @@ -0,0 +1,343 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "fmt" + "strconv" + "sync/atomic" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/metrics" + "github.com/pingcap/tidb/ttl/sqlbuilder" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" +) + +var ( + scanTaskExecuteSQLMaxRetry = 5 + scanTaskExecuteSQLRetryInterval = 2 * time.Second + taskStartCheckErrorRateCnt = 10000 + taskMaxErrorRate = 0.4 +) + +type ttlStatistics struct { + TotalRows atomic.Uint64 + SuccessRows atomic.Uint64 + ErrorRows atomic.Uint64 +} + +func (s *ttlStatistics) IncTotalRows(cnt int) { + metrics.ScannedExpiredRows.Add(float64(cnt)) + s.TotalRows.Add(uint64(cnt)) +} + +func (s *ttlStatistics) IncSuccessRows(cnt int) { + metrics.DeleteSuccessExpiredRows.Add(float64(cnt)) + s.SuccessRows.Add(uint64(cnt)) +} + +func (s *ttlStatistics) IncErrorRows(cnt int) { + metrics.DeleteErrorExpiredRows.Add(float64(cnt)) + s.ErrorRows.Add(uint64(cnt)) +} + +func (s *ttlStatistics) Reset() { + s.SuccessRows.Store(0) + s.ErrorRows.Store(0) + s.TotalRows.Store(0) +} + +func (s *ttlStatistics) String() string { + return fmt.Sprintf("Total Rows: %d, Success Rows: %d, Error Rows: %d", s.TotalRows.Load(), s.SuccessRows.Load(), s.ErrorRows.Load()) +} + +type ttlScanTask struct { + ctx context.Context + + *cache.TTLTask + + tbl *cache.PhysicalTable + statistics *ttlStatistics +} + +type ttlScanTaskExecResult struct { + task *ttlScanTask + err error +} + +func (t *ttlScanTask) result(err error) *ttlScanTaskExecResult { + return &ttlScanTaskExecResult{task: t, err: err} +} + +func (t *ttlScanTask) getDatumRows(rows []chunk.Row) [][]types.Datum { + datums := make([][]types.Datum, len(rows)) + for i, row := range rows { + datums[i] = row.GetDatumRow(t.tbl.KeyColumnTypes) + } + return datums +} + +func (t *ttlScanTask) doScan(ctx context.Context, delCh chan<- *ttlDeleteTask, sessPool sessionPool) *ttlScanTaskExecResult { + // TODO: merge the ctx and the taskCtx in ttl scan task, to allow both "cancel" and gracefully stop workers + // now, the taskCtx is only check at the beginning of every loop + taskCtx := t.ctx + tracer := metrics.PhaseTracerFromCtx(ctx) + defer tracer.EnterPhase(tracer.Phase()) + + tracer.EnterPhase(metrics.PhaseOther) + rawSess, err := getSession(sessPool) + if err != nil { + return t.result(err) + } + defer rawSess.Close() + + origConcurrency := rawSess.GetSessionVars().DistSQLScanConcurrency() + if _, err = rawSess.ExecuteSQL(ctx, "set @@tidb_distsql_scan_concurrency=1"); err != nil { + return t.result(err) + } + + defer func() { + _, err = rawSess.ExecuteSQL(ctx, "set @@tidb_distsql_scan_concurrency="+strconv.Itoa(origConcurrency)) + terror.Log(err) + }() + + sess := newTableSession(rawSess, t.tbl, t.ExpireTime) + generator, err := sqlbuilder.NewScanQueryGenerator(t.tbl, t.ExpireTime, t.ScanRangeStart, t.ScanRangeEnd) + if err != nil { + return t.result(err) + } + + retrySQL := "" + retryTimes := 0 + var lastResult [][]types.Datum + for { + if err = taskCtx.Err(); err != nil { + return t.result(err) + } + if err = ctx.Err(); err != nil { + return t.result(err) + } + + if total := t.statistics.TotalRows.Load(); total > uint64(taskStartCheckErrorRateCnt) { + if t.statistics.ErrorRows.Load() > uint64(float64(total)*taskMaxErrorRate) { + return t.result(errors.Errorf("error exceeds the limit")) + } + } + + sql := retrySQL + if sql == "" { + limit := int(variable.TTLScanBatchSize.Load()) + if sql, err = generator.NextSQL(lastResult, limit); err != nil { + return t.result(err) + } + } + + if sql == "" { + return t.result(nil) + } + + sqlStart := time.Now() + rows, retryable, sqlErr := sess.ExecuteSQLWithCheck(ctx, sql) + selectInterval := time.Since(sqlStart) + if sqlErr != nil { + metrics.SelectErrorDuration.Observe(selectInterval.Seconds()) + needRetry := retryable && retryTimes < scanTaskExecuteSQLMaxRetry && ctx.Err() == nil + logutil.BgLogger().Error("execute query for ttl scan task failed", + zap.String("SQL", sql), + zap.Int("retryTimes", retryTimes), + zap.Bool("needRetry", needRetry), + zap.Error(err), + ) + + if !needRetry { + return t.result(sqlErr) + } + retrySQL = sql + retryTimes++ + + tracer.EnterPhase(metrics.PhaseWaitRetry) + select { + case <-ctx.Done(): + return t.result(ctx.Err()) + case <-time.After(scanTaskExecuteSQLRetryInterval): + } + tracer.EnterPhase(metrics.PhaseOther) + continue + } + + metrics.SelectSuccessDuration.Observe(selectInterval.Seconds()) + retrySQL = "" + retryTimes = 0 + lastResult = t.getDatumRows(rows) + if len(rows) == 0 { + continue + } + + delTask := &ttlDeleteTask{ + tbl: t.tbl, + expire: t.ExpireTime, + rows: lastResult, + statistics: t.statistics, + } + + tracer.EnterPhase(metrics.PhaseDispatch) + select { + case <-ctx.Done(): + return t.result(ctx.Err()) + case delCh <- delTask: + t.statistics.IncTotalRows(len(lastResult)) + } + tracer.EnterPhase(metrics.PhaseOther) + } +} + +type scanTaskExecEndMsg struct { + result *ttlScanTaskExecResult +} + +type ttlScanWorker struct { + baseWorker + curTask *ttlScanTask + curTaskResult *ttlScanTaskExecResult + delCh chan<- *ttlDeleteTask + notifyStateCh chan<- interface{} + sessionPool sessionPool +} + +func newScanWorker(delCh chan<- *ttlDeleteTask, notifyStateCh chan<- interface{}, sessPool sessionPool) *ttlScanWorker { + w := &ttlScanWorker{ + delCh: delCh, + notifyStateCh: notifyStateCh, + sessionPool: sessPool, + } + w.init(w.loop) + return w +} + +func (w *ttlScanWorker) CouldSchedule() bool { + w.Lock() + defer w.Unlock() + // see `Schedule`. If a `worker.CouldSchedule()` is true, `worker.Schedule` must success + return w.status == workerStatusRunning && w.curTask == nil && w.curTaskResult == nil +} + +func (w *ttlScanWorker) Schedule(task *ttlScanTask) error { + w.Lock() + if w.status != workerStatusRunning { + w.Unlock() + return errors.New("worker is not running") + } + + if w.curTaskResult != nil { + w.Unlock() + return errors.New("the result of previous task has not been polled") + } + + if w.curTask != nil { + w.Unlock() + return errors.New("a task is running") + } + + w.curTask = task + w.curTaskResult = nil + w.Unlock() + w.baseWorker.ch <- task + return nil +} + +func (w *ttlScanWorker) CurrentTask() *ttlScanTask { + w.Lock() + defer w.Unlock() + return w.curTask +} + +func (w *ttlScanWorker) PollTaskResult() *ttlScanTaskExecResult { + w.Lock() + defer w.Unlock() + if r := w.curTaskResult; r != nil { + w.curTask = nil + w.curTaskResult = nil + return r + } + return nil +} + +func (w *ttlScanWorker) loop() error { + ctx := w.baseWorker.ctx + tracer := metrics.NewScanWorkerPhaseTracer() + defer func() { + tracer.EndPhase() + logutil.BgLogger().Info("ttlScanWorker loop exited.") + }() + + ticker := time.Tick(time.Second * 5) + for w.Status() == workerStatusRunning { + tracer.EnterPhase(metrics.PhaseIdle) + select { + case <-ctx.Done(): + return nil + case <-ticker: + // ticker is used to update metrics on time + case msg, ok := <-w.baseWorker.ch: + tracer.EnterPhase(metrics.PhaseOther) + if !ok { + return nil + } + switch task := msg.(type) { + case *ttlScanTask: + w.handleScanTask(tracer, task) + default: + logutil.BgLogger().Warn("unrecognized message for ttlScanWorker", zap.Any("msg", msg)) + } + } + } + return nil +} + +func (w *ttlScanWorker) handleScanTask(tracer *metrics.PhaseTracer, task *ttlScanTask) { + ctx := metrics.CtxWithPhaseTracer(w.ctx, tracer) + result := task.doScan(ctx, w.delCh, w.sessionPool) + if result == nil { + result = task.result(nil) + } + + w.baseWorker.Lock() + w.curTaskResult = result + w.baseWorker.Unlock() + + if w.notifyStateCh != nil { + select { + case w.notifyStateCh <- &scanTaskExecEndMsg{result: result}: + default: + } + } +} + +type scanWorker interface { + worker + + CouldSchedule() bool + Schedule(*ttlScanTask) error + PollTaskResult() *ttlScanTaskExecResult + CurrentTask() *ttlScanTask +} diff --git a/ttl/ttlworker/scan_test.go b/ttl/ttlworker/scan_test.go new file mode 100644 index 0000000000000..1c280a5b0f2b2 --- /dev/null +++ b/ttl/ttlworker/scan_test.go @@ -0,0 +1,409 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/stretchr/testify/require" +) + +type mockScanWorker struct { + *ttlScanWorker + t *testing.T + delCh chan *ttlDeleteTask + notifyCh chan interface{} + sessPoll *mockSessionPool +} + +func NewMockScanWorker(t *testing.T) *mockScanWorker { + w := &mockScanWorker{ + t: t, + delCh: make(chan *ttlDeleteTask), + notifyCh: make(chan interface{}, 10), + sessPoll: newMockSessionPool(t), + } + + w.ttlScanWorker = newScanWorker(w.delCh, w.notifyCh, w.sessPoll) + require.Equal(t, workerStatusCreated, w.Status()) + require.False(t, w.CouldSchedule()) + result := w.PollTaskResult() + require.Nil(t, result) + return w +} + +func (w *mockScanWorker) checkWorkerStatus(status workerStatus, idle bool, curTask *ttlScanTask) { + require.Equal(w.t, status, w.status) + require.Equal(w.t, idle, w.CouldSchedule()) + require.Same(w.t, curTask, w.CurrentTask()) +} + +func (w *mockScanWorker) checkPollResult(exist bool, err string) { + curTask := w.CurrentTask() + r := w.PollTaskResult() + require.Equal(w.t, exist, r != nil) + if !exist { + require.Nil(w.t, r) + } else { + require.NotNil(w.t, r) + require.NotNil(w.t, r.task) + require.Same(w.t, curTask, r.task) + if err == "" { + require.NoError(w.t, r.err) + } else { + require.EqualError(w.t, r.err, err) + } + } +} + +func (w *mockScanWorker) waitNotifyScanTaskEnd() *scanTaskExecEndMsg { + select { + case msg := <-w.notifyCh: + endMsg, ok := msg.(*scanTaskExecEndMsg) + require.True(w.t, ok) + require.NotNil(w.t, endMsg.result) + require.Same(w.t, w.CurrentTask(), endMsg.result.task) + return endMsg + case <-time.After(10 * time.Second): + require.FailNow(w.t, "timeout") + } + + require.FailNow(w.t, "") + return nil +} + +func (w *mockScanWorker) pollDelTask() *ttlDeleteTask { + select { + case del := <-w.delCh: + require.NotNil(w.t, del) + require.NotNil(w.t, del.statistics) + require.Same(w.t, w.curTask.tbl, del.tbl) + require.Equal(w.t, w.curTask.ExpireTime, del.expire) + require.NotEqual(w.t, 0, len(del.rows)) + return del + case <-time.After(10 * time.Second): + require.FailNow(w.t, "timeout") + } + + require.FailNow(w.t, "") + return nil +} + +func (w *mockScanWorker) setOneRowResult(tbl *cache.PhysicalTable, val ...interface{}) { + w.sessPoll.se.sessionInfoSchema = newMockInfoSchema(tbl.TableInfo) + w.sessPoll.se.rows = newMockRows(w.t, tbl.KeyColumnTypes...).Append(val...).Rows() +} + +func (w *mockScanWorker) clearInfoSchema() { + w.sessPoll.se.sessionInfoSchema = newMockInfoSchema() +} + +func (w *mockScanWorker) stopWithWait() { + w.Stop() + require.NoError(w.t, w.WaitStopped(context.TODO(), 10*time.Second)) +} + +func TestScanWorkerSchedule(t *testing.T) { + origLimit := variable.TTLScanBatchSize.Load() + variable.TTLScanBatchSize.Store(5) + defer variable.TTLScanBatchSize.Store(origLimit) + + tbl := newMockTTLTbl(t, "t1") + w := NewMockScanWorker(t) + w.setOneRowResult(tbl, 7) + defer w.stopWithWait() + + task := &ttlScanTask{ + ctx: context.Background(), + tbl: tbl, + TTLTask: &cache.TTLTask{ + ExpireTime: time.UnixMilli(0), + }, + statistics: &ttlStatistics{}, + } + + require.EqualError(t, w.Schedule(task), "worker is not running") + w.checkWorkerStatus(workerStatusCreated, false, nil) + w.checkPollResult(false, "") + + w.Start() + w.checkWorkerStatus(workerStatusRunning, true, nil) + w.checkPollResult(false, "") + + require.NoError(t, w.Schedule(task)) + w.checkWorkerStatus(workerStatusRunning, false, task) + w.checkPollResult(false, "") + + require.EqualError(t, w.Schedule(task), "a task is running") + w.checkWorkerStatus(workerStatusRunning, false, task) + w.checkPollResult(false, "") + + del := w.pollDelTask() + require.Equal(t, 1, len(del.rows)) + require.Equal(t, 1, len(del.rows[0])) + require.Equal(t, int64(7), del.rows[0][0].GetInt64()) + + msg := w.waitNotifyScanTaskEnd() + require.Same(t, task, msg.result.task) + require.NoError(t, msg.result.err) + w.checkWorkerStatus(workerStatusRunning, false, task) + w.checkPollResult(true, "") + w.checkWorkerStatus(workerStatusRunning, true, nil) + w.checkPollResult(false, "") +} + +func TestScanWorkerScheduleWithFailedTask(t *testing.T) { + origLimit := variable.TTLScanBatchSize.Load() + variable.TTLScanBatchSize.Store(5) + defer variable.TTLScanBatchSize.Store(origLimit) + + tbl := newMockTTLTbl(t, "t1") + w := NewMockScanWorker(t) + w.clearInfoSchema() + defer w.stopWithWait() + + task := &ttlScanTask{ + ctx: context.Background(), + tbl: tbl, + TTLTask: &cache.TTLTask{ + ExpireTime: time.UnixMilli(0), + }, + statistics: &ttlStatistics{}, + } + + w.Start() + w.checkWorkerStatus(workerStatusRunning, true, nil) + w.checkPollResult(false, "") + + require.NoError(t, w.Schedule(task)) + w.checkWorkerStatus(workerStatusRunning, false, task) + msg := w.waitNotifyScanTaskEnd() + require.Same(t, task, msg.result.task) + require.EqualError(t, msg.result.err, "table 'test.t1' meta changed, should abort current job: [schema:1146]Table 'test.t1' doesn't exist") + w.checkWorkerStatus(workerStatusRunning, false, task) + w.checkPollResult(true, msg.result.err.Error()) + w.checkWorkerStatus(workerStatusRunning, true, nil) +} + +type mockScanTask struct { + *ttlScanTask + t *testing.T + tbl *cache.PhysicalTable + sessPool *mockSessionPool + sqlRetry []int + + delCh chan *ttlDeleteTask + prevSQL string + prevSQLRetry int + delTasks []*ttlDeleteTask + schemaChangeIdx int + schemaChangeInRetry int +} + +func newMockScanTask(t *testing.T, sqlCnt int) *mockScanTask { + tbl := newMockTTLTbl(t, "t1") + task := &mockScanTask{ + t: t, + ttlScanTask: &ttlScanTask{ + ctx: context.Background(), + tbl: tbl, + TTLTask: &cache.TTLTask{ + ExpireTime: time.UnixMilli(0), + ScanRangeStart: []types.Datum{types.NewIntDatum(0)}, + }, + statistics: &ttlStatistics{}, + }, + tbl: tbl, + delCh: make(chan *ttlDeleteTask, sqlCnt*(scanTaskExecuteSQLMaxRetry+1)), + sessPool: newMockSessionPool(t), + sqlRetry: make([]int, sqlCnt), + schemaChangeIdx: -1, + } + task.sessPool.se.executeSQL = task.execSQL + return task +} + +func (t *mockScanTask) selectSQL(i int) string { + op := ">" + if i == 0 { + op = ">=" + } + return fmt.Sprintf("SELECT LOW_PRIORITY `_tidb_rowid` FROM `test`.`t1` WHERE `_tidb_rowid` %s %d AND `time` < '1970-01-01 08:00:00' ORDER BY `_tidb_rowid` ASC LIMIT 3", op, i*100) +} + +func (t *mockScanTask) runDoScanForTest(delTaskCnt int, errString string) *ttlScanTaskExecResult { + t.ttlScanTask.statistics.Reset() + origLimit := variable.TTLScanBatchSize.Load() + variable.TTLScanBatchSize.Store(3) + origRetryInterval := scanTaskExecuteSQLRetryInterval + scanTaskExecuteSQLRetryInterval = time.Millisecond + defer func() { + variable.TTLScanBatchSize.Store(origLimit) + scanTaskExecuteSQLRetryInterval = origRetryInterval + }() + + t.sessPool.se.sessionInfoSchema = newMockInfoSchema(t.tbl.TableInfo) + t.prevSQL = "" + t.prevSQLRetry = 0 + t.sessPool.lastSession = nil + r := t.doScan(context.TODO(), t.delCh, t.sessPool) + require.NotNil(t.t, t.sessPool.lastSession) + require.True(t.t, t.sessPool.lastSession.closed) + require.Greater(t.t, t.sessPool.lastSession.resetTimeZoneCalls, 0) + require.NotNil(t.t, r) + require.Same(t.t, t.ttlScanTask, r.task) + if errString == "" { + require.NoError(t.t, r.err) + } else { + require.EqualError(t.t, r.err, errString) + } + + previousIdx := delTaskCnt + if errString == "" { + previousIdx = len(t.sqlRetry) - 1 + } + require.Equal(t.t, t.selectSQL(previousIdx), t.prevSQL) + if errString == "" { + require.Equal(t.t, t.sqlRetry[previousIdx], t.prevSQLRetry) + } else if previousIdx == t.schemaChangeIdx && t.schemaChangeInRetry <= scanTaskExecuteSQLMaxRetry { + require.Equal(t.t, t.schemaChangeInRetry, t.prevSQLRetry) + } else { + require.Equal(t.t, scanTaskExecuteSQLMaxRetry, t.prevSQLRetry) + } + t.delTasks = make([]*ttlDeleteTask, 0, len(t.sqlRetry)) +loop: + for { + select { + case del, ok := <-t.delCh: + if !ok { + break loop + } + t.delTasks = append(t.delTasks, del) + default: + break loop + } + } + + require.Equal(t.t, delTaskCnt, len(t.delTasks)) + expectTotalRows := 0 + for i, del := range t.delTasks { + require.NotNil(t.t, del) + require.NotNil(t.t, del.statistics) + require.Same(t.t, t.statistics, del.statistics) + require.Same(t.t, t.tbl, del.tbl) + require.Equal(t.t, t.ExpireTime, del.expire) + if i < len(t.sqlRetry)-1 { + require.Equal(t.t, 3, len(del.rows)) + require.Equal(t.t, 1, len(del.rows[2])) + require.Equal(t.t, int64((i+1)*100), del.rows[2][0].GetInt64()) + } else { + require.Equal(t.t, 2, len(del.rows)) + } + require.Equal(t.t, 1, len(del.rows[0])) + require.Equal(t.t, int64(i*100+1), del.rows[0][0].GetInt64()) + require.Equal(t.t, 1, len(del.rows[0])) + require.Equal(t.t, int64(i*100+2), del.rows[1][0].GetInt64()) + expectTotalRows += len(del.rows) + } + require.Equal(t.t, expectTotalRows, int(t.statistics.TotalRows.Load())) + return r +} + +func (t *mockScanTask) checkDelTasks(cnt int) { + require.Equal(t.t, cnt, len(t.delTasks)) + for i := 0; i < cnt; i++ { + del := t.delTasks[i] + require.Nil(t.t, del) + require.NotNil(t.t, del.statistics) + require.Same(t.t, t.statistics, del.statistics) + if i < 2 { + require.Equal(t.t, 3, len(del.rows)) + require.Equal(t.t, 1, len(del.rows[2])) + require.Equal(t.t, int64((i+1)*100), del.rows[2][0].GetInt64()) + } else { + require.Equal(t.t, 2, len(del.rows)) + } + require.Equal(t.t, 1, len(del.rows[0])) + require.Equal(t.t, int64(i*100+1), del.rows[0][0].GetInt64()) + require.Equal(t.t, 1, len(del.rows[0])) + require.Equal(t.t, int64(i*100+2), del.rows[1][0].GetInt64()) + } +} + +func (t *mockScanTask) execSQL(_ context.Context, sql string, _ ...interface{}) ([]chunk.Row, error) { + var i int + found := false + for i = 0; i < len(t.sqlRetry); i++ { + if sql == t.selectSQL(i) { + found = true + break + } + } + require.True(t.t, found, sql) + + curRetry := 0 + if sql == t.prevSQL { + curRetry = t.prevSQLRetry + 1 + } + + if curRetry == 0 && i > 0 { + require.Equal(t.t, t.selectSQL(i-1), t.prevSQL) + require.Equal(t.t, t.sqlRetry[i-1], t.prevSQLRetry) + } + t.prevSQL = sql + t.prevSQLRetry = curRetry + require.LessOrEqual(t.t, curRetry, t.sqlRetry[i]) + + if t.schemaChangeIdx == i && t.schemaChangeInRetry == curRetry { + t.sessPool.lastSession.sessionInfoSchema = newMockInfoSchema() + } + + if curRetry < t.sqlRetry[i] { + return nil, errors.New("mockErr") + } + + rows := newMockRows(t.t, t.tbl.KeyColumnTypes...).Append(i*100 + 1).Append(i*100 + 2) + if i < len(t.sqlRetry)-1 { + rows.Append((i + 1) * 100) + } + return rows.Rows(), nil +} + +func TestScanTaskDoScan(t *testing.T) { + task := newMockScanTask(t, 3) + task.sqlRetry[1] = scanTaskExecuteSQLMaxRetry + task.runDoScanForTest(3, "") + + task.sqlRetry[1] = scanTaskExecuteSQLMaxRetry + 1 + task.runDoScanForTest(1, "mockErr") + + task.sqlRetry[1] = scanTaskExecuteSQLMaxRetry + task.schemaChangeIdx = 1 + task.schemaChangeInRetry = 0 + task.runDoScanForTest(1, "table 'test.t1' meta changed, should abort current job: [schema:1146]Table 'test.t1' doesn't exist") + + task.sqlRetry[1] = scanTaskExecuteSQLMaxRetry + task.schemaChangeIdx = 1 + task.schemaChangeInRetry = 2 + task.runDoScanForTest(1, "table 'test.t1' meta changed, should abort current job: [schema:1146]Table 'test.t1' doesn't exist") +} diff --git a/ttl/ttlworker/session.go b/ttl/ttlworker/session.go new file mode 100644 index 0000000000000..d3e0c940e78c7 --- /dev/null +++ b/ttl/ttlworker/session.go @@ -0,0 +1,248 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "fmt" + "time" + + "github.com/ngaut/pools" + "github.com/pingcap/errors" + "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/metrics" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/sqlexec" + "go.uber.org/zap" +) + +// The following two functions are using `sqlexec.SQLExecutor` to represent session +// which is actually not correct. It's a work around for the cyclic dependency problem. +// It actually doesn't accept arbitrary SQLExecutor, but just `*session.session`, which means +// you cannot pass the `(ttl/session).Session` into it. +// Use `sqlexec.SQLExecutor` and `sessionctx.Session` or another other interface (including +// `interface{}`) here is the same, I just pick one small enough interface. +// Also, we cannot use the functions in `session/session.go` (to avoid cyclic dependency), so +// registering function here is really needed. + +// AttachStatsCollector attaches the stats collector for the session. +// this function is registered in BootstrapSession in /session/session.go +var AttachStatsCollector = func(s sqlexec.SQLExecutor) sqlexec.SQLExecutor { + return s +} + +// DetachStatsCollector removes the stats collector for the session +// this function is registered in BootstrapSession in /session/session.go +var DetachStatsCollector = func(s sqlexec.SQLExecutor) sqlexec.SQLExecutor { + return s +} + +type sessionPool interface { + Get() (pools.Resource, error) + Put(pools.Resource) +} + +func getSession(pool sessionPool) (session.Session, error) { + resource, err := pool.Get() + if err != nil { + return nil, err + } + + if se, ok := resource.(session.Session); ok { + // Only for test, in this case, the return session is mockSession + return se, nil + } + + sctx, ok := resource.(sessionctx.Context) + if !ok { + pool.Put(resource) + return nil, errors.Errorf("%T cannot be casted to sessionctx.Context", sctx) + } + + exec, ok := resource.(sqlexec.SQLExecutor) + if !ok { + pool.Put(resource) + return nil, errors.Errorf("%T cannot be casted to sqlexec.SQLExecutor", sctx) + } + + originalRetryLimit := sctx.GetSessionVars().RetryLimit + originalEnable1PC := sctx.GetSessionVars().Enable1PC + originalEnableAsyncCommit := sctx.GetSessionVars().EnableAsyncCommit + se := session.NewSession(sctx, exec, func(se session.Session) { + _, err = se.ExecuteSQL(context.Background(), fmt.Sprintf("set tidb_retry_limit=%d", originalRetryLimit)) + if err != nil { + logutil.BgLogger().Error("fail to reset tidb_retry_limit", zap.Int64("originalRetryLimit", originalRetryLimit), zap.Error(err)) + } + + if !originalEnable1PC { + _, err = se.ExecuteSQL(context.Background(), "set tidb_enable_1pc=OFF") + terror.Log(err) + } + + if !originalEnableAsyncCommit { + _, err = se.ExecuteSQL(context.Background(), "set tidb_enable_async_commit=OFF") + terror.Log(err) + } + + DetachStatsCollector(exec) + + pool.Put(resource) + }) + + exec = AttachStatsCollector(exec) + + // store and set the retry limit to 0 + _, err = se.ExecuteSQL(context.Background(), "set tidb_retry_limit=0") + if err != nil { + se.Close() + return nil, err + } + + // set enable 1pc to ON + _, err = se.ExecuteSQL(context.Background(), "set tidb_enable_1pc=ON") + if err != nil { + se.Close() + return nil, err + } + + // set enable async commit to ON + _, err = se.ExecuteSQL(context.Background(), "set tidb_enable_async_commit=ON") + if err != nil { + se.Close() + return nil, err + } + + // Force rollback the session to guarantee the session is not in any explicit transaction + if _, err = se.ExecuteSQL(context.Background(), "ROLLBACK"); err != nil { + se.Close() + return nil, err + } + + return se, nil +} + +func newTableSession(se session.Session, tbl *cache.PhysicalTable, expire time.Time) *ttlTableSession { + return &ttlTableSession{ + Session: se, + tbl: tbl, + expire: expire, + } +} + +type ttlTableSession struct { + session.Session + tbl *cache.PhysicalTable + expire time.Time +} + +func (s *ttlTableSession) ExecuteSQLWithCheck(ctx context.Context, sql string) ([]chunk.Row, bool, error) { + tracer := metrics.PhaseTracerFromCtx(ctx) + defer tracer.EnterPhase(tracer.Phase()) + + tracer.EnterPhase(metrics.PhaseOther) + if !variable.EnableTTLJob.Load() { + return nil, false, errors.New("global TTL job is disabled") + } + + if err := s.ResetWithGlobalTimeZone(ctx); err != nil { + return nil, false, err + } + + var result []chunk.Row + shouldRetry := true + err := s.RunInTxn(ctx, func() error { + tracer.EnterPhase(metrics.PhaseQuery) + defer tracer.EnterPhase(tracer.Phase()) + rows, err := s.ExecuteSQL(ctx, sql) + tracer.EnterPhase(metrics.PhaseCheckTTL) + // We must check the configuration after ExecuteSQL because of MDL and the meta the current transaction used + // can only be determined after executed one query. + if validateErr := validateTTLWork(ctx, s.Session, s.tbl, s.expire); validateErr != nil { + shouldRetry = false + return errors.Annotatef(validateErr, "table '%s.%s' meta changed, should abort current job", s.tbl.Schema, s.tbl.Name) + } + + if err != nil { + return err + } + + result = rows + return nil + }, session.TxnModeOptimistic) + + if err != nil { + return nil, shouldRetry, err + } + + return result, false, nil +} + +func validateTTLWork(ctx context.Context, s session.Session, tbl *cache.PhysicalTable, expire time.Time) error { + curTbl, err := s.SessionInfoSchema().TableByName(tbl.Schema, tbl.Name) + if err != nil { + return err + } + + newTblInfo := curTbl.Meta() + if tbl.TableInfo == newTblInfo { + return nil + } + + if tbl.TableInfo.ID != newTblInfo.ID { + return errors.New("table id changed") + } + + newTTLTbl, err := cache.NewPhysicalTable(tbl.Schema, newTblInfo, tbl.Partition) + if err != nil { + return err + } + + if newTTLTbl.ID != tbl.ID { + return errors.New("physical id changed") + } + + if tbl.Partition.L != "" { + if newTTLTbl.PartitionDef.Name.L != tbl.PartitionDef.Name.L { + return errors.New("partition name changed") + } + } + + if !newTTLTbl.TTLInfo.Enable { + return errors.New("table TTL disabled") + } + + if newTTLTbl.TimeColumn.Name.L != tbl.TimeColumn.Name.L { + return errors.New("time column name changed") + } + + if newTblInfo.TTLInfo.IntervalExprStr != tbl.TTLInfo.IntervalExprStr || + newTblInfo.TTLInfo.IntervalTimeUnit != tbl.TTLInfo.IntervalTimeUnit { + newExpireTime, err := newTTLTbl.EvalExpireTime(ctx, s, s.Now()) + if err != nil { + return err + } + + if newExpireTime.Before(expire) { + return errors.New("expire interval changed") + } + } + + return nil +} diff --git a/ttl/ttlworker/session_test.go b/ttl/ttlworker/session_test.go new file mode 100644 index 0000000000000..335f6a5701a99 --- /dev/null +++ b/ttl/ttlworker/session_test.go @@ -0,0 +1,354 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "errors" + "strings" + "testing" + "time" + + "github.com/ngaut/pools" + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/chunk" + "github.com/stretchr/testify/require" +) + +func newMockTTLTbl(t *testing.T, name string) *cache.PhysicalTable { + tblInfo := &model.TableInfo{ + Name: model.NewCIStr(name), + Columns: []*model.ColumnInfo{ + { + ID: 1, + Name: model.NewCIStr("time"), + Offset: 0, + FieldType: *types.NewFieldType(mysql.TypeDatetime), + State: model.StatePublic, + }, + }, + TTLInfo: &model.TTLInfo{ + ColumnName: model.NewCIStr("time"), + IntervalExprStr: "1", + IntervalTimeUnit: int(ast.TimeUnitSecond), + Enable: true, + JobInterval: "1h", + }, + State: model.StatePublic, + } + + tbl, err := cache.NewPhysicalTable(model.NewCIStr("test"), tblInfo, model.NewCIStr("")) + require.NoError(t, err) + return tbl +} + +func newMockInfoSchema(tbl ...*model.TableInfo) infoschema.InfoSchema { + return infoschema.MockInfoSchema(tbl) +} + +type mockRows struct { + t *testing.T + fieldTypes []*types.FieldType + *chunk.Chunk +} + +func newMockRows(t *testing.T, fieldTypes ...*types.FieldType) *mockRows { + return &mockRows{ + t: t, + fieldTypes: fieldTypes, + Chunk: chunk.NewChunkWithCapacity(fieldTypes, 8), + } +} + +func (r *mockRows) Append(row ...interface{}) *mockRows { + require.Equal(r.t, len(r.fieldTypes), len(row)) + for i, ft := range r.fieldTypes { + tp := ft.GetType() + switch tp { + case mysql.TypeTimestamp, mysql.TypeDate, mysql.TypeDatetime: + tm, ok := row[i].(time.Time) + require.True(r.t, ok) + r.AppendTime(i, types.NewTime(types.FromGoTime(tm), tp, types.DefaultFsp)) + case mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: + val, ok := row[i].(int) + require.True(r.t, ok) + r.AppendInt64(i, int64(val)) + default: + require.FailNow(r.t, "unsupported tp %v", tp) + } + } + return r +} + +func (r *mockRows) Rows() []chunk.Row { + rows := make([]chunk.Row, r.NumRows()) + for i := 0; i < r.NumRows(); i++ { + rows[i] = r.GetRow(i) + } + return rows +} + +type mockSessionPool struct { + t *testing.T + se *mockSession + lastSession *mockSession +} + +func (p *mockSessionPool) Get() (pools.Resource, error) { + se := *(p.se) + p.lastSession = &se + return p.lastSession, nil +} + +func (p *mockSessionPool) Put(pools.Resource) {} + +func newMockSessionPool(t *testing.T, tbl ...*cache.PhysicalTable) *mockSessionPool { + return &mockSessionPool{ + se: newMockSession(t, tbl...), + } +} + +type mockSession struct { + t *testing.T + sessionctx.Context + sessionVars *variable.SessionVars + sessionInfoSchema infoschema.InfoSchema + executeSQL func(ctx context.Context, sql string, args ...interface{}) ([]chunk.Row, error) + rows []chunk.Row + execErr error + evalExpire time.Time + resetTimeZoneCalls int + closed bool + commitErr error +} + +func newMockSession(t *testing.T, tbl ...*cache.PhysicalTable) *mockSession { + tbls := make([]*model.TableInfo, len(tbl)) + for i, ttlTbl := range tbl { + tbls[i] = ttlTbl.TableInfo + } + sessVars := variable.NewSessionVars(nil) + sessVars.TimeZone = time.UTC + return &mockSession{ + t: t, + sessionInfoSchema: newMockInfoSchema(tbls...), + evalExpire: time.Now(), + sessionVars: sessVars, + } +} + +func (s *mockSession) GetDomainInfoSchema() sessionctx.InfoschemaMetaVersion { + return s.sessionInfoSchema +} + +func (s *mockSession) SessionInfoSchema() infoschema.InfoSchema { + require.False(s.t, s.closed) + return s.sessionInfoSchema +} + +func (s *mockSession) GetSessionVars() *variable.SessionVars { + require.False(s.t, s.closed) + return s.sessionVars +} + +func (s *mockSession) ExecuteSQL(ctx context.Context, sql string, args ...interface{}) ([]chunk.Row, error) { + require.False(s.t, s.closed) + if strings.HasPrefix(strings.ToUpper(sql), "SELECT FROM_UNIXTIME") { + return newMockRows(s.t, types.NewFieldType(mysql.TypeTimestamp)).Append(s.evalExpire.In(s.GetSessionVars().TimeZone)).Rows(), nil + } + + if strings.HasPrefix(strings.ToUpper(sql), "SET ") { + return nil, nil + } + + if s.executeSQL != nil { + return s.executeSQL(ctx, sql, args...) + } + return s.rows, s.execErr +} + +func (s *mockSession) RunInTxn(_ context.Context, fn func() error, _ session.TxnMode) error { + require.False(s.t, s.closed) + if err := fn(); err != nil { + return err + } + return s.commitErr +} + +func (s *mockSession) ResetWithGlobalTimeZone(_ context.Context) (err error) { + require.False(s.t, s.closed) + s.resetTimeZoneCalls++ + return nil +} + +func (s *mockSession) Close() { + s.closed = true +} + +func (s *mockSession) Now() time.Time { + tz := s.sessionVars.TimeZone + if tz != nil { + tz = time.UTC + } + return time.Now().In(tz) +} + +func TestExecuteSQLWithCheck(t *testing.T) { + ctx := context.TODO() + tbl := newMockTTLTbl(t, "t1") + s := newMockSession(t, tbl) + s.execErr = errors.New("mockErr") + s.rows = newMockRows(t, types.NewFieldType(mysql.TypeInt24)).Append(12).Rows() + tblSe := newTableSession(s, tbl, time.UnixMilli(0).In(time.UTC)) + + rows, shouldRetry, err := tblSe.ExecuteSQLWithCheck(ctx, "select 1") + require.EqualError(t, err, "mockErr") + require.True(t, shouldRetry) + require.Nil(t, rows) + require.Equal(t, 1, s.resetTimeZoneCalls) + + s.sessionInfoSchema = newMockInfoSchema() + rows, shouldRetry, err = tblSe.ExecuteSQLWithCheck(ctx, "select 1") + require.EqualError(t, err, "table 'test.t1' meta changed, should abort current job: [schema:1146]Table 'test.t1' doesn't exist") + require.False(t, shouldRetry) + require.Nil(t, rows) + require.Equal(t, 2, s.resetTimeZoneCalls) + + s.sessionInfoSchema = newMockInfoSchema(tbl.TableInfo) + s.execErr = nil + rows, shouldRetry, err = tblSe.ExecuteSQLWithCheck(ctx, "select 1") + require.NoError(t, err) + require.False(t, shouldRetry) + require.Equal(t, 1, len(rows)) + require.Equal(t, int64(12), rows[0].GetInt64(0)) + require.Equal(t, 3, s.resetTimeZoneCalls) + + s.commitErr = errors.New("mockCommitErr") + rows, shouldRetry, err = tblSe.ExecuteSQLWithCheck(ctx, "select 1") + require.EqualError(t, err, "mockCommitErr") + require.True(t, shouldRetry) + require.Nil(t, rows) + require.Equal(t, 4, s.resetTimeZoneCalls) +} + +func TestValidateTTLWork(t *testing.T) { + ctx := context.TODO() + tbl := newMockTTLTbl(t, "t1") + expire := time.UnixMilli(0).In(time.UTC) + + s := newMockSession(t, tbl) + s.execErr = errors.New("mockErr") + s.evalExpire = time.UnixMilli(0).In(time.UTC) + + // test table dropped + s.sessionInfoSchema = newMockInfoSchema() + err := validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "[schema:1146]Table 'test.t1' doesn't exist") + + // test TTL option removed + tbl2 := tbl.TableInfo.Clone() + tbl2.TTLInfo = nil + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "table 'test.t1' is not a ttl table") + + // test table state not public + tbl2 = tbl.TableInfo.Clone() + tbl2.State = model.StateDeleteOnly + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "table 'test.t1' is not a public table") + + // test table name changed + tbl2 = tbl.TableInfo.Clone() + tbl2.Name = model.NewCIStr("testcc") + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "[schema:1146]Table 'test.t1' doesn't exist") + + // test table id changed + tbl2 = tbl.TableInfo.Clone() + tbl2.ID = 123 + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "table id changed") + + // test time column name changed + tbl2 = tbl.TableInfo.Clone() + tbl2.Columns[0] = tbl2.Columns[0].Clone() + tbl2.Columns[0].Name = model.NewCIStr("time2") + tbl2.TTLInfo.ColumnName = model.NewCIStr("time2") + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "time column name changed") + + // test interval changed and expire time before previous + tbl2 = tbl.TableInfo.Clone() + tbl2.TTLInfo.IntervalExprStr = "10" + s.sessionInfoSchema = newMockInfoSchema(tbl2) + s.evalExpire = time.UnixMilli(-1) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "expire interval changed") + + tbl2 = tbl.TableInfo.Clone() + tbl2.TTLInfo.IntervalTimeUnit = int(ast.TimeUnitDay) + s.evalExpire = time.UnixMilli(-1) + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "expire interval changed") + + // test for safe meta change + tbl2 = tbl.TableInfo.Clone() + tbl2.Columns[0] = tbl2.Columns[0].Clone() + tbl2.Columns[0].ID += 10 + tbl2.Columns[0].FieldType = *types.NewFieldType(mysql.TypeDate) + tbl2.TTLInfo.IntervalExprStr = "100" + s.evalExpire = time.UnixMilli(1000) + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.NoError(t, err) + + // test table partition name changed + tp := tbl.TableInfo.Clone() + tp.Partition = &model.PartitionInfo{ + Definitions: []model.PartitionDefinition{ + {ID: 1023, Name: model.NewCIStr("p0")}, + }, + } + tbl, err = cache.NewPhysicalTable(model.NewCIStr("test"), tp, model.NewCIStr("p0")) + require.NoError(t, err) + tbl2 = tp.Clone() + tbl2.Partition = tp.Partition.Clone() + tbl2.Partition.Definitions[0].Name = model.NewCIStr("p1") + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "partition 'p0' is not found in ttl table 'test.t1'") + + // test table partition id changed + tbl2 = tp.Clone() + tbl2.Partition = tp.Partition.Clone() + tbl2.Partition.Definitions[0].ID += 100 + s.sessionInfoSchema = newMockInfoSchema(tbl2) + err = validateTTLWork(ctx, s, tbl, expire) + require.EqualError(t, err, "physical id changed") +} diff --git a/ttl/ttlworker/task_manager.go b/ttl/ttlworker/task_manager.go new file mode 100644 index 0000000000000..f20e5cee4f3f6 --- /dev/null +++ b/ttl/ttlworker/task_manager.go @@ -0,0 +1,485 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "encoding/json" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/multierr" + "go.uber.org/zap" +) + +const setTTLTaskOwnerTemplate = `UPDATE mysql.tidb_ttl_task + SET owner_id = %?, + owner_hb_time = %?, + status = 'running', + status_update_time = %? + WHERE job_id = %? AND scan_id = %?` + +func setTTLTaskOwnerSQL(jobID string, scanID int64, id string, now time.Time) (string, []interface{}) { + return setTTLTaskOwnerTemplate, []interface{}{id, now.Format(timeFormat), now.Format(timeFormat), jobID, scanID} +} + +const setTTLTaskFinishedTemplate = `UPDATE mysql.tidb_ttl_task + SET status = 'finished', + status_update_time = %?, + state = %? + WHERE job_id = %? AND scan_id = %?` + +func setTTLTaskFinishedSQL(jobID string, scanID int64, state *cache.TTLTaskState, now time.Time) (string, []interface{}, error) { + stateStr, err := json.Marshal(state) + if err != nil { + return "", nil, err + } + return setTTLTaskFinishedTemplate, []interface{}{now.Format(timeFormat), string(stateStr), jobID, scanID}, nil +} + +const updateTTLTaskHeartBeatTempalte = `UPDATE mysql.tidb_ttl_task + SET state = %?, + owner_hb_time = %? + WHERE job_id = %? AND scan_id = %?` + +func updateTTLTaskHeartBeatSQL(jobID string, scanID int64, now time.Time, state *cache.TTLTaskState) (string, []interface{}, error) { + stateStr, err := json.Marshal(state) + if err != nil { + return "", nil, err + } + return updateTTLTaskHeartBeatTempalte, []interface{}{string(stateStr), now.Format(timeFormat), jobID, scanID}, nil +} + +// taskManager schedules and manages the ttl tasks on this instance +type taskManager struct { + ctx context.Context + sessPool sessionPool + + id string + + scanWorkers []worker + delWorkers []worker + + infoSchemaCache *cache.InfoSchemaCache + runningTasks []*runningScanTask + + delCh chan *ttlDeleteTask + notifyStateCh chan interface{} +} + +func newTaskManager(ctx context.Context, sessPool sessionPool, infoSchemaCache *cache.InfoSchemaCache, id string) *taskManager { + return &taskManager{ + ctx: logutil.WithKeyValue(ctx, "ttl-worker", "task-manager"), + sessPool: sessPool, + + id: id, + + scanWorkers: []worker{}, + delWorkers: []worker{}, + + infoSchemaCache: infoSchemaCache, + runningTasks: []*runningScanTask{}, + + delCh: make(chan *ttlDeleteTask), + notifyStateCh: make(chan interface{}, 1), + } +} + +func (m *taskManager) resizeWorkersWithSysVar() { + err := m.resizeScanWorkers(int(variable.TTLScanWorkerCount.Load())) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to resize scan workers", zap.Error(err)) + } + err = m.resizeDelWorkers(int(variable.TTLDeleteWorkerCount.Load())) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to resize delete workers", zap.Error(err)) + } +} + +func (m *taskManager) resizeScanWorkers(count int) error { + var err error + var canceledWorkers []worker + m.scanWorkers, canceledWorkers, err = m.resizeWorkers(m.scanWorkers, count, func() worker { + return newScanWorker(m.delCh, m.notifyStateCh, m.sessPool) + }) + for _, w := range canceledWorkers { + s := w.(scanWorker) + + var jobID string + var scanID int64 + var scanErr error + result := s.PollTaskResult() + if result != nil { + jobID = result.task.JobID + scanID = result.task.ScanID + + scanErr = result.err + } else { + // if the scan worker failed to poll the task, it's possible that the `WaitStopped` has timeout + // we still consider the scan task as finished + curTask := s.CurrentTask() + if curTask == nil { + continue + } + jobID = curTask.JobID + scanID = curTask.ScanID + scanErr = errors.New("timeout to cancel scan task") + } + + task := findTaskWithID(m.runningTasks, jobID, scanID) + if task == nil { + logutil.Logger(m.ctx).Warn("task state changed but job not found", zap.String("jobID", jobID), zap.Int64("scanID", scanID)) + continue + } + logutil.Logger(m.ctx).Debug("scan task finished", zap.String("jobID", task.JobID), zap.Int64("taskID", task.ScanID), zap.Error(scanErr)) + + task.result = result + } + return err +} + +func findTaskWithID(tasks []*runningScanTask, jobID string, scanID int64) *runningScanTask { + for _, t := range tasks { + if t.ScanID == scanID && t.JobID == jobID { + return t + } + } + + return nil +} + +func (m *taskManager) resizeDelWorkers(count int) error { + var err error + m.delWorkers, _, err = m.resizeWorkers(m.delWorkers, count, func() worker { + return newDeleteWorker(m.delCh, m.sessPool) + }) + return err +} + +// resizeWorkers scales the worker, and returns the full set of workers as the first return value. If there are workers +// stopped, return the stopped worker in the second return value +func (m *taskManager) resizeWorkers(workers []worker, count int, factory func() worker) ([]worker, []worker, error) { + if count < len(workers) { + logutil.Logger(m.ctx).Info("shrink ttl worker", zap.Int("originalCount", len(workers)), zap.Int("newCount", count)) + + for _, w := range workers[count:] { + w.Stop() + } + + var errs error + // don't use `m.ctx` here, because when shutdown the server, `m.ctx` has already been cancelled + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + for _, w := range workers[count:] { + err := w.WaitStopped(ctx, 30*time.Second) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to stop ttl worker", zap.Error(err)) + errs = multierr.Append(errs, err) + } + } + cancel() + + // remove the existing workers, and keep the left workers + return workers[:count], workers[count:], errs + } + + if count > len(workers) { + logutil.Logger(m.ctx).Info("scale ttl worker", zap.Int("originalCount", len(workers)), zap.Int("newCount", count)) + + for i := len(workers); i < count; i++ { + w := factory() + w.Start() + workers = append(workers, w) + } + return workers, nil, nil + } + + return workers, nil, nil +} + +// handleScanFinishedTask polls the result from scan worker and returns whether there are result polled +func (m *taskManager) handleScanFinishedTask() bool { + results := m.pollScanWorkerResults() + for _, result := range results { + logger := logutil.Logger(m.ctx).With(zap.Int64("tableID", result.task.tbl.ID), zap.String("jobID", result.task.JobID), zap.Int64("scanID", result.task.ScanID)) + if result.err != nil { + logger = logger.With(zap.Error(result.err)) + } + + task := findTaskWithID(m.runningTasks, result.task.JobID, result.task.ScanID) + if task == nil { + logger.Warn("task state changed but task not found") + continue + } + logger.Info("task scans finished") + task.result = result + } + + return len(results) > 0 +} + +func (m *taskManager) pollScanWorkerResults() []*ttlScanTaskExecResult { + results := make([]*ttlScanTaskExecResult, 0, len(m.scanWorkers)) + for _, w := range m.scanWorkers { + worker := w.(scanWorker) + result := worker.PollTaskResult() + if result != nil { + results = append(results, result) + } + } + + return results +} + +func (m *taskManager) idleScanWorkers() []scanWorker { + workers := make([]scanWorker, 0, len(m.scanWorkers)) + for _, w := range m.scanWorkers { + if w.(scanWorker).CouldSchedule() { + workers = append(workers, w.(scanWorker)) + } + } + return workers +} + +func (m *taskManager) rescheduleTasks(se session.Session, now time.Time) { + idleScanWorkers := m.idleScanWorkers() + if len(idleScanWorkers) == 0 { + return + } + + for len(idleScanWorkers) > 0 { + tasks, err := m.peekWaitingScanTasks(se, len(idleScanWorkers), now) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to peek scan task", zap.Error(err)) + return + } + + if len(tasks) == 0 { + break + } + + for _, t := range tasks { + logger := logutil.Logger(m.ctx).With(zap.String("jobID", t.JobID), zap.Int64("scanID", t.ScanID)) + + task, err := m.lockScanTask(se, t, now) + if err != nil { + // If other nodes lock the task, it will return an error. It's expected + // so the log level is only `info` + logutil.Logger(m.ctx).Info("fail to lock scan task", zap.Error(err)) + continue + } + + idleWorker := idleScanWorkers[0] + idleScanWorkers = idleScanWorkers[1:] + + err = idleWorker.Schedule(task.ttlScanTask) + if err != nil { + logger.Warn("fail to schedule task", zap.Error(err)) + continue + } + + logger.Info("scheduled ttl task") + m.runningTasks = append(m.runningTasks, task) + } + } +} + +func (m *taskManager) peekWaitingScanTasks(se session.Session, limit int, now time.Time) ([]*cache.TTLTask, error) { + sql, args := cache.PeekWaitingTTLTask(limit, now.Add(-2*ttlTaskHeartBeatTickerInterval)) + rows, err := se.ExecuteSQL(m.ctx, sql, args...) + if err != nil { + return nil, errors.Wrapf(err, "execute sql: %s", sql) + } + + tasks := make([]*cache.TTLTask, 0, len(rows)) + for _, r := range rows { + task, err := cache.RowToTTLTask(se, r) + if err != nil { + return nil, err + } + tasks = append(tasks, task) + } + + return tasks, nil +} + +func (m *taskManager) lockScanTask(se session.Session, task *cache.TTLTask, now time.Time) (*runningScanTask, error) { + ctx := m.ctx + + table, ok := m.infoSchemaCache.Tables[task.TableID] + if !ok { + return nil, errors.Errorf("didn't find table with id: %d", task.TableID) + } + + err := se.RunInTxn(ctx, func() error { + sql, args := cache.SelectFromTTLTaskWithID(task.JobID, task.ScanID) + rows, err := se.ExecuteSQL(ctx, sql+" FOR UPDATE NOWAIT", args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + if len(rows) == 0 { + return errors.Errorf("didn't find task with jobID: %s, scanID: %d", task.JobID, task.ScanID) + } + task, err = cache.RowToTTLTask(se, rows[0]) + if err != nil { + return err + } + if task.OwnerID != "" && !task.OwnerHBTime.Add(2*jobManagerLoopTickerInterval).Before(now) { + return errors.New("task is already scheduled") + } + + sql, args = setTTLTaskOwnerSQL(task.JobID, task.ScanID, m.id, now) + _, err = se.ExecuteSQL(ctx, sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + + return nil + }, session.TxnModePessimistic) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithCancel(m.ctx) + scanTask := &ttlScanTask{ + ctx: ctx, + + TTLTask: task, + + tbl: table, + statistics: &ttlStatistics{}, + } + return &runningScanTask{ + scanTask, + cancel, + nil, + }, nil +} + +// updateHeartBeat updates the heartbeat for all tasks with current instance as owner +func (m *taskManager) updateHeartBeat(ctx context.Context, se session.Session, now time.Time) error { + for _, task := range m.runningTasks { + state := &cache.TTLTaskState{ + TotalRows: task.statistics.TotalRows.Load(), + SuccessRows: task.statistics.SuccessRows.Load(), + ErrorRows: task.statistics.ErrorRows.Load(), + } + if task.result != nil && task.result.err != nil { + state.ScanTaskErr = task.result.err.Error() + } + + sql, args, err := updateTTLTaskHeartBeatSQL(task.JobID, task.ScanID, now, state) + if err != nil { + return err + } + _, err = se.ExecuteSQL(ctx, sql, args...) + if err != nil { + return errors.Wrapf(err, "execute sql: %s", sql) + } + } + return nil +} + +func (m *taskManager) checkFinishedTask(se session.Session, now time.Time) { + stillRunningTasks := make([]*runningScanTask, 0, len(m.runningTasks)) + for _, task := range m.runningTasks { + if !task.finished() { + stillRunningTasks = append(stillRunningTasks, task) + continue + } + err := m.reportTaskFinished(se, now, task) + if err != nil { + logutil.Logger(m.ctx).Error("fail to report finished task", zap.Error(err)) + stillRunningTasks = append(stillRunningTasks, task) + continue + } + } + + m.runningTasks = stillRunningTasks +} + +func (m *taskManager) reportTaskFinished(se session.Session, now time.Time, task *runningScanTask) error { + state := &cache.TTLTaskState{ + TotalRows: task.statistics.TotalRows.Load(), + SuccessRows: task.statistics.SuccessRows.Load(), + ErrorRows: task.statistics.ErrorRows.Load(), + } + if task.result.err != nil { + state.ScanTaskErr = task.result.err.Error() + } + + sql, args, err := setTTLTaskFinishedSQL(task.JobID, task.ScanID, state, now) + if err != nil { + return err + } + + timeoutCtx, cancel := context.WithTimeout(m.ctx, ttlInternalSQLTimeout) + _, err = se.ExecuteSQL(timeoutCtx, sql, args...) + cancel() + if err != nil { + return err + } + + return nil +} + +// checkInvalidTask removes the task whose owner is not myself or which has disappeared +func (m *taskManager) checkInvalidTask(se session.Session) { + // TODO: optimize this function through cache or something else + ownRunningTask := make([]*runningScanTask, 0, len(m.runningTasks)) + + for _, task := range m.runningTasks { + sql, args := cache.SelectFromTTLTaskWithID(task.JobID, task.ScanID) + + timeoutCtx, cancel := context.WithTimeout(m.ctx, ttlInternalSQLTimeout) + rows, err := se.ExecuteSQL(timeoutCtx, sql, args...) + cancel() + if err != nil { + logutil.Logger(m.ctx).Warn("fail to execute sql", zap.String("sql", sql), zap.Any("args", args), zap.Error(err)) + task.cancel() + continue + } + if len(rows) == 0 { + logutil.Logger(m.ctx).Warn("didn't find task", zap.String("jobID", task.JobID), zap.Int64("scanID", task.ScanID)) + task.cancel() + continue + } + t, err := cache.RowToTTLTask(se, rows[0]) + if err != nil { + logutil.Logger(m.ctx).Warn("fail to get task", zap.Error(err)) + task.cancel() + continue + } + + if t.OwnerID == m.id { + ownRunningTask = append(ownRunningTask, task) + } + } + + m.runningTasks = ownRunningTask +} + +type runningScanTask struct { + *ttlScanTask + cancel func() + result *ttlScanTaskExecResult +} + +func (t *runningScanTask) finished() bool { + return t.result != nil && t.statistics.TotalRows.Load() == t.statistics.ErrorRows.Load()+t.statistics.SuccessRows.Load() +} diff --git a/ttl/ttlworker/task_manager_integration_test.go b/ttl/ttlworker/task_manager_integration_test.go new file mode 100644 index 0000000000000..8b7d0df5257b0 --- /dev/null +++ b/ttl/ttlworker/task_manager_integration_test.go @@ -0,0 +1,187 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker_test + +import ( + "context" + "fmt" + "sync" + "testing" + "time" + + "github.com/pingcap/tidb/infoschema" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/ttlworker" + "github.com/pingcap/tidb/util/logutil" + "github.com/stretchr/testify/require" + "go.uber.org/atomic" + "go.uber.org/zap" +) + +func TestParallelLockNewTask(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnTTL) + tk.MustExec("create table test.t (id int, created_at datetime) TTL= created_at + interval 1 hour") + testTable, err := tk.Session().GetDomainInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + + sessionFactory := sessionFactory(t, store) + se := sessionFactory() + + now := time.Now() + + isc := cache.NewInfoSchemaCache(time.Minute) + require.NoError(t, isc.Update(se)) + m := ttlworker.NewTaskManager(context.Background(), nil, isc, "test-id") + + // insert and lock a new task + sql, args, err := cache.InsertIntoTTLTask(tk.Session(), "test-job", testTable.Meta().ID, 1, nil, nil, now, now) + require.NoError(t, err) + _, err = tk.Session().ExecuteInternal(ctx, sql, args...) + require.NoError(t, err) + _, err = m.LockScanTask(se, &cache.TTLTask{ + ScanID: 1, + JobID: "test-job", + TableID: testTable.Meta().ID, + }, now) + require.NoError(t, err) + tk.MustExec("DELETE FROM mysql.tidb_ttl_task") + + // lock one table in parallel, only one of them should lock successfully + testTimes := 100 + concurrency := 5 + for i := 0; i < testTimes; i++ { + sql, args, err := cache.InsertIntoTTLTask(tk.Session(), "test-job", testTable.Meta().ID, 1, nil, nil, now, now) + require.NoError(t, err) + _, err = tk.Session().ExecuteInternal(ctx, sql, args...) + require.NoError(t, err) + + successCounter := atomic.NewUint64(0) + + now = now.Add(time.Hour * 48) + + wg := sync.WaitGroup{} + for j := 0; j < concurrency; j++ { + scanManagerID := fmt.Sprintf("test-ttl-manager-%d", j) + wg.Add(1) + go func() { + se := sessionFactory() + + isc := cache.NewInfoSchemaCache(time.Minute) + require.NoError(t, isc.Update(se)) + m := ttlworker.NewTaskManager(context.Background(), nil, isc, scanManagerID) + + _, err := m.LockScanTask(se, &cache.TTLTask{ + ScanID: 1, + JobID: "test-job", + TableID: testTable.Meta().ID, + }, now) + if err == nil { + successCounter.Add(1) + } else { + logutil.BgLogger().Error("lock new task with error", zap.Error(err)) + } + wg.Done() + }() + } + wg.Wait() + + require.Equal(t, uint64(1), successCounter.Load()) + tk.MustExec("DELETE FROM mysql.tidb_ttl_task") + } +} + +func TestParallelSchedule(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + waitAndStopTTLManager(t, dom) + tk := testkit.NewTestKit(t, store) + sessionFactory := sessionFactory(t, store) + + tk.MustExec("create table test.t(id int, created_at datetime) ttl=created_at + interval 1 day") + table, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + // 16 tasks and 16 scan workers (in 4 task manager) should be able to be scheduled in a single "reschedule" + for i := 0; i < 16; i++ { + sql := fmt.Sprintf("insert into mysql.tidb_ttl_task(job_id,table_id,scan_id,expire_time,created_time) values ('test-job', %d, %d, NOW(), NOW())", table.Meta().ID, i) + tk.MustExec(sql) + } + isc := cache.NewInfoSchemaCache(time.Second) + require.NoError(t, isc.Update(sessionFactory())) + now := time.Now() + scheduleWg := sync.WaitGroup{} + for i := 0; i < 4; i++ { + workers := []ttlworker.Worker{} + for j := 0; j < 4; j++ { + scanWorker := ttlworker.NewMockScanWorker(t) + scanWorker.Start() + workers = append(workers, scanWorker) + } + + m := ttlworker.NewTaskManager(context.Background(), nil, isc, fmt.Sprintf("task-manager-%d", i)) + m.SetScanWorkers4Test(workers) + scheduleWg.Add(1) + go func() { + se := sessionFactory() + m.RescheduleTasks(se, now) + scheduleWg.Done() + }() + } + scheduleWg.Wait() + // all tasks should have been scheduled + tk.MustQuery("select count(1) from mysql.tidb_ttl_task where status = 'running'").Check(testkit.Rows("16")) + for i := 0; i < 4; i++ { + sql := fmt.Sprintf("select count(1) from mysql.tidb_ttl_task where status = 'running' AND owner_id = 'task-manager-%d'", i) + tk.MustQuery(sql).Check(testkit.Rows("4")) + } +} + +func TestTaskScheduleExpireHeartBeat(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + waitAndStopTTLManager(t, dom) + tk := testkit.NewTestKit(t, store) + sessionFactory := sessionFactory(t, store) + + // create table and scan task + tk.MustExec("create table test.t(id int, created_at datetime) ttl=created_at + interval 1 day") + table, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + sql := fmt.Sprintf("insert into mysql.tidb_ttl_task(job_id,table_id,scan_id,expire_time,created_time) values ('test-job', %d, %d, NOW(), NOW())", table.Meta().ID, 1) + tk.MustExec(sql) + + // update the infoschema cache + isc := cache.NewInfoSchemaCache(time.Second) + require.NoError(t, isc.Update(sessionFactory())) + now := time.Now() + + // schedule in a task manager + scanWorker := ttlworker.NewMockScanWorker(t) + scanWorker.Start() + m := ttlworker.NewTaskManager(context.Background(), nil, isc, "task-manager-1") + m.SetScanWorkers4Test([]ttlworker.Worker{scanWorker}) + m.RescheduleTasks(sessionFactory(), now) + tk.MustQuery("select status,owner_id from mysql.tidb_ttl_task").Check(testkit.Rows("running task-manager-1")) + + // another task manager should fetch this task after heartbeat expire + scanWorker2 := ttlworker.NewMockScanWorker(t) + scanWorker2.Start() + m2 := ttlworker.NewTaskManager(context.Background(), nil, isc, "task-manager-2") + m2.SetScanWorkers4Test([]ttlworker.Worker{scanWorker2}) + m2.RescheduleTasks(sessionFactory(), now.Add(time.Hour)) + tk.MustQuery("select status,owner_id from mysql.tidb_ttl_task").Check(testkit.Rows("running task-manager-2")) +} diff --git a/ttl/ttlworker/task_manager_test.go b/ttl/ttlworker/task_manager_test.go new file mode 100644 index 0000000000000..9241146b719b3 --- /dev/null +++ b/ttl/ttlworker/task_manager_test.go @@ -0,0 +1,118 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "testing" + "time" + + "github.com/pingcap/tidb/ttl/cache" + "github.com/pingcap/tidb/ttl/session" + "github.com/stretchr/testify/assert" +) + +// NewTaskManager is an exported version of newTaskManager for test +var NewTaskManager = newTaskManager + +// Worker is an exported version of worker +type Worker = worker + +func (m *taskManager) SetScanWorkers4Test(workers []worker) { + m.scanWorkers = workers +} + +// LockScanTask is an exported version of lockScanTask +func (m *taskManager) LockScanTask(se session.Session, task *cache.TTLTask, now time.Time) (*runningScanTask, error) { + return m.lockScanTask(se, task, now) +} + +// ResizeWorkersWithSysVar is an exported version of resizeWorkersWithSysVar +func (m *taskManager) ResizeWorkersWithSysVar() { + m.resizeWorkersWithSysVar() +} + +// RescheduleTasks is an exported version of rescheduleTasks +func (m *taskManager) RescheduleTasks(se session.Session, now time.Time) { + m.rescheduleTasks(se, now) +} + +func TestResizeWorkers(t *testing.T) { + tbl := newMockTTLTbl(t, "t1") + + // scale workers + scanWorker1 := NewMockScanWorker(t) + scanWorker1.Start() + scanWorker2 := NewMockScanWorker(t) + + m := newTaskManager(context.Background(), nil, nil, "test-id") + m.sessPool = newMockSessionPool(t, tbl) + m.SetScanWorkers4Test([]worker{ + scanWorker1, + }) + newWorkers, _, err := m.resizeWorkers(m.scanWorkers, 2, func() worker { + return scanWorker2 + }) + assert.NoError(t, err) + assert.Len(t, newWorkers, 2) + scanWorker1.checkWorkerStatus(workerStatusRunning, true, nil) + scanWorker2.checkWorkerStatus(workerStatusRunning, true, nil) + + // shrink scan workers + scanWorker1 = NewMockScanWorker(t) + scanWorker1.Start() + scanWorker2 = NewMockScanWorker(t) + scanWorker2.Start() + + m = newTaskManager(context.Background(), nil, nil, "test-id") + m.sessPool = newMockSessionPool(t, tbl) + m.SetScanWorkers4Test([]worker{ + scanWorker1, + scanWorker2, + }) + + assert.NoError(t, m.resizeScanWorkers(1)) + scanWorker2.checkWorkerStatus(workerStatusStopped, false, nil) + + // shrink scan workers after job is run + scanWorker1 = NewMockScanWorker(t) + scanWorker1.Start() + scanWorker2 = NewMockScanWorker(t) + scanWorker2.Start() + + m = newTaskManager(context.Background(), nil, nil, "test-id") + m.sessPool = newMockSessionPool(t, tbl) + m.SetScanWorkers4Test([]worker{ + scanWorker1, + scanWorker2, + }) + m.runningTasks = append(m.runningTasks, &runningScanTask{ + ttlScanTask: &ttlScanTask{ + tbl: tbl, + TTLTask: &cache.TTLTask{ + JobID: "test-job-id", + ScanID: 1, + }, + }, + }) + + scanWorker2.curTaskResult = &ttlScanTaskExecResult{task: &ttlScanTask{tbl: tbl, TTLTask: &cache.TTLTask{ + JobID: "test-job-id", + ScanID: 1, + }}} + assert.NoError(t, m.resizeScanWorkers(1)) + scanWorker2.checkWorkerStatus(workerStatusStopped, false, nil) + assert.NotNil(t, m.runningTasks[0].result) +} diff --git a/ttl/ttlworker/worker.go b/ttl/ttlworker/worker.go new file mode 100644 index 0000000000000..c89d90cb1d061 --- /dev/null +++ b/ttl/ttlworker/worker.go @@ -0,0 +1,141 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ttlworker + +import ( + "context" + "sync" + "time" + + "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" +) + +type workerStatus int + +const ( + workerStatusCreated workerStatus = iota + workerStatusRunning + workerStatusStopping + workerStatusStopped +) + +type worker interface { + Start() + Stop() + Status() workerStatus + Error() error + Send() chan<- interface{} + WaitStopped(ctx context.Context, timeout time.Duration) error +} + +type baseWorker struct { + sync.Mutex + ctx context.Context + cancel func() + ch chan interface{} + loopFunc func() error + + err error + status workerStatus + wg util.WaitGroupWrapper +} + +func (w *baseWorker) init(loop func() error) { + w.ctx, w.cancel = context.WithCancel(context.Background()) + w.status = workerStatusCreated + w.loopFunc = loop + w.ch = make(chan interface{}) +} + +func (w *baseWorker) Start() { + w.Lock() + defer w.Unlock() + if w.status != workerStatusCreated { + return + } + + w.wg.Run(w.loop) + w.status = workerStatusRunning +} + +func (w *baseWorker) Stop() { + w.Lock() + defer w.Unlock() + switch w.status { + case workerStatusCreated: + w.cancel() + w.toStopped(nil) + case workerStatusRunning: + w.cancel() + w.status = workerStatusStopping + } +} + +func (w *baseWorker) Status() workerStatus { + w.Lock() + defer w.Unlock() + return w.status +} + +func (w *baseWorker) Error() error { + w.Lock() + defer w.Unlock() + return w.err +} + +func (w *baseWorker) WaitStopped(ctx context.Context, timeout time.Duration) error { + // consider the situation when the worker has stopped, but the context has also stopped. We should + // return without error + if w.Status() == workerStatusStopped { + return nil + } + + ctx, cancel := context.WithTimeout(ctx, timeout) + go func() { + w.wg.Wait() + cancel() + }() + + <-ctx.Done() + if w.Status() != workerStatusStopped { + return ctx.Err() + } + return nil +} + +func (w *baseWorker) Send() chan<- interface{} { + return w.ch +} + +func (w *baseWorker) loop() { + var err error + defer func() { + if r := recover(); r != nil { + logutil.BgLogger().Info("ttl worker panic", zap.Any("recover", r), zap.Stack("stack")) + } + w.Lock() + w.toStopped(err) + w.Unlock() + }() + err = w.loopFunc() +} + +func (w *baseWorker) toStopped(err error) { + w.status = workerStatusStopped + w.err = err + close(w.ch) +} diff --git a/types/const_test.go b/types/const_test.go index 3942b6d1c5fd1..3815efde54338 100644 --- a/types/const_test.go +++ b/types/const_test.go @@ -338,8 +338,7 @@ func TestIgnoreSpaceMode(t *testing.T) { tk.MustExec("DROP TABLE BIT_AND;") tk.MustExec("CREATE TABLE `BIT_AND` (a bigint);") tk.MustExec("DROP TABLE BIT_AND;") - _, err = tk.Exec("CREATE TABLE BIT_AND(a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE BIT_AND(a bigint);") tk.MustExec("CREATE TABLE test.BIT_AND(a bigint);") tk.MustExec("DROP TABLE BIT_AND;") @@ -347,36 +346,29 @@ func TestIgnoreSpaceMode(t *testing.T) { tk.MustExec("DROP TABLE NOW;") tk.MustExec("CREATE TABLE `NOW` (a bigint);") tk.MustExec("DROP TABLE NOW;") - _, err = tk.Exec("CREATE TABLE NOW(a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE NOW(a bigint);") tk.MustExec("CREATE TABLE test.NOW(a bigint);") tk.MustExec("DROP TABLE NOW;") tk.MustExec("set sql_mode='IGNORE_SPACE'") - _, err = tk.Exec("CREATE TABLE COUNT (a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE COUNT (a bigint);") tk.MustExec("CREATE TABLE `COUNT` (a bigint);") tk.MustExec("DROP TABLE COUNT;") - _, err = tk.Exec("CREATE TABLE COUNT(a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE COUNT(a bigint);") tk.MustExec("CREATE TABLE test.COUNT(a bigint);") tk.MustExec("DROP TABLE COUNT;") - _, err = tk.Exec("CREATE TABLE BIT_AND (a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE BIT_AND (a bigint);") tk.MustExec("CREATE TABLE `BIT_AND` (a bigint);") tk.MustExec("DROP TABLE BIT_AND;") - _, err = tk.Exec("CREATE TABLE BIT_AND(a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE BIT_AND(a bigint);") tk.MustExec("CREATE TABLE test.BIT_AND(a bigint);") tk.MustExec("DROP TABLE BIT_AND;") - _, err = tk.Exec("CREATE TABLE NOW (a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE NOW (a bigint);") tk.MustExec("CREATE TABLE `NOW` (a bigint);") tk.MustExec("DROP TABLE NOW;") - _, err = tk.Exec("CREATE TABLE NOW(a bigint);") - require.Error(t, err) + tk.MustExecToErr("CREATE TABLE NOW(a bigint);") tk.MustExec("CREATE TABLE test.NOW(a bigint);") tk.MustExec("DROP TABLE NOW;") } diff --git a/types/convert.go b/types/convert.go index 96a12f64ca641..1b97b7336ef66 100644 --- a/types/convert.go +++ b/types/convert.go @@ -758,6 +758,8 @@ func ToString(value interface{}) (string, error) { return v.String(), nil case Set: return v.String(), nil + case BinaryJSON: + return v.String(), nil default: return "", errors.Errorf("cannot convert %v(type %T) to string", value, value) } diff --git a/types/core_time.go b/types/core_time.go index 3a0cd42ed1c3e..aaf3f5711fea9 100644 --- a/types/core_time.go +++ b/types/core_time.go @@ -184,42 +184,6 @@ func (t CoreTime) GoTime(loc *gotime.Location) (gotime.Time, error) { return tm, nil } -// FindZoneTransition check for one Time Zone transition within +/- 4h -// Currently the needed functions are not exported, if gotime.Location.lookup would be exported -// then it would be easy to use that directly -func FindZoneTransition(tIn gotime.Time) (gotime.Time, error) { - // Check most common case first, DST transition on full hour. - // round truncates away from zero! - t2 := tIn.Round(gotime.Hour).Add(-1 * gotime.Hour) - t1 := t2.Add(-1 * gotime.Second) - _, offset1 := t1.Zone() - _, offset2 := t2.Zone() - if offset1 != offset2 { - return t2, nil - } - - // Check if any offset change? - t1 = tIn.Add(-4 * gotime.Hour) - t2 = tIn.Add(4 * gotime.Hour) - _, offset1 = t1.Zone() - _, offset2 = t2.Zone() - if offset1 == offset2 { - return tIn, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, tIn)) - } - - // Check generic case, like for 'Australia/Lord_Howe' - for t2.After(t1.Add(gotime.Second)) { - t := t1.Add(t2.Sub(t1) / 2).Round(gotime.Second) - _, offset := t.Zone() - if offset == offset1 { - t1 = t - } else { - t2 = t - } - } - return t2, nil -} - // AdjustedGoTime converts Time to GoTime and adjust for invalid DST times // like during the DST change with increased offset, // normally moving to Daylight Saving Time. @@ -230,11 +194,18 @@ func (t CoreTime) AdjustedGoTime(loc *gotime.Location) (gotime.Time, error) { return tm, nil } - tAdj, err2 := FindZoneTransition(tm) - if err2 == nil { - return tAdj, nil + // The converted go time did not map back to the same time, probably it was between a + // daylight saving transition, adjust the time to the closest Zone bound. + start, end := tm.ZoneBounds() + // time zone transitions are normally 1 hour, allow up to 4 hours before returning error + if start.Sub(tm).Abs().Hours() > 4.0 && end.Sub(tm).Abs().Hours() > 4.0 { + return tm, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, tm)) + } + // use the closest transition time + if tm.Sub(start).Abs() <= tm.Sub(end).Abs() { + return start, nil } - return tm, err + return end, nil } // IsLeapYear returns if it's leap year. diff --git a/types/core_time_test.go b/types/core_time_test.go index 18d21ddaf8563..999a5504f0899 100644 --- a/types/core_time_test.go +++ b/types/core_time_test.go @@ -293,45 +293,6 @@ func TestWeekday(t *testing.T) { } } -func TestFindZoneTransition(t *testing.T) { - tests := []struct { - TZ string - dt string - Expect string - Success bool - }{ - {"Australia/Lord_Howe", "2020-06-29 03:45:00", "", false}, - {"Australia/Lord_Howe", "2020-10-04 02:15:00", "2020-10-04 02:30:00 +11 +1100", true}, - {"Australia/Lord_Howe", "2020-10-04 02:29:59", "2020-10-04 02:30:00 +11 +1100", true}, - {"Australia/Lord_Howe", "2020-10-04 02:29:59.99", "2020-10-04 02:30:00 +11 +1100", true}, - {"Australia/Lord_Howe", "2020-10-04 02:30:00.0001", "2020-10-04 02:30:00 +11 +1100", true}, - {"Australia/Lord_Howe", "2020-10-04 02:30:00", "2020-10-04 02:30:00 +11 +1100", true}, - {"Australia/Lord_Howe", "2020-10-04 02:30:01", "2020-10-04 02:30:00 +11 +1100", true}, - {"Europe/Vilnius", "2020-03-29 03:45:00", "2020-03-29 04:00:00 EEST +0300", true}, - {"Europe/Vilnius", "2020-10-25 03:45:00", "2020-10-25 03:00:00 EET +0200", true}, - {"Europe/Vilnius", "2020-06-29 03:45:00", "", false}, - {"Europe/Amsterdam", "2020-03-29 02:45:00", "2020-03-29 03:00:00 CEST +0200", true}, - {"Europe/Amsterdam", "2020-10-25 02:35:00", "2020-10-25 02:00:00 CET +0100", true}, - {"Europe/Amsterdam", "2020-03-29 02:59:59", "2020-03-29 03:00:00 CEST +0200", true}, - {"Europe/Amsterdam", "2020-03-29 02:59:59.999999999", "2020-03-29 03:00:00 CEST +0200", true}, - {"Europe/Amsterdam", "2020-03-29 03:00:00.000000001", "2020-03-29 03:00:00 CEST +0200", true}, - } - - for _, tt := range tests { - loc, err := time.LoadLocation(tt.TZ) - require.NoError(t, err) - tm, err := time.ParseInLocation("2006-01-02 15:04:05", tt.dt, loc) - require.NoError(t, err) - tp, err := FindZoneTransition(tm) - if !tt.Success { - require.Error(t, err) - } else { - require.NoError(t, err) - require.Equal(t, tt.Expect, tp.Format("2006-01-02 15:04:05.999999999 MST -0700")) - } - } -} - func TestAdjustedGoTime(t *testing.T) { tests := []struct { TZ string @@ -361,9 +322,9 @@ func TestAdjustedGoTime(t *testing.T) { require.NoError(t, err) tp, err := tt.dt.AdjustedGoTime(loc) if !tt.Success { - require.Error(t, err) + require.Error(t, err, tp.Format("2006-01-02 15:04:05.999999999 MST -0700")) } else { - require.NoError(t, err) + require.NoError(t, err, tp.Format("2006-01-02 15:04:05.999999999 MST -0700")) require.Equal(t, tt.Expect, tp.Format("2006-01-02 15:04:05.999999999 MST -0700")) } } diff --git a/types/datum.go b/types/datum.go index 34639cdf10bdb..231de4dd9a069 100644 --- a/types/datum.go +++ b/types/datum.go @@ -2016,6 +2016,10 @@ func (d *Datum) ToMysqlJSON() (j BinaryJSON, err error) { in = d.GetBinaryLiteral().ToString() case KindNull: in = nil + case KindMysqlTime: + in = d.GetMysqlTime() + case KindMysqlDuration: + in = d.GetMysqlDuration() default: in, err = d.ToString() } diff --git a/types/errors.go b/types/errors.go index 68b12d48d8218..94ac823891aa2 100644 --- a/types/errors.go +++ b/types/errors.go @@ -82,6 +82,8 @@ var ( ErrSyntax = dbterror.ClassTypes.NewStdErr(mysql.ErrParse, mysql.MySQLErrName[mysql.ErrSyntax]) // ErrWrongValue is returned when the input value is in wrong format. ErrWrongValue = dbterror.ClassTypes.NewStdErr(mysql.ErrTruncatedWrongValue, mysql.MySQLErrName[mysql.ErrWrongValue]) + // ErrWrongValue2 is returned when the input value is in wrong format. + ErrWrongValue2 = dbterror.ClassTypes.NewStdErr(mysql.ErrWrongValue, mysql.MySQLErrName[mysql.ErrWrongValue]) // ErrWrongValueForType is returned when the input value is in wrong format for function. ErrWrongValueForType = dbterror.ClassTypes.NewStdErr(mysql.ErrWrongValueForType, mysql.MySQLErrName[mysql.ErrWrongValueForType]) // ErrPartitionStatsMissing is returned when the partition-level stats is missing and the build global-level stats fails. diff --git a/types/etc.go b/types/etc.go index 56309d0c41ac4..6d371138193f8 100644 --- a/types/etc.go +++ b/types/etc.go @@ -90,6 +90,11 @@ func IsTypeNumeric(tp byte) bool { return false } +// IsTypeBit returns a boolean indicating whether the tp is bit type. +func IsTypeBit(ft *FieldType) bool { + return ft.GetType() == mysql.TypeBit +} + // IsTemporalWithDate returns a boolean indicating // whether the tp is time type with date. func IsTemporalWithDate(tp byte) bool { diff --git a/types/explain_format.go b/types/explain_format.go index 2599f7bb046ed..9ef1dd0ccb975 100644 --- a/types/explain_format.go +++ b/types/explain_format.go @@ -33,6 +33,10 @@ var ( ExplainFormatTrueCardCost = "true_card_cost" // ExplainFormatBinary prints the proto for binary plan. ExplainFormatBinary = "binary" + // ExplainFormatTiDBJSON warp the default result in JSON format + ExplainFormatTiDBJSON = "tidb_json" + // ExplainFormatCostTrace prints the cost and cost formula of each operator. + ExplainFormatCostTrace = "cost_trace" // ExplainFormats stores the valid formats for explain statement, used by validator. ExplainFormats = []string{ @@ -45,5 +49,7 @@ var ( ExplainFormatTraditional, ExplainFormatTrueCardCost, ExplainFormatBinary, + ExplainFormatTiDBJSON, + ExplainFormatCostTrace, } ) diff --git a/types/field_type_builder.go b/types/field_type_builder.go index 7c9f3bdc3177d..81554c4585442 100644 --- a/types/field_type_builder.go +++ b/types/field_type_builder.go @@ -114,6 +114,12 @@ func (b *FieldTypeBuilder) SetElems(elems []string) *FieldTypeBuilder { return b } +// SetArray sets array of the ft +func (b *FieldTypeBuilder) SetArray(x bool) *FieldTypeBuilder { + b.ft.SetArray(x) + return b +} + // Build returns the ft func (b *FieldTypeBuilder) Build() FieldType { return b.ft diff --git a/types/json_binary.go b/types/json_binary.go index eb9a818b6a7f5..cacf5b69b025a 100644 --- a/types/json_binary.go +++ b/types/json_binary.go @@ -31,6 +31,8 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/util/hack" + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" "golang.org/x/exp/slices" ) @@ -275,7 +277,8 @@ func (bj BinaryJSON) GetElemCount() int { return int(jsonEndian.Uint32(bj.Value)) } -func (bj BinaryJSON) arrayGetElem(idx int) BinaryJSON { +// ArrayGetElem gets the element of the index `idx`. +func (bj BinaryJSON) ArrayGetElem(idx int) BinaryJSON { return bj.valEntryGet(headerSize + idx*valEntrySize) } @@ -355,7 +358,7 @@ func (bj BinaryJSON) marshalArrayTo(buf []byte) ([]byte, error) { buf = append(buf, ", "...) } var err error - buf, err = bj.arrayGetElem(i).marshalTo(buf) + buf, err = bj.ArrayGetElem(i).marshalTo(buf) if err != nil { return nil, errors.Trace(err) } @@ -557,7 +560,7 @@ func (bj BinaryJSON) HashValue(buf []byte) []byte { elemCount := int(jsonEndian.Uint32(bj.Value)) buf = append(buf, bj.Value[0:dataSizeOff]...) for i := 0; i < elemCount; i++ { - buf = bj.arrayGetElem(i).HashValue(buf) + buf = bj.ArrayGetElem(i).HashValue(buf) } case JSONTypeCodeObject: // this hash value is bidirectional, because you can get the key using the json @@ -577,6 +580,26 @@ func (bj BinaryJSON) HashValue(buf []byte) []byte { return buf } +// GetValue return the primitive value of the JSON. +func (bj BinaryJSON) GetValue() any { + switch bj.TypeCode { + case JSONTypeCodeInt64: + return bj.GetInt64() + case JSONTypeCodeUint64: + return bj.GetUint64() + case JSONTypeCodeDuration: + return bj.GetDuration() + case JSONTypeCodeFloat64: + return bj.GetFloat64() + case JSONTypeCodeString: + return bj.GetString() + case JSONTypeCodeDate, JSONTypeCodeDatetime: + return bj.GetTime() + } + logutil.BgLogger().Error("unreachable JSON type", zap.Any("type", bj.TypeCode)) + return nil +} + // CreateBinaryJSON creates a BinaryJSON from interface. func CreateBinaryJSON(in interface{}) BinaryJSON { bj, err := CreateBinaryJSONWithCheck(in) diff --git a/types/json_binary_functions.go b/types/json_binary_functions.go index 71e6e1854ff56..7c4d7bf7f97bc 100644 --- a/types/json_binary_functions.go +++ b/types/json_binary_functions.go @@ -244,7 +244,7 @@ func (bj BinaryJSON) Extract(pathExprList []JSONPathExpression) (ret BinaryJSON, found = true ret = buf[0] // Fix https://github.com/pingcap/tidb/issues/30352 - if pathExprList[0].ContainsAnyAsterisk() { + if pathExprList[0].CouldMatchMultipleValues() { ret = buildBinaryJSONArray(buf) } } else { @@ -270,20 +270,32 @@ func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr JSONPathExpression, du return append(buf, bj) } currentLeg, subPathExpr := pathExpr.popOneLeg() - if currentLeg.typ == jsonPathLegIndex { + if currentLeg.typ == jsonPathLegArraySelection { if bj.TypeCode != JSONTypeCodeArray { - if currentLeg.arrayIndex <= 0 && currentLeg.arrayIndex != arrayIndexAsterisk { - buf = bj.extractTo(buf, subPathExpr, dup, one) + // If the current object is not an array, still append them if the selection includes + // 0. But for asterisk, it still returns NULL. + // + // don't call `getIndexRange` or `getIndexFromStart`, they will panic if the argument + // is not array. + switch selection := currentLeg.arraySelection.(type) { + case jsonPathArraySelectionIndex: + if selection.index == 0 { + buf = bj.extractTo(buf, subPathExpr, dup, one) + } + case jsonPathArraySelectionRange: + // for [0 to Non-negative Number] and [0 to last], it extracts itself + if selection.start == 0 && selection.end >= -1 { + buf = bj.extractTo(buf, subPathExpr, dup, one) + } } return buf } - elemCount := bj.GetElemCount() - if currentLeg.arrayIndex == arrayIndexAsterisk { - for i := 0; i < elemCount && !jsonFinished(buf, one); i++ { - buf = bj.arrayGetElem(i).extractTo(buf, subPathExpr, dup, one) + + start, end := currentLeg.arraySelection.getIndexRange(bj) + if start >= 0 && start <= end { + for i := start; i <= end; i++ { + buf = bj.ArrayGetElem(i).extractTo(buf, subPathExpr, dup, one) } - } else if currentLeg.arrayIndex < elemCount { - buf = bj.arrayGetElem(currentLeg.arrayIndex).extractTo(buf, subPathExpr, dup, one) } } else if currentLeg.typ == jsonPathLegKey && bj.TypeCode == JSONTypeCodeObject { elemCount := bj.GetElemCount() @@ -302,7 +314,7 @@ func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr JSONPathExpression, du if bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() for i := 0; i < elemCount && !jsonFinished(buf, one); i++ { - buf = bj.arrayGetElem(i).extractTo(buf, pathExpr, dup, one) + buf = bj.ArrayGetElem(i).extractTo(buf, pathExpr, dup, one) } } else if bj.TypeCode == JSONTypeCodeObject { elemCount := bj.GetElemCount() @@ -389,7 +401,7 @@ func (bj BinaryJSON) Modify(pathExprList []JSONPathExpression, values []BinaryJS return retj, errors.New("Incorrect parameter count") } for _, pathExpr := range pathExprList { - if pathExpr.flags.containsAnyAsterisk() { + if pathExpr.flags.containsAnyAsterisk() || pathExpr.flags.containsAnyRange() { // TODO: should return 3149(42000) return retj, errors.New("Invalid path expression") } @@ -424,7 +436,7 @@ func (bj BinaryJSON) ArrayInsert(pathExpr JSONPathExpression, value BinaryJSON) return bj, ErrInvalidJSONPathArrayCell } parentPath, lastLeg := pathExpr.popOneLastLeg() - if lastLeg.typ != jsonPathLegIndex { + if lastLeg.typ != jsonPathLegArraySelection { return bj, ErrInvalidJSONPathArrayCell } // Find the target array @@ -433,7 +445,13 @@ func (bj BinaryJSON) ArrayInsert(pathExpr JSONPathExpression, value BinaryJSON) return bj, nil } - idx := lastLeg.arrayIndex + idx := 0 + switch selection := lastLeg.arraySelection.(type) { + case jsonPathArraySelectionIndex: + idx = selection.index.getIndexFromStart(obj) + default: + return bj, ErrInvalidJSONPathArrayCell + } count := obj.GetElemCount() if idx >= count { idx = count @@ -441,12 +459,12 @@ func (bj BinaryJSON) ArrayInsert(pathExpr JSONPathExpression, value BinaryJSON) // Insert into the array newArray := make([]BinaryJSON, 0, count+1) for i := 0; i < idx; i++ { - elem := obj.arrayGetElem(i) + elem := obj.ArrayGetElem(i) newArray = append(newArray, elem) } newArray = append(newArray, value) for i := idx; i < count; i++ { - elem := obj.arrayGetElem(i) + elem := obj.ArrayGetElem(i) newArray = append(newArray, elem) } obj = buildBinaryJSONArray(newArray) @@ -465,7 +483,7 @@ func (bj BinaryJSON) Remove(pathExprList []JSONPathExpression) (BinaryJSON, erro // TODO: should return 3153(42000) return bj, errors.New("Invalid path expression") } - if pathExpr.flags.containsAnyAsterisk() { + if pathExpr.flags.containsAnyAsterisk() || pathExpr.flags.containsAnyRange() { // TODO: should return 3149(42000) return bj, errors.New("Invalid path expression") } @@ -529,7 +547,7 @@ func (bm *binaryModifier) doInsert(path JSONPathExpression, newBj BinaryJSON) { return } parentBj := result[0] - if lastLeg.typ == jsonPathLegIndex { + if lastLeg.typ == jsonPathLegArraySelection { bm.modifyPtr = &parentBj.Value[0] if parentBj.TypeCode != JSONTypeCodeArray { bm.modifyValue = buildBinaryJSONArray([]BinaryJSON{parentBj, newBj}) @@ -538,7 +556,7 @@ func (bm *binaryModifier) doInsert(path JSONPathExpression, newBj BinaryJSON) { elemCount := parentBj.GetElemCount() elems := make([]BinaryJSON, 0, elemCount+1) for i := 0; i < elemCount; i++ { - elems = append(elems, parentBj.arrayGetElem(i)) + elems = append(elems, parentBj.ArrayGetElem(i)) } elems = append(elems, newBj) bm.modifyValue = buildBinaryJSONArray(elems) @@ -589,16 +607,22 @@ func (bm *binaryModifier) doRemove(path JSONPathExpression) { return } parentBj := result[0] - if lastLeg.typ == jsonPathLegIndex { + if lastLeg.typ == jsonPathLegArraySelection { if parentBj.TypeCode != JSONTypeCodeArray { return } + selectionIndex, ok := lastLeg.arraySelection.(jsonPathArraySelectionIndex) + if !ok { + return + } + idx := selectionIndex.index.getIndexFromStart(parentBj) + bm.modifyPtr = &parentBj.Value[0] elemCount := parentBj.GetElemCount() elems := make([]BinaryJSON, 0, elemCount-1) for i := 0; i < elemCount; i++ { - if i != lastLeg.arrayIndex { - elems = append(elems, parentBj.arrayGetElem(i)) + if i != idx { + elems = append(elems, parentBj.ArrayGetElem(i)) } } bm.modifyValue = buildBinaryJSONArray(elems) @@ -785,8 +809,8 @@ func CompareBinaryJSON(left, right BinaryJSON) int { leftCount := left.GetElemCount() rightCount := right.GetElemCount() for i := 0; i < leftCount && i < rightCount; i++ { - elem1 := left.arrayGetElem(i) - elem2 := right.arrayGetElem(i) + elem1 := left.ArrayGetElem(i) + elem2 := right.ArrayGetElem(i) cmp = CompareBinaryJSON(elem1, elem2) if cmp != 0 { return cmp @@ -969,7 +993,7 @@ func mergeBinaryArray(elems []BinaryJSON) BinaryJSON { } else { childCount := elem.GetElemCount() for j := 0; j < childCount; j++ { - buf = append(buf, elem.arrayGetElem(j)) + buf = append(buf, elem.ArrayGetElem(j)) } } } @@ -1064,7 +1088,7 @@ func ContainsBinaryJSON(obj, target BinaryJSON) bool { if target.TypeCode == JSONTypeCodeArray { elemCount := target.GetElemCount() for i := 0; i < elemCount; i++ { - if !ContainsBinaryJSON(obj, target.arrayGetElem(i)) { + if !ContainsBinaryJSON(obj, target.ArrayGetElem(i)) { return false } } @@ -1072,7 +1096,49 @@ func ContainsBinaryJSON(obj, target BinaryJSON) bool { } elemCount := obj.GetElemCount() for i := 0; i < elemCount; i++ { - if ContainsBinaryJSON(obj.arrayGetElem(i), target) { + if ContainsBinaryJSON(obj.ArrayGetElem(i), target) { + return true + } + } + return false + default: + return CompareBinaryJSON(obj, target) == 0 + } +} + +// OverlapsBinaryJSON is similar with ContainsBinaryJSON, but it checks the `OR` relationship. +func OverlapsBinaryJSON(obj, target BinaryJSON) bool { + if obj.TypeCode != JSONTypeCodeArray && target.TypeCode == JSONTypeCodeArray { + obj, target = target, obj + } + switch obj.TypeCode { + case JSONTypeCodeObject: + if target.TypeCode == JSONTypeCodeObject { + elemCount := target.GetElemCount() + for i := 0; i < elemCount; i++ { + key := target.objectGetKey(i) + val := target.objectGetVal(i) + if exp, exists := obj.objectSearchKey(key); exists && CompareBinaryJSON(exp, val) == 0 { + return true + } + } + } + return false + case JSONTypeCodeArray: + if target.TypeCode == JSONTypeCodeArray { + for i := 0; i < obj.GetElemCount(); i++ { + o := obj.ArrayGetElem(i) + for j := 0; j < target.GetElemCount(); j++ { + if CompareBinaryJSON(o, target.ArrayGetElem(j)) == 0 { + return true + } + } + } + return false + } + elemCount := obj.GetElemCount() + for i := 0; i < elemCount; i++ { + if CompareBinaryJSON(obj.ArrayGetElem(i), target) == 0 { return true } } @@ -1109,7 +1175,7 @@ func (bj BinaryJSON) GetElemDepth() int { elemCount := bj.GetElemCount() maxDepth := 0 for i := 0; i < elemCount; i++ { - obj := bj.arrayGetElem(i) + obj := bj.ArrayGetElem(i) depth := obj.GetElemDepth() if depth > maxDepth { maxDepth = depth @@ -1175,23 +1241,42 @@ func (bj BinaryJSON) extractToCallback(pathExpr JSONPathExpression, callbackFn e } currentLeg, subPathExpr := pathExpr.popOneLeg() - if currentLeg.typ == jsonPathLegIndex && bj.TypeCode == JSONTypeCodeArray { + if currentLeg.typ == jsonPathLegArraySelection && bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() - if currentLeg.arrayIndex == arrayIndexAsterisk { + switch selection := currentLeg.arraySelection.(type) { + case jsonPathArraySelectionAsterisk: for i := 0; i < elemCount; i++ { - // buf = bj.arrayGetElem(i).extractTo(buf, subPathExpr) - path := fullpath.pushBackOneIndexLeg(i) - stop, err = bj.arrayGetElem(i).extractToCallback(subPathExpr, callbackFn, path) + // buf = bj.ArrayGetElem(i).extractTo(buf, subPathExpr) + path := fullpath.pushBackOneArraySelectionLeg(jsonPathArraySelectionIndex{jsonPathArrayIndexFromStart(i)}) + stop, err = bj.ArrayGetElem(i).extractToCallback(subPathExpr, callbackFn, path) if stop || err != nil { return } } - } else if currentLeg.arrayIndex < elemCount { - // buf = bj.arrayGetElem(currentLeg.arrayIndex).extractTo(buf, subPathExpr) - path := fullpath.pushBackOneIndexLeg(currentLeg.arrayIndex) - stop, err = bj.arrayGetElem(currentLeg.arrayIndex).extractToCallback(subPathExpr, callbackFn, path) - if stop || err != nil { - return + case jsonPathArraySelectionIndex: + idx := selection.index.getIndexFromStart(bj) + if idx < elemCount && idx >= 0 { + // buf = bj.ArrayGetElem(currentLeg.arraySelection).extractTo(buf, subPathExpr) + path := fullpath.pushBackOneArraySelectionLeg(currentLeg.arraySelection) + stop, err = bj.ArrayGetElem(idx).extractToCallback(subPathExpr, callbackFn, path) + if stop || err != nil { + return + } + } + case jsonPathArraySelectionRange: + start := selection.start.getIndexFromStart(bj) + end := selection.end.getIndexFromStart(bj) + if end >= elemCount { + end = elemCount - 1 + } + if start <= end && start >= 0 { + for i := start; i <= end; i++ { + path := fullpath.pushBackOneArraySelectionLeg(jsonPathArraySelectionIndex{jsonPathArrayIndexFromStart(i)}) + stop, err = bj.ArrayGetElem(i).extractToCallback(subPathExpr, callbackFn, path) + if stop || err != nil { + return + } + } } } } else if currentLeg.typ == jsonPathLegKey && bj.TypeCode == JSONTypeCodeObject { @@ -1226,9 +1311,9 @@ func (bj BinaryJSON) extractToCallback(pathExpr JSONPathExpression, callbackFn e if bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() for i := 0; i < elemCount; i++ { - // buf = bj.arrayGetElem(i).extractTo(buf, pathExpr) - path := fullpath.pushBackOneIndexLeg(i) - stop, err = bj.arrayGetElem(i).extractToCallback(pathExpr, callbackFn, path) + // buf = bj.ArrayGetElem(i).extractTo(buf, pathExpr) + path := fullpath.pushBackOneArraySelectionLeg(jsonPathArraySelectionIndex{jsonPathArrayIndexFromStart(i)}) + stop, err = bj.ArrayGetElem(i).extractToCallback(pathExpr, callbackFn, path) if stop || err != nil { return } @@ -1271,8 +1356,8 @@ func (bj BinaryJSON) Walk(walkFn BinaryJSONWalkFunc, pathExprList ...JSONPathExp if bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() for i := 0; i < elemCount; i++ { - path := fullpath.pushBackOneIndexLeg(i) - stop, err = doWalk(path, bj.arrayGetElem(i)) + path := fullpath.pushBackOneArraySelectionLeg(jsonPathArraySelectionIndex{jsonPathArrayIndexFromStart(i)}) + stop, err = doWalk(path, bj.ArrayGetElem(i)) if stop || err != nil { return } diff --git a/types/json_binary_test.go b/types/json_binary_test.go index c5de6dffcbf5e..fdee480e396dc 100644 --- a/types/json_binary_test.go +++ b/types/json_binary_test.go @@ -50,6 +50,8 @@ func TestBinaryJSONExtract(t *testing.T) { bj8 := mustParseBinaryFromString(t, `{ "a": { "b" : [ 1, 2, 3 ] } }`) bj9 := mustParseBinaryFromString(t, `[[0,1],[2,3],[4,[5,6]]]`) bj10 := mustParseBinaryFromString(t, `[1]`) + bj11 := mustParseBinaryFromString(t, `{"metadata": {"comment": "1234"}}`) + bj12 := mustParseBinaryFromString(t, `{"metadata": {"age": 19, "name": "Tom"}}`) var tests = []struct { bj BinaryJSON @@ -74,6 +76,16 @@ func TestBinaryJSONExtract(t *testing.T) { {bj4, []string{`$.properties.$type$type.$a$a`}, mustParseBinaryFromString(t, `"TiDB"`), true, nil}, {bj5, []string{`$.properties.$type.$a.$b`}, mustParseBinaryFromString(t, `"TiDB"`), true, nil}, {bj5, []string{`$.properties.$type.$a.*[0]`}, mustParseBinaryFromString(t, `["TiDB"]`), true, nil}, + {bj11, []string{"$.metadata.comment"}, mustParseBinaryFromString(t, `"1234"`), true, nil}, + {bj9, []string{"$[0]"}, mustParseBinaryFromString(t, `[0, 1] `), true, nil}, + {bj9, []string{"$[last][last]"}, mustParseBinaryFromString(t, `[5,6]`), true, nil}, + {bj9, []string{"$[last-1][last]"}, mustParseBinaryFromString(t, `3`), true, nil}, + {bj9, []string{"$[last-1][last-1]"}, mustParseBinaryFromString(t, `2`), true, nil}, + {bj9, []string{"$[1 to 2]"}, mustParseBinaryFromString(t, `[[2,3],[4,[5,6]]]`), true, nil}, + {bj9, []string{"$[1 to 2][1 to 2]"}, mustParseBinaryFromString(t, `[3,[5,6]]`), true, nil}, + {bj9, []string{"$[1 to last][1 to last]"}, mustParseBinaryFromString(t, `[3,[5,6]]`), true, nil}, + {bj9, []string{"$[1 to last][1 to last - 1]"}, bj9, false, nil}, + {bj9, []string{"$[1 to last][0 to last - 1]"}, mustParseBinaryFromString(t, `[2,4]`), true, nil}, // test extract with multi path expressions. {bj1, []string{"$.a", "$[5]"}, mustParseBinaryFromString(t, `[[1, "2", {"aa": "bb"}, 4.0, {"aa": "cc"}]]`), true, nil}, @@ -84,6 +96,7 @@ func TestBinaryJSONExtract(t *testing.T) { {bj8, []string{"$**[0]"}, mustParseBinaryFromString(t, `[{"a": {"b": [1, 2, 3]}}, {"b": [1, 2, 3]}, 1, 2, 3]`), true, nil}, {bj9, []string{"$**[0]"}, mustParseBinaryFromString(t, `[[0, 1], 0, 1, 2, 3, 4, 5, 6] `), true, nil}, {bj10, []string{"$**[0]"}, mustParseBinaryFromString(t, `[1]`), true, nil}, + {bj12, []string{"$.metadata.age", "$.metadata.name"}, mustParseBinaryFromString(t, `[19, "Tom"]`), true, nil}, } for _, test := range tests { @@ -95,7 +108,7 @@ func TestBinaryJSONExtract(t *testing.T) { } result, found := test.bj.Extract(pathExprList) - require.Equal(t, test.found, found) + require.Equal(t, test.found, found, test.bj.String()) if found { require.Equal(t, test.expected.String(), result.String()) } @@ -192,6 +205,16 @@ func TestBinaryJSONModify(t *testing.T) { {`{"a": [3]}`, "$[1]", `4`, `[{"a": [3]}, 4]`, true, JSONModifySet}, {`{"b": true}`, "$.b", `false`, `{"b": false}`, true, JSONModifySet}, + // These tests illustrate the differences among the three JSONModifyType + {`{"foo": "bar"}`, "$.foo", `"moo"`, `{"foo": "bar"}`, true, JSONModifyInsert}, + {`{"foo": "bar"}`, "$.foo", `"moo"`, `{"foo": "moo"}`, true, JSONModifyReplace}, + {`{"foo": "bar"}`, "$.foo", `"moo"`, `{"foo": "moo"}`, true, JSONModifySet}, + {`{"foo": "bar"}`, "$.foo", `null`, `{"foo": null}`, true, JSONModifySet}, + {`{"foo": "bar"}`, "$.baz", `"moo"`, `{"foo": "bar", "baz": "moo"}`, true, JSONModifyInsert}, + {`{"foo": "bar"}`, "$.baz", `"moo"`, `{"foo": "bar"}`, true, JSONModifyReplace}, + {`{"foo": "bar"}`, "$.baz", `"moo"`, `{"foo": "bar", "baz": "moo"}`, true, JSONModifySet}, + {`{"foo": "bar"}`, "$.baz", `null`, `{"foo": "bar", "baz": null}`, true, JSONModifySet}, + // nothing changed because the path is empty and we want to insert. {`{}`, "$", `1`, `{}`, true, JSONModifyInsert}, // nothing changed because the path without last leg doesn't exist. @@ -342,6 +365,9 @@ func TestBinaryJSONMerge(t *testing.T) { {[]string{`4`, `{"a": 1}`}, `[4, {"a": 1}]`}, {[]string{`4`, `1`}, `[4, 1]`}, {[]string{`{}`, `[]`}, `[{}]`}, + {[]string{`{"comment": "1234"}`, `{"age": 19, "name": "Tom"}`}, `{"age": 19, "comment": "1234", "name": "Tom"}`}, + {[]string{`{"metadata": {"comment": "1234"}}`, `{"metadata": {"age": 19, "name": "Tom"}}`}, `{"metadata": {"age": 19, "comment": "1234", "name": "Tom"}}`}, + {[]string{`{"comment": "1234"}`, `{"comment": "abc"}`}, `{"comment": ["1234", "abc"]}`}, } for _, test := range tests { @@ -351,7 +377,7 @@ func TestBinaryJSONMerge(t *testing.T) { } result := MergeBinaryJSON(suffixes) cmp := CompareBinaryJSON(result, mustParseBinaryFromString(t, test.expected)) - require.Equal(t, 0, cmp) + require.Equal(t, 0, cmp, result.String()) } } @@ -418,6 +444,11 @@ func TestGetKeys(t *testing.T) { require.Equal(t, "[]", parsedBJ.GetKeys().String()) parsedBJ = mustParseBinaryFromString(t, "{}") require.Equal(t, "[]", parsedBJ.GetKeys().String()) + parsedBJ = mustParseBinaryFromString(t, "{\"comment\": \"1234\"}") + require.Equal(t, "[\"comment\"]", parsedBJ.GetKeys().String()) + parsedBJ = mustParseBinaryFromString(t, "{\"name\": \"Tom\", \"age\": 19}") + require.Equal(t, "[\"age\", \"name\"]", parsedBJ.GetKeys().String()) + require.Equal(t, 2, parsedBJ.GetKeys().GetElemCount()) b := strings.Builder{} b.WriteString("{\"") diff --git a/types/json_constants.go b/types/json_constants.go index 56ff6df1cd9f7..d7486d4025201 100644 --- a/types/json_constants.go +++ b/types/json_constants.go @@ -208,8 +208,10 @@ type JSONModifyType byte const ( // JSONModifyInsert is for insert a new element into a JSON. + // If an old elemList exists, it would NOT replace it. JSONModifyInsert JSONModifyType = 0x01 // JSONModifyReplace is for replace an old elemList from a JSON. + // If no elemList exists, it would NOT insert it. JSONModifyReplace JSONModifyType = 0x02 // JSONModifySet = JSONModifyInsert | JSONModifyReplace JSONModifySet JSONModifyType = 0x03 @@ -224,8 +226,8 @@ var ( ErrInvalidJSONCharset = dbterror.ClassJSON.NewStd(mysql.ErrInvalidJSONCharset) // ErrInvalidJSONData means invalid JSON data. ErrInvalidJSONData = dbterror.ClassJSON.NewStd(mysql.ErrInvalidJSONData) - // ErrInvalidJSONPathWildcard means invalid JSON path that contain wildcard characters. - ErrInvalidJSONPathWildcard = dbterror.ClassJSON.NewStd(mysql.ErrInvalidJSONPathWildcard) + // ErrInvalidJSONPathMultipleSelection means invalid JSON path that contain wildcard characters or range selection. + ErrInvalidJSONPathMultipleSelection = dbterror.ClassJSON.NewStd(mysql.ErrInvalidJSONPathMultipleSelection) // ErrInvalidJSONContainsPathType means invalid JSON contains path type. ErrInvalidJSONContainsPathType = dbterror.ClassJSON.NewStd(mysql.ErrInvalidJSONContainsPathType) // ErrJSONDocumentNULLKey means that json's key is null diff --git a/types/json_path_expr.go b/types/json_path_expr.go index 9c66b3254114c..e784155518da9 100644 --- a/types/json_path_expr.go +++ b/types/json_path_expr.go @@ -50,34 +50,113 @@ import ( select json_extract('{"a": "b", "c": [1, "2"]}', '$.*') -> ["b", [1, "2"]] */ +// if index is positive, it represents the [index] +// if index is negative, it represents the [len() + index] +// a normal index "5" will be parsed into "5", and the "last - 5" will be "-6" +type jsonPathArrayIndex int + +func (index jsonPathArrayIndex) getIndexFromStart(obj BinaryJSON) int { + if index < 0 { + return obj.GetElemCount() + int(index) + } + + return int(index) +} + +// validateIndexRange returns whether `a` could be less or equal than `b` +// if two indexes are all non-negative, or all negative, the comparison follows the number order +// if the sign of them differs, this function will still return true +func validateIndexRange(a jsonPathArrayIndex, b jsonPathArrayIndex) bool { + if (a >= 0 && b >= 0) || (a < 0 && b < 0) { + return a <= b + } + + return true +} + +func jsonPathArrayIndexFromStart(index int) jsonPathArrayIndex { + return jsonPathArrayIndex(index) +} + +func jsonPathArrayIndexFromLast(index int) jsonPathArrayIndex { + return jsonPathArrayIndex(-1 - index) +} + +type jsonPathArraySelection interface { + // returns the closed interval of the range it represents + // it ensures the `end` is less or equal than element count - 1 + // the caller should validate the return value through checking start <= end + getIndexRange(bj BinaryJSON) (int, int) +} + +var _ jsonPathArraySelection = jsonPathArraySelectionAsterisk{} +var _ jsonPathArraySelection = jsonPathArraySelectionIndex{} +var _ jsonPathArraySelection = jsonPathArraySelectionRange{} + +type jsonPathArraySelectionAsterisk struct{} + +func (jsonPathArraySelectionAsterisk) getIndexRange(bj BinaryJSON) (int, int) { + return 0, bj.GetElemCount() - 1 +} + +type jsonPathArraySelectionIndex struct { + index jsonPathArrayIndex +} + +func (i jsonPathArraySelectionIndex) getIndexRange(bj BinaryJSON) (int, int) { + end := i.index.getIndexFromStart(bj) + + // returns index, min(index, count - 1) + // so that the caller could only check the start <= end + elemCount := bj.GetElemCount() + if end >= elemCount { + end = elemCount - 1 + } + return i.index.getIndexFromStart(bj), end +} + +// jsonPathArraySelectionRange represents a closed interval +type jsonPathArraySelectionRange struct { + start jsonPathArrayIndex + end jsonPathArrayIndex +} + +func (i jsonPathArraySelectionRange) getIndexRange(bj BinaryJSON) (int, int) { + start := i.start.getIndexFromStart(bj) + end := i.end.getIndexFromStart(bj) + + elemCount := bj.GetElemCount() + if end >= elemCount { + end = elemCount - 1 + } + return start, end +} + type jsonPathLegType byte const ( // jsonPathLegKey indicates the path leg with '.key'. jsonPathLegKey jsonPathLegType = 0x01 - // jsonPathLegIndex indicates the path leg with form '[number]'. - jsonPathLegIndex jsonPathLegType = 0x02 + // jsonPathLegArraySelection indicates the path leg with form '[index]', '[index to index]'. + jsonPathLegArraySelection jsonPathLegType = 0x02 // jsonPathLegDoubleAsterisk indicates the path leg with form '**'. jsonPathLegDoubleAsterisk jsonPathLegType = 0x03 ) // jsonPathLeg is only used by JSONPathExpression. type jsonPathLeg struct { - typ jsonPathLegType - arrayIndex int // if typ is jsonPathLegIndex, the value should be parsed into here. - dotKey string // if typ is jsonPathLegKey, the key should be parsed into here. + typ jsonPathLegType + arraySelection jsonPathArraySelection // if typ is jsonPathLegArraySelection, the value should be parsed into here. + dotKey string // if typ is jsonPathLegKey, the key should be parsed into here. } -// arrayIndexAsterisk is for parsing `*` into a number. -// we need this number represent "all". -const arrayIndexAsterisk = -1 - // jsonPathExpressionFlag holds attributes of JSONPathExpression type jsonPathExpressionFlag byte const ( jsonPathExpressionContainsAsterisk jsonPathExpressionFlag = 0x01 jsonPathExpressionContainsDoubleAsterisk jsonPathExpressionFlag = 0x02 + jsonPathExpressionContainsRange jsonPathExpressionFlag = 0x04 ) // containsAnyAsterisk returns true if pef contains any asterisk. @@ -86,6 +165,12 @@ func (pef jsonPathExpressionFlag) containsAnyAsterisk() bool { return byte(pef) != 0 } +// containsAnyRange returns true if pef contains any range. +func (pef jsonPathExpressionFlag) containsAnyRange() bool { + pef &= jsonPathExpressionContainsRange + return byte(pef) != 0 +} + // JSONPathExpression is for JSON path expression. type JSONPathExpression struct { legs []jsonPathLeg @@ -119,8 +204,13 @@ func (pe JSONPathExpression) popOneLeg() (jsonPathLeg, JSONPathExpression) { flags: 0, } for _, leg := range newPe.legs { - if leg.typ == jsonPathLegIndex && leg.arrayIndex == -1 { - newPe.flags |= jsonPathExpressionContainsAsterisk + if leg.typ == jsonPathLegArraySelection { + switch leg.arraySelection.(type) { + case jsonPathArraySelectionAsterisk: + newPe.flags |= jsonPathExpressionContainsAsterisk + case jsonPathArraySelectionRange: + newPe.flags |= jsonPathExpressionContainsRange + } } else if leg.typ == jsonPathLegKey && leg.dotKey == "*" { newPe.flags |= jsonPathExpressionContainsAsterisk } else if leg.typ == jsonPathLegDoubleAsterisk { @@ -138,14 +228,17 @@ func (pe JSONPathExpression) popOneLastLeg() (JSONPathExpression, jsonPathLeg) { return JSONPathExpression{legs: pe.legs[:lastLegIdx]}, lastLeg } -// pushBackOneIndexLeg pushback one leg of INDEX type -func (pe JSONPathExpression) pushBackOneIndexLeg(index int) JSONPathExpression { +// pushBackOneArraySelectionLeg pushback one leg of INDEX type +func (pe JSONPathExpression) pushBackOneArraySelectionLeg(arraySelection jsonPathArraySelection) JSONPathExpression { newPe := JSONPathExpression{ - legs: append(pe.legs, jsonPathLeg{typ: jsonPathLegIndex, arrayIndex: index}), + legs: append(pe.legs, jsonPathLeg{typ: jsonPathLegArraySelection, arraySelection: arraySelection}), flags: pe.flags, } - if index == -1 { + switch arraySelection.(type) { + case jsonPathArraySelectionAsterisk: newPe.flags |= jsonPathExpressionContainsAsterisk + case jsonPathArraySelectionRange: + newPe.flags |= jsonPathExpressionContainsRange } return newPe } @@ -162,9 +255,9 @@ func (pe JSONPathExpression) pushBackOneKeyLeg(key string) JSONPathExpression { return newPe } -// ContainsAnyAsterisk returns true if pe contains any asterisk. -func (pe JSONPathExpression) ContainsAnyAsterisk() bool { - return pe.flags.containsAnyAsterisk() +// CouldMatchMultipleValues returns true if pe contains any asterisk or range selection. +func (pe JSONPathExpression) CouldMatchMultipleValues() bool { + return pe.flags.containsAnyAsterisk() || pe.flags.containsAnyRange() } type jsonPathStream struct { @@ -261,6 +354,85 @@ func parseJSONPathWildcard(s *jsonPathStream, p *JSONPathExpression) bool { return true } +func (s *jsonPathStream) tryReadString(expected string) bool { + recordPos := s.pos + + i := 0 + str, meetEnd := s.readWhile(func(b byte) bool { + i += 1 + return i <= len(expected) + }) + + if meetEnd || str != expected { + s.pos = recordPos + return false + } + return true +} + +func (s *jsonPathStream) tryReadIndexNumber() (int, bool) { + recordPos := s.pos + + str, meetEnd := s.readWhile(func(b byte) bool { + return b >= '0' && b <= '9' + }) + if meetEnd { + s.pos = recordPos + return 0, false + } + + index, err := strconv.Atoi(str) + if err != nil || index > math.MaxUint32 { + s.pos = recordPos + return 0, false + } + + return index, true +} + +// tryParseArrayIndex tries to read an arrayIndex, which is 'number', 'last' or 'last - number' +// if failed, the stream will not be pushed forward +func (s *jsonPathStream) tryParseArrayIndex() (jsonPathArrayIndex, bool) { + recordPos := s.pos + + s.skipWhiteSpace() + if s.exhausted() { + return 0, false + } + switch c := s.peek(); { + case c >= '0' && c <= '9': + index, ok := s.tryReadIndexNumber() + if !ok { + s.pos = recordPos + return 0, false + } + return jsonPathArrayIndexFromStart(index), true + case c == 'l': + if !s.tryReadString("last") { + s.pos = recordPos + return 0, false + } + s.skipWhiteSpace() + if s.exhausted() { + return jsonPathArrayIndexFromLast(0), true + } + + if s.peek() != '-' { + return jsonPathArrayIndexFromLast(0), true + } + s.skip(1) + s.skipWhiteSpace() + + index, ok := s.tryReadIndexNumber() + if !ok { + s.pos = recordPos + return 0, false + } + return jsonPathArrayIndexFromLast(index), true + } + return 0, false +} + func parseJSONPathArray(s *jsonPathStream, p *JSONPathExpression) bool { s.skip(1) s.skipWhiteSpace() @@ -271,20 +443,37 @@ func parseJSONPathArray(s *jsonPathStream, p *JSONPathExpression) bool { if s.peek() == '*' { s.skip(1) p.flags |= jsonPathExpressionContainsAsterisk - p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegIndex, arrayIndex: arrayIndexAsterisk}) + p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegArraySelection, arraySelection: jsonPathArraySelectionAsterisk{}}) } else { - // FIXME: only support an integer index for now. Need to support [last], [1 to 2]... in the future. - str, meetEnd := s.readWhile(func(b byte) bool { - return b >= '0' && b <= '9' - }) - if meetEnd { + start, ok := s.tryParseArrayIndex() + if !ok { return false } - index, err := strconv.Atoi(str) - if err != nil || index > math.MaxUint32 { - return false + + var selection jsonPathArraySelection + selection = jsonPathArraySelectionIndex{start} + // try to read " to " and the end + if unicode.IsSpace(rune(s.peek())) { + s.skipWhiteSpace() + if s.tryReadString("to") && unicode.IsSpace(rune(s.peek())) { + s.skipWhiteSpace() + if s.exhausted() { + return false + } + end, ok := s.tryParseArrayIndex() + if !ok { + return false + } + + if !validateIndexRange(start, end) { + return false + } + p.flags |= jsonPathExpressionContainsRange + selection = jsonPathArraySelectionRange{start, end} + } } - p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegIndex, arrayIndex: index}) + + p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegArraySelection, arraySelection: selection}) } s.skipWhiteSpace() @@ -381,18 +570,35 @@ func ParseJSONPathExpr(pathExpr string) (JSONPathExpression, error) { return pathExpression, err } +func (index jsonPathArrayIndex) String() string { + if index < 0 { + indexStr := strconv.Itoa(int(math.Abs(float64(index + 1)))) + return "last-" + indexStr + } + + indexStr := strconv.Itoa(int(index)) + return indexStr +} + func (pe JSONPathExpression) String() string { var s strings.Builder s.WriteString("$") for _, leg := range pe.legs { switch leg.typ { - case jsonPathLegIndex: - if leg.arrayIndex == -1 { + case jsonPathLegArraySelection: + switch selection := leg.arraySelection.(type) { + case jsonPathArraySelectionAsterisk: s.WriteString("[*]") - } else { + case jsonPathArraySelectionIndex: + s.WriteString("[") + s.WriteString(selection.index.String()) + s.WriteString("]") + case jsonPathArraySelectionRange: s.WriteString("[") - s.WriteString(strconv.Itoa(leg.arrayIndex)) + s.WriteString(selection.start.String()) + s.WriteString(" to ") + s.WriteString(selection.end.String()) s.WriteString("]") } case jsonPathLegKey: diff --git a/types/json_path_expr_test.go b/types/json_path_expr_test.go index 2de75ba8bd5d5..2fb0c50446d4a 100644 --- a/types/json_path_expr_test.go +++ b/types/json_path_expr_test.go @@ -53,6 +53,12 @@ func TestValidatePathExpr(t *testing.T) { {" $ . key1 [ 3 ]**[*].*.key3", true, 6}, {`$."key1 string"[ 3 ][*].*.key3`, true, 5}, {`$."hello \"escaped quotes\" world\\n"[3][*].*.key3`, true, 5}, + {`$[1 to 5]`, true, 1}, + {`$[2 to 1]`, false, 1}, + {`$[last]`, true, 1}, + {`$[1 to last]`, true, 1}, + {`$[1to3]`, false, 1}, + {`$[last - 5 to last - 10]`, false, 1}, {`$.\"escaped quotes\"[3][*].*.key3`, false, 0}, {`$.hello \"escaped quotes\" world[3][*].*.key3`, false, 0}, @@ -111,17 +117,19 @@ func TestPathExprToString(t *testing.T) { func TestPushBackOneIndexLeg(t *testing.T) { var tests = []struct { - expression string - index int - expected string - containsAnyAsterisk bool + expression string + index int + expected string + couldReturnMultipleValues bool }{ {"$", 1, "$[1]", false}, {"$.a[1]", 1, "$.a[1][1]", false}, - {"$.a[1]", -1, "$.a[1][*]", true}, {"$.a[*]", 10, "$.a[*][10]", true}, {"$.*[2]", 2, "$.*[2][2]", true}, {"$**.a[3]", 3, "$**.a[3][3]", true}, + {"$.a[1 to 3]", 3, "$.a[1 to 3][3]", true}, + {"$.a[last-3 to last-3]", 3, "$.a[last-3 to last-3][3]", true}, + {"$**.a[3]", -3, "$**.a[3][last-2]", true}, } for _, test := range tests { @@ -131,19 +139,19 @@ func TestPushBackOneIndexLeg(t *testing.T) { pe, err := ParseJSONPathExpr(test.expression) require.NoError(t, err) - pe = pe.pushBackOneIndexLeg(test.index) + pe = pe.pushBackOneArraySelectionLeg(jsonPathArraySelectionIndex{index: jsonPathArrayIndexFromStart(test.index)}) require.Equal(t, test.expected, pe.String()) - require.Equal(t, test.containsAnyAsterisk, pe.ContainsAnyAsterisk()) + require.Equal(t, test.couldReturnMultipleValues, pe.CouldMatchMultipleValues()) }) } } func TestPushBackOneKeyLeg(t *testing.T) { var tests = []struct { - expression string - key string - expected string - containsAnyAsterisk bool + expression string + key string + expected string + couldReturnMultipleValues bool }{ {"$", "aa", "$.aa", false}, {"$.a[1]", "aa", "$.a[1].aa", false}, @@ -160,7 +168,7 @@ func TestPushBackOneKeyLeg(t *testing.T) { pe = pe.pushBackOneKeyLeg(test.key) require.Equal(t, test.expected, pe.String()) - require.Equal(t, test.containsAnyAsterisk, pe.ContainsAnyAsterisk()) + require.Equal(t, test.couldReturnMultipleValues, pe.CouldMatchMultipleValues()) }) } } diff --git a/types/main_test.go b/types/main_test.go index 81069e118ea61..3e4fb3f087159 100644 --- a/types/main_test.go +++ b/types/main_test.go @@ -25,7 +25,9 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } goleak.VerifyTestMain(m, opts...) } diff --git a/types/parser_driver/main_test.go b/types/parser_driver/main_test.go index 19251613811d6..ebf7bf042bd54 100644 --- a/types/parser_driver/main_test.go +++ b/types/parser_driver/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/types/time.go b/types/time.go index 974b69602dd63..ebdfc462d8cdb 100644 --- a/types/time.go +++ b/types/time.go @@ -18,6 +18,7 @@ import ( "bytes" "encoding/json" "fmt" + "io" "math" "regexp" "strconv" @@ -1155,6 +1156,9 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int, isFloat bo hhmmss = true } if err != nil { + if err == io.EOF { + return ZeroDatetime, errors.Trace(ErrWrongValue.GenWithStackByArgs(DateTimeStr, str)) + } return ZeroDatetime, errors.Trace(err) } diff --git a/util/BUILD.bazel b/util/BUILD.bazel index 879b7e86df089..f0a137cb20431 100644 --- a/util/BUILD.bazel +++ b/util/BUILD.bazel @@ -33,8 +33,10 @@ go_library( "//session/txninfo", "//sessionctx/stmtctx", "//util/collate", + "//util/disk", "//util/execdetails", "//util/logutil", + "//util/memory", "//util/tls", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", @@ -44,6 +46,7 @@ go_library( "@io_etcd_go_etcd_client_v3//:client", "@io_etcd_go_etcd_client_v3//concurrency", "@org_golang_google_grpc//:grpc", + "@org_uber_go_atomic//:atomic", "@org_uber_go_zap//:zap", ], ) diff --git a/util/admin/main_test.go b/util/admin/main_test.go index 949b636970e43..ee1f2d5f2f116 100644 --- a/util/admin/main_test.go +++ b/util/admin/main_test.go @@ -32,6 +32,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } diff --git a/util/arena/main_test.go b/util/arena/main_test.go index e35c6f526bf57..a399ad116c1b6 100644 --- a/util/arena/main_test.go +++ b/util/arena/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/benchdaily/main_test.go b/util/benchdaily/main_test.go index 6863e85113088..02836578e971d 100644 --- a/util/benchdaily/main_test.go +++ b/util/benchdaily/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/bitmap/main_test.go b/util/bitmap/main_test.go index e5f42a15b9d78..e023854dbc74e 100644 --- a/util/bitmap/main_test.go +++ b/util/bitmap/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/cgroup/BUILD.bazel b/util/cgroup/BUILD.bazel index a5c5e3f75d358..58848ac153701 100644 --- a/util/cgroup/BUILD.bazel +++ b/util/cgroup/BUILD.bazel @@ -21,7 +21,10 @@ go_library( go_test( name = "cgroup_test", - srcs = ["cgroup_mock_test.go"], + srcs = [ + "cgroup_cpu_test.go", + "cgroup_mock_test.go", + ], embed = [":cgroup"], flaky = True, deps = ["@com_github_stretchr_testify//require"], diff --git a/util/cgroup/cgroup_cpu.go b/util/cgroup/cgroup_cpu.go index 29092c96914b6..bafa319f5ad62 100644 --- a/util/cgroup/cgroup_cpu.go +++ b/util/cgroup/cgroup_cpu.go @@ -67,3 +67,12 @@ func getCgroupCPU(root string) (CPUUsage, error) { return res, nil } + +// CPUShares returns the number of CPUs this cgroup can be expected to +// max out. If there's no limit, NumCPU is returned. +func (c CPUUsage) CPUShares() float64 { + if c.Period <= 0 || c.Quota <= 0 { + return float64(c.NumCPU) + } + return float64(c.Quota) / float64(c.Period) +} diff --git a/util/cgroup/cgroup_cpu_linux.go b/util/cgroup/cgroup_cpu_linux.go index 69cde58c5d2cd..0322e6282e5a4 100644 --- a/util/cgroup/cgroup_cpu_linux.go +++ b/util/cgroup/cgroup_cpu_linux.go @@ -13,7 +13,6 @@ // limitations under the License. //go:build linux -// +build linux package cgroup @@ -24,15 +23,6 @@ import ( "strings" ) -// CPUShares returns the number of CPUs this cgroup can be expected to -// max out. If there's no limit, NumCPU is returned. -func (c CPUUsage) CPUShares() float64 { - if c.Period <= 0 || c.Quota <= 0 { - return float64(c.NumCPU) - } - return float64(c.Quota) / float64(c.Period) -} - // GetCgroupCPU returns the CPU usage and quota for the current cgroup. func GetCgroupCPU() (CPUUsage, error) { cpuusage, err := getCgroupCPU("/") diff --git a/util/cgroup/cgroup_cpu_test.go b/util/cgroup/cgroup_cpu_test.go new file mode 100644 index 0000000000000..481ed3e32ccf8 --- /dev/null +++ b/util/cgroup/cgroup_cpu_test.go @@ -0,0 +1,50 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package cgroup + +import ( + "runtime" + "sync" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetCgroupCPU(t *testing.T) { + exit := make(chan struct{}) + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case <-exit: + return + default: + runtime.Gosched() + } + } + }() + } + cpu, err := GetCgroupCPU() + require.NoError(t, err) + require.NotZero(t, cpu.Period) + require.Less(t, int64(1), cpu.Period) + close(exit) + wg.Wait() +} diff --git a/util/cgroup/cgroup_cpu_unsupport.go b/util/cgroup/cgroup_cpu_unsupport.go index 8e0550fd7b3a9..97cb9f4ef3b73 100644 --- a/util/cgroup/cgroup_cpu_unsupport.go +++ b/util/cgroup/cgroup_cpu_unsupport.go @@ -13,7 +13,6 @@ // limitations under the License. //go:build !linux -// +build !linux package cgroup diff --git a/util/checksum/main_test.go b/util/checksum/main_test.go index e5465a5e61eec..4e41ef991f925 100644 --- a/util/checksum/main_test.go +++ b/util/checksum/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/chunk/alloc.go b/util/chunk/alloc.go index 4b706e6297431..af3385a644389 100644 --- a/util/chunk/alloc.go +++ b/util/chunk/alloc.go @@ -15,6 +15,8 @@ package chunk import ( + "math" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/mathutil" ) @@ -24,18 +26,37 @@ import ( // and Alloc() allocates from the pool. type Allocator interface { Alloc(fields []*types.FieldType, capacity, maxChunkSize int) *Chunk + CheckReuseAllocSize() bool Reset() } +var maxFreeChunks = 64 +var maxFreeColumnsPerType = 256 + +// InitChunkAllocSize init the maximum cache size +func InitChunkAllocSize(setMaxFreeChunks, setMaxFreeColumns uint32) { + if setMaxFreeChunks > math.MaxInt32 { + setMaxFreeChunks = math.MaxInt32 + } + if setMaxFreeColumns > math.MaxInt32 { + setMaxFreeColumns = math.MaxInt32 + } + maxFreeChunks = int(setMaxFreeChunks) + maxFreeColumnsPerType = int(setMaxFreeColumns) +} + // NewAllocator creates an Allocator. func NewAllocator() *allocator { - ret := &allocator{} + ret := &allocator{freeChunk: maxFreeChunks} ret.columnAlloc.init() return ret } var _ Allocator = &allocator{} +// MaxCachedLen Maximum cacheable length +var MaxCachedLen = 16 * 1024 + // allocator try to reuse objects. // It uses `poolColumnAllocator` to alloc chunk column objects. // The allocated chunks are recorded in the `allocated` array. @@ -45,6 +66,27 @@ type allocator struct { allocated []*Chunk free []*Chunk columnAlloc poolColumnAllocator + freeChunk int +} + +// columnList keep column +type columnList struct { + freeColumns []*Column + allocColumns []*Column +} + +func (cList *columnList) add(col *Column) { + cList.freeColumns = append(cList.freeColumns, col) +} + +// columnList Len Get the number of elements in the list +func (cList *columnList) Len() int { + return len(cList.freeColumns) + len(cList.allocColumns) +} + +// CheckReuseAllocSize return whether the cache can cache objects +func (a *allocator) CheckReuseAllocSize() bool { + return a.freeChunk > 0 || a.columnAlloc.freeColumnsPerType > 0 } // Alloc implements the Allocator interface. @@ -66,53 +108,101 @@ func (a *allocator) Alloc(fields []*types.FieldType, capacity, maxChunkSize int) chk.columns = append(chk.columns, a.columnAlloc.NewColumn(f, chk.capacity)) } - a.allocated = append(a.allocated, chk) + //avoid OOM + if a.freeChunk > len(a.allocated) { + a.allocated = append(a.allocated, chk) + } + return chk } -const ( - maxFreeChunks = 64 - maxFreeColumnsPerType = 256 -) - // Reset implements the Allocator interface. func (a *allocator) Reset() { - a.free = a.free[:0] for i, chk := range a.allocated { a.allocated[i] = nil - // Decouple chunk into chunk column objects and put them back to the column allocator for reuse. - for _, col := range chk.columns { - a.columnAlloc.put(col) - } - // Reset the chunk and put it to the free list for reuse. chk.resetForReuse() - - if len(a.free) < maxFreeChunks { // Don't cache too much data. + if len(a.free) < a.freeChunk { // Don't cache too much data. a.free = append(a.free, chk) } } a.allocated = a.allocated[:0] + + //column objects and put them to the column allocator for reuse. + for id, pool := range a.columnAlloc.pool { + for _, col := range pool.allocColumns { + if (len(pool.freeColumns) < a.columnAlloc.freeColumnsPerType) && checkColumnType(id, col) { + col.reset() + pool.freeColumns = append(pool.freeColumns, col) + } + } + pool.allocColumns = pool.allocColumns[:0] + } +} + +// checkColumnType check whether the conditions for entering the corresponding queue are met +// column Reset may change type +func checkColumnType(id int, col *Column) bool { + if col.avoidReusing { + return false + } + + if id == varElemLen { + //Take up too much memory, + if cap(col.data) > MaxCachedLen { + return false + } + return col.elemBuf == nil + } + + if col.elemBuf == nil { + return false + } + return id == cap(col.elemBuf) } var _ ColumnAllocator = &poolColumnAllocator{} type poolColumnAllocator struct { - pool map[int]freeList + pool map[int]*columnList + freeColumnsPerType int } // poolColumnAllocator implements the ColumnAllocator interface. func (alloc *poolColumnAllocator) NewColumn(ft *types.FieldType, count int) *Column { typeSize := getFixedLen(ft) + col := alloc.NewSizeColumn(typeSize, count) + + //column objects and put them back to the allocated column . + alloc.put(col) + return col +} + +// poolColumnAllocator implements the ColumnAllocator interface. +func (alloc *poolColumnAllocator) NewSizeColumn(typeSize int, count int) *Column { l := alloc.pool[typeSize] if l != nil && !l.empty() { col := l.pop() + + if cap(col.data) < count { + col = newColumn(typeSize, count) + } return col } return newColumn(typeSize, count) } +func (cList *columnList) pop() *Column { + if len(cList.freeColumns) == 0 { + return nil + } + col := cList.freeColumns[len(cList.freeColumns)-1] + cList.freeColumns = cList.freeColumns[:len(cList.freeColumns)-1] + return col +} + func (alloc *poolColumnAllocator) init() { - alloc.pool = make(map[int]freeList) + alloc.pool = make(map[int]*columnList) + alloc.freeColumnsPerType = maxFreeColumnsPerType } func (alloc *poolColumnAllocator) put(col *Column) { @@ -120,16 +210,20 @@ func (alloc *poolColumnAllocator) put(col *Column) { return } typeSize := col.typeSize() - if typeSize <= 0 { + if typeSize <= 0 && typeSize != varElemLen { return } l := alloc.pool[typeSize] if l == nil { - l = make(map[*Column]struct{}, 8) + l = &columnList{freeColumns: nil, allocColumns: nil} + l.freeColumns = make([]*Column, 0, alloc.freeColumnsPerType) + l.allocColumns = make([]*Column, 0, alloc.freeColumnsPerType) alloc.pool[typeSize] = l } - l.push(col) + if len(l.allocColumns) < alloc.freeColumnsPerType { + l.push(col) + } } // freeList is defined as a map, rather than a list, because when recycling chunk @@ -137,22 +231,12 @@ func (alloc *poolColumnAllocator) put(col *Column) { // reference to the others. type freeList map[*Column]struct{} -func (l freeList) empty() bool { - return len(l) == 0 +func (cList *columnList) empty() bool { + return len(cList.freeColumns) == 0 } -func (l freeList) pop() *Column { - for k := range l { - delete(l, k) - return k - } - return nil -} - -func (l freeList) push(c *Column) { - if len(l) >= maxFreeColumnsPerType { - // Don't cache too much to save memory. - return +func (cList *columnList) push(col *Column) { + if cap(col.data) < MaxCachedLen { + cList.allocColumns = append(cList.allocColumns, col) } - l[c] = struct{}{} } diff --git a/util/chunk/alloc_test.go b/util/chunk/alloc_test.go index 33b52590eab7c..7c09d818d1222 100644 --- a/util/chunk/alloc_test.go +++ b/util/chunk/alloc_test.go @@ -114,7 +114,7 @@ func TestColumnAllocator(t *testing.T) { // Check max column size. freeList := alloc1.pool[getFixedLen(ft)] require.NotNil(t, freeList) - require.Len(t, freeList, maxFreeColumnsPerType) + require.Equal(t, freeList.Len(), maxFreeColumnsPerType) } func TestNoDuplicateColumnReuse(t *testing.T) { @@ -202,3 +202,90 @@ func TestAvoidColumnReuse(t *testing.T) { require.True(t, col.avoidReusing) } } + +func TestColumnAllocatorLimit(t *testing.T) { + fieldTypes := []*types.FieldType{ + types.NewFieldTypeBuilder().SetType(mysql.TypeVarchar).BuildP(), + types.NewFieldTypeBuilder().SetType(mysql.TypeJSON).BuildP(), + types.NewFieldTypeBuilder().SetType(mysql.TypeFloat).BuildP(), + types.NewFieldTypeBuilder().SetType(mysql.TypeNewDecimal).BuildP(), + types.NewFieldTypeBuilder().SetType(mysql.TypeDouble).BuildP(), + types.NewFieldTypeBuilder().SetType(mysql.TypeLonglong).BuildP(), + types.NewFieldTypeBuilder().SetType(mysql.TypeDatetime).BuildP(), + } + + //set cache size + InitChunkAllocSize(10, 20) + alloc := NewAllocator() + require.True(t, alloc.CheckReuseAllocSize()) + for i := 0; i < maxFreeChunks+10; i++ { + alloc.Alloc(fieldTypes, 5, 10) + } + alloc.Reset() + require.Equal(t, len(alloc.free), 10) + for _, p := range alloc.columnAlloc.pool { + require.True(t, (p.Len() <= 20)) + } + + //Reduce capacity + InitChunkAllocSize(5, 10) + alloc = NewAllocator() + for i := 0; i < maxFreeChunks+10; i++ { + alloc.Alloc(fieldTypes, 5, 10) + } + alloc.Reset() + require.Equal(t, len(alloc.free), 5) + for _, p := range alloc.columnAlloc.pool { + require.True(t, (p.Len() <= 10)) + } + + //increase capacity + InitChunkAllocSize(50, 100) + alloc = NewAllocator() + for i := 0; i < maxFreeChunks+10; i++ { + alloc.Alloc(fieldTypes, 5, 10) + } + alloc.Reset() + require.Equal(t, len(alloc.free), 50) + for _, p := range alloc.columnAlloc.pool { + require.True(t, (p.Len() <= 100)) + } + + //long characters are not cached + alloc = NewAllocator() + rs := alloc.Alloc([]*types.FieldType{types.NewFieldTypeBuilder().SetType(mysql.TypeVarchar).BuildP()}, 1024, 1024) + nu := len(alloc.columnAlloc.pool[varElemLen].allocColumns) + require.Equal(t, nu, 1) + for _, col := range rs.columns { + for i := 0; i < 20480; i++ { + col.data = append(col.data, byte('a')) + } + } + alloc.Reset() + for _, p := range alloc.columnAlloc.pool { + require.True(t, (p.Len() == 0)) + } + + InitChunkAllocSize(0, 0) + alloc = NewAllocator() + require.False(t, alloc.CheckReuseAllocSize()) +} + +func TestColumnAllocatorCheck(t *testing.T) { + fieldTypes := []*types.FieldType{ + types.NewFieldTypeBuilder().SetType(mysql.TypeFloat).BuildP(), + types.NewFieldTypeBuilder().SetType(mysql.TypeDatetime).BuildP(), + } + InitChunkAllocSize(10, 20) + alloc := NewAllocator() + for i := 0; i < 4; i++ { + alloc.Alloc(fieldTypes, 5, 10) + } + col := alloc.columnAlloc.NewColumn(types.NewFieldTypeBuilder().SetType(mysql.TypeFloat).BuildP(), 10) + col.Reset(types.ETDatetime) + alloc.Reset() + num := alloc.columnAlloc.pool[getFixedLen(types.NewFieldTypeBuilder().SetType(mysql.TypeFloat).BuildP())].Len() + require.Equal(t, num, 4) + num = alloc.columnAlloc.pool[getFixedLen(types.NewFieldTypeBuilder().SetType(mysql.TypeDatetime).BuildP())].Len() + require.Equal(t, num, 4) +} diff --git a/util/chunk/iterator.go b/util/chunk/iterator.go index 2adebc5822c9f..74d78b9cb62ea 100644 --- a/util/chunk/iterator.go +++ b/util/chunk/iterator.go @@ -14,33 +14,17 @@ package chunk -import "sync" +import "golang.org/x/sys/cpu" var ( _ Iterator = (*Iterator4Chunk)(nil) _ Iterator = (*iterator4RowPtr)(nil) _ Iterator = (*iterator4List)(nil) - _ Iterator = (*iterator4Slice)(nil) + _ Iterator = (*Iterator4Slice)(nil) _ Iterator = (*iterator4RowContainer)(nil) _ Iterator = (*multiIterator)(nil) ) -var ( - iterator4SlicePool = &sync.Pool{New: func() any { return new(iterator4Slice) }} -) - -// FreeIterator try to free and reuse the iterator. -func FreeIterator(it any) { - switch it := it.(type) { - case *iterator4Slice: - it.rows = nil - it.cursor = 0 - iterator4SlicePool.Put(it) - default: - // Do Nothing. - } -} - // Iterator is used to iterate a number of rows. // // for row := it.Begin(); row != it.End(); row = it.Next() { @@ -71,19 +55,19 @@ type Iterator interface { // NewIterator4Slice returns a Iterator for Row slice. func NewIterator4Slice(rows []Row) Iterator { - it := iterator4SlicePool.Get().(*iterator4Slice) - it.rows = rows - it.cursor = 0 - return it + return &Iterator4Slice{rows: rows} } -type iterator4Slice struct { +// Iterator4Slice is used to iterate rows inside a slice. +type Iterator4Slice struct { + _ cpu.CacheLinePad rows []Row cursor int + _ cpu.CacheLinePad } // Begin implements the Iterator interface. -func (it *iterator4Slice) Begin() Row { +func (it *Iterator4Slice) Begin() Row { if it.Len() == 0 { return it.End() } @@ -92,7 +76,7 @@ func (it *iterator4Slice) Begin() Row { } // Next implements the Iterator interface. -func (it *iterator4Slice) Next() Row { +func (it *Iterator4Slice) Next() Row { if l := it.Len(); it.cursor >= l { it.cursor = l + 1 return it.End() @@ -103,7 +87,7 @@ func (it *iterator4Slice) Next() Row { } // Current implements the Iterator interface. -func (it *iterator4Slice) Current() Row { +func (it *Iterator4Slice) Current() Row { if it.cursor == 0 || it.cursor > it.Len() { return it.End() } @@ -111,22 +95,28 @@ func (it *iterator4Slice) Current() Row { } // End implements the Iterator interface. -func (*iterator4Slice) End() Row { +func (*Iterator4Slice) End() Row { return Row{} } // ReachEnd implements the Iterator interface. -func (it *iterator4Slice) ReachEnd() { +func (it *Iterator4Slice) ReachEnd() { it.cursor = it.Len() + 1 } // Len implements the Iterator interface. -func (it *iterator4Slice) Len() int { +func (it *Iterator4Slice) Len() int { return len(it.rows) } +// Reset iterator.rows and cursor. +func (it *Iterator4Slice) Reset(rows []Row) { + it.rows = rows + it.cursor = 0 +} + // Error returns none-nil error if anything wrong happens during the iteration. -func (*iterator4Slice) Error() error { +func (*Iterator4Slice) Error() error { return nil } diff --git a/util/chunk/row.go b/util/chunk/row.go index 96aa92acb65fb..70cd974d6ffd5 100644 --- a/util/chunk/row.go +++ b/util/chunk/row.go @@ -115,10 +115,14 @@ func (r Row) GetJSON(colIdx int) types.BinaryJSON { // Keep in mind that GetDatumRow has a reference to r.c, which is a chunk, // this function works only if the underlying chunk is valid or unchanged. func (r Row) GetDatumRow(fields []*types.FieldType) []types.Datum { - datumRow := make([]types.Datum, 0, r.c.NumCols()) - for colIdx := 0; colIdx < r.c.NumCols(); colIdx++ { - datum := r.GetDatum(colIdx, fields[colIdx]) - datumRow = append(datumRow, datum) + datumRow := make([]types.Datum, r.c.NumCols()) + return r.GetDatumRowWithBuffer(fields, datumRow) +} + +// GetDatumRowWithBuffer gets datum using the buffer datumRow. +func (r Row) GetDatumRowWithBuffer(fields []*types.FieldType, datumRow []types.Datum) []types.Datum { + for colIdx := 0; colIdx < len(datumRow); colIdx++ { + r.GetDatumWithBuffer(colIdx, fields[colIdx], &datumRow[colIdx]) } return datumRow } @@ -126,6 +130,12 @@ func (r Row) GetDatumRow(fields []*types.FieldType) []types.Datum { // GetDatum implements the chunk.Row interface. func (r Row) GetDatum(colIdx int, tp *types.FieldType) types.Datum { var d types.Datum + r.GetDatumWithBuffer(colIdx, tp, &d) + return d +} + +// GetDatumWithBuffer gets datum using the buffer d. +func (r Row) GetDatumWithBuffer(colIdx int, tp *types.FieldType, d *types.Datum) types.Datum { switch tp.GetType() { case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong: if !r.IsNull(colIdx) { @@ -192,7 +202,10 @@ func (r Row) GetDatum(colIdx int, tp *types.FieldType) types.Datum { d.SetMysqlJSON(r.GetJSON(colIdx)) } } - return d + if r.IsNull(colIdx) { + d.SetNull() + } + return *d } // GetRaw returns the underlying raw bytes with the colIdx. diff --git a/util/chunk/row_container.go b/util/chunk/row_container.go index b4c73ae8e3cab..7ae1a67879b03 100644 --- a/util/chunk/row_container.go +++ b/util/chunk/row_container.go @@ -136,6 +136,7 @@ func (c *RowContainer) SpillToDisk() { defer c.actionSpill.setStatus(spilledYet) } var err error + memory.QueryForceDisk.Add(1) n := c.m.records.inMemory.NumChunks() c.m.records.inDisk = NewListInDisk(c.m.records.inMemory.FieldTypes()) c.m.records.inDisk.diskTracker.AttachTo(c.diskTracker) @@ -411,9 +412,6 @@ func (a *SpillDiskAction) Reset() { a.once = sync.Once{} } -// SetLogHook sets the hook, it does nothing just to form the memory.ActionOnExceed interface. -func (*SpillDiskAction) SetLogHook(_ func(uint64)) {} - // GetPriority get the priority of the Action. func (*SpillDiskAction) GetPriority() int64 { return memory.DefSpillPriority @@ -446,6 +444,10 @@ type SortedRowContainer struct { actionSpill *SortAndSpillDiskAction memTracker *memory.Tracker + + // Sort is a time-consuming operation, we need to set a checkpoint to detect + // the outside signal periodically. + timesOfRowCompare uint } // NewSortedRowContainer creates a new SortedRowContainer in memory. @@ -470,21 +472,37 @@ func (c *SortedRowContainer) Close() error { func (c *SortedRowContainer) lessRow(rowI, rowJ Row) bool { for i, colIdx := range c.keyColumns { cmpFunc := c.keyCmpFuncs[i] - cmp := cmpFunc(rowI, colIdx, rowJ, colIdx) - if c.ByItemsDesc[i] { - cmp = -cmp - } - if cmp < 0 { - return true - } else if cmp > 0 { - return false + if cmpFunc != nil { + cmp := cmpFunc(rowI, colIdx, rowJ, colIdx) + if c.ByItemsDesc[i] { + cmp = -cmp + } + if cmp < 0 { + return true + } else if cmp > 0 { + return false + } } } return false } +// SignalCheckpointForSort indicates the times of row comparation that a signal detection will be triggered. +const SignalCheckpointForSort uint = 10240 + // keyColumnsLess is the less function for key columns. func (c *SortedRowContainer) keyColumnsLess(i, j int) bool { + if c.timesOfRowCompare >= SignalCheckpointForSort { + // Trigger Consume for checking the NeedKill signal + c.memTracker.Consume(1) + c.timesOfRowCompare = 0 + } + failpoint.Inject("SignalCheckpointForSort", func(val failpoint.Value) { + if val.(bool) { + c.timesOfRowCompare += 1024 + } + }) + c.timesOfRowCompare++ rowI := c.m.records.inMemory.GetRow(c.ptrM.rowPtrs[i]) rowJ := c.m.records.inMemory.GetRow(c.ptrM.rowPtrs[j]) return c.lessRow(rowI, rowJ) @@ -607,9 +625,6 @@ func (a *SortAndSpillDiskAction) Action(t *memory.Tracker) { } } -// SetLogHook sets the hook, it does nothing just to form the memory.ActionOnExceed interface. -func (*SortAndSpillDiskAction) SetLogHook(_ func(uint64)) {} - // WaitForTest waits all goroutine have gone. func (a *SortAndSpillDiskAction) WaitForTest() { a.testWg.Wait() diff --git a/util/codec/main_test.go b/util/codec/main_test.go index 32c64581b07df..d754807331c7f 100644 --- a/util/codec/main_test.go +++ b/util/codec/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/collate/main_test.go b/util/collate/main_test.go index 53916051ad294..42632ee9bd640 100644 --- a/util/collate/main_test.go +++ b/util/collate/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/cpu/BUILD.bazel b/util/cpu/BUILD.bazel new file mode 100644 index 0000000000000..b831ba544947b --- /dev/null +++ b/util/cpu/BUILD.bazel @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "cpu", + srcs = ["cpu.go"], + importpath = "github.com/pingcap/tidb/util/cpu", + visibility = ["//visibility:public"], + deps = [ + "//metrics", + "//util/cgroup", + "//util/mathutil", + "@com_github_cloudfoundry_gosigar//:gosigar", + "@com_github_pingcap_log//:log", + "@org_uber_go_atomic//:atomic", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "cpu_test", + srcs = ["cpu_test.go"], + embed = [":cpu"], + flaky = True, + race = "on", + deps = ["@com_github_stretchr_testify//require"], +) diff --git a/util/cpu/cpu.go b/util/cpu/cpu.go new file mode 100644 index 0000000000000..2803b4e106c49 --- /dev/null +++ b/util/cpu/cpu.go @@ -0,0 +1,113 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cpu + +import ( + "os" + "sync" + "time" + + "github.com/cloudfoundry/gosigar" + "github.com/pingcap/log" + "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/util/cgroup" + "github.com/pingcap/tidb/util/mathutil" + "go.uber.org/atomic" + "go.uber.org/zap" +) + +var cpuUsage atomic.Float64 + +// GetCPUUsage returns the cpu usage of the current process. +func GetCPUUsage() float64 { + return cpuUsage.Load() +} + +// Observer is used to observe the cpu usage of the current process. +type Observer struct { + utime int64 + stime int64 + now int64 + exit chan struct{} + cpu mathutil.ExponentialMovingAverage + wg sync.WaitGroup +} + +// NewCPUObserver returns a cpu observer. +func NewCPUObserver() *Observer { + return &Observer{ + exit: make(chan struct{}), + now: time.Now().UnixNano(), + cpu: *mathutil.NewExponentialMovingAverage(0.95, 10), + } +} + +// Start starts the cpu observer. +func (c *Observer) Start() { + c.wg.Add(1) + go func() { + ticker := time.NewTicker(100 * time.Millisecond) + defer func() { + ticker.Stop() + c.wg.Done() + }() + for { + select { + case <-ticker.C: + curr := c.observe() + c.cpu.Add(curr) + cpuUsage.Store(c.cpu.Get()) + metrics.EMACPUUsageGauge.Set(c.cpu.Get()) + case <-c.exit: + return + } + } + }() +} + +// Stop stops the cpu observer. +func (c *Observer) Stop() { + close(c.exit) + c.wg.Wait() +} + +func (c *Observer) observe() float64 { + user, sys, err := getCPUTime() + if err != nil { + log.Error("getCPUTime", zap.Error(err)) + } + cgroupCPU, _ := cgroup.GetCgroupCPU() + cpuShare := cgroupCPU.CPUShares() + now := time.Now().UnixNano() + dur := float64(now - c.now) + utime := user * 1e6 + stime := sys * 1e6 + urate := float64(utime-c.utime) / dur + srate := float64(stime-c.stime) / dur + c.now = now + c.utime = utime + c.stime = stime + return (srate + urate) / cpuShare +} + +// getCPUTime returns the cumulative user/system time (in ms) since the process start. +func getCPUTime() (userTimeMillis, sysTimeMillis int64, err error) { + pid := os.Getpid() + cpuTime := sigar.ProcTime{} + if err := cpuTime.Get(pid); err != nil { + return 0, 0, err + } + return int64(cpuTime.User), int64(cpuTime.Sys), nil +} diff --git a/util/cpu/cpu_test.go b/util/cpu/cpu_test.go new file mode 100644 index 0000000000000..a191227b72f78 --- /dev/null +++ b/util/cpu/cpu_test.go @@ -0,0 +1,51 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cpu + +import ( + "runtime" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestCPUValue(t *testing.T) { + observer := NewCPUObserver() + exit := make(chan struct{}) + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case <-exit: + return + default: + runtime.Gosched() + } + } + }() + } + observer.Start() + time.Sleep(5 * time.Second) + require.GreaterOrEqual(t, GetCPUUsage(), 0.0) + require.Less(t, GetCPUUsage(), 1.0) + observer.Stop() + close(exit) + wg.Wait() +} diff --git a/util/cpuprofile/cpuprofile_test.go b/util/cpuprofile/cpuprofile_test.go index 2d400264ede10..b20428dcf21fd 100644 --- a/util/cpuprofile/cpuprofile_test.go +++ b/util/cpuprofile/cpuprofile_test.go @@ -18,7 +18,6 @@ import ( "bytes" "context" "io" - "io/ioutil" "net" "net/http" "runtime/pprof" @@ -237,7 +236,7 @@ func TestProfileHTTPHandler(t *testing.T) { resp, err = http.Get("http://" + address + "/debug/pprof/profile?seconds=100000") require.NoError(t, err) require.Equal(t, 400, resp.StatusCode) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) require.Equal(t, "profile duration exceeds server's WriteTimeout\n", string(body)) require.NoError(t, resp.Body.Close()) diff --git a/util/cteutil/main_test.go b/util/cteutil/main_test.go index 2c6bb6eed00fa..44a7aeb89bc09 100644 --- a/util/cteutil/main_test.go +++ b/util/cteutil/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/dbterror/ddl_terror.go b/util/dbterror/ddl_terror.go index 65a02fb23da24..ddacf77c025ef 100644 --- a/util/dbterror/ddl_terror.go +++ b/util/dbterror/ddl_terror.go @@ -369,6 +369,8 @@ var ( ErrDependentByFunctionalIndex = ClassDDL.NewStd(mysql.ErrDependentByFunctionalIndex) // ErrFunctionalIndexOnBlob when the expression of expression index returns blob or text. ErrFunctionalIndexOnBlob = ClassDDL.NewStd(mysql.ErrFunctionalIndexOnBlob) + // ErrDependentByPartitionFunctional returns when the dropped column depends by expression partition. + ErrDependentByPartitionFunctional = ClassDDL.NewStd(mysql.ErrDependentByPartitionFunctional) // ErrUnsupportedAlterTableSpec means we don't support this alter table specification (i.e. unknown) ErrUnsupportedAlterTableSpec = ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message(fmt.Sprintf(mysql.MySQLErrName[mysql.ErrUnsupportedDDLOperation].Raw, "Unsupported/unknown ALTER TABLE specification"), nil)) @@ -391,6 +393,8 @@ var ( ErrCannotCancelDDLJob = ClassDDL.NewStd(mysql.ErrCannotCancelDDLJob) // ErrDDLSetting returns when failing to enable/disable DDL ErrDDLSetting = ClassDDL.NewStd(mysql.ErrDDLSetting) + // ErrIngestFailed returns when the DDL ingest job is failed. + ErrIngestFailed = ClassDDL.NewStd(mysql.ErrIngestFailed) // ErrColumnInChange indicates there is modification on the column in parallel. ErrColumnInChange = ClassDDL.NewStd(mysql.ErrColumnInChange) @@ -416,4 +420,20 @@ var ( ErrForeignKeyColumnCannotChangeChild = ClassDDL.NewStd(mysql.ErrForeignKeyColumnCannotChangeChild) // ErrNoReferencedRow2 returns when there are rows in child table don't have related foreign key value in refer table. ErrNoReferencedRow2 = ClassDDL.NewStd(mysql.ErrNoReferencedRow2) + + // ErrUnsupportedColumnInTTLConfig returns when a column type is not expected in TTL config + ErrUnsupportedColumnInTTLConfig = ClassDDL.NewStd(mysql.ErrUnsupportedColumnInTTLConfig) + // ErrTTLColumnCannotDrop returns when a column is dropped while referenced by TTL config + ErrTTLColumnCannotDrop = ClassDDL.NewStd(mysql.ErrTTLColumnCannotDrop) + // ErrSetTTLOptionForNonTTLTable returns when the `TTL_ENABLE` or `TTL_JOB_INTERVAL` option is set on a non-TTL table + ErrSetTTLOptionForNonTTLTable = ClassDDL.NewStd(mysql.ErrSetTTLOptionForNonTTLTable) + // ErrTempTableNotAllowedWithTTL returns when setting TTL config for a temp table + ErrTempTableNotAllowedWithTTL = ClassDDL.NewStd(mysql.ErrTempTableNotAllowedWithTTL) + // ErrUnsupportedTTLReferencedByFK returns when the TTL config is set for a table referenced by foreign key + ErrUnsupportedTTLReferencedByFK = ClassDDL.NewStd(mysql.ErrUnsupportedTTLReferencedByFK) + // ErrUnsupportedPrimaryKeyTypeWithTTL returns when create or alter a table with TTL options but the primary key is not supported + ErrUnsupportedPrimaryKeyTypeWithTTL = ClassDDL.NewStd(mysql.ErrUnsupportedPrimaryKeyTypeWithTTL) + + // ErrNotSupportedYet returns when tidb does not support this feature. + ErrNotSupportedYet = ClassDDL.NewStd(mysql.ErrNotSupportedYet) ) diff --git a/util/dbterror/main_test.go b/util/dbterror/main_test.go index 133187cfb5e26..9e86cc8d329e3 100644 --- a/util/dbterror/main_test.go +++ b/util/dbterror/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), } goleak.VerifyTestMain(m, opts...) } diff --git a/util/dbutil/common.go b/util/dbutil/common.go index 37b6da5fd1f49..df54e18bd6909 100644 --- a/util/dbutil/common.go +++ b/util/dbutil/common.go @@ -19,7 +19,7 @@ import ( "database/sql" "encoding/json" "fmt" - "net/url" + "net" "os" "strconv" "strings" @@ -107,26 +107,31 @@ func GetDBConfigFromEnv(schema string) DBConfig { // OpenDB opens a mysql connection FD func OpenDB(cfg DBConfig, vars map[string]string) (*sql.DB, error) { - var dbDSN string + driverCfg := mysql.NewConfig() + driverCfg.Params = make(map[string]string) + driverCfg.User = cfg.User + driverCfg.Passwd = cfg.Password + driverCfg.Net = "tcp" + driverCfg.Addr = net.JoinHostPort(cfg.Host, strconv.Itoa(cfg.Port)) + driverCfg.Params["charset"] = "utf8mb4" + if len(cfg.Snapshot) != 0 { log.Info("create connection with snapshot", zap.String("snapshot", cfg.Snapshot)) - dbDSN = fmt.Sprintf("%s:%s@tcp(%s:%d)/?charset=utf8mb4&tidb_snapshot=%s", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.Snapshot) - } else { - dbDSN = fmt.Sprintf("%s:%s@tcp(%s:%d)/?charset=utf8mb4", cfg.User, cfg.Password, cfg.Host, cfg.Port) + driverCfg.Params["tidb_snapshot"] = cfg.Snapshot } for key, val := range vars { // key='val'. add single quote for better compatibility. - dbDSN += fmt.Sprintf("&%s=%%27%s%%27", key, url.QueryEscape(val)) + driverCfg.Params[key] = fmt.Sprintf("'%s'", val) } - dbConn, err := sql.Open("mysql", dbDSN) + c, err := mysql.NewConnector(driverCfg) if err != nil { return nil, errors.Trace(err) } - - err = dbConn.Ping() - return dbConn, errors.Trace(err) + db := sql.OpenDB(c) + err = db.Ping() + return db, errors.Trace(err) } // CloseDB closes the mysql fd diff --git a/util/ddl-checker/executable_checker.go b/util/ddl-checker/executable_checker.go index 47fd059a79530..7571cbfe3f524 100644 --- a/util/ddl-checker/executable_checker.go +++ b/util/ddl-checker/executable_checker.go @@ -100,7 +100,7 @@ func (ec *ExecutableChecker) DropTable(context context.Context, tableName string // Close closes the ExecutableChecker func (ec *ExecutableChecker) Close() error { - if !ec.isClosed.CAS(false, true) { + if !ec.isClosed.CompareAndSwap(false, true) { return errors.New("ExecutableChecker is already closed") } ec.session.Close() diff --git a/util/deadlockhistory/main_test.go b/util/deadlockhistory/main_test.go index 6e21d6d732021..388b04f00bbf0 100644 --- a/util/deadlockhistory/main_test.go +++ b/util/deadlockhistory/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/disjointset/main_test.go b/util/disjointset/main_test.go index 1b4460b26d17c..4c7620d69dc07 100644 --- a/util/disjointset/main_test.go +++ b/util/disjointset/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/disk/main_test.go b/util/disk/main_test.go index 247e29ff0047d..b5dc84c28cf70 100644 --- a/util/disk/main_test.go +++ b/util/disk/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/engine/engine.go b/util/engine/engine.go index 68c369154888e..0a1614041f3bc 100644 --- a/util/engine/engine.go +++ b/util/engine/engine.go @@ -21,7 +21,7 @@ import ( // IsTiFlash tests whether the store is based on tiflash engine. func IsTiFlash(store *metapb.Store) bool { for _, label := range store.Labels { - if label.Key == "engine" && label.Value == "tiflash" { + if label.Key == "engine" && (label.Value == "tiflash_compute" || label.Value == "tiflash") { return true } } diff --git a/util/etcd/BUILD.bazel b/util/etcd/BUILD.bazel index 65b3e7a016047..f832e254d74a7 100644 --- a/util/etcd/BUILD.bazel +++ b/util/etcd/BUILD.bazel @@ -8,6 +8,7 @@ go_library( deps = [ "@com_github_pingcap_errors//:errors", "@io_etcd_go_etcd_client_v3//:client", + "@io_etcd_go_etcd_client_v3//namespace", ], ) diff --git a/util/etcd/etcd.go b/util/etcd/etcd.go index 6735adbb9c12a..167889849bf36 100644 --- a/util/etcd/etcd.go +++ b/util/etcd/etcd.go @@ -24,6 +24,7 @@ import ( "github.com/pingcap/errors" clientv3 "go.etcd.io/etcd/client/v3" + "go.etcd.io/etcd/client/v3/namespace" ) // Node organizes the ectd query result as a Trie tree @@ -333,3 +334,10 @@ func keyWithPrefix(prefix, key string) string { return path.Join(prefix, key) } + +// SetEtcdCliByNamespace is used to add an etcd namespace prefix before etcd path. +func SetEtcdCliByNamespace(cli *clientv3.Client, namespacePrefix string) { + cli.KV = namespace.NewKV(cli.KV, namespacePrefix) + cli.Watcher = namespace.NewWatcher(cli.Watcher, namespacePrefix) + cli.Lease = namespace.NewLease(cli.Lease, namespacePrefix) +} diff --git a/util/etcd/etcd_test.go b/util/etcd/etcd_test.go index c99b43bf46841..f98c1393d5f6c 100644 --- a/util/etcd/etcd_test.go +++ b/util/etcd/etcd_test.go @@ -395,3 +395,30 @@ func testSetup(t *testing.T) (context.Context, *Client, *integration.ClusterV3) etcd := NewClient(cluster.RandClient(), "binlog") return context.Background(), etcd, cluster } + +func testSetupOriginal(t *testing.T) (context.Context, *clientv3.Client, *integration.ClusterV3) { + cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) + return context.Background(), cluster.RandClient(), cluster +} + +func TestSetEtcdCliByNamespace(t *testing.T) { + integration.BeforeTest(t) + ctx, origEtcdCli, etcdMockCluster := testSetupOriginal(t) + defer etcdMockCluster.Terminate(t) + + namespacePrefix := "testNamespace/" + key := "testkey" + obj := "test" + + unprefixedKV := origEtcdCli.KV + cliNamespace := origEtcdCli + SetEtcdCliByNamespace(cliNamespace, namespacePrefix) + + _, err := cliNamespace.Put(ctx, key, obj) + require.NoError(t, err) + + // verify that kv pair is empty before set + getResp, err := unprefixedKV.Get(ctx, namespacePrefix+key) + require.NoError(t, err) + require.Len(t, getResp.Kvs, 1) +} diff --git a/util/execdetails/execdetails.go b/util/execdetails/execdetails.go index 2d483e167df61..bc88857fe439c 100644 --- a/util/execdetails/execdetails.go +++ b/util/execdetails/execdetails.go @@ -32,17 +32,22 @@ import ( // ExecDetails contains execution detail information. type ExecDetails struct { - CalleeAddress string + DetailsNeedP90 + CommitDetail *util.CommitDetails + LockKeysDetail *util.LockKeysDetails + ScanDetail *util.ScanDetail CopTime time.Duration BackoffTime time.Duration LockKeysDuration time.Duration - BackoffSleep map[string]time.Duration - BackoffTimes map[string]int RequestCount int - CommitDetail *util.CommitDetails - LockKeysDetail *util.LockKeysDetails - ScanDetail *util.ScanDetail - TimeDetail util.TimeDetail +} + +// DetailsNeedP90 contains execution detail information which need calculate P90. +type DetailsNeedP90 struct { + BackoffSleep map[string]time.Duration + BackoffTimes map[string]int + CalleeAddress string + TimeDetail util.TimeDetail } type stmtExecDetailKeyType struct{} @@ -318,15 +323,17 @@ func (d ExecDetails) ToZapFields() (fields []zap.Field) { } type basicCopRuntimeStats struct { - BasicRuntimeStats - threads int32 storeType string + BasicRuntimeStats + threads int32 + totalTasks int32 + procTimes []time.Duration } // String implements the RuntimeStats interface. func (e *basicCopRuntimeStats) String() string { if e.storeType == "tiflash" { - return fmt.Sprintf("time:%v, loops:%d, threads:%d", FormatDuration(time.Duration(e.consume)), e.loop, e.threads) + return fmt.Sprintf("time:%v, loops:%d, threads:%d, ", FormatDuration(time.Duration(e.consume)), e.loop, e.threads) + e.BasicRuntimeStats.tiflashScanContext.String() } return fmt.Sprintf("time:%v, loops:%d", FormatDuration(time.Duration(e.consume)), e.loop) } @@ -334,9 +341,11 @@ func (e *basicCopRuntimeStats) String() string { // Clone implements the RuntimeStats interface. func (e *basicCopRuntimeStats) Clone() RuntimeStats { return &basicCopRuntimeStats{ - BasicRuntimeStats: BasicRuntimeStats{loop: e.loop, consume: e.consume, rows: e.rows}, + BasicRuntimeStats: BasicRuntimeStats{loop: e.loop, consume: e.consume, rows: e.rows, tiflashScanContext: e.tiflashScanContext.Clone()}, threads: e.threads, storeType: e.storeType, + totalTasks: e.totalTasks, + procTimes: e.procTimes, } } @@ -350,6 +359,13 @@ func (e *basicCopRuntimeStats) Merge(rs RuntimeStats) { e.consume += tmp.consume e.rows += tmp.rows e.threads += tmp.threads + e.totalTasks += tmp.totalTasks + if len(tmp.procTimes) > 0 { + e.procTimes = append(e.procTimes, tmp.procTimes...) + } else { + e.procTimes = append(e.procTimes, time.Duration(tmp.consume)) + } + e.tiflashScanContext.Merge(tmp.tiflashScanContext) } // Tp implements the RuntimeStats interface. @@ -359,52 +375,66 @@ func (*basicCopRuntimeStats) Tp() int { // CopRuntimeStats collects cop tasks' execution info. type CopRuntimeStats struct { - sync.Mutex - // stats stores the runtime statistics of coprocessor tasks. // The key of the map is the tikv-server address. Because a tikv-server can // have many region leaders, several coprocessor tasks can be sent to the // same tikv-server instance. We have to use a list to maintain all tasks // executed on each instance. - stats map[string][]*basicCopRuntimeStats + stats map[string]*basicCopRuntimeStats scanDetail *util.ScanDetail // do not use kv.StoreType because it will meet cycle import error storeType string + sync.Mutex } // RecordOneCopTask records a specific cop tasks's execution detail. func (crs *CopRuntimeStats) RecordOneCopTask(address string, summary *tipb.ExecutorExecutionSummary) { crs.Lock() defer crs.Unlock() - crs.stats[address] = append(crs.stats[address], - &basicCopRuntimeStats{BasicRuntimeStats: BasicRuntimeStats{loop: int32(*summary.NumIterations), + + if crs.stats[address] == nil { + crs.stats[address] = &basicCopRuntimeStats{ + storeType: crs.storeType, + } + } + crs.stats[address].Merge(&basicCopRuntimeStats{ + storeType: crs.storeType, + BasicRuntimeStats: BasicRuntimeStats{loop: int32(*summary.NumIterations), consume: int64(*summary.TimeProcessedNs), - rows: int64(*summary.NumProducedRows)}, - threads: int32(summary.GetConcurrency()), - storeType: crs.storeType}) + rows: int64(*summary.NumProducedRows), + tiflashScanContext: TiFlashScanContext{ + totalDmfileScannedPacks: summary.GetTiflashScanContext().GetTotalDmfileScannedPacks(), + totalDmfileSkippedPacks: summary.GetTiflashScanContext().GetTotalDmfileSkippedPacks(), + totalDmfileScannedRows: summary.GetTiflashScanContext().GetTotalDmfileScannedRows(), + totalDmfileSkippedRows: summary.GetTiflashScanContext().GetTotalDmfileSkippedRows(), + totalDmfileRoughSetIndexLoadTimeMs: summary.GetTiflashScanContext().GetTotalDmfileRoughSetIndexLoadTimeMs(), + totalDmfileReadTimeMs: summary.GetTiflashScanContext().GetTotalDmfileReadTimeMs(), + totalCreateSnapshotTimeMs: summary.GetTiflashScanContext().GetTotalCreateSnapshotTimeMs(), + totalLocalRegionNum: summary.GetTiflashScanContext().GetTotalLocalRegionNum(), + totalRemoteRegionNum: summary.GetTiflashScanContext().GetTotalRemoteRegionNum()}}, threads: int32(summary.GetConcurrency()), + totalTasks: 1, + }) } // GetActRows return total rows of CopRuntimeStats. func (crs *CopRuntimeStats) GetActRows() (totalRows int64) { for _, instanceStats := range crs.stats { - for _, stat := range instanceStats { - totalRows += stat.rows - } + totalRows += instanceStats.rows } return totalRows } // MergeBasicStats traverses basicCopRuntimeStats in the CopRuntimeStats and collects some useful information. -func (crs *CopRuntimeStats) MergeBasicStats() (procTimes []time.Duration, totalTime time.Duration, totalTasks, totalLoops, totalThreads int32) { +func (crs *CopRuntimeStats) MergeBasicStats() (procTimes []time.Duration, totalTime time.Duration, totalTasks, totalLoops, totalThreads int32, totalTiFlashScanContext TiFlashScanContext) { procTimes = make([]time.Duration, 0, 32) + totalTiFlashScanContext = TiFlashScanContext{} for _, instanceStats := range crs.stats { - for _, stat := range instanceStats { - procTimes = append(procTimes, time.Duration(stat.consume)*time.Nanosecond) - totalTime += time.Duration(stat.consume) - totalLoops += stat.loop - totalThreads += stat.threads - totalTasks++ - } + procTimes = append(procTimes, instanceStats.procTimes...) + totalTime += time.Duration(instanceStats.consume) + totalLoops += instanceStats.loop + totalThreads += instanceStats.threads + totalTiFlashScanContext.Merge(instanceStats.tiflashScanContext) + totalTasks += instanceStats.totalTasks } return } @@ -414,7 +444,7 @@ func (crs *CopRuntimeStats) String() string { return "" } - procTimes, totalTime, totalTasks, totalLoops, totalThreads := crs.MergeBasicStats() + procTimes, totalTime, totalTasks, totalLoops, totalThreads, totalTiFlashScanContext := crs.MergeBasicStats() avgTime := time.Duration(totalTime.Nanoseconds() / int64(totalTasks)) isTiFlashCop := crs.storeType == "tiflash" @@ -423,6 +453,9 @@ func (crs *CopRuntimeStats) String() string { buf.WriteString(fmt.Sprintf("%v_task:{time:%v, loops:%d", crs.storeType, FormatDuration(procTimes[0]), totalLoops)) if isTiFlashCop { buf.WriteString(fmt.Sprintf(", threads:%d}", totalThreads)) + if !totalTiFlashScanContext.Empty() { + buf.WriteString(", " + totalTiFlashScanContext.String()) + } } else { buf.WriteString("}") } @@ -434,6 +467,9 @@ func (crs *CopRuntimeStats) String() string { FormatDuration(procTimes[n*4/5]), FormatDuration(procTimes[n*19/20]), totalLoops, totalTasks)) if isTiFlashCop { buf.WriteString(fmt.Sprintf(", threads:%d}", totalThreads)) + if !totalTiFlashScanContext.Empty() { + buf.WriteString(", " + totalTiFlashScanContext.String()) + } } else { buf.WriteString("}") } @@ -481,6 +517,10 @@ const ( TpBasicCopRunTimeStats // TpUpdateRuntimeStats is the tp for UpdateRuntimeStats TpUpdateRuntimeStats + // TpFKCheckRuntimeStats is the tp for FKCheckRuntimeStats + TpFKCheckRuntimeStats + // TpFKCascadeRuntimeStats is the tp for FKCascadeRuntimeStats + TpFKCascadeRuntimeStats ) // RuntimeStats is used to express the executor runtime information. @@ -491,6 +531,56 @@ type RuntimeStats interface { Tp() int } +// TiFlashScanContext is used to express the table scan information in tiflash +type TiFlashScanContext struct { + totalDmfileScannedPacks uint64 + totalDmfileScannedRows uint64 + totalDmfileSkippedPacks uint64 + totalDmfileSkippedRows uint64 + totalDmfileRoughSetIndexLoadTimeMs uint64 + totalDmfileReadTimeMs uint64 + totalCreateSnapshotTimeMs uint64 + totalLocalRegionNum uint64 + totalRemoteRegionNum uint64 +} + +// Clone implements the deep copy of * TiFlashshScanContext +func (context *TiFlashScanContext) Clone() TiFlashScanContext { + return TiFlashScanContext{ + totalDmfileScannedPacks: context.totalDmfileScannedPacks, + totalDmfileScannedRows: context.totalDmfileScannedRows, + totalDmfileSkippedPacks: context.totalDmfileSkippedPacks, + totalDmfileSkippedRows: context.totalDmfileSkippedRows, + totalDmfileRoughSetIndexLoadTimeMs: context.totalDmfileRoughSetIndexLoadTimeMs, + totalDmfileReadTimeMs: context.totalDmfileReadTimeMs, + totalCreateSnapshotTimeMs: context.totalCreateSnapshotTimeMs, + totalLocalRegionNum: context.totalLocalRegionNum, + totalRemoteRegionNum: context.totalRemoteRegionNum, + } +} +func (context *TiFlashScanContext) String() string { + return fmt.Sprintf("tiflash_scan:{dtfile:{total_scanned_packs:%d, total_skipped_packs:%d, total_scanned_rows:%d, total_skipped_rows:%d, total_rs_index_load_time: %dms, total_read_time: %dms}, total_create_snapshot_time: %dms, total_local_region_num: %d, total_remote_region_num: %d}", context.totalDmfileScannedPacks, context.totalDmfileSkippedPacks, context.totalDmfileScannedRows, context.totalDmfileSkippedRows, context.totalDmfileRoughSetIndexLoadTimeMs, context.totalDmfileReadTimeMs, context.totalCreateSnapshotTimeMs, context.totalLocalRegionNum, context.totalRemoteRegionNum) +} + +// Merge make sum to merge the information in TiFlashScanContext +func (context *TiFlashScanContext) Merge(other TiFlashScanContext) { + context.totalDmfileScannedPacks += other.totalDmfileScannedPacks + context.totalDmfileScannedRows += other.totalDmfileScannedRows + context.totalDmfileSkippedPacks += other.totalDmfileSkippedPacks + context.totalDmfileSkippedRows += other.totalDmfileSkippedRows + context.totalDmfileRoughSetIndexLoadTimeMs += other.totalDmfileRoughSetIndexLoadTimeMs + context.totalDmfileReadTimeMs += other.totalDmfileReadTimeMs + context.totalCreateSnapshotTimeMs += other.totalCreateSnapshotTimeMs + context.totalLocalRegionNum += other.totalLocalRegionNum + context.totalRemoteRegionNum += other.totalRemoteRegionNum +} + +// Empty check whether TiFlashScanContext is Empty, if scan no pack and skip no pack, we regard it as empty +func (context *TiFlashScanContext) Empty() bool { + res := (context.totalDmfileScannedPacks == 0 && context.totalDmfileSkippedPacks == 0) + return res +} + // BasicRuntimeStats is the basic runtime stats. type BasicRuntimeStats struct { // executor's Next() called times. @@ -499,6 +589,8 @@ type BasicRuntimeStats struct { consume int64 // executor return row count. rows int64 + // executor extra infos + tiflashScanContext TiFlashScanContext } // GetActRows return total rows of BasicRuntimeStats. @@ -509,9 +601,10 @@ func (e *BasicRuntimeStats) GetActRows() int64 { // Clone implements the RuntimeStats interface. func (e *BasicRuntimeStats) Clone() RuntimeStats { return &BasicRuntimeStats{ - loop: e.loop, - consume: e.consume, - rows: e.rows, + loop: e.loop, + consume: e.consume, + rows: e.rows, + tiflashScanContext: e.tiflashScanContext.Clone(), } } @@ -524,6 +617,7 @@ func (e *BasicRuntimeStats) Merge(rs RuntimeStats) { e.loop += tmp.loop e.consume += tmp.consume e.rows += tmp.rows + e.tiflashScanContext.Merge(tmp.tiflashScanContext) } // Tp implements the RuntimeStats interface. @@ -533,65 +627,33 @@ func (*BasicRuntimeStats) Tp() int { // RootRuntimeStats is the executor runtime stats that combine with multiple runtime stats. type RootRuntimeStats struct { - basics []*BasicRuntimeStats - groupRss [][]RuntimeStats -} - -// GetActRows return total rows of RootRuntimeStats. -func (e *RootRuntimeStats) GetActRows() int64 { - num := int64(0) - for _, basic := range e.basics { - num += basic.GetActRows() - } - return num + basic *BasicRuntimeStats + groupRss []RuntimeStats } -// MergeBasicStats merges BasicRuntimeStats in the RootRuntimeStats into single one. -func (e *RootRuntimeStats) MergeBasicStats() *BasicRuntimeStats { - if len(e.basics) == 0 { - return nil - } - basic := e.basics[0].Clone().(*BasicRuntimeStats) - for i := 1; i < len(e.basics); i++ { - basic.Merge(e.basics[i]) - } - return basic +// NewRootRuntimeStats returns a new RootRuntimeStats +func NewRootRuntimeStats() *RootRuntimeStats { + return &RootRuntimeStats{} } -// MergeGroupStats merges every slice in e.groupRss into single RuntimeStats. -func (e *RootRuntimeStats) MergeGroupStats() (res []RuntimeStats) { - if len(e.groupRss) == 0 { - return nil - } - for _, rss := range e.groupRss { - if len(rss) == 0 { - continue - } else if len(rss) == 1 { - res = append(res, rss[0]) - continue - } - rs := rss[0].Clone() - for i := 1; i < len(rss); i++ { - rs.Merge(rss[i]) - } - res = append(res, rs) +// GetActRows return total rows of RootRuntimeStats. +func (e *RootRuntimeStats) GetActRows() int64 { + if e.basic == nil { + return 0 } - return + return e.basic.rows } // MergeStats merges stats in the RootRuntimeStats and return the stats suitable for display directly. func (e *RootRuntimeStats) MergeStats() (basic *BasicRuntimeStats, groups []RuntimeStats) { - basic = e.MergeBasicStats() - groups = e.MergeGroupStats() - return + return e.basic, e.groupRss } // String implements the RuntimeStats interface. func (e *RootRuntimeStats) String() string { basic, groups := e.MergeStats() strs := make([]string, 0, len(groups)+1) - basicStr := basic.String() - if len(basicStr) > 0 { + if basic != nil { strs = append(strs, basic.String()) } for _, group := range groups { @@ -635,9 +697,9 @@ func (e *BasicRuntimeStats) GetTime() int64 { // RuntimeStatsColl collects executors's execution info. type RuntimeStatsColl struct { - mu sync.Mutex rootStats map[int]*RootRuntimeStats copStats map[int]*CopRuntimeStats + mu sync.Mutex } // NewRuntimeStatsColl creates new executor collector. @@ -665,38 +727,46 @@ func (e *RuntimeStatsColl) RegisterStats(planID int, info RuntimeStats) { e.mu.Lock() stats, ok := e.rootStats[planID] if !ok { - stats = &RootRuntimeStats{} + stats = NewRootRuntimeStats() e.rootStats[planID] = stats } - if basic, ok := info.(*BasicRuntimeStats); ok { - stats.basics = append(stats.basics, basic) - } else { - tp := info.Tp() - found := false - for i, rss := range stats.groupRss { - if len(rss) == 0 { - continue - } - if rss[0].Tp() == tp { - stats.groupRss[i] = append(stats.groupRss[i], info) - found = true - break - } - } - if !found { - stats.groupRss = append(stats.groupRss, []RuntimeStats{info}) + tp := info.Tp() + found := false + for _, rss := range stats.groupRss { + if rss.Tp() == tp { + rss.Merge(info) + found = true + break } } + if !found { + stats.groupRss = append(stats.groupRss, info.Clone()) + } e.mu.Unlock() } +// GetBasicRuntimeStats gets basicRuntimeStats for a executor. +func (e *RuntimeStatsColl) GetBasicRuntimeStats(planID int) *BasicRuntimeStats { + e.mu.Lock() + defer e.mu.Unlock() + stats, ok := e.rootStats[planID] + if !ok { + stats = NewRootRuntimeStats() + e.rootStats[planID] = stats + } + if stats.basic == nil { + stats.basic = &BasicRuntimeStats{} + } + return stats.basic +} + // GetRootStats gets execStat for a executor. func (e *RuntimeStatsColl) GetRootStats(planID int) *RootRuntimeStats { e.mu.Lock() defer e.mu.Unlock() runtimeStats, exists := e.rootStats[planID] if !exists { - runtimeStats = &RootRuntimeStats{} + runtimeStats = NewRootRuntimeStats() e.rootStats[planID] = runtimeStats } return runtimeStats @@ -720,7 +790,7 @@ func (e *RuntimeStatsColl) GetOrCreateCopStats(planID int, storeType string) *Co copStats, ok := e.copStats[planID] if !ok { copStats = &CopRuntimeStats{ - stats: make(map[string][]*basicCopRuntimeStats), + stats: make(map[string]*basicCopRuntimeStats), scanDetail: &util.ScanDetail{}, storeType: storeType, } @@ -786,10 +856,10 @@ func NewConcurrencyInfo(name string, num int) *ConcurrencyInfo { // RuntimeStatsWithConcurrencyInfo is the BasicRuntimeStats with ConcurrencyInfo. type RuntimeStatsWithConcurrencyInfo struct { - // protect concurrency - sync.Mutex // executor concurrency information concurrency []*ConcurrencyInfo + // protect concurrency + sync.Mutex } // Tp implements the RuntimeStats interface. @@ -840,8 +910,8 @@ func (*RuntimeStatsWithConcurrencyInfo) Merge(RuntimeStats) {} // RuntimeStatsWithCommit is the RuntimeStats with commit detail. type RuntimeStatsWithCommit struct { Commit *util.CommitDetails - TxnCnt int LockKeys *util.LockKeysDetails + TxnCnt int } // Tp implements the RuntimeStats interface. diff --git a/util/execdetails/execdetails_test.go b/util/execdetails/execdetails_test.go index 1f14f9f933509..21dd8ec8a9a50 100644 --- a/util/execdetails/execdetails_test.go +++ b/util/execdetails/execdetails_test.go @@ -109,10 +109,10 @@ func TestString(t *testing.T) { RocksdbBlockReadByte: 100, RocksdbBlockReadDuration: time.Millisecond, }, - TimeDetail: util.TimeDetail{ + DetailsNeedP90: DetailsNeedP90{TimeDetail: util.TimeDetail{ ProcessTime: 2*time.Second + 5*time.Millisecond, WaitTime: time.Second, - }, + }}, } expected := "Cop_time: 1.003 Process_time: 2.005 Wait_time: 1 Backoff_time: 1 Request_count: 1 Prewrite_time: 1 Commit_time: " + "1 Get_commit_ts_time: 1 Get_latest_ts_time: 1 Commit_backoff_time: 1 " + @@ -135,9 +135,20 @@ func mockExecutorExecutionSummary(TimeProcessedNs, NumProducedRows, NumIteration NumIterations: &NumIterations, XXX_unrecognized: nil} } -func mockExecutorExecutionSummaryForTiFlash(TimeProcessedNs, NumProducedRows, NumIterations, Concurrency uint64, ExecutorID string) *tipb.ExecutorExecutionSummary { +func mockExecutorExecutionSummaryForTiFlash(TimeProcessedNs, NumProducedRows, NumIterations, Concurrency, totalDmfileScannedPacks, totalDmfileScannedRows, totalDmfileSkippedPacks, totalDmfileSkippedRows, totalDmfileRoughSetIndexLoadTimeMs, totalDmfileReadTimeMs, totalCreateSnapshotTimeMs uint64, totalLocalRegionNum uint64, totalRemoteRegionNum uint64, ExecutorID string) *tipb.ExecutorExecutionSummary { + tiflashScanContext := tipb.TiFlashScanContext{ + TotalDmfileScannedPacks: &totalDmfileScannedPacks, + TotalDmfileSkippedPacks: &totalDmfileSkippedPacks, + TotalDmfileScannedRows: &totalDmfileScannedRows, + TotalDmfileSkippedRows: &totalDmfileSkippedRows, + TotalDmfileRoughSetIndexLoadTimeMs: &totalDmfileRoughSetIndexLoadTimeMs, + TotalDmfileReadTimeMs: &totalDmfileReadTimeMs, + TotalCreateSnapshotTimeMs: &totalCreateSnapshotTimeMs, + TotalLocalRegionNum: &totalLocalRegionNum, + TotalRemoteRegionNum: &totalRemoteRegionNum, + } return &tipb.ExecutorExecutionSummary{TimeProcessedNs: &TimeProcessedNs, NumProducedRows: &NumProducedRows, - NumIterations: &NumIterations, Concurrency: &Concurrency, ExecutorId: &ExecutorID, XXX_unrecognized: nil} + NumIterations: &NumIterations, Concurrency: &Concurrency, ExecutorId: &ExecutorID, DetailInfo: &tipb.ExecutorExecutionSummary_TiflashScanContext{TiflashScanContext: &tiflashScanContext}, XXX_unrecognized: nil} } func TestCopRuntimeStats(t *testing.T) { @@ -170,9 +181,11 @@ func TestCopRuntimeStats(t *testing.T) { copStats := cop.stats["8.8.8.8"] require.NotNil(t, copStats) - copStats[0].SetRowNum(10) - copStats[0].Record(time.Second, 10) - require.Equal(t, "time:1s, loops:2", copStats[0].String()) + newCopStats := &basicCopRuntimeStats{} + newCopStats.SetRowNum(10) + newCopStats.Record(time.Second, 10) + copStats.Merge(newCopStats) + require.Equal(t, "time:1s, loops:2", copStats.String()) require.Equal(t, "tikv_task:{proc max:4ns, min:3ns, avg: 3ns, p80:4ns, p95:4ns, iters:7, tasks:2}", stats.GetOrCreateCopStats(aggID, "tikv").String()) rootStats := stats.GetRootStats(tableReaderID) @@ -184,7 +197,7 @@ func TestCopRuntimeStats(t *testing.T) { cop.scanDetail.RocksdbKeySkippedCount = 0 cop.scanDetail.RocksdbBlockReadCount = 0 // Print all fields even though the value of some fields is 0. - str := "tikv_task:{proc max:1s, min:2ns, avg: 500ms, p80:1s, p95:1s, iters:4, tasks:2}, " + + str := "tikv_task:{proc max:1s, min:1ns, avg: 500ms, p80:1s, p95:1s, iters:4, tasks:2}, " + "scan_detail: {total_keys: 15, rocksdb: {delete_skipped_count: 5, block: {cache_hit_count: 10, read_byte: 100 Bytes}}}" require.Equal(t, str, cop.String()) @@ -197,10 +210,10 @@ func TestCopRuntimeStatsForTiFlash(t *testing.T) { tableScanID := 1 aggID := 2 tableReaderID := 3 - stats.RecordOneCopTask(aggID, "tiflash", "8.8.8.8", mockExecutorExecutionSummaryForTiFlash(1, 1, 1, 1, "tablescan_"+strconv.Itoa(tableScanID))) - stats.RecordOneCopTask(aggID, "tiflash", "8.8.8.9", mockExecutorExecutionSummaryForTiFlash(2, 2, 2, 1, "tablescan_"+strconv.Itoa(tableScanID))) - stats.RecordOneCopTask(tableScanID, "tiflash", "8.8.8.8", mockExecutorExecutionSummaryForTiFlash(3, 3, 3, 1, "aggregation_"+strconv.Itoa(aggID))) - stats.RecordOneCopTask(tableScanID, "tiflash", "8.8.8.9", mockExecutorExecutionSummaryForTiFlash(4, 4, 4, 1, "aggregation_"+strconv.Itoa(aggID))) + stats.RecordOneCopTask(aggID, "tiflash", "8.8.8.8", mockExecutorExecutionSummaryForTiFlash(1, 1, 1, 1, 1, 8192, 0, 0, 15, 200, 40, 10, 4, "tablescan_"+strconv.Itoa(tableScanID))) + stats.RecordOneCopTask(aggID, "tiflash", "8.8.8.9", mockExecutorExecutionSummaryForTiFlash(2, 2, 2, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, "tablescan_"+strconv.Itoa(tableScanID))) + stats.RecordOneCopTask(tableScanID, "tiflash", "8.8.8.8", mockExecutorExecutionSummaryForTiFlash(3, 3, 3, 1, 2, 12000, 1, 6000, 60, 1000, 20, 5, 1, "aggregation_"+strconv.Itoa(aggID))) + stats.RecordOneCopTask(tableScanID, "tiflash", "8.8.8.9", mockExecutorExecutionSummaryForTiFlash(4, 4, 4, 1, 1, 8192, 10, 80000, 40, 2000, 30, 1, 1, "aggregation_"+strconv.Itoa(aggID))) scanDetail := &util.ScanDetail{ TotalKeys: 10, ProcessedKeys: 10, @@ -214,15 +227,15 @@ func TestCopRuntimeStatsForTiFlash(t *testing.T) { require.True(t, stats.ExistsCopStats(tableScanID)) cop := stats.GetOrCreateCopStats(tableScanID, "tiflash") - require.Equal(t, "tiflash_task:{proc max:2ns, min:1ns, avg: 1ns, p80:2ns, p95:2ns, iters:3, tasks:2, threads:2}", cop.String()) + require.Equal(t, "tiflash_task:{proc max:2ns, min:1ns, avg: 1ns, p80:2ns, p95:2ns, iters:3, tasks:2, threads:2}, tiflash_scan:{dtfile:{total_scanned_packs:1, total_skipped_packs:0, total_scanned_rows:8192, total_skipped_rows:0, total_rs_index_load_time: 15ms, total_read_time: 202ms}, total_create_snapshot_time: 40ms, total_local_region_num: 10, total_remote_region_num: 4}", cop.String()) copStats := cop.stats["8.8.8.8"] require.NotNil(t, copStats) - copStats[0].SetRowNum(10) - copStats[0].Record(time.Second, 10) - require.Equal(t, "time:1s, loops:2, threads:1", copStats[0].String()) - expected := "tiflash_task:{proc max:4ns, min:3ns, avg: 3ns, p80:4ns, p95:4ns, iters:7, tasks:2, threads:2}" + copStats.SetRowNum(10) + copStats.Record(time.Second, 10) + require.Equal(t, "time:1s, loops:2, threads:1, tiflash_scan:{dtfile:{total_scanned_packs:1, total_skipped_packs:0, total_scanned_rows:8192, total_skipped_rows:0, total_rs_index_load_time: 15ms, total_read_time: 200ms}, total_create_snapshot_time: 40ms, total_local_region_num: 10, total_remote_region_num: 4}", copStats.String()) + expected := "tiflash_task:{proc max:4ns, min:3ns, avg: 3ns, p80:4ns, p95:4ns, iters:7, tasks:2, threads:2}, tiflash_scan:{dtfile:{total_scanned_packs:3, total_skipped_packs:11, total_scanned_rows:20192, total_skipped_rows:86000, total_rs_index_load_time: 100ms, total_read_time: 3000ms}, total_create_snapshot_time: 50ms, total_local_region_num: 6, total_remote_region_num: 2}" require.Equal(t, expected, stats.GetOrCreateCopStats(aggID, "tiflash").String()) rootStats := stats.GetRootStats(tableReaderID) @@ -376,17 +389,14 @@ func TestRuntimeStatsWithCommit(t *testing.T) { } func TestRootRuntimeStats(t *testing.T) { - basic1 := &BasicRuntimeStats{} - basic2 := &BasicRuntimeStats{} - basic1.Record(time.Second, 20) - basic2.Record(time.Second*2, 30) pid := 1 stmtStats := NewRuntimeStatsColl(nil) - stmtStats.RegisterStats(pid, basic1) - stmtStats.RegisterStats(pid, basic2) + basic1 := stmtStats.GetBasicRuntimeStats(pid) + basic2 := stmtStats.GetBasicRuntimeStats(pid) + basic1.Record(time.Second, 20) + basic2.Record(time.Second*2, 30) concurrency := &RuntimeStatsWithConcurrencyInfo{} concurrency.SetConcurrencyInfo(NewConcurrencyInfo("worker", 15)) - stmtStats.RegisterStats(pid, concurrency) commitDetail := &util.CommitDetails{ GetCommitTsTime: time.Second, PrewriteTime: time.Second, @@ -396,6 +406,7 @@ func TestRootRuntimeStats(t *testing.T) { PrewriteRegionNum: 5, TxnRetry: 2, } + stmtStats.RegisterStats(pid, concurrency) stmtStats.RegisterStats(pid, &RuntimeStatsWithCommit{ Commit: commitDetail, }) diff --git a/util/execdetails/main_test.go b/util/execdetails/main_test.go index ee97941b29a63..0299931b53e97 100644 --- a/util/execdetails/main_test.go +++ b/util/execdetails/main_test.go @@ -24,6 +24,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/expensivequery/expensivequerey_test.go b/util/expensivequery/expensivequerey_test.go index 2d98435339d46..d7a83b14019fc 100644 --- a/util/expensivequery/expensivequerey_test.go +++ b/util/expensivequery/expensivequerey_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/expensivequery/expensivequery.go b/util/expensivequery/expensivequery.go index 51513cdbe50b0..88eb24bdd01dd 100644 --- a/util/expensivequery/expensivequery.go +++ b/util/expensivequery/expensivequery.go @@ -62,9 +62,9 @@ func (eqh *Handle) Run() { } costTime := time.Since(info.Time) - if !info.ExceedExpensiveTimeThresh && costTime >= time.Second*time.Duration(threshold) && log.GetLevel() <= zapcore.WarnLevel { - logExpensiveQuery(costTime, info) - info.ExceedExpensiveTimeThresh = true + if time.Since(info.ExpensiveLogTime) > 60*time.Second && costTime >= time.Second*time.Duration(threshold) && log.GetLevel() <= zapcore.WarnLevel { + logExpensiveQuery(costTime, info, "expensive_query") + info.ExpensiveLogTime = time.Now() } if info.MaxExecutionTime > 0 && costTime > time.Duration(info.MaxExecutionTime)*time.Millisecond { logutil.BgLogger().Warn("execution timeout, kill it", zap.Duration("costTime", costTime), @@ -106,10 +106,14 @@ func (eqh *Handle) LogOnQueryExceedMemQuota(connID uint64) { if !ok { return } - logExpensiveQuery(time.Since(info.Time), info) + logExpensiveQuery(time.Since(info.Time), info, "memory exceeds quota") } // logExpensiveQuery logs the queries which exceed the time threshold or memory threshold. -func logExpensiveQuery(costTime time.Duration, info *util.ProcessInfo) { - logutil.BgLogger().Warn("expensive_query", util.GenLogFields(costTime, info, true)...) +func logExpensiveQuery(costTime time.Duration, info *util.ProcessInfo, msg string) { + fields := util.GenLogFields(costTime, info, true) + if fields == nil { + return + } + logutil.BgLogger().Warn(msg, fields...) } diff --git a/util/fastrand/main_test.go b/util/fastrand/main_test.go index cf275eca82116..3aadf6e7f0a25 100644 --- a/util/fastrand/main_test.go +++ b/util/fastrand/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/format/main_test.go b/util/format/main_test.go index 4755a0230915c..080132ddf8844 100644 --- a/util/format/main_test.go +++ b/util/format/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/gctuner/mem.go b/util/gctuner/mem.go index 68c02db8a7c66..9fb85f1d801cb 100644 --- a/util/gctuner/mem.go +++ b/util/gctuner/mem.go @@ -15,12 +15,10 @@ package gctuner import ( - "runtime" + "github.com/pingcap/tidb/util/memory" ) -var memStats runtime.MemStats - func readMemoryInuse() uint64 { - runtime.ReadMemStats(&memStats) + memStats := memory.ForceReadMemStats() return memStats.HeapInuse } diff --git a/util/gctuner/memory_limit_tuner.go b/util/gctuner/memory_limit_tuner.go index 7a9035a387b39..1679e012579d0 100644 --- a/util/gctuner/memory_limit_tuner.go +++ b/util/gctuner/memory_limit_tuner.go @@ -16,7 +16,6 @@ package gctuner import ( "math" - "runtime" "runtime/debug" "time" @@ -39,14 +38,16 @@ type memoryLimitTuner struct { nextGCTriggeredByMemoryLimit atomicutil.Bool } +// fallbackPercentage indicates the fallback memory limit percentage when turning. +const fallbackPercentage float64 = 1.1 + // tuning check the memory nextGC and judge whether this GC is trigger by memory limit. // Go runtime ensure that it will be called serially. func (t *memoryLimitTuner) tuning() { if !t.isTuning.Load() { return } - r := &runtime.MemStats{} - runtime.ReadMemStats(r) + r := memory.ForceReadMemStats() gogc := util.GetGOGC() ratio := float64(100+gogc) / 100 // This `if` checks whether the **last** GC was triggered by MemoryLimit as far as possible. @@ -61,7 +62,9 @@ func (t *memoryLimitTuner) tuning() { if float64(r.HeapInuse)*ratio > float64(debug.SetMemoryLimit(-1)) { if t.nextGCTriggeredByMemoryLimit.Load() && t.waitingReset.CompareAndSwap(false, true) { go func() { - debug.SetMemoryLimit(math.MaxInt64) + memory.MemoryLimitGCLast.Store(time.Now()) + memory.MemoryLimitGCTotal.Add(1) + debug.SetMemoryLimit(t.calcMemoryLimit(fallbackPercentage)) resetInterval := 1 * time.Minute // Wait 1 minute and set back, to avoid frequent GC failpoint.Inject("testMemoryLimitTuner", func(val failpoint.Value) { if val, ok := val.(bool); val && ok { @@ -69,23 +72,27 @@ func (t *memoryLimitTuner) tuning() { } }) time.Sleep(resetInterval) - debug.SetMemoryLimit(t.calcMemoryLimit()) + debug.SetMemoryLimit(t.calcMemoryLimit(t.GetPercentage())) for !t.waitingReset.CompareAndSwap(true, false) { continue } }() + memory.TriggerMemoryLimitGC.Store(true) } t.nextGCTriggeredByMemoryLimit.Store(true) } else { t.nextGCTriggeredByMemoryLimit.Store(false) + memory.TriggerMemoryLimitGC.Store(false) } } -func (t *memoryLimitTuner) start() { - t.finalizer = newFinalizer(t.tuning) // start tuning +// Start starts the memory limit tuner. +func (t *memoryLimitTuner) Start() { + t.finalizer = newFinalizer(t.tuning) // Start tuning } -func (t *memoryLimitTuner) stop() { +// Stop stops the memory limit tuner. +func (t *memoryLimitTuner) Stop() { t.finalizer.stop() } @@ -102,26 +109,27 @@ func (t *memoryLimitTuner) GetPercentage() float64 { // UpdateMemoryLimit updates the memory limit. // This function should be called when `tidb_server_memory_limit` or `tidb_server_memory_limit_gc_trigger` is modified. func (t *memoryLimitTuner) UpdateMemoryLimit() { - var memoryLimit int64 = math.MaxInt64 - if !EnableGOGCTuner.Load() { - memoryLimit = t.calcMemoryLimit() - } + var memoryLimit = t.calcMemoryLimit(t.GetPercentage()) if memoryLimit == math.MaxInt64 { t.isTuning.Store(false) + memoryLimit = initGOMemoryLimitValue } else { t.isTuning.Store(true) } debug.SetMemoryLimit(memoryLimit) } -func (t *memoryLimitTuner) calcMemoryLimit() int64 { - memoryLimit := int64(float64(memory.ServerMemoryLimit.Load()) * t.percentage.Load()) // `tidb_server_memory_limit` * `tidb_server_memory_limit_gc_trigger` +func (*memoryLimitTuner) calcMemoryLimit(percentage float64) int64 { + memoryLimit := int64(float64(memory.ServerMemoryLimit.Load()) * percentage) // `tidb_server_memory_limit` * `tidb_server_memory_limit_gc_trigger` if memoryLimit == 0 { memoryLimit = math.MaxInt64 } return memoryLimit } +var initGOMemoryLimitValue int64 + func init() { - GlobalMemoryLimitTuner.start() + initGOMemoryLimitValue = debug.SetMemoryLimit(-1) + GlobalMemoryLimitTuner.Start() } diff --git a/util/gctuner/memory_limit_tuner_test.go b/util/gctuner/memory_limit_tuner_test.go index 47d1d8409d8b5..c6f63215c01dd 100644 --- a/util/gctuner/memory_limit_tuner_test.go +++ b/util/gctuner/memory_limit_tuner_test.go @@ -15,7 +15,6 @@ package gctuner import ( - "math" "runtime" "runtime/debug" "testing" @@ -76,10 +75,9 @@ func TestGlobalMemoryTuner(t *testing.T) { checkNextGCEqualMemoryLimit := func() { runtime.ReadMemStats(r) nextGC := r.NextGC - memoryLimit := GlobalMemoryLimitTuner.calcMemoryLimit() - // In golang source, nextGC = memoryLimit - three parts memory. So check 90%~100% here. + memoryLimit := GlobalMemoryLimitTuner.calcMemoryLimit(GlobalMemoryLimitTuner.GetPercentage()) + // In golang source, nextGC = memoryLimit - three parts memory. require.True(t, nextGC < uint64(memoryLimit)) - require.True(t, nextGC > uint64(memoryLimit)/10*9) } memory600mb := allocator.alloc(600 << 20) @@ -91,7 +89,7 @@ func TestGlobalMemoryTuner(t *testing.T) { require.True(t, gcNum < getNowGCNum()) // Test waiting for reset time.Sleep(500 * time.Millisecond) - require.Equal(t, int64(math.MaxInt64), debug.SetMemoryLimit(-1)) + require.Equal(t, GlobalMemoryLimitTuner.calcMemoryLimit(fallbackPercentage), debug.SetMemoryLimit(-1)) gcNum = getNowGCNum() memory100mb := allocator.alloc(100 << 20) time.Sleep(100 * time.Millisecond) @@ -102,7 +100,7 @@ func TestGlobalMemoryTuner(t *testing.T) { runtime.GC() // Trigger GC in 80% again time.Sleep(500 * time.Millisecond) - require.Equal(t, GlobalMemoryLimitTuner.calcMemoryLimit(), debug.SetMemoryLimit(-1)) + require.Equal(t, GlobalMemoryLimitTuner.calcMemoryLimit(GlobalMemoryLimitTuner.GetPercentage()), debug.SetMemoryLimit(-1)) time.Sleep(100 * time.Millisecond) gcNum = getNowGCNum() checkNextGCEqualMemoryLimit() diff --git a/util/gctuner/tuner.go b/util/gctuner/tuner.go index 2ee3679ef2363..ec74f48ec4be0 100644 --- a/util/gctuner/tuner.go +++ b/util/gctuner/tuner.go @@ -23,22 +23,37 @@ import ( "github.com/pingcap/tidb/util" ) +var ( + maxGCPercent atomic.Uint32 + minGCPercent atomic.Uint32 + + // EnableGOGCTuner is to control whether enable the GOGC tuner. + EnableGOGCTuner atomic.Bool + + defaultGCPercent uint32 = 100 +) + const ( - // MaxGCPercent is the default max cost of memory. - MaxGCPercent uint32 = 500 - // MinGCPercent is the default min cost of memory. - MinGCPercent uint32 = 20 + defaultMaxGCPercent uint32 = 500 + defaultMinGCPercent uint32 = 100 ) -var defaultGCPercent uint32 = 100 +// SetMaxGCPercent sets the max cost of memory. +func SetMaxGCPercent(percent uint32) { + maxGCPercent.Store(percent) +} -// EnableGOGCTuner is to control whether enable the GOGC tuner. -var EnableGOGCTuner atomic.Bool +// SetMinGCPercent sets the max cost of memory. +func SetMinGCPercent(percent uint32) { + minGCPercent.Store(percent) +} func init() { if val, err := strconv.Atoi(os.Getenv("GOGC")); err == nil { defaultGCPercent = uint32(val) } + SetMinGCPercent(defaultMinGCPercent) + SetMaxGCPercent(defaultMaxGCPercent) } // SetDefaultGOGC is to set the default GOGC value. @@ -46,7 +61,7 @@ func SetDefaultGOGC() { util.SetGOGC(int(defaultGCPercent)) } -// Tuning sets the threshold of heap which will be respect by gc tuner. +// Tuning sets the threshold of heap which will be respect by gogc tuner. // When Tuning, the env GOGC will not be take effect. // threshold: disable tuning if threshold == 0 func Tuning(threshold uint64) { @@ -151,13 +166,13 @@ func calcGCPercent(inuse, threshold uint64) uint32 { } // inuse heap larger than threshold, use min percent if threshold <= inuse { - return MinGCPercent + return minGCPercent.Load() } gcPercent := uint32(math.Floor(float64(threshold-inuse) / float64(inuse) * 100)) - if gcPercent < MinGCPercent { - return MinGCPercent - } else if gcPercent > MaxGCPercent { - return MaxGCPercent + if gcPercent < minGCPercent.Load() { + return minGCPercent.Load() + } else if gcPercent > maxGCPercent.Load() { + return maxGCPercent.Load() } return gcPercent } diff --git a/util/gctuner/tuner_test.go b/util/gctuner/tuner_test.go index 153bf7368ab14..397f4a621c96a 100644 --- a/util/gctuner/tuner_test.go +++ b/util/gctuner/tuner_test.go @@ -25,7 +25,7 @@ var testHeap []byte func TestTuner(t *testing.T) { EnableGOGCTuner.Store(true) - memLimit := uint64(100 * 1024 * 1024) //100 MB + memLimit := uint64(1000 * 1024 * 1024) //1000 MB threshold := memLimit / 2 tn := newTuner(threshold) require.Equal(t, threshold, tn.threshold.Load()) @@ -37,15 +37,15 @@ func TestTuner(t *testing.T) { runtime.GC() for i := 0; i < 100; i++ { runtime.GC() - require.Equal(t, MaxGCPercent, tn.getGCPercent()) + require.Equal(t, maxGCPercent.Load(), tn.getGCPercent()) } // 1/4 threshold testHeap = make([]byte, threshold/4) for i := 0; i < 100; i++ { runtime.GC() - require.GreaterOrEqual(t, tn.getGCPercent(), uint32(100)) - require.LessOrEqual(t, tn.getGCPercent(), uint32(500)) + require.GreaterOrEqual(t, tn.getGCPercent(), maxGCPercent.Load()/2) + require.LessOrEqual(t, tn.getGCPercent(), maxGCPercent.Load()) } // 1/2 threshold @@ -53,8 +53,8 @@ func TestTuner(t *testing.T) { runtime.GC() for i := 0; i < 100; i++ { runtime.GC() - require.GreaterOrEqual(t, tn.getGCPercent(), uint32(50)) - require.LessOrEqual(t, tn.getGCPercent(), uint32(100)) + require.GreaterOrEqual(t, tn.getGCPercent(), minGCPercent.Load()) + require.LessOrEqual(t, tn.getGCPercent(), maxGCPercent.Load()/2) } // 3/4 threshold @@ -62,7 +62,7 @@ func TestTuner(t *testing.T) { runtime.GC() for i := 0; i < 100; i++ { runtime.GC() - require.Equal(t, MinGCPercent, tn.getGCPercent()) + require.Equal(t, minGCPercent.Load(), tn.getGCPercent()) } // out of threshold @@ -70,7 +70,7 @@ func TestTuner(t *testing.T) { runtime.GC() for i := 0; i < 100; i++ { runtime.GC() - require.Equal(t, MinGCPercent, tn.getGCPercent()) + require.Equal(t, minGCPercent.Load(), tn.getGCPercent()) } } @@ -81,13 +81,13 @@ func TestCalcGCPercent(t *testing.T) { require.Equal(t, defaultGCPercent, calcGCPercent(0, 1)) require.Equal(t, defaultGCPercent, calcGCPercent(1, 0)) - require.Equal(t, MaxGCPercent, calcGCPercent(1, 3*gb)) - require.Equal(t, MaxGCPercent, calcGCPercent(gb/10, 4*gb)) - require.Equal(t, MaxGCPercent, calcGCPercent(gb/2, 4*gb)) + require.Equal(t, maxGCPercent.Load(), calcGCPercent(1, 3*gb)) + require.Equal(t, maxGCPercent.Load(), calcGCPercent(gb/10, 4*gb)) + require.Equal(t, maxGCPercent.Load(), calcGCPercent(gb/2, 4*gb)) require.Equal(t, uint32(300), calcGCPercent(1*gb, 4*gb)) require.Equal(t, uint32(166), calcGCPercent(1.5*gb, 4*gb)) require.Equal(t, uint32(100), calcGCPercent(2*gb, 4*gb)) - require.Equal(t, uint32(33), calcGCPercent(3*gb, 4*gb)) - require.Equal(t, MinGCPercent, calcGCPercent(4*gb, 4*gb)) - require.Equal(t, MinGCPercent, calcGCPercent(5*gb, 4*gb)) + require.Equal(t, uint32(100), calcGCPercent(3*gb, 4*gb)) + require.Equal(t, minGCPercent.Load(), calcGCPercent(4*gb, 4*gb)) + require.Equal(t, minGCPercent.Load(), calcGCPercent(5*gb, 4*gb)) } diff --git a/util/gcutil/gcutil.go b/util/gcutil/gcutil.go index 0d3ae7da53ee2..9474cace52378 100644 --- a/util/gcutil/gcutil.go +++ b/util/gcutil/gcutil.go @@ -42,12 +42,12 @@ func CheckGCEnable(ctx sessionctx.Context) (enable bool, err error) { // DisableGC will disable GC enable variable. func DisableGC(ctx sessionctx.Context) error { - return ctx.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBGCEnable, variable.Off) + return ctx.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBGCEnable, variable.Off) } // EnableGC will enable GC enable variable. func EnableGC(ctx sessionctx.Context) error { - return ctx.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(variable.TiDBGCEnable, variable.On) + return ctx.GetSessionVars().GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.TiDBGCEnable, variable.On) } // ValidateSnapshot checks that the newly set snapshot time is after GC safe point time. diff --git a/util/generatedexpr/main_test.go b/util/generatedexpr/main_test.go index 13347ccf5d48d..fc8f011ecfa2b 100644 --- a/util/generatedexpr/main_test.go +++ b/util/generatedexpr/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/gpool/BUILD.bazel b/util/gpool/BUILD.bazel new file mode 100644 index 0000000000000..4f9eb753be57a --- /dev/null +++ b/util/gpool/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "gpool", + srcs = [ + "gpool.go", + "spinlock.go", + ], + importpath = "github.com/pingcap/tidb/util/gpool", + visibility = ["//visibility:public"], + deps = ["@org_uber_go_atomic//:atomic"], +) diff --git a/util/gpool/gpool.go b/util/gpool/gpool.go new file mode 100644 index 0000000000000..bd65eaca9f505 --- /dev/null +++ b/util/gpool/gpool.go @@ -0,0 +1,84 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gpool + +import ( + "errors" + "sync/atomic" + "time" + + atomicutil "go.uber.org/atomic" +) + +const ( + // DefaultCleanIntervalTime is the interval time to clean up goroutines. + DefaultCleanIntervalTime = 5 * time.Second + + // OPENED represents that the pool is opened. + OPENED = iota + + // CLOSED represents that the pool is closed. + CLOSED +) + +var ( + // ErrPoolClosed will be returned when submitting task to a closed pool. + ErrPoolClosed = errors.New("this pool has been closed") + + // ErrPoolOverload will be returned when the pool is full and no workers available. + ErrPoolOverload = errors.New("too many goroutines blocked on submit or Nonblocking is set") + + // ErrProducerClosed will be returned when the producer is closed. + ErrProducerClosed = errors.New("this producer has been closed") +) + +// BasePool is base class of pool +type BasePool struct { + name string + lastTuneTs atomicutil.Time + generator atomic.Uint64 +} + +// NewBasePool is to create a new BasePool. +func NewBasePool() BasePool { + return BasePool{ + lastTuneTs: *atomicutil.NewTime(time.Now()), + } +} + +// SetName is to set name. +func (p *BasePool) SetName(name string) { + p.name = name +} + +// Name is to get name. +func (p *BasePool) Name() string { + return p.name +} + +// NewTaskID is to get a new task ID. +func (p *BasePool) NewTaskID() uint64 { + return p.generator.Add(1) +} + +// LastTunerTs returns the last time when the pool was tuned. +func (p *BasePool) LastTunerTs() time.Time { + return p.lastTuneTs.Load() +} + +// SetLastTuneTs sets the last time when the pool was tuned. +func (p *BasePool) SetLastTuneTs(t time.Time) { + p.lastTuneTs.Store(t) +} diff --git a/util/gpool/spinlock.go b/util/gpool/spinlock.go new file mode 100644 index 0000000000000..acf7d15192416 --- /dev/null +++ b/util/gpool/spinlock.go @@ -0,0 +1,47 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gpool + +import ( + "runtime" + "sync" + "sync/atomic" +) + +type spinLock uint32 + +const maxBackoff = 16 + +func (sl *spinLock) Lock() { + backoff := 1 + for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) { + // Leverage the exponential backoff algorithm, see https://en.wikipedia.org/wiki/Exponential_backoff. + for i := 0; i < backoff; i++ { + runtime.Gosched() + } + if backoff < maxBackoff { + backoff <<= 1 + } + } +} + +func (sl *spinLock) Unlock() { + atomic.StoreUint32((*uint32)(sl), 0) +} + +// NewSpinLock instantiates a spin-lock. +func NewSpinLock() sync.Locker { + return new(spinLock) +} diff --git a/util/gpool/spmc/BUILD.bazel b/util/gpool/spmc/BUILD.bazel new file mode 100644 index 0000000000000..db4d724052666 --- /dev/null +++ b/util/gpool/spmc/BUILD.bazel @@ -0,0 +1,47 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "spmc", + srcs = [ + "option.go", + "spmcpool.go", + "worker.go", + "worker_loop_queue.go", + ], + importpath = "github.com/pingcap/tidb/util/gpool/spmc", + visibility = ["//visibility:public"], + deps = [ + "//resourcemanager", + "//resourcemanager/pooltask", + "//resourcemanager/util", + "//util/gpool", + "//util/logutil", + "@com_github_pingcap_errors//:errors", + "@com_github_pingcap_log//:log", + "@org_uber_go_atomic//:atomic", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "spmc_test", + srcs = [ + "main_test.go", + "spmcpool_benchmark_test.go", + "spmcpool_test.go", + "worker_loop_queue_test.go", + ], + embed = [":spmc"], + flaky = True, + race = "on", + deps = [ + "//resourcemanager/pooltask", + "//resourcemanager/util", + "//testkit/testsetup", + "//util", + "//util/gpool", + "@com_github_stretchr_testify//require", + "@org_uber_go_atomic//:atomic", + "@org_uber_go_goleak//:goleak", + ], +) diff --git a/util/gpool/spmc/main_test.go b/util/gpool/spmc/main_test.go new file mode 100644 index 0000000000000..381e5302598d5 --- /dev/null +++ b/util/gpool/spmc/main_test.go @@ -0,0 +1,27 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "testing" + + "github.com/pingcap/tidb/testkit/testsetup" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + testsetup.SetupForCommonTest() + goleak.VerifyTestMain(m) +} diff --git a/util/gpool/spmc/option.go b/util/gpool/spmc/option.go new file mode 100644 index 0000000000000..e317ce157b93d --- /dev/null +++ b/util/gpool/spmc/option.go @@ -0,0 +1,138 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "time" +) + +// Option represents the optional function. +type Option func(opts *Options) + +func loadOptions(options ...Option) *Options { + opts := DefaultOption() + for _, option := range options { + option(opts) + } + return opts +} + +// Options contains all options which will be applied when instantiating an pool. +type Options struct { + // PanicHandler is used to handle panics from each worker goroutine. + // if nil, panics will be thrown out again from worker goroutines. + PanicHandler func(interface{}) + + // ExpiryDuration is a period for the scavenger goroutine to clean up those expired workers, + // the scavenger scans all workers every `ExpiryDuration` and clean up those workers that haven't been + // used for more than `ExpiryDuration`. + ExpiryDuration time.Duration + + // LimitDuration is a period in the limit mode. + LimitDuration time.Duration + + // Max number of goroutine blocking on pool.Submit. + // 0 (default value) means no such limit. + MaxBlockingTasks int + + // When Nonblocking is true, Pool.AddProduce will never be blocked. + // ErrPoolOverload will be returned when Pool.Submit cannot be done at once. + // When Nonblocking is true, MaxBlockingTasks is inoperative. + Nonblocking bool +} + +// DefaultOption is the default option. +func DefaultOption() *Options { + return &Options{ + LimitDuration: 200 * time.Millisecond, + Nonblocking: true, + } +} + +// WithExpiryDuration sets up the interval time of cleaning up goroutines. +func WithExpiryDuration(expiryDuration time.Duration) Option { + return func(opts *Options) { + opts.ExpiryDuration = expiryDuration + } +} + +// WithMaxBlockingTasks sets up the maximum number of goroutines that are blocked when it reaches the capacity of pool. +func WithMaxBlockingTasks(maxBlockingTasks int) Option { + return func(opts *Options) { + opts.MaxBlockingTasks = maxBlockingTasks + } +} + +// WithNonblocking indicates that pool will return nil when there is no available workers. +func WithNonblocking(nonblocking bool) Option { + return func(opts *Options) { + opts.Nonblocking = nonblocking + } +} + +// WithPanicHandler sets up panic handler. +func WithPanicHandler(panicHandler func(interface{})) Option { + return func(opts *Options) { + opts.PanicHandler = panicHandler + } +} + +// TaskOption represents the optional function. +type TaskOption func(opts *TaskOptions) + +func loadTaskOptions(options ...TaskOption) *TaskOptions { + opts := new(TaskOptions) + for _, option := range options { + option(opts) + } + if opts.Concurrency == 0 { + opts.Concurrency = 1 + } + if opts.ResultChanLen == 0 { + opts.ResultChanLen = uint64(opts.Concurrency) + } + if opts.ResultChanLen == 0 { + opts.ResultChanLen = uint64(opts.Concurrency) + } + return opts +} + +// TaskOptions contains all options +type TaskOptions struct { + Concurrency int + ResultChanLen uint64 + TaskChanLen uint64 +} + +// WithResultChanLen is to set the length of result channel. +func WithResultChanLen(resultChanLen uint64) TaskOption { + return func(opts *TaskOptions) { + opts.ResultChanLen = resultChanLen + } +} + +// WithTaskChanLen is to set the length of task channel. +func WithTaskChanLen(taskChanLen uint64) TaskOption { + return func(opts *TaskOptions) { + opts.TaskChanLen = taskChanLen + } +} + +// WithConcurrency is to set the concurrency of task. +func WithConcurrency(c int) TaskOption { + return func(opts *TaskOptions) { + opts.Concurrency = c + } +} diff --git a/util/gpool/spmc/spmcpool.go b/util/gpool/spmc/spmcpool.go new file mode 100644 index 0000000000000..6644a0e895650 --- /dev/null +++ b/util/gpool/spmc/spmcpool.go @@ -0,0 +1,451 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "errors" + "sync" + "sync/atomic" + "time" + + "github.com/pingcap/log" + "github.com/pingcap/tidb/resourcemanager" + "github.com/pingcap/tidb/resourcemanager/pooltask" + "github.com/pingcap/tidb/resourcemanager/util" + "github.com/pingcap/tidb/util/gpool" + "github.com/pingcap/tidb/util/logutil" + atomicutil "go.uber.org/atomic" + "go.uber.org/zap" +) + +// Pool is a single producer, multiple consumer goroutine pool. +// T is the type of the task. We can treat it as input. +// U is the type of the result. We can treat it as output. +// C is the type of the const parameter. if Our task look like y = ax + b, C acts like b as const parameter. +// CT is the type of the context. It needs to be read/written parallel. +// TF is the type of the context getter. It is used to get a context. +// if we don't need to use CT/TF, we can define CT as any and TF as NilContext. +type Pool[T any, U any, C any, CT any, TF pooltask.Context[CT]] struct { + gpool.BasePool + workerCache sync.Pool + workers *loopQueue[T, U, C, CT, TF] + lock sync.Locker + cond *sync.Cond + taskCh chan *pooltask.TaskBox[T, U, C, CT, TF] + taskManager pooltask.TaskManager[T, U, C, CT, TF] + options *Options + stopCh chan struct{} + consumerFunc func(T, C, CT) U + capacity atomic.Int32 + running atomic.Int32 + state atomic.Int32 + waiting atomic.Int32 // waiting is the number of goroutines that are waiting for the pool to be available. + heartbeatDone atomic.Bool + + waitingTask atomicutil.Uint32 // waitingTask is the number of tasks that are waiting for the pool to be available. +} + +// NewSPMCPool create a single producer, multiple consumer goroutine pool. +func NewSPMCPool[T any, U any, C any, CT any, TF pooltask.Context[CT]](name string, size int32, component util.Component, options ...Option) (*Pool[T, U, C, CT, TF], error) { + opts := loadOptions(options...) + if expiry := opts.ExpiryDuration; expiry <= 0 { + opts.ExpiryDuration = gpool.DefaultCleanIntervalTime + } + result := &Pool[T, U, C, CT, TF]{ + BasePool: gpool.NewBasePool(), + taskCh: make(chan *pooltask.TaskBox[T, U, C, CT, TF], 128), + stopCh: make(chan struct{}), + lock: gpool.NewSpinLock(), + taskManager: pooltask.NewTaskManager[T, U, C, CT, TF](size), + options: opts, + } + result.SetName(name) + result.state.Store(int32(gpool.OPENED)) + result.workerCache.New = func() interface{} { + return &goWorker[T, U, C, CT, TF]{ + pool: result, + } + } + result.capacity.Add(size) + result.workers = newWorkerLoopQueue[T, U, C, CT, TF](int(size)) + result.cond = sync.NewCond(result.lock) + err := resourcemanager.InstanceResourceManager.Register(result, name, component) + if err != nil { + return nil, err + } + // Start a goroutine to clean up expired workers periodically. + go result.purgePeriodically() + return result, nil +} + +// purgePeriodically clears expired workers periodically which runs in an individual goroutine, as a scavenger. +func (p *Pool[T, U, C, CT, TF]) purgePeriodically() { + heartbeat := time.NewTicker(p.options.ExpiryDuration) + defer func() { + heartbeat.Stop() + p.heartbeatDone.Store(true) + }() + for { + select { + case <-heartbeat.C: + case <-p.stopCh: + return + } + + if p.IsClosed() { + break + } + + p.lock.Lock() + expiredWorkers := p.workers.retrieveExpiry(p.options.ExpiryDuration) + p.lock.Unlock() + + // Notify obsolete workers to stop. + // This notification must be outside the p.lock, since w.task + // may be blocking and may consume a lot of time if many workers + // are located on non-local CPUs. + for i := range expiredWorkers { + expiredWorkers[i].taskBoxCh <- nil + expiredWorkers[i] = nil + } + + // There might be a situation where all workers have been cleaned up(no worker is running), + // or another case where the pool capacity has been Tuned up, + // while some invokers still get stuck in "p.cond.Wait()", + // then it ought to wake all those invokers. + if p.Running() == 0 || (p.Waiting() > 0 && p.Free() > 0) || p.waitingTask.Load() > 0 { + p.cond.Broadcast() + } + } +} + +// Tune changes the capacity of this pool, note that it is noneffective to the infinite or pre-allocation pool. +func (p *Pool[T, U, C, CT, TF]) Tune(size int) { + capacity := p.Cap() + if capacity == -1 || size <= 0 || size == capacity { + return + } + p.SetLastTuneTs(time.Now()) + p.capacity.Store(int32(size)) + if size > capacity { + // boost + if size-capacity == 1 { + p.cond.Signal() + return + } + p.cond.Broadcast() + } +} + +// Running returns the number of workers currently running. +func (p *Pool[T, U, C, CT, TF]) Running() int { + return int(p.running.Load()) +} + +// Free returns the number of available goroutines to work, -1 indicates this pool is unlimited. +func (p *Pool[T, U, C, CT, TF]) Free() int { + c := p.Cap() + if c < 0 { + return -1 + } + return c - p.Running() +} + +// Waiting returns the number of tasks which are waiting be executed. +func (p *Pool[T, U, C, CT, TF]) Waiting() int { + return int(p.waiting.Load()) +} + +// IsClosed indicates whether the pool is closed. +func (p *Pool[T, U, C, CT, TF]) IsClosed() bool { + return p.state.Load() == gpool.CLOSED +} + +// Cap returns the capacity of this pool. +func (p *Pool[T, U, C, CT, TF]) Cap() int { + return int(p.capacity.Load()) +} + +func (p *Pool[T, U, C, CT, TF]) addRunning(delta int) { + p.running.Add(int32(delta)) +} + +func (p *Pool[T, U, C, CT, TF]) addWaiting(delta int) { + p.waiting.Add(int32(delta)) +} + +func (p *Pool[T, U, C, CT, TF]) addWaitingTask() { + p.waitingTask.Inc() +} + +func (p *Pool[T, U, C, CT, TF]) subWaitingTask() { + p.waitingTask.Dec() +} + +// release closes this pool and releases the worker queue. +func (p *Pool[T, U, C, CT, TF]) release() { + if !p.state.CompareAndSwap(gpool.OPENED, gpool.CLOSED) { + return + } + p.lock.Lock() + p.workers.reset() + p.lock.Unlock() + // There might be some callers waiting in retrieveWorker(), so we need to wake them up to prevent + // those callers blocking infinitely. + p.cond.Broadcast() + close(p.taskCh) +} + +func isClose(exitCh chan struct{}) bool { + select { + case <-exitCh: + return true + default: + } + return false +} + +// ReleaseAndWait is like Release, it waits all workers to exit. +func (p *Pool[T, U, C, CT, TF]) ReleaseAndWait() { + if p.IsClosed() || isClose(p.stopCh) { + return + } + + close(p.stopCh) + p.release() + defer resourcemanager.InstanceResourceManager.Unregister(p.Name()) + for { + // Wait for all workers to exit and all task to be completed. + if p.Running() == 0 && p.heartbeatDone.Load() && p.waitingTask.Load() == 0 { + return + } + } +} + +// SetConsumerFunc is to set ConsumerFunc which is to process the task. +func (p *Pool[T, U, C, CT, TF]) SetConsumerFunc(consumerFunc func(T, C, CT) U) { + p.consumerFunc = consumerFunc +} + +// AddProduceBySlice is to add Produce by a slice. +// Producer need to return ErrProducerClosed when to exit. +func (p *Pool[T, U, C, CT, TF]) AddProduceBySlice(producer func() ([]T, error), constArg C, contextFn TF, options ...TaskOption) (<-chan U, pooltask.TaskController[T, U, C, CT, TF]) { + opt := loadTaskOptions(options...) + taskID := p.NewTaskID() + var wg sync.WaitGroup + result := make(chan U, opt.ResultChanLen) + closeCh := make(chan struct{}) + inputCh := make(chan pooltask.Task[T], opt.TaskChanLen) + tc := pooltask.NewTaskController[T, U, C, CT, TF](p, taskID, closeCh, &wg, result) + p.taskManager.RegisterTask(taskID, int32(opt.Concurrency)) + for i := 0; i < opt.Concurrency; i++ { + err := p.run() + if err == gpool.ErrPoolClosed { + break + } + taskBox := pooltask.NewTaskBox[T, U, C, CT, TF](constArg, contextFn, &wg, inputCh, result, taskID) + p.addWaitingTask() + p.taskManager.AddSubTask(taskID, &taskBox) + p.taskCh <- &taskBox + } + go func() { + defer func() { + if r := recover(); r != nil { + logutil.BgLogger().Error("producer panic", zap.Any("recover", r), zap.Stack("stack")) + } + close(closeCh) + close(inputCh) + }() + for { + tasks, err := producer() + if err != nil { + if errors.Is(err, gpool.ErrProducerClosed) { + return + } + log.Error("producer error", zap.Error(err)) + return + } + for _, task := range tasks { + wg.Add(1) + task := pooltask.Task[T]{ + Task: task, + } + inputCh <- task + } + } + }() + return result, tc +} + +// AddProducer is to add producer. +// Producer need to return ErrProducerClosed when to exit. +func (p *Pool[T, U, C, CT, TF]) AddProducer(producer func() (T, error), constArg C, contextFn TF, options ...TaskOption) (<-chan U, pooltask.TaskController[T, U, C, CT, TF]) { + opt := loadTaskOptions(options...) + taskID := p.NewTaskID() + var wg sync.WaitGroup + result := make(chan U, opt.ResultChanLen) + closeCh := make(chan struct{}) + inputCh := make(chan pooltask.Task[T], opt.TaskChanLen) + p.taskManager.RegisterTask(taskID, int32(opt.Concurrency)) + tc := pooltask.NewTaskController[T, U, C, CT, TF](p, taskID, closeCh, &wg, result) + for i := 0; i < opt.Concurrency; i++ { + err := p.run() + if err == gpool.ErrPoolClosed { + break + } + p.addWaitingTask() + taskBox := pooltask.NewTaskBox[T, U, C, CT, TF](constArg, contextFn, &wg, inputCh, result, taskID) + p.taskManager.AddSubTask(taskID, &taskBox) + p.taskCh <- &taskBox + } + go func() { + defer func() { + if r := recover(); r != nil { + logutil.BgLogger().Error("producer panic", zap.Any("recover", r), zap.Stack("stack")) + } + close(closeCh) + close(inputCh) + }() + for { + task, err := producer() + if err != nil { + if errors.Is(err, gpool.ErrProducerClosed) { + return + } + log.Error("producer error", zap.Error(err)) + return + } + wg.Add(1) + t := pooltask.Task[T]{ + Task: task, + } + inputCh <- t + } + }() + return result, tc +} + +func (p *Pool[T, U, C, CT, TF]) run() error { + if p.IsClosed() { + return gpool.ErrPoolClosed + } + var w *goWorker[T, U, C, CT, TF] + if w = p.retrieveWorker(); w == nil { + return gpool.ErrPoolOverload + } + return nil +} + +// retrieveWorker returns an available worker to run the tasks. +func (p *Pool[T, U, C, CT, TF]) retrieveWorker() (w *goWorker[T, U, C, CT, TF]) { + spawnWorker := func() { + w = p.workerCache.Get().(*goWorker[T, U, C, CT, TF]) + w.taskBoxCh = p.taskCh + w.run() + } + + p.lock.Lock() + + w = p.workers.detach() + if w != nil { // first try to fetch the worker from the queue + p.lock.Unlock() + } else if capacity := p.Cap(); capacity == -1 || capacity > p.Running() { + // if the worker queue is empty and we don't run out of the pool capacity, + // then just spawn a new worker goroutine. + p.lock.Unlock() + spawnWorker() + } else { // otherwise, we'll have to keep them blocked and wait for at least one worker to be put back into pool. + if p.options.Nonblocking { + p.lock.Unlock() + return + } + retry: + if p.options.MaxBlockingTasks != 0 && p.Waiting() >= p.options.MaxBlockingTasks { + p.lock.Unlock() + return + } + p.addWaiting(1) + p.cond.Wait() // block and wait for an available worker + p.addWaiting(-1) + + if p.IsClosed() { + p.lock.Unlock() + return + } + + var nw int + if nw = p.Running(); nw == 0 { // awakened by the scavenger + p.lock.Unlock() + spawnWorker() + return + } + if w = p.workers.detach(); w == nil { + if nw < p.Cap() { + p.lock.Unlock() + spawnWorker() + return + } + goto retry + } + p.lock.Unlock() + } + return +} + +// revertWorker puts a worker back into free pool, recycling the goroutines. +func (p *Pool[T, U, C, CT, TF]) revertWorker(worker *goWorker[T, U, C, CT, TF]) bool { + if capacity := p.Cap(); capacity > 0 && p.Running() > capacity || p.IsClosed() { + p.cond.Broadcast() + return false + } + worker.recycleTime.Store(time.Now()) + p.lock.Lock() + + if p.IsClosed() { + p.lock.Unlock() + return false + } + + err := p.workers.insert(worker) + if err != nil { + p.lock.Unlock() + if err == errQueueIsFull && p.waitingTask.Load() > 0 { + return true + } + return false + } + + // Notify the invoker stuck in 'retrieveWorker()' of there is an available worker in the worker queue. + p.cond.Signal() + p.lock.Unlock() + return true +} + +// DeleteTask is to delete task. +// Please don't use it manually. +func (p *Pool[T, U, C, CT, TF]) DeleteTask(id uint64) { + p.taskManager.DeleteTask(id) +} + +// StopTask is to stop task by id +// Please don't use it manually. +func (p *Pool[T, U, C, CT, TF]) StopTask(id uint64) { + p.taskManager.StopTask(id) +} + +// ExitSubTask is to reduce the number of subtasks. +func (p *Pool[T, U, C, CT, TF]) ExitSubTask(id uint64) { + p.taskManager.ExitSubTask(id) +} diff --git a/util/gpool/spmc/spmcpool_benchmark_test.go b/util/gpool/spmc/spmcpool_benchmark_test.go new file mode 100644 index 0000000000000..2d2f39511ea1c --- /dev/null +++ b/util/gpool/spmc/spmcpool_benchmark_test.go @@ -0,0 +1,112 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "testing" + "time" + + "github.com/pingcap/tidb/resourcemanager/pooltask" + rmutil "github.com/pingcap/tidb/resourcemanager/util" + "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/gpool" +) + +const ( + RunTimes = 10000 + DefaultExpiredTime = 10 * time.Second +) + +func BenchmarkGPool(b *testing.B) { + p, err := NewSPMCPool[struct{}, struct{}, int, any, pooltask.NilContext]("test", 10, rmutil.UNKNOWN) + if err != nil { + b.Fatal(err) + } + defer p.ReleaseAndWait() + p.SetConsumerFunc(func(a struct{}, b int, c any) struct{} { + return struct{}{} + }) + b.ResetTimer() + for i := 0; i < b.N; i++ { + sema := make(chan struct{}, 10) + var wg util.WaitGroupWrapper + wg.Run(func() { + for j := 0; j < RunTimes; j++ { + sema <- struct{}{} + } + close(sema) + }) + producerFunc := func() (struct{}, error) { + _, ok := <-sema + if ok { + return struct{}{}, nil + } + return struct{}{}, gpool.ErrProducerClosed + } + resultCh, ctl := p.AddProducer(producerFunc, RunTimes, pooltask.NilContext{}, WithConcurrency(6), WithResultChanLen(10)) + exitCh := make(chan struct{}) + wg.Run(func() { + for { + select { + case <-resultCh: + case <-exitCh: + return + } + } + }) + ctl.Wait() + close(exitCh) + wg.Wait() + } +} + +func BenchmarkGoCommon(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + var wg util.WaitGroupWrapper + var wgp util.WaitGroupWrapper + sema := make(chan struct{}, 10) + result := make(chan struct{}, 10) + wg.Run(func() { + for j := 0; j < RunTimes; j++ { + sema <- struct{}{} + } + close(sema) + }) + + for n := 0; n < 6; n++ { + wg.Run(func() { + item, ok := <-sema + if !ok { + return + } + result <- item + }) + } + exitCh := make(chan struct{}) + wgp.Run(func() { + for { + select { + case <-result: + case <-exitCh: + return + } + } + }) + wg.Wait() + close(exitCh) + wgp.Wait() + } +} diff --git a/util/gpool/spmc/spmcpool_test.go b/util/gpool/spmc/spmcpool_test.go new file mode 100644 index 0000000000000..3036ad7412a3c --- /dev/null +++ b/util/gpool/spmc/spmcpool_test.go @@ -0,0 +1,335 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "sync" + "sync/atomic" + "testing" + + "github.com/pingcap/tidb/resourcemanager/pooltask" + rmutil "github.com/pingcap/tidb/resourcemanager/util" + "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/gpool" + "github.com/stretchr/testify/require" +) + +func TestPool(t *testing.T) { + type ConstArgs struct { + a int + } + myArgs := ConstArgs{a: 10} + // init the pool + // input type, output type, constArgs type + pool, err := NewSPMCPool[int, int, ConstArgs, any, pooltask.NilContext]("TestPool", 10, rmutil.UNKNOWN) + require.NoError(t, err) + pool.SetConsumerFunc(func(task int, constArgs ConstArgs, ctx any) int { + return task + constArgs.a + }) + taskCh := make(chan int, 10) + for i := 1; i < 11; i++ { + taskCh <- i + } + pfunc := func() (int, error) { + select { + case task := <-taskCh: + return task, nil + default: + return 0, gpool.ErrProducerClosed + } + } + // add new task + resultCh, control := pool.AddProducer(pfunc, myArgs, pooltask.NilContext{}, WithConcurrency(4)) + + var count atomic.Uint32 + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + for result := range resultCh { + count.Add(1) + require.Greater(t, result, 10) + } + }() + // Waiting task finishing + control.Wait() + wg.Wait() + require.Equal(t, uint32(10), count.Load()) + // close pool + pool.ReleaseAndWait() + + // test renew is normal + pool, err = NewSPMCPool[int, int, ConstArgs, any, pooltask.NilContext]("TestPool", 10, rmutil.UNKNOWN) + require.NoError(t, err) + pool.ReleaseAndWait() +} + +func TestStopPool(t *testing.T) { + type ConstArgs struct { + a int + } + myArgs := ConstArgs{a: 10} + // init the pool + // input type, output type, constArgs type + pool, err := NewSPMCPool[int, int, ConstArgs, any, pooltask.NilContext]("TestPool", 10, rmutil.UNKNOWN) + require.NoError(t, err) + pool.SetConsumerFunc(func(task int, constArgs ConstArgs, ctx any) int { + return task + constArgs.a + }) + + exit := make(chan struct{}) + + pfunc := func() (int, error) { + select { + case <-exit: + return 0, gpool.ErrProducerClosed + default: + return 1, nil + } + } + // add new task + resultCh, control := pool.AddProducer(pfunc, myArgs, pooltask.NilContext{}, WithConcurrency(4)) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + for result := range resultCh { + require.Greater(t, result, 10) + } + }() + // Waiting task finishing + control.Stop() + close(exit) + control.Wait() + // it should pass. Stop can be used after the pool is closed. we should prevent it from panic. + control.Stop() + wg.Wait() + // close pool + pool.ReleaseAndWait() +} + +func TestPoolWithEnoughCapacity(t *testing.T) { + const ( + RunTimes = 1000 + poolsize = 30 + concurrency = 6 + ) + p, err := NewSPMCPool[struct{}, struct{}, int, any, pooltask.NilContext]("TestPoolWithEnoughCapa", poolsize, rmutil.UNKNOWN, WithExpiryDuration(DefaultExpiredTime)) + require.NoError(t, err) + defer p.ReleaseAndWait() + p.SetConsumerFunc(func(a struct{}, b int, c any) struct{} { + return struct{}{} + }) + var twg util.WaitGroupWrapper + for i := 0; i < 3; i++ { + twg.Run(func() { + sema := make(chan struct{}, 10) + var wg util.WaitGroupWrapper + exitCh := make(chan struct{}) + wg.Run(func() { + for j := 0; j < RunTimes; j++ { + sema <- struct{}{} + } + close(exitCh) + }) + producerFunc := func() (struct{}, error) { + for { + select { + case <-sema: + return struct{}{}, nil + default: + select { + case <-exitCh: + return struct{}{}, gpool.ErrProducerClosed + default: + } + } + } + } + resultCh, ctl := p.AddProducer(producerFunc, RunTimes, pooltask.NilContext{}, WithConcurrency(concurrency)) + wg.Add(1) + go func() { + defer wg.Done() + for range resultCh { + } + }() + ctl.Wait() + wg.Wait() + }) + } + twg.Wait() +} + +func TestPoolWithoutEnoughCapacity(t *testing.T) { + const ( + RunTimes = 5 + concurrency = 2 + poolsize = 2 + ) + p, err := NewSPMCPool[struct{}, struct{}, int, any, pooltask.NilContext]("TestPoolWithoutEnoughCapacity", poolsize, rmutil.UNKNOWN, + WithExpiryDuration(DefaultExpiredTime)) + require.NoError(t, err) + defer p.ReleaseAndWait() + p.SetConsumerFunc(func(a struct{}, b int, c any) struct{} { + return struct{}{} + }) + var twg sync.WaitGroup + for i := 0; i < 10; i++ { + func() { + sema := make(chan struct{}, 10) + var wg util.WaitGroupWrapper + exitCh := make(chan struct{}) + wg.Add(1) + go func() { + defer wg.Done() + for j := 0; j < RunTimes; j++ { + sema <- struct{}{} + } + close(exitCh) + }() + producerFunc := func() (struct{}, error) { + for { + select { + case <-sema: + return struct{}{}, nil + default: + select { + case <-exitCh: + return struct{}{}, gpool.ErrProducerClosed + default: + } + } + } + } + resultCh, ctl := p.AddProducer(producerFunc, RunTimes, pooltask.NilContext{}, WithConcurrency(concurrency)) + + wg.Add(1) + go func() { + defer wg.Done() + for range resultCh { + } + }() + ctl.Wait() + wg.Wait() + }() + } + twg.Wait() +} + +func TestPoolWithoutEnoughCapacityParallel(t *testing.T) { + const ( + RunTimes = 5 + concurrency = 2 + poolsize = 2 + ) + p, err := NewSPMCPool[struct{}, struct{}, int, any, pooltask.NilContext]("TestPoolWithoutEnoughCapacityParallel", poolsize, rmutil.UNKNOWN, + WithExpiryDuration(DefaultExpiredTime), WithNonblocking(true)) + require.NoError(t, err) + defer p.ReleaseAndWait() + p.SetConsumerFunc(func(a struct{}, b int, c any) struct{} { + return struct{}{} + }) + var twg sync.WaitGroup + for i := 0; i < 10; i++ { + twg.Add(1) + go func() { + defer twg.Done() + sema := make(chan struct{}, 10) + var wg sync.WaitGroup + exitCh := make(chan struct{}) + wg.Add(1) + go func() { + wg.Done() + for j := 0; j < RunTimes; j++ { + sema <- struct{}{} + } + close(exitCh) + }() + producerFunc := func() (struct{}, error) { + for { + select { + case <-sema: + return struct{}{}, nil + default: + select { + case <-exitCh: + return struct{}{}, gpool.ErrProducerClosed + default: + } + } + } + } + resultCh, ctl := p.AddProducer(producerFunc, RunTimes, pooltask.NilContext{}, WithConcurrency(concurrency)) + wg.Add(1) + go func() { + defer wg.Done() + for range resultCh { + } + }() + ctl.Wait() + wg.Wait() + }() + } + twg.Wait() +} + +func TestBenchPool(t *testing.T) { + p, err := NewSPMCPool[struct{}, struct{}, int, any, pooltask.NilContext]("TestBenchPool", 10, + rmutil.UNKNOWN, WithExpiryDuration(DefaultExpiredTime)) + require.NoError(t, err) + defer p.ReleaseAndWait() + p.SetConsumerFunc(func(a struct{}, b int, c any) struct{} { + return struct{}{} + }) + + for i := 0; i < 1000; i++ { + sema := make(chan struct{}, 10) + var wg sync.WaitGroup + exitCh := make(chan struct{}) + wg.Add(1) + go func() { + defer wg.Done() + for j := 0; j < RunTimes; j++ { + sema <- struct{}{} + } + close(exitCh) + }() + producerFunc := func() (struct{}, error) { + for { + select { + case <-sema: + return struct{}{}, nil + default: + select { + case <-exitCh: + return struct{}{}, gpool.ErrProducerClosed + default: + } + } + } + } + resultCh, ctl := p.AddProducer(producerFunc, RunTimes, pooltask.NilContext{}, WithConcurrency(6)) + wg.Add(1) + go func() { + defer wg.Done() + for range resultCh { + } + }() + ctl.Wait() + wg.Wait() + } + p.ReleaseAndWait() +} diff --git a/util/gpool/spmc/worker.go b/util/gpool/spmc/worker.go new file mode 100644 index 0000000000000..b8e22376bb79a --- /dev/null +++ b/util/gpool/spmc/worker.go @@ -0,0 +1,83 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "github.com/pingcap/log" + "github.com/pingcap/tidb/resourcemanager/pooltask" + atomicutil "go.uber.org/atomic" + "go.uber.org/zap" +) + +// goWorker is the actual executor who runs the tasks, +// it starts a goroutine that accepts tasks and +// performs function calls. +type goWorker[T any, U any, C any, CT any, TF pooltask.Context[CT]] struct { + // pool who owns this worker. + pool *Pool[T, U, C, CT, TF] + + // taskBoxCh is a job should be done. + taskBoxCh chan *pooltask.TaskBox[T, U, C, CT, TF] + + // recycleTime will be updated when putting a worker back into queue. + recycleTime atomicutil.Time +} + +// run starts a goroutine to repeat the process +// that performs the function calls. +func (w *goWorker[T, U, C, CT, TF]) run() { + w.pool.addRunning(1) + go func() { + defer func() { + w.pool.addRunning(-1) + w.pool.workerCache.Put(w) + if p := recover(); p != nil { + if ph := w.pool.options.PanicHandler; ph != nil { + ph(p) + } else { + log.Error("worker exits from a panic", zap.Any("recover", p), zap.Stack("stack")) + } + } + // Call Signal() here in case there are goroutines waiting for available workers. + w.pool.cond.Signal() + }() + + for f := range w.taskBoxCh { + if f == nil { + return + } + if f.GetStatus() == pooltask.PendingTask { + f.SetStatus(pooltask.RunningTask) + } + w.pool.subWaitingTask() + ctx := f.GetContextFunc().GetContext() + if f.GetResultCh() != nil { + for t := range f.GetTaskCh() { + if f.GetStatus() == pooltask.StopTask { + f.Done() + continue + } + f.GetResultCh() <- w.pool.consumerFunc(t.Task, f.ConstArgs(), ctx) + f.Done() + } + w.pool.ExitSubTask(f.TaskID()) + } + f.Finish() + if ok := w.pool.revertWorker(w); !ok { + return + } + } + }() +} diff --git a/util/gpool/spmc/worker_loop_queue.go b/util/gpool/spmc/worker_loop_queue.go new file mode 100644 index 0000000000000..59c7b97fd425a --- /dev/null +++ b/util/gpool/spmc/worker_loop_queue.go @@ -0,0 +1,192 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/resourcemanager/pooltask" +) + +var ( + // errQueueIsFull will be returned when the worker queue is full. + errQueueIsFull = errors.New("the queue is full") + + // errQueueIsReleased will be returned when trying to insert item to a released worker queue. + errQueueIsReleased = errors.New("the queue is released could not accept item anymore") +) + +type loopQueue[T any, U any, C any, CT any, TF pooltask.Context[CT]] struct { + items []*goWorker[T, U, C, CT, TF] + expiry []*goWorker[T, U, C, CT, TF] + head int + tail int + size int + isFull bool +} + +func newWorkerLoopQueue[T any, U any, C any, CT any, TF pooltask.Context[CT]](size int) *loopQueue[T, U, C, CT, TF] { + return &loopQueue[T, U, C, CT, TF]{ + items: make([]*goWorker[T, U, C, CT, TF], size), + size: size, + } +} + +func (wq *loopQueue[T, U, C, CT, TF]) len() int { + if wq.size == 0 { + return 0 + } + + if wq.head == wq.tail { + if wq.isFull { + return wq.size + } + return 0 + } + + if wq.tail > wq.head { + return wq.tail - wq.head + } + + return wq.size - wq.head + wq.tail +} + +func (wq *loopQueue[T, U, C, CT, TF]) isEmpty() bool { + return wq.head == wq.tail && !wq.isFull +} + +func (wq *loopQueue[T, U, C, CT, TF]) insert(worker *goWorker[T, U, C, CT, TF]) error { + if wq.size == 0 { + return errQueueIsReleased + } + + if wq.isFull { + return errQueueIsFull + } + wq.items[wq.tail] = worker + wq.tail++ + + if wq.tail == wq.size { + wq.tail = 0 + } + if wq.tail == wq.head { + wq.isFull = true + } + + return nil +} + +func (wq *loopQueue[T, U, C, CT, TF]) detach() *goWorker[T, U, C, CT, TF] { + if wq.isEmpty() { + return nil + } + + w := wq.items[wq.head] + wq.items[wq.head] = nil + wq.head++ + if wq.head == wq.size { + wq.head = 0 + } + wq.isFull = false + + return w +} + +func (wq *loopQueue[T, U, C, CT, TF]) retrieveExpiry(duration time.Duration) []*goWorker[T, U, C, CT, TF] { + expiryTime := time.Now().Add(-duration) + index := wq.binarySearch(expiryTime) + if index == -1 { + return nil + } + wq.expiry = wq.expiry[:0] + + if wq.head <= index { + wq.expiry = append(wq.expiry, wq.items[wq.head:index+1]...) + for i := wq.head; i < index+1; i++ { + wq.items[i] = nil + } + } else { + wq.expiry = append(wq.expiry, wq.items[0:index+1]...) + wq.expiry = append(wq.expiry, wq.items[wq.head:]...) + for i := 0; i < index+1; i++ { + wq.items[i] = nil + } + for i := wq.head; i < wq.size; i++ { + wq.items[i] = nil + } + } + head := (index + 1) % wq.size + wq.head = head + if len(wq.expiry) > 0 { + wq.isFull = false + } + + return wq.expiry +} + +// binarySearch is to find the first worker which is idle for more than duration. +func (wq *loopQueue[T, U, C, CT, TF]) binarySearch(expiryTime time.Time) int { + var mid, nlen, basel, tmid int + nlen = len(wq.items) + + // if no need to remove work, return -1 + if wq.isEmpty() || expiryTime.Before(wq.items[wq.head].recycleTime.Load()) { + return -1 + } + + // example + // size = 8, head = 7, tail = 4 + // [ 2, 3, 4, 5, nil, nil, nil, 1] true position + // 0 1 2 3 4 5 6 7 + // tail head + // + // 1 2 3 4 nil nil nil 0 mapped position + // r l + + // base algorithm is a copy from worker_stack + // map head and tail to effective left and right + r := (wq.tail - 1 - wq.head + nlen) % nlen + basel = wq.head + l := 0 + for l <= r { + mid = l + ((r - l) >> 1) + // calculate true mid position from mapped mid position + tmid = (mid + basel + nlen) % nlen + if expiryTime.Before(wq.items[tmid].recycleTime.Load()) { + r = mid - 1 + } else { + l = mid + 1 + } + } + // return true position from mapped position + return (r + basel + nlen) % nlen +} + +func (wq *loopQueue[T, U, C, CT, TF]) reset() { + if wq.isEmpty() { + return + } + +Releasing: + if w := wq.detach(); w != nil { + w.taskBoxCh <- nil + goto Releasing + } + wq.items = wq.items[:0] + wq.size = 0 + wq.head = 0 + wq.tail = 0 +} diff --git a/util/gpool/spmc/worker_loop_queue_test.go b/util/gpool/spmc/worker_loop_queue_test.go new file mode 100644 index 0000000000000..da9bdc8dbc36c --- /dev/null +++ b/util/gpool/spmc/worker_loop_queue_test.go @@ -0,0 +1,184 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package spmc + +import ( + "testing" + "time" + + "github.com/pingcap/tidb/resourcemanager/pooltask" + "github.com/stretchr/testify/require" + atomicutil "go.uber.org/atomic" +) + +func TestNewLoopQueue(t *testing.T) { + size := 100 + q := newWorkerLoopQueue[struct{}, struct{}, int, any, pooltask.NilContext](size) + require.EqualValues(t, 0, q.len(), "Len error") + require.Equal(t, true, q.isEmpty(), "IsEmpty error") + require.Nil(t, q.detach(), "Dequeue error") +} + +func TestLoopQueue(t *testing.T) { + size := 10 + q := newWorkerLoopQueue[struct{}, struct{}, int, any, pooltask.NilContext](size) + + for i := 0; i < 5; i++ { + err := q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + if err != nil { + break + } + } + require.EqualValues(t, 5, q.len(), "Len error") + _ = q.detach() + require.EqualValues(t, 4, q.len(), "Len error") + + time.Sleep(time.Second) + + for i := 0; i < 6; i++ { + err := q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + if err != nil { + break + } + } + require.EqualValues(t, 10, q.len(), "Len error") + + err := q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + require.Error(t, err, "Enqueue, error") + + q.retrieveExpiry(time.Second) + require.EqualValuesf(t, 6, q.len(), "Len error: %d", q.len()) +} + +func TestRotatedArraySearch(t *testing.T) { + size := 10 + q := newWorkerLoopQueue[struct{}, struct{}, int, any, pooltask.NilContext](size) + + expiry1 := time.Now() + + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + + require.EqualValues(t, 0, q.binarySearch(time.Now()), "index should be 0") + require.EqualValues(t, -1, q.binarySearch(expiry1), "index should be -1") + + expiry2 := time.Now() + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + require.EqualValues(t, -1, q.binarySearch(expiry1), "index should be -1") + require.EqualValues(t, 0, q.binarySearch(expiry2), "index should be 0") + require.EqualValues(t, 1, q.binarySearch(time.Now()), "index should be 1") + + for i := 0; i < 5; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + + expiry3 := time.Now() + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(expiry3)}) + + var err error + for err != errQueueIsFull { + err = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + + require.EqualValues(t, 7, q.binarySearch(expiry3), "index should be 7") + + // rotate + for i := 0; i < 6; i++ { + _ = q.detach() + } + + expiry4 := time.Now() + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(expiry4)}) + + for i := 0; i < 4; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + // head = 6, tail = 5, insert direction -> + // [expiry4, time, time, time, time, nil/tail, time/head, time, time, time] + require.EqualValues(t, 0, q.binarySearch(expiry4), "index should be 0") + + for i := 0; i < 3; i++ { + _ = q.detach() + } + expiry5 := time.Now() + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(expiry5)}) + + // head = 6, tail = 5, insert direction -> + // [expiry4, time, time, time, time, expiry5, nil/tail, nil, nil, time/head] + require.EqualValues(t, 5, q.binarySearch(expiry5), "index should be 5") + + for i := 0; i < 3; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + // head = 9, tail = 9, insert direction -> + // [expiry4, time, time, time, time, expiry5, time, time, time, time/head/tail] + require.EqualValues(t, -1, q.binarySearch(expiry2), "index should be -1") + + require.EqualValues(t, 9, q.binarySearch(q.items[9].recycleTime.Load()), "index should be 9") + require.EqualValues(t, 8, q.binarySearch(time.Now()), "index should be 8") +} + +func TestRetrieveExpiry(t *testing.T) { + size := 10 + q := newWorkerLoopQueue[struct{}, struct{}, int, any, pooltask.NilContext](size) + expirew := make([]*goWorker[struct{}, struct{}, int, any, pooltask.NilContext], 0) + u, _ := time.ParseDuration("1s") + + // test [ time+1s, time+1s, time+1s, time+1s, time+1s, time, time, time, time, time] + for i := 0; i < size/2; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + expirew = append(expirew, q.items[:size/2]...) + time.Sleep(u) + + for i := 0; i < size/2; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + workers := q.retrieveExpiry(u) + + require.EqualValues(t, expirew, workers, "expired workers aren't right") + + // test [ time, time, time, time, time, time+1s, time+1s, time+1s, time+1s, time+1s] + time.Sleep(u) + + for i := 0; i < size/2; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + expirew = expirew[:0] + expirew = append(expirew, q.items[size/2:]...) + + workers2 := q.retrieveExpiry(u) + + require.EqualValues(t, expirew, workers2, "expired workers aren't right") + + // test [ time+1s, time+1s, time+1s, nil, nil, time+1s, time+1s, time+1s, time+1s, time+1s] + for i := 0; i < size/2; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + for i := 0; i < size/2; i++ { + _ = q.detach() + } + for i := 0; i < 3; i++ { + _ = q.insert(&goWorker[struct{}, struct{}, int, any, pooltask.NilContext]{recycleTime: *atomicutil.NewTime(time.Now())}) + } + time.Sleep(u) + + expirew = expirew[:0] + expirew = append(expirew, q.items[0:3]...) + expirew = append(expirew, q.items[size/2:]...) + + workers3 := q.retrieveExpiry(u) + + require.EqualValues(t, expirew, workers3, "expired workers aren't right") +} diff --git a/util/hack/main_test.go b/util/hack/main_test.go index 7503891fc847b..152f4c57d6bb7 100644 --- a/util/hack/main_test.go +++ b/util/hack/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/hint/BUILD.bazel b/util/hint/BUILD.bazel index 05fb356dcfbf2..817a1237fa9df 100644 --- a/util/hint/BUILD.bazel +++ b/util/hint/BUILD.bazel @@ -14,6 +14,7 @@ go_library( "//sessionctx", "//util/dbterror", "//util/logutil", + "@com_github_pingcap_errors//:errors", "@org_uber_go_zap//:zap", ], ) diff --git a/util/hint/hint_processor.go b/util/hint/hint_processor.go index ce61936aa1cf7..9d3fcf1005858 100644 --- a/util/hint/hint_processor.go +++ b/util/hint/hint_processor.go @@ -19,6 +19,7 @@ import ( "strconv" "strings" + "github.com/pingcap/errors" "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/ast" @@ -273,6 +274,13 @@ func ParseHintsSet(p *parser.Parser, sql, charset, collation, db string) (*Hints } for _, tblHint := range tblHints { if tblHint.HintName.L == hintQBName { + if len(tblHint.Tables) > 0 { + newHints = append(newHints, tblHint) + } + continue + } + if processor.isHint4View(tblHint) { + newHints = append(newHints, tblHint) continue } offset := processor.GetHintOffset(tblHint.QBName, curOffset) @@ -314,8 +322,14 @@ func extractHintWarns(warns []error) []error { // BlockHintProcessor processes hints at different level of sql statement. type BlockHintProcessor struct { - QbNameMap map[string]int // Map from query block name to select stmt offset. - QbHints map[int][]*ast.TableOptimizerHint // Group all hints at same query block. + QbNameMap map[string]int // Map from query block name to select stmt offset. + QbHints map[int][]*ast.TableOptimizerHint // Group all hints at same query block. + + // Used for the view's hint + QbNameMap4View map[string][]ast.HintTable // Map from view's query block name to view's table list. + QbHints4View map[string][]*ast.TableOptimizerHint // Group all hints at same query block for view hints. + QbNameUsed4View map[string]struct{} // Store all the qb_name hints which are used for view + Ctx sessionctx.Context selectStmtOffset int } @@ -335,7 +349,13 @@ func (p *BlockHintProcessor) Enter(in ast.Node) (ast.Node, bool) { case *ast.SelectStmt: p.selectStmtOffset++ node.QueryBlockOffset = p.selectStmtOffset + // Handle the view hints and update the left hint. + node.TableHints = p.handleViewHints(node.TableHints, node.QueryBlockOffset) p.checkQueryBlockHints(node.TableHints, node.QueryBlockOffset) + case *ast.ExplainStmt: + return in, true + case *ast.CreateBindingStmt: + return in, true } return in, false } @@ -356,7 +376,7 @@ func (p *BlockHintProcessor) checkQueryBlockHints(hints []*ast.TableOptimizerHin } if qbName != "" { if p.Ctx != nil { - p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("There are more than two query names in same query block,, using the first one %s", qbName)) + p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("There are more than two query names in same query block, using the first one %s", qbName)) } } else { qbName = hint.QBName.L @@ -377,6 +397,100 @@ func (p *BlockHintProcessor) checkQueryBlockHints(hints []*ast.TableOptimizerHin } } +func (p *BlockHintProcessor) handleViewHints(hints []*ast.TableOptimizerHint, offset int) (leftHints []*ast.TableOptimizerHint) { + if len(hints) == 0 { + return + } + + usedHints := make([]bool, len(hints)) + // handle the query block name hints for view + for i, hint := range hints { + if hint.HintName.L != hintQBName || len(hint.Tables) == 0 { + continue + } + usedHints[i] = true + if p.QbNameMap4View == nil { + p.QbNameMap4View = make(map[string][]ast.HintTable) + p.QbNameUsed4View = make(map[string]struct{}) + } + qbName := hint.QBName.L + if qbName == "" { + continue + } + if _, ok := p.QbNameMap4View[qbName]; ok { + if p.Ctx != nil { + p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("Duplicate query block name %s for view's query block hint, only the first one is effective", qbName)) + } + } else { + if offset != 1 { + // If there are some qb_name hints for view are not defined in the first query block, + // we should add the query block number where it is located to the first table in the view's qb_name hint table list. + qbNum := hint.Tables[0].QBName.L + if qbNum == "" { + hint.Tables[0].QBName = model.NewCIStr(fmt.Sprintf("%s%d", defaultSelectBlockPrefix, offset)) + } + } + p.QbNameMap4View[qbName] = hint.Tables + } + } + + // handle the view hints + for i, hint := range hints { + if usedHints[i] || hint.HintName.L == hintQBName { + continue + } + + ok := false + qbName := hint.QBName.L + if qbName != "" { + _, ok = p.QbNameMap4View[qbName] + } else if len(hint.Tables) > 0 { + // Only support to define the tables belong to the same query block in one view hint + qbName = hint.Tables[0].QBName.L + _, ok = p.QbNameMap4View[qbName] + if ok { + for _, table := range hint.Tables { + if table.QBName.L != qbName { + ok = false + break + } + } + if !ok { + p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("Only one query block name is allowed in a view hint, otherwise the hint will be invalid")) + usedHints[i] = true + } + } + } + + if ok { + if p.QbHints4View == nil { + p.QbHints4View = make(map[string][]*ast.TableOptimizerHint) + } + usedHints[i] = true + p.QbHints4View[qbName] = append(p.QbHints4View[qbName], hint) + } + } + + for i, hint := range hints { + if !usedHints[i] { + leftHints = append(leftHints, hint) + } + } + return +} + +// HandleUnusedViewHints handle the unused view hints. +func (p *BlockHintProcessor) HandleUnusedViewHints() { + if p.QbNameMap4View != nil { + for qbName := range p.QbNameMap4View { + _, ok := p.QbNameUsed4View[qbName] + if !ok && p.Ctx != nil { + p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("The qb_name hint %s is unused, please check whether the table list in the qb_name hint %s is correct", qbName, qbName)) + } + } + } +} + const ( defaultUpdateBlockName = "upd_1" defaultDeleteBlockName = "del_1" @@ -452,6 +566,25 @@ func (p *BlockHintProcessor) checkTableQBName(tables []ast.HintTable) bool { return true } +func (p *BlockHintProcessor) isHint4View(hint *ast.TableOptimizerHint) bool { + if hint.QBName.L != "" { + if p.QbNameMap4View != nil { + _, ok := p.QbNameMap4View[hint.QBName.L] + return ok + } + return false + } + allViewHints := true + for _, table := range hint.Tables { + qbName := table.QBName.L + if _, ok := p.QbNameMap4View[qbName]; !ok { + allViewHints = false + break + } + } + return allViewHints +} + // GetCurrentStmtHints extracts all hints that take effects at current stmt. func (p *BlockHintProcessor) GetCurrentStmtHints(hints []*ast.TableOptimizerHint, currentOffset int) []*ast.TableOptimizerHint { if p.QbHints == nil { @@ -485,3 +618,55 @@ func GenerateQBName(nodeType NodeType, blockOffset int) (model.CIStr, error) { } return model.NewCIStr(fmt.Sprintf("%s%d", defaultSelectBlockPrefix, blockOffset)), nil } + +// CheckBindingFromHistoryBindable checks whether the ast and hint string from history is bindable. +// Not support: +// 1. query use tiFlash engine +// 2. query with sub query +// 3. query with more than 2 table join +func CheckBindingFromHistoryBindable(node ast.Node, hintStr string) error { + // check tiflash + contain := strings.Contains(hintStr, "tiflash") + if contain { + return errors.New("can't create binding for query with tiflash engine") + } + + checker := bindableChecker{ + bindable: true, + tables: make(map[model.CIStr]struct{}, 2), + } + node.Accept(&checker) + return checker.reason +} + +// bindableChecker checks whether a binding from history can be created. +type bindableChecker struct { + bindable bool + reason error + tables map[model.CIStr]struct{} +} + +// Enter implements Visitor interface. +func (checker *bindableChecker) Enter(in ast.Node) (out ast.Node, skipChildren bool) { + switch node := in.(type) { + case *ast.ExistsSubqueryExpr, *ast.SubqueryExpr: + checker.bindable = false + checker.reason = errors.New("can't create binding for query with sub query") + return in, true + case *ast.TableName: + if _, ok := checker.tables[node.Schema]; !ok { + checker.tables[node.Name] = struct{}{} + } + if len(checker.tables) >= 3 { + checker.bindable = false + checker.reason = errors.New("can't create binding for query with more than two table join") + return in, true + } + } + return in, false +} + +// Leave implements Visitor interface. +func (checker *bindableChecker) Leave(in ast.Node) (out ast.Node, ok bool) { + return in, checker.bindable +} diff --git a/util/keydecoder/main_test.go b/util/keydecoder/main_test.go index 56d9e58ffea48..893be9ecbb29e 100644 --- a/util/keydecoder/main_test.go +++ b/util/keydecoder/main_test.go @@ -24,6 +24,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } testsetup.SetupForCommonTest() diff --git a/util/kvcache/main_test.go b/util/kvcache/main_test.go index ea0330d7ef031..b6b1f7ef92d8f 100644 --- a/util/kvcache/main_test.go +++ b/util/kvcache/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/localpool/main_test.go b/util/localpool/main_test.go index 8e9efc8ad5ef3..10314587bb0a7 100644 --- a/util/localpool/main_test.go +++ b/util/localpool/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/logutil/hex_test.go b/util/logutil/hex_test.go index 9351b0216cf52..fac76d0406ad9 100644 --- a/util/logutil/hex_test.go +++ b/util/logutil/hex_test.go @@ -32,7 +32,7 @@ func TestHex(t *testing.T) { region.StartKey = []byte{'t', 200, '\\', 000, 000, 000, '\\', 000, 000, 000, 37, '-', 000, 000, 000, 000, 000, 000, 000, 37} region.EndKey = []byte("3asg3asd") - expected := "{Id:6662 StartKey:74c85c0000005c000000252d0000000000000025 EndKey:3361736733617364 RegionEpoch: Peers:[] EncryptionMeta:}" + expected := "{Id:6662 StartKey:74c85c0000005c000000252d0000000000000025 EndKey:3361736733617364 RegionEpoch: Peers:[] EncryptionMeta: IsInFlashback:false}" require.Equal(t, expected, logutil.Hex(®ion).String()) } diff --git a/util/logutil/log.go b/util/logutil/log.go index 83eb44eb9d2cc..a7d59ae0c2d0f 100644 --- a/util/logutil/log.go +++ b/util/logutil/log.go @@ -111,37 +111,30 @@ func InitLogger(cfg *LogConfig) error { return errors.Trace(err) } - _, _, err = initGRPCLogger(cfg) - if err != nil { - return errors.Trace(err) - } - + initGRPCLogger(gl) return nil } -func initGRPCLogger(cfg *LogConfig) (*zap.Logger, *log.ZapProperties, error) { - // Copy Config struct by assignment. - config := cfg.Config - var l *zap.Logger - var err error - var prop *log.ZapProperties +func initGRPCLogger(gl *zap.Logger) { + level := zapcore.ErrorLevel + verbosity := 0 if len(os.Getenv("GRPC_DEBUG")) > 0 { - config.Level = "debug" - l, prop, err = log.InitLogger(&config, zap.AddStacktrace(zapcore.FatalLevel)) - if err != nil { - return nil, nil, errors.Trace(err) - } - gzap.ReplaceGrpcLoggerV2WithVerbosity(l, 999) - } else { - config.Level = "error" - l, prop, err = log.InitLogger(&config, zap.AddStacktrace(zapcore.FatalLevel)) - if err != nil { - return nil, nil, errors.Trace(err) - } - gzap.ReplaceGrpcLoggerV2(l) + verbosity = 999 + level = zapcore.DebugLevel } - return l, prop, nil + newgl := gl.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core { + oldcore, ok := core.(*log.TextIOCore) + if !ok { + return oldcore + } + newcore := oldcore.Clone() + leveler := zap.NewAtomicLevel() + leveler.SetLevel(level) + newcore.LevelEnabler = leveler + return newcore + })) + gzap.ReplaceGrpcLoggerV2WithVerbosity(newgl, verbosity) } // ReplaceLogger replace global logger instance with given log config. diff --git a/util/logutil/log_test.go b/util/logutil/log_test.go index d059204973678..57a7786c0e530 100644 --- a/util/logutil/log_test.go +++ b/util/logutil/log_test.go @@ -100,21 +100,6 @@ func TestSetLevel(t *testing.T) { require.Equal(t, zap.DebugLevel, log.GetLevel()) } -func TestGrpcLoggerCreation(t *testing.T) { - level := "info" - conf := NewLogConfig(level, DefaultLogFormat, "", EmptyFileLogConfig, false) - _, p, err := initGRPCLogger(conf) - // assert after init grpc logger, the original conf is not changed - require.Equal(t, conf.Level, level) - require.NoError(t, err) - require.Equal(t, p.Level.Level(), zap.ErrorLevel) - os.Setenv("GRPC_DEBUG", "1") - defer os.Unsetenv("GRPC_DEBUG") - _, newP, err := initGRPCLogger(conf) - require.NoError(t, err) - require.Equal(t, newP.Level.Level(), zap.DebugLevel) -} - func TestSlowQueryLoggerCreation(t *testing.T) { level := "Error" conf := NewLogConfig(level, DefaultLogFormat, "", EmptyFileLogConfig, false) diff --git a/util/logutil/main_test.go b/util/logutil/main_test.go index b1ac511fec3c1..03fdc6cc0bc3c 100644 --- a/util/logutil/main_test.go +++ b/util/logutil/main_test.go @@ -37,6 +37,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("gopkg.in/natefinch/lumberjack%2ev2.(*Logger).millRun"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/main_test.go b/util/main_test.go index 195cb2094222b..05ed110d044d6 100644 --- a/util/main_test.go +++ b/util/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/mathutil/BUILD.bazel b/util/mathutil/BUILD.bazel index 971a1ded219e4..4d0b9810eaa57 100644 --- a/util/mathutil/BUILD.bazel +++ b/util/mathutil/BUILD.bazel @@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "mathutil", srcs = [ + "exponential_average.go", "math.go", "rand.go", ], @@ -15,6 +16,7 @@ go_test( name = "mathutil_test", timeout = "short", srcs = [ + "exponential_average_test.go", "main_test.go", "math_test.go", "rand_test.go", diff --git a/util/mathutil/exponential_average.go b/util/mathutil/exponential_average.go new file mode 100644 index 0000000000000..bf3cb440e0633 --- /dev/null +++ b/util/mathutil/exponential_average.go @@ -0,0 +1,54 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mathutil + +// ExponentialMovingAverage is an exponential moving average measurement implementation. It is not thread-safe. +type ExponentialMovingAverage struct { + value float64 + sum float64 + factor float64 + warmupWindow int + count int +} + +// NewExponentialMovingAverage will create a new ExponentialMovingAverage. +func NewExponentialMovingAverage( + factor float64, + warmupWindow int, +) *ExponentialMovingAverage { + if factor >= 1 || factor <= 0 { + panic("factor must be (0, 1)") + } + return &ExponentialMovingAverage{ + factor: factor, + warmupWindow: warmupWindow, + } +} + +// Add a single sample and update the internal state. +func (m *ExponentialMovingAverage) Add(value float64) { + if m.count < m.warmupWindow { + m.count++ + m.sum += value + m.value = m.sum / float64(m.count) + } else { + m.value = m.value*(1-m.factor) + value*m.factor + } +} + +// Get the current value. +func (m *ExponentialMovingAverage) Get() float64 { + return m.value +} diff --git a/util/mathutil/exponential_average_test.go b/util/mathutil/exponential_average_test.go new file mode 100644 index 0000000000000..b622c780a5ad8 --- /dev/null +++ b/util/mathutil/exponential_average_test.go @@ -0,0 +1,39 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mathutil + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +var samples = [100]float64{ + 1576, 1524, 6746, 6426, 9476, 1721, 8528, 7827, 8613, 6969, 4200, 4686, 2408, 3956, 7105, 1341, + 9938, 9789, 6199, 4868, 4280, 7738, 7219, 3388, 2431, 1193, 1954, 2147, 7726, 3545, 8043, 2379, + 4859, 4247, 2873, 6419, 3114, 3132, 6534, 8515, 1632, 9710, 6699, 1552, 2412, 4679, 4499, 9577, + 7528, 8931, 7904, 5104, 8533, 7633, 4933, 1078, 3209, 1168, 1421, 4495, 2333, 1439, 8584, 7814, + 4320, 9569, 1370, 6635, 7870, 2828, 1599, 3592, 1934, 5944, 9418, 4143, 2285, 6756, 2674, 7293, + 4206, 5279, 9744, 2610, 2760, 9176, 1731, 3877, 2084, 2016, 3505, 5951, 4797, 5948, 8287, 8641, + 9349, 2690, 3820, 3895, +} + +func TestExponential(t *testing.T) { + win := NewExponentialMovingAverage(0.8, 2) + for _, s := range samples { + win.Add(s) + } + require.Equal(t, int64(3886), int64(win.Get())) +} diff --git a/util/mathutil/main_test.go b/util/mathutil/main_test.go index db09a75eb56af..3bdc670b7df19 100644 --- a/util/mathutil/main_test.go +++ b/util/mathutil/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/memory/BUILD.bazel b/util/memory/BUILD.bazel index fd9a8ecb399ef..f2a98af689cc0 100644 --- a/util/memory/BUILD.bazel +++ b/util/memory/BUILD.bazel @@ -5,6 +5,7 @@ go_library( srcs = [ "action.go", "meminfo.go", + "memstats.go", "tracker.go", ], importpath = "github.com/pingcap/tidb/util/memory", @@ -16,6 +17,8 @@ go_library( "//util/cgroup", "//util/dbterror", "//util/logutil", + "//util/mathutil", + "@com_github_pingcap_failpoint//:failpoint", "@com_github_shirou_gopsutil_v3//mem", "@org_golang_x_exp//slices", "@org_uber_go_atomic//:atomic", diff --git a/util/memory/action.go b/util/memory/action.go index 2ad4f76dcb695..75b587e2157f9 100644 --- a/util/memory/action.go +++ b/util/memory/action.go @@ -31,9 +31,6 @@ type ActionOnExceed interface { // Action will be called when memory usage exceeds memory quota by the // corresponding Tracker. Action(t *Tracker) - // SetLogHook binds a log hook which will be triggered and log an detailed - // message for the out-of-memory sql. - SetLogHook(hook func(uint64)) // SetFallback sets a fallback action which will be triggered if itself has // already been triggered. SetFallback(a ActionOnExceed) @@ -134,15 +131,20 @@ func (a *PanicOnExceed) SetLogHook(hook func(uint64)) { } // Action panics when memory usage exceeds memory quota. -func (a *PanicOnExceed) Action(_ *Tracker) { +func (a *PanicOnExceed) Action(t *Tracker) { a.mutex.Lock() + defer func() { + a.mutex.Unlock() + }() if !a.acted { - if a.logHook != nil { + if a.logHook == nil { + logutil.BgLogger().Warn("memory exceeds quota", + zap.Uint64("connID", t.SessionID), zap.Error(errMemExceedThreshold.GenWithStackByArgs(t.label, t.BytesConsumed(), t.GetBytesLimit(), t.String()))) + } else { a.logHook(a.ConnID) } } a.acted = true - a.mutex.Unlock() panic(PanicMemoryExceed + fmt.Sprintf("[conn_id=%d]", a.ConnID)) } diff --git a/util/memory/meminfo.go b/util/memory/meminfo.go index b4efab9c769db..4db9ac67b07dc 100644 --- a/util/memory/meminfo.go +++ b/util/memory/meminfo.go @@ -15,12 +15,13 @@ package memory import ( - "runtime" "sync" "time" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/util/cgroup" + "github.com/pingcap/tidb/util/mathutil" "github.com/shirou/gopsutil/v3/mem" ) @@ -33,6 +34,11 @@ var MemUsed func() (uint64, error) // GetMemTotalIgnoreErr returns the total amount of RAM on this system/container. If error occurs, return 0. func GetMemTotalIgnoreErr() uint64 { if memTotal, err := MemTotal(); err == nil { + failpoint.Inject("GetMemTotalError", func(val failpoint.Value) { + if val, ok := val.(bool); val && ok { + memTotal = 0 + } + }) return memTotal } return 0 @@ -105,6 +111,11 @@ func MemTotalCGroup() (uint64, error) { if err != nil { return memo, err } + v, err := mem.VirtualMemory() + if err != nil { + return 0, err + } + memo = mathutil.Min(v.Total, memo) memLimit.set(memo, time.Now()) return memo, nil } @@ -119,6 +130,11 @@ func MemUsedCGroup() (uint64, error) { if err != nil { return memo, err } + v, err := mem.VirtualMemory() + if err != nil { + return 0, err + } + memo = mathutil.Min(v.Used, memo) memUsage.set(memo, time.Now()) return memo, nil } @@ -153,8 +169,7 @@ func InstanceMemUsed() (uint64, error) { return used, nil } var memoryUsage uint64 - instanceStats := &runtime.MemStats{} - runtime.ReadMemStats(instanceStats) + instanceStats := ReadMemStats() memoryUsage = instanceStats.HeapAlloc serverMemUsage.set(memoryUsage, time.Now()) return memoryUsage, nil diff --git a/util/memory/memstats.go b/util/memory/memstats.go new file mode 100644 index 0000000000000..9cc4a3b14fb5a --- /dev/null +++ b/util/memory/memstats.go @@ -0,0 +1,57 @@ +// Copyright 2018 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package memory + +import ( + "runtime" + "sync/atomic" + "time" + + "github.com/pingcap/failpoint" +) + +var stats atomic.Pointer[globalMstats] + +// ReadMemInterval controls the interval to read memory stats. +const ReadMemInterval = 300 * time.Millisecond + +// ReadMemStats read the mem stats from runtime.ReadMemStats +func ReadMemStats() (memStats *runtime.MemStats) { + s := stats.Load() + if s != nil { + memStats = &s.m + } else { + memStats = ForceReadMemStats() + } + failpoint.Inject("ReadMemStats", func(val failpoint.Value) { + injectedSize := val.(int) + memStats.HeapInuse += uint64(injectedSize) + }) + return +} + +// ForceReadMemStats is to force read memory stats. +func ForceReadMemStats() *runtime.MemStats { + var g globalMstats + g.ts = time.Now() + runtime.ReadMemStats(&g.m) + stats.Store(&g) + return &g.m +} + +type globalMstats struct { + ts time.Time + m runtime.MemStats +} diff --git a/util/memory/tracker.go b/util/memory/tracker.go index c967f47a05509..39261a45355a1 100644 --- a/util/memory/tracker.go +++ b/util/memory/tracker.go @@ -21,9 +21,12 @@ import ( "strconv" "sync" "sync/atomic" + "time" "github.com/pingcap/tidb/metrics" + "github.com/pingcap/tidb/util/logutil" atomicutil "go.uber.org/atomic" + "go.uber.org/zap" "golang.org/x/exp/slices" ) @@ -32,8 +35,14 @@ const TrackMemWhenExceeds = 104857600 // 100MB // Process global variables for memory limit. var ( + ServerMemoryLimitOriginText = atomicutil.NewString("0") ServerMemoryLimit = atomicutil.NewUint64(0) ServerMemoryLimitSessMinSize = atomicutil.NewUint64(128 << 20) + + QueryForceDisk = atomicutil.NewInt64(0) + TriggerMemoryLimitGC = atomicutil.NewBool(false) + MemoryLimitGCLast = atomicutil.NewTime(time.Time{}) + MemoryLimitGCTotal = atomicutil.NewInt64(0) ) // Tracker is used to track the memory usage during query execution. @@ -77,14 +86,16 @@ type Tracker struct { parent *Tracker // The parent memory tracker. sync.Mutex } - label int // Label of this "Tracker". + label int // Label of this "Tracker". + // following fields are used with atomic operations, so make them 64-byte aligned. bytesConsumed int64 // Consumed bytes. bytesReleased int64 // Released bytes. maxConsumed atomicutil.Int64 // max number of bytes consumed during execution. SessionID uint64 // SessionID indicates the sessionID the tracker is bound. NeedKill atomic.Bool // NeedKill indicates whether this session need kill because OOM - IsRootTrackerOfSess bool // IsRootTrackerOfSess indicates whether this tracker is bound for session - isGlobal bool // isGlobal indicates whether this tracker is global tracker + NeedKillReceived sync.Once + IsRootTrackerOfSess bool // IsRootTrackerOfSess indicates whether this tracker is bound for session + isGlobal bool // isGlobal indicates whether this tracker is global tracker } type actionMu struct { @@ -225,6 +236,17 @@ func (t *Tracker) GetFallbackForTest(ignoreFinishedAction bool) ActionOnExceed { return t.actionMuForHardLimit.actionOnExceed } +// UnbindActions unbinds actionForHardLimit and actionForSoftLimit. +func (t *Tracker) UnbindActions() { + t.actionMuForSoftLimit.Lock() + defer t.actionMuForSoftLimit.Unlock() + t.actionMuForSoftLimit.actionOnExceed = nil + + t.actionMuForHardLimit.Lock() + defer t.actionMuForHardLimit.Unlock() + t.actionMuForHardLimit.actionOnExceed = &LogOnExceed{} +} + // reArrangeFallback merge two action chains and rearrange them by priority in descending order. func reArrangeFallback(a ActionOnExceed, b ActionOnExceed) ActionOnExceed { if a == nil { @@ -288,6 +310,17 @@ func (t *Tracker) Detach() { t.DetachFromGlobalTracker() return } + if parent.IsRootTrackerOfSess && t.label == LabelForSQLText { + parent.actionMuForHardLimit.Lock() + parent.actionMuForHardLimit.actionOnExceed = nil + parent.actionMuForHardLimit.Unlock() + + parent.actionMuForSoftLimit.Lock() + parent.actionMuForSoftLimit.actionOnExceed = nil + parent.actionMuForSoftLimit.Unlock() + parent.NeedKill.Store(false) + parent.NeedKillReceived = sync.Once{} + } parent.remove(t) t.mu.Lock() defer t.mu.Unlock() @@ -384,7 +417,7 @@ func (t *Tracker) Consume(bs int64) { for { maxNow := tracker.maxConsumed.Load() consumed := atomic.LoadInt64(&tracker.bytesConsumed) - if consumed > maxNow && !tracker.maxConsumed.CAS(maxNow, consumed) { + if consumed > maxNow && !tracker.maxConsumed.CompareAndSwap(maxNow, consumed) { continue } if label, ok := MetricsTypes[tracker.label]; ok { @@ -420,6 +453,11 @@ func (t *Tracker) Consume(bs int64) { if bs > 0 && sessionRootTracker != nil { // Kill the Top1 session if sessionRootTracker.NeedKill.Load() { + sessionRootTracker.NeedKillReceived.Do( + func() { + logutil.BgLogger().Warn("global memory controller, NeedKill signal is received successfully", + zap.Uint64("connID", sessionRootTracker.SessionID)) + }) tryActionLastOne(&sessionRootTracker.actionMuForHardLimit, sessionRootTracker) } // Update the Top1 session @@ -528,6 +566,11 @@ func (t *Tracker) MaxConsumed() int64 { return t.maxConsumed.Load() } +// ResetMaxConsumed should be invoked before executing a new statement in a session. +func (t *Tracker) ResetMaxConsumed() { + t.maxConsumed.Store(t.BytesConsumed()) +} + // SearchTrackerWithoutLock searches the specific tracker under this tracker without lock. func (t *Tracker) SearchTrackerWithoutLock(label int) *Tracker { if t.label == label { @@ -712,6 +755,39 @@ func (t *Tracker) setParent(parent *Tracker) { t.parMu.parent = parent } +// CountAllChildrenMemUse return memory used tree for the tracker +func (t *Tracker) CountAllChildrenMemUse() map[string]int64 { + trackerMemUseMap := make(map[string]int64, 1024) + countChildMem(t, "", trackerMemUseMap) + return trackerMemUseMap +} + +// GetChildrenForTest returns children trackers +func (t *Tracker) GetChildrenForTest() []*Tracker { + t.mu.Lock() + defer t.mu.Unlock() + trackers := make([]*Tracker, 0) + for _, list := range t.mu.children { + trackers = append(trackers, list...) + } + return trackers +} + +func countChildMem(t *Tracker, familyTreeName string, trackerMemUseMap map[string]int64) { + if len(familyTreeName) > 0 { + familyTreeName += " <- " + } + familyTreeName += "[" + strconv.Itoa(t.Label()) + "]" + trackerMemUseMap[familyTreeName] += t.BytesConsumed() + t.mu.Lock() + defer t.mu.Unlock() + for _, sli := range t.mu.children { + for _, tracker := range sli { + countChildMem(tracker, familyTreeName, trackerMemUseMap) + } + } +} + const ( // LabelForSQLText represents the label of the SQL Text LabelForSQLText int = -1 @@ -763,6 +839,12 @@ const ( LabelForAnalyzeMemory int = -24 // LabelForGlobalAnalyzeMemory represents the label of the global memory of all analyze jobs LabelForGlobalAnalyzeMemory int = -25 + // LabelForPreparedPlanCache represents the label of the prepared plan cache memory usage + LabelForPreparedPlanCache int = -26 + // LabelForSession represents the label of a session. + LabelForSession int = -27 + // LabelForMemDB represents the label of the MemDB + LabelForMemDB int = -28 ) // MetricsTypes is used to get label for metrics diff --git a/util/memory/tracker_test.go b/util/memory/tracker_test.go index baa6461ac76c5..cdfc4ff353435 100644 --- a/util/memory/tracker_test.go +++ b/util/memory/tracker_test.go @@ -251,9 +251,6 @@ type mockAction struct { priority int64 } -func (a *mockAction) SetLogHook(hook func(uint64)) { -} - func (a *mockAction) Action(t *Tracker) { if a.called && a.fallbackAction != nil { a.fallbackAction.Action(t) diff --git a/util/memoryusagealarm/BUILD.bazel b/util/memoryusagealarm/BUILD.bazel index 48c7910492ecc..80d092d6e4723 100644 --- a/util/memoryusagealarm/BUILD.bazel +++ b/util/memoryusagealarm/BUILD.bazel @@ -26,8 +26,8 @@ go_test( race = "on", deps = [ "//sessionctx/stmtctx", + "//sessionctx/variable", "//util", - "//util/execdetails", "//util/memory", "@com_github_stretchr_testify//assert", ], diff --git a/util/memoryusagealarm/memoryusagealarm.go b/util/memoryusagealarm/memoryusagealarm.go index b934d38e646c4..c8a6fd0eaecda 100644 --- a/util/memoryusagealarm/memoryusagealarm.go +++ b/util/memoryusagealarm/memoryusagealarm.go @@ -18,7 +18,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" rpprof "runtime/pprof" "strings" "sync/atomic" @@ -73,38 +72,42 @@ func (eqh *Handle) Run() { type memoryUsageAlarm struct { lastCheckTime time.Time + lastUpdateVariableTime time.Time err error baseRecordDir string lastRecordDirName []string lastRecordMemUsed uint64 memoryUsageAlarmRatio float64 memoryUsageAlarmKeepRecordNum int64 - serverMemoryQuota uint64 - isServerMemoryQuotaSet bool + serverMemoryLimit uint64 + isServerMemoryLimitSet bool initialized bool } func (record *memoryUsageAlarm) updateVariable() { + if time.Since(record.lastUpdateVariableTime) < 60*time.Second { + return + } record.memoryUsageAlarmRatio = variable.MemoryUsageAlarmRatio.Load() record.memoryUsageAlarmKeepRecordNum = variable.MemoryUsageAlarmKeepRecordNum.Load() -} - -func (record *memoryUsageAlarm) initMemoryUsageAlarmRecord() { - record.memoryUsageAlarmRatio = variable.MemoryUsageAlarmRatio.Load() - record.memoryUsageAlarmKeepRecordNum = variable.MemoryUsageAlarmKeepRecordNum.Load() - if quota := config.GetGlobalConfig().Performance.ServerMemoryQuota; quota != 0 { - record.serverMemoryQuota = quota - record.isServerMemoryQuotaSet = true + record.serverMemoryLimit = memory.ServerMemoryLimit.Load() + if record.serverMemoryLimit != 0 { + record.isServerMemoryLimitSet = true } else { - record.serverMemoryQuota, record.err = memory.MemTotal() + record.serverMemoryLimit, record.err = memory.MemTotal() if record.err != nil { logutil.BgLogger().Error("get system total memory fail", zap.Error(record.err)) return } - record.isServerMemoryQuotaSet = false + record.isServerMemoryLimitSet = false } + record.lastUpdateVariableTime = time.Now() +} + +func (record *memoryUsageAlarm) initMemoryUsageAlarmRecord() { record.lastCheckTime = time.Time{} - record.lastRecordMemUsed = uint64(float64(record.serverMemoryQuota) * record.memoryUsageAlarmRatio) + record.lastUpdateVariableTime = time.Time{} + record.updateVariable() tidbLogDir, _ := filepath.Split(config.GetGlobalConfig().Log.File.Filename) record.baseRecordDir = filepath.Join(tidbLogDir, "oom_record") if record.err = disk.CheckAndCreateDir(record.baseRecordDir); record.err != nil { @@ -140,9 +143,8 @@ func (record *memoryUsageAlarm) alarm4ExcessiveMemUsage(sm util.SessionManager) return } var memoryUsage uint64 - instanceStats := &runtime.MemStats{} - runtime.ReadMemStats(instanceStats) - if record.isServerMemoryQuotaSet { + instanceStats := memory.ReadMemStats() + if record.isServerMemoryLimitSet { memoryUsage = instanceStats.HeapAlloc } else { memoryUsage, record.err = memory.MemUsed() @@ -181,7 +183,7 @@ func (record *memoryUsageAlarm) needRecord(memoryUsage uint64) (bool, AlarmReaso // At least 60 seconds between two recordings that memory usage is less than threshold (default 70% system memory). // If the memory is still exceeded, only records once. // If the memory used ratio recorded this time is 0.1 higher than last time, we will force record this time. - if float64(memoryUsage) <= float64(record.serverMemoryQuota)*record.memoryUsageAlarmRatio { + if float64(memoryUsage) <= float64(record.serverMemoryLimit)*record.memoryUsageAlarmRatio { return false, NoReason } @@ -190,7 +192,7 @@ func (record *memoryUsageAlarm) needRecord(memoryUsage uint64) (bool, AlarmReaso if interval > 60*time.Second { return true, ExceedAlarmRatio } - if float64(memDiff) > 0.1*float64(record.serverMemoryQuota) { + if float64(memDiff) > 0.1*float64(record.serverMemoryLimit) { return true, GrowTooFast } return false, NoReason @@ -198,12 +200,12 @@ func (record *memoryUsageAlarm) needRecord(memoryUsage uint64) (bool, AlarmReaso func (record *memoryUsageAlarm) doRecord(memUsage uint64, instanceMemoryUsage uint64, sm util.SessionManager, alarmReason AlarmReason) { fields := make([]zap.Field, 0, 6) - fields = append(fields, zap.Bool("is server-memory-quota set", record.isServerMemoryQuotaSet)) - if record.isServerMemoryQuotaSet { - fields = append(fields, zap.Any("server-memory-quota", record.serverMemoryQuota)) + fields = append(fields, zap.Bool("is tidb_server_memory_limit set", record.isServerMemoryLimitSet)) + if record.isServerMemoryLimitSet { + fields = append(fields, zap.Any("tidb_server_memory_limit", record.serverMemoryLimit)) fields = append(fields, zap.Any("tidb-server memory usage", memUsage)) } else { - fields = append(fields, zap.Any("system memory total", record.serverMemoryQuota)) + fields = append(fields, zap.Any("system memory total", record.serverMemoryLimit)) fields = append(fields, zap.Any("system memory usage", memUsage)) fields = append(fields, zap.Any("tidb-server memory usage", instanceMemoryUsage)) } @@ -234,22 +236,12 @@ func (record *memoryUsageAlarm) tryRemoveRedundantRecords() { } } -func getRelevantSystemVariableBuf() string { +func getPlanString(info *util.ProcessInfo) string { var buf strings.Builder - buf.WriteString("System variables : \n") - buf.WriteString(fmt.Sprintf("oom-action: %v \n", config.GetGlobalConfig().OOMAction)) - buf.WriteString(fmt.Sprintf("mem-quota-query : %v \n", config.GetGlobalConfig().MemQuotaQuery)) - buf.WriteString(fmt.Sprintf("server-memory-quota : %v \n", config.GetGlobalConfig().Performance.ServerMemoryQuota)) - buf.WriteString("\n") - return buf.String() -} - -func getCurrentAnalyzePlan(info *util.ProcessInfo) string { - var buf strings.Builder - rows := info.CurrentAnalyzeRows(info.Plan, info.RuntimeStatsColl) - buf.WriteString(fmt.Sprintf("|%v|%v|%v|%v|%v|%v|%v|%v|%v|", "id", "estRows", "actRows", "task", "access object", "execution info", "operator info", "memory", "disk")) + rows := info.PlanExplainRows + buf.WriteString(fmt.Sprintf("|%v|%v|%v|%v|%v|", "id", "estRows", "task", "access object", "operator info")) for _, row := range rows { - buf.WriteString(fmt.Sprintf("\n|%v|%v|%v|%v|%v|%v|%v|%v|%v|", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8])) + buf.WriteString(fmt.Sprintf("\n|%v|%v|%v|%v|%v|", row[0], row[1], row[2], row[3], row[4])) } return buf.String() } @@ -274,16 +266,22 @@ func (record *memoryUsageAlarm) printTop10SqlInfo(pinfo []*util.ProcessInfo, f * func (record *memoryUsageAlarm) getTop10SqlInfo(cmp func(i, j *util.ProcessInfo) bool, pinfo []*util.ProcessInfo) strings.Builder { slices.SortFunc(pinfo, cmp) list := pinfo - if len(list) > 10 { - list = list[:10] - } var buf strings.Builder - for i, info := range list { + oomAction := variable.OOMAction.Load() + serverMemoryLimit := memory.ServerMemoryLimit.Load() + for i, totalCnt := 0, 10; i < len(list) && totalCnt > 0; i++ { + info := list[i] buf.WriteString(fmt.Sprintf("SQL %v: \n", i)) fields := util.GenLogFields(record.lastCheckTime.Sub(info.Time), info, false) - fields = append(fields, zap.Int("analyze-version", info.OOMAlarmVariablesInfo.SessionAnalyzeVersion)) + if fields == nil { + continue + } + fields = append(fields, zap.String("tidb_mem_oom_action", oomAction)) + fields = append(fields, zap.Uint64("tidb_server_memory_limit", serverMemoryLimit)) + fields = append(fields, zap.Int64("tidb_mem_quota_query", info.OOMAlarmVariablesInfo.SessionMemQuotaQuery)) + fields = append(fields, zap.Int("tidb_analyze_version", info.OOMAlarmVariablesInfo.SessionAnalyzeVersion)) fields = append(fields, zap.Bool("tidb_enable_rate_limit_action", info.OOMAlarmVariablesInfo.SessionEnabledRateLimitAction)) - fields = append(fields, zap.String("current_analyze_plan", getCurrentAnalyzePlan(info))) + fields = append(fields, zap.String("current_analyze_plan", getPlanString(info))) for _, field := range fields { switch field.Type { case zapcore.StringType: @@ -297,6 +295,7 @@ func (record *memoryUsageAlarm) getTop10SqlInfo(cmp func(i, j *util.ProcessInfo) } buf.WriteString("\n") } + totalCnt-- } buf.WriteString("\n") return buf @@ -304,7 +303,7 @@ func (record *memoryUsageAlarm) getTop10SqlInfo(cmp func(i, j *util.ProcessInfo) func (record *memoryUsageAlarm) getTop10SqlInfoByMemoryUsage(pinfo []*util.ProcessInfo) strings.Builder { return record.getTop10SqlInfo(func(i, j *util.ProcessInfo) bool { - return i.StmtCtx.MemTracker.MaxConsumed() > j.StmtCtx.MemTracker.MaxConsumed() + return i.MemTracker.MaxConsumed() > j.MemTracker.MaxConsumed() }, pinfo) } @@ -334,9 +333,6 @@ func (record *memoryUsageAlarm) recordSQL(sm util.SessionManager, recordDir stri logutil.BgLogger().Error("close oom record file fail", zap.Error(err)) } }() - if _, err = f.WriteString(getRelevantSystemVariableBuf()); err != nil { - logutil.BgLogger().Error("write oom record file fail", zap.Error(err)) - } record.printTop10SqlInfo(pinfo, f) return nil } diff --git a/util/memoryusagealarm/memoryusagealarm_test.go b/util/memoryusagealarm/memoryusagealarm_test.go index de40f228eea64..6e5147805676f 100644 --- a/util/memoryusagealarm/memoryusagealarm_test.go +++ b/util/memoryusagealarm/memoryusagealarm_test.go @@ -19,8 +19,8 @@ import ( "time" "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/util" - "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/memory" "github.com/stretchr/testify/assert" ) @@ -30,13 +30,13 @@ func TestIfNeedDoRecord(t *testing.T) { record.initMemoryUsageAlarmRecord() // mem usage ratio < 70% will not be recorded - memUsed := 0.69 * float64(record.serverMemoryQuota) + memUsed := 0.69 * float64(record.serverMemoryLimit) needRecord, reason := record.needRecord(uint64(memUsed)) assert.False(t, needRecord) assert.Equal(t, NoReason, reason) // mem usage ratio > 70% will not be recorded - memUsed = 0.71 * float64(record.serverMemoryQuota) + memUsed = 0.71 * float64(record.serverMemoryLimit) needRecord, reason = record.needRecord(uint64(memUsed)) assert.True(t, needRecord) assert.Equal(t, ExceedAlarmRatio, reason) @@ -44,14 +44,14 @@ func TestIfNeedDoRecord(t *testing.T) { record.lastRecordMemUsed = uint64(memUsed) // check time - last record time < 60s will not be recorded - memUsed = 0.71 * float64(record.serverMemoryQuota) + memUsed = 0.71 * float64(record.serverMemoryLimit) needRecord, reason = record.needRecord(uint64(memUsed)) assert.False(t, needRecord) assert.Equal(t, NoReason, reason) // check time - last record time > 60s will be recorded record.lastCheckTime = record.lastCheckTime.Add(-60 * time.Second) - memUsed = 0.71 * float64(record.serverMemoryQuota) + memUsed = 0.71 * float64(record.serverMemoryLimit) needRecord, reason = record.needRecord(uint64(memUsed)) assert.True(t, needRecord) assert.Equal(t, ExceedAlarmRatio, reason) @@ -59,13 +59,13 @@ func TestIfNeedDoRecord(t *testing.T) { record.lastRecordMemUsed = uint64(memUsed) // mem usage ratio - last mem usage ratio < 10% will not be recorded - memUsed = 0.80 * float64(record.serverMemoryQuota) + memUsed = 0.80 * float64(record.serverMemoryLimit) needRecord, reason = record.needRecord(uint64(memUsed)) assert.False(t, needRecord) assert.Equal(t, NoReason, reason) // mem usage ratio - last mem usage ratio > 10% will not be recorded even though check time - last record time - memUsed = 0.82 * float64(record.serverMemoryQuota) + memUsed = 0.82 * float64(record.serverMemoryLimit) needRecord, reason = record.needRecord(uint64(memUsed)) assert.True(t, needRecord) assert.Equal(t, GrowTooFast, reason) @@ -85,18 +85,18 @@ func TestGetTop10Sql(t *testing.T) { []time.Time{genTime(1234), genTime(123456), genTime(12)}, 3) actual := record.getTop10SqlInfoByMemoryUsage(processInfoList) - assert.Equal(t, "SQL 0: \ncost_time: 0s\ntxn_start_ts: 0\nmem_max: 87263523 Bytes (83.2 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 1: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 2: \ncost_time: 122222s\ntxn_start_ts: 0\nmem_max: 1000 Bytes (1000 Bytes)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\n\n", + assert.Equal(t, "SQL 0: \ncost_time: 0s\ntxn_start_ts: 0\nmem_max: 87263523 Bytes (83.2 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 1: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 2: \ncost_time: 122222s\ntxn_start_ts: 0\nmem_max: 1000 Bytes (1000 Bytes)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\n\n", actual.String()) actual = record.getTop10SqlInfoByCostTime(processInfoList) - assert.Equal(t, "SQL 0: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 1: \ncost_time: 122222s\ntxn_start_ts: 0\nmem_max: 1000 Bytes (1000 Bytes)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 2: \ncost_time: 0s\ntxn_start_ts: 0\nmem_max: 87263523 Bytes (83.2 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\n\n", actual.String()) + assert.Equal(t, "SQL 0: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 1: \ncost_time: 122222s\ntxn_start_ts: 0\nmem_max: 1000 Bytes (1000 Bytes)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 2: \ncost_time: 0s\ntxn_start_ts: 0\nmem_max: 87263523 Bytes (83.2 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\n\n", actual.String()) processInfoList = genMockProcessInfoList([]int64{1000, 87263523, 34223, 532355, 123225151, 231231515, 12312, 12515134234, 232, 12414, 15263236, 123123123, 15}, []time.Time{genTime(1234), genTime(123456), genTime(12), genTime(3241), genTime(12515), genTime(3215), genTime(61314), genTime(12234), genTime(1123), genTime(512), genTime(11111), genTime(22222), genTime(5512)}, 13) actual = record.getTop10SqlInfoByMemoryUsage(processInfoList) - assert.Equal(t, "SQL 0: \ncost_time: 111222s\ntxn_start_ts: 0\nmem_max: 12515134234 Bytes (11.7 GB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 1: \ncost_time: 120241s\ntxn_start_ts: 0\nmem_max: 231231515 Bytes (220.5 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 2: \ncost_time: 110941s\ntxn_start_ts: 0\nmem_max: 123225151 Bytes (117.5 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 3: \ncost_time: 101234s\ntxn_start_ts: 0\nmem_max: 123123123 Bytes (117.4 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 4: \ncost_time: 0s\ntxn_start_ts: 0\nmem_max: 87263523 Bytes (83.2 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 5: \ncost_time: 112345s\ntxn_start_ts: 0\nmem_max: 15263236 Bytes (14.6 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 6: \ncost_time: 120215s\ntxn_start_ts: 0\nmem_max: 532355 Bytes (519.9 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 7: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 8: \ncost_time: 122944s\ntxn_start_ts: 0\nmem_max: 12414 Bytes (12.1 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 9: \ncost_time: 62142s\ntxn_start_ts: 0\nmem_max: 12312 Bytes (12.0 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\n\n", actual.String()) + assert.Equal(t, "SQL 0: \ncost_time: 111222s\ntxn_start_ts: 0\nmem_max: 12515134234 Bytes (11.7 GB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 1: \ncost_time: 120241s\ntxn_start_ts: 0\nmem_max: 231231515 Bytes (220.5 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 2: \ncost_time: 110941s\ntxn_start_ts: 0\nmem_max: 123225151 Bytes (117.5 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 3: \ncost_time: 101234s\ntxn_start_ts: 0\nmem_max: 123123123 Bytes (117.4 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 4: \ncost_time: 0s\ntxn_start_ts: 0\nmem_max: 87263523 Bytes (83.2 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 5: \ncost_time: 112345s\ntxn_start_ts: 0\nmem_max: 15263236 Bytes (14.6 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 6: \ncost_time: 120215s\ntxn_start_ts: 0\nmem_max: 532355 Bytes (519.9 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 7: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 8: \ncost_time: 122944s\ntxn_start_ts: 0\nmem_max: 12414 Bytes (12.1 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 9: \ncost_time: 62142s\ntxn_start_ts: 0\nmem_max: 12312 Bytes (12.0 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\n\n", actual.String()) actual = record.getTop10SqlInfoByCostTime(processInfoList) - assert.Equal(t, "SQL 0: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 1: \ncost_time: 122944s\ntxn_start_ts: 0\nmem_max: 12414 Bytes (12.1 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 2: \ncost_time: 122333s\ntxn_start_ts: 0\nmem_max: 232 Bytes (232 Bytes)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 3: \ncost_time: 122222s\ntxn_start_ts: 0\nmem_max: 1000 Bytes (1000 Bytes)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 4: \ncost_time: 120241s\ntxn_start_ts: 0\nmem_max: 231231515 Bytes (220.5 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 5: \ncost_time: 120215s\ntxn_start_ts: 0\nmem_max: 532355 Bytes (519.9 KB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 6: \ncost_time: 117944s\ntxn_start_ts: 0\nmem_max: 15 Bytes (15 Bytes)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 7: \ncost_time: 112345s\ntxn_start_ts: 0\nmem_max: 15263236 Bytes (14.6 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 8: \ncost_time: 111222s\ntxn_start_ts: 0\nmem_max: 12515134234 Bytes (11.7 GB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\nSQL 9: \ncost_time: 110941s\ntxn_start_ts: 0\nmem_max: 123225151 Bytes (117.5 MB)\nsql: \nanalyze-version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|actRows|task|access object|execution info|operator info|memory|disk|\n\n", actual.String()) + assert.Equal(t, "SQL 0: \ncost_time: 123444s\ntxn_start_ts: 0\nmem_max: 34223 Bytes (33.4 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 1: \ncost_time: 122944s\ntxn_start_ts: 0\nmem_max: 12414 Bytes (12.1 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 2: \ncost_time: 122333s\ntxn_start_ts: 0\nmem_max: 232 Bytes (232 Bytes)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 3: \ncost_time: 122222s\ntxn_start_ts: 0\nmem_max: 1000 Bytes (1000 Bytes)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 4: \ncost_time: 120241s\ntxn_start_ts: 0\nmem_max: 231231515 Bytes (220.5 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 5: \ncost_time: 120215s\ntxn_start_ts: 0\nmem_max: 532355 Bytes (519.9 KB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 6: \ncost_time: 117944s\ntxn_start_ts: 0\nmem_max: 15 Bytes (15 Bytes)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 7: \ncost_time: 112345s\ntxn_start_ts: 0\nmem_max: 15263236 Bytes (14.6 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 8: \ncost_time: 111222s\ntxn_start_ts: 0\nmem_max: 12515134234 Bytes (11.7 GB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\nSQL 9: \ncost_time: 110941s\ntxn_start_ts: 0\nmem_max: 123225151 Bytes (117.5 MB)\nsql: \ntidb_mem_oom_action: CANCEL\ntidb_server_memory_limit: 0\ntidb_mem_quota_query: 0\ntidb_analyze_version: 0\ntidb_enable_rate_limit_action: false\ncurrent_analyze_plan: |id|estRows|task|access object|operator info|\n\n", actual.String()) } func genMockProcessInfoList(memConsumeList []int64, startTimeList []time.Time, size int) []*util.ProcessInfo { @@ -104,16 +104,42 @@ func genMockProcessInfoList(memConsumeList []int64, startTimeList []time.Time, s for i := 0; i < size; i++ { tracker := memory.NewTracker(0, 0) tracker.Consume(memConsumeList[i]) + var stmtCtxRefCount stmtctx.ReferenceCount = 0 processInfo := util.ProcessInfo{Time: startTimeList[i], - StmtCtx: &stmtctx.StatementContext{MemTracker: tracker}, + StmtCtx: &stmtctx.StatementContext{}, + MemTracker: tracker, StatsInfo: func(interface{}) map[string]uint64 { return map[string]uint64{} }, - CurrentAnalyzeRows: func(interface{}, *execdetails.RuntimeStatsColl) [][]string { - return [][]string{} - }, + RefCountOfStmtCtx: &stmtCtxRefCount, } processInfoList = append(processInfoList, &processInfo) } return processInfoList } + +func TestUpdateVariables(t *testing.T) { + variable.MemoryUsageAlarmRatio.Store(0.3) + variable.MemoryUsageAlarmKeepRecordNum.Store(3) + memory.ServerMemoryLimit.Store(1024) + + record := memoryUsageAlarm{} + + record.initMemoryUsageAlarmRecord() + assert.Equal(t, 0.3, record.memoryUsageAlarmRatio) + assert.Equal(t, int64(3), record.memoryUsageAlarmKeepRecordNum) + assert.Equal(t, uint64(1024), record.serverMemoryLimit) + variable.MemoryUsageAlarmRatio.Store(0.6) + variable.MemoryUsageAlarmKeepRecordNum.Store(6) + memory.ServerMemoryLimit.Store(2048) + + record.updateVariable() + assert.Equal(t, 0.3, record.memoryUsageAlarmRatio) + assert.Equal(t, int64(3), record.memoryUsageAlarmKeepRecordNum) + assert.Equal(t, uint64(1024), record.serverMemoryLimit) + record.lastUpdateVariableTime = record.lastUpdateVariableTime.Add(-60 * time.Second) + record.updateVariable() + assert.Equal(t, 0.6, record.memoryUsageAlarmRatio) + assert.Equal(t, int64(6), record.memoryUsageAlarmKeepRecordNum) + assert.Equal(t, uint64(2048), record.serverMemoryLimit) +} diff --git a/util/misc.go b/util/misc.go index 0e28baa5f62fc..d336aa5765451 100644 --- a/util/misc.go +++ b/util/misc.go @@ -394,10 +394,10 @@ func TLSCipher2String(n uint16) string { } // ColumnsToProto converts a slice of model.ColumnInfo to a slice of tipb.ColumnInfo. -func ColumnsToProto(columns []*model.ColumnInfo, pkIsHandle bool) []*tipb.ColumnInfo { +func ColumnsToProto(columns []*model.ColumnInfo, pkIsHandle bool, forIndex bool) []*tipb.ColumnInfo { cols := make([]*tipb.ColumnInfo, 0, len(columns)) for _, c := range columns { - col := ColumnToProto(c) + col := ColumnToProto(c, forIndex) // TODO: Here `PkHandle`'s meaning is changed, we will change it to `IsHandle` when tikv's old select logic // is abandoned. if (pkIsHandle && mysql.HasPriKeyFlag(c.GetFlag())) || c.ID == model.ExtraHandleID { @@ -411,7 +411,7 @@ func ColumnsToProto(columns []*model.ColumnInfo, pkIsHandle bool) []*tipb.Column } // ColumnToProto converts model.ColumnInfo to tipb.ColumnInfo. -func ColumnToProto(c *model.ColumnInfo) *tipb.ColumnInfo { +func ColumnToProto(c *model.ColumnInfo, forIndex bool) *tipb.ColumnInfo { pc := &tipb.ColumnInfo{ ColumnId: c.ID, Collation: collate.RewriteNewCollationIDIfNeeded(int32(mysql.CollationNames[c.GetCollate()])), @@ -420,7 +420,12 @@ func ColumnToProto(c *model.ColumnInfo) *tipb.ColumnInfo { Flag: int32(c.GetFlag()), Elems: c.GetElems(), } - pc.Tp = int32(c.GetType()) + if forIndex { + // Use array type for read the multi-valued index. + pc.Tp = int32(c.FieldType.ArrayType().GetType()) + } else { + pc.Tp = int32(c.GetType()) + } return pc } diff --git a/util/misc_test.go b/util/misc_test.go index c1510625593f0..7a5baeb197d28 100644 --- a/util/misc_test.go +++ b/util/misc_test.go @@ -174,8 +174,8 @@ func TestToPB(t *testing.T) { } column2.SetCollate("utf8mb4_bin") - assert.Equal(t, "column_id:1 collation:-45 columnLen:-1 decimal:-1 ", ColumnToProto(column).String()) - assert.Equal(t, "column_id:1 collation:-45 columnLen:-1 decimal:-1 ", ColumnsToProto([]*model.ColumnInfo{column, column2}, false)[0].String()) + assert.Equal(t, "column_id:1 collation:-45 columnLen:-1 decimal:-1 ", ColumnToProto(column, false).String()) + assert.Equal(t, "column_id:1 collation:-45 columnLen:-1 decimal:-1 ", ColumnsToProto([]*model.ColumnInfo{column, column2}, false, false)[0].String()) } func TestComposeURL(t *testing.T) { diff --git a/util/mock/BUILD.bazel b/util/mock/BUILD.bazel index 511678cb9ca60..78ba5291cbe8b 100644 --- a/util/mock/BUILD.bazel +++ b/util/mock/BUILD.bazel @@ -11,6 +11,7 @@ go_library( importpath = "github.com/pingcap/tidb/util/mock", visibility = ["//visibility:public"], deps = [ + "//extension", "//kv", "//parser/ast", "//parser/model", diff --git a/util/mock/context.go b/util/mock/context.go index fd4c4d8bef376..219b72e310ba3 100644 --- a/util/mock/context.go +++ b/util/mock/context.go @@ -22,6 +22,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/kvproto/pkg/kvrpcpb" + "github.com/pingcap/tidb/extension" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" @@ -47,16 +48,17 @@ var ( // Context represents mocked sessionctx.Context. type Context struct { - txn wrapTxn // mock global variable - Store kv.Storage // mock global variable - ctx context.Context - sm util.SessionManager - is sessionctx.InfoschemaMetaVersion - values map[fmt.Stringer]interface{} - sessionVars *variable.SessionVars - cancel context.CancelFunc - pcache sessionctx.PlanCache - level kvrpcpb.DiskFullOpt + txn wrapTxn // mock global variable + Store kv.Storage // mock global variable + ctx context.Context + sm util.SessionManager + is sessionctx.InfoschemaMetaVersion + values map[fmt.Stringer]interface{} + sessionVars *variable.SessionVars + cancel context.CancelFunc + pcache sessionctx.PlanCache + level kvrpcpb.DiskFullOpt + inSandBoxMode bool } type wrapTxn struct { @@ -344,11 +346,10 @@ func (*Context) GetTxnWriteThroughputSLI() *sli.TxnWriteThroughputSLI { } // StmtCommit implements the sessionctx.Context interface. -func (*Context) StmtCommit() {} +func (*Context) StmtCommit(context.Context) {} // StmtRollback implements the sessionctx.Context interface. -func (*Context) StmtRollback() { -} +func (*Context) StmtRollback(context.Context, bool) {} // StmtGetMutation implements the sessionctx.Context interface. func (*Context) StmtGetMutation(_ int64) *binlog.TableMutation { @@ -432,6 +433,26 @@ func (*Context) DecodeSessionStates(context.Context, sessionctx.Context, *sessio return errors.Errorf("Not Supported") } +// GetExtensions returns the `*extension.SessionExtensions` object +func (*Context) GetExtensions() *extension.SessionExtensions { + return nil +} + +// EnableSandBoxMode enable the sandbox mode. +func (c *Context) EnableSandBoxMode() { + c.inSandBoxMode = true +} + +// DisableSandBoxMode enable the sandbox mode. +func (c *Context) DisableSandBoxMode() { + c.inSandBoxMode = false +} + +// InSandBoxMode indicates that this Session is in sandbox mode +func (c *Context) InSandBoxMode() bool { + return c.inSandBoxMode +} + // Close implements the sessionctx.Context interface. func (*Context) Close() {} @@ -443,17 +464,21 @@ func NewContext() *Context { ctx: ctx, cancel: cancel, } - sctx.sessionVars = variable.NewSessionVars(sctx) - sctx.sessionVars.InitChunkSize = 2 - sctx.sessionVars.MaxChunkSize = 32 - sctx.sessionVars.StmtCtx.TimeZone = time.UTC - sctx.sessionVars.StmtCtx.MemTracker = memory.NewTracker(-1, -1) - sctx.sessionVars.StmtCtx.DiskTracker = disk.NewTracker(-1, -1) - sctx.sessionVars.GlobalVarsAccessor = variable.NewMockGlobalAccessor() - sctx.sessionVars.EnablePaging = variable.DefTiDBEnablePaging - sctx.sessionVars.MinPagingSize = variable.DefMinPagingSize - sctx.sessionVars.CostModelVersion = variable.DefTiDBCostModelVer - sctx.sessionVars.EnableChunkRPC = true + vars := variable.NewSessionVars(sctx) + sctx.sessionVars = vars + vars.InitChunkSize = 2 + vars.MaxChunkSize = 32 + vars.StmtCtx.TimeZone = time.UTC + vars.MemTracker.SetBytesLimit(-1) + vars.DiskTracker.SetBytesLimit(-1) + vars.StmtCtx.MemTracker, vars.StmtCtx.DiskTracker = memory.NewTracker(-1, -1), disk.NewTracker(-1, -1) + vars.MemTracker.AttachTo(vars.MemTracker) + vars.DiskTracker.AttachTo(vars.DiskTracker) + vars.GlobalVarsAccessor = variable.NewMockGlobalAccessor() + vars.EnablePaging = variable.DefTiDBEnablePaging + vars.MinPagingSize = variable.DefMinPagingSize + vars.CostModelVersion = variable.DefTiDBCostModelVer + vars.EnableChunkRPC = true if err := sctx.GetSessionVars().SetSystemVar(variable.MaxAllowedPacket, "67108864"); err != nil { panic(err) } diff --git a/util/mock/main_test.go b/util/mock/main_test.go index 52fd2c12574b3..4583bc43b0f13 100644 --- a/util/mock/main_test.go +++ b/util/mock/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/mock/store.go b/util/mock/store.go index 3e5784fdb4d5a..ea7ca8e55fa3f 100644 --- a/util/mock/store.go +++ b/util/mock/store.go @@ -80,3 +80,8 @@ func (*Store) GetMinSafeTS(_ string) uint64 { func (*Store) GetLockWaits() ([]*deadlockpb.WaitForEntry, error) { return nil, nil } + +// GetCodec implements kv.Storage interface. +func (*Store) GetCodec() tikv.Codec { + return nil +} diff --git a/util/mvmap/main_test.go b/util/mvmap/main_test.go index c2ff6e9dac75f..7a5f3a941f68c 100644 --- a/util/mvmap/main_test.go +++ b/util/mvmap/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/paging/main_test.go b/util/paging/main_test.go index 52190006ff270..4fc9fe6e363ad 100644 --- a/util/paging/main_test.go +++ b/util/paging/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/parser/main_test.go b/util/parser/main_test.go index 467ed06d6bbee..4b1832ae442a3 100644 --- a/util/parser/main_test.go +++ b/util/parser/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/password-validation/BUILD.bazel b/util/password-validation/BUILD.bazel new file mode 100644 index 0000000000000..c3649a3a15383 --- /dev/null +++ b/util/password-validation/BUILD.bazel @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "password-validation", + srcs = ["password_validation.go"], + importpath = "github.com/pingcap/tidb/util/password-validation", + visibility = ["//visibility:public"], + deps = [ + "//sessionctx/variable", + "//util/hack", + ], +) + +go_test( + name = "password-validation_test", + srcs = ["password_validation_test.go"], + embed = [":password-validation"], + deps = [ + "//parser/auth", + "//sessionctx/variable", + "@com_github_stretchr_testify//require", + ], +) diff --git a/util/password-validation/password_validation.go b/util/password-validation/password_validation.go new file mode 100644 index 0000000000000..edd0bd39ec38a --- /dev/null +++ b/util/password-validation/password_validation.go @@ -0,0 +1,175 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package validator + +import ( + "bytes" + "fmt" + "strconv" + "strings" + "unicode" + + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/util/hack" +) + +const maxPwdValidationLength int = 100 + +const minPwdValidationLength int = 4 + +// ValidateDictionaryPassword checks if the password contains words in the dictionary. +func ValidateDictionaryPassword(pwd string, globalVars *variable.GlobalVarAccessor) (bool, error) { + dictionary, err := (*globalVars).GetGlobalSysVar(variable.ValidatePasswordDictionary) + if err != nil { + return false, err + } + words := strings.Split(dictionary, ";") + if len(words) == 0 { + return true, nil + } + pwd = strings.ToLower(pwd) + for _, word := range words { + if len(word) >= minPwdValidationLength && len(word) <= maxPwdValidationLength { + if strings.Contains(pwd, strings.ToLower(word)) { + return false, nil + } + } + } + return true, nil +} + +// ValidateUserNameInPassword checks whether pwd exists in the dictionary. +func ValidateUserNameInPassword(pwd string, sessionVars *variable.SessionVars) (string, error) { + currentUser := sessionVars.User + globalVars := sessionVars.GlobalVarsAccessor + pwdBytes := hack.Slice(pwd) + if checkUserName, err := globalVars.GetGlobalSysVar(variable.ValidatePasswordCheckUserName); err != nil { + return "", err + } else if currentUser != nil && variable.TiDBOptOn(checkUserName) { + for _, username := range []string{currentUser.AuthUsername, currentUser.Username} { + usernameBytes := hack.Slice(username) + userNameLen := len(usernameBytes) + if userNameLen == 0 { + continue + } + if bytes.Contains(pwdBytes, usernameBytes) { + return "Password Contains User Name", nil + } + usernameReversedBytes := make([]byte, userNameLen) + for i := range usernameBytes { + usernameReversedBytes[i] = usernameBytes[userNameLen-1-i] + } + if bytes.Contains(pwdBytes, usernameReversedBytes) { + return "Password Contains Reversed User Name", nil + } + } + } + return "", nil +} + +// ValidatePasswordLowPolicy checks whether pwd satisfies the low policy of password validation. +func ValidatePasswordLowPolicy(pwd string, globalVars *variable.GlobalVarAccessor) (string, error) { + if validateLengthStr, err := (*globalVars).GetGlobalSysVar(variable.ValidatePasswordLength); err != nil { + return "", err + } else if validateLength, err := strconv.ParseInt(validateLengthStr, 10, 64); err != nil { + return "", err + } else if (int64)(len([]rune(pwd))) < validateLength { + return fmt.Sprintf("Require Password Length: %d", validateLength), nil + } + return "", nil +} + +// ValidatePasswordMediumPolicy checks whether pwd satisfies the medium policy of password validation. +func ValidatePasswordMediumPolicy(pwd string, globalVars *variable.GlobalVarAccessor) (string, error) { + var lowerCaseCount, upperCaseCount, numberCount, specialCharCount int64 + runes := []rune(pwd) + for i := 0; i < len(runes); i++ { + if unicode.IsUpper(runes[i]) { + upperCaseCount++ + } else if unicode.IsLower(runes[i]) { + lowerCaseCount++ + } else if unicode.IsDigit(runes[i]) { + numberCount++ + } else { + specialCharCount++ + } + } + if mixedCaseCountStr, err := (*globalVars).GetGlobalSysVar(variable.ValidatePasswordMixedCaseCount); err != nil { + return "", err + } else if mixedCaseCount, err := strconv.ParseInt(mixedCaseCountStr, 10, 64); err != nil { + return "", err + } else if lowerCaseCount < mixedCaseCount { + return fmt.Sprintf("Require Password Lowercase Count: %d", mixedCaseCount), nil + } else if upperCaseCount < mixedCaseCount { + return fmt.Sprintf("Require Password Uppercase Count: %d", mixedCaseCount), nil + } + if requireNumberCountStr, err := (*globalVars).GetGlobalSysVar(variable.ValidatePasswordNumberCount); err != nil { + return "", err + } else if requireNumberCount, err := strconv.ParseInt(requireNumberCountStr, 10, 64); err != nil { + return "", err + } else if numberCount < requireNumberCount { + return fmt.Sprintf("Require Password Digit Count: %d", requireNumberCount), nil + } + if requireSpecialCharCountStr, err := (*globalVars).GetGlobalSysVar(variable.ValidatePasswordSpecialCharCount); err != nil { + return "", err + } else if requireSpecialCharCount, err := strconv.ParseInt(requireSpecialCharCountStr, 10, 64); err != nil { + return "", err + } else if specialCharCount < requireSpecialCharCount { + return fmt.Sprintf("Require Password Non-alphanumeric Count: %d", requireSpecialCharCount), nil + } + return "", nil +} + +// ValidatePassword checks whether the pwd can be used. +func ValidatePassword(sessionVars *variable.SessionVars, pwd string) error { + globalVars := sessionVars.GlobalVarsAccessor + + validatePolicy, err := globalVars.GetGlobalSysVar(variable.ValidatePasswordPolicy) + if err != nil { + return err + } + if warn, err := ValidateUserNameInPassword(pwd, sessionVars); err != nil { + return err + } else if len(warn) > 0 { + return variable.ErrNotValidPassword.GenWithStack(warn) + } + if warn, err := ValidatePasswordLowPolicy(pwd, &globalVars); err != nil { + return err + } else if len(warn) > 0 { + return variable.ErrNotValidPassword.GenWithStack(warn) + } + // LOW + if validatePolicy == "LOW" { + return nil + } + + // MEDIUM + if warn, err := ValidatePasswordMediumPolicy(pwd, &globalVars); err != nil { + return err + } else if len(warn) > 0 { + return variable.ErrNotValidPassword.GenWithStack(warn) + } + if validatePolicy == "MEDIUM" { + return nil + } + + // STRONG + if ok, err := ValidateDictionaryPassword(pwd, &globalVars); err != nil { + return err + } else if !ok { + return variable.ErrNotValidPassword.GenWithStack("Password contains word in the dictionary") + } + return nil +} diff --git a/util/password-validation/password_validation_test.go b/util/password-validation/password_validation_test.go new file mode 100644 index 0000000000000..8a851b2006203 --- /dev/null +++ b/util/password-validation/password_validation_test.go @@ -0,0 +1,175 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package validator + +import ( + "context" + "testing" + + "github.com/pingcap/tidb/parser/auth" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/stretchr/testify/require" +) + +func TestValidateDictionaryPassword(t *testing.T) { + vars := variable.NewSessionVars(nil) + mock := variable.NewMockGlobalAccessor4Tests() + mock.SessionVars = vars + vars.GlobalVarsAccessor = mock + + err := mock.SetGlobalSysVar(context.Background(), variable.ValidatePasswordDictionary, "abc;123;1234;5678;HIJK;中文测试;。,;!") + require.NoError(t, err) + testcases := []struct { + pwd string + result bool + }{ + {"abcdefg", true}, + {"abcd123efg", true}, + {"abcd1234efg", false}, + {"abcd12345efg", false}, + {"abcd123efghij", true}, + {"abcd123efghijk", false}, + {"abcd123efghij中文测试", false}, + {"abcd123。,;!", false}, + } + for _, testcase := range testcases { + ok, err := ValidateDictionaryPassword(testcase.pwd, &vars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, testcase.result, ok, testcase.pwd) + } +} + +func TestValidateUserNameInPassword(t *testing.T) { + sessionVars := variable.NewSessionVars(nil) + sessionVars.User = &auth.UserIdentity{Username: "user", AuthUsername: "authuser"} + sessionVars.GlobalVarsAccessor = variable.NewMockGlobalAccessor4Tests() + testcases := []struct { + pwd string + warn string + }{ + {"", ""}, + {"user", "Password Contains User Name"}, + {"authuser", "Password Contains User Name"}, + {"resu000", "Password Contains Reversed User Name"}, + {"resuhtua", "Password Contains Reversed User Name"}, + {"User", ""}, + {"authUser", ""}, + {"Resu", ""}, + {"Resuhtua", ""}, + } + // Enable check_user_name + err := sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordCheckUserName, "ON") + require.NoError(t, err) + for _, testcase := range testcases { + warn, err := ValidateUserNameInPassword(testcase.pwd, sessionVars) + require.NoError(t, err) + require.Equal(t, testcase.warn, warn, testcase.pwd) + } + + // Disable check_user_name + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordCheckUserName, "OFF") + require.NoError(t, err) + for _, testcase := range testcases { + warn, err := ValidateUserNameInPassword(testcase.pwd, sessionVars) + require.NoError(t, err) + require.Equal(t, "", warn, testcase.pwd) + } +} + +func TestValidatePasswordLowPolicy(t *testing.T) { + sessionVars := variable.NewSessionVars(nil) + sessionVars.GlobalVarsAccessor = variable.NewMockGlobalAccessor4Tests() + sessionVars.GlobalVarsAccessor.(*variable.MockGlobalAccessor).SessionVars = sessionVars + err := sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordLength, "8") + require.NoError(t, err) + + warn, err := ValidatePasswordLowPolicy("1234", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "Require Password Length: 8", warn) + warn, err = ValidatePasswordLowPolicy("12345678", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "", warn) + + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordLength, "12") + require.NoError(t, err) + warn, err = ValidatePasswordLowPolicy("12345678", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "Require Password Length: 12", warn) +} + +func TestValidatePasswordMediumPolicy(t *testing.T) { + sessionVars := variable.NewSessionVars(nil) + sessionVars.GlobalVarsAccessor = variable.NewMockGlobalAccessor4Tests() + sessionVars.GlobalVarsAccessor.(*variable.MockGlobalAccessor).SessionVars = sessionVars + + err := sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordMixedCaseCount, "1") + require.NoError(t, err) + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordSpecialCharCount, "2") + require.NoError(t, err) + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordNumberCount, "3") + require.NoError(t, err) + + warn, err := ValidatePasswordMediumPolicy("!@A123", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "Require Password Lowercase Count: 1", warn) + warn, err = ValidatePasswordMediumPolicy("!@a123", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "Require Password Uppercase Count: 1", warn) + warn, err = ValidatePasswordMediumPolicy("!@Aa12", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "Require Password Digit Count: 3", warn) + warn, err = ValidatePasswordMediumPolicy("!Aa123", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "Require Password Non-alphanumeric Count: 2", warn) + warn, err = ValidatePasswordMediumPolicy("!@Aa123", &sessionVars.GlobalVarsAccessor) + require.NoError(t, err) + require.Equal(t, "", warn) +} + +func TestValidatePassword(t *testing.T) { + sessionVars := variable.NewSessionVars(nil) + sessionVars.GlobalVarsAccessor = variable.NewMockGlobalAccessor4Tests() + sessionVars.GlobalVarsAccessor.(*variable.MockGlobalAccessor).SessionVars = sessionVars + sessionVars.User = &auth.UserIdentity{Username: "user", AuthUsername: "authuser"} + + err := sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordPolicy, "LOW") + require.NoError(t, err) + err = ValidatePassword(sessionVars, "1234") + require.Error(t, err) + err = ValidatePassword(sessionVars, "user1234") + require.Error(t, err) + err = ValidatePassword(sessionVars, "authuser1234") + require.Error(t, err) + err = ValidatePassword(sessionVars, "User1234") + require.NoError(t, err) + + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordPolicy, "MEDIUM") + require.NoError(t, err) + err = ValidatePassword(sessionVars, "User1234") + require.Error(t, err) + err = ValidatePassword(sessionVars, "!User1234") + require.NoError(t, err) + err = ValidatePassword(sessionVars, "!User1234") + require.NoError(t, err) + + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordPolicy, "STRONG") + require.NoError(t, err) + err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(context.Background(), variable.ValidatePasswordDictionary, "User") + require.NoError(t, err) + err = ValidatePassword(sessionVars, "!User1234") + require.Error(t, err) + err = ValidatePassword(sessionVars, "!ABcd1234") + require.NoError(t, err) +} diff --git a/util/plancodec/id.go b/util/plancodec/id.go index 8b17660bfa589..0366b7dc3f5a6 100644 --- a/util/plancodec/id.go +++ b/util/plancodec/id.go @@ -127,6 +127,10 @@ const ( TypeCTE = "CTEFullScan" // TypeCTEDefinition is the type of CTE definition TypeCTEDefinition = "CTE" + // TypeForeignKeyCheck is the type of FKCheck + TypeForeignKeyCheck = "Foreign_Key_Check" + // TypeForeignKeyCascade is the type of FKCascade + TypeForeignKeyCascade = "Foreign_Key_Cascade" ) // plan id. @@ -187,6 +191,8 @@ const ( typePartitionUnionID int = 53 typeShuffleID int = 54 typeShuffleReceiverID int = 55 + typeForeignKeyCheck int = 56 + typeForeignKeyCascade int = 57 ) // TypeStringToPhysicalID converts the plan type string to plan id. @@ -302,6 +308,10 @@ func TypeStringToPhysicalID(tp string) int { return typeCTEDefinitionID case TypeCTETable: return typeCTETableID + case TypeForeignKeyCheck: + return typeForeignKeyCheck + case TypeForeignKeyCascade: + return typeForeignKeyCascade } // Should never reach here. return 0 @@ -420,6 +430,10 @@ func PhysicalIDToTypeString(id int) string { return TypeCTEDefinition case typeCTETableID: return TypeCTETable + case typeForeignKeyCheck: + return TypeForeignKeyCheck + case typeForeignKeyCascade: + return TypeForeignKeyCascade } // Should never reach here. diff --git a/util/plancodec/main_test.go b/util/plancodec/main_test.go index b561ae2ab3141..e91a5c7442f47 100644 --- a/util/plancodec/main_test.go +++ b/util/plancodec/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/printer.go b/util/printer.go index 748097f91429a..56724bc1ff664 100644 --- a/util/printer.go +++ b/util/printer.go @@ -31,6 +31,7 @@ var ( ) // GetRawInfo do what its name tells +// nolint:unused func GetRawInfo(app string) string { info := "" info += fmt.Sprintf("App Name: %s\n", app) @@ -43,6 +44,7 @@ func GetRawInfo(app string) string { } // PrintInfo prints the app's basic information in log +// nolint:unused func PrintInfo(app string) { log.Info("Welcome to "+app, zap.String("Release Version", Version), diff --git a/util/printer/main_test.go b/util/printer/main_test.go index ce782dd021804..d56b58e4e2c77 100644 --- a/util/printer/main_test.go +++ b/util/printer/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/processinfo.go b/util/processinfo.go index 27d79e517b2d4..dee4f4ea30a53 100644 --- a/util/processinfo.go +++ b/util/processinfo.go @@ -15,7 +15,6 @@ package util import ( - "context" "crypto/tls" "errors" "fmt" @@ -26,40 +25,55 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/session/txninfo" "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/util/disk" "github.com/pingcap/tidb/util/execdetails" + "github.com/pingcap/tidb/util/memory" "github.com/tikv/client-go/v2/oracle" ) +// ProtectedTSList holds a list of timestamps that should delay GC. +type ProtectedTSList interface { + // HoldTS holds the timestamp to prevent its data from being GCed. + HoldTS(ts uint64) (unhold func()) + // GetMinProtectedTS returns the minimum protected timestamp that greater than `lowerBound` (0 if no such one). + GetMinProtectedTS(lowerBound uint64) (ts uint64) +} + // OOMAlarmVariablesInfo is a struct for OOM alarm variables. type OOMAlarmVariablesInfo struct { SessionAnalyzeVersion int SessionEnabledRateLimitAction bool + SessionMemQuotaQuery int64 } // ProcessInfo is a struct used for show processlist statement. type ProcessInfo struct { - Time time.Time - Plan interface{} - ctx context.Context - StmtCtx *stmtctx.StatementContext - CurrentAnalyzeRows func(interface{}, *execdetails.RuntimeStatsColl) [][]string - RuntimeStatsColl *execdetails.RuntimeStatsColl - StatsInfo func(interface{}) map[string]uint64 - User string - Digest string - DB string - Port string - Host string - Info string - PlanExplainRows [][]string - OOMAlarmVariablesInfo OOMAlarmVariablesInfo - ID uint64 - CurTxnStartTS uint64 - MaxExecutionTime uint64 - State uint16 - Command byte - ExceedExpensiveTimeThresh bool - RedactSQL bool + ProtectedTSList + Time time.Time + ExpensiveLogTime time.Time + Plan interface{} + StmtCtx *stmtctx.StatementContext + RefCountOfStmtCtx *stmtctx.ReferenceCount + MemTracker *memory.Tracker + DiskTracker *disk.Tracker + StatsInfo func(interface{}) map[string]uint64 + RuntimeStatsColl *execdetails.RuntimeStatsColl + DB string + Digest string + Host string + User string + Info string + Port string + PlanExplainRows [][]string + OOMAlarmVariablesInfo OOMAlarmVariablesInfo + ID uint64 + CurTxnStartTS uint64 + // MaxExecutionTime is the timeout for select statement, in milliseconds. + // If the query takes too long, kill it. + MaxExecutionTime uint64 + State uint16 + Command byte + RedactSQL bool } // ToRowForShow returns []interface{} for the row data of "SHOW [FULL] PROCESSLIST". @@ -114,16 +128,33 @@ func (pi *ProcessInfo) ToRow(tz *time.Location) []interface{} { bytesConsumed := int64(0) diskConsumed := int64(0) if pi.StmtCtx != nil { - if pi.StmtCtx.MemTracker != nil { - bytesConsumed = pi.StmtCtx.MemTracker.BytesConsumed() + if pi.MemTracker != nil { + bytesConsumed = pi.MemTracker.BytesConsumed() } - if pi.StmtCtx.DiskTracker != nil { - diskConsumed = pi.StmtCtx.DiskTracker.BytesConsumed() + if pi.DiskTracker != nil { + diskConsumed = pi.DiskTracker.BytesConsumed() } } return append(pi.ToRowForShow(true), pi.Digest, bytesConsumed, diskConsumed, pi.txnStartTs(tz)) } +// GetMinStartTS returns the minimum start-ts (used to delay GC) that greater than `lowerBound` (0 if no such one). +func (pi *ProcessInfo) GetMinStartTS(lowerBound uint64) (ts uint64) { + if pi == nil { + return + } + if thisTS := pi.CurTxnStartTS; thisTS > lowerBound && (thisTS < ts || ts == 0) { + ts = thisTS + } + if pi.ProtectedTSList == nil { + return + } + if thisTS := pi.GetMinProtectedTS(lowerBound); thisTS > lowerBound && (thisTS < ts || ts == 0) { + ts = thisTS + } + return +} + // ascServerStatus is a slice of all defined server status in ascending order. var ascServerStatus = []uint16{ mysql.ServerStatusInTrans, @@ -190,6 +221,10 @@ type SessionManager interface { GetInternalSessionStartTSList() []uint64 // CheckOldRunningTxn checks if there is an old transaction running in the current sessions CheckOldRunningTxn(job2ver map[int64]int64, job2ids map[int64]string) + // KillNonFlashbackClusterConn kill all non flashback cluster connections. + KillNonFlashbackClusterConn() + // GetMinStartTS returns the minimum start-ts (used to delay GC) that greater than `lowerBound` (0 if no such one). + GetMinStartTS(lowerBound uint64) uint64 } // GlobalConnID is the global connection ID, providing UNIQUE connection IDs across the whole TiDB cluster. diff --git a/util/profile/main_test.go b/util/profile/main_test.go index 5c66882744193..f55422d993b8b 100644 --- a/util/profile/main_test.go +++ b/util/profile/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/ranger/bench_test.go b/util/ranger/bench_test.go index e72a5caa31ee6..c980a806f6066 100644 --- a/util/ranger/bench_test.go +++ b/util/ranger/bench_test.go @@ -109,7 +109,7 @@ WHERE require.NoError(b, err) require.Len(b, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(b, err) ctx := context.Background() p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) diff --git a/util/ranger/checker.go b/util/ranger/checker.go index 48f6e3a389a13..0468d3c92472e 100644 --- a/util/ranger/checker.go +++ b/util/ranger/checker.go @@ -24,57 +24,83 @@ import ( // conditionChecker checks if this condition can be pushed to index planner. type conditionChecker struct { - checkerCol *expression.Column - colUniqueID int64 - length int - shouldReserve bool // check if a access condition should be reserved in filter conditions. + checkerCol *expression.Column + length int + optPrefixIndexSingleScan bool } -func (c *conditionChecker) check(condition expression.Expression) bool { +func (c *conditionChecker) isFullLengthColumn() bool { + return c.length == types.UnspecifiedLength || c.length == c.checkerCol.GetType().GetFlen() +} + +// check returns two values, isAccessCond and shouldReserve. +// isAccessCond indicates whether the condition can be used to build ranges. +// shouldReserve indicates whether the condition should be reserved in filter conditions. +func (c *conditionChecker) check(condition expression.Expression) (isAccessCond, shouldReserve bool) { switch x := condition.(type) { case *expression.ScalarFunction: return c.checkScalarFunction(x) case *expression.Column: if x.RetType.EvalType() == types.ETString { - return false + return false, true } return c.checkColumn(x) case *expression.Constant: - return true + return true, false } - return false + return false, true } -func (c *conditionChecker) checkScalarFunction(scalar *expression.ScalarFunction) bool { +func (c *conditionChecker) checkScalarFunction(scalar *expression.ScalarFunction) (isAccessCond, shouldReserve bool) { _, collation := scalar.CharsetAndCollation() switch scalar.FuncName.L { case ast.LogicOr, ast.LogicAnd: - return c.check(scalar.GetArgs()[0]) && c.check(scalar.GetArgs()[1]) + isAccessCond0, shouldReserve0 := c.check(scalar.GetArgs()[0]) + isAccessCond1, shouldReserve1 := c.check(scalar.GetArgs()[1]) + if isAccessCond0 && isAccessCond1 { + return true, shouldReserve0 || shouldReserve1 + } + return false, true case ast.EQ, ast.NE, ast.GE, ast.GT, ast.LE, ast.LT, ast.NullEQ: if _, ok := scalar.GetArgs()[0].(*expression.Constant); ok { - if c.checkColumn(scalar.GetArgs()[1]) { + if c.matchColumn(scalar.GetArgs()[1]) { // Checks whether the scalar function is calculated use the collation compatible with the column. if scalar.GetArgs()[1].GetType().EvalType() == types.ETString && !collate.CompatibleCollate(scalar.GetArgs()[1].GetType().GetCollate(), collation) { - return false + return false, true } - return scalar.FuncName.L != ast.NE || c.length == types.UnspecifiedLength + isFullLength := c.isFullLengthColumn() + if scalar.FuncName.L == ast.NE { + return isFullLength, !isFullLength + } + return true, !isFullLength } } if _, ok := scalar.GetArgs()[1].(*expression.Constant); ok { - if c.checkColumn(scalar.GetArgs()[0]) { + if c.matchColumn(scalar.GetArgs()[0]) { // Checks whether the scalar function is calculated use the collation compatible with the column. if scalar.GetArgs()[0].GetType().EvalType() == types.ETString && !collate.CompatibleCollate(scalar.GetArgs()[0].GetType().GetCollate(), collation) { - return false + return false, true + } + isFullLength := c.isFullLengthColumn() + if scalar.FuncName.L == ast.NE { + return isFullLength, !isFullLength } - return scalar.FuncName.L != ast.NE || c.length == types.UnspecifiedLength + return true, !isFullLength } } case ast.IsNull: - return c.checkColumn(scalar.GetArgs()[0]) + if c.matchColumn(scalar.GetArgs()[0]) { + var isNullReserve bool // We can know whether the column is null from prefix column of any length. + if !c.optPrefixIndexSingleScan { + isNullReserve = !c.isFullLengthColumn() + } + return true, isNullReserve + } + return false, true case ast.IsTruthWithoutNull, ast.IsFalsity, ast.IsTruthWithNull: if s, ok := scalar.GetArgs()[0].(*expression.Column); ok { if s.RetType.EvalType() == types.ETString { - return false + return false, true } } return c.checkColumn(scalar.GetArgs()[0]) @@ -83,34 +109,35 @@ func (c *conditionChecker) checkScalarFunction(scalar *expression.ScalarFunction s, ok := scalar.GetArgs()[0].(*expression.ScalarFunction) if !ok { // "not column" or "not constant" can't lead to a range. - return false + return false, true } if s.FuncName.L == ast.Like || s.FuncName.L == ast.NullEQ { - return false + return false, true } return c.check(scalar.GetArgs()[0]) case ast.In: - if !c.checkColumn(scalar.GetArgs()[0]) { - return false + if !c.matchColumn(scalar.GetArgs()[0]) { + return false, true } if scalar.GetArgs()[0].GetType().EvalType() == types.ETString && !collate.CompatibleCollate(scalar.GetArgs()[0].GetType().GetCollate(), collation) { - return false + return false, true } for _, v := range scalar.GetArgs()[1:] { if _, ok := v.(*expression.Constant); !ok { - return false + return false, true } } - return true + return true, !c.isFullLengthColumn() case ast.Like: return c.checkLikeFunc(scalar) case ast.GetParam: - return true + // TODO + return true, false } - return false + return false, true } -func (c *conditionChecker) checkLikeFunc(scalar *expression.ScalarFunction) bool { +func (c *conditionChecker) checkLikeFunc(scalar *expression.ScalarFunction) (isAccessCond, shouldReserve bool) { _, collation := scalar.CharsetAndCollation() if collate.NewCollationEnabled() && !collate.IsBinCollation(collation) { // The algorithm constructs the range in byte-level: for example, ab% is mapped to [ab, ac] by adding 1 to the last byte. @@ -120,29 +147,30 @@ func (c *conditionChecker) checkLikeFunc(scalar *expression.ScalarFunction) bool // Finally, the range comes to be [`, A], which is actually an empty range. // See https://github.com/pingcap/tidb/issues/31174 for more details. // In short, when the column type is non-binary collation string, we cannot use `like` expressions to generate the range. - return false + return false, true } if !collate.CompatibleCollate(scalar.GetArgs()[0].GetType().GetCollate(), collation) { - return false + return false, true } - if !c.checkColumn(scalar.GetArgs()[0]) { - return false + if !c.matchColumn(scalar.GetArgs()[0]) { + return false, true } pattern, ok := scalar.GetArgs()[1].(*expression.Constant) if !ok { - return false + return false, true } if pattern.Value.IsNull() { - return false + return false, true } patternStr, err := pattern.Value.ToString() if err != nil { - return false + return false, true } if len(patternStr) == 0 { - return true + return true, !c.isFullLengthColumn() } escape := byte(scalar.GetArgs()[2].(*expression.Constant).Value.GetInt64()) + likeFuncReserve := !c.isFullLengthColumn() for i := 0; i < len(patternStr); i++ { if patternStr[i] == escape { i++ @@ -152,16 +180,16 @@ func (c *conditionChecker) checkLikeFunc(scalar *expression.ScalarFunction) bool break } if i == 0 && (patternStr[i] == '%' || patternStr[i] == '_') { - return false + return false, true } if patternStr[i] == '%' { // We currently do not support using `enum like 'xxx%'` to build range // see https://github.com/pingcap/tidb/issues/27130 for more details if scalar.GetArgs()[0].GetType().GetType() == mysql.TypeEnum { - return false + return false, true } if i != len(patternStr)-1 { - c.shouldReserve = true + likeFuncReserve = true } break } @@ -169,23 +197,26 @@ func (c *conditionChecker) checkLikeFunc(scalar *expression.ScalarFunction) bool // We currently do not support using `enum like 'xxx_'` to build range // see https://github.com/pingcap/tidb/issues/27130 for more details if scalar.GetArgs()[0].GetType().GetType() == mysql.TypeEnum { - return false + return false, true } - c.shouldReserve = true + likeFuncReserve = true break } } - return true + return true, likeFuncReserve } -func (c *conditionChecker) checkColumn(expr expression.Expression) bool { - col, ok := expr.(*expression.Column) - if !ok { - return false - } +func (c *conditionChecker) matchColumn(expr expression.Expression) bool { // Check if virtual expression column matched if c.checkerCol != nil { - return c.checkerCol.EqualByExprAndID(nil, col) + return c.checkerCol.EqualByExprAndID(nil, expr) + } + return false +} + +func (c *conditionChecker) checkColumn(expr expression.Expression) (isAccessCond, shouldReserve bool) { + if c.matchColumn(expr) { + return true, !c.isFullLengthColumn() } - return c.colUniqueID == col.UniqueID + return false, true } diff --git a/util/ranger/detacher.go b/util/ranger/detacher.go index cd47c50d3cce0..606f53c40265f 100644 --- a/util/ranger/detacher.go +++ b/util/ranger/detacher.go @@ -49,14 +49,14 @@ func detachColumnCNFConditions(sctx sessionctx.Context, conditions []expression. accessConditions = append(accessConditions, rebuildDNF) continue } - if !checker.check(cond) { + isAccessCond, shouldReserve := checker.check(cond) + if !isAccessCond { filterConditions = append(filterConditions, cond) continue } accessConditions = append(accessConditions, cond) - if checker.shouldReserve { + if shouldReserve { filterConditions = append(filterConditions, cond) - checker.shouldReserve = checker.length != types.UnspecifiedLength } } return accessConditions, filterConditions @@ -82,13 +82,14 @@ func detachColumnDNFConditions(sctx sessionctx.Context, conditions []expression. } rebuildCNF := expression.ComposeCNFCondition(sctx, columnCNFItems...) accessConditions = append(accessConditions, rebuildCNF) - } else if !checker.check(cond) { - return nil, true } else { + isAccessCond, shouldReserve := checker.check(cond) + if !isAccessCond { + return nil, true + } accessConditions = append(accessConditions, cond) - if checker.shouldReserve { + if shouldReserve { hasResidualConditions = true - checker.shouldReserve = checker.length != types.UnspecifiedLength } } } @@ -331,9 +332,9 @@ func (d *rangeDetacher) detachCNFCondAndBuildRangeForIndex(conditions []expressi return res, nil } checker := &conditionChecker{ - checkerCol: d.cols[eqOrInCount], - length: d.lengths[eqOrInCount], - shouldReserve: d.lengths[eqOrInCount] != types.UnspecifiedLength, + checkerCol: d.cols[eqOrInCount], + length: d.lengths[eqOrInCount], + optPrefixIndexSingleScan: d.sctx.GetSessionVars().OptPrefixIndexSingleScan, } if considerDNF { pointRes, offset, columnValues, err := extractIndexPointRangesForCNF(d.sctx, conditions, d.cols, d.lengths, d.rangeMaxSize) @@ -410,7 +411,8 @@ func (d *rangeDetacher) detachCNFCondAndBuildRangeForIndex(conditions []expressi return res, nil } for _, cond := range newConditions { - if !checker.check(cond) { + isAccessCond, _ := checker.check(cond) + if !isAccessCond { filterConds = append(filterConds, cond) continue } @@ -579,9 +581,8 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex points[offset] = rb.intersection(points[offset], rb.build(cond, collator), collator) if len(points[offset]) == 0 { // Early termination if false expression found if expression.MaybeOverOptimized4PlanCache(sctx, conditions) { - // cannot return an empty-range for plan-cache since the range may become non-empty as parameters change - // for safety, return the whole conditions in this case - return nil, conditions, nil, nil, false + // `a>@x and a<@y` --> `invalid-range if @x>=@y` + sctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: some parameters may be overwritten")) } return nil, nil, nil, nil, true } @@ -604,9 +605,8 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex accesses[i] = nil } else if len(points[i]) == 0 { // Early termination if false expression found if expression.MaybeOverOptimized4PlanCache(sctx, conditions) { - // cannot return an empty-range for plan-cache since the range may become non-empty as parameters change - // for safety, return the whole conditions in this case - return nil, conditions, nil, nil, false + // `a>@x and a<@y` --> `invalid-range if @x>=@y` + sctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: some parameters may be overwritten")) } return nil, nil, nil, nil, true } else { @@ -619,8 +619,8 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex columnValues[i] = &valueInfo{mutable: true} } if expression.MaybeOverOptimized4PlanCache(sctx, conditions) { - // TODO: optimize it more elaborately, e.g. return [2 3, 2 3] as accesses for 'where a = 2 and b = 3 and c >= ? and c <= ?' - return nil, conditions, nil, nil, false + // `a=@x and a=@y` --> `a=@x if @x==@y` + sctx.GetSessionVars().StmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: some parameters may be overwritten")) } } } @@ -642,7 +642,8 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex // However, please notice that if you're implementing this, please (1) set StatementContext.OptimDependOnMutableConst to true, // or (2) don't do this optimization when StatementContext.UseCache is true. That's because this plan is affected by // flen of user variable, we cannot cache this plan. - if lengths[i] != types.UnspecifiedLength { + isFullLength := lengths[i] == types.UnspecifiedLength || lengths[i] == cols[i].GetType().GetFlen() + if !isFullLength { filters = append(filters, cond) } } @@ -655,9 +656,9 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex // We will detach the conditions of every DNF items, then compose them to a DNF. func (d *rangeDetacher) detachDNFCondAndBuildRangeForIndex(condition *expression.ScalarFunction, newTpSlice []*types.FieldType) (Ranges, []expression.Expression, []*valueInfo, bool, error) { firstColumnChecker := &conditionChecker{ - checkerCol: d.cols[0], - shouldReserve: d.lengths[0] != types.UnspecifiedLength, - length: d.lengths[0], + checkerCol: d.cols[0], + length: d.lengths[0], + optPrefixIndexSingleScan: d.sctx.GetSessionVars().OptPrefixIndexSingleScan, } rb := builder{sc: d.sctx.GetSessionVars().StmtCtx} dnfItems := expression.FlattenDNFConditions(condition) @@ -709,12 +710,13 @@ func (d *rangeDetacher) detachDNFCondAndBuildRangeForIndex(condition *expression } } } - } else if !firstColumnChecker.check(item) { - return FullRange(), nil, nil, true, nil } else { - if firstColumnChecker.shouldReserve { + isAccessCond, shouldReserve := firstColumnChecker.check(item) + if !isAccessCond { + return FullRange(), nil, nil, true, nil + } + if shouldReserve { hasResidual = true - firstColumnChecker.shouldReserve = d.lengths[0] != types.UnspecifiedLength } points := rb.build(item, collate.GetCollator(newTpSlice[0].GetCollate())) // TODO: restrict the mem usage of ranges @@ -917,20 +919,26 @@ func AppendConditionsIfNotExist(conditions, condsToAppend []expression.Expressio // ExtractAccessConditionsForColumn extracts the access conditions used for range calculation. Since // we don't need to return the remained filter conditions, it is much simpler than DetachCondsForColumn. -func ExtractAccessConditionsForColumn(conds []expression.Expression, col *expression.Column) []expression.Expression { +func ExtractAccessConditionsForColumn(ctx sessionctx.Context, conds []expression.Expression, col *expression.Column) []expression.Expression { checker := conditionChecker{ - checkerCol: col, - length: types.UnspecifiedLength, + checkerCol: col, + length: types.UnspecifiedLength, + optPrefixIndexSingleScan: ctx.GetSessionVars().OptPrefixIndexSingleScan, } accessConds := make([]expression.Expression, 0, 8) - return expression.Filter(accessConds, conds, checker.check) + filter := func(expr expression.Expression) bool { + isAccessCond, _ := checker.check(expr) + return isAccessCond + } + return expression.Filter(accessConds, conds, filter) } // DetachCondsForColumn detaches access conditions for specified column from other filter conditions. func DetachCondsForColumn(sctx sessionctx.Context, conds []expression.Expression, col *expression.Column) (accessConditions, otherConditions []expression.Expression) { checker := &conditionChecker{ - checkerCol: col, - length: types.UnspecifiedLength, + checkerCol: col, + length: types.UnspecifiedLength, + optPrefixIndexSingleScan: sctx.GetSessionVars().OptPrefixIndexSingleScan, } return detachColumnCNFConditions(sctx, conds, checker) } @@ -951,14 +959,16 @@ func MergeDNFItems4Col(ctx sessionctx.Context, dnfItems []expression.Expression) uniqueID := cols[0].UniqueID checker := &conditionChecker{ - checkerCol: cols[0], - length: types.UnspecifiedLength, + checkerCol: cols[0], + length: types.UnspecifiedLength, + optPrefixIndexSingleScan: ctx.GetSessionVars().OptPrefixIndexSingleScan, } // If we can't use this condition to build range, we can't merge it. // Currently, we assume if every condition in a DNF expression can pass this check, then `Selectivity` must be able to // cover this entire DNF directly without recursively call `Selectivity`. If this doesn't hold in the future, this logic // may cause infinite recursion in `Selectivity`. - if !checker.check(dnfItem) { + isAccessCond, _ := checker.check(dnfItem) + if !isAccessCond { mergedDNFItems = append(mergedDNFItems, dnfItem) continue } diff --git a/util/ranger/main_test.go b/util/ranger/main_test.go index 92ffa6f422fc1..462007239334c 100644 --- a/util/ranger/main_test.go +++ b/util/ranger/main_test.go @@ -44,7 +44,9 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), } if err := goleak.Find(opts...); err != nil { diff --git a/util/ranger/ranger_test.go b/util/ranger/ranger_test.go index ccaba66b5e50d..74af841563b0f 100644 --- a/util/ranger/ranger_test.go +++ b/util/ranger/ranger_test.go @@ -31,6 +31,7 @@ import ( "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/testkit/testdata" "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/ranger" "github.com/stretchr/testify/require" ) @@ -264,7 +265,7 @@ func TestTableRange(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -453,7 +454,7 @@ create table t( require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -814,7 +815,7 @@ func TestColumnRange(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -827,7 +828,7 @@ func TestColumnRange(t *testing.T) { } col := expression.ColInfo2Col(sel.Schema().Columns, ds.TableInfo().Columns[tt.colPos]) require.NotNil(t, col) - conds = ranger.ExtractAccessConditionsForColumn(conds, col) + conds = ranger.ExtractAccessConditionsForColumn(sctx, conds, col) require.Equal(t, tt.accessConds, fmt.Sprintf("%s", conds)) result, _, _, err := ranger.BuildColumnRange(conds, sctx, col.RetType, tt.length, 0) require.NoError(t, err) @@ -865,6 +866,7 @@ func TestCompIndexInExprCorrCol(t *testing.T) { testKit := testkit.NewTestKit(t, store) testKit.MustExec("use test") + testKit.MustExec("set tidb_cost_model_version=2") testKit.MustExec("drop table if exists t") testKit.MustExec("create table t(a int primary key, b int, c int, d int, e int, index idx(b,c,d))") testKit.MustExec("insert into t values(1,1,1,1,2),(2,1,2,1,0)") @@ -890,6 +892,7 @@ func TestIndexStringIsTrueRange(t *testing.T) { testKit := testkit.NewTestKit(t, store) testKit.MustExec("use test") + testKit.MustExec("set tidb_cost_model_version=2") testKit.MustExec("drop table if exists t0") testKit.MustExec("CREATE TABLE t0(c0 TEXT(10));") testKit.MustExec("INSERT INTO t0(c0) VALUES (1);") @@ -1196,7 +1199,7 @@ func TestIndexRangeForYear(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -1264,7 +1267,7 @@ func TestPrefixIndexRangeScan(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -1673,7 +1676,7 @@ create table t( require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -1914,7 +1917,7 @@ func TestTableShardIndex(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -1942,7 +1945,7 @@ func TestTableShardIndex(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -1960,7 +1963,7 @@ func TestTableShardIndex(t *testing.T) { require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -2105,7 +2108,7 @@ func getSelectionFromQuery(t *testing.T, sctx sessionctx.Context, sql string) *p require.NoError(t, err) require.Len(t, stmts, 1) ret := &plannercore.PreprocessorReturn{} - err = plannercore.Preprocess(sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) require.NoError(t, err) p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) require.NoError(t, err) @@ -2447,3 +2450,118 @@ func TestRangeFallbackForBuildColumnRange(t *testing.T) { require.Equal(t, "[]", fmt.Sprintf("%v", access)) require.Equal(t, "[in(test.t.b, 10, 20, 30)]", fmt.Sprintf("%v", remained)) } + +func TestPrefixIndexRange(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec(` +create table t( + a varchar(50), + b varchar(50), + c text(50), + d varbinary(50), + index idx_a(a(2)), + index idx_ab(a(2), b(2)), + index idx_c(c(2)), + index idx_d(d(2)) +)`) + tk.MustExec("set tidb_opt_prefix_index_single_scan = 1") + + tests := []struct { + indexPos int + exprStr string + accessConds string + filterConds string + resultStr string + }{ + { + indexPos: 0, + exprStr: "a is null", + accessConds: "[isnull(test.t.a)]", + filterConds: "[]", + resultStr: "[[NULL,NULL]]", + }, + { + indexPos: 0, + exprStr: "a is not null", + accessConds: "[not(isnull(test.t.a))]", + filterConds: "[]", + resultStr: "[[-inf,+inf]]", + }, + { + indexPos: 1, + exprStr: "a = 'a' and b is null", + accessConds: "[eq(test.t.a, a) isnull(test.t.b)]", + filterConds: "[eq(test.t.a, a)]", + resultStr: "[[\"a\" NULL,\"a\" NULL]]", + }, + { + indexPos: 1, + exprStr: "a = 'a' and b is not null", + accessConds: "[eq(test.t.a, a) not(isnull(test.t.b))]", + filterConds: "[eq(test.t.a, a)]", + resultStr: "[[\"a\" -inf,\"a\" +inf]]", + }, + { + indexPos: 2, + exprStr: "c is null", + accessConds: "[isnull(test.t.c)]", + filterConds: "[]", + resultStr: "[[NULL,NULL]]", + }, + { + indexPos: 2, + exprStr: "c is not null", + accessConds: "[not(isnull(test.t.c))]", + filterConds: "[]", + resultStr: "[[-inf,+inf]]", + }, + { + indexPos: 3, + exprStr: "d is null", + accessConds: "[isnull(test.t.d)]", + filterConds: "[]", + resultStr: "[[NULL,NULL]]", + }, + { + indexPos: 3, + exprStr: "d is not null", + accessConds: "[not(isnull(test.t.d))]", + filterConds: "[]", + resultStr: "[[-inf,+inf]]", + }, + } + + collate.SetNewCollationEnabledForTest(true) + defer func() { collate.SetNewCollationEnabledForTest(false) }() + ctx := context.Background() + for _, tt := range tests { + sql := "select * from t where " + tt.exprStr + sctx := tk.Session() + stmts, err := session.Parse(sctx, sql) + require.NoError(t, err, fmt.Sprintf("error %v, for expr %s", err, tt.exprStr)) + require.Len(t, stmts, 1) + ret := &plannercore.PreprocessorReturn{} + err = plannercore.Preprocess(context.Background(), sctx, stmts[0], plannercore.WithPreprocessorReturn(ret)) + require.NoError(t, err, fmt.Sprintf("error %v, for resolve name, expr %s", err, tt.exprStr)) + p, _, err := plannercore.BuildLogicalPlanForTest(ctx, sctx, stmts[0], ret.InfoSchema) + require.NoError(t, err, fmt.Sprintf("error %v, for build plan, expr %s", err, tt.exprStr)) + selection := p.(plannercore.LogicalPlan).Children()[0].(*plannercore.LogicalSelection) + tbl := selection.Children()[0].(*plannercore.DataSource).TableInfo() + require.NotNil(t, selection, fmt.Sprintf("expr:%v", tt.exprStr)) + conds := make([]expression.Expression, len(selection.Conditions)) + for i, cond := range selection.Conditions { + conds[i] = expression.PushDownNot(sctx, cond) + } + cols, lengths := expression.IndexInfo2PrefixCols(tbl.Columns, selection.Schema().Columns, tbl.Indices[tt.indexPos]) + require.NotNil(t, cols) + res, err := ranger.DetachCondAndBuildRangeForIndex(sctx, conds, cols, lengths, 0) + require.NoError(t, err) + require.Equal(t, tt.accessConds, fmt.Sprintf("%s", res.AccessConds), fmt.Sprintf("wrong access conditions for expr: %s", tt.exprStr)) + require.Equal(t, tt.filterConds, fmt.Sprintf("%s", res.RemainedConds), fmt.Sprintf("wrong filter conditions for expr: %s", tt.exprStr)) + got := fmt.Sprintf("%v", res.Ranges) + require.Equal(t, tt.resultStr, got, fmt.Sprintf("different for expr %s", tt.exprStr)) + } +} diff --git a/util/ranger/testdata/ranger_suite_out.json b/util/ranger/testdata/ranger_suite_out.json index f9d4ede451753..4a4f0c85e2682 100644 --- a/util/ranger/testdata/ranger_suite_out.json +++ b/util/ranger/testdata/ranger_suite_out.json @@ -9,12 +9,12 @@ "└─Apply 2.00 root CARTESIAN left outer semi join, other cond:eq(test.t.e, Column#26)", " ├─TableReader(Build) 2.00 root data:TableFullScan", " │ └─TableFullScan 2.00 cop[tikv] table:t keep order:false", - " └─StreamAgg(Probe) 1.00 root funcs:count(1)->Column#26", - " └─HashJoin 2.00 root inner join, equal:[eq(test.t.a, test.t.a)]", - " ├─TableReader(Build) 2.00 root data:TableFullScan", - " │ └─TableFullScan 2.00 cop[tikv] table:t1 keep order:false", - " └─IndexReader(Probe) 2.00 root index:IndexRangeScan", - " └─IndexRangeScan 2.00 cop[tikv] table:s, index:idx(b, c, d) range: decided by [eq(test.t.b, 1) in(test.t.c, 1, 2) eq(test.t.d, test.t.a)], keep order:false" + " └─StreamAgg(Probe) 2.00 root funcs:count(1)->Column#26", + " └─HashJoin 4.00 root inner join, equal:[eq(test.t.a, test.t.a)]", + " ├─IndexReader(Build) 4.00 root index:IndexFullScan", + " │ └─IndexFullScan 4.00 cop[tikv] table:t1, index:idx(b, c, d) keep order:false", + " └─IndexReader(Probe) 4.00 root index:IndexRangeScan", + " └─IndexRangeScan 4.00 cop[tikv] table:s, index:idx(b, c, d) range: decided by [eq(test.t.b, 1) in(test.t.c, 1, 2) eq(test.t.d, test.t.a)], keep order:false" ] }, { @@ -32,9 +32,9 @@ { "SQL": "explain format = 'brief' select * from t0 where c0", "Result": [ - "TableReader 0.80 root data:Selection", - "└─Selection 0.80 cop[tikv] test.t0.c0", - " └─TableFullScan 1.00 cop[tikv] table:t0 keep order:false" + "IndexReader 1.00 root index:Selection", + "└─Selection 1.00 cop[tikv] test.t0.c0", + " └─IndexFullScan 1.00 cop[tikv] table:t0, index:i0(c0) keep order:false" ] }, { @@ -56,17 +56,17 @@ { "SQL": "explain format = 'brief' select * from t0 where c0 is true", "Result": [ - "TableReader 0.80 root data:Selection", - "└─Selection 0.80 cop[tikv] istrue(cast(test.t0.c0, double BINARY))", - " └─TableFullScan 1.00 cop[tikv] table:t0 keep order:false" + "IndexReader 1.00 root index:Selection", + "└─Selection 1.00 cop[tikv] istrue(cast(test.t0.c0, double BINARY))", + " └─IndexFullScan 1.00 cop[tikv] table:t0, index:i0(c0) keep order:false" ] }, { "SQL": "explain format = 'brief' select * from t0 where c0 is false", "Result": [ - "TableReader 0.80 root data:Selection", - "└─Selection 0.80 cop[tikv] isfalse(cast(test.t0.c0, double BINARY))", - " └─TableFullScan 1.00 cop[tikv] table:t0 keep order:false" + "IndexReader 1.00 root index:Selection", + "└─Selection 1.00 cop[tikv] isfalse(cast(test.t0.c0, double BINARY))", + " └─IndexFullScan 1.00 cop[tikv] table:t0, index:i0(c0) keep order:false" ] }, { diff --git a/util/ranger/types.go b/util/ranger/types.go index d0beaa1c19a1d..6c6ab98c52157 100644 --- a/util/ranger/types.go +++ b/util/ranger/types.go @@ -75,6 +75,9 @@ func (ran *Range) Width() int { // Clone clones a Range. func (ran *Range) Clone() *Range { + if ran == nil { + return nil + } newRange := &Range{ LowVal: make([]types.Datum, 0, len(ran.LowVal)), HighVal: make([]types.Datum, 0, len(ran.HighVal)), diff --git a/util/replayer/BUILD.bazel b/util/replayer/BUILD.bazel new file mode 100644 index 0000000000000..bd04735f32d31 --- /dev/null +++ b/util/replayer/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "replayer", + srcs = ["replayer.go"], + importpath = "github.com/pingcap/tidb/util/replayer", + visibility = ["//visibility:public"], + deps = [ + "//config", + "@com_github_pingcap_errors//:errors", + ], +) diff --git a/util/replayer/replayer.go b/util/replayer/replayer.go new file mode 100644 index 0000000000000..de7439bd724f2 --- /dev/null +++ b/util/replayer/replayer.go @@ -0,0 +1,74 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package replayer + +import ( + "encoding/base64" + "fmt" + "math/rand" + "os" + "path/filepath" + "time" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/config" +) + +// PlanReplayerTaskKey indicates key of a plan replayer task +type PlanReplayerTaskKey struct { + SQLDigest string + PlanDigest string +} + +// GeneratePlanReplayerFile generates plan replayer file +func GeneratePlanReplayerFile(isCapture, isContinuesCapture, enableHistoricalStatsForCapture bool) (*os.File, string, error) { + path := GetPlanReplayerDirName() + err := os.MkdirAll(path, os.ModePerm) + if err != nil { + return nil, "", errors.AddStack(err) + } + fileName, err := generatePlanReplayerFileName(isCapture, isContinuesCapture, enableHistoricalStatsForCapture) + if err != nil { + return nil, "", errors.AddStack(err) + } + zf, err := os.Create(filepath.Join(path, fileName)) + if err != nil { + return nil, "", errors.AddStack(err) + } + return zf, fileName, err +} + +func generatePlanReplayerFileName(isCapture, isContinuesCapture, enableHistoricalStatsForCapture bool) (string, error) { + // Generate key and create zip file + time := time.Now().UnixNano() + b := make([]byte, 16) + //nolint: gosec + _, err := rand.Read(b) + if err != nil { + return "", err + } + key := base64.URLEncoding.EncodeToString(b) + if isContinuesCapture || isCapture && enableHistoricalStatsForCapture { + return fmt.Sprintf("capture_replayer_%v_%v.zip", key, time), nil + } + return fmt.Sprintf("replayer_%v_%v.zip", key, time), nil +} + +// GetPlanReplayerDirName returns plan replayer directory path. +// The path is related to the process id. +func GetPlanReplayerDirName() string { + tidbLogDir := filepath.Dir(config.GetGlobalConfig().Log.File.Filename) + return filepath.Join(tidbLogDir, "replayer") +} diff --git a/util/resourcegrouptag/main_test.go b/util/resourcegrouptag/main_test.go index 436c89e6a7c9b..3b661ec89f0c6 100644 --- a/util/resourcegrouptag/main_test.go +++ b/util/resourcegrouptag/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/rowDecoder/main_test.go b/util/rowDecoder/main_test.go index e153efc436e7c..887a047796ea9 100644 --- a/util/rowDecoder/main_test.go +++ b/util/rowDecoder/main_test.go @@ -24,6 +24,7 @@ import ( func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } testsetup.SetupForCommonTest() diff --git a/util/rowcodec/main_test.go b/util/rowcodec/main_test.go index 884964318ec8f..8a4515ed1c558 100644 --- a/util/rowcodec/main_test.go +++ b/util/rowcodec/main_test.go @@ -28,6 +28,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/security.go b/util/security.go index 648c6c76fa435..ce89633cbad57 100644 --- a/util/security.go +++ b/util/security.go @@ -231,9 +231,21 @@ func NewTLSConfig(opts ...TLSConfigOption) (*tls.Config, error) { return err } + intermediates := x509.NewCertPool() + for _, certBytes := range rawCerts[1:] { + c, err2 := x509.ParseCertificate(certBytes) + if err2 != nil { + return err2 + } + intermediates.AddCert(c) + } + certPoolMu.RLock() defer certPoolMu.RUnlock() - if _, err = cert.Verify(x509.VerifyOptions{Roots: certPool}); err != nil { + if _, err = cert.Verify(x509.VerifyOptions{ + Roots: certPool, + Intermediates: intermediates, + }); err != nil { return errors.Wrap(err, "can't verify certificate, maybe different CA is used") } return nil diff --git a/util/selection/main_test.go b/util/selection/main_test.go index 1296c123f6bb7..74c14e7867157 100644 --- a/util/selection/main_test.go +++ b/util/selection/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/sem/main_test.go b/util/sem/main_test.go index a3c39e71b6135..7f6d20b904741 100644 --- a/util/sem/main_test.go +++ b/util/sem/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/sem/sem.go b/util/sem/sem.go index 161334c880a4a..e2364893b05b2 100644 --- a/util/sem/sem.go +++ b/util/sem/sem.go @@ -136,7 +136,6 @@ func IsInvisibleStatusVar(varName string) bool { func IsInvisibleSysVar(varNameInLower string) bool { switch varNameInLower { case variable.TiDBDDLSlowOprThreshold, // ddl_slow_threshold - variable.TiDBAllowRemoveAutoInc, variable.TiDBCheckMb4ValueInUTF8, variable.TiDBConfig, variable.TiDBEnableSlowLog, diff --git a/util/sem/sem_test.go b/util/sem/sem_test.go index cb0c47ad9225d..d19c2af27adcb 100644 --- a/util/sem/sem_test.go +++ b/util/sem/sem_test.go @@ -81,8 +81,8 @@ func TestIsInvisibleSysVar(t *testing.T) { assert.False(IsInvisibleSysVar(variable.Hostname)) // changes the value to default, but is not invisible assert.False(IsInvisibleSysVar(variable.TiDBEnableEnhancedSecurity)) // should be able to see the mode is on. + assert.False(IsInvisibleSysVar(variable.TiDBAllowRemoveAutoInc)) - assert.True(IsInvisibleSysVar(variable.TiDBAllowRemoveAutoInc)) assert.True(IsInvisibleSysVar(variable.TiDBCheckMb4ValueInUTF8)) assert.True(IsInvisibleSysVar(variable.TiDBConfig)) assert.True(IsInvisibleSysVar(variable.TiDBEnableSlowLog)) diff --git a/util/servermemorylimit/BUILD.bazel b/util/servermemorylimit/BUILD.bazel index b03c059049567..0d2c4d4f3cb59 100644 --- a/util/servermemorylimit/BUILD.bazel +++ b/util/servermemorylimit/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "servermemorylimit", @@ -6,7 +6,25 @@ go_library( importpath = "github.com/pingcap/tidb/util/servermemorylimit", visibility = ["//visibility:public"], deps = [ + "//parser/mysql", + "//types", "//util", + "//util/logutil", "//util/memory", + "@org_uber_go_atomic//:atomic", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "servermemorylimit_test", + srcs = ["servermemorylimit_test.go"], + embed = [":servermemorylimit"], + flaky = True, + race = "on", + deps = [ + "//types", + "//util", + "@com_github_stretchr_testify//require", ], ) diff --git a/util/servermemorylimit/servermemorylimit.go b/util/servermemorylimit/servermemorylimit.go index 2e60032d61da1..511a86703db17 100644 --- a/util/servermemorylimit/servermemorylimit.go +++ b/util/servermemorylimit/servermemorylimit.go @@ -15,12 +15,28 @@ package servermemorylimit import ( + "fmt" "runtime" + "sync" "sync/atomic" "time" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util" + "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/memory" + atomicutil "go.uber.org/atomic" + "go.uber.org/zap" +) + +// Process global Observation indicators for memory limit. +var ( + MemoryMaxUsed = atomicutil.NewUint64(0) + SessionKillLast = atomicutil.NewTime(time.Time{}) + SessionKillTotal = atomicutil.NewInt64(0) + IsKilling = atomicutil.NewBool(false) + GlobalMemoryOpsHistoryManager = &memoryOpsHistoryManager{} ) // Handle is the handler for server memory limit. @@ -63,37 +79,142 @@ func (smqh *Handle) Run() { } type sessionToBeKilled struct { - isKilling bool - sqlStartTime time.Time - sessionID uint64 + isKilling bool + sqlStartTime time.Time + sessionID uint64 + sessionTracker *memory.Tracker + + killStartTime time.Time + lastLogTime time.Time } func killSessIfNeeded(s *sessionToBeKilled, bt uint64, sm util.SessionManager) { if s.isKilling { if info, ok := sm.GetProcessInfo(s.sessionID); ok { if info.Time == s.sqlStartTime { + if time.Since(s.lastLogTime) > 5*time.Second { + logutil.BgLogger().Warn(fmt.Sprintf("global memory controller failed to kill the top-consumer in %ds", + time.Since(s.killStartTime)/time.Second), + zap.Uint64("connID", info.ID), + zap.String("sql digest", info.Digest), + zap.String("sql text", fmt.Sprintf("%.100v", info.Info)), + zap.Int64("sql memory usage", info.MemTracker.BytesConsumed())) + s.lastLogTime = time.Now() + } return } } s.isKilling = false + IsKilling.Store(false) + memory.MemUsageTop1Tracker.CompareAndSwap(s.sessionTracker, nil) //nolint: all_revive,revive runtime.GC() + logutil.BgLogger().Warn("global memory controller killed the top1 memory consumer successfully") } if bt == 0 { return } - instanceStats := &runtime.MemStats{} - runtime.ReadMemStats(instanceStats) + instanceStats := memory.ReadMemStats() + if instanceStats.HeapInuse > MemoryMaxUsed.Load() { + MemoryMaxUsed.Store(instanceStats.HeapInuse) + } if instanceStats.HeapInuse > bt { t := memory.MemUsageTop1Tracker.Load() if t != nil { if info, ok := sm.GetProcessInfo(t.SessionID); ok { + logutil.BgLogger().Warn("global memory controller tries to kill the top1 memory consumer", + zap.Uint64("connID", info.ID), + zap.String("sql digest", info.Digest), + zap.String("sql text", fmt.Sprintf("%.100v", info.Info)), + zap.Uint64("tidb_server_memory_limit", bt), + zap.Uint64("heap inuse", instanceStats.HeapInuse), + zap.Int64("sql memory usage", info.MemTracker.BytesConsumed()), + ) s.sessionID = t.SessionID s.sqlStartTime = info.Time s.isKilling = true + s.sessionTracker = t t.NeedKill.Store(true) + + killTime := time.Now() + SessionKillTotal.Add(1) + SessionKillLast.Store(killTime) + IsKilling.Store(true) + GlobalMemoryOpsHistoryManager.recordOne(info, killTime, bt, instanceStats.HeapInuse) + s.lastLogTime = time.Now() + s.killStartTime = time.Now() } } } } + +type memoryOpsHistoryManager struct { + mu sync.Mutex + infos []memoryOpsHistory + offsets int +} + +type memoryOpsHistory struct { + killTime time.Time + memoryLimit uint64 + memoryCurrent uint64 + processInfoDatum []types.Datum // id,user,host,db,command,time,state,info,digest,mem,disk,txnStart +} + +func (m *memoryOpsHistoryManager) init() { + m.infos = make([]memoryOpsHistory, 50) + m.offsets = 0 +} + +func (m *memoryOpsHistoryManager) recordOne(info *util.ProcessInfo, killTime time.Time, memoryLimit uint64, memoryCurrent uint64) { + m.mu.Lock() + defer m.mu.Unlock() + op := memoryOpsHistory{killTime: killTime, memoryLimit: memoryLimit, memoryCurrent: memoryCurrent, processInfoDatum: types.MakeDatums(info.ToRow(time.UTC)...)} + sqlInfo := op.processInfoDatum[7] + sqlInfo.SetString(fmt.Sprintf("%.256v", sqlInfo.GetString()), mysql.DefaultCollationName) // Truncated + // Only record the last 50 history ops + m.infos[m.offsets] = op + m.offsets++ + if m.offsets >= 50 { + m.offsets = 0 + } +} + +func (m *memoryOpsHistoryManager) GetRows() [][]types.Datum { + m.mu.Lock() + defer m.mu.Unlock() + rows := make([][]types.Datum, 0, len(m.infos)) + getRowFromInfo := func(info memoryOpsHistory) { + killTime := types.NewTime(types.FromGoTime(info.killTime), mysql.TypeDatetime, 0) + op := "SessionKill" + rows = append(rows, []types.Datum{ + types.NewDatum(killTime), // TIME + types.NewDatum(op), // OPS + types.NewDatum(info.memoryLimit), // MEMORY_LIMIT + types.NewDatum(info.memoryCurrent), // MEMORY_CURRENT + info.processInfoDatum[0], // PROCESSID + info.processInfoDatum[9], // MEM + info.processInfoDatum[10], // DISK + info.processInfoDatum[2], // CLIENT + info.processInfoDatum[3], // DB + info.processInfoDatum[1], // USER + info.processInfoDatum[8], // SQL_DIGEST + info.processInfoDatum[7], // SQL_TEXT + }) + } + var zeroTime = time.Time{} + for i := 0; i < len(m.infos); i++ { + pos := (m.offsets + i) % len(m.infos) + info := m.infos[pos] + if info.killTime.Equal(zeroTime) { + continue + } + getRowFromInfo(info) + } + return rows +} + +func init() { + GlobalMemoryOpsHistoryManager.init() +} diff --git a/util/servermemorylimit/servermemorylimit_test.go b/util/servermemorylimit/servermemorylimit_test.go new file mode 100644 index 0000000000000..35c96942d29b5 --- /dev/null +++ b/util/servermemorylimit/servermemorylimit_test.go @@ -0,0 +1,71 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package servermemorylimit + +import ( + "strconv" + "testing" + "time" + + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/util" + "github.com/stretchr/testify/require" +) + +func TestMemoryUsageOpsHistory(t *testing.T) { + info := util.ProcessInfo{} + genInfo := func(i int) { + info.ID = uint64(i) + info.DB = strconv.Itoa(2 * i) + info.User = strconv.Itoa(3 * i) + info.Host = strconv.Itoa(4 * i) + info.Digest = strconv.Itoa(5 * i) + info.Info = strconv.Itoa(6 * i) + } + + for i := 0; i < 3; i++ { + genInfo(i) + GlobalMemoryOpsHistoryManager.recordOne(&info, time.Now(), uint64(i), uint64(2*i)) + } + + checkResult := func(datums []types.Datum, i int) { + require.Equal(t, datums[1].GetString(), "SessionKill") + require.Equal(t, datums[2].GetInt64(), int64(i)) + require.Equal(t, datums[3].GetInt64(), int64(2*i)) + require.Equal(t, datums[4].GetInt64(), int64(i)) + require.Equal(t, datums[7].GetString(), strconv.Itoa(4*i)) + require.Equal(t, datums[8].GetString(), strconv.Itoa(2*i)) + require.Equal(t, datums[9].GetString(), strconv.Itoa(3*i)) + require.Equal(t, datums[10].GetString(), strconv.Itoa(5*i)) + require.Equal(t, datums[11].GetString(), strconv.Itoa(6*i)) + } + + rows := GlobalMemoryOpsHistoryManager.GetRows() + require.Equal(t, 3, len(rows)) + for i := 0; i < 3; i++ { + checkResult(rows[i], i) + } + // Test evict + for i := 3; i < 53; i++ { + genInfo(i) + GlobalMemoryOpsHistoryManager.recordOne(&info, time.Now(), uint64(i), uint64(2*i)) + } + rows = GlobalMemoryOpsHistoryManager.GetRows() + require.Equal(t, 50, len(rows)) + for i := 3; i < 53; i++ { + checkResult(rows[i-3], i) + } + require.Equal(t, GlobalMemoryOpsHistoryManager.offsets, 3) +} diff --git a/util/set/main_test.go b/util/set/main_test.go index 515b5d13fc265..59f224554513f 100644 --- a/util/set/main_test.go +++ b/util/set/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/slice/main_test.go b/util/slice/main_test.go index cb09685762f55..3e886afa6be7b 100644 --- a/util/slice/main_test.go +++ b/util/slice/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/slice/slice.go b/util/slice/slice.go index 078772d58c15a..12738614a115f 100644 --- a/util/slice/slice.go +++ b/util/slice/slice.go @@ -39,3 +39,16 @@ func AllOf(s interface{}, p func(int) bool) bool { } return NoneOf(s, np) } + +// Copy is a deep copy of the slice. +func Copy[T any](a []*T) []*T { + b := make([]*T, len(a)) + for i, p := range a { + if p == nil { + continue + } + v := *p + b[i] = &v + } + return b +} diff --git a/util/slice/slice_test.go b/util/slice/slice_test.go index 5a9b9ec17100f..787e0584c0f77 100644 --- a/util/slice/slice_test.go +++ b/util/slice/slice_test.go @@ -43,3 +43,19 @@ func TestSlice(t *testing.T) { }) } } + +func TestCopy(t *testing.T) { + type T int + v0, v1, v2, v3 := T(0), T(1), T(2), T(3) + s := []*T{&v0, &v1, &v2, &v3, nil} + e := Copy(s) + require.Equal(t, len(s), len(e)) + for i := range s { + if s[i] == nil { + require.Nil(t, e[i]) + } else { + require.Equal(t, *s[i], *e[i]) + require.True(t, s[i] != e[i]) + } + } +} diff --git a/util/sqlexec/main_test.go b/util/sqlexec/main_test.go index 4b62e457496cd..f6e80059c0bab 100644 --- a/util/sqlexec/main_test.go +++ b/util/sqlexec/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/stmtsummary/BUILD.bazel b/util/stmtsummary/BUILD.bazel index 121d09caa6825..3c8c295a5d659 100644 --- a/util/stmtsummary/BUILD.bazel +++ b/util/stmtsummary/BUILD.bazel @@ -15,6 +15,7 @@ go_library( "//parser/mysql", "//sessionctx/stmtctx", "//types", + "//util/chunk", "//util/execdetails", "//util/hack", "//util/kvcache", @@ -23,6 +24,7 @@ go_library( "//util/set", "@com_github_pingcap_failpoint//:failpoint", "@com_github_tikv_client_go_v2//util", + "@org_golang_x_exp//maps", "@org_golang_x_exp//slices", "@org_uber_go_atomic//:atomic", "@org_uber_go_zap//:zap", diff --git a/util/stmtsummary/main_test.go b/util/stmtsummary/main_test.go index 0b9a7e8d677f4..b2e92cd9a56ba 100644 --- a/util/stmtsummary/main_test.go +++ b/util/stmtsummary/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/stmtsummary/reader.go b/util/stmtsummary/reader.go index eca48ae4e82eb..e5e9a2db39705 100644 --- a/util/stmtsummary/reader.go +++ b/util/stmtsummary/reader.go @@ -310,6 +310,9 @@ const ( PlanDigestStr = "PLAN_DIGEST" PlanStr = "PLAN" BinaryPlan = "BINARY_PLAN" + Charset = "CHARSET" + Collation = "COLLATION" + PlanHint = "PLAN_HINT" ) type columnValueFactory func(reader *stmtSummaryReader, ssElement *stmtSummaryByDigestElement, ssbd *stmtSummaryByDigest) interface{} @@ -620,4 +623,13 @@ var columnValueFactoryMap = map[string]columnValueFactory{ BinaryPlan: func(_ *stmtSummaryReader, ssElement *stmtSummaryByDigestElement, _ *stmtSummaryByDigest) interface{} { return ssElement.sampleBinaryPlan }, + Charset: func(_ *stmtSummaryReader, ssElement *stmtSummaryByDigestElement, _ *stmtSummaryByDigest) interface{} { + return ssElement.charset + }, + Collation: func(_ *stmtSummaryReader, ssElement *stmtSummaryByDigestElement, _ *stmtSummaryByDigest) interface{} { + return ssElement.collation + }, + PlanHint: func(_ *stmtSummaryReader, ssElement *stmtSummaryByDigestElement, _ *stmtSummaryByDigest) interface{} { + return ssElement.planHint + }, } diff --git a/util/stmtsummary/statement_summary.go b/util/stmtsummary/statement_summary.go index 8582dc522828e..0ac60f70a1e4a 100644 --- a/util/stmtsummary/statement_summary.go +++ b/util/stmtsummary/statement_summary.go @@ -27,12 +27,14 @@ import ( "github.com/pingcap/failpoint" "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/kvcache" "github.com/pingcap/tidb/util/plancodec" "github.com/tikv/client-go/v2/util" atomic2 "go.uber.org/atomic" + "golang.org/x/exp/maps" "golang.org/x/exp/slices" ) @@ -403,8 +405,9 @@ func (ssMap *stmtSummaryByDigestMap) GetMoreThanCntBindableStmt(cnt int64) []*Bi PlanHint: ssElement.planHint, Charset: ssElement.charset, Collation: ssElement.collation, - Users: ssElement.authUsers, + Users: make(map[string]struct{}), } + maps.Copy(stmt.Users, ssElement.authUsers) // If it is SQL command prepare / execute, the ssElement.sampleSQL is `execute ...`, we should get the original select query. // If it is binary protocol prepare / execute, ssbd.normalizedSQL should be same as ssElement.sampleSQL. if ssElement.prepared { @@ -498,6 +501,31 @@ func (ssMap *stmtSummaryByDigestMap) maxSQLLength() int { return int(ssMap.optMaxSQLLength.Load()) } +// GetBindableStmtFromCluster gets users' select/update/delete SQL. +func GetBindableStmtFromCluster(rows []chunk.Row) *BindableStmt { + for _, row := range rows { + user := row.GetString(3) + stmtType := row.GetString(0) + if user != "" && (stmtType == "Select" || stmtType == "Delete" || stmtType == "Update" || stmtType == "Insert" || stmtType == "Replace") { + // Empty auth users means that it is an internal queries. + stmt := &BindableStmt{ + Schema: row.GetString(1), //schemaName + Query: row.GetString(5), //sampleSQL + PlanHint: row.GetString(8), //planHint + Charset: row.GetString(6), //charset + Collation: row.GetString(7), //collation + } + // If it is SQL command prepare / execute, the ssElement.sampleSQL is `execute ...`, we should get the original select query. + // If it is binary protocol prepare / execute, ssbd.normalizedSQL should be same as ssElement.sampleSQL. + if row.GetInt64(4) == 1 { + stmt.Query = row.GetString(2) //normalizedSQL + } + return stmt + } + } + return nil +} + // newStmtSummaryByDigest creates a stmtSummaryByDigest from StmtExecInfo. func (ssbd *stmtSummaryByDigest) init(sei *StmtExecInfo, _ int64, _ int64, _ int) { // Use "," to separate table names to support FIND_IN_SET. diff --git a/util/stmtsummary/statement_summary_test.go b/util/stmtsummary/statement_summary_test.go index 8ee767f2342e0..ac7e1b06e059b 100644 --- a/util/stmtsummary/statement_summary_test.go +++ b/util/stmtsummary/statement_summary_test.go @@ -175,9 +175,8 @@ func TestAddStatement(t *testing.T) { MaxWaitTime: 2500, }, ExecDetail: &execdetails.ExecDetails{ - CalleeAddress: "202", - BackoffTime: 180, - RequestCount: 20, + BackoffTime: 180, + RequestCount: 20, CommitDetail: &util.CommitDetails{ GetCommitTsTime: 500, PrewriteTime: 50000, @@ -214,9 +213,11 @@ func TestAddStatement(t *testing.T) { RocksdbBlockReadCount: 10, RocksdbBlockReadByte: 1000, }, - TimeDetail: util.TimeDetail{ - ProcessTime: 1500, - WaitTime: 150, + DetailsNeedP90: execdetails.DetailsNeedP90{ + TimeDetail: util.TimeDetail{ + ProcessTime: 1500, + WaitTime: 150, + }, CalleeAddress: "202", }, }, StmtCtx: &stmtctx.StatementContext{ @@ -313,9 +314,8 @@ func TestAddStatement(t *testing.T) { MaxWaitTime: 250, }, ExecDetail: &execdetails.ExecDetails{ - CalleeAddress: "302", - BackoffTime: 18, - RequestCount: 2, + BackoffTime: 18, + RequestCount: 2, CommitDetail: &util.CommitDetails{ GetCommitTsTime: 50, PrewriteTime: 5000, @@ -352,9 +352,12 @@ func TestAddStatement(t *testing.T) { RocksdbBlockReadCount: 10, RocksdbBlockReadByte: 1000, }, - TimeDetail: util.TimeDetail{ - ProcessTime: 150, - WaitTime: 15, + DetailsNeedP90: execdetails.DetailsNeedP90{ + TimeDetail: util.TimeDetail{ + ProcessTime: 150, + WaitTime: 15, + }, + CalleeAddress: "302", }, }, StmtCtx: &stmtctx.StatementContext{ @@ -605,9 +608,8 @@ func generateAnyExecInfo() *StmtExecInfo { MaxWaitTime: 1500, }, ExecDetail: &execdetails.ExecDetails{ - CalleeAddress: "129", - BackoffTime: 80, - RequestCount: 10, + BackoffTime: 80, + RequestCount: 10, CommitDetail: &util.CommitDetails{ GetCommitTsTime: 100, PrewriteTime: 10000, @@ -644,9 +646,12 @@ func generateAnyExecInfo() *StmtExecInfo { RocksdbBlockReadCount: 10, RocksdbBlockReadByte: 1000, }, - TimeDetail: util.TimeDetail{ - ProcessTime: 500, - WaitTime: 50, + DetailsNeedP90: execdetails.DetailsNeedP90{ + TimeDetail: util.TimeDetail{ + ProcessTime: 500, + WaitTime: 50, + }, + CalleeAddress: "129", }, }, StmtCtx: &stmtctx.StatementContext{ diff --git a/util/stringutil/main_test.go b/util/stringutil/main_test.go index 0ae6ce85d93ec..09b386feae213 100644 --- a/util/stringutil/main_test.go +++ b/util/stringutil/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/syncutil/BUILD.bazel b/util/syncutil/BUILD.bazel new file mode 100644 index 0000000000000..919301546f69c --- /dev/null +++ b/util/syncutil/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "syncutil", + srcs = [ + "mutex_deadlock.go", + "mutex_sync.go", + ], + importpath = "github.com/pingcap/tidb/util/syncutil", + visibility = ["//visibility:public"], + deps = ["@com_github_sasha_s_go_deadlock//:go-deadlock"], +) diff --git a/util/syncutil/mutex_deadlock.go b/util/syncutil/mutex_deadlock.go new file mode 100644 index 0000000000000..8879ff5138104 --- /dev/null +++ b/util/syncutil/mutex_deadlock.go @@ -0,0 +1,40 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build deadlock + +package syncutil + +import ( + "time" + + deadlock "github.com/sasha-s/go-deadlock" +) + +// EnableDeadlock is a flag to enable deadlock detection. +const EnableDeadlock = true + +func init() { + deadlock.Opts.DeadlockTimeout = 20 * time.Second +} + +// A Mutex is a mutual exclusion lock. +type Mutex struct { + deadlock.Mutex +} + +// An RWMutex is a reader/writer mutual exclusion lock. +type RWMutex struct { + deadlock.RWMutex +} diff --git a/util/syncutil/mutex_sync.go b/util/syncutil/mutex_sync.go new file mode 100644 index 0000000000000..c6bdc55ccf87b --- /dev/null +++ b/util/syncutil/mutex_sync.go @@ -0,0 +1,32 @@ +// Copyright 2023 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !deadlock + +package syncutil + +import "sync" + +// EnableDeadlock is a flag to enable deadlock detection. +const EnableDeadlock = false + +// A Mutex is a mutual exclusion lock. +type Mutex struct { + sync.Mutex +} + +// An RWMutex is a reader/writer mutual exclusion lock. +type RWMutex struct { + sync.RWMutex +} diff --git a/util/sys/linux/main_test.go b/util/sys/linux/main_test.go index b021e636a64ed..88f9f2fdf24c3 100644 --- a/util/sys/linux/main_test.go +++ b/util/sys/linux/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/sys/storage/main_test.go b/util/sys/storage/main_test.go index 7a24dde8259a0..ef6ea743450f3 100644 --- a/util/sys/storage/main_test.go +++ b/util/sys/storage/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/systimemon/main_test.go b/util/systimemon/main_test.go index 7d9f1efd961c4..9539aca3a1096 100644 --- a/util/systimemon/main_test.go +++ b/util/systimemon/main_test.go @@ -26,6 +26,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("github.com/pingcap/tidb/util/systimemon.StartMonitor"), } diff --git a/util/systimemon/systime_mon.go b/util/systimemon/systime_mon.go index 67b23ed894b5b..26819a4159776 100644 --- a/util/systimemon/systime_mon.go +++ b/util/systimemon/systime_mon.go @@ -22,11 +22,10 @@ import ( ) // StartMonitor calls systimeErrHandler if system time jump backward. -func StartMonitor(now func() time.Time, systimeErrHandler func(), successCallback func()) { +func StartMonitor(now func() time.Time, systimeErrHandler func()) { logutil.BgLogger().Info("start system time monitor") tick := time.NewTicker(100 * time.Millisecond) defer tick.Stop() - tickCount := 0 for { last := now().UnixNano() <-tick.C @@ -34,11 +33,5 @@ func StartMonitor(now func() time.Time, systimeErrHandler func(), successCallbac logutil.BgLogger().Error("system time jump backward", zap.Int64("last", last)) systimeErrHandler() } - // call successCallback per second. - tickCount++ - if tickCount >= 10 { - tickCount = 0 - successCallback() - } } } diff --git a/util/systimemon/systime_mon_test.go b/util/systimemon/systime_mon_test.go index f05098b63db7e..6964a9ac3d70d 100644 --- a/util/systimemon/systime_mon_test.go +++ b/util/systimemon/systime_mon_test.go @@ -35,7 +35,7 @@ func TestSystimeMonitor(t *testing.T) { return time.Now().Add(-2 * time.Second) }, func() { errTriggered.Store(true) - }, func() {}) + }) require.Eventually(t, errTriggered.Load, time.Second, 10*time.Millisecond) } diff --git a/util/testleak/BUILD.bazel b/util/testleak/BUILD.bazel deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/util/texttree/main_test.go b/util/texttree/main_test.go index 8516e5e769179..c73786745d798 100644 --- a/util/texttree/main_test.go +++ b/util/texttree/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/timeutil/main_test.go b/util/timeutil/main_test.go index 2f09e2a8b84c6..add3ffbb50126 100644 --- a/util/timeutil/main_test.go +++ b/util/timeutil/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/topsql/collector/main_test.go b/util/topsql/collector/main_test.go index 82eddcefd5a34..1177b5d4f9c16 100644 --- a/util/topsql/collector/main_test.go +++ b/util/topsql/collector/main_test.go @@ -31,6 +31,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/topsql/main_test.go b/util/topsql/main_test.go index e5867303db32b..7317f50b2001b 100644 --- a/util/topsql/main_test.go +++ b/util/topsql/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/topsql/reporter/main_test.go b/util/topsql/reporter/main_test.go index cc46791c945df..f5f17f44ac7a6 100644 --- a/util/topsql/reporter/main_test.go +++ b/util/topsql/reporter/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/topsql/stmtstats/main_test.go b/util/topsql/stmtstats/main_test.go index c5d1ac3b50560..e75153cf9141f 100644 --- a/util/topsql/stmtstats/main_test.go +++ b/util/topsql/stmtstats/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/tracing/main_test.go b/util/tracing/main_test.go index 207e2e1b7b8e8..02cf4faecadb9 100644 --- a/util/tracing/main_test.go +++ b/util/tracing/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/util.go b/util/util.go index 485869adae2e3..e3a9cf25f750f 100644 --- a/util/util.go +++ b/util/util.go @@ -15,9 +15,11 @@ package util import ( + "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" + "net" "net/http" "strconv" "strings" @@ -25,6 +27,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/parser" + "go.uber.org/atomic" "go.uber.org/zap" ) @@ -60,6 +63,8 @@ func StringsToInterfaces(strs []string) []interface{} { // return errors.Trace(err) // } // fmt.Println(resp.IP) +// +// nolint:unused func GetJSON(client *http.Client, url string, v interface{}) error { resp, err := client.Get(url) if err != nil { @@ -68,7 +73,7 @@ func GetJSON(client *http.Client, url string, v interface{}) error { defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return errors.Trace(err) } @@ -106,6 +111,11 @@ func Str2Int64Map(str string) map[int64]struct{} { // GenLogFields generate log fields. func GenLogFields(costTime time.Duration, info *ProcessInfo, needTruncateSQL bool) []zap.Field { + if info.RefCountOfStmtCtx != nil && !info.RefCountOfStmtCtx.TryIncrease() { + return nil + } + defer info.RefCountOfStmtCtx.Decrease() + logFields := make([]zap.Field, 0, 20) logFields = append(logFields, zap.String("cost_time", strconv.FormatFloat(costTime.Seconds(), 'f', -1, 64)+"s")) execDetail := info.StmtCtx.GetExecDetails() @@ -151,7 +161,7 @@ func GenLogFields(costTime time.Duration, info *ProcessInfo, needTruncateSQL boo logFields = append(logFields, zap.String("index_names", indexNames)) } logFields = append(logFields, zap.Uint64("txn_start_ts", info.CurTxnStartTS)) - if memTracker := info.StmtCtx.MemTracker; memTracker != nil { + if memTracker := info.MemTracker; memTracker != nil { logFields = append(logFields, zap.String("mem_max", fmt.Sprintf("%d Bytes (%v)", memTracker.MaxConsumed(), memTracker.FormatBytes(memTracker.MaxConsumed())))) } @@ -169,3 +179,57 @@ func GenLogFields(costTime time.Duration, info *ProcessInfo, needTruncateSQL boo logFields = append(logFields, zap.String("sql", sql)) return logFields } + +// PrintableASCII detects if b is a printable ASCII character. +// Ref to:http://facweb.cs.depaul.edu/sjost/it212/documents/ascii-pr.htm +func PrintableASCII(b byte) bool { + if b < 32 || b > 127 { + return false + } + + return true +} + +// FmtNonASCIIPrintableCharToHex turns non-printable-ASCII characters into Hex +func FmtNonASCIIPrintableCharToHex(str string) string { + var b bytes.Buffer + b.Grow(len(str) * 2) + for i := 0; i < len(str); i++ { + if PrintableASCII(str[i]) { + b.WriteByte(str[i]) + continue + } + + b.WriteString(`\x`) + // turns non-printable-ASCII character into hex-string + b.WriteString(fmt.Sprintf("%02X", str[i])) + } + return b.String() +} + +// TCPConnWithIOCounter is a wrapper of net.TCPConn with counter that accumulates +// the bytes this connection reads/writes. +type TCPConnWithIOCounter struct { + *net.TCPConn + c *atomic.Uint64 +} + +// NewTCPConnWithIOCounter creates a new TCPConnWithIOCounter. +func NewTCPConnWithIOCounter(conn *net.TCPConn, c *atomic.Uint64) net.Conn { + return &TCPConnWithIOCounter{ + TCPConn: conn, + c: c, + } +} + +func (t *TCPConnWithIOCounter) Read(b []byte) (n int, err error) { + n, err = t.TCPConn.Read(b) + t.c.Add(uint64(n)) + return n, err +} + +func (t *TCPConnWithIOCounter) Write(b []byte) (n int, err error) { + n, err = t.TCPConn.Write(b) + t.c.Add(uint64(n)) + return n, err +} diff --git a/util/util_test.go b/util/util_test.go index 152d5fe3e651f..ca68a55cd8ba6 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -28,6 +28,7 @@ func TestLogFormat(t *testing.T) { mem.Consume(1<<30 + 1<<29 + 1<<28 + 1<<27) mockTooLongQuery := make([]byte, 1024*9) + var refCount stmtctx.ReferenceCount = 0 info := &ProcessInfo{ ID: 233, User: "PingCAP", @@ -38,10 +39,10 @@ func TestLogFormat(t *testing.T) { StatsInfo: func(interface{}) map[string]uint64 { return nil }, - StmtCtx: &stmtctx.StatementContext{ - MemTracker: mem, - }, - RedactSQL: false, + StmtCtx: &stmtctx.StatementContext{}, + RefCountOfStmtCtx: &refCount, + MemTracker: mem, + RedactSQL: false, } costTime := time.Second * 233 logSQLTruncateLen := 1024 * 8 diff --git a/util/vitess/main_test.go b/util/vitess/main_test.go index 498274e846fcf..b5f91d4df1535 100644 --- a/util/vitess/main_test.go +++ b/util/vitess/main_test.go @@ -25,6 +25,7 @@ func TestMain(m *testing.M) { testsetup.SetupForCommonTest() opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), + goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), } goleak.VerifyTestMain(m, opts...) diff --git a/util/wait_group_wrapper.go b/util/wait_group_wrapper.go index 16c8704920a28..21f808934f8d7 100644 --- a/util/wait_group_wrapper.go +++ b/util/wait_group_wrapper.go @@ -16,8 +16,129 @@ package util import ( "sync" + "time" + + "github.com/pingcap/tidb/util/logutil" + "go.uber.org/zap" ) +// WaitGroupEnhancedWrapper wrapper wg, it provides the basic ability of WaitGroupWrapper with checking unexited process +// if the `exited` signal is true by print them on log. +type WaitGroupEnhancedWrapper struct { + sync.WaitGroup + source string + registerProcess sync.Map +} + +// NewWaitGroupEnhancedWrapper returns WaitGroupEnhancedWrapper, the empty source indicates the unit test, then +// the `checkUnExitedProcess` won't be executed. +func NewWaitGroupEnhancedWrapper(source string, exit chan struct{}, exitedCheck bool) *WaitGroupEnhancedWrapper { + wgew := &WaitGroupEnhancedWrapper{ + source: source, + registerProcess: sync.Map{}, + } + if exitedCheck { + wgew.Add(1) + go wgew.checkUnExitedProcess(exit) + } + return wgew +} + +func (w *WaitGroupEnhancedWrapper) checkUnExitedProcess(exit chan struct{}) { + defer func() { + logutil.BgLogger().Info("waitGroupWrapper exit-checking exited", zap.String("source", w.source)) + w.Done() + }() + logutil.BgLogger().Info("waitGroupWrapper enable exit-checking", zap.String("source", w.source)) + <-exit + logutil.BgLogger().Info("waitGroupWrapper start exit-checking", zap.String("source", w.source)) + if w.check() { + ticker := time.NewTimer(2 * time.Second) + defer ticker.Stop() + for { + <-ticker.C + continueCheck := w.check() + if !continueCheck { + return + } + } + } +} + +func (w *WaitGroupEnhancedWrapper) check() bool { + unexitedProcess := make([]string, 0) + w.registerProcess.Range(func(key, value any) bool { + unexitedProcess = append(unexitedProcess, key.(string)) + return true + }) + if len(unexitedProcess) > 0 { + logutil.BgLogger().Warn("background process unexited while received exited signal", + zap.Strings("process", unexitedProcess), + zap.String("source", w.source)) + return true + } + logutil.BgLogger().Info("waitGroupWrapper finish checking unexited process", zap.String("source", w.source)) + return false +} + +// Run runs a function in a goroutine, adds 1 to WaitGroup +// and calls done when function returns. Please DO NOT use panic +// in the cb function. +// Note that the registered label shouldn't be duplicated. +func (w *WaitGroupEnhancedWrapper) Run(exec func(), label string) { + w.onStart(label) + w.Add(1) + go func() { + defer func() { + w.onExit(label) + w.Done() + }() + exec() + }() +} + +// RunWithRecover wraps goroutine startup call with force recovery, add 1 to WaitGroup +// and call done when function return. +// exec is that execute logic function. recoverFn is that handler will be called after recover and before dump stack, +// passing `nil` means noop. +// Note that the registered label shouldn't be duplicated. +func (w *WaitGroupEnhancedWrapper) RunWithRecover(exec func(), recoverFn func(r interface{}), label string) { + w.onStart(label) + w.Add(1) + go func() { + defer func() { + r := recover() + if r != nil && recoverFn != nil { + logutil.BgLogger().Info("WaitGroupEnhancedWrapper exec panic recovered", zap.String("process", label)) + recoverFn(r) + } + w.onExit(label) + w.Done() + }() + exec() + }() +} + +func (w *WaitGroupEnhancedWrapper) onStart(label string) { + _, ok := w.registerProcess.Load(label) + if ok { + logutil.BgLogger().Panic("WaitGroupEnhancedWrapper received duplicated source process", + zap.String("source", w.source), + zap.String("process", label)) + } + w.registerProcess.Store(label, struct{}{}) + logutil.BgLogger().Info("background process started", + zap.String("source", w.source), + zap.String("process", label)) +} + +func (w *WaitGroupEnhancedWrapper) onExit(label string) { + w.registerProcess.Delete(label) + logutil.BgLogger().Info("background process exited", + zap.String("source", w.source), + zap.String("process", label)) +} + // WaitGroupWrapper is a wrapper for sync.WaitGroup type WaitGroupWrapper struct { sync.WaitGroup @@ -43,7 +164,7 @@ func (w *WaitGroupWrapper) RunWithRecover(exec func(), recoverFn func(r interfac go func() { defer func() { r := recover() - if r != nil && recoverFn != nil { + if recoverFn != nil { recoverFn(r) } w.Done() diff --git a/util/wait_group_wrapper_test.go b/util/wait_group_wrapper_test.go index 40e66fdaf5759..2d06abdd689df 100644 --- a/util/wait_group_wrapper_test.go +++ b/util/wait_group_wrapper_test.go @@ -15,7 +15,9 @@ package util import ( + "fmt" "testing" + "time" "github.com/stretchr/testify/require" "go.uber.org/atomic" @@ -32,6 +34,16 @@ func TestWaitGroupWrapperRun(t *testing.T) { } wg.Wait() require.Equal(t, expect, val.Load()) + + val.Store(0) + wg2 := NewWaitGroupEnhancedWrapper("", nil, false) + for i := int32(0); i < expect; i++ { + wg2.Run(func() { + val.Inc() + }, fmt.Sprintf("test_%v", i)) + } + wg2.Wait() + require.Equal(t, expect, val.Load()) } func TestWaitGroupWrapperRunWithRecover(t *testing.T) { @@ -47,4 +59,34 @@ func TestWaitGroupWrapperRunWithRecover(t *testing.T) { } wg.Wait() require.Equal(t, expect, val.Load()) + + val.Store(0) + wg2 := NewWaitGroupEnhancedWrapper("", nil, false) + for i := int32(0); i < expect; i++ { + wg2.RunWithRecover(func() { + panic("test1") + }, func(r interface{}) { + val.Inc() + }, fmt.Sprintf("test_%v", i)) + } + wg2.Wait() + require.Equal(t, expect, val.Load()) +} + +func TestWaitGroupWrapperCheck(t *testing.T) { + exit := make(chan struct{}) + wg := NewWaitGroupEnhancedWrapper("", exit, false) + quit := make(chan struct{}) + wg.Run(func() { + <-quit + }, "test") + + // need continue check as existed unexited process + close(exit) + require.True(t, wg.check()) + + // no need to continue check as all process exited + quit <- struct{}{} + time.Sleep(1 * time.Second) + require.False(t, wg.check()) } diff --git a/util/watcher/watcher.go b/util/watcher/watcher.go index d91bd89cd076f..fa09c058217b0 100644 --- a/util/watcher/watcher.go +++ b/util/watcher/watcher.go @@ -63,7 +63,7 @@ func NewWatcher() *Watcher { // Start starts the watching func (w *Watcher) Start(d time.Duration) error { - if !w.running.CAS(0, 1) { + if !w.running.CompareAndSwap(0, 1) { return ErrWatcherStarted } @@ -83,7 +83,7 @@ func (w *Watcher) Start(d time.Duration) error { // Close stops the watching func (w *Watcher) Close() { - if !w.running.CAS(1, 0) { + if !w.running.CompareAndSwap(1, 0) { return }